if_fxp.c (22975) | if_fxp.c (23964) |
---|---|
1/* 2 * Copyright (c) 1995, David Greenman 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * | 1/* 2 * Copyright (c) 1995, David Greenman 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * |
27 * $Id$ | 27 * $Id: if_fxp.c,v 1.29 1997/02/22 09:44:05 peter Exp $ |
28 */ 29 30/* 31 * Intel EtherExpress Pro/100B PCI Fast Ethernet driver 32 */ 33 34#include "bpfilter.h" 35 --- 47 unchanged lines hidden (view full) --- 83 struct fxp_cb_tx *cbl_base; /* base of TxCB list */ 84 struct fxp_cb_tx *cbl_first; /* first active TxCB in list */ 85 struct fxp_cb_tx *cbl_last; /* last active TxCB in list */ 86 struct mbuf *rfa_headm; /* first mbuf in receive frame area */ 87 struct mbuf *rfa_tailm; /* last mbuf in receive frame area */ 88 struct fxp_stats *fxp_stats; /* Pointer to interface stats */ 89 int tx_queued; /* # of active TxCB's */ 90 int promisc_mode; /* promiscuous mode enabled */ | 28 */ 29 30/* 31 * Intel EtherExpress Pro/100B PCI Fast Ethernet driver 32 */ 33 34#include "bpfilter.h" 35 --- 47 unchanged lines hidden (view full) --- 83 struct fxp_cb_tx *cbl_base; /* base of TxCB list */ 84 struct fxp_cb_tx *cbl_first; /* first active TxCB in list */ 85 struct fxp_cb_tx *cbl_last; /* last active TxCB in list */ 86 struct mbuf *rfa_headm; /* first mbuf in receive frame area */ 87 struct mbuf *rfa_tailm; /* last mbuf in receive frame area */ 88 struct fxp_stats *fxp_stats; /* Pointer to interface stats */ 89 int tx_queued; /* # of active TxCB's */ 90 int promisc_mode; /* promiscuous mode enabled */ |
91 int phy_primary_addr; /* address of primary PHY */ 92 int phy_primary_device; /* device type of primary PHY */ 93 int phy_10Mbps_only; /* PHY is 10Mbps-only device */ |
|
91}; 92 93static u_long fxp_count; 94 95/* 96 * Template for default configuration parameters. 97 * See struct fxp_cb_config for the bit definitions. 98 */ --- 30 unchanged lines hidden (view full) --- 129static char *fxp_probe __P((pcici_t, pcidi_t)); 130static void fxp_attach __P((pcici_t, int)); 131static void fxp_intr __P((void *)); 132static void fxp_start __P((struct ifnet *)); 133static int fxp_ioctl __P((struct ifnet *, int, caddr_t)); 134static void fxp_init __P((void *)); 135static void fxp_stop __P((struct fxp_softc *)); 136static void fxp_watchdog __P((struct ifnet *)); | 94}; 95 96static u_long fxp_count; 97 98/* 99 * Template for default configuration parameters. 100 * See struct fxp_cb_config for the bit definitions. 101 */ --- 30 unchanged lines hidden (view full) --- 132static char *fxp_probe __P((pcici_t, pcidi_t)); 133static void fxp_attach __P((pcici_t, int)); 134static void fxp_intr __P((void *)); 135static void fxp_start __P((struct ifnet *)); 136static int fxp_ioctl __P((struct ifnet *, int, caddr_t)); 137static void fxp_init __P((void *)); 138static void fxp_stop __P((struct fxp_softc *)); 139static void fxp_watchdog __P((struct ifnet *)); |
137static void fxp_get_macaddr __P((struct fxp_softc *)); | |
138static int fxp_add_rfabuf __P((struct fxp_softc *, struct mbuf *)); 139static void fxp_shutdown __P((int, void *)); | 140static int fxp_add_rfabuf __P((struct fxp_softc *, struct mbuf *)); 141static void fxp_shutdown __P((int, void *)); |
142static int fxp_mdi_read __P((struct fxp_csr *, int, int)); 143static void fxp_mdi_write __P((struct fxp_csr *, int, int, int)); 144static void fxp_read_eeprom __P((struct fxp_csr *, u_short *, int, int)); |
|
140 | 145 |
146 |
|
141timeout_t fxp_stats_update; 142 143static struct pci_device fxp_device = { 144 "fxp", 145 fxp_probe, 146 fxp_attach, 147 &fxp_count, 148 NULL --- 54 unchanged lines hidden (view full) --- 203 */ 204static char * 205fxp_probe(config_id, device_id) 206 pcici_t config_id; 207 pcidi_t device_id; 208{ 209 if (((device_id & 0xffff) == FXP_VENDORID_INTEL) && 210 ((device_id >> 16) & 0xffff) == FXP_DEVICEID_i82557) | 147timeout_t fxp_stats_update; 148 149static struct pci_device fxp_device = { 150 "fxp", 151 fxp_probe, 152 fxp_attach, 153 &fxp_count, 154 NULL --- 54 unchanged lines hidden (view full) --- 209 */ 210static char * 211fxp_probe(config_id, device_id) 212 pcici_t config_id; 213 pcidi_t device_id; 214{ 215 if (((device_id & 0xffff) == FXP_VENDORID_INTEL) && 216 ((device_id >> 16) & 0xffff) == FXP_DEVICEID_i82557) |
211 return ("Intel EtherExpress Pro/100B Fast Ethernet"); | 217 return ("Intel EtherExpress Pro 10/100B Ethernet"); |
212 213 return NULL; 214} 215 216/* 217 * Allocate data structures and attach the device. 218 */ 219static void 220fxp_attach(config_id, unit) 221 pcici_t config_id; 222 int unit; 223{ 224 struct fxp_softc *sc; 225 struct ifnet *ifp; 226 vm_offset_t pbase; 227 int s, i; | 218 219 return NULL; 220} 221 222/* 223 * Allocate data structures and attach the device. 224 */ 225static void 226fxp_attach(config_id, unit) 227 pcici_t config_id; 228 int unit; 229{ 230 struct fxp_softc *sc; 231 struct ifnet *ifp; 232 vm_offset_t pbase; 233 int s, i; |
234 u_short data; |
|
228 229 sc = malloc(sizeof(struct fxp_softc), M_DEVBUF, M_NOWAIT); 230 if (sc == NULL) 231 return; 232 bzero(sc, sizeof(struct fxp_softc)); 233 234 s = splimp(); 235 --- 34 unchanged lines hidden (view full) --- 270 * Pre-allocate our receive buffers. 271 */ 272 for (i = 0; i < FXP_NRFABUFS; i++) { 273 if (fxp_add_rfabuf(sc, NULL) != 0) { 274 goto malloc_fail; 275 } 276 } 277 | 235 236 sc = malloc(sizeof(struct fxp_softc), M_DEVBUF, M_NOWAIT); 237 if (sc == NULL) 238 return; 239 bzero(sc, sizeof(struct fxp_softc)); 240 241 s = splimp(); 242 --- 34 unchanged lines hidden (view full) --- 277 * Pre-allocate our receive buffers. 278 */ 279 for (i = 0; i < FXP_NRFABUFS; i++) { 280 if (fxp_add_rfabuf(sc, NULL) != 0) { 281 goto malloc_fail; 282 } 283 } 284 |
285 /* 286 * Get info about the primary PHY 287 */ 288 fxp_read_eeprom(sc->csr, (u_short *)&data, 6, 1); 289 sc->phy_primary_addr = data & 0xff; 290 sc->phy_primary_device = (data >> 8) & 0x3f; 291 sc->phy_10Mbps_only = data >> 15; 292 |
|
278 ifp = &sc->arpcom.ac_if; 279 ifp->if_softc = sc; 280 ifp->if_unit = unit; 281 ifp->if_name = "fxp"; 282 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 283 ifp->if_ioctl = fxp_ioctl; 284 ifp->if_output = ether_output; 285 ifp->if_start = fxp_start; 286 ifp->if_watchdog = fxp_watchdog; 287 ifp->if_baudrate = 100000000; 288 ifp->if_init = fxp_init; 289 | 293 ifp = &sc->arpcom.ac_if; 294 ifp->if_softc = sc; 295 ifp->if_unit = unit; 296 ifp->if_name = "fxp"; 297 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 298 ifp->if_ioctl = fxp_ioctl; 299 ifp->if_output = ether_output; 300 ifp->if_start = fxp_start; 301 ifp->if_watchdog = fxp_watchdog; 302 ifp->if_baudrate = 100000000; 303 ifp->if_init = fxp_init; 304 |
290 fxp_get_macaddr(sc); 291 printf("fxp%d: Ethernet address %6D\n", unit, 292 sc->arpcom.ac_enaddr, ":"); | 305 /* 306 * Read MAC address 307 */ 308 fxp_read_eeprom(sc->csr, (u_short *)sc->arpcom.ac_enaddr, 0, 3); 309 printf("fxp%d: Ethernet address %6D", unit, sc->arpcom.ac_enaddr, ":"); 310 if (sc->phy_10Mbps_only) 311 printf(", 10Mbps"); 312 printf("\n"); |
293 294 /* 295 * Attach the interface. 296 */ 297 if_attach(ifp); 298 ether_ifattach(ifp); 299 300#if NBPFILTER > 0 --- 22 unchanged lines hidden (view full) --- 323 m_freem(sc->rfa_headm); 324fail: 325 if (sc) 326 free(sc, M_DEVBUF); 327 splx(s); 328} 329 330/* | 313 314 /* 315 * Attach the interface. 316 */ 317 if_attach(ifp); 318 ether_ifattach(ifp); 319 320#if NBPFILTER > 0 --- 22 unchanged lines hidden (view full) --- 343 m_freem(sc->rfa_headm); 344fail: 345 if (sc) 346 free(sc, M_DEVBUF); 347 splx(s); 348} 349 350/* |
331 * Read station (MAC) address from serial EEPROM. Basically, you 332 * manually shift in the read opcode (one bit at a time) and then 333 * shift in the address, and then you shift out the data (all of 334 * this one bit at a time). The word size is 16 bits, so you have 335 * to provide the address for every 16 bits of data. The MAC address 336 * is in the first 3 words (6 bytes total). | 351 * Read from the serial EEPROM. Basically, you manually shift in 352 * the read opcode (one bit at a time) and then shift in the address, 353 * and then you shift out the data (all of this one bit at a time). 354 * The word size is 16 bits, so you have to provide the address for 355 * every 16 bits of data. |
337 */ 338static void | 356 */ 357static void |
339fxp_get_macaddr(sc) 340 struct fxp_softc *sc; 341{ | 358fxp_read_eeprom(csr, data, offset, words) |
342 struct fxp_csr *csr; | 359 struct fxp_csr *csr; |
343 u_short reg, *data; | 360 u_short *data; 361 int offset; 362 int words; 363{ 364 u_short reg; |
344 int i, x; 345 | 365 int i, x; 366 |
346 csr = sc->csr; 347 data = (u_short *)sc->arpcom.ac_enaddr; 348 349 for (i = 0; i < 3; i++) { | 367 for (i = 0; i < words; i++) { |
350 csr->eeprom_control = FXP_EEPROM_EECS; 351 /* 352 * Shift in read opcode. 353 */ 354 for (x = 3; x > 0; x--) { 355 if (FXP_EEPROM_OPC_READ & (1 << (x - 1))) { 356 reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI; 357 } else { --- 4 unchanged lines hidden (view full) --- 362 DELAY(1); 363 csr->eeprom_control = reg; 364 DELAY(1); 365 } 366 /* 367 * Shift in address. 368 */ 369 for (x = 6; x > 0; x--) { | 368 csr->eeprom_control = FXP_EEPROM_EECS; 369 /* 370 * Shift in read opcode. 371 */ 372 for (x = 3; x > 0; x--) { 373 if (FXP_EEPROM_OPC_READ & (1 << (x - 1))) { 374 reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI; 375 } else { --- 4 unchanged lines hidden (view full) --- 380 DELAY(1); 381 csr->eeprom_control = reg; 382 DELAY(1); 383 } 384 /* 385 * Shift in address. 386 */ 387 for (x = 6; x > 0; x--) { |
370 if (i & (1 << (x - 1))) { | 388 if ((i + offset) & (1 << (x - 1))) { |
371 reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI; 372 } else { 373 reg = FXP_EEPROM_EECS; 374 } 375 csr->eeprom_control = reg; 376 csr->eeprom_control = reg | FXP_EEPROM_EESK; 377 DELAY(1); 378 csr->eeprom_control = reg; --- 480 unchanged lines hidden (view full) --- 859 cbp->tx_dma_bytecount = 0; /* (no) tx DMA max */ 860 cbp->dma_bce = 0; /* (disable) dma max counters */ 861 cbp->late_scb = 0; /* (don't) defer SCB update */ 862 cbp->tno_int = 0; /* (disable) tx not okay interrupt */ 863 cbp->ci_int = 0; /* interrupt on CU not active */ 864 cbp->save_bf = prm; /* save bad frames */ 865 cbp->disc_short_rx = !prm; /* discard short packets */ 866 cbp->underrun_retry = 1; /* retry mode (1) on DMA underrun */ | 389 reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI; 390 } else { 391 reg = FXP_EEPROM_EECS; 392 } 393 csr->eeprom_control = reg; 394 csr->eeprom_control = reg | FXP_EEPROM_EESK; 395 DELAY(1); 396 csr->eeprom_control = reg; --- 480 unchanged lines hidden (view full) --- 877 cbp->tx_dma_bytecount = 0; /* (no) tx DMA max */ 878 cbp->dma_bce = 0; /* (disable) dma max counters */ 879 cbp->late_scb = 0; /* (don't) defer SCB update */ 880 cbp->tno_int = 0; /* (disable) tx not okay interrupt */ 881 cbp->ci_int = 0; /* interrupt on CU not active */ 882 cbp->save_bf = prm; /* save bad frames */ 883 cbp->disc_short_rx = !prm; /* discard short packets */ 884 cbp->underrun_retry = 1; /* retry mode (1) on DMA underrun */ |
867 cbp->mediatype = 1; /* (MII) interface mode */ | 885 cbp->mediatype = !sc->phy_10Mbps_only; /* interface mode */ |
868 cbp->nsai = 1; /* (don't) disable source addr insert */ 869 cbp->preamble_length = 2; /* (7 byte) preamble */ 870 cbp->loopback = 0; /* (don't) loopback */ 871 cbp->linear_priority = 0; /* (normal CSMA/CD operation) */ 872 cbp->linear_pri_mode = 0; /* (wait after xmit only) */ 873 cbp->interfrm_spacing = 6; /* (96 bits of) interframe spacing */ 874 cbp->promiscuous = prm; /* promiscuous mode */ 875 cbp->bcast_disable = 0; /* (don't) disable broadcasts */ --- 60 unchanged lines hidden (view full) --- 936 937 /* 938 * Initialize receiver buffer area - RFA. 939 */ 940 fxp_scb_wait(csr); 941 csr->scb_general = vtophys(sc->rfa_headm->m_ext.ext_buf); 942 csr->scb_command = FXP_SCB_COMMAND_RU_START; 943 | 886 cbp->nsai = 1; /* (don't) disable source addr insert */ 887 cbp->preamble_length = 2; /* (7 byte) preamble */ 888 cbp->loopback = 0; /* (don't) loopback */ 889 cbp->linear_priority = 0; /* (normal CSMA/CD operation) */ 890 cbp->linear_pri_mode = 0; /* (wait after xmit only) */ 891 cbp->interfrm_spacing = 6; /* (96 bits of) interframe spacing */ 892 cbp->promiscuous = prm; /* promiscuous mode */ 893 cbp->bcast_disable = 0; /* (don't) disable broadcasts */ --- 60 unchanged lines hidden (view full) --- 954 955 /* 956 * Initialize receiver buffer area - RFA. 957 */ 958 fxp_scb_wait(csr); 959 csr->scb_general = vtophys(sc->rfa_headm->m_ext.ext_buf); 960 csr->scb_command = FXP_SCB_COMMAND_RU_START; 961 |
962 /* 963 * Toggle a few bits in the DP83840 PHY. 964 */ 965 if (sc->phy_primary_device == FXP_PHY_DP83840) { 966 fxp_mdi_write(sc->csr, sc->phy_primary_addr, FXP_DP83840_PCR, 967 fxp_mdi_read(sc->csr, sc->phy_primary_addr, FXP_DP83840_PCR) | 968 FXP_DP83840_PCR_LED4_MODE | /* LED4 always indicates duplex */ 969 FXP_DP83840_PCR_F_CONNECT | /* force link disconnect bypass */ 970 FXP_DP83840_PCR_BIT10); /* XXX I have no idea */ 971 } 972 |
|
944 ifp->if_flags |= IFF_RUNNING; 945 ifp->if_flags &= ~IFF_OACTIVE; 946 splx(s); 947 948 /* 949 * Start stats updater. 950 */ 951 timeout(fxp_stats_update, sc, hz); --- 57 unchanged lines hidden (view full) --- 1009 sc->rfa_headm = m; 1010 } 1011 sc->rfa_tailm = m; 1012 1013 return (m == oldm); 1014} 1015 1016static int | 973 ifp->if_flags |= IFF_RUNNING; 974 ifp->if_flags &= ~IFF_OACTIVE; 975 splx(s); 976 977 /* 978 * Start stats updater. 979 */ 980 timeout(fxp_stats_update, sc, hz); --- 57 unchanged lines hidden (view full) --- 1038 sc->rfa_headm = m; 1039 } 1040 sc->rfa_tailm = m; 1041 1042 return (m == oldm); 1043} 1044 1045static int |
1046fxp_mdi_read(csr, phy, reg) 1047 struct fxp_csr *csr; 1048 int phy; 1049 int reg; 1050{ 1051 int count = 10000; 1052 1053 csr->mdi_control = (FXP_MDI_READ << 26) | (reg << 16) | (phy << 21); 1054 1055 while ((csr->mdi_control & 0x10000000) == 0 && count--) 1056 DELAY(1); 1057 1058 if (count <= 0) 1059 printf("fxp_mdi_read: timed out\n"); 1060 1061 return (csr->mdi_control & 0xffff); 1062} 1063 1064static void 1065fxp_mdi_write(csr, phy, reg, value) 1066 struct fxp_csr *csr; 1067 int phy; 1068 int reg; 1069 int value; 1070{ 1071 int count = 10000; 1072 1073 csr->mdi_control = (FXP_MDI_WRITE << 26) | (reg << 16) | (phy << 21) 1074 | (value & 0xffff); 1075 1076 while ((csr->mdi_control & 10000000) == 0 && count--) 1077 DELAY(1); 1078 1079 if (count <= 0) 1080 printf("fxp_mdi_write: timed out\n"); 1081} 1082 1083static int |
|
1017fxp_ioctl(ifp, command, data) 1018 struct ifnet *ifp; 1019 int command; 1020 caddr_t data; 1021{ 1022 struct ifaddr *ifa = (struct ifaddr *) data; 1023 struct fxp_softc *sc = ifp->if_softc; 1024 struct ifreq *ifr = (struct ifreq *) data; --- 44 unchanged lines hidden --- | 1084fxp_ioctl(ifp, command, data) 1085 struct ifnet *ifp; 1086 int command; 1087 caddr_t data; 1088{ 1089 struct ifaddr *ifa = (struct ifaddr *) data; 1090 struct fxp_softc *sc = ifp->if_softc; 1091 struct ifreq *ifr = (struct ifreq *) data; --- 44 unchanged lines hidden --- |