Skip to content

Commit

Permalink
e1000e: fix IPMI traffic
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jeff Kirsher authored and David S. Miller committed Nov 17, 2008
1 parent e82f54b commit eb7c3ad
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 2 deletions.
5 changes: 5 additions & 0 deletions drivers/net/e1000e/e1000.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,13 +299,15 @@ struct e1000_adapter {
unsigned long led_status;

unsigned int flags;
unsigned int flags2;
struct work_struct downshift_task;
struct work_struct update_phy_task;
};

struct e1000_info {
enum e1000_mac_type mac;
unsigned int flags;
unsigned int flags2;
u32 pba;
s32 (*get_variants)(struct e1000_adapter *);
struct e1000_mac_operations *mac_ops;
Expand Down Expand Up @@ -347,6 +349,9 @@ struct e1000_info {
#define FLAG_RX_RESTART_NOW (1 << 30)
#define FLAG_MSI_TEST_FAILED (1 << 31)

/* CRC Stripping defines */
#define FLAG2_CRC_STRIPPING (1 << 0)

#define E1000_RX_DESC_PS(R, i) \
(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
#define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
Expand Down
23 changes: 21 additions & 2 deletions drivers/net/e1000e/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,10 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
goto next_desc;
}

/* adjust length to remove Ethernet CRC */
if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
length -= 4;

total_rx_bytes += length;
total_rx_packets++;

Expand Down Expand Up @@ -804,6 +808,10 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
pci_dma_sync_single_for_device(pdev, ps_page->dma,
PAGE_SIZE, PCI_DMA_FROMDEVICE);

/* remove the CRC */
if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
l1 -= 4;

skb_put(skb, l1);
goto copydone;
} /* if */
Expand All @@ -825,6 +833,12 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
skb->truesize += length;
}

/* strip the ethernet crc, problem is we're using pages now so
* this whole operation can get a little cpu intensive
*/
if (!(adapter->flags2 & FLAG2_CRC_STRIPPING))
pskb_trim(skb, skb->len - 4);

copydone:
total_rx_bytes += skb->len;
total_rx_packets++;
Expand Down Expand Up @@ -2301,8 +2315,12 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
else
rctl |= E1000_RCTL_LPE;

/* Enable hardware CRC frame stripping */
rctl |= E1000_RCTL_SECRC;
/* Some systems expect that the CRC is included in SMBUS traffic. The
* hardware strips the CRC before sending to both SMBUS (BMC) and to
* host memory when this is enabled
*/
if (adapter->flags2 & FLAG2_CRC_STRIPPING)
rctl |= E1000_RCTL_SECRC;

/* Setup buffer sizes */
rctl &= ~E1000_RCTL_SZ_4096;
Expand Down Expand Up @@ -4766,6 +4784,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
adapter->ei = ei;
adapter->pba = ei->pba;
adapter->flags = ei->flags;
adapter->flags2 = ei->flags2;
adapter->hw.adapter = adapter;
adapter->hw.mac.type = ei->mac;
adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
Expand Down
25 changes: 25 additions & 0 deletions drivers/net/e1000e/param.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,16 @@ E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround");
*/
E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lead to corrupted NVM]");

/*
* Enable CRC Stripping
*
* Valid Range: 0, 1
*
* Default Value: 1 (enabled)
*/
E1000_PARAM(CrcStripping, "Enable CRC Stripping, disable if your BMC needs " \
"the CRC");

struct e1000_option {
enum { enable_option, range_option, list_option } type;
const char *name;
Expand Down Expand Up @@ -404,6 +414,21 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
adapter->flags |= FLAG_SMART_POWER_DOWN;
}
}
{ /* CRC Stripping */
const struct e1000_option opt = {
.type = enable_option,
.name = "CRC Stripping",
.err = "defaulting to enabled",
.def = OPTION_ENABLED
};

if (num_CrcStripping > bd) {
unsigned int crc_stripping = CrcStripping[bd];
e1000_validate_option(&crc_stripping, &opt, adapter);
if (crc_stripping == OPTION_ENABLED)
adapter->flags2 |= FLAG2_CRC_STRIPPING;
}
}
{ /* Kumeran Lock Loss Workaround */
const struct e1000_option opt = {
.type = enable_option,
Expand Down

0 comments on commit eb7c3ad

Please sign in to comment.