📄 uclinux040408.44b0.patch
字号:
+ TxColOvfiE | MissOvfloiE | BufCFG_LOW);++ /* configure BusCTL */+ temp = reg_read(REG_BusCTL);+ temp |= EnableIRQ;+ reg_write(REG_BusCTL, temp);++ /* configure valid INTRQ0 */+ reg_write(REG_InterruptNumber, INTRQ0);+} + ++static void cs8900a_chip_stop(void)+{+ /* cleanup RxCFG */+ reg_write(REG_RxCFG, RxCFG_LOW);+ /* cleanup TxCFG */+ reg_write(REG_TxCFG, TxCFG_LOW);+ /* cleanup BufCFG */+ reg_write(REG_BufCFG, BufCFG_LOW);++ /* cleanup BusCTL */+ reg_write(REG_BusCTL, BusCTL_LOW);+ /* cleanup RxCTL */+ reg_write(REG_RxCTL, RxCTL_LOW);+ /* cleanup LineCTL */+ reg_write(REG_LineCTL, LineCTL_LOW);+}+++static int cs8900a_packet_receive(unsigned char *buf, int len)+{+ int i;+ unsigned short *data_ptr;++ /* Read frame */+ data_ptr = (unsigned short *)buf;+ for(i=0; i<len; i+=2)+ *data_ptr++ = io_read(IO_BASE+IO_RX_TX_DATA0);++ return len;+}+++static int cs8900a_packet_transmit(const unsigned char *buf, int len)+{+ int i;+ const unsigned short *data_ptr;++ /* write frame */+ data_ptr = (const unsigned short *)buf;+ for(i=0; i<len; i+=2)+ io_write(IO_BASE+IO_RX_TX_DATA0, *data_ptr++);++ return len;+}+++static int cs8900a_rx(struct net_device *dev)+{+ struct sk_buff *skb;+ int length;+ struct cs8900a_priv *priv = (struct cs8900a_priv *)dev->priv;++ /* Discard RxStatus */+ reg_read(REG_RxStatus);+ /* Read the frame's length. */+ length = reg_read(REG_RxLength);+ if(length == 0)+ return 0;++ /* Malloc up new buffer. */+ skb = dev_alloc_skb(length+2);+ if(skb == NULL) {+ priv->stats.rx_dropped++;+ return 0;+ }++ skb->dev = dev;+ skb_reserve(skb, 2);+ skb_put(skb, length);+ cs8900a_packet_receive(skb->data, length);+ skb->protocol=eth_type_trans(skb,dev);+ netif_rx(skb);+ dev->last_rx = jiffies;++ priv->stats.rx_packets++;+ priv->stats.rx_bytes += length;++ return length;+}+++static int cs8900a_start_xmit(struct sk_buff *skb, struct net_device *dev)+{+ int len;+ struct cs8900a_priv *priv = (struct cs8900a_priv *) dev->priv;++ TRACE("start_xmit\n");+ len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;+ spin_lock_irq(&priv->lock);+ netif_stop_queue(dev);++ /* initiate a transmit sequence */+ reg_write(REG_TxCommand, TxStart | TxCMD_LOW);+ reg_write(REG_TxLength, len);++ /* Test to see if the chip has allocated memory for the packet */+ if((reg_read(REG_BusST) & Rdy4TxNOW) == 0) {+ /*+ * Gasp! It hasn't. But that shouldn't happen since+ * we're waiting for TxOk, so return 1 and requeue this packet.+ */+ spin_unlock_irq(&lp->lock);+ TRACE("Tx buffer not free!\n");+ return 1;+ }++ /* Write the contents of the packet */+ cs8900a_packet_transmit(skb->data, len);+ spin_unlock_irq(&priv->lock);++ dev->trans_start = jiffies;+ dev_kfree_skb(skb);++ return 0;+}+++/*+* Handle the network interface interrupts.+*/+static void cs8900a_interrupt(int irq, void *dev_id, struct pt_regs * regs)+{+ unsigned short status;+ struct net_device *dev = dev_id;+ struct cs8900a_priv *priv = dev->priv;++ TRACE("interrupt\n");+ for(;;) {+ status = reg_read(REG_ISQ);+ if(status == 0)+ break;++ switch(status & ISQ_MASK) {+ case ISQ_RxEvent:+ if(status & RxOK) {+ cs8900a_rx(dev);+ }else {+ priv->stats.rx_errors++;+ if(status & (Runt | Extradata)) priv->stats.rx_length_errors++;+ else if(status & CRCerror) priv->stats.rx_crc_errors++;+ else if(status & Dribblebits) priv->stats.rx_frame_errors++;+ }+ break;+ + case ISQ_TxEvent:+ if(status & TxOK) {+ priv->stats.tx_packets++;+ }else {+ priv->stats.tx_errors++;+ if(status & Loss_of_CRS) priv->stats.tx_carrier_errors++;+ else if(status & SQError) priv->stats.tx_heartbeat_errors++;+ else if(status & Out_of_window) priv->stats.tx_window_errors++;+ else if(status & _16coll) priv->stats.tx_aborted_errors++;+ }+ /* if(netif_queue_stopped(dev)) */+ netif_wake_queue(dev);+ break;+ + case ISQ_BufEvent:+ if((status & Rdy4Tx)/* && netif_queue_stopped(dev)*/) {+ netif_wake_queue(dev);+ }+ break;+ + case ISQ_RxMISS:+ priv->stats.rx_missed_errors += (status >>6);+ break;+ + case ISQ_TxCOL:+ priv->stats.collisions += (status >>6);+ break;+ }+ }+}+++/*+ * Open and Close+ */+static int cs8900a_open(struct net_device *dev)+{+ struct cs8900a_priv *priv = (struct cs8900a_priv *)dev->priv;++ TRACE("open\n");+ MOD_INC_USE_COUNT;++ /* Disable irqs */+/* disable_irq(dev->irq); */++ /* register rx isr */+ if(request_irq(dev->irq, cs8900a_interrupt, 0,/*SA_INTERRUPT,*/ "CrystalLAN_cs8900a", dev)) {+ printk(KERN_ERR "cs8900a: Can't get irq %d\n", dev->irq);+ return -EAGAIN;+ }++ /* Init cs8900a */+ if(cs8900a_chip_probe() < 0)+ return -ENODEV;+ if(cs8900a_chip_reset() < 0)+ return -ETIME;+ cs8900a_chip_membase(MEM_BASE);+ cs8900a_chip_macaddr(mac_addr);+ cs8900a_chip_config();+ priv->dev_open = 1;++ /* Start the transmit queue */+ netif_start_queue(dev);++ return 0;+}+++static int cs8900a_stop(struct net_device *dev)+{+ struct cs8900a_priv *priv = (struct cs8900a_priv *)dev->priv;++ TRACE("stop\n");+ priv->dev_open = 0;++ /* stop cs8900a */+ cs8900a_chip_stop();++ free_irq(dev->irq, dev);+ netif_stop_queue(dev);++ MOD_DEC_USE_COUNT;+ + return 0;+}+++static struct net_device_stats *cs8900a_get_stats(struct net_device *dev)+{+ struct cs8900a_priv *priv = (struct cs8900a_priv *)dev->priv;++ TRACE("get_stats\n");+ if(priv->dev_open) {+ priv->stats.rx_missed_errors += (reg_read(REG_RxMISS) >> 6);+ priv->stats.collisions += (reg_read(REG_TxCOL) >> 6);+ }++ return &priv->stats;+}+++#ifdef CS8900A_HWADDR+static void cs8900a_get_mac_addr(void)+{+ int i, j;+ char src_mac_addr[32] = CS8900A_HWADDR;++ for(i=0, j=0; i<ETH_ALEN; i++) {+ for(; j < 32; j++) {+ if(src_mac_addr[j] >= '0' && src_mac_addr[j] <= '9') {+ src_mac_addr[j] -= '0';+ break;+ }+ else if(src_mac_addr[j] >= 'a' && src_mac_addr[j] <= 'f') {+ src_mac_addr[j] -= ('a' - 10);+ break;+ }+ else if(src_mac_addr[j] >= 'A' && src_mac_addr[j] <= 'F') {+ src_mac_addr[j] -= ('A' - 10);+ break;+ }+ }+ if(j == 32)+ break;+ mac_addr[i] = src_mac_addr[j++] << 4;++ for(; j < 32; j++) {+ if(src_mac_addr[j] >= '0' && src_mac_addr[j] <= '9') {+ src_mac_addr[j] -= '0';+ break;+ }+ else if(src_mac_addr[j] >= 'a' && src_mac_addr[j] <= 'f') {+ src_mac_addr[j] -= ('a' - 10);+ break;+ }+ else if(src_mac_addr[j] >= 'A' && src_mac_addr[j] <= 'F') {+ src_mac_addr[j] -= ('A' - 10);+ break;+ }+ }+ if(j == 32)+ break;+ mac_addr[i] += src_mac_addr[j];+ }+}+#endif+++/*+* The init function, invoked by register_netdev()+*/+static int cs8900a_init(struct net_device *dev)+{+ int i;++ TRACE("init\n");+ /* Assign some of the fields */+ ether_setup(dev);++ /* set net_device methods */+ dev->open = cs8900a_open;+ dev->stop = cs8900a_stop;+ dev->get_stats = cs8900a_get_stats;+ dev->hard_start_xmit = cs8900a_start_xmit;++ /* set net_device data members */+ dev->watchdog_timeo = timeout;+ dev->irq = S3C44B0X_INTERRUPT_EINT3;+ dev->dma = 0;++ /* set MAC address manually */+#ifdef CS8900A_HWADDR+ cs8900a_get_mac_addr();+#endif+ printk(KERN_INFO "%s: ", dev->name);+ for(i=0; i<ETH_ALEN; i++) {+ dev->dev_addr[i] = mac_addr[i];+ printk("%2.2x%c", dev->dev_addr[i], (i == 5) ? ' ' : ':');+ }+ printk("\n");++ SET_MODULE_OWNER(dev);++ dev->priv = kmalloc(sizeof(struct cs8900a_priv), GFP_KERNEL);+ if(dev->priv == NULL)+ return -ENOMEM;+ memset(dev->priv, 0, sizeof(struct cs8900a_priv));+ spin_lock_init(&((struct cs8900a_priv *)(dev->priv))->lock);++ return 0;+}+++static struct net_device cs8900a_netdevs = {+ init: cs8900a_init,+};+++/*+* Finally, the module stuff+*/+int __init cs8900a_init_module(void)+{+ int result;++ TRACE("init_module\n");+ /* Print version information */+ printk(KERN_INFO "%s", version);++ /* register_netdev will call cs8900a_init() */+ if((result = register_netdev(&cs8900a_netdevs)))+ printk("CS8900A eth: Error %i registering device \"%s\"\n", result, cs8900a_netdevs.name);++ return result ? 0 : -ENODEV;+}+++void __exit cs8900a_cleanup(void)+{+ TRACE("cleanup\n");+ kfree(cs8900a_netdevs.priv);+ unregister_netdev(&cs8900a_netdevs);+}+++module_init(cs8900a_init_module);+module_exit(cs8900a_cleanup);+++MODULE_DESCRIPTION("Crystal LAN CS8900A ethernet driver");+MODULE_AUTHOR("Embest tech&info Co.,Ltd. <www.embedinfo.com>");+MODULE_LICENSE("GPL");diff -Nur uClinux-dist.040408.original/linux-2.4.x/drivers/net/ekii-cs8900a.h uClinux-dist/linux-2.4.x/drivers/net/ekii-cs8900a.h--- uClinux-dist.040408.original/linux-2.4.x/drivers/net/ekii-cs8900a.h 1970-01-01 08:00:00.000000000 +0800+++ uClinux-dist/linux-2.4.x/drivers/net/ekii-cs8900a.h 2005-03-29 09:53:26.281250000 +0800@@ -0,0 +1,289 @@+/*+* linux/deriver/net/ekii-cs8900a.h+* Ethernet driver for Embest EduKit II+* Copyright (C) 2005 Embest <www.embedinfo.com>+*/+#ifndef __EKII_CS8900A_H__+#define __EKII_CS8900A_H__+++/*--- CS8900A Register defines ---*/+++/*+* Bus interface registers+*/+#define REG_Identification 0x0000+#define REG_IOBaseAddress 0x0020+#define REG_InterruptNumber 0x0022+#define REG_DMAChannelNumber 0x0024+#define REG_DMAStartOfFrame 0x0026+#define REG_DMARrameCount 0x0028+#define REG_RxDMAByteCount 0x002A+#define REG_MemoryBaseAddress 0x002C+#define REG_BootBaseAddress 0x0030+#define REG_BootAddressMask 0x0034+#define REG_EEPROMCommand 0x0040+#define REG_EEPROMData 0x0042+#define REG_ReceivedByteCounter 0x0050+++/*+* Status and control registers+*/+#define REG_RxCFG 0x0102+#define REG_RxCTL 0x0104+#define REG_TxCFG 0x0106+#define REG_TxCMD 0x0108+#define REG_BufCFG 0x010A+#define REG_LineCTL 0x0112+#define REG_SelfCTL 0x0114+#define REG_BusCTL 0x0116+#define REG_TestCTL 0x0118++#define REG_ISQ 0x0120+#define REG_RxEvent 0x0124+#define REG_TxEvent 0x0128+#define REG_BufEvent 0x012C+#define REG_RxMISS 0x0130+#define REG_TxCOL 0x0132
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -