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 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 |
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 |
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 |
361 if (chip_type == CS8900) { |
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 /* |
379 * If no interrupt specified, use what the board tells us. |
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"); |
392 } else { |
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]; |
409 } else { |
410 if (irq > CS8920_NO_INTS) 411 irq = 255; |
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); |
420 } 421 } 422 |
423 if (!error && !(sc->flags & CS_NO_IRQ)) { |
424 if (chip_type == CS8900) { |
425 if (irq >= 0 || irq < 16) 426 irq = cs8900_irq2eeint[irq]; 427 else 428 irq = 255; |
429 } else { |
430 if (irq > CS8920_NO_INTS) 431 irq = 255; |
432 } |
433 if (irq == 255) 434 error = EINVAL; |
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", |
458 chip_type == CS8900 ? '0' : '2', 459 chip_type == CS8920M ? "M" : "", |
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{ |
1236 int error = 0; |
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: |
1255 enable_tp(sc); |
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 --- |