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>

authored by David Daney and committed by Ralf Baechle f696a108 773cb77d

+390 -396
-1
drivers/staging/octeon/Makefile
··· 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
-328
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 - }
-29
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);
+3 -6
drivers/staging/octeon/ethernet-rgmii.c
··· 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" ··· 264 265 return return_status; 265 266 } 266 267 267 - static int cvm_oct_rgmii_open(struct net_device *dev) 268 + int cvm_oct_rgmii_open(struct net_device *dev) 268 269 { 269 270 union cvmx_gmxx_prtx_cfg gmx_cfg; 270 271 struct octeon_ethernet *priv = netdev_priv(dev); ··· 285 286 return 0; 286 287 } 287 288 288 - static int cvm_oct_rgmii_stop(struct net_device *dev) 289 + int cvm_oct_rgmii_stop(struct net_device *dev) 289 290 { 290 291 union cvmx_gmxx_prtx_cfg gmx_cfg; 291 292 struct octeon_ethernet *priv = netdev_priv(dev); ··· 304 305 int r; 305 306 306 307 cvm_oct_common_init(dev); 307 - dev->open = cvm_oct_rgmii_open; 308 - dev->stop = cvm_oct_rgmii_stop; 309 - dev->stop(dev); 308 + dev->netdev_ops->ndo_stop(dev); 310 309 311 310 /* 312 311 * Due to GMX errata in CN3XXX series chips, it is necessary
+3 -6
drivers/staging/octeon/ethernet-sgmii.c
··· 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); ··· 60 61 return 0; 61 62 } 62 63 63 - static int cvm_oct_sgmii_stop(struct net_device *dev) 64 + int cvm_oct_sgmii_stop(struct net_device *dev) 64 65 { 65 66 union cvmx_gmxx_prtx_cfg gmx_cfg; 66 67 struct octeon_ethernet *priv = netdev_priv(dev); ··· 112 113 { 113 114 struct octeon_ethernet *priv = netdev_priv(dev); 114 115 cvm_oct_common_init(dev); 115 - dev->open = cvm_oct_sgmii_open; 116 - dev->stop = cvm_oct_sgmii_stop; 117 - dev->stop(dev); 116 + dev->netdev_ops->ndo_stop(dev); 118 117 if (!octeon_is_simulation()) 119 118 priv->poll = cvm_oct_sgmii_poll; 120 119
-1
drivers/staging/octeon/ethernet-spi.c
··· 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"
+3 -3
drivers/staging/octeon/ethernet-tx.c
··· 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;
+3 -6
drivers/staging/octeon/ethernet-xaui.c
··· 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); ··· 59 60 return 0; 60 61 } 61 62 62 - static int cvm_oct_xaui_stop(struct net_device *dev) 63 + int cvm_oct_xaui_stop(struct net_device *dev) 63 64 { 64 65 union cvmx_gmxx_prtx_cfg gmx_cfg; 65 66 struct octeon_ethernet *priv = netdev_priv(dev); ··· 111 112 { 112 113 struct octeon_ethernet *priv = netdev_priv(dev); 113 114 cvm_oct_common_init(dev); 114 - dev->open = cvm_oct_xaui_open; 115 - dev->stop = cvm_oct_xaui_stop; 116 - dev->stop(dev); 115 + dev->netdev_ops->ndo_stop(dev); 117 116 if (!octeon_is_simulation()) 118 117 priv->poll = cvm_oct_xaui_poll; 119 118
+367 -16
drivers/staging/octeon/ethernet.c
··· 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 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) \ ··· 165 164 lock); 166 165 } 167 166 } 168 - cvm_oct_device[port]->get_stats(cvm_oct_device[port]); 167 + cvm_oct_device[port]->netdev_ops->ndo_get_stats(cvm_oct_device[port]); 169 168 } 170 169 port++; 171 170 /* Poll the next port in a 50th of a second. ··· 247 246 EXPORT_SYMBOL(cvm_oct_free_work); 248 247 249 248 /** 249 + * Get the low level ethernet statistics 250 + * 251 + * @dev: Device to get the statistics from 252 + * Returns Pointer to the statistics 253 + */ 254 + static struct net_device_stats *cvm_oct_common_get_stats(struct net_device *dev) 255 + { 256 + cvmx_pip_port_status_t rx_status; 257 + cvmx_pko_port_status_t tx_status; 258 + struct octeon_ethernet *priv = netdev_priv(dev); 259 + 260 + if (priv->port < CVMX_PIP_NUM_INPUT_PORTS) { 261 + if (octeon_is_simulation()) { 262 + /* The simulator doesn't support statistics */ 263 + memset(&rx_status, 0, sizeof(rx_status)); 264 + memset(&tx_status, 0, sizeof(tx_status)); 265 + } else { 266 + cvmx_pip_get_port_status(priv->port, 1, &rx_status); 267 + cvmx_pko_get_port_status(priv->port, 1, &tx_status); 268 + } 269 + 270 + priv->stats.rx_packets += rx_status.inb_packets; 271 + priv->stats.tx_packets += tx_status.packets; 272 + priv->stats.rx_bytes += rx_status.inb_octets; 273 + priv->stats.tx_bytes += tx_status.octets; 274 + priv->stats.multicast += rx_status.multicast_packets; 275 + priv->stats.rx_crc_errors += rx_status.inb_errors; 276 + priv->stats.rx_frame_errors += rx_status.fcs_align_err_packets; 277 + 278 + /* 279 + * The drop counter must be incremented atomically 280 + * since the RX tasklet also increments it. 281 + */ 282 + #ifdef CONFIG_64BIT 283 + atomic64_add(rx_status.dropped_packets, 284 + (atomic64_t *)&priv->stats.rx_dropped); 285 + #else 286 + atomic_add(rx_status.dropped_packets, 287 + (atomic_t *)&priv->stats.rx_dropped); 288 + #endif 289 + } 290 + 291 + return &priv->stats; 292 + } 293 + 294 + /** 295 + * Change the link MTU. Unimplemented 296 + * 297 + * @dev: Device to change 298 + * @new_mtu: The new MTU 299 + * 300 + * Returns Zero on success 301 + */ 302 + static int cvm_oct_common_change_mtu(struct net_device *dev, int new_mtu) 303 + { 304 + struct octeon_ethernet *priv = netdev_priv(dev); 305 + int interface = INTERFACE(priv->port); 306 + int index = INDEX(priv->port); 307 + #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) 308 + int vlan_bytes = 4; 309 + #else 310 + int vlan_bytes = 0; 311 + #endif 312 + 313 + /* 314 + * Limit the MTU to make sure the ethernet packets are between 315 + * 64 bytes and 65535 bytes. 316 + */ 317 + if ((new_mtu + 14 + 4 + vlan_bytes < 64) 318 + || (new_mtu + 14 + 4 + vlan_bytes > 65392)) { 319 + pr_err("MTU must be between %d and %d.\n", 320 + 64 - 14 - 4 - vlan_bytes, 65392 - 14 - 4 - vlan_bytes); 321 + return -EINVAL; 322 + } 323 + dev->mtu = new_mtu; 324 + 325 + if ((interface < 2) 326 + && (cvmx_helper_interface_get_mode(interface) != 327 + CVMX_HELPER_INTERFACE_MODE_SPI)) { 328 + /* Add ethernet header and FCS, and VLAN if configured. */ 329 + int max_packet = new_mtu + 14 + 4 + vlan_bytes; 330 + 331 + if (OCTEON_IS_MODEL(OCTEON_CN3XXX) 332 + || OCTEON_IS_MODEL(OCTEON_CN58XX)) { 333 + /* Signal errors on packets larger than the MTU */ 334 + cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface), 335 + max_packet); 336 + } else { 337 + /* 338 + * Set the hardware to truncate packets larger 339 + * than the MTU and smaller the 64 bytes. 340 + */ 341 + union cvmx_pip_frm_len_chkx frm_len_chk; 342 + frm_len_chk.u64 = 0; 343 + frm_len_chk.s.minlen = 64; 344 + frm_len_chk.s.maxlen = max_packet; 345 + cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface), 346 + frm_len_chk.u64); 347 + } 348 + /* 349 + * Set the hardware to truncate packets larger than 350 + * the MTU. The jabber register must be set to a 351 + * multiple of 8 bytes, so round up. 352 + */ 353 + cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface), 354 + (max_packet + 7) & ~7u); 355 + } 356 + return 0; 357 + } 358 + 359 + /** 360 + * Set the multicast list. Currently unimplemented. 361 + * 362 + * @dev: Device to work on 363 + */ 364 + static void cvm_oct_common_set_multicast_list(struct net_device *dev) 365 + { 366 + union cvmx_gmxx_prtx_cfg gmx_cfg; 367 + struct octeon_ethernet *priv = netdev_priv(dev); 368 + int interface = INTERFACE(priv->port); 369 + int index = INDEX(priv->port); 370 + 371 + if ((interface < 2) 372 + && (cvmx_helper_interface_get_mode(interface) != 373 + CVMX_HELPER_INTERFACE_MODE_SPI)) { 374 + union cvmx_gmxx_rxx_adr_ctl control; 375 + control.u64 = 0; 376 + control.s.bcst = 1; /* Allow broadcast MAC addresses */ 377 + 378 + if (dev->mc_list || (dev->flags & IFF_ALLMULTI) || 379 + (dev->flags & IFF_PROMISC)) 380 + /* Force accept multicast packets */ 381 + control.s.mcst = 2; 382 + else 383 + /* Force reject multicat packets */ 384 + control.s.mcst = 1; 385 + 386 + if (dev->flags & IFF_PROMISC) 387 + /* 388 + * Reject matches if promisc. Since CAM is 389 + * shut off, should accept everything. 390 + */ 391 + control.s.cam_mode = 0; 392 + else 393 + /* Filter packets based on the CAM */ 394 + control.s.cam_mode = 1; 395 + 396 + gmx_cfg.u64 = 397 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 398 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), 399 + gmx_cfg.u64 & ~1ull); 400 + 401 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface), 402 + control.u64); 403 + if (dev->flags & IFF_PROMISC) 404 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN 405 + (index, interface), 0); 406 + else 407 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN 408 + (index, interface), 1); 409 + 410 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), 411 + gmx_cfg.u64); 412 + } 413 + } 414 + 415 + /** 416 + * Set the hardware MAC address for a device 417 + * 418 + * @dev: Device to change the MAC address for 419 + * @addr: Address structure to change it too. MAC address is addr + 2. 420 + * Returns Zero on success 421 + */ 422 + static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr) 423 + { 424 + struct octeon_ethernet *priv = netdev_priv(dev); 425 + union cvmx_gmxx_prtx_cfg gmx_cfg; 426 + int interface = INTERFACE(priv->port); 427 + int index = INDEX(priv->port); 428 + 429 + memcpy(dev->dev_addr, addr + 2, 6); 430 + 431 + if ((interface < 2) 432 + && (cvmx_helper_interface_get_mode(interface) != 433 + CVMX_HELPER_INTERFACE_MODE_SPI)) { 434 + int i; 435 + uint8_t *ptr = addr; 436 + uint64_t mac = 0; 437 + for (i = 0; i < 6; i++) 438 + mac = (mac << 8) | (uint64_t) (ptr[i + 2]); 439 + 440 + gmx_cfg.u64 = 441 + cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 442 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), 443 + gmx_cfg.u64 & ~1ull); 444 + 445 + cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac); 446 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface), 447 + ptr[2]); 448 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface), 449 + ptr[3]); 450 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface), 451 + ptr[4]); 452 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface), 453 + ptr[5]); 454 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface), 455 + ptr[6]); 456 + cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface), 457 + ptr[7]); 458 + cvm_oct_common_set_multicast_list(dev); 459 + cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), 460 + gmx_cfg.u64); 461 + } 462 + return 0; 463 + } 464 + 465 + /** 466 + * Per network device initialization 467 + * 468 + * @dev: Device to initialize 469 + * Returns Zero on success 470 + */ 471 + int cvm_oct_common_init(struct net_device *dev) 472 + { 473 + static int count; 474 + char mac[8] = { 0x00, 0x00, 475 + octeon_bootinfo->mac_addr_base[0], 476 + octeon_bootinfo->mac_addr_base[1], 477 + octeon_bootinfo->mac_addr_base[2], 478 + octeon_bootinfo->mac_addr_base[3], 479 + octeon_bootinfo->mac_addr_base[4], 480 + octeon_bootinfo->mac_addr_base[5] + count 481 + }; 482 + struct octeon_ethernet *priv = netdev_priv(dev); 483 + 484 + /* 485 + * Force the interface to use the POW send if always_use_pow 486 + * was specified or it is in the pow send list. 487 + */ 488 + if ((pow_send_group != -1) 489 + && (always_use_pow || strstr(pow_send_list, dev->name))) 490 + priv->queue = -1; 491 + 492 + if (priv->queue != -1 && USE_HW_TCPUDP_CHECKSUM) 493 + dev->features |= NETIF_F_IP_CSUM; 494 + 495 + count++; 496 + 497 + /* We do our own locking, Linux doesn't need to */ 498 + dev->features |= NETIF_F_LLTX; 499 + SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); 500 + 501 + cvm_oct_mdio_setup_device(dev); 502 + dev->netdev_ops->ndo_set_mac_address(dev, mac); 503 + dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); 504 + 505 + /* 506 + * Zero out stats for port so we won't mistakenly show 507 + * counters from the bootloader. 508 + */ 509 + memset(dev->netdev_ops->ndo_get_stats(dev), 0, 510 + sizeof(struct net_device_stats)); 511 + 512 + return 0; 513 + } 514 + 515 + void cvm_oct_common_uninit(struct net_device *dev) 516 + { 517 + /* Currently nothing to do */ 518 + } 519 + 520 + static const struct net_device_ops cvm_oct_npi_netdev_ops = { 521 + .ndo_init = cvm_oct_common_init, 522 + .ndo_uninit = cvm_oct_common_uninit, 523 + .ndo_start_xmit = cvm_oct_xmit, 524 + .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, 525 + .ndo_set_mac_address = cvm_oct_common_set_mac_address, 526 + .ndo_do_ioctl = cvm_oct_ioctl, 527 + .ndo_change_mtu = cvm_oct_common_change_mtu, 528 + .ndo_get_stats = cvm_oct_common_get_stats, 529 + #ifdef CONFIG_NET_POLL_CONTROLLER 530 + .ndo_poll_controller = cvm_oct_poll_controller, 531 + #endif 532 + }; 533 + static const struct net_device_ops cvm_oct_xaui_netdev_ops = { 534 + .ndo_init = cvm_oct_xaui_init, 535 + .ndo_uninit = cvm_oct_xaui_uninit, 536 + .ndo_open = cvm_oct_xaui_open, 537 + .ndo_stop = cvm_oct_xaui_stop, 538 + .ndo_start_xmit = cvm_oct_xmit, 539 + .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, 540 + .ndo_set_mac_address = cvm_oct_common_set_mac_address, 541 + .ndo_do_ioctl = cvm_oct_ioctl, 542 + .ndo_change_mtu = cvm_oct_common_change_mtu, 543 + .ndo_get_stats = cvm_oct_common_get_stats, 544 + #ifdef CONFIG_NET_POLL_CONTROLLER 545 + .ndo_poll_controller = cvm_oct_poll_controller, 546 + #endif 547 + }; 548 + static const struct net_device_ops cvm_oct_sgmii_netdev_ops = { 549 + .ndo_init = cvm_oct_sgmii_init, 550 + .ndo_uninit = cvm_oct_sgmii_uninit, 551 + .ndo_open = cvm_oct_sgmii_open, 552 + .ndo_stop = cvm_oct_sgmii_stop, 553 + .ndo_start_xmit = cvm_oct_xmit, 554 + .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, 555 + .ndo_set_mac_address = cvm_oct_common_set_mac_address, 556 + .ndo_do_ioctl = cvm_oct_ioctl, 557 + .ndo_change_mtu = cvm_oct_common_change_mtu, 558 + .ndo_get_stats = cvm_oct_common_get_stats, 559 + #ifdef CONFIG_NET_POLL_CONTROLLER 560 + .ndo_poll_controller = cvm_oct_poll_controller, 561 + #endif 562 + }; 563 + static const struct net_device_ops cvm_oct_spi_netdev_ops = { 564 + .ndo_init = cvm_oct_spi_init, 565 + .ndo_uninit = cvm_oct_spi_uninit, 566 + .ndo_start_xmit = cvm_oct_xmit, 567 + .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, 568 + .ndo_set_mac_address = cvm_oct_common_set_mac_address, 569 + .ndo_do_ioctl = cvm_oct_ioctl, 570 + .ndo_change_mtu = cvm_oct_common_change_mtu, 571 + .ndo_get_stats = cvm_oct_common_get_stats, 572 + #ifdef CONFIG_NET_POLL_CONTROLLER 573 + .ndo_poll_controller = cvm_oct_poll_controller, 574 + #endif 575 + }; 576 + static const struct net_device_ops cvm_oct_rgmii_netdev_ops = { 577 + .ndo_init = cvm_oct_rgmii_init, 578 + .ndo_uninit = cvm_oct_rgmii_uninit, 579 + .ndo_open = cvm_oct_rgmii_open, 580 + .ndo_stop = cvm_oct_rgmii_stop, 581 + .ndo_start_xmit = cvm_oct_xmit, 582 + .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, 583 + .ndo_set_mac_address = cvm_oct_common_set_mac_address, 584 + .ndo_do_ioctl = cvm_oct_ioctl, 585 + .ndo_change_mtu = cvm_oct_common_change_mtu, 586 + .ndo_get_stats = cvm_oct_common_get_stats, 587 + #ifdef CONFIG_NET_POLL_CONTROLLER 588 + .ndo_poll_controller = cvm_oct_poll_controller, 589 + #endif 590 + }; 591 + static const struct net_device_ops cvm_oct_pow_netdev_ops = { 592 + .ndo_init = cvm_oct_common_init, 593 + .ndo_start_xmit = cvm_oct_xmit_pow, 594 + .ndo_set_multicast_list = cvm_oct_common_set_multicast_list, 595 + .ndo_set_mac_address = cvm_oct_common_set_mac_address, 596 + .ndo_do_ioctl = cvm_oct_ioctl, 597 + .ndo_change_mtu = cvm_oct_common_change_mtu, 598 + .ndo_get_stats = cvm_oct_common_get_stats, 599 + #ifdef CONFIG_NET_POLL_CONTROLLER 600 + .ndo_poll_controller = cvm_oct_poll_controller, 601 + #endif 602 + }; 603 + 604 + /** 250 605 * Module/ driver initialization. Creates the linux network 251 606 * devices. 252 607 * ··· 660 303 struct octeon_ethernet *priv = netdev_priv(dev); 661 304 memset(priv, 0, sizeof(struct octeon_ethernet)); 662 305 663 - dev->init = cvm_oct_common_init; 306 + dev->netdev_ops = &cvm_oct_pow_netdev_ops; 664 307 priv->imode = CVMX_HELPER_INTERFACE_MODE_DISABLED; 665 308 priv->port = CVMX_PIP_NUM_INPUT_PORTS; 666 309 priv->queue = -1; ··· 729 372 break; 730 373 731 374 case CVMX_HELPER_INTERFACE_MODE_NPI: 732 - dev->init = cvm_oct_common_init; 733 - dev->uninit = cvm_oct_common_uninit; 375 + dev->netdev_ops = &cvm_oct_npi_netdev_ops; 734 376 strcpy(dev->name, "npi%d"); 735 377 break; 736 378 737 379 case CVMX_HELPER_INTERFACE_MODE_XAUI: 738 - dev->init = cvm_oct_xaui_init; 739 - dev->uninit = cvm_oct_xaui_uninit; 380 + dev->netdev_ops = &cvm_oct_xaui_netdev_ops; 740 381 strcpy(dev->name, "xaui%d"); 741 382 break; 742 383 743 384 case CVMX_HELPER_INTERFACE_MODE_LOOP: 744 - dev->init = cvm_oct_common_init; 745 - dev->uninit = cvm_oct_common_uninit; 385 + dev->netdev_ops = &cvm_oct_npi_netdev_ops; 746 386 strcpy(dev->name, "loop%d"); 747 387 break; 748 388 749 389 case CVMX_HELPER_INTERFACE_MODE_SGMII: 750 - dev->init = cvm_oct_sgmii_init; 751 - dev->uninit = cvm_oct_sgmii_uninit; 390 + dev->netdev_ops = &cvm_oct_sgmii_netdev_ops; 752 391 strcpy(dev->name, "eth%d"); 753 392 break; 754 393 755 394 case CVMX_HELPER_INTERFACE_MODE_SPI: 756 - dev->init = cvm_oct_spi_init; 757 - dev->uninit = cvm_oct_spi_uninit; 395 + dev->netdev_ops = &cvm_oct_spi_netdev_ops; 758 396 strcpy(dev->name, "spi%d"); 759 397 break; 760 398 761 399 case CVMX_HELPER_INTERFACE_MODE_RGMII: 762 400 case CVMX_HELPER_INTERFACE_MODE_GMII: 763 - dev->init = cvm_oct_rgmii_init; 764 - dev->uninit = cvm_oct_rgmii_uninit; 401 + dev->netdev_ops = &cvm_oct_rgmii_netdev_ops; 765 402 strcpy(dev->name, "eth%d"); 766 403 break; 767 404 } 768 405 769 - if (!dev->init) { 406 + if (!dev->netdev_ops) { 770 407 kfree(dev); 771 408 } else if (register_netdev(dev) < 0) { 772 409 pr_err("Failed to register ethernet device "
+11
drivers/staging/octeon/octeon-ethernet.h
··· 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;