aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManish Chopra <Manish.Chopra@qlogic.com>2016-05-15 07:48:07 -0400
committerDavid S. Miller <davem@davemloft.net>2016-05-16 13:59:19 -0400
commit079d20a6739e0b4a06d73f37b8435d443897cc0c (patch)
tree786b914f4a960de3eeb0bbab14451fbf14ef2539
parentb2b897eba66636b7fd8e56cc4f7464819623609e (diff)
qed: Reset link on IOV disable
PF updates its VFs' bulletin boards with link configurations whenever the physical carrier changes or whenever hyper-user explicitly requires some setting of the VFs link via the hypervisor's PF. Since the bulletin board is getting cleaned as part of the IOV disable flow on the PF side, re-enabling sriov would lead to a VF that sees the carrier as 'down', until an event causing the PF to re-fill the bulletin with the link configuration would occur. To fix this we simply refelect the link state during the flows, giving the later VFs a default reflecting the PFs link state. Signed-off-by: Manish Chopra <Manish.Chopra@qlogic.com> Signed-off-by: Yuval Mintz <Yuval.Mintz@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/qlogic/qed/qed_sriov.c90
1 files changed, 51 insertions, 39 deletions
diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
index 7b6b4a0f5d1d..a977f39f534c 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c
@@ -806,9 +806,51 @@ static int qed_iov_init_hw_for_vf(struct qed_hwfn *p_hwfn,
806 return rc; 806 return rc;
807} 807}
808 808
809static void qed_iov_set_link(struct qed_hwfn *p_hwfn,
810 u16 vfid,
811 struct qed_mcp_link_params *params,
812 struct qed_mcp_link_state *link,
813 struct qed_mcp_link_capabilities *p_caps)
814{
815 struct qed_vf_info *p_vf = qed_iov_get_vf_info(p_hwfn,
816 vfid,
817 false);
818 struct qed_bulletin_content *p_bulletin;
819
820 if (!p_vf)
821 return;
822
823 p_bulletin = p_vf->bulletin.p_virt;
824 p_bulletin->req_autoneg = params->speed.autoneg;
825 p_bulletin->req_adv_speed = params->speed.advertised_speeds;
826 p_bulletin->req_forced_speed = params->speed.forced_speed;
827 p_bulletin->req_autoneg_pause = params->pause.autoneg;
828 p_bulletin->req_forced_rx = params->pause.forced_rx;
829 p_bulletin->req_forced_tx = params->pause.forced_tx;
830 p_bulletin->req_loopback = params->loopback_mode;
831
832 p_bulletin->link_up = link->link_up;
833 p_bulletin->speed = link->speed;
834 p_bulletin->full_duplex = link->full_duplex;
835 p_bulletin->autoneg = link->an;
836 p_bulletin->autoneg_complete = link->an_complete;
837 p_bulletin->parallel_detection = link->parallel_detection;
838 p_bulletin->pfc_enabled = link->pfc_enabled;
839 p_bulletin->partner_adv_speed = link->partner_adv_speed;
840 p_bulletin->partner_tx_flow_ctrl_en = link->partner_tx_flow_ctrl_en;
841 p_bulletin->partner_rx_flow_ctrl_en = link->partner_rx_flow_ctrl_en;
842 p_bulletin->partner_adv_pause = link->partner_adv_pause;
843 p_bulletin->sfp_tx_fault = link->sfp_tx_fault;
844
845 p_bulletin->capability_speed = p_caps->speed_capabilities;
846}
847
809static int qed_iov_release_hw_for_vf(struct qed_hwfn *p_hwfn, 848static int qed_iov_release_hw_for_vf(struct qed_hwfn *p_hwfn,
810 struct qed_ptt *p_ptt, u16 rel_vf_id) 849 struct qed_ptt *p_ptt, u16 rel_vf_id)
811{ 850{
851 struct qed_mcp_link_capabilities caps;
852 struct qed_mcp_link_params params;
853 struct qed_mcp_link_state link;
812 struct qed_vf_info *vf = NULL; 854 struct qed_vf_info *vf = NULL;
813 int rc = 0; 855 int rc = 0;
814 856
@@ -823,6 +865,15 @@ static int qed_iov_release_hw_for_vf(struct qed_hwfn *p_hwfn,
823 865
824 memset(&vf->p_vf_info, 0, sizeof(vf->p_vf_info)); 866 memset(&vf->p_vf_info, 0, sizeof(vf->p_vf_info));
825 867
868 /* Get the link configuration back in bulletin so
869 * that when VFs are re-enabled they get the actual
870 * link configuration.
871 */
872 memcpy(&params, qed_mcp_get_link_params(p_hwfn), sizeof(params));
873 memcpy(&link, qed_mcp_get_link_state(p_hwfn), sizeof(link));
874 memcpy(&caps, qed_mcp_get_link_capabilities(p_hwfn), sizeof(caps));
875 qed_iov_set_link(p_hwfn, rel_vf_id, &params, &link, &caps);
876
826 if (vf->state != VF_STOPPED) { 877 if (vf->state != VF_STOPPED) {
827 /* Stopping the VF */ 878 /* Stopping the VF */
828 rc = qed_sp_vf_stop(p_hwfn, vf->concrete_fid, vf->opaque_fid); 879 rc = qed_sp_vf_stop(p_hwfn, vf->concrete_fid, vf->opaque_fid);
@@ -2542,45 +2593,6 @@ int qed_iov_mark_vf_flr(struct qed_hwfn *p_hwfn, u32 *p_disabled_vfs)
2542 return found; 2593 return found;
2543} 2594}
2544 2595
2545void qed_iov_set_link(struct qed_hwfn *p_hwfn,
2546 u16 vfid,
2547 struct qed_mcp_link_params *params,
2548 struct qed_mcp_link_state *link,
2549 struct qed_mcp_link_capabilities *p_caps)
2550{
2551 struct qed_vf_info *p_vf = qed_iov_get_vf_info(p_hwfn,
2552 vfid,
2553 false);
2554 struct qed_bulletin_content *p_bulletin;
2555
2556 if (!p_vf)
2557 return;
2558
2559 p_bulletin = p_vf->bulletin.p_virt;
2560 p_bulletin->req_autoneg = params->speed.autoneg;
2561 p_bulletin->req_adv_speed = params->speed.advertised_speeds;
2562 p_bulletin->req_forced_speed = params->speed.forced_speed;
2563 p_bulletin->req_autoneg_pause = params->pause.autoneg;
2564 p_bulletin->req_forced_rx = params->pause.forced_rx;
2565 p_bulletin->req_forced_tx = params->pause.forced_tx;
2566 p_bulletin->req_loopback = params->loopback_mode;
2567
2568 p_bulletin->link_up = link->link_up;
2569 p_bulletin->speed = link->speed;
2570 p_bulletin->full_duplex = link->full_duplex;
2571 p_bulletin->autoneg = link->an;
2572 p_bulletin->autoneg_complete = link->an_complete;
2573 p_bulletin->parallel_detection = link->parallel_detection;
2574 p_bulletin->pfc_enabled = link->pfc_enabled;
2575 p_bulletin->partner_adv_speed = link->partner_adv_speed;
2576 p_bulletin->partner_tx_flow_ctrl_en = link->partner_tx_flow_ctrl_en;
2577 p_bulletin->partner_rx_flow_ctrl_en = link->partner_rx_flow_ctrl_en;
2578 p_bulletin->partner_adv_pause = link->partner_adv_pause;
2579 p_bulletin->sfp_tx_fault = link->sfp_tx_fault;
2580
2581 p_bulletin->capability_speed = p_caps->speed_capabilities;
2582}
2583
2584static void qed_iov_get_link(struct qed_hwfn *p_hwfn, 2596static void qed_iov_get_link(struct qed_hwfn *p_hwfn,
2585 u16 vfid, 2597 u16 vfid,
2586 struct qed_mcp_link_params *p_params, 2598 struct qed_mcp_link_params *p_params,