| .. | .. |
|---|
| 20 | 20 | |
|---|
| 21 | 21 | #include <net/dst.h> |
|---|
| 22 | 22 | |
|---|
| 23 | | -#include <asm/octeon/octeon.h> |
|---|
| 24 | | - |
|---|
| 25 | | -#include "ethernet-defines.h" |
|---|
| 26 | 23 | #include "octeon-ethernet.h" |
|---|
| 24 | +#include "ethernet-defines.h" |
|---|
| 27 | 25 | #include "ethernet-mem.h" |
|---|
| 28 | 26 | #include "ethernet-rx.h" |
|---|
| 29 | 27 | #include "ethernet-tx.h" |
|---|
| 30 | 28 | #include "ethernet-mdio.h" |
|---|
| 31 | 29 | #include "ethernet-util.h" |
|---|
| 32 | | - |
|---|
| 33 | | -#include <asm/octeon/cvmx-pip.h> |
|---|
| 34 | | -#include <asm/octeon/cvmx-pko.h> |
|---|
| 35 | | -#include <asm/octeon/cvmx-fau.h> |
|---|
| 36 | | -#include <asm/octeon/cvmx-ipd.h> |
|---|
| 37 | | -#include <asm/octeon/cvmx-helper.h> |
|---|
| 38 | | -#include <asm/octeon/cvmx-asxx-defs.h> |
|---|
| 39 | | -#include <asm/octeon/cvmx-gmxx-defs.h> |
|---|
| 40 | | -#include <asm/octeon/cvmx-smix-defs.h> |
|---|
| 41 | 30 | |
|---|
| 42 | 31 | #define OCTEON_MAX_MTU 65392 |
|---|
| 43 | 32 | |
|---|
| .. | .. |
|---|
| 142 | 131 | if (priv->poll) |
|---|
| 143 | 132 | priv->poll(cvm_oct_device[priv->port]); |
|---|
| 144 | 133 | |
|---|
| 145 | | - cvm_oct_device[priv->port]->netdev_ops->ndo_get_stats( |
|---|
| 146 | | - cvm_oct_device[priv->port]); |
|---|
| 134 | + cvm_oct_device[priv->port]->netdev_ops->ndo_get_stats |
|---|
| 135 | + (cvm_oct_device[priv->port]); |
|---|
| 147 | 136 | |
|---|
| 148 | 137 | if (!atomic_read(&cvm_oct_poll_queue_stopping)) |
|---|
| 149 | 138 | schedule_delayed_work(&priv->port_periodic_work, HZ); |
|---|
| .. | .. |
|---|
| 184 | 173 | */ |
|---|
| 185 | 174 | int cvm_oct_free_work(void *work_queue_entry) |
|---|
| 186 | 175 | { |
|---|
| 187 | | - cvmx_wqe_t *work = work_queue_entry; |
|---|
| 176 | + struct cvmx_wqe *work = work_queue_entry; |
|---|
| 188 | 177 | |
|---|
| 189 | 178 | int segments = work->word2.s.bufs; |
|---|
| 190 | 179 | union cvmx_buf_ptr segment_ptr = work->packet_ptr; |
|---|
| .. | .. |
|---|
| 423 | 412 | if (priv->of_node) |
|---|
| 424 | 413 | mac = of_get_mac_address(priv->of_node); |
|---|
| 425 | 414 | |
|---|
| 426 | | - if (mac) |
|---|
| 415 | + if (!IS_ERR_OR_NULL(mac)) |
|---|
| 427 | 416 | ether_addr_copy(dev->dev_addr, mac); |
|---|
| 428 | 417 | else |
|---|
| 429 | 418 | eth_hw_addr_random(dev); |
|---|
| .. | .. |
|---|
| 472 | 461 | struct octeon_ethernet *priv = netdev_priv(dev); |
|---|
| 473 | 462 | int interface = INTERFACE(priv->port); |
|---|
| 474 | 463 | int index = INDEX(priv->port); |
|---|
| 475 | | - cvmx_helper_link_info_t link_info; |
|---|
| 464 | + union cvmx_helper_link_info link_info; |
|---|
| 476 | 465 | int rv; |
|---|
| 477 | 466 | |
|---|
| 478 | 467 | rv = cvm_oct_phy_setup_device(dev); |
|---|
| .. | .. |
|---|
| 508 | 497 | void cvm_oct_link_poll(struct net_device *dev) |
|---|
| 509 | 498 | { |
|---|
| 510 | 499 | struct octeon_ethernet *priv = netdev_priv(dev); |
|---|
| 511 | | - cvmx_helper_link_info_t link_info; |
|---|
| 500 | + union cvmx_helper_link_info link_info; |
|---|
| 512 | 501 | |
|---|
| 513 | 502 | link_info = cvmx_helper_link_get(priv->port); |
|---|
| 514 | 503 | if (link_info.u64 == priv->link_info) |
|---|
| .. | .. |
|---|
| 622 | 611 | #endif |
|---|
| 623 | 612 | }; |
|---|
| 624 | 613 | |
|---|
| 625 | | -static struct device_node *cvm_oct_of_get_child( |
|---|
| 626 | | - const struct device_node *parent, int reg_val) |
|---|
| 614 | +static struct device_node *cvm_oct_of_get_child |
|---|
| 615 | + (const struct device_node *parent, int reg_val) |
|---|
| 627 | 616 | { |
|---|
| 628 | 617 | struct device_node *node = NULL; |
|---|
| 629 | 618 | int size; |
|---|
| .. | .. |
|---|
| 655 | 644 | return np; |
|---|
| 656 | 645 | } |
|---|
| 657 | 646 | |
|---|
| 658 | | -static void cvm_set_rgmii_delay(struct device_node *np, int iface, int port) |
|---|
| 647 | +static void cvm_set_rgmii_delay(struct octeon_ethernet *priv, int iface, |
|---|
| 648 | + int port) |
|---|
| 659 | 649 | { |
|---|
| 650 | + struct device_node *np = priv->of_node; |
|---|
| 660 | 651 | u32 delay_value; |
|---|
| 652 | + bool rx_delay; |
|---|
| 653 | + bool tx_delay; |
|---|
| 661 | 654 | |
|---|
| 662 | | - if (!of_property_read_u32(np, "rx-delay", &delay_value)) |
|---|
| 655 | + /* By default, both RX/TX delay is enabled in |
|---|
| 656 | + * __cvmx_helper_rgmii_enable(). |
|---|
| 657 | + */ |
|---|
| 658 | + rx_delay = true; |
|---|
| 659 | + tx_delay = true; |
|---|
| 660 | + |
|---|
| 661 | + if (!of_property_read_u32(np, "rx-delay", &delay_value)) { |
|---|
| 663 | 662 | cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(port, iface), delay_value); |
|---|
| 664 | | - if (!of_property_read_u32(np, "tx-delay", &delay_value)) |
|---|
| 663 | + rx_delay = delay_value > 0; |
|---|
| 664 | + } |
|---|
| 665 | + if (!of_property_read_u32(np, "tx-delay", &delay_value)) { |
|---|
| 665 | 666 | cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(port, iface), delay_value); |
|---|
| 667 | + tx_delay = delay_value > 0; |
|---|
| 668 | + } |
|---|
| 669 | + |
|---|
| 670 | + if (!rx_delay && !tx_delay) |
|---|
| 671 | + priv->phy_mode = PHY_INTERFACE_MODE_RGMII_ID; |
|---|
| 672 | + else if (!rx_delay) |
|---|
| 673 | + priv->phy_mode = PHY_INTERFACE_MODE_RGMII_RXID; |
|---|
| 674 | + else if (!tx_delay) |
|---|
| 675 | + priv->phy_mode = PHY_INTERFACE_MODE_RGMII_TXID; |
|---|
| 676 | + else |
|---|
| 677 | + priv->phy_mode = PHY_INTERFACE_MODE_RGMII; |
|---|
| 666 | 678 | } |
|---|
| 667 | 679 | |
|---|
| 668 | 680 | static int cvm_oct_probe(struct platform_device *pdev) |
|---|
| .. | .. |
|---|
| 677 | 689 | #if IS_ENABLED(CONFIG_VLAN_8021Q) |
|---|
| 678 | 690 | mtu_overhead += VLAN_HLEN; |
|---|
| 679 | 691 | #endif |
|---|
| 680 | | - |
|---|
| 681 | | - octeon_mdiobus_force_mod_depencency(); |
|---|
| 682 | 692 | |
|---|
| 683 | 693 | pip = pdev->dev.of_node; |
|---|
| 684 | 694 | if (!pip) { |
|---|
| .. | .. |
|---|
| 773 | 783 | priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED; |
|---|
| 774 | 784 | priv->port = CVMX_PIP_NUM_INPUT_PORTS; |
|---|
| 775 | 785 | priv->queue = -1; |
|---|
| 776 | | - strcpy(dev->name, "pow%d"); |
|---|
| 786 | + strscpy(dev->name, "pow%d", sizeof(dev->name)); |
|---|
| 777 | 787 | for (qos = 0; qos < 16; qos++) |
|---|
| 778 | 788 | skb_queue_head_init(&priv->tx_free_list[qos]); |
|---|
| 779 | 789 | dev->min_mtu = VLAN_ETH_ZLEN - mtu_overhead; |
|---|
| .. | .. |
|---|
| 819 | 829 | priv = netdev_priv(dev); |
|---|
| 820 | 830 | priv->netdev = dev; |
|---|
| 821 | 831 | priv->of_node = cvm_oct_node_for_port(pip, interface, |
|---|
| 822 | | - port_index); |
|---|
| 832 | + port_index); |
|---|
| 823 | 833 | |
|---|
| 824 | 834 | INIT_DELAYED_WORK(&priv->port_periodic_work, |
|---|
| 825 | 835 | cvm_oct_periodic_worker); |
|---|
| .. | .. |
|---|
| 827 | 837 | priv->port = port; |
|---|
| 828 | 838 | priv->queue = cvmx_pko_get_base_queue(priv->port); |
|---|
| 829 | 839 | priv->fau = fau - cvmx_pko_get_num_queues(port) * 4; |
|---|
| 840 | + priv->phy_mode = PHY_INTERFACE_MODE_NA; |
|---|
| 830 | 841 | for (qos = 0; qos < 16; qos++) |
|---|
| 831 | 842 | skb_queue_head_init(&priv->tx_free_list[qos]); |
|---|
| 832 | 843 | for (qos = 0; qos < cvmx_pko_get_num_queues(port); |
|---|
| .. | .. |
|---|
| 844 | 855 | |
|---|
| 845 | 856 | case CVMX_HELPER_INTERFACE_MODE_NPI: |
|---|
| 846 | 857 | dev->netdev_ops = &cvm_oct_npi_netdev_ops; |
|---|
| 847 | | - strcpy(dev->name, "npi%d"); |
|---|
| 858 | + strscpy(dev->name, "npi%d", sizeof(dev->name)); |
|---|
| 848 | 859 | break; |
|---|
| 849 | 860 | |
|---|
| 850 | 861 | case CVMX_HELPER_INTERFACE_MODE_XAUI: |
|---|
| 851 | 862 | dev->netdev_ops = &cvm_oct_xaui_netdev_ops; |
|---|
| 852 | | - strcpy(dev->name, "xaui%d"); |
|---|
| 863 | + strscpy(dev->name, "xaui%d", sizeof(dev->name)); |
|---|
| 853 | 864 | break; |
|---|
| 854 | 865 | |
|---|
| 855 | 866 | case CVMX_HELPER_INTERFACE_MODE_LOOP: |
|---|
| 856 | 867 | dev->netdev_ops = &cvm_oct_npi_netdev_ops; |
|---|
| 857 | | - strcpy(dev->name, "loop%d"); |
|---|
| 868 | + strscpy(dev->name, "loop%d", sizeof(dev->name)); |
|---|
| 858 | 869 | break; |
|---|
| 859 | 870 | |
|---|
| 860 | 871 | case CVMX_HELPER_INTERFACE_MODE_SGMII: |
|---|
| 872 | + priv->phy_mode = PHY_INTERFACE_MODE_SGMII; |
|---|
| 861 | 873 | dev->netdev_ops = &cvm_oct_sgmii_netdev_ops; |
|---|
| 862 | | - strcpy(dev->name, "eth%d"); |
|---|
| 874 | + strscpy(dev->name, "eth%d", sizeof(dev->name)); |
|---|
| 863 | 875 | break; |
|---|
| 864 | 876 | |
|---|
| 865 | 877 | case CVMX_HELPER_INTERFACE_MODE_SPI: |
|---|
| 866 | 878 | dev->netdev_ops = &cvm_oct_spi_netdev_ops; |
|---|
| 867 | | - strcpy(dev->name, "spi%d"); |
|---|
| 879 | + strscpy(dev->name, "spi%d", sizeof(dev->name)); |
|---|
| 880 | + break; |
|---|
| 881 | + |
|---|
| 882 | + case CVMX_HELPER_INTERFACE_MODE_GMII: |
|---|
| 883 | + priv->phy_mode = PHY_INTERFACE_MODE_GMII; |
|---|
| 884 | + dev->netdev_ops = &cvm_oct_rgmii_netdev_ops; |
|---|
| 885 | + strscpy(dev->name, "eth%d", sizeof(dev->name)); |
|---|
| 868 | 886 | break; |
|---|
| 869 | 887 | |
|---|
| 870 | 888 | case CVMX_HELPER_INTERFACE_MODE_RGMII: |
|---|
| 871 | | - case CVMX_HELPER_INTERFACE_MODE_GMII: |
|---|
| 872 | 889 | dev->netdev_ops = &cvm_oct_rgmii_netdev_ops; |
|---|
| 873 | | - strcpy(dev->name, "eth%d"); |
|---|
| 874 | | - cvm_set_rgmii_delay(priv->of_node, interface, |
|---|
| 890 | + strscpy(dev->name, "eth%d", sizeof(dev->name)); |
|---|
| 891 | + cvm_set_rgmii_delay(priv, interface, |
|---|
| 875 | 892 | port_index); |
|---|
| 876 | 893 | break; |
|---|
| 877 | 894 | } |
|---|
| .. | .. |
|---|
| 977 | 994 | |
|---|
| 978 | 995 | module_platform_driver(cvm_oct_driver); |
|---|
| 979 | 996 | |
|---|
| 997 | +MODULE_SOFTDEP("pre: mdio-cavium"); |
|---|
| 980 | 998 | MODULE_LICENSE("GPL"); |
|---|
| 981 | 999 | MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>"); |
|---|
| 982 | 1000 | MODULE_DESCRIPTION("Cavium Networks Octeon ethernet driver."); |
|---|