diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2008-11-14 01:45:23 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-16 22:05:16 -0500 |
commit | eb7c3adb1ca92450870dbb0d347fc986cd5e2af4 (patch) | |
tree | fb8cbfec74c76437641f1e3fb1c53463fdb9b987 /drivers/net/e1000e | |
parent | e82f54ba030b429c06b5240cbe7eeaaa03a8db11 (diff) |
e1000e: fix IPMI traffic
Some users reported that they have machines with BMCs enabled that cannot
receive IPMI traffic after e1000e is loaded.
http://marc.info/?l=e1000-devel&m=121909039127414&w=2
http://marc.info/?l=e1000-devel&m=121365543823387&w=2
This fixes the issue if they load with the new parameter = 0 by disabling
crc stripping, but leaves the performance feature on for most users.
Based on work done by Hong Zhang.
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r-- | drivers/net/e1000e/e1000.h | 5 | ||||
-rw-r--r-- | drivers/net/e1000e/netdev.c | 23 | ||||
-rw-r--r-- | drivers/net/e1000e/param.c | 25 |
3 files changed, 51 insertions, 2 deletions
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index c55de1c027af..c55fd6fdb91c 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
@@ -299,6 +299,7 @@ struct e1000_adapter { | |||
299 | unsigned long led_status; | 299 | unsigned long led_status; |
300 | 300 | ||
301 | unsigned int flags; | 301 | unsigned int flags; |
302 | unsigned int flags2; | ||
302 | struct work_struct downshift_task; | 303 | struct work_struct downshift_task; |
303 | struct work_struct update_phy_task; | 304 | struct work_struct update_phy_task; |
304 | }; | 305 | }; |
@@ -306,6 +307,7 @@ struct e1000_adapter { | |||
306 | struct e1000_info { | 307 | struct e1000_info { |
307 | enum e1000_mac_type mac; | 308 | enum e1000_mac_type mac; |
308 | unsigned int flags; | 309 | unsigned int flags; |
310 | unsigned int flags2; | ||
309 | u32 pba; | 311 | u32 pba; |
310 | s32 (*get_variants)(struct e1000_adapter *); | 312 | s32 (*get_variants)(struct e1000_adapter *); |
311 | struct e1000_mac_operations *mac_ops; | 313 | struct e1000_mac_operations *mac_ops; |
@@ -347,6 +349,9 @@ struct e1000_info { | |||
347 | #define FLAG_RX_RESTART_NOW (1 << 30) | 349 | #define FLAG_RX_RESTART_NOW (1 << 30) |
348 | #define FLAG_MSI_TEST_FAILED (1 << 31) | 350 | #define FLAG_MSI_TEST_FAILED (1 << 31) |
349 | 351 | ||
352 | /* CRC Stripping defines */ | ||
353 | #define FLAG2_CRC_STRIPPING (1 << 0) | ||
354 | |||
350 | #define E1000_RX_DESC_PS(R, i) \ | 355 | #define E1000_RX_DESC_PS(R, i) \ |
351 | (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) | 356 | (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) |
352 | #define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) | 357 | #define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index f6ebebb8cfa5..91795f78c3e4 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -499,6 +499,10 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, | |||
499 | goto next_desc; | 499 | goto next_desc; |
500 | } | 500 | } |
501 | 501 | ||
502 | /* adjust length to remove Ethernet CRC */ | ||
503 | if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) | ||
504 | length -= 4; | ||
505 | |||
502 | total_rx_bytes += length; | 506 | total_rx_bytes += length; |
503 | total_rx_packets++; | 507 | total_rx_packets++; |
504 | 508 | ||
@@ -804,6 +808,10 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
804 | pci_dma_sync_single_for_device(pdev, ps_page->dma, | 808 | pci_dma_sync_single_for_device(pdev, ps_page->dma, |
805 | PAGE_SIZE, PCI_DMA_FROMDEVICE); | 809 | PAGE_SIZE, PCI_DMA_FROMDEVICE); |
806 | 810 | ||
811 | /* remove the CRC */ | ||
812 | if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) | ||
813 | l1 -= 4; | ||
814 | |||
807 | skb_put(skb, l1); | 815 | skb_put(skb, l1); |
808 | goto copydone; | 816 | goto copydone; |
809 | } /* if */ | 817 | } /* if */ |
@@ -825,6 +833,12 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
825 | skb->truesize += length; | 833 | skb->truesize += length; |
826 | } | 834 | } |
827 | 835 | ||
836 | /* strip the ethernet crc, problem is we're using pages now so | ||
837 | * this whole operation can get a little cpu intensive | ||
838 | */ | ||
839 | if (!(adapter->flags2 & FLAG2_CRC_STRIPPING)) | ||
840 | pskb_trim(skb, skb->len - 4); | ||
841 | |||
828 | copydone: | 842 | copydone: |
829 | total_rx_bytes += skb->len; | 843 | total_rx_bytes += skb->len; |
830 | total_rx_packets++; | 844 | total_rx_packets++; |
@@ -2301,8 +2315,12 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) | |||
2301 | else | 2315 | else |
2302 | rctl |= E1000_RCTL_LPE; | 2316 | rctl |= E1000_RCTL_LPE; |
2303 | 2317 | ||
2304 | /* Enable hardware CRC frame stripping */ | 2318 | /* Some systems expect that the CRC is included in SMBUS traffic. The |
2305 | rctl |= E1000_RCTL_SECRC; | 2319 | * hardware strips the CRC before sending to both SMBUS (BMC) and to |
2320 | * host memory when this is enabled | ||
2321 | */ | ||
2322 | if (adapter->flags2 & FLAG2_CRC_STRIPPING) | ||
2323 | rctl |= E1000_RCTL_SECRC; | ||
2306 | 2324 | ||
2307 | /* Setup buffer sizes */ | 2325 | /* Setup buffer sizes */ |
2308 | rctl &= ~E1000_RCTL_SZ_4096; | 2326 | rctl &= ~E1000_RCTL_SZ_4096; |
@@ -4766,6 +4784,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
4766 | adapter->ei = ei; | 4784 | adapter->ei = ei; |
4767 | adapter->pba = ei->pba; | 4785 | adapter->pba = ei->pba; |
4768 | adapter->flags = ei->flags; | 4786 | adapter->flags = ei->flags; |
4787 | adapter->flags2 = ei->flags2; | ||
4769 | adapter->hw.adapter = adapter; | 4788 | adapter->hw.adapter = adapter; |
4770 | adapter->hw.mac.type = ei->mac; | 4789 | adapter->hw.mac.type = ei->mac; |
4771 | adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1; | 4790 | adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1; |
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index 77a3d7207a5f..e909f96698e8 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c | |||
@@ -151,6 +151,16 @@ E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround"); | |||
151 | */ | 151 | */ |
152 | E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]"); | 152 | E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]"); |
153 | 153 | ||
154 | /* | ||
155 | * Enable CRC Stripping | ||
156 | * | ||
157 | * Valid Range: 0, 1 | ||
158 | * | ||
159 | * Default Value: 1 (enabled) | ||
160 | */ | ||
161 | E1000_PARAM(CrcStripping, "Enable CRC Stripping, disable if your BMC needs " \ | ||
162 | "the CRC"); | ||
163 | |||
154 | struct e1000_option { | 164 | struct e1000_option { |
155 | enum { enable_option, range_option, list_option } type; | 165 | enum { enable_option, range_option, list_option } type; |
156 | const char *name; | 166 | const char *name; |
@@ -404,6 +414,21 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) | |||
404 | adapter->flags |= FLAG_SMART_POWER_DOWN; | 414 | adapter->flags |= FLAG_SMART_POWER_DOWN; |
405 | } | 415 | } |
406 | } | 416 | } |
417 | { /* CRC Stripping */ | ||
418 | const struct e1000_option opt = { | ||
419 | .type = enable_option, | ||
420 | .name = "CRC Stripping", | ||
421 | .err = "defaulting to enabled", | ||
422 | .def = OPTION_ENABLED | ||
423 | }; | ||
424 | |||
425 | if (num_CrcStripping > bd) { | ||
426 | unsigned int crc_stripping = CrcStripping[bd]; | ||
427 | e1000_validate_option(&crc_stripping, &opt, adapter); | ||
428 | if (crc_stripping == OPTION_ENABLED) | ||
429 | adapter->flags2 |= FLAG2_CRC_STRIPPING; | ||
430 | } | ||
431 | } | ||
407 | { /* Kumeran Lock Loss Workaround */ | 432 | { /* Kumeran Lock Loss Workaround */ |
408 | const struct e1000_option opt = { | 433 | const struct e1000_option opt = { |
409 | .type = enable_option, | 434 | .type = enable_option, |