Merge branch 'bnx2x'
Yuval Mintz says: ==================== This patch series contains several enhancements, as well as small fixes: - Patch [1/5] - Prevent a theoretical problem in our GRO implementation. - Patch [2/5] - Support Rx/Tx pause control configuration in autoneg. - Patch [3/5] - Enhance support for VF's MAC setting and removal. - Patch [4/5] - Fix a small memory leak between bnx2x and cnic. - Patch [5/5] - Allow bnx2x to recover after a second slot reset. Please consider applying these patches to `net-next'. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
01f27fc085
|
@ -642,6 +642,14 @@ static void bnx2x_gro_ipv6_csum(struct bnx2x *bp, struct sk_buff *skb)
|
||||||
th->check = ~tcp_v6_check(skb->len - skb_transport_offset(skb),
|
th->check = ~tcp_v6_check(skb->len - skb_transport_offset(skb),
|
||||||
&iph->saddr, &iph->daddr, 0);
|
&iph->saddr, &iph->daddr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bnx2x_gro_csum(struct bnx2x *bp, struct sk_buff *skb,
|
||||||
|
void (*gro_func)(struct bnx2x*, struct sk_buff*))
|
||||||
|
{
|
||||||
|
skb_set_network_header(skb, 0);
|
||||||
|
gro_func(bp, skb);
|
||||||
|
tcp_gro_complete(skb);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void bnx2x_gro_receive(struct bnx2x *bp, struct bnx2x_fastpath *fp,
|
static void bnx2x_gro_receive(struct bnx2x *bp, struct bnx2x_fastpath *fp,
|
||||||
|
@ -649,19 +657,17 @@ static void bnx2x_gro_receive(struct bnx2x *bp, struct bnx2x_fastpath *fp,
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_INET
|
#ifdef CONFIG_INET
|
||||||
if (skb_shinfo(skb)->gso_size) {
|
if (skb_shinfo(skb)->gso_size) {
|
||||||
skb_set_network_header(skb, 0);
|
|
||||||
switch (be16_to_cpu(skb->protocol)) {
|
switch (be16_to_cpu(skb->protocol)) {
|
||||||
case ETH_P_IP:
|
case ETH_P_IP:
|
||||||
bnx2x_gro_ip_csum(bp, skb);
|
bnx2x_gro_csum(bp, skb, bnx2x_gro_ip_csum);
|
||||||
break;
|
break;
|
||||||
case ETH_P_IPV6:
|
case ETH_P_IPV6:
|
||||||
bnx2x_gro_ipv6_csum(bp, skb);
|
bnx2x_gro_csum(bp, skb, bnx2x_gro_ipv6_csum);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
BNX2X_ERR("FW GRO supports only IPv4/IPv6, not 0x%04x\n",
|
BNX2X_ERR("Error: FW GRO supports only IPv4/IPv6, not 0x%04x\n",
|
||||||
be16_to_cpu(skb->protocol));
|
be16_to_cpu(skb->protocol));
|
||||||
}
|
}
|
||||||
tcp_gro_complete(skb);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
napi_gro_receive(&fp->napi, skb);
|
napi_gro_receive(&fp->napi, skb);
|
||||||
|
@ -2658,7 +2664,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
|
||||||
if (IS_PF(bp))
|
if (IS_PF(bp))
|
||||||
rc = bnx2x_set_eth_mac(bp, true);
|
rc = bnx2x_set_eth_mac(bp, true);
|
||||||
else /* vf */
|
else /* vf */
|
||||||
rc = bnx2x_vfpf_set_mac(bp);
|
rc = bnx2x_vfpf_config_mac(bp, bp->dev->dev_addr, bp->fp->index,
|
||||||
|
true);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
BNX2X_ERR("Setting Ethernet MAC failed\n");
|
BNX2X_ERR("Setting Ethernet MAC failed\n");
|
||||||
LOAD_ERROR_EXIT(bp, load_error3);
|
LOAD_ERROR_EXIT(bp, load_error3);
|
||||||
|
@ -2927,9 +2934,9 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode, bool keep_link)
|
||||||
bnx2x_free_fp_mem_cnic(bp);
|
bnx2x_free_fp_mem_cnic(bp);
|
||||||
|
|
||||||
if (IS_PF(bp)) {
|
if (IS_PF(bp)) {
|
||||||
bnx2x_free_mem(bp);
|
|
||||||
if (CNIC_LOADED(bp))
|
if (CNIC_LOADED(bp))
|
||||||
bnx2x_free_mem_cnic(bp);
|
bnx2x_free_mem_cnic(bp);
|
||||||
|
bnx2x_free_mem(bp);
|
||||||
}
|
}
|
||||||
bp->state = BNX2X_STATE_CLOSED;
|
bp->state = BNX2X_STATE_CLOSED;
|
||||||
bp->cnic_loaded = false;
|
bp->cnic_loaded = false;
|
||||||
|
|
|
@ -1889,12 +1889,15 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
|
||||||
bp->link_params.req_flow_ctrl[cfg_idx] =
|
bp->link_params.req_flow_ctrl[cfg_idx] =
|
||||||
BNX2X_FLOW_CTRL_AUTO;
|
BNX2X_FLOW_CTRL_AUTO;
|
||||||
}
|
}
|
||||||
bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_NONE;
|
bp->link_params.req_fc_auto_adv = 0;
|
||||||
if (epause->rx_pause)
|
if (epause->rx_pause)
|
||||||
bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_RX;
|
bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_RX;
|
||||||
|
|
||||||
if (epause->tx_pause)
|
if (epause->tx_pause)
|
||||||
bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_TX;
|
bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_TX;
|
||||||
|
|
||||||
|
if (!bp->link_params.req_fc_auto_adv)
|
||||||
|
bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DP(BNX2X_MSG_ETHTOOL,
|
DP(BNX2X_MSG_ETHTOOL,
|
||||||
|
|
|
@ -3426,13 +3426,19 @@ static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
|
||||||
|
|
||||||
switch (phy->req_flow_ctrl) {
|
switch (phy->req_flow_ctrl) {
|
||||||
case BNX2X_FLOW_CTRL_AUTO:
|
case BNX2X_FLOW_CTRL_AUTO:
|
||||||
if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH)
|
switch (params->req_fc_auto_adv) {
|
||||||
|
case BNX2X_FLOW_CTRL_BOTH:
|
||||||
*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
|
*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
|
||||||
else
|
break;
|
||||||
|
case BNX2X_FLOW_CTRL_RX:
|
||||||
|
case BNX2X_FLOW_CTRL_TX:
|
||||||
*ieee_fc |=
|
*ieee_fc |=
|
||||||
MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
|
MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case BNX2X_FLOW_CTRL_TX:
|
case BNX2X_FLOW_CTRL_TX:
|
||||||
*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
|
*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -7786,7 +7786,7 @@ int bnx2x_alloc_mem_cnic(struct bnx2x *bp)
|
||||||
sizeof(struct
|
sizeof(struct
|
||||||
host_hc_status_block_e1x));
|
host_hc_status_block_e1x));
|
||||||
|
|
||||||
if (CONFIGURE_NIC_MODE(bp))
|
if (CONFIGURE_NIC_MODE(bp) && !bp->t2)
|
||||||
/* allocate searcher T2 table, as it wan't allocated before */
|
/* allocate searcher T2 table, as it wan't allocated before */
|
||||||
BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ);
|
BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ);
|
||||||
|
|
||||||
|
@ -7809,7 +7809,7 @@ int bnx2x_alloc_mem(struct bnx2x *bp)
|
||||||
{
|
{
|
||||||
int i, allocated, context_size;
|
int i, allocated, context_size;
|
||||||
|
|
||||||
if (!CONFIGURE_NIC_MODE(bp))
|
if (!CONFIGURE_NIC_MODE(bp) && !bp->t2)
|
||||||
/* allocate searcher T2 table */
|
/* allocate searcher T2 table */
|
||||||
BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ);
|
BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ);
|
||||||
|
|
||||||
|
@ -7930,8 +7930,6 @@ int bnx2x_del_all_macs(struct bnx2x *bp,
|
||||||
|
|
||||||
int bnx2x_set_eth_mac(struct bnx2x *bp, bool set)
|
int bnx2x_set_eth_mac(struct bnx2x *bp, bool set)
|
||||||
{
|
{
|
||||||
unsigned long ramrod_flags = 0;
|
|
||||||
|
|
||||||
if (is_zero_ether_addr(bp->dev->dev_addr) &&
|
if (is_zero_ether_addr(bp->dev->dev_addr) &&
|
||||||
(IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))) {
|
(IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))) {
|
||||||
DP(NETIF_MSG_IFUP | NETIF_MSG_IFDOWN,
|
DP(NETIF_MSG_IFUP | NETIF_MSG_IFDOWN,
|
||||||
|
@ -7939,12 +7937,18 @@ int bnx2x_set_eth_mac(struct bnx2x *bp, bool set)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DP(NETIF_MSG_IFUP, "Adding Eth MAC\n");
|
if (IS_PF(bp)) {
|
||||||
|
unsigned long ramrod_flags = 0;
|
||||||
|
|
||||||
|
DP(NETIF_MSG_IFUP, "Adding Eth MAC\n");
|
||||||
__set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
|
__set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
|
||||||
/* Eth MAC is set on RSS leading client (fp[0]) */
|
return bnx2x_set_mac_one(bp, bp->dev->dev_addr,
|
||||||
return bnx2x_set_mac_one(bp, bp->dev->dev_addr, &bp->sp_objs->mac_obj,
|
&bp->sp_objs->mac_obj, set,
|
||||||
set, BNX2X_ETH_MAC, &ramrod_flags);
|
BNX2X_ETH_MAC, &ramrod_flags);
|
||||||
|
} else { /* vf */
|
||||||
|
return bnx2x_vfpf_config_mac(bp, bp->dev->dev_addr,
|
||||||
|
bp->fp->index, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int bnx2x_setup_leading(struct bnx2x *bp)
|
int bnx2x_setup_leading(struct bnx2x *bp)
|
||||||
|
@ -12803,6 +12807,7 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
|
||||||
|
|
||||||
pci_set_master(pdev);
|
pci_set_master(pdev);
|
||||||
pci_restore_state(pdev);
|
pci_restore_state(pdev);
|
||||||
|
pci_save_state(pdev);
|
||||||
|
|
||||||
if (netif_running(dev))
|
if (netif_running(dev))
|
||||||
bnx2x_set_power_state(bp, PCI_D0);
|
bnx2x_set_power_state(bp, PCI_D0);
|
||||||
|
|
|
@ -733,7 +733,7 @@ int bnx2x_vfpf_init(struct bnx2x *bp);
|
||||||
void bnx2x_vfpf_close_vf(struct bnx2x *bp);
|
void bnx2x_vfpf_close_vf(struct bnx2x *bp);
|
||||||
int bnx2x_vfpf_setup_q(struct bnx2x *bp, int fp_idx);
|
int bnx2x_vfpf_setup_q(struct bnx2x *bp, int fp_idx);
|
||||||
int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx);
|
int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx);
|
||||||
int bnx2x_vfpf_set_mac(struct bnx2x *bp);
|
int bnx2x_vfpf_config_mac(struct bnx2x *bp, u8 *addr, u8 vf_qid, bool set);
|
||||||
int bnx2x_vfpf_set_mcast(struct net_device *dev);
|
int bnx2x_vfpf_set_mcast(struct net_device *dev);
|
||||||
int bnx2x_vfpf_storm_rx_mode(struct bnx2x *bp);
|
int bnx2x_vfpf_storm_rx_mode(struct bnx2x *bp);
|
||||||
|
|
||||||
|
@ -794,7 +794,8 @@ static inline int bnx2x_vfpf_init(struct bnx2x *bp) {return 0; }
|
||||||
static inline void bnx2x_vfpf_close_vf(struct bnx2x *bp) {}
|
static inline void bnx2x_vfpf_close_vf(struct bnx2x *bp) {}
|
||||||
static inline int bnx2x_vfpf_setup_q(struct bnx2x *bp, int fp_idx) {return 0; }
|
static inline int bnx2x_vfpf_setup_q(struct bnx2x *bp, int fp_idx) {return 0; }
|
||||||
static inline int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx) {return 0; }
|
static inline int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx) {return 0; }
|
||||||
static inline int bnx2x_vfpf_set_mac(struct bnx2x *bp) {return 0; }
|
static inline int bnx2x_vfpf_config_mac(struct bnx2x *bp, u8 *addr,
|
||||||
|
u8 vf_qid, bool set) {return 0; }
|
||||||
static inline int bnx2x_vfpf_set_mcast(struct net_device *dev) {return 0; }
|
static inline int bnx2x_vfpf_set_mcast(struct net_device *dev) {return 0; }
|
||||||
static inline int bnx2x_vfpf_storm_rx_mode(struct bnx2x *bp) {return 0; }
|
static inline int bnx2x_vfpf_storm_rx_mode(struct bnx2x *bp) {return 0; }
|
||||||
static inline int bnx2x_iov_nic_init(struct bnx2x *bp) {return 0; }
|
static inline int bnx2x_iov_nic_init(struct bnx2x *bp) {return 0; }
|
||||||
|
|
|
@ -406,6 +406,9 @@ void bnx2x_vfpf_close_vf(struct bnx2x *bp)
|
||||||
for_each_queue(bp, i)
|
for_each_queue(bp, i)
|
||||||
bnx2x_vfpf_teardown_queue(bp, i);
|
bnx2x_vfpf_teardown_queue(bp, i);
|
||||||
|
|
||||||
|
/* remove mac */
|
||||||
|
bnx2x_vfpf_config_mac(bp, bp->dev->dev_addr, bp->fp->index, false);
|
||||||
|
|
||||||
/* clear mailbox and prep first tlv */
|
/* clear mailbox and prep first tlv */
|
||||||
bnx2x_vfpf_prep(bp, &req->first_tlv, CHANNEL_TLV_CLOSE, sizeof(*req));
|
bnx2x_vfpf_prep(bp, &req->first_tlv, CHANNEL_TLV_CLOSE, sizeof(*req));
|
||||||
|
|
||||||
|
@ -561,10 +564,11 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* request pf to add a mac for the vf */
|
/* request pf to add a mac for the vf */
|
||||||
int bnx2x_vfpf_set_mac(struct bnx2x *bp)
|
int bnx2x_vfpf_config_mac(struct bnx2x *bp, u8 *addr, u8 vf_qid, bool set)
|
||||||
{
|
{
|
||||||
struct vfpf_set_q_filters_tlv *req = &bp->vf2pf_mbox->req.set_q_filters;
|
struct vfpf_set_q_filters_tlv *req = &bp->vf2pf_mbox->req.set_q_filters;
|
||||||
struct pfvf_general_resp_tlv *resp = &bp->vf2pf_mbox->resp.general_resp;
|
struct pfvf_general_resp_tlv *resp = &bp->vf2pf_mbox->resp.general_resp;
|
||||||
|
struct pf_vf_bulletin_content bulletin = bp->pf2vf_bulletin->content;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
/* clear mailbox and prep first tlv */
|
/* clear mailbox and prep first tlv */
|
||||||
|
@ -572,16 +576,18 @@ int bnx2x_vfpf_set_mac(struct bnx2x *bp)
|
||||||
sizeof(*req));
|
sizeof(*req));
|
||||||
|
|
||||||
req->flags = VFPF_SET_Q_FILTERS_MAC_VLAN_CHANGED;
|
req->flags = VFPF_SET_Q_FILTERS_MAC_VLAN_CHANGED;
|
||||||
req->vf_qid = 0;
|
req->vf_qid = vf_qid;
|
||||||
req->n_mac_vlan_filters = 1;
|
req->n_mac_vlan_filters = 1;
|
||||||
req->filters[0].flags =
|
|
||||||
VFPF_Q_FILTER_DEST_MAC_VALID | VFPF_Q_FILTER_SET_MAC;
|
req->filters[0].flags = VFPF_Q_FILTER_DEST_MAC_VALID;
|
||||||
|
if (set)
|
||||||
|
req->filters[0].flags |= VFPF_Q_FILTER_SET_MAC;
|
||||||
|
|
||||||
/* sample bulletin board for new mac */
|
/* sample bulletin board for new mac */
|
||||||
bnx2x_sample_bulletin(bp);
|
bnx2x_sample_bulletin(bp);
|
||||||
|
|
||||||
/* copy mac from device to request */
|
/* copy mac from device to request */
|
||||||
memcpy(req->filters[0].mac, bp->dev->dev_addr, ETH_ALEN);
|
memcpy(req->filters[0].mac, addr, ETH_ALEN);
|
||||||
|
|
||||||
/* add list termination tlv */
|
/* add list termination tlv */
|
||||||
bnx2x_add_tlv(bp, req, req->first_tlv.tl.length, CHANNEL_TLV_LIST_END,
|
bnx2x_add_tlv(bp, req, req->first_tlv.tl.length, CHANNEL_TLV_LIST_END,
|
||||||
|
@ -602,6 +608,9 @@ int bnx2x_vfpf_set_mac(struct bnx2x *bp)
|
||||||
DP(BNX2X_MSG_IOV,
|
DP(BNX2X_MSG_IOV,
|
||||||
"vfpf SET MAC failed. Check bulletin board for new posts\n");
|
"vfpf SET MAC failed. Check bulletin board for new posts\n");
|
||||||
|
|
||||||
|
/* copy mac from bulletin to device */
|
||||||
|
memcpy(bp->dev->dev_addr, bulletin.mac, ETH_ALEN);
|
||||||
|
|
||||||
/* check if bulletin board was updated */
|
/* check if bulletin board was updated */
|
||||||
if (bnx2x_sample_bulletin(bp) == PFVF_BULLETIN_UPDATED) {
|
if (bnx2x_sample_bulletin(bp) == PFVF_BULLETIN_UPDATED) {
|
||||||
/* copy mac from device to request */
|
/* copy mac from device to request */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче