Skip to content

Commit 92f11ea

Browse files
IronShendavem330
authored andcommitted
net: hns3: fix set port based VLAN issue for VF
In original codes, ndo_set_vf_vlan() in hns3 driver was implemented wrong. It adds or removes VLAN into VLAN filter for VF, but VF is unaware of it. This patch fixes it. When VF loads up, it firstly queries the port based VLAN state from PF. When user change port based VLAN state from PF, PF firstly checks whether the VF is alive. If the VF is alive, then PF notifies the VF the modification; otherwise PF configure the port based VLAN state directly. Fixes: 46a3df9 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support") Signed-off-by: Jian Shen <[email protected]> Signed-off-by: Huazhong Tan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 21e043c commit 92f11ea

File tree

7 files changed

+111
-9
lines changed

7 files changed

+111
-9
lines changed

drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ enum HCLGE_MBX_OPCODE {
4343
HCLGE_MBX_GET_QID_IN_PF, /* (VF -> PF) get queue id in pf */
4444
HCLGE_MBX_LINK_STAT_MODE, /* (PF -> VF) link mode has changed */
4545
HCLGE_MBX_GET_LINK_MODE, /* (VF -> PF) get the link mode of pf */
46+
HLCGE_MBX_PUSH_VLAN_INFO, /* (PF -> VF) push port base vlan */
4647
HCLGE_MBX_GET_MEDIA_TYPE, /* (VF -> PF) get media type */
4748

4849
HCLGE_MBX_GET_VF_FLR_STATUS = 200, /* (M7 -> PF) get vf reset status */
@@ -63,6 +64,8 @@ enum hclge_mbx_vlan_cfg_subcode {
6364
HCLGE_MBX_VLAN_FILTER = 0, /* set vlan filter */
6465
HCLGE_MBX_VLAN_TX_OFF_CFG, /* set tx side vlan offload */
6566
HCLGE_MBX_VLAN_RX_OFF_CFG, /* set rx side vlan offload */
67+
HCLGE_MBX_PORT_BASE_VLAN_CFG, /* set port based vlan configuration */
68+
HCLGE_MBX_GET_PORT_BASE_VLAN_STATE, /* get port based vlan state */
6669
};
6770

6871
#define HCLGE_MBX_MAX_MSG_SIZE 16

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7067,7 +7067,16 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
70677067
return ret;
70687068
}
70697069

7070-
return -EOPNOTSUPP;
7070+
if (!test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) {
7071+
return hclge_update_port_base_vlan_cfg(vport, state,
7072+
&vlan_info);
7073+
} else {
7074+
ret = hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
7075+
(u8)vfid, state,
7076+
vlan, qos,
7077+
ntohs(proto));
7078+
return ret;
7079+
}
70717080
}
70727081

70737082
int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,4 +941,7 @@ void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list);
941941
void hclge_uninit_vport_vlan_table(struct hclge_dev *hdev);
942942
int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state,
943943
struct hclge_vlan_info *vlan_info);
944+
int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid,
945+
u16 state, u16 vlan_tag, u16 qos,
946+
u16 vlan_proto);
944947
#endif

drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -289,9 +289,25 @@ static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport,
289289
return 0;
290290
}
291291

292+
int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid,
293+
u16 state, u16 vlan_tag, u16 qos,
294+
u16 vlan_proto)
295+
{
296+
#define MSG_DATA_SIZE 8
297+
298+
u8 msg_data[MSG_DATA_SIZE];
299+
300+
memcpy(&msg_data[0], &state, sizeof(u16));
301+
memcpy(&msg_data[2], &vlan_proto, sizeof(u16));
302+
memcpy(&msg_data[4], &qos, sizeof(u16));
303+
memcpy(&msg_data[6], &vlan_tag, sizeof(u16));
304+
305+
return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
306+
HLCGE_MBX_PUSH_VLAN_INFO, vfid);
307+
}
308+
292309
static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport,
293-
struct hclge_mbx_vf_to_pf_cmd *mbx_req,
294-
bool gen_resp)
310+
struct hclge_mbx_vf_to_pf_cmd *mbx_req)
295311
{
296312
int status = 0;
297313

@@ -310,11 +326,22 @@ static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport,
310326
bool en = mbx_req->msg[2] ? true : false;
311327

312328
status = hclge_en_hw_strip_rxvtag(handle, en);
329+
} else if (mbx_req->msg[1] == HCLGE_MBX_PORT_BASE_VLAN_CFG) {
330+
struct hclge_vlan_info *vlan_info;
331+
u16 *state;
332+
333+
state = (u16 *)&mbx_req->msg[2];
334+
vlan_info = (struct hclge_vlan_info *)&mbx_req->msg[4];
335+
status = hclge_update_port_base_vlan_cfg(vport, *state,
336+
vlan_info);
337+
} else if (mbx_req->msg[1] == HCLGE_MBX_GET_PORT_BASE_VLAN_STATE) {
338+
u8 state;
339+
340+
state = vport->port_base_vlan_cfg.state;
341+
status = hclge_gen_resp_to_vf(vport, mbx_req, 0, &state,
342+
sizeof(u8));
313343
}
314344

315-
if (gen_resp)
316-
status = hclge_gen_resp_to_vf(vport, mbx_req, status, NULL, 0);
317-
318345
return status;
319346
}
320347

@@ -584,7 +611,7 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
584611
ret);
585612
break;
586613
case HCLGE_MBX_SET_VLAN:
587-
ret = hclge_set_vf_vlan_cfg(vport, req, false);
614+
ret = hclge_set_vf_vlan_cfg(vport, req);
588615
if (ret)
589616
dev_err(&hdev->pdev->dev,
590617
"PF failed(%d) to config VF's VLAN\n",

drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,27 @@ static int hclgevf_get_tc_info(struct hclgevf_dev *hdev)
245245
return 0;
246246
}
247247

248+
static int hclgevf_get_port_base_vlan_filter_state(struct hclgevf_dev *hdev)
249+
{
250+
struct hnae3_handle *nic = &hdev->nic;
251+
u8 resp_msg;
252+
int ret;
253+
254+
ret = hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN,
255+
HCLGE_MBX_GET_PORT_BASE_VLAN_STATE,
256+
NULL, 0, true, &resp_msg, sizeof(u8));
257+
if (ret) {
258+
dev_err(&hdev->pdev->dev,
259+
"VF request to get port based vlan state failed %d",
260+
ret);
261+
return ret;
262+
}
263+
264+
nic->port_base_vlan_state = resp_msg;
265+
266+
return 0;
267+
}
268+
248269
static int hclgevf_get_queue_info(struct hclgevf_dev *hdev)
249270
{
250271
#define HCLGEVF_TQPS_RSS_INFO_LEN 6
@@ -1834,6 +1855,11 @@ static int hclgevf_configure(struct hclgevf_dev *hdev)
18341855
{
18351856
int ret;
18361857

1858+
/* get current port based vlan state from PF */
1859+
ret = hclgevf_get_port_base_vlan_filter_state(hdev);
1860+
if (ret)
1861+
return ret;
1862+
18371863
/* get queue configuration from PF */
18381864
ret = hclgevf_get_queue_info(hdev);
18391865
if (ret)
@@ -2790,6 +2816,31 @@ static void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
27902816
}
27912817
}
27922818

2819+
void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state,
2820+
u8 *port_base_vlan_info, u8 data_size)
2821+
{
2822+
struct hnae3_handle *nic = &hdev->nic;
2823+
2824+
rtnl_lock();
2825+
hclgevf_notify_client(hdev, HNAE3_DOWN_CLIENT);
2826+
rtnl_unlock();
2827+
2828+
/* send msg to PF and wait update port based vlan info */
2829+
hclgevf_send_mbx_msg(hdev, HCLGE_MBX_SET_VLAN,
2830+
HCLGE_MBX_PORT_BASE_VLAN_CFG,
2831+
port_base_vlan_info, data_size,
2832+
false, NULL, 0);
2833+
2834+
if (state == HNAE3_PORT_BASE_VLAN_DISABLE)
2835+
nic->port_base_vlan_state = HNAE3_PORT_BASE_VLAN_DISABLE;
2836+
else
2837+
nic->port_base_vlan_state = HNAE3_PORT_BASE_VLAN_ENABLE;
2838+
2839+
rtnl_lock();
2840+
hclgevf_notify_client(hdev, HNAE3_UP_CLIENT);
2841+
rtnl_unlock();
2842+
}
2843+
27932844
static const struct hnae3_ae_ops hclgevf_ops = {
27942845
.init_ae_dev = hclgevf_init_ae_dev,
27952846
.uninit_ae_dev = hclgevf_uninit_ae_dev,

drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,4 +290,6 @@ void hclgevf_update_speed_duplex(struct hclgevf_dev *hdev, u32 speed,
290290
u8 duplex);
291291
void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev);
292292
void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev);
293+
void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state,
294+
u8 *port_base_vlan_info, u8 data_size);
293295
#endif

drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
198198
case HCLGE_MBX_LINK_STAT_CHANGE:
199199
case HCLGE_MBX_ASSERTING_RESET:
200200
case HCLGE_MBX_LINK_STAT_MODE:
201+
case HLCGE_MBX_PUSH_VLAN_INFO:
201202
/* set this mbx event as pending. This is required as we
202203
* might loose interrupt event when mbx task is busy
203204
* handling. This shall be cleared when mbx task just
@@ -243,8 +244,8 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
243244
void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
244245
{
245246
enum hnae3_reset_type reset_type;
246-
u16 link_status;
247-
u16 *msg_q;
247+
u16 link_status, state;
248+
u16 *msg_q, *vlan_info;
248249
u8 duplex;
249250
u32 speed;
250251
u32 tail;
@@ -299,6 +300,12 @@ void hclgevf_mbx_async_handler(struct hclgevf_dev *hdev)
299300
hclgevf_reset_task_schedule(hdev);
300301

301302
break;
303+
case HLCGE_MBX_PUSH_VLAN_INFO:
304+
state = le16_to_cpu(msg_q[1]);
305+
vlan_info = &msg_q[1];
306+
hclgevf_update_port_base_vlan_info(hdev, state,
307+
(u8 *)vlan_info, 8);
308+
break;
302309
default:
303310
dev_err(&hdev->pdev->dev,
304311
"fetched unsupported(%d) message from arq\n",

0 commit comments

Comments
 (0)