Skip to content

Commit 6b7c5b9

Browse files
Sathya Perladavem330
authored andcommitted
net: Add be2net driver.
Signed-off-by: Sathya Perla <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2c5849e commit 6b7c5b9

File tree

11 files changed

+4378
-0
lines changed

11 files changed

+4378
-0
lines changed

MAINTAINERS

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3880,6 +3880,15 @@ L: [email protected]
38803880
T: git kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev.git
38813881
S: Supported
38823882

3883+
SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER
3884+
P: Sathya Perla
3885+
3886+
P: Subbu Seetharaman
3887+
3888+
3889+
W: http://www.serverengines.com
3890+
S: Supported
3891+
38833892
SFC NETWORK DRIVER
38843893
P: Steve Hodgson
38853894
P: Ben Hutchings

drivers/net/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2630,6 +2630,8 @@ config QLGE
26302630

26312631
source "drivers/net/sfc/Kconfig"
26322632

2633+
source "drivers/net/benet/Kconfig"
2634+
26332635
endif # NETDEV_10000
26342636

26352637
source "drivers/net/tokenring/Kconfig"

drivers/net/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ obj-$(CONFIG_GIANFAR) += gianfar_driver.o
2222
obj-$(CONFIG_TEHUTI) += tehuti.o
2323
obj-$(CONFIG_ENIC) += enic/
2424
obj-$(CONFIG_JME) += jme.o
25+
obj-$(CONFIG_BE2NET) += benet/
2526

2627
gianfar_driver-objs := gianfar.o \
2728
gianfar_ethtool.o \

drivers/net/benet/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
config BE2NET
2+
tristate "ServerEngines' 10Gbps NIC - BladeEngine 2"
3+
depends on PCI && INET
4+
select INET_LRO
5+
help
6+
This driver implements the NIC functionality for ServerEngines'
7+
10Gbps network adapter - BladeEngine 2.

drivers/net/benet/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#
2+
# Makefile to build the network driver for ServerEngine's BladeEngine.
3+
#
4+
5+
obj-$(CONFIG_BE2NET) += be2net.o
6+
7+
be2net-y := be_main.o be_cmds.o be_ethtool.o

drivers/net/benet/be.h

Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
/*
2+
* Copyright (C) 2005 - 2009 ServerEngines
3+
* All rights reserved.
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU General Public License version 2
7+
* as published by the Free Software Foundation. The full GNU General
8+
* Public License is included in this distribution in the file called COPYING.
9+
*
10+
* Contact Information:
11+
12+
*
13+
* ServerEngines
14+
* 209 N. Fair Oaks Ave
15+
* Sunnyvale, CA 94085
16+
*/
17+
18+
#ifndef BE_H
19+
#define BE_H
20+
21+
#include <linux/pci.h>
22+
#include <linux/etherdevice.h>
23+
#include <linux/version.h>
24+
#include <linux/delay.h>
25+
#include <net/tcp.h>
26+
#include <net/ip.h>
27+
#include <net/ipv6.h>
28+
#include <linux/if_vlan.h>
29+
#include <linux/workqueue.h>
30+
#include <linux/interrupt.h>
31+
#include <linux/inet_lro.h>
32+
33+
#include "be_hw.h"
34+
35+
#define DRV_VER "2.0.348"
36+
#define DRV_NAME "be2net"
37+
#define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC"
38+
#define DRV_DESC BE_NAME "Driver"
39+
40+
/* Number of bytes of an RX frame that are copied to skb->data */
41+
#define BE_HDR_LEN 64
42+
#define BE_MAX_JUMBO_FRAME_SIZE 9018
43+
#define BE_MIN_MTU 256
44+
45+
#define BE_NUM_VLANS_SUPPORTED 64
46+
#define BE_MAX_EQD 96
47+
#define BE_MAX_TX_FRAG_COUNT 30
48+
49+
#define EVNT_Q_LEN 1024
50+
#define TX_Q_LEN 2048
51+
#define TX_CQ_LEN 1024
52+
#define RX_Q_LEN 1024 /* Does not support any other value */
53+
#define RX_CQ_LEN 1024
54+
#define MCC_Q_LEN 64 /* total size not to exceed 8 pages */
55+
#define MCC_CQ_LEN 256
56+
57+
#define BE_NAPI_WEIGHT 64
58+
#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
59+
#define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST)
60+
61+
#define BE_MAX_LRO_DESCRIPTORS 16
62+
#define BE_MAX_FRAGS_PER_FRAME 16
63+
64+
struct be_dma_mem {
65+
void *va;
66+
dma_addr_t dma;
67+
u32 size;
68+
};
69+
70+
struct be_queue_info {
71+
struct be_dma_mem dma_mem;
72+
u16 len;
73+
u16 entry_size; /* Size of an element in the queue */
74+
u16 id;
75+
u16 tail, head;
76+
bool created;
77+
atomic_t used; /* Number of valid elements in the queue */
78+
};
79+
80+
struct be_ctrl_info {
81+
u8 __iomem *csr;
82+
u8 __iomem *db; /* Door Bell */
83+
u8 __iomem *pcicfg; /* PCI config space */
84+
int pci_func;
85+
86+
/* Mbox used for cmd request/response */
87+
spinlock_t cmd_lock; /* For serializing cmds to BE card */
88+
struct be_dma_mem mbox_mem;
89+
/* Mbox mem is adjusted to align to 16 bytes. The allocated addr
90+
* is stored for freeing purpose */
91+
struct be_dma_mem mbox_mem_alloced;
92+
};
93+
94+
#include "be_cmds.h"
95+
96+
struct be_drvr_stats {
97+
u32 be_tx_reqs; /* number of TX requests initiated */
98+
u32 be_tx_stops; /* number of times TX Q was stopped */
99+
u32 be_fwd_reqs; /* number of send reqs through forwarding i/f */
100+
u32 be_tx_wrbs; /* number of tx WRBs used */
101+
u32 be_tx_events; /* number of tx completion events */
102+
u32 be_tx_compl; /* number of tx completion entries processed */
103+
u64 be_tx_jiffies;
104+
ulong be_tx_bytes;
105+
ulong be_tx_bytes_prev;
106+
u32 be_tx_rate;
107+
108+
u32 cache_barrier[16];
109+
110+
u32 be_ethrx_post_fail;/* number of ethrx buffer alloc failures */
111+
u32 be_polls; /* number of times NAPI called poll function */
112+
u32 be_rx_events; /* number of ucast rx completion events */
113+
u32 be_rx_compl; /* number of rx completion entries processed */
114+
u32 be_lro_hgram_data[8]; /* histogram of LRO data packets */
115+
u32 be_lro_hgram_ack[8]; /* histogram of LRO ACKs */
116+
u64 be_rx_jiffies;
117+
ulong be_rx_bytes;
118+
ulong be_rx_bytes_prev;
119+
u32 be_rx_rate;
120+
/* number of non ether type II frames dropped where
121+
* frame len > length field of Mac Hdr */
122+
u32 be_802_3_dropped_frames;
123+
/* number of non ether type II frames malformed where
124+
* in frame len < length field of Mac Hdr */
125+
u32 be_802_3_malformed_frames;
126+
u32 be_rxcp_err; /* Num rx completion entries w/ err set. */
127+
ulong rx_fps_jiffies; /* jiffies at last FPS calc */
128+
u32 be_rx_frags;
129+
u32 be_prev_rx_frags;
130+
u32 be_rx_fps; /* Rx frags per second */
131+
};
132+
133+
struct be_stats_obj {
134+
struct be_drvr_stats drvr_stats;
135+
struct net_device_stats net_stats;
136+
struct be_dma_mem cmd;
137+
};
138+
139+
struct be_eq_obj {
140+
struct be_queue_info q;
141+
char desc[32];
142+
143+
/* Adaptive interrupt coalescing (AIC) info */
144+
bool enable_aic;
145+
u16 min_eqd; /* in usecs */
146+
u16 max_eqd; /* in usecs */
147+
u16 cur_eqd; /* in usecs */
148+
149+
struct napi_struct napi;
150+
};
151+
152+
struct be_tx_obj {
153+
struct be_queue_info q;
154+
struct be_queue_info cq;
155+
/* Remember the skbs that were transmitted */
156+
struct sk_buff *sent_skb_list[TX_Q_LEN];
157+
};
158+
159+
/* Struct to remember the pages posted for rx frags */
160+
struct be_rx_page_info {
161+
struct page *page;
162+
dma_addr_t bus;
163+
u16 page_offset;
164+
bool last_page_user;
165+
};
166+
167+
struct be_rx_obj {
168+
struct be_queue_info q;
169+
struct be_queue_info cq;
170+
struct be_rx_page_info page_info_tbl[RX_Q_LEN];
171+
struct net_lro_mgr lro_mgr;
172+
struct net_lro_desc lro_desc[BE_MAX_LRO_DESCRIPTORS];
173+
};
174+
175+
#define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */
176+
struct be_adapter {
177+
struct pci_dev *pdev;
178+
struct net_device *netdev;
179+
180+
/* Mbox, pci config, csr address information */
181+
struct be_ctrl_info ctrl;
182+
183+
struct msix_entry msix_entries[BE_NUM_MSIX_VECTORS];
184+
bool msix_enabled;
185+
bool isr_registered;
186+
187+
/* TX Rings */
188+
struct be_eq_obj tx_eq;
189+
struct be_tx_obj tx_obj;
190+
191+
u32 cache_line_break[8];
192+
193+
/* Rx rings */
194+
struct be_eq_obj rx_eq;
195+
struct be_rx_obj rx_obj;
196+
u32 big_page_size; /* Compounded page size shared by rx wrbs */
197+
198+
struct vlan_group *vlan_grp;
199+
u16 num_vlans;
200+
u8 vlan_tag[VLAN_GROUP_ARRAY_LEN];
201+
202+
struct be_stats_obj stats;
203+
/* Work queue used to perform periodic tasks like getting statistics */
204+
struct delayed_work work;
205+
206+
/* Ethtool knobs and info */
207+
bool rx_csum; /* BE card must perform rx-checksumming */
208+
u32 max_rx_coal;
209+
char fw_ver[FW_VER_LEN];
210+
u32 if_handle; /* Used to configure filtering */
211+
u32 pmac_id; /* MAC addr handle used by BE card */
212+
213+
struct be_link_info link;
214+
u32 port_num;
215+
};
216+
217+
extern struct ethtool_ops be_ethtool_ops;
218+
219+
#define drvr_stats(adapter) (&adapter->stats.drvr_stats)
220+
221+
#define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops)
222+
223+
static inline u32 MODULO(u16 val, u16 limit)
224+
{
225+
BUG_ON(limit & (limit - 1));
226+
return val & (limit - 1);
227+
}
228+
229+
static inline void index_adv(u16 *index, u16 val, u16 limit)
230+
{
231+
*index = MODULO((*index + val), limit);
232+
}
233+
234+
static inline void index_inc(u16 *index, u16 limit)
235+
{
236+
*index = MODULO((*index + 1), limit);
237+
}
238+
239+
#define PAGE_SHIFT_4K 12
240+
#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
241+
242+
/* Returns number of pages spanned by the data starting at the given addr */
243+
#define PAGES_4K_SPANNED(_address, size) \
244+
((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \
245+
(size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K))
246+
247+
/* Byte offset into the page corresponding to given address */
248+
#define OFFSET_IN_PAGE(addr) \
249+
((size_t)(addr) & (PAGE_SIZE_4K-1))
250+
251+
/* Returns bit offset within a DWORD of a bitfield */
252+
#define AMAP_BIT_OFFSET(_struct, field) \
253+
(((size_t)&(((_struct *)0)->field))%32)
254+
255+
/* Returns the bit mask of the field that is NOT shifted into location. */
256+
static inline u32 amap_mask(u32 bitsize)
257+
{
258+
return (bitsize == 32 ? 0xFFFFFFFF : (1 << bitsize) - 1);
259+
}
260+
261+
static inline void
262+
amap_set(void *ptr, u32 dw_offset, u32 mask, u32 offset, u32 value)
263+
{
264+
u32 *dw = (u32 *) ptr + dw_offset;
265+
*dw &= ~(mask << offset);
266+
*dw |= (mask & value) << offset;
267+
}
268+
269+
#define AMAP_SET_BITS(_struct, field, ptr, val) \
270+
amap_set(ptr, \
271+
offsetof(_struct, field)/32, \
272+
amap_mask(sizeof(((_struct *)0)->field)), \
273+
AMAP_BIT_OFFSET(_struct, field), \
274+
val)
275+
276+
static inline u32 amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset)
277+
{
278+
u32 *dw = (u32 *) ptr;
279+
return mask & (*(dw + dw_offset) >> offset);
280+
}
281+
282+
#define AMAP_GET_BITS(_struct, field, ptr) \
283+
amap_get(ptr, \
284+
offsetof(_struct, field)/32, \
285+
amap_mask(sizeof(((_struct *)0)->field)), \
286+
AMAP_BIT_OFFSET(_struct, field))
287+
288+
#define be_dws_cpu_to_le(wrb, len) swap_dws(wrb, len)
289+
#define be_dws_le_to_cpu(wrb, len) swap_dws(wrb, len)
290+
static inline void swap_dws(void *wrb, int len)
291+
{
292+
#ifdef __BIG_ENDIAN
293+
u32 *dw = wrb;
294+
BUG_ON(len % 4);
295+
do {
296+
*dw = cpu_to_le32(*dw);
297+
dw++;
298+
len -= 4;
299+
} while (len);
300+
#endif /* __BIG_ENDIAN */
301+
}
302+
303+
static inline u8 is_tcp_pkt(struct sk_buff *skb)
304+
{
305+
u8 val = 0;
306+
307+
if (ip_hdr(skb)->version == 4)
308+
val = (ip_hdr(skb)->protocol == IPPROTO_TCP);
309+
else if (ip_hdr(skb)->version == 6)
310+
val = (ipv6_hdr(skb)->nexthdr == NEXTHDR_TCP);
311+
312+
return val;
313+
}
314+
315+
static inline u8 is_udp_pkt(struct sk_buff *skb)
316+
{
317+
u8 val = 0;
318+
319+
if (ip_hdr(skb)->version == 4)
320+
val = (ip_hdr(skb)->protocol == IPPROTO_UDP);
321+
else if (ip_hdr(skb)->version == 6)
322+
val = (ipv6_hdr(skb)->nexthdr == NEXTHDR_UDP);
323+
324+
return val;
325+
}
326+
327+
#endif /* BE_H */

0 commit comments

Comments
 (0)