if_cs.c (179507) | if_cs.c (179532) |
---|---|
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 179507 2008-06-03 05:47:28Z imp $"); | 30__FBSDID("$FreeBSD: head/sys/dev/cs/if_cs.c 179532 2008-06-04 06:07:13Z 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/* --- 75 unchanged lines hidden (view full) --- 114SYSCTL_INT(_hw_cs, OID_AUTO, ignore_checksum_failure, CTLFLAG_RW, 115 &cs_ignore_cksum_failure, 0, 116 "ignore checksum errors in cs card EEPROM"); 117 118static int cs_recv_delay = 570; 119TUNABLE_INT("hw.cs.recv_delay", &cs_recv_delay); 120SYSCTL_INT(_hw_cs, OID_AUTO, recv_delay, CTLFLAG_RW, &cs_recv_delay, 570, ""); 121 | 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/* --- 75 unchanged lines hidden (view full) --- 114SYSCTL_INT(_hw_cs, OID_AUTO, ignore_checksum_failure, CTLFLAG_RW, 115 &cs_ignore_cksum_failure, 0, 116 "ignore checksum errors in cs card EEPROM"); 117 118static int cs_recv_delay = 570; 119TUNABLE_INT("hw.cs.recv_delay", &cs_recv_delay); 120SYSCTL_INT(_hw_cs, OID_AUTO, recv_delay, CTLFLAG_RW, &cs_recv_delay, 570, ""); 121 |
122static int cs8900_eeint2irq[16] = { 123 10, 11, 12, 5, 255, 255, 255, 255, 124 255, 255, 255, 255, 255, 255, 255, 255 125}; 126 127static int cs8900_irq2eeint[16] = { 128 255, 255, 255, 255, 255, 3, 255, 255, 129 255, 0, 1, 2, 255, 255, 255, 255 130}; 131 |
|
122static int 123get_eeprom_data(struct cs_softc *sc, int off, int len, uint16_t *buffer) 124{ 125 int i; 126 127#ifdef CS_DEBUG 128 printf(CS_NAME":EEPROM data from %x for %x:\n", off, len); 129#endif --- 213 unchanged lines hidden (view full) --- 343 return (ENXIO); 344 345 rev_type = cs_readreg(sc, PRODUCT_ID_ADD); 346 chip_type = rev_type & ~REVISON_BITS; 347 chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A'; 348 349 sc->chip_type = chip_type; 350 | 132static int 133get_eeprom_data(struct cs_softc *sc, int off, int len, uint16_t *buffer) 134{ 135 int i; 136 137#ifdef CS_DEBUG 138 printf(CS_NAME":EEPROM data from %x for %x:\n", off, len); 139#endif --- 213 unchanged lines hidden (view full) --- 353 return (ENXIO); 354 355 rev_type = cs_readreg(sc, PRODUCT_ID_ADD); 356 chip_type = rev_type & ~REVISON_BITS; 357 chip_revision = ((rev_type & REVISON_BITS) >> 8) + 'A'; 358 359 sc->chip_type = chip_type; 360 |
351 if(chip_type==CS8900) { | 361 if (chip_type == CS8900) { |
352 pp_isaint = PP_CS8900_ISAINT; 353 pp_isadma = PP_CS8900_ISADMA; 354 sc->send_cmd = TX_CS8900_AFTER_ALL; 355 } else { 356 pp_isaint = PP_CS8920_ISAINT; 357 pp_isadma = PP_CS8920_ISADMA; 358 sc->send_cmd = TX_CS8920_AFTER_ALL; 359 } 360 361 /* 362 * Clear some fields so that fail of EEPROM will left them clean 363 */ 364 sc->auto_neg_cnf = 0; 365 sc->adapter_cnf = 0; 366 sc->isa_config = 0; 367 368 /* | 362 pp_isaint = PP_CS8900_ISAINT; 363 pp_isadma = PP_CS8900_ISADMA; 364 sc->send_cmd = TX_CS8900_AFTER_ALL; 365 } else { 366 pp_isaint = PP_CS8920_ISAINT; 367 pp_isadma = PP_CS8920_ISADMA; 368 sc->send_cmd = TX_CS8920_AFTER_ALL; 369 } 370 371 /* 372 * Clear some fields so that fail of EEPROM will left them clean 373 */ 374 sc->auto_neg_cnf = 0; 375 sc->adapter_cnf = 0; 376 sc->isa_config = 0; 377 378 /* |
369 * If no interrupt specified (or "?"), use what the board tells us. | 379 * If no interrupt specified, use what the board tells us. |
370 */ 371 error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, &junk); 372 373 /* 374 * Get data from EEPROM 375 */ 376 if((cs_readreg(sc, PP_SelfST) & EEPROM_PRESENT) == 0) { 377 device_printf(dev, "No EEPROM, assuming defaults.\n"); | 380 */ 381 error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, &junk); 382 383 /* 384 * Get data from EEPROM 385 */ 386 if((cs_readreg(sc, PP_SelfST) & EEPROM_PRESENT) == 0) { 387 device_printf(dev, "No EEPROM, assuming defaults.\n"); |
388 } else if (get_eeprom_data(sc,START_EEPROM_DATA,CHKSUM_LEN, eeprom_buff)<0) { 389 device_printf(dev, "EEPROM read failed, assuming defaults.\n"); 390 } else if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN, eeprom_buff)<0) { 391 device_printf(dev, "EEPROM cheksum bad, assuming defaults.\n"); |
|
378 } else { | 392 } else { |
379 if (get_eeprom_data(sc,START_EEPROM_DATA,CHKSUM_LEN, eeprom_buff)<0) { 380 device_printf(dev, "EEPROM read failed, " 381 "assuming defaults.\n"); 382 } else { 383 if (get_eeprom_cksum(START_EEPROM_DATA,CHKSUM_LEN, eeprom_buff)<0) { 384 device_printf(dev, "EEPROM cheksum bad, " 385 "assuming defaults.\n"); | 393 sc->auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2]; 394 sc->adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2]; 395 sc->isa_config = eeprom_buff[ISA_CNF_OFFSET/2]; 396 for (i=0; i<ETHER_ADDR_LEN/2; i++) { 397 sc->enaddr[i*2] = eeprom_buff[i]; 398 sc->enaddr[i*2+1] = eeprom_buff[i] >> 8; 399 } 400 /* 401 * If no interrupt specified, use what the 402 * board tells us. 403 */ 404 if (error) { 405 irq = sc->isa_config & INT_NO_MASK; 406 error = 0; 407 if (chip_type == CS8900) { 408 irq = cs8900_eeint2irq[irq]; |
386 } else { | 409 } else { |
387 sc->auto_neg_cnf = 388 eeprom_buff[AUTO_NEG_CNF_OFFSET/2]; 389 sc->adapter_cnf = 390 eeprom_buff[ADAPTER_CNF_OFFSET/2]; 391 sc->isa_config = 392 eeprom_buff[ISA_CNF_OFFSET/2]; 393 394 for (i=0; i<ETHER_ADDR_LEN/2; i++) { 395 sc->enaddr[i*2]= 396 eeprom_buff[i]; 397 sc->enaddr[i*2+1]= 398 eeprom_buff[i] >> 8; 399 } 400 401 /* 402 * If no interrupt specified, 403 * use what the board tells us. 404 */ 405 if (error) { 406 irq = sc->isa_config & INT_NO_MASK; 407 error = 0; 408 if (chip_type==CS8900) { 409 switch(irq) { 410 case 0: 411 irq=10; 412 break; 413 case 1: 414 irq=11; 415 break; 416 case 2: 417 irq=12; 418 break; 419 case 3: 420 irq=5; 421 break; 422 default: 423 device_printf(dev, "invalid irq in EEPROM.\n"); 424 error=EINVAL; 425 } 426 } else { 427 if (irq>CS8920_NO_INTS) { 428 device_printf(dev, "invalid irq in EEPROM.\n"); 429 error=EINVAL; 430 } 431 } 432 if (!error) 433 bus_set_resource(dev, SYS_RES_IRQ, 0, 434 irq, 1); 435 } | 410 if (irq > CS8920_NO_INTS) 411 irq = 255; |
436 } | 412 } |
413 if (irq == 255) { 414 device_printf(dev, "invalid irq in EEPROM.\n"); 415 error = EINVAL; 416 } 417 if (!error) 418 bus_set_resource(dev, SYS_RES_IRQ, 0, 419 irq, 1); |
|
437 } 438 } 439 | 420 } 421 } 422 |
440 if (!error) { | 423 if (!error && !(sc->flags & CS_NO_IRQ)) { |
441 if (chip_type == CS8900) { | 424 if (chip_type == CS8900) { |
442 switch(irq) { 443 case 5: 444 irq = 3; 445 break; 446 case 10: 447 irq = 0; 448 break; 449 case 11: 450 irq = 1; 451 break; 452 case 12: 453 irq = 2; 454 break; 455 default: 456 error = EINVAL; 457 break; 458 } | 425 if (irq >= 0 || irq < 16) 426 irq = cs8900_irq2eeint[irq]; 427 else 428 irq = 255; |
459 } else { | 429 } else { |
460 if (irq > CS8920_NO_INTS && !(sc->flags & CS_NO_IRQ)) 461 error = EINVAL; | 430 if (irq > CS8920_NO_INTS) 431 irq = 255; |
462 } | 432 } |
433 if (irq == 255) 434 error = EINVAL; |
|
463 } 464 465 if (error) { 466 device_printf(dev, "Unknown or invalid irq\n"); 467 return (error); 468 } 469 470 if (!(sc->flags & CS_NO_IRQ)) --- 7 unchanged lines hidden (view full) --- 478 else { 479 device_printf(dev, "incorrect drq\n",); 480 return (0); 481 } 482 */ 483 484 if (bootverbose) 485 device_printf(dev, "CS89%c0%s rev %c media%s%s%s\n", | 435 } 436 437 if (error) { 438 device_printf(dev, "Unknown or invalid irq\n"); 439 return (error); 440 } 441 442 if (!(sc->flags & CS_NO_IRQ)) --- 7 unchanged lines hidden (view full) --- 450 else { 451 device_printf(dev, "incorrect drq\n",); 452 return (0); 453 } 454 */ 455 456 if (bootverbose) 457 device_printf(dev, "CS89%c0%s rev %c media%s%s%s\n", |
486 chip_type==CS8900 ? '0' : '2', 487 chip_type==CS8920M ? "M" : "", | 458 chip_type == CS8900 ? '0' : '2', 459 chip_type == CS8920M ? "M" : "", |
488 chip_revision, 489 (sc->adapter_cnf & A_CNF_10B_T) ? " TP" : "", 490 (sc->adapter_cnf & A_CNF_AUI) ? " AUI" : "", 491 (sc->adapter_cnf & A_CNF_10B_2) ? " BNC" : ""); 492 493 if ((sc->adapter_cnf & A_CNF_EXTND_10B_2) && 494 (sc->adapter_cnf & A_CNF_LOW_RX_SQUELCH)) 495 sc->line_ctl = LOW_RX_SQUELCH; --- 760 unchanged lines hidden (view full) --- 1256 ifmr->ifm_active |= IFM_10_5; 1257 } 1258 } 1259} 1260 1261static int 1262cs_mediaset(struct cs_softc *sc, int media) 1263{ | 460 chip_revision, 461 (sc->adapter_cnf & A_CNF_10B_T) ? " TP" : "", 462 (sc->adapter_cnf & A_CNF_AUI) ? " AUI" : "", 463 (sc->adapter_cnf & A_CNF_10B_2) ? " BNC" : ""); 464 465 if ((sc->adapter_cnf & A_CNF_EXTND_10B_2) && 466 (sc->adapter_cnf & A_CNF_LOW_RX_SQUELCH)) 467 sc->line_ctl = LOW_RX_SQUELCH; --- 760 unchanged lines hidden (view full) --- 1228 ifmr->ifm_active |= IFM_10_5; 1229 } 1230 } 1231} 1232 1233static int 1234cs_mediaset(struct cs_softc *sc, int media) 1235{ |
1264 int error; | 1236 int error = 0; |
1265 1266 /* Stop the receiver & transmitter */ 1267 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) & 1268 ~(SERIAL_RX_ON | SERIAL_TX_ON)); 1269 1270#ifdef CS_DEBUG 1271 device_printf(sc->dev, "%s media=%x\n", __func__, media); 1272#endif 1273 1274 switch (IFM_SUBTYPE(media)) { 1275 default: 1276 case IFM_AUTO: 1277 if ((error=enable_tp(sc))==0) 1278 error = cs_duplex_auto(sc); 1279 else if ((error=enable_bnc(sc)) != 0) 1280 error = enable_aui(sc); 1281 break; 1282 case IFM_10_T: | 1237 1238 /* Stop the receiver & transmitter */ 1239 cs_writereg(sc, PP_LineCTL, cs_readreg(sc, PP_LineCTL) & 1240 ~(SERIAL_RX_ON | SERIAL_TX_ON)); 1241 1242#ifdef CS_DEBUG 1243 device_printf(sc->dev, "%s media=%x\n", __func__, media); 1244#endif 1245 1246 switch (IFM_SUBTYPE(media)) { 1247 default: 1248 case IFM_AUTO: 1249 if ((error=enable_tp(sc))==0) 1250 error = cs_duplex_auto(sc); 1251 else if ((error=enable_bnc(sc)) != 0) 1252 error = enable_aui(sc); 1253 break; 1254 case IFM_10_T: |
1283 if ((error=enable_tp(sc)) != 0) 1284 break; | 1255 enable_tp(sc); |
1285 if (media & IFM_FDX) 1286 cs_duplex_full(sc); 1287 else if (media & IFM_HDX) 1288 cs_duplex_half(sc); 1289 else 1290 error = cs_duplex_auto(sc); 1291 break; 1292 case IFM_10_2: --- 15 unchanged lines hidden --- | 1256 if (media & IFM_FDX) 1257 cs_duplex_full(sc); 1258 else if (media & IFM_HDX) 1259 cs_duplex_half(sc); 1260 else 1261 error = cs_duplex_auto(sc); 1262 break; 1263 case IFM_10_2: --- 15 unchanged lines hidden --- |