28 * 29 * MAINTAINER: Matthew N. Dodd <winter@jurai.net> 30 * <mdodd@FreeBSD.org> 31 */ 32 33/* 34 * Intel EtherExpress Pro/10, Pro/10+ Ethernet driver 35 * 36 * Revision history: 37 * 38 * 30-Oct-1996: first beta version. Inet and BPF supported, but no multicast. 39 */ 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/kernel.h> 44#include <sys/sockio.h> 45#include <sys/mbuf.h> 46#include <sys/socket.h> 47 48#include <sys/module.h> 49#include <sys/bus.h> 50 51#include <machine/bus.h> 52#include <machine/resource.h> 53#include <sys/rman.h> 54 55#include <net/if.h> 56#include <net/if_arp.h> 57#include <net/if_media.h> 58#include <net/ethernet.h> 59#include <net/bpf.h> 60 61#include <netinet/in.h> 62#include <netinet/if_ether.h> 63 64#include <machine/clock.h> 65 66#include <isa/isavar.h> 67#include <isa/pnpvar.h> 68 69#include <dev/ex/if_exreg.h> 70#include <dev/ex/if_exvar.h> 71 72#ifdef EXDEBUG 73# define Start_End 1 74# define Rcvd_Pkts 2 75# define Sent_Pkts 4 76# define Status 8 77static int debug_mask = 0; 78static int exintr_count = 0; 79# define DODEBUG(level, action) if (level & debug_mask) action 80#else 81# define DODEBUG(level, action) 82#endif 83 84char irq2eemap[] = 85 { -1, -1, 0, 1, -1, 2, -1, -1, -1, 0, 3, 4, -1, -1, -1, -1 }; 86u_char ee2irqmap[] = 87 { 9, 3, 5, 10, 11, 0, 0, 0 }; 88 89char plus_irq2eemap[] = 90 { -1, -1, -1, 0, 1, 2, -1, 3, -1, 4, 5, 6, 7, -1, -1, -1 }; 91u_char plus_ee2irqmap[] = 92 { 3, 4, 5, 7, 9, 10, 11, 12 }; 93 94/* Network Interface Functions */ 95static void ex_init __P((void *)); 96static void ex_start __P((struct ifnet *)); 97static int ex_ioctl __P((struct ifnet *, u_long, caddr_t)); 98static void ex_watchdog __P((struct ifnet *)); 99 100/* ifmedia Functions */ 101static int ex_ifmedia_upd __P((struct ifnet *)); 102static void ex_ifmedia_sts __P((struct ifnet *, struct ifmediareq *)); 103 104static int ex_get_media __P((u_int32_t iobase)); 105 106static void ex_stop __P((struct ex_softc *)); 107static void ex_reset __P((struct ex_softc *)); 108 109static void ex_tx_intr __P((struct ex_softc *)); 110static void ex_rx_intr __P((struct ex_softc *)); 111 112int 113look_for_card (u_int32_t iobase) 114{ 115 int count1, count2; 116 117 /* 118 * Check for the i82595 signature, and check that the round robin 119 * counter actually advances. 120 */ 121 if (((count1 = inb(iobase + ID_REG)) & Id_Mask) != Id_Sig) 122 return(0); 123 count2 = inb(iobase + ID_REG); 124 count2 = inb(iobase + ID_REG); 125 count2 = inb(iobase + ID_REG); 126 127 return((count2 & Counter_bits) == ((count1 + 0xc0) & Counter_bits)); 128} 129 130void 131ex_get_address (u_int32_t iobase, u_char *enaddr) 132{ 133 u_int16_t eaddr_tmp; 134 135 eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Lo); 136 enaddr[5] = eaddr_tmp & 0xff; 137 enaddr[4] = eaddr_tmp >> 8; 138 eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Mid); 139 enaddr[3] = eaddr_tmp & 0xff; 140 enaddr[2] = eaddr_tmp >> 8; 141 eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Hi); 142 enaddr[1] = eaddr_tmp & 0xff; 143 enaddr[0] = eaddr_tmp >> 8; 144 145 return; 146} 147 148int 149ex_card_type (u_char *enaddr) 150{ 151 if ((enaddr[0] == 0x00) && (enaddr[1] == 0xA0) && (enaddr[2] == 0xC9)) 152 return (CARD_TYPE_EX_10_PLUS); 153 154 return (CARD_TYPE_EX_10); 155} 156 157/* 158 * Caller is responsible for eventually calling 159 * ex_release_resources() on failure. 160 */ 161int 162ex_alloc_resources (device_t dev) 163{ 164 struct ex_softc * sc = device_get_softc(dev); 165 int error = 0; 166 167 sc->ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->ioport_rid, 168 0, ~0, 1, RF_ACTIVE); 169 if (!sc->ioport) { 170 device_printf(dev, "No I/O space?!\n"); 171 error = ENOMEM; 172 goto bad; 173 } 174 175 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, 176 0, ~0, 1, RF_ACTIVE); 177 178 if (!sc->irq) { 179 device_printf(dev, "No IRQ?!\n"); 180 error = ENOMEM; 181 goto bad; 182 } 183 184bad: 185 return (error); 186} 187 188void 189ex_release_resources (device_t dev) 190{ 191 struct ex_softc * sc = device_get_softc(dev); 192 193 if (sc->ih) { 194 bus_teardown_intr(dev, sc->irq, sc->ih); 195 sc->ih = NULL; 196 } 197 198 if (sc->ioport) { 199 bus_release_resource(dev, SYS_RES_IOPORT, 200 sc->ioport_rid, sc->ioport); 201 sc->ioport = NULL; 202 } 203 204 if (sc->irq) { 205 bus_release_resource(dev, SYS_RES_IRQ, 206 sc->irq_rid, sc->irq); 207 sc->irq = NULL; 208 } 209 210 return; 211} 212 213int 214ex_attach(device_t dev) 215{ 216 struct ex_softc * sc = device_get_softc(dev); 217 struct ifnet * ifp = &sc->arpcom.ac_if; 218 struct ifmedia * ifm; 219 int unit = device_get_unit(dev); 220 u_int16_t temp; 221 222 /* work out which set of irq <-> internal tables to use */ 223 if (ex_card_type(sc->arpcom.ac_enaddr) == CARD_TYPE_EX_10_PLUS) { 224 sc->irq2ee = plus_irq2eemap; 225 sc->ee2irq = plus_ee2irqmap; 226 } else { 227 sc->irq2ee = irq2eemap; 228 sc->ee2irq = ee2irqmap; 229 } 230 231 sc->mem_size = CARD_RAM_SIZE; /* XXX This should be read from the card itself. */ 232 233 /* 234 * Initialize the ifnet structure. 235 */ 236 ifp->if_softc = sc; 237 ifp->if_unit = unit; 238 ifp->if_name = "ex"; 239 ifp->if_mtu = ETHERMTU; 240 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST /* XXX not done yet. | IFF_MULTICAST */; 241 ifp->if_output = ether_output; 242 ifp->if_start = ex_start; 243 ifp->if_ioctl = ex_ioctl; 244 ifp->if_watchdog = ex_watchdog; 245 ifp->if_init = ex_init; 246 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 247 248 ifmedia_init(&sc->ifmedia, 0, ex_ifmedia_upd, ex_ifmedia_sts); 249 250 temp = eeprom_read(sc->iobase, EE_W5); 251 if (temp & EE_W5_PORT_TPE) 252 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); 253 if (temp & EE_W5_PORT_BNC) 254 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_2, 0, NULL); 255 if (temp & EE_W5_PORT_AUI) 256 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_5, 0, NULL); 257 258 ifmedia_set(&sc->ifmedia, ex_get_media(sc->iobase)); 259 260 ifm = &sc->ifmedia; 261 ifm->ifm_media = ifm->ifm_cur->ifm_media; 262 ex_ifmedia_upd(ifp); 263 264 /* 265 * Attach the interface. 266 */
| 28 * 29 * MAINTAINER: Matthew N. Dodd <winter@jurai.net> 30 * <mdodd@FreeBSD.org> 31 */ 32 33/* 34 * Intel EtherExpress Pro/10, Pro/10+ Ethernet driver 35 * 36 * Revision history: 37 * 38 * 30-Oct-1996: first beta version. Inet and BPF supported, but no multicast. 39 */ 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/kernel.h> 44#include <sys/sockio.h> 45#include <sys/mbuf.h> 46#include <sys/socket.h> 47 48#include <sys/module.h> 49#include <sys/bus.h> 50 51#include <machine/bus.h> 52#include <machine/resource.h> 53#include <sys/rman.h> 54 55#include <net/if.h> 56#include <net/if_arp.h> 57#include <net/if_media.h> 58#include <net/ethernet.h> 59#include <net/bpf.h> 60 61#include <netinet/in.h> 62#include <netinet/if_ether.h> 63 64#include <machine/clock.h> 65 66#include <isa/isavar.h> 67#include <isa/pnpvar.h> 68 69#include <dev/ex/if_exreg.h> 70#include <dev/ex/if_exvar.h> 71 72#ifdef EXDEBUG 73# define Start_End 1 74# define Rcvd_Pkts 2 75# define Sent_Pkts 4 76# define Status 8 77static int debug_mask = 0; 78static int exintr_count = 0; 79# define DODEBUG(level, action) if (level & debug_mask) action 80#else 81# define DODEBUG(level, action) 82#endif 83 84char irq2eemap[] = 85 { -1, -1, 0, 1, -1, 2, -1, -1, -1, 0, 3, 4, -1, -1, -1, -1 }; 86u_char ee2irqmap[] = 87 { 9, 3, 5, 10, 11, 0, 0, 0 }; 88 89char plus_irq2eemap[] = 90 { -1, -1, -1, 0, 1, 2, -1, 3, -1, 4, 5, 6, 7, -1, -1, -1 }; 91u_char plus_ee2irqmap[] = 92 { 3, 4, 5, 7, 9, 10, 11, 12 }; 93 94/* Network Interface Functions */ 95static void ex_init __P((void *)); 96static void ex_start __P((struct ifnet *)); 97static int ex_ioctl __P((struct ifnet *, u_long, caddr_t)); 98static void ex_watchdog __P((struct ifnet *)); 99 100/* ifmedia Functions */ 101static int ex_ifmedia_upd __P((struct ifnet *)); 102static void ex_ifmedia_sts __P((struct ifnet *, struct ifmediareq *)); 103 104static int ex_get_media __P((u_int32_t iobase)); 105 106static void ex_stop __P((struct ex_softc *)); 107static void ex_reset __P((struct ex_softc *)); 108 109static void ex_tx_intr __P((struct ex_softc *)); 110static void ex_rx_intr __P((struct ex_softc *)); 111 112int 113look_for_card (u_int32_t iobase) 114{ 115 int count1, count2; 116 117 /* 118 * Check for the i82595 signature, and check that the round robin 119 * counter actually advances. 120 */ 121 if (((count1 = inb(iobase + ID_REG)) & Id_Mask) != Id_Sig) 122 return(0); 123 count2 = inb(iobase + ID_REG); 124 count2 = inb(iobase + ID_REG); 125 count2 = inb(iobase + ID_REG); 126 127 return((count2 & Counter_bits) == ((count1 + 0xc0) & Counter_bits)); 128} 129 130void 131ex_get_address (u_int32_t iobase, u_char *enaddr) 132{ 133 u_int16_t eaddr_tmp; 134 135 eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Lo); 136 enaddr[5] = eaddr_tmp & 0xff; 137 enaddr[4] = eaddr_tmp >> 8; 138 eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Mid); 139 enaddr[3] = eaddr_tmp & 0xff; 140 enaddr[2] = eaddr_tmp >> 8; 141 eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Hi); 142 enaddr[1] = eaddr_tmp & 0xff; 143 enaddr[0] = eaddr_tmp >> 8; 144 145 return; 146} 147 148int 149ex_card_type (u_char *enaddr) 150{ 151 if ((enaddr[0] == 0x00) && (enaddr[1] == 0xA0) && (enaddr[2] == 0xC9)) 152 return (CARD_TYPE_EX_10_PLUS); 153 154 return (CARD_TYPE_EX_10); 155} 156 157/* 158 * Caller is responsible for eventually calling 159 * ex_release_resources() on failure. 160 */ 161int 162ex_alloc_resources (device_t dev) 163{ 164 struct ex_softc * sc = device_get_softc(dev); 165 int error = 0; 166 167 sc->ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->ioport_rid, 168 0, ~0, 1, RF_ACTIVE); 169 if (!sc->ioport) { 170 device_printf(dev, "No I/O space?!\n"); 171 error = ENOMEM; 172 goto bad; 173 } 174 175 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, 176 0, ~0, 1, RF_ACTIVE); 177 178 if (!sc->irq) { 179 device_printf(dev, "No IRQ?!\n"); 180 error = ENOMEM; 181 goto bad; 182 } 183 184bad: 185 return (error); 186} 187 188void 189ex_release_resources (device_t dev) 190{ 191 struct ex_softc * sc = device_get_softc(dev); 192 193 if (sc->ih) { 194 bus_teardown_intr(dev, sc->irq, sc->ih); 195 sc->ih = NULL; 196 } 197 198 if (sc->ioport) { 199 bus_release_resource(dev, SYS_RES_IOPORT, 200 sc->ioport_rid, sc->ioport); 201 sc->ioport = NULL; 202 } 203 204 if (sc->irq) { 205 bus_release_resource(dev, SYS_RES_IRQ, 206 sc->irq_rid, sc->irq); 207 sc->irq = NULL; 208 } 209 210 return; 211} 212 213int 214ex_attach(device_t dev) 215{ 216 struct ex_softc * sc = device_get_softc(dev); 217 struct ifnet * ifp = &sc->arpcom.ac_if; 218 struct ifmedia * ifm; 219 int unit = device_get_unit(dev); 220 u_int16_t temp; 221 222 /* work out which set of irq <-> internal tables to use */ 223 if (ex_card_type(sc->arpcom.ac_enaddr) == CARD_TYPE_EX_10_PLUS) { 224 sc->irq2ee = plus_irq2eemap; 225 sc->ee2irq = plus_ee2irqmap; 226 } else { 227 sc->irq2ee = irq2eemap; 228 sc->ee2irq = ee2irqmap; 229 } 230 231 sc->mem_size = CARD_RAM_SIZE; /* XXX This should be read from the card itself. */ 232 233 /* 234 * Initialize the ifnet structure. 235 */ 236 ifp->if_softc = sc; 237 ifp->if_unit = unit; 238 ifp->if_name = "ex"; 239 ifp->if_mtu = ETHERMTU; 240 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST /* XXX not done yet. | IFF_MULTICAST */; 241 ifp->if_output = ether_output; 242 ifp->if_start = ex_start; 243 ifp->if_ioctl = ex_ioctl; 244 ifp->if_watchdog = ex_watchdog; 245 ifp->if_init = ex_init; 246 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; 247 248 ifmedia_init(&sc->ifmedia, 0, ex_ifmedia_upd, ex_ifmedia_sts); 249 250 temp = eeprom_read(sc->iobase, EE_W5); 251 if (temp & EE_W5_PORT_TPE) 252 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_T, 0, NULL); 253 if (temp & EE_W5_PORT_BNC) 254 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_2, 0, NULL); 255 if (temp & EE_W5_PORT_AUI) 256 ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_10_5, 0, NULL); 257 258 ifmedia_set(&sc->ifmedia, ex_get_media(sc->iobase)); 259 260 ifm = &sc->ifmedia; 261 ifm->ifm_media = ifm->ifm_cur->ifm_media; 262 ex_ifmedia_upd(ifp); 263 264 /* 265 * Attach the interface. 266 */
|
276 277 return(0); 278} 279 280static void 281ex_init(void *xsc) 282{ 283 struct ex_softc * sc = (struct ex_softc *) xsc; 284 struct ifnet * ifp = &sc->arpcom.ac_if; 285 int s; 286 int i; 287 register int iobase = sc->iobase; 288 unsigned short temp_reg; 289 290 DODEBUG(Start_End, printf("ex_init%d: start\n", ifp->if_unit);); 291 292 if (ifp->if_addrhead.tqh_first == NULL) { 293 return; 294 } 295 s = splimp(); 296 ifp->if_timer = 0; 297 298 /* 299 * Load the ethernet address into the card. 300 */ 301 outb(iobase + CMD_REG, Bank2_Sel); 302 temp_reg = inb(iobase + EEPROM_REG); 303 if (temp_reg & Trnoff_Enable) { 304 outb(iobase + EEPROM_REG, temp_reg & ~Trnoff_Enable); 305 } 306 for (i = 0; i < ETHER_ADDR_LEN; i++) { 307 outb(iobase + I_ADDR_REG0 + i, sc->arpcom.ac_enaddr[i]); 308 } 309 /* 310 * - Setup transmit chaining and discard bad received frames. 311 * - Match broadcast. 312 * - Clear test mode. 313 * - Set receiving mode. 314 * - Set IRQ number. 315 */ 316 outb(iobase + REG1, inb(iobase + REG1) | Tx_Chn_Int_Md | Tx_Chn_ErStp | Disc_Bad_Fr); 317 outb(iobase + REG2, inb(iobase + REG2) | No_SA_Ins | RX_CRC_InMem); 318 outb(iobase + REG3, inb(iobase + REG3) & 0x3f /* XXX constants. */ ); 319 outb(iobase + CMD_REG, Bank1_Sel); 320 outb(iobase + INT_NO_REG, (inb(iobase + INT_NO_REG) & 0xf8) | sc->irq2ee[sc->irq_no]); 321 322 /* 323 * Divide the available memory in the card into rcv and xmt buffers. 324 * By default, I use the first 3/4 of the memory for the rcv buffer, 325 * and the remaining 1/4 of the memory for the xmt buffer. 326 */ 327 sc->rx_mem_size = sc->mem_size * 3 / 4; 328 sc->tx_mem_size = sc->mem_size - sc->rx_mem_size; 329 sc->rx_lower_limit = 0x0000; 330 sc->rx_upper_limit = sc->rx_mem_size - 2; 331 sc->tx_lower_limit = sc->rx_mem_size; 332 sc->tx_upper_limit = sc->mem_size - 2; 333 outb(iobase + RCV_LOWER_LIMIT_REG, sc->rx_lower_limit >> 8); 334 outb(iobase + RCV_UPPER_LIMIT_REG, sc->rx_upper_limit >> 8); 335 outb(iobase + XMT_LOWER_LIMIT_REG, sc->tx_lower_limit >> 8); 336 outb(iobase + XMT_UPPER_LIMIT_REG, sc->tx_upper_limit >> 8); 337 338 /* 339 * Enable receive and transmit interrupts, and clear any pending int. 340 */ 341 outb(iobase + REG1, inb(iobase + REG1) | TriST_INT); 342 outb(iobase + CMD_REG, Bank0_Sel); 343 outb(iobase + MASK_REG, All_Int & ~(Rx_Int | Tx_Int)); 344 outb(iobase + STATUS_REG, All_Int); 345 346 /* 347 * Initialize receive and transmit ring buffers. 348 */ 349 outw(iobase + RCV_BAR, sc->rx_lower_limit); 350 sc->rx_head = sc->rx_lower_limit; 351 outw(iobase + RCV_STOP_REG, sc->rx_upper_limit | 0xfe); 352 outw(iobase + XMT_BAR, sc->tx_lower_limit); 353 sc->tx_head = sc->tx_tail = sc->tx_lower_limit; 354 355 ifp->if_flags |= IFF_RUNNING; 356 ifp->if_flags &= ~IFF_OACTIVE; 357 DODEBUG(Status, printf("OIDLE init\n");); 358 359 /* 360 * Final reset of the board, and enable operation. 361 */ 362 outb(iobase + CMD_REG, Sel_Reset_CMD); 363 DELAY(2); 364 outb(iobase + CMD_REG, Rcv_Enable_CMD); 365 366 ex_start(ifp); 367 splx(s); 368 369 DODEBUG(Start_End, printf("ex_init%d: finish\n", ifp->if_unit);); 370} 371 372 373static void 374ex_start(struct ifnet *ifp) 375{ 376 struct ex_softc * sc = ifp->if_softc; 377 int iobase = sc->iobase; 378 int i, s, len, data_len, avail, dest, next; 379 unsigned char tmp16[2]; 380 struct mbuf * opkt; 381 struct mbuf * m; 382 383 DODEBUG(Start_End, printf("ex_start%d: start\n", unit);); 384 385 s = splimp(); 386 387 /* 388 * Main loop: send outgoing packets to network card until there are no 389 * more packets left, or the card cannot accept any more yet. 390 */ 391 while (((opkt = ifp->if_snd.ifq_head) != NULL) && 392 !(ifp->if_flags & IFF_OACTIVE)) { 393 394 /* 395 * Ensure there is enough free transmit buffer space for 396 * this packet, including its header. Note: the header 397 * cannot wrap around the end of the transmit buffer and 398 * must be kept together, so we allow space for twice the 399 * length of the header, just in case. 400 */ 401 402 for (len = 0, m = opkt; m != NULL; m = m->m_next) { 403 len += m->m_len; 404 } 405 406 data_len = len; 407 408 DODEBUG(Sent_Pkts, printf("1. Sending packet with %d data bytes. ", data_len);); 409 410 if (len & 1) { 411 len += XMT_HEADER_LEN + 1; 412 } else { 413 len += XMT_HEADER_LEN; 414 } 415 416 if ((i = sc->tx_tail - sc->tx_head) >= 0) { 417 avail = sc->tx_mem_size - i; 418 } else { 419 avail = -i; 420 } 421 422 DODEBUG(Sent_Pkts, printf("i=%d, avail=%d\n", i, avail);); 423 424 if (avail >= len + XMT_HEADER_LEN) { 425 IF_DEQUEUE(&ifp->if_snd, opkt); 426 427#ifdef EX_PSA_INTR 428 /* 429 * Disable rx and tx interrupts, to avoid corruption 430 * of the host address register by interrupt service 431 * routines. 432 * XXX Is this necessary with splimp() enabled? 433 */ 434 outb(iobase + MASK_REG, All_Int); 435#endif 436 437 /* 438 * Compute the start and end addresses of this 439 * frame in the tx buffer. 440 */ 441 dest = sc->tx_tail; 442 next = dest + len; 443 444 if (next > sc->tx_upper_limit) { 445 if ((sc->tx_upper_limit + 2 - sc->tx_tail) <= 446 XMT_HEADER_LEN) { 447 dest = sc->tx_lower_limit; 448 next = dest + len; 449 } else { 450 next = sc->tx_lower_limit + 451 next - sc->tx_upper_limit - 2; 452 } 453 } 454 455 /* 456 * Build the packet frame in the card's ring buffer. 457 */ 458 DODEBUG(Sent_Pkts, printf("2. dest=%d, next=%d. ", dest, next);); 459 460 outw(iobase + HOST_ADDR_REG, dest); 461 outw(iobase + IO_PORT_REG, Transmit_CMD); 462 outw(iobase + IO_PORT_REG, 0); 463 outw(iobase + IO_PORT_REG, next); 464 outw(iobase + IO_PORT_REG, data_len); 465 466 /* 467 * Output the packet data to the card. Ensure all 468 * transfers are 16-bit wide, even if individual 469 * mbufs have odd length. 470 */ 471 472 for (m = opkt, i = 0; m != NULL; m = m->m_next) { 473 DODEBUG(Sent_Pkts, printf("[%d]", m->m_len);); 474 if (i) { 475 tmp16[1] = *(mtod(m, caddr_t)); 476 outsw(iobase + IO_PORT_REG, tmp16, 1); 477 } 478 outsw(iobase + IO_PORT_REG, 479 mtod(m, caddr_t) + i, (m->m_len - i) / 2); 480 481 if ((i = (m->m_len - i) & 1) != 0) { 482 tmp16[0] = *(mtod(m, caddr_t) + 483 m->m_len - 1); 484 } 485 } 486 if (i) { 487 outsw(iobase + IO_PORT_REG, tmp16, 1); 488 } 489 490 /* 491 * If there were other frames chained, update the 492 * chain in the last one. 493 */ 494 if (sc->tx_head != sc->tx_tail) { 495 if (sc->tx_tail != dest) { 496 outw(iobase + HOST_ADDR_REG, 497 sc->tx_last + XMT_Chain_Point); 498 outw(iobase + IO_PORT_REG, dest); 499 } 500 outw(iobase + HOST_ADDR_REG, 501 sc->tx_last + XMT_Byte_Count); 502 i = inw(iobase + IO_PORT_REG); 503 outw(iobase + HOST_ADDR_REG, 504 sc->tx_last + XMT_Byte_Count); 505 outw(iobase + IO_PORT_REG, i | Ch_bit); 506 } 507 508 /* 509 * Resume normal operation of the card: 510 * - Make a dummy read to flush the DRAM write 511 * pipeline. 512 * - Enable receive and transmit interrupts. 513 * - Send Transmit or Resume_XMT command, as 514 * appropriate. 515 */ 516 inw(iobase + IO_PORT_REG); 517#ifdef EX_PSA_INTR 518 outb(iobase + MASK_REG, All_Int & ~(Rx_Int | Tx_Int)); 519#endif 520 if (sc->tx_head == sc->tx_tail) { 521 outw(iobase + XMT_BAR, dest); 522 outb(iobase + CMD_REG, Transmit_CMD); 523 sc->tx_head = dest; 524 DODEBUG(Sent_Pkts, printf("Transmit\n");); 525 } else { 526 outb(iobase + CMD_REG, Resume_XMT_List_CMD); 527 DODEBUG(Sent_Pkts, printf("Resume\n");); 528 } 529 530 sc->tx_last = dest; 531 sc->tx_tail = next; 532 533 if (ifp->if_bpf != NULL) { 534 bpf_mtap(ifp, opkt); 535 } 536 537 ifp->if_timer = 2; 538 ifp->if_opackets++; 539 m_freem(opkt); 540 } else { 541 ifp->if_flags |= IFF_OACTIVE; 542 DODEBUG(Status, printf("OACTIVE start\n");); 543 } 544 } 545 546 splx(s); 547 548 DODEBUG(Start_End, printf("ex_start%d: finish\n", unit);); 549} 550 551static void 552ex_stop(struct ex_softc *sc) 553{ 554 int iobase = sc->iobase; 555 556 DODEBUG(Start_End, printf("ex_stop%d: start\n", unit);); 557 558 /* 559 * Disable card operation: 560 * - Disable the interrupt line. 561 * - Flush transmission and disable reception. 562 * - Mask and clear all interrupts. 563 * - Reset the 82595. 564 */ 565 outb(iobase + CMD_REG, Bank1_Sel); 566 outb(iobase + REG1, inb(iobase + REG1) & ~TriST_INT); 567 outb(iobase + CMD_REG, Bank0_Sel); 568 outb(iobase + CMD_REG, Rcv_Stop); 569 sc->tx_head = sc->tx_tail = sc->tx_lower_limit; 570 sc->tx_last = 0; /* XXX I think these two lines are not necessary, because ex_init will always be called again to reinit the interface. */ 571 outb(iobase + MASK_REG, All_Int); 572 outb(iobase + STATUS_REG, All_Int); 573 outb(iobase + CMD_REG, Reset_CMD); 574 DELAY(200); 575 576 DODEBUG(Start_End, printf("ex_stop%d: finish\n", unit);); 577 578 return; 579} 580 581void 582ex_intr(void *arg) 583{ 584 struct ex_softc * sc = (struct ex_softc *)arg; 585 struct ifnet * ifp = &sc->arpcom.ac_if; 586 int iobase = sc->iobase; 587 int int_status, send_pkts; 588 589 DODEBUG(Start_End, printf("ex_intr%d: start\n", unit);); 590 591#ifdef EXDEBUG 592 if (++exintr_count != 1) 593 printf("WARNING: nested interrupt (%d). Mail the author.\n", exintr_count); 594#endif 595 596 send_pkts = 0; 597 while ((int_status = inb(iobase + STATUS_REG)) & (Tx_Int | Rx_Int)) { 598 if (int_status & Rx_Int) { 599 outb(iobase + STATUS_REG, Rx_Int); 600 601 ex_rx_intr(sc); 602 } else if (int_status & Tx_Int) { 603 outb(iobase + STATUS_REG, Tx_Int); 604 605 ex_tx_intr(sc); 606 send_pkts = 1; 607 } 608 } 609 610 /* 611 * If any packet has been transmitted, and there are queued packets to 612 * be sent, attempt to send more packets to the network card. 613 */ 614 615 if (send_pkts && (ifp->if_snd.ifq_head != NULL)) { 616 ex_start(ifp); 617 } 618 619#ifdef EXDEBUG 620 exintr_count--; 621#endif 622 623 DODEBUG(Start_End, printf("ex_intr%d: finish\n", unit);); 624 625 return; 626} 627 628static void 629ex_tx_intr(struct ex_softc *sc) 630{ 631 struct ifnet * ifp = &sc->arpcom.ac_if; 632 int iobase = sc->iobase; 633 int tx_status; 634 635 DODEBUG(Start_End, printf("ex_tx_intr%d: start\n", unit);); 636 637 /* 638 * - Cancel the watchdog. 639 * For all packets transmitted since last transmit interrupt: 640 * - Advance chain pointer to next queued packet. 641 * - Update statistics. 642 */ 643 644 ifp->if_timer = 0; 645 646 while (sc->tx_head != sc->tx_tail) { 647 outw(iobase + HOST_ADDR_REG, sc->tx_head); 648 649 if (! inw(iobase + IO_PORT_REG) & Done_bit) 650 break; 651 652 tx_status = inw(iobase + IO_PORT_REG); 653 sc->tx_head = inw(iobase + IO_PORT_REG); 654 655 if (tx_status & TX_OK_bit) { 656 ifp->if_opackets++; 657 } else { 658 ifp->if_oerrors++; 659 } 660 661 ifp->if_collisions += tx_status & No_Collisions_bits; 662 } 663 664 /* 665 * The card should be ready to accept more packets now. 666 */ 667 668 ifp->if_flags &= ~IFF_OACTIVE; 669 670 DODEBUG(Status, printf("OIDLE tx_intr\n");); 671 DODEBUG(Start_End, printf("ex_tx_intr%d: finish\n", unit);); 672 673 return; 674} 675 676static void 677ex_rx_intr(struct ex_softc *sc) 678{ 679 struct ifnet * ifp = &sc->arpcom.ac_if; 680 int iobase = sc->iobase; 681 int rx_status; 682 int pkt_len; 683 int QQQ; 684 struct mbuf * m; 685 struct mbuf * ipkt; 686 struct ether_header * eh; 687 688 DODEBUG(Start_End, printf("ex_rx_intr%d: start\n", unit);); 689 690 /* 691 * For all packets received since last receive interrupt: 692 * - If packet ok, read it into a new mbuf and queue it to interface, 693 * updating statistics. 694 * - If packet bad, just discard it, and update statistics. 695 * Finally, advance receive stop limit in card's memory to new location. 696 */ 697 698 outw(iobase + HOST_ADDR_REG, sc->rx_head); 699 700 while (inw(iobase + IO_PORT_REG) == RCV_Done) { 701 702 rx_status = inw(iobase + IO_PORT_REG); 703 sc->rx_head = inw(iobase + IO_PORT_REG); 704 QQQ = pkt_len = inw(iobase + IO_PORT_REG); 705 706 if (rx_status & RCV_OK_bit) { 707 MGETHDR(m, M_DONTWAIT, MT_DATA); 708 ipkt = m; 709 if (ipkt == NULL) { 710 ifp->if_iqdrops++; 711 } else { 712 ipkt->m_pkthdr.rcvif = ifp; 713 ipkt->m_pkthdr.len = pkt_len; 714 ipkt->m_len = MHLEN; 715 716 while (pkt_len > 0) { 717 if (pkt_len > MINCLSIZE) { 718 MCLGET(m, M_DONTWAIT); 719 if (m->m_flags & M_EXT) { 720 m->m_len = MCLBYTES; 721 } else { 722 m_freem(ipkt); 723 ifp->if_iqdrops++; 724 goto rx_another; 725 } 726 } 727 m->m_len = min(m->m_len, pkt_len); 728 729 /* 730 * NOTE: I'm assuming that all mbufs allocated are of even length, 731 * except for the last one in an odd-length packet. 732 */ 733 734 insw(iobase + IO_PORT_REG, 735 mtod(m, caddr_t), m->m_len / 2); 736 737 if (m->m_len & 1) { 738 *(mtod(m, caddr_t) + m->m_len - 1) = inb(iobase + IO_PORT_REG); 739 } 740 pkt_len -= m->m_len; 741 742 if (pkt_len > 0) { 743 MGET(m->m_next, M_DONTWAIT, MT_DATA); 744 if (m->m_next == NULL) { 745 m_freem(ipkt); 746 ifp->if_iqdrops++; 747 goto rx_another; 748 } 749 m = m->m_next; 750 m->m_len = MLEN; 751 } 752 } 753 eh = mtod(ipkt, struct ether_header *); 754#ifdef EXDEBUG 755 if (debug_mask & Rcvd_Pkts) { 756 if ((eh->ether_dhost[5] != 0xff) || (eh->ether_dhost[0] != 0xff)) { 757 printf("Receive packet with %d data bytes: %6D -> ", QQQ, eh->ether_shost, ":"); 758 printf("%6D\n", eh->ether_dhost, ":"); 759 } /* QQQ */ 760 } 761#endif 762 m_adj(ipkt, sizeof(struct ether_header)); 763 ether_input(ifp, eh, ipkt); 764 ifp->if_ipackets++; 765 } 766 } else { 767 ifp->if_ierrors++; 768 } 769 outw(iobase + HOST_ADDR_REG, sc->rx_head); 770rx_another: ; 771 } 772 773 if (sc->rx_head < sc->rx_lower_limit + 2) 774 outw(iobase + RCV_STOP_REG, sc->rx_upper_limit); 775 else 776 outw(iobase + RCV_STOP_REG, sc->rx_head - 2); 777 778 DODEBUG(Start_End, printf("ex_rx_intr%d: finish\n", unit);); 779 780 return; 781} 782 783 784static int 785ex_ioctl(register struct ifnet *ifp, u_long cmd, caddr_t data) 786{ 787 struct ex_softc * sc = ifp->if_softc; 788 struct ifreq * ifr = (struct ifreq *)data; 789 int s; 790 int error = 0; 791 792 DODEBUG(Start_End, printf("ex_ioctl%d: start ", ifp->if_unit);); 793 794 s = splimp(); 795 796 switch(cmd) { 797 case SIOCSIFADDR: 798 case SIOCGIFADDR: 799 case SIOCSIFMTU: 800 error = ether_ioctl(ifp, cmd, data); 801 break; 802 803 case SIOCSIFFLAGS: 804 DODEBUG(Start_End, printf("SIOCSIFFLAGS");); 805 if ((ifp->if_flags & IFF_UP) == 0 && 806 (ifp->if_flags & IFF_RUNNING)) { 807 808 ifp->if_flags &= ~IFF_RUNNING; 809 ex_stop(sc); 810 } else { 811 ex_init(sc); 812 } 813 break; 814#ifdef NODEF 815 case SIOCGHWADDR: 816 DODEBUG(Start_End, printf("SIOCGHWADDR");); 817 bcopy((caddr_t)sc->sc_addr, (caddr_t)&ifr->ifr_data, 818 sizeof(sc->sc_addr)); 819 break; 820#endif 821 case SIOCADDMULTI: 822 DODEBUG(Start_End, printf("SIOCADDMULTI");); 823 case SIOCDELMULTI: 824 DODEBUG(Start_End, printf("SIOCDELMULTI");); 825 /* XXX Support not done yet. */ 826 error = EINVAL; 827 break; 828 case SIOCSIFMEDIA: 829 case SIOCGIFMEDIA: 830 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd); 831 break; 832 default: 833 DODEBUG(Start_End, printf("unknown");); 834 error = EINVAL; 835 } 836 837 splx(s); 838 839 DODEBUG(Start_End, printf("\nex_ioctl%d: finish\n", ifp->if_unit);); 840 841 return(error); 842} 843 844 845static void 846ex_reset(struct ex_softc *sc) 847{ 848 int s; 849 850 DODEBUG(Start_End, printf("ex_reset%d: start\n", unit);); 851 852 s = splimp(); 853 854 ex_stop(sc); 855 ex_init(sc); 856 857 splx(s); 858 859 DODEBUG(Start_End, printf("ex_reset%d: finish\n", unit);); 860 861 return; 862} 863 864static void 865ex_watchdog(struct ifnet *ifp) 866{ 867 struct ex_softc * sc = ifp->if_softc; 868 869 DODEBUG(Start_End, printf("ex_watchdog%d: start\n", ifp->if_unit);); 870 871 ifp->if_flags &= ~IFF_OACTIVE; 872 873 DODEBUG(Status, printf("OIDLE watchdog\n");); 874 875 ifp->if_oerrors++; 876 ex_reset(sc); 877 ex_start(ifp); 878 879 DODEBUG(Start_End, printf("ex_watchdog%d: finish\n", ifp->if_unit);); 880 881 return; 882} 883 884static int 885ex_get_media (u_int32_t iobase) 886{ 887 int tmp; 888 889 outb(iobase + CMD_REG, Bank2_Sel); 890 tmp = inb(iobase + REG3); 891 outb(iobase + CMD_REG, Bank0_Sel); 892 893 if (tmp & TPE_bit) 894 return(IFM_ETHER|IFM_10_T); 895 if (tmp & BNC_bit) 896 return(IFM_ETHER|IFM_10_2); 897 898 return (IFM_ETHER|IFM_10_5); 899} 900 901static int 902ex_ifmedia_upd (ifp) 903 struct ifnet * ifp; 904{ 905 struct ex_softc * sc = ifp->if_softc; 906 907 return (0); 908} 909 910static void 911ex_ifmedia_sts(ifp, ifmr) 912 struct ifnet * ifp; 913 struct ifmediareq * ifmr; 914{ 915 struct ex_softc * sc = ifp->if_softc; 916 917 ifmr->ifm_active = ex_get_media(sc->iobase); 918 919 return; 920} 921 922u_short 923eeprom_read(u_int32_t iobase, int location) 924{ 925 int i; 926 u_short data = 0; 927 int ee_addr; 928 int read_cmd = location | EE_READ_CMD; 929 short ctrl_val = EECS; 930 931 ee_addr = iobase + EEPROM_REG; 932 outb(iobase + CMD_REG, Bank2_Sel); 933 outb(ee_addr, EECS); 934 for (i = 8; i >= 0; i--) { 935 short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val; 936 outb(ee_addr, outval); 937 outb(ee_addr, outval | EESK); 938 DELAY(3); 939 outb(ee_addr, outval); 940 DELAY(2); 941 } 942 outb(ee_addr, ctrl_val); 943 944 for (i = 16; i > 0; i--) { 945 outb(ee_addr, ctrl_val | EESK); 946 DELAY(3); 947 data = (data << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0); 948 outb(ee_addr, ctrl_val); 949 DELAY(2); 950 } 951 952 ctrl_val &= ~EECS; 953 outb(ee_addr, ctrl_val | EESK); 954 DELAY(3); 955 outb(ee_addr, ctrl_val); 956 DELAY(2); 957 outb(iobase + CMD_REG, Bank0_Sel); 958 return(data); 959}
| 271 272 return(0); 273} 274 275static void 276ex_init(void *xsc) 277{ 278 struct ex_softc * sc = (struct ex_softc *) xsc; 279 struct ifnet * ifp = &sc->arpcom.ac_if; 280 int s; 281 int i; 282 register int iobase = sc->iobase; 283 unsigned short temp_reg; 284 285 DODEBUG(Start_End, printf("ex_init%d: start\n", ifp->if_unit);); 286 287 if (ifp->if_addrhead.tqh_first == NULL) { 288 return; 289 } 290 s = splimp(); 291 ifp->if_timer = 0; 292 293 /* 294 * Load the ethernet address into the card. 295 */ 296 outb(iobase + CMD_REG, Bank2_Sel); 297 temp_reg = inb(iobase + EEPROM_REG); 298 if (temp_reg & Trnoff_Enable) { 299 outb(iobase + EEPROM_REG, temp_reg & ~Trnoff_Enable); 300 } 301 for (i = 0; i < ETHER_ADDR_LEN; i++) { 302 outb(iobase + I_ADDR_REG0 + i, sc->arpcom.ac_enaddr[i]); 303 } 304 /* 305 * - Setup transmit chaining and discard bad received frames. 306 * - Match broadcast. 307 * - Clear test mode. 308 * - Set receiving mode. 309 * - Set IRQ number. 310 */ 311 outb(iobase + REG1, inb(iobase + REG1) | Tx_Chn_Int_Md | Tx_Chn_ErStp | Disc_Bad_Fr); 312 outb(iobase + REG2, inb(iobase + REG2) | No_SA_Ins | RX_CRC_InMem); 313 outb(iobase + REG3, inb(iobase + REG3) & 0x3f /* XXX constants. */ ); 314 outb(iobase + CMD_REG, Bank1_Sel); 315 outb(iobase + INT_NO_REG, (inb(iobase + INT_NO_REG) & 0xf8) | sc->irq2ee[sc->irq_no]); 316 317 /* 318 * Divide the available memory in the card into rcv and xmt buffers. 319 * By default, I use the first 3/4 of the memory for the rcv buffer, 320 * and the remaining 1/4 of the memory for the xmt buffer. 321 */ 322 sc->rx_mem_size = sc->mem_size * 3 / 4; 323 sc->tx_mem_size = sc->mem_size - sc->rx_mem_size; 324 sc->rx_lower_limit = 0x0000; 325 sc->rx_upper_limit = sc->rx_mem_size - 2; 326 sc->tx_lower_limit = sc->rx_mem_size; 327 sc->tx_upper_limit = sc->mem_size - 2; 328 outb(iobase + RCV_LOWER_LIMIT_REG, sc->rx_lower_limit >> 8); 329 outb(iobase + RCV_UPPER_LIMIT_REG, sc->rx_upper_limit >> 8); 330 outb(iobase + XMT_LOWER_LIMIT_REG, sc->tx_lower_limit >> 8); 331 outb(iobase + XMT_UPPER_LIMIT_REG, sc->tx_upper_limit >> 8); 332 333 /* 334 * Enable receive and transmit interrupts, and clear any pending int. 335 */ 336 outb(iobase + REG1, inb(iobase + REG1) | TriST_INT); 337 outb(iobase + CMD_REG, Bank0_Sel); 338 outb(iobase + MASK_REG, All_Int & ~(Rx_Int | Tx_Int)); 339 outb(iobase + STATUS_REG, All_Int); 340 341 /* 342 * Initialize receive and transmit ring buffers. 343 */ 344 outw(iobase + RCV_BAR, sc->rx_lower_limit); 345 sc->rx_head = sc->rx_lower_limit; 346 outw(iobase + RCV_STOP_REG, sc->rx_upper_limit | 0xfe); 347 outw(iobase + XMT_BAR, sc->tx_lower_limit); 348 sc->tx_head = sc->tx_tail = sc->tx_lower_limit; 349 350 ifp->if_flags |= IFF_RUNNING; 351 ifp->if_flags &= ~IFF_OACTIVE; 352 DODEBUG(Status, printf("OIDLE init\n");); 353 354 /* 355 * Final reset of the board, and enable operation. 356 */ 357 outb(iobase + CMD_REG, Sel_Reset_CMD); 358 DELAY(2); 359 outb(iobase + CMD_REG, Rcv_Enable_CMD); 360 361 ex_start(ifp); 362 splx(s); 363 364 DODEBUG(Start_End, printf("ex_init%d: finish\n", ifp->if_unit);); 365} 366 367 368static void 369ex_start(struct ifnet *ifp) 370{ 371 struct ex_softc * sc = ifp->if_softc; 372 int iobase = sc->iobase; 373 int i, s, len, data_len, avail, dest, next; 374 unsigned char tmp16[2]; 375 struct mbuf * opkt; 376 struct mbuf * m; 377 378 DODEBUG(Start_End, printf("ex_start%d: start\n", unit);); 379 380 s = splimp(); 381 382 /* 383 * Main loop: send outgoing packets to network card until there are no 384 * more packets left, or the card cannot accept any more yet. 385 */ 386 while (((opkt = ifp->if_snd.ifq_head) != NULL) && 387 !(ifp->if_flags & IFF_OACTIVE)) { 388 389 /* 390 * Ensure there is enough free transmit buffer space for 391 * this packet, including its header. Note: the header 392 * cannot wrap around the end of the transmit buffer and 393 * must be kept together, so we allow space for twice the 394 * length of the header, just in case. 395 */ 396 397 for (len = 0, m = opkt; m != NULL; m = m->m_next) { 398 len += m->m_len; 399 } 400 401 data_len = len; 402 403 DODEBUG(Sent_Pkts, printf("1. Sending packet with %d data bytes. ", data_len);); 404 405 if (len & 1) { 406 len += XMT_HEADER_LEN + 1; 407 } else { 408 len += XMT_HEADER_LEN; 409 } 410 411 if ((i = sc->tx_tail - sc->tx_head) >= 0) { 412 avail = sc->tx_mem_size - i; 413 } else { 414 avail = -i; 415 } 416 417 DODEBUG(Sent_Pkts, printf("i=%d, avail=%d\n", i, avail);); 418 419 if (avail >= len + XMT_HEADER_LEN) { 420 IF_DEQUEUE(&ifp->if_snd, opkt); 421 422#ifdef EX_PSA_INTR 423 /* 424 * Disable rx and tx interrupts, to avoid corruption 425 * of the host address register by interrupt service 426 * routines. 427 * XXX Is this necessary with splimp() enabled? 428 */ 429 outb(iobase + MASK_REG, All_Int); 430#endif 431 432 /* 433 * Compute the start and end addresses of this 434 * frame in the tx buffer. 435 */ 436 dest = sc->tx_tail; 437 next = dest + len; 438 439 if (next > sc->tx_upper_limit) { 440 if ((sc->tx_upper_limit + 2 - sc->tx_tail) <= 441 XMT_HEADER_LEN) { 442 dest = sc->tx_lower_limit; 443 next = dest + len; 444 } else { 445 next = sc->tx_lower_limit + 446 next - sc->tx_upper_limit - 2; 447 } 448 } 449 450 /* 451 * Build the packet frame in the card's ring buffer. 452 */ 453 DODEBUG(Sent_Pkts, printf("2. dest=%d, next=%d. ", dest, next);); 454 455 outw(iobase + HOST_ADDR_REG, dest); 456 outw(iobase + IO_PORT_REG, Transmit_CMD); 457 outw(iobase + IO_PORT_REG, 0); 458 outw(iobase + IO_PORT_REG, next); 459 outw(iobase + IO_PORT_REG, data_len); 460 461 /* 462 * Output the packet data to the card. Ensure all 463 * transfers are 16-bit wide, even if individual 464 * mbufs have odd length. 465 */ 466 467 for (m = opkt, i = 0; m != NULL; m = m->m_next) { 468 DODEBUG(Sent_Pkts, printf("[%d]", m->m_len);); 469 if (i) { 470 tmp16[1] = *(mtod(m, caddr_t)); 471 outsw(iobase + IO_PORT_REG, tmp16, 1); 472 } 473 outsw(iobase + IO_PORT_REG, 474 mtod(m, caddr_t) + i, (m->m_len - i) / 2); 475 476 if ((i = (m->m_len - i) & 1) != 0) { 477 tmp16[0] = *(mtod(m, caddr_t) + 478 m->m_len - 1); 479 } 480 } 481 if (i) { 482 outsw(iobase + IO_PORT_REG, tmp16, 1); 483 } 484 485 /* 486 * If there were other frames chained, update the 487 * chain in the last one. 488 */ 489 if (sc->tx_head != sc->tx_tail) { 490 if (sc->tx_tail != dest) { 491 outw(iobase + HOST_ADDR_REG, 492 sc->tx_last + XMT_Chain_Point); 493 outw(iobase + IO_PORT_REG, dest); 494 } 495 outw(iobase + HOST_ADDR_REG, 496 sc->tx_last + XMT_Byte_Count); 497 i = inw(iobase + IO_PORT_REG); 498 outw(iobase + HOST_ADDR_REG, 499 sc->tx_last + XMT_Byte_Count); 500 outw(iobase + IO_PORT_REG, i | Ch_bit); 501 } 502 503 /* 504 * Resume normal operation of the card: 505 * - Make a dummy read to flush the DRAM write 506 * pipeline. 507 * - Enable receive and transmit interrupts. 508 * - Send Transmit or Resume_XMT command, as 509 * appropriate. 510 */ 511 inw(iobase + IO_PORT_REG); 512#ifdef EX_PSA_INTR 513 outb(iobase + MASK_REG, All_Int & ~(Rx_Int | Tx_Int)); 514#endif 515 if (sc->tx_head == sc->tx_tail) { 516 outw(iobase + XMT_BAR, dest); 517 outb(iobase + CMD_REG, Transmit_CMD); 518 sc->tx_head = dest; 519 DODEBUG(Sent_Pkts, printf("Transmit\n");); 520 } else { 521 outb(iobase + CMD_REG, Resume_XMT_List_CMD); 522 DODEBUG(Sent_Pkts, printf("Resume\n");); 523 } 524 525 sc->tx_last = dest; 526 sc->tx_tail = next; 527 528 if (ifp->if_bpf != NULL) { 529 bpf_mtap(ifp, opkt); 530 } 531 532 ifp->if_timer = 2; 533 ifp->if_opackets++; 534 m_freem(opkt); 535 } else { 536 ifp->if_flags |= IFF_OACTIVE; 537 DODEBUG(Status, printf("OACTIVE start\n");); 538 } 539 } 540 541 splx(s); 542 543 DODEBUG(Start_End, printf("ex_start%d: finish\n", unit);); 544} 545 546static void 547ex_stop(struct ex_softc *sc) 548{ 549 int iobase = sc->iobase; 550 551 DODEBUG(Start_End, printf("ex_stop%d: start\n", unit);); 552 553 /* 554 * Disable card operation: 555 * - Disable the interrupt line. 556 * - Flush transmission and disable reception. 557 * - Mask and clear all interrupts. 558 * - Reset the 82595. 559 */ 560 outb(iobase + CMD_REG, Bank1_Sel); 561 outb(iobase + REG1, inb(iobase + REG1) & ~TriST_INT); 562 outb(iobase + CMD_REG, Bank0_Sel); 563 outb(iobase + CMD_REG, Rcv_Stop); 564 sc->tx_head = sc->tx_tail = sc->tx_lower_limit; 565 sc->tx_last = 0; /* XXX I think these two lines are not necessary, because ex_init will always be called again to reinit the interface. */ 566 outb(iobase + MASK_REG, All_Int); 567 outb(iobase + STATUS_REG, All_Int); 568 outb(iobase + CMD_REG, Reset_CMD); 569 DELAY(200); 570 571 DODEBUG(Start_End, printf("ex_stop%d: finish\n", unit);); 572 573 return; 574} 575 576void 577ex_intr(void *arg) 578{ 579 struct ex_softc * sc = (struct ex_softc *)arg; 580 struct ifnet * ifp = &sc->arpcom.ac_if; 581 int iobase = sc->iobase; 582 int int_status, send_pkts; 583 584 DODEBUG(Start_End, printf("ex_intr%d: start\n", unit);); 585 586#ifdef EXDEBUG 587 if (++exintr_count != 1) 588 printf("WARNING: nested interrupt (%d). Mail the author.\n", exintr_count); 589#endif 590 591 send_pkts = 0; 592 while ((int_status = inb(iobase + STATUS_REG)) & (Tx_Int | Rx_Int)) { 593 if (int_status & Rx_Int) { 594 outb(iobase + STATUS_REG, Rx_Int); 595 596 ex_rx_intr(sc); 597 } else if (int_status & Tx_Int) { 598 outb(iobase + STATUS_REG, Tx_Int); 599 600 ex_tx_intr(sc); 601 send_pkts = 1; 602 } 603 } 604 605 /* 606 * If any packet has been transmitted, and there are queued packets to 607 * be sent, attempt to send more packets to the network card. 608 */ 609 610 if (send_pkts && (ifp->if_snd.ifq_head != NULL)) { 611 ex_start(ifp); 612 } 613 614#ifdef EXDEBUG 615 exintr_count--; 616#endif 617 618 DODEBUG(Start_End, printf("ex_intr%d: finish\n", unit);); 619 620 return; 621} 622 623static void 624ex_tx_intr(struct ex_softc *sc) 625{ 626 struct ifnet * ifp = &sc->arpcom.ac_if; 627 int iobase = sc->iobase; 628 int tx_status; 629 630 DODEBUG(Start_End, printf("ex_tx_intr%d: start\n", unit);); 631 632 /* 633 * - Cancel the watchdog. 634 * For all packets transmitted since last transmit interrupt: 635 * - Advance chain pointer to next queued packet. 636 * - Update statistics. 637 */ 638 639 ifp->if_timer = 0; 640 641 while (sc->tx_head != sc->tx_tail) { 642 outw(iobase + HOST_ADDR_REG, sc->tx_head); 643 644 if (! inw(iobase + IO_PORT_REG) & Done_bit) 645 break; 646 647 tx_status = inw(iobase + IO_PORT_REG); 648 sc->tx_head = inw(iobase + IO_PORT_REG); 649 650 if (tx_status & TX_OK_bit) { 651 ifp->if_opackets++; 652 } else { 653 ifp->if_oerrors++; 654 } 655 656 ifp->if_collisions += tx_status & No_Collisions_bits; 657 } 658 659 /* 660 * The card should be ready to accept more packets now. 661 */ 662 663 ifp->if_flags &= ~IFF_OACTIVE; 664 665 DODEBUG(Status, printf("OIDLE tx_intr\n");); 666 DODEBUG(Start_End, printf("ex_tx_intr%d: finish\n", unit);); 667 668 return; 669} 670 671static void 672ex_rx_intr(struct ex_softc *sc) 673{ 674 struct ifnet * ifp = &sc->arpcom.ac_if; 675 int iobase = sc->iobase; 676 int rx_status; 677 int pkt_len; 678 int QQQ; 679 struct mbuf * m; 680 struct mbuf * ipkt; 681 struct ether_header * eh; 682 683 DODEBUG(Start_End, printf("ex_rx_intr%d: start\n", unit);); 684 685 /* 686 * For all packets received since last receive interrupt: 687 * - If packet ok, read it into a new mbuf and queue it to interface, 688 * updating statistics. 689 * - If packet bad, just discard it, and update statistics. 690 * Finally, advance receive stop limit in card's memory to new location. 691 */ 692 693 outw(iobase + HOST_ADDR_REG, sc->rx_head); 694 695 while (inw(iobase + IO_PORT_REG) == RCV_Done) { 696 697 rx_status = inw(iobase + IO_PORT_REG); 698 sc->rx_head = inw(iobase + IO_PORT_REG); 699 QQQ = pkt_len = inw(iobase + IO_PORT_REG); 700 701 if (rx_status & RCV_OK_bit) { 702 MGETHDR(m, M_DONTWAIT, MT_DATA); 703 ipkt = m; 704 if (ipkt == NULL) { 705 ifp->if_iqdrops++; 706 } else { 707 ipkt->m_pkthdr.rcvif = ifp; 708 ipkt->m_pkthdr.len = pkt_len; 709 ipkt->m_len = MHLEN; 710 711 while (pkt_len > 0) { 712 if (pkt_len > MINCLSIZE) { 713 MCLGET(m, M_DONTWAIT); 714 if (m->m_flags & M_EXT) { 715 m->m_len = MCLBYTES; 716 } else { 717 m_freem(ipkt); 718 ifp->if_iqdrops++; 719 goto rx_another; 720 } 721 } 722 m->m_len = min(m->m_len, pkt_len); 723 724 /* 725 * NOTE: I'm assuming that all mbufs allocated are of even length, 726 * except for the last one in an odd-length packet. 727 */ 728 729 insw(iobase + IO_PORT_REG, 730 mtod(m, caddr_t), m->m_len / 2); 731 732 if (m->m_len & 1) { 733 *(mtod(m, caddr_t) + m->m_len - 1) = inb(iobase + IO_PORT_REG); 734 } 735 pkt_len -= m->m_len; 736 737 if (pkt_len > 0) { 738 MGET(m->m_next, M_DONTWAIT, MT_DATA); 739 if (m->m_next == NULL) { 740 m_freem(ipkt); 741 ifp->if_iqdrops++; 742 goto rx_another; 743 } 744 m = m->m_next; 745 m->m_len = MLEN; 746 } 747 } 748 eh = mtod(ipkt, struct ether_header *); 749#ifdef EXDEBUG 750 if (debug_mask & Rcvd_Pkts) { 751 if ((eh->ether_dhost[5] != 0xff) || (eh->ether_dhost[0] != 0xff)) { 752 printf("Receive packet with %d data bytes: %6D -> ", QQQ, eh->ether_shost, ":"); 753 printf("%6D\n", eh->ether_dhost, ":"); 754 } /* QQQ */ 755 } 756#endif 757 m_adj(ipkt, sizeof(struct ether_header)); 758 ether_input(ifp, eh, ipkt); 759 ifp->if_ipackets++; 760 } 761 } else { 762 ifp->if_ierrors++; 763 } 764 outw(iobase + HOST_ADDR_REG, sc->rx_head); 765rx_another: ; 766 } 767 768 if (sc->rx_head < sc->rx_lower_limit + 2) 769 outw(iobase + RCV_STOP_REG, sc->rx_upper_limit); 770 else 771 outw(iobase + RCV_STOP_REG, sc->rx_head - 2); 772 773 DODEBUG(Start_End, printf("ex_rx_intr%d: finish\n", unit);); 774 775 return; 776} 777 778 779static int 780ex_ioctl(register struct ifnet *ifp, u_long cmd, caddr_t data) 781{ 782 struct ex_softc * sc = ifp->if_softc; 783 struct ifreq * ifr = (struct ifreq *)data; 784 int s; 785 int error = 0; 786 787 DODEBUG(Start_End, printf("ex_ioctl%d: start ", ifp->if_unit);); 788 789 s = splimp(); 790 791 switch(cmd) { 792 case SIOCSIFADDR: 793 case SIOCGIFADDR: 794 case SIOCSIFMTU: 795 error = ether_ioctl(ifp, cmd, data); 796 break; 797 798 case SIOCSIFFLAGS: 799 DODEBUG(Start_End, printf("SIOCSIFFLAGS");); 800 if ((ifp->if_flags & IFF_UP) == 0 && 801 (ifp->if_flags & IFF_RUNNING)) { 802 803 ifp->if_flags &= ~IFF_RUNNING; 804 ex_stop(sc); 805 } else { 806 ex_init(sc); 807 } 808 break; 809#ifdef NODEF 810 case SIOCGHWADDR: 811 DODEBUG(Start_End, printf("SIOCGHWADDR");); 812 bcopy((caddr_t)sc->sc_addr, (caddr_t)&ifr->ifr_data, 813 sizeof(sc->sc_addr)); 814 break; 815#endif 816 case SIOCADDMULTI: 817 DODEBUG(Start_End, printf("SIOCADDMULTI");); 818 case SIOCDELMULTI: 819 DODEBUG(Start_End, printf("SIOCDELMULTI");); 820 /* XXX Support not done yet. */ 821 error = EINVAL; 822 break; 823 case SIOCSIFMEDIA: 824 case SIOCGIFMEDIA: 825 error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, cmd); 826 break; 827 default: 828 DODEBUG(Start_End, printf("unknown");); 829 error = EINVAL; 830 } 831 832 splx(s); 833 834 DODEBUG(Start_End, printf("\nex_ioctl%d: finish\n", ifp->if_unit);); 835 836 return(error); 837} 838 839 840static void 841ex_reset(struct ex_softc *sc) 842{ 843 int s; 844 845 DODEBUG(Start_End, printf("ex_reset%d: start\n", unit);); 846 847 s = splimp(); 848 849 ex_stop(sc); 850 ex_init(sc); 851 852 splx(s); 853 854 DODEBUG(Start_End, printf("ex_reset%d: finish\n", unit);); 855 856 return; 857} 858 859static void 860ex_watchdog(struct ifnet *ifp) 861{ 862 struct ex_softc * sc = ifp->if_softc; 863 864 DODEBUG(Start_End, printf("ex_watchdog%d: start\n", ifp->if_unit);); 865 866 ifp->if_flags &= ~IFF_OACTIVE; 867 868 DODEBUG(Status, printf("OIDLE watchdog\n");); 869 870 ifp->if_oerrors++; 871 ex_reset(sc); 872 ex_start(ifp); 873 874 DODEBUG(Start_End, printf("ex_watchdog%d: finish\n", ifp->if_unit);); 875 876 return; 877} 878 879static int 880ex_get_media (u_int32_t iobase) 881{ 882 int tmp; 883 884 outb(iobase + CMD_REG, Bank2_Sel); 885 tmp = inb(iobase + REG3); 886 outb(iobase + CMD_REG, Bank0_Sel); 887 888 if (tmp & TPE_bit) 889 return(IFM_ETHER|IFM_10_T); 890 if (tmp & BNC_bit) 891 return(IFM_ETHER|IFM_10_2); 892 893 return (IFM_ETHER|IFM_10_5); 894} 895 896static int 897ex_ifmedia_upd (ifp) 898 struct ifnet * ifp; 899{ 900 struct ex_softc * sc = ifp->if_softc; 901 902 return (0); 903} 904 905static void 906ex_ifmedia_sts(ifp, ifmr) 907 struct ifnet * ifp; 908 struct ifmediareq * ifmr; 909{ 910 struct ex_softc * sc = ifp->if_softc; 911 912 ifmr->ifm_active = ex_get_media(sc->iobase); 913 914 return; 915} 916 917u_short 918eeprom_read(u_int32_t iobase, int location) 919{ 920 int i; 921 u_short data = 0; 922 int ee_addr; 923 int read_cmd = location | EE_READ_CMD; 924 short ctrl_val = EECS; 925 926 ee_addr = iobase + EEPROM_REG; 927 outb(iobase + CMD_REG, Bank2_Sel); 928 outb(ee_addr, EECS); 929 for (i = 8; i >= 0; i--) { 930 short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val; 931 outb(ee_addr, outval); 932 outb(ee_addr, outval | EESK); 933 DELAY(3); 934 outb(ee_addr, outval); 935 DELAY(2); 936 } 937 outb(ee_addr, ctrl_val); 938 939 for (i = 16; i > 0; i--) { 940 outb(ee_addr, ctrl_val | EESK); 941 DELAY(3); 942 data = (data << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0); 943 outb(ee_addr, ctrl_val); 944 DELAY(2); 945 } 946 947 ctrl_val &= ~EECS; 948 outb(ee_addr, ctrl_val | EESK); 949 DELAY(3); 950 outb(ee_addr, ctrl_val); 951 DELAY(2); 952 outb(iobase + CMD_REG, Bank0_Sel); 953 return(data); 954}
|