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

Merge branch 'hnx3-next'



Huazhong Tan says:

====================
code optimizations & bugfixes for HNS3 driver

This patchset includes bugfixes and code optimizations for
the HNS3 ethernet controller driver.

Change log:
V1->V2: fixes comments from Sergei Shtylyov
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b571bc62 d223dfa4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ enum HCLGE_MBX_OPCODE {
	HCLGE_MBX_GET_QID_IN_PF,	/* (VF -> PF) get queue id in pf */
	HCLGE_MBX_LINK_STAT_MODE,	/* (PF -> VF) link mode has changed */
	HCLGE_MBX_GET_LINK_MODE,	/* (VF -> PF) get the link mode of pf */
	HCLGE_MBX_GET_MEDIA_TYPE,       /* (VF -> PF) get media type */

	HCLGE_MBX_GET_VF_FLR_STATUS = 200, /* (M7 -> PF) get vf reset status */
};
+22 −18
Original line number Diff line number Diff line
@@ -76,8 +76,8 @@ static int hnae3_get_client_init_flag(struct hnae3_client *client,
	return inited;
}

static int hnae3_match_n_instantiate(struct hnae3_client *client,
				     struct hnae3_ae_dev *ae_dev, bool is_reg)
static int hnae3_init_client_instance(struct hnae3_client *client,
				      struct hnae3_ae_dev *ae_dev)
{
	int ret;

@@ -87,8 +87,6 @@ static int hnae3_match_n_instantiate(struct hnae3_client *client,
		return 0;
	}

	/* now, (un-)instantiate client by calling lower layer */
	if (is_reg) {
	ret = ae_dev->ops->init_client_instance(client, ae_dev);
	if (ret)
		dev_err(&ae_dev->pdev->dev,
@@ -97,13 +95,19 @@ static int hnae3_match_n_instantiate(struct hnae3_client *client,
	return ret;
}

static void hnae3_uninit_client_instance(struct hnae3_client *client,
					 struct hnae3_ae_dev *ae_dev)
{
	/* check if this client matches the type of ae_dev */
	if (!(hnae3_client_match(client->type, ae_dev->dev_type) &&
	      hnae3_get_bit(ae_dev->flag, HNAE3_DEV_INITED_B)))
		return;

	if (hnae3_get_client_init_flag(client, ae_dev)) {
		ae_dev->ops->uninit_client_instance(client, ae_dev);

		hnae3_set_client_init_flag(client, ae_dev, 0);
	}

	return 0;
}

int hnae3_register_client(struct hnae3_client *client)
@@ -129,7 +133,7 @@ int hnae3_register_client(struct hnae3_client *client)
		/* if the client could not be initialized on current port, for
		 * any error reasons, move on to next available port
		 */
		ret = hnae3_match_n_instantiate(client, ae_dev, true);
		ret = hnae3_init_client_instance(client, ae_dev);
		if (ret)
			dev_err(&ae_dev->pdev->dev,
				"match and instantiation failed for port, ret = %d\n",
@@ -153,7 +157,7 @@ void hnae3_unregister_client(struct hnae3_client *client)
	mutex_lock(&hnae3_common_lock);
	/* un-initialize the client on every matched port */
	list_for_each_entry(ae_dev, &hnae3_ae_dev_list, node) {
		hnae3_match_n_instantiate(client, ae_dev, false);
		hnae3_uninit_client_instance(client, ae_dev);
	}

	list_del(&client->node);
@@ -205,7 +209,7 @@ void hnae3_register_ae_algo(struct hnae3_ae_algo *ae_algo)
		 * initialize the figure out client instance
		 */
		list_for_each_entry(client, &hnae3_client_list, node) {
			ret = hnae3_match_n_instantiate(client, ae_dev, true);
			ret = hnae3_init_client_instance(client, ae_dev);
			if (ret)
				dev_err(&ae_dev->pdev->dev,
					"match and instantiation failed, ret = %d\n",
@@ -243,7 +247,7 @@ void hnae3_unregister_ae_algo(struct hnae3_ae_algo *ae_algo)
		 * un-initialize the figure out client instance
		 */
		list_for_each_entry(client, &hnae3_client_list, node)
			hnae3_match_n_instantiate(client, ae_dev, false);
			hnae3_uninit_client_instance(client, ae_dev);

		ae_algo->ops->uninit_ae_dev(ae_dev);
		hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0);
@@ -301,7 +305,7 @@ int hnae3_register_ae_dev(struct hnae3_ae_dev *ae_dev)
	 * initialize the figure out client instance
	 */
	list_for_each_entry(client, &hnae3_client_list, node) {
		ret = hnae3_match_n_instantiate(client, ae_dev, true);
		ret = hnae3_init_client_instance(client, ae_dev);
		if (ret)
			dev_err(&ae_dev->pdev->dev,
				"match and instantiation failed, ret = %d\n",
@@ -343,7 +347,7 @@ void hnae3_unregister_ae_dev(struct hnae3_ae_dev *ae_dev)
			continue;

		list_for_each_entry(client, &hnae3_client_list, node)
			hnae3_match_n_instantiate(client, ae_dev, false);
			hnae3_uninit_client_instance(client, ae_dev);

		ae_algo->ops->uninit_ae_dev(ae_dev);
		hnae3_set_bit(ae_dev->flag, HNAE3_DEV_INITED_B, 0);
+33 −8
Original line number Diff line number Diff line
@@ -1012,7 +1012,6 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
	struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use];
	struct hns3_desc *desc = &ring->desc[ring->next_to_use];
	struct device *dev = ring_to_dev(ring);
	u16 bdtp_fe_sc_vld_ra_ri = 0;
	struct skb_frag_struct *frag;
	unsigned int frag_buf_num;
	int k, sizeoflast;
@@ -1080,12 +1079,30 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,

	desc_cb->length = size;

	if (likely(size <= HNS3_MAX_BD_SIZE)) {
		u16 bdtp_fe_sc_vld_ra_ri = 0;

		desc_cb->priv = priv;
		desc_cb->dma = dma;
		desc_cb->type = type;
		desc->addr = cpu_to_le64(dma);
		desc->tx.send_size = cpu_to_le16(size);
		hns3_set_txbd_baseinfo(&bdtp_fe_sc_vld_ra_ri, frag_end);
		desc->tx.bdtp_fe_sc_vld_ra_ri =
			cpu_to_le16(bdtp_fe_sc_vld_ra_ri);

		ring_ptr_move_fw(ring, next_to_use);
		return 0;
	}

	frag_buf_num = hns3_tx_bd_count(size);
	sizeoflast = size & HNS3_TX_LAST_SIZE_M;
	sizeoflast = sizeoflast ? sizeoflast : HNS3_MAX_BD_SIZE;

	/* When frag size is bigger than hardware limit, split this frag */
	for (k = 0; k < frag_buf_num; k++) {
		u16 bdtp_fe_sc_vld_ra_ri = 0;

		/* The txbd's baseinfo of DESC_TYPE_PAGE & DESC_TYPE_SKB */
		desc_cb->priv = priv;
		desc_cb->dma = dma + HNS3_MAX_BD_SIZE * k;
@@ -1574,6 +1591,9 @@ static int hns3_nic_change_mtu(struct net_device *netdev, int new_mtu)
	struct hnae3_handle *h = hns3_get_handle(netdev);
	int ret;

	if (hns3_nic_resetting(netdev))
		return -EBUSY;

	if (!h->ae_algo->ops->set_mtu)
		return -EOPNOTSUPP;

@@ -2891,7 +2911,7 @@ static int hns3_nic_common_poll(struct napi_struct *napi, int budget)
	struct hns3_enet_tqp_vector *tqp_vector =
		container_of(napi, struct hns3_enet_tqp_vector, napi);
	bool clean_complete = true;
	int rx_budget;
	int rx_budget = budget;

	if (unlikely(test_bit(HNS3_NIC_STATE_DOWN, &priv->state))) {
		napi_complete(napi);
@@ -2905,6 +2925,7 @@ static int hns3_nic_common_poll(struct napi_struct *napi, int budget)
		hns3_clean_tx_ring(ring);

	/* make sure rx ring budget not smaller than 1 */
	if (tqp_vector->num_tqps > 1)
		rx_budget = max(budget / tqp_vector->num_tqps, 1);

	hns3_for_each_ring(ring, tqp_vector->rx_group) {
@@ -3773,12 +3794,13 @@ static int hns3_recover_hw_addr(struct net_device *ndev)
	struct netdev_hw_addr *ha, *tmp;
	int ret = 0;

	netif_addr_lock_bh(ndev);
	/* go through and sync uc_addr entries to the device */
	list = &ndev->uc;
	list_for_each_entry_safe(ha, tmp, &list->list, list) {
		ret = hns3_nic_uc_sync(ndev, ha->addr);
		if (ret)
			return ret;
			goto out;
	}

	/* go through and sync mc_addr entries to the device */
@@ -3786,9 +3808,11 @@ static int hns3_recover_hw_addr(struct net_device *ndev)
	list_for_each_entry_safe(ha, tmp, &list->list, list) {
		ret = hns3_nic_mc_sync(ndev, ha->addr);
		if (ret)
			return ret;
			goto out;
	}

out:
	netif_addr_unlock_bh(ndev);
	return ret;
}

@@ -3799,6 +3823,7 @@ static void hns3_remove_hw_addr(struct net_device *netdev)

	hns3_nic_uc_unsync(netdev, netdev->dev_addr);

	netif_addr_lock_bh(netdev);
	/* go through and unsync uc_addr entries to the device */
	list = &netdev->uc;
	list_for_each_entry_safe(ha, tmp, &list->list, list)
@@ -3809,6 +3834,8 @@ static void hns3_remove_hw_addr(struct net_device *netdev)
	list_for_each_entry_safe(ha, tmp, &list->list, list)
		if (ha->refcount > 1)
			hns3_nic_mc_unsync(netdev, ha->addr);

	netif_addr_unlock_bh(netdev);
}

static void hns3_clear_tx_ring(struct hns3_enet_ring *ring)
@@ -4101,7 +4128,7 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
	struct hns3_nic_priv *priv = netdev_priv(netdev);
	int ret;

	if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state)) {
	if (!test_and_clear_bit(HNS3_NIC_STATE_INITED, &priv->state)) {
		netdev_warn(netdev, "already uninitialized\n");
		return 0;
	}
@@ -4123,8 +4150,6 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
	hns3_put_ring_config(priv);
	priv->ring_data = NULL;

	clear_bit(HNS3_NIC_STATE_INITED, &priv->state);

	return ret;
}

+5 −10
Original line number Diff line number Diff line
@@ -577,18 +577,13 @@ union l4_hdr_info {
	unsigned char *hdr;
};

/* the distance between [begin, end) in a ring buffer
 * note: there is a unuse slot between the begin and the end
 */
static inline int ring_dist(struct hns3_enet_ring *ring, int begin, int end)
{
	return (end - begin + ring->desc_num) % ring->desc_num;
}

static inline int ring_space(struct hns3_enet_ring *ring)
{
	return ring->desc_num -
		ring_dist(ring, ring->next_to_clean, ring->next_to_use) - 1;
	int begin = ring->next_to_clean;
	int end = ring->next_to_use;

	return ((end >= begin) ? (ring->desc_num - end + begin) :
			(begin - end)) - 1;
}

static inline int is_ring_empty(struct hns3_enet_ring *ring)
+9 −0
Original line number Diff line number Diff line
@@ -483,6 +483,11 @@ static void hns3_get_stats(struct net_device *netdev,
	struct hnae3_handle *h = hns3_get_handle(netdev);
	u64 *p = data;

	if (hns3_nic_resetting(netdev)) {
		netdev_err(netdev, "dev resetting, could not get stats\n");
		return;
	}

	if (!h->ae_algo->ops->get_stats || !h->ae_algo->ops->update_stats) {
		netdev_err(netdev, "could not get any statistics\n");
		return;
@@ -648,6 +653,10 @@ static int hns3_get_link_ksettings(struct net_device *netdev,
static int hns3_set_link_ksettings(struct net_device *netdev,
				   const struct ethtool_link_ksettings *cmd)
{
	/* Chip doesn't support this mode. */
	if (cmd->base.speed == SPEED_1000 && cmd->base.duplex == DUPLEX_HALF)
		return -EINVAL;

	/* Only support ksettings_set for netdev with phy attached for now */
	if (netdev->phydev)
		return phy_ethtool_ksettings_set(netdev->phydev, cmd);
Loading