| .. | .. |
|---|
| 5 | 5 | #include "hclge_mbx.h" |
|---|
| 6 | 6 | #include "hnae3.h" |
|---|
| 7 | 7 | |
|---|
| 8 | +#define CREATE_TRACE_POINTS |
|---|
| 9 | +#include "hclge_trace.h" |
|---|
| 10 | + |
|---|
| 11 | +static u16 hclge_errno_to_resp(int errno) |
|---|
| 12 | +{ |
|---|
| 13 | + int resp = abs(errno); |
|---|
| 14 | + |
|---|
| 15 | + /* The status for pf to vf msg cmd is u16, constrainted by HW. |
|---|
| 16 | + * We need to keep the same type with it. |
|---|
| 17 | + * The intput errno is the stander error code, it's safely to |
|---|
| 18 | + * use a u16 to store the abs(errno). |
|---|
| 19 | + */ |
|---|
| 20 | + return (u16)resp; |
|---|
| 21 | +} |
|---|
| 22 | + |
|---|
| 8 | 23 | /* hclge_gen_resp_to_vf: used to generate a synchronous response to VF when PF |
|---|
| 9 | 24 | * receives a mailbox message from VF. |
|---|
| 10 | 25 | * @vport: pointer to struct hclge_vport |
|---|
| .. | .. |
|---|
| 14 | 29 | */ |
|---|
| 15 | 30 | static int hclge_gen_resp_to_vf(struct hclge_vport *vport, |
|---|
| 16 | 31 | struct hclge_mbx_vf_to_pf_cmd *vf_to_pf_req, |
|---|
| 17 | | - int resp_status, |
|---|
| 18 | | - u8 *resp_data, u16 resp_data_len) |
|---|
| 32 | + struct hclge_respond_to_vf_msg *resp_msg) |
|---|
| 19 | 33 | { |
|---|
| 20 | 34 | struct hclge_mbx_pf_to_vf_cmd *resp_pf_to_vf; |
|---|
| 21 | 35 | struct hclge_dev *hdev = vport->back; |
|---|
| 22 | 36 | enum hclge_cmd_status status; |
|---|
| 23 | 37 | struct hclge_desc desc; |
|---|
| 38 | + u16 resp; |
|---|
| 24 | 39 | |
|---|
| 25 | 40 | resp_pf_to_vf = (struct hclge_mbx_pf_to_vf_cmd *)desc.data; |
|---|
| 26 | 41 | |
|---|
| 27 | | - if (resp_data_len > HCLGE_MBX_MAX_RESP_DATA_SIZE) { |
|---|
| 42 | + if (resp_msg->len > HCLGE_MBX_MAX_RESP_DATA_SIZE) { |
|---|
| 28 | 43 | dev_err(&hdev->pdev->dev, |
|---|
| 29 | | - "PF fail to gen resp to VF len %d exceeds max len %d\n", |
|---|
| 30 | | - resp_data_len, |
|---|
| 44 | + "PF fail to gen resp to VF len %u exceeds max len %u\n", |
|---|
| 45 | + resp_msg->len, |
|---|
| 31 | 46 | HCLGE_MBX_MAX_RESP_DATA_SIZE); |
|---|
| 47 | + /* If resp_msg->len is too long, set the value to max length |
|---|
| 48 | + * and return the msg to VF |
|---|
| 49 | + */ |
|---|
| 50 | + resp_msg->len = HCLGE_MBX_MAX_RESP_DATA_SIZE; |
|---|
| 32 | 51 | } |
|---|
| 33 | 52 | |
|---|
| 34 | 53 | hclge_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_PF_TO_VF, false); |
|---|
| 35 | 54 | |
|---|
| 36 | 55 | resp_pf_to_vf->dest_vfid = vf_to_pf_req->mbx_src_vfid; |
|---|
| 37 | 56 | resp_pf_to_vf->msg_len = vf_to_pf_req->msg_len; |
|---|
| 57 | + resp_pf_to_vf->match_id = vf_to_pf_req->match_id; |
|---|
| 38 | 58 | |
|---|
| 39 | | - resp_pf_to_vf->msg[0] = HCLGE_MBX_PF_VF_RESP; |
|---|
| 40 | | - resp_pf_to_vf->msg[1] = vf_to_pf_req->msg[0]; |
|---|
| 41 | | - resp_pf_to_vf->msg[2] = vf_to_pf_req->msg[1]; |
|---|
| 42 | | - resp_pf_to_vf->msg[3] = (resp_status == 0) ? 0 : 1; |
|---|
| 59 | + resp_pf_to_vf->msg.code = HCLGE_MBX_PF_VF_RESP; |
|---|
| 60 | + resp_pf_to_vf->msg.vf_mbx_msg_code = vf_to_pf_req->msg.code; |
|---|
| 61 | + resp_pf_to_vf->msg.vf_mbx_msg_subcode = vf_to_pf_req->msg.subcode; |
|---|
| 62 | + resp = hclge_errno_to_resp(resp_msg->status); |
|---|
| 63 | + if (resp < SHRT_MAX) { |
|---|
| 64 | + resp_pf_to_vf->msg.resp_status = resp; |
|---|
| 65 | + } else { |
|---|
| 66 | + dev_warn(&hdev->pdev->dev, |
|---|
| 67 | + "failed to send response to VF, response status %d is out-of-bound\n", |
|---|
| 68 | + resp); |
|---|
| 69 | + resp_pf_to_vf->msg.resp_status = EIO; |
|---|
| 70 | + } |
|---|
| 43 | 71 | |
|---|
| 44 | | - if (resp_data && resp_data_len > 0) |
|---|
| 45 | | - memcpy(&resp_pf_to_vf->msg[4], resp_data, resp_data_len); |
|---|
| 72 | + if (resp_msg->len > 0) |
|---|
| 73 | + memcpy(resp_pf_to_vf->msg.resp_data, resp_msg->data, |
|---|
| 74 | + resp_msg->len); |
|---|
| 46 | 75 | |
|---|
| 47 | 76 | status = hclge_cmd_send(&hdev->hw, &desc, 1); |
|---|
| 48 | 77 | if (status) |
|---|
| 49 | 78 | dev_err(&hdev->pdev->dev, |
|---|
| 50 | | - "PF failed(=%d) to send response to VF\n", status); |
|---|
| 79 | + "failed to send response to VF, status: %d, vfid: %u, code: %u, subcode: %u.\n", |
|---|
| 80 | + status, vf_to_pf_req->mbx_src_vfid, |
|---|
| 81 | + vf_to_pf_req->msg.code, vf_to_pf_req->msg.subcode); |
|---|
| 51 | 82 | |
|---|
| 52 | 83 | return status; |
|---|
| 53 | 84 | } |
|---|
| .. | .. |
|---|
| 60 | 91 | enum hclge_cmd_status status; |
|---|
| 61 | 92 | struct hclge_desc desc; |
|---|
| 62 | 93 | |
|---|
| 94 | + if (msg_len > HCLGE_MBX_MAX_MSG_SIZE) { |
|---|
| 95 | + dev_err(&hdev->pdev->dev, |
|---|
| 96 | + "msg data length(=%u) exceeds maximum(=%u)\n", |
|---|
| 97 | + msg_len, HCLGE_MBX_MAX_MSG_SIZE); |
|---|
| 98 | + return -EMSGSIZE; |
|---|
| 99 | + } |
|---|
| 100 | + |
|---|
| 63 | 101 | resp_pf_to_vf = (struct hclge_mbx_pf_to_vf_cmd *)desc.data; |
|---|
| 64 | 102 | |
|---|
| 65 | 103 | hclge_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_PF_TO_VF, false); |
|---|
| 66 | 104 | |
|---|
| 67 | 105 | resp_pf_to_vf->dest_vfid = dest_vfid; |
|---|
| 68 | 106 | resp_pf_to_vf->msg_len = msg_len; |
|---|
| 69 | | - resp_pf_to_vf->msg[0] = mbx_opcode; |
|---|
| 107 | + resp_pf_to_vf->msg.code = mbx_opcode; |
|---|
| 70 | 108 | |
|---|
| 71 | | - memcpy(&resp_pf_to_vf->msg[1], msg, msg_len); |
|---|
| 109 | + memcpy(&resp_pf_to_vf->msg.vf_mbx_msg_code, msg, msg_len); |
|---|
| 110 | + |
|---|
| 111 | + trace_hclge_pf_mbx_send(hdev, resp_pf_to_vf); |
|---|
| 72 | 112 | |
|---|
| 73 | 113 | status = hclge_cmd_send(&hdev->hw, &desc, 1); |
|---|
| 74 | 114 | if (status) |
|---|
| 75 | 115 | dev_err(&hdev->pdev->dev, |
|---|
| 76 | | - "PF failed(=%d) to send mailbox message to VF\n", |
|---|
| 77 | | - status); |
|---|
| 116 | + "failed to send mailbox to VF, status: %d, vfid: %u, opcode: %u\n", |
|---|
| 117 | + status, dest_vfid, mbx_opcode); |
|---|
| 78 | 118 | |
|---|
| 79 | 119 | return status; |
|---|
| 80 | 120 | } |
|---|
| 81 | 121 | |
|---|
| 82 | | -static int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport) |
|---|
| 122 | +int hclge_inform_reset_assert_to_vf(struct hclge_vport *vport) |
|---|
| 83 | 123 | { |
|---|
| 124 | + struct hclge_dev *hdev = vport->back; |
|---|
| 125 | + u16 reset_type; |
|---|
| 84 | 126 | u8 msg_data[2]; |
|---|
| 85 | 127 | u8 dest_vfid; |
|---|
| 86 | 128 | |
|---|
| 129 | + BUILD_BUG_ON(HNAE3_MAX_RESET > U16_MAX); |
|---|
| 130 | + |
|---|
| 87 | 131 | dest_vfid = (u8)vport->vport_id; |
|---|
| 88 | 132 | |
|---|
| 133 | + if (hdev->reset_type == HNAE3_FUNC_RESET) |
|---|
| 134 | + reset_type = HNAE3_VF_PF_FUNC_RESET; |
|---|
| 135 | + else if (hdev->reset_type == HNAE3_FLR_RESET) |
|---|
| 136 | + reset_type = HNAE3_VF_FULL_RESET; |
|---|
| 137 | + else |
|---|
| 138 | + reset_type = HNAE3_VF_FUNC_RESET; |
|---|
| 139 | + |
|---|
| 140 | + memcpy(&msg_data[0], &reset_type, sizeof(u16)); |
|---|
| 141 | + |
|---|
| 89 | 142 | /* send this requested info to VF */ |
|---|
| 90 | | - return hclge_send_mbx_msg(vport, msg_data, sizeof(u8), |
|---|
| 143 | + return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data), |
|---|
| 91 | 144 | HCLGE_MBX_ASSERTING_RESET, dest_vfid); |
|---|
| 92 | 145 | } |
|---|
| 93 | 146 | |
|---|
| .. | .. |
|---|
| 99 | 152 | |
|---|
| 100 | 153 | while (chain) { |
|---|
| 101 | 154 | chain_tmp = chain->next; |
|---|
| 102 | | - kzfree(chain); |
|---|
| 155 | + kfree_sensitive(chain); |
|---|
| 103 | 156 | chain = chain_tmp; |
|---|
| 104 | 157 | } |
|---|
| 105 | 158 | } |
|---|
| .. | .. |
|---|
| 120 | 173 | struct hclge_vport *vport) |
|---|
| 121 | 174 | { |
|---|
| 122 | 175 | struct hnae3_ring_chain_node *cur_chain, *new_chain; |
|---|
| 176 | + struct hclge_dev *hdev = vport->back; |
|---|
| 123 | 177 | int ring_num; |
|---|
| 124 | 178 | int i; |
|---|
| 125 | 179 | |
|---|
| 126 | | - ring_num = req->msg[2]; |
|---|
| 180 | + ring_num = req->msg.ring_num; |
|---|
| 127 | 181 | |
|---|
| 128 | | - if (ring_num > ((HCLGE_MBX_VF_MSG_DATA_NUM - |
|---|
| 129 | | - HCLGE_MBX_RING_MAP_BASIC_MSG_NUM) / |
|---|
| 130 | | - HCLGE_MBX_RING_NODE_VARIABLE_NUM)) |
|---|
| 131 | | - return -ENOMEM; |
|---|
| 182 | + if (ring_num > HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM) |
|---|
| 183 | + return -EINVAL; |
|---|
| 132 | 184 | |
|---|
| 133 | | - hnae3_set_bit(ring_chain->flag, HNAE3_RING_TYPE_B, req->msg[3]); |
|---|
| 185 | + for (i = 0; i < ring_num; i++) { |
|---|
| 186 | + if (req->msg.param[i].tqp_index >= vport->nic.kinfo.rss_size) { |
|---|
| 187 | + dev_err(&hdev->pdev->dev, "tqp index(%u) is out of range(0-%u)\n", |
|---|
| 188 | + req->msg.param[i].tqp_index, |
|---|
| 189 | + vport->nic.kinfo.rss_size - 1); |
|---|
| 190 | + return -EINVAL; |
|---|
| 191 | + } |
|---|
| 192 | + } |
|---|
| 193 | + |
|---|
| 194 | + hnae3_set_bit(ring_chain->flag, HNAE3_RING_TYPE_B, |
|---|
| 195 | + req->msg.param[0].ring_type); |
|---|
| 134 | 196 | ring_chain->tqp_index = |
|---|
| 135 | | - hclge_get_queue_id(vport->nic.kinfo.tqp[req->msg[4]]); |
|---|
| 197 | + hclge_get_queue_id(vport->nic.kinfo.tqp |
|---|
| 198 | + [req->msg.param[0].tqp_index]); |
|---|
| 136 | 199 | hnae3_set_field(ring_chain->int_gl_idx, HNAE3_RING_GL_IDX_M, |
|---|
| 137 | | - HNAE3_RING_GL_IDX_S, |
|---|
| 138 | | - req->msg[5]); |
|---|
| 200 | + HNAE3_RING_GL_IDX_S, req->msg.param[0].int_gl_index); |
|---|
| 139 | 201 | |
|---|
| 140 | 202 | cur_chain = ring_chain; |
|---|
| 141 | 203 | |
|---|
| .. | .. |
|---|
| 145 | 207 | goto err; |
|---|
| 146 | 208 | |
|---|
| 147 | 209 | hnae3_set_bit(new_chain->flag, HNAE3_RING_TYPE_B, |
|---|
| 148 | | - req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i + |
|---|
| 149 | | - HCLGE_MBX_RING_MAP_BASIC_MSG_NUM]); |
|---|
| 210 | + req->msg.param[i].ring_type); |
|---|
| 150 | 211 | |
|---|
| 151 | 212 | new_chain->tqp_index = |
|---|
| 152 | 213 | hclge_get_queue_id(vport->nic.kinfo.tqp |
|---|
| 153 | | - [req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i + |
|---|
| 154 | | - HCLGE_MBX_RING_MAP_BASIC_MSG_NUM + 1]]); |
|---|
| 214 | + [req->msg.param[i].tqp_index]); |
|---|
| 155 | 215 | |
|---|
| 156 | 216 | hnae3_set_field(new_chain->int_gl_idx, HNAE3_RING_GL_IDX_M, |
|---|
| 157 | 217 | HNAE3_RING_GL_IDX_S, |
|---|
| 158 | | - req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i + |
|---|
| 159 | | - HCLGE_MBX_RING_MAP_BASIC_MSG_NUM + 2]); |
|---|
| 218 | + req->msg.param[i].int_gl_index); |
|---|
| 160 | 219 | |
|---|
| 161 | 220 | cur_chain->next = new_chain; |
|---|
| 162 | 221 | cur_chain = new_chain; |
|---|
| .. | .. |
|---|
| 172 | 231 | struct hclge_mbx_vf_to_pf_cmd *req) |
|---|
| 173 | 232 | { |
|---|
| 174 | 233 | struct hnae3_ring_chain_node ring_chain; |
|---|
| 175 | | - int vector_id = req->msg[1]; |
|---|
| 234 | + int vector_id = req->msg.vector_id; |
|---|
| 176 | 235 | int ret; |
|---|
| 177 | 236 | |
|---|
| 178 | 237 | memset(&ring_chain, 0, sizeof(ring_chain)); |
|---|
| .. | .. |
|---|
| 190 | 249 | static int hclge_set_vf_promisc_mode(struct hclge_vport *vport, |
|---|
| 191 | 250 | struct hclge_mbx_vf_to_pf_cmd *req) |
|---|
| 192 | 251 | { |
|---|
| 193 | | - bool en_uc = req->msg[1] ? true : false; |
|---|
| 194 | | - bool en_mc = req->msg[2] ? true : false; |
|---|
| 195 | | - struct hclge_promisc_param param; |
|---|
| 196 | | - |
|---|
| 197 | | - /* always enable broadcast promisc bit */ |
|---|
| 198 | | - hclge_promisc_param_init(¶m, en_uc, en_mc, true, vport->vport_id); |
|---|
| 199 | | - return hclge_cmd_set_promisc_mode(vport->back, ¶m); |
|---|
| 200 | | -} |
|---|
| 201 | | - |
|---|
| 202 | | -static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport, |
|---|
| 203 | | - struct hclge_mbx_vf_to_pf_cmd *mbx_req, |
|---|
| 204 | | - bool gen_resp) |
|---|
| 205 | | -{ |
|---|
| 206 | | - const u8 *mac_addr = (const u8 *)(&mbx_req->msg[2]); |
|---|
| 207 | | - struct hclge_dev *hdev = vport->back; |
|---|
| 208 | | - int status; |
|---|
| 209 | | - |
|---|
| 210 | | - if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_MODIFY) { |
|---|
| 211 | | - const u8 *old_addr = (const u8 *)(&mbx_req->msg[8]); |
|---|
| 212 | | - |
|---|
| 213 | | - hclge_rm_uc_addr_common(vport, old_addr); |
|---|
| 214 | | - status = hclge_add_uc_addr_common(vport, mac_addr); |
|---|
| 215 | | - if (status) |
|---|
| 216 | | - hclge_add_uc_addr_common(vport, old_addr); |
|---|
| 217 | | - } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_ADD) { |
|---|
| 218 | | - status = hclge_add_uc_addr_common(vport, mac_addr); |
|---|
| 219 | | - } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_UC_REMOVE) { |
|---|
| 220 | | - status = hclge_rm_uc_addr_common(vport, mac_addr); |
|---|
| 221 | | - } else { |
|---|
| 222 | | - dev_err(&hdev->pdev->dev, |
|---|
| 223 | | - "failed to set unicast mac addr, unknown subcode %d\n", |
|---|
| 224 | | - mbx_req->msg[1]); |
|---|
| 225 | | - return -EIO; |
|---|
| 226 | | - } |
|---|
| 227 | | - |
|---|
| 228 | | - if (gen_resp) |
|---|
| 229 | | - hclge_gen_resp_to_vf(vport, mbx_req, status, NULL, 0); |
|---|
| 230 | | - |
|---|
| 231 | | - return 0; |
|---|
| 232 | | -} |
|---|
| 233 | | - |
|---|
| 234 | | -static int hclge_set_vf_mc_mta_status(struct hclge_vport *vport, |
|---|
| 235 | | - u8 *msg, u8 idx, bool is_end) |
|---|
| 236 | | -{ |
|---|
| 237 | | -#define HCLGE_MTA_STATUS_MSG_SIZE 13 |
|---|
| 238 | | -#define HCLGE_MTA_STATUS_MSG_BITS \ |
|---|
| 239 | | - (HCLGE_MTA_STATUS_MSG_SIZE * BITS_PER_BYTE) |
|---|
| 240 | | -#define HCLGE_MTA_STATUS_MSG_END_BITS \ |
|---|
| 241 | | - (HCLGE_MTA_TBL_SIZE % HCLGE_MTA_STATUS_MSG_BITS) |
|---|
| 242 | | - unsigned long status[BITS_TO_LONGS(HCLGE_MTA_STATUS_MSG_BITS)]; |
|---|
| 243 | | - u16 tbl_cnt; |
|---|
| 244 | | - u16 tbl_idx; |
|---|
| 245 | | - u8 msg_ofs; |
|---|
| 246 | | - u8 msg_bit; |
|---|
| 247 | | - |
|---|
| 248 | | - tbl_cnt = is_end ? HCLGE_MTA_STATUS_MSG_END_BITS : |
|---|
| 249 | | - HCLGE_MTA_STATUS_MSG_BITS; |
|---|
| 250 | | - |
|---|
| 251 | | - /* set msg field */ |
|---|
| 252 | | - msg_ofs = 0; |
|---|
| 253 | | - msg_bit = 0; |
|---|
| 254 | | - memset(status, 0, sizeof(status)); |
|---|
| 255 | | - for (tbl_idx = 0; tbl_idx < tbl_cnt; tbl_idx++) { |
|---|
| 256 | | - if (msg[msg_ofs] & BIT(msg_bit)) |
|---|
| 257 | | - set_bit(tbl_idx, status); |
|---|
| 258 | | - |
|---|
| 259 | | - msg_bit++; |
|---|
| 260 | | - if (msg_bit == BITS_PER_BYTE) { |
|---|
| 261 | | - msg_bit = 0; |
|---|
| 262 | | - msg_ofs++; |
|---|
| 263 | | - } |
|---|
| 264 | | - } |
|---|
| 265 | | - |
|---|
| 266 | | - return hclge_update_mta_status_common(vport, |
|---|
| 267 | | - status, idx * HCLGE_MTA_STATUS_MSG_BITS, |
|---|
| 268 | | - tbl_cnt, is_end); |
|---|
| 269 | | -} |
|---|
| 270 | | - |
|---|
| 271 | | -static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport, |
|---|
| 272 | | - struct hclge_mbx_vf_to_pf_cmd *mbx_req, |
|---|
| 273 | | - bool gen_resp) |
|---|
| 274 | | -{ |
|---|
| 275 | | - const u8 *mac_addr = (const u8 *)(&mbx_req->msg[2]); |
|---|
| 276 | | - struct hclge_dev *hdev = vport->back; |
|---|
| 277 | | - u8 resp_len = 0; |
|---|
| 278 | | - u8 resp_data; |
|---|
| 279 | | - int status; |
|---|
| 280 | | - |
|---|
| 281 | | - if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MC_ADD) { |
|---|
| 282 | | - status = hclge_add_mc_addr_common(vport, mac_addr); |
|---|
| 283 | | - } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MC_REMOVE) { |
|---|
| 284 | | - status = hclge_rm_mc_addr_common(vport, mac_addr); |
|---|
| 285 | | - } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MC_FUNC_MTA_ENABLE) { |
|---|
| 286 | | - u8 func_id = vport->vport_id; |
|---|
| 287 | | - bool enable = mbx_req->msg[2]; |
|---|
| 288 | | - |
|---|
| 289 | | - status = hclge_cfg_func_mta_filter(hdev, func_id, enable); |
|---|
| 290 | | - } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MTA_TYPE_READ) { |
|---|
| 291 | | - resp_data = hdev->mta_mac_sel_type; |
|---|
| 292 | | - resp_len = sizeof(u8); |
|---|
| 293 | | - gen_resp = true; |
|---|
| 294 | | - status = 0; |
|---|
| 295 | | - } else if (mbx_req->msg[1] == HCLGE_MBX_MAC_VLAN_MTA_STATUS_UPDATE) { |
|---|
| 296 | | - /* mta status update msg format |
|---|
| 297 | | - * msg[2.6 : 2.0] msg index |
|---|
| 298 | | - * msg[2.7] msg is end |
|---|
| 299 | | - * msg[15 : 3] mta status bits[103 : 0] |
|---|
| 300 | | - */ |
|---|
| 301 | | - bool is_end = (mbx_req->msg[2] & 0x80) ? true : false; |
|---|
| 302 | | - |
|---|
| 303 | | - status = hclge_set_vf_mc_mta_status(vport, &mbx_req->msg[3], |
|---|
| 304 | | - mbx_req->msg[2] & 0x7F, |
|---|
| 305 | | - is_end); |
|---|
| 306 | | - } else { |
|---|
| 307 | | - dev_err(&hdev->pdev->dev, |
|---|
| 308 | | - "failed to set mcast mac addr, unknown subcode %d\n", |
|---|
| 309 | | - mbx_req->msg[1]); |
|---|
| 310 | | - return -EIO; |
|---|
| 311 | | - } |
|---|
| 312 | | - |
|---|
| 313 | | - if (gen_resp) |
|---|
| 314 | | - hclge_gen_resp_to_vf(vport, mbx_req, status, |
|---|
| 315 | | - &resp_data, resp_len); |
|---|
| 316 | | - |
|---|
| 317 | | - return 0; |
|---|
| 318 | | -} |
|---|
| 319 | | - |
|---|
| 320 | | -static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport, |
|---|
| 321 | | - struct hclge_mbx_vf_to_pf_cmd *mbx_req, |
|---|
| 322 | | - bool gen_resp) |
|---|
| 323 | | -{ |
|---|
| 324 | | - int status = 0; |
|---|
| 325 | | - |
|---|
| 326 | | - if (mbx_req->msg[1] == HCLGE_MBX_VLAN_FILTER) { |
|---|
| 327 | | - struct hnae3_handle *handle = &vport->nic; |
|---|
| 328 | | - u16 vlan, proto; |
|---|
| 329 | | - bool is_kill; |
|---|
| 330 | | - |
|---|
| 331 | | - is_kill = !!mbx_req->msg[2]; |
|---|
| 332 | | - memcpy(&vlan, &mbx_req->msg[3], sizeof(vlan)); |
|---|
| 333 | | - memcpy(&proto, &mbx_req->msg[5], sizeof(proto)); |
|---|
| 334 | | - status = hclge_set_vlan_filter(handle, cpu_to_be16(proto), |
|---|
| 335 | | - vlan, is_kill); |
|---|
| 336 | | - } else if (mbx_req->msg[1] == HCLGE_MBX_VLAN_RX_OFF_CFG) { |
|---|
| 337 | | - struct hnae3_handle *handle = &vport->nic; |
|---|
| 338 | | - bool en = mbx_req->msg[2] ? true : false; |
|---|
| 339 | | - |
|---|
| 340 | | - status = hclge_en_hw_strip_rxvtag(handle, en); |
|---|
| 341 | | - } |
|---|
| 342 | | - |
|---|
| 343 | | - if (gen_resp) |
|---|
| 344 | | - status = hclge_gen_resp_to_vf(vport, mbx_req, status, NULL, 0); |
|---|
| 345 | | - |
|---|
| 346 | | - return status; |
|---|
| 347 | | -} |
|---|
| 348 | | - |
|---|
| 349 | | -static int hclge_get_vf_tcinfo(struct hclge_vport *vport, |
|---|
| 350 | | - struct hclge_mbx_vf_to_pf_cmd *mbx_req, |
|---|
| 351 | | - bool gen_resp) |
|---|
| 352 | | -{ |
|---|
| 353 | | - struct hclge_dev *hdev = vport->back; |
|---|
| 252 | + bool en_bc = req->msg.en_bc ? true : false; |
|---|
| 253 | + bool en_uc = req->msg.en_uc ? true : false; |
|---|
| 254 | + bool en_mc = req->msg.en_mc ? true : false; |
|---|
| 354 | 255 | int ret; |
|---|
| 355 | 256 | |
|---|
| 356 | | - ret = hclge_gen_resp_to_vf(vport, mbx_req, 0, &hdev->hw_tc_map, |
|---|
| 357 | | - sizeof(u8)); |
|---|
| 257 | + if (!vport->vf_info.trusted) { |
|---|
| 258 | + en_uc = false; |
|---|
| 259 | + en_mc = false; |
|---|
| 260 | + } |
|---|
| 261 | + |
|---|
| 262 | + ret = hclge_set_vport_promisc_mode(vport, en_uc, en_mc, en_bc); |
|---|
| 263 | + |
|---|
| 264 | + vport->vf_info.promisc_enable = (en_uc || en_mc) ? 1 : 0; |
|---|
| 358 | 265 | |
|---|
| 359 | 266 | return ret; |
|---|
| 360 | 267 | } |
|---|
| 361 | 268 | |
|---|
| 362 | | -static int hclge_get_vf_queue_info(struct hclge_vport *vport, |
|---|
| 363 | | - struct hclge_mbx_vf_to_pf_cmd *mbx_req, |
|---|
| 364 | | - bool gen_resp) |
|---|
| 269 | +void hclge_inform_vf_promisc_info(struct hclge_vport *vport) |
|---|
| 365 | 270 | { |
|---|
| 366 | | -#define HCLGE_TQPS_RSS_INFO_LEN 8 |
|---|
| 367 | | - u8 resp_data[HCLGE_TQPS_RSS_INFO_LEN]; |
|---|
| 271 | + u8 dest_vfid = (u8)vport->vport_id; |
|---|
| 272 | + u8 msg_data[2]; |
|---|
| 273 | + |
|---|
| 274 | + memcpy(&msg_data[0], &vport->vf_info.promisc_enable, sizeof(u16)); |
|---|
| 275 | + |
|---|
| 276 | + hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data), |
|---|
| 277 | + HCLGE_MBX_PUSH_PROMISC_INFO, dest_vfid); |
|---|
| 278 | +} |
|---|
| 279 | + |
|---|
| 280 | +static int hclge_set_vf_uc_mac_addr(struct hclge_vport *vport, |
|---|
| 281 | + struct hclge_mbx_vf_to_pf_cmd *mbx_req) |
|---|
| 282 | +{ |
|---|
| 283 | +#define HCLGE_MBX_VF_OLD_MAC_ADDR_OFFSET 6 |
|---|
| 284 | + |
|---|
| 285 | + const u8 *mac_addr = (const u8 *)(mbx_req->msg.data); |
|---|
| 286 | + struct hclge_dev *hdev = vport->back; |
|---|
| 287 | + int status; |
|---|
| 288 | + |
|---|
| 289 | + if (mbx_req->msg.subcode == HCLGE_MBX_MAC_VLAN_UC_MODIFY) { |
|---|
| 290 | + const u8 *old_addr = (const u8 *) |
|---|
| 291 | + (&mbx_req->msg.data[HCLGE_MBX_VF_OLD_MAC_ADDR_OFFSET]); |
|---|
| 292 | + |
|---|
| 293 | + /* If VF MAC has been configured by the host then it |
|---|
| 294 | + * cannot be overridden by the MAC specified by the VM. |
|---|
| 295 | + */ |
|---|
| 296 | + if (!is_zero_ether_addr(vport->vf_info.mac) && |
|---|
| 297 | + !ether_addr_equal(mac_addr, vport->vf_info.mac)) |
|---|
| 298 | + return -EPERM; |
|---|
| 299 | + |
|---|
| 300 | + if (!is_valid_ether_addr(mac_addr)) |
|---|
| 301 | + return -EINVAL; |
|---|
| 302 | + |
|---|
| 303 | + spin_lock_bh(&vport->mac_list_lock); |
|---|
| 304 | + status = hclge_update_mac_node_for_dev_addr(vport, old_addr, |
|---|
| 305 | + mac_addr); |
|---|
| 306 | + spin_unlock_bh(&vport->mac_list_lock); |
|---|
| 307 | + hclge_task_schedule(hdev, 0); |
|---|
| 308 | + } else if (mbx_req->msg.subcode == HCLGE_MBX_MAC_VLAN_UC_ADD) { |
|---|
| 309 | + status = hclge_update_mac_list(vport, HCLGE_MAC_TO_ADD, |
|---|
| 310 | + HCLGE_MAC_ADDR_UC, mac_addr); |
|---|
| 311 | + } else if (mbx_req->msg.subcode == HCLGE_MBX_MAC_VLAN_UC_REMOVE) { |
|---|
| 312 | + status = hclge_update_mac_list(vport, HCLGE_MAC_TO_DEL, |
|---|
| 313 | + HCLGE_MAC_ADDR_UC, mac_addr); |
|---|
| 314 | + } else { |
|---|
| 315 | + dev_err(&hdev->pdev->dev, |
|---|
| 316 | + "failed to set unicast mac addr, unknown subcode %u\n", |
|---|
| 317 | + mbx_req->msg.subcode); |
|---|
| 318 | + return -EIO; |
|---|
| 319 | + } |
|---|
| 320 | + |
|---|
| 321 | + return status; |
|---|
| 322 | +} |
|---|
| 323 | + |
|---|
| 324 | +static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport, |
|---|
| 325 | + struct hclge_mbx_vf_to_pf_cmd *mbx_req) |
|---|
| 326 | +{ |
|---|
| 327 | + const u8 *mac_addr = (const u8 *)(mbx_req->msg.data); |
|---|
| 328 | + struct hclge_dev *hdev = vport->back; |
|---|
| 329 | + |
|---|
| 330 | + if (mbx_req->msg.subcode == HCLGE_MBX_MAC_VLAN_MC_ADD) { |
|---|
| 331 | + hclge_update_mac_list(vport, HCLGE_MAC_TO_ADD, |
|---|
| 332 | + HCLGE_MAC_ADDR_MC, mac_addr); |
|---|
| 333 | + } else if (mbx_req->msg.subcode == HCLGE_MBX_MAC_VLAN_MC_REMOVE) { |
|---|
| 334 | + hclge_update_mac_list(vport, HCLGE_MAC_TO_DEL, |
|---|
| 335 | + HCLGE_MAC_ADDR_MC, mac_addr); |
|---|
| 336 | + } else { |
|---|
| 337 | + dev_err(&hdev->pdev->dev, |
|---|
| 338 | + "failed to set mcast mac addr, unknown subcode %u\n", |
|---|
| 339 | + mbx_req->msg.subcode); |
|---|
| 340 | + return -EIO; |
|---|
| 341 | + } |
|---|
| 342 | + |
|---|
| 343 | + return 0; |
|---|
| 344 | +} |
|---|
| 345 | + |
|---|
| 346 | +int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid, |
|---|
| 347 | + u16 state, u16 vlan_tag, u16 qos, |
|---|
| 348 | + u16 vlan_proto) |
|---|
| 349 | +{ |
|---|
| 350 | +#define MSG_DATA_SIZE 8 |
|---|
| 351 | + |
|---|
| 352 | + u8 msg_data[MSG_DATA_SIZE]; |
|---|
| 353 | + |
|---|
| 354 | + memcpy(&msg_data[0], &state, sizeof(u16)); |
|---|
| 355 | + memcpy(&msg_data[2], &vlan_proto, sizeof(u16)); |
|---|
| 356 | + memcpy(&msg_data[4], &qos, sizeof(u16)); |
|---|
| 357 | + memcpy(&msg_data[6], &vlan_tag, sizeof(u16)); |
|---|
| 358 | + |
|---|
| 359 | + return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data), |
|---|
| 360 | + HCLGE_MBX_PUSH_VLAN_INFO, vfid); |
|---|
| 361 | +} |
|---|
| 362 | + |
|---|
| 363 | +static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport, |
|---|
| 364 | + struct hclge_mbx_vf_to_pf_cmd *mbx_req, |
|---|
| 365 | + struct hclge_respond_to_vf_msg *resp_msg) |
|---|
| 366 | +{ |
|---|
| 367 | +#define HCLGE_MBX_VLAN_STATE_OFFSET 0 |
|---|
| 368 | +#define HCLGE_MBX_VLAN_INFO_OFFSET 2 |
|---|
| 369 | + |
|---|
| 370 | + struct hclge_vf_vlan_cfg *msg_cmd; |
|---|
| 371 | + int status = 0; |
|---|
| 372 | + |
|---|
| 373 | + msg_cmd = (struct hclge_vf_vlan_cfg *)&mbx_req->msg; |
|---|
| 374 | + if (msg_cmd->subcode == HCLGE_MBX_VLAN_FILTER) { |
|---|
| 375 | + struct hnae3_handle *handle = &vport->nic; |
|---|
| 376 | + u16 vlan, proto; |
|---|
| 377 | + bool is_kill; |
|---|
| 378 | + |
|---|
| 379 | + is_kill = !!msg_cmd->is_kill; |
|---|
| 380 | + vlan = msg_cmd->vlan; |
|---|
| 381 | + proto = msg_cmd->proto; |
|---|
| 382 | + status = hclge_set_vlan_filter(handle, cpu_to_be16(proto), |
|---|
| 383 | + vlan, is_kill); |
|---|
| 384 | + } else if (msg_cmd->subcode == HCLGE_MBX_VLAN_RX_OFF_CFG) { |
|---|
| 385 | + struct hnae3_handle *handle = &vport->nic; |
|---|
| 386 | + bool en = msg_cmd->is_kill ? true : false; |
|---|
| 387 | + |
|---|
| 388 | + status = hclge_en_hw_strip_rxvtag(handle, en); |
|---|
| 389 | + } else if (msg_cmd->subcode == HCLGE_MBX_PORT_BASE_VLAN_CFG) { |
|---|
| 390 | + struct hclge_vlan_info *vlan_info; |
|---|
| 391 | + u16 *state; |
|---|
| 392 | + |
|---|
| 393 | + state = (u16 *)&mbx_req->msg.data[HCLGE_MBX_VLAN_STATE_OFFSET]; |
|---|
| 394 | + vlan_info = (struct hclge_vlan_info *) |
|---|
| 395 | + &mbx_req->msg.data[HCLGE_MBX_VLAN_INFO_OFFSET]; |
|---|
| 396 | + status = hclge_update_port_base_vlan_cfg(vport, *state, |
|---|
| 397 | + vlan_info); |
|---|
| 398 | + } else if (msg_cmd->subcode == HCLGE_MBX_GET_PORT_BASE_VLAN_STATE) { |
|---|
| 399 | + resp_msg->data[0] = vport->port_base_vlan_cfg.state; |
|---|
| 400 | + resp_msg->len = sizeof(u8); |
|---|
| 401 | + } |
|---|
| 402 | + |
|---|
| 403 | + return status; |
|---|
| 404 | +} |
|---|
| 405 | + |
|---|
| 406 | +static int hclge_set_vf_alive(struct hclge_vport *vport, |
|---|
| 407 | + struct hclge_mbx_vf_to_pf_cmd *mbx_req) |
|---|
| 408 | +{ |
|---|
| 409 | + bool alive = !!mbx_req->msg.data[0]; |
|---|
| 410 | + int ret = 0; |
|---|
| 411 | + |
|---|
| 412 | + if (alive) |
|---|
| 413 | + ret = hclge_vport_start(vport); |
|---|
| 414 | + else |
|---|
| 415 | + hclge_vport_stop(vport); |
|---|
| 416 | + |
|---|
| 417 | + return ret; |
|---|
| 418 | +} |
|---|
| 419 | + |
|---|
| 420 | +static void hclge_get_vf_tcinfo(struct hclge_vport *vport, |
|---|
| 421 | + struct hclge_respond_to_vf_msg *resp_msg) |
|---|
| 422 | +{ |
|---|
| 423 | + struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; |
|---|
| 424 | + unsigned int i; |
|---|
| 425 | + |
|---|
| 426 | + for (i = 0; i < kinfo->num_tc; i++) |
|---|
| 427 | + resp_msg->data[0] |= BIT(i); |
|---|
| 428 | + |
|---|
| 429 | + resp_msg->len = sizeof(u8); |
|---|
| 430 | +} |
|---|
| 431 | + |
|---|
| 432 | +static void hclge_get_vf_queue_info(struct hclge_vport *vport, |
|---|
| 433 | + struct hclge_respond_to_vf_msg *resp_msg) |
|---|
| 434 | +{ |
|---|
| 435 | +#define HCLGE_TQPS_RSS_INFO_LEN 6 |
|---|
| 436 | +#define HCLGE_TQPS_ALLOC_OFFSET 0 |
|---|
| 437 | +#define HCLGE_TQPS_RSS_SIZE_OFFSET 2 |
|---|
| 438 | +#define HCLGE_TQPS_RX_BUFFER_LEN_OFFSET 4 |
|---|
| 439 | + |
|---|
| 368 | 440 | struct hclge_dev *hdev = vport->back; |
|---|
| 369 | 441 | |
|---|
| 370 | 442 | /* get the queue related info */ |
|---|
| 371 | | - memcpy(&resp_data[0], &vport->alloc_tqps, sizeof(u16)); |
|---|
| 372 | | - memcpy(&resp_data[2], &vport->nic.kinfo.rss_size, sizeof(u16)); |
|---|
| 373 | | - memcpy(&resp_data[4], &hdev->num_desc, sizeof(u16)); |
|---|
| 374 | | - memcpy(&resp_data[6], &hdev->rx_buf_len, sizeof(u16)); |
|---|
| 443 | + memcpy(&resp_msg->data[HCLGE_TQPS_ALLOC_OFFSET], |
|---|
| 444 | + &vport->alloc_tqps, sizeof(u16)); |
|---|
| 445 | + memcpy(&resp_msg->data[HCLGE_TQPS_RSS_SIZE_OFFSET], |
|---|
| 446 | + &vport->nic.kinfo.rss_size, sizeof(u16)); |
|---|
| 447 | + memcpy(&resp_msg->data[HCLGE_TQPS_RX_BUFFER_LEN_OFFSET], |
|---|
| 448 | + &hdev->rx_buf_len, sizeof(u16)); |
|---|
| 449 | + resp_msg->len = HCLGE_TQPS_RSS_INFO_LEN; |
|---|
| 450 | +} |
|---|
| 375 | 451 | |
|---|
| 376 | | - return hclge_gen_resp_to_vf(vport, mbx_req, 0, resp_data, |
|---|
| 377 | | - HCLGE_TQPS_RSS_INFO_LEN); |
|---|
| 452 | +static void hclge_get_vf_mac_addr(struct hclge_vport *vport, |
|---|
| 453 | + struct hclge_respond_to_vf_msg *resp_msg) |
|---|
| 454 | +{ |
|---|
| 455 | + ether_addr_copy(resp_msg->data, vport->vf_info.mac); |
|---|
| 456 | + resp_msg->len = ETH_ALEN; |
|---|
| 457 | +} |
|---|
| 458 | + |
|---|
| 459 | +static void hclge_get_vf_queue_depth(struct hclge_vport *vport, |
|---|
| 460 | + struct hclge_respond_to_vf_msg *resp_msg) |
|---|
| 461 | +{ |
|---|
| 462 | +#define HCLGE_TQPS_DEPTH_INFO_LEN 4 |
|---|
| 463 | +#define HCLGE_TQPS_NUM_TX_DESC_OFFSET 0 |
|---|
| 464 | +#define HCLGE_TQPS_NUM_RX_DESC_OFFSET 2 |
|---|
| 465 | + |
|---|
| 466 | + struct hclge_dev *hdev = vport->back; |
|---|
| 467 | + |
|---|
| 468 | + /* get the queue depth info */ |
|---|
| 469 | + memcpy(&resp_msg->data[HCLGE_TQPS_NUM_TX_DESC_OFFSET], |
|---|
| 470 | + &hdev->num_tx_desc, sizeof(u16)); |
|---|
| 471 | + memcpy(&resp_msg->data[HCLGE_TQPS_NUM_RX_DESC_OFFSET], |
|---|
| 472 | + &hdev->num_rx_desc, sizeof(u16)); |
|---|
| 473 | + resp_msg->len = HCLGE_TQPS_DEPTH_INFO_LEN; |
|---|
| 474 | +} |
|---|
| 475 | + |
|---|
| 476 | +static void hclge_get_vf_media_type(struct hclge_vport *vport, |
|---|
| 477 | + struct hclge_respond_to_vf_msg *resp_msg) |
|---|
| 478 | +{ |
|---|
| 479 | +#define HCLGE_VF_MEDIA_TYPE_OFFSET 0 |
|---|
| 480 | +#define HCLGE_VF_MODULE_TYPE_OFFSET 1 |
|---|
| 481 | +#define HCLGE_VF_MEDIA_TYPE_LENGTH 2 |
|---|
| 482 | + |
|---|
| 483 | + struct hclge_dev *hdev = vport->back; |
|---|
| 484 | + |
|---|
| 485 | + resp_msg->data[HCLGE_VF_MEDIA_TYPE_OFFSET] = |
|---|
| 486 | + hdev->hw.mac.media_type; |
|---|
| 487 | + resp_msg->data[HCLGE_VF_MODULE_TYPE_OFFSET] = |
|---|
| 488 | + hdev->hw.mac.module_type; |
|---|
| 489 | + resp_msg->len = HCLGE_VF_MEDIA_TYPE_LENGTH; |
|---|
| 378 | 490 | } |
|---|
| 379 | 491 | |
|---|
| 380 | 492 | static int hclge_get_link_info(struct hclge_vport *vport, |
|---|
| 381 | 493 | struct hclge_mbx_vf_to_pf_cmd *mbx_req) |
|---|
| 382 | 494 | { |
|---|
| 495 | +#define HCLGE_VF_LINK_STATE_UP 1U |
|---|
| 496 | +#define HCLGE_VF_LINK_STATE_DOWN 0U |
|---|
| 497 | + |
|---|
| 383 | 498 | struct hclge_dev *hdev = vport->back; |
|---|
| 384 | 499 | u16 link_status; |
|---|
| 385 | 500 | u8 msg_data[8]; |
|---|
| .. | .. |
|---|
| 387 | 502 | u16 duplex; |
|---|
| 388 | 503 | |
|---|
| 389 | 504 | /* mac.link can only be 0 or 1 */ |
|---|
| 390 | | - link_status = (u16)hdev->hw.mac.link; |
|---|
| 505 | + switch (vport->vf_info.link_state) { |
|---|
| 506 | + case IFLA_VF_LINK_STATE_ENABLE: |
|---|
| 507 | + link_status = HCLGE_VF_LINK_STATE_UP; |
|---|
| 508 | + break; |
|---|
| 509 | + case IFLA_VF_LINK_STATE_DISABLE: |
|---|
| 510 | + link_status = HCLGE_VF_LINK_STATE_DOWN; |
|---|
| 511 | + break; |
|---|
| 512 | + case IFLA_VF_LINK_STATE_AUTO: |
|---|
| 513 | + default: |
|---|
| 514 | + link_status = (u16)hdev->hw.mac.link; |
|---|
| 515 | + break; |
|---|
| 516 | + } |
|---|
| 517 | + |
|---|
| 391 | 518 | duplex = hdev->hw.mac.duplex; |
|---|
| 392 | 519 | memcpy(&msg_data[0], &link_status, sizeof(u16)); |
|---|
| 393 | 520 | memcpy(&msg_data[2], &hdev->hw.mac.speed, sizeof(u32)); |
|---|
| .. | .. |
|---|
| 399 | 526 | HCLGE_MBX_LINK_STAT_CHANGE, dest_vfid); |
|---|
| 400 | 527 | } |
|---|
| 401 | 528 | |
|---|
| 529 | +static void hclge_get_link_mode(struct hclge_vport *vport, |
|---|
| 530 | + struct hclge_mbx_vf_to_pf_cmd *mbx_req) |
|---|
| 531 | +{ |
|---|
| 532 | +#define HCLGE_SUPPORTED 1 |
|---|
| 533 | + struct hclge_dev *hdev = vport->back; |
|---|
| 534 | + unsigned long advertising; |
|---|
| 535 | + unsigned long supported; |
|---|
| 536 | + unsigned long send_data; |
|---|
| 537 | + u8 msg_data[10] = {}; |
|---|
| 538 | + u8 dest_vfid; |
|---|
| 539 | + |
|---|
| 540 | + advertising = hdev->hw.mac.advertising[0]; |
|---|
| 541 | + supported = hdev->hw.mac.supported[0]; |
|---|
| 542 | + dest_vfid = mbx_req->mbx_src_vfid; |
|---|
| 543 | + msg_data[0] = mbx_req->msg.data[0]; |
|---|
| 544 | + |
|---|
| 545 | + send_data = msg_data[0] == HCLGE_SUPPORTED ? supported : advertising; |
|---|
| 546 | + |
|---|
| 547 | + memcpy(&msg_data[2], &send_data, sizeof(unsigned long)); |
|---|
| 548 | + hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data), |
|---|
| 549 | + HCLGE_MBX_LINK_STAT_MODE, dest_vfid); |
|---|
| 550 | +} |
|---|
| 551 | + |
|---|
| 402 | 552 | static void hclge_mbx_reset_vf_queue(struct hclge_vport *vport, |
|---|
| 403 | 553 | struct hclge_mbx_vf_to_pf_cmd *mbx_req) |
|---|
| 404 | 554 | { |
|---|
| 405 | 555 | u16 queue_id; |
|---|
| 406 | 556 | |
|---|
| 407 | | - memcpy(&queue_id, &mbx_req->msg[2], sizeof(queue_id)); |
|---|
| 557 | + memcpy(&queue_id, mbx_req->msg.data, sizeof(queue_id)); |
|---|
| 408 | 558 | |
|---|
| 409 | 559 | hclge_reset_vf_queue(vport, queue_id); |
|---|
| 410 | | - |
|---|
| 411 | | - /* send response msg to VF after queue reset complete*/ |
|---|
| 412 | | - hclge_gen_resp_to_vf(vport, mbx_req, 0, NULL, 0); |
|---|
| 413 | 560 | } |
|---|
| 414 | 561 | |
|---|
| 415 | | -static void hclge_reset_vf(struct hclge_vport *vport, |
|---|
| 416 | | - struct hclge_mbx_vf_to_pf_cmd *mbx_req) |
|---|
| 562 | +static int hclge_reset_vf(struct hclge_vport *vport) |
|---|
| 417 | 563 | { |
|---|
| 418 | 564 | struct hclge_dev *hdev = vport->back; |
|---|
| 419 | | - int ret; |
|---|
| 420 | 565 | |
|---|
| 421 | | - dev_warn(&hdev->pdev->dev, "PF received VF reset request from VF %d!", |
|---|
| 422 | | - mbx_req->mbx_src_vfid); |
|---|
| 566 | + dev_warn(&hdev->pdev->dev, "PF received VF reset request from VF %u!", |
|---|
| 567 | + vport->vport_id); |
|---|
| 423 | 568 | |
|---|
| 424 | | - /* Acknowledge VF that PF is now about to assert the reset for the VF. |
|---|
| 425 | | - * On receiving this message VF will get into pending state and will |
|---|
| 426 | | - * start polling for the hardware reset completion status. |
|---|
| 427 | | - */ |
|---|
| 428 | | - ret = hclge_inform_reset_assert_to_vf(vport); |
|---|
| 429 | | - if (ret) { |
|---|
| 430 | | - dev_err(&hdev->pdev->dev, |
|---|
| 431 | | - "PF fail(%d) to inform VF(%d)of reset, reset failed!\n", |
|---|
| 432 | | - ret, vport->vport_id); |
|---|
| 433 | | - return; |
|---|
| 569 | + return hclge_func_reset_cmd(hdev, vport->vport_id); |
|---|
| 570 | +} |
|---|
| 571 | + |
|---|
| 572 | +static void hclge_vf_keep_alive(struct hclge_vport *vport) |
|---|
| 573 | +{ |
|---|
| 574 | + vport->last_active_jiffies = jiffies; |
|---|
| 575 | +} |
|---|
| 576 | + |
|---|
| 577 | +static int hclge_set_vf_mtu(struct hclge_vport *vport, |
|---|
| 578 | + struct hclge_mbx_vf_to_pf_cmd *mbx_req) |
|---|
| 579 | +{ |
|---|
| 580 | + u32 mtu; |
|---|
| 581 | + |
|---|
| 582 | + memcpy(&mtu, mbx_req->msg.data, sizeof(mtu)); |
|---|
| 583 | + |
|---|
| 584 | + return hclge_set_vport_mtu(vport, mtu); |
|---|
| 585 | +} |
|---|
| 586 | + |
|---|
| 587 | +static int hclge_get_queue_id_in_pf(struct hclge_vport *vport, |
|---|
| 588 | + struct hclge_mbx_vf_to_pf_cmd *mbx_req, |
|---|
| 589 | + struct hclge_respond_to_vf_msg *resp_msg) |
|---|
| 590 | +{ |
|---|
| 591 | + struct hnae3_handle *handle = &vport->nic; |
|---|
| 592 | + struct hclge_dev *hdev = vport->back; |
|---|
| 593 | + u16 queue_id, qid_in_pf; |
|---|
| 594 | + |
|---|
| 595 | + memcpy(&queue_id, mbx_req->msg.data, sizeof(queue_id)); |
|---|
| 596 | + if (queue_id >= handle->kinfo.num_tqps) { |
|---|
| 597 | + dev_err(&hdev->pdev->dev, "Invalid queue id(%u) from VF %u\n", |
|---|
| 598 | + queue_id, mbx_req->mbx_src_vfid); |
|---|
| 599 | + return -EINVAL; |
|---|
| 434 | 600 | } |
|---|
| 435 | 601 | |
|---|
| 436 | | - dev_warn(&hdev->pdev->dev, "PF is now resetting VF %d.\n", |
|---|
| 437 | | - mbx_req->mbx_src_vfid); |
|---|
| 438 | | - /* reset this virtual function */ |
|---|
| 439 | | - hclge_func_reset_cmd(hdev, mbx_req->mbx_src_vfid); |
|---|
| 602 | + qid_in_pf = hclge_covert_handle_qid_global(&vport->nic, queue_id); |
|---|
| 603 | + memcpy(resp_msg->data, &qid_in_pf, sizeof(qid_in_pf)); |
|---|
| 604 | + resp_msg->len = sizeof(qid_in_pf); |
|---|
| 605 | + return 0; |
|---|
| 606 | +} |
|---|
| 607 | + |
|---|
| 608 | +static int hclge_get_rss_key(struct hclge_vport *vport, |
|---|
| 609 | + struct hclge_mbx_vf_to_pf_cmd *mbx_req, |
|---|
| 610 | + struct hclge_respond_to_vf_msg *resp_msg) |
|---|
| 611 | +{ |
|---|
| 612 | +#define HCLGE_RSS_MBX_RESP_LEN 8 |
|---|
| 613 | + struct hclge_dev *hdev = vport->back; |
|---|
| 614 | + u8 index; |
|---|
| 615 | + |
|---|
| 616 | + index = mbx_req->msg.data[0]; |
|---|
| 617 | + |
|---|
| 618 | + /* Check the query index of rss_hash_key from VF, make sure no |
|---|
| 619 | + * more than the size of rss_hash_key. |
|---|
| 620 | + */ |
|---|
| 621 | + if (((index + 1) * HCLGE_RSS_MBX_RESP_LEN) > |
|---|
| 622 | + sizeof(vport[0].rss_hash_key)) { |
|---|
| 623 | + dev_warn(&hdev->pdev->dev, |
|---|
| 624 | + "failed to get the rss hash key, the index(%u) invalid !\n", |
|---|
| 625 | + index); |
|---|
| 626 | + return -EINVAL; |
|---|
| 627 | + } |
|---|
| 628 | + |
|---|
| 629 | + memcpy(resp_msg->data, |
|---|
| 630 | + &hdev->vport[0].rss_hash_key[index * HCLGE_RSS_MBX_RESP_LEN], |
|---|
| 631 | + HCLGE_RSS_MBX_RESP_LEN); |
|---|
| 632 | + resp_msg->len = HCLGE_RSS_MBX_RESP_LEN; |
|---|
| 633 | + return 0; |
|---|
| 634 | +} |
|---|
| 635 | + |
|---|
| 636 | +static void hclge_link_fail_parse(struct hclge_dev *hdev, u8 link_fail_code) |
|---|
| 637 | +{ |
|---|
| 638 | + switch (link_fail_code) { |
|---|
| 639 | + case HCLGE_LF_REF_CLOCK_LOST: |
|---|
| 640 | + dev_warn(&hdev->pdev->dev, "Reference clock lost!\n"); |
|---|
| 641 | + break; |
|---|
| 642 | + case HCLGE_LF_XSFP_TX_DISABLE: |
|---|
| 643 | + dev_warn(&hdev->pdev->dev, "SFP tx is disabled!\n"); |
|---|
| 644 | + break; |
|---|
| 645 | + case HCLGE_LF_XSFP_ABSENT: |
|---|
| 646 | + dev_warn(&hdev->pdev->dev, "SFP is absent!\n"); |
|---|
| 647 | + break; |
|---|
| 648 | + default: |
|---|
| 649 | + break; |
|---|
| 650 | + } |
|---|
| 651 | +} |
|---|
| 652 | + |
|---|
| 653 | +static void hclge_handle_link_change_event(struct hclge_dev *hdev, |
|---|
| 654 | + struct hclge_mbx_vf_to_pf_cmd *req) |
|---|
| 655 | +{ |
|---|
| 656 | + hclge_task_schedule(hdev, 0); |
|---|
| 657 | + |
|---|
| 658 | + if (!req->msg.subcode) |
|---|
| 659 | + hclge_link_fail_parse(hdev, req->msg.data[0]); |
|---|
| 440 | 660 | } |
|---|
| 441 | 661 | |
|---|
| 442 | 662 | static bool hclge_cmd_crq_empty(struct hclge_hw *hw) |
|---|
| .. | .. |
|---|
| 446 | 666 | return tail == hw->cmq.crq.next_to_use; |
|---|
| 447 | 667 | } |
|---|
| 448 | 668 | |
|---|
| 669 | +static void hclge_handle_ncsi_error(struct hclge_dev *hdev) |
|---|
| 670 | +{ |
|---|
| 671 | + struct hnae3_ae_dev *ae_dev = hdev->ae_dev; |
|---|
| 672 | + |
|---|
| 673 | + ae_dev->ops->set_default_reset_request(ae_dev, HNAE3_GLOBAL_RESET); |
|---|
| 674 | + dev_warn(&hdev->pdev->dev, "requesting reset due to NCSI error\n"); |
|---|
| 675 | + ae_dev->ops->reset_event(hdev->pdev, NULL); |
|---|
| 676 | +} |
|---|
| 677 | + |
|---|
| 678 | +static void hclge_handle_vf_tbl(struct hclge_vport *vport, |
|---|
| 679 | + struct hclge_mbx_vf_to_pf_cmd *mbx_req) |
|---|
| 680 | +{ |
|---|
| 681 | + struct hclge_dev *hdev = vport->back; |
|---|
| 682 | + struct hclge_vf_vlan_cfg *msg_cmd; |
|---|
| 683 | + |
|---|
| 684 | + msg_cmd = (struct hclge_vf_vlan_cfg *)&mbx_req->msg; |
|---|
| 685 | + if (msg_cmd->subcode == HCLGE_MBX_VPORT_LIST_CLEAR) { |
|---|
| 686 | + hclge_rm_vport_all_mac_table(vport, true, HCLGE_MAC_ADDR_UC); |
|---|
| 687 | + hclge_rm_vport_all_mac_table(vport, true, HCLGE_MAC_ADDR_MC); |
|---|
| 688 | + hclge_rm_vport_all_vlan_table(vport, true); |
|---|
| 689 | + } else { |
|---|
| 690 | + dev_warn(&hdev->pdev->dev, "Invalid cmd(%u)\n", |
|---|
| 691 | + msg_cmd->subcode); |
|---|
| 692 | + } |
|---|
| 693 | +} |
|---|
| 694 | + |
|---|
| 449 | 695 | void hclge_mbx_handler(struct hclge_dev *hdev) |
|---|
| 450 | 696 | { |
|---|
| 451 | 697 | struct hclge_cmq_ring *crq = &hdev->hw.cmq.crq; |
|---|
| 698 | + struct hclge_respond_to_vf_msg resp_msg; |
|---|
| 452 | 699 | struct hclge_mbx_vf_to_pf_cmd *req; |
|---|
| 453 | 700 | struct hclge_vport *vport; |
|---|
| 454 | 701 | struct hclge_desc *desc; |
|---|
| 455 | | - int ret, flag; |
|---|
| 702 | + bool is_del = false; |
|---|
| 703 | + unsigned int flag; |
|---|
| 704 | + int ret = 0; |
|---|
| 456 | 705 | |
|---|
| 457 | 706 | /* handle all the mailbox requests in the queue */ |
|---|
| 458 | 707 | while (!hclge_cmd_crq_empty(&hdev->hw)) { |
|---|
| .. | .. |
|---|
| 468 | 717 | flag = le16_to_cpu(crq->desc[crq->next_to_use].flag); |
|---|
| 469 | 718 | if (unlikely(!hnae3_get_bit(flag, HCLGE_CMDQ_RX_OUTVLD_B))) { |
|---|
| 470 | 719 | dev_warn(&hdev->pdev->dev, |
|---|
| 471 | | - "dropped invalid mailbox message, code = %d\n", |
|---|
| 472 | | - req->msg[0]); |
|---|
| 720 | + "dropped invalid mailbox message, code = %u\n", |
|---|
| 721 | + req->msg.code); |
|---|
| 473 | 722 | |
|---|
| 474 | 723 | /* dropping/not processing this invalid message */ |
|---|
| 475 | 724 | crq->desc[crq->next_to_use].flag = 0; |
|---|
| .. | .. |
|---|
| 479 | 728 | |
|---|
| 480 | 729 | vport = &hdev->vport[req->mbx_src_vfid]; |
|---|
| 481 | 730 | |
|---|
| 482 | | - switch (req->msg[0]) { |
|---|
| 731 | + trace_hclge_pf_mbx_get(hdev, req); |
|---|
| 732 | + |
|---|
| 733 | + /* clear the resp_msg before processing every mailbox message */ |
|---|
| 734 | + memset(&resp_msg, 0, sizeof(resp_msg)); |
|---|
| 735 | + |
|---|
| 736 | + switch (req->msg.code) { |
|---|
| 483 | 737 | case HCLGE_MBX_MAP_RING_TO_VECTOR: |
|---|
| 484 | 738 | ret = hclge_map_unmap_ring_to_vf_vector(vport, true, |
|---|
| 485 | 739 | req); |
|---|
| .. | .. |
|---|
| 496 | 750 | ret); |
|---|
| 497 | 751 | break; |
|---|
| 498 | 752 | case HCLGE_MBX_SET_UNICAST: |
|---|
| 499 | | - ret = hclge_set_vf_uc_mac_addr(vport, req, true); |
|---|
| 753 | + ret = hclge_set_vf_uc_mac_addr(vport, req); |
|---|
| 500 | 754 | if (ret) |
|---|
| 501 | 755 | dev_err(&hdev->pdev->dev, |
|---|
| 502 | 756 | "PF fail(%d) to set VF UC MAC Addr\n", |
|---|
| 503 | 757 | ret); |
|---|
| 504 | 758 | break; |
|---|
| 505 | 759 | case HCLGE_MBX_SET_MULTICAST: |
|---|
| 506 | | - ret = hclge_set_vf_mc_mac_addr(vport, req, false); |
|---|
| 760 | + ret = hclge_set_vf_mc_mac_addr(vport, req); |
|---|
| 507 | 761 | if (ret) |
|---|
| 508 | 762 | dev_err(&hdev->pdev->dev, |
|---|
| 509 | 763 | "PF fail(%d) to set VF MC MAC Addr\n", |
|---|
| 510 | 764 | ret); |
|---|
| 511 | 765 | break; |
|---|
| 512 | 766 | case HCLGE_MBX_SET_VLAN: |
|---|
| 513 | | - ret = hclge_set_vf_vlan_cfg(vport, req, false); |
|---|
| 767 | + ret = hclge_set_vf_vlan_cfg(vport, req, &resp_msg); |
|---|
| 514 | 768 | if (ret) |
|---|
| 515 | 769 | dev_err(&hdev->pdev->dev, |
|---|
| 516 | 770 | "PF failed(%d) to config VF's VLAN\n", |
|---|
| 517 | 771 | ret); |
|---|
| 518 | 772 | break; |
|---|
| 519 | | - case HCLGE_MBX_GET_QINFO: |
|---|
| 520 | | - ret = hclge_get_vf_queue_info(vport, req, true); |
|---|
| 773 | + case HCLGE_MBX_SET_ALIVE: |
|---|
| 774 | + ret = hclge_set_vf_alive(vport, req); |
|---|
| 521 | 775 | if (ret) |
|---|
| 522 | 776 | dev_err(&hdev->pdev->dev, |
|---|
| 523 | | - "PF failed(%d) to get Q info for VF\n", |
|---|
| 777 | + "PF failed(%d) to set VF's ALIVE\n", |
|---|
| 524 | 778 | ret); |
|---|
| 525 | 779 | break; |
|---|
| 780 | + case HCLGE_MBX_GET_QINFO: |
|---|
| 781 | + hclge_get_vf_queue_info(vport, &resp_msg); |
|---|
| 782 | + break; |
|---|
| 783 | + case HCLGE_MBX_GET_QDEPTH: |
|---|
| 784 | + hclge_get_vf_queue_depth(vport, &resp_msg); |
|---|
| 785 | + break; |
|---|
| 526 | 786 | case HCLGE_MBX_GET_TCINFO: |
|---|
| 527 | | - ret = hclge_get_vf_tcinfo(vport, req, true); |
|---|
| 528 | | - if (ret) |
|---|
| 529 | | - dev_err(&hdev->pdev->dev, |
|---|
| 530 | | - "PF failed(%d) to get TC info for VF\n", |
|---|
| 531 | | - ret); |
|---|
| 787 | + hclge_get_vf_tcinfo(vport, &resp_msg); |
|---|
| 532 | 788 | break; |
|---|
| 533 | 789 | case HCLGE_MBX_GET_LINK_STATUS: |
|---|
| 534 | 790 | ret = hclge_get_link_info(vport, req); |
|---|
| 535 | 791 | if (ret) |
|---|
| 536 | 792 | dev_err(&hdev->pdev->dev, |
|---|
| 537 | | - "PF fail(%d) to get link stat for VF\n", |
|---|
| 793 | + "failed to inform link stat to VF, ret = %d\n", |
|---|
| 538 | 794 | ret); |
|---|
| 539 | 795 | break; |
|---|
| 540 | 796 | case HCLGE_MBX_QUEUE_RESET: |
|---|
| 541 | 797 | hclge_mbx_reset_vf_queue(vport, req); |
|---|
| 542 | 798 | break; |
|---|
| 543 | 799 | case HCLGE_MBX_RESET: |
|---|
| 544 | | - hclge_reset_vf(vport, req); |
|---|
| 800 | + ret = hclge_reset_vf(vport); |
|---|
| 801 | + break; |
|---|
| 802 | + case HCLGE_MBX_KEEP_ALIVE: |
|---|
| 803 | + hclge_vf_keep_alive(vport); |
|---|
| 804 | + break; |
|---|
| 805 | + case HCLGE_MBX_SET_MTU: |
|---|
| 806 | + ret = hclge_set_vf_mtu(vport, req); |
|---|
| 807 | + if (ret) |
|---|
| 808 | + dev_err(&hdev->pdev->dev, |
|---|
| 809 | + "VF fail(%d) to set mtu\n", ret); |
|---|
| 810 | + break; |
|---|
| 811 | + case HCLGE_MBX_GET_QID_IN_PF: |
|---|
| 812 | + ret = hclge_get_queue_id_in_pf(vport, req, &resp_msg); |
|---|
| 813 | + break; |
|---|
| 814 | + case HCLGE_MBX_GET_RSS_KEY: |
|---|
| 815 | + ret = hclge_get_rss_key(vport, req, &resp_msg); |
|---|
| 816 | + break; |
|---|
| 817 | + case HCLGE_MBX_GET_LINK_MODE: |
|---|
| 818 | + hclge_get_link_mode(vport, req); |
|---|
| 819 | + break; |
|---|
| 820 | + case HCLGE_MBX_GET_VF_FLR_STATUS: |
|---|
| 821 | + case HCLGE_MBX_VF_UNINIT: |
|---|
| 822 | + is_del = req->msg.code == HCLGE_MBX_VF_UNINIT; |
|---|
| 823 | + hclge_rm_vport_all_mac_table(vport, is_del, |
|---|
| 824 | + HCLGE_MAC_ADDR_UC); |
|---|
| 825 | + hclge_rm_vport_all_mac_table(vport, is_del, |
|---|
| 826 | + HCLGE_MAC_ADDR_MC); |
|---|
| 827 | + hclge_rm_vport_all_vlan_table(vport, is_del); |
|---|
| 828 | + break; |
|---|
| 829 | + case HCLGE_MBX_GET_MEDIA_TYPE: |
|---|
| 830 | + hclge_get_vf_media_type(vport, &resp_msg); |
|---|
| 831 | + break; |
|---|
| 832 | + case HCLGE_MBX_PUSH_LINK_STATUS: |
|---|
| 833 | + hclge_handle_link_change_event(hdev, req); |
|---|
| 834 | + break; |
|---|
| 835 | + case HCLGE_MBX_GET_MAC_ADDR: |
|---|
| 836 | + hclge_get_vf_mac_addr(vport, &resp_msg); |
|---|
| 837 | + break; |
|---|
| 838 | + case HCLGE_MBX_NCSI_ERROR: |
|---|
| 839 | + hclge_handle_ncsi_error(hdev); |
|---|
| 840 | + break; |
|---|
| 841 | + case HCLGE_MBX_HANDLE_VF_TBL: |
|---|
| 842 | + hclge_handle_vf_tbl(vport, req); |
|---|
| 545 | 843 | break; |
|---|
| 546 | 844 | default: |
|---|
| 547 | 845 | dev_err(&hdev->pdev->dev, |
|---|
| 548 | | - "un-supported mailbox message, code = %d\n", |
|---|
| 549 | | - req->msg[0]); |
|---|
| 846 | + "un-supported mailbox message, code = %u\n", |
|---|
| 847 | + req->msg.code); |
|---|
| 550 | 848 | break; |
|---|
| 551 | 849 | } |
|---|
| 850 | + |
|---|
| 851 | + /* PF driver should not reply IMP */ |
|---|
| 852 | + if (hnae3_get_bit(req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B) && |
|---|
| 853 | + req->msg.code < HCLGE_MBX_GET_VF_FLR_STATUS) { |
|---|
| 854 | + resp_msg.status = ret; |
|---|
| 855 | + hclge_gen_resp_to_vf(vport, req, &resp_msg); |
|---|
| 856 | + } |
|---|
| 857 | + |
|---|
| 552 | 858 | crq->desc[crq->next_to_use].flag = 0; |
|---|
| 553 | 859 | hclge_mbx_ring_ptr_move_crq(crq); |
|---|
| 860 | + |
|---|
| 861 | + /* reinitialize ret after complete the mbx message processing */ |
|---|
| 862 | + ret = 0; |
|---|
| 554 | 863 | } |
|---|
| 555 | 864 | |
|---|
| 556 | 865 | /* Write back CMDQ_RQ header pointer, M7 need this pointer */ |
|---|