Commit d877f1e3 authored by Dhananjay Phadke's avatar Dhananjay Phadke Committed by David S. Miller

netxen: refactor transmit code

o move tx stuff into nx_host_tx_ring structure, this will
  help managing multiple tx rings in future.
o sanitize some variable names
Signed-off-by: default avatarDhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1b1f7898
...@@ -74,10 +74,10 @@ ...@@ -74,10 +74,10 @@
(sizeof(struct netxen_rx_buffer) * rds_ring->num_desc) (sizeof(struct netxen_rx_buffer) * rds_ring->num_desc)
#define STATUS_DESC_RINGSIZE(sds_ring) \ #define STATUS_DESC_RINGSIZE(sds_ring) \
(sizeof(struct status_desc) * (sds_ring)->num_desc) (sizeof(struct status_desc) * (sds_ring)->num_desc)
#define TX_BUFF_RINGSIZE(adapter) \ #define TX_BUFF_RINGSIZE(tx_ring) \
(sizeof(struct netxen_cmd_buffer) * adapter->num_txd) (sizeof(struct netxen_cmd_buffer) * tx_ring->num_desc)
#define TX_DESC_RINGSIZE(adapter) \ #define TX_DESC_RINGSIZE(tx_ring) \
(sizeof(struct cmd_desc_type0) * adapter->num_txd) (sizeof(struct cmd_desc_type0) * tx_ring->num_desc)
#define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a))) #define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
...@@ -639,7 +639,7 @@ extern char netxen_nic_driver_name[]; ...@@ -639,7 +639,7 @@ extern char netxen_nic_driver_name[];
*/ */
struct netxen_skb_frag { struct netxen_skb_frag {
u64 dma; u64 dma;
ulong length; u64 length;
}; };
#define _netxen_set_bits(config_word, start, bits, val) {\ #define _netxen_set_bits(config_word, start, bits, val) {\
...@@ -704,9 +704,6 @@ struct netxen_hardware_context { ...@@ -704,9 +704,6 @@ struct netxen_hardware_context {
u8 linkup; u8 linkup;
u16 port_type; u16 port_type;
u16 board_type; u16 board_type;
/* Address of cmd ring in Phantom */
struct cmd_desc_type0 *cmd_desc_head;
dma_addr_t cmd_desc_phys_addr;
}; };
#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */ #define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */
...@@ -752,14 +749,25 @@ struct nx_host_sds_ring { ...@@ -752,14 +749,25 @@ struct nx_host_sds_ring {
struct napi_struct napi; struct napi_struct napi;
struct list_head free_list[NUM_RCV_DESC_RINGS]; struct list_head free_list[NUM_RCV_DESC_RINGS];
u16 clean_tx;
u16 post_rxd;
int irq; int irq;
dma_addr_t phys_addr; dma_addr_t phys_addr;
char name[IFNAMSIZ+4]; char name[IFNAMSIZ+4];
}; };
struct nx_host_tx_ring {
u32 producer;
__le32 *hw_consumer;
u32 sw_consumer;
u32 crb_cmd_producer;
u32 crb_cmd_consumer;
u32 num_desc;
struct netxen_cmd_buffer *cmd_buf_arr;
struct cmd_desc_type0 *desc_head;
dma_addr_t phys_addr;
};
/* /*
* Receive context. There is one such structure per instance of the * Receive context. There is one such structure per instance of the
* receive processing. Any state information that is relevant to * receive processing. Any state information that is relevant to
...@@ -1152,11 +1160,6 @@ struct netxen_adapter { ...@@ -1152,11 +1160,6 @@ struct netxen_adapter {
rwlock_t adapter_lock; rwlock_t adapter_lock;
spinlock_t tx_clean_lock; spinlock_t tx_clean_lock;
u32 cmd_producer;
u32 last_cmd_consumer;
u32 crb_addr_cmd_producer;
u32 crb_addr_cmd_consumer;
__le32 *cmd_consumer;
u32 num_txd; u32 num_txd;
u32 num_rxd; u32 num_rxd;
...@@ -1191,13 +1194,8 @@ struct netxen_adapter { ...@@ -1191,13 +1194,8 @@ struct netxen_adapter {
struct netxen_adapter_stats stats; struct netxen_adapter_stats stats;
struct netxen_cmd_buffer *cmd_buf_arr; /* Command buffers for xmit */
/*
* Receive instances. These can be either one per port,
* or one per peg, etc.
*/
struct netxen_recv_context recv_ctx; struct netxen_recv_context recv_ctx;
struct nx_host_tx_ring tx_ring;
/* Context interface shared between card and host */ /* Context interface shared between card and host */
struct netxen_ring_ctx *ctx_desc; struct netxen_ring_ctx *ctx_desc;
...@@ -1409,7 +1407,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p); ...@@ -1409,7 +1407,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p);
struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
uint32_t crb_producer); struct nx_host_tx_ring *tx_ring, uint32_t crb_producer);
/* /*
* NetXen Board information * NetXen Board information
......
...@@ -328,6 +328,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) ...@@ -328,6 +328,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
int err = 0; int err = 0;
u64 offset, phys_addr; u64 offset, phys_addr;
dma_addr_t rq_phys_addr, rsp_phys_addr; dma_addr_t rq_phys_addr, rsp_phys_addr;
struct nx_host_tx_ring *tx_ring = &adapter->tx_ring;
rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t); rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
rq_addr = pci_alloc_consistent(adapter->pdev, rq_addr = pci_alloc_consistent(adapter->pdev,
...@@ -367,10 +368,8 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) ...@@ -367,10 +368,8 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
prq_cds = &prq->cds_ring; prq_cds = &prq->cds_ring;
prq_cds->host_phys_addr = prq_cds->host_phys_addr = cpu_to_le64(tx_ring->phys_addr);
cpu_to_le64(adapter->ahw.cmd_desc_phys_addr); prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
prq_cds->ring_size = cpu_to_le32(adapter->num_txd);
phys_addr = rq_phys_addr; phys_addr = rq_phys_addr;
err = netxen_issue_cmd(adapter, err = netxen_issue_cmd(adapter,
...@@ -383,8 +382,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter) ...@@ -383,8 +382,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
if (err == NX_RCODE_SUCCESS) { if (err == NX_RCODE_SUCCESS) {
temp = le32_to_cpu(prsp->cds_ring.host_producer_crb); temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
adapter->crb_addr_cmd_producer = tx_ring->crb_cmd_producer = NETXEN_NIC_REG(temp - 0x200);
NETXEN_NIC_REG(temp - 0x200);
#if 0 #if 0
adapter->tx_state = adapter->tx_state =
le32_to_cpu(prsp->host_ctx_state); le32_to_cpu(prsp->host_ctx_state);
...@@ -497,13 +495,13 @@ netxen_init_old_ctx(struct netxen_adapter *adapter) ...@@ -497,13 +495,13 @@ netxen_init_old_ctx(struct netxen_adapter *adapter)
struct netxen_recv_context *recv_ctx; struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring; struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring; struct nx_host_sds_ring *sds_ring;
struct nx_host_tx_ring *tx_ring;
int ring; int ring;
int func_id = adapter->portnum; int func_id = adapter->portnum;
adapter->ctx_desc->cmd_ring_addr = tx_ring = &adapter->tx_ring;
cpu_to_le64(adapter->ahw.cmd_desc_phys_addr); adapter->ctx_desc->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr);
adapter->ctx_desc->cmd_ring_size = adapter->ctx_desc->cmd_ring_size = cpu_to_le32(tx_ring->num_desc);
cpu_to_le32(adapter->num_txd);
recv_ctx = &adapter->recv_ctx; recv_ctx = &adapter->recv_ctx;
...@@ -535,25 +533,17 @@ static uint32_t sw_int_mask[4] = { ...@@ -535,25 +533,17 @@ static uint32_t sw_int_mask[4] = {
int netxen_alloc_hw_resources(struct netxen_adapter *adapter) int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
{ {
struct netxen_hardware_context *hw = &adapter->ahw;
u32 state = 0;
void *addr; void *addr;
int err = 0; int err = 0;
int ring; int ring;
struct netxen_recv_context *recv_ctx; struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring; struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring; struct nx_host_sds_ring *sds_ring;
struct nx_host_tx_ring *tx_ring = &adapter->tx_ring;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
err = netxen_receive_peg_ready(adapter);
if (err) {
printk(KERN_ERR "Rcv Peg initialization not complete:%x.\n",
state);
return err;
}
addr = pci_alloc_consistent(pdev, addr = pci_alloc_consistent(pdev,
sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), sizeof(struct netxen_ring_ctx) + sizeof(uint32_t),
&adapter->ctx_desc_phys_addr); &adapter->ctx_desc_phys_addr);
...@@ -568,13 +558,12 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) ...@@ -568,13 +558,12 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
adapter->ctx_desc->cmd_consumer_offset = adapter->ctx_desc->cmd_consumer_offset =
cpu_to_le64(adapter->ctx_desc_phys_addr + cpu_to_le64(adapter->ctx_desc_phys_addr +
sizeof(struct netxen_ring_ctx)); sizeof(struct netxen_ring_ctx));
adapter->cmd_consumer = tx_ring->hw_consumer =
(__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx)); (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx));
/* cmd desc ring */ /* cmd desc ring */
addr = pci_alloc_consistent(pdev, addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring),
TX_DESC_RINGSIZE(adapter), &tx_ring->phys_addr);
&hw->cmd_desc_phys_addr);
if (addr == NULL) { if (addr == NULL) {
dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n", dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n",
...@@ -582,7 +571,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) ...@@ -582,7 +571,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
return -ENOMEM; return -ENOMEM;
} }
hw->cmd_desc_head = (struct cmd_desc_type0 *)addr; tx_ring->desc_head = (struct cmd_desc_type0 *)addr;
recv_ctx = &adapter->recv_ctx; recv_ctx = &adapter->recv_ctx;
...@@ -658,6 +647,7 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) ...@@ -658,6 +647,7 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
struct netxen_recv_context *recv_ctx; struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring; struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring; struct nx_host_sds_ring *sds_ring;
struct nx_host_tx_ring *tx_ring;
int ring; int ring;
if (adapter->fw_major >= 4) { if (adapter->fw_major >= 4) {
...@@ -674,13 +664,12 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter) ...@@ -674,13 +664,12 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
adapter->ctx_desc = NULL; adapter->ctx_desc = NULL;
} }
if (adapter->ahw.cmd_desc_head != NULL) { tx_ring = &adapter->tx_ring;
if (tx_ring->desc_head != NULL) {
pci_free_consistent(adapter->pdev, pci_free_consistent(adapter->pdev,
sizeof(struct cmd_desc_type0) * TX_DESC_RINGSIZE(tx_ring),
adapter->num_txd, tx_ring->desc_head, tx_ring->phys_addr);
adapter->ahw.cmd_desc_head, tx_ring->desc_head = NULL;
adapter->ahw.cmd_desc_phys_addr);
adapter->ahw.cmd_desc_head = NULL;
} }
recv_ctx = &adapter->recv_ctx; recv_ctx = &adapter->recv_ctx;
......
...@@ -501,45 +501,44 @@ static int nx_p3_nic_add_mac(struct netxen_adapter *adapter, ...@@ -501,45 +501,44 @@ static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
static int static int
netxen_send_cmd_descs(struct netxen_adapter *adapter, netxen_send_cmd_descs(struct netxen_adapter *adapter,
struct cmd_desc_type0 *cmd_desc_arr, int nr_elements) struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
{ {
uint32_t i, producer; u32 i, producer, consumer;
struct netxen_cmd_buffer *pbuf; struct netxen_cmd_buffer *pbuf;
struct cmd_desc_type0 *cmd_desc; struct cmd_desc_type0 *cmd_desc;
struct nx_host_tx_ring *tx_ring;
if (nr_elements > MAX_PENDING_DESC_BLOCK_SIZE || nr_elements == 0) {
printk(KERN_WARNING "%s: Too many command descriptors in a "
"request\n", __func__);
return -EINVAL;
}
i = 0; i = 0;
tx_ring = &adapter->tx_ring;
netif_tx_lock_bh(adapter->netdev); netif_tx_lock_bh(adapter->netdev);
producer = adapter->cmd_producer; producer = tx_ring->producer;
consumer = tx_ring->sw_consumer;
if (nr_desc > find_diff_among(producer, consumer, tx_ring->num_desc)) {
netif_tx_unlock_bh(adapter->netdev);
return -EBUSY;
}
do { do {
cmd_desc = &cmd_desc_arr[i]; cmd_desc = &cmd_desc_arr[i];
pbuf = &adapter->cmd_buf_arr[producer]; pbuf = &tx_ring->cmd_buf_arr[producer];
pbuf->skb = NULL; pbuf->skb = NULL;
pbuf->frag_count = 0; pbuf->frag_count = 0;
/* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */ memcpy(&tx_ring->desc_head[producer],
memcpy(&adapter->ahw.cmd_desc_head[producer],
&cmd_desc_arr[i], sizeof(struct cmd_desc_type0)); &cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
producer = get_next_index(producer, producer = get_next_index(producer, tx_ring->num_desc);
adapter->num_txd);
i++; i++;
} while (i != nr_elements); } while (i != nr_desc);
adapter->cmd_producer = producer;
/* write producer index to start the xmit */ tx_ring->producer = producer;
netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer); netxen_nic_update_cmd_producer(adapter, tx_ring, producer);
netif_tx_unlock_bh(adapter->netdev); netif_tx_unlock_bh(adapter->netdev);
......
...@@ -173,9 +173,10 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter) ...@@ -173,9 +173,10 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
struct netxen_cmd_buffer *cmd_buf; struct netxen_cmd_buffer *cmd_buf;
struct netxen_skb_frag *buffrag; struct netxen_skb_frag *buffrag;
int i, j; int i, j;
struct nx_host_tx_ring *tx_ring = &adapter->tx_ring;
cmd_buf = adapter->cmd_buf_arr; cmd_buf = tx_ring->cmd_buf_arr;
for (i = 0; i < adapter->num_txd; i++) { for (i = 0; i < tx_ring->num_desc; i++) {
buffrag = cmd_buf->frag_array; buffrag = cmd_buf->frag_array;
if (buffrag->dma) { if (buffrag->dma) {
pci_unmap_single(adapter->pdev, buffrag->dma, pci_unmap_single(adapter->pdev, buffrag->dma,
...@@ -203,6 +204,7 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter) ...@@ -203,6 +204,7 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter)
{ {
struct netxen_recv_context *recv_ctx; struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring; struct nx_host_rds_ring *rds_ring;
struct nx_host_tx_ring *tx_ring;
int ring; int ring;
recv_ctx = &adapter->recv_ctx; recv_ctx = &adapter->recv_ctx;
...@@ -214,8 +216,9 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter) ...@@ -214,8 +216,9 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter)
} }
} }
if (adapter->cmd_buf_arr) tx_ring = &adapter->tx_ring;
vfree(adapter->cmd_buf_arr); if (tx_ring->cmd_buf_arr)
vfree(tx_ring->cmd_buf_arr);
return; return;
} }
...@@ -224,21 +227,24 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) ...@@ -224,21 +227,24 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
struct netxen_recv_context *recv_ctx; struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring; struct nx_host_rds_ring *rds_ring;
struct nx_host_sds_ring *sds_ring; struct nx_host_sds_ring *sds_ring;
struct nx_host_tx_ring *tx_ring = &adapter->tx_ring;
struct netxen_rx_buffer *rx_buf; struct netxen_rx_buffer *rx_buf;
int ring, i, num_rx_bufs; int ring, i, num_rx_bufs;
struct netxen_cmd_buffer *cmd_buf_arr; struct netxen_cmd_buffer *cmd_buf_arr;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
tx_ring->num_desc = adapter->num_txd;
cmd_buf_arr = cmd_buf_arr =
(struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(adapter)); (struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(tx_ring));
if (cmd_buf_arr == NULL) { if (cmd_buf_arr == NULL) {
printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n", dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n",
netdev->name); netdev->name);
return -ENOMEM; return -ENOMEM;
} }
memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(adapter)); memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring));
adapter->cmd_buf_arr = cmd_buf_arr; tx_ring->cmd_buf_arr = cmd_buf_arr;
recv_ctx = &adapter->recv_ctx; recv_ctx = &adapter->recv_ctx;
for (ring = 0; ring < adapter->max_rds_rings; ring++) { for (ring = 0; ring < adapter->max_rds_rings; ring++) {
...@@ -307,8 +313,6 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) ...@@ -307,8 +313,6 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
for (ring = 0; ring < adapter->max_sds_rings; ring++) { for (ring = 0; ring < adapter->max_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->clean_tx = (ring == 0);
sds_ring->post_rxd = (ring == 0);
sds_ring->adapter = adapter; sds_ring->adapter = adapter;
sds_ring->num_desc = adapter->num_rxd; sds_ring->num_desc = adapter->num_rxd;
...@@ -990,23 +994,24 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max) ...@@ -990,23 +994,24 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
/* Process Command status ring */ /* Process Command status ring */
int netxen_process_cmd_ring(struct netxen_adapter *adapter) int netxen_process_cmd_ring(struct netxen_adapter *adapter)
{ {
u32 last_consumer, consumer; u32 sw_consumer, hw_consumer;
int count = 0, i; int count = 0, i;
struct netxen_cmd_buffer *buffer; struct netxen_cmd_buffer *buffer;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct netxen_skb_frag *frag; struct netxen_skb_frag *frag;
int done = 0; int done = 0;
struct nx_host_tx_ring *tx_ring = &adapter->tx_ring;
if (!spin_trylock(&adapter->tx_clean_lock)) if (!spin_trylock(&adapter->tx_clean_lock))
return 1; return 1;
last_consumer = adapter->last_cmd_consumer; sw_consumer = tx_ring->sw_consumer;
barrier(); /* cmd_consumer can change underneath */ barrier(); /* hw_consumer can change underneath */
consumer = le32_to_cpu(*(adapter->cmd_consumer)); hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
while (last_consumer != consumer) { while (sw_consumer != hw_consumer) {
buffer = &adapter->cmd_buf_arr[last_consumer]; buffer = &tx_ring->cmd_buf_arr[sw_consumer];
if (buffer->skb) { if (buffer->skb) {
frag = &buffer->frag_array[0]; frag = &buffer->frag_array[0];
pci_unmap_single(pdev, frag->dma, frag->length, pci_unmap_single(pdev, frag->dma, frag->length,
...@@ -1024,14 +1029,13 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) ...@@ -1024,14 +1029,13 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
buffer->skb = NULL; buffer->skb = NULL;
} }
last_consumer = get_next_index(last_consumer, sw_consumer = get_next_index(sw_consumer, tx_ring->num_desc);
adapter->num_txd);
if (++count >= MAX_STATUS_HANDLE) if (++count >= MAX_STATUS_HANDLE)
break; break;
} }
if (count) { if (count) {
adapter->last_cmd_consumer = last_consumer; tx_ring->sw_consumer = sw_consumer;
smp_mb(); smp_mb();
if (netif_queue_stopped(netdev) && netif_running(netdev)) { if (netif_queue_stopped(netdev) && netif_running(netdev)) {
netif_tx_lock(netdev); netif_tx_lock(netdev);
...@@ -1053,9 +1057,9 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) ...@@ -1053,9 +1057,9 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
* There is still a possible race condition and the host could miss an * There is still a possible race condition and the host could miss an
* interrupt. The card has to take care of this. * interrupt. The card has to take care of this.
*/ */
barrier(); /* cmd_consumer can change underneath */ barrier(); /* hw_consumer can change underneath */
consumer = le32_to_cpu(*(adapter->cmd_consumer)); hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
done = (last_consumer == consumer); done = (sw_consumer == hw_consumer);
spin_unlock(&adapter->tx_clean_lock); spin_unlock(&adapter->tx_clean_lock);
return (done); return (done);
......
...@@ -107,10 +107,10 @@ static uint32_t crb_cmd_producer[4] = { ...@@ -107,10 +107,10 @@ static uint32_t crb_cmd_producer[4] = {
void void
netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
uint32_t crb_producer) struct nx_host_tx_ring *tx_ring, u32 producer)
{ {
adapter->pci_write_normalize(adapter, adapter->pci_write_normalize(adapter,
adapter->crb_addr_cmd_producer, crb_producer); tx_ring->crb_cmd_producer, producer);
} }
static uint32_t crb_cmd_consumer[4] = { static uint32_t crb_cmd_consumer[4] = {
...@@ -120,10 +120,10 @@ static uint32_t crb_cmd_consumer[4] = { ...@@ -120,10 +120,10 @@ static uint32_t crb_cmd_consumer[4] = {
static inline void static inline void
netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
u32 crb_consumer) struct nx_host_tx_ring *tx_ring, u32 consumer)
{ {
adapter->pci_write_normalize(adapter, adapter->pci_write_normalize(adapter,
adapter->crb_addr_cmd_consumer, crb_consumer); tx_ring->crb_cmd_consumer, consumer);
} }
static uint32_t msi_tgt_status[8] = { static uint32_t msi_tgt_status[8] = {
...@@ -814,6 +814,7 @@ netxen_nic_attach(struct netxen_adapter *adapter) ...@@ -814,6 +814,7 @@ netxen_nic_attach(struct netxen_adapter *adapter)
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
int err, ring; int err, ring;
struct nx_host_rds_ring *rds_ring; struct nx_host_rds_ring *rds_ring;
struct nx_host_tx_ring *tx_ring;
err = netxen_init_firmware(adapter); err = netxen_init_firmware(adapter);
if (err != 0) { if (err != 0) {
...@@ -843,13 +844,12 @@ netxen_nic_attach(struct netxen_adapter *adapter) ...@@ -843,13 +844,12 @@ netxen_nic_attach(struct netxen_adapter *adapter)
} }
if (adapter->fw_major < 4) { if (adapter->fw_major < 4) {
adapter->crb_addr_cmd_producer = tx_ring = &adapter->tx_ring;
crb_cmd_producer[adapter->portnum]; tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum];
adapter->crb_addr_cmd_consumer = tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum];
crb_cmd_consumer[adapter->portnum];
netxen_nic_update_cmd_producer(adapter, 0); netxen_nic_update_cmd_producer(adapter, tx_ring, 0);
netxen_nic_update_cmd_consumer(adapter, 0); netxen_nic_update_cmd_consumer(adapter, tx_ring, 0);
} }
for (ring = 0; ring < adapter->max_rds_rings; ring++) { for (ring = 0; ring < adapter->max_rds_rings; ring++) {
...@@ -1304,7 +1304,7 @@ static int ...@@ -1304,7 +1304,7 @@ static int
netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
{ {
struct netxen_adapter *adapter = netdev_priv(netdev); struct netxen_adapter *adapter = netdev_priv(netdev);
struct netxen_hardware_context *hw = &adapter->ahw; struct nx_host_tx_ring *tx_ring = &adapter->tx_ring;
unsigned int first_seg_len = skb->len - skb->data_len; unsigned int first_seg_len = skb->len - skb->data_len;
struct netxen_cmd_buffer *pbuf; struct netxen_cmd_buffer *pbuf;
struct netxen_skb_frag *buffrag; struct netxen_skb_frag *buffrag;
...@@ -1315,28 +1315,26 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -1315,28 +1315,26 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
u32 producer, consumer; u32 producer, consumer;
int frag_count, no_of_desc; int frag_count, no_of_desc;
u32 num_txd = adapter->num_txd; u32 num_txd = tx_ring->num_desc;
bool is_tso = false; bool is_tso = false;
frag_count = skb_shinfo(skb)->nr_frags + 1; frag_count = skb_shinfo(skb)->nr_frags + 1;
/* There 4 fragments per descriptor */ /* 4 fragments per cmd des */
no_of_desc = (frag_count + 3) >> 2; no_of_desc = (frag_count + 3) >> 2;
producer = adapter->cmd_producer; producer = tx_ring->producer;
smp_mb(); smp_mb();
consumer = adapter->last_cmd_consumer; consumer = tx_ring->sw_consumer;
if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) { if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) {
netif_stop_queue(netdev); netif_stop_queue(netdev);
smp_mb(); smp_mb();
return NETDEV_TX_BUSY; return NETDEV_TX_BUSY;
} }
/* Copy the descriptors into the hardware */ hwdesc = &tx_ring->desc_head[producer];
hwdesc = &hw->cmd_desc_head[producer];
netxen_clear_cmddesc((u64 *)hwdesc); netxen_clear_cmddesc((u64 *)hwdesc);
/* Take skb->data itself */ pbuf = &tx_ring->cmd_buf_arr[producer];
pbuf = &adapter->cmd_buf_arr[producer];
is_tso = netxen_tso_check(netdev, hwdesc, skb); is_tso = netxen_tso_check(netdev, hwdesc, skb);
...@@ -1365,9 +1363,9 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -1365,9 +1363,9 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
if ((i & 0x3) == 0) { if ((i & 0x3) == 0) {
k = 0; k = 0;
producer = get_next_index(producer, num_txd); producer = get_next_index(producer, num_txd);
hwdesc = &hw->cmd_desc_head[producer]; hwdesc = &tx_ring->desc_head[producer];
netxen_clear_cmddesc((u64 *)hwdesc); netxen_clear_cmddesc((u64 *)hwdesc);
pbuf = &adapter->cmd_buf_arr[producer]; pbuf = &tx_ring->cmd_buf_arr[producer];
pbuf->skb = NULL; pbuf->skb = NULL;
} }
frag = &skb_shinfo(skb)->frags[i - 1]; frag = &skb_shinfo(skb)->frags[i - 1];
...@@ -1419,8 +1417,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -1419,8 +1417,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
more_hdr = 0; more_hdr = 0;
} }
/* copy the MAC/IP/TCP headers to the cmd descriptor list */ /* copy the MAC/IP/TCP headers to the cmd descriptor list */
hwdesc = &hw->cmd_desc_head[producer]; hwdesc = &tx_ring->desc_head[producer];
pbuf = &adapter->cmd_buf_arr[producer]; pbuf = &tx_ring->cmd_buf_arr[producer];
pbuf->skb = NULL; pbuf->skb = NULL;
/* copy the first 64 bytes */ /* copy the first 64 bytes */
...@@ -1429,8 +1427,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -1429,8 +1427,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
producer = get_next_index(producer, num_txd); producer = get_next_index(producer, num_txd);
if (more_hdr) { if (more_hdr) {
hwdesc = &hw->cmd_desc_head[producer]; hwdesc = &tx_ring->desc_head[producer];
pbuf = &adapter->cmd_buf_arr[producer]; pbuf = &tx_ring->cmd_buf_arr[producer];
pbuf->skb = NULL; pbuf->skb = NULL;
/* copy the next 64 bytes - should be enough except /* copy the next 64 bytes - should be enough except
* for pathological case * for pathological case
...@@ -1443,10 +1441,10 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -1443,10 +1441,10 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
} }
} }
adapter->cmd_producer = producer; tx_ring->producer = producer;
adapter->stats.txbytes += skb->len; adapter->stats.txbytes += skb->len;
netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer); netxen_nic_update_cmd_producer(adapter, tx_ring, producer);
adapter->stats.xmitcalled++; adapter->stats.xmitcalled++;
netdev->trans_start = jiffies; netdev->trans_start = jiffies;
......
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