Skip to content

Commit

Permalink
qlcnic: refactor Tx/SDS ring calculation and validation in driver.
Browse files Browse the repository at this point in the history
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: Himanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Himanshu Madhani authored and David S. Miller committed Nov 4, 2013
1 parent f27c75b commit 34e8c40
Show file tree
Hide file tree
Showing 12 changed files with 404 additions and 311 deletions.
66 changes: 41 additions & 25 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,22 @@
#define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \
+ MGMT_CMD_DESC_RESV)
#define QLCNIC_MAX_TX_TIMEOUTS 2
#define QLCNIC_MAX_TX_RINGS 8
#define QLCNIC_MAX_SDS_RINGS 8

/* 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
Expand Down Expand Up @@ -945,8 +959,6 @@ struct qlcnic_ipaddr {
#define QLCNIC_BEACON_EANBLE 0xC
#define QLCNIC_BEACON_DISABLE 0xD

#define QLCNIC_DEF_NUM_STS_DESC_RINGS 4
#define QLCNIC_DEF_NUM_TX_RINGS 4
#define QLCNIC_MSIX_TBL_SPACE 8192
#define QLCNIC_PCI_REG_MSIX_TBL 0x44
#define QLCNIC_MSIX_TBL_PGSIZE 4096
Expand Down Expand Up @@ -1017,15 +1029,20 @@ struct qlcnic_adapter {
unsigned long state;
u32 flags;

int max_drv_tx_rings;
u16 num_txd;
u16 num_rxd;
u16 num_jumbo_rxd;
u16 max_rxd;
u16 max_jumbo_rxd;

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 portnum;

Expand Down Expand Up @@ -1548,12 +1565,13 @@ int qlcnic_loopback_test(struct net_device *, u8);

/* Functions from qlcnic_main.c */
int qlcnic_reset_context(struct qlcnic_adapter *);
void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings);
int qlcnic_diag_alloc_res(struct net_device *netdev, int test);
netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
int qlcnic_set_max_rss(struct qlcnic_adapter *, u8, int);
int qlcnic_validate_max_rss(struct qlcnic_adapter *, __u32);
int qlcnic_validate_max_tx_rings(struct qlcnic_adapter *, u32 txq);
void qlcnic_diag_free_res(struct net_device *netdev, int);
int qlcnic_diag_alloc_res(struct net_device *netdev, int);
netdev_tx_t qlcnic_xmit_frame(struct sk_buff *, struct net_device *);
void qlcnic_set_tx_ring_count(struct qlcnic_adapter *, u8);
void qlcnic_set_sds_ring_count(struct qlcnic_adapter *, u8);
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_82xx_set_mac_filter_count(struct qlcnic_adapter *);
int qlcnic_enable_msix(struct qlcnic_adapter *, u32);
Expand Down Expand Up @@ -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,
struct net_device *netdev)
{
int err, tx_q;

tx_q = adapter->max_drv_tx_rings;
int err;

netdev->num_tx_queues = tx_q;
netdev->real_num_tx_queues = tx_q;
netdev->num_tx_queues = adapter->drv_tx_rings;
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)
dev_err(&adapter->pdev->dev, "failed to set %d Tx queues\n",
tx_q);
adapter->drv_tx_rings);
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;
}
Expand Down Expand Up @@ -1700,7 +1717,7 @@ struct qlcnic_hardware_ops {
int (*write_reg) (struct qlcnic_adapter *, ulong, u32);
void (*get_ocm_win) (struct qlcnic_hardware_context *);
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 *,
struct qlcnic_adapter *, u32);
int (*mbx_cmd) (struct qlcnic_adapter *, struct qlcnic_cmd_args *);
Expand Down Expand Up @@ -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);
}

static inline int qlcnic_setup_intr(struct qlcnic_adapter *adapter,
u8 num_intr, int txq)
static inline int qlcnic_setup_intr(struct qlcnic_adapter *adapter)
{
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,
Expand Down Expand Up @@ -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)
{
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
Expand Down
69 changes: 34 additions & 35 deletions drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include <linux/interrupt.h>
#include <linux/aer.h>

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

Expand Down Expand Up @@ -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;
struct qlcnic_hardware_context *ahw = adapter->ahw;

if (!num_intr)
num_intr = QLCNIC_DEF_NUM_STS_DESC_RINGS;
num_msix = rounddown_pow_of_two(min_t(int, num_online_cpus(),
num_intr));
num_msix = adapter->drv_sds_rings;

/* account for AEN interrupt MSI-X based interrupts */
num_msix += 1;

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);
if (err == -ENOMEM)
Expand Down Expand Up @@ -986,14 +983,14 @@ static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)

sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
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,
QLCNIC_CMD_ADD_RCV_RINGS);
cmd.req.arg[1] = 0 | (num_sds << 8) | (context_id << 16);

/* set up status rings, mbx 2-81 */
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);
sds = &recv_ctx->sds_rings[i];
sds->consumer = 0;
Expand Down Expand Up @@ -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];
index = 0;
/* 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->crb_sts_consumer = ahw->pci_base0 +
mbx_out->host_csmr[index];
Expand Down Expand Up @@ -1086,10 +1083,10 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
struct qlcnic_hardware_context *ahw = adapter->ahw;
num_rds = adapter->max_rds_rings;

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

sds_mbx_size = sizeof(struct qlcnic_sds_mbx);
rds_mbx_size = sizeof(struct qlcnic_rds_mbx);
Expand Down Expand Up @@ -1190,7 +1187,7 @@ int qlcnic_83xx_create_rx_ctx(struct qlcnic_adapter *adapter)
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);
out:
qlcnic_free_mbx_args(&cmd);
Expand Down Expand Up @@ -1246,9 +1243,9 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
mbx.size = tx->num_desc;
if (adapter->flags & QLCNIC_MSIX_ENABLED) {
if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
msix_vector = adapter->max_sds_rings + ring;
msix_vector = adapter->drv_sds_rings + ring;
else
msix_vector = adapter->max_sds_rings - 1;
msix_vector = adapter->drv_sds_rings - 1;
msix_id = ahw->intr_tbl[msix_vector].id;
} else {
msix_id = QLCRDX(ahw, QLCNIC_DEF_INT_ID);
Expand All @@ -1271,7 +1268,8 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
qlcnic_pf_set_interface_id_create_tx_ctx(adapter, &temp);

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];
memcpy(buf, &mbx, sizeof(struct qlcnic_tx_mbx));
/* send the mailbox command*/
Expand All @@ -1286,7 +1284,7 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
tx->ctx_id = mbx_out->ctx_id;
if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
!(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;
}
dev_info(&adapter->pdev->dev, "Tx Context[0x%x] Created, state:0x%x\n",
Expand All @@ -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,
int num_sds_ring)
u8 num_sds_ring)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_host_sds_ring *sds_ring;
Expand All @@ -1313,7 +1311,7 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,

qlcnic_detach(adapter);

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

Expand All @@ -1327,7 +1325,7 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
if (ret) {
qlcnic_detach(adapter);
if (adapter_state == QLCNIC_ADAPTER_UP_MAGIC) {
adapter->max_sds_rings = num_sds_ring;
adapter->drv_sds_rings = num_sds_ring;
qlcnic_attach(adapter);
}
netif_device_attach(netdev);
Expand All @@ -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) {
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];
qlcnic_83xx_enable_intr(adapter, sds_ring);
}
Expand All @@ -1361,15 +1359,15 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
}

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_host_sds_ring *sds_ring;
int ring, err;

clear_bit(__QLCNIC_DEV_UP, &adapter->state);
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];
qlcnic_83xx_disable_intr(adapter, sds_ring);
if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
Expand All @@ -1393,7 +1391,7 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
}
}
adapter->ahw->diag_test = 0;
adapter->max_sds_rings = max_sds_rings;
adapter->drv_sds_rings = drv_sds_rings;

if (qlcnic_attach(adapter))
goto out;
Expand Down Expand Up @@ -1655,7 +1653,8 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
{
struct qlcnic_adapter *adapter = netdev_priv(netdev);
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) {
netdev_warn(netdev,
Expand All @@ -1677,7 +1676,7 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
mode == QLCNIC_ILB_MODE ? "internal" : "external");

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

Expand Down Expand Up @@ -1715,10 +1714,10 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
qlcnic_83xx_clear_lb_mode(adapter, mode);

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

fail_diag_alloc:
adapter->max_sds_rings = max_sds_rings;
adapter->drv_sds_rings = drv_sds_rings;
qlcnic_release_diag_lock(adapter);
return ret;
}
Expand Down Expand Up @@ -3303,10 +3302,10 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_hardware_context *ahw = adapter->ahw;
struct qlcnic_cmd_args cmd;
u8 val, drv_sds_rings = adapter->drv_sds_rings;
u32 data;
u16 intrpt_id, id;
u8 val;
int ret, max_sds_rings = adapter->max_sds_rings;
int ret;

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

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

Expand Down Expand Up @@ -3356,10 +3355,10 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev)

done:
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:
adapter->max_sds_rings = max_sds_rings;
adapter->drv_sds_rings = drv_sds_rings;
qlcnic_release_diag_lock(adapter);
return ret;
}
Expand Down Expand Up @@ -3513,7 +3512,7 @@ int qlcnic_83xx_resume(struct qlcnic_adapter *adapter)
if (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) {
qlcnic_83xx_set_vnic_opmode(adapter);
} else {
Expand Down
Loading

0 comments on commit 34e8c40

Please sign in to comment.