Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b29bd412 authored by lipeng's avatar lipeng Committed by David S. Miller
Browse files

net: hns: Fix to adjust buf_size of ring according to mtu



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.

Signed-off-by: default avatarlipeng <lipeng321@huawei.com>
reviewed-by: default avatarYisen Zhuang <yisen.zhuang@huawei.com>
Signed-off-by: default avatarSalil Mehta <salil.mehta@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 36eedfde
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ do { \
#define AE_IS_VER1(ver) ((ver) == AE_VERSION_1)
#define AE_NAME_SIZE 16

#define BD_SIZE_2048_MAX_MTU   6000

/* some said the RX and TX RCB format should not be the same in the future. But
 * it is the same now...
 */
@@ -646,6 +648,41 @@ static inline void hnae_reuse_buffer(struct hnae_ring *ring, int i)
	ring->desc[i].rx.ipoff_bnum_pid_flag = 0;
}

/* 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)); \
+25 −1
Original line number Diff line number Diff line
@@ -267,8 +267,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);

	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 hns_mac_set_mtu(mac_cb, new_mtu);
	return ret;
}

static void hns_ae_set_tso_stats(struct hnae_handle *handle, int enable)
+1 −2
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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,
+32 −9
Original line number Diff line number Diff line
@@ -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)
	}

	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;
Loading