1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright (c) 2016-2017 Hisilicon Limited.
5 #include "hclgevf_main.h"
8 static void hclgevf_reset_mbx_resp_status(struct hclgevf_dev
*hdev
)
10 /* this function should be called with mbx_resp.mbx_mutex held
11 * to prtect the received_response from race condition
13 hdev
->mbx_resp
.received_resp
= false;
14 hdev
->mbx_resp
.origin_mbx_msg
= 0;
15 hdev
->mbx_resp
.resp_status
= 0;
16 memset(hdev
->mbx_resp
.additional_info
, 0, HCLGE_MBX_MAX_RESP_DATA_SIZE
);
19 /* hclgevf_get_mbx_resp: used to get a response from PF after VF sends a mailbox
21 * @hdev: pointer to struct hclgevf_dev
22 * @resp_msg: pointer to store the original message type and response status
23 * @len: the resp_msg data array length.
25 static int hclgevf_get_mbx_resp(struct hclgevf_dev
*hdev
, u16 code0
, u16 code1
,
26 u8
*resp_data
, u16 resp_len
)
28 #define HCLGEVF_MAX_TRY_TIMES 500
29 #define HCLGEVF_SLEEP_USCOEND 1000
30 struct hclgevf_mbx_resp_status
*mbx_resp
;
34 if (resp_len
> HCLGE_MBX_MAX_RESP_DATA_SIZE
) {
35 dev_err(&hdev
->pdev
->dev
,
36 "VF mbx response len(=%d) exceeds maximum(=%d)\n",
38 HCLGE_MBX_MAX_RESP_DATA_SIZE
);
42 while ((!hdev
->mbx_resp
.received_resp
) && (i
< HCLGEVF_MAX_TRY_TIMES
)) {
43 udelay(HCLGEVF_SLEEP_USCOEND
);
47 if (i
>= HCLGEVF_MAX_TRY_TIMES
) {
48 dev_err(&hdev
->pdev
->dev
,
49 "VF could not get mbx resp(=%d) from PF in %d tries\n",
50 hdev
->mbx_resp
.received_resp
, i
);
54 mbx_resp
= &hdev
->mbx_resp
;
55 r_code0
= (u16
)(mbx_resp
->origin_mbx_msg
>> 16);
56 r_code1
= (u16
)(mbx_resp
->origin_mbx_msg
& 0xff);
58 memcpy(resp_data
, &mbx_resp
->additional_info
[0], resp_len
);
60 hclgevf_reset_mbx_resp_status(hdev
);
62 if (!(r_code0
== code0
&& r_code1
== code1
&& !mbx_resp
->resp_status
)) {
63 dev_err(&hdev
->pdev
->dev
,
64 "VF could not match resp code(code0=%d,code1=%d), %d",
65 code0
, code1
, mbx_resp
->resp_status
);
72 int hclgevf_send_mbx_msg(struct hclgevf_dev
*hdev
, u16 code
, u16 subcode
,
73 const u8
*msg_data
, u8 msg_len
, bool need_resp
,
74 u8
*resp_data
, u16 resp_len
)
76 struct hclge_mbx_vf_to_pf_cmd
*req
;
77 struct hclgevf_desc desc
;
80 req
= (struct hclge_mbx_vf_to_pf_cmd
*)desc
.data
;
82 /* first two bytes are reserved for code & subcode */
83 if (msg_len
> (HCLGE_MBX_MAX_MSG_SIZE
- 2)) {
84 dev_err(&hdev
->pdev
->dev
,
85 "VF send mbx msg fail, msg len %d exceeds max len %d\n",
86 msg_len
, HCLGE_MBX_MAX_MSG_SIZE
);
90 hclgevf_cmd_setup_basic_desc(&desc
, HCLGEVF_OPC_MBX_VF_TO_PF
, false);
92 req
->msg
[1] = subcode
;
93 memcpy(&req
->msg
[2], msg_data
, msg_len
);
95 /* synchronous send */
97 mutex_lock(&hdev
->mbx_resp
.mbx_mutex
);
98 hclgevf_reset_mbx_resp_status(hdev
);
99 status
= hclgevf_cmd_send(&hdev
->hw
, &desc
, 1);
101 dev_err(&hdev
->pdev
->dev
,
102 "VF failed(=%d) to send mbx message to PF\n",
104 mutex_unlock(&hdev
->mbx_resp
.mbx_mutex
);
108 status
= hclgevf_get_mbx_resp(hdev
, code
, subcode
, resp_data
,
110 mutex_unlock(&hdev
->mbx_resp
.mbx_mutex
);
112 /* asynchronous send */
113 status
= hclgevf_cmd_send(&hdev
->hw
, &desc
, 1);
115 dev_err(&hdev
->pdev
->dev
,
116 "VF failed(=%d) to send mbx message to PF\n",
125 void hclgevf_mbx_handler(struct hclgevf_dev
*hdev
)
127 struct hclgevf_mbx_resp_status
*resp
;
128 struct hclge_mbx_pf_to_vf_cmd
*req
;
129 struct hclgevf_cmq_ring
*crq
;
130 struct hclgevf_desc
*desc
;
131 u16 link_status
, flag
;
135 resp
= &hdev
->mbx_resp
;
136 crq
= &hdev
->hw
.cmq
.crq
;
138 flag
= le16_to_cpu(crq
->desc
[crq
->next_to_use
].flag
);
139 while (hnae_get_bit(flag
, HCLGEVF_CMDQ_RX_OUTVLD_B
)) {
140 desc
= &crq
->desc
[crq
->next_to_use
];
141 req
= (struct hclge_mbx_pf_to_vf_cmd
*)desc
->data
;
143 switch (req
->msg
[0]) {
144 case HCLGE_MBX_PF_VF_RESP
:
145 if (resp
->received_resp
)
146 dev_warn(&hdev
->pdev
->dev
,
147 "VF mbx resp flag not clear(%d)\n",
149 resp
->received_resp
= true;
151 resp
->origin_mbx_msg
= (req
->msg
[1] << 16);
152 resp
->origin_mbx_msg
|= req
->msg
[2];
153 resp
->resp_status
= req
->msg
[3];
155 temp
= (u8
*)&req
->msg
[4];
156 for (i
= 0; i
< HCLGE_MBX_MAX_RESP_DATA_SIZE
; i
++) {
157 resp
->additional_info
[i
] = *temp
;
161 case HCLGE_MBX_LINK_STAT_CHANGE
:
162 link_status
= le16_to_cpu(req
->msg
[1]);
164 /* update upper layer with new link link status */
165 hclgevf_update_link_status(hdev
, link_status
);
169 dev_err(&hdev
->pdev
->dev
,
170 "VF received unsupported(%d) mbx msg from PF\n",
174 hclge_mbx_ring_ptr_move_crq(crq
);
175 flag
= le16_to_cpu(crq
->desc
[crq
->next_to_use
].flag
);
178 /* Write back CMDQ_RQ header pointer, M7 need this pointer */
179 hclgevf_write_dev(&hdev
->hw
, HCLGEVF_NIC_CRQ_HEAD_REG
,