Skip to content

Commit

Permalink
net: hns3: add byte order conversion for PF to VF mailbox message
Browse files Browse the repository at this point in the history
Currently, hns3 mailbox processing between PF and VF missed to convert
message byte order and use data type u16 instead of __le16 for mailbox
data process. These processes may cause problems between different
architectures.

So this patch uses __le16/__le32 data type to define mailbox data
structures. To be compatible with old hns3 driver, these structures use
one-byte alignment. Then byte order conversions are added to mailbox
messages from PF to VF.

Signed-off-by: Jie Wang <wangjie125@huawei.com>
Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jie Wang authored and David S. Miller committed May 9, 2022
1 parent bbed702 commit 767975e
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 77 deletions.
36 changes: 29 additions & 7 deletions drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,13 @@ struct hclge_vf_to_pf_msg {
};

struct hclge_pf_to_vf_msg {
u16 code;
__le16 code;
union {
/* used for mbx response */
struct {
u16 vf_mbx_msg_code;
u16 vf_mbx_msg_subcode;
u16 resp_status;
__le16 vf_mbx_msg_code;
__le16 vf_mbx_msg_subcode;
__le16 resp_status;
u8 resp_data[HCLGE_MBX_MAX_RESP_DATA_SIZE];
};
/* used for general mbx */
Expand All @@ -157,7 +157,7 @@ struct hclge_mbx_vf_to_pf_cmd {
u8 rsv1[1];
u8 msg_len;
u8 rsv2;
u16 match_id;
__le16 match_id;
struct hclge_vf_to_pf_msg msg;
};

Expand All @@ -168,7 +168,7 @@ struct hclge_mbx_pf_to_vf_cmd {
u8 rsv[3];
u8 msg_len;
u8 rsv1;
u16 match_id;
__le16 match_id;
struct hclge_pf_to_vf_msg msg;
};

Expand All @@ -178,6 +178,28 @@ struct hclge_vf_rst_cmd {
u8 rsv[22];
};

#pragma pack(1)
struct hclge_mbx_link_status {
__le16 link_status;
__le32 speed;
__le16 duplex;
u8 flag;
};

struct hclge_mbx_link_mode {
__le16 idx;
__le64 link_mode;
};

struct hclge_mbx_port_base_vlan {
__le16 state;
__le16 vlan_proto;
__le16 qos;
__le16 vlan_tag;
};

#pragma pack()

/* used by VF to store the received Async responses from PF */
struct hclgevf_mbx_arq_ring {
#define HCLGE_MBX_MAX_ARQ_MSG_SIZE 8
Expand All @@ -186,7 +208,7 @@ struct hclgevf_mbx_arq_ring {
u32 head;
u32 tail;
atomic_t count;
u16 msg_q[HCLGE_MBX_MAX_ARQ_MSG_NUM][HCLGE_MBX_MAX_ARQ_MSG_SIZE];
__le16 msg_q[HCLGE_MBX_MAX_ARQ_MSG_NUM][HCLGE_MBX_MAX_ARQ_MSG_SIZE];
};

#define hclge_mbx_ring_ptr_move_crq(crq) \
Expand Down
60 changes: 29 additions & 31 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,19 @@ static int hclge_gen_resp_to_vf(struct hclge_vport *vport,
resp_pf_to_vf->msg_len = vf_to_pf_req->msg_len;
resp_pf_to_vf->match_id = vf_to_pf_req->match_id;

resp_pf_to_vf->msg.code = HCLGE_MBX_PF_VF_RESP;
resp_pf_to_vf->msg.vf_mbx_msg_code = vf_to_pf_req->msg.code;
resp_pf_to_vf->msg.vf_mbx_msg_subcode = vf_to_pf_req->msg.subcode;
resp_pf_to_vf->msg.code = cpu_to_le16(HCLGE_MBX_PF_VF_RESP);
resp_pf_to_vf->msg.vf_mbx_msg_code =
cpu_to_le16(vf_to_pf_req->msg.code);
resp_pf_to_vf->msg.vf_mbx_msg_subcode =
cpu_to_le16(vf_to_pf_req->msg.subcode);
resp = hclge_errno_to_resp(resp_msg->status);
if (resp < SHRT_MAX) {
resp_pf_to_vf->msg.resp_status = resp;
resp_pf_to_vf->msg.resp_status = cpu_to_le16(resp);
} else {
dev_warn(&hdev->pdev->dev,
"failed to send response to VF, response status %u is out-of-bound\n",
resp);
resp_pf_to_vf->msg.resp_status = EIO;
resp_pf_to_vf->msg.resp_status = cpu_to_le16(EIO);
}

if (resp_msg->len > 0)
Expand Down Expand Up @@ -107,7 +109,7 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len,

resp_pf_to_vf->dest_vfid = dest_vfid;
resp_pf_to_vf->msg_len = msg_len;
resp_pf_to_vf->msg.code = mbx_opcode;
resp_pf_to_vf->msg.code = cpu_to_le16(mbx_opcode);

memcpy(resp_pf_to_vf->msg.msg_data, msg, msg_len);

Expand All @@ -125,8 +127,8 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len,
int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
{
struct hclge_dev *hdev = vport->back;
__le16 msg_data;
u16 reset_type;
u8 msg_data[2];
u8 dest_vfid;

BUILD_BUG_ON(HNAE3_MAX_RESET > U16_MAX);
Expand All @@ -140,10 +142,10 @@ int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport)
else
reset_type = HNAE3_VF_FUNC_RESET;

memcpy(&msg_data[0], &reset_type, sizeof(u16));
msg_data = cpu_to_le16(reset_type);

/* send this requested info to VF */
return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
return hclge_send_mbx_msg(vport, (u8 *)&msg_data, sizeof(msg_data),
HCLGE_MBX_ASSERTING_RESET, dest_vfid);
}

Expand Down Expand Up @@ -339,16 +341,14 @@ int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid,
u16 state,
struct hclge_vlan_info *vlan_info)
{
#define MSG_DATA_SIZE 8
struct hclge_mbx_port_base_vlan base_vlan;

u8 msg_data[MSG_DATA_SIZE];
base_vlan.state = cpu_to_le16(state);
base_vlan.vlan_proto = cpu_to_le16(vlan_info->vlan_proto);
base_vlan.qos = cpu_to_le16(vlan_info->qos);
base_vlan.vlan_tag = cpu_to_le16(vlan_info->vlan_tag);

memcpy(&msg_data[0], &state, sizeof(u16));
memcpy(&msg_data[2], &vlan_info->vlan_proto, sizeof(u16));
memcpy(&msg_data[4], &vlan_info->qos, sizeof(u16));
memcpy(&msg_data[6], &vlan_info->vlan_tag, sizeof(u16));

return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
return hclge_send_mbx_msg(vport, (u8 *)&base_vlan, sizeof(base_vlan),
HCLGE_MBX_PUSH_VLAN_INFO, vfid);
}

Expand Down Expand Up @@ -488,10 +488,9 @@ int hclge_push_vf_link_status(struct hclge_vport *vport)
#define HCLGE_VF_LINK_STATE_UP 1U
#define HCLGE_VF_LINK_STATE_DOWN 0U

struct hclge_mbx_link_status link_info;
struct hclge_dev *hdev = vport->back;
u16 link_status;
u8 msg_data[9];
u16 duplex;

/* mac.link can only be 0 or 1 */
switch (vport->vf_info.link_state) {
Expand All @@ -507,37 +506,36 @@ int hclge_push_vf_link_status(struct hclge_vport *vport)
break;
}

duplex = hdev->hw.mac.duplex;
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));
msg_data[8] = HCLGE_MBX_PUSH_LINK_STATUS_EN;
link_info.link_status = cpu_to_le16(link_status);
link_info.speed = cpu_to_le32(hdev->hw.mac.speed);
link_info.duplex = cpu_to_le16(hdev->hw.mac.duplex);
link_info.flag = HCLGE_MBX_PUSH_LINK_STATUS_EN;

/* send this requested info to VF */
return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
return hclge_send_mbx_msg(vport, (u8 *)&link_info, sizeof(link_info),
HCLGE_MBX_LINK_STAT_CHANGE, vport->vport_id);
}

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_mbx_link_mode link_mode;
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.data[0];

send_data = msg_data[0] == HCLGE_SUPPORTED ? supported : advertising;
send_data = mbx_req->msg.data[0] == HCLGE_SUPPORTED ? supported :
advertising;
link_mode.idx = cpu_to_le16((u16)mbx_req->msg.data[0]);
link_mode.link_mode = cpu_to_le64(send_data);

memcpy(&msg_data[2], &send_data, sizeof(unsigned long));
hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
hclge_send_mbx_msg(vport, (u8 *)&link_mode, sizeof(link_mode),
HCLGE_MBX_LINK_STAT_MODE, dest_vfid);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ TRACE_EVENT(hclge_pf_mbx_send,

TP_fast_assign(
__entry->vfid = req->dest_vfid;
__entry->code = req->msg.code;
__entry->code = le16_to_cpu(req->msg.code);
__assign_str(pciname, pci_name(hdev->pdev));
__assign_str(devname, &hdev->vport[0].nic.kinfo.netdev->name);
memcpy(__entry->mbx_data, req,
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3333,7 +3333,7 @@ static void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
}

void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state,
u8 *port_base_vlan_info, u8 data_size)
struct hclge_mbx_port_base_vlan *port_base_vlan)
{
struct hnae3_handle *nic = &hdev->nic;
struct hclge_vf_to_pf_msg send_msg;
Expand All @@ -3358,7 +3358,7 @@ void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state,
/* send msg to PF and wait update port based vlan info */
hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN,
HCLGE_MBX_PORT_BASE_VLAN_CFG);
memcpy(send_msg.data, port_base_vlan_info, data_size);
memcpy(send_msg.data, port_base_vlan, sizeof(*port_base_vlan));
ret = hclgevf_send_mbx_msg(hdev, &send_msg, false, NULL, 0);
if (!ret) {
if (state == HNAE3_PORT_BASE_VLAN_DISABLE)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,5 +293,5 @@ void hclgevf_update_speed_duplex(struct hclgevf_dev *hdev, u32 speed,
void hclgevf_reset_task_schedule(struct hclgevf_dev *hdev);
void hclgevf_mbx_task_schedule(struct hclgevf_dev *hdev);
void hclgevf_update_port_base_vlan_info(struct hclgevf_dev *hdev, u16 state,
u8 *port_base_vlan_info, u8 data_size);
struct hclge_mbx_port_base_vlan *port_base_vlan);
#endif
Loading

0 comments on commit 767975e

Please sign in to comment.