]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.39/patches.drivers/netxen-fix-ipv6-offload-and-tx-cleanup.patch
Fix oinkmaster patch.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.drivers / netxen-fix-ipv6-offload-and-tx-cleanup.patch
1 From 391587c3447d99b842a647f8e701895c9eea050b Mon Sep 17 00:00:00 2001
2 From: Dhananjay Phadke <dhananjay@netxen.com>
3 Date: Wed, 14 Jan 2009 20:48:11 -0800
4 Subject: netxen: fix ipv6 offload and tx cleanup
5 Acked-by: Karsten Keil <kkeil@novell.com>
6 Reference: bnc#472416
7
8 o fix the ip/tcp hdr offset in tx descriptors for ipv6.
9 o cleanup xmit function, move the tso checks into separate function,
10 this reduces unnecessary endian conversions back and forth.
11 o optimize macros to initialize tx descriptors.
12
13 Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
14 Signed-off-by: David S. Miller <davem@davemloft.net>
15 ---
16 drivers/net/netxen/netxen_nic.h | 43 ++++----------
17 drivers/net/netxen/netxen_nic_hw.c | 4 -
18 drivers/net/netxen/netxen_nic_main.c | 101 +++++++++++++++-------------------
19 3 files changed, 57 insertions(+), 91 deletions(-)
20
21 Index: linux-2.6.27-kketmp/drivers/net/netxen/netxen_nic.h
22 ===================================================================
23 --- linux-2.6.27-kketmp.orig/drivers/net/netxen/netxen_nic.h
24 +++ linux-2.6.27-kketmp/drivers/net/netxen/netxen_nic.h
25 @@ -308,27 +308,16 @@ struct netxen_ring_ctx {
26 #define netxen_set_cmd_desc_ctxid(cmd_desc, var) \
27 ((cmd_desc)->port_ctxid |= ((var) << 4 & 0xF0))
28
29 -#define netxen_set_cmd_desc_flags(cmd_desc, val) \
30 - (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \
31 - ~cpu_to_le16(0x7f)) | cpu_to_le16((val) & 0x7f)
32 -#define netxen_set_cmd_desc_opcode(cmd_desc, val) \
33 - (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \
34 - ~cpu_to_le16((u16)0x3f << 7)) | cpu_to_le16(((val) & 0x3f) << 7)
35 -
36 -#define netxen_set_cmd_desc_num_of_buff(cmd_desc, val) \
37 - (cmd_desc)->num_of_buffers_total_length = \
38 - ((cmd_desc)->num_of_buffers_total_length & \
39 - ~cpu_to_le32(0xff)) | cpu_to_le32((val) & 0xff)
40 -#define netxen_set_cmd_desc_totallength(cmd_desc, val) \
41 - (cmd_desc)->num_of_buffers_total_length = \
42 - ((cmd_desc)->num_of_buffers_total_length & \
43 - ~cpu_to_le32((u32)0xffffff << 8)) | \
44 - cpu_to_le32(((val) & 0xffffff) << 8)
45 -
46 -#define netxen_get_cmd_desc_opcode(cmd_desc) \
47 - ((le16_to_cpu((cmd_desc)->flags_opcode) >> 7) & 0x003f)
48 -#define netxen_get_cmd_desc_totallength(cmd_desc) \
49 - ((le32_to_cpu((cmd_desc)->num_of_buffers_total_length) >> 8) & 0xffffff)
50 +#define netxen_set_tx_port(_desc, _port) \
51 + (_desc)->port_ctxid = ((_port) & 0xf) | (((_port) << 4) & 0xf0)
52 +
53 +#define netxen_set_tx_flags_opcode(_desc, _flags, _opcode) \
54 + (_desc)->flags_opcode = \
55 + cpu_to_le16(((_flags) & 0x7f) | (((_opcode) & 0x3f) << 7))
56 +
57 +#define netxen_set_tx_frags_len(_desc, _frags, _len) \
58 + (_desc)->num_of_buffers_total_length = \
59 + cpu_to_le32(((_frags) & 0xff) | (((_len) & 0xffffff) << 8))
60
61 struct cmd_desc_type0 {
62 u8 tcp_hdr_offset; /* For LSO only */
63 @@ -757,7 +746,7 @@ extern char netxen_nic_driver_name[];
64 */
65 struct netxen_skb_frag {
66 u64 dma;
67 - u32 length;
68 + ulong length;
69 };
70
71 #define _netxen_set_bits(config_word, start, bits, val) {\
72 @@ -783,13 +772,7 @@ struct netxen_skb_frag {
73 struct netxen_cmd_buffer {
74 struct sk_buff *skb;
75 struct netxen_skb_frag frag_array[MAX_BUFFERS_PER_CMD + 1];
76 - u32 total_length;
77 - u32 mss;
78 - u16 port;
79 - u8 cmd;
80 - u8 frag_count;
81 - unsigned long time_stamp;
82 - u32 state;
83 + u32 frag_count;
84 };
85
86 /* In rx_buffer, we do not need multiple fragments as is a single buffer */
87 @@ -1486,8 +1469,6 @@ void netxen_release_tx_buffers(struct ne
88
89 void netxen_initialize_adapter_ops(struct netxen_adapter *adapter);
90 int netxen_init_firmware(struct netxen_adapter *adapter);
91 -void netxen_tso_check(struct netxen_adapter *adapter,
92 - struct cmd_desc_type0 *desc, struct sk_buff *skb);
93 void netxen_nic_clear_stats(struct netxen_adapter *adapter);
94 void netxen_watchdog_task(struct work_struct *work);
95 void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
96 Index: linux-2.6.27-kketmp/drivers/net/netxen/netxen_nic_hw.c
97 ===================================================================
98 --- linux-2.6.27-kketmp.orig/drivers/net/netxen/netxen_nic_hw.c
99 +++ linux-2.6.27-kketmp/drivers/net/netxen/netxen_nic_hw.c
100 @@ -508,12 +508,8 @@ netxen_send_cmd_descs(struct netxen_adap
101 cmd_desc = &cmd_desc_arr[i];
102
103 pbuf = &adapter->cmd_buf_arr[producer];
104 - pbuf->mss = 0;
105 - pbuf->total_length = 0;
106 pbuf->skb = NULL;
107 - pbuf->cmd = 0;
108 pbuf->frag_count = 0;
109 - pbuf->port = 0;
110
111 /* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */
112 memcpy(&adapter->ahw.cmd_desc_head[producer],
113 Index: linux-2.6.27-kketmp/drivers/net/netxen/netxen_nic_main.c
114 ===================================================================
115 --- linux-2.6.27-kketmp.orig/drivers/net/netxen/netxen_nic_main.c
116 +++ linux-2.6.27-kketmp/drivers/net/netxen/netxen_nic_main.c
117 @@ -39,6 +39,7 @@
118 #include "netxen_nic_phan_reg.h"
119
120 #include <linux/dma-mapping.h>
121 +#include <linux/if_vlan.h>
122 #include <net/ip.h>
123
124 MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
125 @@ -1126,29 +1127,46 @@ static int netxen_nic_close(struct net_d
126 return 0;
127 }
128
129 -void netxen_tso_check(struct netxen_adapter *adapter,
130 +static bool netxen_tso_check(struct net_device *netdev,
131 struct cmd_desc_type0 *desc, struct sk_buff *skb)
132 {
133 - if (desc->mss) {
134 - desc->total_hdr_length = (sizeof(struct ethhdr) +
135 - ip_hdrlen(skb) + tcp_hdrlen(skb));
136 -
137 - if ((NX_IS_REVISION_P3(adapter->ahw.revision_id)) &&
138 - (skb->protocol == htons(ETH_P_IPV6)))
139 - netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO6);
140 - else
141 - netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO);
142 + bool tso = false;
143 + u8 opcode = TX_ETHER_PKT;
144 +
145 + if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
146 + skb_shinfo(skb)->gso_size > 0) {
147 +
148 + desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
149 + desc->total_hdr_length =
150 + skb_transport_offset(skb) + tcp_hdrlen(skb);
151 +
152 + opcode = (skb->protocol == htons(ETH_P_IPV6)) ?
153 + TX_TCP_LSO6 : TX_TCP_LSO;
154 + tso = true;
155
156 } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
157 - if (ip_hdr(skb)->protocol == IPPROTO_TCP)
158 - netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT);
159 - else if (ip_hdr(skb)->protocol == IPPROTO_UDP)
160 - netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT);
161 - else
162 - return;
163 + u8 l4proto;
164 +
165 + if (skb->protocol == htons(ETH_P_IP)) {
166 + l4proto = ip_hdr(skb)->protocol;
167 +
168 + if (l4proto == IPPROTO_TCP)
169 + opcode = TX_TCP_PKT;
170 + else if(l4proto == IPPROTO_UDP)
171 + opcode = TX_UDP_PKT;
172 + } else if (skb->protocol == htons(ETH_P_IPV6)) {
173 + l4proto = ipv6_hdr(skb)->nexthdr;
174 +
175 + if (l4proto == IPPROTO_TCP)
176 + opcode = TX_TCPV6_PKT;
177 + else if(l4proto == IPPROTO_UDP)
178 + opcode = TX_UDPV6_PKT;
179 + }
180 }
181 desc->tcp_hdr_offset = skb_transport_offset(skb);
182 desc->ip_hdr_offset = skb_network_offset(skb);
183 + netxen_set_tx_flags_opcode(desc, 0, opcode);
184 + return tso;
185 }
186
187 static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
188 @@ -1156,33 +1174,20 @@ static int netxen_nic_xmit_frame(struct
189 struct netxen_adapter *adapter = netdev_priv(netdev);
190 struct netxen_hardware_context *hw = &adapter->ahw;
191 unsigned int first_seg_len = skb->len - skb->data_len;
192 + struct netxen_cmd_buffer *pbuf;
193 struct netxen_skb_frag *buffrag;
194 - unsigned int i;
195 + struct cmd_desc_type0 *hwdesc;
196 + int i, k;
197
198 u32 producer, consumer;
199 - u32 saved_producer = 0;
200 - struct cmd_desc_type0 *hwdesc;
201 - int k;
202 - struct netxen_cmd_buffer *pbuf = NULL;
203 - int frag_count;
204 - int no_of_desc;
205 + int frag_count, no_of_desc;
206 u32 num_txd = adapter->max_tx_desc_count;
207 + bool is_tso = false;
208
209 frag_count = skb_shinfo(skb)->nr_frags + 1;
210
211 /* There 4 fragments per descriptor */
212 no_of_desc = (frag_count + 3) >> 2;
213 - if (netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) {
214 - if (skb_shinfo(skb)->gso_size > 0) {
215 -
216 - no_of_desc++;
217 - if ((ip_hdrlen(skb) + tcp_hdrlen(skb) +
218 - sizeof(struct ethhdr)) >
219 - (sizeof(struct cmd_desc_type0) - 2)) {
220 - no_of_desc++;
221 - }
222 - }
223 - }
224
225 producer = adapter->cmd_producer;
226 smp_mb();
227 @@ -1194,34 +1199,22 @@ static int netxen_nic_xmit_frame(struct
228 }
229
230 /* Copy the descriptors into the hardware */
231 - saved_producer = producer;
232 hwdesc = &hw->cmd_desc_head[producer];
233 memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
234 /* Take skb->data itself */
235 pbuf = &adapter->cmd_buf_arr[producer];
236 - if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
237 - skb_shinfo(skb)->gso_size > 0) {
238 - pbuf->mss = skb_shinfo(skb)->gso_size;
239 - hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
240 - } else {
241 - pbuf->mss = 0;
242 - hwdesc->mss = 0;
243 - }
244 - pbuf->total_length = skb->len;
245 +
246 + is_tso = netxen_tso_check(netdev, hwdesc, skb);
247 +
248 pbuf->skb = skb;
249 - pbuf->cmd = TX_ETHER_PKT;
250 pbuf->frag_count = frag_count;
251 - pbuf->port = adapter->portnum;
252 buffrag = &pbuf->frag_array[0];
253 buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len,
254 PCI_DMA_TODEVICE);
255 buffrag->length = first_seg_len;
256 - netxen_set_cmd_desc_totallength(hwdesc, skb->len);
257 - netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count);
258 - netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT);
259 + netxen_set_tx_frags_len(hwdesc, frag_count, skb->len);
260 + netxen_set_tx_port(hwdesc, adapter->portnum);
261
262 - netxen_set_cmd_desc_port(hwdesc, adapter->portnum);
263 - netxen_set_cmd_desc_ctxid(hwdesc, adapter->portnum);
264 hwdesc->buffer1_length = cpu_to_le16(first_seg_len);
265 hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
266
267 @@ -1274,16 +1267,12 @@ static int netxen_nic_xmit_frame(struct
268 }
269 producer = get_next_index(producer, num_txd);
270
271 - /* might change opcode to TX_TCP_LSO */
272 - netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb);
273 -
274 /* For LSO, we need to copy the MAC/IP/TCP headers into
275 * the descriptor ring
276 */
277 - if (netxen_get_cmd_desc_opcode(&hw->cmd_desc_head[saved_producer])
278 - == TX_TCP_LSO) {
279 + if (is_tso) {
280 int hdr_len, first_hdr_len, more_hdr;
281 - hdr_len = hw->cmd_desc_head[saved_producer].total_hdr_length;
282 + hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
283 if (hdr_len > (sizeof(struct cmd_desc_type0) - 2)) {
284 first_hdr_len = sizeof(struct cmd_desc_type0) - 2;
285 more_hdr = 1;