Commit f696a10838ffab85e5bc07e7cff0d0e1870a30d7

Authored by David Daney
Committed by Ralf Baechle
1 parent 773cb77d0e

Staging: octeon-ethernet: Convert to use net_device_ops.

Convert the driver to use net_device_ops as it is now mandatory.

Also compensate for the removal of struct sk_buff's dst field.

The changes are mostly mechanical, the content of ethernet-common.c
was moved to ethernet.c and ethernet-common.{c,h} are removed.

Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

Showing 10 changed files with 390 additions and 396 deletions Side-by-side Diff

drivers/staging/octeon/Makefile
... ... @@ -12,7 +12,6 @@
12 12 obj-${CONFIG_OCTEON_ETHERNET} := octeon-ethernet.o
13 13  
14 14 octeon-ethernet-objs := ethernet.o
15   -octeon-ethernet-objs += ethernet-common.o
16 15 octeon-ethernet-objs += ethernet-mdio.o
17 16 octeon-ethernet-objs += ethernet-mem.o
18 17 octeon-ethernet-objs += ethernet-proc.o
drivers/staging/octeon/ethernet-common.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/kernel.h>
28   -#include <linux/mii.h>
29   -#include <net/dst.h>
30   -
31   -#include <asm/atomic.h>
32   -#include <asm/octeon/octeon.h>
33   -
34   -#include "ethernet-defines.h"
35   -#include "ethernet-tx.h"
36   -#include "ethernet-mdio.h"
37   -#include "ethernet-util.h"
38   -#include "octeon-ethernet.h"
39   -#include "ethernet-common.h"
40   -
41   -#include "cvmx-pip.h"
42   -#include "cvmx-pko.h"
43   -#include "cvmx-fau.h"
44   -#include "cvmx-helper.h"
45   -
46   -#include "cvmx-gmxx-defs.h"
47   -
48   -/**
49   - * Get the low level ethernet statistics
50   - *
51   - * @dev: Device to get the statistics from
52   - * Returns Pointer to the statistics
53   - */
54   -static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev)
55   -{
56   - cvmx_pip_port_status_t rx_status;
57   - cvmx_pko_port_status_t tx_status;
58   - struct octeon_ethernet *priv = netdev_priv(dev);
59   -
60   - if (priv->port < CVMX_PIP_NUM_INPUT_PORTS) {
61   - if (octeon_is_simulation()) {
62   - /* The simulator doesn't support statistics */
63   - memset(&rx_status, 0, sizeof(rx_status));
64   - memset(&tx_status, 0, sizeof(tx_status));
65   - } else {
66   - cvmx_pip_get_port_status(priv->port, 1, &rx_status);
67   - cvmx_pko_get_port_status(priv->port, 1, &tx_status);
68   - }
69   -
70   - priv->stats.rx_packets += rx_status.inb_packets;
71   - priv->stats.tx_packets += tx_status.packets;
72   - priv->stats.rx_bytes += rx_status.inb_octets;
73   - priv->stats.tx_bytes += tx_status.octets;
74   - priv->stats.multicast += rx_status.multicast_packets;
75   - priv->stats.rx_crc_errors += rx_status.inb_errors;
76   - priv->stats.rx_frame_errors += rx_status.fcs_align_err_packets;
77   -
78   - /*
79   - * The drop counter must be incremented atomically
80   - * since the RX tasklet also increments it.
81   - */
82   -#ifdef CONFIG_64BIT
83   - atomic64_add(rx_status.dropped_packets,
84   - (atomic64_t *)&priv->stats.rx_dropped);
85   -#else
86   - atomic_add(rx_status.dropped_packets,
87   - (atomic_t *)&priv->stats.rx_dropped);
88   -#endif
89   - }
90   -
91   - return &priv->stats;
92   -}
93   -
94   -/**
95   - * Set the multicast list. Currently unimplemented.
96   - *
97   - * @dev: Device to work on
98   - */
99   -static void cvm_oct_common_set_multicast_list(struct net_device *dev)
100   -{
101   - union cvmx_gmxx_prtx_cfg gmx_cfg;
102   - struct octeon_ethernet *priv = netdev_priv(dev);
103   - int interface = INTERFACE(priv->port);
104   - int index = INDEX(priv->port);
105   -
106   - if ((interface < 2)
107   - && (cvmx_helper_interface_get_mode(interface) !=
108   - CVMX_HELPER_INTERFACE_MODE_SPI)) {
109   - union cvmx_gmxx_rxx_adr_ctl control;
110   - control.u64 = 0;
111   - control.s.bcst = 1; /* Allow broadcast MAC addresses */
112   -
113   - if (dev->mc_list || (dev->flags & IFF_ALLMULTI) ||
114   - (dev->flags & IFF_PROMISC))
115   - /* Force accept multicast packets */
116   - control.s.mcst = 2;
117   - else
118   - /* Force reject multicat packets */
119   - control.s.mcst = 1;
120   -
121   - if (dev->flags & IFF_PROMISC)
122   - /*
123   - * Reject matches if promisc. Since CAM is
124   - * shut off, should accept everything.
125   - */
126   - control.s.cam_mode = 0;
127   - else
128   - /* Filter packets based on the CAM */
129   - control.s.cam_mode = 1;
130   -
131   - gmx_cfg.u64 =
132   - cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
133   - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
134   - gmx_cfg.u64 & ~1ull);
135   -
136   - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface),
137   - control.u64);
138   - if (dev->flags & IFF_PROMISC)
139   - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
140   - (index, interface), 0);
141   - else
142   - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
143   - (index, interface), 1);
144   -
145   - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
146   - gmx_cfg.u64);
147   - }
148   -}
149   -
150   -/**
151   - * Set the hardware MAC address for a device
152   - *
153   - * @dev: Device to change the MAC address for
154   - * @addr: Address structure to change it too. MAC address is addr + 2.
155   - * Returns Zero on success
156   - */
157   -static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
158   -{
159   - struct octeon_ethernet *priv = netdev_priv(dev);
160   - union cvmx_gmxx_prtx_cfg gmx_cfg;
161   - int interface = INTERFACE(priv->port);
162   - int index = INDEX(priv->port);
163   -
164   - memcpy(dev->dev_addr, addr + 2, 6);
165   -
166   - if ((interface < 2)
167   - && (cvmx_helper_interface_get_mode(interface) !=
168   - CVMX_HELPER_INTERFACE_MODE_SPI)) {
169   - int i;
170   - uint8_t *ptr = addr;
171   - uint64_t mac = 0;
172   - for (i = 0; i < 6; i++)
173   - mac = (mac << 8) | (uint64_t) (ptr[i + 2]);
174   -
175   - gmx_cfg.u64 =
176   - cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
177   - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
178   - gmx_cfg.u64 & ~1ull);
179   -
180   - cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac);
181   - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface),
182   - ptr[2]);
183   - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface),
184   - ptr[3]);
185   - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface),
186   - ptr[4]);
187   - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface),
188   - ptr[5]);
189   - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface),
190   - ptr[6]);
191   - cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface),
192   - ptr[7]);
193   - cvm_oct_common_set_multicast_list(dev);
194   - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
195   - gmx_cfg.u64);
196   - }
197   - return 0;
198   -}
199   -
200   -/**
201   - * Change the link MTU. Unimplemented
202   - *
203   - * @dev: Device to change
204   - * @new_mtu: The new MTU
205   - *
206   - * Returns Zero on success
207   - */
208   -static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu)
209   -{
210   - struct octeon_ethernet *priv = netdev_priv(dev);
211   - int interface = INTERFACE(priv->port);
212   - int index = INDEX(priv->port);
213   -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
214   - int vlan_bytes = 4;
215   -#else
216   - int vlan_bytes = 0;
217   -#endif
218   -
219   - /*
220   - * Limit the MTU to make sure the ethernet packets are between
221   - * 64 bytes and 65535 bytes.
222   - */
223   - if ((new_mtu + 14 + 4 + vlan_bytes < 64)
224   - || (new_mtu + 14 + 4 + vlan_bytes > 65392)) {
225   - pr_err("MTU must be between %d and %d.\n",
226   - 64 - 14 - 4 - vlan_bytes, 65392 - 14 - 4 - vlan_bytes);
227   - return -EINVAL;
228   - }
229   - dev->mtu = new_mtu;
230   -
231   - if ((interface < 2)
232   - && (cvmx_helper_interface_get_mode(interface) !=
233   - CVMX_HELPER_INTERFACE_MODE_SPI)) {
234   - /* Add ethernet header and FCS, and VLAN if configured. */
235   - int max_packet = new_mtu + 14 + 4 + vlan_bytes;
236   -
237   - if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
238   - || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
239   - /* Signal errors on packets larger than the MTU */
240   - cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface),
241   - max_packet);
242   - } else {
243   - /*
244   - * Set the hardware to truncate packets larger
245   - * than the MTU and smaller the 64 bytes.
246   - */
247   - union cvmx_pip_frm_len_chkx frm_len_chk;
248   - frm_len_chk.u64 = 0;
249   - frm_len_chk.s.minlen = 64;
250   - frm_len_chk.s.maxlen = max_packet;
251   - cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface),
252   - frm_len_chk.u64);
253   - }
254   - /*
255   - * Set the hardware to truncate packets larger than
256   - * the MTU. The jabber register must be set to a
257   - * multiple of 8 bytes, so round up.
258   - */
259   - cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface),
260   - (max_packet + 7) & ~7u);
261   - }
262   - return 0;
263   -}
264   -
265   -/**
266   - * Per network device initialization
267   - *
268   - * @dev: Device to initialize
269   - * Returns Zero on success
270   - */
271   -int cvm_oct_common_init(struct net_device *dev)
272   -{
273   - static int count;
274   - char mac[8] = { 0x00, 0x00,
275   - octeon_bootinfo->mac_addr_base[0],
276   - octeon_bootinfo->mac_addr_base[1],
277   - octeon_bootinfo->mac_addr_base[2],
278   - octeon_bootinfo->mac_addr_base[3],
279   - octeon_bootinfo->mac_addr_base[4],
280   - octeon_bootinfo->mac_addr_base[5] + count
281   - };
282   - struct octeon_ethernet *priv = netdev_priv(dev);
283   -
284   - /*
285   - * Force the interface to use the POW send if always_use_pow
286   - * was specified or it is in the pow send list.
287   - */
288   - if ((pow_send_group != -1)
289   - && (always_use_pow || strstr(pow_send_list, dev->name)))
290   - priv->queue = -1;
291   -
292   - if (priv->queue != -1) {
293   - dev->hard_start_xmit = cvm_oct_xmit;
294   - if (USE_HW_TCPUDP_CHECKSUM)
295   - dev->features |= NETIF_F_IP_CSUM;
296   - } else
297   - dev->hard_start_xmit = cvm_oct_xmit_pow;
298   - count++;
299   -
300   - dev->get_stats = cvm_oct_common_get_stats;
301   - dev->set_mac_address = cvm_oct_common_set_mac_address;
302   - dev->set_multicast_list = cvm_oct_common_set_multicast_list;
303   - dev->change_mtu = cvm_oct_common_change_mtu;
304   - dev->do_ioctl = cvm_oct_ioctl;
305   - /* We do our own locking, Linux doesn't need to */
306   - dev->features |= NETIF_F_LLTX;
307   - SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
308   -#ifdef CONFIG_NET_POLL_CONTROLLER
309   - dev->poll_controller = cvm_oct_poll_controller;
310   -#endif
311   -
312   - cvm_oct_mdio_setup_device(dev);
313   - dev->set_mac_address(dev, mac);
314   - dev->change_mtu(dev, dev->mtu);
315   -
316   - /*
317   - * Zero out stats for port so we won't mistakenly show
318   - * counters from the bootloader.
319   - */
320   - memset(dev->get_stats(dev), 0, sizeof(struct net_device_stats));
321   -
322   - return 0;
323   -}
324   -
325   -void cvm_oct_common_uninit(struct net_device *dev)
326   -{
327   - /* Currently nothing to do */
328   -}
drivers/staging/octeon/ethernet-common.h
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   -
28   -int cvm_oct_common_init(struct net_device *dev);
29   -void cvm_oct_common_uninit(struct net_device *dev);
drivers/staging/octeon/ethernet-rgmii.c
... ... @@ -33,7 +33,6 @@
33 33  
34 34 #include "ethernet-defines.h"
35 35 #include "octeon-ethernet.h"
36   -#include "ethernet-common.h"
37 36 #include "ethernet-util.h"
38 37  
39 38 #include "cvmx-helper.h"
... ... @@ -265,7 +264,7 @@
265 264 return return_status;
266 265 }
267 266  
268   -static int cvm_oct_rgmii_open(struct net_device *dev)
  267 +int cvm_oct_rgmii_open(struct net_device *dev)
269 268 {
270 269 union cvmx_gmxx_prtx_cfg gmx_cfg;
271 270 struct octeon_ethernet *priv = netdev_priv(dev);
... ... @@ -286,7 +285,7 @@
286 285 return 0;
287 286 }
288 287  
289   -static int cvm_oct_rgmii_stop(struct net_device *dev)
  288 +int cvm_oct_rgmii_stop(struct net_device *dev)
290 289 {
291 290 union cvmx_gmxx_prtx_cfg gmx_cfg;
292 291 struct octeon_ethernet *priv = netdev_priv(dev);
... ... @@ -305,9 +304,7 @@
305 304 int r;
306 305  
307 306 cvm_oct_common_init(dev);
308   - dev->open = cvm_oct_rgmii_open;
309   - dev->stop = cvm_oct_rgmii_stop;
310   - dev->stop(dev);
  307 + dev->netdev_ops->ndo_stop(dev);
311 308  
312 309 /*
313 310 * Due to GMX errata in CN3XXX series chips, it is necessary
drivers/staging/octeon/ethernet-sgmii.c
... ... @@ -34,13 +34,12 @@
34 34 #include "ethernet-defines.h"
35 35 #include "octeon-ethernet.h"
36 36 #include "ethernet-util.h"
37   -#include "ethernet-common.h"
38 37  
39 38 #include "cvmx-helper.h"
40 39  
41 40 #include "cvmx-gmxx-defs.h"
42 41  
43   -static int cvm_oct_sgmii_open(struct net_device *dev)
  42 +int cvm_oct_sgmii_open(struct net_device *dev)
44 43 {
45 44 union cvmx_gmxx_prtx_cfg gmx_cfg;
46 45 struct octeon_ethernet *priv = netdev_priv(dev);
... ... @@ -61,7 +60,7 @@
61 60 return 0;
62 61 }
63 62  
64   -static int cvm_oct_sgmii_stop(struct net_device *dev)
  63 +int cvm_oct_sgmii_stop(struct net_device *dev)
65 64 {
66 65 union cvmx_gmxx_prtx_cfg gmx_cfg;
67 66 struct octeon_ethernet *priv = netdev_priv(dev);
... ... @@ -113,9 +112,7 @@
113 112 {
114 113 struct octeon_ethernet *priv = netdev_priv(dev);
115 114 cvm_oct_common_init(dev);
116   - dev->open = cvm_oct_sgmii_open;
117   - dev->stop = cvm_oct_sgmii_stop;
118   - dev->stop(dev);
  115 + dev->netdev_ops->ndo_stop(dev);
119 116 if (!octeon_is_simulation())
120 117 priv->poll = cvm_oct_sgmii_poll;
121 118  
drivers/staging/octeon/ethernet-spi.c
... ... @@ -33,7 +33,6 @@
33 33  
34 34 #include "ethernet-defines.h"
35 35 #include "octeon-ethernet.h"
36   -#include "ethernet-common.h"
37 36 #include "ethernet-util.h"
38 37  
39 38 #include "cvmx-spi.h"
drivers/staging/octeon/ethernet-tx.c
... ... @@ -253,10 +253,10 @@
253 253  
254 254 /*
255 255 * The skbuff will be reused without ever being freed. We must
256   - * cleanup a bunch of Linux stuff.
  256 + * cleanup a bunch of core things.
257 257 */
258   - dst_release(skb->dst);
259   - skb->dst = NULL;
  258 + dst_release(skb_dst(skb));
  259 + skb_dst_set(skb, NULL);
260 260 #ifdef CONFIG_XFRM
261 261 secpath_put(skb->sp);
262 262 skb->sp = NULL;
drivers/staging/octeon/ethernet-xaui.c
... ... @@ -33,14 +33,13 @@
33 33  
34 34 #include "ethernet-defines.h"
35 35 #include "octeon-ethernet.h"
36   -#include "ethernet-common.h"
37 36 #include "ethernet-util.h"
38 37  
39 38 #include "cvmx-helper.h"
40 39  
41 40 #include "cvmx-gmxx-defs.h"
42 41  
43   -static int cvm_oct_xaui_open(struct net_device *dev)
  42 +int cvm_oct_xaui_open(struct net_device *dev)
44 43 {
45 44 union cvmx_gmxx_prtx_cfg gmx_cfg;
46 45 struct octeon_ethernet *priv = netdev_priv(dev);
... ... @@ -60,7 +59,7 @@
60 59 return 0;
61 60 }
62 61  
63   -static int cvm_oct_xaui_stop(struct net_device *dev)
  62 +int cvm_oct_xaui_stop(struct net_device *dev)
64 63 {
65 64 union cvmx_gmxx_prtx_cfg gmx_cfg;
66 65 struct octeon_ethernet *priv = netdev_priv(dev);
... ... @@ -112,9 +111,7 @@
112 111 {
113 112 struct octeon_ethernet *priv = netdev_priv(dev);
114 113 cvm_oct_common_init(dev);
115   - dev->open = cvm_oct_xaui_open;
116   - dev->stop = cvm_oct_xaui_stop;
117   - dev->stop(dev);
  114 + dev->netdev_ops->ndo_stop(dev);
118 115 if (!octeon_is_simulation())
119 116 priv->poll = cvm_oct_xaui_poll;
120 117  
drivers/staging/octeon/ethernet.c
... ... @@ -40,9 +40,9 @@
40 40 #include "ethernet-mem.h"
41 41 #include "ethernet-rx.h"
42 42 #include "ethernet-tx.h"
  43 +#include "ethernet-mdio.h"
43 44 #include "ethernet-util.h"
44 45 #include "ethernet-proc.h"
45   -#include "ethernet-common.h"
46 46 #include "octeon-ethernet.h"
47 47  
48 48 #include "cvmx-pip.h"
... ... @@ -51,6 +51,7 @@
51 51 #include "cvmx-ipd.h"
52 52 #include "cvmx-helper.h"
53 53  
  54 +#include "cvmx-gmxx-defs.h"
54 55 #include "cvmx-smix-defs.h"
55 56  
56 57 #if defined(CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS) \
... ... @@ -164,7 +165,7 @@
164 165 lock);
165 166 }
166 167 }
167   - cvm_oct_device[port]->get_stats(cvm_oct_device[port]);
  168 + cvm_oct_device[port]->netdev_ops->ndo_get_stats(cvm_oct_device[port]);
168 169 }
169 170 port++;
170 171 /* Poll the next port in a 50th of a second.
... ... @@ -246,6 +247,362 @@
246 247 EXPORT_SYMBOL(cvm_oct_free_work);
247 248  
248 249 /**
  250 + * Get the low level ethernet statistics
  251 + *
  252 + * @dev: Device to get the statistics from
  253 + * Returns Pointer to the statistics
  254 + */
  255 +static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev)
  256 +{
  257 + cvmx_pip_port_status_t rx_status;
  258 + cvmx_pko_port_status_t tx_status;
  259 + struct octeon_ethernet *priv = netdev_priv(dev);
  260 +
  261 + if (priv->port < CVMX_PIP_NUM_INPUT_PORTS) {
  262 + if (octeon_is_simulation()) {
  263 + /* The simulator doesn't support statistics */
  264 + memset(&rx_status, 0, sizeof(rx_status));
  265 + memset(&tx_status, 0, sizeof(tx_status));
  266 + } else {
  267 + cvmx_pip_get_port_status(priv->port, 1, &rx_status);
  268 + cvmx_pko_get_port_status(priv->port, 1, &tx_status);
  269 + }
  270 +
  271 + priv->stats.rx_packets += rx_status.inb_packets;
  272 + priv->stats.tx_packets += tx_status.packets;
  273 + priv->stats.rx_bytes += rx_status.inb_octets;
  274 + priv->stats.tx_bytes += tx_status.octets;
  275 + priv->stats.multicast += rx_status.multicast_packets;
  276 + priv->stats.rx_crc_errors += rx_status.inb_errors;
  277 + priv->stats.rx_frame_errors += rx_status.fcs_align_err_packets;
  278 +
  279 + /*
  280 + * The drop counter must be incremented atomically
  281 + * since the RX tasklet also increments it.
  282 + */
  283 +#ifdef CONFIG_64BIT
  284 + atomic64_add(rx_status.dropped_packets,
  285 + (atomic64_t *)&priv->stats.rx_dropped);
  286 +#else
  287 + atomic_add(rx_status.dropped_packets,
  288 + (atomic_t *)&priv->stats.rx_dropped);
  289 +#endif
  290 + }
  291 +
  292 + return &priv->stats;
  293 +}
  294 +
  295 +/**
  296 + * Change the link MTU. Unimplemented
  297 + *
  298 + * @dev: Device to change
  299 + * @new_mtu: The new MTU
  300 + *
  301 + * Returns Zero on success
  302 + */
  303 +static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu)
  304 +{
  305 + struct octeon_ethernet *priv = netdev_priv(dev);
  306 + int interface = INTERFACE(priv->port);
  307 + int index = INDEX(priv->port);
  308 +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
  309 + int vlan_bytes = 4;
  310 +#else
  311 + int vlan_bytes = 0;
  312 +#endif
  313 +
  314 + /*
  315 + * Limit the MTU to make sure the ethernet packets are between
  316 + * 64 bytes and 65535 bytes.
  317 + */
  318 + if ((new_mtu + 14 + 4 + vlan_bytes < 64)
  319 + || (new_mtu + 14 + 4 + vlan_bytes > 65392)) {
  320 + pr_err("MTU must be between %d and %d.\n",
  321 + 64 - 14 - 4 - vlan_bytes, 65392 - 14 - 4 - vlan_bytes);
  322 + return -EINVAL;
  323 + }
  324 + dev->mtu = new_mtu;
  325 +
  326 + if ((interface < 2)
  327 + && (cvmx_helper_interface_get_mode(interface) !=
  328 + CVMX_HELPER_INTERFACE_MODE_SPI)) {
  329 + /* Add ethernet header and FCS, and VLAN if configured. */
  330 + int max_packet = new_mtu + 14 + 4 + vlan_bytes;
  331 +
  332 + if (OCTEON_IS_MODEL(OCTEON_CN3XXX)
  333 + || OCTEON_IS_MODEL(OCTEON_CN58XX)) {
  334 + /* Signal errors on packets larger than the MTU */
  335 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface),
  336 + max_packet);
  337 + } else {
  338 + /*
  339 + * Set the hardware to truncate packets larger
  340 + * than the MTU and smaller the 64 bytes.
  341 + */
  342 + union cvmx_pip_frm_len_chkx frm_len_chk;
  343 + frm_len_chk.u64 = 0;
  344 + frm_len_chk.s.minlen = 64;
  345 + frm_len_chk.s.maxlen = max_packet;
  346 + cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface),
  347 + frm_len_chk.u64);
  348 + }
  349 + /*
  350 + * Set the hardware to truncate packets larger than
  351 + * the MTU. The jabber register must be set to a
  352 + * multiple of 8 bytes, so round up.
  353 + */
  354 + cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface),
  355 + (max_packet + 7) & ~7u);
  356 + }
  357 + return 0;
  358 +}
  359 +
  360 +/**
  361 + * Set the multicast list. Currently unimplemented.
  362 + *
  363 + * @dev: Device to work on
  364 + */
  365 +static void cvm_oct_common_set_multicast_list(struct net_device *dev)
  366 +{
  367 + union cvmx_gmxx_prtx_cfg gmx_cfg;
  368 + struct octeon_ethernet *priv = netdev_priv(dev);
  369 + int interface = INTERFACE(priv->port);
  370 + int index = INDEX(priv->port);
  371 +
  372 + if ((interface < 2)
  373 + && (cvmx_helper_interface_get_mode(interface) !=
  374 + CVMX_HELPER_INTERFACE_MODE_SPI)) {
  375 + union cvmx_gmxx_rxx_adr_ctl control;
  376 + control.u64 = 0;
  377 + control.s.bcst = 1; /* Allow broadcast MAC addresses */
  378 +
  379 + if (dev->mc_list || (dev->flags & IFF_ALLMULTI) ||
  380 + (dev->flags & IFF_PROMISC))
  381 + /* Force accept multicast packets */
  382 + control.s.mcst = 2;
  383 + else
  384 + /* Force reject multicat packets */
  385 + control.s.mcst = 1;
  386 +
  387 + if (dev->flags & IFF_PROMISC)
  388 + /*
  389 + * Reject matches if promisc. Since CAM is
  390 + * shut off, should accept everything.
  391 + */
  392 + control.s.cam_mode = 0;
  393 + else
  394 + /* Filter packets based on the CAM */
  395 + control.s.cam_mode = 1;
  396 +
  397 + gmx_cfg.u64 =
  398 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
  399 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
  400 + gmx_cfg.u64 & ~1ull);
  401 +
  402 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface),
  403 + control.u64);
  404 + if (dev->flags & IFF_PROMISC)
  405 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
  406 + (index, interface), 0);
  407 + else
  408 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN
  409 + (index, interface), 1);
  410 +
  411 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
  412 + gmx_cfg.u64);
  413 + }
  414 +}
  415 +
  416 +/**
  417 + * Set the hardware MAC address for a device
  418 + *
  419 + * @dev: Device to change the MAC address for
  420 + * @addr: Address structure to change it too. MAC address is addr + 2.
  421 + * Returns Zero on success
  422 + */
  423 +static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
  424 +{
  425 + struct octeon_ethernet *priv = netdev_priv(dev);
  426 + union cvmx_gmxx_prtx_cfg gmx_cfg;
  427 + int interface = INTERFACE(priv->port);
  428 + int index = INDEX(priv->port);
  429 +
  430 + memcpy(dev->dev_addr, addr + 2, 6);
  431 +
  432 + if ((interface < 2)
  433 + && (cvmx_helper_interface_get_mode(interface) !=
  434 + CVMX_HELPER_INTERFACE_MODE_SPI)) {
  435 + int i;
  436 + uint8_t *ptr = addr;
  437 + uint64_t mac = 0;
  438 + for (i = 0; i < 6; i++)
  439 + mac = (mac << 8) | (uint64_t) (ptr[i + 2]);
  440 +
  441 + gmx_cfg.u64 =
  442 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface));
  443 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
  444 + gmx_cfg.u64 & ~1ull);
  445 +
  446 + cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac);
  447 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface),
  448 + ptr[2]);
  449 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface),
  450 + ptr[3]);
  451 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface),
  452 + ptr[4]);
  453 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface),
  454 + ptr[5]);
  455 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface),
  456 + ptr[6]);
  457 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface),
  458 + ptr[7]);
  459 + cvm_oct_common_set_multicast_list(dev);
  460 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface),
  461 + gmx_cfg.u64);
  462 + }
  463 + return 0;
  464 +}
  465 +
  466 +/**
  467 + * Per network device initialization
  468 + *
  469 + * @dev: Device to initialize
  470 + * Returns Zero on success
  471 + */
  472 +int cvm_oct_common_init(struct net_device *dev)
  473 +{
  474 + static int count;
  475 + char mac[8] = { 0x00, 0x00,
  476 + octeon_bootinfo->mac_addr_base[0],
  477 + octeon_bootinfo->mac_addr_base[1],
  478 + octeon_bootinfo->mac_addr_base[2],
  479 + octeon_bootinfo->mac_addr_base[3],
  480 + octeon_bootinfo->mac_addr_base[4],
  481 + octeon_bootinfo->mac_addr_base[5] + count
  482 + };
  483 + struct octeon_ethernet *priv = netdev_priv(dev);
  484 +
  485 + /*
  486 + * Force the interface to use the POW send if always_use_pow
  487 + * was specified or it is in the pow send list.
  488 + */
  489 + if ((pow_send_group != -1)
  490 + && (always_use_pow || strstr(pow_send_list, dev->name)))
  491 + priv->queue = -1;
  492 +
  493 + if (priv->queue != -1 && USE_HW_TCPUDP_CHECKSUM)
  494 + dev->features |= NETIF_F_IP_CSUM;
  495 +
  496 + count++;
  497 +
  498 + /* We do our own locking, Linux doesn't need to */
  499 + dev->features |= NETIF_F_LLTX;
  500 + SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
  501 +
  502 + cvm_oct_mdio_setup_device(dev);
  503 + dev->netdev_ops->ndo_set_mac_address(dev, mac);
  504 + dev->netdev_ops->ndo_change_mtu(dev, dev->mtu);
  505 +
  506 + /*
  507 + * Zero out stats for port so we won't mistakenly show
  508 + * counters from the bootloader.
  509 + */
  510 + memset(dev->netdev_ops->ndo_get_stats(dev), 0,
  511 + sizeof(struct net_device_stats));
  512 +
  513 + return 0;
  514 +}
  515 +
  516 +void cvm_oct_common_uninit(struct net_device *dev)
  517 +{
  518 + /* Currently nothing to do */
  519 +}
  520 +
  521 +static const struct net_device_ops cvm_oct_npi_netdev_ops = {
  522 + .ndo_init = cvm_oct_common_init,
  523 + .ndo_uninit = cvm_oct_common_uninit,
  524 + .ndo_start_xmit = cvm_oct_xmit,
  525 + .ndo_set_multicast_list = cvm_oct_common_set_multicast_list,
  526 + .ndo_set_mac_address = cvm_oct_common_set_mac_address,
  527 + .ndo_do_ioctl = cvm_oct_ioctl,
  528 + .ndo_change_mtu = cvm_oct_common_change_mtu,
  529 + .ndo_get_stats = cvm_oct_common_get_stats,
  530 +#ifdef CONFIG_NET_POLL_CONTROLLER
  531 + .ndo_poll_controller = cvm_oct_poll_controller,
  532 +#endif
  533 +};
  534 +static const struct net_device_ops cvm_oct_xaui_netdev_ops = {
  535 + .ndo_init = cvm_oct_xaui_init,
  536 + .ndo_uninit = cvm_oct_xaui_uninit,
  537 + .ndo_open = cvm_oct_xaui_open,
  538 + .ndo_stop = cvm_oct_xaui_stop,
  539 + .ndo_start_xmit = cvm_oct_xmit,
  540 + .ndo_set_multicast_list = cvm_oct_common_set_multicast_list,
  541 + .ndo_set_mac_address = cvm_oct_common_set_mac_address,
  542 + .ndo_do_ioctl = cvm_oct_ioctl,
  543 + .ndo_change_mtu = cvm_oct_common_change_mtu,
  544 + .ndo_get_stats = cvm_oct_common_get_stats,
  545 +#ifdef CONFIG_NET_POLL_CONTROLLER
  546 + .ndo_poll_controller = cvm_oct_poll_controller,
  547 +#endif
  548 +};
  549 +static const struct net_device_ops cvm_oct_sgmii_netdev_ops = {
  550 + .ndo_init = cvm_oct_sgmii_init,
  551 + .ndo_uninit = cvm_oct_sgmii_uninit,
  552 + .ndo_open = cvm_oct_sgmii_open,
  553 + .ndo_stop = cvm_oct_sgmii_stop,
  554 + .ndo_start_xmit = cvm_oct_xmit,
  555 + .ndo_set_multicast_list = cvm_oct_common_set_multicast_list,
  556 + .ndo_set_mac_address = cvm_oct_common_set_mac_address,
  557 + .ndo_do_ioctl = cvm_oct_ioctl,
  558 + .ndo_change_mtu = cvm_oct_common_change_mtu,
  559 + .ndo_get_stats = cvm_oct_common_get_stats,
  560 +#ifdef CONFIG_NET_POLL_CONTROLLER
  561 + .ndo_poll_controller = cvm_oct_poll_controller,
  562 +#endif
  563 +};
  564 +static const struct net_device_ops cvm_oct_spi_netdev_ops = {
  565 + .ndo_init = cvm_oct_spi_init,
  566 + .ndo_uninit = cvm_oct_spi_uninit,
  567 + .ndo_start_xmit = cvm_oct_xmit,
  568 + .ndo_set_multicast_list = cvm_oct_common_set_multicast_list,
  569 + .ndo_set_mac_address = cvm_oct_common_set_mac_address,
  570 + .ndo_do_ioctl = cvm_oct_ioctl,
  571 + .ndo_change_mtu = cvm_oct_common_change_mtu,
  572 + .ndo_get_stats = cvm_oct_common_get_stats,
  573 +#ifdef CONFIG_NET_POLL_CONTROLLER
  574 + .ndo_poll_controller = cvm_oct_poll_controller,
  575 +#endif
  576 +};
  577 +static const struct net_device_ops cvm_oct_rgmii_netdev_ops = {
  578 + .ndo_init = cvm_oct_rgmii_init,
  579 + .ndo_uninit = cvm_oct_rgmii_uninit,
  580 + .ndo_open = cvm_oct_rgmii_open,
  581 + .ndo_stop = cvm_oct_rgmii_stop,
  582 + .ndo_start_xmit = cvm_oct_xmit,
  583 + .ndo_set_multicast_list = cvm_oct_common_set_multicast_list,
  584 + .ndo_set_mac_address = cvm_oct_common_set_mac_address,
  585 + .ndo_do_ioctl = cvm_oct_ioctl,
  586 + .ndo_change_mtu = cvm_oct_common_change_mtu,
  587 + .ndo_get_stats = cvm_oct_common_get_stats,
  588 +#ifdef CONFIG_NET_POLL_CONTROLLER
  589 + .ndo_poll_controller = cvm_oct_poll_controller,
  590 +#endif
  591 +};
  592 +static const struct net_device_ops cvm_oct_pow_netdev_ops = {
  593 + .ndo_init = cvm_oct_common_init,
  594 + .ndo_start_xmit = cvm_oct_xmit_pow,
  595 + .ndo_set_multicast_list = cvm_oct_common_set_multicast_list,
  596 + .ndo_set_mac_address = cvm_oct_common_set_mac_address,
  597 + .ndo_do_ioctl = cvm_oct_ioctl,
  598 + .ndo_change_mtu = cvm_oct_common_change_mtu,
  599 + .ndo_get_stats = cvm_oct_common_get_stats,
  600 +#ifdef CONFIG_NET_POLL_CONTROLLER
  601 + .ndo_poll_controller = cvm_oct_poll_controller,
  602 +#endif
  603 +};
  604 +
  605 +/**
249 606 * Module/ driver initialization. Creates the linux network
250 607 * devices.
251 608 *
... ... @@ -303,7 +660,7 @@
303 660 struct octeon_ethernet *priv = netdev_priv(dev);
304 661 memset(priv, 0, sizeof(struct octeon_ethernet));
305 662  
306   - dev->init = cvm_oct_common_init;
  663 + dev->netdev_ops = &cvm_oct_pow_netdev_ops;
307 664 priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED;
308 665 priv->port = CVMX_PIP_NUM_INPUT_PORTS;
309 666 priv->queue = -1;
310 667  
311 668  
312 669  
313 670  
314 671  
315 672  
... ... @@ -372,44 +729,38 @@
372 729 break;
373 730  
374 731 case CVMX_HELPER_INTERFACE_MODE_NPI:
375   - dev->init = cvm_oct_common_init;
376   - dev->uninit = cvm_oct_common_uninit;
  732 + dev->netdev_ops = &cvm_oct_npi_netdev_ops;
377 733 strcpy(dev->name, "npi%d");
378 734 break;
379 735  
380 736 case CVMX_HELPER_INTERFACE_MODE_XAUI:
381   - dev->init = cvm_oct_xaui_init;
382   - dev->uninit = cvm_oct_xaui_uninit;
  737 + dev->netdev_ops = &cvm_oct_xaui_netdev_ops;
383 738 strcpy(dev->name, "xaui%d");
384 739 break;
385 740  
386 741 case CVMX_HELPER_INTERFACE_MODE_LOOP:
387   - dev->init = cvm_oct_common_init;
388   - dev->uninit = cvm_oct_common_uninit;
  742 + dev->netdev_ops = &cvm_oct_npi_netdev_ops;
389 743 strcpy(dev->name, "loop%d");
390 744 break;
391 745  
392 746 case CVMX_HELPER_INTERFACE_MODE_SGMII:
393   - dev->init = cvm_oct_sgmii_init;
394   - dev->uninit = cvm_oct_sgmii_uninit;
  747 + dev->netdev_ops = &cvm_oct_sgmii_netdev_ops;
395 748 strcpy(dev->name, "eth%d");
396 749 break;
397 750  
398 751 case CVMX_HELPER_INTERFACE_MODE_SPI:
399   - dev->init = cvm_oct_spi_init;
400   - dev->uninit = cvm_oct_spi_uninit;
  752 + dev->netdev_ops = &cvm_oct_spi_netdev_ops;
401 753 strcpy(dev->name, "spi%d");
402 754 break;
403 755  
404 756 case CVMX_HELPER_INTERFACE_MODE_RGMII:
405 757 case CVMX_HELPER_INTERFACE_MODE_GMII:
406   - dev->init = cvm_oct_rgmii_init;
407   - dev->uninit = cvm_oct_rgmii_uninit;
  758 + dev->netdev_ops = &cvm_oct_rgmii_netdev_ops;
408 759 strcpy(dev->name, "eth%d");
409 760 break;
410 761 }
411 762  
412   - if (!dev->init) {
  763 + if (!dev->netdev_ops) {
413 764 kfree(dev);
414 765 } else if (register_netdev(dev) < 0) {
415 766 pr_err("Failed to register ethernet device "
drivers/staging/octeon/octeon-ethernet.h
... ... @@ -111,12 +111,23 @@
111 111  
112 112 extern int cvm_oct_rgmii_init(struct net_device *dev);
113 113 extern void cvm_oct_rgmii_uninit(struct net_device *dev);
  114 +extern int cvm_oct_rgmii_open(struct net_device *dev);
  115 +extern int cvm_oct_rgmii_stop(struct net_device *dev);
  116 +
114 117 extern int cvm_oct_sgmii_init(struct net_device *dev);
115 118 extern void cvm_oct_sgmii_uninit(struct net_device *dev);
  119 +extern int cvm_oct_sgmii_open(struct net_device *dev);
  120 +extern int cvm_oct_sgmii_stop(struct net_device *dev);
  121 +
116 122 extern int cvm_oct_spi_init(struct net_device *dev);
117 123 extern void cvm_oct_spi_uninit(struct net_device *dev);
118 124 extern int cvm_oct_xaui_init(struct net_device *dev);
119 125 extern void cvm_oct_xaui_uninit(struct net_device *dev);
  126 +extern int cvm_oct_xaui_open(struct net_device *dev);
  127 +extern int cvm_oct_xaui_stop(struct net_device *dev);
  128 +
  129 +extern int cvm_oct_common_init(struct net_device *dev);
  130 +extern void cvm_oct_common_uninit(struct net_device *dev);
120 131  
121 132 extern int always_use_pow;
122 133 extern int pow_send_group;