From de86a2f22230d3193ba08afe02b5bdfe75575089 Mon Sep 17 00:00:00 2001 From: Vadim Suraev Date: Mon, 8 Feb 2016 15:57:30 -0500 Subject: [PATCH] i40e: Enable getting link status from VF Add handling of custom OP code sent from the PMD VF to get link status via the virtual channel interface. Signed-off-by: Allain Legacy Signed-off-by: eric zhang Signed-off-by: Jim Somerville Signed-off-by: Steven Webster Signed-off-by: Babak Sarashki [mvb: Refresh patch for i40e v2.6.11] Signed-off-by: M. Vefa Bicakci --- src/i40e_virtchnl_pf.c | 78 ++++++++++++++++++++++++++++++++++++++++++ src/virtchnl.h | 1 + 2 files changed, 79 insertions(+) diff --git a/src/i40e_virtchnl_pf.c b/src/i40e_virtchnl_pf.c index 5ec2a78b937d..11190fb94c29 100644 --- a/src/i40e_virtchnl_pf.c +++ b/src/i40e_virtchnl_pf.c @@ -3249,6 +3249,81 @@ err_out: aq_ret); } +struct i40e_eth_link { + uint16_t link_speed; /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */ + uint16_t link_duplex; /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */ + uint8_t link_status : 1; /**< 1 -> link up, 0 -> link down */ +}__attribute__((aligned(8))); + +#define ETH_LINK_SPEED_AUTONEG 0 /**< Auto-negotiate link speed. */ +#define ETH_LINK_SPEED_10 10 /**< 10 megabits/second. */ +#define ETH_LINK_SPEED_100 100 /**< 100 megabits/second. */ +#define ETH_LINK_SPEED_1000 1000 /**< 1 gigabits/second. */ +#define ETH_LINK_SPEED_10000 10000 /**< 10 gigabits/second. */ +#define ETH_LINK_SPEED_10G 10000 /**< alias of 10 gigabits/second. */ +#define ETH_LINK_SPEED_20G 20000 /**< 20 gigabits/second. */ +#define ETH_LINK_SPEED_40G 40000 /**< 40 gigabits/second. */ + +#define ETH_LINK_AUTONEG_DUPLEX 0 /**< Auto-negotiate duplex. */ +#define ETH_LINK_HALF_DUPLEX 1 /**< Half-duplex connection. */ +#define ETH_LINK_FULL_DUPLEX 2 /**< Full-duplex connection. */ + +static void +i40e_vc_get_link_status(struct i40e_vf *vf) +{ + struct i40e_pf *pf = vf->pf; + struct i40e_hw *hw; + i40e_status aq_ret = I40E_SUCCESS; + i40e_status status; + struct i40e_eth_link eth_link; + bool new_link; + + if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states) || + !test_bit(I40E_VIRTCHNL_VF_CAP_PRIVILEGE, &vf->vf_caps)) { + aq_ret = I40E_ERR_PARAM; + goto error_param; + } + hw = &pf->hw; + + /* set this to force the get_link_status call to refresh state */ + pf->hw.phy.get_link_info = true; + + status = i40e_get_link_status(&pf->hw, &new_link); + if (status != I40E_SUCCESS) { + dev_dbg(&pf->pdev->dev, "couldn't get link state, status: %d\n", + status); + aq_ret = I40E_ERR_INVALID_LINK_SETTINGS; + goto error_param; + } + + /* Update link status first to acquire latest link change */ + eth_link.link_status = new_link ? 1 : 0; + + switch(hw->phy.link_info.link_speed) { + case I40E_LINK_SPEED_40GB: + eth_link.link_speed = ETH_LINK_SPEED_40G; + break; + case I40E_LINK_SPEED_10GB: + eth_link.link_speed = ETH_LINK_SPEED_10G; + break; + case I40E_LINK_SPEED_1GB: + eth_link.link_speed = ETH_LINK_SPEED_1000; + break; + case I40E_LINK_SPEED_100MB: + eth_link.link_speed = ETH_LINK_SPEED_100; + break; + default: + eth_link.link_speed = ETH_LINK_SPEED_AUTONEG; + break; + } + eth_link.link_duplex = ETH_LINK_FULL_DUPLEX;/* always */ + +error_param: + i40e_vc_send_msg_to_vf(vf, VIRTCHNL_OP_GET_LINK_STAT, + aq_ret, (uint8_t *)ð_link, + sizeof(eth_link)); +} + /** * i40e_vc_config_queues_msg * @vf: pointer to the VF info @@ -5331,6 +5406,9 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, s16 vf_id, u32 v_opcode, case VIRTCHNL_OP_REQUEST_QUEUES: ret = i40e_vc_request_queues_msg(vf, msg); break; + case VIRTCHNL_OP_GET_LINK_STAT: + i40e_vc_get_link_status(vf); + break; #ifdef __TC_MQPRIO_MODE_MAX case VIRTCHNL_OP_ENABLE_CHANNELS: ret = i40e_vc_add_qch_msg(vf, msg); diff --git a/src/virtchnl.h b/src/virtchnl.h index e72daf5130de..07f6d8a88db9 100644 --- a/src/virtchnl.h +++ b/src/virtchnl.h @@ -150,6 +150,7 @@ enum virtchnl_ops { VIRTCHNL_OP_ENABLE_QUEUES_V2 = 107, VIRTCHNL_OP_DISABLE_QUEUES_V2 = 108, VIRTCHNL_OP_MAP_QUEUE_VECTOR = 111, + VIRTCHNL_OP_GET_LINK_STAT = 0x101, VIRTCHNL_OP_MAX, }; -- 2.29.2