diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2007-12-31 13:08:57 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-12 17:35:38 -0500 |
commit | 5dc162682d4901025a02b7045f3112d569b4bab9 (patch) | |
tree | 410daa76d45f3f7aee13eb0750b890a9ba8ad49f | |
parent | 53a01e00f8c78bc5875e09aca7749ea54bb09798 (diff) |
netxen: fix byte-swapping in tx and rx
Here's the reworked patch.
This cleans up some unnecessary byte-swapping while setting up tx and
interpreting rx desc. The 64 bit rx status data should be converted
to host endian format only once and the macros just need to extract
bitfields.
This saves a spate of interrupts on pseries blades caused by buggy
(non) processing rx status ring.
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 65 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 10 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 10 |
3 files changed, 40 insertions, 45 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 2cefd8b43ac4..a8f63c47b3cd 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -309,23 +309,26 @@ struct netxen_ring_ctx { | |||
309 | ((cmd_desc)->port_ctxid |= ((var) & 0xF0)) | 309 | ((cmd_desc)->port_ctxid |= ((var) & 0xF0)) |
310 | 310 | ||
311 | #define netxen_set_cmd_desc_flags(cmd_desc, val) \ | 311 | #define netxen_set_cmd_desc_flags(cmd_desc, val) \ |
312 | ((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x7f), \ | 312 | (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \ |
313 | (cmd_desc)->flags_opcode |= cpu_to_le16((val) & 0x7f)) | 313 | ~cpu_to_le16(0x7f)) | cpu_to_le16((val) & 0x7f) |
314 | #define netxen_set_cmd_desc_opcode(cmd_desc, val) \ | 314 | #define netxen_set_cmd_desc_opcode(cmd_desc, val) \ |
315 | ((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x3f<<7), \ | 315 | (cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \ |
316 | (cmd_desc)->flags_opcode |= cpu_to_le16(((val & 0x3f)<<7))) | 316 | ~cpu_to_le16((u16)0x3f << 7)) | cpu_to_le16(((val) & 0x3f) << 7) |
317 | 317 | ||
318 | #define netxen_set_cmd_desc_num_of_buff(cmd_desc, val) \ | 318 | #define netxen_set_cmd_desc_num_of_buff(cmd_desc, val) \ |
319 | ((cmd_desc)->num_of_buffers_total_length &= ~cpu_to_le32(0xff), \ | 319 | (cmd_desc)->num_of_buffers_total_length = \ |
320 | (cmd_desc)->num_of_buffers_total_length |= cpu_to_le32((val) & 0xff)) | 320 | ((cmd_desc)->num_of_buffers_total_length & \ |
321 | ~cpu_to_le32(0xff)) | cpu_to_le32((val) & 0xff) | ||
321 | #define netxen_set_cmd_desc_totallength(cmd_desc, val) \ | 322 | #define netxen_set_cmd_desc_totallength(cmd_desc, val) \ |
322 | ((cmd_desc)->num_of_buffers_total_length &= ~cpu_to_le32(0xffffff00), \ | 323 | (cmd_desc)->num_of_buffers_total_length = \ |
323 | (cmd_desc)->num_of_buffers_total_length |= cpu_to_le32(val << 8)) | 324 | ((cmd_desc)->num_of_buffers_total_length & \ |
325 | ~cpu_to_le32((u32)0xffffff << 8)) | \ | ||
326 | cpu_to_le32(((val) & 0xffffff) << 8) | ||
324 | 327 | ||
325 | #define netxen_get_cmd_desc_opcode(cmd_desc) \ | 328 | #define netxen_get_cmd_desc_opcode(cmd_desc) \ |
326 | ((le16_to_cpu((cmd_desc)->flags_opcode) >> 7) & 0x003F) | 329 | ((le16_to_cpu((cmd_desc)->flags_opcode) >> 7) & 0x003f) |
327 | #define netxen_get_cmd_desc_totallength(cmd_desc) \ | 330 | #define netxen_get_cmd_desc_totallength(cmd_desc) \ |
328 | (le32_to_cpu((cmd_desc)->num_of_buffers_total_length) >> 8) | 331 | ((le32_to_cpu((cmd_desc)->num_of_buffers_total_length) >> 8) & 0xffffff) |
329 | 332 | ||
330 | struct cmd_desc_type0 { | 333 | struct cmd_desc_type0 { |
331 | u8 tcp_hdr_offset; /* For LSO only */ | 334 | u8 tcp_hdr_offset; /* For LSO only */ |
@@ -412,29 +415,29 @@ struct rcv_desc { | |||
412 | #define netxen_get_sts_desc_lro_last_frag(status_desc) \ | 415 | #define netxen_get_sts_desc_lro_last_frag(status_desc) \ |
413 | (((status_desc)->lro & 0x80) >> 7) | 416 | (((status_desc)->lro & 0x80) >> 7) |
414 | 417 | ||
415 | #define netxen_get_sts_port(status_desc) \ | 418 | #define netxen_get_sts_port(sts_data) \ |
416 | (le64_to_cpu((status_desc)->status_desc_data) & 0x0F) | 419 | ((sts_data) & 0x0F) |
417 | #define netxen_get_sts_status(status_desc) \ | 420 | #define netxen_get_sts_status(sts_data) \ |
418 | ((le64_to_cpu((status_desc)->status_desc_data) >> 4) & 0x0F) | 421 | (((sts_data) >> 4) & 0x0F) |
419 | #define netxen_get_sts_type(status_desc) \ | 422 | #define netxen_get_sts_type(sts_data) \ |
420 | ((le64_to_cpu((status_desc)->status_desc_data) >> 8) & 0x0F) | 423 | (((sts_data) >> 8) & 0x0F) |
421 | #define netxen_get_sts_totallength(status_desc) \ | 424 | #define netxen_get_sts_totallength(sts_data) \ |
422 | ((le64_to_cpu((status_desc)->status_desc_data) >> 12) & 0xFFFF) | 425 | (((sts_data) >> 12) & 0xFFFF) |
423 | #define netxen_get_sts_refhandle(status_desc) \ | 426 | #define netxen_get_sts_refhandle(sts_data) \ |
424 | ((le64_to_cpu((status_desc)->status_desc_data) >> 28) & 0xFFFF) | 427 | (((sts_data) >> 28) & 0xFFFF) |
425 | #define netxen_get_sts_prot(status_desc) \ | 428 | #define netxen_get_sts_prot(sts_data) \ |
426 | ((le64_to_cpu((status_desc)->status_desc_data) >> 44) & 0x0F) | 429 | (((sts_data) >> 44) & 0x0F) |
430 | #define netxen_get_sts_opcode(sts_data) \ | ||
431 | (((sts_data) >> 58) & 0x03F) | ||
432 | |||
427 | #define netxen_get_sts_owner(status_desc) \ | 433 | #define netxen_get_sts_owner(status_desc) \ |
428 | ((le64_to_cpu((status_desc)->status_desc_data) >> 56) & 0x03) | 434 | ((le64_to_cpu((status_desc)->status_desc_data) >> 56) & 0x03) |
429 | #define netxen_get_sts_opcode(status_desc) \ | 435 | #define netxen_set_sts_owner(status_desc, val) { \ |
430 | ((le64_to_cpu((status_desc)->status_desc_data) >> 58) & 0x03F) | 436 | (status_desc)->status_desc_data = \ |
431 | 437 | ((status_desc)->status_desc_data & \ | |
432 | #define netxen_clear_sts_owner(status_desc) \ | 438 | ~cpu_to_le64(0x3ULL << 56)) | \ |
433 | ((status_desc)->status_desc_data &= \ | 439 | cpu_to_le64((u64)((val) & 0x3) << 56); \ |
434 | ~cpu_to_le64(((unsigned long long)3) << 56 )) | 440 | } |
435 | #define netxen_set_sts_owner(status_desc, val) \ | ||
436 | ((status_desc)->status_desc_data |= \ | ||
437 | cpu_to_le64(((unsigned long long)((val) & 0x3)) << 56 )) | ||
438 | 441 | ||
439 | struct status_desc { | 442 | struct status_desc { |
440 | /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length | 443 | /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 5f85ad686c98..485ff9398910 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -1070,16 +1070,17 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, | |||
1070 | { | 1070 | { |
1071 | struct pci_dev *pdev = adapter->pdev; | 1071 | struct pci_dev *pdev = adapter->pdev; |
1072 | struct net_device *netdev = adapter->netdev; | 1072 | struct net_device *netdev = adapter->netdev; |
1073 | int index = netxen_get_sts_refhandle(desc); | 1073 | u64 sts_data = le64_to_cpu(desc->status_desc_data); |
1074 | int index = netxen_get_sts_refhandle(sts_data); | ||
1074 | struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]); | 1075 | struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]); |
1075 | struct netxen_rx_buffer *buffer; | 1076 | struct netxen_rx_buffer *buffer; |
1076 | struct sk_buff *skb; | 1077 | struct sk_buff *skb; |
1077 | u32 length = netxen_get_sts_totallength(desc); | 1078 | u32 length = netxen_get_sts_totallength(sts_data); |
1078 | u32 desc_ctx; | 1079 | u32 desc_ctx; |
1079 | struct netxen_rcv_desc_ctx *rcv_desc; | 1080 | struct netxen_rcv_desc_ctx *rcv_desc; |
1080 | int ret; | 1081 | int ret; |
1081 | 1082 | ||
1082 | desc_ctx = netxen_get_sts_type(desc); | 1083 | desc_ctx = netxen_get_sts_type(sts_data); |
1083 | if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) { | 1084 | if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) { |
1084 | printk("%s: %s Bad Rcv descriptor ring\n", | 1085 | printk("%s: %s Bad Rcv descriptor ring\n", |
1085 | netxen_nic_driver_name, netdev->name); | 1086 | netxen_nic_driver_name, netdev->name); |
@@ -1119,7 +1120,7 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, | |||
1119 | skb = (struct sk_buff *)buffer->skb; | 1120 | skb = (struct sk_buff *)buffer->skb; |
1120 | 1121 | ||
1121 | if (likely(adapter->rx_csum && | 1122 | if (likely(adapter->rx_csum && |
1122 | netxen_get_sts_status(desc) == STATUS_CKSUM_OK)) { | 1123 | netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) { |
1123 | adapter->stats.csummed++; | 1124 | adapter->stats.csummed++; |
1124 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1125 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1125 | } else | 1126 | } else |
@@ -1209,7 +1210,6 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) | |||
1209 | break; | 1210 | break; |
1210 | } | 1211 | } |
1211 | netxen_process_rcv(adapter, ctxid, desc); | 1212 | netxen_process_rcv(adapter, ctxid, desc); |
1212 | netxen_clear_sts_owner(desc); | ||
1213 | netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM); | 1213 | netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM); |
1214 | consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); | 1214 | consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1); |
1215 | count++; | 1215 | count++; |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index cec9e04f51ea..263b55e36c7a 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -1152,16 +1152,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1152 | } | 1152 | } |
1153 | } | 1153 | } |
1154 | 1154 | ||
1155 | i = netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]); | ||
1156 | |||
1157 | hw->cmd_desc_head[saved_producer].flags_opcode = | ||
1158 | cpu_to_le16(hw->cmd_desc_head[saved_producer].flags_opcode); | ||
1159 | hw->cmd_desc_head[saved_producer].num_of_buffers_total_length = | ||
1160 | cpu_to_le32(hw->cmd_desc_head[saved_producer]. | ||
1161 | num_of_buffers_total_length); | ||
1162 | |||
1163 | spin_lock_bh(&adapter->tx_lock); | 1155 | spin_lock_bh(&adapter->tx_lock); |
1164 | adapter->stats.txbytes += i; | 1156 | adapter->stats.txbytes += skb->len; |
1165 | 1157 | ||
1166 | /* Code to update the adapter considering how many producer threads | 1158 | /* Code to update the adapter considering how many producer threads |
1167 | are currently working */ | 1159 | are currently working */ |