1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
45:
46: 47: 48: 49:
50:
51: #include "netdrv.h"
52:
53:
54: #define SMSC9118_IOSZ 0x100
55:
56:
57: #define RX_DATA 0x00
58: #define TX_DATA 0x20
59: #define RX_STS 0x40
60: #define TX_STS 0x48
61: #define ID_REV 0x50
62: #define IRQ_CFG 0x54
63: #define INT_STS 0x58
64: #define INT_EN 0x5c
65: #define BYTE_TEST 0x64
66: #define FIFO_INT 0x68
67: #define RX_CFG 0x6c
68: #define TX_CFG 0x70
69: #define HW_CFG 0x74
70: #define RX_DP_CTL 0x78
71: #define RX_FIFO_INF 0x7c
72: #define TX_FIFO_INF 0x80
73: #define PMT_CTRL 0x84
74: #define GPIO_CFG 0x88
75: #define ENDIAN 0x98
76: #define RX_DROP 0xa0
77: #define MAC_CSR_CMD 0xa4
78: #define MAC_CSR_DATA 0xa8
79: #define AFC_CFG 0xac
80: #define E2P_CMD 0xb0
81: #define E2P_DATA 0xb4
82:
83:
84: #define IRQ_CFG_INT_DEAS(x) ((x) << 24)
85: #define IRQ_CFG_IRQ_EN (1 << 8)
86: #define IRQ_CFG_IRQ_POL (1 << 4)
87: #define IRQ_CFG_IRQ_TYPE (1 << 0)
88:
89:
90: #define INT_TXSTOP (1 << 25)
91: #define INT_RXSTOP (1 << 24)
92: #define INT_TSFF (1 << 8)
93: #define INT_TSFL (1 << 7)
94: #define INT_RSFF (1 << 4)
95: #define INT_RSFL (1 << 3)
96:
97:
98: #define BYTE_TEST_MAGIC 0x87654321
99:
100:
101: #define FIFO_INT_TSFL(x) ((x) << 16)
102: #define FIFO_INT_RSFL(x) ((x) << 0)
103:
104:
105: #define RX_CFG_ALIGN_4 (0 << 30)
106: #define RX_CFG_DUMP (1 << 15)
107: #define RX_CFG_DOFF(x) ((x) << 8)
108:
109:
110: #define TX_CFG_SDUMP (1 << 15)
111: #define TX_CFG_DDUMP (1 << 14)
112: #define TX_CFG_ON (1 << 1)
113: #define TX_CFG_STOP (1 << 0)
114:
115:
116: #define HW_CFG_SF (1 << 20)
117: #define HW_CFG_TX_FIF_SZ(x) ((x) << 16)
118: #define HW_CFG_PHY_CLK_INT (0 << 5)
119: #define HW_CFG_SRST_TO (1 << 1)
120: #define HW_CFG_SRST (1 << 0)
121:
122:
123: #define RX_DP_CTL_FFWD (1 << 31)
124:
125:
126: #define PMT_CTRL_PM_MODE(x) ((x) << 12)
127: #define PMT_CTRL_PHY_RST (1 << 10)
128: #define PMT_CTRL_READY (1 << 0)
129:
130:
131: #define MAC_CSR_CMD_BUSY (1 << 31)
132: #define MAC_CSR_CMD_READ (1 << 30)
133: #define MAC_CSR_CMD_ADDR(x) ((x) << 0)
134:
135:
136: #define E2P_CMD_BUSY (1 << 31)
137: #define E2P_CMD_READ (0 << 28)
138: #define E2P_CMD_TMO (1 << 9)
139: #define E2P_CMD_ADDR(x) ((x) << 0)
140:
141:
142: #define MAC_CR 0x01
143: #define ADDRH 0x02
144: #define ADDRL 0x03
145: #define HASHH 0x04
146: #define HASHL 0x05
147: #define MII_ACC 0x06
148: #define MII_DATA 0x07
149: #define FLOW 0x08
150: #define VLAN1 0x09
151: #define VLAN2 0x0a
152: #define WUFF 0x0b
153: #define WUCSR 0x0c
154:
155:
156: #define MAC_CR_FDPX (1 << 20)
157: #define MAC_CR_TXEN (1 << 3)
158: #define MAC_CR_RXEN (1 << 2)
159:
160:
161: #define MII_ACC_PHYADR(x) ((x) << 11)
162: #define MII_ACC_MIIRINDA(x) ((x) << 6)
163: #define MII_ACC_MIIWnR (1 << 1)
164: #define MII_ACC_MIIBZY (1 << 0)
165:
166:
167: #define BadState wrk.uw[0]
168: #define ChipID wrk.uw[3]
169: #define IntMask wrk.uw[6]
170:
171:
172: #define RX_STS_ES (1 << 15)
173:
174:
175: #define TX_CMDA_ALIGN_4 (0 << 24)
176: #define TX_CMDA_OFFSET(x) ((x) << 16)
177: #define TX_CMDA_FS (1 << 13)
178: #define TX_CMDA_LS (1 << 12)
179: #define TX_CMDA_BUFSZ(x) ((x) << 0)
180:
181:
182: #define TX_CMDB_PADDIS (1 << 12)
183: #define TX_CMDB_PKTSZ(x) ((x) << 0)
184:
185:
186: #define TX_STS_ES (1 << 15)
187:
188:
189: #define IOBase di.iobase
190:
191: #define POLL_LIMIT 100000
192: #define DLY_LIMIT 100
193:
194: #define TX_FIFO_SIZE 5
195:
196:
197: LOCAL const UB *SMSC9118_PNAME1[] = {
198: "SMSC ",
199: };
200:
201: LOCAL const UB *SMSC9118_PNAME2[] = {
202: "LAN9118 family",
203: };
204:
205:
206: 207: 208:
209: LOCAL void wait_reg(NetInf *inf, W reg, W mask, W val)
210: {
211: UW IOB = inf->IOBase;
212: W i;
213:
214: for (i = POLL_LIMIT; i > 0; i--) {
215: InW(BYTE_TEST);
216: if ((InW(reg) & mask) == val) goto fin0;
217: }
218: for (i = DLY_LIMIT; i > 0; i--) {
219: if (tk_dly_tsk(10) < E_OK) InW(BYTE_TEST);
220: if ((InW(reg) & mask) == val) goto fin0;
221: }
222:
223: inf->BadState = 1;
224: DP(("wait_reg: reg %#x mask %#x timeout\n", reg, mask));
225: fin0:
226: return;
227: }
228:
229: 230: 231:
232: #define wait_mac(inf) wait_reg((inf), MAC_CSR_CMD, MAC_CSR_CMD_BUSY, 0)
233:
234: 235: 236:
237: LOCAL void poke_mac(NetInf *inf, W reg, W dat)
238: {
239: UW IOB = inf->IOBase;
240:
241: wait_mac(inf);
242: OutW(MAC_CSR_DATA, dat);
243: OutW(MAC_CSR_CMD, reg | MAC_CSR_CMD_BUSY);
244: wait_mac(inf);
245:
246: return;
247: }
248:
249: 250: 251:
252: LOCAL W peek_mac(NetInf *inf, W reg)
253: {
254: UW IOB = inf->IOBase;
255:
256: wait_mac(inf);
257: OutW(MAC_CSR_CMD, reg | MAC_CSR_CMD_BUSY | MAC_CSR_CMD_READ);
258: wait_mac(inf);
259:
260: return InW(MAC_CSR_DATA);
261: }
262:
263: 264: 265:
266: LOCAL void wait_mii(NetInf *inf)
267: {
268: W i;
269:
270: for (i = POLL_LIMIT; i > 0; i--) {
271: if (!(peek_mac(inf, MII_ACC) & MII_ACC_MIIBZY)) break;
272: }
273:
274: if (!i) {
275: inf->BadState = 1;
276: DP(("wait_mii: timeout\n"));
277: }
278:
279: return;
280: }
281:
282: 283: 284:
285: LOCAL void poke_mii(NetInf *inf, W adr, W reg, W dat)
286: {
287: wait_mii(inf);
288: poke_mac(inf, MII_DATA, dat);
289: poke_mac(inf, MII_ACC, (MII_ACC_PHYADR(adr) | MII_ACC_MIIRINDA(reg) |
290: MII_ACC_MIIBZY | MII_ACC_MIIWnR));
291: wait_mii(inf);
292:
293: return;
294: }
295:
296: 297: 298:
299: LOCAL UH peek_mii(NetInf *inf, W adr, W reg)
300: {
301: wait_mii(inf);
302: poke_mac(inf, MII_ACC, (MII_ACC_PHYADR(adr) | MII_ACC_MIIRINDA(reg) |
303: MII_ACC_MIIBZY));
304: wait_mii(inf);
305:
306: return peek_mac(inf, MII_DATA);
307: }
308:
309: 310: 311:
312: #define wait_srom(inf) wait_reg((inf), E2P_CMD, E2P_CMD_BUSY, 0)
313:
314: 315: 316:
317: LOCAL W peek_srom(NetInf *inf, W adr)
318: {
319: UW IOB = inf->IOBase;
320:
321: wait_srom(inf);
322: OutW(E2P_CMD, (E2P_CMD_BUSY | E2P_CMD_READ |
323: E2P_CMD_TMO | E2P_CMD_ADDR(adr)));
324: wait_srom(inf);
325:
326: return (InW(E2P_CMD) & E2P_CMD_TMO) ? -1 : InW(E2P_DATA);
327: }
328:
329: 330: 331:
332: LOCAL void smsc9118_wakeup(NetInf *inf)
333: {
334: UW IOB = inf->IOBase;
335:
336:
337: if (InW(PMT_CTRL) & PMT_CTRL_PM_MODE(3)) {
338: OutW(BYTE_TEST, BYTE_TEST_MAGIC);
339: wait_reg(inf, PMT_CTRL, PMT_CTRL_READY, PMT_CTRL_READY);
340: }
341:
342:
343: OutW(PMT_CTRL, PMT_CTRL_PHY_RST);
344: WaitUsec(100);
345: wait_reg(inf, PMT_CTRL, PMT_CTRL_PHY_RST, 0);
346:
347: return;
348: }
349:
350: 351: 352:
353: LOCAL void smsc9118_phyen(NetInf *inf, BOOL power_on)
354: {
355: #define BMCR_PDN (1 << 11)
356:
357: W adr;
358:
359: adr = MIIfind(inf, 1);
360: if (adr >= 0) {
361: if (power_on) {
362: poke_mii(inf, adr, 0,
363: peek_mii(inf, adr, 0) & ~BMCR_PDN);
364: } else {
365: poke_mii(inf, adr, 0,
366: peek_mii(inf, adr, 0) | BMCR_PDN);
367: }
368: }
369:
370: return;
371: }
372:
373: 374: 375:
376: LOCAL void smsc9118_reset(NetInf *inf, BOOL start)
377: {
378: UW IOB = inf->IOBase;
379: UW cr;
380:
381:
382: smsc9118_wakeup(inf);
383:
384:
385: OutW(INT_EN, 0);
386: inf->IntMask = 0;
387: inf->BadState = 0;
388: inf->txbusy = FALSE;
389:
390:
391: smsc9118_phyen(inf, TRUE);
392:
393:
394: OutW(HW_CFG, HW_CFG_SRST);
395: wait_reg(inf, HW_CFG, HW_CFG_SRST, 0);
396: wait_reg(inf, PMT_CTRL, PMT_CTRL_READY, PMT_CTRL_READY);
397: if (InW(HW_CFG) & HW_CFG_SRST_TO) inf->BadState = 1;
398: wait_srom(inf);
399: if (start && inf->BadState) goto fin0;
400:
401: OutW(HW_CFG, HW_CFG_SF | HW_CFG_TX_FIF_SZ(TX_FIFO_SIZE) |
402: HW_CFG_PHY_CLK_INT);
403: OutW(AFC_CFG, 0x006e3740);
404: OutW(FIFO_INT, FIFO_INT_TSFL(0) | FIFO_INT_RSFL(0));
405: OutW(RX_CFG, RX_CFG_ALIGN_4 | RX_CFG_DUMP | RX_CFG_DOFF(0));
406: wait_reg(inf, RX_CFG, RX_CFG_DUMP, 0);
407: OutW(TX_CFG, TX_CFG_SDUMP | TX_CFG_DDUMP);
408: wait_reg(inf, TX_CFG, TX_CFG_SDUMP | TX_CFG_DDUMP, 0);
409: #ifdef GPIO_CFG_VAL
410: OutW(GPIO_CFG, GPIO_CFG_VAL);
411: #else
412: OutW(GPIO_CFG, 0x70000000);
413: #endif
414: InW(RX_DROP);
415:
416:
417: poke_mac(inf, ADDRH, *((UH *)&inf->eaddr.c[4]));
418: poke_mac(inf, ADDRL, *((UW *)&inf->eaddr.c[0]));
419:
420:
421: poke_mac(inf, HASHH, 0);
422: poke_mac(inf, HASHL, 0);
423:
424:
425: MIIinit(inf, 1);
426:
427:
428: if (!start) {
429: smsc9118_phyen(inf, FALSE);
430: goto fin0;
431: }
432:
433:
434: tk_dly_tsk(1500);
435:
436:
437: peek_mii(inf, 1, 1);
438:
439:
440: OutW(TX_CFG, TX_CFG_ON);
441: cr = MAC_CR_TXEN | MAC_CR_RXEN;
442: if (isFDX(inf)) cr |= MAC_CR_FDPX;
443: poke_mac(inf, MAC_CR, cr);
444:
445:
446: #ifdef IRQ_CFG_VAL
447: OutW(IRQ_CFG, IRQ_CFG_IRQ_EN | IRQ_CFG_VAL);
448: #else
449: OutW(IRQ_CFG, (IRQ_CFG_INT_DEAS(22) |
450: IRQ_CFG_IRQ_EN | IRQ_CFG_IRQ_TYPE));
451: #endif
452: inf->IntMask = (INT_TXSTOP | INT_RXSTOP |
453: INT_TSFF | INT_TSFL | INT_RSFF | INT_RSFL);
454: OutW(INT_EN, inf->IntMask);
455: fin0:
456: return;
457: }
458:
459: 460: 461:
462: Inline void smsc9118_poprx(NetInf *inf, UB *bp, W len)
463: {
464: UW IOB = inf->IOBase;
465: UW d;
466:
467:
468: switch ((W)bp & 3) {
469: case 0:
470: for (; len > 7; len -= 4) {
471: *(UW *)bp = InW(RX_DATA);
472: bp += 4;
473: }
474: break;
475: case 2:
476: for (; len > 7; len -= 4) {
477: d = InW(RX_DATA);
478: *(UH *)bp = d;
479: bp += 2;
480: *(UH *)bp = d >> 16;
481: bp += 2;
482: }
483: break;
484: default:
485: for (; len > 7; len -= 4) {
486: d = InW(RX_DATA);
487: *bp++ = d;
488: *bp++ = d >> 8;
489: *bp++ = d >> 16;
490: *bp++ = d >> 24;
491: }
492: break;
493: }
494:
495:
496: if (len >= 4) {
497: d = InW(RX_DATA);
498: switch (len) {
499: case 7: bp[2] = d >> 16;
500: case 6: bp[1] = d >> 8;
501: case 5: bp[0] = d;
502: default: break;
503: }
504: len -= 4;
505: }
506:
507:
508: if (len) InW(RX_DATA);
509:
510: return;
511: }
512:
513: 514: 515:
516: Inline void smsc9118_receive(NetInf *inf)
517: {
518: UW IOB = inf->IOBase;
519: UW i, rxsused, sts, len, pktlen;
520: UB *bp;
521:
522:
523: rxsused = (InW(RX_FIFO_INF) >> 16) & 0xff;
524:
525:
526: for (i = 0; i < rxsused; i++) {
527: sts = InW(RX_STS);
528: len = (sts >> 16) & 0x3fff;
529: pktlen = len - 4;
530:
531: if (sts & RX_STS_ES) {
532: inf->stinf.rxerr++;
533: inf->stinf.other[2] |= sts;
534:
535: } else if ((pktlen < inf->bufsz.minsz) ||
536: (pktlen > inf->bufsz.maxsz)) {
537: inf->stinf.invpkt++;
538:
539: } else if (inf->mbfid > 0) {
540: bp = GetRxBuf(inf);
541:
542: if (bp == NULL) {
543: inf->stinf.misspkt++;
544: } else {
545:
546: smsc9118_poprx(inf, bp, len);
547: SendMsg(inf, bp, pktlen);
548: continue;
549: }
550: }
551:
552: 553:
554: len = (len + 3) / 4;
555: if (len >= 4) {
556: OutW(RX_DP_CTL, RX_DP_CTL_FFWD);
557: wait_reg(inf, RX_DP_CTL, RX_DP_CTL_FFWD, 0);
558: } else {
559: for (; len > 0; len--) InW(RX_DATA);
560: }
561: }
562:
563: return;
564: }
565:
566: 567: 568:
569: #define TXFIFOisReady ((InW(TX_FIFO_INF) & 0xffff) >= MAXPKTLEN + 8)
570:
571: 572: 573:
574: Inline void smsc9118_sendcomplete(NetInf *inf)
575: {
576: UW IOB = inf->IOBase;
577: UW i, txsused, sts;
578:
579:
580: txsused = (InW(TX_FIFO_INF) >> 16) & 0xff;
581:
582:
583: for (i = 0; i < txsused; i++) {
584: sts = InW(TX_STS);
585: if (sts & TX_STS_ES) {
586: inf->stinf.txerr++;
587: inf->stinf.other[1] |= sts;
588: }
589: inf->stinf.collision += (sts >> 3) & 0x0f;
590: }
591:
592: 593:
594: if (inf->txbusy && TXFIFOisReady) {
595: inf->txbusy = FALSE;
596: SendMsg(inf, NULL, 0);
597: }
598:
599: return;
600: }
601:
602: 603: 604:
605: LOCAL void smsc9118_inthdr(NetInf *inf)
606: {
607: UW IOB = inf->IOBase;
608: UW sts, limit;
609:
610: inf->stinf.nint++;
611: limit = 1000000;
612:
613: while (1) {
614:
615: sts = InW(INT_STS);
616: OutW(INT_STS, sts & ~inf->IntMask);
617:
618:
619: if (!(sts & inf->IntMask)) break;
620:
621:
622: if (--limit < 0) {
623: inf->stinf.hwerr++;
624: smsc9118_reset(inf, FALSE);
625: break;
626: }
627:
628:
629: if (sts & (INT_RSFF | INT_RSFL)) {
630: inf->stinf.rxint++;
631: smsc9118_receive(inf);
632: OutW(INT_STS, sts & (INT_RSFF | INT_RSFL));
633: }
634:
635:
636: if (sts & (INT_TSFF | INT_TSFL)) {
637: inf->stinf.txint++;
638: smsc9118_sendcomplete(inf);
639: OutW(INT_STS, sts & (INT_TSFF | INT_TSFL));
640: }
641:
642:
643: if (sts & (INT_TXSTOP | INT_RXSTOP)) {
644: inf->stinf.hwerr++;
645: smsc9118_reset(inf, TRUE);
646: break;
647: }
648:
649:
650: InW(BYTE_TEST);
651: }
652:
653: return;
654: }
655:
656: 657: 658:
659: LOCAL INT smsc9118_send(NetInf *inf, UB *buf, W len)
660: {
661: UW IOB = inf->IOBase;
662: UW i, d, ofs;
663:
664: 665:
666: if (!inf->IntMask || inf->txbusy) {
667: inf->stinf.txbusy++;
668: return E_BUSY;
669: }
670:
671:
672: OutW(INT_EN, 0);
673:
674:
675: len = (len < MAXPKTLEN) ? len : MAXPKTLEN;
676:
677:
678: ofs = (W)buf & 3;
679:
680:
681: OutW(TX_DATA, (TX_CMDA_ALIGN_4 | TX_CMDA_OFFSET(ofs) |
682: TX_CMDA_FS | TX_CMDA_LS | TX_CMDA_BUFSZ(len)));
683: OutW(TX_DATA, TX_CMDB_PADDIS | TX_CMDB_PKTSZ(len));
684:
685:
686: if (ofs) {
687: for (d = i = 0; i < 4 - ofs && len > 0; i++, len--, buf++) {
688: d |= *buf << (((W)buf & 3) * 8);
689: }
690: OutW(TX_DATA, d);
691: }
692:
693:
694: for (; len > 3; len -= 4, buf += 4) OutW(TX_DATA, *(UW *)buf);
695:
696:
697: if (len) {
698: d = 0;
699: switch (len) {
700: case 3: d |= (buf[2] << 16);
701: case 2: d |= (buf[1] << 8);
702: case 1: d |= buf[0];
703: default: break;
704: }
705: OutW(TX_DATA, d);
706: }
707:
708: 709:
710: if (TXFIFOisReady) {
711: SendMsg(inf, NULL, 0);
712: } else {
713: inf->txbusy = TRUE;
714: }
715:
716:
717: OutW(INT_EN, inf->IntMask);
718: inf->stinf.txpkt++;
719:
720: return len;
721: }
722:
723: 724: 725:
726: LOCAL void smsc9118_getstatus(NetInf *inf)
727: {
728: UW IOB = inf->IOBase;
729:
730:
731: if (!inf->opencnt) goto fin0;
732:
733: inf->stinf.overrun += InW(RX_DROP);
734:
735: 736: 737: 738: 739: 740: 741:
742: if (!(InW(PMT_CTRL) & PMT_CTRL_READY) ||
743: InW(BYTE_TEST) != BYTE_TEST_MAGIC ||
744: inf->txbusy || ((InW(TX_FIFO_INF) >> 16) & 0xff) ||
745: (InW(TX_FIFO_INF) & 0xffff) < (TX_FIFO_SIZE * 1024 - 512) ||
746: (peek_mii(inf, 1, 2) != 0x0007)) {
747: inf->BadState = 1;
748: }
749:
750:
751: if (inf->BadState) {
752: inf->stinf.other[0]++;
753: DP(("smsc9118_getstatus: Bad state, try restart\n"));
754:
755: smsc9118_reset(inf, TRUE);
756: }
757:
758: fin0:
759: return;
760: }
761:
762: 763: 764:
765: LOCAL W smsc9118_probe(NetInf *inf)
766: {
767: UW IOB = inf->IOBase;
768: W i, err;
769:
770:
771: inf->IntMask = 0;
772:
773:
774: smsc9118_wakeup(inf);
775:
776:
777: if (InW(BYTE_TEST) != BYTE_TEST_MAGIC) {
778: DP(("smsc9118_probe: LAN911x not found\n"));
779: err = E_NOMDA;
780: goto fin0;
781: }
782:
783:
784: if (inf->di.stat < E_OK) {
785: err = E_OK;
786: goto fin0;
787: }
788:
789:
790: OutW(INT_EN, 0);
791: OutW(TX_CFG, TX_CFG_STOP);
792: wait_reg(inf, TX_CFG, TX_CFG_STOP, 0);
793: poke_mac(inf, MAC_CR,
794: peek_mac(inf, MAC_CR) & ~(MAC_CR_TXEN | MAC_CR_RXEN));
795:
796:
797: smsc9118_phyen(inf, FALSE);
798:
799:
800: inf->ChipID = InW(ID_REV);
801: DP(("smsc9118_probe: ID_REV %#x\n", inf->ChipID));
802:
803:
804: for (i = 0; i < L_EADDR; i++) {
805: inf->eaddr.c[i] = peek_srom(inf, i + 1);
806: DP(("%02x ", inf->eaddr.c[i]));
807: }
808: DP(("\n"));
809:
810:
811: err = E_OK;
812: fin0:
813: return err;
814: }
815:
816: 817: 818: 819: 820: 821: 822: 823: 824: 825: 826: 827: 828: 829: 830: 831: 832: 833: 834: 835: 836: 837: 838: 839: 840: 841: 842: 843: 844: 845: 846: 847: 848: 849: 850: 851: 852: 853: 854: 855: 856: 857: 858: 859: 860: 861: 862: 863: 864: 865: 866:
867: EXPORT ER InitSMSC9118(NetInf *inf, W init)
868: {
869: ER err;
870:
871:
872: if (init < 0) goto fin1;
873:
874: inf->di.iosize = SMSC9118_IOSZ;
875:
876: DP(("Net%c: InitSMSC9118 kind:%#x\n", NetUnit(inf), inf->di.kind));
877:
878:
879: inf->mii_read = peek_mii;
880: inf->mii_write = poke_mii;
881:
882:
883: err = smsc9118_probe(inf);
884: if (err < E_OK) goto fin0;
885:
886:
887: SetProdName(inf, (UB **)SMSC9118_PNAME1, (UB **)SMSC9118_PNAME2);
888:
889:
890: inf->inthdr = smsc9118_inthdr;
891: inf->sendfn = smsc9118_send;
892: inf->reset = smsc9118_reset;
893: inf->cardchk = NULL;
894: inf->misc = NULL;
895: inf->mcast = NULL;
896: inf->tmout = 10000;
897: inf->tmofn = smsc9118_getstatus;
898:
899: fin1:
900: err = E_OK;
901: fin0:
902: return err;
903: }
904: