qed: Reflect PF link when initializing VF
authorMintz, Yuval <Yuval.Mintz@cavium.com>
Mon, 20 Feb 2017 20:43:36 +0000 (22:43 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 20 Feb 2017 22:11:54 +0000 (17:11 -0500)
VF learns of the current link state via its bulletin board,
which might reflect either the physical link state or some
user-configured logical state.
Whenever the physical link changes or whnever such a configuration
is explicitly made by user the PF driver would update the bulletin
that the VF reads. But if neither has happened - i.e., PF still
hasn't got a physical link up and no additional configuration was
done the VF wouldn't have a valid link information available.

Simply reflect the physical link state whenever the VF is
initialized. The user could then affect it however he wants.

Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qed/qed_sriov.c

index 3f4bf31f45e0acc4846d0d6e02b7397f18cf88f0..29ed785f1dc22699962ea15904118c3fee314207 100644 (file)
@@ -831,10 +831,52 @@ static void qed_iov_free_vf_igu_sbs(struct qed_hwfn *p_hwfn,
        vf->num_sbs = 0;
 }
 
+static void qed_iov_set_link(struct qed_hwfn *p_hwfn,
+                            u16 vfid,
+                            struct qed_mcp_link_params *params,
+                            struct qed_mcp_link_state *link,
+                            struct qed_mcp_link_capabilities *p_caps)
+{
+       struct qed_vf_info *p_vf = qed_iov_get_vf_info(p_hwfn,
+                                                      vfid,
+                                                      false);
+       struct qed_bulletin_content *p_bulletin;
+
+       if (!p_vf)
+               return;
+
+       p_bulletin = p_vf->bulletin.p_virt;
+       p_bulletin->req_autoneg = params->speed.autoneg;
+       p_bulletin->req_adv_speed = params->speed.advertised_speeds;
+       p_bulletin->req_forced_speed = params->speed.forced_speed;
+       p_bulletin->req_autoneg_pause = params->pause.autoneg;
+       p_bulletin->req_forced_rx = params->pause.forced_rx;
+       p_bulletin->req_forced_tx = params->pause.forced_tx;
+       p_bulletin->req_loopback = params->loopback_mode;
+
+       p_bulletin->link_up = link->link_up;
+       p_bulletin->speed = link->speed;
+       p_bulletin->full_duplex = link->full_duplex;
+       p_bulletin->autoneg = link->an;
+       p_bulletin->autoneg_complete = link->an_complete;
+       p_bulletin->parallel_detection = link->parallel_detection;
+       p_bulletin->pfc_enabled = link->pfc_enabled;
+       p_bulletin->partner_adv_speed = link->partner_adv_speed;
+       p_bulletin->partner_tx_flow_ctrl_en = link->partner_tx_flow_ctrl_en;
+       p_bulletin->partner_rx_flow_ctrl_en = link->partner_rx_flow_ctrl_en;
+       p_bulletin->partner_adv_pause = link->partner_adv_pause;
+       p_bulletin->sfp_tx_fault = link->sfp_tx_fault;
+
+       p_bulletin->capability_speed = p_caps->speed_capabilities;
+}
+
 static int qed_iov_init_hw_for_vf(struct qed_hwfn *p_hwfn,
                                  struct qed_ptt *p_ptt,
                                  struct qed_iov_vf_init_params *p_params)
 {
+       struct qed_mcp_link_capabilities link_caps;
+       struct qed_mcp_link_params link_params;
+       struct qed_mcp_link_state link_state;
        u8 num_of_vf_avaiable_chains = 0;
        struct qed_vf_info *vf = NULL;
        u16 qid, num_irqs;
@@ -923,6 +965,15 @@ static int qed_iov_init_hw_for_vf(struct qed_hwfn *p_hwfn,
                           p_queue->fw_tx_qid, p_queue->fw_cid);
        }
 
+       /* Update the link configuration in bulletin */
+       memcpy(&link_params, qed_mcp_get_link_params(p_hwfn),
+              sizeof(link_params));
+       memcpy(&link_state, qed_mcp_get_link_state(p_hwfn), sizeof(link_state));
+       memcpy(&link_caps, qed_mcp_get_link_capabilities(p_hwfn),
+              sizeof(link_caps));
+       qed_iov_set_link(p_hwfn, p_params->rel_vf_id,
+                        &link_params, &link_state, &link_caps);
+
        rc = qed_iov_enable_vf_access(p_hwfn, p_ptt, vf);
        if (!rc) {
                vf->b_init = true;
@@ -934,45 +985,6 @@ static int qed_iov_init_hw_for_vf(struct qed_hwfn *p_hwfn,
        return rc;
 }
 
-static void qed_iov_set_link(struct qed_hwfn *p_hwfn,
-                            u16 vfid,
-                            struct qed_mcp_link_params *params,
-                            struct qed_mcp_link_state *link,
-                            struct qed_mcp_link_capabilities *p_caps)
-{
-       struct qed_vf_info *p_vf = qed_iov_get_vf_info(p_hwfn,
-                                                      vfid,
-                                                      false);
-       struct qed_bulletin_content *p_bulletin;
-
-       if (!p_vf)
-               return;
-
-       p_bulletin = p_vf->bulletin.p_virt;
-       p_bulletin->req_autoneg = params->speed.autoneg;
-       p_bulletin->req_adv_speed = params->speed.advertised_speeds;
-       p_bulletin->req_forced_speed = params->speed.forced_speed;
-       p_bulletin->req_autoneg_pause = params->pause.autoneg;
-       p_bulletin->req_forced_rx = params->pause.forced_rx;
-       p_bulletin->req_forced_tx = params->pause.forced_tx;
-       p_bulletin->req_loopback = params->loopback_mode;
-
-       p_bulletin->link_up = link->link_up;
-       p_bulletin->speed = link->speed;
-       p_bulletin->full_duplex = link->full_duplex;
-       p_bulletin->autoneg = link->an;
-       p_bulletin->autoneg_complete = link->an_complete;
-       p_bulletin->parallel_detection = link->parallel_detection;
-       p_bulletin->pfc_enabled = link->pfc_enabled;
-       p_bulletin->partner_adv_speed = link->partner_adv_speed;
-       p_bulletin->partner_tx_flow_ctrl_en = link->partner_tx_flow_ctrl_en;
-       p_bulletin->partner_rx_flow_ctrl_en = link->partner_rx_flow_ctrl_en;
-       p_bulletin->partner_adv_pause = link->partner_adv_pause;
-       p_bulletin->sfp_tx_fault = link->sfp_tx_fault;
-
-       p_bulletin->capability_speed = p_caps->speed_capabilities;
-}
-
 static int qed_iov_release_hw_for_vf(struct qed_hwfn *p_hwfn,
                                     struct qed_ptt *p_ptt, u16 rel_vf_id)
 {