be2net: Workaround to fix a bug in Rx Completion processing.
vtp bit in RX completion descriptor could be wrongly set in some skews of BladEngine. Ignore this bit if vtm is not set. Resending because the previous patch was against net-next tree. This patch is against the net-2.6 tree. Signed-off-by: Ajit Khaparde <ajitk@serverengines.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
7bfc4ab562
commit
dcb9b5648a
4 changed files with 24 additions and 6 deletions
|
@ -258,6 +258,7 @@ struct be_adapter {
|
|||
bool link_up;
|
||||
u32 port_num;
|
||||
bool promiscuous;
|
||||
u32 cap;
|
||||
};
|
||||
|
||||
extern const struct ethtool_ops be_ethtool_ops;
|
||||
|
|
|
@ -1068,7 +1068,7 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
|
|||
}
|
||||
|
||||
/* Uses mbox */
|
||||
int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num)
|
||||
int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *cap)
|
||||
{
|
||||
struct be_mcc_wrb *wrb;
|
||||
struct be_cmd_req_query_fw_cfg *req;
|
||||
|
@ -1088,6 +1088,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num)
|
|||
if (!status) {
|
||||
struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
|
||||
*port_num = le32_to_cpu(resp->phys_port);
|
||||
*cap = le32_to_cpu(resp->function_cap);
|
||||
}
|
||||
|
||||
spin_unlock(&adapter->mbox_lock);
|
||||
|
|
|
@ -760,7 +760,8 @@ extern int be_cmd_set_flow_control(struct be_adapter *adapter,
|
|||
u32 tx_fc, u32 rx_fc);
|
||||
extern int be_cmd_get_flow_control(struct be_adapter *adapter,
|
||||
u32 *tx_fc, u32 *rx_fc);
|
||||
extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num);
|
||||
extern int be_cmd_query_fw_cfg(struct be_adapter *adapter,
|
||||
u32 *port_num, u32 *cap);
|
||||
extern int be_cmd_reset_function(struct be_adapter *adapter);
|
||||
extern int be_process_mcc(struct be_adapter *adapter);
|
||||
extern int be_cmd_write_flashrom(struct be_adapter *adapter,
|
||||
|
|
|
@ -747,9 +747,16 @@ static void be_rx_compl_process(struct be_adapter *adapter,
|
|||
struct be_eth_rx_compl *rxcp)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u32 vtp, vid;
|
||||
u32 vlanf, vid;
|
||||
u8 vtm;
|
||||
|
||||
vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
|
||||
vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
|
||||
vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
|
||||
|
||||
/* vlanf could be wrongly set in some cards.
|
||||
* ignore if vtm is not set */
|
||||
if ((adapter->cap == 0x400) && !vtm)
|
||||
vlanf = 0;
|
||||
|
||||
skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN);
|
||||
if (!skb) {
|
||||
|
@ -772,7 +779,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
|
|||
skb->protocol = eth_type_trans(skb, adapter->netdev);
|
||||
skb->dev = adapter->netdev;
|
||||
|
||||
if (vtp) {
|
||||
if (vlanf) {
|
||||
if (!adapter->vlan_grp || adapter->num_vlans == 0) {
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
|
@ -797,11 +804,18 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
|
|||
struct be_eq_obj *eq_obj = &adapter->rx_eq;
|
||||
u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len;
|
||||
u16 i, rxq_idx = 0, vid, j;
|
||||
u8 vtm;
|
||||
|
||||
num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
|
||||
pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
|
||||
vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
|
||||
rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
|
||||
vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
|
||||
|
||||
/* vlanf could be wrongly set in some cards.
|
||||
* ignore if vtm is not set */
|
||||
if ((adapter->cap == 0x400) && !vtm)
|
||||
vlanf = 0;
|
||||
|
||||
skb = napi_get_frags(&eq_obj->napi);
|
||||
if (!skb) {
|
||||
|
@ -2045,7 +2059,8 @@ static int be_hw_up(struct be_adapter *adapter)
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
status = be_cmd_query_fw_cfg(adapter, &adapter->port_num);
|
||||
status = be_cmd_query_fw_cfg(adapter,
|
||||
&adapter->port_num, &adapter->cap);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue