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

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

Merge branch 'bnxt_en-fixes'



Michael Chan says:

====================
bnxt_en: Bug fixes.

Fixed autoneg logic and some related cleanups, fixed tx push operation,
and reduced default ring sizes.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 56bb7fd9 51dd55b5
Loading
Loading
Loading
Loading
+32 −30
Original line number Original line Diff line number Diff line
@@ -69,7 +69,7 @@ MODULE_VERSION(DRV_MODULE_VERSION);
#define BNXT_RX_DMA_OFFSET NET_SKB_PAD
#define BNXT_RX_DMA_OFFSET NET_SKB_PAD
#define BNXT_RX_COPY_THRESH 256
#define BNXT_RX_COPY_THRESH 256


#define BNXT_TX_PUSH_THRESH 92
#define BNXT_TX_PUSH_THRESH 164


enum board_idx {
enum board_idx {
	BCM57301,
	BCM57301,
@@ -223,11 +223,12 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
	}
	}


	if (free_size == bp->tx_ring_size && length <= bp->tx_push_thresh) {
	if (free_size == bp->tx_ring_size && length <= bp->tx_push_thresh) {
		struct tx_push_bd *push = txr->tx_push;
		struct tx_push_buffer *tx_push_buf = txr->tx_push;
		struct tx_bd *tx_push = &push->txbd1;
		struct tx_push_bd *tx_push = &tx_push_buf->push_bd;
		struct tx_bd_ext *tx_push1 = &push->txbd2;
		struct tx_bd_ext *tx_push1 = &tx_push->txbd2;
		void *pdata = tx_push1 + 1;
		void *pdata = tx_push_buf->data;
		int j;
		u64 *end;
		int j, push_len;


		/* Set COAL_NOW to be ready quickly for the next push */
		/* Set COAL_NOW to be ready quickly for the next push */
		tx_push->tx_bd_len_flags_type =
		tx_push->tx_bd_len_flags_type =
@@ -247,6 +248,9 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
		tx_push1->tx_bd_cfa_meta = cpu_to_le32(vlan_tag_flags);
		tx_push1->tx_bd_cfa_meta = cpu_to_le32(vlan_tag_flags);
		tx_push1->tx_bd_cfa_action = cpu_to_le32(cfa_action);
		tx_push1->tx_bd_cfa_action = cpu_to_le32(cfa_action);


		end = PTR_ALIGN(pdata + length + 1, 8) - 1;
		*end = 0;

		skb_copy_from_linear_data(skb, pdata, len);
		skb_copy_from_linear_data(skb, pdata, len);
		pdata += len;
		pdata += len;
		for (j = 0; j < last_frag; j++) {
		for (j = 0; j < last_frag; j++) {
@@ -261,22 +265,29 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
			pdata += skb_frag_size(frag);
			pdata += skb_frag_size(frag);
		}
		}


		memcpy(txbd, tx_push, sizeof(*txbd));
		txbd->tx_bd_len_flags_type = tx_push->tx_bd_len_flags_type;
		txbd->tx_bd_haddr = txr->data_mapping;
		prod = NEXT_TX(prod);
		prod = NEXT_TX(prod);
		txbd = &txr->tx_desc_ring[TX_RING(prod)][TX_IDX(prod)];
		txbd = &txr->tx_desc_ring[TX_RING(prod)][TX_IDX(prod)];
		memcpy(txbd, tx_push1, sizeof(*txbd));
		memcpy(txbd, tx_push1, sizeof(*txbd));
		prod = NEXT_TX(prod);
		prod = NEXT_TX(prod);
		push->doorbell =
		tx_push->doorbell =
			cpu_to_le32(DB_KEY_TX_PUSH | DB_LONG_TX_PUSH | prod);
			cpu_to_le32(DB_KEY_TX_PUSH | DB_LONG_TX_PUSH | prod);
		txr->tx_prod = prod;
		txr->tx_prod = prod;


		netdev_tx_sent_queue(txq, skb->len);
		netdev_tx_sent_queue(txq, skb->len);


		__iowrite64_copy(txr->tx_doorbell, push,
		push_len = (length + sizeof(*tx_push) + 7) / 8;
				 (length + sizeof(*push) + 8) / 8);
		if (push_len > 16) {
			__iowrite64_copy(txr->tx_doorbell, tx_push_buf, 16);
			__iowrite64_copy(txr->tx_doorbell + 4, tx_push_buf + 1,
					 push_len - 16);
		} else {
			__iowrite64_copy(txr->tx_doorbell, tx_push_buf,
					 push_len);
		}


		tx_buf->is_push = 1;
		tx_buf->is_push = 1;

		goto tx_done;
		goto tx_done;
	}
	}


@@ -1753,7 +1764,7 @@ static int bnxt_alloc_tx_rings(struct bnxt *bp)
		push_size  = L1_CACHE_ALIGN(sizeof(struct tx_push_bd) +
		push_size  = L1_CACHE_ALIGN(sizeof(struct tx_push_bd) +
					bp->tx_push_thresh);
					bp->tx_push_thresh);


		if (push_size > 128) {
		if (push_size > 256) {
			push_size = 0;
			push_size = 0;
			bp->tx_push_thresh = 0;
			bp->tx_push_thresh = 0;
		}
		}
@@ -1772,7 +1783,6 @@ static int bnxt_alloc_tx_rings(struct bnxt *bp)
			return rc;
			return rc;


		if (bp->tx_push_size) {
		if (bp->tx_push_size) {
			struct tx_bd *txbd;
			dma_addr_t mapping;
			dma_addr_t mapping;


			/* One pre-allocated DMA buffer to backup
			/* One pre-allocated DMA buffer to backup
@@ -1786,13 +1796,11 @@ static int bnxt_alloc_tx_rings(struct bnxt *bp)
			if (!txr->tx_push)
			if (!txr->tx_push)
				return -ENOMEM;
				return -ENOMEM;


			txbd = &txr->tx_push->txbd1;

			mapping = txr->tx_push_mapping +
			mapping = txr->tx_push_mapping +
				sizeof(struct tx_push_bd);
				sizeof(struct tx_push_bd);
			txbd->tx_bd_haddr = cpu_to_le64(mapping);
			txr->data_mapping = cpu_to_le64(mapping);


			memset(txbd + 1, 0, sizeof(struct tx_bd_ext));
			memset(txr->tx_push, 0, sizeof(struct tx_push_bd));
		}
		}
		ring->queue_id = bp->q_info[j].queue_id;
		ring->queue_id = bp->q_info[j].queue_id;
		if (i % bp->tx_nr_rings_per_tc == (bp->tx_nr_rings_per_tc - 1))
		if (i % bp->tx_nr_rings_per_tc == (bp->tx_nr_rings_per_tc - 1))
@@ -5670,22 +5678,16 @@ static int bnxt_probe_phy(struct bnxt *bp)
	}
	}


	/*initialize the ethool setting copy with NVM settings */
	/*initialize the ethool setting copy with NVM settings */
	if (BNXT_AUTO_MODE(link_info->auto_mode))
	if (BNXT_AUTO_MODE(link_info->auto_mode)) {
		link_info->autoneg |= BNXT_AUTONEG_SPEED;
		link_info->autoneg = BNXT_AUTONEG_SPEED |

				     BNXT_AUTONEG_FLOW_CTRL;
	if (link_info->auto_pause_setting & BNXT_LINK_PAUSE_BOTH) {
		link_info->advertising = link_info->auto_link_speeds;
		if (link_info->auto_pause_setting == BNXT_LINK_PAUSE_BOTH)
			link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL;
		link_info->req_flow_ctrl = link_info->auto_pause_setting;
		link_info->req_flow_ctrl = link_info->auto_pause_setting;
	} else if (link_info->force_pause_setting & BNXT_LINK_PAUSE_BOTH) {
	} else {
		link_info->req_link_speed = link_info->force_link_speed;
		link_info->req_duplex = link_info->duplex_setting;
		link_info->req_flow_ctrl = link_info->force_pause_setting;
		link_info->req_flow_ctrl = link_info->force_pause_setting;
	}
	}
	link_info->req_duplex = link_info->duplex_setting;
	if (link_info->autoneg & BNXT_AUTONEG_SPEED)
		link_info->req_link_speed = link_info->auto_link_speed;
	else
		link_info->req_link_speed = link_info->force_link_speed;
	link_info->advertising = link_info->auto_link_speeds;
	snprintf(phy_ver, PHY_VER_STR_LEN, " ph %d.%d.%d",
	snprintf(phy_ver, PHY_VER_STR_LEN, " ph %d.%d.%d",
		 link_info->phy_ver[0],
		 link_info->phy_ver[0],
		 link_info->phy_ver[1],
		 link_info->phy_ver[1],
+11 −4
Original line number Original line Diff line number Diff line
@@ -411,8 +411,8 @@ struct rx_tpa_end_cmp_ext {


#define BNXT_NUM_TESTS(bp)	0
#define BNXT_NUM_TESTS(bp)	0


#define BNXT_DEFAULT_RX_RING_SIZE	1023
#define BNXT_DEFAULT_RX_RING_SIZE	511
#define BNXT_DEFAULT_TX_RING_SIZE	512
#define BNXT_DEFAULT_TX_RING_SIZE	511


#define MAX_TPA		64
#define MAX_TPA		64


@@ -523,10 +523,16 @@ struct bnxt_ring_struct {


struct tx_push_bd {
struct tx_push_bd {
	__le32			doorbell;
	__le32			doorbell;
	struct tx_bd		txbd1;
	__le32			tx_bd_len_flags_type;
	u32			tx_bd_opaque;
	struct tx_bd_ext	txbd2;
	struct tx_bd_ext	txbd2;
};
};


struct tx_push_buffer {
	struct tx_push_bd	push_bd;
	u32			data[25];
};

struct bnxt_tx_ring_info {
struct bnxt_tx_ring_info {
	struct bnxt_napi	*bnapi;
	struct bnxt_napi	*bnapi;
	u16			tx_prod;
	u16			tx_prod;
@@ -538,8 +544,9 @@ struct bnxt_tx_ring_info {


	dma_addr_t		tx_desc_mapping[MAX_TX_PAGES];
	dma_addr_t		tx_desc_mapping[MAX_TX_PAGES];


	struct tx_push_bd	*tx_push;
	struct tx_push_buffer	*tx_push;
	dma_addr_t		tx_push_mapping;
	dma_addr_t		tx_push_mapping;
	__le64			data_mapping;


#define BNXT_DEV_STATE_CLOSING	0x1
#define BNXT_DEV_STATE_CLOSING	0x1
	u32			dev_state;
	u32			dev_state;
+13 −33
Original line number Original line Diff line number Diff line
@@ -486,15 +486,8 @@ static u32 bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info)
		speed_mask |= SUPPORTED_2500baseX_Full;
		speed_mask |= SUPPORTED_2500baseX_Full;
	if (fw_speeds & BNXT_LINK_SPEED_MSK_10GB)
	if (fw_speeds & BNXT_LINK_SPEED_MSK_10GB)
		speed_mask |= SUPPORTED_10000baseT_Full;
		speed_mask |= SUPPORTED_10000baseT_Full;
	/* TODO: support 25GB, 50GB with different cable type */
	if (fw_speeds & BNXT_LINK_SPEED_MSK_20GB)
		speed_mask |= SUPPORTED_20000baseMLD2_Full |
			SUPPORTED_20000baseKR2_Full;
	if (fw_speeds & BNXT_LINK_SPEED_MSK_40GB)
	if (fw_speeds & BNXT_LINK_SPEED_MSK_40GB)
		speed_mask |= SUPPORTED_40000baseKR4_Full |
		speed_mask |= SUPPORTED_40000baseCR4_Full;
			SUPPORTED_40000baseCR4_Full |
			SUPPORTED_40000baseSR4_Full |
			SUPPORTED_40000baseLR4_Full;


	return speed_mask;
	return speed_mask;
}
}
@@ -514,15 +507,8 @@ static u32 bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info)
		speed_mask |= ADVERTISED_2500baseX_Full;
		speed_mask |= ADVERTISED_2500baseX_Full;
	if (fw_speeds & BNXT_LINK_SPEED_MSK_10GB)
	if (fw_speeds & BNXT_LINK_SPEED_MSK_10GB)
		speed_mask |= ADVERTISED_10000baseT_Full;
		speed_mask |= ADVERTISED_10000baseT_Full;
	/* TODO: how to advertise 20, 25, 40, 50GB with different cable type ?*/
	if (fw_speeds & BNXT_LINK_SPEED_MSK_20GB)
		speed_mask |= ADVERTISED_20000baseMLD2_Full |
			      ADVERTISED_20000baseKR2_Full;
	if (fw_speeds & BNXT_LINK_SPEED_MSK_40GB)
	if (fw_speeds & BNXT_LINK_SPEED_MSK_40GB)
		speed_mask |= ADVERTISED_40000baseKR4_Full |
		speed_mask |= ADVERTISED_40000baseCR4_Full;
			      ADVERTISED_40000baseCR4_Full |
			      ADVERTISED_40000baseSR4_Full |
			      ADVERTISED_40000baseLR4_Full;
	return speed_mask;
	return speed_mask;
}
}


@@ -557,11 +543,12 @@ static int bnxt_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
	u16 ethtool_speed;
	u16 ethtool_speed;


	cmd->supported = bnxt_fw_to_ethtool_support_spds(link_info);
	cmd->supported = bnxt_fw_to_ethtool_support_spds(link_info);
	cmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;


	if (link_info->auto_link_speeds)
	if (link_info->auto_link_speeds)
		cmd->supported |= SUPPORTED_Autoneg;
		cmd->supported |= SUPPORTED_Autoneg;


	if (BNXT_AUTO_MODE(link_info->auto_mode)) {
	if (link_info->autoneg) {
		cmd->advertising =
		cmd->advertising =
			bnxt_fw_to_ethtool_advertised_spds(link_info);
			bnxt_fw_to_ethtool_advertised_spds(link_info);
		cmd->advertising |= ADVERTISED_Autoneg;
		cmd->advertising |= ADVERTISED_Autoneg;
@@ -570,28 +557,16 @@ static int bnxt_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
		cmd->autoneg = AUTONEG_DISABLE;
		cmd->autoneg = AUTONEG_DISABLE;
		cmd->advertising = 0;
		cmd->advertising = 0;
	}
	}
	if (link_info->auto_pause_setting & BNXT_LINK_PAUSE_BOTH) {
	if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL) {
		if ((link_info->auto_pause_setting & BNXT_LINK_PAUSE_BOTH) ==
		if ((link_info->auto_pause_setting & BNXT_LINK_PAUSE_BOTH) ==
		    BNXT_LINK_PAUSE_BOTH) {
		    BNXT_LINK_PAUSE_BOTH) {
			cmd->advertising |= ADVERTISED_Pause;
			cmd->advertising |= ADVERTISED_Pause;
			cmd->supported |= SUPPORTED_Pause;
		} else {
		} else {
			cmd->advertising |= ADVERTISED_Asym_Pause;
			cmd->advertising |= ADVERTISED_Asym_Pause;
			cmd->supported |= SUPPORTED_Asym_Pause;
			if (link_info->auto_pause_setting &
			if (link_info->auto_pause_setting &
			    BNXT_LINK_PAUSE_RX)
			    BNXT_LINK_PAUSE_RX)
				cmd->advertising |= ADVERTISED_Pause;
				cmd->advertising |= ADVERTISED_Pause;
		}
		}
	} else if (link_info->force_pause_setting & BNXT_LINK_PAUSE_BOTH) {
		if ((link_info->force_pause_setting & BNXT_LINK_PAUSE_BOTH) ==
		    BNXT_LINK_PAUSE_BOTH) {
			cmd->supported |= SUPPORTED_Pause;
		} else {
			cmd->supported |= SUPPORTED_Asym_Pause;
			if (link_info->force_pause_setting &
			    BNXT_LINK_PAUSE_RX)
				cmd->supported |= SUPPORTED_Pause;
		}
	}
	}


	cmd->port = PORT_NONE;
	cmd->port = PORT_NONE;
@@ -670,6 +645,9 @@ static u16 bnxt_get_fw_auto_link_speeds(u32 advertising)
	if (advertising & ADVERTISED_10000baseT_Full)
	if (advertising & ADVERTISED_10000baseT_Full)
		fw_speed_mask |= BNXT_LINK_SPEED_MSK_10GB;
		fw_speed_mask |= BNXT_LINK_SPEED_MSK_10GB;


	if (advertising & ADVERTISED_40000baseCR4_Full)
		fw_speed_mask |= BNXT_LINK_SPEED_MSK_40GB;

	return fw_speed_mask;
	return fw_speed_mask;
}
}


@@ -729,7 +707,7 @@ static int bnxt_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
		speed = ethtool_cmd_speed(cmd);
		speed = ethtool_cmd_speed(cmd);
		link_info->req_link_speed = bnxt_get_fw_speed(dev, speed);
		link_info->req_link_speed = bnxt_get_fw_speed(dev, speed);
		link_info->req_duplex = BNXT_LINK_DUPLEX_FULL;
		link_info->req_duplex = BNXT_LINK_DUPLEX_FULL;
		link_info->autoneg &= ~BNXT_AUTONEG_SPEED;
		link_info->autoneg = 0;
		link_info->advertising = 0;
		link_info->advertising = 0;
	}
	}


@@ -748,8 +726,7 @@ static void bnxt_get_pauseparam(struct net_device *dev,


	if (BNXT_VF(bp))
	if (BNXT_VF(bp))
		return;
		return;
	epause->autoneg = !!(link_info->auto_pause_setting &
	epause->autoneg = !!(link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL);
			     BNXT_LINK_PAUSE_BOTH);
	epause->rx_pause = ((link_info->pause & BNXT_LINK_PAUSE_RX) != 0);
	epause->rx_pause = ((link_info->pause & BNXT_LINK_PAUSE_RX) != 0);
	epause->tx_pause = ((link_info->pause & BNXT_LINK_PAUSE_TX) != 0);
	epause->tx_pause = ((link_info->pause & BNXT_LINK_PAUSE_TX) != 0);
}
}
@@ -765,6 +742,9 @@ static int bnxt_set_pauseparam(struct net_device *dev,
		return rc;
		return rc;


	if (epause->autoneg) {
	if (epause->autoneg) {
		if (!(link_info->autoneg & BNXT_AUTONEG_SPEED))
			return -EINVAL;

		link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL;
		link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL;
		link_info->req_flow_ctrl |= BNXT_LINK_PAUSE_BOTH;
		link_info->req_flow_ctrl |= BNXT_LINK_PAUSE_BOTH;
	} else {
	} else {