Commit a7105e34 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'hns3-next'



Huazhong Tan says:

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

This patchset adds support for tc mqprio offload, hw tc
offload of tc flower, and adpation for max rss size changes.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c0ead555 cdab7c97
Loading
Loading
Loading
Loading
+24 −10
Original line number Diff line number Diff line
@@ -29,7 +29,9 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/pkt_sched.h>
#include <linux/types.h>
#include <net/pkt_cls.h>

#define HNAE3_MOD_VERSION "1.0"

@@ -457,6 +459,12 @@ struct hnae3_ae_dev {
 *   Configure the default MAC for specified VF
 * get_module_eeprom
 *   Get the optical module eeprom info.
 * add_cls_flower
 *   Add clsflower rule
 * del_cls_flower
 *   Delete clsflower rule
 * cls_flower_active
 *   Check if any cls flower rule exist
 */
struct hnae3_ae_ops {
	int (*init_ae_dev)(struct hnae3_ae_dev *ae_dev);
@@ -634,6 +642,11 @@ struct hnae3_ae_ops {
	int (*get_module_eeprom)(struct hnae3_handle *handle, u32 offset,
				 u32 len, u8 *data);
	bool (*get_cmdq_stat)(struct hnae3_handle *handle);
	int (*add_cls_flower)(struct hnae3_handle *handle,
			      struct flow_cls_offload *cls_flower, int tc);
	int (*del_cls_flower)(struct hnae3_handle *handle,
			      struct flow_cls_offload *cls_flower);
	bool (*cls_flower_active)(struct hnae3_handle *handle);
};

struct hnae3_dcb_ops {
@@ -647,7 +660,8 @@ struct hnae3_dcb_ops {
	u8   (*getdcbx)(struct hnae3_handle *);
	u8   (*setdcbx)(struct hnae3_handle *, u8);

	int (*setup_tc)(struct hnae3_handle *, u8, u8 *);
	int (*setup_tc)(struct hnae3_handle *handle,
			struct tc_mqprio_qopt_offload *mqprio_qopt);
};

struct hnae3_ae_algo {
@@ -659,15 +673,17 @@ struct hnae3_ae_algo {
#define HNAE3_INT_NAME_LEN        32
#define HNAE3_ITR_COUNTDOWN_START 100

#define HNAE3_MAX_TC		8
#define HNAE3_MAX_USER_PRIO	8
struct hnae3_tc_info {
	u16	tqp_offset;	/* TQP offset from base TQP */
	u16	tqp_count;	/* Total TQPs */
	u8	tc;		/* TC index */
	bool	enable;		/* If this TC is enable or not */
	u8 prio_tc[HNAE3_MAX_USER_PRIO]; /* TC indexed by prio */
	u16 tqp_count[HNAE3_MAX_TC];
	u16 tqp_offset[HNAE3_MAX_TC];
	unsigned long tc_en; /* bitmap of TC enabled */
	u8 num_tc; /* Total number of enabled TCs */
	bool mqprio_active;
};

#define HNAE3_MAX_TC		8
#define HNAE3_MAX_USER_PRIO	8
struct hnae3_knic_private_info {
	struct net_device *netdev; /* Set by KNIC client when init instance */
	u16 rss_size;		   /* Allocated RSS queues */
@@ -676,9 +692,7 @@ struct hnae3_knic_private_info {
	u16 num_tx_desc;
	u16 num_rx_desc;

	u8 num_tc;		   /* Total number of enabled TCs */
	u8 prio_tc[HNAE3_MAX_USER_PRIO];  /* TC indexed by prio */
	struct hnae3_tc_info tc_info[HNAE3_MAX_TC]; /* Idx of array is HW TC */
	struct hnae3_tc_info tc_info;

	u16 num_tqps;		  /* total number of TQPs in this handle */
	struct hnae3_queue **tqp;  /* array base of all TQPs in this instance */
+2 −1
Original line number Diff line number Diff line
@@ -385,7 +385,8 @@ static void hns3_dbg_dev_specs(struct hnae3_handle *h)
	dev_info(priv->dev, "RX buffer length: %u\n", kinfo->rx_buf_len);
	dev_info(priv->dev, "Desc num per TX queue: %u\n", kinfo->num_tx_desc);
	dev_info(priv->dev, "Desc num per RX queue: %u\n", kinfo->num_rx_desc);
	dev_info(priv->dev, "Total number of enabled TCs: %u\n", kinfo->num_tc);
	dev_info(priv->dev, "Total number of enabled TCs: %u\n",
		 kinfo->tc_info.num_tc);
	dev_info(priv->dev, "MAX INT QL: %u\n", dev_specs->int_ql_max);
	dev_info(priv->dev, "MAX INT GL: %u\n", dev_specs->max_int_gl);
}
+91 −21
Original line number Diff line number Diff line
@@ -323,13 +323,14 @@ static int hns3_nic_set_real_num_queue(struct net_device *netdev)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);
	struct hnae3_knic_private_info *kinfo = &h->kinfo;
	unsigned int queue_size = kinfo->rss_size * kinfo->num_tc;
	struct hnae3_tc_info *tc_info = &kinfo->tc_info;
	unsigned int queue_size = kinfo->num_tqps;
	int i, ret;

	if (kinfo->num_tc <= 1) {
	if (tc_info->num_tc <= 1 && !tc_info->mqprio_active) {
		netdev_reset_tc(netdev);
	} else {
		ret = netdev_set_num_tc(netdev, kinfo->num_tc);
		ret = netdev_set_num_tc(netdev, tc_info->num_tc);
		if (ret) {
			netdev_err(netdev,
				   "netdev_set_num_tc fail, ret=%d!\n", ret);
@@ -337,13 +338,11 @@ static int hns3_nic_set_real_num_queue(struct net_device *netdev)
		}

		for (i = 0; i < HNAE3_MAX_TC; i++) {
			if (!kinfo->tc_info[i].enable)
			if (!test_bit(i, &tc_info->tc_en))
				continue;

			netdev_set_tc_queue(netdev,
					    kinfo->tc_info[i].tc,
					    kinfo->tc_info[i].tqp_count,
					    kinfo->tc_info[i].tqp_offset);
			netdev_set_tc_queue(netdev, i, tc_info->tqp_count[i],
					    tc_info->tqp_offset[i]);
		}
	}

@@ -369,7 +368,7 @@ static u16 hns3_get_max_available_channels(struct hnae3_handle *h)
	u16 alloc_tqps, max_rss_size, rss_size;

	h->ae_algo->ops->get_tqps_and_rss_info(h, &alloc_tqps, &max_rss_size);
	rss_size = alloc_tqps / h->kinfo.num_tc;
	rss_size = alloc_tqps / h->kinfo.tc_info.num_tc;

	return min_t(u16, rss_size, max_rss_size);
}
@@ -508,7 +507,7 @@ static int hns3_nic_net_open(struct net_device *netdev)

	kinfo = &h->kinfo;
	for (i = 0; i < HNAE3_MAX_USER_PRIO; i++)
		netdev_set_prio_tc_map(netdev, i, kinfo->prio_tc[i]);
		netdev_set_prio_tc_map(netdev, i, kinfo->tc_info.prio_tc[i]);

	if (h->ae_algo->ops->set_timer_task)
		h->ae_algo->ops->set_timer_task(priv->ae_handle, true);
@@ -1669,6 +1668,13 @@ static int hns3_nic_set_features(struct net_device *netdev,
		h->ae_algo->ops->enable_fd(h, enable);
	}

	if ((netdev->features & NETIF_F_HW_TC) > (features & NETIF_F_HW_TC) &&
	    h->ae_algo->ops->cls_flower_active(h)) {
		netdev_err(netdev,
			   "there are offloaded TC filters active, cannot disable HW TC offload");
		return -EINVAL;
	}

	netdev->features = features;
	return 0;
}
@@ -1794,7 +1800,6 @@ static void hns3_nic_get_stats64(struct net_device *netdev,
static int hns3_setup_tc(struct net_device *netdev, void *type_data)
{
	struct tc_mqprio_qopt_offload *mqprio_qopt = type_data;
	u8 *prio_tc = mqprio_qopt->qopt.prio_tc_map;
	struct hnae3_knic_private_info *kinfo;
	u8 tc = mqprio_qopt->qopt.num_tc;
	u16 mode = mqprio_qopt->mode;
@@ -1817,16 +1822,70 @@ static int hns3_setup_tc(struct net_device *netdev, void *type_data)
	netif_dbg(h, drv, netdev, "setup tc: num_tc=%u\n", tc);

	return (kinfo->dcb_ops && kinfo->dcb_ops->setup_tc) ?
		kinfo->dcb_ops->setup_tc(h, tc ? tc : 1, prio_tc) : -EOPNOTSUPP;
		kinfo->dcb_ops->setup_tc(h, mqprio_qopt) : -EOPNOTSUPP;
}

static int hns3_setup_tc_cls_flower(struct hns3_nic_priv *priv,
				    struct flow_cls_offload *flow)
{
	int tc = tc_classid_to_hwtc(priv->netdev, flow->classid);
	struct hnae3_handle *h = hns3_get_handle(priv->netdev);

	switch (flow->command) {
	case FLOW_CLS_REPLACE:
		if (h->ae_algo->ops->add_cls_flower)
			return h->ae_algo->ops->add_cls_flower(h, flow, tc);
		break;
	case FLOW_CLS_DESTROY:
		if (h->ae_algo->ops->del_cls_flower)
			return h->ae_algo->ops->del_cls_flower(h, flow);
		break;
	default:
		break;
	}

	return -EOPNOTSUPP;
}

static int hns3_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
				  void *cb_priv)
{
	struct hns3_nic_priv *priv = cb_priv;

	if (!tc_cls_can_offload_and_chain0(priv->netdev, type_data))
		return -EOPNOTSUPP;

	switch (type) {
	case TC_SETUP_CLSFLOWER:
		return hns3_setup_tc_cls_flower(priv, type_data);
	default:
		return -EOPNOTSUPP;
	}
}

static LIST_HEAD(hns3_block_cb_list);

static int hns3_nic_setup_tc(struct net_device *dev, enum tc_setup_type type,
			     void *type_data)
{
	if (type != TC_SETUP_QDISC_MQPRIO)
	struct hns3_nic_priv *priv = netdev_priv(dev);
	int ret;

	switch (type) {
	case TC_SETUP_QDISC_MQPRIO:
		ret = hns3_setup_tc(dev, type_data);
		break;
	case TC_SETUP_BLOCK:
		ret = flow_block_cb_setup_simple(type_data,
						 &hns3_block_cb_list,
						 hns3_setup_tc_block_cb,
						 priv, priv, true);
		break;
	default:
		return -EOPNOTSUPP;
	}

	return hns3_setup_tc(dev, type_data);
	return ret;
}

static int hns3_vlan_rx_add_vid(struct net_device *netdev,
@@ -2423,6 +2482,11 @@ static void hns3_set_default_feature(struct net_device *netdev)
		netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
		netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL_CSUM;
	}

	if (test_bit(HNAE3_DEV_SUPPORT_FD_FORWARD_TC_B, ae_dev->caps)) {
		netdev->hw_features |= NETIF_F_HW_TC;
		netdev->features |= NETIF_F_HW_TC;
	}
}

static int hns3_alloc_buffer(struct hns3_enet_ring *ring,
@@ -3980,21 +4044,20 @@ static void hns3_init_ring_hw(struct hns3_enet_ring *ring)
static void hns3_init_tx_ring_tc(struct hns3_nic_priv *priv)
{
	struct hnae3_knic_private_info *kinfo = &priv->ae_handle->kinfo;
	struct hnae3_tc_info *tc_info = &kinfo->tc_info;
	int i;

	for (i = 0; i < HNAE3_MAX_TC; i++) {
		struct hnae3_tc_info *tc_info = &kinfo->tc_info[i];
		int j;

		if (!tc_info->enable)
		if (!test_bit(i, &tc_info->tc_en))
			continue;

		for (j = 0; j < tc_info->tqp_count; j++) {
		for (j = 0; j < tc_info->tqp_count[i]; j++) {
			struct hnae3_queue *q;

			q = priv->ring[tc_info->tqp_offset + j].tqp;
			hns3_write_dev(q, HNS3_RING_TX_RING_TC_REG,
				       tc_info->tc);
			q = priv->ring[tc_info->tqp_offset[i] + j].tqp;
			hns3_write_dev(q, HNS3_RING_TX_RING_TC_REG, i);
		}
	}
}
@@ -4121,7 +4184,8 @@ static void hns3_info_show(struct hns3_nic_priv *priv)
	dev_info(priv->dev, "RX buffer length: %u\n", kinfo->rx_buf_len);
	dev_info(priv->dev, "Desc num per TX queue: %u\n", kinfo->num_tx_desc);
	dev_info(priv->dev, "Desc num per RX queue: %u\n", kinfo->num_rx_desc);
	dev_info(priv->dev, "Total number of enabled TCs: %u\n", kinfo->num_tc);
	dev_info(priv->dev, "Total number of enabled TCs: %u\n",
		 kinfo->tc_info.num_tc);
	dev_info(priv->dev, "Max mtu size: %u\n", priv->netdev->max_mtu);
}

@@ -4692,6 +4756,12 @@ int hns3_set_channels(struct net_device *netdev,
	if (ch->rx_count || ch->tx_count)
		return -EINVAL;

	if (kinfo->tc_info.mqprio_active) {
		dev_err(&netdev->dev,
			"it's not allowed to set channels via ethtool when MQPRIO mode is on\n");
		return -EINVAL;
	}

	if (new_tqp_num > hns3_get_max_available_channels(h) ||
	    new_tqp_num < 1) {
		dev_err(&netdev->dev,
+2 −0
Original line number Diff line number Diff line
@@ -359,6 +359,8 @@ static void hclge_parse_capability(struct hclge_dev *hdev,
		set_bit(HNAE3_DEV_SUPPORT_HW_TX_CSUM_B, ae_dev->caps);
	if (hnae3_get_bit(caps, HCLGE_CAP_UDP_TUNNEL_CSUM_B))
		set_bit(HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B, ae_dev->caps);
	if (hnae3_get_bit(caps, HCLGE_CAP_FD_FORWARD_TC_B))
		set_bit(HNAE3_DEV_SUPPORT_FD_FORWARD_TC_B, ae_dev->caps);
}

static enum hclge_cmd_status
+13 −3
Original line number Diff line number Diff line
@@ -518,6 +518,8 @@ struct hclge_pf_res_cmd {
#define HCLGE_CFG_SPEED_ABILITY_EXT_M	GENMASK(15, 10)
#define HCLGE_CFG_UMV_TBL_SPACE_S	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_M		GENMASK(3, 0)

#define HCLGE_CFG_CMD_CNT		4

@@ -558,18 +560,23 @@ struct hclge_rss_input_tuple_cmd {
};

#define HCLGE_RSS_CFG_TBL_SIZE	16
#define HCLGE_RSS_CFG_TBL_SIZE_H	4
#define HCLGE_RSS_CFG_TBL_BW_H		2U
#define HCLGE_RSS_CFG_TBL_BW_L		8U

struct hclge_rss_indirection_table_cmd {
	__le16 start_table_index;
	__le16 rss_set_bitmap;
	u8 rsv[4];
	u8 rss_result[HCLGE_RSS_CFG_TBL_SIZE];
	u8 rss_qid_h[HCLGE_RSS_CFG_TBL_SIZE_H];
	u8 rss_qid_l[HCLGE_RSS_CFG_TBL_SIZE];
};

#define HCLGE_RSS_TC_OFFSET_S		0
#define HCLGE_RSS_TC_OFFSET_M		GENMASK(9, 0)
#define HCLGE_RSS_TC_OFFSET_M		GENMASK(10, 0)
#define HCLGE_RSS_TC_SIZE_MSB_B		11
#define HCLGE_RSS_TC_SIZE_S		12
#define HCLGE_RSS_TC_SIZE_M		GENMASK(14, 12)
#define HCLGE_RSS_TC_SIZE_MSB_OFFSET	3
#define HCLGE_RSS_TC_VALID_B		15
struct hclge_rss_tc_mode_cmd {
	__le16 rss_tc_mode[HCLGE_MAX_TC_NUM];
@@ -1051,6 +1058,9 @@ struct hclge_fd_tcam_config_3_cmd {
#define HCLGE_FD_AD_WR_RULE_ID_B	0
#define HCLGE_FD_AD_RULE_ID_S		1
#define HCLGE_FD_AD_RULE_ID_M		GENMASK(13, 1)
#define HCLGE_FD_AD_TC_OVRD_B		16
#define HCLGE_FD_AD_TC_SIZE_S		17
#define HCLGE_FD_AD_TC_SIZE_M		GENMASK(20, 17)

struct hclge_fd_ad_config_cmd {
	u8 stage;
Loading