3c59x.c
来自「linux 内核源代码」· C语言 代码 · 共 1,988 行 · 第 1/5 页
C
1,988 行
{ 0x10B7, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9805 }, { 0x10B7, 0x7646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CSOHO100_TX }, { 0x10B7, 0x5055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C555 }, { 0x10B7, 0x6055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C556 }, { 0x10B7, 0x6056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C556B }, { 0x10B7, 0x5b57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C575 }, { 0x10B7, 0x5057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C575_1 }, { 0x10B7, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CCFE575 }, { 0x10B7, 0x5257, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CCFE575CT }, { 0x10B7, 0x6560, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CCFE656 }, { 0x10B7, 0x6562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CCFEM656 }, { 0x10B7, 0x6564, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CCFEM656_1 }, { 0x10B7, 0x4500, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C450 }, { 0x10B7, 0x9201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C920 }, { 0x10B7, 0x1201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C982A }, { 0x10B7, 0x1202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C982B }, { 0x10B7, 0x9056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_905BT4 }, { 0x10B7, 0x9210, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_920B_EMB_WNM }, {0,} /* 0 terminated list. */};MODULE_DEVICE_TABLE(pci, vortex_pci_tbl);/* Operational definitions. These are not used by other compilation units and thus are not exported in a ".h" file. First the windows. There are eight register windows, with the command and status registers available in each. */#define EL3WINDOW(win_num) iowrite16(SelectWindow + (win_num), ioaddr + EL3_CMD)#define EL3_CMD 0x0e#define EL3_STATUS 0x0e/* The top five bits written to EL3_CMD are a command, the lower 11 bits are the parameter, if applicable. Note that 11 parameters bits was fine for ethernet, but the new chip can handle FDDI length frames (~4500 octets) and now parameters count 32-bit 'Dwords' rather than octets. */enum vortex_cmd { TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11, RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, UpStall = 6<<11, UpUnstall = (6<<11)+1, DownStall = (6<<11)+2, DownUnstall = (6<<11)+3, RxDiscard = 8<<11, TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11, FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11, SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11, SetTxThreshold = 18<<11, SetTxStart = 19<<11, StartDMAUp = 20<<11, StartDMADown = (20<<11)+1, StatsEnable = 21<<11, StatsDisable = 22<<11, StopCoax = 23<<11, SetFilterBit = 25<<11,};/* The SetRxFilter command accepts the following classes: */enum RxFilter { RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 };/* Bits in the general status register. */enum vortex_status { IntLatch = 0x0001, HostError = 0x0002, TxComplete = 0x0004, TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020, IntReq = 0x0040, StatsFull = 0x0080, DMADone = 1<<8, DownComplete = 1<<9, UpComplete = 1<<10, DMAInProgress = 1<<11, /* DMA controller is still busy.*/ CmdInProgress = 1<<12, /* EL3_CMD is still busy.*/};/* Register window 1 offsets, the window used in normal operation. On the Vortex this window is always mapped at offsets 0x10-0x1f. */enum Window1 { TX_FIFO = 0x10, RX_FIFO = 0x10, RxErrors = 0x14, RxStatus = 0x18, Timer=0x1A, TxStatus = 0x1B, TxFree = 0x1C, /* Remaining free bytes in Tx buffer. */};enum Window0 { Wn0EepromCmd = 10, /* Window 0: EEPROM command register. */ Wn0EepromData = 12, /* Window 0: EEPROM results register. */ IntrStatus=0x0E, /* Valid in all windows. */};enum Win0_EEPROM_bits { EEPROM_Read = 0x80, EEPROM_WRITE = 0x40, EEPROM_ERASE = 0xC0, EEPROM_EWENB = 0x30, /* Enable erasing/writing for 10 msec. */ EEPROM_EWDIS = 0x00, /* Disable EWENB before 10 msec timeout. */};/* EEPROM locations. */enum eeprom_offset { PhysAddr01=0, PhysAddr23=1, PhysAddr45=2, ModelID=3, EtherLink3ID=7, IFXcvrIO=8, IRQLine=9, NodeAddr01=10, NodeAddr23=11, NodeAddr45=12, DriverTune=13, Checksum=15};enum Window2 { /* Window 2. */ Wn2_ResetOptions=12,};enum Window3 { /* Window 3: MAC/config bits. */ Wn3_Config=0, Wn3_MaxPktSize=4, Wn3_MAC_Ctrl=6, Wn3_Options=8,};#define BFEXT(value, offset, bitcount) \ ((((unsigned long)(value)) >> (offset)) & ((1 << (bitcount)) - 1))#define BFINS(lhs, rhs, offset, bitcount) \ (((lhs) & ~((((1 << (bitcount)) - 1)) << (offset))) | \ (((rhs) & ((1 << (bitcount)) - 1)) << (offset)))#define RAM_SIZE(v) BFEXT(v, 0, 3)#define RAM_WIDTH(v) BFEXT(v, 3, 1)#define RAM_SPEED(v) BFEXT(v, 4, 2)#define ROM_SIZE(v) BFEXT(v, 6, 2)#define RAM_SPLIT(v) BFEXT(v, 16, 2)#define XCVR(v) BFEXT(v, 20, 4)#define AUTOSELECT(v) BFEXT(v, 24, 1)enum Window4 { /* Window 4: Xcvr/media bits. */ Wn4_FIFODiag = 4, Wn4_NetDiag = 6, Wn4_PhysicalMgmt=8, Wn4_Media = 10,};enum Win4_Media_bits { Media_SQE = 0x0008, /* Enable SQE error counting for AUI. */ Media_10TP = 0x00C0, /* Enable link beat and jabber for 10baseT. */ Media_Lnk = 0x0080, /* Enable just link beat for 100TX/100FX. */ Media_LnkBeat = 0x0800,};enum Window7 { /* Window 7: Bus Master control. */ Wn7_MasterAddr = 0, Wn7_VlanEtherType=4, Wn7_MasterLen = 6, Wn7_MasterStatus = 12,};/* Boomerang bus master control registers. */enum MasterCtrl { PktStatus = 0x20, DownListPtr = 0x24, FragAddr = 0x28, FragLen = 0x2c, TxFreeThreshold = 0x2f, UpPktStatus = 0x30, UpListPtr = 0x38,};/* The Rx and Tx descriptor lists. Caution Alpha hackers: these types are 32 bits! Note also the 8 byte alignment contraint on tx_ring[] and rx_ring[]. */#define LAST_FRAG 0x80000000 /* Last Addr/Len pair in descriptor. */#define DN_COMPLETE 0x00010000 /* This packet has been downloaded */struct boom_rx_desc { __le32 next; /* Last entry points to 0. */ __le32 status; __le32 addr; /* Up to 63 addr/len pairs possible. */ __le32 length; /* Set LAST_FRAG to indicate last pair. */};/* Values for the Rx status entry. */enum rx_desc_status { RxDComplete=0x00008000, RxDError=0x4000, /* See boomerang_rx() for actual error bits */ IPChksumErr=1<<25, TCPChksumErr=1<<26, UDPChksumErr=1<<27, IPChksumValid=1<<29, TCPChksumValid=1<<30, UDPChksumValid=1<<31,};#ifdef MAX_SKB_FRAGS#define DO_ZEROCOPY 1#else#define DO_ZEROCOPY 0#endifstruct boom_tx_desc { __le32 next; /* Last entry points to 0. */ __le32 status; /* bits 0:12 length, others see below. */#if DO_ZEROCOPY struct { __le32 addr; __le32 length; } frag[1+MAX_SKB_FRAGS];#else __le32 addr; __le32 length;#endif};/* Values for the Tx status entry. */enum tx_desc_status { CRCDisable=0x2000, TxDComplete=0x8000, AddIPChksum=0x02000000, AddTCPChksum=0x04000000, AddUDPChksum=0x08000000, TxIntrUploaded=0x80000000, /* IRQ when in FIFO, but maybe not sent. */};/* Chip features we care about in vp->capabilities, read from the EEPROM. */enum ChipCaps { CapBusMaster=0x20, CapPwrMgmt=0x2000 };struct vortex_extra_stats { unsigned long tx_deferred; unsigned long tx_max_collisions; unsigned long tx_multiple_collisions; unsigned long tx_single_collisions; unsigned long rx_bad_ssd;};struct vortex_private { /* The Rx and Tx rings should be quad-word-aligned. */ struct boom_rx_desc* rx_ring; struct boom_tx_desc* tx_ring; dma_addr_t rx_ring_dma; dma_addr_t tx_ring_dma; /* The addresses of transmit- and receive-in-place skbuffs. */ struct sk_buff* rx_skbuff[RX_RING_SIZE]; struct sk_buff* tx_skbuff[TX_RING_SIZE]; unsigned int cur_rx, cur_tx; /* The next free ring entry */ unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ struct net_device_stats stats; /* Generic stats */ struct vortex_extra_stats xstats; /* NIC-specific extra stats */ struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */ dma_addr_t tx_skb_dma; /* Allocated DMA address for bus master ctrl DMA. */ /* PCI configuration space information. */ struct device *gendev; void __iomem *ioaddr; /* IO address space */ void __iomem *cb_fn_base; /* CardBus function status addr space. */ /* Some values here only for performance evaluation and path-coverage */ int rx_nocopy, rx_copy, queued_packet, rx_csumhits; int card_idx; /* The remainder are related to chip state, mostly media selection. */ struct timer_list timer; /* Media selection timer. */ struct timer_list rx_oom_timer; /* Rx skb allocation retry timer */ int options; /* User-settable misc. driver options. */ unsigned int media_override:4, /* Passed-in media type. */ default_media:4, /* Read from the EEPROM/Wn3_Config. */ full_duplex:1, autoselect:1, bus_master:1, /* Vortex can only do a fragment bus-m. */ full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang */ flow_ctrl:1, /* Use 802.3x flow control (PAUSE only) */ partner_flow_ctrl:1, /* Partner supports flow control */ has_nway:1, enable_wol:1, /* Wake-on-LAN is enabled */ pm_state_valid:1, /* pci_dev->saved_config_space has sane contents */ open:1, medialock:1, must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ large_frames:1; /* accept large frames */ int drv_flags; u16 status_enable; u16 intr_enable; u16 available_media; /* From Wn3_Options. */ u16 capabilities, info1, info2; /* Various, from EEPROM. */ u16 advertising; /* NWay media advertisement */ unsigned char phys[2]; /* MII device addresses. */ u16 deferred; /* Resend these interrupts when we * bale from the ISR */ u16 io_size; /* Size of PCI region (for release_region) */ spinlock_t lock; /* Serialise access to device & its vortex_private */ struct mii_if_info mii; /* MII lib hooks/info */};#ifdef CONFIG_PCI#define DEVICE_PCI(dev) (((dev)->bus == &pci_bus_type) ? to_pci_dev((dev)) : NULL)#else#define DEVICE_PCI(dev) NULL#endif#define VORTEX_PCI(vp) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL)#ifdef CONFIG_EISA#define DEVICE_EISA(dev) (((dev)->bus == &eisa_bus_type) ? to_eisa_device((dev)) : NULL)#else#define DEVICE_EISA(dev) NULL#endif#define VORTEX_EISA(vp) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL)/* The action to take with a media selection timer tick. Note that we deviate from the 3Com order by checking 10base2 before AUI. */enum xcvr_types { XCVR_10baseT=0, XCVR_AUI, XCVR_10baseTOnly, XCVR_10base2, XCVR_100baseTx, XCVR_100baseFx, XCVR_MII=6, XCVR_NWAY=8, XCVR_ExtMII=9, XCVR_Default=10,};static const struct media_table { char *name; unsigned int media_bits:16, /* Bits to set in Wn4_Media register. */ mask:8, /* The transceiver-present bit in Wn3_Config.*/ next:8; /* The media type to try next. */ int wait; /* Time before we check media status. */} media_tbl[] = { { "10baseT", Media_10TP,0x08, XCVR_10base2, (14*HZ)/10}, { "10Mbs AUI", Media_SQE, 0x20, XCVR_Default, (1*HZ)/10}, { "undefined", 0, 0x80, XCVR_10baseT, 10000}, { "10base2", 0, 0x10, XCVR_AUI, (1*HZ)/10}, { "100baseTX", Media_Lnk, 0x02, XCVR_100baseFx, (14*HZ)/10}, { "100baseFX", Media_Lnk, 0x04, XCVR_MII, (14*HZ)/10}, { "MII", 0, 0x41, XCVR_10baseT, 3*HZ }, { "undefined", 0, 0x01, XCVR_10baseT, 10000}, { "Autonegotiate", 0, 0x41, XCVR_10baseT, 3*HZ}, { "MII-External", 0, 0x41, XCVR_10baseT, 3*HZ }, { "Default", 0, 0xFF, XCVR_10baseT, 10000},};static struct { const char str[ETH_GSTRING_LEN];} ethtool_stats_keys[] = { { "tx_deferred" }, { "tx_max_collisions" }, { "tx_multiple_collisions" }, { "tx_single_collisions" }, { "rx_bad_ssd" },};/* number of ETHTOOL_GSTATS u64's */#define VORTEX_NUM_STATS 5static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq, int chip_idx, int card_idx);static int vortex_up(struct net_device *dev);static void vortex_down(struct net_device *dev, int final);static int vortex_open(struct net_device *dev);static void mdio_sync(void __iomem *ioaddr, int bits);static int mdio_read(struct net_device *dev, int phy_id, int location);static void mdio_write(struct net_device *vp, int phy_id, int location, int value);static void vortex_timer(unsigned long arg);static void rx_oom_timer(unsigned long arg);static int vortex_start_xmit(struct sk_buff *skb, struct net_device *dev);static int boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev);static int vortex_rx(struct net_device *dev);static int boomerang_rx(struct net_device *dev);static irqreturn_t vortex_interrupt(int irq, void *dev_id);static irqreturn_t boomerang_interrupt(int irq, void *dev_id);static int vortex_close(struct net_device *dev);static void dump_tx_ring(struct net_device *dev);static void update_stats(void __iomem *ioaddr, struct net_device *dev);static struct net_device_stats *vortex_get_stats(struct net_device *dev);static void set_rx_mode(struct net_device *dev);#ifdef CONFIG_PCIstatic int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);#endifstatic void vortex_tx_timeout(struct net_device *dev);static void acpi_set_WOL(struct net_device *dev);static const struct ethtool_ops vortex_ethtool_ops;static void set_8021q_mode(struct net_device *dev, int enable);/* This driver uses 'options' to pass the media type, full-duplex flag, etc. *//* Option count limit only -- unlimited interfaces are supported. */#define MAX_UNITS 8static int options[MAX_UNITS] = { [0 ... MAX_UNITS-1] = -1 };static int full_duplex[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };static int hw_checksums[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };static int flow_ctrl[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };static int enable_wol[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };static int use_mmio[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };static int global_options = -1;static int global_full_duplex = -1;static int global_enable_wol = -1;static int global_use_mmio = -1;/* Variables to work-around the Compaq PCI BIOS32 problem. */static int compaq_ioaddr, compaq_irq, compaq_device_id = 0x5900;static struct net_device *compaq_net_device;static int vortex_cards_found;module_param(debug, int, 0);module_param(global_options, int, 0);module_param_array(options, int, NULL, 0);module_param(global_full_duplex, int, 0);module_param_array(full_duplex, int, NULL, 0);module_param_array(hw_checksums, int, NULL, 0);module_param_array(flow_ctrl, int, NULL, 0);module_param(global_enable_wol, int, 0);module_param_array(enable_wol, int, NULL, 0);module_param(rx_copybreak, int, 0);module_param(max_interrupt_work, int, 0);module_param(compaq_ioaddr, int, 0);module_param(compaq_irq, int, 0);module_param(compaq_device_id, int, 0);module_param(watchdog, int, 0);module_param(global_use_mmio, int, 0);module_param_array(use_mmio, int, NULL, 0);MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");MODULE_PARM_DESC(full_duplex, "3c59x full duplex setting(s) (1)");MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if full_duplex is unset");MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)");MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)");MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)");MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if enable_wol is unset");MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames");MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt");MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)");MODULE_PARM_DESC(compaq_irq, "3c59x PCI IRQ number (Compaq BIOS problem workaround)");MODULE_PARM_DESC(compaq_device_id, "3c59x PCI device ID (Compaq BIOS problem workaround)");MODULE_PARM_DESC(watchdog, "3c59x transmit timeout in milliseconds");MODULE_PARM_DESC(global_use_mmio, "3c59x: same as use_mmio, but applies to all NICs if options is unset");MODULE_PARM_DESC(use_mmio, "3c59x: use memory-mapped PCI I/O resource (0-1)");#ifdef CONFIG_NET_POLL_CONTROLLERstatic void poll_vortex(struct net_device *dev){ struct vortex_private *vp = netdev_priv(dev); unsigned long flags; local_irq_save(flags); (vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?