Merge branch 'bnx2x'
authorDavid S. Miller <davem@davemloft.net>
Wed, 24 Apr 2013 20:34:00 +0000 (16:34 -0400)
committerDavid S. Miller <davem@davemloft.net>
Wed, 24 Apr 2013 20:34:09 +0000 (16:34 -0400)
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>
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c

index d72bd8c40aa15ec40c8be248cabaea49453ccfb7..fd20a4ff015054fe875a8f6709bf7c11c884027f 100644 (file)
@@ -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),
                                  &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
 
 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
        if (skb_shinfo(skb)->gso_size) {
-               skb_set_network_header(skb, 0);
                switch (be16_to_cpu(skb->protocol)) {
                case ETH_P_IP:
-                       bnx2x_gro_ip_csum(bp, skb);
+                       bnx2x_gro_csum(bp, skb, bnx2x_gro_ip_csum);
                        break;
                case ETH_P_IPV6:
-                       bnx2x_gro_ipv6_csum(bp, skb);
+                       bnx2x_gro_csum(bp, skb, bnx2x_gro_ipv6_csum);
                        break;
                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));
                }
-               tcp_gro_complete(skb);
        }
 #endif
        napi_gro_receive(&fp->napi, skb);
@@ -2658,7 +2664,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
        if (IS_PF(bp))
                rc = bnx2x_set_eth_mac(bp, true);
        else /* vf */
-               rc = bnx2x_vfpf_set_mac(bp);
+               rc = bnx2x_vfpf_config_mac(bp, bp->dev->dev_addr, bp->fp->index,
+                                          true);
        if (rc) {
                BNX2X_ERR("Setting Ethernet MAC failed\n");
                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);
 
        if (IS_PF(bp)) {
-               bnx2x_free_mem(bp);
                if (CNIC_LOADED(bp))
                        bnx2x_free_mem_cnic(bp);
+               bnx2x_free_mem(bp);
        }
        bp->state = BNX2X_STATE_CLOSED;
        bp->cnic_loaded = false;
index 88e9b47a3eb6a2255c687fb4b43f54e164b58686..397537bb44483cd2ce4a0de546a7d93d2b794cb8 100644 (file)
@@ -1889,12 +1889,15 @@ static int bnx2x_set_pauseparam(struct net_device *dev,
                        bp->link_params.req_flow_ctrl[cfg_idx] =
                                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)
                        bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_RX;
 
                if (epause->tx_pause)
                        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,
index 40f58d73de78ae297f38fe7397d3cc35eaf7a28e..9d64b988ab34e03be950a9da2f8642770b35586b 100644 (file)
@@ -3426,13 +3426,19 @@ static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
 
        switch (phy->req_flow_ctrl) {
        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;
-               else
+                       break;
+               case BNX2X_FLOW_CTRL_RX:
+               case BNX2X_FLOW_CTRL_TX:
                        *ieee_fc |=
-                       MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+                               MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
+                       break;
+               default:
+                       break;
+               }
                break;
-
        case BNX2X_FLOW_CTRL_TX:
                *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
                break;
index 86d13870399ef0737835e813ee28942dc274a6fd..fbfff1b3365e22d73fa702f399d95283e844fbcb 100644 (file)
@@ -7786,7 +7786,7 @@ int bnx2x_alloc_mem_cnic(struct bnx2x *bp)
                                sizeof(struct
                                       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 */
                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;
 
-       if (!CONFIGURE_NIC_MODE(bp))
+       if (!CONFIGURE_NIC_MODE(bp) && !bp->t2)
                /* allocate searcher T2 table */
                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)
 {
-       unsigned long ramrod_flags = 0;
-
        if (is_zero_ether_addr(bp->dev->dev_addr) &&
            (IS_MF_STORAGE_SD(bp) || IS_MF_FCOE_AFEX(bp))) {
                DP(NETIF_MSG_IFUP | NETIF_MSG_IFDOWN,
@@ -7939,12 +7937,18 @@ int bnx2x_set_eth_mac(struct bnx2x *bp, bool set)
                return 0;
        }
 
-       DP(NETIF_MSG_IFUP, "Adding Eth MAC\n");
+       if (IS_PF(bp)) {
+               unsigned long ramrod_flags = 0;
 
-       __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, &bp->sp_objs->mac_obj,
-                                set, BNX2X_ETH_MAC, &ramrod_flags);
+               DP(NETIF_MSG_IFUP, "Adding Eth MAC\n");
+               __set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
+               return bnx2x_set_mac_one(bp, bp->dev->dev_addr,
+                                        &bp->sp_objs->mac_obj, set,
+                                        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)
@@ -12803,6 +12807,7 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev)
 
        pci_set_master(pdev);
        pci_restore_state(pdev);
+       pci_save_state(pdev);
 
        if (netif_running(dev))
                bnx2x_set_power_state(bp, PCI_D0);
index d4b17b7a774e244c95b7690da027c99b0a89a6e7..d67ddc554c0f27065c7912996230d2aafb6ea89f 100644 (file)
@@ -733,7 +733,7 @@ int bnx2x_vfpf_init(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_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_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 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_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_storm_rx_mode(struct bnx2x *bp) {return 0; }
 static inline int bnx2x_iov_nic_init(struct bnx2x *bp) {return 0; }
index 90fbf9cc2c2c78b8f2d1d044cba4abfdc835f0bf..928b074d7d80bdf9b71ea2a7e5121d9c393050ba 100644 (file)
@@ -406,6 +406,9 @@ void bnx2x_vfpf_close_vf(struct bnx2x *bp)
        for_each_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 */
        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 */
-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 pfvf_general_resp_tlv *resp = &bp->vf2pf_mbox->resp.general_resp;
+       struct pf_vf_bulletin_content bulletin = bp->pf2vf_bulletin->content;
        int rc = 0;
 
        /* clear mailbox and prep first tlv */
@@ -572,16 +576,18 @@ int bnx2x_vfpf_set_mac(struct bnx2x *bp)
                        sizeof(*req));
 
        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->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 */
        bnx2x_sample_bulletin(bp);
 
        /* 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 */
        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,
                   "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 */
                if (bnx2x_sample_bulletin(bp) == PFVF_BULLETIN_UPDATED) {
                        /* copy mac from device to request */