aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXi Wang <wangxi11@huawei.com>2018-06-06 09:07:52 -0400
committerDavid S. Miller <davem@davemloft.net>2018-06-06 14:02:48 -0400
commit6444e2a5f1e680278b58ced3568bdff84afe14a5 (patch)
tree54d907607d58aa3a9820c7070ec76a159a209ff3
parent1819e40908ee76c7219287224c22c772556c927e (diff)
net: hns3: Fix for VF mailbox receiving unknown message
Before the firmware updates the crq's tail pointer, if the VF driver reads the data in the crq, the data may be incomplete at this time, which will lead to the driver read an unknown message. This patch fixes it by checking if crq is empty before reading the message. Fixes: b11a0bb231f3 ("net: hns3: Add mailbox support to VF driver") Signed-off-by: Xi Wang <wangxi11@huawei.com> Signed-off-by: Peng Li <lipeng321@huawei.com> Signed-off-by: Salil Mehta <salil.mehta@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
index a28618428338..b598c06af8e0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
@@ -126,6 +126,13 @@ int hclgevf_send_mbx_msg(struct hclgevf_dev *hdev, u16 code, u16 subcode,
126 return status; 126 return status;
127} 127}
128 128
129static bool hclgevf_cmd_crq_empty(struct hclgevf_hw *hw)
130{
131 u32 tail = hclgevf_read_dev(hw, HCLGEVF_NIC_CRQ_TAIL_REG);
132
133 return tail == hw->cmq.crq.next_to_use;
134}
135
129void hclgevf_mbx_handler(struct hclgevf_dev *hdev) 136void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
130{ 137{
131 struct hclgevf_mbx_resp_status *resp; 138 struct hclgevf_mbx_resp_status *resp;
@@ -140,11 +147,22 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
140 resp = &hdev->mbx_resp; 147 resp = &hdev->mbx_resp;
141 crq = &hdev->hw.cmq.crq; 148 crq = &hdev->hw.cmq.crq;
142 149
143 flag = le16_to_cpu(crq->desc[crq->next_to_use].flag); 150 while (!hclgevf_cmd_crq_empty(&hdev->hw)) {
144 while (hnae_get_bit(flag, HCLGEVF_CMDQ_RX_OUTVLD_B)) {
145 desc = &crq->desc[crq->next_to_use]; 151 desc = &crq->desc[crq->next_to_use];
146 req = (struct hclge_mbx_pf_to_vf_cmd *)desc->data; 152 req = (struct hclge_mbx_pf_to_vf_cmd *)desc->data;
147 153
154 flag = le16_to_cpu(crq->desc[crq->next_to_use].flag);
155 if (unlikely(!hnae_get_bit(flag, HCLGEVF_CMDQ_RX_OUTVLD_B))) {
156 dev_warn(&hdev->pdev->dev,
157 "dropped invalid mailbox message, code = %d\n",
158 req->msg[0]);
159
160 /* dropping/not processing this invalid message */
161 crq->desc[crq->next_to_use].flag = 0;
162 hclge_mbx_ring_ptr_move_crq(crq);
163 continue;
164 }
165
148 /* synchronous messages are time critical and need preferential 166 /* synchronous messages are time critical and need preferential
149 * treatment. Therefore, we need to acknowledge all the sync 167 * treatment. Therefore, we need to acknowledge all the sync
150 * responses as quickly as possible so that waiting tasks do not 168 * responses as quickly as possible so that waiting tasks do not
@@ -205,7 +223,6 @@ void hclgevf_mbx_handler(struct hclgevf_dev *hdev)
205 } 223 }
206 crq->desc[crq->next_to_use].flag = 0; 224 crq->desc[crq->next_to_use].flag = 0;
207 hclge_mbx_ring_ptr_move_crq(crq); 225 hclge_mbx_ring_ptr_move_crq(crq);
208 flag = le16_to_cpu(crq->desc[crq->next_to_use].flag);
209 } 226 }
210 227
211 /* Write back CMDQ_RQ header pointer, M7 need this pointer */ 228 /* Write back CMDQ_RQ header pointer, M7 need this pointer */