📄 1022.ethernet.patch
字号:
+ * helpers to access registers+ */+#define enet_readl(x) gbus_read_uint32(0, (x))++static inline void enet_writel(unsigned long addr, unsigned long data)+{+ gbus_write_uint32(0, addr, data);++ /* some write read sequence seems to freeze completly if no+ * barrier is done between each access. To be safe, we do this+ * after all write access */+ iob();+}++#endif /* __TANGO2_ENET_H */+diff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linuxmips-2.4.30.ref/drivers/net/em86xx_eth.c linuxmips-2.4.30/drivers/net/em86xx_eth.c--- linuxmips-2.4.30.ref/drivers/net/em86xx_eth.c 1969-12-31 16:00:00.000000000 -0800+++ linuxmips-2.4.30/drivers/net/em86xx_eth.c 2007-06-11 10:40:45.000000000 -0700@@ -0,0 +1,2284 @@+/*+ * Embedded Ethernet driver for TANGO2 ES4 or above.+ */+#ifdef BOOTLOADER+#include "config.h"+#include "version.h"+#include "util.h"+#include "net.h"+#include "net_ipv4.h"+#include "em86xxapi.h"+#include "irqs.h"+#include "errno.h"+#include "uart.h"+#include "memcfg.h"+#else+#include <linux/config.h>+#include <linux/kernel.h>+#include <linux/netdevice.h>+#include <linux/etherdevice.h>+#include <linux/spinlock.h>+#include <linux/interrupt.h>+#include <linux/signal.h>+#include <linux/sched.h>+#include <linux/module.h>+#include <linux/compatmac.h>+#include <linux/mm.h>+#include <linux/init.h>+#include <linux/timer.h>+#include <linux/mii.h>+#include <linux/ethtool.h>+#include <linux/crc32.h>+#ifndef CONFIG_TANGO2+#include <asm/virtconvert.h>+#include <asm/arch/irqs.h>+#include <asm/arch/memcfg.h>+#else+#include <asm/tango2/memcfg.h>+#endif++// Use kernel timer implementation for polling the link status+// #define USE_KERNEL_TIMER++#endif //BOOTLOADER++#include "em86xx_eth.h"++#define DRV_NAME "em86xx-eth"+#define DRV_VERSION "-0.0.0.0.1"++/* Uncomment this for different messages */+//#define ETH_DEBUG +#define ETH_ERRMSG +#define ETH_MSG+//#define ETH_DBG_INOUT+//#define DEBUG_RX_TX_STATE+//#define DEBUG_MDIO++#ifdef BOOTLOADER+#define DRIVER "em86xx_eth"++/* For static buffer allocation */+// #define STATIC_BUF_ALLOC+#define printk uart_printf++#define PAGE_SHIFT 12+#define PAGE_SIZE (1UL << PAGE_SHIFT)+#define PAGE_MASK (~(PAGE_SIZE-1))+#define MAX_ORDER 10++#endif /* BOOTLOADER */++/* For software filtering*/+//#define USE_SW_FILTERING+#define USE_HW_FILTERING++#ifdef ETH_DEBUG+#define DBG_PRINT printk+#else+static void inline DBG_PRINT(const char *x, ...) { ; }+#endif /* ETH_DEBUG */++#ifdef ETH_ERRMSG+#define ERR_PRINT printk+#else+static void inline ERR_PRINT(const char *x, ...) { ; }+#endif /* ETH_ERRMSG */++#ifdef ETH_MSG+#define MSG_PRINT printk+#else+static void inline MSG_PRINT(const char *x, ...) { ; }+#endif /* ETH_ERRMSG */++#ifdef ETH_DBG_INOUT+#define DBG_PRINT_INOUT_FUNC(x) printk("%s: %s\n", __func__, x);+#define MSG_PRINT printk+#else+static void inline DBG_PRINT_INOUT_FUNC(const char *x, ...) { ; }+#endif /* ETH_ERRMSG */++/* Hack: this is the mac address by default */+#define DEF_MAC_HI 0x00000011+#ifdef BOOTLOADER+#define DEF_MAC_LO 0xdeadbeef+#else+#define DEF_MAC_LO 0xaabbccdd+#endif++/* Default maximum link wait */+#ifdef USE_KERNEL_TIMER+#define DEF_LINK_LOOP 0x10000+#else+#define DEF_LINK_LOOP 0x100+#endif+#define DEF_MAX_LINK_LOOP (DEF_LINK_LOOP * 16)++#define ETH_IRQ_FLAGS (DmaIntNormal | DmaIntAbnormal | DmaIntRxStopped | \+ DmaIntRxNoBuffer | DmaIntRxCompleted | DmaIeTxUnderflow | \+ DmaIeTxStopped | DmaIeTxCompleted) +/* (DmaIntNormal | DmaIntAbnormal | DmaIntRxStopped | \+ DmaIntRxNoBuffer | DmaIntRxCompleted | DmaIntTxCompleted)+*/+#define ETH_RXTX_FLAGS (DmaTxStart | DmaRxStart | DmaStoreAndForward)++#ifndef USE_HW_FILTERING +#define ETH_MAC_FLAGS (MacTxEnable | MacRxEnable | MacPromiscuousModeOn | \+ MacPadStripEnable | MacHashFilterOn | MacPerfectFilterOff | \+ MacRetryEnable | MacHeartBeatOff)+#else +#define ETH_MAC_FLAGS (MacTxEnable | MacRxEnable | MacPromiscuousModeOff | \+ MacPadStripEnable | MacHashFilterOn | MacPerfectFilterOn | \+ MacRetryEnable | MacMulticastFilterOn | MacHeartBeatOff)+#define DEFAULT_BROADCAST_ADDRESS { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF }+static void em86xx_eth_set_multicast_list(struct net_device *dev);+#endif /*USE_HW_FILTERING*/++#define MD_FRAME_FLAGS (DescRxLast | DescRxFirst)+#define TX_DESC1_FLAGS (DescTxLast | DescTxFirst | DescChain | \+ DescTxIntEnable)+#define RX_ERROR_FLAGS (DescFilteringFail | DescError | DescRxTruncated | \+ DescLengthError | DescRxDamaged | DescRxLongFrame | \+ DescRxCollision | DescRxMiiError | DescRxCrc)+#define TX_ERROR_FLAGS (DescTxLostCarrier | DescTxNoCarrier | DescTxLateCollision | \+ DescTxExcCollisions| DescTxHeartbeatFail| DescTxUnderflow)++#if defined(CONFIG_TANGO2) +#if defined(CONFIG_TANGO2_SIG_BLOCK) || defined(CONFIG_TANGO2_XENV)+extern int tango2_ethernet_getmac(unsigned char *mac);+#endif+#endif++#define PHY_10BASET_HD_ANAR (CSMACD | BASET10 | FLOWCONTROL | RF)+#define PHY_10BASET_FD_ANAR (CSMACD | BASET10 | BASET10FD | FLOWCONTROL | RF)+#define PHY_100BASET_HD_ANAR (CSMACD | BASET10 | BASET10FD | BASET100 | FLOWCONTROL | RF)+#define PHY_100BASET_FD_ANAR (CSMACD | BASET10 | BASET10FD | BASET100 | BASET100FD | FLOWCONTROL | RF)++/* Number of descriptors and buffer size */+#define MIN_NUM_RDESC 8+#define MIN_NUM_TDESC 8+#define NUM_RDESC 64+#define NUM_TDESC 64+#define R_BUF_SIZE 0x700 /* needs to be < 2KB */+#define T_BUF_SIZE 0x700 /* needs to be < 2KB */++#if (R_BUF_SIZE < (1 << 14))+/* For multi-descriptor frame support: only when receive buffer size < 16384 */+#define MULTI_DESCS_FRAME_SUPPORT+#endif++/* Private data for this ethernet device */+typedef struct {+ struct net_device_stats stats; /* stats */+ unsigned long last_rxidx; /* last rx idx to descriptor */+ unsigned long next_txidx; /* next tx idx to descriptor */+++ spinlock_t lock;+ /* MII transceiver section. */+ struct mii_if_info mii_if;+ /* Mode selection */+ int autoneg_active;+ int phy_loopback; ++ /* Descriptors and buffers: notice the alignments */+#ifdef STATIC_BUF_ALLOC + struct em86xx_desc eth_rxdsc[NUM_RDESC] __attribute__ ((__aligned__(16)));+ struct em86xx_desc eth_txdsc[NUM_TDESC] __attribute__ ((__aligned__(16)));+ unsigned char eth_rxbuf[NUM_RDESC * R_BUF_SIZE] __attribute__ ((__aligned__(16)));+ unsigned char eth_txbuf[NUM_TDESC * T_BUF_SIZE] __attribute__ ((__aligned__(16)));+#else+ struct em86xx_desc *eth_rxdsc;+ struct em86xx_desc *eth_txdsc;+ unsigned char *eth_rxbuf;+ unsigned char *eth_txbuf;+ unsigned long desc_page;+ unsigned long rxbuf_pages;+ unsigned long txbuf_pages;+#ifndef BOOTLOADER+ unsigned long rxbuf_order;+ unsigned long txbuf_order;+#endif+#endif++ /* Number of descriptors */+ unsigned long num_rxdesc;+ unsigned long num_txdesc;++/* The real data pointer to be accessed in non-cache region */+ volatile struct em86xx_desc *rxdsc;+ volatile struct em86xx_desc *txdsc;+ volatile unsigned char *rxbuf;+ volatile unsigned char *txbuf;++ /* Reference count for device */+ int dev_count;++ int reset_flag;+ int phy_id;+ int stop_thread;++#ifndef BOOTLOADER+#ifdef USE_KERNEL_TIMER + struct timer_list eth_timer;+#endif+ struct sk_buff **rx_skb_list;+ int need_restart_tx_queue; +#endif++} EM86XX_ETH_PRIV;++/* For storing MAC address */+static unsigned long def_mac_hi = DEF_MAC_HI;+static unsigned long def_mac_lo = DEF_MAC_LO;+unsigned long num_rxdesc_param = NUM_RDESC;+unsigned long num_txdesc_param = NUM_TDESC;++/* Default PHY address: -1 for search */+static int phy_address = -1;+/* Default to 100BaseT/FD*/++static int em86xx_eth_reset_desc(struct net_device *dev, int *reset);++#ifdef BOOTLOADER+static void em86xx_eth_intr_handler(int irq, void *dev_id);+#else+static struct net_device em86xx_eth_dev;+static void em86xx_eth_intr_handler(int irq, void *dev_id, struct pt_regs *regs);+static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);++MODULE_AUTHOR("Craig Qu");+MODULE_DESCRIPTION("Sigma Designs ethernet driver");+MODULE_LICENSE("GPL");++MODULE_PARM(def_mac_hi, "i");+MODULE_PARM(def_mac_lo, "i");+MODULE_PARM(phy_address, "i");+MODULE_PARM_DESC(phy_address, "PHY address connecting to the MAC.");++#ifndef STATIC_BUF_ALLOC +MODULE_PARM(num_rxdesc_param, "i");+MODULE_PARM(num_txdesc_param, "i");+#endif+#endif /* BOOTLOADER */++#define TX_ERRORS 12+#define TX_ERRORS_START 1++#define RX_ERRORS 31+#define RX_ERRORS_START 1++static const char *rx_error_msg[RX_ERRORS]= {+ NULL,+ "A CRC error is detected.",+ NULL,+ "A receive error was detected during frame reception.",+ NULL,NULL,+ "The frame has seen a collision after the collision window.",+ "The frame is longer than 1518 bytes.",+ NULL,NULL,NULL,+ "The frame is prematurely terminated before the collision window.", + "The actual length does not match with the Length Type field of the incoming frame.",+ NULL,+ "No more descriptors for receive frame.",+ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,+ "The frame failed the address recognizing filtering.",+};++static const int rx_stat_offset[RX_ERRORS] = {+ -1,+ (int)&(((struct net_device_stats *)0)->rx_crc_errors),+ -1,-1,-1,-1,+ (int)&(((struct net_device_stats *)0)->collisions),+ -1,-1,-1,-1,-1,+ (int)&(((struct net_device_stats *)0)->rx_length_errors),+ -1,+ (int)&(((struct net_device_stats *)0)->rx_over_errors),+ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,+}; ++static const char *tx_error_msg[TX_ERRORS]= {+ NULL,+ "Late data arrival from the memory.",+ "Excessive deferral.",+ NULL,NULL,NULL,NULL,+ "Heartbeat collision check failure.",+ "Transmission aborted after 16 collisions.",+ "Transmission aborted due to collision.",+ "No carrier signal from the tranceiver.",+ "Loss of carrier during transmission.", +};++static const int tx_stat_offset[TX_ERRORS] = {+ -1,+ (int)&(((struct net_device_stats *)0)->tx_aborted_errors),+ (int)&(((struct net_device_stats *)0)->tx_aborted_errors),+ -1,-1,-1,-1,+ (int)&(((struct net_device_stats *)0)->tx_heartbeat_errors),+ (int)&(((struct net_device_stats *)0)->collisions),+ (int)&(((struct net_device_stats *)0)->collisions),+ (int)&(((struct net_device_stats *)0)->tx_carrier_errors),+ (int)&(((struct net_device_stats *)0)->tx_carrier_errors),+}; ++/* Helper routine */+static void wait_ms (int ms)+{+ DBG_PRINT_INOUT_FUNC("START");+ if (!in_interrupt()) {+ set_current_state(TASK_UNINTERRUPTIBLE);+ schedule_timeout(1 + ms * HZ / 1000);+ } else {+ mdelay(ms);+ }+ DBG_PRINT_INOUT_FUNC("END");+}+++/* MDIO access routines - used by MII standard Linux API */+static int mdio_read (struct net_device *dev, int phy_addr, int reg_num)+{+ u32 addr;+ u16 ret;+ int count;+ +#ifdef DEBUG_MDIO+ DBG_PRINT("%s: start addr %d reg %d\n", __func__, phy_addr, reg_num);+#endif+ /* Wait while the PHY is busy */+ for (count = 1000; count != 0; count--) {+ if (!(em86xx_read_reg(EM86XX_MIIAR_REG) & MiiBusy))+ break;+ }+ /* Set PHY & register to read */+ addr = ((phy_addr & 0x1F) << 11) | ((reg_num & 0x1F) << 6);+ em86xx_write_reg(EM86XX_MIIAR_REG, addr);+ /* Work-around Sigma-Designs MAC bug */+ udelay(40);+ /* Wait while PHY is busy */+ for (count = 1000; count != 0; count--) {+ if (!(em86xx_read_reg(EM86XX_MIIAR_REG) & MiiBusy))+ break;+ }+ ret = em86xx_read_reg(EM86XX_MIIDR_REG) & 0xFFFF;+#ifdef DEBUG_MDIO+ DBG_PRINT(" => %04x\n", ret);+#endif+ + return ret;+}++static void mdio_write (struct net_device *dev,+ int phy_addr, int reg_num, int value)+{+ u32 addr;+ int count;+ +#ifdef DEBUG_MDIO+ DBG_PRINT("%s: start addr %d reg %d val %04x\n",+ __func__, phy_addr, reg_num, value);+#endif+ /* Wait while the PHY is busy */+ for (count = 1000; count != 0; count--) {+ if (!(em86xx_read_reg(EM86XX_MIIAR_REG) & MiiBusy))+ break;+ }+ /* Set PHY & register to write */+ addr = ((phy_addr & 0x1F) << 11) | ((reg_num & 0x1F) << 6) | (1 << 1);+ em86xx_write_reg(EM86XX_MIIDR_REG, value);+ em86xx_write_reg(EM86XX_MIIAR_REG, addr);++ while (em86xx_read_reg(EM86XX_MIIAR_REG) & MiiBusy);++}++static int dump_ethtool_cmd(struct ethtool_cmd *ep)+{++ printk(" Speed: ");+ switch (ep->speed) {+ case SPEED_10:+ printk("10Mb/s\n");+ break;+ case SPEED_100:+ printk("100Mb/s\n");+ break;+ case SPEED_1000:+ printk("1000Mb/s\n");+ break;+ default:+ printk("Unknown! (%i)\n", ep->speed);+ break;+ };++ printk(" Duplex: ");+ switch (ep->duplex) {+ case DUPLEX_HALF:+ printk("Half\n");+ break;+ case DUPLEX_FULL:+ printk("Full\n");+ break;+ default:+ printk("Unknown! (%i)\n", ep->duplex);+ break;+ };++ printk(" Auto-negotiation: %s\n",+ (ep->autoneg == AUTONEG_DISABLE) ?+ "off" : "on");+ return 0;+}++++/* Routine to configure the PHY */+void setup_phy (struct mii_if_info *mii_if)+{+ struct net_device *dev = mii_if->dev;+ EM86XX_ETH_PRIV *private = (EM86XX_ETH_PRIV *)dev->priv;+ u16 phy_cntl, phy_caps, ad_caps, status;+ int timeout;+ struct ethtool_cmd cmd = { ETHTOOL_GSET };+ + DBG_PRINT_INOUT_FUNC("START");+ phy_cntl = mdio_read(dev, mii_if->phy_id, MII_BMCR);++ /* Avoid multiple instances */+ if (private->autoneg_active || !(phy_cntl & BMCR_ANENABLE) )+ return;++ private->autoneg_active = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -