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

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

Merge branch 'qlcnic'



Himanshu Madhani says:

====================
qlcnic: Multiple Tx queue support and code refactoring

This Patch series contains following changes

o Refactored code to calculate, validate and assign Tx/SDS rings for  various modes of driver.
o Enhanced ethtool statistics for multi Tx queue on all supported adapters.
o Enable multiple Tx queue for 83xx and 84xx Series adapters.
o Register netdev for failed device state.

changes from v1 -> v2
o Dropped patch to replace inappropriate usage of kzalloc() with vzalloc().

Please apply to net-next.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 16514839 db62d7d9
Loading
Loading
Loading
Loading
+53 −31
Original line number Original line Diff line number Diff line
@@ -38,8 +38,8 @@


#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MAJOR 5
#define _QLCNIC_LINUX_MINOR 3
#define _QLCNIC_LINUX_MINOR 3
#define _QLCNIC_LINUX_SUBVERSION 51
#define _QLCNIC_LINUX_SUBVERSION 52
#define QLCNIC_LINUX_VERSIONID  "5.3.51"
#define QLCNIC_LINUX_VERSIONID  "5.3.52"
#define QLCNIC_DRV_IDC_VER  0x01
#define QLCNIC_DRV_IDC_VER  0x01
#define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
#define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -98,8 +98,22 @@
#define TX_STOP_THRESH		((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \
#define TX_STOP_THRESH		((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \
							+ MGMT_CMD_DESC_RESV)
							+ MGMT_CMD_DESC_RESV)
#define QLCNIC_MAX_TX_TIMEOUTS	2
#define QLCNIC_MAX_TX_TIMEOUTS	2
#define QLCNIC_MAX_TX_RINGS	8

#define QLCNIC_MAX_SDS_RINGS	8
/* Driver will use 1 Tx ring in INT-x/MSI/SRIOV mode. */
#define QLCNIC_SINGLE_RING		1
#define QLCNIC_DEF_SDS_RINGS		4
#define QLCNIC_DEF_TX_RINGS		4
#define QLCNIC_MAX_VNIC_TX_RINGS	4
#define QLCNIC_MAX_VNIC_SDS_RINGS	4

enum qlcnic_queue_type {
	QLCNIC_TX_QUEUE = 1,
	QLCNIC_RX_QUEUE,
};

/* Operational mode for driver */
#define QLCNIC_VNIC_MODE	0xFF
#define QLCNIC_DEFAULT_MODE	0x0


/*
/*
 * Following are the states of the Phantom. Phantom will set them and
 * Following are the states of the Phantom. Phantom will set them and
@@ -533,6 +547,14 @@ struct qlcnic_host_sds_ring {
	char name[IFNAMSIZ + 12];
	char name[IFNAMSIZ + 12];
} ____cacheline_internodealigned_in_smp;
} ____cacheline_internodealigned_in_smp;


struct qlcnic_tx_queue_stats {
	u64 xmit_on;
	u64 xmit_off;
	u64 xmit_called;
	u64 xmit_finished;
	u64 tx_bytes;
};

struct qlcnic_host_tx_ring {
struct qlcnic_host_tx_ring {
	int irq;
	int irq;
	void __iomem *crb_intr_mask;
	void __iomem *crb_intr_mask;
@@ -544,10 +566,7 @@ struct qlcnic_host_tx_ring {
	u32 sw_consumer;
	u32 sw_consumer;
	u32 num_desc;
	u32 num_desc;


	u64 xmit_on;
	struct qlcnic_tx_queue_stats tx_stats;
	u64 xmit_off;
	u64 xmit_called;
	u64 xmit_finished;


	void __iomem *crb_cmd_producer;
	void __iomem *crb_cmd_producer;
	struct cmd_desc_type0 *desc_head;
	struct cmd_desc_type0 *desc_head;
@@ -940,8 +959,6 @@ struct qlcnic_ipaddr {
#define QLCNIC_BEACON_EANBLE		0xC
#define QLCNIC_BEACON_EANBLE		0xC
#define QLCNIC_BEACON_DISABLE		0xD
#define QLCNIC_BEACON_DISABLE		0xD


#define QLCNIC_DEF_NUM_STS_DESC_RINGS	4
#define QLCNIC_DEF_NUM_TX_RINGS		4
#define QLCNIC_MSIX_TBL_SPACE		8192
#define QLCNIC_MSIX_TBL_SPACE		8192
#define QLCNIC_PCI_REG_MSIX_TBL 	0x44
#define QLCNIC_PCI_REG_MSIX_TBL 	0x44
#define QLCNIC_MSIX_TBL_PGSIZE		4096
#define QLCNIC_MSIX_TBL_PGSIZE		4096
@@ -961,6 +978,7 @@ struct qlcnic_ipaddr {
#define __QLCNIC_SRIOV_CAPABLE		11
#define __QLCNIC_SRIOV_CAPABLE		11
#define __QLCNIC_MBX_POLL_ENABLE	12
#define __QLCNIC_MBX_POLL_ENABLE	12
#define __QLCNIC_DIAG_MODE		13
#define __QLCNIC_DIAG_MODE		13
#define __QLCNIC_MAINTENANCE_MODE	16


#define QLCNIC_INTERRUPT_TEST		1
#define QLCNIC_INTERRUPT_TEST		1
#define QLCNIC_LOOPBACK_TEST		2
#define QLCNIC_LOOPBACK_TEST		2
@@ -1011,7 +1029,6 @@ struct qlcnic_adapter {
	unsigned long state;
	unsigned long state;
	u32 flags;
	u32 flags;


	int max_drv_tx_rings;
	u16 num_txd;
	u16 num_txd;
	u16 num_rxd;
	u16 num_rxd;
	u16 num_jumbo_rxd;
	u16 num_jumbo_rxd;
@@ -1019,7 +1036,13 @@ struct qlcnic_adapter {
	u16 max_jumbo_rxd;
	u16 max_jumbo_rxd;


	u8 max_rds_rings;
	u8 max_rds_rings;
	u8 max_sds_rings;

	u8 max_sds_rings; /* max sds rings supported by adapter */
	u8 max_tx_rings;  /* max tx rings supported by adapter */

	u8 drv_tx_rings;  /* max tx rings supported by driver */
	u8 drv_sds_rings; /* max sds rings supported by driver */

	u8 rx_csum;
	u8 rx_csum;
	u8 portnum;
	u8 portnum;


@@ -1542,12 +1565,13 @@ int qlcnic_loopback_test(struct net_device *, u8);


/* Functions from qlcnic_main.c */
/* Functions from qlcnic_main.c */
int qlcnic_reset_context(struct qlcnic_adapter *);
int qlcnic_reset_context(struct qlcnic_adapter *);
void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings);
void qlcnic_diag_free_res(struct net_device *netdev, int);
int qlcnic_diag_alloc_res(struct net_device *netdev, int test);
int qlcnic_diag_alloc_res(struct net_device *netdev, int);
netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
netdev_tx_t qlcnic_xmit_frame(struct sk_buff *, struct net_device *);
int qlcnic_set_max_rss(struct qlcnic_adapter *, u8, int);
void qlcnic_set_tx_ring_count(struct qlcnic_adapter *, u8);
int qlcnic_validate_max_rss(struct qlcnic_adapter *, __u32);
void qlcnic_set_sds_ring_count(struct qlcnic_adapter *, u8);
int qlcnic_validate_max_tx_rings(struct qlcnic_adapter *, u32 txq);
int qlcnic_setup_rings(struct qlcnic_adapter *, u8, u8);
int qlcnic_validate_rings(struct qlcnic_adapter *, __u32, int);
void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter);
void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter);
void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *);
void qlcnic_82xx_set_mac_filter_count(struct qlcnic_adapter *);
int qlcnic_enable_msix(struct qlcnic_adapter *, u32);
int qlcnic_enable_msix(struct qlcnic_adapter *, u32);
@@ -1640,19 +1664,18 @@ static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring)
static inline int qlcnic_set_real_num_queues(struct qlcnic_adapter *adapter,
static inline int qlcnic_set_real_num_queues(struct qlcnic_adapter *adapter,
					     struct net_device *netdev)
					     struct net_device *netdev)
{
{
	int err, tx_q;
	int err;

	tx_q = adapter->max_drv_tx_rings;


	netdev->num_tx_queues = tx_q;
	netdev->num_tx_queues = adapter->drv_tx_rings;
	netdev->real_num_tx_queues = tx_q;
	netdev->real_num_tx_queues = adapter->drv_tx_rings;


	err = netif_set_real_num_tx_queues(netdev, tx_q);
	err = netif_set_real_num_tx_queues(netdev, adapter->drv_tx_rings);
	if (err)
	if (err)
		dev_err(&adapter->pdev->dev, "failed to set %d Tx queues\n",
		dev_err(&adapter->pdev->dev, "failed to set %d Tx queues\n",
			tx_q);
			adapter->drv_tx_rings);
	else
	else
		dev_info(&adapter->pdev->dev, "set %d Tx queues\n", tx_q);
		dev_info(&adapter->pdev->dev, "Set %d Tx queues\n",
			 adapter->drv_tx_rings);


	return err;
	return err;
}
}
@@ -1694,7 +1717,7 @@ struct qlcnic_hardware_ops {
	int (*write_reg) (struct qlcnic_adapter *, ulong, u32);
	int (*write_reg) (struct qlcnic_adapter *, ulong, u32);
	void (*get_ocm_win) (struct qlcnic_hardware_context *);
	void (*get_ocm_win) (struct qlcnic_hardware_context *);
	int (*get_mac_address) (struct qlcnic_adapter *, u8 *, u8);
	int (*get_mac_address) (struct qlcnic_adapter *, u8 *, u8);
	int (*setup_intr) (struct qlcnic_adapter *, u8, int);
	int (*setup_intr) (struct qlcnic_adapter *);
	int (*alloc_mbx_args)(struct qlcnic_cmd_args *,
	int (*alloc_mbx_args)(struct qlcnic_cmd_args *,
			      struct qlcnic_adapter *, u32);
			      struct qlcnic_adapter *, u32);
	int (*mbx_cmd) (struct qlcnic_adapter *, struct qlcnic_cmd_args *);
	int (*mbx_cmd) (struct qlcnic_adapter *, struct qlcnic_cmd_args *);
@@ -1765,10 +1788,9 @@ static inline int qlcnic_get_mac_address(struct qlcnic_adapter *adapter,
	return adapter->ahw->hw_ops->get_mac_address(adapter, mac, function);
	return adapter->ahw->hw_ops->get_mac_address(adapter, mac, function);
}
}


static inline int qlcnic_setup_intr(struct qlcnic_adapter *adapter,
static inline int qlcnic_setup_intr(struct qlcnic_adapter *adapter)
				    u8 num_intr, int txq)
{
{
	return adapter->ahw->hw_ops->setup_intr(adapter, num_intr, txq);
	return adapter->ahw->hw_ops->setup_intr(adapter);
}
}


static inline int qlcnic_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
static inline int qlcnic_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
@@ -2004,7 +2026,7 @@ static inline bool qlcnic_check_multi_tx(struct qlcnic_adapter *adapter)
static inline void qlcnic_disable_multi_tx(struct qlcnic_adapter *adapter)
static inline void qlcnic_disable_multi_tx(struct qlcnic_adapter *adapter)
{
{
	test_and_clear_bit(__QLCNIC_MULTI_TX_UNIQUE, &adapter->state);
	test_and_clear_bit(__QLCNIC_MULTI_TX_UNIQUE, &adapter->state);
	adapter->max_drv_tx_rings = 1;
	adapter->drv_tx_rings = QLCNIC_SINGLE_RING;
}
}


/* When operating in a muti tx mode, driver needs to write 0x1
/* When operating in a muti tx mode, driver needs to write 0x1
+62 −43
Original line number Original line Diff line number Diff line
@@ -13,7 +13,6 @@
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/aer.h>
#include <linux/aer.h>


#define QLCNIC_MAX_TX_QUEUES		1
#define RSS_HASHTYPE_IP_TCP		0x3
#define RSS_HASHTYPE_IP_TCP		0x3
#define QLC_83XX_FW_MBX_CMD		0
#define QLC_83XX_FW_MBX_CMD		0


@@ -268,20 +267,18 @@ int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
	}
	}
}
}


int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr, int txq)
int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter)
{
{
	int err, i, num_msix;
	int err, i, num_msix;
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct qlcnic_hardware_context *ahw = adapter->ahw;


	if (!num_intr)
	num_msix = adapter->drv_sds_rings;
		num_intr = QLCNIC_DEF_NUM_STS_DESC_RINGS;

	num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(),
					      num_intr));
	/* account for AEN interrupt MSI-X based interrupts */
	/* account for AEN interrupt MSI-X based interrupts */
	num_msix += 1;
	num_msix += 1;


	if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
	if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
		num_msix += adapter->max_drv_tx_rings;
		num_msix += adapter->drv_tx_rings;


	err = qlcnic_enable_msix(adapter, num_msix);
	err = qlcnic_enable_msix(adapter, num_msix);
	if (err == -ENOMEM)
	if (err == -ENOMEM)
@@ -325,6 +322,7 @@ inline void qlcnic_83xx_clear_legacy_intr_mask(struct qlcnic_adapter *adapter)


inline void qlcnic_83xx_set_legacy_intr_mask(struct qlcnic_adapter *adapter)
inline void qlcnic_83xx_set_legacy_intr_mask(struct qlcnic_adapter *adapter)
{
{
	if (adapter->tgt_mask_reg)
		writel(1, adapter->tgt_mask_reg);
		writel(1, adapter->tgt_mask_reg);
}
}


@@ -498,9 +496,12 @@ void qlcnic_83xx_free_mbx_intr(struct qlcnic_adapter *adapter)
		num_msix = 0;
		num_msix = 0;


	msleep(20);
	msleep(20);

	if (adapter->msix_entries) {
		synchronize_irq(adapter->msix_entries[num_msix].vector);
		synchronize_irq(adapter->msix_entries[num_msix].vector);
		free_irq(adapter->msix_entries[num_msix].vector, adapter);
		free_irq(adapter->msix_entries[num_msix].vector, adapter);
	}
	}
}


int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
int qlcnic_83xx_setup_mbx_intr(struct qlcnic_adapter *adapter)
{
{
@@ -760,6 +761,9 @@ int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *adapter,
	int cmd_type, err, opcode;
	int cmd_type, err, opcode;
	unsigned long timeout;
	unsigned long timeout;


	if (!mbx)
		return -EIO;

	opcode = LSW(cmd->req.arg[0]);
	opcode = LSW(cmd->req.arg[0]);
	cmd_type = cmd->type;
	cmd_type = cmd->type;
	err = mbx->ops->enqueue_cmd(adapter, cmd, &timeout);
	err = mbx->ops->enqueue_cmd(adapter, cmd, &timeout);
@@ -979,14 +983,14 @@ static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)


	sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
	sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
	context_id = recv_ctx->context_id;
	context_id = recv_ctx->context_id;
	num_sds = (adapter->max_sds_rings - QLCNIC_MAX_RING_SETS);
	num_sds = adapter->drv_sds_rings - QLCNIC_MAX_SDS_RINGS;
	ahw->hw_ops->alloc_mbx_args(&cmd, adapter,
	ahw->hw_ops->alloc_mbx_args(&cmd, adapter,
				    QLCNIC_CMD_ADD_RCV_RINGS);
				    QLCNIC_CMD_ADD_RCV_RINGS);
	cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16);
	cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16);


	/* set up status rings, mbx 2-81 */
	/* set up status rings, mbx 2-81 */
	index = 2;
	index = 2;
	for (i = 8; i < adapter->max_sds_rings; i++) {
	for (i = 8; i < adapter->drv_sds_rings; i++) {
		memset(&sds_mbx, 0, sds_mbx_size);
		memset(&sds_mbx, 0, sds_mbx_size);
		sds = &recv_ctx->sds_rings[i];
		sds = &recv_ctx->sds_rings[i];
		sds->consumer = 0;
		sds->consumer = 0;
@@ -1021,7 +1025,7 @@ static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
	mbx_out = (struct qlcnic_add_rings_mbx_out *)&cmd.rsp.arg[1];
	mbx_out = (struct qlcnic_add_rings_mbx_out *)&cmd.rsp.arg[1];
	index = 0;
	index = 0;
	/* status descriptor ring */
	/* status descriptor ring */
	for (i = 8; i < adapter->max_sds_rings; i++) {
	for (i = 8; i < adapter->drv_sds_rings; i++) {
		sds = &recv_ctx->sds_rings[i];
		sds = &recv_ctx->sds_rings[i];
		sds->crb_sts_consumer = ahw->pci_base0 +
		sds->crb_sts_consumer = ahw->pci_base0 +
					mbx_out->host_csmr[index];
					mbx_out->host_csmr[index];
@@ -1079,10 +1083,10 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	num_rds = adapter->max_rds_rings;
	num_rds = adapter->max_rds_rings;


	if (adapter->max_sds_rings <= QLCNIC_MAX_RING_SETS)
	if (adapter->drv_sds_rings <= QLCNIC_MAX_SDS_RINGS)
		num_sds = adapter->max_sds_rings;
		num_sds = adapter->drv_sds_rings;
	else
	else
		num_sds = QLCNIC_MAX_RING_SETS;
		num_sds = QLCNIC_MAX_SDS_RINGS;


	sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
	sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
	rds_mbx_size = sizeof(struct qlcnic_rds_mbx);
	rds_mbx_size = sizeof(struct qlcnic_rds_mbx);
@@ -1183,7 +1187,7 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
		sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
		sds->crb_intr_mask = ahw->pci_base0 + intr_mask;
	}
	}


	if (adapter->max_sds_rings > QLCNIC_MAX_RING_SETS)
	if (adapter->drv_sds_rings > QLCNIC_MAX_SDS_RINGS)
		err = qlcnic_83xx_add_rings(adapter);
		err = qlcnic_83xx_add_rings(adapter);
out:
out:
	qlcnic_free_mbx_args(&cmd);
	qlcnic_free_mbx_args(&cmd);
@@ -1239,9 +1243,9 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
	mbx.size = tx->num_desc;
	mbx.size = tx->num_desc;
	if (adapter->flags & QLCNIC_MSIX_ENABLED) {
	if (adapter->flags & QLCNIC_MSIX_ENABLED) {
		if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
		if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
			msix_vector = adapter->max_sds_rings + ring;
			msix_vector = adapter->drv_sds_rings + ring;
		else
		else
			msix_vector = adapter->max_sds_rings - 1;
			msix_vector = adapter->drv_sds_rings - 1;
		msix_id = ahw->intr_tbl[msix_vector].id;
		msix_id = ahw->intr_tbl[msix_vector].id;
	} else {
	} else {
		msix_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
		msix_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
@@ -1264,7 +1268,8 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
		qlcnic_pf_set_interface_id_create_tx_ctx(adapter, &temp);
		qlcnic_pf_set_interface_id_create_tx_ctx(adapter, &temp);


	cmd.req.arg[1] = QLCNIC_CAP0_LEGACY_CONTEXT;
	cmd.req.arg[1] = QLCNIC_CAP0_LEGACY_CONTEXT;
	cmd.req.arg[5] = QLCNIC_MAX_TX_QUEUES | temp;
	cmd.req.arg[5] = QLCNIC_SINGLE_RING | temp;

	buf = &cmd.req.arg[6];
	buf = &cmd.req.arg[6];
	memcpy(buf, &mbx, sizeof(struct qlcnic_tx_mbx));
	memcpy(buf, &mbx, sizeof(struct qlcnic_tx_mbx));
	/* send the mailbox command*/
	/* send the mailbox command*/
@@ -1279,7 +1284,7 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
	tx->ctx_id = mbx_out->ctx_id;
	tx->ctx_id = mbx_out->ctx_id;
	if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
	if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
	    !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
	    !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
		intr_mask = ahw->intr_tbl[adapter->max_sds_rings + ring].src;
		intr_mask = ahw->intr_tbl[adapter->drv_sds_rings + ring].src;
		tx->crb_intr_mask = ahw->pci_base0 + intr_mask;
		tx->crb_intr_mask = ahw->pci_base0 + intr_mask;
	}
	}
	dev_info(&adapter->pdev->dev, "Tx Context[0x%x] Created, state:0x%x\n",
	dev_info(&adapter->pdev->dev, "Tx Context[0x%x] Created, state:0x%x\n",
@@ -1290,7 +1295,7 @@ out:
}
}


static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
				      int num_sds_ring)
				      u8 num_sds_ring)
{
{
	struct qlcnic_adapter *adapter = netdev_priv(netdev);
	struct qlcnic_adapter *adapter = netdev_priv(netdev);
	struct qlcnic_host_sds_ring *sds_ring;
	struct qlcnic_host_sds_ring *sds_ring;
@@ -1306,7 +1311,7 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,


	qlcnic_detach(adapter);
	qlcnic_detach(adapter);


	adapter->max_sds_rings = 1;
	adapter->drv_sds_rings = QLCNIC_SINGLE_RING;
	adapter->ahw->diag_test = test;
	adapter->ahw->diag_test = test;
	adapter->ahw->linkup = 0;
	adapter->ahw->linkup = 0;


@@ -1320,7 +1325,7 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
	if (ret) {
	if (ret) {
		qlcnic_detach(adapter);
		qlcnic_detach(adapter);
		if (adapter_state == QLCNIC_ADAPTER_UP_MAGIC) {
		if (adapter_state == QLCNIC_ADAPTER_UP_MAGIC) {
			adapter->max_sds_rings = num_sds_ring;
			adapter->drv_sds_rings = num_sds_ring;
			qlcnic_attach(adapter);
			qlcnic_attach(adapter);
		}
		}
		netif_device_attach(netdev);
		netif_device_attach(netdev);
@@ -1333,7 +1338,7 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
	}
	}


	if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
	if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
		for (ring = 0; ring < adapter->max_sds_rings; ring++) {
		for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
			sds_ring = &adapter->recv_ctx->sds_rings[ring];
			sds_ring = &adapter->recv_ctx->sds_rings[ring];
			qlcnic_83xx_enable_intr(adapter, sds_ring);
			qlcnic_83xx_enable_intr(adapter, sds_ring);
		}
		}
@@ -1354,7 +1359,7 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
}
}


static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
					int max_sds_rings)
				      u8 drv_sds_rings)
{
{
	struct qlcnic_adapter *adapter = netdev_priv(netdev);
	struct qlcnic_adapter *adapter = netdev_priv(netdev);
	struct qlcnic_host_sds_ring *sds_ring;
	struct qlcnic_host_sds_ring *sds_ring;
@@ -1362,7 +1367,7 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,


	clear_bit(__QLCNIC_DEV_UP, &adapter->state);
	clear_bit(__QLCNIC_DEV_UP, &adapter->state);
	if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
	if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
		for (ring = 0; ring < adapter->max_sds_rings; ring++) {
		for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
			sds_ring = &adapter->recv_ctx->sds_rings[ring];
			sds_ring = &adapter->recv_ctx->sds_rings[ring];
			qlcnic_83xx_disable_intr(adapter, sds_ring);
			qlcnic_83xx_disable_intr(adapter, sds_ring);
			if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
			if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
@@ -1386,7 +1391,7 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
		}
		}
	}
	}
	adapter->ahw->diag_test = 0;
	adapter->ahw->diag_test = 0;
	adapter->max_sds_rings = max_sds_rings;
	adapter->drv_sds_rings = drv_sds_rings;


	if (qlcnic_attach(adapter))
	if (qlcnic_attach(adapter))
		goto out;
		goto out;
@@ -1648,7 +1653,9 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
{
{
	struct qlcnic_adapter *adapter = netdev_priv(netdev);
	struct qlcnic_adapter *adapter = netdev_priv(netdev);
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	int ret = 0, loop = 0, max_sds_rings = adapter->max_sds_rings;
	u8 drv_sds_rings = adapter->drv_sds_rings;
	u8 drv_tx_rings = adapter->drv_tx_rings;
	int ret = 0, loop = 0;


	if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
	if (ahw->op_mode == QLCNIC_NON_PRIV_FUNC) {
		netdev_warn(netdev,
		netdev_warn(netdev,
@@ -1670,7 +1677,7 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
		    mode == QLCNIC_ILB_MODE ? "internal" : "external");
		    mode == QLCNIC_ILB_MODE ? "internal" : "external");


	ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST,
	ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST,
					 max_sds_rings);
					 drv_sds_rings);
	if (ret)
	if (ret)
		goto fail_diag_alloc;
		goto fail_diag_alloc;


@@ -1708,10 +1715,11 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
	qlcnic_83xx_clear_lb_mode(adapter, mode);
	qlcnic_83xx_clear_lb_mode(adapter, mode);


free_diag_res:
free_diag_res:
	qlcnic_83xx_diag_free_res(netdev, max_sds_rings);
	qlcnic_83xx_diag_free_res(netdev, drv_sds_rings);


fail_diag_alloc:
fail_diag_alloc:
	adapter->max_sds_rings = max_sds_rings;
	adapter->drv_sds_rings = drv_sds_rings;
	adapter->drv_tx_rings = drv_tx_rings;
	qlcnic_release_diag_lock(adapter);
	qlcnic_release_diag_lock(adapter);
	return ret;
	return ret;
}
}
@@ -3049,11 +3057,14 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
	int status = 0;
	int status = 0;
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct qlcnic_hardware_context *ahw = adapter->ahw;


	if (!test_bit(__QLCNIC_MAINTENANCE_MODE, &adapter->state)) {
		/* Get port configuration info */
		/* Get port configuration info */
		status = qlcnic_83xx_get_port_info(adapter);
		status = qlcnic_83xx_get_port_info(adapter);
		/* Get Link Status related info */
		/* Get Link Status related info */
		config = qlcnic_83xx_test_link(adapter);
		config = qlcnic_83xx_test_link(adapter);
		ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
		ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
	}

	/* hard code until there is a way to get it from flash */
	/* hard code until there is a way to get it from flash */
	ahw->board_type = QLCNIC_BRDTYPE_83XX_10G;
	ahw->board_type = QLCNIC_BRDTYPE_83XX_10G;


@@ -3293,10 +3304,11 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev)
	struct qlcnic_adapter *adapter = netdev_priv(netdev);
	struct qlcnic_adapter *adapter = netdev_priv(netdev);
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct qlcnic_cmd_args cmd;
	struct qlcnic_cmd_args cmd;
	u8 val, drv_sds_rings = adapter->drv_sds_rings;
	u8 drv_tx_rings = adapter->drv_tx_rings;
	u32 data;
	u32 data;
	u16 intrpt_id, id;
	u16 intrpt_id, id;
	u8 val;
	int ret;
	int ret, max_sds_rings = adapter->max_sds_rings;


	if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
	if (test_bit(__QLCNIC_RESETTING, &adapter->state)) {
		netdev_info(netdev, "Device is resetting\n");
		netdev_info(netdev, "Device is resetting\n");
@@ -3309,7 +3321,7 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev)
	}
	}


	ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST,
	ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST,
					 max_sds_rings);
					 drv_sds_rings);
	if (ret)
	if (ret)
		goto fail_diag_irq;
		goto fail_diag_irq;


@@ -3346,10 +3358,11 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev)


done:
done:
	qlcnic_free_mbx_args(&cmd);
	qlcnic_free_mbx_args(&cmd);
	qlcnic_83xx_diag_free_res(netdev, max_sds_rings);
	qlcnic_83xx_diag_free_res(netdev, drv_sds_rings);


fail_diag_irq:
fail_diag_irq:
	adapter->max_sds_rings = max_sds_rings;
	adapter->drv_sds_rings = drv_sds_rings;
	adapter->drv_tx_rings = drv_tx_rings;
	qlcnic_release_diag_lock(adapter);
	qlcnic_release_diag_lock(adapter);
	return ret;
	return ret;
}
}
@@ -3503,7 +3516,7 @@ int qlcnic_83xx_resume(struct qlcnic_adapter *adapter)
	if (err)
	if (err)
		return err;
		return err;


	if (ahw->nic_mode == QLC_83XX_VIRTUAL_NIC_MODE) {
	if (ahw->nic_mode == QLCNIC_VNIC_MODE) {
		if (ahw->op_mode == QLCNIC_MGMT_FUNC) {
		if (ahw->op_mode == QLCNIC_MGMT_FUNC) {
			qlcnic_83xx_set_vnic_opmode(adapter);
			qlcnic_83xx_set_vnic_opmode(adapter);
		} else {
		} else {
@@ -3530,6 +3543,9 @@ void qlcnic_83xx_reinit_mbx_work(struct qlcnic_mailbox *mbx)


void qlcnic_83xx_free_mailbox(struct qlcnic_mailbox *mbx)
void qlcnic_83xx_free_mailbox(struct qlcnic_mailbox *mbx)
{
{
	if (!mbx)
		return;

	destroy_workqueue(mbx->work_q);
	destroy_workqueue(mbx->work_q);
	kfree(mbx);
	kfree(mbx);
}
}
@@ -3650,6 +3666,9 @@ void qlcnic_83xx_detach_mailbox_work(struct qlcnic_adapter *adapter)
{
{
	struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;
	struct qlcnic_mailbox *mbx = adapter->ahw->mailbox;


	if (!mbx)
		return;

	clear_bit(QLC_83XX_MBX_READY, &mbx->status);
	clear_bit(QLC_83XX_MBX_READY, &mbx->status);
	complete(&mbx->completion);
	complete(&mbx->completion);
	cancel_work_sync(&mbx->work);
	cancel_work_sync(&mbx->work);
+5 −8
Original line number Original line Diff line number Diff line
@@ -61,7 +61,6 @@
#define QLC_83XX_HOST_SDS_MBX_IDX		8
#define QLC_83XX_HOST_SDS_MBX_IDX		8


#define QLCNIC_HOST_RDS_MBX_IDX			88
#define QLCNIC_HOST_RDS_MBX_IDX			88
#define QLCNIC_MAX_RING_SETS			8


/* Pause control registers */
/* Pause control registers */
#define QLC_83XX_SRE_SHIM_REG		0x0D200284
#define QLC_83XX_SRE_SHIM_REG		0x0D200284
@@ -183,8 +182,8 @@ struct qlcnic_rcv_mbx_out {
	u8	num_pci_func;
	u8	num_pci_func;
	u8	state;
	u8	state;
#endif
#endif
	u32	host_csmr[QLCNIC_MAX_RING_SETS];
	u32	host_csmr[QLCNIC_MAX_SDS_RINGS];
	struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS];
	struct __host_producer_mbx host_prod[QLCNIC_MAX_SDS_RINGS];
} __packed;
} __packed;


struct qlcnic_add_rings_mbx_out {
struct qlcnic_add_rings_mbx_out {
@@ -197,8 +196,8 @@ struct qlcnic_add_rings_mbx_out {
	u8	sts_num;
	u8	sts_num;
	u8	rcv_num;
	u8	rcv_num;
#endif
#endif
	u32  host_csmr[QLCNIC_MAX_RING_SETS];
	u32  host_csmr[QLCNIC_MAX_SDS_RINGS];
	struct __host_producer_mbx host_prod[QLCNIC_MAX_RING_SETS];
	struct __host_producer_mbx host_prod[QLCNIC_MAX_SDS_RINGS];
} __packed;
} __packed;


/* Transmit context mailbox inbox registers
/* Transmit context mailbox inbox registers
@@ -415,8 +414,6 @@ enum qlcnic_83xx_states {
#define QLC_83XX_GET_VLAN_ALIGN_CAPABILITY(val)	(val & 0x4000)
#define QLC_83XX_GET_VLAN_ALIGN_CAPABILITY(val)	(val & 0x4000)
#define QLC_83XX_GET_FW_LRO_MSS_CAPABILITY(val)	(val & 0x20000)
#define QLC_83XX_GET_FW_LRO_MSS_CAPABILITY(val)	(val & 0x20000)
#define QLC_83XX_ESWITCH_CAPABILITY			BIT_23
#define QLC_83XX_ESWITCH_CAPABILITY			BIT_23
#define QLC_83XX_VIRTUAL_NIC_MODE			0xFF
#define QLC_83XX_DEFAULT_MODE				0x0
#define QLC_83XX_SRIOV_MODE				0x1
#define QLC_83XX_SRIOV_MODE				0x1
#define QLCNIC_BRDTYPE_83XX_10G			0x0083
#define QLCNIC_BRDTYPE_83XX_10G			0x0083


@@ -524,7 +521,7 @@ enum qlc_83xx_ext_regs {
/* 83xx funcitons */
/* 83xx funcitons */
int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *);
int qlcnic_83xx_get_fw_version(struct qlcnic_adapter *);
int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *, struct qlcnic_cmd_args *);
int qlcnic_83xx_issue_cmd(struct qlcnic_adapter *, struct qlcnic_cmd_args *);
int qlcnic_83xx_setup_intr(struct qlcnic_adapter *, u8, int);
int qlcnic_83xx_setup_intr(struct qlcnic_adapter *);
void qlcnic_83xx_get_func_no(struct qlcnic_adapter *);
void qlcnic_83xx_get_func_no(struct qlcnic_adapter *);
int qlcnic_83xx_cam_lock(struct qlcnic_adapter *);
int qlcnic_83xx_cam_lock(struct qlcnic_adapter *);
void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *);
void qlcnic_83xx_cam_unlock(struct qlcnic_adapter *);
+44 −14
Original line number Original line Diff line number Diff line
@@ -902,7 +902,7 @@ static int qlcnic_83xx_idc_need_reset_state(struct qlcnic_adapter *adapter)
		qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
		qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
		set_bit(__QLCNIC_RESETTING, &adapter->state);
		set_bit(__QLCNIC_RESETTING, &adapter->state);
		clear_bit(QLC_83XX_MBX_READY, &mbx->status);
		clear_bit(QLC_83XX_MBX_READY, &mbx->status);
		if (adapter->ahw->nic_mode == QLC_83XX_VIRTUAL_NIC_MODE)
		if (adapter->ahw->nic_mode == QLCNIC_VNIC_MODE)
			qlcnic_83xx_disable_vnic_mode(adapter, 1);
			qlcnic_83xx_disable_vnic_mode(adapter, 1);


		if (qlcnic_check_diag_status(adapter)) {
		if (qlcnic_check_diag_status(adapter)) {
@@ -2033,6 +2033,8 @@ int qlcnic_83xx_get_nic_configuration(struct qlcnic_adapter *adapter)
	ahw->max_mac_filters = nic_info.max_mac_filters;
	ahw->max_mac_filters = nic_info.max_mac_filters;
	ahw->max_mtu = nic_info.max_mtu;
	ahw->max_mtu = nic_info.max_mtu;


	adapter->max_tx_rings = ahw->max_tx_ques;
	adapter->max_sds_rings = ahw->max_rx_ques;
	/* eSwitch capability indicates vNIC mode.
	/* eSwitch capability indicates vNIC mode.
	 * vNIC and SRIOV are mutually exclusive operational modes.
	 * vNIC and SRIOV are mutually exclusive operational modes.
	 * If SR-IOV capability is detected, SR-IOV physical function
	 * If SR-IOV capability is detected, SR-IOV physical function
@@ -2045,7 +2047,7 @@ int qlcnic_83xx_get_nic_configuration(struct qlcnic_adapter *adapter)
		return QLC_83XX_DEFAULT_OPMODE;
		return QLC_83XX_DEFAULT_OPMODE;


	if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY)
	if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY)
		return QLC_83XX_VIRTUAL_NIC_MODE;
		return QLCNIC_VNIC_MODE;


	return QLC_83XX_DEFAULT_OPMODE;
	return QLC_83XX_DEFAULT_OPMODE;
}
}
@@ -2059,15 +2061,20 @@ int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter)
	if (ret == -EIO)
	if (ret == -EIO)
		return -EIO;
		return -EIO;


	if (ret == QLC_83XX_VIRTUAL_NIC_MODE) {
	if (ret == QLCNIC_VNIC_MODE) {
		ahw->nic_mode = QLC_83XX_VIRTUAL_NIC_MODE;
		ahw->nic_mode = QLCNIC_VNIC_MODE;

		if (qlcnic_83xx_config_vnic_opmode(adapter))
		if (qlcnic_83xx_config_vnic_opmode(adapter))
			return -EIO;
			return -EIO;


		adapter->max_sds_rings = QLCNIC_MAX_VNIC_SDS_RINGS;
		adapter->max_tx_rings = QLCNIC_MAX_VNIC_TX_RINGS;
	} else if (ret == QLC_83XX_DEFAULT_OPMODE) {
	} else if (ret == QLC_83XX_DEFAULT_OPMODE) {
		ahw->nic_mode = QLC_83XX_DEFAULT_MODE;
		ahw->nic_mode = QLCNIC_DEFAULT_MODE;
		adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver;
		adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver;
		ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
		ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
		adapter->max_sds_rings = ahw->max_rx_ques;
		adapter->max_tx_rings = ahw->max_tx_ques;
	} else {
	} else {
		return -EIO;
		return -EIO;
	}
	}
@@ -2170,6 +2177,23 @@ static int qlcnic_83xx_get_fw_info(struct qlcnic_adapter *adapter)
	return err;
	return err;
}
}


static void qlcnic_83xx_init_rings(struct qlcnic_adapter *adapter)
{
	u8 rx_cnt = QLCNIC_DEF_SDS_RINGS;
	u8 tx_cnt = QLCNIC_DEF_TX_RINGS;

	adapter->max_tx_rings = QLCNIC_MAX_TX_RINGS;
	adapter->max_sds_rings = QLCNIC_MAX_SDS_RINGS;

	if (!adapter->ahw->msix_supported) {
		rx_cnt = QLCNIC_SINGLE_RING;
		tx_cnt = QLCNIC_SINGLE_RING;
	}

	/* compute and set drv sds rings */
	qlcnic_set_tx_ring_count(adapter, tx_cnt);
	qlcnic_set_sds_ring_count(adapter, rx_cnt);
}


int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
{
{
@@ -2178,6 +2202,9 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
	int err = 0;
	int err = 0;


	ahw->msix_supported = !!qlcnic_use_msi_x;
	ahw->msix_supported = !!qlcnic_use_msi_x;

	qlcnic_83xx_init_rings(adapter);

	err = qlcnic_83xx_init_mailbox_work(adapter);
	err = qlcnic_83xx_init_mailbox_work(adapter);
	if (err)
	if (err)
		goto exit;
		goto exit;
@@ -2190,22 +2217,26 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
			return err;
			return err;
	}
	}


	if (qlcnic_83xx_read_flash_descriptor_table(adapter) ||
	    qlcnic_83xx_read_flash_mfg_id(adapter)) {
		dev_err(&adapter->pdev->dev, "Failed reading flash mfg id\n");
		err = -ENOTRECOVERABLE;
		goto detach_mbx;
	}

	err = qlcnic_83xx_check_hw_status(adapter);
	err = qlcnic_83xx_check_hw_status(adapter);
	if (err)
	if (err)
		goto detach_mbx;
		goto detach_mbx;


	if (!qlcnic_83xx_read_flash_descriptor_table(adapter))
		qlcnic_83xx_read_flash_mfg_id(adapter);

	err = qlcnic_83xx_get_fw_info(adapter);
	err = qlcnic_83xx_get_fw_info(adapter);
	if (err)
	if (err)
		goto detach_mbx;
		goto detach_mbx;


	err = qlcnic_83xx_idc_init(adapter);
	err = qlcnic_83xx_idc_init(adapter);
	if (err)
	if (err)
		goto clear_fw_info;
		goto detach_mbx;


	err = qlcnic_setup_intr(adapter, 0, 0);
	err = qlcnic_setup_intr(adapter);
	if (err) {
	if (err) {
		dev_err(&adapter->pdev->dev, "Failed to setup interrupt\n");
		dev_err(&adapter->pdev->dev, "Failed to setup interrupt\n");
		goto disable_intr;
		goto disable_intr;
@@ -2227,6 +2258,7 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
	if (err)
	if (err)
		goto disable_mbx_intr;
		goto disable_mbx_intr;



	/* Perform operating mode specific initialization */
	/* Perform operating mode specific initialization */
	err = adapter->nic_ops->init_driver(adapter);
	err = adapter->nic_ops->init_driver(adapter);
	if (err)
	if (err)
@@ -2247,12 +2279,10 @@ disable_mbx_intr:
disable_intr:
disable_intr:
	qlcnic_teardown_intr(adapter);
	qlcnic_teardown_intr(adapter);


clear_fw_info:
	kfree(ahw->fw_info);

detach_mbx:
detach_mbx:
	qlcnic_83xx_detach_mailbox_work(adapter);
	qlcnic_83xx_detach_mailbox_work(adapter);
	qlcnic_83xx_free_mailbox(ahw->mailbox);
	qlcnic_83xx_free_mailbox(ahw->mailbox);
	ahw->mailbox = NULL;
exit:
exit:
	return err;
	return err;
}
}
@@ -2265,7 +2295,7 @@ void qlcnic_83xx_aer_stop_poll_work(struct qlcnic_adapter *adapter)
	clear_bit(QLC_83XX_MBX_READY, &idc->status);
	clear_bit(QLC_83XX_MBX_READY, &idc->status);
	cancel_delayed_work_sync(&adapter->fw_work);
	cancel_delayed_work_sync(&adapter->fw_work);


	if (ahw->nic_mode == QLC_83XX_VIRTUAL_NIC_MODE)
	if (ahw->nic_mode == QLCNIC_VNIC_MODE)
		qlcnic_83xx_disable_vnic_mode(adapter, 1);
		qlcnic_83xx_disable_vnic_mode(adapter, 1);


	qlcnic_83xx_idc_detach_driver(adapter);
	qlcnic_83xx_idc_detach_driver(adapter);
+11 −9
Original line number Original line Diff line number Diff line
@@ -270,7 +270,7 @@ int qlcnic_82xx_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
	int err;
	int err;


	nrds_rings = adapter->max_rds_rings;
	nrds_rings = adapter->max_rds_rings;
	nsds_rings = adapter->max_sds_rings;
	nsds_rings = adapter->drv_sds_rings;


	rq_size = SIZEOF_HOSTRQ_RX(struct qlcnic_hostrq_rx_ctx, nrds_rings,
	rq_size = SIZEOF_HOSTRQ_RX(struct qlcnic_hostrq_rx_ctx, nrds_rings,
				   nsds_rings);
				   nsds_rings);
@@ -475,7 +475,7 @@ int qlcnic_82xx_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter,


	if (qlcnic_check_multi_tx(adapter) &&
	if (qlcnic_check_multi_tx(adapter) &&
	    !adapter->ahw->diag_test) {
	    !adapter->ahw->diag_test) {
		temp_nsds_rings = adapter->max_sds_rings;
		temp_nsds_rings = adapter->drv_sds_rings;
		index = temp_nsds_rings + ring;
		index = temp_nsds_rings + ring;
		msix_id = ahw->intr_tbl[index].id;
		msix_id = ahw->intr_tbl[index].id;
		prq->msi_index = cpu_to_le16(msix_id);
		prq->msi_index = cpu_to_le16(msix_id);
@@ -512,7 +512,7 @@ int qlcnic_82xx_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter,
		if (qlcnic_check_multi_tx(adapter) &&
		if (qlcnic_check_multi_tx(adapter) &&
		    !adapter->ahw->diag_test &&
		    !adapter->ahw->diag_test &&
		    (adapter->flags & QLCNIC_MSIX_ENABLED)) {
		    (adapter->flags & QLCNIC_MSIX_ENABLED)) {
			index = adapter->max_sds_rings + ring;
			index = adapter->drv_sds_rings + ring;
			intr_mask = ahw->intr_tbl[index].src;
			intr_mask = ahw->intr_tbl[index].src;
			tx_ring->crb_intr_mask = ahw->pci_base0 + intr_mask;
			tx_ring->crb_intr_mask = ahw->pci_base0 + intr_mask;
		}
		}
@@ -582,7 +582,7 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)


	recv_ctx = adapter->recv_ctx;
	recv_ctx = adapter->recv_ctx;


	for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
	for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
		tx_ring = &adapter->tx_ring[ring];
		tx_ring = &adapter->tx_ring[ring];
		ptr = (__le32 *)dma_alloc_coherent(&pdev->dev, sizeof(u32),
		ptr = (__le32 *)dma_alloc_coherent(&pdev->dev, sizeof(u32),
						   &tx_ring->hw_cons_phys_addr,
						   &tx_ring->hw_cons_phys_addr,
@@ -616,7 +616,7 @@ int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)


	}
	}


	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
	for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
		sds_ring = &recv_ctx->sds_rings[ring];
		sds_ring = &recv_ctx->sds_rings[ring];


		addr = dma_alloc_coherent(&adapter->pdev->dev,
		addr = dma_alloc_coherent(&adapter->pdev->dev,
@@ -664,7 +664,7 @@ int qlcnic_fw_create_ctx(struct qlcnic_adapter *dev)
	if (err)
	if (err)
		goto err_out;
		goto err_out;


	for (ring = 0; ring < dev->max_drv_tx_rings; ring++) {
	for (ring = 0; ring < dev->drv_tx_rings; ring++) {
		err = qlcnic_fw_cmd_create_tx_ctx(dev,
		err = qlcnic_fw_cmd_create_tx_ctx(dev,
						  &dev->tx_ring[ring],
						  &dev->tx_ring[ring],
						  ring);
						  ring);
@@ -703,7 +703,7 @@ void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter)


	if (test_and_clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) {
	if (test_and_clear_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) {
		qlcnic_fw_cmd_del_rx_ctx(adapter);
		qlcnic_fw_cmd_del_rx_ctx(adapter);
		for (ring = 0; ring < adapter->max_drv_tx_rings; ring++)
		for (ring = 0; ring < adapter->drv_tx_rings; ring++)
			qlcnic_fw_cmd_del_tx_ctx(adapter,
			qlcnic_fw_cmd_del_tx_ctx(adapter,
						 &adapter->tx_ring[ring]);
						 &adapter->tx_ring[ring]);


@@ -733,7 +733,7 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)


	recv_ctx = adapter->recv_ctx;
	recv_ctx = adapter->recv_ctx;


	for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
	for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
		tx_ring = &adapter->tx_ring[ring];
		tx_ring = &adapter->tx_ring[ring];
		if (tx_ring->hw_consumer != NULL) {
		if (tx_ring->hw_consumer != NULL) {
			dma_free_coherent(&adapter->pdev->dev, sizeof(u32),
			dma_free_coherent(&adapter->pdev->dev, sizeof(u32),
@@ -764,7 +764,7 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
		}
		}
	}
	}


	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
	for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
		sds_ring = &recv_ctx->sds_rings[ring];
		sds_ring = &recv_ctx->sds_rings[ring];


		if (sds_ring->desc_head != NULL) {
		if (sds_ring->desc_head != NULL) {
@@ -895,6 +895,8 @@ int qlcnic_82xx_get_nic_info(struct qlcnic_adapter *adapter,
		npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques);
		npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques);
		npar_info->capabilities = le32_to_cpu(nic_info->capabilities);
		npar_info->capabilities = le32_to_cpu(nic_info->capabilities);
		npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu);
		npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu);
		adapter->max_tx_rings = npar_info->max_tx_ques;
		adapter->max_sds_rings = npar_info->max_rx_ques;
	}
	}


	qlcnic_free_mbx_args(&cmd);
	qlcnic_free_mbx_args(&cmd);
Loading