1/************************************************************************* 2Copyright (c) 2003-2007 Cavium Networks (support@cavium.com). All rights 3reserved. 4 5 6Redistribution and use in source and binary forms, with or without 7modification, are permitted provided that the following conditions are 8met: 9 10 * Redistributions of source code must retain the above copyright 11 notice, this list of conditions and the following disclaimer. 12 13 * Redistributions in binary form must reproduce the above 14 copyright notice, this list of conditions and the following 15 disclaimer in the documentation and/or other materials provided 16 with the distribution. 17 18 * Neither the name of Cavium Networks nor the names of 19 its contributors may be used to endorse or promote products 20 derived from this software without specific prior written 21 permission. 22 23This Software, including technical data, may be subject to U.S. export control laws, including the U.S. Export Administration Act and its associated regulations, and may be subject to export or import regulations in other countries. 24 25TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 26AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 27 28*************************************************************************/ 29 30#include <sys/cdefs.h>
| 1/************************************************************************* 2Copyright (c) 2003-2007 Cavium Networks (support@cavium.com). All rights 3reserved. 4 5 6Redistribution and use in source and binary forms, with or without 7modification, are permitted provided that the following conditions are 8met: 9 10 * Redistributions of source code must retain the above copyright 11 notice, this list of conditions and the following disclaimer. 12 13 * Redistributions in binary form must reproduce the above 14 copyright notice, this list of conditions and the following 15 disclaimer in the documentation and/or other materials provided 16 with the distribution. 17 18 * Neither the name of Cavium Networks nor the names of 19 its contributors may be used to endorse or promote products 20 derived from this software without specific prior written 21 permission. 22 23This Software, including technical data, may be subject to U.S. export control laws, including the U.S. Export Administration Act and its associated regulations, and may be subject to export or import regulations in other countries. 24 25TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 26AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 27 28*************************************************************************/ 29 30#include <sys/cdefs.h>
|
31__FBSDID("$FreeBSD: head/sys/mips/cavium/octe/ethernet-common.c 226024 2011-10-04 20:17:43Z marcel $");
| 31__FBSDID("$FreeBSD: head/sys/mips/cavium/octe/ethernet-common.c 231987 2012-02-22 01:30:25Z gonzo $");
|
32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/bus.h> 36#include <sys/endian.h> 37#include <sys/kernel.h> 38#include <sys/mbuf.h> 39#include <sys/socket.h> 40 41#include <net/ethernet.h> 42#include <net/if.h> 43 44#include "wrapper-cvmx-includes.h" 45#include "ethernet-headers.h" 46 47extern int octeon_is_simulation(void); 48
| 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/bus.h> 36#include <sys/endian.h> 37#include <sys/kernel.h> 38#include <sys/mbuf.h> 39#include <sys/socket.h> 40 41#include <net/ethernet.h> 42#include <net/if.h> 43 44#include "wrapper-cvmx-includes.h" 45#include "ethernet-headers.h" 46 47extern int octeon_is_simulation(void); 48
|
| 49static uint64_t mac_addr = 0; 50static uint32_t mac_offset = 0;
|
49 50/** 51 * Set the multicast list. Currently unimplemented. 52 * 53 * @param dev Device to work on 54 */ 55void cvm_oct_common_set_multicast_list(struct ifnet *ifp) 56{ 57 cvmx_gmxx_prtx_cfg_t gmx_cfg; 58 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 59 int interface = INTERFACE(priv->port); 60 int index = INDEX(priv->port); 61 62 if ((interface < 2) && (cvmx_helper_interface_get_mode(interface) != CVMX_HELPER_INTERFACE_MODE_SPI)) { 63 cvmx_gmxx_rxx_adr_ctl_t control; 64 control.u64 = 0; 65 control.s.bcst = 1; /* Allow broadcast MAC addresses */ 66 67 if (/*ifp->mc_list || */(ifp->if_flags&IFF_ALLMULTI) || 68 (ifp->if_flags & IFF_PROMISC)) 69 control.s.mcst = 2; /* Force accept multicast packets */ 70 else 71 control.s.mcst = 1; /* Force reject multicat packets */ 72 73 if (ifp->if_flags & IFF_PROMISC) 74 control.s.cam_mode = 0; /* Reject matches if promisc. Since CAM is shut off, should accept everything */ 75 else 76 control.s.cam_mode = 1; /* Filter packets based on the CAM */ 77 78 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 79 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64 & ~1ull); 80 81 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface), control.u64); 82 if (ifp->if_flags&IFF_PROMISC) 83 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN(index, interface), 0); 84 else 85 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN(index, interface), 1); 86 87 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); 88 } 89} 90 91 92/**
| 51 52/** 53 * Set the multicast list. Currently unimplemented. 54 * 55 * @param dev Device to work on 56 */ 57void cvm_oct_common_set_multicast_list(struct ifnet *ifp) 58{ 59 cvmx_gmxx_prtx_cfg_t gmx_cfg; 60 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 61 int interface = INTERFACE(priv->port); 62 int index = INDEX(priv->port); 63 64 if ((interface < 2) && (cvmx_helper_interface_get_mode(interface) != CVMX_HELPER_INTERFACE_MODE_SPI)) { 65 cvmx_gmxx_rxx_adr_ctl_t control; 66 control.u64 = 0; 67 control.s.bcst = 1; /* Allow broadcast MAC addresses */ 68 69 if (/*ifp->mc_list || */(ifp->if_flags&IFF_ALLMULTI) || 70 (ifp->if_flags & IFF_PROMISC)) 71 control.s.mcst = 2; /* Force accept multicast packets */ 72 else 73 control.s.mcst = 1; /* Force reject multicat packets */ 74 75 if (ifp->if_flags & IFF_PROMISC) 76 control.s.cam_mode = 0; /* Reject matches if promisc. Since CAM is shut off, should accept everything */ 77 else 78 control.s.cam_mode = 1; /* Filter packets based on the CAM */ 79 80 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 81 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64 & ~1ull); 82 83 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CTL(index, interface), control.u64); 84 if (ifp->if_flags&IFF_PROMISC) 85 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN(index, interface), 0); 86 else 87 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM_EN(index, interface), 1); 88 89 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); 90 } 91} 92 93 94/**
|
| 95 * Assign a MAC addres from the pool of available MAC addresses 96 * Can return as either a 64-bit value and/or 6 octets. 97 * 98 * @param macp Filled in with the assigned address if non-NULL 99 * @param octets Filled in with the assigned address if non-NULL 100 * @return Zero on success 101 */ 102int cvm_assign_mac_address(uint64_t *macp, uint8_t *octets) 103{ 104 /* Initialize from global MAC address base; fail if not set */ 105 if (mac_addr == 0) { 106 memcpy((uint8_t *)&mac_addr + 2, cvmx_sysinfo_get()->mac_addr_base, 6); 107 if (mac_addr == 0) 108 return ENXIO; 109 } 110 111 if (mac_offset >= cvmx_sysinfo_get()->mac_addr_count) 112 return ENXIO; /* Out of addresses to assign */ 113 114 if (macp) 115 *macp = mac_addr; 116 if (octets) 117 memcpy(octets, (u_int8_t *)&mac_addr + 2, 6); 118 119 mac_addr++; 120 mac_offset++; 121 122 return 0; 123} 124 125/**
|
93 * Set the hardware MAC address for a device 94 * 95 * @param dev Device to change the MAC address for 96 * @param addr Address structure to change it too. 97 */ 98void cvm_oct_common_set_mac_address(struct ifnet *ifp, const void *addr) 99{ 100 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 101 cvmx_gmxx_prtx_cfg_t gmx_cfg; 102 int interface = INTERFACE(priv->port); 103 int index = INDEX(priv->port); 104 105 memcpy(priv->mac, addr, 6); 106 107 if ((interface < 2) && (cvmx_helper_interface_get_mode(interface) != CVMX_HELPER_INTERFACE_MODE_SPI)) { 108 int i; 109 const uint8_t *ptr = addr; 110 uint64_t mac = 0; 111 for (i = 0; i < 6; i++) 112 mac = (mac<<8) | (uint64_t)(ptr[i]); 113 114 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 115 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64 & ~1ull); 116 117 cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac); 118 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface), ptr[0]); 119 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface), ptr[1]); 120 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface), ptr[2]); 121 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface), ptr[3]); 122 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface), ptr[4]); 123 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface), ptr[5]); 124 cvm_oct_common_set_multicast_list(ifp); 125 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); 126 } 127} 128 129 130/** 131 * Change the link MTU. Unimplemented 132 * 133 * @param dev Device to change 134 * @param new_mtu The new MTU 135 * @return Zero on success 136 */ 137int cvm_oct_common_change_mtu(struct ifnet *ifp, int new_mtu) 138{ 139 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 140 int interface = INTERFACE(priv->port); 141 int index = INDEX(priv->port); 142 int vlan_bytes = 4; 143 144 /* Limit the MTU to make sure the ethernet packets are between 64 bytes 145 and 65535 bytes */ 146 if ((new_mtu + 14 + 4 + vlan_bytes < 64) || (new_mtu + 14 + 4 + vlan_bytes > 65392)) { 147 printf("MTU must be between %d and %d.\n", 64-14-4-vlan_bytes, 65392-14-4-vlan_bytes); 148 return -EINVAL; 149 } 150 ifp->if_mtu = new_mtu; 151 152 if ((interface < 2) && (cvmx_helper_interface_get_mode(interface) != CVMX_HELPER_INTERFACE_MODE_SPI)) { 153 int max_packet = new_mtu + 14 + 4 + vlan_bytes; /* Add ethernet header and FCS, and VLAN if configured. */ 154 155 if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) { 156 /* Signal errors on packets larger than the MTU */ 157 cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface), max_packet); 158 } else { 159 /* Set the hardware to truncate packets larger than the MTU and 160 smaller the 64 bytes */ 161 cvmx_pip_frm_len_chkx_t frm_len_chk; 162 frm_len_chk.u64 = 0; 163 frm_len_chk.s.minlen = 64; 164 frm_len_chk.s.maxlen = max_packet; 165 cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface), frm_len_chk.u64); 166 } 167 /* Set the hardware to truncate packets larger than the MTU. The 168 jabber register must be set to a multiple of 8 bytes, so round up */ 169 cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface), (max_packet + 7) & ~7u); 170 } 171 return 0; 172} 173 174 175/** 176 * Enable port. 177 */ 178int cvm_oct_common_open(struct ifnet *ifp) 179{ 180 cvmx_gmxx_prtx_cfg_t gmx_cfg; 181 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 182 int interface = INTERFACE(priv->port); 183 int index = INDEX(priv->port); 184 cvmx_helper_link_info_t link_info; 185 186 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 187 gmx_cfg.s.en = 1; 188 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); 189 190 /* 191 * Set the link state unless we are using MII. 192 */ 193 if (!octeon_is_simulation() && priv->miibus == NULL) { 194 link_info = cvmx_helper_link_get(priv->port); 195 if (!link_info.s.link_up) 196 if_link_state_change(ifp, LINK_STATE_DOWN); 197 else 198 if_link_state_change(ifp, LINK_STATE_UP); 199 } 200 201 return 0; 202} 203 204 205/** 206 * Disable port. 207 */ 208int cvm_oct_common_stop(struct ifnet *ifp) 209{ 210 cvmx_gmxx_prtx_cfg_t gmx_cfg; 211 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 212 int interface = INTERFACE(priv->port); 213 int index = INDEX(priv->port); 214 215 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 216 gmx_cfg.s.en = 0; 217 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); 218 return 0; 219} 220 221/** 222 * Poll for link status change. 223 */ 224void cvm_oct_common_poll(struct ifnet *ifp) 225{ 226 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 227 cvmx_helper_link_info_t link_info; 228 229 /* 230 * If this is a simulation, do nothing. 231 */ 232 if (octeon_is_simulation()) 233 return; 234 235 /* 236 * If there is a device-specific poll method, use it. 237 */ 238 if (priv->poll != NULL) { 239 priv->poll(ifp); 240 return; 241 } 242 243 /* 244 * If an MII bus is attached, don't use the Simple Executive's link 245 * state routines. 246 */ 247 if (priv->miibus != NULL) 248 return; 249 250 /* 251 * Use the Simple Executive's link state routines. 252 */ 253 link_info = cvmx_helper_link_get(priv->port); 254 if (link_info.u64 == priv->link_info) 255 return; 256 257 link_info = cvmx_helper_link_autoconf(priv->port); 258 priv->link_info = link_info.u64; 259 priv->need_link_update = 1; 260} 261 262 263/** 264 * Per network device initialization 265 * 266 * @param dev Device to initialize 267 * @return Zero on success 268 */ 269int cvm_oct_common_init(struct ifnet *ifp) 270{
| 126 * Set the hardware MAC address for a device 127 * 128 * @param dev Device to change the MAC address for 129 * @param addr Address structure to change it too. 130 */ 131void cvm_oct_common_set_mac_address(struct ifnet *ifp, const void *addr) 132{ 133 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 134 cvmx_gmxx_prtx_cfg_t gmx_cfg; 135 int interface = INTERFACE(priv->port); 136 int index = INDEX(priv->port); 137 138 memcpy(priv->mac, addr, 6); 139 140 if ((interface < 2) && (cvmx_helper_interface_get_mode(interface) != CVMX_HELPER_INTERFACE_MODE_SPI)) { 141 int i; 142 const uint8_t *ptr = addr; 143 uint64_t mac = 0; 144 for (i = 0; i < 6; i++) 145 mac = (mac<<8) | (uint64_t)(ptr[i]); 146 147 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 148 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64 & ~1ull); 149 150 cvmx_write_csr(CVMX_GMXX_SMACX(index, interface), mac); 151 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM0(index, interface), ptr[0]); 152 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM1(index, interface), ptr[1]); 153 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM2(index, interface), ptr[2]); 154 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM3(index, interface), ptr[3]); 155 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM4(index, interface), ptr[4]); 156 cvmx_write_csr(CVMX_GMXX_RXX_ADR_CAM5(index, interface), ptr[5]); 157 cvm_oct_common_set_multicast_list(ifp); 158 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); 159 } 160} 161 162 163/** 164 * Change the link MTU. Unimplemented 165 * 166 * @param dev Device to change 167 * @param new_mtu The new MTU 168 * @return Zero on success 169 */ 170int cvm_oct_common_change_mtu(struct ifnet *ifp, int new_mtu) 171{ 172 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 173 int interface = INTERFACE(priv->port); 174 int index = INDEX(priv->port); 175 int vlan_bytes = 4; 176 177 /* Limit the MTU to make sure the ethernet packets are between 64 bytes 178 and 65535 bytes */ 179 if ((new_mtu + 14 + 4 + vlan_bytes < 64) || (new_mtu + 14 + 4 + vlan_bytes > 65392)) { 180 printf("MTU must be between %d and %d.\n", 64-14-4-vlan_bytes, 65392-14-4-vlan_bytes); 181 return -EINVAL; 182 } 183 ifp->if_mtu = new_mtu; 184 185 if ((interface < 2) && (cvmx_helper_interface_get_mode(interface) != CVMX_HELPER_INTERFACE_MODE_SPI)) { 186 int max_packet = new_mtu + 14 + 4 + vlan_bytes; /* Add ethernet header and FCS, and VLAN if configured. */ 187 188 if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN58XX)) { 189 /* Signal errors on packets larger than the MTU */ 190 cvmx_write_csr(CVMX_GMXX_RXX_FRM_MAX(index, interface), max_packet); 191 } else { 192 /* Set the hardware to truncate packets larger than the MTU and 193 smaller the 64 bytes */ 194 cvmx_pip_frm_len_chkx_t frm_len_chk; 195 frm_len_chk.u64 = 0; 196 frm_len_chk.s.minlen = 64; 197 frm_len_chk.s.maxlen = max_packet; 198 cvmx_write_csr(CVMX_PIP_FRM_LEN_CHKX(interface), frm_len_chk.u64); 199 } 200 /* Set the hardware to truncate packets larger than the MTU. The 201 jabber register must be set to a multiple of 8 bytes, so round up */ 202 cvmx_write_csr(CVMX_GMXX_RXX_JABBER(index, interface), (max_packet + 7) & ~7u); 203 } 204 return 0; 205} 206 207 208/** 209 * Enable port. 210 */ 211int cvm_oct_common_open(struct ifnet *ifp) 212{ 213 cvmx_gmxx_prtx_cfg_t gmx_cfg; 214 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 215 int interface = INTERFACE(priv->port); 216 int index = INDEX(priv->port); 217 cvmx_helper_link_info_t link_info; 218 219 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 220 gmx_cfg.s.en = 1; 221 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); 222 223 /* 224 * Set the link state unless we are using MII. 225 */ 226 if (!octeon_is_simulation() && priv->miibus == NULL) { 227 link_info = cvmx_helper_link_get(priv->port); 228 if (!link_info.s.link_up) 229 if_link_state_change(ifp, LINK_STATE_DOWN); 230 else 231 if_link_state_change(ifp, LINK_STATE_UP); 232 } 233 234 return 0; 235} 236 237 238/** 239 * Disable port. 240 */ 241int cvm_oct_common_stop(struct ifnet *ifp) 242{ 243 cvmx_gmxx_prtx_cfg_t gmx_cfg; 244 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 245 int interface = INTERFACE(priv->port); 246 int index = INDEX(priv->port); 247 248 gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); 249 gmx_cfg.s.en = 0; 250 cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); 251 return 0; 252} 253 254/** 255 * Poll for link status change. 256 */ 257void cvm_oct_common_poll(struct ifnet *ifp) 258{ 259 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 260 cvmx_helper_link_info_t link_info; 261 262 /* 263 * If this is a simulation, do nothing. 264 */ 265 if (octeon_is_simulation()) 266 return; 267 268 /* 269 * If there is a device-specific poll method, use it. 270 */ 271 if (priv->poll != NULL) { 272 priv->poll(ifp); 273 return; 274 } 275 276 /* 277 * If an MII bus is attached, don't use the Simple Executive's link 278 * state routines. 279 */ 280 if (priv->miibus != NULL) 281 return; 282 283 /* 284 * Use the Simple Executive's link state routines. 285 */ 286 link_info = cvmx_helper_link_get(priv->port); 287 if (link_info.u64 == priv->link_info) 288 return; 289 290 link_info = cvmx_helper_link_autoconf(priv->port); 291 priv->link_info = link_info.u64; 292 priv->need_link_update = 1; 293} 294 295 296/** 297 * Per network device initialization 298 * 299 * @param dev Device to initialize 300 * @return Zero on success 301 */ 302int cvm_oct_common_init(struct ifnet *ifp) 303{
|
271 char mac[6] = { 272 cvmx_sysinfo_get()->mac_addr_base[0], 273 cvmx_sysinfo_get()->mac_addr_base[1], 274 cvmx_sysinfo_get()->mac_addr_base[2], 275 cvmx_sysinfo_get()->mac_addr_base[3], 276 cvmx_sysinfo_get()->mac_addr_base[4], 277 cvmx_sysinfo_get()->mac_addr_base[5] };
| 304 uint8_t mac[6];
|
278 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 279
| 305 cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; 306
|
280 mac[5] += cvm_oct_mac_addr_offset++;
| 307 if (cvm_assign_mac_address(NULL, mac) != 0) 308 return ENXIO;
|
281 282 ifp->if_mtu = ETHERMTU; 283 284 cvm_oct_mdio_setup_device(ifp); 285 286 cvm_oct_common_set_mac_address(ifp, mac); 287 cvm_oct_common_change_mtu(ifp, ifp->if_mtu); 288 289 /* 290 * Do any last-minute board-specific initialization. 291 */ 292 switch (cvmx_sysinfo_get()->board_type) { 293#if defined(OCTEON_VENDOR_LANNER) 294 case CVMX_BOARD_TYPE_CUST_LANNER_MR320: 295 case CVMX_BOARD_TYPE_CUST_LANNER_MR321X: 296 if (priv->phy_id == 16) 297 cvm_oct_mv88e61xx_setup_device(ifp); 298 break; 299#endif 300 default: 301 break; 302 } 303 304 device_attach(priv->dev); 305 306 return 0; 307} 308 309void cvm_oct_common_uninit(struct ifnet *ifp) 310{ 311 /* Currently nothing to do */ 312} 313
| 309 310 ifp->if_mtu = ETHERMTU; 311 312 cvm_oct_mdio_setup_device(ifp); 313 314 cvm_oct_common_set_mac_address(ifp, mac); 315 cvm_oct_common_change_mtu(ifp, ifp->if_mtu); 316 317 /* 318 * Do any last-minute board-specific initialization. 319 */ 320 switch (cvmx_sysinfo_get()->board_type) { 321#if defined(OCTEON_VENDOR_LANNER) 322 case CVMX_BOARD_TYPE_CUST_LANNER_MR320: 323 case CVMX_BOARD_TYPE_CUST_LANNER_MR321X: 324 if (priv->phy_id == 16) 325 cvm_oct_mv88e61xx_setup_device(ifp); 326 break; 327#endif 328 default: 329 break; 330 } 331 332 device_attach(priv->dev); 333 334 return 0; 335} 336 337void cvm_oct_common_uninit(struct ifnet *ifp) 338{ 339 /* Currently nothing to do */ 340} 341
|