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

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

Merge branch 'bnxt_en-Misc-updates-for-net-next'



Michael Chan says:

====================
bnxt_en: Misc. updates for net-next.

The 1st 2 patches add short firmware message support for new VF devices.
The 3rd patch adds a pci shutdown callback for the RDMA driver for proper
shutdown.  The next 3 patches improve the doorbell operations by
elimiating the double doorbell workaround on newer chips, and by adding
xmit_more support.  The last patch adds a parameter to bnxt_set_dflt_rings().
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e6cbef0c 702c221c
Loading
Loading
Loading
Loading
+88 −26
Original line number Diff line number Diff line
@@ -175,6 +175,8 @@ static const struct pci_device_id bnxt_pci_tbl[] = {
	{ PCI_VDEVICE(BROADCOM, 0x16f1), .driver_data = BCM57452 },
	{ PCI_VDEVICE(BROADCOM, 0x1614), .driver_data = BCM57454 },
#ifdef CONFIG_BNXT_SRIOV
	{ PCI_VDEVICE(BROADCOM, 0x1606), .driver_data = NETXTREME_E_VF },
	{ PCI_VDEVICE(BROADCOM, 0x1609), .driver_data = NETXTREME_E_VF },
	{ PCI_VDEVICE(BROADCOM, 0x16c1), .driver_data = NETXTREME_E_VF },
	{ PCI_VDEVICE(BROADCOM, 0x16cb), .driver_data = NETXTREME_C_VF },
	{ PCI_VDEVICE(BROADCOM, 0x16d3), .driver_data = NETXTREME_E_VF },
@@ -461,14 +463,17 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev)
	prod = NEXT_TX(prod);
	txr->tx_prod = prod;

	writel(DB_KEY_TX | prod, txr->tx_doorbell);
	writel(DB_KEY_TX | prod, txr->tx_doorbell);
	if (!skb->xmit_more)
		bnxt_db_write(bp, txr->tx_doorbell, DB_KEY_TX | prod);

tx_done:

	mmiowb();

	if (unlikely(bnxt_tx_avail(bp, txr) <= MAX_SKB_FRAGS + 1)) {
		if (skb->xmit_more && !tx_buf->is_push)
			bnxt_db_write(bp, txr->tx_doorbell, DB_KEY_TX | prod);

		netif_tx_stop_queue(txq);

		/* netif_tx_stop_queue() must be done before checking
@@ -1777,8 +1782,7 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
		/* Sync BD data before updating doorbell */
		wmb();

		writel(DB_KEY_TX | prod, db);
		writel(DB_KEY_TX | prod, db);
		bnxt_db_write(bp, db, DB_KEY_TX | prod);
	}

	cpr->cp_raw_cons = raw_cons;
@@ -1794,14 +1798,10 @@ static int bnxt_poll_work(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
	if (event & BNXT_RX_EVENT) {
		struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;

		writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
		writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
		if (event & BNXT_AGG_EVENT) {
			writel(DB_KEY_RX | rxr->rx_agg_prod,
			       rxr->rx_agg_doorbell);
			writel(DB_KEY_RX | rxr->rx_agg_prod,
			       rxr->rx_agg_doorbell);
		}
		bnxt_db_write(bp, rxr->rx_doorbell, DB_KEY_RX | rxr->rx_prod);
		if (event & BNXT_AGG_EVENT)
			bnxt_db_write(bp, rxr->rx_agg_doorbell,
				      DB_KEY_RX | rxr->rx_agg_prod);
	}
	return rx_pkts;
}
@@ -1861,13 +1861,11 @@ static int bnxt_poll_nitroa0(struct napi_struct *napi, int budget)

	cpr->cp_raw_cons = raw_cons;
	BNXT_CP_DB(cpr->cp_doorbell, cpr->cp_raw_cons);
	writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
	writel(DB_KEY_RX | rxr->rx_prod, rxr->rx_doorbell);
	bnxt_db_write(bp, rxr->rx_doorbell, DB_KEY_RX | rxr->rx_prod);

	if (event & BNXT_AGG_EVENT) {
		writel(DB_KEY_RX | rxr->rx_agg_prod, rxr->rx_agg_doorbell);
		writel(DB_KEY_RX | rxr->rx_agg_prod, rxr->rx_agg_doorbell);
	}
	if (event & BNXT_AGG_EVENT)
		bnxt_db_write(bp, rxr->rx_agg_doorbell,
			      DB_KEY_RX | rxr->rx_agg_prod);

	if (!bnxt_has_work(bp, cpr) && rx_pkts < budget) {
		napi_complete_done(napi, rx_pkts);
@@ -2868,6 +2866,32 @@ static int bnxt_alloc_hwrm_resources(struct bnxt *bp)
	return 0;
}

static void bnxt_free_hwrm_short_cmd_req(struct bnxt *bp)
{
	if (bp->hwrm_short_cmd_req_addr) {
		struct pci_dev *pdev = bp->pdev;

		dma_free_coherent(&pdev->dev, BNXT_HWRM_MAX_REQ_LEN,
				  bp->hwrm_short_cmd_req_addr,
				  bp->hwrm_short_cmd_req_dma_addr);
		bp->hwrm_short_cmd_req_addr = NULL;
	}
}

static int bnxt_alloc_hwrm_short_cmd_req(struct bnxt *bp)
{
	struct pci_dev *pdev = bp->pdev;

	bp->hwrm_short_cmd_req_addr =
		dma_alloc_coherent(&pdev->dev, BNXT_HWRM_MAX_REQ_LEN,
				   &bp->hwrm_short_cmd_req_dma_addr,
				   GFP_KERNEL);
	if (!bp->hwrm_short_cmd_req_addr)
		return -ENOMEM;

	return 0;
}

static void bnxt_free_stats(struct bnxt *bp)
{
	u32 size, i;
@@ -3215,16 +3239,41 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
	__le32 *resp_len, *valid;
	u16 cp_ring_id, len = 0;
	struct hwrm_err_output *resp = bp->hwrm_cmd_resp_addr;
	u16 max_req_len = BNXT_HWRM_MAX_REQ_LEN;

	req->seq_id = cpu_to_le16(bp->hwrm_cmd_seq++);
	memset(resp, 0, PAGE_SIZE);
	cp_ring_id = le16_to_cpu(req->cmpl_ring);
	intr_process = (cp_ring_id == INVALID_HW_RING_ID) ? 0 : 1;

	if (bp->flags & BNXT_FLAG_SHORT_CMD) {
		void *short_cmd_req = bp->hwrm_short_cmd_req_addr;
		struct hwrm_short_input short_input = {0};

		memcpy(short_cmd_req, req, msg_len);
		memset(short_cmd_req + msg_len, 0, BNXT_HWRM_MAX_REQ_LEN -
						   msg_len);

		short_input.req_type = req->req_type;
		short_input.signature =
				cpu_to_le16(SHORT_REQ_SIGNATURE_SHORT_CMD);
		short_input.size = cpu_to_le16(msg_len);
		short_input.req_addr =
			cpu_to_le64(bp->hwrm_short_cmd_req_dma_addr);

		data = (u32 *)&short_input;
		msg_len = sizeof(short_input);

		/* Sync memory write before updating doorbell */
		wmb();

		max_req_len = BNXT_HWRM_SHORT_REQ_LEN;
	}

	/* Write request msg to hwrm channel */
	__iowrite32_copy(bp->bar0, data, msg_len / 4);

	for (i = msg_len; i < BNXT_HWRM_MAX_REQ_LEN; i += 4)
	for (i = msg_len; i < max_req_len; i += 4)
		writel(0, bp->bar0 + i);

	/* currently supports only one outstanding message */
@@ -4662,6 +4711,7 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
	int rc;
	struct hwrm_ver_get_input req = {0};
	struct hwrm_ver_get_output *resp = bp->hwrm_cmd_resp_addr;
	u32 dev_caps_cfg;

	bp->hwrm_max_req_len = HWRM_MAX_REQ_LEN;
	bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VER_GET, -1, -1);
@@ -4699,6 +4749,11 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
	    !resp->chip_metal)
		bp->flags |= BNXT_FLAG_CHIP_NITRO_A0;

	dev_caps_cfg = le32_to_cpu(resp->dev_caps_cfg);
	if ((dev_caps_cfg & VER_GET_RESP_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) &&
	    (dev_caps_cfg & VER_GET_RESP_DEV_CAPS_CFG_SHORT_CMD_REQUIRED))
		bp->flags |= BNXT_FLAG_SHORT_CMD;

hwrm_ver_get_exit:
	mutex_unlock(&bp->hwrm_cmd_lock);
	return rc;
@@ -7357,6 +7412,7 @@ static void bnxt_remove_one(struct pci_dev *pdev)
	bnxt_clear_int_mode(bp);
	bnxt_hwrm_func_drv_unrgtr(bp);
	bnxt_free_hwrm_resources(bp);
	bnxt_free_hwrm_short_cmd_req(bp);
	bnxt_ethtool_free(bp);
	bnxt_dcb_free(bp);
	kfree(bp->edev);
@@ -7511,10 +7567,9 @@ static int bnxt_get_dflt_rings(struct bnxt *bp, int *max_rx, int *max_tx,
	return rc;
}

static int bnxt_set_dflt_rings(struct bnxt *bp)
static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
{
	int dflt_rings, max_rx_rings, max_tx_rings, rc;
	bool sh = true;

	if (sh)
		bp->flags |= BNXT_FLAG_SHARED_RINGS;
@@ -7607,6 +7662,12 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
	if (rc)
		goto init_err_pci_clean;

	if (bp->flags & BNXT_FLAG_SHORT_CMD) {
		rc = bnxt_alloc_hwrm_short_cmd_req(bp);
		if (rc)
			goto init_err_pci_clean;
	}

	rc = bnxt_hwrm_func_reset(bp);
	if (rc)
		goto init_err_pci_clean;
@@ -7646,8 +7707,10 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
	init_waitqueue_head(&bp->sriov_cfg_wait);
#endif
	bp->gro_func = bnxt_gro_func_5730x;
	if (BNXT_CHIP_NUM_57X1X(bp->chip_num))
	if (BNXT_CHIP_P4_PLUS(bp))
		bp->gro_func = bnxt_gro_func_5731x;
	else
		bp->flags |= BNXT_FLAG_DOUBLE_DB;

	rc = bnxt_hwrm_func_drv_rgtr(bp);
	if (rc)
@@ -7685,7 +7748,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
	bnxt_set_tpa_flags(bp);
	bnxt_set_ring_params(bp);
	bnxt_set_max_func_irqs(bp, max_irqs);
	rc = bnxt_set_dflt_rings(bp);
	rc = bnxt_set_dflt_rings(bp, true);
	if (rc) {
		netdev_err(bp->dev, "Not enough rings available.\n");
		rc = -ENOMEM;
@@ -7697,9 +7760,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
			   VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4 |
			   VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6 |
			   VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6;
	if (!BNXT_CHIP_NUM_57X0X(bp->chip_num) &&
	    !BNXT_CHIP_TYPE_NITRO_A0(bp) &&
	    bp->hwrm_spec_code >= 0x10501) {
	if (BNXT_CHIP_P4_PLUS(bp) && bp->hwrm_spec_code >= 0x10501) {
		bp->flags |= BNXT_FLAG_UDP_RSS_CAP;
		bp->rss_hash_cfg |= VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4 |
				    VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6;
@@ -7771,6 +7832,7 @@ static void bnxt_shutdown(struct pci_dev *pdev)
		dev_close(dev);

	if (system_state == SYSTEM_POWER_OFF) {
		bnxt_ulp_shutdown(bp);
		bnxt_clear_int_mode(bp);
		pci_wake_from_d3(pdev, bp->wol);
		pci_set_power_state(pdev, PCI_D3hot);
+38 −4
Original line number Diff line number Diff line
@@ -500,6 +500,7 @@ struct rx_tpa_end_cmp_ext {
#define NEXT_CMP(idx)		RING_CMP(ADV_RAW_CMP(idx, 1))

#define BNXT_HWRM_MAX_REQ_LEN		(bp->hwrm_max_req_len)
#define BNXT_HWRM_SHORT_REQ_LEN		sizeof(struct hwrm_short_input)
#define DFLT_HWRM_CMD_TIMEOUT		500
#define HWRM_CMD_TIMEOUT		(bp->hwrm_cmd_timeout)
#define HWRM_RESET_TIMEOUT		((HWRM_CMD_TIMEOUT) * 4)
@@ -937,31 +938,45 @@ struct bnxt {
#define CHIP_NUM_57402		0x16d0
#define CHIP_NUM_57404		0x16d1
#define CHIP_NUM_57406		0x16d2
#define CHIP_NUM_57407		0x16d5

#define CHIP_NUM_57311		0x16ce
#define CHIP_NUM_57312		0x16cf
#define CHIP_NUM_57314		0x16df
#define CHIP_NUM_57317		0x16e0
#define CHIP_NUM_57412		0x16d6
#define CHIP_NUM_57414		0x16d7
#define CHIP_NUM_57416		0x16d8
#define CHIP_NUM_57417		0x16d9
#define CHIP_NUM_57412L		0x16da
#define CHIP_NUM_57414L		0x16db

#define CHIP_NUM_5745X		0xd730

#define BNXT_CHIP_NUM_5730X(chip_num)		\
	((chip_num) >= CHIP_NUM_57301 &&	\
	 (chip_num) <= CHIP_NUM_57304)

#define BNXT_CHIP_NUM_5740X(chip_num)		\
	((chip_num) >= CHIP_NUM_57402 &&	\
	 (chip_num) <= CHIP_NUM_57406)
	(((chip_num) >= CHIP_NUM_57402 &&	\
	  (chip_num) <= CHIP_NUM_57406) ||	\
	 (chip_num) == CHIP_NUM_57407)

#define BNXT_CHIP_NUM_5731X(chip_num)		\
	((chip_num) == CHIP_NUM_57311 ||	\
	 (chip_num) == CHIP_NUM_57312 ||	\
	 (chip_num) == CHIP_NUM_57314)
	 (chip_num) == CHIP_NUM_57314 ||	\
	 (chip_num) == CHIP_NUM_57317)

#define BNXT_CHIP_NUM_5741X(chip_num)		\
	((chip_num) >= CHIP_NUM_57412 &&	\
	 (chip_num) <= CHIP_NUM_57417)
	 (chip_num) <= CHIP_NUM_57414L)

#define BNXT_CHIP_NUM_58700(chip_num)		\
	 ((chip_num) == CHIP_NUM_58700)

#define BNXT_CHIP_NUM_5745X(chip_num)		\
	 ((chip_num) == CHIP_NUM_5745X)

#define BNXT_CHIP_NUM_57X0X(chip_num)		\
	(BNXT_CHIP_NUM_5730X(chip_num) || BNXT_CHIP_NUM_5740X(chip_num))
@@ -1006,6 +1021,8 @@ struct bnxt {
	#define BNXT_FLAG_RX_PAGE_MODE	0x40000
	#define BNXT_FLAG_FW_LLDP_AGENT	0x80000
	#define BNXT_FLAG_MULTI_HOST	0x100000
	#define BNXT_FLAG_SHORT_CMD	0x200000
	#define BNXT_FLAG_DOUBLE_DB	0x400000
	#define BNXT_FLAG_CHIP_NITRO_A0	0x1000000

	#define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA |		\
@@ -1020,6 +1037,13 @@ struct bnxt {
#define BNXT_CHIP_TYPE_NITRO_A0(bp) ((bp)->flags & BNXT_FLAG_CHIP_NITRO_A0)
#define BNXT_RX_PAGE_MODE(bp)	((bp)->flags & BNXT_FLAG_RX_PAGE_MODE)

/* Chip class phase 4 and later */
#define BNXT_CHIP_P4_PLUS(bp)			\
	(BNXT_CHIP_NUM_57X1X((bp)->chip_num) ||	\
	 BNXT_CHIP_NUM_5745X((bp)->chip_num) ||	\
	 (BNXT_CHIP_NUM_58700((bp)->chip_num) &&	\
	  !BNXT_CHIP_TYPE_NITRO_A0(bp)))

	struct bnxt_en_dev	*edev;
	struct bnxt_en_dev *	(*ulp_probe)(struct net_device *);

@@ -1106,6 +1130,8 @@ struct bnxt {
	u32			hwrm_spec_code;
	u16			hwrm_cmd_seq;
	u32			hwrm_intr_seq_id;
	void			*hwrm_short_cmd_req_addr;
	dma_addr_t		hwrm_short_cmd_req_dma_addr;
	void			*hwrm_cmd_resp_addr;
	dma_addr_t		hwrm_cmd_resp_dma_addr;
	void			*hwrm_dbg_resp_addr;
@@ -1229,6 +1255,14 @@ static inline u32 bnxt_tx_avail(struct bnxt *bp, struct bnxt_tx_ring_info *txr)
		((txr->tx_prod - txr->tx_cons) & bp->tx_ring_mask);
}

/* For TX and RX ring doorbells */
static inline void bnxt_db_write(struct bnxt *bp, void __iomem *db, u32 val)
{
	writel(val, db);
	if (bp->flags & BNXT_FLAG_DOUBLE_DB)
		writel(val, db);
}

extern const u16 bnxt_lhint_arr[];

int bnxt_alloc_rx_data(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
+1 −2
Original line number Diff line number Diff line
@@ -2376,8 +2376,7 @@ static int bnxt_run_loopback(struct bnxt *bp)
	/* Sync BD data before updating doorbell */
	wmb();

	writel(DB_KEY_TX | txr->tx_prod, txr->tx_doorbell);
	writel(DB_KEY_TX | txr->tx_prod, txr->tx_doorbell);
	bnxt_db_write(bp, txr->tx_doorbell, DB_KEY_TX | txr->tx_prod);
	rc = bnxt_poll_loopback(bp, pkt_size);

	dma_unmap_single(&bp->pdev->dev, map, pkt_size, PCI_DMA_TODEVICE);
+19 −0
Original line number Diff line number Diff line
@@ -266,6 +266,25 @@ void bnxt_ulp_sriov_cfg(struct bnxt *bp, int num_vfs)
	}
}

void bnxt_ulp_shutdown(struct bnxt *bp)
{
	struct bnxt_en_dev *edev = bp->edev;
	struct bnxt_ulp_ops *ops;
	int i;

	if (!edev)
		return;

	for (i = 0; i < BNXT_MAX_ULP; i++) {
		struct bnxt_ulp *ulp = &edev->ulp_tbl[i];

		ops = rtnl_dereference(ulp->ulp_ops);
		if (!ops || !ops->ulp_shutdown)
			continue;
		ops->ulp_shutdown(ulp->handle);
	}
}

void bnxt_ulp_async_events(struct bnxt *bp, struct hwrm_async_event_cmpl *cmpl)
{
	u16 event_id = le16_to_cpu(cmpl->event_id);
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ struct bnxt_ulp_ops {
	void (*ulp_stop)(void *);
	void (*ulp_start)(void *);
	void (*ulp_sriov_config)(void *, int);
	void (*ulp_shutdown)(void *);
};

struct bnxt_msix_entry {
@@ -87,6 +88,7 @@ void bnxt_subtract_ulp_resources(struct bnxt *bp, int ulp_id);
void bnxt_ulp_stop(struct bnxt *bp);
void bnxt_ulp_start(struct bnxt *bp);
void bnxt_ulp_sriov_cfg(struct bnxt *bp, int num_vfs);
void bnxt_ulp_shutdown(struct bnxt *bp);
void bnxt_ulp_async_events(struct bnxt *bp, struct hwrm_async_event_cmpl *cmpl);
struct bnxt_en_dev *bnxt_ulp_probe(struct net_device *dev);

Loading