📄 sk_g16.c
字号:
int i,j; /* Counters */ unsigned int rom_addr; /* used to store RAM address used for POS_ADDR */ struct priv *p; /* SK_G16 private structure */ if (SK_ADDR & 0x3fff || SK_ADDR < 0xa0000) { /* * Now here we could use a routine which searches for a free * place in the ram and set SK_ADDR if found. TODO. */ printf("%s: SK_ADDR %#hX is not valid. Check configuration.\n", SK_NAME, SK_ADDR); return -1; } rom_addr = SK_ADDR; outb(SK_ROM_RAM_OFF, SK_POS2); /* Boot_ROM + RAM off */ outb(POS_ADDR, SK_POS3); /* Set RAM address */ outb(SK_ROM_RAM_ON, SK_POS2); /* RAM on, BOOT_ROM on */#ifdef SK_DEBUG SK_print_pos(nic, "POS registers after ROM, RAM config");#endif board = (SK_RAM *) rom_addr; PRINTF(("adr[0]: %hX, adr[1]: %hX, adr[2]: %hX\n", board->rom[0], board->rom[2], board->rom[4])); /* Read in station address */ for (i = 0, j = 0; i < ETH_ALEN; i++, j+=2) { *(nic->node_addr+i) = board->rom[j]; } /* Check for manufacturer code */#ifdef SK_DEBUG if (!(*(nic->node_addr+0) == SK_MAC0 && *(nic->node_addr+1) == SK_MAC1 && *(nic->node_addr+2) == SK_MAC2) ) { PRINTF(("## %s: We did not find SK_G16 at RAM location.\n", SK_NAME)); return -1; /* NO SK_G16 found */ }#endif p = nic->priv_data; /* Initialize private structure */ p->ram = (struct SK_ram *) rom_addr; /* Set dual ported RAM addr */ p->tmdhead = &(p->ram)->tmde[0]; /* Set TMD head */ p->rmdhead = &(p->ram)->rmde[0]; /* Set RMD head */ printf("Schneider & Koch G16 at %#hX, mem at %#hX, HW addr: %!\n", (unsigned int) ioaddr, (unsigned int) p->ram, nic->node_addr); /* Initialize buffer pointers */ for (i = 0; i < TMDNUM; i++) { p->tmdbufs[i] = p->ram->tmdbuf[i]; } for (i = 0; i < RMDNUM; i++) { p->rmdbufs[i] = p->ram->rmdbuf[i]; } i = 0; if (!(i = SK_lance_init(nic, MODE_NORMAL))) /* LANCE init OK? */ {#ifdef SK_DEBUG /* * This debug block tries to stop LANCE, * reinit LANCE with transmitter and receiver disabled, * then stop again and reinit with NORMAL_MODE */ printf("## %s: After lance init. CSR0: %#hX\n", SK_NAME, SK_read_reg(CSR0)); SK_write_reg(CSR0, CSR0_STOP); printf("## %s: LANCE stopped. CSR0: %#hX\n", SK_NAME, SK_read_reg(CSR0)); SK_lance_init(nic, MODE_DTX | MODE_DRX); printf("## %s: Reinit with DTX + DRX off. CSR0: %#hX\n", SK_NAME, SK_read_reg(CSR0)); SK_write_reg(CSR0, CSR0_STOP); printf("## %s: LANCE stopped. CSR0: %#hX\n", SK_NAME, SK_read_reg(CSR0)); SK_lance_init(nic, MODE_NORMAL); printf("## %s: LANCE back to normal mode. CSR0: %#hX\n", SK_NAME, SK_read_reg(CSR0)); SK_print_pos(nic, "POS regs before returning OK");#endif /* SK_DEBUG */ } else /* LANCE init failed */ { PRINTF(("## %s: LANCE init failed: CSR0: %#hX\n", SK_NAME, SK_read_reg(CSR0))); return -1; }#ifdef SK_DEBUG SK_print_pos(nic, "End of SK_probe1"); SK_print_ram(nic);#endif return 0; /* Initialization done */} /* End of SK_probe1() */static int SK_lance_init(struct nic *nic, unsigned short mode){ int i; struct priv *p = (struct priv *) nic->priv_data; struct tmd *tmdp; struct rmd *rmdp; PRINTF(("## %s: At beginning of LANCE init. CSR0: %#hX\n", SK_NAME, SK_read_reg(CSR0))); /* Reset LANCE */ SK_reset_board(); /* Initialize TMD's with start values */ p->tmdnum = 0; /* First descriptor for transmitting */ p->tmdlast = 0; /* First descriptor for reading stats */ for (i = 0; i < TMDNUM; i++) /* Init all TMD's */ { tmdp = p->tmdhead + i; tmdp->u.buffer = (unsigned long) p->tmdbufs[i]; /* assign buffer */ /* Mark TMD as start and end of packet */ tmdp->u.s.status = TX_STP | TX_ENP; } /* Initialize RMD's with start values */ p->rmdnum = 0; /* First RMD which will be used */ for (i = 0; i < RMDNUM; i++) /* Init all RMD's */ { rmdp = p->rmdhead + i; rmdp->u.buffer = (unsigned long) p->rmdbufs[i]; /* assign buffer */ /* * LANCE must be owner at beginning so that he can fill in * receiving packets, set status and release RMD */ rmdp->u.s.status = RX_OWN; rmdp->blen = -PKT_BUF_SZ; /* Buffer Size in a two's complement */ rmdp->mlen = 0; /* init message length */ } /* Fill LANCE Initialize Block */ (p->ram)->ib.mode = mode; /* Set operation mode */ for (i = 0; i < ETH_ALEN; i++) /* Set physical address */ { (p->ram)->ib.paddr[i] = *(nic->node_addr+i); } for (i = 0; i < 8; i++) /* Set multicast, logical address */ { (p->ram)->ib.laddr[i] = 0; /* We do not use logical addressing */ } /* Set ring descriptor pointers and set number of descriptors */ (p->ram)->ib.rdrp = (int) p->rmdhead | RMDNUMMASK; (p->ram)->ib.tdrp = (int) p->tmdhead | TMDNUMMASK; /* Prepare LANCE Control and Status Registers */ SK_write_reg(CSR3, CSR3_ACON); /* Ale Control !!!THIS MUST BE SET!!!! */ /* * LANCE addresses the RAM from 0x0000 to 0x3fbf and has no access to * PC Memory locations. * * In structure SK_ram is defined that the first thing in ram * is the initialization block. So his address is for LANCE always * 0x0000 * * CSR1 contains low order bits 15:0 of initialization block address * CSR2 is built of: * 7:0 High order bits 23:16 of initialization block address * 15:8 reserved, must be 0 */ /* Set initialization block address (must be on word boundary) */ SK_write_reg(CSR1, 0); /* Set low order bits 15:0 */ SK_write_reg(CSR2, 0); /* Set high order bits 23:16 */ PRINTF(("## %s: After setting CSR1-3. CSR0: %#hX\n", SK_NAME, SK_read_reg(CSR0))); /* Initialize LANCE */ /* * INIT = Initialize, when set, causes the LANCE to begin the * initialization procedure and access the Init Block. */ SK_write_reg(CSR0, CSR0_INIT); /* Wait until LANCE finished initialization */ SK_set_RAP(CSR0); /* Register Address Pointer to CSR0 */ for (i = 0; (i < 100) && !(SK_rread_reg() & CSR0_IDON); i++) ; /* Wait until init done or go ahead if problems (i>=100) */ if (i >= 100) /* Something is wrong ! */ { printf("%s: can't init am7990, status: %#hX " "init_block: %#hX\n", SK_NAME, (int) SK_read_reg(CSR0), (unsigned int) &(p->ram)->ib);#ifdef SK_DEBUG SK_print_pos(nic, "LANCE INIT failed");#endif return -1; /* LANCE init failed */ } PRINTF(("## %s: init done after %d ticks\n", SK_NAME, i)); /* Clear Initialize done, enable Interrupts, start LANCE */ SK_write_reg(CSR0, CSR0_IDON | CSR0_INEA | CSR0_STRT); PRINTF(("## %s: LANCE started. CSR0: %#hX\n", SK_NAME, SK_read_reg(CSR0))); return 0; /* LANCE is up and running */} /* End of SK_lance_init() *//* LANCE access functions * * ! CSR1-3 can only be accessed when in CSR0 the STOP bit is set ! */static void SK_reset_board(void){ int i; PRINTF(("## %s: At beginning of SK_reset_board.\n", SK_NAME)); SK_PORT = 0x00; /* Reset active */ for (i = 0; i < 10 ; i++) /* Delay min 5ms */ ; SK_PORT = SK_RESET; /* Set back to normal operation */} /* End of SK_reset_board() */static void SK_set_RAP(int reg_number){ SK_IOREG = reg_number; SK_PORT = SK_RESET | SK_RAP | SK_WREG; SK_IOCOM = SK_DOIO; while (SK_PORT & SK_IORUN) ;} /* End of SK_set_RAP() */static int SK_read_reg(int reg_number){ SK_set_RAP(reg_number); SK_PORT = SK_RESET | SK_RDATA | SK_RREG; SK_IOCOM = SK_DOIO; while (SK_PORT & SK_IORUN) ; return (SK_IOREG);} /* End of SK_read_reg() */static int SK_rread_reg(void){ SK_PORT = SK_RESET | SK_RDATA | SK_RREG; SK_IOCOM = SK_DOIO; while (SK_PORT & SK_IORUN) ; return (SK_IOREG);} /* End of SK_rread_reg() */static void SK_write_reg(int reg_number, int value){ SK_set_RAP(reg_number); SK_IOREG = value; SK_PORT = SK_RESET | SK_RDATA | SK_WREG; SK_IOCOM = SK_DOIO; while (SK_PORT & SK_IORUN) ;} /* End of SK_write_reg *//* * Debugging functions * ------------------- */#ifdef SK_DEBUGstatic void SK_print_pos(struct nic *nic, char *text){ unsigned char pos0 = inb(SK_POS0), pos1 = inb(SK_POS1), pos2 = inb(SK_POS2), pos3 = inb(SK_POS3), pos4 = inb(SK_POS4); printf("## %s: %s.\n" "## pos0=%#hX pos1=%#hX pos2=%#hX pos3=%#hX pos4=%#hX\n", SK_NAME, text, pos0, pos1, pos2, (pos3<<14), pos4);} /* End of SK_print_pos() */static void SK_print_ram(struct nic *nic){ int i; struct priv *p = (struct priv *) nic->priv_data; printf("## %s: RAM Details.\n" "## RAM at %#hX tmdhead: %#hX rmdhead: %#hX initblock: %#hX\n", SK_NAME, (unsigned int) p->ram, (unsigned int) p->tmdhead, (unsigned int) p->rmdhead, (unsigned int) &(p->ram)->ib); printf("## "); for(i = 0; i < TMDNUM; i++) { if (!(i % 3)) /* Every third line do a newline */ { printf("\n## "); } printf("tmdbufs%d: %#hX ", (i+1), (int) p->tmdbufs[i]); } printf("## "); for(i = 0; i < RMDNUM; i++) { if (!(i % 3)) /* Every third line do a newline */ { printf("\n## "); } printf("rmdbufs%d: %#hX ", (i+1), (int) p->rmdbufs[i]); } putchar('\n');} /* End of SK_print_ram() */#endifstatic struct isa_driver SK_driver __isa_driver = { .type = NIC_DRIVER, .name = "SK_G16", .probe = SK_probe, .ioaddrs = 0,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -