if_cs.c (140927) | if_cs.c (140928) |
---|---|
1/*- 2 * Copyright (c) 1997,1998 Maxim Bolotin and Oleg Sharoiko. 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 --- 13 unchanged lines hidden (view full) --- 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 */ 28 29#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1997,1998 Maxim Bolotin and Oleg Sharoiko. 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 --- 13 unchanged lines hidden (view full) --- 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 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/dev/cs/if_cs.c 140927 2005-01-28 06:45:42Z imp $"); | 30__FBSDID("$FreeBSD: head/sys/dev/cs/if_cs.c 140928 2005-01-28 06:50:59Z imp $"); |
31 32/* 33 * 34 * Device driver for Crystal Semiconductor CS8920 based ethernet 35 * adapters. By Maxim Bolotin and Oleg Sharoiko, 27-April-1997 36 */ 37 38/* --- 125 unchanged lines hidden (view full) --- 164 } 165 return (-1); 166} 167 168static int 169wait_eeprom_ready(struct cs_softc *sc) 170{ 171 DELAY(30000); /* XXX should we do some checks here ? */ | 31 32/* 33 * 34 * Device driver for Crystal Semiconductor CS8920 based ethernet 35 * adapters. By Maxim Bolotin and Oleg Sharoiko, 27-April-1997 36 */ 37 38/* --- 125 unchanged lines hidden (view full) --- 164 } 165 return (-1); 166} 167 168static int 169wait_eeprom_ready(struct cs_softc *sc) 170{ 171 DELAY(30000); /* XXX should we do some checks here ? */ |
172 return 0; | 172 return (0); |
173} 174 175static void 176control_dc_dc(struct cs_softc *sc, int on_not_off) 177{ 178 unsigned int self_control = HCB1_ENBL; 179 180 if (((sc->adapter_cnf & A_CNF_DC_DC_POLARITY)!=0) ^ on_not_off) --- 18 unchanged lines hidden (view full) --- 199 if_printf(&sc->arpcom.ac_if, 200 "full/half duplex auto negotiation timeout\n"); 201 error = ETIMEDOUT; 202 break; 203 } 204 DELAY(1000); 205 } 206 DELAY(1000000); | 173} 174 175static void 176control_dc_dc(struct cs_softc *sc, int on_not_off) 177{ 178 unsigned int self_control = HCB1_ENBL; 179 180 if (((sc->adapter_cnf & A_CNF_DC_DC_POLARITY)!=0) ^ on_not_off) --- 18 unchanged lines hidden (view full) --- 199 if_printf(&sc->arpcom.ac_if, 200 "full/half duplex auto negotiation timeout\n"); 201 error = ETIMEDOUT; 202 break; 203 } 204 DELAY(1000); 205 } 206 DELAY(1000000); |
207 return error; | 207 return (error); |
208} 209 210static int 211enable_tp(struct cs_softc *sc) 212{ 213 214 cs_writereg(sc, PP_LineCTL, sc->line_ctl & ~AUI_ONLY); 215 control_dc_dc(sc, 0); 216 DELAY( 150000 ); 217 218 if ((cs_readreg(sc, PP_LineST) & LINK_OK)==0) { 219 if_printf(&sc->arpcom.ac_if, "failed to enable TP\n"); | 208} 209 210static int 211enable_tp(struct cs_softc *sc) 212{ 213 214 cs_writereg(sc, PP_LineCTL, sc->line_ctl & ~AUI_ONLY); 215 control_dc_dc(sc, 0); 216 DELAY( 150000 ); 217 218 if ((cs_readreg(sc, PP_LineST) & LINK_OK)==0) { 219 if_printf(&sc->arpcom.ac_if, "failed to enable TP\n"); |
220 return EINVAL; | 220 return (EINVAL); |
221 } 222 | 221 } 222 |
223 return 0; | 223 return (0); |
224} 225 226/* 227 * XXX This was rewritten from Linux driver without any tests. 228 */ 229static int 230send_test_pkt(struct cs_softc *sc) 231{ --- 14 unchanged lines hidden (view full) --- 246 cs_outw(sc, TX_CMD_PORT, sc->send_cmd); 247 cs_outw(sc, TX_LEN_PORT, sizeof(test_packet)); 248 249 /* Wait for chip to allocate memory */ 250 DELAY(50000); 251 if (!(cs_readreg(sc, PP_BusST) & READY_FOR_TX_NOW)) { 252 for (i = 0; i < ETHER_ADDR_LEN; i++) 253 sc->arpcom.ac_enaddr[i] = ether_address_backup[i]; | 224} 225 226/* 227 * XXX This was rewritten from Linux driver without any tests. 228 */ 229static int 230send_test_pkt(struct cs_softc *sc) 231{ --- 14 unchanged lines hidden (view full) --- 246 cs_outw(sc, TX_CMD_PORT, sc->send_cmd); 247 cs_outw(sc, TX_LEN_PORT, sizeof(test_packet)); 248 249 /* Wait for chip to allocate memory */ 250 DELAY(50000); 251 if (!(cs_readreg(sc, PP_BusST) & READY_FOR_TX_NOW)) { 252 for (i = 0; i < ETHER_ADDR_LEN; i++) 253 sc->arpcom.ac_enaddr[i] = ether_address_backup[i]; |
254 return 0; | 254 return (0); |
255 } 256 257 outsw(sc->nic_addr + TX_FRAME_PORT, test_packet, sizeof(test_packet)); 258 259 DELAY(30000); 260 261 for (i = 0; i < ETHER_ADDR_LEN; i++) 262 sc->arpcom.ac_enaddr[i] = ether_address_backup[i]; 263 if ((cs_readreg(sc, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) | 255 } 256 257 outsw(sc->nic_addr + TX_FRAME_PORT, test_packet, sizeof(test_packet)); 258 259 DELAY(30000); 260 261 for (i = 0; i < ETHER_ADDR_LEN; i++) 262 sc->arpcom.ac_enaddr[i] = ether_address_backup[i]; 263 if ((cs_readreg(sc, PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) |
264 return 1; 265 return 0; | 264 return (1); 265 return (0); |
266} 267 268/* 269 * XXX This was rewritten from Linux driver without any tests. 270 */ 271static int 272enable_aui(struct cs_softc *sc) 273{ 274 275 control_dc_dc(sc, 0); 276 cs_writereg(sc, PP_LineCTL, 277 (sc->line_ctl & ~AUTO_AUI_10BASET) | AUI_ONLY); 278 279 if (!send_test_pkt(sc)) { 280 if_printf(&sc->arpcom.ac_if, "failed to enable AUI\n"); | 266} 267 268/* 269 * XXX This was rewritten from Linux driver without any tests. 270 */ 271static int 272enable_aui(struct cs_softc *sc) 273{ 274 275 control_dc_dc(sc, 0); 276 cs_writereg(sc, PP_LineCTL, 277 (sc->line_ctl & ~AUTO_AUI_10BASET) | AUI_ONLY); 278 279 if (!send_test_pkt(sc)) { 280 if_printf(&sc->arpcom.ac_if, "failed to enable AUI\n"); |
281 return EINVAL; | 281 return (EINVAL); |
282 } | 282 } |
283 return 0; | 283 return (0); |
284} 285 286/* 287 * XXX This was rewritten from Linux driver without any tests. 288 */ 289static int 290enable_bnc(struct cs_softc *sc) 291{ 292 293 control_dc_dc(sc, 1); 294 cs_writereg(sc, PP_LineCTL, 295 (sc->line_ctl & ~AUTO_AUI_10BASET) | AUI_ONLY); 296 297 if (!send_test_pkt(sc)) { 298 if_printf(&sc->arpcom.ac_if, "failed to enable BNC\n"); | 284} 285 286/* 287 * XXX This was rewritten from Linux driver without any tests. 288 */ 289static int 290enable_bnc(struct cs_softc *sc) 291{ 292 293 control_dc_dc(sc, 1); 294 cs_writereg(sc, PP_LineCTL, 295 (sc->line_ctl & ~AUTO_AUI_10BASET) | AUI_ONLY); 296 297 if (!send_test_pkt(sc)) { 298 if_printf(&sc->arpcom.ac_if, "failed to enable BNC\n"); |
299 return EINVAL; | 299 return (EINVAL); |
300 } | 300 } |
301 return 0; | 301 return (0); |
302} 303 304int 305cs_cs89x0_probe(device_t dev) 306{ 307 int i; 308 int error; 309 u_long irq, junk; --- 87 unchanged lines hidden (view full) --- 397 } 398 399 /* 400 * If no interrupt specified, 401 * use what the board tells us. 402 */ 403 if (error) { 404 irq = sc->isa_config & INT_NO_MASK; | 302} 303 304int 305cs_cs89x0_probe(device_t dev) 306{ 307 int i; 308 int error; 309 u_long irq, junk; --- 87 unchanged lines hidden (view full) --- 397 } 398 399 /* 400 * If no interrupt specified, 401 * use what the board tells us. 402 */ 403 if (error) { 404 irq = sc->isa_config & INT_NO_MASK; |
405 error = 0; |
|
405 if (chip_type==CS8900) { 406 switch(irq) { 407 case 0: 408 irq=10; | 406 if (chip_type==CS8900) { 407 switch(irq) { 408 case 0: 409 irq=10; |
409 error=0; | |
410 break; 411 case 1: 412 irq=11; | 410 break; 411 case 1: 412 irq=11; |
413 error=0; | |
414 break; 415 case 2: 416 irq=12; | 413 break; 414 case 2: 415 irq=12; |
417 error=0; | |
418 break; 419 case 3: 420 irq=5; | 416 break; 417 case 3: 418 irq=5; |
421 error=0; | |
422 break; 423 default: 424 device_printf(dev, "invalid irq in EEPROM.\n"); 425 error=EINVAL; 426 } 427 } else { 428 if (irq>CS8920_NO_INTS) { 429 device_printf(dev, "invalid irq in EEPROM.\n"); 430 error=EINVAL; | 419 break; 420 default: 421 device_printf(dev, "invalid irq in EEPROM.\n"); 422 error=EINVAL; 423 } 424 } else { 425 if (irq>CS8920_NO_INTS) { 426 device_printf(dev, "invalid irq in EEPROM.\n"); 427 error=EINVAL; |
431 } else { 432 error=0; | |
433 } 434 } | 428 } 429 } |
435 | |
436 if (!error) 437 bus_set_resource(dev, SYS_RES_IRQ, 0, 438 irq, 1); 439 } 440 } 441 } 442 } 443 --- 32 unchanged lines hidden (view full) --- 476 477 /* 478 * Temporary disabled 479 * 480 if (drq>0) 481 cs_writereg(sc, pp_isadma, drq); 482 else { 483 device_printf(dev, "incorrect drq\n",); | 430 if (!error) 431 bus_set_resource(dev, SYS_RES_IRQ, 0, 432 irq, 1); 433 } 434 } 435 } 436 } 437 --- 32 unchanged lines hidden (view full) --- 470 471 /* 472 * Temporary disabled 473 * 474 if (drq>0) 475 cs_writereg(sc, pp_isadma, drq); 476 else { 477 device_printf(dev, "incorrect drq\n",); |
484 return 0; | 478 return (0); |
485 } 486 */ 487 488 if (bootverbose) 489 device_printf(dev, "CS89%c0%s rev %c media%s%s%s\n", 490 chip_type==CS8900 ? '0' : '2', 491 chip_type==CS8920M ? "M" : "", 492 chip_revision, 493 (sc->adapter_cnf & A_CNF_10B_T) ? " TP" : "", 494 (sc->adapter_cnf & A_CNF_AUI) ? " AUI" : "", 495 (sc->adapter_cnf & A_CNF_10B_2) ? " BNC" : ""); 496 497 if ((sc->adapter_cnf & A_CNF_EXTND_10B_2) && 498 (sc->adapter_cnf & A_CNF_LOW_RX_SQUELCH)) 499 sc->line_ctl = LOW_RX_SQUELCH; 500 else 501 sc->line_ctl = 0; 502 | 479 } 480 */ 481 482 if (bootverbose) 483 device_printf(dev, "CS89%c0%s rev %c media%s%s%s\n", 484 chip_type==CS8900 ? '0' : '2', 485 chip_type==CS8920M ? "M" : "", 486 chip_revision, 487 (sc->adapter_cnf & A_CNF_10B_T) ? " TP" : "", 488 (sc->adapter_cnf & A_CNF_AUI) ? " AUI" : "", 489 (sc->adapter_cnf & A_CNF_10B_2) ? " BNC" : ""); 490 491 if ((sc->adapter_cnf & A_CNF_EXTND_10B_2) && 492 (sc->adapter_cnf & A_CNF_LOW_RX_SQUELCH)) 493 sc->line_ctl = LOW_RX_SQUELCH; 494 else 495 sc->line_ctl = 0; 496 |
503 return 0; | 497 return (0); |
504} 505 506/* 507 * Allocate a port resource with the given resource id. 508 */ 509int cs_alloc_port(device_t dev, int rid, int size) 510{ 511 struct cs_softc *sc = device_get_softc(dev); 512 struct resource *res; 513 514 res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 515 0ul, ~0ul, size, RF_ACTIVE); | 498} 499 500/* 501 * Allocate a port resource with the given resource id. 502 */ 503int cs_alloc_port(device_t dev, int rid, int size) 504{ 505 struct cs_softc *sc = device_get_softc(dev); 506 struct resource *res; 507 508 res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 509 0ul, ~0ul, size, RF_ACTIVE); |
516 if (res) { 517 sc->port_rid = rid; 518 sc->port_res = res; 519 sc->port_used = size; 520 return (0); 521 } else { | 510 if (res == NULL) |
522 return (ENOENT); | 511 return (ENOENT); |
523 } | 512 sc->port_rid = rid; 513 sc->port_res = res; 514 sc->port_used = size; 515 return (0); |
524} 525 526/* 527 * Allocate a memory resource with the given resource id. 528 */ 529int cs_alloc_memory(device_t dev, int rid, int size) 530{ 531 struct cs_softc *sc = device_get_softc(dev); 532 struct resource *res; 533 534 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 535 0ul, ~0ul, size, RF_ACTIVE); | 516} 517 518/* 519 * Allocate a memory resource with the given resource id. 520 */ 521int cs_alloc_memory(device_t dev, int rid, int size) 522{ 523 struct cs_softc *sc = device_get_softc(dev); 524 struct resource *res; 525 526 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 527 0ul, ~0ul, size, RF_ACTIVE); |
536 if (res) { 537 sc->mem_rid = rid; 538 sc->mem_res = res; 539 sc->mem_used = size; 540 return (0); 541 } else { | 528 if (res == NULL) |
542 return (ENOENT); | 529 return (ENOENT); |
543 } | 530 sc->mem_rid = rid; 531 sc->mem_res = res; 532 sc->mem_used = size; 533 return (0); |
544} 545 546/* 547 * Allocate an irq resource with the given resource id. 548 */ 549int cs_alloc_irq(device_t dev, int rid, int flags) 550{ 551 struct cs_softc *sc = device_get_softc(dev); 552 struct resource *res; 553 554 res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 555 (RF_ACTIVE | flags)); | 534} 535 536/* 537 * Allocate an irq resource with the given resource id. 538 */ 539int cs_alloc_irq(device_t dev, int rid, int flags) 540{ 541 struct cs_softc *sc = device_get_softc(dev); 542 struct resource *res; 543 544 res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 545 (RF_ACTIVE | flags)); |
556 if (res) { 557 sc->irq_rid = rid; 558 sc->irq_res = res; 559 return (0); 560 } else { | 546 if (res == NULL) |
561 return (ENOENT); | 547 return (ENOENT); |
562 } | 548 sc->irq_rid = rid; 549 sc->irq_res = res; 550 return (0); |
563} 564 565/* 566 * Release all resources 567 */ 568void cs_release_resources(device_t dev) 569{ 570 struct cs_softc *sc = device_get_softc(dev); --- 235 unchanged lines hidden (view full) --- 806 status, length); 807#endif 808 809 if (!(status & RX_OK)) { 810#ifdef CS_DEBUG 811 if_printf(ifp, "bad pkt stat %x\n", status); 812#endif 813 ifp->if_ierrors++; | 551} 552 553/* 554 * Release all resources 555 */ 556void cs_release_resources(device_t dev) 557{ 558 struct cs_softc *sc = device_get_softc(dev); --- 235 unchanged lines hidden (view full) --- 794 status, length); 795#endif 796 797 if (!(status & RX_OK)) { 798#ifdef CS_DEBUG 799 if_printf(ifp, "bad pkt stat %x\n", status); 800#endif 801 ifp->if_ierrors++; |
814 return -1; | 802 return (-1); |
815 } 816 817 MGETHDR(m, M_DONTWAIT, MT_DATA); 818 if (m==NULL) | 803 } 804 805 MGETHDR(m, M_DONTWAIT, MT_DATA); 806 if (m==NULL) |
819 return -1; | 807 return (-1); |
820 821 if (length > MHLEN) { 822 MCLGET(m, M_DONTWAIT); 823 if (!(m->m_flags & M_EXT)) { 824 m_freem(m); | 808 809 if (length > MHLEN) { 810 MCLGET(m, M_DONTWAIT); 811 if (!(m->m_flags & M_EXT)) { 812 m_freem(m); |
825 return -1; | 813 return (-1); |
826 } 827 } 828 829 /* Initialize packet's header info */ 830 m->m_pkthdr.rcvif = ifp; 831 m->m_pkthdr.len = length; 832 m->m_len = length; 833 --- 14 unchanged lines hidden (view full) --- 848 (*ifp->if_input)(ifp, m); 849 ifp->if_ipackets++; 850 if (length == ETHER_MAX_LEN-ETHER_CRC_LEN) 851 DELAY(cs_recv_delay); 852 } else { 853 m_freem(m); 854 } 855 | 814 } 815 } 816 817 /* Initialize packet's header info */ 818 m->m_pkthdr.rcvif = ifp; 819 m->m_pkthdr.len = length; 820 m->m_len = length; 821 --- 14 unchanged lines hidden (view full) --- 836 (*ifp->if_input)(ifp, m); 837 ifp->if_ipackets++; 838 if (length == ETHER_MAX_LEN-ETHER_CRC_LEN) 839 DELAY(cs_recv_delay); 840 } else { 841 m_freem(m); 842 } 843 |
856 return 0; | 844 return (0); |
857} 858 859/* 860 * Handle interrupts 861 */ 862void 863csintr(void *arg) 864{ --- 286 unchanged lines hidden (view full) --- 1151 break; 1152 1153 default: 1154 error = ether_ioctl(ifp, command, data); 1155 break; 1156 } 1157 1158 (void) splx(s); | 845} 846 847/* 848 * Handle interrupts 849 */ 850void 851csintr(void *arg) 852{ --- 286 unchanged lines hidden (view full) --- 1139 break; 1140 1141 default: 1142 error = ether_ioctl(ifp, command, data); 1143 break; 1144 } 1145 1146 (void) splx(s); |
1159 return error; | 1147 return (error); |
1160} 1161 1162/* 1163 * Device timeout/watchdog routine. Entered if the device neglects to 1164 * generate an interrupt after a transmit has been started on it. 1165 */ 1166static void 1167cs_watchdog(struct ifnet *ifp) --- 12 unchanged lines hidden (view full) --- 1180 1181static int 1182cs_mediachange(struct ifnet *ifp) 1183{ 1184 struct cs_softc *sc = ifp->if_softc; 1185 struct ifmedia *ifm = &sc->media; 1186 1187 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) | 1148} 1149 1150/* 1151 * Device timeout/watchdog routine. Entered if the device neglects to 1152 * generate an interrupt after a transmit has been started on it. 1153 */ 1154static void 1155cs_watchdog(struct ifnet *ifp) --- 12 unchanged lines hidden (view full) --- 1168 1169static int 1170cs_mediachange(struct ifnet *ifp) 1171{ 1172 struct cs_softc *sc = ifp->if_softc; 1173 struct ifmedia *ifm = &sc->media; 1174 1175 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) |
1188 return EINVAL; | 1176 return (EINVAL); |
1189 | 1177 |
1190 return cs_mediaset(sc, ifm->ifm_media); | 1178 return (cs_mediaset(sc, ifm->ifm_media)); |
1191} 1192 1193static void 1194cs_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 1195{ 1196 int line_status; 1197 struct cs_softc *sc = ifp->if_softc; 1198 --- 63 unchanged lines hidden (view full) --- 1262 } 1263 1264 /* 1265 * Turn the transmitter & receiver back on 1266 */ 1267 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) | 1268 SERIAL_RX_ON | SERIAL_TX_ON); 1269 | 1179} 1180 1181static void 1182cs_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 1183{ 1184 int line_status; 1185 struct cs_softc *sc = ifp->if_softc; 1186 --- 63 unchanged lines hidden (view full) --- 1250 } 1251 1252 /* 1253 * Turn the transmitter & receiver back on 1254 */ 1255 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) | 1256 SERIAL_RX_ON | SERIAL_TX_ON); 1257 |
1270 return error; | 1258 return (error); |
1271} | 1259} |