1 /**********************************************************************
2 * Author: Cavium Networks
4 * Contact: support@caviumnetworks.com
5 * This file is part of the OCTEON SDK
7 * Copyright (c) 2003-2007 Cavium Networks
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.
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
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/.
24 * This file may also be available under a different license from Cavium.
25 * Contact Cavium Networks for more information
26 **********************************************************************/
27 #include <linux/kernel.h>
28 #include <linux/init.h>
29 #include <linux/module.h>
30 #include <linux/netdevice.h>
31 #include <linux/etherdevice.h>
32 #include <linux/delay.h>
33 #include <linux/mii.h>
37 #include <asm/octeon/octeon.h>
39 #include "ethernet-defines.h"
40 #include "ethernet-mem.h"
41 #include "ethernet-rx.h"
42 #include "ethernet-tx.h"
43 #include "ethernet-util.h"
44 #include "ethernet-proc.h"
45 #include "ethernet-common.h"
46 #include "octeon-ethernet.h"
52 #include "cvmx-helper.h"
54 #include "cvmx-smix-defs.h"
56 #if defined(CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS) \
57 && CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS
58 int num_packet_buffers = CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS;
60 int num_packet_buffers = 1024;
62 module_param(num_packet_buffers, int, 0444);
63 MODULE_PARM_DESC(num_packet_buffers, "\n"
64 "\tNumber of packet buffers to allocate and store in the\n"
65 "\tFPA. By default, 1024 packet buffers are used unless\n"
66 "\tCONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS is defined.");
68 int pow_receive_group = 15;
69 module_param(pow_receive_group, int, 0444);
70 MODULE_PARM_DESC(pow_receive_group, "\n"
71 "\tPOW group to receive packets from. All ethernet hardware\n"
72 "\twill be configured to send incomming packets to this POW\n"
73 "\tgroup. Also any other software can submit packets to this\n"
74 "\tgroup for the kernel to process.");
76 int pow_send_group = -1;
77 module_param(pow_send_group, int, 0644);
78 MODULE_PARM_DESC(pow_send_group, "\n"
79 "\tPOW group to send packets to other software on. This\n"
80 "\tcontrols the creation of the virtual device pow0.\n"
81 "\talways_use_pow also depends on this value.");
84 module_param(always_use_pow, int, 0444);
85 MODULE_PARM_DESC(always_use_pow, "\n"
86 "\tWhen set, always send to the pow group. This will cause\n"
87 "\tpackets sent to real ethernet devices to be sent to the\n"
88 "\tPOW group instead of the hardware. Unless some other\n"
89 "\tapplication changes the config, packets will still be\n"
90 "\treceived from the low level hardware. Use this option\n"
91 "\tto allow a CVMX app to intercept all packets from the\n"
92 "\tlinux kernel. You must specify pow_send_group along with\n"
95 char pow_send_list[128] = "";
96 module_param_string(pow_send_list, pow_send_list, sizeof(pow_send_list), 0444);
97 MODULE_PARM_DESC(pow_send_list, "\n"
98 "\tComma separated list of ethernet devices that should use the\n"
99 "\tPOW for transmit instead of the actual ethernet hardware. This\n"
100 "\tis a per port version of always_use_pow. always_use_pow takes\n"
101 "\tprecedence over this list. For example, setting this to\n"
102 "\t\"eth2,spi3,spi7\" would cause these three devices to transmit\n"
103 "\tusing the pow_send_group.");
105 static int disable_core_queueing = 1;
106 module_param(disable_core_queueing, int, 0444);
107 MODULE_PARM_DESC(disable_core_queueing, "\n"
108 "\tWhen set the networking core's tx_queue_len is set to zero. This\n"
109 "\tallows packets to be sent without lock contention in the packet\n"
110 "\tscheduler resulting in some cases in improved throughput.\n");
113 * Periodic timer to check auto negotiation
115 static struct timer_list cvm_oct_poll_timer;
118 * Array of every ethernet device owned by this driver indexed by
119 * the ipd input port number.
121 struct net_device *cvm_oct_device[TOTAL_NUMBER_OF_PORTS];
123 extern struct semaphore mdio_sem;
126 * Periodic timer tick for slow management operations
128 * @arg: Device to check
130 static void cvm_do_timer(unsigned long arg)
133 if (port < CVMX_PIP_NUM_INPUT_PORTS) {
134 if (cvm_oct_device[port]) {
137 struct octeon_ethernet *priv =
138 netdev_priv(cvm_oct_device[port]);
140 /* skip polling if we don't get the lock */
141 if (!down_trylock(&mdio_sem)) {
142 priv->poll(cvm_oct_device[port]);
147 queues_per_port = cvmx_pko_get_num_queues(port);
148 /* Drain any pending packets in the free list */
149 for (qos = 0; qos < queues_per_port; qos++) {
150 if (skb_queue_len(&priv->tx_free_list[qos])) {
151 spin_lock(&priv->tx_free_list[qos].
154 (&priv->tx_free_list[qos]) >
155 cvmx_fau_fetch_and_add32(priv->
159 dev_kfree_skb(__skb_dequeue
163 spin_unlock(&priv->tx_free_list[qos].
167 cvm_oct_device[port]->get_stats(cvm_oct_device[port]);
170 /* Poll the next port in a 50th of a second.
171 This spreads the polling of ports out a little bit */
172 mod_timer(&cvm_oct_poll_timer, jiffies + HZ / 50);
175 /* All ports have been polled. Start the next iteration through
176 the ports in one second */
177 mod_timer(&cvm_oct_poll_timer, jiffies + HZ);
182 * Configure common hardware for all interfaces
184 static __init void cvm_oct_configure_common_hw(void)
189 cvm_oct_mem_fill_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
191 cvm_oct_mem_fill_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
193 if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
194 cvm_oct_mem_fill_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
195 CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
198 cvmx_helper_setup_red(num_packet_buffers / 4,
199 num_packet_buffers / 8);
201 /* Enable the MII interface */
202 if (!octeon_is_simulation())
203 cvmx_write_csr(CVMX_SMIX_EN(0), 1);
205 /* Register an IRQ hander for to receive POW interrupts */
206 r = request_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group,
207 cvm_oct_do_interrupt, IRQF_SHARED, "Ethernet",
210 #if defined(CONFIG_SMP) && 0
211 if (USE_MULTICORE_RECEIVE) {
212 irq_set_affinity(OCTEON_IRQ_WORKQ0 + pow_receive_group,
219 * Free a work queue entry received in a intercept callback.
222 * Work queue entry to free
223 * Returns Zero on success, Negative on failure.
225 int cvm_oct_free_work(void *work_queue_entry)
227 cvmx_wqe_t *work = work_queue_entry;
229 int segments = work->word2.s.bufs;
230 union cvmx_buf_ptr segment_ptr = work->packet_ptr;
233 union cvmx_buf_ptr next_ptr = *(union cvmx_buf_ptr *)
234 cvmx_phys_to_ptr(segment_ptr.s.addr - 8);
235 if (unlikely(!segment_ptr.s.i))
236 cvmx_fpa_free(cvm_oct_get_buffer_ptr(segment_ptr),
238 DONT_WRITEBACK(CVMX_FPA_PACKET_POOL_SIZE /
240 segment_ptr = next_ptr;
242 cvmx_fpa_free(work, CVMX_FPA_WQE_POOL, DONT_WRITEBACK(1));
246 EXPORT_SYMBOL(cvm_oct_free_work);
249 * Module/ driver initialization. Creates the linux network
252 * Returns Zero on success
254 static int __init cvm_oct_init_module(void)
258 int fau = FAU_NUM_PACKET_BUFFERS_TO_FREE;
261 pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
263 cvm_oct_proc_initialize();
264 cvm_oct_rx_initialize();
265 cvm_oct_configure_common_hw();
267 cvmx_helper_initialize_packet_io_global();
269 /* Change the input group for all ports before input is enabled */
270 num_interfaces = cvmx_helper_get_number_of_interfaces();
271 for (interface = 0; interface < num_interfaces; interface++) {
272 int num_ports = cvmx_helper_ports_on_interface(interface);
275 for (port = cvmx_helper_get_ipd_port(interface, 0);
276 port < cvmx_helper_get_ipd_port(interface, num_ports);
278 union cvmx_pip_prt_tagx pip_prt_tagx;
280 cvmx_read_csr(CVMX_PIP_PRT_TAGX(port));
281 pip_prt_tagx.s.grp = pow_receive_group;
282 cvmx_write_csr(CVMX_PIP_PRT_TAGX(port),
287 cvmx_helper_ipd_and_packet_input_enable();
289 memset(cvm_oct_device, 0, sizeof(cvm_oct_device));
292 * Initialize the FAU used for counting packet buffers that
295 cvmx_fau_atomic_write32(FAU_NUM_PACKET_BUFFERS_TO_FREE, 0);
297 if ((pow_send_group != -1)) {
298 struct net_device *dev;
299 pr_info("\tConfiguring device for POW only access\n");
300 dev = alloc_etherdev(sizeof(struct octeon_ethernet));
302 /* Initialize the device private structure. */
303 struct octeon_ethernet *priv = netdev_priv(dev);
304 memset(priv, 0, sizeof(struct octeon_ethernet));
306 dev->init = cvm_oct_common_init;
307 priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED;
308 priv->port = CVMX_PIP_NUM_INPUT_PORTS;
310 strcpy(dev->name, "pow%d");
311 for (qos = 0; qos < 16; qos++)
312 skb_queue_head_init(&priv->tx_free_list[qos]);
314 if (register_netdev(dev) < 0) {
315 pr_err("Failed to register ethernet "
319 cvm_oct_device[CVMX_PIP_NUM_INPUT_PORTS] = dev;
320 pr_info("%s: POW send group %d, receive "
322 dev->name, pow_send_group,
326 pr_err("Failed to allocate ethernet device "
331 num_interfaces = cvmx_helper_get_number_of_interfaces();
332 for (interface = 0; interface < num_interfaces; interface++) {
333 cvmx_helper_interface_mode_t imode =
334 cvmx_helper_interface_get_mode(interface);
335 int num_ports = cvmx_helper_ports_on_interface(interface);
338 for (port = cvmx_helper_get_ipd_port(interface, 0);
339 port < cvmx_helper_get_ipd_port(interface, num_ports);
341 struct octeon_ethernet *priv;
342 struct net_device *dev =
343 alloc_etherdev(sizeof(struct octeon_ethernet));
345 pr_err("Failed to allocate ethernet device "
346 "for port %d\n", port);
349 if (disable_core_queueing)
350 dev->tx_queue_len = 0;
352 /* Initialize the device private structure. */
353 priv = netdev_priv(dev);
354 memset(priv, 0, sizeof(struct octeon_ethernet));
358 priv->queue = cvmx_pko_get_base_queue(priv->port);
359 priv->fau = fau - cvmx_pko_get_num_queues(port) * 4;
360 for (qos = 0; qos < 16; qos++)
361 skb_queue_head_init(&priv->tx_free_list[qos]);
362 for (qos = 0; qos < cvmx_pko_get_num_queues(port);
364 cvmx_fau_atomic_write32(priv->fau + qos * 4, 0);
366 switch (priv->imode) {
368 /* These types don't support ports to IPD/PKO */
369 case CVMX_HELPER_INTERFACE_MODE_DISABLED:
370 case CVMX_HELPER_INTERFACE_MODE_PCIE:
371 case CVMX_HELPER_INTERFACE_MODE_PICMG:
374 case CVMX_HELPER_INTERFACE_MODE_NPI:
375 dev->init = cvm_oct_common_init;
376 dev->uninit = cvm_oct_common_uninit;
377 strcpy(dev->name, "npi%d");
380 case CVMX_HELPER_INTERFACE_MODE_XAUI:
381 dev->init = cvm_oct_xaui_init;
382 dev->uninit = cvm_oct_xaui_uninit;
383 strcpy(dev->name, "xaui%d");
386 case CVMX_HELPER_INTERFACE_MODE_LOOP:
387 dev->init = cvm_oct_common_init;
388 dev->uninit = cvm_oct_common_uninit;
389 strcpy(dev->name, "loop%d");
392 case CVMX_HELPER_INTERFACE_MODE_SGMII:
393 dev->init = cvm_oct_sgmii_init;
394 dev->uninit = cvm_oct_sgmii_uninit;
395 strcpy(dev->name, "eth%d");
398 case CVMX_HELPER_INTERFACE_MODE_SPI:
399 dev->init = cvm_oct_spi_init;
400 dev->uninit = cvm_oct_spi_uninit;
401 strcpy(dev->name, "spi%d");
404 case CVMX_HELPER_INTERFACE_MODE_RGMII:
405 case CVMX_HELPER_INTERFACE_MODE_GMII:
406 dev->init = cvm_oct_rgmii_init;
407 dev->uninit = cvm_oct_rgmii_uninit;
408 strcpy(dev->name, "eth%d");
414 } else if (register_netdev(dev) < 0) {
415 pr_err("Failed to register ethernet device "
416 "for interface %d, port %d\n",
417 interface, priv->port);
420 cvm_oct_device[priv->port] = dev;
422 cvmx_pko_get_num_queues(priv->port) *
428 if (INTERRUPT_LIMIT) {
430 * Set the POW timer rate to give an interrupt at most
431 * INTERRUPT_LIMIT times per second.
433 cvmx_write_csr(CVMX_POW_WQ_INT_PC,
434 octeon_bootinfo->eclock_hz / (INTERRUPT_LIMIT *
438 * Enable POW timer interrupt. It will count when
439 * there are packets available.
441 cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group),
444 /* Enable POW interrupt when our port has at least one packet */
445 cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0x1001);
448 /* Enable the poll timer for checking RGMII status */
449 init_timer(&cvm_oct_poll_timer);
450 cvm_oct_poll_timer.data = 0;
451 cvm_oct_poll_timer.function = cvm_do_timer;
452 mod_timer(&cvm_oct_poll_timer, jiffies + HZ);
458 * Module / driver shutdown
460 * Returns Zero on success
462 static void __exit cvm_oct_cleanup_module(void)
466 /* Disable POW interrupt */
467 cvmx_write_csr(CVMX_POW_WQ_INT_THRX(pow_receive_group), 0);
471 /* Free the interrupt handler */
472 free_irq(OCTEON_IRQ_WORKQ0 + pow_receive_group, cvm_oct_device);
474 del_timer(&cvm_oct_poll_timer);
475 cvm_oct_rx_shutdown();
478 /* Free the ethernet devices */
479 for (port = 0; port < TOTAL_NUMBER_OF_PORTS; port++) {
480 if (cvm_oct_device[port]) {
481 cvm_oct_tx_shutdown(cvm_oct_device[port]);
482 unregister_netdev(cvm_oct_device[port]);
483 kfree(cvm_oct_device[port]);
484 cvm_oct_device[port] = NULL;
489 cvm_oct_proc_shutdown();
493 /* Free the HW pools */
494 cvm_oct_mem_empty_fpa(CVMX_FPA_PACKET_POOL, CVMX_FPA_PACKET_POOL_SIZE,
496 cvm_oct_mem_empty_fpa(CVMX_FPA_WQE_POOL, CVMX_FPA_WQE_POOL_SIZE,
498 if (CVMX_FPA_OUTPUT_BUFFER_POOL != CVMX_FPA_PACKET_POOL)
499 cvm_oct_mem_empty_fpa(CVMX_FPA_OUTPUT_BUFFER_POOL,
500 CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE, 128);
503 MODULE_LICENSE("GPL");
504 MODULE_AUTHOR("Cavium Networks <support@caviumnetworks.com>");
505 MODULE_DESCRIPTION("Cavium Networks Octeon ethernet driver.");
506 module_init(cvm_oct_init_module);
507 module_exit(cvm_oct_cleanup_module);