Commit 66aeec85 authored by David S. Miller's avatar David S. Miller

Merge branch 'hns3-next'

Guangbin Huang says:

====================
net: hns3: updates for -next

This series includes some optimization in IO path for the HNS3 ethernet
driver.
====================

Cc: Loic Poulain <loic.poulain@linaro.org>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: default avatarStephan Gerhold <stephan@gerhold.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a078d981 99f6b5fb
...@@ -159,13 +159,6 @@ enum HNAE3_PF_CAP_BITS { ...@@ -159,13 +159,6 @@ enum HNAE3_PF_CAP_BITS {
#define ring_ptr_move_bw(ring, p) \ #define ring_ptr_move_bw(ring, p) \
((ring)->p = ((ring)->p - 1 + (ring)->desc_num) % (ring)->desc_num) ((ring)->p = ((ring)->p - 1 + (ring)->desc_num) % (ring)->desc_num)
enum hns_desc_type {
DESC_TYPE_UNKNOWN,
DESC_TYPE_SKB,
DESC_TYPE_FRAGLIST_SKB,
DESC_TYPE_PAGE,
};
struct hnae3_handle; struct hnae3_handle;
struct hnae3_queue { struct hnae3_queue {
...@@ -767,6 +760,7 @@ struct hnae3_knic_private_info { ...@@ -767,6 +760,7 @@ struct hnae3_knic_private_info {
u16 rx_buf_len; u16 rx_buf_len;
u16 num_tx_desc; u16 num_tx_desc;
u16 num_rx_desc; u16 num_rx_desc;
u32 tx_spare_buf_size;
struct hnae3_tc_info tc_info; struct hnae3_tc_info tc_info;
......
...@@ -392,6 +392,56 @@ static void hns3_dbg_fill_content(char *content, u16 len, ...@@ -392,6 +392,56 @@ static void hns3_dbg_fill_content(char *content, u16 len,
*pos++ = '\0'; *pos++ = '\0';
} }
static const struct hns3_dbg_item tx_spare_info_items[] = {
{ "QUEUE_ID", 2 },
{ "COPYBREAK", 2 },
{ "LEN", 7 },
{ "NTU", 4 },
{ "NTC", 4 },
{ "LTC", 4 },
{ "DMA", 17 },
};
static void hns3_dbg_tx_spare_info(struct hns3_enet_ring *ring, char *buf,
int len, u32 ring_num, int *pos)
{
char data_str[ARRAY_SIZE(tx_spare_info_items)][HNS3_DBG_DATA_STR_LEN];
struct hns3_tx_spare *tx_spare = ring->tx_spare;
char *result[ARRAY_SIZE(tx_spare_info_items)];
char content[HNS3_DBG_INFO_LEN];
u32 i, j;
if (!tx_spare) {
*pos += scnprintf(buf + *pos, len - *pos,
"tx spare buffer is not enabled\n");
return;
}
for (i = 0; i < ARRAY_SIZE(tx_spare_info_items); i++)
result[i] = &data_str[i][0];
*pos += scnprintf(buf + *pos, len - *pos, "tx spare buffer info\n");
hns3_dbg_fill_content(content, sizeof(content), tx_spare_info_items,
NULL, ARRAY_SIZE(tx_spare_info_items));
*pos += scnprintf(buf + *pos, len - *pos, "%s", content);
for (i = 0; i < ring_num; i++) {
j = 0;
sprintf(result[j++], "%8u", i);
sprintf(result[j++], "%9u", ring->tx_copybreak);
sprintf(result[j++], "%3u", tx_spare->len);
sprintf(result[j++], "%3u", tx_spare->next_to_use);
sprintf(result[j++], "%3u", tx_spare->next_to_clean);
sprintf(result[j++], "%3u", tx_spare->last_to_clean);
sprintf(result[j++], "%pad", &tx_spare->dma);
hns3_dbg_fill_content(content, sizeof(content),
tx_spare_info_items,
(const char **)result,
ARRAY_SIZE(tx_spare_info_items));
*pos += scnprintf(buf + *pos, len - *pos, "%s", content);
}
}
static const struct hns3_dbg_item rx_queue_info_items[] = { static const struct hns3_dbg_item rx_queue_info_items[] = {
{ "QUEUE_ID", 2 }, { "QUEUE_ID", 2 },
{ "BD_NUM", 2 }, { "BD_NUM", 2 },
...@@ -400,6 +450,7 @@ static const struct hns3_dbg_item rx_queue_info_items[] = { ...@@ -400,6 +450,7 @@ static const struct hns3_dbg_item rx_queue_info_items[] = {
{ "HEAD", 2 }, { "HEAD", 2 },
{ "FBDNUM", 2 }, { "FBDNUM", 2 },
{ "PKTNUM", 2 }, { "PKTNUM", 2 },
{ "COPYBREAK", 2 },
{ "RING_EN", 2 }, { "RING_EN", 2 },
{ "RX_RING_EN", 2 }, { "RX_RING_EN", 2 },
{ "BASE_ADDR", 10 }, { "BASE_ADDR", 10 },
...@@ -431,6 +482,7 @@ static void hns3_dump_rx_queue_info(struct hns3_enet_ring *ring, ...@@ -431,6 +482,7 @@ static void hns3_dump_rx_queue_info(struct hns3_enet_ring *ring,
sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base +
HNS3_RING_RX_RING_PKTNUM_RECORD_REG)); HNS3_RING_RX_RING_PKTNUM_RECORD_REG));
sprintf(result[j++], "%9u", ring->rx_copybreak);
sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base + sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base +
HNS3_RING_EN_REG) ? "on" : "off"); HNS3_RING_EN_REG) ? "on" : "off");
...@@ -593,6 +645,8 @@ static int hns3_dbg_tx_queue_info(struct hnae3_handle *h, ...@@ -593,6 +645,8 @@ static int hns3_dbg_tx_queue_info(struct hnae3_handle *h,
pos += scnprintf(buf + pos, len - pos, "%s", content); pos += scnprintf(buf + pos, len - pos, "%s", content);
} }
hns3_dbg_tx_spare_info(ring, buf, len, h->kinfo.num_tqps, &pos);
return 0; return 0;
} }
......
...@@ -299,6 +299,16 @@ struct __packed hns3_desc { ...@@ -299,6 +299,16 @@ struct __packed hns3_desc {
}; };
}; };
enum hns3_desc_type {
DESC_TYPE_UNKNOWN = 0,
DESC_TYPE_SKB = 1 << 0,
DESC_TYPE_FRAGLIST_SKB = 1 << 1,
DESC_TYPE_PAGE = 1 << 2,
DESC_TYPE_BOUNCE_ALL = 1 << 3,
DESC_TYPE_BOUNCE_HEAD = 1 << 4,
DESC_TYPE_SGL_SKB = 1 << 5,
};
struct hns3_desc_cb { struct hns3_desc_cb {
dma_addr_t dma; /* dma address of this desc */ dma_addr_t dma; /* dma address of this desc */
void *buf; /* cpu addr for a desc */ void *buf; /* cpu addr for a desc */
...@@ -398,6 +408,12 @@ struct ring_stats { ...@@ -398,6 +408,12 @@ struct ring_stats {
u64 tx_tso_err; u64 tx_tso_err;
u64 over_max_recursion; u64 over_max_recursion;
u64 hw_limitation; u64 hw_limitation;
u64 tx_bounce;
u64 tx_spare_full;
u64 copy_bits_err;
u64 tx_sgl;
u64 skb2sgl_err;
u64 map_sg_err;
}; };
struct { struct {
u64 rx_pkts; u64 rx_pkts;
...@@ -411,11 +427,22 @@ struct ring_stats { ...@@ -411,11 +427,22 @@ struct ring_stats {
u64 csum_complete; u64 csum_complete;
u64 rx_multicast; u64 rx_multicast;
u64 non_reuse_pg; u64 non_reuse_pg;
u64 frag_alloc_err;
u64 frag_alloc;
}; };
__le16 csum; __le16 csum;
}; };
}; };
struct hns3_tx_spare {
dma_addr_t dma;
void *buf;
u32 next_to_use;
u32 next_to_clean;
u32 last_to_clean;
u32 len;
};
struct hns3_enet_ring { struct hns3_enet_ring {
struct hns3_desc *desc; /* dma map address space */ struct hns3_desc *desc; /* dma map address space */
struct hns3_desc_cb *desc_cb; struct hns3_desc_cb *desc_cb;
...@@ -438,18 +465,29 @@ struct hns3_enet_ring { ...@@ -438,18 +465,29 @@ struct hns3_enet_ring {
* next_to_use * next_to_use
*/ */
int next_to_clean; int next_to_clean;
union {
int last_to_use; /* last idx used by xmit */
u32 pull_len; /* memcpy len for current rx packet */
};
u32 frag_num;
void *va; /* first buffer address for current packet */
u32 flag; /* ring attribute */ u32 flag; /* ring attribute */
int pending_buf; int pending_buf;
struct sk_buff *skb; union {
struct sk_buff *tail_skb; /* for Tx ring */
struct {
u32 fd_qb_tx_sample;
int last_to_use; /* last idx used by xmit */
u32 tx_copybreak;
struct hns3_tx_spare *tx_spare;
};
/* for Rx ring */
struct {
u32 pull_len; /* memcpy len for current rx packet */
u32 rx_copybreak;
u32 frag_num;
/* first buffer address for current packet */
unsigned char *va;
struct sk_buff *skb;
struct sk_buff *tail_skb;
};
};
} ____cacheline_internodealigned_in_smp; } ____cacheline_internodealigned_in_smp;
enum hns3_flow_level_range { enum hns3_flow_level_range {
...@@ -533,6 +571,8 @@ struct hns3_nic_priv { ...@@ -533,6 +571,8 @@ struct hns3_nic_priv {
struct hns3_enet_coalesce tx_coal; struct hns3_enet_coalesce tx_coal;
struct hns3_enet_coalesce rx_coal; struct hns3_enet_coalesce rx_coal;
u32 tx_copybreak;
u32 rx_copybreak;
}; };
union l3_hdr_info { union l3_hdr_info {
......
...@@ -46,6 +46,12 @@ static const struct hns3_stats hns3_txq_stats[] = { ...@@ -46,6 +46,12 @@ static const struct hns3_stats hns3_txq_stats[] = {
HNS3_TQP_STAT("tso_err", tx_tso_err), HNS3_TQP_STAT("tso_err", tx_tso_err),
HNS3_TQP_STAT("over_max_recursion", over_max_recursion), HNS3_TQP_STAT("over_max_recursion", over_max_recursion),
HNS3_TQP_STAT("hw_limitation", hw_limitation), HNS3_TQP_STAT("hw_limitation", hw_limitation),
HNS3_TQP_STAT("bounce", tx_bounce),
HNS3_TQP_STAT("spare_full", tx_spare_full),
HNS3_TQP_STAT("copy_bits_err", copy_bits_err),
HNS3_TQP_STAT("sgl", tx_sgl),
HNS3_TQP_STAT("skb2sgl_err", skb2sgl_err),
HNS3_TQP_STAT("map_sg_err", map_sg_err),
}; };
#define HNS3_TXQ_STATS_COUNT ARRAY_SIZE(hns3_txq_stats) #define HNS3_TXQ_STATS_COUNT ARRAY_SIZE(hns3_txq_stats)
...@@ -65,6 +71,8 @@ static const struct hns3_stats hns3_rxq_stats[] = { ...@@ -65,6 +71,8 @@ static const struct hns3_stats hns3_rxq_stats[] = {
HNS3_TQP_STAT("csum_complete", csum_complete), HNS3_TQP_STAT("csum_complete", csum_complete),
HNS3_TQP_STAT("multicast", rx_multicast), HNS3_TQP_STAT("multicast", rx_multicast),
HNS3_TQP_STAT("non_reuse_pg", non_reuse_pg), HNS3_TQP_STAT("non_reuse_pg", non_reuse_pg),
HNS3_TQP_STAT("frag_alloc_err", frag_alloc_err),
HNS3_TQP_STAT("frag_alloc", frag_alloc),
}; };
#define HNS3_PRIV_FLAGS_LEN ARRAY_SIZE(hns3_priv_flags) #define HNS3_PRIV_FLAGS_LEN ARRAY_SIZE(hns3_priv_flags)
...@@ -1592,6 +1600,60 @@ static int hns3_set_priv_flags(struct net_device *netdev, u32 pflags) ...@@ -1592,6 +1600,60 @@ static int hns3_set_priv_flags(struct net_device *netdev, u32 pflags)
return 0; return 0;
} }
static int hns3_get_tunable(struct net_device *netdev,
const struct ethtool_tunable *tuna,
void *data)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
int ret = 0;
switch (tuna->id) {
case ETHTOOL_TX_COPYBREAK:
/* all the tx rings have the same tx_copybreak */
*(u32 *)data = priv->tx_copybreak;
break;
case ETHTOOL_RX_COPYBREAK:
*(u32 *)data = priv->rx_copybreak;
break;
default:
ret = -EOPNOTSUPP;
break;
}
return ret;
}
static int hns3_set_tunable(struct net_device *netdev,
const struct ethtool_tunable *tuna,
const void *data)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = priv->ae_handle;
int i, ret = 0;
switch (tuna->id) {
case ETHTOOL_TX_COPYBREAK:
priv->tx_copybreak = *(u32 *)data;
for (i = 0; i < h->kinfo.num_tqps; i++)
priv->ring[i].tx_copybreak = priv->tx_copybreak;
break;
case ETHTOOL_RX_COPYBREAK:
priv->rx_copybreak = *(u32 *)data;
for (i = h->kinfo.num_tqps; i < h->kinfo.num_tqps * 2; i++)
priv->ring[i].rx_copybreak = priv->rx_copybreak;
break;
default:
ret = -EOPNOTSUPP;
break;
}
return ret;
}
#define HNS3_ETHTOOL_COALESCE (ETHTOOL_COALESCE_USECS | \ #define HNS3_ETHTOOL_COALESCE (ETHTOOL_COALESCE_USECS | \
ETHTOOL_COALESCE_USE_ADAPTIVE | \ ETHTOOL_COALESCE_USE_ADAPTIVE | \
ETHTOOL_COALESCE_RX_USECS_HIGH | \ ETHTOOL_COALESCE_RX_USECS_HIGH | \
...@@ -1635,6 +1697,8 @@ static const struct ethtool_ops hns3vf_ethtool_ops = { ...@@ -1635,6 +1697,8 @@ static const struct ethtool_ops hns3vf_ethtool_ops = {
.set_msglevel = hns3_set_msglevel, .set_msglevel = hns3_set_msglevel,
.get_priv_flags = hns3_get_priv_flags, .get_priv_flags = hns3_get_priv_flags,
.set_priv_flags = hns3_set_priv_flags, .set_priv_flags = hns3_set_priv_flags,
.get_tunable = hns3_get_tunable,
.set_tunable = hns3_set_tunable,
}; };
static const struct ethtool_ops hns3_ethtool_ops = { static const struct ethtool_ops hns3_ethtool_ops = {
...@@ -1674,6 +1738,8 @@ static const struct ethtool_ops hns3_ethtool_ops = { ...@@ -1674,6 +1738,8 @@ static const struct ethtool_ops hns3_ethtool_ops = {
.get_priv_flags = hns3_get_priv_flags, .get_priv_flags = hns3_get_priv_flags,
.set_priv_flags = hns3_set_priv_flags, .set_priv_flags = hns3_set_priv_flags,
.get_ts_info = hns3_get_ts_info, .get_ts_info = hns3_get_ts_info,
.get_tunable = hns3_get_tunable,
.set_tunable = hns3_set_tunable,
}; };
void hns3_ethtool_set_ops(struct net_device *netdev) void hns3_ethtool_set_ops(struct net_device *netdev)
......
...@@ -542,6 +542,8 @@ struct hclge_pf_res_cmd { ...@@ -542,6 +542,8 @@ struct hclge_pf_res_cmd {
#define HCLGE_CFG_UMV_TBL_SPACE_M GENMASK(31, 16) #define HCLGE_CFG_UMV_TBL_SPACE_M GENMASK(31, 16)
#define HCLGE_CFG_PF_RSS_SIZE_S 0 #define HCLGE_CFG_PF_RSS_SIZE_S 0
#define HCLGE_CFG_PF_RSS_SIZE_M GENMASK(3, 0) #define HCLGE_CFG_PF_RSS_SIZE_M GENMASK(3, 0)
#define HCLGE_CFG_TX_SPARE_BUF_SIZE_S 4
#define HCLGE_CFG_TX_SPARE_BUF_SIZE_M GENMASK(15, 4)
#define HCLGE_CFG_CMD_CNT 4 #define HCLGE_CFG_CMD_CNT 4
......
...@@ -1279,6 +1279,7 @@ static u32 hclge_get_max_speed(u16 speed_ability) ...@@ -1279,6 +1279,7 @@ static u32 hclge_get_max_speed(u16 speed_ability)
static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc) static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc)
{ {
#define HCLGE_TX_SPARE_SIZE_UNIT 4096
#define SPEED_ABILITY_EXT_SHIFT 8 #define SPEED_ABILITY_EXT_SHIFT 8
struct hclge_cfg_param_cmd *req; struct hclge_cfg_param_cmd *req;
...@@ -1358,6 +1359,15 @@ static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc) ...@@ -1358,6 +1359,15 @@ static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc)
cfg->pf_rss_size_max = cfg->pf_rss_size_max ? cfg->pf_rss_size_max = cfg->pf_rss_size_max ?
1U << cfg->pf_rss_size_max : 1U << cfg->pf_rss_size_max :
cfg->vf_rss_size_max; cfg->vf_rss_size_max;
/* The unit of the tx spare buffer size queried from configuration
* file is HCLGE_TX_SPARE_SIZE_UNIT(4096) bytes, so a conversion is
* needed here.
*/
cfg->tx_spare_buf_size = hnae3_get_field(__le32_to_cpu(req->param[2]),
HCLGE_CFG_TX_SPARE_BUF_SIZE_M,
HCLGE_CFG_TX_SPARE_BUF_SIZE_S);
cfg->tx_spare_buf_size *= HCLGE_TX_SPARE_SIZE_UNIT;
} }
/* hclge_get_cfg: query the static parameter from flash /* hclge_get_cfg: query the static parameter from flash
...@@ -1539,6 +1549,7 @@ static int hclge_configure(struct hclge_dev *hdev) ...@@ -1539,6 +1549,7 @@ static int hclge_configure(struct hclge_dev *hdev)
hdev->tc_max = cfg.tc_num; hdev->tc_max = cfg.tc_num;
hdev->tm_info.hw_pfc_map = 0; hdev->tm_info.hw_pfc_map = 0;
hdev->wanted_umv_size = cfg.umv_space; hdev->wanted_umv_size = cfg.umv_space;
hdev->tx_spare_buf_size = cfg.tx_spare_buf_size;
if (cfg.vlan_fliter_cap == HCLGE_VLAN_FLTR_CAN_MDF) if (cfg.vlan_fliter_cap == HCLGE_VLAN_FLTR_CAN_MDF)
set_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps); set_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps);
...@@ -1736,6 +1747,7 @@ static int hclge_knic_setup(struct hclge_vport *vport, u16 num_tqps, ...@@ -1736,6 +1747,7 @@ static int hclge_knic_setup(struct hclge_vport *vport, u16 num_tqps,
kinfo->num_rx_desc = num_rx_desc; kinfo->num_rx_desc = num_rx_desc;
kinfo->rx_buf_len = hdev->rx_buf_len; kinfo->rx_buf_len = hdev->rx_buf_len;
kinfo->tx_spare_buf_size = hdev->tx_spare_buf_size;
kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, num_tqps, kinfo->tqp = devm_kcalloc(&hdev->pdev->dev, num_tqps,
sizeof(struct hnae3_queue *), GFP_KERNEL); sizeof(struct hnae3_queue *), GFP_KERNEL);
...@@ -11059,6 +11071,8 @@ static void hclge_info_show(struct hclge_dev *hdev) ...@@ -11059,6 +11071,8 @@ static void hclge_info_show(struct hclge_dev *hdev)
hdev->flag & HCLGE_FLAG_DCB_ENABLE ? "enable" : "disable"); hdev->flag & HCLGE_FLAG_DCB_ENABLE ? "enable" : "disable");
dev_info(dev, "MQPRIO %s\n", dev_info(dev, "MQPRIO %s\n",
hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE ? "enable" : "disable"); hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE ? "enable" : "disable");
dev_info(dev, "Default tx spare buffer size: %u\n",
hdev->tx_spare_buf_size);
dev_info(dev, "PF info end.\n"); dev_info(dev, "PF info end.\n");
} }
......
...@@ -384,6 +384,7 @@ struct hclge_cfg { ...@@ -384,6 +384,7 @@ struct hclge_cfg {
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN];
u8 default_speed; u8 default_speed;
u32 numa_node_map; u32 numa_node_map;
u32 tx_spare_buf_size;
u16 speed_ability; u16 speed_ability;
u16 umv_space; u16 umv_space;
}; };
...@@ -848,6 +849,7 @@ struct hclge_dev { ...@@ -848,6 +849,7 @@ struct hclge_dev {
u16 alloc_rss_size; /* Allocated RSS task queue */ u16 alloc_rss_size; /* Allocated RSS task queue */
u16 vf_rss_size_max; /* HW defined VF max RSS task queue */ u16 vf_rss_size_max; /* HW defined VF max RSS task queue */
u16 pf_rss_size_max; /* HW defined PF max RSS task queue */ u16 pf_rss_size_max; /* HW defined PF max RSS task queue */
u32 tx_spare_buf_size; /* HW defined TX spare buffer size */
u16 fdir_pf_filter_count; /* Num of guaranteed filters for this PF */ u16 fdir_pf_filter_count; /* Num of guaranteed filters for this PF */
u16 num_alloc_vport; /* Num vports this driver supports */ u16 num_alloc_vport; /* Num vports this driver supports */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment