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 {
#define ring_ptr_move_bw(ring, p) \
((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_queue {
......@@ -767,6 +760,7 @@ struct hnae3_knic_private_info {
u16 rx_buf_len;
u16 num_tx_desc;
u16 num_rx_desc;
u32 tx_spare_buf_size;
struct hnae3_tc_info tc_info;
......
......@@ -392,6 +392,56 @@ static void hns3_dbg_fill_content(char *content, u16 len,
*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[] = {
{ "QUEUE_ID", 2 },
{ "BD_NUM", 2 },
......@@ -400,6 +450,7 @@ static const struct hns3_dbg_item rx_queue_info_items[] = {
{ "HEAD", 2 },
{ "FBDNUM", 2 },
{ "PKTNUM", 2 },
{ "COPYBREAK", 2 },
{ "RING_EN", 2 },
{ "RX_RING_EN", 2 },
{ "BASE_ADDR", 10 },
......@@ -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 +
HNS3_RING_RX_RING_PKTNUM_RECORD_REG));
sprintf(result[j++], "%9u", ring->rx_copybreak);
sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base +
HNS3_RING_EN_REG) ? "on" : "off");
......@@ -593,6 +645,8 @@ static int hns3_dbg_tx_queue_info(struct hnae3_handle *h,
pos += scnprintf(buf + pos, len - pos, "%s", content);
}
hns3_dbg_tx_spare_info(ring, buf, len, h->kinfo.num_tqps, &pos);
return 0;
}
......
......@@ -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 {
dma_addr_t dma; /* dma address of this desc */
void *buf; /* cpu addr for a desc */
......@@ -398,6 +408,12 @@ struct ring_stats {
u64 tx_tso_err;
u64 over_max_recursion;
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 {
u64 rx_pkts;
......@@ -411,11 +427,22 @@ struct ring_stats {
u64 csum_complete;
u64 rx_multicast;
u64 non_reuse_pg;
u64 frag_alloc_err;
u64 frag_alloc;
};
__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_desc *desc; /* dma map address space */
struct hns3_desc_cb *desc_cb;
......@@ -438,18 +465,29 @@ struct hns3_enet_ring {
* next_to_use
*/
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 */
int pending_buf;
struct sk_buff *skb;
struct sk_buff *tail_skb;
union {
/* 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;
enum hns3_flow_level_range {
......@@ -533,6 +571,8 @@ struct hns3_nic_priv {
struct hns3_enet_coalesce tx_coal;
struct hns3_enet_coalesce rx_coal;
u32 tx_copybreak;
u32 rx_copybreak;
};
union l3_hdr_info {
......
......@@ -46,6 +46,12 @@ static const struct hns3_stats hns3_txq_stats[] = {
HNS3_TQP_STAT("tso_err", tx_tso_err),
HNS3_TQP_STAT("over_max_recursion", over_max_recursion),
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)
......@@ -65,6 +71,8 @@ static const struct hns3_stats hns3_rxq_stats[] = {
HNS3_TQP_STAT("csum_complete", csum_complete),
HNS3_TQP_STAT("multicast", rx_multicast),
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)
......@@ -1592,6 +1600,60 @@ static int hns3_set_priv_flags(struct net_device *netdev, u32 pflags)
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 | \
ETHTOOL_COALESCE_USE_ADAPTIVE | \
ETHTOOL_COALESCE_RX_USECS_HIGH | \
......@@ -1635,6 +1697,8 @@ static const struct ethtool_ops hns3vf_ethtool_ops = {
.set_msglevel = hns3_set_msglevel,
.get_priv_flags = hns3_get_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 = {
......@@ -1674,6 +1738,8 @@ static const struct ethtool_ops hns3_ethtool_ops = {
.get_priv_flags = hns3_get_priv_flags,
.set_priv_flags = hns3_set_priv_flags,
.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)
......
......@@ -542,6 +542,8 @@ struct hclge_pf_res_cmd {
#define HCLGE_CFG_UMV_TBL_SPACE_M GENMASK(31, 16)
#define HCLGE_CFG_PF_RSS_SIZE_S 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
......
......@@ -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)
{
#define HCLGE_TX_SPARE_SIZE_UNIT 4096
#define SPEED_ABILITY_EXT_SHIFT 8
struct hclge_cfg_param_cmd *req;
......@@ -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 ?
1U << cfg->pf_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
......@@ -1539,6 +1549,7 @@ static int hclge_configure(struct hclge_dev *hdev)
hdev->tc_max = cfg.tc_num;
hdev->tm_info.hw_pfc_map = 0;
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)
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,
kinfo->num_rx_desc = num_rx_desc;
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,
sizeof(struct hnae3_queue *), GFP_KERNEL);
......@@ -11059,6 +11071,8 @@ static void hclge_info_show(struct hclge_dev *hdev)
hdev->flag & HCLGE_FLAG_DCB_ENABLE ? "enable" : "disable");
dev_info(dev, "MQPRIO %s\n",
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");
}
......
......@@ -384,6 +384,7 @@ struct hclge_cfg {
u8 mac_addr[ETH_ALEN];
u8 default_speed;
u32 numa_node_map;
u32 tx_spare_buf_size;
u16 speed_ability;
u16 umv_space;
};
......@@ -848,6 +849,7 @@ struct hclge_dev {
u16 alloc_rss_size; /* Allocated 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 */
u32 tx_spare_buf_size; /* HW defined TX spare buffer size */
u16 fdir_pf_filter_count; /* Num of guaranteed filters for this PF */
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