linux/drivers/staging/octeon/ethernet.c
<<
>>
Prefs
   1/**********************************************************************
   2 * Author: Cavium Networks
   3 *
   4 * Contact: support@caviumnetworks.com
   5 * This file is part of the OCTEON SDK
   6 *
   7 * Copyright (c) 2003-2007 Cavium Networks
   8 *
   9 * This file is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License, Version 2, as
  11 * published by the Free Software Foundation.
  12 *
  13 * This file is distributed in the hope that it will be useful, but
  14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
  15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
  16 * NONINFRINGEMENT.  See the GNU General Public License for more
  17 * details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this file; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22 * or visit http://www.gnu.org/licenses/.
  23 *
  24 * This file may also be available under a different license from Cavium.
  25 * Contact Cavium Networks for more information
  26**********************************************************************/
  27#include <linux/platform_device.h>
  28#include <linux/kernel.h>
  29#include <linux/init.h>
  30#include <linux/module.h>
  31#include <linux/netdevice.h>
  32#include <linux/etherdevice.h>
  33#include <linux/phy.h>
  34#include <linux/slab.h>
  35#include <linux/interrupt.h>
  36#include <linux/of_net.h>
  37
  38#include <net/dst.h>
  39
  40#include <asm/octeon/octeon.h>
  41
  42#include "ethernet-defines.h"
  43#include "octeon-ethernet.h"
  44#include "ethernet-mem.h"
  45#include "ethernet-rx.h"
  46#include "ethernet-tx.h"
  47#include "ethernet-mdio.h"
  48#include "ethernet-util.h"
  49
  50#include <asm/octeon/cvmx-pip.h>
  51#include <asm/octeon/cvmx-pko.h>
  52#include <asm/octeon/cvmx-fau.h>
  53#include <asm/octeon/cvmx-ipd.h>
  54#include <asm/octeon/cvmx-helper.h>
  55
  56#include <asm/octeon/cvmx-gmxx-defs.h>
  57#include <asm/octeon/cvmx-smix-defs.h>
  58
  59#if defined(CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS) \
  60        && CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS
  61int num_packet_buffers = CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS;
  62#else
  63int num_packet_buffers = 1024;
  64#endif
  65module_param(num_packet_buffers, int, 0444);
  66MODULE_PARM_DESC(num_packet_buffers, "\n"
  67        "\tNumber of packet buffers to allocate and store in the\n"
  68        "\tFPA. By default, 1024 packet buffers are used unless\n"
  69        "\tCONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS is defined.");
  70
  71int pow_receive_group = 15;
  72module_param(pow_receive_group, int, 0444);
  73MODULE_PARM_DESC(pow_receive_group, "\n"
  74        "\tPOW group to receive packets from. All ethernet hardware\n"
  75        "\twill be configured to send incoming packets to this POW\n"
  76        "\tgroup. Also any other software can submit packets to this\n"
  77        "\tgroup for the kernel to process.");
  78
  79int pow_send_group = -1;
  80module_param(pow_send_group, int, 0644);
  81MODULE_PARM_DESC(pow_send_group, "\n"
  82        "\tPOW group to send packets to other software on. This\n"
  83        "\tcontrols the creation of the virtual device pow0.\n"
  84        "\talways_use_pow also depends on this value.");
  85
  86int always_use_pow;
  87module_param(always_use_pow, int, 0444);
  88MODULE_PARM_DESC(always_use_pow, "\n"
  89        "\tWhen set, always send to the pow group. This will cause\n"
  90        "\tpackets sent to real ethernet devices to be sent to the\n"
  91        "\tPOW group instead of the hardware. Unless some other\n"
  92        "\tapplication changes the config, packets will still be\n"
  93        "\treceived from the low level hardware. Use this option\n"
  94        "\tto allow a CVMX app to intercept all packets from the\n"
  95        "\tlinux kernel. You must specify pow_send_group along with\n"
  96        "\tthis option.");
  97
  98char pow_send_list[128] = "";
  99module_param_string(pow_send_list, pow_send_list, sizeof(pow_send_list), 0444);
 100MODULE_PARM_DESC(pow_send_list, "\n"
 101        "\tComma separated list of ethernet devices that should use the\n"
 102        "\tPOW for transmit instead of the actual ethernet hardware. This\n"
 103        "\tis a per port version of always_use_pow. always_use_pow takes\n"
 104        "\tprecedence over this list. For example, setting this to\n"
 105        "\t\"eth2,spi3,spi7\" would cause these three devices to transmit\n"
 106        "\tusing the pow_send_group.");
 107
 108int max_rx_cpus = -1;
 109module_param(max_rx_cpus, int, 0444);
 110MODULE_PARM_DESC(max_rx_cpus, "\n"
 111        "\t\tThe maximum number of CPUs to use for packet reception.\n"
 112        "\t\tUse -1 to use all available CPUs.");
 113
 114int rx_napi_weight = 32;
 115module_param(rx_napi_weight, int, 0444);
 116MODULE_PARM_DESC(rx_napi_weight, "The NAPI WEIGHT parameter.");
 117
 118/**
 119 * cvm_oct_poll_queue - Workqueue for polling operations.
 120 */
 121struct workqueue_struct *cvm_oct_poll_queue;
 122
 123/**
 124 * cvm_oct_poll_queue_stopping - flag to indicate polling should stop.
 125 *
 126 * Set to one right before cvm_oct_poll_queue is destroyed.
 127 */
 128atomic_t cvm_oct_poll_queue_stopping = ATOMIC_INIT(0);
 129
 130/**
 131 * Array of every ethernet device owned by this driver indexed by
 132 * the ipd input port number.
 133 */
 134struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS];
 135
 136u64 cvm_oct_tx_poll_interval;
 137
 138static void cvm_oct_rx_refill_worker(struct work_struct *work);
 139static DECLARE_DELAYED_WORK(cvm_oct_rx_refill_work, cvm_oct_rx_refill_worker);
 140
 141static void cvm_oct_rx_refill_worker(struct work_struct *work)
 142{
 143        /*
 144         * FPA 0 may have been drained, try to refill it if we need
 145         * more than num_packet_buffers / 2, otherwise normal receive
 146         * processing will refill it.  If it were drained, no packets
 147         * could be received so cvm_oct_napi_poll would never be
 148         * invoked to do the refill.
 149         */
 150        cvm_oct_rx_refill_pool(num_packet_buffers / 2);
 151
 152        if (!atomic_read(&cvm_oct_poll_queue_stopping))
 153                queue_delayed_work(cvm_oct_poll_queue,
 154                                   &cvm_oct_rx_refill_work, HZ);
 155}
 156
 157static void cvm_oct_periodic_worker(struct work_struct *work)
 158{
 159        struct octeon_ethernet *priv = container_of(work,
 160                                                    struct octeon_ethernet,
 161                                                    port_periodic_work.work);
 162
 163        if (priv->poll)
 164                priv->poll(cvm_oct_device[priv->port]);
 165
 166        cvm_oct_device[priv->port]->netdev_ops->ndo_get_stats(cvm_oct_device[priv->port]);
 167
 168        if (!atomic_read(&cvm_oct_poll_queue_stopping))
 169                queue_delayed_work(cvm_oct_poll_queue, &priv->port_periodic_work, HZ);
 170 }
 171
 172static void cvm_oct_configure_common_hw(void)
 173{
 174        /* Setup the FPA */
 175        cvmx_fpa_enable();
 176        cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
 177                             num_packet_buffers);
 178        cvm_oct_mem_fill_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
 179                             num_packet_buffers);
 180        if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
 181                cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
 182                                     CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
 183
 184        if (USE_RED)
 185                cvmx_helper_setup_red(num_packet_buffers / 4,
 186                                      num_packet_buffers / 8);
 187
 188}
 189
 190/**
 191 * cvm_oct_free_work- Free a work queue entry
 192 *
 193 * @work_queue_entry: Work queue entry to free
 194 *
 195 * Returns Zero on success, Negative on failure.
 196 */
 197int cvm_oct_free_work(void *work_queue_entry)
 198{
 199        cvmx_wqe_t *work = work_queue_entry;
 200
 201        int segments = work->word2.s.bufs;
 202        union cvmx_buf_ptr segment_ptr = work->packet_ptr;
 203
 204        while (segments--) {
 205                union cvmx_buf_ptr next_ptr = *(union cvmx_buf_ptr *)
 206                        cvmx_phys_to_ptr(segment_ptr.s.addr - 8);
 207                if (unlikely(!segment_ptr.s.i))
 208                        cvmx_fpa_free(cvm_oct_get_buffer_ptr(segment_ptr),
 209                                      segment_ptr.s.pool,
 210                                      DONT_WRITEBACK(CVMX_FPA_PACKET_POOL_SIZE /
 211                                                     128));
 212                segment_ptr = next_ptr;
 213        }
 214        cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
 215
 216        return 0;
 217}
 218EXPORT_SYMBOL(cvm_oct_free_work);
 219
 220/**
 221 * cvm_oct_common_get_stats - get the low level ethernet statistics
 222 * @dev:    Device to get the statistics from
 223 *
 224 * Returns Pointer to the statistics
 225 */
 226static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev)
 227{
 228        cvmx_pip_port_status_t rx_status;
 229        cvmx_pko_port_status_t tx_status;
 230        struct octeon_ethernet *priv = netdev_priv(dev);
 231
 232        if (priv->port < CVMX_PIP_NUM_INPUT_PORTS) {
 233                if (octeon_is_simulation()) {
 234                        /* The simulator doesn't support statistics */
 235                        memset(&rx_status, 0, sizeof(rx_status));
 236                        memset(&tx_status, 0, sizeof(tx_status));
 237                } else {
 238                        cvmx_pip_get_port_status(priv->port, 1, &rx_status);
 239                        cvmx_pko_get_port_status(priv->port, 1, &tx_status);
 240                }
 241
 242                priv->stats.rx_packets += rx_status.inb_packets;
 243                priv->stats.tx_packets += tx_status.packets;
 244                priv->stats.rx_bytes += rx_status.inb_octets;
 245                priv->stats.tx_bytes += tx_status.octets;
 246                priv->stats.multicast += rx_status.multicast_packets;
 247                priv->stats.rx_crc_errors += rx_status.inb_errors;
 248                priv->stats.rx_frame_errors += rx_status.fcs_align_err_packets;
 249
 250                /*
 251                 * The drop counter must be incremented atomically
 252                 * since the RX tasklet also increments it.
 253                 */
 254#ifdef CONFIG_64BIT
 255                atomic64_add(rx_status.dropped_packets,
 256                             (atomic64_t *)&priv->stats.rx_dropped);
 257#else
 258                atomic_add(rx_status.dropped_packets,
 259                             (atomic_t *)&priv->stats.rx_dropped);
 260#endif
 261        }
 262
 263        return &priv->stats;
 264}
 265
 266/**
 267 * cvm_oct_common_change_mtu - change the link MTU
 268 * @dev:     Device to change
 269 * @new_mtu: The new MTU
 270 *
 271 * Returns Zero on success
 272 */
 273static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu)
 274{
 275        struct octeon_ethernet *priv = netdev_priv(dev);
 276        int interface = INTERFACE(priv->port);
 277        int index = INDEX(priv->port);
 278#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 279        int vlan_bytes = 4;
 280#else
 281        int vlan_bytes = 0;
 282#endif
 283
 284        /*
 285         * Limit the MTU to make sure the ethernet packets are between
 286         * 64 bytes and 65535 bytes.
 287         */
 288        if ((new_mtu + 14 + 4 + vlan_bytes < 64)
 289            || (new_mtu + 14 + 4 + vlan_bytes > 65392)) {
 290                pr_err("MTU must be between %d and %d.\n",
 291                       64 - 14 - 4 - vlan_bytes, 65392 - 14 - 4 - vlan_bytes);
 292                return -EINVAL;
 293        }
 294        dev->mtu = new_mtu;
 295
 296        if ((interface < 2)
 297            && (cvmx_helper_interface_get_mode(interface) !=
 298                CVMX_HELPER_INTERFACE_MODE_SPI)) {
 299                /* Add ethernet header and FCS, and VLAN if configured. */
 300                int max_packet = new_mtu + 14 + 4 + vlan_bytes;
 301
 302                if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
 303                    || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
 304                        /* Signal errors on packets larger than the MTU */
 305                        cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface),
 306                                       max_packet);
 307                } else {
 308                        /*
 309                         * Set the hardware to truncate packets larger
 310                         * than the MTU and smaller the 64 bytes.
 311                         */
 312                        union cvmx_pip_frm_len_chkx frm_len_chk;
 313                        frm_len_chk.u64 = 0;
 314                        frm_len_chk.s.minlen = 64;
 315                        frm_len_chk.s.maxlen = max_packet;
 316                        cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface),
 317                                       frm_len_chk.u64);
 318                }
 319                /*
 320                 * Set the hardware to truncate packets larger than
 321                 * the MTU. The jabber register must be set to a
 322                 * multiple of 8 bytes, so round up.
 323                 */
 324                cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface),
 325                               (max_packet + 7) & ~7u);
 326        }
 327        return 0;
 328}
 329
 330/**
 331 * cvm_oct_common_set_multicast_list - set the multicast list
 332 * @dev:    Device to work on
 333 */
 334static void cvm_oct_common_set_multicast_list(struct net_device *dev)
 335{
 336        union cvmx_gmxx_prtx_cfg gmx_cfg;
 337        struct octeon_ethernet *priv = netdev_priv(dev);
 338        int interface = INTERFACE(priv->port);
 339        int index = INDEX(priv->port);
 340
 341        if ((interface < 2)
 342            && (cvmx_helper_interface_get_mode(interface) !=
 343                CVMX_HELPER_INTERFACE_MODE_SPI)) {
 344                union cvmx_gmxx_rxx_adr_ctl control;
 345                control.u64 = 0;
 346                control.s.bcst = 1;     /* Allow broadcast MAC addresses */
 347
 348                if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI) ||
 349                    (dev->flags & IFF_PROMISC))
 350                        /* Force accept multicast packets */
 351                        control.s.mcst = 2;
 352                else
 353                        /* Force reject multicast packets */
 354                        control.s.mcst = 1;
 355
 356                if (dev->flags & IFF_PROMISC)
 357                        /*
 358                         * Reject matches if promisc. Since CAM is
 359                         * shut off, should accept everything.
 360                         */
 361                        control.s.cam_mode = 0;
 362                else
 363                        /* Filter packets based on the CAM */
 364                        control.s.cam_mode = 1;
 365
 366                gmx_cfg.u64 =
 367                    cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
 368                cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
 369                               gmx_cfg.u64 & ~1ull);
 370
 371                cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface),
 372                               control.u64);
 373                if (dev->flags & IFF_PROMISC)
 374                        cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
 375                                       (index, interface), 0);
 376                else
 377                        cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
 378                                       (index, interface), 1);
 379
 380                cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
 381                               gmx_cfg.u64);
 382        }
 383}
 384
 385/**
 386 * cvm_oct_common_set_mac_address - set the hardware MAC address for a device
 387 * @dev:    The device in question.
 388 * @addr:   Address structure to change it too.
 389
 390 * Returns Zero on success
 391 */
 392static int cvm_oct_set_mac_filter(struct net_device *dev)
 393{
 394        struct octeon_ethernet *priv = netdev_priv(dev);
 395        union cvmx_gmxx_prtx_cfg gmx_cfg;
 396        int interface = INTERFACE(priv->port);
 397        int index = INDEX(priv->port);
 398
 399        if ((interface < 2)
 400            && (cvmx_helper_interface_get_mode(interface) !=
 401                CVMX_HELPER_INTERFACE_MODE_SPI)) {
 402                int i;
 403                uint8_t *ptr = dev->dev_addr;
 404                uint64_t mac = 0;
 405                for (i = 0; i < 6; i++)
 406                        mac = (mac << 8) | (uint64_t)ptr[i];
 407
 408                gmx_cfg.u64 =
 409                    cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
 410                cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
 411                               gmx_cfg.u64 & ~1ull);
 412
 413                cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac);
 414                cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface),
 415                               ptr[0]);
 416                cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface),
 417                               ptr[1]);
 418                cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface),
 419                               ptr[2]);
 420                cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface),
 421                               ptr[3]);
 422                cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface),
 423                               ptr[4]);
 424                cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface),
 425                               ptr[5]);
 426                cvm_oct_common_set_multicast_list(dev);
 427                cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
 428                               gmx_cfg.u64);
 429        }
 430        return 0;
 431}
 432
 433static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
 434{
 435        int r = eth_mac_addr(dev, addr);
 436
 437        if (r)
 438                return r;
 439        return cvm_oct_set_mac_filter(dev);
 440}
 441
 442/**
 443 * cvm_oct_common_init - per network device initialization
 444 * @dev:    Device to initialize
 445 *
 446 * Returns Zero on success
 447 */
 448int cvm_oct_common_init(struct net_device *dev)
 449{
 450        struct octeon_ethernet *priv = netdev_priv(dev);
 451        const u8 *mac = NULL;
 452
 453        if (priv->of_node)
 454                mac = of_get_mac_address(priv->of_node);
 455
 456        if (mac && is_valid_ether_addr(mac))
 457                memcpy(dev->dev_addr, mac, ETH_ALEN);
 458        else
 459                eth_hw_addr_random(dev);
 460
 461        /*
 462         * Force the interface to use the POW send if always_use_pow
 463         * was specified or it is in the pow send list.
 464         */
 465        if ((pow_send_group != -1)
 466            && (always_use_pow || strstr(pow_send_list, dev->name)))
 467                priv->queue = -1;
 468
 469        if (priv->queue != -1) {
 470                dev->features |= NETIF_F_SG;
 471                if (USE_HW_TCPUDP_CHECKSUM)
 472                        dev->features |= NETIF_F_IP_CSUM;
 473        }
 474
 475        /* We do our own locking, Linux doesn't need to */
 476        dev->features |= NETIF_F_LLTX;
 477        SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
 478
 479        cvm_oct_phy_setup_device(dev);
 480        cvm_oct_set_mac_filter(dev);
 481        dev->netdev_ops->ndo_change_mtu(dev, dev->mtu);
 482
 483        /*
 484         * Zero out stats for port so we won't mistakenly show
 485         * counters from the bootloader.
 486         */
 487        memset(dev->netdev_ops->ndo_get_stats(dev), 0,
 488               sizeof(struct net_device_stats));
 489
 490        return 0;
 491}
 492
 493void cvm_oct_common_uninit(struct net_device *dev)
 494{
 495        struct octeon_ethernet *priv = netdev_priv(dev);
 496
 497        if (priv->phydev)
 498                phy_disconnect(priv->phydev);
 499}
 500
 501static const struct net_device_ops cvm_oct_npi_netdev_ops = {
 502        .ndo_init               = cvm_oct_common_init,
 503        .ndo_uninit             = cvm_oct_common_uninit,
 504        .ndo_start_xmit         = cvm_oct_xmit,
 505        .ndo_set_rx_mode        = cvm_oct_common_set_multicast_list,
 506        .ndo_set_mac_address    = cvm_oct_common_set_mac_address,
 507        .ndo_do_ioctl           = cvm_oct_ioctl,
 508        .ndo_change_mtu         = cvm_oct_common_change_mtu,
 509        .ndo_get_stats          = cvm_oct_common_get_stats,
 510#ifdef CONFIG_NET_POLL_CONTROLLER
 511        .ndo_poll_controller    = cvm_oct_poll_controller,
 512#endif
 513};
 514static const struct net_device_ops cvm_oct_xaui_netdev_ops = {
 515        .ndo_init               = cvm_oct_xaui_init,
 516        .ndo_uninit             = cvm_oct_xaui_uninit,
 517        .ndo_open               = cvm_oct_xaui_open,
 518        .ndo_stop               = cvm_oct_xaui_stop,
 519        .ndo_start_xmit         = cvm_oct_xmit,
 520        .ndo_set_rx_mode        = cvm_oct_common_set_multicast_list,
 521        .ndo_set_mac_address    = cvm_oct_common_set_mac_address,
 522        .ndo_do_ioctl           = cvm_oct_ioctl,
 523        .ndo_change_mtu         = cvm_oct_common_change_mtu,
 524        .ndo_get_stats          = cvm_oct_common_get_stats,
 525#ifdef CONFIG_NET_POLL_CONTROLLER
 526        .ndo_poll_controller    = cvm_oct_poll_controller,
 527#endif
 528};
 529static const struct net_device_ops cvm_oct_sgmii_netdev_ops = {
 530        .ndo_init               = cvm_oct_sgmii_init,
 531        .ndo_uninit             = cvm_oct_sgmii_uninit,
 532        .ndo_open               = cvm_oct_sgmii_open,
 533        .ndo_stop               = cvm_oct_sgmii_stop,
 534        .ndo_start_xmit         = cvm_oct_xmit,
 535        .ndo_set_rx_mode        = cvm_oct_common_set_multicast_list,
 536        .ndo_set_mac_address    = cvm_oct_common_set_mac_address,
 537        .ndo_do_ioctl           = cvm_oct_ioctl,
 538        .ndo_change_mtu         = cvm_oct_common_change_mtu,
 539        .ndo_get_stats          = cvm_oct_common_get_stats,
 540#ifdef CONFIG_NET_POLL_CONTROLLER
 541        .ndo_poll_controller    = cvm_oct_poll_controller,
 542#endif
 543};
 544static const struct net_device_ops cvm_oct_spi_netdev_ops = {
 545        .ndo_init               = cvm_oct_spi_init,
 546        .ndo_uninit             = cvm_oct_spi_uninit,
 547        .ndo_start_xmit         = cvm_oct_xmit,
 548        .ndo_set_rx_mode        = cvm_oct_common_set_multicast_list,
 549        .ndo_set_mac_address    = cvm_oct_common_set_mac_address,
 550        .ndo_do_ioctl           = cvm_oct_ioctl,
 551        .ndo_change_mtu         = cvm_oct_common_change_mtu,
 552        .ndo_get_stats          = cvm_oct_common_get_stats,
 553#ifdef CONFIG_NET_POLL_CONTROLLER
 554        .ndo_poll_controller    = cvm_oct_poll_controller,
 555#endif
 556};
 557static const struct net_device_ops cvm_oct_rgmii_netdev_ops = {
 558        .ndo_init               = cvm_oct_rgmii_init,
 559        .ndo_uninit             = cvm_oct_rgmii_uninit,
 560        .ndo_open               = cvm_oct_rgmii_open,
 561        .ndo_stop               = cvm_oct_rgmii_stop,
 562        .ndo_start_xmit         = cvm_oct_xmit,
 563        .ndo_set_rx_mode        = cvm_oct_common_set_multicast_list,
 564        .ndo_set_mac_address    = cvm_oct_common_set_mac_address,
 565        .ndo_do_ioctl           = cvm_oct_ioctl,
 566        .ndo_change_mtu         = cvm_oct_common_change_mtu,
 567        .ndo_get_stats          = cvm_oct_common_get_stats,
 568#ifdef CONFIG_NET_POLL_CONTROLLER
 569        .ndo_poll_controller    = cvm_oct_poll_controller,
 570#endif
 571};
 572static const struct net_device_ops cvm_oct_pow_netdev_ops = {
 573        .ndo_init               = cvm_oct_common_init,
 574        .ndo_start_xmit         = cvm_oct_xmit_pow,
 575        .ndo_set_rx_mode        = cvm_oct_common_set_multicast_list,
 576        .ndo_set_mac_address    = cvm_oct_common_set_mac_address,
 577        .ndo_do_ioctl           = cvm_oct_ioctl,
 578        .ndo_change_mtu         = cvm_oct_common_change_mtu,
 579        .ndo_get_stats          = cvm_oct_common_get_stats,
 580#ifdef CONFIG_NET_POLL_CONTROLLER
 581        .ndo_poll_controller    = cvm_oct_poll_controller,
 582#endif
 583};
 584
 585extern void octeon_mdiobus_force_mod_depencency(void);
 586
 587static struct device_node *cvm_oct_of_get_child(const struct device_node *parent,
 588                                                           int reg_val)
 589{
 590        struct device_node *node = NULL;
 591        int size;
 592        const __be32 *addr;
 593
 594        for (;;) {
 595                node = of_get_next_child(parent, node);
 596                if (!node)
 597                        break;
 598                addr = of_get_property(node, "reg", &size);
 599                if (addr && (be32_to_cpu(*addr) == reg_val))
 600                        break;
 601        }
 602        return node;
 603}
 604
 605static struct device_node *cvm_oct_node_for_port(struct device_node *pip,
 606                                                            int interface, int port)
 607{
 608        struct device_node *ni, *np;
 609
 610        ni = cvm_oct_of_get_child(pip, interface);
 611        if (!ni)
 612                return NULL;
 613
 614        np = cvm_oct_of_get_child(ni, port);
 615        of_node_put(ni);
 616
 617        return np;
 618}
 619
 620static int cvm_oct_probe(struct platform_device *pdev)
 621{
 622        int num_interfaces;
 623        int interface;
 624        int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
 625        int qos;
 626        struct device_node *pip;
 627
 628        octeon_mdiobus_force_mod_depencency();
 629        pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
 630
 631        pip = pdev->dev.of_node;
 632        if (!pip) {
 633                pr_err("Error: No 'pip' in /aliases\n");
 634                return -EINVAL;
 635        }
 636
 637        cvm_oct_poll_queue = create_singlethread_workqueue("octeon-ethernet");
 638        if (cvm_oct_poll_queue == NULL) {
 639                pr_err("octeon-ethernet: Cannot create workqueue");
 640                return -ENOMEM;
 641        }
 642
 643        cvm_oct_configure_common_hw();
 644
 645        cvmx_helper_initialize_packet_io_global();
 646
 647        /* Change the input group for all ports before input is enabled */
 648        num_interfaces = cvmx_helper_get_number_of_interfaces();
 649        for (interface = 0; interface < num_interfaces; interface++) {
 650                int num_ports = cvmx_helper_ports_on_interface(interface);
 651                int port;
 652
 653                for (port = cvmx_helper_get_ipd_port(interface, 0);
 654                     port < cvmx_helper_get_ipd_port(interface, num_ports);
 655                     port++) {
 656                        union cvmx_pip_prt_tagx pip_prt_tagx;
 657                        pip_prt_tagx.u64 =
 658                            cvmx_read_csr(CVMX_PIP_PRT_TAGX(port));
 659                        pip_prt_tagx.s.grp = pow_receive_group;
 660                        cvmx_write_csr(CVMX_PIP_PRT_TAGX(port),
 661                                       pip_prt_tagx.u64);
 662                }
 663        }
 664
 665        cvmx_helper_ipd_and_packet_input_enable();
 666
 667        memset(cvm_oct_device, 0, sizeof(cvm_oct_device));
 668
 669        /*
 670         * Initialize the FAU used for counting packet buffers that
 671         * need to be freed.
 672         */
 673        cvmx_fau_atomic_write32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
 674
 675        /* Initialize the FAU used for counting tx SKBs that need to be freed */
 676        cvmx_fau_atomic_write32(FAU_TOTAL_TX_TO_CLEAN, 0);
 677
 678        if ((pow_send_group != -1)) {
 679                struct net_device *dev;
 680                pr_info("\tConfiguring device for POW only access\n");
 681                dev = alloc_etherdev(sizeof(struct octeon_ethernet));
 682                if (dev) {
 683                        /* Initialize the device private structure. */
 684                        struct octeon_ethernet *priv = netdev_priv(dev);
 685
 686                        dev->netdev_ops = &cvm_oct_pow_netdev_ops;
 687                        priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED;
 688                        priv->port = CVMX_PIP_NUM_INPUT_PORTS;
 689                        priv->queue = -1;
 690                        strcpy(dev->name, "pow%d");
 691                        for (qos = 0; qos < 16; qos++)
 692                                skb_queue_head_init(&priv->tx_free_list[qos]);
 693
 694                        if (register_netdev(dev) < 0) {
 695                                pr_err("Failed to register ethernet device for POW\n");
 696                                free_netdev(dev);
 697                        } else {
 698                                cvm_oct_device[CVMX_PIP_NUM_INPUT_PORTS] = dev;
 699                                pr_info("%s: POW send group %d, receive group %d\n",
 700                                        dev->name, pow_send_group,
 701                                        pow_receive_group);
 702                        }
 703                } else {
 704                        pr_err("Failed to allocate ethernet device for POW\n");
 705                }
 706        }
 707
 708        num_interfaces = cvmx_helper_get_number_of_interfaces();
 709        for (interface = 0; interface < num_interfaces; interface++) {
 710                cvmx_helper_interface_mode_t imode =
 711                    cvmx_helper_interface_get_mode(interface);
 712                int num_ports = cvmx_helper_ports_on_interface(interface);
 713                int port;
 714                int port_index;
 715
 716                for (port_index = 0, port = cvmx_helper_get_ipd_port(interface, 0);
 717                     port < cvmx_helper_get_ipd_port(interface, num_ports);
 718                     port_index++, port++) {
 719                        struct octeon_ethernet *priv;
 720                        struct net_device *dev =
 721                            alloc_etherdev(sizeof(struct octeon_ethernet));
 722                        if (!dev) {
 723                                pr_err("Failed to allocate ethernet device for port %d\n", port);
 724                                continue;
 725                        }
 726
 727                        /* Initialize the device private structure. */
 728                        priv = netdev_priv(dev);
 729                        priv->of_node = cvm_oct_node_for_port(pip, interface, port_index);
 730
 731                        INIT_DELAYED_WORK(&priv->port_periodic_work,
 732                                          cvm_oct_periodic_worker);
 733                        priv->imode = imode;
 734                        priv->port = port;
 735                        priv->queue = cvmx_pko_get_base_queue(priv->port);
 736                        priv->fau = fau - cvmx_pko_get_num_queues(port) * 4;
 737                        for (qos = 0; qos < 16; qos++)
 738                                skb_queue_head_init(&priv->tx_free_list[qos]);
 739                        for (qos = 0; qos < cvmx_pko_get_num_queues(port);
 740                             qos++)
 741                                cvmx_fau_atomic_write32(priv->fau + qos * 4, 0);
 742
 743                        switch (priv->imode) {
 744
 745                        /* These types don't support ports to IPD/PKO */
 746                        case CVMX_HELPER_INTERFACE_MODE_DISABLED:
 747                        case CVMX_HELPER_INTERFACE_MODE_PCIE:
 748                        case CVMX_HELPER_INTERFACE_MODE_PICMG:
 749                                break;
 750
 751                        case CVMX_HELPER_INTERFACE_MODE_NPI:
 752                                dev->netdev_ops = &cvm_oct_npi_netdev_ops;
 753                                strcpy(dev->name, "npi%d");
 754                                break;
 755
 756                        case CVMX_HELPER_INTERFACE_MODE_XAUI:
 757                                dev->netdev_ops = &cvm_oct_xaui_netdev_ops;
 758                                strcpy(dev->name, "xaui%d");
 759                                break;
 760
 761                        case CVMX_HELPER_INTERFACE_MODE_LOOP:
 762                                dev->netdev_ops = &cvm_oct_npi_netdev_ops;
 763                                strcpy(dev->name, "loop%d");
 764                                break;
 765
 766                        case CVMX_HELPER_INTERFACE_MODE_SGMII:
 767                                dev->netdev_ops = &cvm_oct_sgmii_netdev_ops;
 768                                strcpy(dev->name, "eth%d");
 769                                break;
 770
 771                        case CVMX_HELPER_INTERFACE_MODE_SPI:
 772                                dev->netdev_ops = &cvm_oct_spi_netdev_ops;
 773                                strcpy(dev->name, "spi%d");
 774                                break;
 775
 776                        case CVMX_HELPER_INTERFACE_MODE_RGMII:
 777                        case CVMX_HELPER_INTERFACE_MODE_GMII:
 778                                dev->netdev_ops = &cvm_oct_rgmii_netdev_ops;
 779                                strcpy(dev->name, "eth%d");
 780                                break;
 781                        }
 782
 783                        if (!dev->netdev_ops) {
 784                                free_netdev(dev);
 785                        } else if (register_netdev(dev) < 0) {
 786                                pr_err("Failed to register ethernet device "
 787                                         "for interface %d, port %d\n",
 788                                         interface, priv->port);
 789                                free_netdev(dev);
 790                        } else {
 791                                cvm_oct_device[priv->port] = dev;
 792                                fau -=
 793                                    cvmx_pko_get_num_queues(priv->port) *
 794                                    sizeof(uint32_t);
 795                                queue_delayed_work(cvm_oct_poll_queue,
 796                                                   &priv->port_periodic_work, HZ);
 797                        }
 798                }
 799        }
 800
 801        cvm_oct_tx_initialize();
 802        cvm_oct_rx_initialize();
 803
 804        /*
 805         * 150 uS: about 10 1500-byte packtes at 1GE.
 806         */
 807        cvm_oct_tx_poll_interval = 150 * (octeon_get_clock_rate() / 1000000);
 808
 809        queue_delayed_work(cvm_oct_poll_queue, &cvm_oct_rx_refill_work, HZ);
 810
 811        return 0;
 812}
 813
 814static int cvm_oct_remove(struct platform_device *pdev)
 815{
 816        int port;
 817
 818        /* Disable POW interrupt */
 819        cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0);
 820
 821        cvmx_ipd_disable();
 822
 823        /* Free the interrupt handler */
 824        free_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group, cvm_oct_device);
 825
 826        atomic_inc_return(&cvm_oct_poll_queue_stopping);
 827        cancel_delayed_work_sync(&cvm_oct_rx_refill_work);
 828
 829        cvm_oct_rx_shutdown();
 830        cvm_oct_tx_shutdown();
 831
 832        cvmx_pko_disable();
 833
 834        /* Free the ethernet devices */
 835        for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
 836                if (cvm_oct_device[port]) {
 837                        struct net_device *dev = cvm_oct_device[port];
 838                        struct octeon_ethernet *priv = netdev_priv(dev);
 839                        cancel_delayed_work_sync(&priv->port_periodic_work);
 840
 841                        cvm_oct_tx_shutdown_dev(dev);
 842                        unregister_netdev(dev);
 843                        free_netdev(dev);
 844                        cvm_oct_device[port] = NULL;
 845                }
 846        }
 847
 848        destroy_workqueue(cvm_oct_poll_queue);
 849
 850        cvmx_pko_shutdown();
 851
 852        cvmx_ipd_free_ptr();
 853
 854        /* Free the HW pools */
 855        cvm_oct_mem_empty_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
 856                              num_packet_buffers);
 857        cvm_oct_mem_empty_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
 858                              num_packet_buffers);
 859        if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
 860                cvm_oct_mem_empty_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
 861                                      CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
 862        return 0;
 863}
 864
 865static struct of_device_id cvm_oct_match[] = {
 866        {
 867                .compatible = "cavium,octeon-3860-pip",
 868        },
 869        {},
 870};
 871MODULE_DEVICE_TABLE(of, cvm_oct_match);
 872
 873static struct platform_driver cvm_oct_driver = {
 874        .probe          = cvm_oct_probe,
 875        .remove         = cvm_oct_remove,
 876        .driver         = {
 877                .owner  = THIS_MODULE,
 878                .name   = KBUILD_MODNAME,
 879                .of_match_table = cvm_oct_match,
 880        },
 881};
 882
 883module_platform_driver(cvm_oct_driver);
 884
 885MODULE_LICENSE("GPL");
 886MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
 887MODULE_DESCRIPTION("Cavium Networks Octeon ethernet driver.");
 888