Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / broadcom / bnx2x / bnx2x_vfpf.c
index 531eebf40d60b7b064043415b6c3ca44ef3e0b51..90fbf9cc2c2c78b8f2d1d044cba4abfdc835f0bf 100644 (file)
@@ -36,6 +36,8 @@ void bnx2x_add_tlv(struct bnx2x *bp, void *tlvs_list, u16 offset, u16 type,
 void bnx2x_vfpf_prep(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv,
                     u16 type, u16 length)
 {
+       mutex_lock(&bp->vf2pf_mutex);
+
        DP(BNX2X_MSG_IOV, "preparing to send %d tlv over vf pf channel\n",
           type);
 
@@ -49,6 +51,15 @@ void bnx2x_vfpf_prep(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv,
        first_tlv->resp_msg_offset = sizeof(bp->vf2pf_mbox->req);
 }
 
+/* releases the mailbox */
+void bnx2x_vfpf_finalize(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv)
+{
+       DP(BNX2X_MSG_IOV, "done sending [%d] tlv over vf pf channel\n",
+          first_tlv->tl.type);
+
+       mutex_unlock(&bp->vf2pf_mutex);
+}
+
 /* list the types and lengths of the tlvs on the buffer */
 void bnx2x_dp_tlv_list(struct bnx2x *bp, void *tlvs_list)
 {
@@ -181,8 +192,10 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count)
        /* clear mailbox and prep first tlv */
        bnx2x_vfpf_prep(bp, &req->first_tlv, CHANNEL_TLV_ACQUIRE, sizeof(*req));
 
-       if (bnx2x_get_vf_id(bp, &vf_id))
-               return -EAGAIN;
+       if (bnx2x_get_vf_id(bp, &vf_id)) {
+               rc = -EAGAIN;
+               goto out;
+       }
 
        req->vfdev_info.vf_id = vf_id;
        req->vfdev_info.vf_os = 0;
@@ -213,7 +226,7 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count)
 
                /* PF timeout */
                if (rc)
-                       return rc;
+                       goto out;
 
                /* copy acquire response from buffer to bp */
                memcpy(&bp->acquire_resp, resp, sizeof(bp->acquire_resp));
@@ -253,7 +266,8 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count)
                        /* PF reports error */
                        BNX2X_ERR("Failed to get the requested amount of resources: %d. Breaking...\n",
                                  bp->acquire_resp.hdr.status);
-                       return -EAGAIN;
+                       rc = -EAGAIN;
+                       goto out;
                }
        }
 
@@ -279,20 +293,24 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count)
                       bp->acquire_resp.resc.current_mac_addr,
                       ETH_ALEN);
 
-       return 0;
+out:
+       bnx2x_vfpf_finalize(bp, &req->first_tlv);
+       return rc;
 }
 
 int bnx2x_vfpf_release(struct bnx2x *bp)
 {
        struct vfpf_release_tlv *req = &bp->vf2pf_mbox->req.release;
        struct pfvf_general_resp_tlv *resp = &bp->vf2pf_mbox->resp.general_resp;
-       u32 rc = 0, vf_id;
+       u32 rc, vf_id;
 
        /* clear mailbox and prep first tlv */
        bnx2x_vfpf_prep(bp, &req->first_tlv, CHANNEL_TLV_RELEASE, sizeof(*req));
 
-       if (bnx2x_get_vf_id(bp, &vf_id))
-               return -EAGAIN;
+       if (bnx2x_get_vf_id(bp, &vf_id)) {
+               rc = -EAGAIN;
+               goto out;
+       }
 
        req->vf_id = vf_id;
 
@@ -308,7 +326,8 @@ int bnx2x_vfpf_release(struct bnx2x *bp)
 
        if (rc)
                /* PF timeout */
-               return rc;
+               goto out;
+
        if (resp->hdr.status == PFVF_STATUS_SUCCESS) {
                /* PF released us */
                DP(BNX2X_MSG_SP, "vf released\n");
@@ -316,10 +335,13 @@ int bnx2x_vfpf_release(struct bnx2x *bp)
                /* PF reports error */
                BNX2X_ERR("PF failed our release request - are we out of sync? response status: %d\n",
                          resp->hdr.status);
-               return -EAGAIN;
+               rc = -EAGAIN;
+               goto out;
        }
+out:
+       bnx2x_vfpf_finalize(bp, &req->first_tlv);
 
-       return 0;
+       return rc;
 }
 
 /* Tell PF about SB addresses */
@@ -350,16 +372,20 @@ int bnx2x_vfpf_init(struct bnx2x *bp)
 
        rc = bnx2x_send_msg2pf(bp, &resp->hdr.status, bp->vf2pf_mbox_mapping);
        if (rc)
-               return rc;
+               goto out;
 
        if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
                BNX2X_ERR("INIT VF failed: %d. Breaking...\n",
                          resp->hdr.status);
-               return -EAGAIN;
+               rc = -EAGAIN;
+               goto out;
        }
 
        DP(BNX2X_MSG_SP, "INIT VF Succeeded\n");
-       return 0;
+out:
+       bnx2x_vfpf_finalize(bp, &req->first_tlv);
+
+       return rc;
 }
 
 /* CLOSE VF - opposite to INIT_VF */
@@ -401,6 +427,8 @@ void bnx2x_vfpf_close_vf(struct bnx2x *bp)
                BNX2X_ERR("Sending CLOSE failed: pf response was %d\n",
                          resp->hdr.status);
 
+       bnx2x_vfpf_finalize(bp, &req->first_tlv);
+
 free_irq:
        /* Disable HW interrupts, NAPI */
        bnx2x_netif_stop(bp, 0);
@@ -435,7 +463,6 @@ int bnx2x_vfpf_setup_q(struct bnx2x *bp, int fp_idx)
        /* calculate queue flags */
        flags |= VFPF_QUEUE_FLG_STATS;
        flags |= VFPF_QUEUE_FLG_CACHE_ALIGN;
-       flags |= IS_MF_SD(bp) ? VFPF_QUEUE_FLG_OV : 0;
        flags |= VFPF_QUEUE_FLG_VLAN;
        DP(NETIF_MSG_IFUP, "vlan removal enabled\n");
 
@@ -486,8 +513,11 @@ int bnx2x_vfpf_setup_q(struct bnx2x *bp, int fp_idx)
        if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
                BNX2X_ERR("Status of SETUP_Q for queue[%d] is %d\n",
                          fp_idx, resp->hdr.status);
-               return -EINVAL;
+               rc = -EINVAL;
        }
+
+       bnx2x_vfpf_finalize(bp, &req->first_tlv);
+
        return rc;
 }
 
@@ -515,17 +545,19 @@ int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx)
        if (rc) {
                BNX2X_ERR("Sending TEARDOWN for queue %d failed: %d\n", qidx,
                          rc);
-               return rc;
+               goto out;
        }
 
        /* PF failed the transaction */
        if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
                BNX2X_ERR("TEARDOWN for queue %d failed: %d\n", qidx,
                          resp->hdr.status);
-               return -EINVAL;
+               rc = -EINVAL;
        }
 
-       return 0;
+out:
+       bnx2x_vfpf_finalize(bp, &req->first_tlv);
+       return rc;
 }
 
 /* request pf to add a mac for the vf */
@@ -533,7 +565,7 @@ int bnx2x_vfpf_set_mac(struct bnx2x *bp)
 {
        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;
-       int rc;
+       int rc = 0;
 
        /* clear mailbox and prep first tlv */
        bnx2x_vfpf_prep(bp, &req->first_tlv, CHANNEL_TLV_SET_Q_FILTERS,
@@ -562,7 +594,7 @@ int bnx2x_vfpf_set_mac(struct bnx2x *bp)
        rc = bnx2x_send_msg2pf(bp, &resp->hdr.status, bp->vf2pf_mbox_mapping);
        if (rc) {
                BNX2X_ERR("failed to send message to pf. rc was %d\n", rc);
-               return rc;
+               goto out;
        }
 
        /* failure may mean PF was configured with a new mac for us */
@@ -587,8 +619,10 @@ int bnx2x_vfpf_set_mac(struct bnx2x *bp)
 
        if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
                BNX2X_ERR("vfpf SET MAC failed: %d\n", resp->hdr.status);
-               return -EINVAL;
+               rc = -EINVAL;
        }
+out:
+       bnx2x_vfpf_finalize(bp, &req->first_tlv);
 
        return 0;
 }
@@ -643,14 +677,16 @@ int bnx2x_vfpf_set_mcast(struct net_device *dev)
        rc = bnx2x_send_msg2pf(bp, &resp->hdr.status, bp->vf2pf_mbox_mapping);
        if (rc) {
                BNX2X_ERR("Sending a message failed: %d\n", rc);
-               return rc;
+               goto out;
        }
 
        if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
                BNX2X_ERR("Set Rx mode/multicast failed: %d\n",
                          resp->hdr.status);
-               return -EINVAL;
+               rc = -EINVAL;
        }
+out:
+       bnx2x_vfpf_finalize(bp, &req->first_tlv);
 
        return 0;
 }
@@ -689,7 +725,8 @@ int bnx2x_vfpf_storm_rx_mode(struct bnx2x *bp)
                break;
        default:
                BNX2X_ERR("BAD rx mode (%d)\n", mode);
-               return -EINVAL;
+               rc = -EINVAL;
+               goto out;
        }
 
        req->flags |= VFPF_SET_Q_FILTERS_RX_MASK_CHANGED;
@@ -708,8 +745,10 @@ int bnx2x_vfpf_storm_rx_mode(struct bnx2x *bp)
 
        if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
                BNX2X_ERR("Set Rx mode failed: %d\n", resp->hdr.status);
-               return -EINVAL;
+               rc = -EINVAL;
        }
+out:
+       bnx2x_vfpf_finalize(bp, &req->first_tlv);
 
        return rc;
 }
@@ -1004,7 +1043,7 @@ static void bnx2x_vf_mbx_init_vf(struct bnx2x *bp, struct bnx2x_virtf *vf,
 }
 
 /* convert MBX queue-flags to standard SP queue-flags */
-static void bnx2x_vf_mbx_set_q_flags(u32 mbx_q_flags,
+static void bnx2x_vf_mbx_set_q_flags(struct bnx2x *bp, u32 mbx_q_flags,
                                     unsigned long *sp_q_flags)
 {
        if (mbx_q_flags & VFPF_QUEUE_FLG_TPA)
@@ -1015,8 +1054,6 @@ static void bnx2x_vf_mbx_set_q_flags(u32 mbx_q_flags,
                __set_bit(BNX2X_Q_FLG_TPA_GRO, sp_q_flags);
        if (mbx_q_flags & VFPF_QUEUE_FLG_STATS)
                __set_bit(BNX2X_Q_FLG_STATS, sp_q_flags);
-       if (mbx_q_flags & VFPF_QUEUE_FLG_OV)
-               __set_bit(BNX2X_Q_FLG_OV, sp_q_flags);
        if (mbx_q_flags & VFPF_QUEUE_FLG_VLAN)
                __set_bit(BNX2X_Q_FLG_VLAN, sp_q_flags);
        if (mbx_q_flags & VFPF_QUEUE_FLG_COS)
@@ -1025,6 +1062,10 @@ static void bnx2x_vf_mbx_set_q_flags(u32 mbx_q_flags,
                __set_bit(BNX2X_Q_FLG_HC, sp_q_flags);
        if (mbx_q_flags & VFPF_QUEUE_FLG_DHC)
                __set_bit(BNX2X_Q_FLG_DHC, sp_q_flags);
+
+       /* outer vlan removal is set according to the PF's multi fuction mode */
+       if (IS_MF_SD(bp))
+               __set_bit(BNX2X_Q_FLG_OV, sp_q_flags);
 }
 
 static void bnx2x_vf_mbx_setup_q(struct bnx2x *bp, struct bnx2x_virtf *vf,
@@ -1075,11 +1116,11 @@ static void bnx2x_vf_mbx_setup_q(struct bnx2x *bp, struct bnx2x_virtf *vf,
                        init_p->tx.hc_rate = setup_q->txq.hc_rate;
                        init_p->tx.sb_cq_index = setup_q->txq.sb_index;
 
-                       bnx2x_vf_mbx_set_q_flags(setup_q->txq.flags,
+                       bnx2x_vf_mbx_set_q_flags(bp, setup_q->txq.flags,
                                                 &init_p->tx.flags);
 
                        /* tx setup - flags */
-                       bnx2x_vf_mbx_set_q_flags(setup_q->txq.flags,
+                       bnx2x_vf_mbx_set_q_flags(bp, setup_q->txq.flags,
                                                 &setup_p->flags);
 
                        /* tx setup - general, nothing */
@@ -1107,11 +1148,11 @@ static void bnx2x_vf_mbx_setup_q(struct bnx2x *bp, struct bnx2x_virtf *vf,
                        /* rx init */
                        init_p->rx.hc_rate = setup_q->rxq.hc_rate;
                        init_p->rx.sb_cq_index = setup_q->rxq.sb_index;
-                       bnx2x_vf_mbx_set_q_flags(setup_q->rxq.flags,
+                       bnx2x_vf_mbx_set_q_flags(bp, setup_q->rxq.flags,
                                                 &init_p->rx.flags);
 
                        /* rx setup - flags */
-                       bnx2x_vf_mbx_set_q_flags(setup_q->rxq.flags,
+                       bnx2x_vf_mbx_set_q_flags(bp, setup_q->rxq.flags,
                                                 &setup_p->flags);
 
                        /* rx setup - general */