Deleted Added
full compact
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}