Inter-revision diff: patch 8

Comparing v1 (message) to v3 (message)

--- v1
+++ v3
@@ -1,541 +1,118 @@
 From: lipeng <lipeng321@huawei.com>
 
-Because buf_size of ring set to 2048, the process of rx_poll_one
-can reuse the page, therefore the performance of XGE can improve.
-But the chip only supports three bds in one package, so the max mtu
-is 6K when it sets to 2048. For better performane in litter mtu, we
-need change buf_size according to mtu.
-
-When user change mtu, hns is only change the desc in memory. There
-are some desc has been fetched by the chip, these desc can not be
-changed by the code. So it needs set the port loopback and send
-some packages to let the chip consumes the wrong desc and fetch new
-desc.
-Because the Pv660 do not support rss indirection, we need add version
-check in mtu change process.
+netif_tx_lock is a global spin lock, it will take affect
+in all rings in the netdevice. In tx_poll_one process, it can
+only lock the current ring, in this case, we define a spin lock
+in hnae_ring struct for it.
 
 Signed-off-by: lipeng <lipeng321@huawei.com>
 reviewed-by: Yisen Zhuang <yisen.zhuang@huawei.com>
 Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
 ---
- drivers/net/ethernet/hisilicon/hns/hnae.h         |  37 ++++
- drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c |  26 ++-
- drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c |   3 +-
- drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h |   2 +-
- drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c |  41 +++-
- drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h |   3 +
- drivers/net/ethernet/hisilicon/hns/hns_enet.c     | 249 +++++++++++++++++++++-
- 7 files changed, 337 insertions(+), 24 deletions(-)
+ drivers/net/ethernet/hisilicon/hns/hnae.c     |  1 +
+ drivers/net/ethernet/hisilicon/hns/hnae.h     |  3 +++
+ drivers/net/ethernet/hisilicon/hns/hns_enet.c | 21 +++++++++++----------
+ 3 files changed, 15 insertions(+), 10 deletions(-)
 
+diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c
+index 78af663..513c257 100644
+--- a/drivers/net/ethernet/hisilicon/hns/hnae.c
++++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
+@@ -196,6 +196,7 @@ hnae_init_ring(struct hnae_queue *q, struct hnae_ring *ring, int flags)
+ 
+ 	ring->q = q;
+ 	ring->flags = flags;
++	spin_lock_init(&ring->lock);
+ 	assert(!ring->desc && !ring->desc_cb && !ring->desc_dma_addr);
+ 
+ 	/* not matter for tx or rx ring, the ntc and ntc start from 0 */
 diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h b/drivers/net/ethernet/hisilicon/hns/hnae.h
-index 85df7c7..ad79a76 100644
+index c66581d..859c536 100644
 --- a/drivers/net/ethernet/hisilicon/hns/hnae.h
 +++ b/drivers/net/ethernet/hisilicon/hns/hnae.h
-@@ -67,6 +67,8 @@ do { \
- #define AE_IS_VER1(ver) ((ver) == AE_VERSION_1)
- #define AE_NAME_SIZE 16
+@@ -275,6 +275,9 @@ struct hnae_ring {
+ 	/* statistic */
+ 	struct ring_stats stats;
  
-+#define BD_SIZE_2048_MAX_MTU   6000
++	/* ring lock for poll one */
++	spinlock_t lock;
 +
- /* some said the RX and TX RCB format should not be the same in the future. But
-  * it is the same now...
+ 	dma_addr_t desc_dma_addr;
+ 	u32 buf_size;       /* size for hnae_desc->addr, preset by AE */
+ 	u16 desc_num;       /* total number of desc */
+diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+index 3449a18..3634366 100644
+--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
++++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+@@ -922,12 +922,13 @@ static int is_valid_clean_head(struct hnae_ring *ring, int h)
+ 
+ /* netif_tx_lock will turn down the performance, set only when necessary */
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+-#define NETIF_TX_LOCK(ndev) netif_tx_lock(ndev)
+-#define NETIF_TX_UNLOCK(ndev) netif_tx_unlock(ndev)
++#define NETIF_TX_LOCK(ring) spin_lock(&ring->lock)
++#define NETIF_TX_UNLOCK(ring) spin_unlock(&ring->lock)
+ #else
+-#define NETIF_TX_LOCK(ndev)
+-#define NETIF_TX_UNLOCK(ndev)
++#define NETIF_TX_LOCK(ring)
++#define NETIF_TX_UNLOCK(ring)
+ #endif
++
+ /* reclaim all desc in one budget
+  * return error or number of desc left
   */
-@@ -648,6 +650,41 @@ static inline void hnae_reuse_buffer(struct hnae_ring *ring, int i)
- 	ring->desc[i].rx.ipoff_bnum_pid_flag = 0;
- }
+@@ -941,13 +942,13 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data *ring_data,
+ 	int head;
+ 	int bytes, pkts;
  
-+/* when reinit buffer size, we should reinit buffer description */
-+static inline void hnae_reinit_all_ring_desc(struct hnae_handle *h)
-+{
-+	int i, j;
-+	struct hnae_ring *ring;
-+
-+	for (i = 0; i < h->q_num; i++) {
-+		ring = &h->qs[i]->rx_ring;
-+		for (j = 0; j < ring->desc_num; j++)
-+			ring->desc[j].addr = cpu_to_le64(ring->desc_cb[j].dma);
-+	}
-+
-+	wmb();	/* commit all data before submit */
-+}
-+
-+/* when reinit buffer size, we should reinit page offset */
-+static inline void hnae_reinit_all_ring_page_off(struct hnae_handle *h)
-+{
-+	int i, j;
-+	struct hnae_ring *ring;
-+
-+	for (i = 0; i < h->q_num; i++) {
-+		ring = &h->qs[i]->rx_ring;
-+		for (j = 0; j < ring->desc_num; j++) {
-+			ring->desc_cb[j].page_offset = 0;
-+			if (ring->desc[j].addr !=
-+			    cpu_to_le64(ring->desc_cb[j].dma))
-+				ring->desc[j].addr =
-+					cpu_to_le64(ring->desc_cb[j].dma);
-+		}
-+	}
-+
-+	wmb();	/* commit all data before submit */
-+}
-+
- #define hnae_set_field(origin, mask, shift, val) \
- 	do { \
- 		(origin) &= (~(mask)); \
-diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
-index abafa25..53af14e 100644
---- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
-+++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
-@@ -272,8 +272,32 @@ static int hns_ae_clr_multicast(struct hnae_handle *handle)
- static int hns_ae_set_mtu(struct hnae_handle *handle, int new_mtu)
- {
- 	struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
-+	struct hnae_queue *q;
-+	u32 rx_buf_size;
-+	int i, ret;
-+
-+	/* when buf_size is 2048, max mtu is 6K for rx ring max bd num is 3. */
-+	if (!AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) {
-+		if (new_mtu <= BD_SIZE_2048_MAX_MTU)
-+			rx_buf_size = 2048;
-+		else
-+			rx_buf_size = 4096;
-+	} else {
-+		rx_buf_size = mac_cb->dsaf_dev->buf_size;
-+	}
-+
-+	ret = hns_mac_set_mtu(mac_cb, new_mtu, rx_buf_size);
+-	NETIF_TX_LOCK(ndev);
++	NETIF_TX_LOCK(ring);
  
--	return hns_mac_set_mtu(mac_cb, new_mtu);
-+	if (!ret) {
-+		/* reinit ring buf_size */
-+		for (i = 0; i < handle->q_num; i++) {
-+			q = handle->qs[i];
-+			q->rx_ring.buf_size = rx_buf_size;
-+			hns_rcb_set_rx_ring_bs(q, rx_buf_size);
-+		}
-+	}
-+
-+	return ret;
- }
+ 	head = readl_relaxed(ring->io_base + RCB_REG_HEAD);
+ 	rmb(); /* make sure head is ready before touch any data */
  
- static void hns_ae_set_tso_stats(struct hnae_handle *handle, int enable)
-diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
-index 3239d27..edf9a23 100644
---- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
-+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
-@@ -491,10 +491,9 @@ void hns_mac_reset(struct hns_mac_cb *mac_cb)
- 	}
- }
- 
--int hns_mac_set_mtu(struct hns_mac_cb *mac_cb, u32 new_mtu)
-+int hns_mac_set_mtu(struct hns_mac_cb *mac_cb, u32 new_mtu, u32 buf_size)
- {
- 	struct mac_driver *drv = hns_mac_get_drv(mac_cb);
--	u32 buf_size = mac_cb->dsaf_dev->buf_size;
- 	u32 new_frm = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
- 	u32 max_frm = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver) ?
- 			MAC_MAX_MTU : MAC_MAX_MTU_V2;
-diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
-index 2bb3d1e..7f14d91 100644
---- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
-+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.h
-@@ -444,7 +444,7 @@ void hns_mac_get_autoneg(struct hns_mac_cb *mac_cb, u32 *auto_neg);
- void hns_mac_get_pauseparam(struct hns_mac_cb *mac_cb, u32 *rx_en, u32 *tx_en);
- int hns_mac_set_autoneg(struct hns_mac_cb *mac_cb, u8 enable);
- int hns_mac_set_pauseparam(struct hns_mac_cb *mac_cb, u32 rx_en, u32 tx_en);
--int hns_mac_set_mtu(struct hns_mac_cb *mac_cb, u32 new_mtu);
-+int hns_mac_set_mtu(struct hns_mac_cb *mac_cb, u32 new_mtu, u32 buf_size);
- int hns_mac_get_port_info(struct hns_mac_cb *mac_cb,
- 			  u8 *auto_neg, u16 *speed, u8 *duplex);
- int hns_mac_config_mac_loopback(struct hns_mac_cb *mac_cb,
-diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
-index f0ed80d6..a6ab168 100644
---- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
-+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
-@@ -32,6 +32,9 @@
- #define RCB_RESET_WAIT_TIMES 30
- #define RCB_RESET_TRY_TIMES 10
- 
-+/* Because default mtu is 1500, rcb buffer size is set to 2048 enough */
-+#define RCB_DEFAULT_BUFFER_SIZE 2048
-+
- /**
-  *hns_rcb_wait_fbd_clean - clean fbd
-  *@qs: ring struct pointer array
-@@ -192,6 +195,30 @@ void hns_rcb_common_init_commit_hw(struct rcb_common_cb *rcb_common)
- 	wmb();	/* Sync point after breakpoint */
- }
- 
-+/* hns_rcb_set_tx_ring_bs - init rcb ring buf size regester
-+ *@q: hnae_queue
-+ *@buf_size: buffer size set to hw
-+ */
-+void hns_rcb_set_tx_ring_bs(struct hnae_queue *q, u32 buf_size)
-+{
-+	u32 bd_size_type = hns_rcb_buf_size2type(buf_size);
-+
-+	dsaf_write_dev(q, RCB_RING_TX_RING_BD_LEN_REG,
-+		       bd_size_type);
-+}
-+
-+/* hns_rcb_set_rx_ring_bs - init rcb ring buf size regester
-+ *@q: hnae_queue
-+ *@buf_size: buffer size set to hw
-+ */
-+void hns_rcb_set_rx_ring_bs(struct hnae_queue *q, u32 buf_size)
-+{
-+	u32 bd_size_type = hns_rcb_buf_size2type(buf_size);
-+
-+	dsaf_write_dev(q, RCB_RING_RX_RING_BD_LEN_REG,
-+		       bd_size_type);
-+}
-+
- /**
-  *hns_rcb_ring_init - init rcb ring
-  *@ring_pair: ring pair control block
-@@ -200,8 +227,6 @@ void hns_rcb_common_init_commit_hw(struct rcb_common_cb *rcb_common)
- static void hns_rcb_ring_init(struct ring_pair_cb *ring_pair, int ring_type)
- {
- 	struct hnae_queue *q = &ring_pair->q;
--	struct rcb_common_cb *rcb_common = ring_pair->rcb_common;
--	u32 bd_size_type = rcb_common->dsaf_dev->buf_size_type;
- 	struct hnae_ring *ring =
- 		(ring_type == RX_RING) ? &q->rx_ring : &q->tx_ring;
- 	dma_addr_t dma = ring->desc_dma_addr;
-@@ -212,8 +237,8 @@ static void hns_rcb_ring_init(struct ring_pair_cb *ring_pair, int ring_type)
- 		dsaf_write_dev(q, RCB_RING_RX_RING_BASEADDR_H_REG,
- 			       (u32)((dma >> 31) >> 1));
- 
--		dsaf_write_dev(q, RCB_RING_RX_RING_BD_LEN_REG,
--			       bd_size_type);
-+		hns_rcb_set_rx_ring_bs(q, ring->buf_size);
-+
- 		dsaf_write_dev(q, RCB_RING_RX_RING_BD_NUM_REG,
- 			       ring_pair->port_id_in_comm);
- 		dsaf_write_dev(q, RCB_RING_RX_RING_PKTLINE_REG,
-@@ -224,8 +249,8 @@ static void hns_rcb_ring_init(struct ring_pair_cb *ring_pair, int ring_type)
- 		dsaf_write_dev(q, RCB_RING_TX_RING_BASEADDR_H_REG,
- 			       (u32)((dma >> 31) >> 1));
- 
--		dsaf_write_dev(q, RCB_RING_TX_RING_BD_LEN_REG,
--			       bd_size_type);
-+		hns_rcb_set_tx_ring_bs(q, ring->buf_size);
-+
- 		dsaf_write_dev(q, RCB_RING_TX_RING_BD_NUM_REG,
- 			       ring_pair->port_id_in_comm);
- 		dsaf_write_dev(q, RCB_RING_TX_RING_PKTLINE_REG,
-@@ -380,7 +405,6 @@ static void hns_rcb_ring_get_cfg(struct hnae_queue *q, int ring_type)
- 	struct hnae_ring *ring;
- 	struct rcb_common_cb *rcb_common;
- 	struct ring_pair_cb *ring_pair_cb;
--	u32 buf_size;
- 	u16 desc_num, mdnum_ppkt;
- 	bool irq_idx, is_ver1;
- 
-@@ -401,7 +425,6 @@ static void hns_rcb_ring_get_cfg(struct hnae_queue *q, int ring_type)
+ 	if (is_ring_empty(ring) || head == ring->next_to_clean) {
+-		NETIF_TX_UNLOCK(ndev);
++		NETIF_TX_UNLOCK(ring);
+ 		return 0; /* no data to poll */
  	}
  
- 	rcb_common = ring_pair_cb->rcb_common;
--	buf_size = rcb_common->dsaf_dev->buf_size;
- 	desc_num = rcb_common->dsaf_dev->desc_num;
- 
- 	ring->desc = NULL;
-@@ -410,7 +433,7 @@ static void hns_rcb_ring_get_cfg(struct hnae_queue *q, int ring_type)
- 	ring->irq = ring_pair_cb->virq[irq_idx];
- 	ring->desc_dma_addr = 0;
- 
--	ring->buf_size = buf_size;
-+	ring->buf_size = RCB_DEFAULT_BUFFER_SIZE;
- 	ring->desc_num = desc_num;
- 	ring->max_desc_num_per_pkt = mdnum_ppkt;
- 	ring->max_raw_data_sz_per_desc = HNS_RCB_MAX_PKT_SIZE;
-diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h
-index 99b4e1b..afe563c 100644
---- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h
-+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h
-@@ -146,4 +146,7 @@ int hns_rcb_get_ring_regs_count(void);
- void hns_rcb_get_ring_regs(struct hnae_queue *queue, void *data);
- 
- void hns_rcb_get_strings(int stringset, u8 *data, int index);
-+void hns_rcb_set_rx_ring_bs(struct hnae_queue *q, u32 buf_size);
-+void hns_rcb_set_tx_ring_bs(struct hnae_queue *q, u32 buf_size);
-+
- #endif /* _HNS_DSAF_RCB_H */
-diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
-index a083660..2a12764 100644
---- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
-+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
-@@ -1482,32 +1482,259 @@ static netdev_tx_t hns_nic_net_xmit(struct sk_buff *skb,
- 	return (netdev_tx_t)ret;
- }
- 
-+static void hns_nic_drop_rx_fetch(struct hns_nic_ring_data *ring_data,
-+				  struct sk_buff *skb)
-+{
-+	dev_kfree_skb_any(skb);
-+}
-+
-+#define HNS_LB_TX_RING	0
-+static struct sk_buff *hns_assemble_skb(struct net_device *ndev)
-+{
-+	struct sk_buff *skb;
-+	struct ethhdr *ethhdr;
-+	int frame_len;
-+
-+	/* allocate test skb */
-+	skb = alloc_skb(64, GFP_KERNEL);
-+	if (!skb)
-+		return NULL;
-+
-+	skb_put(skb, 64);
-+	skb->dev = ndev;
-+	memset(skb->data, 0xFF, skb->len);
-+
-+	/* must be tcp/ip package */
-+	ethhdr = (struct ethhdr *)skb->data;
-+	ethhdr->h_proto = htons(ETH_P_IP);
-+
-+	frame_len = skb->len & (~1ul);
-+	memset(&skb->data[frame_len / 2], 0xAA,
-+	       frame_len / 2 - 1);
-+
-+	skb->queue_mapping = HNS_LB_TX_RING;
-+
-+	return skb;
-+}
-+
-+static bool hns_enable_serdes_lb(struct net_device *ndev)
-+{
-+	struct hns_nic_priv *priv = netdev_priv(ndev);
-+	struct hnae_handle *h = priv->ae_handle;
-+	struct hnae_ae_ops *ops = h->dev->ops;
-+	int speed, duplex;
-+	int ret;
-+
-+	ret = ops->set_loopback(h, MAC_INTERNALLOOP_SERDES, 1);
-+	if (ret)
-+		return ret;
-+
-+	ret = ops->start ? ops->start(h) : 0;
-+	if (ret)
-+		return ret;
-+
-+	/* link adjust duplex*/
-+	if (h->phy_if != PHY_INTERFACE_MODE_XGMII)
-+		speed = 1000;
-+	else
-+		speed = 10000;
-+	duplex = 1;
-+
-+	ops->adjust_link(h, speed, duplex);
-+
-+	/* wait h/w ready */
-+	mdelay(300);
-+
-+	return 0;
-+}
-+
-+static void hns_disable_serdes_lb(struct net_device *ndev)
-+{
-+	struct hns_nic_priv *priv = netdev_priv(ndev);
-+	struct hnae_handle *h = priv->ae_handle;
-+	struct hnae_ae_ops *ops = h->dev->ops;
-+
-+	ops->stop(h);
-+	ops->set_loopback(h, MAC_INTERNALLOOP_SERDES, 0);
-+}
-+
-+/**
-+ *hns_nic_clear_all_rx_fetch - clear the chip fetched descriptions. The
-+ *function as follows:
-+ *    1. if one rx ring has found the page_offset is not equal 0 between head
-+ *       and tail, it means that the chip fetched the wrong descs for the ring
-+ *       which buffer size is 4096.
-+ *    2. we set the chip serdes loopback and set rss indirection to the ring.
-+ *    3. construct 64-bytes ip broadcast packages, wait the associated rx ring
-+ *       recieving all packages and it will fetch new descriptions.
-+ *    4. recover to the original state.
-+ *
-+ *@ndev: net device
-+ */
-+static int hns_nic_clear_all_rx_fetch(struct net_device *ndev)
-+{
-+	struct hns_nic_priv *priv = netdev_priv(ndev);
-+	struct hnae_handle *h = priv->ae_handle;
-+	struct hnae_ae_ops *ops = h->dev->ops;
-+	struct hns_nic_ring_data *rd;
-+	struct hnae_ring *ring;
-+	struct sk_buff *skb;
-+	u32 *org_indir;
-+	u32 *cur_indir;
-+	int indir_size;
-+	int head, tail;
-+	int fetch_num;
-+	int i, j;
-+	bool found;
-+	int retry_times;
-+	int ret = 0;
-+
-+	/* alloc indir memory */
-+	indir_size = ops->get_rss_indir_size(h) * sizeof(*org_indir);
-+	org_indir = kzalloc(indir_size, GFP_KERNEL);
-+	if (!org_indir)
-+		return -ENOMEM;
-+
-+	/* store the orginal indirection */
-+	ops->get_rss(h, org_indir, NULL, NULL);
-+
-+	cur_indir = kzalloc(indir_size, GFP_KERNEL);
-+	if (!cur_indir) {
-+		ret = -ENOMEM;
-+		goto cur_indir_alloc_err;
-+	}
-+
-+	/* set loopback */
-+	if (hns_enable_serdes_lb(ndev)) {
-+		ret = -EINVAL;
-+		goto enable_serdes_lb_err;
-+	}
-+
-+	/* foreach every rx ring to clear fetch desc */
-+	for (i = 0; i < h->q_num; i++) {
-+		ring = &h->qs[i]->rx_ring;
-+		head = readl_relaxed(ring->io_base + RCB_REG_HEAD);
-+		tail = readl_relaxed(ring->io_base + RCB_REG_TAIL);
-+		found = false;
-+		fetch_num = ring_dist(ring, head, tail);
-+
-+		while (head != tail) {
-+			if (ring->desc_cb[head].page_offset != 0) {
-+				found = true;
-+				break;
-+			}
-+
-+			head++;
-+			if (head == ring->desc_num)
-+				head = 0;
-+		}
-+
-+		if (found) {
-+			for (j = 0; j < indir_size / sizeof(*org_indir); j++)
-+				cur_indir[j] = i;
-+			ops->set_rss(h, cur_indir, NULL, 0);
-+
-+			for (j = 0; j < fetch_num; j++) {
-+				/* alloc one skb and init */
-+				skb = hns_assemble_skb(ndev);
-+				if (!skb)
-+					goto out;
-+				rd = &tx_ring_data(priv, skb->queue_mapping);
-+				hns_nic_net_xmit_hw(ndev, skb, rd);
-+
-+				retry_times = 0;
-+				while (retry_times++ < 10) {
-+					mdelay(10);
-+					/* clean rx */
-+					rd = &rx_ring_data(priv, i);
-+					if (rd->poll_one(rd, fetch_num,
-+							 hns_nic_drop_rx_fetch))
-+						break;
-+				}
-+
-+				retry_times = 0;
-+				while (retry_times++ < 10) {
-+					mdelay(10);
-+					/* clean tx ring 0 send package */
-+					rd = &tx_ring_data(priv,
-+							   HNS_LB_TX_RING);
-+					if (rd->poll_one(rd, fetch_num, NULL))
-+						break;
-+				}
-+			}
-+		}
-+	}
-+
-+out:
-+	/* restore everything */
-+	ops->set_rss(h, org_indir, NULL, 0);
-+	hns_disable_serdes_lb(ndev);
-+enable_serdes_lb_err:
-+	kfree(cur_indir);
-+cur_indir_alloc_err:
-+	kfree(org_indir);
-+
-+	return ret;
-+}
-+
- static int hns_nic_change_mtu(struct net_device *ndev, int new_mtu)
- {
- 	struct hns_nic_priv *priv = netdev_priv(ndev);
- 	struct hnae_handle *h = priv->ae_handle;
-+	bool if_running = netif_running(ndev);
- 	int ret;
- 
-+	/* MTU < 68 is an error and causes problems on some kernels */
-+	if (new_mtu < 68)
-+		return -EINVAL;
-+
-+	/* MTU no change */
-+	if (new_mtu == ndev->mtu)
-+		return 0;
-+
- 	if (!h->dev->ops->set_mtu)
- 		return -ENOTSUPP;
- 
--	if (netif_running(ndev)) {
-+	if (if_running) {
- 		(void)hns_nic_net_stop(ndev);
- 		msleep(100);
-+	}
- 
--		ret = h->dev->ops->set_mtu(h, new_mtu);
--		if (ret)
--			netdev_err(ndev, "set mtu fail, return value %d\n",
--				   ret);
-+	if (priv->enet_ver != AE_VERSION_1 &&
-+	    ndev->mtu <= BD_SIZE_2048_MAX_MTU &&
-+	    new_mtu > BD_SIZE_2048_MAX_MTU) {
-+		/* update desc */
-+		hnae_reinit_all_ring_desc(h);
- 
--		if (hns_nic_net_open(ndev))
--			netdev_err(ndev, "hns net open fail\n");
--	} else {
--		ret = h->dev->ops->set_mtu(h, new_mtu);
-+		/* clear the package which the chip has fetched */
-+		ret = hns_nic_clear_all_rx_fetch(ndev);
-+
-+		/* the page offset must be consist with desc */
-+		hnae_reinit_all_ring_page_off(h);
-+
-+		if (ret) {
-+			netdev_err(ndev, "clear the fetched desc fail\n");
-+			goto out;
-+		}
-+	}
-+
-+	ret = h->dev->ops->set_mtu(h, new_mtu);
-+	if (ret) {
-+		netdev_err(ndev, "set mtu fail, return value %d\n",
-+			   ret);
-+		goto out;
+@@ -955,7 +956,7 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data *ring_data,
+ 		netdev_err(ndev, "wrong head (%d, %d-%d)\n", head,
+ 			   ring->next_to_use, ring->next_to_clean);
+ 		ring->stats.io_err_cnt++;
+-		NETIF_TX_UNLOCK(ndev);
++		NETIF_TX_UNLOCK(ring);
+ 		return -EIO;
  	}
  
--	if (!ret)
--		ndev->mtu = new_mtu;
-+	/* finally, set new mtu to netdevice */
-+	ndev->mtu = new_mtu;
-+
-+out:
-+	if (if_running) {
-+		if (hns_nic_net_open(ndev)) {
-+			netdev_err(ndev, "hns net open fail\n");
-+			ret = -EINVAL;
-+		}
-+	}
+@@ -967,7 +968,7 @@ static int hns_nic_tx_poll_one(struct hns_nic_ring_data *ring_data,
+ 		prefetch(&ring->desc_cb[ring->next_to_clean]);
+ 	}
  
- 	return ret;
- }
+-	NETIF_TX_UNLOCK(ndev);
++	NETIF_TX_UNLOCK(ring);
+ 
+ 	dev_queue = netdev_get_tx_queue(ndev, ring_data->queue_index);
+ 	netdev_tx_completed_queue(dev_queue, pkts, bytes);
+@@ -1028,7 +1029,7 @@ static void hns_nic_tx_clr_all_bufs(struct hns_nic_ring_data *ring_data)
+ 	int head;
+ 	int bytes, pkts;
+ 
+-	NETIF_TX_LOCK(ndev);
++	NETIF_TX_LOCK(ring);
+ 
+ 	head = ring->next_to_use; /* ntu :soft setted ring position*/
+ 	bytes = 0;
+@@ -1036,7 +1037,7 @@ static void hns_nic_tx_clr_all_bufs(struct hns_nic_ring_data *ring_data)
+ 	while (head != ring->next_to_clean)
+ 		hns_nic_reclaim_one_desc(ring, &bytes, &pkts);
+ 
+-	NETIF_TX_UNLOCK(ndev);
++	NETIF_TX_UNLOCK(ring);
+ 
+ 	dev_queue = netdev_get_tx_queue(ndev, ring_data->queue_index);
+ 	netdev_tx_reset_queue(dev_queue);
 -- 
 2.7.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help