net: hns3: Add support for PFC setting in TM module
authorYunsheng Lin <linyunsheng@huawei.com>
Wed, 27 Sep 2017 01:45:25 +0000 (09:45 +0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 28 Sep 2017 17:35:11 +0000 (10:35 -0700)
This patch add a pfc_pause_en cmd, and use it to configure
PFC option according to fc_mode in hdev->tm_info.

Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h

index 73a75d7cc5517819b8135324dbc481a0aa993423..0b4b5d9b07982db14c99c948a79c8660ab6bf2f5 100644 (file)
@@ -124,6 +124,20 @@ static int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx)
        return hclge_cmd_send(&hdev->hw, &desc, 1);
 }
 
+static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap,
+                                 u8 pfc_bitmap)
+{
+       struct hclge_desc desc;
+       struct hclge_pfc_en_cmd *pfc = (struct hclge_pfc_en_cmd *)&desc.data;
+
+       hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PFC_PAUSE_EN, false);
+
+       pfc->tx_rx_en_bitmap = tx_rx_bitmap;
+       pfc->pri_en_bitmap = pfc_bitmap;
+
+       return hclge_cmd_send(&hdev->hw, &desc, 1);
+}
+
 static int hclge_fill_pri_array(struct hclge_dev *hdev, u8 *pri, u8 pri_id)
 {
        u8 tc;
@@ -969,20 +983,64 @@ static int hclge_tm_schd_setup_hw(struct hclge_dev *hdev)
        return hclge_tm_schd_mode_hw(hdev);
 }
 
+static int hclge_pfc_setup_hw(struct hclge_dev *hdev)
+{
+       u8 enable_bitmap = 0;
+
+       if (hdev->tm_info.fc_mode == HCLGE_FC_PFC)
+               enable_bitmap = HCLGE_TX_MAC_PAUSE_EN_MSK |
+                               HCLGE_RX_MAC_PAUSE_EN_MSK;
+
+       return hclge_pfc_pause_en_cfg(hdev, enable_bitmap,
+                                     hdev->tm_info.hw_pfc_map);
+}
+
+static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev)
+{
+       bool tx_en, rx_en;
+
+       switch (hdev->tm_info.fc_mode) {
+       case HCLGE_FC_NONE:
+               tx_en = false;
+               rx_en = false;
+               break;
+       case HCLGE_FC_RX_PAUSE:
+               tx_en = false;
+               rx_en = true;
+               break;
+       case HCLGE_FC_TX_PAUSE:
+               tx_en = true;
+               rx_en = false;
+               break;
+       case HCLGE_FC_FULL:
+               tx_en = true;
+               rx_en = true;
+               break;
+       default:
+               tx_en = true;
+               rx_en = true;
+       }
+
+       return hclge_mac_pause_en_cfg(hdev, tx_en, rx_en);
+}
+
 int hclge_pause_setup_hw(struct hclge_dev *hdev)
 {
-       bool en = hdev->tm_info.fc_mode != HCLGE_FC_PFC;
        int ret;
        u8 i;
 
-       ret = hclge_mac_pause_en_cfg(hdev, en, en);
-       if (ret)
-               return ret;
+       if (hdev->tm_info.fc_mode != HCLGE_FC_PFC)
+               return hclge_mac_pause_setup_hw(hdev);
 
-       /* Only DCB-supported dev supports qset back pressure setting */
+       /* Only DCB-supported dev supports qset back pressure and pfc cmd */
        if (!hnae3_dev_dcb_supported(hdev))
                return 0;
 
+       /* When MAC is GE Mode, hdev does not support pfc setting */
+       ret = hclge_pfc_setup_hw(hdev);
+       if (ret)
+               dev_warn(&hdev->pdev->dev, "set pfc pause failed:%d\n", ret);
+
        for (i = 0; i < hdev->tm_info.num_tc; i++) {
                ret = hclge_tm_qs_bp_cfg(hdev, i);
                if (ret)
index 85158b0d73fe395ffa90de916c789e5afca5d15a..8ecd83c50f47f7a66848d473d27a136801d5dfd2 100644 (file)
@@ -94,6 +94,11 @@ struct hclge_bp_to_qs_map_cmd {
        u32 rsvd1;
 };
 
+struct hclge_pfc_en_cmd {
+       u8 tx_rx_en_bitmap;
+       u8 pri_en_bitmap;
+};
+
 #define hclge_tm_set_field(dest, string, val) \
                        hnae_set_field((dest), (HCLGE_TM_SHAP_##string##_MSK), \
                                       (HCLGE_TM_SHAP_##string##_LSH), val)