]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
net: hns3: fix the problem that the supported port is empty
authorliuzhongzhu <liuzhongzhu@huawei.com>
Sat, 2 Feb 2019 14:39:33 +0000 (22:39 +0800)
committerDavid S. Miller <davem@davemloft.net>
Sat, 2 Feb 2019 16:24:08 +0000 (08:24 -0800)
Run ethtool ethx when displaying device information in VF,
the supported port and link mode items will be empty.

This patch fixes it.

Fixes: e2cb1dec9779 ("net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support")
Signed-off-by: liuzhongzhu <liuzhongzhu@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c

index 691d12174902c13dd6fd9fb7a0a26fc1fa6a3273..53089cd980d9b7d0d925526d4927d7ae0b109d6a 100644 (file)
@@ -40,6 +40,8 @@ enum HCLGE_MBX_OPCODE {
        HCLGE_MBX_SET_ALIVE,            /* (VF -> PF) set alive state */
        HCLGE_MBX_SET_MTU,              /* (VF -> PF) set mtu */
        HCLGE_MBX_GET_QID_IN_PF,        /* (VF -> PF) get queue id in pf */
+       HCLGE_MBX_LINK_STAT_MODE,       /* (PF -> VF) link mode has changed */
+       HCLGE_MBX_GET_LINK_MODE,        /* (VF -> PF) get the link mode of pf */
 };
 
 /* below are per-VF mac-vlan subcodes */
@@ -60,7 +62,7 @@ enum hclge_mbx_vlan_cfg_subcode {
 };
 
 #define HCLGE_MBX_MAX_MSG_SIZE 16
-#define HCLGE_MBX_MAX_RESP_DATA_SIZE   8
+#define HCLGE_MBX_MAX_RESP_DATA_SIZE   16
 #define HCLGE_MBX_RING_MAP_BASIC_MSG_NUM       3
 #define HCLGE_MBX_RING_NODE_VARIABLE_NUM       3
 
index 6afb0a4b73f7b9c91c54d48e7a1f64f096c90332..7e4a104582d6ff92e0afb106fe2871631df0a665 100644 (file)
@@ -355,16 +355,19 @@ static int hclge_get_link_info(struct hclge_vport *vport,
 {
        struct hclge_dev *hdev = vport->back;
        u16 link_status;
-       u8 msg_data[8];
+       u8 msg_data[10];
+       u16 media_type;
        u8 dest_vfid;
        u16 duplex;
 
        /* mac.link can only be 0 or 1 */
        link_status = (u16)hdev->hw.mac.link;
        duplex = hdev->hw.mac.duplex;
+       media_type = hdev->hw.mac.media_type;
        memcpy(&msg_data[0], &link_status, sizeof(u16));
        memcpy(&msg_data[2], &hdev->hw.mac.speed, sizeof(u32));
        memcpy(&msg_data[6], &duplex, sizeof(u16));
+       memcpy(&msg_data[8], &media_type, sizeof(u16));
        dest_vfid = mbx_req->mbx_src_vfid;
 
        /* send this requested info to VF */
@@ -372,6 +375,29 @@ static int hclge_get_link_info(struct hclge_vport *vport,
                                  HCLGE_MBX_LINK_STAT_CHANGE, dest_vfid);
 }
 
+static void hclge_get_link_mode(struct hclge_vport *vport,
+                               struct hclge_mbx_vf_to_pf_cmd *mbx_req)
+{
+#define HCLGE_SUPPORTED   1
+       struct hclge_dev *hdev = vport->back;
+       unsigned long advertising;
+       unsigned long supported;
+       unsigned long send_data;
+       u8 msg_data[10];
+       u8 dest_vfid;
+
+       advertising = hdev->hw.mac.advertising[0];
+       supported = hdev->hw.mac.supported[0];
+       dest_vfid = mbx_req->mbx_src_vfid;
+       msg_data[0] = mbx_req->msg[2];
+
+       send_data = msg_data[0] == HCLGE_SUPPORTED ? supported : advertising;
+
+       memcpy(&msg_data[2], &send_data, sizeof(unsigned long));
+       hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
+                          HCLGE_MBX_LINK_STAT_MODE, dest_vfid);
+}
+
 static void hclge_mbx_reset_vf_queue(struct hclge_vport *vport,
                                     struct hclge_mbx_vf_to_pf_cmd *mbx_req)
 {
@@ -556,6 +582,9 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
                                        "PF failed(%d) to get qid for VF\n",
                                        ret);
                        break;
+               case HCLGE_MBX_GET_LINK_MODE:
+                       hclge_get_link_mode(vport, req);
+                       break;
                default:
                        dev_err(&hdev->pdev->dev,
                                "un-supported mailbox message, code = %d\n",
index bc2f29e67280cd35460b7057ec6255b851db9411..4a897cfb573b4581c3718a191264a54335aecac5 100644 (file)
@@ -381,6 +381,21 @@ void hclgevf_update_link_status(struct hclgevf_dev *hdev, int link_state)
        }
 }
 
+void hclgevf_update_link_mode(struct hclgevf_dev *hdev)
+{
+#define HCLGEVF_ADVERTISING 0
+#define HCLGEVF_SUPPORTED   1
+       u8 send_msg;
+       u8 resp_msg;
+
+       send_msg = HCLGEVF_ADVERTISING;
+       hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_LINK_MODE, 0, &send_msg,
+                            sizeof(u8), false, &resp_msg, sizeof(u8));
+       send_msg = HCLGEVF_SUPPORTED;
+       hclgevf_send_mbx_msg(hdev, HCLGE_MBX_GET_LINK_MODE, 0, &send_msg,
+                            sizeof(u8), false, &resp_msg, sizeof(u8));
+}
+
 static int hclgevf_set_handle_info(struct hclgevf_dev *hdev)
 {
        struct hnae3_handle *nic = &hdev->nic;
@@ -1646,6 +1661,8 @@ static void hclgevf_service_task(struct work_struct *work)
         */
        hclgevf_request_link_info(hdev);
 
+       hclgevf_update_link_mode(hdev);
+
        hclgevf_deferred_task_schedule(hdev);
 
        clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state);
@@ -1726,8 +1743,6 @@ static int hclgevf_configure(struct hclgevf_dev *hdev)
 {
        int ret;
 
-       hdev->hw.mac.media_type = HNAE3_MEDIA_TYPE_NONE;
-
        /* get queue configuration from PF */
        ret = hclgevf_get_queue_info(hdev);
        if (ret)
@@ -1880,6 +1895,8 @@ static int hclgevf_ae_start(struct hnae3_handle *handle)
 
        hclgevf_request_link_info(hdev);
 
+       hclgevf_update_link_mode(hdev);
+
        clear_bit(HCLGEVF_STATE_DOWN, &hdev->state);
 
        return 0;
@@ -2586,6 +2603,16 @@ static unsigned long hclgevf_ae_dev_reset_cnt(struct hnae3_handle *handle)
        return hdev->reset_count;
 }
 
+static void hclgevf_get_link_mode(struct hnae3_handle *handle,
+                                 unsigned long *supported,
+                                 unsigned long *advertising)
+{
+       struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
+
+       *supported = hdev->hw.mac.supported;
+       *advertising = hdev->hw.mac.advertising;
+}
+
 #define MAX_SEPARATE_NUM       4
 #define SEPARATOR_VALUE                0xFFFFFFFF
 #define REG_NUM_PER_LINE       4
@@ -2704,6 +2731,7 @@ static const struct hnae3_ae_ops hclgevf_ops = {
        .set_mtu = hclgevf_set_mtu,
        .get_global_queue_id = hclgevf_get_qid_global,
        .set_timer_task = hclgevf_set_timer_task,
+       .get_link_mode = hclgevf_get_link_mode,
 };
 
 static struct hnae3_ae_algo ae_algovf = {
index 787bc06944e5bf6eff5a53479e1e7bcac71e4503..eba1118a766da9df8c6b876907dba402309ab9ae 100644 (file)
@@ -145,6 +145,8 @@ struct hclgevf_mac {
        int link;
        u8 duplex;
        u32 speed;
+       u64 supported;
+       u64 advertising;
 };
 
 struct hclgevf_hw {
index 84653f58b2d1048cc6ff1e53382e46ba3812eea2..7dc3c9f79169f119e53fb44c8ed929611a217878 100644 (file)
@@ -197,6 +197,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
                        break;
                case HCLGE_MBX_LINK_STAT_CHANGE:
                case HCLGE_MBX_ASSERTING_RESET:
+               case HCLGE_MBX_LINK_STAT_MODE:
                        /* set this mbx event as pending. This is required as we
                         * might loose interrupt event when mbx task is busy
                         * handling. This shall be cleared when mbx task just
@@ -247,6 +248,7 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
        u8 duplex;
        u32 speed;
        u32 tail;
+       u8 idx;
 
        /* we can safely clear it now as we are at start of the async message
         * processing
@@ -270,12 +272,22 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
                        link_status = le16_to_cpu(msg_q[1]);
                        memcpy(&speed, &msg_q[2], sizeof(speed));
                        duplex = (u8)le16_to_cpu(msg_q[4]);
+                       hdev->hw.mac.media_type = (u8)le16_to_cpu(msg_q[5]);
 
                        /* update upper layer with new link link status */
                        hclgevf_update_link_status(hdev, link_status);
                        hclgevf_update_speed_duplex(hdev, speed, duplex);
 
                        break;
+               case HCLGE_MBX_LINK_STAT_MODE:
+                       idx = (u8)le16_to_cpu(msg_q[1]);
+                       if (idx)
+                               memcpy(&hdev->hw.mac.supported, &msg_q[2],
+                                      sizeof(unsigned long));
+                       else
+                               memcpy(&hdev->hw.mac.advertising, &msg_q[2],
+                                      sizeof(unsigned long));
+                       break;
                case HCLGE_MBX_ASSERTING_RESET:
                        /* PF has asserted reset hence VF should go in pending
                         * state and poll for the hardware reset status till it