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
- Lines: 511
- Date:
Wed Jun 7 14:26:43 2000
- Orig file:
v2.2.15/linux/drivers/net/acenic.h
- Orig date:
Mon Mar 22 08:08:12 1999
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, ®s->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, ®s->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)