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 + -
显示快捷键?