From caeef6247aa6f5250d14108b33cef5458ba6c58e Mon Sep 17 00:00:00 2001 From: Yunsheng Lin Date: Tue, 18 Dec 2018 19:37:57 +0800 Subject: [PATCH 20/31] net: hns3: getting tx and dv buffer size through firmware Origin: https://git.kernel.org/linus/368686be234daf365ef184a6ee1c4a6c18ede3b1 This patch adds support of getting tx and dv buffer size through firmware, because different version of hardware requires different size of tx and dv buffer. This patch also add dv_buf_size to tc' private buffer size even if pfc is not enable for the tc. Signed-off-by: Yunsheng Lin Signed-off-by: Peng Li Signed-off-by: David S. Miller --- .../hisilicon/hns3/hns3pf/hclge_cmd.h | 5 ++- .../hisilicon/hns3/hns3pf/hclge_main.c | 41 ++++++++++++++----- .../hisilicon/hns3/hns3pf/hclge_main.h | 3 ++ 3 files changed, 38 insertions(+), 11 deletions(-) Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h =================================================================== --- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -365,7 +365,9 @@ struct hclge_pf_res_cmd { #define HCLGE_PF_VEC_NUM_M GENMASK(7, 0) __le16 pf_intr_vector_number; __le16 pf_own_fun_number; - __le32 rsv[3]; + __le16 tx_buf_size; + __le16 dv_buf_size; + __le32 rsv[2]; }; #define HCLGE_CFG_OFFSET_S 0 @@ -791,6 +793,7 @@ struct hclge_serdes_lb_cmd { #define HCLGE_TOTAL_PKT_BUF 0x108000 /* 1.03125M bytes */ #define HCLGE_DEFAULT_DV 0xA000 /* 40k byte */ #define HCLGE_DEFAULT_NON_DCB_DV 0x7800 /* 30K byte */ +#define HCLGE_NON_DCB_ADDITIONAL_BUF 0x200 /* 512 byte */ #define HCLGE_TYPE_CRQ 0 #define HCLGE_TYPE_CSQ 1 Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c =================================================================== --- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -931,6 +931,18 @@ static int hclge_query_pf_resource(struc hdev->num_tqps = __le16_to_cpu(req->tqp_num); hdev->pkt_buf_size = __le16_to_cpu(req->buf_size) << HCLGE_BUF_UNIT_S; + if (req->tx_buf_size) + hdev->tx_buf_size = + __le16_to_cpu(req->tx_buf_size) << HCLGE_BUF_UNIT_S; + else + hdev->tx_buf_size = HCLGE_DEFAULT_TX_BUF; + + if (req->dv_buf_size) + hdev->dv_buf_size = + __le16_to_cpu(req->dv_buf_size) << HCLGE_BUF_UNIT_S; + else + hdev->dv_buf_size = HCLGE_DEFAULT_DV; + if (hnae3_dev_roce_supported(hdev)) { hdev->roce_base_msix_offset = hnae3_get_field(__le16_to_cpu(req->msixcap_localid_ba_rocee), @@ -1591,9 +1603,10 @@ static bool hclge_is_rx_buf_ok(struct h pfc_enable_num = hclge_get_pfc_enalbe_num(hdev); if (hnae3_dev_dcb_supported(hdev)) - shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_DV; + shared_buf_min = 2 * hdev->mps + hdev->dv_buf_size; else - shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_NON_DCB_DV; + shared_buf_min = hdev->mps + HCLGE_NON_DCB_ADDITIONAL_BUF + + hdev->dv_buf_size; shared_buf_tc = pfc_enable_num * hdev->mps + (tc_num - pfc_enable_num) * hdev->mps / 2 + @@ -1606,8 +1619,15 @@ static bool hclge_is_rx_buf_ok(struct h shared_buf = rx_all - rx_priv; buf_alloc->s_buf.buf_size = shared_buf; - buf_alloc->s_buf.self.high = shared_buf; - buf_alloc->s_buf.self.low = 2 * hdev->mps; + if (hnae3_dev_dcb_supported(hdev)) { + buf_alloc->s_buf.self.high = shared_buf - hdev->dv_buf_size; + buf_alloc->s_buf.self.low = buf_alloc->s_buf.self.high + - hdev->mps / 2; + } else { + buf_alloc->s_buf.self.high = hdev->mps + + HCLGE_NON_DCB_ADDITIONAL_BUF; + buf_alloc->s_buf.self.low = hdev->mps / 2; + } for (i = 0; i < HCLGE_MAX_TC_NUM; i++) { if ((hdev->hw_tc_map & BIT(i)) && @@ -1634,11 +1654,11 @@ static int hclge_tx_buffer_calc(struct h for (i = 0; i < HCLGE_MAX_TC_NUM; i++) { struct hclge_priv_buf *priv = &buf_alloc->priv_buf[i]; - if (total_size < HCLGE_DEFAULT_TX_BUF) + if (total_size < hdev->tx_buf_size) return -ENOMEM; if (hdev->hw_tc_map & BIT(i)) - priv->tx_buf_size = HCLGE_DEFAULT_TX_BUF; + priv->tx_buf_size = hdev->tx_buf_size; else priv->tx_buf_size = 0; @@ -1684,11 +1704,12 @@ static int hclge_rx_buffer_calc(struct h priv->wl.low = aligned_mps; priv->wl.high = priv->wl.low + aligned_mps; priv->buf_size = priv->wl.high + - HCLGE_DEFAULT_DV; + hdev->dv_buf_size; } else { priv->wl.low = 0; priv->wl.high = 2 * aligned_mps; - priv->buf_size = priv->wl.high; + priv->buf_size = priv->wl.high + + hdev->dv_buf_size; } } else { priv->enable = 0; @@ -1720,11 +1741,11 @@ static int hclge_rx_buffer_calc(struct h if (hdev->tm_info.hw_pfc_map & BIT(i)) { priv->wl.low = 128; priv->wl.high = priv->wl.low + aligned_mps; - priv->buf_size = priv->wl.high + HCLGE_DEFAULT_DV; + priv->buf_size = priv->wl.high + hdev->dv_buf_size; } else { priv->wl.low = 0; priv->wl.high = aligned_mps; - priv->buf_size = priv->wl.high; + priv->buf_size = priv->wl.high + hdev->dv_buf_size; } } Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h =================================================================== --- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -545,6 +545,9 @@ struct hclge_dev { u32 flag; u32 pkt_buf_size; /* Total pf buf size for tx/rx */ + u32 tx_buf_size; /* Tx buffer size for each TC */ + u32 dv_buf_size; /* Dv buffer size for each TC */ + u32 mps; /* Max packet size */ enum hclge_mta_dmac_sel_type mta_mac_sel_type;