Commit 4be41e92 authored by Sony Chacko's avatar Sony Chacko Committed by David S. Miller

qlcnic: 83xx data path routines

Add 83xx adapter data path routines
Update few 82xx adapter data path routines
Modify datapath resource allocation routines
Signed-off-by: default avatarAnirban Chakraborty <anirban.chakraborty@qlogic.com>
Signed-off-by: default avatarSucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: default avatarSritej Velaga <sritej.velaga@qlogic.com>
Signed-off-by: default avatarSony Chacko <sony.chacko@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7f966452
...@@ -431,6 +431,7 @@ struct qlcnic_adapter_stats { ...@@ -431,6 +431,7 @@ struct qlcnic_adapter_stats {
u64 rx_dma_map_error; u64 rx_dma_map_error;
u64 tx_dma_map_error; u64 tx_dma_map_error;
u64 spurious_intr; u64 spurious_intr;
u64 mac_filter_limit_overrun;
}; };
/* /*
...@@ -469,6 +470,7 @@ struct qlcnic_host_sds_ring { ...@@ -469,6 +470,7 @@ struct qlcnic_host_sds_ring {
} ____cacheline_internodealigned_in_smp; } ____cacheline_internodealigned_in_smp;
struct qlcnic_host_tx_ring { struct qlcnic_host_tx_ring {
int irq;
void __iomem *crb_intr_mask; void __iomem *crb_intr_mask;
char name[IFNAMSIZ+4]; char name[IFNAMSIZ+4];
u16 ctx_id; u16 ctx_id;
...@@ -477,6 +479,8 @@ struct qlcnic_host_tx_ring { ...@@ -477,6 +479,8 @@ struct qlcnic_host_tx_ring {
u32 num_desc; u32 num_desc;
void __iomem *crb_cmd_producer; void __iomem *crb_cmd_producer;
struct cmd_desc_type0 *desc_head; struct cmd_desc_type0 *desc_head;
struct qlcnic_adapter *adapter;
struct napi_struct napi;
struct qlcnic_cmd_buffer *cmd_buf_arr; struct qlcnic_cmd_buffer *cmd_buf_arr;
__le32 *hw_consumer; __le32 *hw_consumer;
...@@ -1402,7 +1406,7 @@ void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter); ...@@ -1402,7 +1406,7 @@ void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter);
int qlcnic_check_fw_status(struct qlcnic_adapter *adapter); int qlcnic_check_fw_status(struct qlcnic_adapter *adapter);
void qlcnic_watchdog_task(struct work_struct *work); void qlcnic_watchdog_task(struct work_struct *work);
void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter,
struct qlcnic_host_rds_ring *rds_ring); struct qlcnic_host_rds_ring *rds_ring, u8 ring_id);
int qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max); int qlcnic_process_rcv_ring(struct qlcnic_host_sds_ring *sds_ring, int max);
void qlcnic_set_multi(struct net_device *netdev); void qlcnic_set_multi(struct net_device *netdev);
void qlcnic_free_mac_list(struct qlcnic_adapter *adapter); void qlcnic_free_mac_list(struct qlcnic_adapter *adapter);
...@@ -1443,7 +1447,6 @@ int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, u8, u8, u8); ...@@ -1443,7 +1447,6 @@ int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, u8, u8, u8);
int qlcnic_get_mac_stats(struct qlcnic_adapter *, struct qlcnic_mac_statistics *); int qlcnic_get_mac_stats(struct qlcnic_adapter *, struct qlcnic_mac_statistics *);
void qlcnic_free_mbx_args(struct qlcnic_cmd_args *cmd); void qlcnic_free_mbx_args(struct qlcnic_cmd_args *cmd);
void qlcnic_napi_del(struct qlcnic_adapter *);
int qlcnic_alloc_sds_rings(struct qlcnic_recv_context *, int); int qlcnic_alloc_sds_rings(struct qlcnic_recv_context *, int);
void qlcnic_free_sds_rings(struct qlcnic_recv_context *); void qlcnic_free_sds_rings(struct qlcnic_recv_context *);
...@@ -1495,6 +1498,7 @@ struct qlcnic_nic_template { ...@@ -1495,6 +1498,7 @@ struct qlcnic_nic_template {
void (*request_reset) (struct qlcnic_adapter *, u32); void (*request_reset) (struct qlcnic_adapter *, u32);
void (*cancel_idc_work) (struct qlcnic_adapter *); void (*cancel_idc_work) (struct qlcnic_adapter *);
int (*napi_add)(struct qlcnic_adapter *, struct net_device *); int (*napi_add)(struct qlcnic_adapter *, struct net_device *);
void (*napi_del)(struct qlcnic_adapter *);
void (*config_ipaddr)(struct qlcnic_adapter *, __be32, int); void (*config_ipaddr)(struct qlcnic_adapter *, __be32, int);
irqreturn_t (*clear_legacy_intr)(struct qlcnic_adapter *); irqreturn_t (*clear_legacy_intr)(struct qlcnic_adapter *);
}; };
...@@ -1670,6 +1674,11 @@ static inline int qlcnic_napi_add(struct qlcnic_adapter *adapter, ...@@ -1670,6 +1674,11 @@ static inline int qlcnic_napi_add(struct qlcnic_adapter *adapter,
return adapter->nic_ops->napi_add(adapter, netdev); return adapter->nic_ops->napi_add(adapter, netdev);
} }
static inline void qlcnic_napi_del(struct qlcnic_adapter *adapter)
{
adapter->nic_ops->napi_del(adapter);
}
static inline void qlcnic_napi_enable(struct qlcnic_adapter *adapter) static inline void qlcnic_napi_enable(struct qlcnic_adapter *adapter)
{ {
adapter->ahw->hw_ops->napi_enable(adapter); adapter->ahw->hw_ops->napi_enable(adapter);
......
...@@ -242,6 +242,7 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = { ...@@ -242,6 +242,7 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
.get_func_no = qlcnic_83xx_get_func_no, .get_func_no = qlcnic_83xx_get_func_no,
.api_lock = qlcnic_83xx_cam_lock, .api_lock = qlcnic_83xx_cam_lock,
.api_unlock = qlcnic_83xx_cam_unlock, .api_unlock = qlcnic_83xx_cam_unlock,
.process_lb_rcv_ring_diag = qlcnic_83xx_process_rcv_ring_diag,
.create_rx_ctx = qlcnic_83xx_create_rx_ctx, .create_rx_ctx = qlcnic_83xx_create_rx_ctx,
.create_tx_ctx = qlcnic_83xx_create_tx_ctx, .create_tx_ctx = qlcnic_83xx_create_tx_ctx,
.setup_link_event = qlcnic_83xx_setup_link_event, .setup_link_event = qlcnic_83xx_setup_link_event,
...@@ -249,6 +250,8 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = { ...@@ -249,6 +250,8 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
.get_pci_info = qlcnic_83xx_get_pci_info, .get_pci_info = qlcnic_83xx_get_pci_info,
.set_nic_info = qlcnic_83xx_set_nic_info, .set_nic_info = qlcnic_83xx_set_nic_info,
.change_macvlan = qlcnic_83xx_sre_macaddr_change, .change_macvlan = qlcnic_83xx_sre_macaddr_change,
.napi_enable = qlcnic_83xx_napi_enable,
.napi_disable = qlcnic_83xx_napi_disable,
.config_intr_coal = qlcnic_83xx_config_intr_coal, .config_intr_coal = qlcnic_83xx_config_intr_coal,
.config_rss = qlcnic_83xx_config_rss, .config_rss = qlcnic_83xx_config_rss,
.config_hw_lro = qlcnic_83xx_config_hw_lro, .config_hw_lro = qlcnic_83xx_config_hw_lro,
...@@ -262,6 +265,8 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = { ...@@ -262,6 +265,8 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
static struct qlcnic_nic_template qlcnic_83xx_ops = { static struct qlcnic_nic_template qlcnic_83xx_ops = {
.config_bridged_mode = qlcnic_config_bridged_mode, .config_bridged_mode = qlcnic_config_bridged_mode,
.config_led = qlcnic_config_led, .config_led = qlcnic_config_led,
.napi_add = qlcnic_83xx_napi_add,
.napi_del = qlcnic_83xx_napi_del,
.config_ipaddr = qlcnic_83xx_config_ipaddr, .config_ipaddr = qlcnic_83xx_config_ipaddr,
.clear_legacy_intr = qlcnic_83xx_clear_legacy_intr, .clear_legacy_intr = qlcnic_83xx_clear_legacy_intr,
}; };
......
...@@ -193,8 +193,7 @@ void qlcnic_83xx_write_crb(struct qlcnic_adapter *, char *, loff_t, size_t); ...@@ -193,8 +193,7 @@ void qlcnic_83xx_write_crb(struct qlcnic_adapter *, char *, loff_t, size_t);
void qlcnic_83xx_read_crb(struct qlcnic_adapter *, char *, loff_t, size_t); void qlcnic_83xx_read_crb(struct qlcnic_adapter *, char *, loff_t, size_t);
int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *, ulong); int qlcnic_83xx_rd_reg_indirect(struct qlcnic_adapter *, ulong);
int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *, ulong, u32); int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *, ulong, u32);
void qlcnic_83xx_process_rcv_diag(struct qlcnic_adapter *, void qlcnic_83xx_process_rcv_diag(struct qlcnic_adapter *, int, u64 []);
struct qlcnic_host_sds_ring *, int, u64 []);
int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *, u32); int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *, u32);
int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *, u8); int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *, u8);
int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *, u8); int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *, u8);
...@@ -206,6 +205,11 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info *); ...@@ -206,6 +205,11 @@ int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info *);
int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *);
void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *, int); void qlcnic_83xx_register_nic_idc_func(struct qlcnic_adapter *, int);
int qlcnic_83xx_napi_add(struct qlcnic_adapter *, struct net_device *);
void qlcnic_83xx_napi_del(struct qlcnic_adapter *);
void qlcnic_83xx_napi_enable(struct qlcnic_adapter *);
void qlcnic_83xx_napi_disable(struct qlcnic_adapter *);
void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32); void qlcnic_ind_wr(struct qlcnic_adapter *, u32, u32);
int qlcnic_ind_rd(struct qlcnic_adapter *, u32); int qlcnic_ind_rd(struct qlcnic_adapter *, u32);
void qlcnic_83xx_get_stats(struct qlcnic_adapter *, void qlcnic_83xx_get_stats(struct qlcnic_adapter *,
......
...@@ -498,36 +498,42 @@ qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config) ...@@ -498,36 +498,42 @@ qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config)
int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter) int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
{ {
void *addr; void *addr;
int err; int err, ring;
int ring;
struct qlcnic_recv_context *recv_ctx; struct qlcnic_recv_context *recv_ctx;
struct qlcnic_host_rds_ring *rds_ring; struct qlcnic_host_rds_ring *rds_ring;
struct qlcnic_host_sds_ring *sds_ring; struct qlcnic_host_sds_ring *sds_ring;
struct qlcnic_host_tx_ring *tx_ring; struct qlcnic_host_tx_ring *tx_ring;
__le32 *ptr;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
recv_ctx = adapter->recv_ctx; recv_ctx = adapter->recv_ctx;
tx_ring = adapter->tx_ring;
tx_ring->hw_consumer = (__le32 *) dma_alloc_coherent(&pdev->dev, for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
sizeof(u32), &tx_ring->hw_cons_phys_addr, GFP_KERNEL); tx_ring = &adapter->tx_ring[ring];
if (tx_ring->hw_consumer == NULL) { ptr = (__le32 *)dma_alloc_coherent(&pdev->dev, sizeof(u32),
dev_err(&pdev->dev, "failed to allocate tx consumer\n"); &tx_ring->hw_cons_phys_addr,
return -ENOMEM; GFP_KERNEL);
}
/* cmd desc ring */ if (ptr == NULL) {
addr = dma_alloc_coherent(&pdev->dev, TX_DESC_RINGSIZE(tx_ring), dev_err(&pdev->dev, "failed to allocate tx consumer\n");
&tx_ring->phys_addr, GFP_KERNEL); return -ENOMEM;
}
tx_ring->hw_consumer = ptr;
/* cmd desc ring */
addr = dma_alloc_coherent(&pdev->dev, TX_DESC_RINGSIZE(tx_ring),
&tx_ring->phys_addr,
GFP_KERNEL);
if (addr == NULL) { if (addr == NULL) {
dev_err(&pdev->dev, "failed to allocate tx desc ring\n"); dev_err(&pdev->dev,
err = -ENOMEM; "failed to allocate tx desc ring\n");
goto err_out_free; err = -ENOMEM;
} goto err_out_free;
}
tx_ring->desc_head = addr; tx_ring->desc_head = addr;
}
for (ring = 0; ring < adapter->max_rds_rings; ring++) { for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring]; rds_ring = &recv_ctx->rds_rings[ring];
...@@ -624,20 +630,23 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter) ...@@ -624,20 +630,23 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter)
recv_ctx = adapter->recv_ctx; recv_ctx = adapter->recv_ctx;
tx_ring = adapter->tx_ring; for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
if (tx_ring->hw_consumer != NULL) { tx_ring = &adapter->tx_ring[ring];
dma_free_coherent(&adapter->pdev->dev, if (tx_ring->hw_consumer != NULL) {
sizeof(u32), dma_free_coherent(&adapter->pdev->dev, sizeof(u32),
tx_ring->hw_consumer, tx_ring->hw_consumer,
tx_ring->hw_cons_phys_addr); tx_ring->hw_cons_phys_addr);
tx_ring->hw_consumer = NULL;
}
if (tx_ring->desc_head != NULL) { tx_ring->hw_consumer = NULL;
dma_free_coherent(&adapter->pdev->dev, }
TX_DESC_RINGSIZE(tx_ring),
tx_ring->desc_head, tx_ring->phys_addr); if (tx_ring->desc_head != NULL) {
tx_ring->desc_head = NULL; dma_free_coherent(&adapter->pdev->dev,
TX_DESC_RINGSIZE(tx_ring),
tx_ring->desc_head,
tx_ring->phys_addr);
tx_ring->desc_head = NULL;
}
} }
for (ring = 0; ring < adapter->max_rds_rings; ring++) { for (ring = 0; ring < adapter->max_rds_rings; ring++) {
......
...@@ -163,13 +163,12 @@ void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter) ...@@ -163,13 +163,12 @@ void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_recv_context *recv_ctx; struct qlcnic_recv_context *recv_ctx;
struct qlcnic_host_rds_ring *rds_ring; struct qlcnic_host_rds_ring *rds_ring;
struct qlcnic_host_tx_ring *tx_ring;
int ring; int ring;
recv_ctx = adapter->recv_ctx; recv_ctx = adapter->recv_ctx;
if (recv_ctx->rds_rings == NULL) if (recv_ctx->rds_rings == NULL)
goto skip_rds; return;
for (ring = 0; ring < adapter->max_rds_rings; ring++) { for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring]; rds_ring = &recv_ctx->rds_rings[ring];
...@@ -177,16 +176,6 @@ void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter) ...@@ -177,16 +176,6 @@ void qlcnic_free_sw_resources(struct qlcnic_adapter *adapter)
rds_ring->rx_buf_arr = NULL; rds_ring->rx_buf_arr = NULL;
} }
kfree(recv_ctx->rds_rings); kfree(recv_ctx->rds_rings);
skip_rds:
if (adapter->tx_ring == NULL)
return;
tx_ring = adapter->tx_ring;
vfree(tx_ring->cmd_buf_arr);
tx_ring->cmd_buf_arr = NULL;
kfree(adapter->tx_ring);
adapter->tx_ring = NULL;
} }
int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
...@@ -194,31 +183,11 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) ...@@ -194,31 +183,11 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
struct qlcnic_recv_context *recv_ctx; struct qlcnic_recv_context *recv_ctx;
struct qlcnic_host_rds_ring *rds_ring; struct qlcnic_host_rds_ring *rds_ring;
struct qlcnic_host_sds_ring *sds_ring; struct qlcnic_host_sds_ring *sds_ring;
struct qlcnic_host_tx_ring *tx_ring;
struct qlcnic_rx_buffer *rx_buf; struct qlcnic_rx_buffer *rx_buf;
int ring, i, size; int ring, i, size;
struct qlcnic_cmd_buffer *cmd_buf_arr;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
size = sizeof(struct qlcnic_host_tx_ring);
tx_ring = kzalloc(size, GFP_KERNEL);
if (tx_ring == NULL) {
dev_err(&netdev->dev, "failed to allocate tx ring struct\n");
return -ENOMEM;
}
adapter->tx_ring = tx_ring;
tx_ring->num_desc = adapter->num_txd;
tx_ring->txq = netdev_get_tx_queue(netdev, 0);
cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring));
if (cmd_buf_arr == NULL) {
dev_err(&netdev->dev, "failed to allocate cmd buffer ring\n");
goto err_out;
}
tx_ring->cmd_buf_arr = cmd_buf_arr;
recv_ctx = adapter->recv_ctx; recv_ctx = adapter->recv_ctx;
size = adapter->max_rds_rings * sizeof(struct qlcnic_host_rds_ring); size = adapter->max_rds_rings * sizeof(struct qlcnic_host_rds_ring);
...@@ -253,10 +222,11 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) ...@@ -253,10 +222,11 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter)
} }
rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring));
if (rds_ring->rx_buf_arr == NULL) { if (rds_ring->rx_buf_arr == NULL) {
dev_err(&netdev->dev, "Failed to allocate " dev_err(&netdev->dev,
"rx buffer ring %d\n", ring); "Failed to allocate rx buffer ring %d\n", ring);
goto err_out; goto err_out;
} }
INIT_LIST_HEAD(&rds_ring->free_list); INIT_LIST_HEAD(&rds_ring->free_list);
/* /*
* Now go through all of them, set reference handles * Now go through all of them, set reference handles
......
...@@ -303,6 +303,7 @@ static struct qlcnic_nic_template qlcnic_ops = { ...@@ -303,6 +303,7 @@ static struct qlcnic_nic_template qlcnic_ops = {
.request_reset = qlcnic_82xx_dev_request_reset, .request_reset = qlcnic_82xx_dev_request_reset,
.cancel_idc_work = qlcnic_82xx_cancel_idc_work, .cancel_idc_work = qlcnic_82xx_cancel_idc_work,
.napi_add = qlcnic_82xx_napi_add, .napi_add = qlcnic_82xx_napi_add,
.napi_del = qlcnic_82xx_napi_del,
.config_ipaddr = qlcnic_82xx_config_ipaddr, .config_ipaddr = qlcnic_82xx_config_ipaddr,
.clear_legacy_intr = qlcnic_82xx_clear_legacy_intr, .clear_legacy_intr = qlcnic_82xx_clear_legacy_intr,
}; };
...@@ -1201,7 +1202,7 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) ...@@ -1201,7 +1202,7 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
for (ring = 0; ring < adapter->max_rds_rings; ring++) { for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &adapter->recv_ctx->rds_rings[ring]; rds_ring = &adapter->recv_ctx->rds_rings[ring];
qlcnic_post_rx_buffers(adapter, rds_ring); qlcnic_post_rx_buffers(adapter, rds_ring, ring);
} }
qlcnic_set_multi(netdev); qlcnic_set_multi(netdev);
...@@ -1380,21 +1381,11 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings) ...@@ -1380,21 +1381,11 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings)
static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
{ {
int err = 0; int err = 0;
adapter->ahw = kzalloc(sizeof(struct qlcnic_hardware_context),
GFP_KERNEL);
if (!adapter->ahw) {
dev_err(&adapter->pdev->dev,
"Failed to allocate recv ctx resources for adapter\n");
err = -ENOMEM;
goto err_out;
}
adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context),
GFP_KERNEL); GFP_KERNEL);
if (!adapter->recv_ctx) { if (!adapter->recv_ctx) {
dev_err(&adapter->pdev->dev, dev_err(&adapter->pdev->dev,
"Failed to allocate recv ctx resources for adapter\n"); "Failed to allocate recv ctx resources for adapter\n");
kfree(adapter->ahw);
adapter->ahw = NULL;
err = -ENOMEM; err = -ENOMEM;
goto err_out; goto err_out;
} }
...@@ -1402,6 +1393,8 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) ...@@ -1402,6 +1393,8 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT; adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT;
adapter->ahw->coal.rx_time_us = QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US; adapter->ahw->coal.rx_time_us = QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
adapter->ahw->coal.rx_packets = QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS; adapter->ahw->coal.rx_packets = QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
/* clear stats */
memset(&adapter->stats, 0, sizeof(adapter->stats));
err_out: err_out:
return err; return err;
} }
...@@ -1415,8 +1408,8 @@ static void qlcnic_free_adapter_resources(struct qlcnic_adapter *adapter) ...@@ -1415,8 +1408,8 @@ static void qlcnic_free_adapter_resources(struct qlcnic_adapter *adapter)
vfree(adapter->ahw->fw_dump.tmpl_hdr); vfree(adapter->ahw->fw_dump.tmpl_hdr);
adapter->ahw->fw_dump.tmpl_hdr = NULL; adapter->ahw->fw_dump.tmpl_hdr = NULL;
} }
kfree(adapter->ahw);
adapter->ahw = NULL; adapter->ahw->fw_dump.tmpl_hdr = NULL;
} }
int qlcnic_diag_alloc_res(struct net_device *netdev, int test) int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
...@@ -1436,6 +1429,7 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test) ...@@ -1436,6 +1429,7 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
adapter->max_sds_rings = 1; adapter->max_sds_rings = 1;
adapter->ahw->diag_test = test; adapter->ahw->diag_test = test;
adapter->ahw->linkup = 0;
ret = qlcnic_attach(adapter); ret = qlcnic_attach(adapter);
if (ret) { if (ret) {
...@@ -1452,7 +1446,7 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test) ...@@ -1452,7 +1446,7 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
for (ring = 0; ring < adapter->max_rds_rings; ring++) { for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &adapter->recv_ctx->rds_rings[ring]; rds_ring = &adapter->recv_ctx->rds_rings[ring];
qlcnic_post_rx_buffers(adapter, rds_ring); qlcnic_post_rx_buffers(adapter, rds_ring, ring);
} }
if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
...@@ -1601,6 +1595,66 @@ qlcnic_alloc_msix_entries(struct qlcnic_adapter *adapter, u16 count) ...@@ -1601,6 +1595,66 @@ qlcnic_alloc_msix_entries(struct qlcnic_adapter *adapter, u16 count)
return -ENOMEM; return -ENOMEM;
} }
void qlcnic_free_tx_rings(struct qlcnic_adapter *adapter)
{
int ring;
struct qlcnic_host_tx_ring *tx_ring;
for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
tx_ring = &adapter->tx_ring[ring];
if (tx_ring && tx_ring->cmd_buf_arr != NULL) {
vfree(tx_ring->cmd_buf_arr);
tx_ring->cmd_buf_arr = NULL;
}
}
if (adapter->tx_ring != NULL)
kfree(adapter->tx_ring);
}
int qlcnic_alloc_tx_rings(struct qlcnic_adapter *adapter,
struct net_device *netdev)
{
int ring, size, vector, index;
struct qlcnic_host_tx_ring *tx_ring;
struct qlcnic_cmd_buffer *cmd_buf_arr;
size = adapter->max_drv_tx_rings * sizeof(struct qlcnic_host_tx_ring);
tx_ring = kzalloc(size, GFP_KERNEL);
if (tx_ring == NULL) {
dev_err(&netdev->dev, "failed to allocate tx rings\n");
return -ENOMEM;
}
adapter->tx_ring = tx_ring;
for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
tx_ring = &adapter->tx_ring[ring];
tx_ring->num_desc = adapter->num_txd;
tx_ring->txq = netdev_get_tx_queue(netdev, ring);
cmd_buf_arr = vzalloc(TX_BUFF_RINGSIZE(tx_ring));
if (cmd_buf_arr == NULL) {
dev_err(&netdev->dev,
"failed to allocate cmd buffer ring\n");
qlcnic_free_tx_rings(adapter);
return -ENOMEM;
}
memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring));
tx_ring->cmd_buf_arr = cmd_buf_arr;
}
if (qlcnic_83xx_check(adapter)) {
for (ring = 0; ring < adapter->max_drv_tx_rings; ring++) {
tx_ring = &adapter->tx_ring[ring];
tx_ring->adapter = adapter;
if (adapter->flags & QLCNIC_MSIX_ENABLED) {
index = adapter->max_sds_rings + ring;
vector = adapter->msix_entries[index].vector;
tx_ring->irq = vector;
}
}
}
return 0;
}
static int __devinit static int __devinit
qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{ {
......
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