net: hns3: simplify hclgevf_cmd_csq_clean
authorHuazhong Tan <tanhuazhong@huawei.com>
Thu, 4 Apr 2019 08:17:54 +0000 (16:17 +0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 4 Apr 2019 17:20:39 +0000 (10:20 -0700)
csq is used as a ring buffer, the value of the desc will be replaced
in next use. This patch removes the unnecessary memset, and just
updates the next_to_clean.

Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c

index 9441b453d38dfa9ac382e3c9f0e330aed09ab445..930b175a70903ab1cbdd026166d606fa8855850c 100644 (file)
@@ -27,26 +27,39 @@ static int hclgevf_ring_space(struct hclgevf_cmq_ring *ring)
        return ring->desc_num - used - 1;
 }
 
+static int hclgevf_is_valid_csq_clean_head(struct hclgevf_cmq_ring *ring,
+                                          int head)
+{
+       int ntu = ring->next_to_use;
+       int ntc = ring->next_to_clean;
+
+       if (ntu > ntc)
+               return head >= ntc && head <= ntu;
+
+       return head >= ntc || head <= ntu;
+}
+
 static int hclgevf_cmd_csq_clean(struct hclgevf_hw *hw)
 {
+       struct hclgevf_dev *hdev = container_of(hw, struct hclgevf_dev, hw);
        struct hclgevf_cmq_ring *csq = &hw->cmq.csq;
-       u16 ntc = csq->next_to_clean;
-       struct hclgevf_desc *desc;
        int clean = 0;
        u32 head;
 
-       desc = &csq->desc[ntc];
        head = hclgevf_read_dev(hw, HCLGEVF_NIC_CSQ_HEAD_REG);
-       while (head != ntc) {
-               memset(desc, 0, sizeof(*desc));
-               ntc++;
-               if (ntc == csq->desc_num)
-                       ntc = 0;
-               desc = &csq->desc[ntc];
-               clean++;
+       rmb(); /* Make sure head is ready before touch any data */
+
+       if (!hclgevf_is_valid_csq_clean_head(csq, head)) {
+               dev_warn(&hdev->pdev->dev, "wrong cmd head (%d, %d-%d)\n", head,
+                        csq->next_to_use, csq->next_to_clean);
+               dev_warn(&hdev->pdev->dev,
+                        "Disabling any further commands to IMP firmware\n");
+               set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state);
+               return -EIO;
        }
-       csq->next_to_clean = ntc;
 
+       clean = (head - csq->next_to_clean + csq->desc_num) % csq->desc_num;
+       csq->next_to_clean = head;
        return clean;
 }