📄 ee_init.c,v
字号:
head 1.3;access;symbols;locks dls:1.3; strict;comment @ * @;1.3date 97.09.21.19.25.55; author dls; state Dist;branches;next 1.2;1.2date 95.02.05.21.46.32; author dls; state Broken;branches;next 1.1;1.1date 94.09.24.01.00.41; author dls; state Works;branches;next ;desc@@1.3log@pre-3e code@text@/* ee_init.c - ee_init */#include <conf.h>#include <kernel.h>#include <network.h>#include <i386.h>#include <ee.h>#include <q.h>static unsigned char eeirq[] = {255, 9, 3, 4, 5, 10, 11, 255 };unsigned char eecf[] = { 0x0c, 0x08, 0x00, 0x2e, 0x00, 0x60, 0x00, 0xf2, 0x00, 0x00, 0x40, 0x00 };/*------------------------------------------------------------------------ * ee_init - startup initialization of Intel EtherExpress device *------------------------------------------------------------------------ */intee_init(pdev)struct devsw *pdev;{ struct etdev *ped; unsigned short eedat, wtmp, *pw; unsigned char irq, tmp, memc, mempc, memdec; int i, offset, ee_int(); unsigned char *pdbuf; unsigned short rom[64]; struct cbl *pcbl; struct iscp *piscp; struct scb *pscb; struct rfd *prfd; struct rbd *prbd; struct tbd *ptbd; pdev->dvioblk = (char *) ped = &ee[pdev->dvminor]; ped->ed_pdev = pdev; ped->ed_outq = newq(ETOUTQSZ, QF_NOWAIT); ped->ed_ifnum = -1; ped->ed_descr = "Intel EtherExpress"; ped->ed_mcc = 0; ped->ed_xpending = 0; /* read ROM data */ for (i=0; i<EE_ROMSIZE; ++i) rom[i] = ee_romread(pdev->dvcsr, i); for (i=0; i<16; ++i) if ((inb(pdev->dvcsr + AID) & 0xf) != i) break; if (i < 16) { kprintf("ee_init: no EtherExpress at 0x%03x\n", pdev->dvcsr); return SYSERR; } /* set IRQ */ irq = pdev->dvivec - IRQBASE; for (i=0; i<sizeof(eeirq); ++i) if (eeirq[i] == irq) { ped->ed_irq = i; break; } if (i == sizeof(eeirq)) { kprintf("ee%d: invalid IRQ (%d)\n", pdev->dvminor, irq); return SYSERR; } else { eedat = rom[EE_BOARD]; eedat >>= 13; if (eeirq[eedat] != irq) kprintf("ee%d: WARNING ROM IRQ (%d) differs\n", pdev->dvminor, eeirq[eedat]); ped->ed_irq = eedat; irq = eeirq[eedat]; } set_evec(pdev->dvivec, ee_int);#ifdef notdef/*XXX */ /* test & set BUS timing */ tmp = inb(pdev->dvcsr + CONFIG); outb(pdev->dvcsr + CONFIG, tmp | CONFIG_IOTE); /* do an I/O for the test */ outb(pdev->dvcsr + RDPTR, 0); inw(pdev->dvcsr + DXREG); tmp = inb(pdev->dvcsr + CONFIG); if (tmp & CONFIG_TOGGLE) { if (tmp & CONFIG_ICLATE) tmp &= ~CONFIG_16EN; /* force 8-bit mode */ else tmp |= CONFIG_ICLATE; } tmp &= ~(CONFIG_IOTE|CONFIG_TOGGLE); outb(pdev->dvcsr + CONFIG, tmp);#endif /* "warm up" DRAMS-- requires 16 bytes buf access */ outb(pdev->dvcsr + RDPTR, 0); for (i=0; i<16; ++i) inw(pdev->dvcsr + DXREG); /* set up SCP */ outw(pdev->dvcsr+WRPTR, SCP); outw(pdev->dvcsr+DXREG, SYSBUS_16); /* 16-bit bus */ outw(pdev->dvcsr+DXREG, 0); /* skip unused words */ outw(pdev->dvcsr+DXREG, 0); outw(pdev->dvcsr+DXREG, ISCP & 0xffff); outw(pdev->dvcsr+DXREG, ISCP >> 16); outb(pdev->dvcsr + EEC, EEC_586R); /* reset 82586 */ outb(pdev->dvcsr + EEC, 0); /* clear reset */ /* set buffer memory map */ eedat = rom[EE_MEM1]; memc = eedat & 0xff; mempc = eedat >> 8; memdec = rom[EE_MEM2]; mempc = ~memdec; tmp = 0x80; for (i=7; i>=0; --i, tmp >>= 1) if (memdec & tmp) { ped->ed_iomem = 0xc0000 + i * 0x4000; break; } if (i < 0) { ped->ed_iomem = 0xcc000; kprintf("invalid ROM configuration, setting to iomem %X\n", ped->ed_iomem); memdec = 0x8; memc = 0x1c; }#ifdef notdef /* test and set mempc */ pw = (unsigned short *)0xc0000; mempc = 0; for (i=0; i<8; ++i) { mempc >>= 1; outb(pdev->dvcsr + CONFIG, CONFIG_MCS16); wtmp = *pw; /* reference it */ mempc |= inb(pdev->dvcsr + CONFIG) & 0x80; pw += 8192; } outb(pdev->dvcsr + CONFIG, CONFIG_MCS16); wtmp = *(unsigned short *)0xf0000; if (inb(pdev->dvcsr + CONFIG) & 0x80) memc |= MEMC_MCS16; else memc &= ~MEMC_MCS16;#endif outb(pdev->dvcsr + MEMDEC, memdec); outb(pdev->dvcsr + MEMC, memc); outb(pdev->dvcsr + MEMPC, mempc); for (i=0; i<EP_ALEN/2 ; ++i) { eedat = rom[EE_EADDR + i]; ped->ed_paddr[EP_ALEN - 2*i -1] = eedat & 0xff; ped->ed_paddr[EP_ALEN - 2*i -2] = eedat >> 8; ped->ed_bcast[2*i] = ~0; ped->ed_bcast[2*i+1] = ~0; } kprintf("ee%d: etheraddr %02x:%02x:%02x:%02x:%02x:%02x ", pdev->dvminor, ped->ed_paddr[0] & 0xff, ped->ed_paddr[1] & 0xff, ped->ed_paddr[2] & 0xff, ped->ed_paddr[3] & 0xff, ped->ed_paddr[4] & 0xff, ped->ed_paddr[5] & 0xff); kprintf("irq %d iomem %X\n", irq, ped->ed_iomem); piscp = (struct iscp *) (ped->ed_iomem + ISCP); piscp->iscp_busy = 1; piscp->iscp_scboff = SCB; piscp->iscp_scbbase = 0; pscb = (struct scb *)(ped->ed_iomem + SCB); ped->ed_scb = pscb; bzero(pscb, sizeof(struct scb)); offset = (unsigned int)pscb + sizeof(struct scb); /* allocate space for a command block */ pcbl = (struct cbl *)offset; ped->ed_cbl = pcbl; pcbl->cbl_next = 0xffff; offset += sizeof(struct cbl); /* allocate transmit buffer */ ptbd = ped->ed_tbd = (struct tbd *)offset; ptbd->tbd_count = 0; ptbd->tbd_eof = 1; ptbd->tbd_next = H2IO(ped, ptbd); offset += sizeof(struct tbd); ped->ed_xmbuf = (unsigned char *)offset; ptbd->tbd_buf = H2IO(ped, ped->ed_xmbuf); offset += EDLEN; /* initialize receive buffers */ ped->ed_rfd = (struct rfd *)offset; offset += EE_NRX * sizeof(struct rfd); ped->ed_rbd = (struct rbd *)offset; offset += EE_NRX * sizeof(struct rbd); pdbuf = (unsigned char *)offset; prfd = ped->ed_rfd; prbd = ped->ed_rbd; for (i=0; i<EE_NRX; ++i) { prfd->rfd_status = 0; prfd->rfd_cmd = 0; prfd->rfd_next = H2IO(ped, prfd + 1); prfd->rfd_rbd = H2IO(ped, prbd); prbd->rbd_count = 0; prbd->rbd_valid = 0; prbd->rbd_eof = 0; prbd->rbd_next = H2IO(ped, prbd + 1); prbd->rbd_buf = H2IO(ped, pdbuf); prbd->rbd_size = EDLEN; prbd->rbd_el = 0; prfd++; prbd++; pdbuf += EDLEN; } prfd--; prbd--; /* go back to last one */ prfd->rfd_cmd = EECMD_EL; /* mark end of receive FD list */ prfd->rfd_next = H2IO(ped, ped->ed_rfd); ped->ed_rfdend = prfd; prbd->rbd_el = 1; prbd->rbd_next = H2IO(ped, ped->ed_rbd); ped->ed_rbdend = prbd; pscb->scb_rfaoff = H2IO(ped, ped->ed_rfd); outb(pdev->dvcsr + CAC, 0); /* start the 82586 */ for (i=0; i<200; ++i) { if (!piscp->iscp_busy) break; delay(1); } if (i == 200) { kprintf("ee%d: failed initialization\n", pdev->dvminor); return SYSERR; } for (i=0; i<200; ++i) { if (pscb->scb_status == STAT_CX|STAT_CNA) break; delay(1); } if (i == 200) { kprintf("ee%d: failed status check (status %x)\n", pdev->dvminor, pscb->scb_status); return SYSERR; } /* configure */ ee_cmd(ped, EECMD_CONFIG, eecf); ee_ack(ped, pscb->scb_status); /* set station address */ ee_cmd(ped, EECMD_IASET, ped->ed_paddr); ee_ack(ped, pscb->scb_status); /* start frame reception */ ee_wait(ped); pscb->scb_cmd = (pscb->scb_status & 0xf000) | SCBCMD_RUS; pscb->scb_status = 0; outb(pdev->dvcsr + CAC, 0); /* start the 82586 */ outb(pdev->dvcsr+SIRQ, ped->ed_irq | SIRQ_IEN); /* enable interrupts */ return OK;}inteedump(ped)struct etdev *ped;{ struct iscp *piscp = (struct iscp *)ped->ed_iomem; struct scb *pscb = ped->ed_scb; struct cbl *pcbl = ped->ed_cbl; struct rfd *prfd = ped->ed_rfd; struct rbd *prbd = ped->ed_rbd; struct tbd *ptbd = ped->ed_tbd; int i; kprintf("\n\nprfd %X prfdend %X prbd %X prbdend %X ptbd %X\n", ped->ed_rfd, ped->ed_rfdend, ped->ed_rbd, ped->ed_rbdend, ped->ed_tbd); kprintf("ISCP: host %X IO %X busy %x scboff %X scbbase %X\n", piscp, H2IO(ped, piscp), piscp->iscp_busy, piscp->iscp_scboff, piscp->iscp_scbbase); kprintf("SCB: host %X IO %X status %x cmd %x cbloff %x rfaoff %x\n", pscb, H2IO(ped, pscb), pscb->scb_status, pscb->scb_cmd, pscb->scb_cbloff, pscb->scb_rfaoff); kprintf("SCB: errors: crc %d align %d resource %d over %d\n", pscb->scb_ecrc, pscb->scb_ealign, pscb->scb_eresource, pscb->scb_eover); kprintf("CBL: status %x cmd %x next %x size %d\n", pcbl->cbl_status, pcbl->cbl_cmd, pcbl->cbl_next, sizeof(struct cbl)); kprintf("TBD: count %d eof %d next %X buf %X\n", ptbd->tbd_count, ptbd->tbd_eof, ptbd->tbd_next, ptbd->tbd_buf); for (i=0; i<EE_NRX; ++i) { kprintf("RFD%d: host %X IO %X status %x cmd %x next %x ", i, prfd, H2IO(ped, prfd), prfd->rfd_status, prfd->rfd_cmd, prfd->rfd_next); kprintf("rbd %x\n", prfd->rfd_rbd); prfd = (struct rfd *)IO2H(ped, prfd->rfd_next); } for (i=0; i<EE_NRX; ++i) { kprintf("RBD%d: host %X IO %X count %d valid %d eof %d ", i, prbd, H2IO(ped, prbd), prbd->rbd_count, prbd->rbd_valid, prbd->rbd_eof); kprintf("next %x buf %X bsize %d el %d\n", prbd->rbd_next, prbd->rbd_buf, prbd->rbd_size, prbd->rbd_el); prbd = (struct rbd *)IO2H(ped, prbd->rbd_next); } kprintf("\n\n");}@1.2log@*** empty log message ***@text@a40 2 ped->ed_cmutex = screate(1); ped->ed_mcset = 0;d42 1d81 7a87 2 outb(pdev->dvcsr + CONFIG, CONFIG_IOTE); inb(pdev->dvcsr);d91 1a91 1 tmp &= ~CONFIG_ICLATE;d95 1a95 2 if (tmp & CONFIG_BUS16) tmp |= CONFIG_16EN;a96 1/*XXX*/a97 1d122 1a122 1mempc = ~memdec;d250 1a250 1 DELAY(1);d259 1a259 1 DELAY(1);@1.1log@Initial revision@text@a9 3#define H2IO(x) ((unsigned short)((char *)(x) - ped->ed_iomem))#define IO2H(x) (ped->ed_iomem + (int)(x))a29 1 struct scp *pscp;d41 3a43 1 ped->ed_xpending = 0;d66 1a66 1 kprintf("ee%d: invalid IRQ (%d)\n", irq);d199 1a199 1 ptbd->tbd_next = H2IO(ptbd);d202 1a202 1 ptbd->tbd_buf = H2IO(ped->ed_xmbuf);d217 2a218 2 prfd->rfd_next = H2IO(prfd + 1); prfd->rfd_rbd = H2IO(prbd);d223 2a224 2 prbd->rbd_next = H2IO(prbd + 1); prbd->rbd_buf = H2IO(pdbuf);d235 1a235 1 prfd->rfd_next = H2IO(ped->ed_rfd);d239 1a239 1 prbd->rbd_next = H2IO(ped->ed_rbd);d242 1a242 1 pscb->scb_rfaoff = H2IO(ped->ed_rfd);d287 1a287 61ee_cmd(ped, cmd, arg1, arg2, arg3)struct etdev *ped;unsigned short cmd;char *arg1, *arg2, *arg3;{ struct devsw *pdev = ped->ed_pdev; struct scb *pscb = ped->ed_scb; struct cbl *pcbl = ped->ed_cbl; ee_wait(ped); /* build command block */ pcbl->cbl_status = 0; pcbl->cbl_cmd = cmd | EECMD_EL; switch (cmd & EECMD_MASK) { case EECMD_CONFIG: blkcopy(pcbl->cbl_cfg, arg1, CFLEN); case EECMD_IASET: blkcopy(pcbl->cbl_addr, arg1, EP_ALEN); break; case EECMD_TX: pcbl->cbl_tbd = H2IO(ped->ed_tbd); break; case EECMD_NOP: break; /* not implemented yet */ } pscb->scb_cmd = SCBCMD_CUS; pscb->scb_status = 0; pscb->scb_cbloff = H2IO(pcbl); outb(pdev->dvcsr + CAC, 0); /* start the 82586 */}ee_wait(ped)struct etdev *ped;{ struct devsw *pdev = ped->ed_pdev; struct scb *pscb = ped->ed_scb; int i; for (i=0; i<5000; ++i) if (!pscb->scb_cmd) return; kprintf("ee%d: ee_wait timed out, SCB status %x cmd %x\n", pdev->dvminor, pscb->scb_status, pscb->scb_cmd);}ee_ack(ped, status)struct etdev *ped;unsigned short status;{ struct devsw *pdev = ped->ed_pdev; struct scb *pscb = ped->ed_scb; ee_wait(ped); pscb->scb_cmd = status & 0xf000; outb(pdev->dvcsr+CAC, 0);}d297 1a297 1 int i, j;d303 1a303 1 piscp, H2IO(piscp), piscp->iscp_busy, piscp->iscp_scboff,d306 1a306 1 pscb, H2IO(pscb),d318 2a319 2 i, prfd, H2IO(prfd), prfd->rfd_status, prfd->rfd_cmd, prfd->rfd_next);d321 1a321 1 prfd = (struct rfd *)IO2H(prfd->rfd_next);d325 2a326 2 i, prbd, H2IO(prbd), prbd->rbd_count, prbd->rbd_valid, prbd->rbd_eof);d330 1a330 1 prbd = (struct rbd *)IO2H(prbd->rbd_next);@
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -