Commit 34e8c406 authored by Himanshu Madhani's avatar Himanshu Madhani Committed by David S. Miller

qlcnic: refactor Tx/SDS ring calculation and validation in driver.

o Current driver has duplicate code for validating user input
  for changing Tx/SDS rings using set_channel ethtool interface.
  This patch removes duplicate code and refactored Tx/SDS ring
  validation for 82xx/83xx/84xx series adapter.
o Refactored code now calculates maximum Tx/Rx ring driver can
  support based on Default, NPAR and SRIOV PF/VF mode of driver.
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f27c75b3
...@@ -98,8 +98,22 @@ ...@@ -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
...@@ -945,8 +959,6 @@ struct qlcnic_ipaddr { ...@@ -945,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
...@@ -1017,7 +1029,6 @@ struct qlcnic_adapter { ...@@ -1017,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;
...@@ -1025,7 +1036,13 @@ struct qlcnic_adapter { ...@@ -1025,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;
...@@ -1548,12 +1565,13 @@ int qlcnic_loopback_test(struct net_device *, u8); ...@@ -1548,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);
...@@ -1646,19 +1664,18 @@ static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring) ...@@ -1646,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;
} }
...@@ -1700,7 +1717,7 @@ struct qlcnic_hardware_ops { ...@@ -1700,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 *);
...@@ -1771,10 +1788,9 @@ static inline int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, ...@@ -1771,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,
...@@ -2010,7 +2026,7 @@ static inline bool qlcnic_check_multi_tx(struct qlcnic_adapter *adapter) ...@@ -2010,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
......
...@@ -13,7 +13,6 @@ ...@@ -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, ...@@ -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)
...@@ -986,14 +983,14 @@ static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter) ...@@ -986,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;
...@@ -1028,7 +1025,7 @@ static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter) ...@@ -1028,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];
...@@ -1086,10 +1083,10 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter) ...@@ -1086,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);
...@@ -1190,7 +1187,7 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter) ...@@ -1190,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);
...@@ -1246,9 +1243,9 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter, ...@@ -1246,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);
...@@ -1271,7 +1268,8 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter, ...@@ -1271,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*/
...@@ -1286,7 +1284,7 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter, ...@@ -1286,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",
...@@ -1297,7 +1295,7 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter, ...@@ -1297,7 +1295,7 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
} }
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;
...@@ -1313,7 +1311,7 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test, ...@@ -1313,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;
...@@ -1327,7 +1325,7 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test, ...@@ -1327,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);
...@@ -1340,7 +1338,7 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test, ...@@ -1340,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);
} }
...@@ -1361,7 +1359,7 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test, ...@@ -1361,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;
...@@ -1369,7 +1367,7 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev, ...@@ -1369,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))
...@@ -1393,7 +1391,7 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev, ...@@ -1393,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;
...@@ -1655,7 +1653,8 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode) ...@@ -1655,7 +1653,8 @@ 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;
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,
...@@ -1677,7 +1676,7 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode) ...@@ -1677,7 +1676,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;
...@@ -1715,10 +1714,10 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode) ...@@ -1715,10 +1714,10 @@ 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;
qlcnic_release_diag_lock(adapter); qlcnic_release_diag_lock(adapter);
return ret; return ret;
} }
...@@ -3303,10 +3302,10 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev) ...@@ -3303,10 +3302,10 @@ 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;
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");
...@@ -3319,7 +3318,7 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev) ...@@ -3319,7 +3318,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;
...@@ -3356,10 +3355,10 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev) ...@@ -3356,10 +3355,10 @@ 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;
qlcnic_release_diag_lock(adapter); qlcnic_release_diag_lock(adapter);
return ret; return ret;
} }
...@@ -3513,7 +3512,7 @@ int qlcnic_83xx_resume(struct qlcnic_adapter *adapter) ...@@ -3513,7 +3512,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 {
......
...@@ -61,7 +61,6 @@ ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 *);
......
...@@ -902,7 +902,7 @@ static int qlcnic_83xx_idc_need_reset_state(struct qlcnic_adapter *adapter) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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_SINGLE_RING;
} 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 = QLCNIC_SINGLE_RING;
} else { } else {
return -EIO; return -EIO;
} }
...@@ -2170,6 +2177,19 @@ static int qlcnic_83xx_get_fw_info(struct qlcnic_adapter *adapter) ...@@ -2170,6 +2177,19 @@ 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)
{
adapter->max_tx_rings = QLCNIC_MAX_TX_RINGS;
adapter->max_sds_rings = QLCNIC_MAX_SDS_RINGS;
qlcnic_set_tx_ring_count(adapter, QLCNIC_SINGLE_RING);
/* compute and set drv sds rings */
if (adapter->ahw->msix_supported)
qlcnic_set_sds_ring_count(adapter, QLCNIC_DEF_SDS_RINGS);
else
qlcnic_set_sds_ring_count(adapter, QLCNIC_SINGLE_RING);
}
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 +2198,9 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) ...@@ -2178,6 +2198,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;
...@@ -2209,7 +2232,7 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) ...@@ -2209,7 +2232,7 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
if (err) if (err)
goto detach_mbx; 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;
...@@ -2231,6 +2254,7 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) ...@@ -2231,6 +2254,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)
...@@ -2267,7 +2291,7 @@ void qlcnic_83xx_aer_stop_poll_work(struct qlcnic_adapter *adapter) ...@@ -2267,7 +2291,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);
......
...@@ -270,7 +270,7 @@ int qlcnic_82xx_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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);
......
...@@ -226,9 +226,9 @@ static const u32 ext_diag_registers[] = { ...@@ -226,9 +226,9 @@ static const u32 ext_diag_registers[] = {
static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter) static inline int qlcnic_get_ring_regs_len(struct qlcnic_adapter *adapter)
{ {
int ring_regs_cnt = (adapter->max_drv_tx_rings * 5) + int ring_regs_cnt = (adapter->drv_tx_rings * 5) +
(adapter->max_rds_rings * 2) + (adapter->max_rds_rings * 2) +
(adapter->max_sds_rings * 3) + 5; (adapter->drv_sds_rings * 3) + 5;
return ring_regs_cnt * sizeof(u32); return ring_regs_cnt * sizeof(u32);
} }
...@@ -530,8 +530,8 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) ...@@ -530,8 +530,8 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
/* Marker btw regs and TX ring count */ /* Marker btw regs and TX ring count */
regs_buff[i++] = 0xFFEFCDAB; regs_buff[i++] = 0xFFEFCDAB;
regs_buff[i++] = adapter->max_drv_tx_rings; /* No. of TX ring */ regs_buff[i++] = adapter->drv_tx_rings; /* No. of TX ring */
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];
regs_buff[i++] = le32_to_cpu(*(tx_ring->hw_consumer)); regs_buff[i++] = le32_to_cpu(*(tx_ring->hw_consumer));
regs_buff[i++] = tx_ring->sw_consumer; regs_buff[i++] = tx_ring->sw_consumer;
...@@ -550,8 +550,8 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) ...@@ -550,8 +550,8 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
regs_buff[i++] = rds_rings->producer; regs_buff[i++] = rds_rings->producer;
} }
regs_buff[i++] = adapter->max_sds_rings; /* No. of SDS ring */ regs_buff[i++] = adapter->drv_sds_rings; /* No. of SDS ring */
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]);
regs_buff[i++] = readl(sds_ring->crb_sts_consumer); regs_buff[i++] = readl(sds_ring->crb_sts_consumer);
regs_buff[i++] = sds_ring->consumer; regs_buff[i++] = sds_ring->consumer;
...@@ -664,18 +664,47 @@ qlcnic_set_ringparam(struct net_device *dev, ...@@ -664,18 +664,47 @@ qlcnic_set_ringparam(struct net_device *dev,
return qlcnic_reset_context(adapter); return qlcnic_reset_context(adapter);
} }
static int qlcnic_validate_ring_count(struct qlcnic_adapter *adapter,
u8 rx_ring, u8 tx_ring)
{
if (rx_ring != 0) {
if (rx_ring > adapter->max_sds_rings) {
netdev_err(adapter->netdev, "Invalid ring count, SDS ring count %d should not be greater than max %d driver sds rings.\n",
rx_ring, adapter->max_sds_rings);
return -EINVAL;
}
}
if (tx_ring != 0) {
if (qlcnic_82xx_check(adapter) &&
(tx_ring > adapter->max_tx_rings)) {
netdev_err(adapter->netdev,
"Invalid ring count, Tx ring count %d should not be greater than max %d driver Tx rings.\n",
tx_ring, adapter->max_tx_rings);
return -EINVAL;
}
if (qlcnic_83xx_check(adapter) &&
(tx_ring > QLCNIC_SINGLE_RING)) {
netdev_err(adapter->netdev,
"Invalid ring count, Tx ring count %d should not be greater than %d driver Tx rings.\n",
tx_ring, QLCNIC_SINGLE_RING);
return -EINVAL;
}
}
return 0;
}
static void qlcnic_get_channels(struct net_device *dev, static void qlcnic_get_channels(struct net_device *dev,
struct ethtool_channels *channel) struct ethtool_channels *channel)
{ {
struct qlcnic_adapter *adapter = netdev_priv(dev); struct qlcnic_adapter *adapter = netdev_priv(dev);
int min;
min = min_t(int, adapter->ahw->max_rx_ques, num_online_cpus()); channel->max_rx = adapter->max_sds_rings;
channel->max_rx = rounddown_pow_of_two(min); channel->max_tx = adapter->max_tx_rings;
channel->max_tx = min_t(int, QLCNIC_MAX_TX_RINGS, num_online_cpus()); channel->rx_count = adapter->drv_sds_rings;
channel->tx_count = adapter->drv_tx_rings;
channel->rx_count = adapter->max_sds_rings;
channel->tx_count = adapter->max_drv_tx_rings;
} }
static int qlcnic_set_channels(struct net_device *dev, static int qlcnic_set_channels(struct net_device *dev,
...@@ -683,27 +712,40 @@ static int qlcnic_set_channels(struct net_device *dev, ...@@ -683,27 +712,40 @@ static int qlcnic_set_channels(struct net_device *dev,
{ {
struct qlcnic_adapter *adapter = netdev_priv(dev); struct qlcnic_adapter *adapter = netdev_priv(dev);
int err; int err;
int txq = 0;
if (channel->other_count || channel->combined_count) if (channel->other_count || channel->combined_count)
return -EINVAL; return -EINVAL;
if (channel->rx_count) { err = qlcnic_validate_ring_count(adapter, channel->rx_count,
err = qlcnic_validate_max_rss(adapter, channel->rx_count); channel->tx_count);
if (err) if (err)
return err; return err;
if (channel->rx_count) {
err = qlcnic_validate_rings(adapter, channel->rx_count,
QLCNIC_RX_QUEUE);
if (err) {
netdev_err(dev, "Unable to configure %u SDS rings\n",
channel->rx_count);
return err;
}
} }
if (qlcnic_82xx_check(adapter) && channel->tx_count) { if (qlcnic_82xx_check(adapter) && channel->tx_count) {
err = qlcnic_validate_max_tx_rings(adapter, channel->tx_count); err = qlcnic_validate_rings(adapter, channel->tx_count,
if (err) QLCNIC_TX_QUEUE);
if (err) {
netdev_err(dev, "Unable to configure %u Tx rings\n",
channel->tx_count);
return err; return err;
txq = channel->tx_count;
} }
}
err = qlcnic_setup_rings(adapter, channel->rx_count,
channel->tx_count);
netdev_info(dev, "Allocated %d SDS rings and %d Tx rings\n",
adapter->drv_sds_rings, adapter->drv_tx_rings);
err = qlcnic_set_max_rss(adapter, channel->rx_count, txq);
netdev_info(dev, "allocated 0x%x sds rings and 0x%x tx rings\n",
adapter->max_sds_rings, adapter->max_drv_tx_rings);
return err; return err;
} }
...@@ -905,7 +947,7 @@ static int qlcnic_irq_test(struct net_device *netdev) ...@@ -905,7 +947,7 @@ static int qlcnic_irq_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;
int ret, max_sds_rings = adapter->max_sds_rings; int ret, drv_sds_rings = adapter->drv_sds_rings;
if (qlcnic_83xx_check(adapter)) if (qlcnic_83xx_check(adapter))
return qlcnic_83xx_interrupt_test(netdev); return qlcnic_83xx_interrupt_test(netdev);
...@@ -934,10 +976,10 @@ static int qlcnic_irq_test(struct net_device *netdev) ...@@ -934,10 +976,10 @@ static int qlcnic_irq_test(struct net_device *netdev)
qlcnic_free_mbx_args(&cmd); qlcnic_free_mbx_args(&cmd);
free_diag_res: free_diag_res:
qlcnic_diag_free_res(netdev, max_sds_rings); qlcnic_diag_free_res(netdev, drv_sds_rings);
clear_diag_irq: clear_diag_irq:
adapter->max_sds_rings = max_sds_rings; adapter->drv_sds_rings = drv_sds_rings;
clear_bit(__QLCNIC_RESETTING, &adapter->state); clear_bit(__QLCNIC_RESETTING, &adapter->state);
return ret; return ret;
...@@ -1013,8 +1055,8 @@ int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode) ...@@ -1013,8 +1055,8 @@ int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
int qlcnic_loopback_test(struct net_device *netdev, u8 mode) int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
{ {
struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_adapter *adapter = netdev_priv(netdev);
int max_drv_tx_rings = adapter->max_drv_tx_rings; int drv_tx_rings = adapter->drv_tx_rings;
int max_sds_rings = adapter->max_sds_rings; int drv_sds_rings = adapter->drv_sds_rings;
struct qlcnic_host_sds_ring *sds_ring; struct qlcnic_host_sds_ring *sds_ring;
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
int loop = 0; int loop = 0;
...@@ -1069,11 +1111,11 @@ int qlcnic_loopback_test(struct net_device *netdev, u8 mode) ...@@ -1069,11 +1111,11 @@ int qlcnic_loopback_test(struct net_device *netdev, u8 mode)
qlcnic_clear_lb_mode(adapter, mode); qlcnic_clear_lb_mode(adapter, mode);
free_res: free_res:
qlcnic_diag_free_res(netdev, max_sds_rings); qlcnic_diag_free_res(netdev, drv_sds_rings);
clear_it: clear_it:
adapter->max_sds_rings = max_sds_rings; adapter->drv_sds_rings = drv_sds_rings;
adapter->max_drv_tx_rings = max_drv_tx_rings; adapter->drv_tx_rings = drv_tx_rings;
clear_bit(__QLCNIC_RESETTING, &adapter->state); clear_bit(__QLCNIC_RESETTING, &adapter->state);
return ret; return ret;
} }
...@@ -1127,7 +1169,7 @@ qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 *data) ...@@ -1127,7 +1169,7 @@ qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 *data)
break; break;
case ETH_SS_STATS: case ETH_SS_STATS:
num_stats = ARRAY_SIZE(qlcnic_tx_queue_stats_strings); num_stats = ARRAY_SIZE(qlcnic_tx_queue_stats_strings);
for (i = 0; i < adapter->max_drv_tx_rings; i++) { for (i = 0; i < adapter->drv_tx_rings; i++) {
for (index = 0; index < num_stats; index++) { for (index = 0; index < num_stats; index++) {
sprintf(data, "tx_queue_%d %s", i, sprintf(data, "tx_queue_%d %s", i,
qlcnic_tx_queue_stats_strings[index]); qlcnic_tx_queue_stats_strings[index]);
...@@ -1233,7 +1275,7 @@ static void qlcnic_update_stats(struct qlcnic_adapter *adapter) ...@@ -1233,7 +1275,7 @@ static void qlcnic_update_stats(struct qlcnic_adapter *adapter)
struct qlcnic_host_tx_ring *tx_ring; struct qlcnic_host_tx_ring *tx_ring;
int ring; int ring;
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];
adapter->stats.xmit_on += tx_ring->tx_stats.xmit_on; adapter->stats.xmit_on += tx_ring->tx_stats.xmit_on;
adapter->stats.xmit_off += tx_ring->tx_stats.xmit_off; adapter->stats.xmit_off += tx_ring->tx_stats.xmit_off;
...@@ -1268,10 +1310,10 @@ static void qlcnic_get_ethtool_stats(struct net_device *dev, ...@@ -1268,10 +1310,10 @@ static void qlcnic_get_ethtool_stats(struct net_device *dev,
int index, ret, length, size, tx_size, ring; int index, ret, length, size, tx_size, ring;
char *p; char *p;
tx_size = adapter->max_drv_tx_rings * QLCNIC_TX_STATS_LEN; tx_size = adapter->drv_tx_rings * QLCNIC_TX_STATS_LEN;
memset(data, 0, tx_size * sizeof(u64)); memset(data, 0, tx_size * sizeof(u64));
for (ring = 0, index = 0; ring < adapter->max_drv_tx_rings; ring++) { for (ring = 0, index = 0; ring < adapter->drv_tx_rings; ring++) {
if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
tx_ring = &adapter->tx_ring[ring]; tx_ring = &adapter->tx_ring[ring];
data = qlcnic_fill_tx_queue_stats(data, tx_ring); data = qlcnic_fill_tx_queue_stats(data, tx_ring);
...@@ -1320,7 +1362,7 @@ static int qlcnic_set_led(struct net_device *dev, ...@@ -1320,7 +1362,7 @@ static int qlcnic_set_led(struct net_device *dev,
enum ethtool_phys_id_state state) enum ethtool_phys_id_state state)
{ {
struct qlcnic_adapter *adapter = netdev_priv(dev); struct qlcnic_adapter *adapter = netdev_priv(dev);
int max_sds_rings = adapter->max_sds_rings; int drv_sds_rings = adapter->drv_sds_rings;
int err = -EIO, active = 1; int err = -EIO, active = 1;
if (qlcnic_83xx_check(adapter)) if (qlcnic_83xx_check(adapter))
...@@ -1378,7 +1420,7 @@ static int qlcnic_set_led(struct net_device *dev, ...@@ -1378,7 +1420,7 @@ static int qlcnic_set_led(struct net_device *dev,
} }
if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
qlcnic_diag_free_res(dev, max_sds_rings); qlcnic_diag_free_res(dev, drv_sds_rings);
if (!active || err) if (!active || err)
clear_bit(__QLCNIC_LED_ENABLE, &adapter->state); clear_bit(__QLCNIC_LED_ENABLE, &adapter->state);
......
...@@ -146,6 +146,12 @@ struct qlcnic_mailbox_metadata { ...@@ -146,6 +146,12 @@ struct qlcnic_mailbox_metadata {
#define QLCNIC_MBX_PORT_RSP_OK 0x1a #define QLCNIC_MBX_PORT_RSP_OK 0x1a
#define QLCNIC_MBX_ASYNC_EVENT BIT_15 #define QLCNIC_MBX_ASYNC_EVENT BIT_15
/* Set HW Tx ring limit for 82xx adapter. */
#define QLCNIC_MAX_HW_TX_RINGS 8
#define QLCNIC_MAX_HW_VNIC_TX_RINGS 4
#define QLCNIC_MAX_TX_RINGS 8
#define QLCNIC_MAX_SDS_RINGS 8
struct qlcnic_pci_info; struct qlcnic_pci_info;
struct qlcnic_info; struct qlcnic_info;
struct qlcnic_cmd_args; struct qlcnic_cmd_args;
...@@ -176,7 +182,7 @@ int qlcnic_82xx_set_lb_mode(struct qlcnic_adapter *, u8); ...@@ -176,7 +182,7 @@ int qlcnic_82xx_set_lb_mode(struct qlcnic_adapter *, u8);
void qlcnic_82xx_write_crb(struct qlcnic_adapter *, char *, loff_t, size_t); void qlcnic_82xx_write_crb(struct qlcnic_adapter *, char *, loff_t, size_t);
void qlcnic_82xx_read_crb(struct qlcnic_adapter *, char *, loff_t, size_t); void qlcnic_82xx_read_crb(struct qlcnic_adapter *, char *, loff_t, size_t);
void qlcnic_82xx_dev_request_reset(struct qlcnic_adapter *, u32); void qlcnic_82xx_dev_request_reset(struct qlcnic_adapter *, u32);
int qlcnic_82xx_setup_intr(struct qlcnic_adapter *, u8, int); int qlcnic_82xx_setup_intr(struct qlcnic_adapter *);
irqreturn_t qlcnic_82xx_clear_legacy_intr(struct qlcnic_adapter *); irqreturn_t qlcnic_82xx_clear_legacy_intr(struct qlcnic_adapter *);
int qlcnic_82xx_issue_cmd(struct qlcnic_adapter *adapter, int qlcnic_82xx_issue_cmd(struct qlcnic_adapter *adapter,
struct qlcnic_cmd_args *); struct qlcnic_cmd_args *);
......
...@@ -236,7 +236,7 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) ...@@ -236,7 +236,7 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
spin_lock_init(&rds_ring->lock); spin_lock_init(&rds_ring->lock);
} }
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];
sds_ring->irq = adapter->msix_entries[ring].vector; sds_ring->irq = adapter->msix_entries[ring].vector;
sds_ring->adapter = adapter; sds_ring->adapter = adapter;
......
...@@ -787,6 +787,9 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter, ...@@ -787,6 +787,9 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter,
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct qlcnic_skb_frag *frag; struct qlcnic_skb_frag *frag;
if (!spin_trylock(&adapter->tx_clean_lock))
return 1;
sw_consumer = tx_ring->sw_consumer; sw_consumer = tx_ring->sw_consumer;
hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
...@@ -840,6 +843,7 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter, ...@@ -840,6 +843,7 @@ static int qlcnic_process_cmd_ring(struct qlcnic_adapter *adapter,
*/ */
hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer)); hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
done = (sw_consumer == hw_consumer); done = (sw_consumer == hw_consumer);
spin_unlock(&adapter->tx_clean_lock);
return done; return done;
} }
...@@ -1459,18 +1463,18 @@ int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter, ...@@ -1459,18 +1463,18 @@ int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter,
struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
struct qlcnic_host_tx_ring *tx_ring; struct qlcnic_host_tx_ring *tx_ring;
if (qlcnic_alloc_sds_rings(recv_ctx, adapter->max_sds_rings)) if (qlcnic_alloc_sds_rings(recv_ctx, adapter->drv_sds_rings))
return -ENOMEM; return -ENOMEM;
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 (qlcnic_check_multi_tx(adapter) && if (qlcnic_check_multi_tx(adapter) &&
!adapter->ahw->diag_test && !adapter->ahw->diag_test &&
(adapter->max_drv_tx_rings > 1)) { (adapter->drv_tx_rings > QLCNIC_SINGLE_RING)) {
netif_napi_add(netdev, &sds_ring->napi, qlcnic_rx_poll, netif_napi_add(netdev, &sds_ring->napi, qlcnic_rx_poll,
NAPI_POLL_WEIGHT); NAPI_POLL_WEIGHT);
} else { } else {
if (ring == (adapter->max_sds_rings - 1)) if (ring == (adapter->drv_sds_rings - 1))
netif_napi_add(netdev, &sds_ring->napi, netif_napi_add(netdev, &sds_ring->napi,
qlcnic_poll, qlcnic_poll,
NAPI_POLL_WEIGHT); NAPI_POLL_WEIGHT);
...@@ -1487,7 +1491,7 @@ int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter, ...@@ -1487,7 +1491,7 @@ int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter,
} }
if (qlcnic_check_multi_tx(adapter) && !adapter->ahw->diag_test) { if (qlcnic_check_multi_tx(adapter) && !adapter->ahw->diag_test) {
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];
netif_napi_add(netdev, &tx_ring->napi, qlcnic_tx_poll, netif_napi_add(netdev, &tx_ring->napi, qlcnic_tx_poll,
NAPI_POLL_WEIGHT); NAPI_POLL_WEIGHT);
...@@ -1504,7 +1508,7 @@ void qlcnic_82xx_napi_del(struct qlcnic_adapter *adapter) ...@@ -1504,7 +1508,7 @@ void qlcnic_82xx_napi_del(struct qlcnic_adapter *adapter)
struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
struct qlcnic_host_tx_ring *tx_ring; struct qlcnic_host_tx_ring *tx_ring;
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];
netif_napi_del(&sds_ring->napi); netif_napi_del(&sds_ring->napi);
} }
...@@ -1512,7 +1516,7 @@ void qlcnic_82xx_napi_del(struct qlcnic_adapter *adapter) ...@@ -1512,7 +1516,7 @@ void qlcnic_82xx_napi_del(struct qlcnic_adapter *adapter)
qlcnic_free_sds_rings(adapter->recv_ctx); qlcnic_free_sds_rings(adapter->recv_ctx);
if (qlcnic_check_multi_tx(adapter) && !adapter->ahw->diag_test) { if (qlcnic_check_multi_tx(adapter) && !adapter->ahw->diag_test) {
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];
netif_napi_del(&tx_ring->napi); netif_napi_del(&tx_ring->napi);
} }
...@@ -1531,7 +1535,7 @@ void qlcnic_82xx_napi_enable(struct qlcnic_adapter *adapter) ...@@ -1531,7 +1535,7 @@ void qlcnic_82xx_napi_enable(struct qlcnic_adapter *adapter)
if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
return; return;
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];
napi_enable(&sds_ring->napi); napi_enable(&sds_ring->napi);
qlcnic_enable_int(sds_ring); qlcnic_enable_int(sds_ring);
...@@ -1540,8 +1544,8 @@ void qlcnic_82xx_napi_enable(struct qlcnic_adapter *adapter) ...@@ -1540,8 +1544,8 @@ void qlcnic_82xx_napi_enable(struct qlcnic_adapter *adapter)
if (qlcnic_check_multi_tx(adapter) && if (qlcnic_check_multi_tx(adapter) &&
(adapter->flags & QLCNIC_MSIX_ENABLED) && (adapter->flags & QLCNIC_MSIX_ENABLED) &&
!adapter->ahw->diag_test && !adapter->ahw->diag_test &&
(adapter->max_drv_tx_rings > 1)) { (adapter->drv_tx_rings > QLCNIC_SINGLE_RING)) {
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];
napi_enable(&tx_ring->napi); napi_enable(&tx_ring->napi);
qlcnic_enable_tx_intr(adapter, tx_ring); qlcnic_enable_tx_intr(adapter, tx_ring);
...@@ -1559,7 +1563,7 @@ void qlcnic_82xx_napi_disable(struct qlcnic_adapter *adapter) ...@@ -1559,7 +1563,7 @@ void qlcnic_82xx_napi_disable(struct qlcnic_adapter *adapter)
if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
return; return;
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];
qlcnic_disable_int(sds_ring); qlcnic_disable_int(sds_ring);
napi_synchronize(&sds_ring->napi); napi_synchronize(&sds_ring->napi);
...@@ -1569,7 +1573,7 @@ void qlcnic_82xx_napi_disable(struct qlcnic_adapter *adapter) ...@@ -1569,7 +1573,7 @@ void qlcnic_82xx_napi_disable(struct qlcnic_adapter *adapter)
if ((adapter->flags & QLCNIC_MSIX_ENABLED) && if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
!adapter->ahw->diag_test && !adapter->ahw->diag_test &&
qlcnic_check_multi_tx(adapter)) { qlcnic_check_multi_tx(adapter)) {
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];
qlcnic_disable_tx_int(adapter, tx_ring); qlcnic_disable_tx_int(adapter, tx_ring);
napi_synchronize(&tx_ring->napi); napi_synchronize(&tx_ring->napi);
...@@ -1907,7 +1911,7 @@ void qlcnic_83xx_napi_enable(struct qlcnic_adapter *adapter) ...@@ -1907,7 +1911,7 @@ void qlcnic_83xx_napi_enable(struct qlcnic_adapter *adapter)
if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
return; return;
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];
napi_enable(&sds_ring->napi); napi_enable(&sds_ring->napi);
if (adapter->flags & QLCNIC_MSIX_ENABLED) if (adapter->flags & QLCNIC_MSIX_ENABLED)
...@@ -1916,7 +1920,7 @@ void qlcnic_83xx_napi_enable(struct qlcnic_adapter *adapter) ...@@ -1916,7 +1920,7 @@ void qlcnic_83xx_napi_enable(struct qlcnic_adapter *adapter)
if ((adapter->flags & QLCNIC_MSIX_ENABLED) && if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
!(adapter->flags & QLCNIC_TX_INTR_SHARED)) { !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
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];
napi_enable(&tx_ring->napi); napi_enable(&tx_ring->napi);
qlcnic_83xx_enable_tx_intr(adapter, tx_ring); qlcnic_83xx_enable_tx_intr(adapter, tx_ring);
...@@ -1934,7 +1938,7 @@ void qlcnic_83xx_napi_disable(struct qlcnic_adapter *adapter) ...@@ -1934,7 +1938,7 @@ void qlcnic_83xx_napi_disable(struct qlcnic_adapter *adapter)
if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
return; return;
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 (adapter->flags & QLCNIC_MSIX_ENABLED) if (adapter->flags & QLCNIC_MSIX_ENABLED)
qlcnic_83xx_disable_intr(adapter, sds_ring); qlcnic_83xx_disable_intr(adapter, sds_ring);
...@@ -1944,7 +1948,7 @@ void qlcnic_83xx_napi_disable(struct qlcnic_adapter *adapter) ...@@ -1944,7 +1948,7 @@ void qlcnic_83xx_napi_disable(struct qlcnic_adapter *adapter)
if ((adapter->flags & QLCNIC_MSIX_ENABLED) && if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
!(adapter->flags & QLCNIC_TX_INTR_SHARED)) { !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
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];
qlcnic_83xx_disable_tx_intr(adapter, tx_ring); qlcnic_83xx_disable_tx_intr(adapter, tx_ring);
napi_synchronize(&tx_ring->napi); napi_synchronize(&tx_ring->napi);
...@@ -1961,10 +1965,10 @@ int qlcnic_83xx_napi_add(struct qlcnic_adapter *adapter, ...@@ -1961,10 +1965,10 @@ int qlcnic_83xx_napi_add(struct qlcnic_adapter *adapter,
struct qlcnic_host_tx_ring *tx_ring; struct qlcnic_host_tx_ring *tx_ring;
struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
if (qlcnic_alloc_sds_rings(recv_ctx, adapter->max_sds_rings)) if (qlcnic_alloc_sds_rings(recv_ctx, adapter->drv_sds_rings))
return -ENOMEM; return -ENOMEM;
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 (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))
...@@ -1990,7 +1994,7 @@ int qlcnic_83xx_napi_add(struct qlcnic_adapter *adapter, ...@@ -1990,7 +1994,7 @@ int qlcnic_83xx_napi_add(struct qlcnic_adapter *adapter,
if ((adapter->flags & QLCNIC_MSIX_ENABLED) && if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
!(adapter->flags & QLCNIC_TX_INTR_SHARED)) { !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
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];
netif_napi_add(netdev, &tx_ring->napi, netif_napi_add(netdev, &tx_ring->napi,
qlcnic_83xx_msix_tx_poll, qlcnic_83xx_msix_tx_poll,
...@@ -2008,7 +2012,7 @@ void qlcnic_83xx_napi_del(struct qlcnic_adapter *adapter) ...@@ -2008,7 +2012,7 @@ void qlcnic_83xx_napi_del(struct qlcnic_adapter *adapter)
struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
struct qlcnic_host_tx_ring *tx_ring; struct qlcnic_host_tx_ring *tx_ring;
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];
netif_napi_del(&sds_ring->napi); netif_napi_del(&sds_ring->napi);
} }
...@@ -2017,7 +2021,7 @@ void qlcnic_83xx_napi_del(struct qlcnic_adapter *adapter) ...@@ -2017,7 +2021,7 @@ void qlcnic_83xx_napi_del(struct qlcnic_adapter *adapter)
if ((adapter->flags & QLCNIC_MSIX_ENABLED) && if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
!(adapter->flags & QLCNIC_TX_INTR_SHARED)) { !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
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];
netif_napi_del(&tx_ring->napi); netif_napi_del(&tx_ring->napi);
} }
......
...@@ -548,36 +548,75 @@ static struct qlcnic_hardware_ops qlcnic_hw_ops = { ...@@ -548,36 +548,75 @@ static struct qlcnic_hardware_ops qlcnic_hw_ops = {
.io_resume = qlcnic_82xx_io_resume, .io_resume = qlcnic_82xx_io_resume,
}; };
static void qlcnic_get_multiq_capability(struct qlcnic_adapter *adapter) static int qlcnic_check_multi_tx_capability(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
int num_tx_q;
if (ahw->msix_supported && if (qlcnic_82xx_check(adapter) &&
(ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_2_MULTI_TX)) { (ahw->extra_capability[0] & QLCNIC_FW_CAPABILITY_2_MULTI_TX)) {
num_tx_q = min_t(int, QLCNIC_DEF_NUM_TX_RINGS, test_and_set_bit(__QLCNIC_MULTI_TX_UNIQUE, &adapter->state);
num_online_cpus()); return 0;
if (num_tx_q > 1) {
test_and_set_bit(__QLCNIC_MULTI_TX_UNIQUE,
&adapter->state);
adapter->max_drv_tx_rings = num_tx_q;
}
} else { } else {
adapter->max_drv_tx_rings = 1; return 1;
} }
} }
static int qlcnic_max_rings(struct qlcnic_adapter *adapter, u8 ring_cnt,
int queue_type)
{
int num_rings, max_rings = QLCNIC_MAX_SDS_RINGS;
if (queue_type == QLCNIC_RX_QUEUE)
max_rings = adapter->max_sds_rings;
else if (queue_type == QLCNIC_TX_QUEUE)
max_rings = adapter->max_tx_rings;
num_rings = rounddown_pow_of_two(min_t(int, num_online_cpus(),
max_rings));
if (ring_cnt > num_rings)
return num_rings;
else
return ring_cnt;
}
void qlcnic_set_tx_ring_count(struct qlcnic_adapter *adapter, u8 tx_cnt)
{
/* 83xx adapter does not have max_tx_rings intialized in probe */
if (adapter->max_tx_rings)
adapter->drv_tx_rings = qlcnic_max_rings(adapter, tx_cnt,
QLCNIC_TX_QUEUE);
else
adapter->drv_tx_rings = tx_cnt;
dev_info(&adapter->pdev->dev, "Set %d Tx rings\n",
adapter->drv_tx_rings);
}
void qlcnic_set_sds_ring_count(struct qlcnic_adapter *adapter, u8 rx_cnt)
{
/* 83xx adapter does not have max_sds_rings intialized in probe */
if (adapter->max_sds_rings)
adapter->drv_sds_rings = qlcnic_max_rings(adapter, rx_cnt,
QLCNIC_RX_QUEUE);
else
adapter->drv_sds_rings = rx_cnt;
dev_info(&adapter->pdev->dev, "Set %d SDS rings\n",
adapter->drv_sds_rings);
}
int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
{ {
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
int max_tx_rings, max_sds_rings, tx_vector; int drv_tx_rings, drv_sds_rings, tx_vector;
int err = -1, i; int err = -1, i;
if (adapter->flags & QLCNIC_TX_INTR_SHARED) { if (adapter->flags & QLCNIC_TX_INTR_SHARED) {
max_tx_rings = 0; drv_tx_rings = 0;
tx_vector = 0; tx_vector = 0;
} else { } else {
max_tx_rings = adapter->max_drv_tx_rings; drv_tx_rings = adapter->drv_tx_rings;
tx_vector = 1; tx_vector = 1;
} }
...@@ -589,7 +628,7 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) ...@@ -589,7 +628,7 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
return -ENOMEM; return -ENOMEM;
} }
adapter->max_sds_rings = 1; adapter->drv_sds_rings = QLCNIC_SINGLE_RING;
adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED); adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED);
if (adapter->ahw->msix_supported) { if (adapter->ahw->msix_supported) {
...@@ -602,18 +641,18 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) ...@@ -602,18 +641,18 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
if (qlcnic_83xx_check(adapter)) { if (qlcnic_83xx_check(adapter)) {
adapter->ahw->num_msix = num_msix; adapter->ahw->num_msix = num_msix;
/* subtract mail box and tx ring vectors */ /* subtract mail box and tx ring vectors */
adapter->max_sds_rings = num_msix - adapter->drv_sds_rings = num_msix -
max_tx_rings - 1; drv_tx_rings - 1;
} else { } else {
adapter->ahw->num_msix = num_msix; adapter->ahw->num_msix = num_msix;
if (qlcnic_check_multi_tx(adapter) && if (qlcnic_check_multi_tx(adapter) &&
!adapter->ahw->diag_test && !adapter->ahw->diag_test &&
(adapter->max_drv_tx_rings > 1)) (adapter->drv_tx_rings > 1))
max_sds_rings = num_msix - max_tx_rings; drv_sds_rings = num_msix - drv_tx_rings;
else else
max_sds_rings = num_msix; drv_sds_rings = num_msix;
adapter->max_sds_rings = max_sds_rings; adapter->drv_sds_rings = drv_sds_rings;
} }
dev_info(&pdev->dev, "using msi-x interrupts\n"); dev_info(&pdev->dev, "using msi-x interrupts\n");
return err; return err;
...@@ -624,13 +663,13 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) ...@@ -624,13 +663,13 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
if (qlcnic_83xx_check(adapter)) { if (qlcnic_83xx_check(adapter)) {
if (err < (QLC_83XX_MINIMUM_VECTOR - tx_vector)) if (err < (QLC_83XX_MINIMUM_VECTOR - tx_vector))
return err; return err;
err -= (max_tx_rings + 1); err -= drv_tx_rings + 1;
num_msix = rounddown_pow_of_two(err); num_msix = rounddown_pow_of_two(err);
num_msix += (max_tx_rings + 1); num_msix += drv_tx_rings + 1;
} else { } else {
num_msix = rounddown_pow_of_two(err); num_msix = rounddown_pow_of_two(err);
if (qlcnic_check_multi_tx(adapter)) if (qlcnic_check_multi_tx(adapter))
num_msix += max_tx_rings; num_msix += drv_tx_rings;
} }
if (num_msix) { if (num_msix) {
...@@ -683,25 +722,14 @@ static int qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter) ...@@ -683,25 +722,14 @@ static int qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter)
return err; return err;
} }
int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter, u8 num_intr, int txq) int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw;
int num_msix, err = 0; int num_msix, err = 0;
if (!num_intr) num_msix = adapter->drv_sds_rings;
num_intr = QLCNIC_DEF_NUM_STS_DESC_RINGS;
if (ahw->msix_supported) { if (qlcnic_check_multi_tx(adapter))
num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(), num_msix += adapter->drv_tx_rings;
num_intr));
if (qlcnic_check_multi_tx(adapter)) {
if (txq)
adapter->max_drv_tx_rings = txq;
num_msix += adapter->max_drv_tx_rings;
}
} else {
num_msix = 1;
}
err = qlcnic_enable_msix(adapter, num_msix); err = qlcnic_enable_msix(adapter, num_msix);
if (err == -ENOMEM) if (err == -ENOMEM)
...@@ -1140,14 +1168,18 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter) ...@@ -1140,14 +1168,18 @@ qlcnic_initialize_nic(struct qlcnic_adapter *adapter)
adapter->ahw->max_mac_filters = nic_info.max_mac_filters; adapter->ahw->max_mac_filters = nic_info.max_mac_filters;
adapter->ahw->max_mtu = nic_info.max_mtu; adapter->ahw->max_mtu = nic_info.max_mtu;
/* Disable NPAR for 83XX */ if (adapter->ahw->capabilities & BIT_6) {
if (qlcnic_83xx_check(adapter))
return err;
if (adapter->ahw->capabilities & BIT_6)
adapter->flags |= QLCNIC_ESWITCH_ENABLED; adapter->flags |= QLCNIC_ESWITCH_ENABLED;
else adapter->ahw->nic_mode = QLCNIC_VNIC_MODE;
adapter->max_tx_rings = QLCNIC_MAX_HW_VNIC_TX_RINGS;
adapter->max_sds_rings = QLCNIC_MAX_VNIC_SDS_RINGS;
dev_info(&adapter->pdev->dev, "vNIC mode enabled.\n");
} else {
adapter->ahw->nic_mode = QLCNIC_DEFAULT_MODE;
adapter->max_tx_rings = QLCNIC_MAX_HW_TX_RINGS;
adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
}
return err; return err;
} }
...@@ -1295,6 +1327,8 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) ...@@ -1295,6 +1327,8 @@ qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter)
"HAL Version: %d, Privileged function\n", "HAL Version: %d, Privileged function\n",
adapter->ahw->fw_hal_version); adapter->ahw->fw_hal_version);
} }
} else {
adapter->ahw->nic_mode = QLCNIC_DEFAULT_MODE;
} }
adapter->flags |= QLCNIC_ADAPTER_INITIALIZED; adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
...@@ -1554,7 +1588,7 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter) ...@@ -1554,7 +1588,7 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter)
if (qlcnic_82xx_check(adapter) || if (qlcnic_82xx_check(adapter) ||
(qlcnic_83xx_check(adapter) && (qlcnic_83xx_check(adapter) &&
(adapter->flags & QLCNIC_MSIX_ENABLED))) { (adapter->flags & QLCNIC_MSIX_ENABLED))) {
num_sds_rings = adapter->max_sds_rings; num_sds_rings = adapter->drv_sds_rings;
for (ring = 0; ring < num_sds_rings; ring++) { for (ring = 0; ring < num_sds_rings; ring++) {
sds_ring = &recv_ctx->sds_rings[ring]; sds_ring = &recv_ctx->sds_rings[ring];
if (qlcnic_82xx_check(adapter) && if (qlcnic_82xx_check(adapter) &&
...@@ -1588,7 +1622,7 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter) ...@@ -1588,7 +1622,7 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter)
(adapter->flags & QLCNIC_MSIX_ENABLED) && (adapter->flags & QLCNIC_MSIX_ENABLED) &&
!(adapter->flags & QLCNIC_TX_INTR_SHARED))) { !(adapter->flags & QLCNIC_TX_INTR_SHARED))) {
handler = qlcnic_msix_tx_intr; handler = qlcnic_msix_tx_intr;
for (ring = 0; ring < adapter->max_drv_tx_rings; for (ring = 0; ring < adapter->drv_tx_rings;
ring++) { ring++) {
tx_ring = &adapter->tx_ring[ring]; tx_ring = &adapter->tx_ring[ring];
snprintf(tx_ring->name, sizeof(tx_ring->name), snprintf(tx_ring->name, sizeof(tx_ring->name),
...@@ -1616,7 +1650,7 @@ qlcnic_free_irq(struct qlcnic_adapter *adapter) ...@@ -1616,7 +1650,7 @@ qlcnic_free_irq(struct qlcnic_adapter *adapter)
if (qlcnic_82xx_check(adapter) || if (qlcnic_82xx_check(adapter) ||
(qlcnic_83xx_check(adapter) && (qlcnic_83xx_check(adapter) &&
(adapter->flags & QLCNIC_MSIX_ENABLED))) { (adapter->flags & QLCNIC_MSIX_ENABLED))) {
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];
free_irq(sds_ring->irq, sds_ring); free_irq(sds_ring->irq, sds_ring);
} }
...@@ -1625,7 +1659,7 @@ qlcnic_free_irq(struct qlcnic_adapter *adapter) ...@@ -1625,7 +1659,7 @@ qlcnic_free_irq(struct qlcnic_adapter *adapter)
!(adapter->flags & QLCNIC_TX_INTR_SHARED)) || !(adapter->flags & QLCNIC_TX_INTR_SHARED)) ||
(qlcnic_82xx_check(adapter) && (qlcnic_82xx_check(adapter) &&
qlcnic_check_multi_tx(adapter))) { qlcnic_check_multi_tx(adapter))) {
for (ring = 0; ring < adapter->max_drv_tx_rings; for (ring = 0; ring < adapter->drv_tx_rings;
ring++) { ring++) {
tx_ring = &adapter->tx_ring[ring]; tx_ring = &adapter->tx_ring[ring];
if (tx_ring->irq) if (tx_ring->irq)
...@@ -1679,7 +1713,7 @@ int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) ...@@ -1679,7 +1713,7 @@ int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
adapter->ahw->linkup = 0; adapter->ahw->linkup = 0;
if (adapter->max_sds_rings > 1) if (adapter->drv_sds_rings > 1)
qlcnic_config_rss(adapter, 1); qlcnic_config_rss(adapter, 1);
qlcnic_config_intr_coalesce(adapter); qlcnic_config_intr_coalesce(adapter);
...@@ -1721,6 +1755,7 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) ...@@ -1721,6 +1755,7 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
if (qlcnic_sriov_vf_check(adapter)) if (qlcnic_sriov_vf_check(adapter))
qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc); qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc);
smp_mb(); smp_mb();
spin_lock(&adapter->tx_clean_lock);
netif_carrier_off(netdev); netif_carrier_off(netdev);
adapter->ahw->linkup = 0; adapter->ahw->linkup = 0;
netif_tx_disable(netdev); netif_tx_disable(netdev);
...@@ -1739,8 +1774,9 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) ...@@ -1739,8 +1774,9 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
qlcnic_reset_rx_buffers_list(adapter); qlcnic_reset_rx_buffers_list(adapter);
for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) for (ring = 0; ring < adapter->drv_tx_rings; ring++)
qlcnic_release_tx_buffers(adapter, &adapter->tx_ring[ring]); qlcnic_release_tx_buffers(adapter, &adapter->tx_ring[ring]);
spin_unlock(&adapter->tx_clean_lock);
} }
/* Usage: During suspend and firmware recovery module */ /* Usage: During suspend and firmware recovery module */
...@@ -1816,16 +1852,16 @@ void qlcnic_detach(struct qlcnic_adapter *adapter) ...@@ -1816,16 +1852,16 @@ void qlcnic_detach(struct qlcnic_adapter *adapter)
adapter->is_up = 0; adapter->is_up = 0;
} }
void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings) void qlcnic_diag_free_res(struct net_device *netdev, int 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;
int max_tx_rings = adapter->max_drv_tx_rings; int drv_tx_rings = adapter->drv_tx_rings;
int ring; int ring;
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_disable_int(sds_ring); qlcnic_disable_int(sds_ring);
} }
...@@ -1836,8 +1872,8 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings) ...@@ -1836,8 +1872,8 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings)
qlcnic_detach(adapter); qlcnic_detach(adapter);
adapter->ahw->diag_test = 0; adapter->ahw->diag_test = 0;
adapter->max_sds_rings = max_sds_rings; adapter->drv_sds_rings = drv_sds_rings;
adapter->max_drv_tx_rings = max_tx_rings; adapter->drv_tx_rings = drv_tx_rings;
if (qlcnic_attach(adapter)) if (qlcnic_attach(adapter))
goto out; goto out;
...@@ -1903,10 +1939,10 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test) ...@@ -1903,10 +1939,10 @@ int qlcnic_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->drv_tx_rings = QLCNIC_SINGLE_RING;
adapter->ahw->diag_test = test; adapter->ahw->diag_test = test;
adapter->ahw->linkup = 0; adapter->ahw->linkup = 0;
adapter->max_drv_tx_rings = 1;
ret = qlcnic_attach(adapter); ret = qlcnic_attach(adapter);
if (ret) { if (ret) {
...@@ -1927,7 +1963,7 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test) ...@@ -1927,7 +1963,7 @@ int qlcnic_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_enable_int(sds_ring); qlcnic_enable_int(sds_ring);
} }
...@@ -2100,7 +2136,7 @@ void qlcnic_free_tx_rings(struct qlcnic_adapter *adapter) ...@@ -2100,7 +2136,7 @@ void qlcnic_free_tx_rings(struct qlcnic_adapter *adapter)
int ring; int ring;
struct qlcnic_host_tx_ring *tx_ring; struct qlcnic_host_tx_ring *tx_ring;
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 && tx_ring->cmd_buf_arr != NULL) { if (tx_ring && tx_ring->cmd_buf_arr != NULL) {
vfree(tx_ring->cmd_buf_arr); vfree(tx_ring->cmd_buf_arr);
...@@ -2118,14 +2154,14 @@ int qlcnic_alloc_tx_rings(struct qlcnic_adapter *adapter, ...@@ -2118,14 +2154,14 @@ int qlcnic_alloc_tx_rings(struct qlcnic_adapter *adapter,
struct qlcnic_host_tx_ring *tx_ring; struct qlcnic_host_tx_ring *tx_ring;
struct qlcnic_cmd_buffer *cmd_buf_arr; struct qlcnic_cmd_buffer *cmd_buf_arr;
tx_ring = kcalloc(adapter->max_drv_tx_rings, tx_ring = kcalloc(adapter->drv_tx_rings,
sizeof(struct qlcnic_host_tx_ring), GFP_KERNEL); sizeof(struct qlcnic_host_tx_ring), GFP_KERNEL);
if (tx_ring == NULL) if (tx_ring == NULL)
return -ENOMEM; return -ENOMEM;
adapter->tx_ring = tx_ring; adapter->tx_ring = tx_ring;
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];
tx_ring->num_desc = adapter->num_txd; tx_ring->num_desc = adapter->num_txd;
tx_ring->txq = netdev_get_tx_queue(netdev, ring); tx_ring->txq = netdev_get_tx_queue(netdev, ring);
...@@ -2140,11 +2176,11 @@ int qlcnic_alloc_tx_rings(struct qlcnic_adapter *adapter, ...@@ -2140,11 +2176,11 @@ int qlcnic_alloc_tx_rings(struct qlcnic_adapter *adapter,
if (qlcnic_83xx_check(adapter) || if (qlcnic_83xx_check(adapter) ||
(qlcnic_82xx_check(adapter) && qlcnic_check_multi_tx(adapter))) { (qlcnic_82xx_check(adapter) && qlcnic_check_multi_tx(adapter))) {
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];
tx_ring->adapter = adapter; tx_ring->adapter = adapter;
if (adapter->flags & QLCNIC_MSIX_ENABLED) { if (adapter->flags & QLCNIC_MSIX_ENABLED) {
index = adapter->max_sds_rings + ring; index = adapter->drv_sds_rings + ring;
vector = adapter->msix_entries[index].vector; vector = adapter->msix_entries[index].vector;
tx_ring->irq = vector; tx_ring->irq = vector;
} }
...@@ -2263,6 +2299,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -2263,6 +2299,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
rwlock_init(&adapter->ahw->crb_lock); rwlock_init(&adapter->ahw->crb_lock);
mutex_init(&adapter->ahw->mem_lock); mutex_init(&adapter->ahw->mem_lock);
spin_lock_init(&adapter->tx_clean_lock);
INIT_LIST_HEAD(&adapter->mac_list); INIT_LIST_HEAD(&adapter->mac_list);
qlcnic_register_dcb(adapter); qlcnic_register_dcb(adapter);
...@@ -2277,20 +2314,21 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -2277,20 +2314,21 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_maintenance_mode; goto err_out_maintenance_mode;
} }
qlcnic_get_multiq_capability(adapter); /* compute and set default and max tx/sds rings */
if (adapter->ahw->msix_supported) {
if ((adapter->ahw->act_pci_func > 2) && if (qlcnic_check_multi_tx_capability(adapter) == 1)
qlcnic_check_multi_tx(adapter)) { qlcnic_set_tx_ring_count(adapter,
adapter->max_drv_tx_rings = QLCNIC_DEF_NUM_TX_RINGS; QLCNIC_SINGLE_RING);
dev_info(&adapter->pdev->dev, else
"vNIC mode enabled, Set max TX rings = %d\n", qlcnic_set_tx_ring_count(adapter,
adapter->max_drv_tx_rings); QLCNIC_DEF_TX_RINGS);
qlcnic_set_sds_ring_count(adapter,
QLCNIC_DEF_SDS_RINGS);
} else {
qlcnic_set_tx_ring_count(adapter, QLCNIC_SINGLE_RING);
qlcnic_set_sds_ring_count(adapter, QLCNIC_SINGLE_RING);
} }
if (!qlcnic_check_multi_tx(adapter)) {
clear_bit(__QLCNIC_MULTI_TX_UNIQUE, &adapter->state);
adapter->max_drv_tx_rings = 1;
}
err = qlcnic_setup_idc_param(adapter); err = qlcnic_setup_idc_param(adapter);
if (err) if (err)
goto err_out_free_hw; goto err_out_free_hw;
...@@ -2301,13 +2339,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -2301,13 +2339,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (dcb && qlcnic_dcb_attach(dcb)) if (dcb && qlcnic_dcb_attach(dcb))
qlcnic_clear_dcb_ops(dcb); qlcnic_clear_dcb_ops(dcb);
} else if (qlcnic_83xx_check(adapter)) { } else if (qlcnic_83xx_check(adapter)) {
adapter->max_drv_tx_rings = 1;
qlcnic_83xx_check_vf(adapter, ent); qlcnic_83xx_check_vf(adapter, ent);
adapter->portnum = adapter->ahw->pci_func; adapter->portnum = adapter->ahw->pci_func;
err = qlcnic_83xx_init(adapter, pci_using_dac); err = qlcnic_83xx_init(adapter, pci_using_dac);
if (err) { if (err) {
switch (err) { switch (err) {
case -ENOTRECOVERABLE: case -ENOTRECOVERABLE:
...@@ -2351,7 +2386,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -2351,7 +2386,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
"Device does not support MSI interrupts\n"); "Device does not support MSI interrupts\n");
if (qlcnic_82xx_check(adapter)) { if (qlcnic_82xx_check(adapter)) {
err = qlcnic_setup_intr(adapter, 0, 0); err = qlcnic_setup_intr(adapter);
if (err) { if (err) {
dev_err(&pdev->dev, "Failed to setup interrupt\n"); dev_err(&pdev->dev, "Failed to setup interrupt\n");
goto err_out_disable_msi; goto err_out_disable_msi;
...@@ -2722,7 +2757,7 @@ static void qlcnic_tx_timeout(struct net_device *netdev) ...@@ -2722,7 +2757,7 @@ static void qlcnic_tx_timeout(struct net_device *netdev)
QLCNIC_FORCE_FW_DUMP_KEY); QLCNIC_FORCE_FW_DUMP_KEY);
} else { } else {
netdev_info(netdev, "Tx timeout, reset adapter context.\n"); netdev_info(netdev, "Tx timeout, reset adapter context.\n");
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];
netdev_info(netdev, "Tx ring=%d\n", ring); netdev_info(netdev, "Tx ring=%d\n", ring);
netdev_info(netdev, netdev_info(netdev,
...@@ -2850,7 +2885,7 @@ static void qlcnic_poll_controller(struct net_device *netdev) ...@@ -2850,7 +2885,7 @@ static void qlcnic_poll_controller(struct net_device *netdev)
struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
disable_irq(adapter->irq); disable_irq(adapter->irq);
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];
qlcnic_intr(adapter->irq, sds_ring); qlcnic_intr(adapter->irq, sds_ring);
} }
...@@ -3517,7 +3552,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev) ...@@ -3517,7 +3552,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev)
qlcnic_clr_drv_state(adapter); qlcnic_clr_drv_state(adapter);
kfree(adapter->msix_entries); kfree(adapter->msix_entries);
adapter->msix_entries = NULL; adapter->msix_entries = NULL;
err = qlcnic_setup_intr(adapter, 0, 0); err = qlcnic_setup_intr(adapter);
if (err) { if (err) {
kfree(adapter->msix_entries); kfree(adapter->msix_entries);
...@@ -3662,130 +3697,94 @@ qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) ...@@ -3662,130 +3697,94 @@ qlcnicvf_start_firmware(struct qlcnic_adapter *adapter)
return err; return err;
} }
int qlcnic_validate_max_tx_rings(struct qlcnic_adapter *adapter, u32 txq) int qlcnic_validate_rings(struct qlcnic_adapter *adapter, __u32 ring_cnt,
int queue_type)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
u8 max_hw = QLCNIC_MAX_TX_RINGS; u8 max_hw_rings = 0;
u32 max_allowed; char buf[8];
int cur_rings;
if (queue_type == QLCNIC_RX_QUEUE) {
max_hw_rings = adapter->max_sds_rings;
cur_rings = adapter->drv_sds_rings;
strcpy(buf, "SDS");
} else if (queue_type == QLCNIC_TX_QUEUE) {
if (qlcnic_83xx_check(adapter))
max_hw_rings = QLCNIC_SINGLE_RING;
else
max_hw_rings = adapter->max_tx_rings;
if (!qlcnic_use_msi_x && !qlcnic_use_msi) { cur_rings = adapter->drv_tx_rings;
netdev_err(netdev, "No Multi TX-Q support in INT-x mode\n"); strcpy(buf, "Tx");
return -EINVAL;
} }
if (!qlcnic_check_multi_tx(adapter)) { if (!qlcnic_use_msi_x && !qlcnic_use_msi) {
netdev_err(netdev, "No Multi TX-Q support\n"); netdev_err(netdev, "No RSS/TSS support in INT-x mode\n");
return -EINVAL; return -EINVAL;
} }
if (txq > QLCNIC_MAX_TX_RINGS) { if (adapter->flags & QLCNIC_MSI_ENABLED) {
netdev_err(netdev, "Invalid ring count\n"); netdev_err(netdev, "No RSS/TSS support in MSI mode\n");
return -EINVAL; return -EINVAL;
} }
max_allowed = rounddown_pow_of_two(min_t(int, max_hw, if (ring_cnt < 2) {
num_online_cpus()));
if ((txq > max_allowed) || !is_power_of_2(txq)) {
if (!is_power_of_2(txq))
netdev_err(netdev,
"TX queue should be a power of 2\n");
if (txq > num_online_cpus())
netdev_err(netdev, netdev_err(netdev,
"Tx queue should not be higher than [%u], number of online CPUs in the system\n", "%s rings value should not be lower than 2\n", buf);
num_online_cpus());
netdev_err(netdev, "Unable to configure %u Tx rings\n", txq);
return -EINVAL; return -EINVAL;
} }
return 0; if (!is_power_of_2(ring_cnt)) {
} netdev_err(netdev, "%s rings value should be a power of 2\n",
buf);
int qlcnic_validate_max_rss(struct qlcnic_adapter *adapter,
__u32 val)
{
struct net_device *netdev = adapter->netdev;
u8 max_hw = adapter->ahw->max_rx_ques;
u32 max_allowed;
if (!qlcnic_use_msi_x && !qlcnic_use_msi) {
netdev_err(netdev, "No RSS support in INT-x mode\n");
return -EINVAL; return -EINVAL;
} }
if (val > QLCNIC_MAX_SDS_RINGS) { if (qlcnic_82xx_check(adapter) && (queue_type == QLCNIC_TX_QUEUE) &&
netdev_err(netdev, "RSS value should not be higher than %u\n", !qlcnic_check_multi_tx(adapter)) {
QLCNIC_MAX_SDS_RINGS); netdev_err(netdev, "No Multi Tx queue support\n");
return -EINVAL; return -EINVAL;
} }
max_allowed = rounddown_pow_of_two(min_t(int, max_hw, if (ring_cnt > num_online_cpus()) {
num_online_cpus()));
if ((val > max_allowed) || (val < 2) || !is_power_of_2(val)) {
if (!is_power_of_2(val))
netdev_err(netdev, "RSS value should be a power of 2\n");
if (val < 2)
netdev_err(netdev, "RSS value should not be lower than 2\n");
if (val > max_hw)
netdev_err(netdev, netdev_err(netdev,
"RSS value should not be higher than[%u], the max RSS rings supported by the adapter\n", "%s value[%u] should not be higher than, number of online CPUs\n",
max_hw); buf, num_online_cpus());
if (val > num_online_cpus())
netdev_err(netdev,
"RSS value should not be higher than[%u], number of online CPUs in the system\n",
num_online_cpus());
netdev_err(netdev, "Unable to configure %u RSS rings\n", val);
return -EINVAL; return -EINVAL;
} }
return 0; return 0;
} }
int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data, int txq) int qlcnic_setup_rings(struct qlcnic_adapter *adapter, u8 rx_cnt, u8 tx_cnt)
{ {
int err;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
int num_msix; int err;
if (test_bit(__QLCNIC_RESETTING, &adapter->state)) if (test_bit(__QLCNIC_RESETTING, &adapter->state))
return -EBUSY; return -EBUSY;
if (qlcnic_82xx_check(adapter) && !qlcnic_use_msi_x &&
!qlcnic_use_msi) {
netdev_err(netdev, "No RSS support in INT-x mode\n");
return -EINVAL;
}
netif_device_detach(netdev); netif_device_detach(netdev);
if (netif_running(netdev)) if (netif_running(netdev))
__qlcnic_down(adapter, netdev); __qlcnic_down(adapter, netdev);
qlcnic_detach(adapter); qlcnic_detach(adapter);
if (qlcnic_82xx_check(adapter)) {
if (txq != 0)
adapter->max_drv_tx_rings = txq;
if (qlcnic_check_multi_tx(adapter) &&
(txq > adapter->max_drv_tx_rings))
num_msix = adapter->max_drv_tx_rings;
else
num_msix = data;
}
if (qlcnic_83xx_check(adapter)) { if (qlcnic_83xx_check(adapter)) {
qlcnic_83xx_free_mbx_intr(adapter); qlcnic_83xx_free_mbx_intr(adapter);
qlcnic_83xx_enable_mbx_poll(adapter); qlcnic_83xx_enable_mbx_poll(adapter);
} }
netif_set_real_num_tx_queues(netdev, adapter->max_drv_tx_rings);
qlcnic_teardown_intr(adapter); qlcnic_teardown_intr(adapter);
err = qlcnic_setup_intr(adapter, data, txq); /* compute and set default and max tx/sds rings */
qlcnic_set_tx_ring_count(adapter, tx_cnt);
qlcnic_set_sds_ring_count(adapter, rx_cnt);
netif_set_real_num_tx_queues(netdev, adapter->drv_tx_rings);
err = qlcnic_setup_intr(adapter);
if (err) { if (err) {
kfree(adapter->msix_entries); kfree(adapter->msix_entries);
netdev_err(netdev, "failed to setup interrupt\n"); netdev_err(netdev, "failed to setup interrupt\n");
......
...@@ -508,7 +508,11 @@ static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter, ...@@ -508,7 +508,11 @@ static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter,
dev_warn(&adapter->pdev->dev, dev_warn(&adapter->pdev->dev,
"Device does not support MSI interrupts\n"); "Device does not support MSI interrupts\n");
err = qlcnic_setup_intr(adapter, 1, 0); /* compute and set default and max tx/sds rings */
qlcnic_set_tx_ring_count(adapter, QLCNIC_SINGLE_RING);
qlcnic_set_sds_ring_count(adapter, QLCNIC_SINGLE_RING);
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 err_out_disable_msi; goto err_out_disable_msi;
......
...@@ -156,7 +156,7 @@ static int qlcnic_82xx_store_beacon(struct qlcnic_adapter *adapter, ...@@ -156,7 +156,7 @@ static int qlcnic_82xx_store_beacon(struct qlcnic_adapter *adapter,
const char *buf, size_t len) const char *buf, size_t len)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_hardware_context *ahw = adapter->ahw;
int err, max_sds_rings = adapter->max_sds_rings; int err, drv_sds_rings = adapter->drv_sds_rings;
u16 beacon; u16 beacon;
u8 h_beacon_state, b_state, b_rate; u8 h_beacon_state, b_state, b_rate;
...@@ -211,7 +211,7 @@ static int qlcnic_82xx_store_beacon(struct qlcnic_adapter *adapter, ...@@ -211,7 +211,7 @@ static int qlcnic_82xx_store_beacon(struct qlcnic_adapter *adapter,
} }
if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state))
qlcnic_diag_free_res(adapter->netdev, max_sds_rings); qlcnic_diag_free_res(adapter->netdev, drv_sds_rings);
out: out:
if (!ahw->beacon_state) if (!ahw->beacon_state)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment