1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright (c) 2016-2017 Hisilicon Limited.
5 #include "hclgevf_main.h"
8 #define CREATE_TRACE_POINTS
9 #include "hclgevf_trace.h"
11 static int hclgevf_resp_to_errno(u16 resp_code
)
13 return resp_code
? -resp_code
: 0;
16 #define HCLGEVF_MBX_MATCH_ID_START 1
17 static void hclgevf_reset_mbx_resp_status(struct hclgevf_dev
*hdev
)
19 /* this function should be called with mbx_resp.mbx_mutex held
20 * to protect the received_response from race condition
22 hdev
->mbx_resp
.received_resp
= false;
23 hdev
->mbx_resp
.origin_mbx_msg
= 0;
24 hdev
->mbx_resp
.resp_status
= 0;
25 hdev
->mbx_resp
.match_id
++;
26 /* Update match_id and ensure the value of match_id is not zero */
27 if (hdev
->mbx_resp
.match_id
== 0)
28 hdev
->mbx_resp
.match_id
= HCLGEVF_MBX_MATCH_ID_START
;
29 memset(hdev
->mbx_resp
.additional_info
, 0, HCLGE_MBX_MAX_RESP_DATA_SIZE
);
32 /* hclgevf_get_mbx_resp: used to get a response from PF after VF sends a mailbox
34 * @hdev: pointer to struct hclgevf_dev
35 * @code0: the message opcode VF send to PF.
36 * @code1: the message sub-opcode VF send to PF.
37 * @resp_data: pointer to store response data from PF to VF.
38 * @resp_len: the length of resp_data from PF to VF.
40 static int hclgevf_get_mbx_resp(struct hclgevf_dev
*hdev
, u16 code0
, u16 code1
,
41 u8
*resp_data
, u16 resp_len
)
43 #define HCLGEVF_MAX_TRY_TIMES 500
44 #define HCLGEVF_SLEEP_USECOND 1000
45 struct hclgevf_mbx_resp_status
*mbx_resp
;
49 if (resp_len
> HCLGE_MBX_MAX_RESP_DATA_SIZE
) {
50 dev_err(&hdev
->pdev
->dev
,
51 "VF mbx response len(=%u) exceeds maximum(=%u)\n",
53 HCLGE_MBX_MAX_RESP_DATA_SIZE
);
57 while ((!hdev
->mbx_resp
.received_resp
) && (i
< HCLGEVF_MAX_TRY_TIMES
)) {
58 if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE
,
59 &hdev
->hw
.hw
.comm_state
))
62 usleep_range(HCLGEVF_SLEEP_USECOND
, HCLGEVF_SLEEP_USECOND
* 2);
66 /* ensure additional_info will be seen after received_resp */
69 if (i
>= HCLGEVF_MAX_TRY_TIMES
) {
70 dev_err(&hdev
->pdev
->dev
,
71 "VF could not get mbx(%u,%u) resp(=%d) from PF in %d tries\n",
72 code0
, code1
, hdev
->mbx_resp
.received_resp
, i
);
76 mbx_resp
= &hdev
->mbx_resp
;
77 r_code0
= (u16
)(mbx_resp
->origin_mbx_msg
>> 16);
78 r_code1
= (u16
)(mbx_resp
->origin_mbx_msg
& 0xff);
80 if (mbx_resp
->resp_status
)
81 return mbx_resp
->resp_status
;
84 memcpy(resp_data
, &mbx_resp
->additional_info
[0], resp_len
);
86 hclgevf_reset_mbx_resp_status(hdev
);
88 if (!(r_code0
== code0
&& r_code1
== code1
&& !mbx_resp
->resp_status
)) {
89 dev_err(&hdev
->pdev
->dev
,
90 "VF could not match resp code(code0=%u,code1=%u), %d\n",
91 code0
, code1
, mbx_resp
->resp_status
);
92 dev_err(&hdev
->pdev
->dev
,
93 "VF could not match resp r_code(r_code0=%u,r_code1=%u)\n",
101 int hclgevf_send_mbx_msg(struct hclgevf_dev
*hdev
,
102 struct hclge_vf_to_pf_msg
*send_msg
, bool need_resp
,
103 u8
*resp_data
, u16 resp_len
)
105 struct hclge_mbx_vf_to_pf_cmd
*req
;
106 struct hclge_desc desc
;
109 req
= (struct hclge_mbx_vf_to_pf_cmd
*)desc
.data
;
112 dev_err(&hdev
->pdev
->dev
,
113 "failed to send mbx, msg is NULL\n");
117 hclgevf_cmd_setup_basic_desc(&desc
, HCLGEVF_OPC_MBX_VF_TO_PF
, false);
119 hnae3_set_bit(req
->mbx_need_resp
, HCLGE_MBX_NEED_RESP_B
, 1);
121 memcpy(&req
->msg
, send_msg
, sizeof(struct hclge_vf_to_pf_msg
));
123 if (test_bit(HCLGEVF_STATE_NIC_REGISTERED
, &hdev
->state
))
124 trace_hclge_vf_mbx_send(hdev
, req
);
126 /* synchronous send */
128 mutex_lock(&hdev
->mbx_resp
.mbx_mutex
);
129 hclgevf_reset_mbx_resp_status(hdev
);
130 req
->match_id
= cpu_to_le16(hdev
->mbx_resp
.match_id
);
131 status
= hclgevf_cmd_send(&hdev
->hw
, &desc
, 1);
133 dev_err(&hdev
->pdev
->dev
,
134 "VF failed(=%d) to send mbx message to PF\n",
136 mutex_unlock(&hdev
->mbx_resp
.mbx_mutex
);
140 status
= hclgevf_get_mbx_resp(hdev
, send_msg
->code
,
141 send_msg
->subcode
, resp_data
,
143 mutex_unlock(&hdev
->mbx_resp
.mbx_mutex
);
145 /* asynchronous send */
146 status
= hclgevf_cmd_send(&hdev
->hw
, &desc
, 1);
148 dev_err(&hdev
->pdev
->dev
,
149 "VF failed(=%d) to send mbx message to PF\n",
158 static bool hclgevf_cmd_crq_empty(struct hclgevf_hw
*hw
)
160 u32 tail
= hclgevf_read_dev(hw
, HCLGE_COMM_NIC_CRQ_TAIL_REG
);
162 return tail
== hw
->hw
.cmq
.crq
.next_to_use
;
165 static void hclgevf_handle_mbx_response(struct hclgevf_dev
*hdev
,
166 struct hclge_mbx_pf_to_vf_cmd
*req
)
168 u16 vf_mbx_msg_subcode
= le16_to_cpu(req
->msg
.vf_mbx_msg_subcode
);
169 u16 vf_mbx_msg_code
= le16_to_cpu(req
->msg
.vf_mbx_msg_code
);
170 struct hclgevf_mbx_resp_status
*resp
= &hdev
->mbx_resp
;
171 u16 resp_status
= le16_to_cpu(req
->msg
.resp_status
);
172 u16 match_id
= le16_to_cpu(req
->match_id
);
174 if (resp
->received_resp
)
175 dev_warn(&hdev
->pdev
->dev
,
176 "VF mbx resp flag not clear(%u)\n",
179 resp
->origin_mbx_msg
= (vf_mbx_msg_code
<< 16);
180 resp
->origin_mbx_msg
|= vf_mbx_msg_subcode
;
181 resp
->resp_status
= hclgevf_resp_to_errno(resp_status
);
182 memcpy(resp
->additional_info
, req
->msg
.resp_data
,
183 HCLGE_MBX_MAX_RESP_DATA_SIZE
* sizeof(u8
));
185 /* ensure additional_info will be seen before setting received_resp */
189 /* If match_id is not zero, it means PF support match_id.
190 * if the match_id is right, VF get the right response, or
191 * ignore the response. and driver will clear hdev->mbx_resp
192 * when send next message which need response.
194 if (match_id
== resp
->match_id
)
195 resp
->received_resp
= true;
197 resp
->received_resp
= true;
201 static void hclgevf_handle_mbx_msg(struct hclgevf_dev
*hdev
,
202 struct hclge_mbx_pf_to_vf_cmd
*req
)
204 /* we will drop the async msg if we find ARQ as full
205 * and continue with next message
207 if (atomic_read(&hdev
->arq
.count
) >=
208 HCLGE_MBX_MAX_ARQ_MSG_NUM
) {
209 dev_warn(&hdev
->pdev
->dev
,
210 "Async Q full, dropping msg(%u)\n",
211 le16_to_cpu(req
->msg
.code
));
215 /* tail the async message in arq */
216 memcpy(hdev
->arq
.msg_q
[hdev
->arq
.tail
], &req
->msg
,
217 HCLGE_MBX_MAX_ARQ_MSG_SIZE
* sizeof(u16
));
218 hclge_mbx_tail_ptr_move_arq(hdev
->arq
);
219 atomic_inc(&hdev
->arq
.count
);
221 hclgevf_mbx_task_schedule(hdev
);
224 void hclgevf_mbx_handler(struct hclgevf_dev
*hdev
)
226 struct hclge_mbx_pf_to_vf_cmd
*req
;
227 struct hclge_comm_cmq_ring
*crq
;
228 struct hclge_desc
*desc
;
232 crq
= &hdev
->hw
.hw
.cmq
.crq
;
234 while (!hclgevf_cmd_crq_empty(&hdev
->hw
)) {
235 if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE
,
236 &hdev
->hw
.hw
.comm_state
)) {
237 dev_info(&hdev
->pdev
->dev
, "vf crq need init\n");
241 desc
= &crq
->desc
[crq
->next_to_use
];
242 req
= (struct hclge_mbx_pf_to_vf_cmd
*)desc
->data
;
244 flag
= le16_to_cpu(crq
->desc
[crq
->next_to_use
].flag
);
245 code
= le16_to_cpu(req
->msg
.code
);
246 if (unlikely(!hnae3_get_bit(flag
, HCLGEVF_CMDQ_RX_OUTVLD_B
))) {
247 dev_warn(&hdev
->pdev
->dev
,
248 "dropped invalid mailbox message, code = %u\n",
251 /* dropping/not processing this invalid message */
252 crq
->desc
[crq
->next_to_use
].flag
= 0;
253 hclge_mbx_ring_ptr_move_crq(crq
);
257 trace_hclge_vf_mbx_get(hdev
, req
);
259 /* synchronous messages are time critical and need preferential
260 * treatment. Therefore, we need to acknowledge all the sync
261 * responses as quickly as possible so that waiting tasks do not
262 * timeout and simultaneously queue the async messages for later
263 * prcessing in context of mailbox task i.e. the slow path.
266 case HCLGE_MBX_PF_VF_RESP
:
267 hclgevf_handle_mbx_response(hdev
, req
);
269 case HCLGE_MBX_LINK_STAT_CHANGE
:
270 case HCLGE_MBX_ASSERTING_RESET
:
271 case HCLGE_MBX_LINK_STAT_MODE
:
272 case HCLGE_MBX_PUSH_VLAN_INFO
:
273 case HCLGE_MBX_PUSH_PROMISC_INFO
:
274 hclgevf_handle_mbx_msg(hdev
, req
);
277 dev_err(&hdev
->pdev
->dev
,
278 "VF received unsupported(%u) mbx msg from PF\n",
282 crq
->desc
[crq
->next_to_use
].flag
= 0;
283 hclge_mbx_ring_ptr_move_crq(crq
);
286 /* Write back CMDQ_RQ header pointer, M7 need this pointer */
287 hclgevf_write_dev(&hdev
->hw
, HCLGE_COMM_NIC_CRQ_HEAD_REG
,
291 static void hclgevf_parse_promisc_info(struct hclgevf_dev
*hdev
,
295 dev_info(&hdev
->pdev
->dev
,
296 "Promisc mode is closed by host for being untrusted.\n");
299 void hclgevf_mbx_async_handler(struct hclgevf_dev
*hdev
)
301 struct hclge_mbx_port_base_vlan
*vlan_info
;
302 struct hclge_mbx_link_status
*link_info
;
303 struct hclge_mbx_link_mode
*link_mode
;
304 enum hnae3_reset_type reset_type
;
305 u16 link_status
, state
;
314 tail
= hdev
->arq
.tail
;
316 /* process all the async queue messages */
317 while (tail
!= hdev
->arq
.head
) {
318 if (test_bit(HCLGE_COMM_STATE_CMD_DISABLE
,
319 &hdev
->hw
.hw
.comm_state
)) {
320 dev_info(&hdev
->pdev
->dev
,
321 "vf crq need init in async\n");
325 msg_q
= hdev
->arq
.msg_q
[hdev
->arq
.head
];
326 opcode
= le16_to_cpu(msg_q
[0]);
328 case HCLGE_MBX_LINK_STAT_CHANGE
:
329 link_info
= (struct hclge_mbx_link_status
*)(msg_q
+ 1);
330 link_status
= le16_to_cpu(link_info
->link_status
);
331 speed
= le32_to_cpu(link_info
->speed
);
332 duplex
= (u8
)le16_to_cpu(link_info
->duplex
);
333 flag
= link_info
->flag
;
335 /* update upper layer with new link link status */
336 hclgevf_update_speed_duplex(hdev
, speed
, duplex
);
337 hclgevf_update_link_status(hdev
, link_status
);
339 if (flag
& HCLGE_MBX_PUSH_LINK_STATUS_EN
)
340 set_bit(HCLGEVF_STATE_PF_PUSH_LINK_STATUS
,
344 case HCLGE_MBX_LINK_STAT_MODE
:
345 link_mode
= (struct hclge_mbx_link_mode
*)(msg_q
+ 1);
346 idx
= le16_to_cpu(link_mode
->idx
);
348 hdev
->hw
.mac
.supported
=
349 le64_to_cpu(link_mode
->link_mode
);
351 hdev
->hw
.mac
.advertising
=
352 le64_to_cpu(link_mode
->link_mode
);
354 case HCLGE_MBX_ASSERTING_RESET
:
355 /* PF has asserted reset hence VF should go in pending
356 * state and poll for the hardware reset status till it
357 * has been completely reset. After this stack should
358 * eventually be re-initialized.
361 (enum hnae3_reset_type
)le16_to_cpu(msg_q
[1]);
362 set_bit(reset_type
, &hdev
->reset_pending
);
363 set_bit(HCLGEVF_RESET_PENDING
, &hdev
->reset_state
);
364 hclgevf_reset_task_schedule(hdev
);
367 case HCLGE_MBX_PUSH_VLAN_INFO
:
369 (struct hclge_mbx_port_base_vlan
*)(msg_q
+ 1);
370 state
= le16_to_cpu(vlan_info
->state
);
371 hclgevf_update_port_base_vlan_info(hdev
, state
,
374 case HCLGE_MBX_PUSH_PROMISC_INFO
:
375 hclgevf_parse_promisc_info(hdev
, le16_to_cpu(msg_q
[1]));
378 dev_err(&hdev
->pdev
->dev
,
379 "fetched unsupported(%u) message from arq\n",
384 hclge_mbx_head_ptr_move_arq(hdev
->arq
);
385 atomic_dec(&hdev
->arq
.count
);
386 msg_q
= hdev
->arq
.msg_q
[hdev
->arq
.head
];