patch-2.2.16 linux/drivers/net/acenic.h

Next file: linux/drivers/net/acenic_firmware.h
Previous file: linux/drivers/net/acenic.c
Back to the patch index
Back to the overall index

diff -urN v2.2.15/linux/drivers/net/acenic.h linux/drivers/net/acenic.h
@@ -14,70 +14,10 @@
  * as some of them are in PCI shared memory and it is necessary to use
  * readl/writel to access them.
  *
- * The addressing code is derived from Pete Beckman's work, but
+ * The addressing code is derived from Pete Wyckoff's work, but
  * modified to deal properly with readl/writel usage.
  */
 
-typedef struct {
-	u32 addrhi;
-	u32 addrlo;
-} aceaddr;
-
-
-static inline void set_aceaddr(aceaddr *aa, volatile void *addr)
-{
-	unsigned long baddr = virt_to_bus((void *)addr);
-#if (BITS_PER_LONG == 64)
-	aa->addrlo = baddr & 0xffffffff;
-	aa->addrhi = baddr >> 32;
-#else
-    /* Don't bother setting zero every time */
-	aa->addrlo = baddr;
-#endif
-	mb();
-}
-
-
-static inline void set_aceaddr_bus(aceaddr *aa, volatile void *addr)
-{
-	unsigned long baddr = (unsigned long)addr;
-#if (BITS_PER_LONG == 64)
-	aa->addrlo = baddr & 0xffffffff;
-	aa->addrhi = baddr >> 32;
-#else
-    /* Don't bother setting zero every time */
-	aa->addrlo = baddr;
-#endif
-	mb();
-}
-
-
-static inline void *get_aceaddr(aceaddr *aa)
-{
-	unsigned long addr;
-	mb();
-#if (BITS_PER_LONG == 64)
-	addr = (u64)aa->addrhi << 32 | aa->addrlo;
-#else
-	addr = aa->addrlo;
-#endif
-	return bus_to_virt(addr);
-}
-
-
-static inline void *get_aceaddr_bus(aceaddr *aa)
-{
-	unsigned long addr;
-	mb();
-#if (BITS_PER_LONG == 64)
-	addr = (u64)aa->addrhi << 32 | aa->addrlo;
-#else
-	addr = aa->addrlo;
-#endif
-	return (void *)addr;
-}
-
-
 struct ace_regs {
 	u32	pad0[16];	/* PCI control registers */
 
@@ -143,11 +83,11 @@
 	u32	Mb2Hi;
 	u32	TxPrd;
 	u32	Mb3Hi;
-	u32	Mb3Lo;
+	u32	RxStdPrd; /* RxStdPrd */
 	u32	Mb4Hi;
-	u32	Mb4Lo;
+	u32	RxJumboPrd; /* RxJumboPrd */
 	u32	Mb5Hi;
-	u32	Mb5Lo;
+	u32	RxMiniPrd;
 	u32	Mb6Hi;
 	u32	Mb6Lo;
 	u32	Mb7Hi;
@@ -197,7 +137,7 @@
 	u32	IfIdx;
 	u32	IfMtu;		/* 0x660 */
 	u32	MaskInt;
-	u32	LnkState;
+	u32	GigLnkState;
 	u32	FastLnkState;
 	u32	pad16[4];	/* 0x670 */
 	u32	RxRetCsm;	/* 0x680 */
@@ -208,6 +148,13 @@
 	u32	Window[0x200];
 };
 
+
+typedef struct {
+	u32 addrhi;
+	u32 addrlo;
+} aceaddr;
+
+
 #define ACE_WINDOW_SIZE	0x800
 
 #define ACE_JUMBO_MTU 9000
@@ -221,6 +168,7 @@
 	
 #define IN_INT		0x01
 #define CLR_INT		0x02
+#define HW_RESET	0x08
 #define BYTE_SWAP	0x10
 #define WORD_SWAP	0x20
 #define MASK_INTS	0x40
@@ -243,6 +191,13 @@
 
 
 /*
+ * udelay() values for when clocking the eeprom
+ */
+#define ACE_SHORT_DELAY		1
+#define ACE_LONG_DELAY		2
+
+
+/*
  * Misc Config bits
  */
 
@@ -278,7 +233,10 @@
 #define DMA_WRITE_MAX_128	0xa0
 #define DMA_WRITE_MAX_256	0xc0
 #define DMA_WRITE_MAX_1K	0xe0
+#define DMA_READ_WRITE_MASK	0xfc
 #define MEM_READ_MULTIPLE	0x00020000
+#define PCI_66MHZ		0x00080000
+#define PCI_32BIT		0x00100000
 #define DMA_WRITE_ALL_ALIGN	0x00800000
 #define READ_CMD_MEM		0x06000000
 #define WRITE_CMD_MEM		0x70000000
@@ -288,9 +246,10 @@
  * Mode status
  */
 
-#define ACE_BYTE_SWAP_DATA	0x10
+#define ACE_BYTE_SWAP_BD	0x02
+#define ACE_WORD_SWAP_BD	0x04		/* not actually used */
 #define ACE_WARN		0x08
-#define ACE_WORD_SWAP		0x04
+#define ACE_BYTE_SWAP_DMA	0x10
 #define ACE_NO_JUMBO_FRAG	0x200
 #define ACE_FATAL		0x40000000
 
@@ -340,7 +299,7 @@
 #define EVT_RING_SIZE	(EVT_RING_ENTRIES * sizeof(struct event))
 
 struct event {
-#ifdef __LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN_BITFIELD
 	u32	idx:12;
 	u32	code:12;
 	u32	evt:8;
@@ -365,6 +324,7 @@
 #define E_LNK_STATE		0x06
 #define E_C_LINK_UP		0x01
 #define E_C_LINK_DOWN		0x02
+#define E_C_LINK_10_100		0x03
 
 #define E_ERROR			0x07
 #define E_C_ERR_INVAL_CMD	0x01
@@ -385,7 +345,7 @@
 #define CMD_RING_ENTRIES	64
 
 struct cmd {
-#ifdef __LITTLE_ENDIAN
+#ifdef __LITTLE_ENDIAN_BITFIELD
 	u32	idx:12;
 	u32	code:12;
 	u32	evt:8;
@@ -416,6 +376,10 @@
 #define C_C_PROMISC_DISABLE	0x02
 
 #define C_LNK_NEGOTIATION	0x0b
+#define C_C_NEGOTIATE_BOTH	0x00
+#define C_C_NEGOTIATE_GIG	0x01
+#define C_C_NEGOTIATE_10_100	0x02
+
 #define C_SET_MAC_ADDR		0x0c
 #define C_CLEAR_PROFILE		0x0d
 
@@ -429,33 +393,30 @@
 
 
 /*
- * Descriptor types.
+ * Descriptor flags
  */
+#define BD_FLG_TCP_UDP_SUM	0x01
+#define BD_FLG_IP_SUM		0x02
+#define BD_FLG_END		0x04
+#define BD_FLG_JUMBO		0x10
+#define BD_FLG_MINI		0x1000
 
-#define DESC_TX			0x01
-#define DESC_RX			0x02
-#define DESC_END		0x04
-#define DESC_MORE		0x08
 
 /*
- * Control block flags
- */
-
-#define FLG_RX_TCP_UDP_SUM	0x01
-#define FLG_RX_IP_SUM		0x02
-#define FLG_RX_SPLIT_HDRS	0x04
-#define FLG_RX_NO_PSDO_HDR_SUM	0x08
-#define FLG_RNG_DISABLED	0x200
+ * Ring Control block flags
+ */
+#define RCB_FLG_TCP_UDP_SUM	0x01
+#define RCB_FLG_IP_SUM		0x02
+#define RCB_FLG_VLAN_ASSIST	0x10
+#define RCB_FLG_COAL_INT_ONLY	0x20
+#define RCB_FLG_IEEE_SNAP_SUM	0x80
+#define RCB_FLG_EXT_RX_BD	0x100
+#define RCB_FLG_RNG_DISABLE	0x200
 
-/*
- * Descriptor flags
- */
-#define DFLG_RX_JUMBO		0x10
 
 /*
  * TX ring
  */
-
 #define TX_RING_ENTRIES	128
 #define TX_RING_SIZE	(TX_RING_ENTRIES * sizeof(struct tx_desc))
 #define TX_RING_BASE	0x3800
@@ -471,12 +432,16 @@
 #if __LITTLE_ENDIAN
 	u16	flags;
 	u16	size;
+	u16	vlan;
+	u16	reserved;
 #else
 	u16	size;
 	u16	flags;
+	u16	reserved;
+	u16	vlan;
 #endif
 #endif
-	u32	nic_addr;
+	u32	vlanres;
 };
 
 
@@ -493,9 +458,6 @@
 #define RX_RETURN_RING_SIZE	(RX_MAX_RETURN_RING_ENTRIES * \
 				 sizeof(struct rx_desc))
 
-#define RX_RING_THRESH		64
-#define RX_RING_JUMBO_THRESH	48
-
 struct rx_desc{
 	aceaddr	addr;
 #ifdef __LITTLE_ENDIAN
@@ -520,14 +482,14 @@
 	u16	tcp_udp_csum;
 #endif
 #ifdef __LITTLE_ENDIAN
-	u16	reserved;
+	u16	vlan;
 	u16	err_flags;
 #else
 	u16	err_flags;
-	u16	reserved;
+	u16	vlan;
 #endif
-	u32	nic_addr;
-	u32	pad[1];
+	u32	reserved;
+	u32	opague;
 };
 
 
@@ -598,77 +560,170 @@
 	aceaddr	stats2_ptr;
 };
 
+
+struct ring_info {
+	struct sk_buff		*skb;
+	dma_addr_t		mapping;
+};
+
+
 /*
- * Struct private for the AceNIC.
+ * struct ace_skb holding the rings of skb's. This is an awful lot of
+ * pointers, but I don't see any other smart mode to do this in an
+ * efficient manner ;-(
  */
+struct ace_skb
+{
+	struct ring_info	tx_skbuff[TX_RING_ENTRIES];
+	struct ring_info	rx_std_skbuff[RX_STD_RING_ENTRIES];
+	struct ring_info	rx_mini_skbuff[RX_MINI_RING_ENTRIES];
+	struct ring_info	rx_jumbo_skbuff[RX_JUMBO_RING_ENTRIES];
+};
 
+
+/*
+ * Struct private for the AceNIC.
+ *
+ * Elements are grouped so variables used by the tx handling goes
+ * together, and will go into the same cache lines etc. in order to
+ * avoid cache line contention between the rx and tx handling on SMP.
+ *
+ * Frequently accessed variables are put at the beginning of the
+ * struct to help the compiler generate better/shorter code.
+ */
 struct ace_private
 {
+	struct ace_skb		*skb;
 	struct ace_regs		*regs;		/* register base */
-	volatile __u32		*sgt;
-	struct sk_buff		*pkt_buf;	/* Receive buffer */
-/*
- * The send ring is located in the shared memory window
- */
-	struct tx_desc		*tx_ring;
-	struct rx_desc		rx_std_ring[RX_STD_RING_ENTRIES];
-	struct rx_desc		rx_jumbo_ring[RX_JUMBO_RING_ENTRIES];
-#if 0
-	struct rx_desc		rx_mini_ring[RX_MINI_RING_ENTRIES];
-#endif
-	struct rx_desc		rx_return_ring[RX_RETURN_RING_ENTRIES];
-	struct event		evt_ring[EVT_RING_ENTRIES];
+	volatile int		fw_running;
+	int			version, fw_up, link;
+	int			promisc, mcast_all;
+	/*
+	 * The send ring is located in the shared memory window
+	 */
 	struct ace_info		*info;
-	struct sk_buff		*tx_skbuff[TX_RING_ENTRIES];
-	struct sk_buff		*rx_std_skbuff[RX_STD_RING_ENTRIES];
-	struct sk_buff		*rx_jumbo_skbuff[RX_JUMBO_RING_ENTRIES];
-	spinlock_t		lock;
+	struct tx_desc		*tx_ring;
+	dma_addr_t		info_dma;
+	u32			tx_prd;
+	volatile u32		tx_full, tx_ret_csm;
 	struct timer_list	timer;
-	u32			cur_rx, tx_prd;
-	u32			dirty_rx, tx_ret_csm, dirty_event;
-	u32			rx_std_skbprd, rx_jumbo_skbprd;
-	u32			tx_full;
-	volatile u32		evt_prd
-				__attribute__ ((aligned (L1_CACHE_BYTES)));
-	volatile u32		rx_ret_prd
-				__attribute__ ((aligned (L1_CACHE_BYTES)));
-	volatile u32		tx_csm
-				__attribute__ ((aligned (L1_CACHE_BYTES)));
-	struct device		*next
+
+	unsigned long		std_refill_busy
 				__attribute__ ((aligned (L1_CACHE_BYTES)));
+	unsigned long		mini_refill_busy, jumbo_refill_busy;
+	atomic_t		cur_rx_bufs,
+				cur_mini_bufs,
+				cur_jumbo_bufs;
+	u32			rx_std_skbprd, rx_mini_skbprd, rx_jumbo_skbprd;
+	u32			cur_rx;
+	struct tq_struct	immediate;
+	int			bh_pending, jumbo;
+	/*
+	 * These elements are allocated using consistent PCI dma memory.
+	 */
+	struct rx_desc		*rx_std_ring;
+	struct rx_desc		*rx_jumbo_ring;
+	struct rx_desc		*rx_mini_ring;
+	struct rx_desc		*rx_return_ring;
+	dma_addr_t		rx_ring_base_dma;
+
+	struct event		*evt_ring;
+	dma_addr_t		evt_ring_dma;
+
+	volatile u32		*evt_prd, *rx_ret_prd, *tx_csm;
+	dma_addr_t		evt_prd_dma, rx_ret_prd_dma, tx_csm_dma;
+
 	unsigned char		*trace_buf;
-	int			fw_running, fw_up, jumbo, promisc, mcast_all;
-	int			version;
-	int			flags;
-	u16			vendor;
-	u16			pci_command;
 	struct pci_dev		*pdev;
-#if 0
-	u8			pci_bus;
-	u8			pci_dev_fun;
+	struct net_device	*next;
+	int			board_idx;
+	u16			pci_command;
+	u8			pci_latency;
+	char			name[48];
+#ifdef INDEX_DEBUG
+	spinlock_t		debug_lock
+				__attribute__ ((aligned (L1_CACHE_BYTES)));;
+	u32			last_tx, last_std_rx, last_mini_rx;
 #endif
-	char			name[24];
 	struct net_device_stats stats;
 };
 
+
+static inline void set_aceaddr(aceaddr *aa, dma_addr_t addr)
+{
+	unsigned long baddr = (unsigned long) addr;
+#if (BITS_PER_LONG == 64)
+	aa->addrlo = baddr & 0xffffffff;
+	aa->addrhi = baddr >> 32;
+#else
+	/* Don't bother setting zero every time */
+	aa->addrlo = baddr;
+#endif
+	mb();
+}
+
+
+#if 0
+static inline void *get_aceaddr(aceaddr *aa)
+{
+	unsigned long addr;
+	mb();
+#if (BITS_PER_LONG == 64)
+	addr = (u64)aa->addrhi << 32 | aa->addrlo;
+#else
+	addr = aa->addrlo;
+#endif
+	return (void *)addr;
+}
+#endif
+
+
+static inline void ace_set_txprd(struct ace_regs *regs,
+				 struct ace_private *ap, u32 value)
+{
+#ifdef INDEX_DEBUG
+	unsigned long flags;
+	spin_lock_irqsave(&ap->debug_lock, flags);
+	writel(value, &regs->TxPrd);
+	if (value == ap->last_tx)
+		printk(KERN_ERR "AceNIC RACE ALERT! writing identical value "
+		       "to tx producer (%i)\n", value);
+	ap->last_tx = value;
+	spin_unlock_irqrestore(&ap->debug_lock, flags);
+#else
+	writel(value, &regs->TxPrd);
+#endif
+	wmb();
+}
+
+
 /*
  * Prototypes
  */
-static int ace_init(struct device *dev, int board_idx);
-static int ace_load_std_rx_ring(struct device *dev);
-static int ace_load_jumbo_rx_ring(struct device *dev);
-static int ace_flush_jumbo_rx_ring(struct device *dev);
+static int ace_init(struct net_device *dev);
+static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs);
+static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs);
+static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs);
 static void ace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static int ace_load_firmware(struct device *dev);
-static int ace_open(struct device *dev);
-static int ace_start_xmit(struct sk_buff *skb, struct device *dev);
-static int ace_close(struct device *dev);
+static int ace_load_firmware(struct net_device *dev);
+static int ace_open(struct net_device *dev);
+static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static int ace_close(struct net_device *dev);
 static void ace_timer(unsigned long data);
+static void ace_bh(struct net_device *dev);
 static void ace_dump_trace(struct ace_private *ap);
-static void ace_set_multicast_list(struct device *dev);
-static int ace_change_mtu(struct device *dev, int new_mtu);
-static int ace_set_mac_addr(struct device *dev, void *p);
-static struct net_device_stats *ace_get_stats(struct device *dev);
-static u8 read_eeprom_byte(struct ace_regs *regs, unsigned long offset);
+static void ace_set_multicast_list(struct net_device *dev);
+static int ace_change_mtu(struct net_device *dev, int new_mtu);
+#ifdef SKB_RECYCLE
+extern int ace_recycle(struct sk_buff *skb);
+#endif
+static int ace_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
+static int ace_set_mac_addr(struct net_device *dev, void *p);
+static void ace_set_rxtx_parms(struct net_device *dev, int jumbo);
+static int ace_allocate_descriptors(struct net_device *dev);
+static void ace_free_descriptors(struct net_device *dev);
+static void ace_init_cleanup(struct net_device *dev);
+static struct net_device_stats *ace_get_stats(struct net_device *dev);
+static int read_eeprom_byte(struct net_device *dev, unsigned long offset);
 
 #endif /* _ACENIC_H_ */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)