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

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

Merge branch 'hns-misc-fixes'



Salil Mehta says:

====================
net: hns: Misc. HNS Bug Fixes & Code Improvements

This patch set introduces various HNS bug fixes, optimizations and code
improvements.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d4f4b915 b4957ab0
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -57,11 +57,15 @@ static int hnae_alloc_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)

static void hnae_free_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
{
	if (unlikely(!cb->priv))
		return;

	if (cb->type == DESC_TYPE_SKB)
		dev_kfree_skb_any((struct sk_buff *)cb->priv);
	else if (unlikely(is_rx_ring(ring)))
		put_page((struct page *)cb->priv);
	memset(cb, 0, sizeof(*cb));

	cb->priv = NULL;
}

static int hnae_map_buffer(struct hnae_ring *ring, struct hnae_desc_cb *cb)
@@ -197,6 +201,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 */
+43 −4
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...
 */
@@ -101,7 +103,6 @@ enum hnae_led_state {
#define HNS_RX_FLAG_L4ID_TCP 0x1
#define HNS_RX_FLAG_L4ID_SCTP 0x3


#define HNS_TXD_ASID_S 0
#define HNS_TXD_ASID_M (0xff << HNS_TXD_ASID_S)
#define HNS_TXD_BUFNUM_S 8
@@ -273,6 +274,9 @@ struct hnae_ring {
	/* statistic */
	struct ring_stats stats;

	/* ring lock for poll one */
	spinlock_t lock;

	dma_addr_t desc_dma_addr;
	u32 buf_size;       /* size for hnae_desc->addr, preset by AE */
	u16 desc_num;       /* total number of desc */
@@ -483,11 +487,11 @@ struct hnae_ae_ops {
			      u32 auto_neg, u32 rx_en, u32 tx_en);
	void (*get_coalesce_usecs)(struct hnae_handle *handle,
				   u32 *tx_usecs, u32 *rx_usecs);
	void (*get_rx_max_coalesced_frames)(struct hnae_handle *handle,
	void (*get_max_coalesced_frames)(struct hnae_handle *handle,
					 u32 *tx_frames, u32 *rx_frames);
	int (*set_coalesce_usecs)(struct hnae_handle *handle, u32 timeout);
	int (*set_coalesce_frames)(struct hnae_handle *handle,
				   u32 coalesce_frames);
				   u32 tx_frames, u32 rx_frames);
	void (*get_coalesce_range)(struct hnae_handle *handle,
				   u32 *tx_frames_low, u32 *rx_frames_low,
				   u32 *tx_frames_high, u32 *rx_frames_high,
@@ -646,6 +650,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)); \
+94 −33
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)
@@ -463,15 +487,21 @@ static void hns_ae_get_coalesce_usecs(struct hnae_handle *handle,
					       ring_pair->port_id_in_comm);
}

static void hns_ae_get_rx_max_coalesced_frames(struct hnae_handle *handle,
static void hns_ae_get_max_coalesced_frames(struct hnae_handle *handle,
					    u32 *tx_frames, u32 *rx_frames)
{
	struct ring_pair_cb *ring_pair =
		container_of(handle->qs[0], struct ring_pair_cb, q);
	struct dsaf_device *dsaf_dev = hns_ae_get_dsaf_dev(handle->dev);

	*tx_frames = hns_rcb_get_coalesced_frames(ring_pair->rcb_common,
						  ring_pair->port_id_in_comm);
	*rx_frames = hns_rcb_get_coalesced_frames(ring_pair->rcb_common,
	if (AE_IS_VER1(dsaf_dev->dsaf_ver) ||
	    handle->port_type == HNAE_PORT_DEBUG)
		*tx_frames = hns_rcb_get_rx_coalesced_frames(
			ring_pair->rcb_common, ring_pair->port_id_in_comm);
	else
		*tx_frames = hns_rcb_get_tx_coalesced_frames(
			ring_pair->rcb_common, ring_pair->port_id_in_comm);
	*rx_frames = hns_rcb_get_rx_coalesced_frames(ring_pair->rcb_common,
						  ring_pair->port_id_in_comm);
}

@@ -486,14 +516,33 @@ static int hns_ae_set_coalesce_usecs(struct hnae_handle *handle,
}

static int hns_ae_set_coalesce_frames(struct hnae_handle *handle,
				       u32 coalesce_frames)
				      u32 tx_frames, u32 rx_frames)
{
	int ret;
	struct ring_pair_cb *ring_pair =
		container_of(handle->qs[0], struct ring_pair_cb, q);
	struct dsaf_device *dsaf_dev = hns_ae_get_dsaf_dev(handle->dev);

	return hns_rcb_set_coalesced_frames(
	if (AE_IS_VER1(dsaf_dev->dsaf_ver) ||
	    handle->port_type == HNAE_PORT_DEBUG) {
		if (tx_frames != rx_frames)
			return -EINVAL;
		return hns_rcb_set_rx_coalesced_frames(
			ring_pair->rcb_common,
			ring_pair->port_id_in_comm, rx_frames);
	} else {
		if (tx_frames != 1)
			return -EINVAL;
		ret = hns_rcb_set_tx_coalesced_frames(
			ring_pair->rcb_common,
		ring_pair->port_id_in_comm, coalesce_frames);
			ring_pair->port_id_in_comm, tx_frames);
		if (ret)
			return ret;

		return hns_rcb_set_rx_coalesced_frames(
			ring_pair->rcb_common,
			ring_pair->port_id_in_comm, rx_frames);
	}
}

static void hns_ae_get_coalesce_range(struct hnae_handle *handle,
@@ -504,20 +553,27 @@ static void hns_ae_get_coalesce_range(struct hnae_handle *handle,
{
	struct dsaf_device *dsaf_dev;

	assert(handle);

	dsaf_dev = hns_ae_get_dsaf_dev(handle->dev);

	*tx_frames_low  = HNS_RCB_MIN_COALESCED_FRAMES;
	*rx_frames_low  = HNS_RCB_MIN_COALESCED_FRAMES;
	*tx_frames_low  = HNS_RCB_TX_FRAMES_LOW;
	*rx_frames_low  = HNS_RCB_RX_FRAMES_LOW;

	if (AE_IS_VER1(dsaf_dev->dsaf_ver) ||
	    handle->port_type == HNAE_PORT_DEBUG)
		*tx_frames_high =
		(dsaf_dev->desc_num - 1 > HNS_RCB_MAX_COALESCED_FRAMES) ?
		HNS_RCB_MAX_COALESCED_FRAMES : dsaf_dev->desc_num - 1;
	*rx_frames_high =
		(dsaf_dev->desc_num - 1 > HNS_RCB_MAX_COALESCED_FRAMES) ?
		 HNS_RCB_MAX_COALESCED_FRAMES : dsaf_dev->desc_num - 1;
	*tx_usecs_low   = 0;
	*rx_usecs_low   = 0;
	*tx_usecs_high  = HNS_RCB_MAX_COALESCED_USECS;
	*rx_usecs_high  = HNS_RCB_MAX_COALESCED_USECS;
			(dsaf_dev->desc_num - 1 > HNS_RCB_TX_FRAMES_HIGH) ?
			HNS_RCB_TX_FRAMES_HIGH : dsaf_dev->desc_num - 1;
	else
		*tx_frames_high = 1;

	*rx_frames_high = (dsaf_dev->desc_num - 1 > HNS_RCB_RX_FRAMES_HIGH) ?
		HNS_RCB_RX_FRAMES_HIGH : dsaf_dev->desc_num - 1;
	*tx_usecs_low   = HNS_RCB_TX_USECS_LOW;
	*rx_usecs_low   = HNS_RCB_RX_USECS_LOW;
	*tx_usecs_high  = HNS_RCB_TX_USECS_HIGH;
	*rx_usecs_high  = HNS_RCB_RX_USECS_HIGH;
}

void hns_ae_update_stats(struct hnae_handle *handle,
@@ -802,6 +858,7 @@ static int hns_ae_get_rss(struct hnae_handle *handle, u32 *indir, u8 *key,
		memcpy(key, ppe_cb->rss_key, HNS_PPEV2_RSS_KEY_SIZE);

	/* update the current hash->queue mappings from the shadow RSS table */
	if (indir)
		memcpy(indir, ppe_cb->rss_indir_table,
		       HNS_PPEV2_RSS_IND_TBL_SIZE  * sizeof(*indir));

@@ -814,15 +871,19 @@ static int hns_ae_set_rss(struct hnae_handle *handle, const u32 *indir,
	struct hns_ppe_cb *ppe_cb = hns_get_ppe_cb(handle);

	/* set the RSS Hash Key if specififed by the user */
	if (key)
		hns_ppe_set_rss_key(ppe_cb, (u32 *)key);
	if (key) {
		memcpy(ppe_cb->rss_key, key, HNS_PPEV2_RSS_KEY_SIZE);
		hns_ppe_set_rss_key(ppe_cb, ppe_cb->rss_key);
	}

	if (indir) {
		/* update the shadow RSS table with user specified qids */
		memcpy(ppe_cb->rss_indir_table, indir,
		       HNS_PPEV2_RSS_IND_TBL_SIZE  * sizeof(*indir));

		/* now update the hardware */
		hns_ppe_set_indir_table(ppe_cb, ppe_cb->rss_indir_table);
	}

	return 0;
}
@@ -846,7 +907,7 @@ static struct hnae_ae_ops hns_dsaf_ops = {
	.get_autoneg = hns_ae_get_autoneg,
	.set_pauseparam = hns_ae_set_pauseparam,
	.get_coalesce_usecs = hns_ae_get_coalesce_usecs,
	.get_rx_max_coalesced_frames = hns_ae_get_rx_max_coalesced_frames,
	.get_max_coalesced_frames = hns_ae_get_max_coalesced_frames,
	.set_coalesce_usecs = hns_ae_set_coalesce_usecs,
	.set_coalesce_frames = hns_ae_set_coalesce_frames,
	.get_coalesce_range = hns_ae_get_coalesce_range,
+27 −34
Original line number Diff line number Diff line
@@ -86,8 +86,7 @@ static void hns_gmac_disable(void *mac_drv, enum mac_commom_mode mode)
		dsaf_set_dev_bit(drv, GMAC_PORT_EN_REG, GMAC_PORT_RX_EN_B, 0);
}

/**
*hns_gmac_get_en - get port enable
/* hns_gmac_get_en - get port enable
 * @mac_drv:mac device
 * @rx:rx enable
 * @tx:tx enable
@@ -148,6 +147,17 @@ static void hns_gmac_config_max_frame_length(void *mac_drv, u16 newval)
			   GMAC_MAX_FRM_SIZE_S, newval);
}

static void hns_gmac_config_pad_and_crc(void *mac_drv, u8 newval)
{
	u32 tx_ctrl;
	struct mac_driver *drv = (struct mac_driver *)mac_drv;

	tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG);
	dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, !!newval);
	dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, !!newval);
	dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl);
}

static void hns_gmac_config_an_mode(void *mac_drv, u8 newval)
{
	struct mac_driver *drv = (struct mac_driver *)mac_drv;
@@ -250,7 +260,6 @@ static void hns_gmac_get_pausefrm_cfg(void *mac_drv, u32 *rx_pause_en,
static int hns_gmac_adjust_link(void *mac_drv, enum mac_speed speed,
				u32 full_duplex)
{
	u32 tx_ctrl;
	struct mac_driver *drv = (struct mac_driver *)mac_drv;

	dsaf_set_dev_bit(drv, GMAC_DUPLEX_TYPE_REG,
@@ -279,14 +288,6 @@ static int hns_gmac_adjust_link(void *mac_drv, enum mac_speed speed,
		return -EINVAL;
	}

	tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG);
	dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, 1);
	dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, 1);
	dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl);

	dsaf_set_dev_bit(drv, GMAC_MODE_CHANGE_EN_REG,
			 GMAC_MODE_CHANGE_EB_B, 1);

	return 0;
}

@@ -325,6 +326,17 @@ static void hns_gmac_init(void *mac_drv)
	hns_gmac_tx_loop_pkt_dis(mac_drv);
	if (drv->mac_cb->mac_type == HNAE_PORT_DEBUG)
		hns_gmac_set_uc_match(mac_drv, 0);

	hns_gmac_config_pad_and_crc(mac_drv, 1);

	dsaf_set_dev_bit(drv, GMAC_MODE_CHANGE_EN_REG,
			 GMAC_MODE_CHANGE_EB_B, 1);

	/* reduce gmac tx water line to avoid gmac hang-up
	 * in speed 100M and duplex half.
	 */
	dsaf_set_dev_field(drv, GMAC_TX_WATER_LINE_REG, GMAC_TX_WATER_LINE_MASK,
			   GMAC_TX_WATER_LINE_SHIFT, 8);
}

void hns_gmac_update_stats(void *mac_drv)
@@ -453,24 +465,6 @@ static int hns_gmac_config_loopback(void *mac_drv, enum hnae_loop loop_mode,
	return 0;
}

static void hns_gmac_config_pad_and_crc(void *mac_drv, u8 newval)
{
	u32 tx_ctrl;
	struct mac_driver *drv = (struct mac_driver *)mac_drv;

	tx_ctrl = dsaf_read_dev(drv, GMAC_TRANSMIT_CONTROL_REG);
	dsaf_set_bit(tx_ctrl, GMAC_TX_PAD_EN_B, !!newval);
	dsaf_set_bit(tx_ctrl, GMAC_TX_CRC_ADD_B, !!newval);
	dsaf_write_dev(drv, GMAC_TRANSMIT_CONTROL_REG, tx_ctrl);
}

static void hns_gmac_get_id(void *mac_drv, u8 *mac_id)
{
	struct mac_driver *drv = (struct mac_driver *)mac_drv;

	*mac_id = drv->mac_id;
}

static void hns_gmac_get_info(void *mac_drv, struct mac_info *mac_info)
{
	enum hns_gmac_duplex_mdoe duplex;
@@ -712,7 +706,6 @@ void *hns_gmac_config(struct hns_mac_cb *mac_cb, struct mac_params *mac_param)
	mac_drv->config_pad_and_crc = hns_gmac_config_pad_and_crc;
	mac_drv->config_half_duplex = hns_gmac_set_duplex_type;
	mac_drv->set_rx_ignore_pause_frames = hns_gmac_set_rx_auto_pause_frames;
	mac_drv->mac_get_id = hns_gmac_get_id;
	mac_drv->get_info = hns_gmac_get_info;
	mac_drv->autoneg_stat = hns_gmac_autoneg_stat;
	mac_drv->get_pause_enable = hns_gmac_get_pausefrm_cfg;
+1 −40
Original line number Diff line number Diff line
@@ -332,44 +332,6 @@ int hns_mac_set_multi(struct hns_mac_cb *mac_cb,
	return 0;
}

/**
 *hns_mac_del_mac - delete mac address into dsaf table,can't delete the same
 *                  address twice
 *@net_dev: net device
 *@vfn :   vf lan
 *@mac : mac address
 *return status
 */
int hns_mac_del_mac(struct hns_mac_cb *mac_cb, u32 vfn, char *mac)
{
	struct mac_entry_idx *old_mac;
	struct dsaf_device *dsaf_dev;
	u32 ret;

	dsaf_dev = mac_cb->dsaf_dev;

	if (vfn < DSAF_MAX_VM_NUM) {
		old_mac = &mac_cb->addr_entry_idx[vfn];
	} else {
		dev_err(mac_cb->dev,
			"vf queue is too large, %s mac%d queue = %#x!\n",
			mac_cb->dsaf_dev->ae_dev.name, mac_cb->mac_id, vfn);
		return -EINVAL;
	}

	if (dsaf_dev) {
		ret = hns_dsaf_del_mac_entry(dsaf_dev, old_mac->vlan_id,
					     mac_cb->mac_id, old_mac->addr);
		if (ret)
			return ret;

		if (memcmp(old_mac->addr, mac, sizeof(old_mac->addr)) == 0)
			old_mac->valid = 0;
	}

	return 0;
}

int hns_mac_clr_multicast(struct hns_mac_cb *mac_cb, int vfn)
{
	struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
@@ -491,10 +453,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;
Loading