static uint8 cs8900a_output (struct device_desc *dev, uint8 * buf, uint16 packet_len) { struct net_device *net_dev = (struct net_device *) dev->dev; struct net_cs8900a_io *io = (struct net_cs8900a_io *) dev->data; int len; //printf("%s: packet_len:%d\n", __FUNCTION__, packet_len); #if 0 print_packet (buf, packet_len); #endif if ((len = net_dev->net_write (net_dev, buf, packet_len)) == -1) { fprintf (stderr, "write to tapif error in skyeye-ne2k.c\n"); return -1; } io->ctrl_st[CtrlStNum (PP_TxEvent)] |= 0x100; io->ctrl_st[CtrlStNum (PP_BusST)] |= Rdy4TxNOW; if (io->ctrl_st[CtrlStNum (PP_BusCTL)] & EnableRQ) { set_time (io->index, packet_len); io->need_update = 1; net_cs8900a_set_update_intr (dev); } return 0; }
static void ctrl_status_read (struct device_desc *dev, uint16 * data) { struct net_device *net_dev = (struct net_device *) dev->dev; struct net_cs8900a_io *io = (struct net_cs8900a_io *) dev->data; *data = io->ctrl_st[CtrlStNum (io->pp_address)]; //printf("%s: addr %x, data %x\n", __FUNCTION__, io->pp_address, *data); }
static void net_cs8900a_reset (struct device_desc *dev) { struct net_device *net_dev = (struct net_device *) dev->dev; struct net_cs8900a_io *io = (struct net_cs8900a_io *) dev->data; int i; eeprom_reset(dev); /* set ProductID: rev_d */ io->product_id[0] = EISA_REG_CODE; io->product_id[1] = CS8900A | (REV_D << 8); /* see section 4.10.5 */ io->pp_address |= 0x3000; /* set control and status registers low 6 bits. see P49. */ for (i = 0; i < 16; i++) { io->ctrl_st[i] |= i * 2 + 1; io->ctrl_st[i + 16] |= i * 2; } io->ctrl_st[CtrlStNum (PP_BusST)] |= Rdy4TxNOW; /*init smdk2410_macaddr*/ memcpy (io->smdk2410_macaddr, net_dev->macaddr, 6); /* init tx/rx buffer */ if (!io->rx_frame) io->rx_frame = (uint16 *) malloc (Rx_Frame_Count); memset (io->rx_frame, 0, Rx_Frame_Count); io->rx_status_p = &(io->rx_frame[0]); io->rx_length_p = &(io->rx_frame[1]); io->rx_head = io->rx_tail = 0; if (!io->tx_frame) io->tx_frame = (uint16 *) malloc (Tx_Frame_Count); memset (io->tx_frame, 0, Tx_Frame_Count); io->tx_head = io->tx_tail = 0; io->ctrl_st[CtrlStNum (PP_SelfST)] |= INITD; io->ctrl_st[CtrlStNum (PP_LineST)] |= LINK_OK; io->ctrl_st[CtrlStNum (PP_TxEvent)] &= 0x3f; }
static void cs8900a_input (struct device_desc *dev) { struct net_device *net_dev = (struct net_device *) dev->dev; struct net_cs8900a_io *io = (struct net_cs8900a_io *) dev->data; int packet_len, cs8900a_len; uint8 *bufptr; /*When the CS8900A commits buffer space to a par- ticular held receive frame ,data from subsequent frames can be written P85*/ if (io->ctrl_st[CtrlStNum (PP_RxEvent)] & 0x100) return; bufptr = (uint8 *) & (io->rx_frame[2]); packet_len = net_dev->net_read (net_dev, bufptr, Rx_Max_Count); if (packet_len < 0) return; *(io->rx_status_p) |= RxOK; *(io->rx_length_p) = packet_len; io->rx_head = 2; io->rx_head = io->rx_head + ((packet_len + 1) / 2) - 1; io->rx_tail = 0; //printf("io->rx_head:%d, io->rx_tail:%d, packet_len:%d\n", io->rx_head, io->rx_tail, packet_len); #if 0 print_packet (bufptr, packet_len); #endif io->ctrl_st[CtrlStNum (PP_RxEvent)] |= 0x100; //TxOK if (io->ctrl_st[CtrlStNum (PP_BusCTL)] & EnableRQ) { //printf("%s:%x, packet_len:%d\n", __FUNCTION__, io->ctrl_st[CtrlStNum(PP_RxEvent)], packet_len); set_time (io->index, packet_len); io->need_update = 1; net_cs8900a_set_update_intr (dev); } }
static void ctrl_status_write (struct device_desc *dev, uint16 data) { struct net_device *net_dev = (struct net_device *) dev->dev; struct net_cs8900a_io *io = (struct net_cs8900a_io *) dev->data; io->ctrl_st[CtrlStNum (io->pp_address)] = data; if (io->pp_address==PP_SelfCTL) { if (data&RESET) net_cs8900a_reset(dev); } //printf("%s: addr %x, data %x\n", __FUNCTION__, io->pp_address, data); }
/* ISQ read*/ static void isq_read (struct device_desc *dev, uint16 * data) { struct net_device *net_dev = (struct net_device *) dev->dev; struct net_cs8900a_io *io = (struct net_cs8900a_io *) dev->data; io->ctrl_st[CtrlStNum (PP_ISQ)] = 0x0; if (io->ctrl_st[CtrlStNum (PP_RxEvent)] & 0xffc0) { io->ctrl_st[CtrlStNum (PP_ISQ)] = io->ctrl_st[CtrlStNum (PP_RxEvent)]; //io->ctrl_st[CtrlStNum (PP_RxEvent)] &= 0x3f; } else if (io->ctrl_st[CtrlStNum (PP_TxEvent)] & 0xffc0) { io->ctrl_st[CtrlStNum (PP_ISQ)] = io->ctrl_st[CtrlStNum (PP_TxEvent)]; io->ctrl_st[CtrlStNum (PP_TxEvent)] &= 0x3f; } *data = io->ctrl_st[CtrlStNum (PP_ISQ)]; }
static void frame_read (struct device_desc *dev, uint16 * data) { struct net_device *net_dev = (struct net_device *) dev->dev; struct net_cs8900a_io *io = (struct net_cs8900a_io *) dev->data; if (io->rx_tail > io->rx_head) { io->rx_head = io->rx_tail = 0; return; } *data = io->rx_frame[io->rx_tail]; if (io->rx_tail==io->rx_head) { io->ctrl_st[CtrlStNum (PP_RxEvent)] &= ~0x100; } io->rx_tail++; }
static void eeprom_reset (struct device_desc *dev) { struct net_device *net_dev = (struct net_device *) dev->dev; struct net_cs8900a_io *io = (struct net_cs8900a_io *) dev->data; uint8 offset, checksum = 0, *buf; uint16 eeprom_val[17] = { 0xa120, 0x2020, 0x0300, 0x0003, 0x0001, 0x502c, 0xe000, 0x000f, 0x0, 0xd, 0xc000, 0xf, 0x2158, 0x0010, 0x0, 0x0, 0x2800 }; /* set eeprom mac address */ eeprom_val[13] = net_dev->macaddr[0] | (net_dev->macaddr[1] << 8); eeprom_val[14] = net_dev->macaddr[2] | (net_dev->macaddr[3] << 8); eeprom_val[15] = net_dev->macaddr[4] | (net_dev->macaddr[5] << 8); /* re-compute checksum. */ buf = (uint8 *) eeprom_val; for (offset = 0; offset < (sizeof (eeprom_val) - 2); offset++) checksum += buf[offset]; eeprom_val[16] = ((uint8) (0x100 - checksum)) << 8; /* fill eeprom. */ memcpy (io->eeprom, eeprom_val, sizeof (eeprom_val)); /* others */ io->eeprom_writable = 1; io->ctrl_st[CtrlStNum (PP_SelfST)] |= EEPROMpresent | EEPROMOK; memcpy (io->ieee_addr, net_dev->macaddr, 6); printf ("In epprom_reset(io->ieee_addr) mac addr=%x:%x:%x:%x:%x:%x\n", io->ieee_addr[0], io->ieee_addr[1], io->ieee_addr[2], io->ieee_addr[3], io->ieee_addr[4], io->ieee_addr[5]); printf ("In epprom_reset(net->macaddr) mac addr=%x:%x:%x:%x:%x:%x\n", net_dev->macaddr[0], net_dev->macaddr[1], net_dev->macaddr[2], net_dev->macaddr[3], net_dev->macaddr[4], net_dev->macaddr[5]); }