📄 tulip.c
字号:
case DC21040: outl(0x00000000, ioaddr + CSR13); outl(0x00000004, ioaddr + CSR13); break; case DC21041: /* This is nway_start(). */ if (tp->sym_advertise == 0) tp->sym_advertise = 0x0061; outl(0x00000000, ioaddr + CSR13); outl(0xFFFFFFFF, ioaddr + CSR14); outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */ outl(inl(ioaddr + CSR6) | 0x0200, ioaddr + CSR6); outl(0x0000EF01, ioaddr + CSR13); break; case DC21140: default: if (tp->mtable) outl(tp->mtable->csr12dir | 0x100, ioaddr + CSR12); break; case DC21142: case PNIC2: if (tp->mii_cnt || media_cap[tp->if_port] & MediaIsMII) { outl(0x82020000, ioaddr + CSR6); outl(0x0000, ioaddr + CSR13); outl(0x0000, ioaddr + CSR14); outl(0x820E0000, ioaddr + CSR6); } else nway_start(nic); break; case LC82C168: if ( ! tp->mii_cnt) { tp->nway = 1; tp->nwayset = 0; outl(0x00420000, ioaddr + CSR6); outl(0x30, ioaddr + CSR12); outl(0x0001F078, ioaddr + 0xB8); outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */ } break; case MX98713: case COMPEX9881: outl(0x00000000, ioaddr + CSR6); outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */ outl(0x00000001, ioaddr + CSR13); break; case MX98715: case MX98725: outl(0x01a80000, ioaddr + CSR6); outl(0xFFFFFFFF, ioaddr + CSR14); outl(0x00001000, ioaddr + CSR12); break; case COMET: /* No initialization necessary. */ break; }}static void nway_start(struct nic *nic){ int csr14 = ((tp->sym_advertise & 0x0780) << 9) | ((tp->sym_advertise&0x0020)<<1) | 0xffbf;#ifdef TULIP_DEBUG_WHERE whereami("nway_start\n");#endif tp->if_port = 0; tp->nway = tp->mediasense = 1; tp->nwayset = tp->lpar = 0; if (tp->chip_id == PNIC2) { tp->csr6 = 0x01000000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0); return; }#ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: Restarting internal NWay autonegotiation, %X.\n", tp->nic_name, csr14);#endif outl(0x0001, ioaddr + CSR13); outl(csr14, ioaddr + CSR14); tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0); outl(tp->csr6, ioaddr + CSR6); if (tp->mtable && tp->mtable->csr15dir) { outl(tp->mtable->csr15dir, ioaddr + CSR15); outl(tp->mtable->csr15val, ioaddr + CSR15); } else if (tp->chip_id != PNIC2) outw(0x0008, ioaddr + CSR15); if (tp->chip_id == DC21041) /* Trigger NWAY. */ outl(0xEF01, ioaddr + CSR12); else outl(0x1301, ioaddr + CSR12);}static void init_media(struct nic *nic){ int i;#ifdef TULIP_DEBUG_WHERE whereami("init_media\n");#endif tp->saved_if_port = tp->if_port; if (tp->if_port == 0) tp->if_port = tp->default_port; /* Allow selecting a default media. */ i = 0; if (tp->mtable == NULL) goto media_picked; if (tp->if_port) { int looking_for = media_cap[tp->if_port] & MediaIsMII ? 11 : (tp->if_port == 12 ? 0 : tp->if_port); for (i = 0; i < tp->mtable->leafcount; i++) if (tp->mtable->mleaf[i].media == looking_for) { printf("%s: Using user-specified media %s.\n", tp->nic_name, medianame[tp->if_port]); goto media_picked; } } if ((tp->mtable->defaultmedia & 0x0800) == 0) { int looking_for = tp->mtable->defaultmedia & 15; for (i = 0; i < tp->mtable->leafcount; i++) if (tp->mtable->mleaf[i].media == looking_for) { printf("%s: Using EEPROM-set media %s.\n", tp->nic_name, medianame[looking_for]); goto media_picked; } } /* Start sensing first non-full-duplex media. */ for (i = tp->mtable->leafcount - 1; (media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--) ; media_picked: tp->csr6 = 0; tp->cur_index = i; tp->nwayset = 0; if (tp->if_port) { if (tp->chip_id == DC21143 && media_cap[tp->if_port] & MediaIsMII) { /* We must reset the media CSRs when we force-select MII mode. */ outl(0x0000, ioaddr + CSR13); outl(0x0000, ioaddr + CSR14); outl(0x0008, ioaddr + CSR15); } select_media(nic, 1); return; } switch(tp->chip_id) { case DC21041: /* tp->nway = 1;*/ nway_start(nic); break; case DC21142: if (tp->mii_cnt) { select_media(nic, 1);#ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: Using MII transceiver %d, status %hX.\n", tp->nic_name, tp->phys[0], mdio_read(nic, tp->phys[0], 1));#endif outl(0x82020000, ioaddr + CSR6); tp->csr6 = 0x820E0000; tp->if_port = 11; outl(0x0000, ioaddr + CSR13); outl(0x0000, ioaddr + CSR14); } else nway_start(nic); break; case PNIC2: nway_start(nic); break; case LC82C168: if (tp->mii_cnt) { tp->if_port = 11; tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0); outl(0x0001, ioaddr + CSR15); } else if (inl(ioaddr + CSR5) & TPLnkPass) pnic_do_nway(nic); else { /* Start with 10mbps to do autonegotiation. */ outl(0x32, ioaddr + CSR12); tp->csr6 = 0x00420000; outl(0x0001B078, ioaddr + 0xB8); outl(0x0201B078, ioaddr + 0xB8); } break; case MX98713: case COMPEX9881: tp->if_port = 0; tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0); outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); break; case MX98715: case MX98725: /* Provided by BOLO, Macronix - 12/10/1998. */ tp->if_port = 0; tp->csr6 = 0x01a80200; outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80); outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0); break; case COMET: tp->if_port = 0; tp->csr6 = 0x00040000; break; case AX88140: case AX88141: tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100; break; default: select_media(nic, 1); }}static void pnic_do_nway(struct nic *nic){ u32 phy_reg = inl(ioaddr + 0xB8); u32 new_csr6 = tp->csr6 & ~0x40C40200;#ifdef TULIP_DEBUG_WHERE whereami("pnic_do_nway\n");#endif if (phy_reg & 0x78000000) { /* Ignore baseT4 */ if (phy_reg & 0x20000000) tp->if_port = 5; else if (phy_reg & 0x40000000) tp->if_port = 3; else if (phy_reg & 0x10000000) tp->if_port = 4; else if (phy_reg & 0x08000000) tp->if_port = 0; tp->nwayset = 1; new_csr6 = (tp->if_port & 1) ? 0x01860000 : 0x00420000; outl(0x32 | (tp->if_port & 1), ioaddr + CSR12); if (tp->if_port & 1) outl(0x1F868, ioaddr + 0xB8); if (phy_reg & 0x30000000) { tp->full_duplex = 1; new_csr6 |= 0x00000200; }#ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: PNIC autonegotiated status %X, %s.\n", tp->nic_name, phy_reg, medianame[tp->if_port]);#endif if (tp->csr6 != new_csr6) { tp->csr6 = new_csr6; outl(tp->csr6 | 0x0002, ioaddr + CSR6); /* Restart Tx */ outl(tp->csr6 | 0x2002, ioaddr + CSR6); } }}/* Set up the transceiver control registers for the selected media type. */static void select_media(struct nic *nic, int startup){ struct mediatable *mtable = tp->mtable; u32 new_csr6; int i;#ifdef TULIP_DEBUG_WHERE whereami("select_media\n");#endif if (mtable) { struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index]; unsigned char *p = mleaf->leafdata; switch (mleaf->type) { case 0: /* 21140 non-MII xcvr. */#ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: Using a 21140 non-MII transceiver" " with control setting %hhX.\n", tp->nic_name, p[1]);#endif tp->if_port = p[0]; if (startup) outl(mtable->csr12dir | 0x100, ioaddr + CSR12); outl(p[1], ioaddr + CSR12); new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18); break; case 2: case 4: { u16 setup[5]; u32 csr13val, csr14val, csr15dir, csr15val; for (i = 0; i < 5; i++) setup[i] = get_u16(&p[i*2 + 1]); tp->if_port = p[0] & 15; if (media_cap[tp->if_port] & MediaAlwaysFD) tp->full_duplex = 1; if (startup && mtable->has_reset) { struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset]; unsigned char *rst = rleaf->leafdata;#ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: Resetting the transceiver.\n", tp->nic_name);#endif for (i = 0; i < rst[0]; i++) outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15); }#ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: 21143 non-MII %s transceiver control " "%hX/%hX.\n", tp->nic_name, medianame[tp->if_port], setup[0], setup[1]);#endif if (p[0] & 0x40) { /* SIA (CSR13-15) setup values are provided. */ csr13val = setup[0]; csr14val = setup[1]; csr15dir = (setup[3]<<16) | setup[2]; csr15val = (setup[4]<<16) | setup[2]; outl(0, ioaddr + CSR13); outl(csr14val, ioaddr + CSR14); outl(csr15dir, ioaddr + CSR15); /* Direction */ outl(csr15val, ioaddr + CSR15); /* Data */ outl(csr13val, ioaddr + CSR13); } else { csr13val = 1; csr14val = 0x0003FF7F; csr15dir = (setup[0]<<16) | 0x0008; csr15val = (setup[1]<<16) | 0x0008; if (tp->if_port <= 4) csr14val = t21142_csr14[tp->if_port]; if (startup) { outl(0, ioaddr + CSR13); outl(csr14val, ioaddr + CSR14); } outl(csr15dir, ioaddr + CSR15); /* Direction */ outl(csr15val, ioaddr + CSR15); /* Data */ if (startup) outl(csr13val, ioaddr + CSR13); }#ifdef TULIP_DEBUG if (tulip_debug > 1) printf("%s: Setting CSR15 to %X/%X.\n", tp->nic_name, csr15dir, csr15val);#endif if (mleaf->type == 4) new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18); else new_csr6 = 0x82420000; break; } case 1: case 3: { int phy_num = p[0]; int init_length = p[1]; u16 *misc_info; tp->if_port = 11; new_csr6 = 0x020E0000; if (mleaf->type == 3) { /* 21142 */ u16 *init_sequence = (u16*)(p+2); u16 *reset_sequence = &((u16*)(p+3))[init_length]; int reset_length = p[2 + init_length*2]; misc_info = reset_sequence + reset_length; if (startup) for (i = 0; i < reset_length; i++) outl(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); for (i = 0; i < init_length; i++) outl(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15); } else { u8 *init_sequence = p + 2; u8 *reset_sequence = p + 3 + init_length; int reset_length = p[2 + init_length]; misc_info = (u16*)(reset_sequence + reset_length); if (startup) { outl(mtable->csr12dir | 0x100, ioaddr + CSR12); for (i = 0; i < reset_length; i++) outl(reset_sequence[i], ioaddr + CSR12);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -