📄 de4x5.c
字号:
*/#define DE4X5_ALIGN4 ((u_long)4 - 1) /* 1 longword align */#define DE4X5_ALIGN8 ((u_long)8 - 1) /* 2 longword align */#define DE4X5_ALIGN16 ((u_long)16 - 1) /* 4 longword align */#define DE4X5_ALIGN32 ((u_long)32 - 1) /* 8 longword align */#define DE4X5_ALIGN64 ((u_long)64 - 1) /* 16 longword align */#define DE4X5_ALIGN128 ((u_long)128 - 1) /* 32 longword align */#define DE4X5_ALIGN DE4X5_ALIGN32 /* Keep the DC21040 happy... */#define DE4X5_CACHE_ALIGN CAL_16LONG#define DESC_SKIP_LEN DSL_0 /* Must agree with DESC_ALIGN *//*#define DESC_ALIGN u32 dummy[4]; / * Must agree with DESC_SKIP_LEN */#define DESC_ALIGN#ifndef DEC_ONLY /* See README.de4x5 for using this */static int dec_only;#elsestatic int dec_only = 1;#endif/*** DE4X5 IRQ ENABLE/DISABLE*/#define ENABLE_IRQs { \ imr |= lp->irq_en;\ outl(imr, DE4X5_IMR); /* Enable the IRQs */\}#define DISABLE_IRQs {\ imr = inl(DE4X5_IMR);\ imr &= ~lp->irq_en;\ outl(imr, DE4X5_IMR); /* Disable the IRQs */\}#define UNMASK_IRQs {\ imr |= lp->irq_mask;\ outl(imr, DE4X5_IMR); /* Unmask the IRQs */\}#define MASK_IRQs {\ imr = inl(DE4X5_IMR);\ imr &= ~lp->irq_mask;\ outl(imr, DE4X5_IMR); /* Mask the IRQs */\}/*** DE4X5 START/STOP*/#define START_DE4X5 {\ omr = inl(DE4X5_OMR);\ omr |= OMR_ST | OMR_SR;\ outl(omr, DE4X5_OMR); /* Enable the TX and/or RX */\}#define STOP_DE4X5 {\ omr = inl(DE4X5_OMR);\ omr &= ~(OMR_ST|OMR_SR);\ outl(omr, DE4X5_OMR); /* Disable the TX and/or RX */ \}/*** DE4X5 SIA RESET*/#define RESET_SIA outl(0, DE4X5_SICR); /* Reset SIA connectivity regs *//*** DE500 AUTOSENSE TIMER INTERVAL (MILLISECS)*/#define DE4X5_AUTOSENSE_MS 250/*** SROM Structure*/struct de4x5_srom { char sub_vendor_id[2]; char sub_system_id[2]; char reserved[12]; char id_block_crc; char reserved2; char version; char num_controllers; char ieee_addr[6]; char info[100]; short chksum;};#define SUB_VENDOR_ID 0x500a/*** DE4X5 Descriptors. Make sure that all the RX buffers are contiguous** and have sizes of both a power of 2 and a multiple of 4.** A size of 256 bytes for each buffer could be chosen because over 90% of** all packets in our network are <256 bytes long and 64 longword alignment** is possible. 1536 showed better 'ttcp' performance. Take your pick. 32 TX** descriptors are needed for machines with an ALPHA CPU.*/#define NUM_RX_DESC 8 /* Number of RX descriptors */#define NUM_TX_DESC 32 /* Number of TX descriptors */#define RX_BUFF_SZ 1536 /* Power of 2 for kmalloc and */ /* Multiple of 4 for DC21040 */ /* Allows 512 byte alignment */struct de4x5_desc { volatile s32 status; u32 des1; u32 buf; u32 next; DESC_ALIGN};/*** The DE4X5 private structure*/#define DE4X5_PKT_STAT_SZ 16#define DE4X5_PKT_BIN_SZ 128 /* Should be >=100 unless you increase DE4X5_PKT_STAT_SZ */struct pkt_stats { u_int bins[DE4X5_PKT_STAT_SZ]; /* Private stats counters */ u_int unicast; u_int multicast; u_int broadcast; u_int excessive_collisions; u_int tx_underruns; u_int excessive_underruns; u_int rx_runt_frames; u_int rx_collision; u_int rx_dribble; u_int rx_overflow;};struct de4x5_private { char adapter_name[80]; /* Adapter name */ u_long interrupt; /* Aligned ISR flag */ struct de4x5_desc *rx_ring; /* RX descriptor ring */ struct de4x5_desc *tx_ring; /* TX descriptor ring */ struct sk_buff *tx_skb[NUM_TX_DESC]; /* TX skb for freeing when sent */ struct sk_buff *rx_skb[NUM_RX_DESC]; /* RX skb's */ int rx_new, rx_old; /* RX descriptor ring pointers */ int tx_new, tx_old; /* TX descriptor ring pointers */ char setup_frame[SETUP_FRAME_LEN]; /* Holds MCA and PA info. */ char frame[64]; /* Min sized packet for loopback*/ spinlock_t lock; /* Adapter specific spinlock */ struct net_device_stats stats; /* Public stats */ struct pkt_stats pktStats; /* Private stats counters */ char rxRingSize; char txRingSize; int bus; /* EISA or PCI */ int bus_num; /* PCI Bus number */ int device; /* Device number on PCI bus */ int state; /* Adapter OPENED or CLOSED */ int chipset; /* DC21040, DC21041 or DC21140 */ s32 irq_mask; /* Interrupt Mask (Enable) bits */ s32 irq_en; /* Summary interrupt bits */ int media; /* Media (eg TP), mode (eg 100B)*/ int c_media; /* Remember the last media conn */ int fdx; /* media full duplex flag */ int linkOK; /* Link is OK */ int autosense; /* Allow/disallow autosensing */ int tx_enable; /* Enable descriptor polling */ int setup_f; /* Setup frame filtering type */ int local_state; /* State within a 'media' state */ struct mii_phy phy[DE4X5_MAX_PHY]; /* List of attached PHY devices */ struct sia_phy sia; /* SIA PHY Information */ int active; /* Index to active PHY device */ int mii_cnt; /* Number of attached PHY's */ int timeout; /* Scheduling counter */ struct timer_list timer; /* Timer info for kernel */ int tmp; /* Temporary global per card */ struct { u_long lock; /* Lock the cache accesses */ s32 csr0; /* Saved Bus Mode Register */ s32 csr6; /* Saved Operating Mode Reg. */ s32 csr7; /* Saved IRQ Mask Register */ s32 gep; /* Saved General Purpose Reg. */ s32 gepc; /* Control info for GEP */ s32 csr13; /* Saved SIA Connectivity Reg. */ s32 csr14; /* Saved SIA TX/RX Register */ s32 csr15; /* Saved SIA General Register */ int save_cnt; /* Flag if state already saved */ struct sk_buff *skb; /* Save the (re-ordered) skb's */ } cache; struct de4x5_srom srom; /* A copy of the SROM */ int cfrv; /* Card CFRV copy */ int rx_ovf; /* Check for 'RX overflow' tag */ int useSROM; /* For non-DEC card use SROM */ int useMII; /* Infoblock using the MII */ int asBitValid; /* Autosense bits in GEP? */ int asPolarity; /* 0 => asserted high */ int asBit; /* Autosense bit number in GEP */ int defMedium; /* SROM default medium */ int tcount; /* Last infoblock number */ int infoblock_init; /* Initialised this infoblock? */ int infoleaf_offset; /* SROM infoleaf for controller */ s32 infoblock_csr6; /* csr6 value in SROM infoblock */ int infoblock_media; /* infoblock media */ int (*infoleaf_fn)(struct net_device *); /* Pointer to infoleaf function */ u_char *rst; /* Pointer to Type 5 reset info */ u_char ibn; /* Infoblock number */ struct parameters params; /* Command line/ #defined params */ struct device *gendev; /* Generic device */ dma_addr_t dma_rings; /* DMA handle for rings */ int dma_size; /* Size of the DMA area */ char *rx_bufs; /* rx bufs on alpha, sparc, ... */};/*** To get around certain poxy cards that don't provide an SROM** for the second and more DECchip, I have to key off the first** chip's address. I'll assume there's not a bad SROM iff:**** o the chipset is the same** o the bus number is the same and > 0** o the sum of all the returned hw address bytes is 0 or 0x5fa**** Also have to save the irq for those cards whose hardware designers** can't follow the PCI to PCI Bridge Architecture spec.*/static struct { int chipset; int bus; int irq; u_char addr[ETH_ALEN];} last = {0,};/*** The transmit ring full condition is described by the tx_old and tx_new** pointers by:** tx_old = tx_new Empty ring** tx_old = tx_new+1 Full ring** tx_old+txRingSize = tx_new+1 Full ring (wrapped condition)*/#define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\ lp->tx_old+lp->txRingSize-lp->tx_new-1:\ lp->tx_old -lp->tx_new-1)#define TX_PKT_PENDING (lp->tx_old != lp->tx_new)/*** Public Functions*/static int de4x5_open(struct net_device *dev);static int de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev);static irqreturn_t de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs);static int de4x5_close(struct net_device *dev);static struct net_device_stats *de4x5_get_stats(struct net_device *dev);static void de4x5_local_stats(struct net_device *dev, char *buf, int pkt_len);static void set_multicast_list(struct net_device *dev);static int de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);/*** Private functions*/static int de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev);static int de4x5_init(struct net_device *dev);static int de4x5_sw_reset(struct net_device *dev);static int de4x5_rx(struct net_device *dev);static int de4x5_tx(struct net_device *dev);static int de4x5_ast(struct net_device *dev);static int de4x5_txur(struct net_device *dev);static int de4x5_rx_ovfc(struct net_device *dev);static int autoconf_media(struct net_device *dev);static void create_packet(struct net_device *dev, char *frame, int len);static void load_packet(struct net_device *dev, char *buf, u32 flags, struct sk_buff *skb);static int dc21040_autoconf(struct net_device *dev);static int dc21041_autoconf(struct net_device *dev);static int dc21140m_autoconf(struct net_device *dev);static int dc2114x_autoconf(struct net_device *dev);static int srom_autoconf(struct net_device *dev);static int de4x5_suspect_state(struct net_device *dev, int timeout, int prev_state, int (*fn)(struct net_device *, int), int (*asfn)(struct net_device *));static int dc21040_state(struct net_device *dev, int csr13, int csr14, int csr15, int timeout, int next_state, int suspect_state, int (*fn)(struct net_device *, int));static int test_media(struct net_device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec);static int test_for_100Mb(struct net_device *dev, int msec);static int wait_for_link(struct net_device *dev);static int test_mii_reg(struct net_device *dev, int reg, int mask, int pol, long msec);static int is_spd_100(struct net_device *dev);static int is_100_up(struct net_device *dev);static int is_10_up(struct net_device *dev);static int is_anc_capable(struct net_device *dev);static int ping_media(struct net_device *dev, int msec);static struct sk_buff *de4x5_alloc_rx_buff(struct net_device *dev, int index, int len);static void de4x5_free_rx_buffs(struct net_device *dev);static void de4x5_free_tx_buffs(struct net_device *dev);static void de4x5_save_skbs(struct net_device *dev);static void de4x5_rst_desc_ring(struct net_device *dev);static void de4x5_cache_state(struct net_device *dev, int flag);static void de4x5_put_cache(struct net_device *dev, struct sk_buff *skb);static void de4x5_putb_cache(struct net_device *dev, struct sk_buff *skb);static struct sk_buff *de4x5_get_cache(struct net_device *dev);static void de4x5_setup_intr(struct net_device *dev);static void de4x5_init_connection(struct net_device *dev);static int de4x5_reset_phy(struct net_device *dev);static void reset_init_sia(struct net_device *dev, s32 sicr, s32 strr, s32 sigr);static int test_ans(struct net_device *dev, s32 irqs, s32 irq_mask, s32 msec);static int test_tp(struct net_device *dev, s32 msec);static int EISA_signature(char *name, struct device *device);static int PCI_signature(char *name, struct de4x5_private *lp);static void DevicePresent(struct net_device *dev, u_long iobase);static void enet_addr_rst(u_long aprom_addr);static int de4x5_bad_srom(struct de4x5_private *lp);static short srom_rd(u_long address, u_char offset);static void srom_latch(u_int command, u_long address);static void srom_command(u_int command, u_long address);static void srom_address(u_int command, u_long address, u_char offset);static short srom_data(u_int command, u_long address);/*static void srom_busy(u_int command, u_long address);*/static void sendto_srom(u_int command, u_long addr);static int getfrom_srom(u_long addr);static int srom_map_media(struct net_device *dev);static int srom_infoleaf_info(struct net_device *dev);static void srom_init(struct net_device *dev);static void srom_exec(struct net_device *dev, u_char *p);static int mii_rd(u_char phyreg, u_char phyaddr, u_long ioaddr);static void mii_wr(int data, u_char phyreg, u_char phyaddr, u_long ioaddr);static int mii_rdata(u_long ioaddr);static void mii_wdata(int data, int len, u_long ioaddr);static void mii_ta(u_long rw, u_long ioaddr);static int mii_swap(int data, int len);static void mii_address(u_char addr, u_long ioaddr);static void sendto_mii(u32 command, int data, u_long ioaddr);static int getfrom_mii(u32 command, u_long ioaddr);static int mii_get_oui(u_char phyaddr, u_long ioaddr);static int mii_get_phy(struct net_device *dev);static void SetMulticastFilter(struct net_device *dev);static int get_hw_addr(struct net_device *dev);static void srom_repair(struct net_device *dev, int card);static int test_bad_enet(struct net_device *dev, int status);static int an_exception(struct de4x5_private *lp);static char *build_setup_frame(struct net_device *dev, int mode);static void disable_ast(struct net_device *dev);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -