.. | .. |
---|
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 */ |
---|