Version:  2.0.40 2.2.26 2.4.37 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18

Linux/drivers/staging/octeon/ethernet.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us