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

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

Merge branch 'bnxt_en-next'



Michael Chan says:

====================
bnxt_en: Updates for net-next.

This series includes firmware interface update, some optimizations,
some new PCI IDs, new MTU checks, ethtool reset method, interrupt coalescing
code cleanup, and TC flower offload for vxlan encap/decap from Sathya
Perla.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e324615b cd66358e
Loading
Loading
Loading
Loading
+96 −74
Original line number Diff line number Diff line
@@ -108,9 +108,11 @@ enum board_idx {
	BCM57452,
	BCM57454,
	BCM58802,
	BCM58804,
	BCM58808,
	NETXTREME_E_VF,
	NETXTREME_C_VF,
	NETXTREME_S_VF,
};

/* indexed by enum above */
@@ -146,9 +148,11 @@ static const struct {
	[BCM57452] = { "Broadcom BCM57452 NetXtreme-E 10Gb/25Gb/40Gb/50Gb Ethernet" },
	[BCM57454] = { "Broadcom BCM57454 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" },
	[BCM58802] = { "Broadcom BCM58802 NetXtreme-S 10Gb/25Gb/40Gb/50Gb Ethernet" },
	[BCM58804] = { "Broadcom BCM58804 NetXtreme-S 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" },
	[BCM58808] = { "Broadcom BCM58808 NetXtreme-S 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" },
	[NETXTREME_E_VF] = { "Broadcom NetXtreme-E Ethernet Virtual Function" },
	[NETXTREME_C_VF] = { "Broadcom NetXtreme-C Ethernet Virtual Function" },
	[NETXTREME_S_VF] = { "Broadcom NetXtreme-S Ethernet Virtual Function" },
};

static const struct pci_device_id bnxt_pci_tbl[] = {
@@ -186,6 +190,7 @@ static const struct pci_device_id bnxt_pci_tbl[] = {
	{ PCI_VDEVICE(BROADCOM, 0x16f0), .driver_data = BCM58808 },
	{ PCI_VDEVICE(BROADCOM, 0x16f1), .driver_data = BCM57452 },
	{ PCI_VDEVICE(BROADCOM, 0xd802), .driver_data = BCM58802 },
	{ PCI_VDEVICE(BROADCOM, 0xd804), .driver_data = BCM58804 },
#ifdef CONFIG_BNXT_SRIOV
	{ PCI_VDEVICE(BROADCOM, 0x1606), .driver_data = NETXTREME_E_VF },
	{ PCI_VDEVICE(BROADCOM, 0x1609), .driver_data = NETXTREME_E_VF },
@@ -195,6 +200,7 @@ static const struct pci_device_id bnxt_pci_tbl[] = {
	{ PCI_VDEVICE(BROADCOM, 0x16dc), .driver_data = NETXTREME_E_VF },
	{ PCI_VDEVICE(BROADCOM, 0x16e1), .driver_data = NETXTREME_C_VF },
	{ PCI_VDEVICE(BROADCOM, 0x16e5), .driver_data = NETXTREME_C_VF },
	{ PCI_VDEVICE(BROADCOM, 0xd800), .driver_data = NETXTREME_S_VF },
#endif
	{ 0 }
};
@@ -219,7 +225,8 @@ static struct workqueue_struct *bnxt_pf_wq;

static bool bnxt_vf_pciid(enum board_idx idx)
{
	return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF);
	return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF ||
		idx == NETXTREME_S_VF);
}

#define DB_CP_REARM_FLAGS	(DB_KEY_CP | DB_IDX_VALID)
@@ -2828,7 +2835,8 @@ int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
	if (page_mode) {
		if (bp->dev->mtu > BNXT_MAX_PAGE_MODE_MTU)
			return -EOPNOTSUPP;
		bp->dev->max_mtu = BNXT_MAX_PAGE_MODE_MTU;
		bp->dev->max_mtu =
			min_t(u16, bp->max_mtu, BNXT_MAX_PAGE_MODE_MTU);
		bp->flags &= ~BNXT_FLAG_AGG_RINGS;
		bp->flags |= BNXT_FLAG_NO_AGG_RINGS | BNXT_FLAG_RX_PAGE_MODE;
		bp->dev->hw_features &= ~NETIF_F_LRO;
@@ -2836,7 +2844,7 @@ int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
		bp->rx_dir = DMA_BIDIRECTIONAL;
		bp->rx_skb_func = bnxt_rx_page_skb;
	} else {
		bp->dev->max_mtu = BNXT_MAX_MTU;
		bp->dev->max_mtu = bp->max_mtu;
		bp->flags &= ~BNXT_FLAG_RX_PAGE_MODE;
		bp->rx_dir = DMA_FROM_DEVICE;
		bp->rx_skb_func = bnxt_rx_skb;
@@ -4529,19 +4537,42 @@ static int bnxt_hwrm_check_tx_rings(struct bnxt *bp, int tx_rings)
	return 0;
}

static void bnxt_hwrm_set_coal_params(struct bnxt *bp, u32 max_bufs,
	u32 buf_tmrs, u16 flags,
static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal,
	struct hwrm_ring_cmpl_ring_cfg_aggint_params_input *req)
{
	u16 val, tmr, max, flags;

	max = hw_coal->bufs_per_record * 128;
	if (hw_coal->budget)
		max = hw_coal->bufs_per_record * hw_coal->budget;

	val = clamp_t(u16, hw_coal->coal_bufs, 1, max);
	req->num_cmpl_aggr_int = cpu_to_le16(val);
	req->num_cmpl_dma_aggr = cpu_to_le16(val);

	val = clamp_t(u16, hw_coal->coal_bufs_irq, 1, max);
	req->num_cmpl_dma_aggr_during_int = cpu_to_le16(val);

	tmr = BNXT_USEC_TO_COAL_TIMER(hw_coal->coal_ticks);
	tmr = max_t(u16, tmr, 1);
	req->int_lat_tmr_max = cpu_to_le16(tmr);

	/* min timer set to 1/2 of interrupt timer */
	val = tmr / 2;
	req->int_lat_tmr_min = cpu_to_le16(val);

	/* buf timer set to 1/4 of interrupt timer */
	val = max_t(u16, tmr / 4, 1);
	req->cmpl_aggr_dma_tmr = cpu_to_le16(val);

	tmr = BNXT_USEC_TO_COAL_TIMER(hw_coal->coal_ticks_irq);
	tmr = max_t(u16, tmr, 1);
	req->cmpl_aggr_dma_tmr_during_int = cpu_to_le16(tmr);

	flags = RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET;
	if (hw_coal->idle_thresh && hw_coal->coal_ticks < hw_coal->idle_thresh)
		flags |= RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_RING_IDLE;
	req->flags = cpu_to_le16(flags);
	req->num_cmpl_dma_aggr = cpu_to_le16((u16)max_bufs);
	req->num_cmpl_dma_aggr_during_int = cpu_to_le16(max_bufs >> 16);
	req->cmpl_aggr_dma_tmr = cpu_to_le16((u16)buf_tmrs);
	req->cmpl_aggr_dma_tmr_during_int = cpu_to_le16(buf_tmrs >> 16);
	/* Minimum time between 2 interrupts set to buf_tmr x 2 */
	req->int_lat_tmr_min = cpu_to_le16((u16)buf_tmrs * 2);
	req->int_lat_tmr_max = cpu_to_le16((u16)buf_tmrs * 4);
	req->num_cmpl_aggr_int = cpu_to_le16((u16)max_bufs * 4);
}

int bnxt_hwrm_set_coal(struct bnxt *bp)
@@ -4549,51 +4580,14 @@ int bnxt_hwrm_set_coal(struct bnxt *bp)
	int i, rc = 0;
	struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req_rx = {0},
							   req_tx = {0}, *req;
	u16 max_buf, max_buf_irq;
	u16 buf_tmr, buf_tmr_irq;
	u32 flags;

	bnxt_hwrm_cmd_hdr_init(bp, &req_rx,
			       HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS, -1, -1);
	bnxt_hwrm_cmd_hdr_init(bp, &req_tx,
			       HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS, -1, -1);

	/* Each rx completion (2 records) should be DMAed immediately.
	 * DMA 1/4 of the completion buffers at a time.
	 */
	max_buf = min_t(u16, bp->rx_coal_bufs / 4, 2);
	/* max_buf must not be zero */
	max_buf = clamp_t(u16, max_buf, 1, 63);
	max_buf_irq = clamp_t(u16, bp->rx_coal_bufs_irq, 1, 63);
	buf_tmr = BNXT_USEC_TO_COAL_TIMER(bp->rx_coal_ticks);
	/* buf timer set to 1/4 of interrupt timer */
	buf_tmr = max_t(u16, buf_tmr / 4, 1);
	buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(bp->rx_coal_ticks_irq);
	buf_tmr_irq = max_t(u16, buf_tmr_irq, 1);

	flags = RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET;

	/* RING_IDLE generates more IRQs for lower latency.  Enable it only
	 * if coal_ticks is less than 25 us.
	 */
	if (bp->rx_coal_ticks < 25)
		flags |= RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_RING_IDLE;

	bnxt_hwrm_set_coal_params(bp, max_buf_irq << 16 | max_buf,
				  buf_tmr_irq << 16 | buf_tmr, flags, &req_rx);

	/* max_buf must not be zero */
	max_buf = clamp_t(u16, bp->tx_coal_bufs, 1, 63);
	max_buf_irq = clamp_t(u16, bp->tx_coal_bufs_irq, 1, 63);
	buf_tmr = BNXT_USEC_TO_COAL_TIMER(bp->tx_coal_ticks);
	/* buf timer set to 1/4 of interrupt timer */
	buf_tmr = max_t(u16, buf_tmr / 4, 1);
	buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(bp->tx_coal_ticks_irq);
	buf_tmr_irq = max_t(u16, buf_tmr_irq, 1);

	flags = RING_CMPL_RING_CFG_AGGINT_PARAMS_REQ_FLAGS_TIMER_RESET;
	bnxt_hwrm_set_coal_params(bp, max_buf_irq << 16 | max_buf,
				  buf_tmr_irq << 16 | buf_tmr, flags, &req_tx);
	bnxt_hwrm_set_coal_params(&bp->rx_coal, &req_rx);
	bnxt_hwrm_set_coal_params(&bp->tx_coal, &req_tx);

	mutex_lock(&bp->hwrm_cmd_lock);
	for (i = 0; i < bp->cp_nr_rings; i++) {
@@ -4725,6 +4719,10 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp)
	else
		bp->br_mode = BRIDGE_MODE_UNDEF;

	bp->max_mtu = le16_to_cpu(resp->max_mtu_configured);
	if (!bp->max_mtu)
		bp->max_mtu = BNXT_MAX_MTU;

func_qcfg_exit:
	mutex_unlock(&bp->hwrm_cmd_lock);
	return rc;
@@ -4885,9 +4883,9 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
			    resp->hwrm_intf_upd);
		netdev_warn(bp->dev, "Please update firmware with HWRM interface 1.0.0 or newer.\n");
	}
	snprintf(bp->fw_ver_str, BC_HWRM_STR_LEN, "%d.%d.%d/%d.%d.%d",
	snprintf(bp->fw_ver_str, BC_HWRM_STR_LEN, "%d.%d.%d.%d",
		 resp->hwrm_fw_maj, resp->hwrm_fw_min, resp->hwrm_fw_bld,
		 resp->hwrm_intf_maj, resp->hwrm_intf_min, resp->hwrm_intf_upd);
		 resp->hwrm_fw_rsvd);

	bp->hwrm_cmd_timeout = le16_to_cpu(resp->def_req_timeout);
	if (!bp->hwrm_cmd_timeout)
@@ -6981,6 +6979,11 @@ static void bnxt_timer(unsigned long data)
		set_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event);
		bnxt_queue_sp_work(bp);
	}

	if (bnxt_tc_flower_enabled(bp)) {
		set_bit(BNXT_FLOW_STATS_SP_EVENT, &bp->sp_event);
		bnxt_queue_sp_work(bp);
	}
bnxt_restart_timer:
	mod_timer(&bp->timer, jiffies + bp->current_interval);
}
@@ -7071,6 +7074,10 @@ static void bnxt_sp_task(struct work_struct *work)
		bnxt_get_port_module_status(bp);
		mutex_unlock(&bp->link_lock);
	}

	if (test_and_clear_bit(BNXT_FLOW_STATS_SP_EVENT, &bp->sp_event))
		bnxt_tc_flow_stats_work(bp);

	/* These functions below will clear BNXT_STATE_IN_SP_TASK.  They
	 * must be the last functions to be called before exiting.
	 */
@@ -7134,6 +7141,32 @@ static void bnxt_cleanup_pci(struct bnxt *bp)
	pci_disable_device(bp->pdev);
}

static void bnxt_init_dflt_coal(struct bnxt *bp)
{
	struct bnxt_coal *coal;

	/* Tick values in micro seconds.
	 * 1 coal_buf x bufs_per_record = 1 completion record.
	 */
	coal = &bp->rx_coal;
	coal->coal_ticks = 14;
	coal->coal_bufs = 30;
	coal->coal_ticks_irq = 1;
	coal->coal_bufs_irq = 2;
	coal->idle_thresh = 25;
	coal->bufs_per_record = 2;
	coal->budget = 64;		/* NAPI budget */

	coal = &bp->tx_coal;
	coal->coal_ticks = 28;
	coal->coal_bufs = 30;
	coal->coal_ticks_irq = 2;
	coal->coal_bufs_irq = 2;
	coal->bufs_per_record = 1;

	bp->stats_coal_ticks = BNXT_DEF_STATS_COAL_TICKS;
}

static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
{
	int rc;
@@ -7202,18 +7235,7 @@ static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
	bp->rx_ring_size = BNXT_DEFAULT_RX_RING_SIZE;
	bp->tx_ring_size = BNXT_DEFAULT_TX_RING_SIZE;

	/* tick values in micro seconds */
	bp->rx_coal_ticks = 12;
	bp->rx_coal_bufs = 30;
	bp->rx_coal_ticks_irq = 1;
	bp->rx_coal_bufs_irq = 2;

	bp->tx_coal_ticks = 25;
	bp->tx_coal_bufs = 30;
	bp->tx_coal_ticks_irq = 2;
	bp->tx_coal_bufs_irq = 2;

	bp->stats_coal_ticks = BNXT_DEF_STATS_COAL_TICKS;
	bnxt_init_dflt_coal(bp);

	setup_timer(&bp->timer, bnxt_timer, (unsigned long)bp);
	bp->current_interval = BNXT_TIMER_INTERVAL;
@@ -7242,13 +7264,13 @@ static int bnxt_change_mac_addr(struct net_device *dev, void *p)
	if (!is_valid_ether_addr(addr->sa_data))
		return -EADDRNOTAVAIL;

	if (ether_addr_equal(addr->sa_data, dev->dev_addr))
		return 0;

	rc = bnxt_approve_mac(bp, addr->sa_data);
	if (rc)
		return rc;

	if (ether_addr_equal(addr->sa_data, dev->dev_addr))
		return 0;

	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
	if (netif_running(dev)) {
		bnxt_close_nic(bp, false, false);
@@ -7325,7 +7347,7 @@ static int bnxt_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
{
	struct bnxt *bp = cb_priv;

	if (BNXT_VF(bp))
	if (!bnxt_tc_flower_enabled(bp))
		return -EOPNOTSUPP;

	switch (type) {
@@ -8088,10 +8110,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
	dev->features |= dev->hw_features | NETIF_F_HIGHDMA;
	dev->priv_flags |= IFF_UNICAST_FLT;

	/* MTU range: 60 - 9500 */
	dev->min_mtu = ETH_ZLEN;
	dev->max_mtu = BNXT_MAX_MTU;

#ifdef CONFIG_BNXT_SRIOV
	init_waitqueue_head(&bp->sriov_cfg_wait);
	mutex_init(&bp->sriov_lock);
@@ -8139,6 +8157,10 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
	bnxt_ethtool_init(bp);
	bnxt_dcb_init(bp);

	/* MTU range: 60 - FW defined max */
	dev->min_mtu = ETH_ZLEN;
	dev->max_mtu = bp->max_mtu;

	rc = bnxt_probe_phy(bp);
	if (rc)
		goto init_err_pci_clean;
+40 −9
Original line number Diff line number Diff line
@@ -944,6 +944,22 @@ struct bnxt_test_info {
#define BNXT_CAG_REG_LEGACY_INT_STATUS	0x4014
#define BNXT_CAG_REG_BASE		0x300000

struct bnxt_coal {
	u16			coal_ticks;
	u16			coal_ticks_irq;
	u16			coal_bufs;
	u16			coal_bufs_irq;
			/* RING_IDLE enabled when coal ticks < idle_thresh  */
	u16			idle_thresh;
	u8			bufs_per_record;
	u8			budget;
};

struct bnxt_tc_flow_stats {
	u64		packets;
	u64		bytes;
};

struct bnxt_tc_info {
	bool				enabled;

@@ -954,12 +970,29 @@ struct bnxt_tc_info {
	/* hash table to store L2 keys of TC flows */
	struct rhashtable		l2_table;
	struct rhashtable_params	l2_ht_params;
	/* hash table to store L2 keys for TC tunnel decap */
	struct rhashtable		decap_l2_table;
	struct rhashtable_params	decap_l2_ht_params;
	/* hash table to store tunnel decap entries */
	struct rhashtable		decap_table;
	struct rhashtable_params	decap_ht_params;
	/* hash table to store tunnel encap entries */
	struct rhashtable		encap_table;
	struct rhashtable_params	encap_ht_params;

	/* lock to atomically add/del an l2 node when a flow is
	 * added or deleted.
	 */
	struct mutex			lock;

	/* Fields used for batching stats query */
	struct rhashtable_iter		iter;
#define BNXT_FLOW_STATS_BATCH_MAX	10
	struct bnxt_tc_stats_batch {
		void			  *flow_node;
		struct bnxt_tc_flow_stats hw_stats;
	} stats_batch[BNXT_FLOW_STATS_BATCH_MAX];

	/* Stat counter mask (width) */
	u64				bytes_mask;
	u64				packets_mask;
@@ -1013,6 +1046,7 @@ struct bnxt {
#define CHIP_NUM_5745X		0xd730

#define CHIP_NUM_58802		0xd802
#define CHIP_NUM_58804		0xd804
#define CHIP_NUM_58808		0xd808

#define BNXT_CHIP_NUM_5730X(chip_num)		\
@@ -1048,6 +1082,7 @@ struct bnxt {

#define BNXT_CHIP_NUM_588XX(chip_num)		\
	((chip_num) == CHIP_NUM_58802 ||	\
	 (chip_num) == CHIP_NUM_58804 ||        \
	 (chip_num) == CHIP_NUM_58808)

	struct net_device	*dev;
@@ -1170,6 +1205,7 @@ struct bnxt {
	int			nr_vnics;
	u32			rss_hash_cfg;

	u16			max_mtu;
	u8			max_tc;
	u8			max_lltc;	/* lossless TCs */
	struct bnxt_queue_info	q_info[BNXT_MAX_QUEUE];
@@ -1232,14 +1268,8 @@ struct bnxt {
	u8			port_count;
	u16			br_mode;

	u16			rx_coal_ticks;
	u16			rx_coal_ticks_irq;
	u16			rx_coal_bufs;
	u16			rx_coal_bufs_irq;
	u16			tx_coal_ticks;
	u16			tx_coal_ticks_irq;
	u16			tx_coal_bufs;
	u16			tx_coal_bufs_irq;
	struct bnxt_coal	rx_coal;
	struct bnxt_coal	tx_coal;

#define BNXT_USEC_TO_COAL_TIMER(x)	((x) * 25 / 2)

@@ -1265,6 +1295,7 @@ struct bnxt {
#define BNXT_GENEVE_ADD_PORT_SP_EVENT	12
#define BNXT_GENEVE_DEL_PORT_SP_EVENT	13
#define BNXT_LINK_SPEED_CHNG_SP_EVENT	14
#define BNXT_FLOW_STATS_SP_EVENT	15

	struct bnxt_pf_info	pf;
#ifdef CONFIG_BNXT_SRIOV
@@ -1315,7 +1346,7 @@ struct bnxt {
	enum devlink_eswitch_mode eswitch_mode;
	struct bnxt_vf_rep	**vf_reps; /* array of vf-rep ptrs */
	u16			*cfa_code_map; /* cfa_code -> vf_idx map */
	struct bnxt_tc_info	tc_info;
	struct bnxt_tc_info	*tc_info;
};

#define BNXT_RX_STATS_OFFSET(counter)			\
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ int bnxt_dl_register(struct bnxt *bp)
	if (!pci_find_ext_capability(bp->pdev, PCI_EXT_CAP_ID_SRIOV))
		return 0;

	if (bp->hwrm_spec_code < 0x10800) {
	if (bp->hwrm_spec_code < 0x10803) {
		netdev_warn(bp->dev, "Firmware does not support SR-IOV E-Switch SWITCHDEV mode.\n");
		return -ENOTSUPP;
	}
+85 −35
Original line number Diff line number Diff line
@@ -26,8 +26,6 @@
#define FLASH_PACKAGE_TIMEOUT	((HWRM_CMD_TIMEOUT) * 200)
#define INSTALL_PACKAGE_TIMEOUT	((HWRM_CMD_TIMEOUT) * 200)

static char *bnxt_get_pkgver(struct net_device *dev, char *buf, size_t buflen);

static u32 bnxt_get_msglevel(struct net_device *dev)
{
	struct bnxt *bp = netdev_priv(dev);
@@ -46,19 +44,24 @@ static int bnxt_get_coalesce(struct net_device *dev,
			     struct ethtool_coalesce *coal)
{
	struct bnxt *bp = netdev_priv(dev);
	struct bnxt_coal *hw_coal;
	u16 mult;

	memset(coal, 0, sizeof(*coal));

	coal->rx_coalesce_usecs = bp->rx_coal_ticks;
	/* 2 completion records per rx packet */
	coal->rx_max_coalesced_frames = bp->rx_coal_bufs / 2;
	coal->rx_coalesce_usecs_irq = bp->rx_coal_ticks_irq;
	coal->rx_max_coalesced_frames_irq = bp->rx_coal_bufs_irq / 2;
	hw_coal = &bp->rx_coal;
	mult = hw_coal->bufs_per_record;
	coal->rx_coalesce_usecs = hw_coal->coal_ticks;
	coal->rx_max_coalesced_frames = hw_coal->coal_bufs / mult;
	coal->rx_coalesce_usecs_irq = hw_coal->coal_ticks_irq;
	coal->rx_max_coalesced_frames_irq = hw_coal->coal_bufs_irq / mult;

	coal->tx_coalesce_usecs = bp->tx_coal_ticks;
	coal->tx_max_coalesced_frames = bp->tx_coal_bufs;
	coal->tx_coalesce_usecs_irq = bp->tx_coal_ticks_irq;
	coal->tx_max_coalesced_frames_irq = bp->tx_coal_bufs_irq;
	hw_coal = &bp->tx_coal;
	mult = hw_coal->bufs_per_record;
	coal->tx_coalesce_usecs = hw_coal->coal_ticks;
	coal->tx_max_coalesced_frames = hw_coal->coal_bufs / mult;
	coal->tx_coalesce_usecs_irq = hw_coal->coal_ticks_irq;
	coal->tx_max_coalesced_frames_irq = hw_coal->coal_bufs_irq / mult;

	coal->stats_block_coalesce_usecs = bp->stats_coal_ticks;

@@ -70,18 +73,23 @@ static int bnxt_set_coalesce(struct net_device *dev,
{
	struct bnxt *bp = netdev_priv(dev);
	bool update_stats = false;
	struct bnxt_coal *hw_coal;
	int rc = 0;

	bp->rx_coal_ticks = coal->rx_coalesce_usecs;
	/* 2 completion records per rx packet */
	bp->rx_coal_bufs = coal->rx_max_coalesced_frames * 2;
	bp->rx_coal_ticks_irq = coal->rx_coalesce_usecs_irq;
	bp->rx_coal_bufs_irq = coal->rx_max_coalesced_frames_irq * 2;

	bp->tx_coal_ticks = coal->tx_coalesce_usecs;
	bp->tx_coal_bufs = coal->tx_max_coalesced_frames;
	bp->tx_coal_ticks_irq = coal->tx_coalesce_usecs_irq;
	bp->tx_coal_bufs_irq = coal->tx_max_coalesced_frames_irq;
	u16 mult;

	hw_coal = &bp->rx_coal;
	mult = hw_coal->bufs_per_record;
	hw_coal->coal_ticks = coal->rx_coalesce_usecs;
	hw_coal->coal_bufs = coal->rx_max_coalesced_frames * mult;
	hw_coal->coal_ticks_irq = coal->rx_coalesce_usecs_irq;
	hw_coal->coal_bufs_irq = coal->rx_max_coalesced_frames_irq * mult;

	hw_coal = &bp->rx_coal;
	mult = hw_coal->bufs_per_record;
	hw_coal->coal_ticks = coal->tx_coalesce_usecs;
	hw_coal->coal_bufs = coal->tx_max_coalesced_frames * mult;
	hw_coal->coal_ticks_irq = coal->tx_coalesce_usecs_irq;
	hw_coal->coal_bufs_irq = coal->tx_max_coalesced_frames_irq * mult;

	if (bp->stats_coal_ticks != coal->stats_block_coalesce_usecs) {
		u32 stats_ticks = coal->stats_block_coalesce_usecs;
@@ -822,20 +830,10 @@ static void bnxt_get_drvinfo(struct net_device *dev,
			     struct ethtool_drvinfo *info)
{
	struct bnxt *bp = netdev_priv(dev);
	char *pkglog;
	char *pkgver = NULL;

	pkglog = kmalloc(BNX_PKG_LOG_MAX_LENGTH, GFP_KERNEL);
	if (pkglog)
		pkgver = bnxt_get_pkgver(dev, pkglog, BNX_PKG_LOG_MAX_LENGTH);
	strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
	strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
	if (pkgver && *pkgver != 0 && isdigit(*pkgver))
		snprintf(info->fw_version, sizeof(info->fw_version) - 1,
			 "%s pkg %s", bp->fw_ver_str, pkgver);
	else
		strlcpy(info->fw_version, bp->fw_ver_str,
			sizeof(info->fw_version));
	strlcpy(info->fw_version, bp->fw_ver_str, sizeof(info->fw_version));
	strlcpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info));
	info->n_stats = bnxt_get_num_stats(bp);
	info->testinfo_len = bp->num_tests;
@@ -843,7 +841,6 @@ static void bnxt_get_drvinfo(struct net_device *dev,
	info->eedump_len = 0;
	/* TODO CHIMP FW: reg dump details */
	info->regdump_len = 0;
	kfree(pkglog);
}

static void bnxt_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
@@ -1350,7 +1347,6 @@ static int bnxt_firmware_reset(struct net_device *dev,

	bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FW_RESET, -1, -1);

	/* TODO: Support ASAP ChiMP self-reset (e.g. upon PF driver unload) */
	/* TODO: Address self-reset of APE/KONG/BONO/TANG or ungraceful reset */
	/*       (e.g. when firmware isn't already running) */
	switch (dir_type) {
@@ -1376,6 +1372,10 @@ static int bnxt_firmware_reset(struct net_device *dev,
	case BNX_DIR_TYPE_BONO_PATCH:
		req.embedded_proc_type = FW_RESET_REQ_EMBEDDED_PROC_TYPE_ROCE;
		break;
	case BNXT_FW_RESET_CHIP:
		req.embedded_proc_type = FW_RESET_REQ_EMBEDDED_PROC_TYPE_CHIP;
		req.selfrst_status = FW_RESET_REQ_SELFRST_STATUS_SELFRSTASAP;
		break;
	default:
		return -EINVAL;
	}
@@ -1773,6 +1773,9 @@ static int bnxt_get_nvram_item(struct net_device *dev, u32 index, u32 offset,
	dma_addr_t dma_handle;
	struct hwrm_nvm_read_input req = {0};

	if (!length)
		return -EINVAL;

	buf = dma_alloc_coherent(&bp->pdev->dev, length, &dma_handle,
				 GFP_KERNEL);
	if (!buf) {
@@ -2495,13 +2498,59 @@ static void bnxt_self_test(struct net_device *dev, struct ethtool_test *etest,
	}
}

static int bnxt_reset(struct net_device *dev, u32 *flags)
{
	struct bnxt *bp = netdev_priv(dev);
	int rc = 0;

	if (!BNXT_PF(bp)) {
		netdev_err(dev, "Reset is not supported from a VF\n");
		return -EOPNOTSUPP;
	}

	if (pci_vfs_assigned(bp->pdev)) {
		netdev_err(dev,
			   "Reset not allowed when VFs are assigned to VMs\n");
		return -EBUSY;
	}

	if (*flags == ETH_RESET_ALL) {
		/* This feature is not supported in older firmware versions */
		if (bp->hwrm_spec_code < 0x10803)
			return -EOPNOTSUPP;

		rc = bnxt_firmware_reset(dev, BNXT_FW_RESET_CHIP);
		if (!rc)
			netdev_info(dev, "Reset request successful. Reload driver to complete reset\n");
	} else {
		rc = -EINVAL;
	}

	return rc;
}

void bnxt_ethtool_init(struct bnxt *bp)
{
	struct hwrm_selftest_qlist_output *resp = bp->hwrm_cmd_resp_addr;
	struct hwrm_selftest_qlist_input req = {0};
	struct bnxt_test_info *test_info;
	struct net_device *dev = bp->dev;
	char *pkglog;
	int i, rc;

	pkglog = kzalloc(BNX_PKG_LOG_MAX_LENGTH, GFP_KERNEL);
	if (pkglog) {
		char *pkgver;
		int len;

		pkgver = bnxt_get_pkgver(dev, pkglog, BNX_PKG_LOG_MAX_LENGTH);
		if (pkgver && *pkgver != 0 && isdigit(*pkgver)) {
			len = strlen(bp->fw_ver_str);
			snprintf(bp->fw_ver_str + len, FW_VER_STR_LEN - len - 1,
				 "/pkg %s", pkgver);
		}
		kfree(pkglog);
	}
	if (bp->hwrm_spec_code < 0x10704 || !BNXT_SINGLE_PF(bp))
		return;

@@ -2592,4 +2641,5 @@ const struct ethtool_ops bnxt_ethtool_ops = {
	.nway_reset		= bnxt_nway_reset,
	.set_phys_id		= bnxt_set_phys_id,
	.self_test		= bnxt_self_test,
	.reset			= bnxt_reset,
};
+2 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ struct bnxt_led_cfg {
#define BNXT_LED_DFLT_ENABLES(x)			\
	cpu_to_le32(BNXT_LED_DFLT_ENA << (BNXT_LED_DFLT_ENA_SHIFT * (x)))

#define BNXT_FW_RESET_CHIP	0xffff

extern const struct ethtool_ops bnxt_ethtool_ops;

u32 _bnxt_fw_to_ethtool_adv_spds(u16, u8);
Loading