aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom
diff options
context:
space:
mode:
authorEddie Wai <eddie.wai@broadcom.com>2016-09-19 03:58:09 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-19 21:32:25 -0400
commit350a714960eb8a980c913c9be5a96bb18b2fe9da (patch)
tree2acb53fef25409cf5b63cc3b9d4707231935876f /drivers/net/ethernet/broadcom
parentae8e98a6fa7a73917196c507e43414ea96b6a0fc (diff)
bnxt_en: Fixed the VF link status after a link state change
The VF link state can be changed via the 'ip link set' cmd. Currently, the new link state does not take effect immediately. The fix is for the PF to send a link change async event to the designated VF after a VF link state change. This async event will trigger the VF to update the link status. Signed-off-by: Eddie Wai <eddie.wai@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom')
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c84
1 files changed, 42 insertions, 42 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
index 50d2007a2640..8be718508600 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
@@ -19,6 +19,45 @@
19#include "bnxt_ethtool.h" 19#include "bnxt_ethtool.h"
20 20
21#ifdef CONFIG_BNXT_SRIOV 21#ifdef CONFIG_BNXT_SRIOV
22static int bnxt_hwrm_fwd_async_event_cmpl(struct bnxt *bp,
23 struct bnxt_vf_info *vf, u16 event_id)
24{
25 struct hwrm_fwd_async_event_cmpl_output *resp = bp->hwrm_cmd_resp_addr;
26 struct hwrm_fwd_async_event_cmpl_input req = {0};
27 struct hwrm_async_event_cmpl *async_cmpl;
28 int rc = 0;
29
30 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FWD_ASYNC_EVENT_CMPL, -1, -1);
31 if (vf)
32 req.encap_async_event_target_id = cpu_to_le16(vf->fw_fid);
33 else
34 /* broadcast this async event to all VFs */
35 req.encap_async_event_target_id = cpu_to_le16(0xffff);
36 async_cmpl = (struct hwrm_async_event_cmpl *)req.encap_async_event_cmpl;
37 async_cmpl->type =
38 cpu_to_le16(HWRM_ASYNC_EVENT_CMPL_TYPE_HWRM_ASYNC_EVENT);
39 async_cmpl->event_id = cpu_to_le16(event_id);
40
41 mutex_lock(&bp->hwrm_cmd_lock);
42 rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
43
44 if (rc) {
45 netdev_err(bp->dev, "hwrm_fwd_async_event_cmpl failed. rc:%d\n",
46 rc);
47 goto fwd_async_event_cmpl_exit;
48 }
49
50 if (resp->error_code) {
51 netdev_err(bp->dev, "hwrm_fwd_async_event_cmpl error %d\n",
52 resp->error_code);
53 rc = -1;
54 }
55
56fwd_async_event_cmpl_exit:
57 mutex_unlock(&bp->hwrm_cmd_lock);
58 return rc;
59}
60
22static int bnxt_vf_ndo_prep(struct bnxt *bp, int vf_id) 61static int bnxt_vf_ndo_prep(struct bnxt *bp, int vf_id)
23{ 62{
24 if (!test_bit(BNXT_STATE_OPEN, &bp->state)) { 63 if (!test_bit(BNXT_STATE_OPEN, &bp->state)) {
@@ -243,8 +282,9 @@ int bnxt_set_vf_link_state(struct net_device *dev, int vf_id, int link)
243 rc = -EINVAL; 282 rc = -EINVAL;
244 break; 283 break;
245 } 284 }
246 /* CHIMP TODO: send msg to VF to update new link state */ 285 if (vf->flags & (BNXT_VF_LINK_UP | BNXT_VF_LINK_FORCED))
247 286 rc = bnxt_hwrm_fwd_async_event_cmpl(bp, vf,
287 HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE);
248 return rc; 288 return rc;
249} 289}
250 290
@@ -525,46 +565,6 @@ err_out1:
525 return rc; 565 return rc;
526} 566}
527 567
528static int bnxt_hwrm_fwd_async_event_cmpl(struct bnxt *bp,
529 struct bnxt_vf_info *vf,
530 u16 event_id)
531{
532 int rc = 0;
533 struct hwrm_fwd_async_event_cmpl_input req = {0};
534 struct hwrm_fwd_async_event_cmpl_output *resp = bp->hwrm_cmd_resp_addr;
535 struct hwrm_async_event_cmpl *async_cmpl;
536
537 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FWD_ASYNC_EVENT_CMPL, -1, -1);
538 if (vf)
539 req.encap_async_event_target_id = cpu_to_le16(vf->fw_fid);
540 else
541 /* broadcast this async event to all VFs */
542 req.encap_async_event_target_id = cpu_to_le16(0xffff);
543 async_cmpl = (struct hwrm_async_event_cmpl *)req.encap_async_event_cmpl;
544 async_cmpl->type =
545 cpu_to_le16(HWRM_ASYNC_EVENT_CMPL_TYPE_HWRM_ASYNC_EVENT);
546 async_cmpl->event_id = cpu_to_le16(event_id);
547
548 mutex_lock(&bp->hwrm_cmd_lock);
549 rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
550
551 if (rc) {
552 netdev_err(bp->dev, "hwrm_fwd_async_event_cmpl failed. rc:%d\n",
553 rc);
554 goto fwd_async_event_cmpl_exit;
555 }
556
557 if (resp->error_code) {
558 netdev_err(bp->dev, "hwrm_fwd_async_event_cmpl error %d\n",
559 resp->error_code);
560 rc = -1;
561 }
562
563fwd_async_event_cmpl_exit:
564 mutex_unlock(&bp->hwrm_cmd_lock);
565 return rc;
566}
567
568void bnxt_sriov_disable(struct bnxt *bp) 568void bnxt_sriov_disable(struct bnxt *bp)
569{ 569{
570 u16 num_vfs = pci_num_vf(bp->pdev); 570 u16 num_vfs = pci_num_vf(bp->pdev);