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

Commit 012ec812 authored by Himanshu Madhani's avatar Himanshu Madhani Committed by David S. Miller
Browse files

qlcnic: Multi Tx queue support for 82xx Series adapter.



o  82xx firmware allows support for multiple Tx queues. This
   patch will enable multi Tx queue support for 82xx series
   adapter. Max number of Tx queues supported will be 8.

Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 954c3967
Loading
Loading
Loading
Loading
+69 −5
Original line number Diff line number Diff line
@@ -97,6 +97,9 @@
#define TX_STOP_THRESH		((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \
							+ MGMT_CMD_DESC_RESV)
#define QLCNIC_MAX_TX_TIMEOUTS	2
#define QLCNIC_MAX_TX_RINGS	8
#define QLCNIC_MAX_SDS_RINGS	8

/*
 * Following are the states of the Phantom. Phantom will set them and
 * Host will read to check if the fields are correct.
@@ -515,6 +518,7 @@ struct qlcnic_host_sds_ring {
	u32 num_desc;
	void __iomem *crb_sts_consumer;

	struct qlcnic_host_tx_ring *tx_ring;
	struct status_desc *desc_head;
	struct qlcnic_adapter *adapter;
	struct napi_struct napi;
@@ -532,9 +536,17 @@ struct qlcnic_host_tx_ring {
	void __iomem *crb_intr_mask;
	char name[IFNAMSIZ + 12];
	u16 ctx_id;

	u32 state;
	u32 producer;
	u32 sw_consumer;
	u32 num_desc;

	u64 xmit_on;
	u64 xmit_off;
	u64 xmit_called;
	u64 xmit_finished;

	void __iomem *crb_cmd_producer;
	struct cmd_desc_type0 *desc_head;
	struct qlcnic_adapter *adapter;
@@ -559,7 +571,6 @@ struct qlcnic_recv_context {
	u32 state;
	u16 context_id;
	u16 virt_port;

};

/* HW context creation */
@@ -604,6 +615,7 @@ struct qlcnic_recv_context {
#define QLCNIC_CAP0_LRO_CONTIGUOUS	(1 << 8)
#define QLCNIC_CAP0_VALIDOFF		(1 << 11)
#define QLCNIC_CAP0_LRO_MSS		(1 << 21)
#define QLCNIC_CAP0_TX_MULTI		(1 << 22)

/*
 * Context state
@@ -814,6 +826,7 @@ struct qlcnic_mac_list_s {
#define QLCNIC_FW_CAPABILITY_BDG		BIT_8
#define QLCNIC_FW_CAPABILITY_FVLANTX		BIT_9
#define QLCNIC_FW_CAPABILITY_HW_LRO		BIT_10
#define QLCNIC_FW_CAPABILITY_2_MULTI_TX		BIT_4
#define QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK	BIT_27
#define QLCNIC_FW_CAPABILITY_MORE_CAPS		BIT_31

@@ -922,6 +935,7 @@ struct qlcnic_ipaddr {
#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_PCI_REG_MSIX_TBL 	0x44
#define QLCNIC_MSIX_TBL_PGSIZE		4096
@@ -937,6 +951,7 @@ struct qlcnic_ipaddr {
#define __QLCNIC_DIAG_RES_ALLOC		6
#define __QLCNIC_LED_ENABLE		7
#define __QLCNIC_ELB_INPROGRESS		8
#define __QLCNIC_MULTI_TX_UNIQUE	9
#define __QLCNIC_SRIOV_ENABLE		10
#define __QLCNIC_SRIOV_CAPABLE		11
#define __QLCNIC_MBX_POLL_ENABLE	12
@@ -1482,7 +1497,8 @@ void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter);

void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter);
void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter);
void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter);
void qlcnic_release_tx_buffers(struct qlcnic_adapter *,
			       struct qlcnic_host_tx_ring *);

int qlcnic_check_fw_status(struct qlcnic_adapter *adapter);
void qlcnic_watchdog_task(struct work_struct *work);
@@ -1543,6 +1559,7 @@ void qlcnic_free_sds_rings(struct qlcnic_recv_context *);
void qlcnic_advert_link_change(struct qlcnic_adapter *, int);
void qlcnic_free_tx_rings(struct qlcnic_adapter *);
int qlcnic_alloc_tx_rings(struct qlcnic_adapter *, struct net_device *);
void qlcnic_dump_mbx(struct qlcnic_adapter *, struct qlcnic_cmd_args *);

void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter);
void qlcnic_remove_sysfs_entries(struct qlcnic_adapter *adapter);
@@ -1605,6 +1622,26 @@ static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring)
				tx_ring->producer;
}

static inline int qlcnic_set_real_num_queues(struct qlcnic_adapter *adapter,
					     struct net_device *netdev)
{
	int err, tx_q;

	tx_q = adapter->max_drv_tx_rings;

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

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

	return err;
}

struct qlcnic_nic_template {
	int (*config_bridged_mode) (struct qlcnic_adapter *, u32);
	int (*config_led) (struct qlcnic_adapter *, u32, u32);
@@ -1932,15 +1969,42 @@ static inline void qlcnic_config_ipaddr(struct qlcnic_adapter *adapter,
	adapter->nic_ops->config_ipaddr(adapter, ip, cmd);
}

static inline bool qlcnic_check_multi_tx(struct qlcnic_adapter *adapter)
{
	return test_bit(__QLCNIC_MULTI_TX_UNIQUE, &adapter->state);
}

static inline void qlcnic_disable_multi_tx(struct qlcnic_adapter *adapter)
{
	test_and_clear_bit(__QLCNIC_MULTI_TX_UNIQUE, &adapter->state);
	adapter->max_drv_tx_rings = 1;
}

/* When operating in a muti tx mode, driver needs to write 0x1
 * to src register, instead of 0x0 to disable receiving interrupt.
 */
static inline void qlcnic_disable_int(struct qlcnic_host_sds_ring *sds_ring)
{
	struct qlcnic_adapter *adapter = sds_ring->adapter;

	if (qlcnic_check_multi_tx(adapter) &&
	    (adapter->flags & QLCNIC_MSIX_ENABLED))
		writel(0x1, sds_ring->crb_intr_mask);
	else
		writel(0, sds_ring->crb_intr_mask);
}

/* When operating in a muti tx mode, driver needs to write 0x0
 * to src register, instead of 0x1 to enable receiving interrupts.
 */
static inline void qlcnic_enable_int(struct qlcnic_host_sds_ring *sds_ring)
{
	struct qlcnic_adapter *adapter = sds_ring->adapter;

	if (qlcnic_check_multi_tx(adapter) &&
	    (adapter->flags & QLCNIC_MSIX_ENABLED))
		writel(0, sds_ring->crb_intr_mask);
	else
		writel(0x1, sds_ring->crb_intr_mask);

	if (!QLCNIC_IS_MSI_FAMILY(adapter))
+3 −3
Original line number Diff line number Diff line
@@ -695,7 +695,7 @@ static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
					    u32 data[]);

static void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
void qlcnic_dump_mbx(struct qlcnic_adapter *adapter,
		     struct qlcnic_cmd_args *cmd)
{
	int i;
@@ -1691,7 +1691,7 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
	/* Make sure carrier is off and queue is stopped during loopback */
	if (netif_running(netdev)) {
		netif_carrier_off(netdev);
		netif_stop_queue(netdev);
		netif_tx_stop_all_queues(netdev);
	}

	ret = qlcnic_do_lb_test(adapter, mode);
+144 −52
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ static const struct qlcnic_mailbox_metadata qlcnic_mbx_tbl[] = {
	{QLCNIC_CMD_GET_TEMP_HDR, 4, 1},
	{QLCNIC_CMD_82XX_SET_DRV_VER, 4, 1},
	{QLCNIC_CMD_GET_LED_STATUS, 4, 2},
	{QLCNIC_CMD_MQ_TX_CONFIG_INTR, 2, 3},
};

static inline u32 qlcnic_get_cmd_signature(struct qlcnic_hardware_context *ahw)
@@ -171,6 +172,7 @@ int qlcnic_82xx_issue_cmd(struct qlcnic_adapter *adapter,
			break;
		}
		dev_err(&pdev->dev, fmt, cmd->rsp.arg[0]);
		qlcnic_dump_mbx(adapter, cmd);
	} else if (rsp == QLCNIC_CDRP_RSP_OK)
		cmd->rsp.arg[0] = QLCNIC_RCODE_SUCCESS;

@@ -243,36 +245,34 @@ qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu)

int qlcnic_82xx_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
{
	void *addr;
	struct qlcnic_hostrq_rx_ctx *prq;
	struct qlcnic_cardrsp_rx_ctx *prsp;
	struct qlcnic_hostrq_rds_ring *prq_rds;
	struct qlcnic_hostrq_sds_ring *prq_sds;
	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
	struct net_device *netdev = adapter->netdev;
	u32 temp_intr_crb_mode, temp_rds_crb_mode;
	struct qlcnic_cardrsp_rds_ring *prsp_rds;
	struct qlcnic_cardrsp_sds_ring *prsp_sds;
	struct qlcnic_hostrq_rds_ring *prq_rds;
	struct qlcnic_hostrq_sds_ring *prq_sds;
	struct qlcnic_host_rds_ring *rds_ring;
	struct qlcnic_host_sds_ring *sds_ring;
	struct qlcnic_cmd_args cmd;

	dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
	u64 phys_addr;

	struct qlcnic_cardrsp_rx_ctx *prsp;
	struct qlcnic_hostrq_rx_ctx *prq;
	u8 i, nrds_rings, nsds_rings;
	u16 temp_u16;
	struct qlcnic_cmd_args cmd;
	size_t rq_size, rsp_size;
	u32 cap, reg, val, reg2;
	u64 phys_addr;
	u16 temp_u16;
	void *addr;
	int err;

	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;

	nrds_rings = adapter->max_rds_rings;
	nsds_rings = adapter->max_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);
	rsp_size =
		SIZEOF_CARDRSP_RX(struct qlcnic_cardrsp_rx_ctx, nrds_rings,
	rsp_size = SIZEOF_CARDRSP_RX(struct qlcnic_cardrsp_rx_ctx, nrds_rings,
				     nsds_rings);

	addr = dma_alloc_coherent(&adapter->pdev->dev, rq_size,
@@ -295,15 +295,19 @@ int qlcnic_82xx_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
						| QLCNIC_CAP0_VALIDOFF);
	cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS);

	if (qlcnic_check_multi_tx(adapter)) {
		cap |= QLCNIC_CAP0_TX_MULTI;
	} else {
		temp_u16 = offsetof(struct qlcnic_hostrq_rx_ctx, msix_handler);
		prq->valid_field_offset = cpu_to_le16(temp_u16);
		prq->txrx_sds_binding = nsds_rings - 1;
		temp_intr_crb_mode = QLCNIC_HOST_INT_CRB_MODE_SHARED;
		prq->host_int_crb_mode = cpu_to_le32(temp_intr_crb_mode);
		temp_rds_crb_mode = QLCNIC_HOST_RDS_CRB_MODE_UNIQUE;
		prq->host_rds_crb_mode = cpu_to_le32(temp_rds_crb_mode);
	}

	prq->capabilities[0] = cpu_to_le32(cap);
	prq->host_int_crb_mode =
		cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED);
	prq->host_rds_crb_mode =
		cpu_to_le32(QLCNIC_HOST_RDS_CRB_MODE_UNIQUE);

	prq->num_rds_rings = cpu_to_le16(nrds_rings);
	prq->num_sds_rings = cpu_to_le16(nsds_rings);
@@ -317,10 +321,8 @@ int qlcnic_82xx_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
			le32_to_cpu(prq->rds_ring_offset));

	for (i = 0; i < nrds_rings; i++) {

		rds_ring = &recv_ctx->rds_rings[i];
		rds_ring->producer = 0;

		prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
		prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc);
		prq_rds[i].ring_kind = cpu_to_le32(i);
@@ -331,13 +333,14 @@ int qlcnic_82xx_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
			le32_to_cpu(prq->sds_ring_offset));

	for (i = 0; i < nsds_rings; i++) {

		sds_ring = &recv_ctx->sds_rings[i];
		sds_ring->consumer = 0;
		memset(sds_ring->desc_head, 0, STATUS_DESC_RINGSIZE(sds_ring));

		prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
		prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
		if (qlcnic_check_multi_tx(adapter))
			prq_sds[i].msi_index = cpu_to_le16(ahw->intr_tbl[i].id);
		else
			prq_sds[i].msi_index = cpu_to_le16(i);
	}

@@ -361,9 +364,8 @@ int qlcnic_82xx_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)

	for (i = 0; i < le16_to_cpu(prsp->num_rds_rings); i++) {
		rds_ring = &recv_ctx->rds_rings[i];

		reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
		rds_ring->crb_rcv_producer = adapter->ahw->pci_base0 + reg;
		rds_ring->crb_rcv_producer = ahw->pci_base0 + reg;
	}

	prsp_sds = ((struct qlcnic_cardrsp_sds_ring *)
@@ -371,24 +373,30 @@ int qlcnic_82xx_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)

	for (i = 0; i < le16_to_cpu(prsp->num_sds_rings); i++) {
		sds_ring = &recv_ctx->sds_rings[i];

		reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
		if (qlcnic_check_multi_tx(adapter))
			reg2 = ahw->intr_tbl[i].src;
		else
			reg2 = le32_to_cpu(prsp_sds[i].interrupt_crb);

		sds_ring->crb_sts_consumer = adapter->ahw->pci_base0 + reg;
		sds_ring->crb_intr_mask = adapter->ahw->pci_base0 + reg2;
		sds_ring->crb_intr_mask = ahw->pci_base0 + reg2;
		sds_ring->crb_sts_consumer = ahw->pci_base0 + reg;
	}

	recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
	recv_ctx->context_id = le16_to_cpu(prsp->context_id);
	recv_ctx->virt_port = prsp->virt_port;

	netdev_info(netdev, "Rx Context[%d] Created, state 0x%x\n",
		    recv_ctx->context_id, recv_ctx->state);
	qlcnic_free_mbx_args(&cmd);

out_free_rsp:
	dma_free_coherent(&adapter->pdev->dev, rsp_size, prsp,
			  cardrsp_phys_addr);
out_free_rq:
	dma_free_coherent(&adapter->pdev->dev, rq_size, prq, hostrq_phys_addr);

	return err;
}

@@ -416,16 +424,19 @@ int qlcnic_82xx_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter,
				     struct qlcnic_host_tx_ring *tx_ring,
				     int ring)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct net_device *netdev = adapter->netdev;
	struct qlcnic_hostrq_tx_ctx	*prq;
	struct qlcnic_hostrq_cds_ring	*prq_cds;
	struct qlcnic_cardrsp_tx_ctx	*prsp;
	struct qlcnic_cmd_args cmd;
	u32 temp, intr_mask, temp_int_crb_mode;
	dma_addr_t rq_phys_addr, rsp_phys_addr;
	int temp_nsds_rings, index, err;
	void *rq_addr, *rsp_addr;
	size_t rq_size, rsp_size;
	u32	temp;
	struct qlcnic_cmd_args cmd;
	int	err;
	u64 phys_addr;
	dma_addr_t	rq_phys_addr, rsp_phys_addr;
	u16 msix_id;

	/* reset host resources */
	tx_ring->producer = 0;
@@ -447,18 +458,28 @@ int qlcnic_82xx_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter,
	}

	prq = rq_addr;

	prsp = rsp_addr;

	prq->host_rsp_dma_addr = cpu_to_le64(rsp_phys_addr);

	temp = (QLCNIC_CAP0_LEGACY_CONTEXT | QLCNIC_CAP0_LEGACY_MN |
		QLCNIC_CAP0_LSO);
	if (qlcnic_check_multi_tx(adapter))
		temp |= QLCNIC_CAP0_TX_MULTI;

	prq->capabilities[0] = cpu_to_le32(temp);

	prq->host_int_crb_mode =
		cpu_to_le32(QLCNIC_HOST_INT_CRB_MODE_SHARED);
	if (qlcnic_check_multi_tx(adapter) &&
	    (adapter->max_drv_tx_rings > 1)) {
		temp_nsds_rings = adapter->max_sds_rings;
		index = temp_nsds_rings + ring;
		msix_id = ahw->intr_tbl[index].id;
		prq->msi_index = cpu_to_le16(msix_id);
	} else {
		temp_int_crb_mode = QLCNIC_HOST_INT_CRB_MODE_SHARED;
		prq->host_int_crb_mode = cpu_to_le32(temp_int_crb_mode);
		prq->msi_index = 0;
	}

	prq->interrupt_ctl = 0;
	prq->cmd_cons_dma_addr = cpu_to_le64(tx_ring->hw_cons_phys_addr);
@@ -480,15 +501,24 @@ int qlcnic_82xx_fw_cmd_create_tx_ctx(struct qlcnic_adapter *adapter,
	err = qlcnic_issue_cmd(adapter, &cmd);

	if (err == QLCNIC_RCODE_SUCCESS) {
		tx_ring->state = le32_to_cpu(prsp->host_ctx_state);
		temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
		tx_ring->crb_cmd_producer = adapter->ahw->pci_base0 + temp;
		tx_ring->ctx_id = le16_to_cpu(prsp->context_id);
		if (qlcnic_check_multi_tx(adapter) &&
		    (adapter->flags & QLCNIC_MSIX_ENABLED)) {
			index = adapter->max_sds_rings + ring;
			intr_mask = ahw->intr_tbl[index].src;
			tx_ring->crb_intr_mask = ahw->pci_base0 + intr_mask;
		}

		netdev_info(netdev, "Tx Context[0x%x] Created, state 0x%x\n",
			    tx_ring->ctx_id, tx_ring->state);
	} else {
		dev_err(&adapter->pdev->dev,
			"Failed to create tx ctx in firmware%d\n", err);
		netdev_err(netdev, "Failed to create tx ctx in firmware%d\n",
			   err);
		err = -EIO;
	}

	qlcnic_free_mbx_args(&cmd);

out_free_rsp:
@@ -618,6 +648,13 @@ int qlcnic_fw_create_ctx(struct qlcnic_adapter *dev)
		}
	}

	if (qlcnic_82xx_check(dev) && (dev->flags & QLCNIC_MSIX_ENABLED) &&
	    qlcnic_check_multi_tx(dev) && !dev->ahw->diag_test) {
		err = qlcnic_82xx_mq_intrpt(dev, 1);
		if (err)
			return err;
	}

	err = qlcnic_fw_cmd_create_rx_ctx(dev);
	if (err)
		goto err_out;
@@ -639,9 +676,14 @@ int qlcnic_fw_create_ctx(struct qlcnic_adapter *dev)
	}

	set_bit(__QLCNIC_FW_ATTACHED, &dev->state);

	return 0;

err_out:
	if (qlcnic_82xx_check(dev) && (dev->flags & QLCNIC_MSIX_ENABLED) &&
	    qlcnic_check_multi_tx(dev))
		qlcnic_82xx_config_intrpt(dev, 0);

	if (qlcnic_83xx_check(dev) && (dev->flags & QLCNIC_MSIX_ENABLED)) {
		if (dev->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
			qlcnic_83xx_config_intrpt(dev, 0);
@@ -659,6 +701,11 @@ void qlcnic_fw_destroy_ctx(struct qlcnic_adapter *adapter)
			qlcnic_fw_cmd_del_tx_ctx(adapter,
						 &adapter->tx_ring[ring]);

		if (qlcnic_82xx_check(adapter) &&
		    (adapter->flags & QLCNIC_MSIX_ENABLED) &&
		    qlcnic_check_multi_tx(adapter))
			qlcnic_82xx_config_intrpt(adapter, 0);

		if (qlcnic_83xx_check(adapter) &&
		    (adapter->flags & QLCNIC_MSIX_ENABLED)) {
			if (adapter->ahw->diag_test != QLCNIC_LOOPBACK_TEST)
@@ -723,6 +770,51 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
	}
}

int qlcnic_82xx_config_intrpt(struct qlcnic_adapter *adapter, u8 op_type)
{
	struct qlcnic_hardware_context *ahw = adapter->ahw;
	struct net_device *netdev = adapter->netdev;
	struct qlcnic_cmd_args cmd;
	u32 type, val;
	int i, err = 0;

	for (i = 0; i < ahw->num_msix; i++) {
		qlcnic_alloc_mbx_args(&cmd, adapter,
				      QLCNIC_CMD_MQ_TX_CONFIG_INTR);
		type = op_type ? QLCNIC_INTRPT_ADD : QLCNIC_INTRPT_DEL;
		val = type | (ahw->intr_tbl[i].type << 4);
		if (ahw->intr_tbl[i].type == QLCNIC_INTRPT_MSIX)
			val |= (ahw->intr_tbl[i].id << 16);
		cmd.req.arg[1] = val;
		err = qlcnic_issue_cmd(adapter, &cmd);
		if (err) {
			netdev_err(netdev, "Failed to %s interrupts %d\n",
				   op_type == QLCNIC_INTRPT_ADD ? "Add" :
				   "Delete", err);
			qlcnic_free_mbx_args(&cmd);
			return err;
		}
		val = cmd.rsp.arg[1];
		if (LSB(val)) {
			netdev_info(netdev,
				    "failed to configure interrupt for %d\n",
				    ahw->intr_tbl[i].id);
			continue;
		}
		if (op_type) {
			ahw->intr_tbl[i].id = MSW(val);
			ahw->intr_tbl[i].enabled = 1;
			ahw->intr_tbl[i].src = cmd.rsp.arg[2];
		} else {
			ahw->intr_tbl[i].id = i;
			ahw->intr_tbl[i].enabled = 0;
			ahw->intr_tbl[i].src = 0;
		}
		qlcnic_free_mbx_args(&cmd);
	}

	return err;
}

int qlcnic_82xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac)
{
+1 −1
Original line number Diff line number Diff line
@@ -387,7 +387,7 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter,
	if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
		return -EIO;

	tx_ring = adapter->tx_ring;
	tx_ring = &adapter->tx_ring[0];
	__netif_tx_lock_bh(tx_ring->txq);

	producer = tx_ring->producer;
+3 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ enum qlcnic_regs {
#define	QLCNIC_CMD_CONFIG_VPORT			0x32
#define QLCNIC_CMD_GET_MAC_STATS		0x37
#define QLCNIC_CMD_82XX_SET_DRV_VER		0x38
#define QLCNIC_CMD_MQ_TX_CONFIG_INTR		0x39
#define QLCNIC_CMD_GET_LED_STATUS		0x3C
#define QLCNIC_CMD_CONFIGURE_RSS		0x41
#define QLCNIC_CMD_CONFIG_INTR_COAL		0x43
@@ -177,6 +178,8 @@ int qlcnic_82xx_setup_intr(struct qlcnic_adapter *, u8);
irqreturn_t qlcnic_82xx_clear_legacy_intr(struct qlcnic_adapter *);
int qlcnic_82xx_issue_cmd(struct qlcnic_adapter *adapter,
			  struct qlcnic_cmd_args *);
int qlcnic_82xx_mq_intrpt(struct qlcnic_adapter *, int);
int qlcnic_82xx_config_intrpt(struct qlcnic_adapter *, u8);
int qlcnic_82xx_fw_cmd_create_rx_ctx(struct qlcnic_adapter *);
int qlcnic_82xx_fw_cmd_create_tx_ctx(struct qlcnic_adapter *,
				     struct qlcnic_host_tx_ring *tx_ring, int);
Loading