* [patch next 0/6] netxen: bugfixes / enhancements
@ 2009-03-14 0:52 Dhananjay Phadke
2009-03-14 0:52 ` [patch next 1/6] netxen: fix endianness in serial number Dhananjay Phadke
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-03-14 0:52 UTC (permalink / raw)
To: netdev; +Cc: davem
This 6 patch series is for net-next-2.6, containing minor bug
fixes and enhancements / new features.
Please apply, thanks.
-Dhananjay
^ permalink raw reply [flat|nested] 8+ messages in thread
* [patch next 1/6] netxen: fix endianness in serial number
2009-03-14 0:52 [patch next 0/6] netxen: bugfixes / enhancements Dhananjay Phadke
@ 2009-03-14 0:52 ` Dhananjay Phadke
2009-03-14 0:52 ` [patch next 2/6] netxen: add suspend resume support Dhananjay Phadke
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-03-14 0:52 UTC (permalink / raw)
To: netdev; +Cc: davem
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
drivers/net/netxen/netxen_nic_hw.c | 10 ++++------
1 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index a93ab58..8db4ac3 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -2268,7 +2268,7 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
u32 fw_major, fw_minor, fw_build;
char brd_name[NETXEN_MAX_SHORT_NAME];
char serial_num[32];
- int i, addr;
+ int i, addr, val;
int *ptr32;
struct pci_dev *pdev = adapter->pdev;
@@ -2278,14 +2278,12 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
addr = NETXEN_USER_START +
offsetof(struct netxen_new_user_info, serial_num);
for (i = 0; i < 8; i++) {
- if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
- printk("%s: ERROR reading %s board userarea.\n",
- netxen_nic_driver_name,
- netxen_nic_driver_name);
+ if (netxen_rom_fast_read(adapter, addr, &val) == -1) {
+ dev_err(&pdev->dev, "error reading board info\n");
adapter->driver_mismatch = 1;
return;
}
- ptr32++;
+ ptr32[i] = cpu_to_le32(val);
addr += sizeof(u32);
}
--
1.6.0.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [patch next 2/6] netxen: add suspend resume support
2009-03-14 0:52 [patch next 0/6] netxen: bugfixes / enhancements Dhananjay Phadke
2009-03-14 0:52 ` [patch next 1/6] netxen: fix endianness in serial number Dhananjay Phadke
@ 2009-03-14 0:52 ` Dhananjay Phadke
2009-03-14 0:52 ` [patch next 3/6] netxen: sanitize variable names Dhananjay Phadke
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-03-14 0:52 UTC (permalink / raw)
To: netdev; +Cc: davem
Detach network interface on PCI suspend and recreate hardware
context after resumes.
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
drivers/net/netxen/netxen_nic.h | 1 +
drivers/net/netxen/netxen_nic_hw.c | 17 ++++++
drivers/net/netxen/netxen_nic_main.c | 102 ++++++++++++++++++++++++++++------
3 files changed, 102 insertions(+), 18 deletions(-)
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 6185070..75cb30f 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1389,6 +1389,7 @@ void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value);
int netxen_nic_get_board_info(struct netxen_adapter *adapter);
void netxen_nic_get_firmware_info(struct netxen_adapter *adapter);
+int netxen_nic_wol_supported(struct netxen_adapter *adapter);
int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
ulong off, void *data, int len);
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 8db4ac3..c8faa53 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -2320,3 +2320,20 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
}
}
+int
+netxen_nic_wol_supported(struct netxen_adapter *adapter)
+{
+ u32 wol_cfg;
+
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+ return 0;
+
+ wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+ if (wol_cfg & (1UL << adapter->portnum)) {
+ wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+ if (wol_cfg & (1 << adapter->portnum))
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 9445277..555b459 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -643,6 +643,18 @@ netxen_start_firmware(struct netxen_adapter *adapter)
int val, err, first_boot;
struct pci_dev *pdev = adapter->pdev;
+ int first_driver = 0;
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+ if (adapter->ahw.pci_func == 0)
+ first_driver = 1;
+ } else {
+ if (adapter->portnum == 0)
+ first_driver = 1;
+ }
+
+ if (!first_driver)
+ return 0;
+
first_boot = adapter->pci_read_normalize(adapter,
NETXEN_CAM_RAM(0x1fc));
@@ -859,7 +871,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct net_device *netdev = NULL;
struct netxen_adapter *adapter = NULL;
int i = 0, err;
- int first_driver;
int pci_func_id = PCI_FUNC(pdev->devfn);
uint8_t revision_id;
@@ -978,20 +989,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
*/
netxen_check_options(adapter);
- first_driver = 0;
- if (NX_IS_REVISION_P3(revision_id)) {
- if (adapter->ahw.pci_func == 0)
- first_driver = 1;
- } else {
- if (adapter->portnum == 0)
- first_driver = 1;
- }
-
- if (first_driver) {
- err = netxen_start_firmware(adapter);
- if (err)
- goto err_out_iounmap;
- }
+ err = netxen_start_firmware(adapter);
+ if (err)
+ goto err_out_iounmap;
nx_update_dma_mask(adapter);
@@ -1062,8 +1062,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
err_out_disable_msi:
netxen_teardown_intr(adapter);
- if (first_driver)
- netxen_free_adapter_offload(adapter);
+ netxen_free_adapter_offload(adapter);
err_out_iounmap:
netxen_cleanup_pci_map(adapter);
@@ -1114,6 +1113,71 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
free_netdev(netdev);
}
+static int
+netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+
+ struct netxen_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
+
+ netif_device_detach(netdev);
+
+ if (netif_running(netdev))
+ netxen_nic_down(adapter, netdev);
+
+ if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
+ netxen_nic_detach(adapter);
+
+ pci_save_state(pdev);
+
+ if (netxen_nic_wol_supported(adapter)) {
+ pci_enable_wake(pdev, PCI_D3cold, 1);
+ pci_enable_wake(pdev, PCI_D3hot, 1);
+ }
+
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+}
+
+static int
+netxen_nic_resume(struct pci_dev *pdev)
+{
+ struct netxen_adapter *adapter = pci_get_drvdata(pdev);
+ struct net_device *netdev = adapter->netdev;
+ int err;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ err = pci_enable_device(pdev);
+ if (err)
+ return err;
+
+ adapter->curr_window = 255;
+
+ err = netxen_start_firmware(adapter);
+ if (err) {
+ dev_err(&pdev->dev, "failed to start firmware\n");
+ return err;
+ }
+
+ if (netif_running(netdev)) {
+ err = netxen_nic_attach(adapter);
+ if (err)
+ return err;
+
+ err = netxen_nic_up(adapter, netdev);
+ if (err)
+ return err;
+
+ netif_device_attach(netdev);
+ }
+
+ return 0;
+}
+
static int netxen_nic_open(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
@@ -1649,7 +1713,9 @@ static struct pci_driver netxen_driver = {
.name = netxen_nic_driver_name,
.id_table = netxen_pci_tbl,
.probe = netxen_nic_probe,
- .remove = __devexit_p(netxen_nic_remove)
+ .remove = __devexit_p(netxen_nic_remove),
+ .suspend = netxen_nic_suspend,
+ .resume = netxen_nic_resume
};
/* Driver Registration on NetXen card */
--
1.6.0.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [patch next 3/6] netxen: sanitize variable names
2009-03-14 0:52 [patch next 0/6] netxen: bugfixes / enhancements Dhananjay Phadke
2009-03-14 0:52 ` [patch next 1/6] netxen: fix endianness in serial number Dhananjay Phadke
2009-03-14 0:52 ` [patch next 2/6] netxen: add suspend resume support Dhananjay Phadke
@ 2009-03-14 0:52 ` Dhananjay Phadke
2009-03-14 0:52 ` [patch next 4/6] netxen: remove old lro code Dhananjay Phadke
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-03-14 0:52 UTC (permalink / raw)
To: netdev; +Cc: davem
o remove max_ prefix from ring sizes, since they don't really
represent max possible sizes.
o cleanup naming of rx ring types (normal, jumbo, lro).
o simplify logic to choose rx ring size, gig ports get half
rx ring of 10 gig ports.
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
drivers/net/netxen/netxen_nic.h | 47 +++++++-------------
drivers/net/netxen/netxen_nic_ctx.c | 16 +++---
drivers/net/netxen/netxen_nic_ethtool.c | 6 +-
drivers/net/netxen/netxen_nic_hw.c | 2 +-
drivers/net/netxen/netxen_nic_init.c | 54 +++++++++-------------
drivers/net/netxen/netxen_nic_main.c | 73 +++++--------------------------
6 files changed, 62 insertions(+), 136 deletions(-)
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 75cb30f..f00efe8 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -79,15 +79,15 @@
#define PHAN_VENDOR_ID 0x4040
#define RCV_DESC_RINGSIZE \
- (sizeof(struct rcv_desc) * adapter->max_rx_desc_count)
+ (sizeof(struct rcv_desc) * adapter->num_rxd)
#define STATUS_DESC_RINGSIZE \
- (sizeof(struct status_desc)* adapter->max_rx_desc_count)
+ (sizeof(struct status_desc) * adapter->num_rxd)
#define LRO_DESC_RINGSIZE \
- (sizeof(rcvDesc_t) * adapter->max_lro_rx_desc_count)
+ (sizeof(rcvDesc_t) * adapter->num_lro_rxd)
#define TX_RINGSIZE \
- (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count)
+ (sizeof(struct netxen_cmd_buffer) * adapter->num_txd)
#define RCV_BUFFSIZE \
- (sizeof(struct netxen_rx_buffer) * rds_ring->max_rx_desc_count)
+ (sizeof(struct netxen_rx_buffer) * rds_ring->num_desc)
#define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
#define NETXEN_RCV_PRODUCER_OFFSET 0
@@ -190,20 +190,9 @@
#define NUM_RCV_DESC_RINGS 3 /* No of Rcv Descriptor contexts */
-/* descriptor types */
-#define RCV_DESC_NORMAL 0x01
-#define RCV_DESC_JUMBO 0x02
-#define RCV_DESC_LRO 0x04
-#define RCV_DESC_NORMAL_CTXID 0
-#define RCV_DESC_JUMBO_CTXID 1
-#define RCV_DESC_LRO_CTXID 2
-
-#define RCV_DESC_TYPE(ID) \
- ((ID == RCV_DESC_JUMBO_CTXID) \
- ? RCV_DESC_JUMBO \
- : ((ID == RCV_DESC_LRO_CTXID) \
- ? RCV_DESC_LRO : \
- (RCV_DESC_NORMAL)))
+#define RCV_RING_NORMAL 0
+#define RCV_RING_JUMBO 1
+#define RCV_RING_LRO 2
#define MAX_CMD_DESCRIPTORS 4096
#define MAX_RCV_DESCRIPTORS 16384
@@ -815,8 +804,6 @@ struct netxen_hardware_context {
int pci_func;
};
-#define RCV_RING_LRO RCV_DESC_LRO
-
#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* With FCS */
#define ETHERNET_FCS_SIZE 4
@@ -842,16 +829,16 @@ struct netxen_adapter_stats {
* be one Rcv Descriptor for normal packets, one for jumbo and may be others.
*/
struct nx_host_rds_ring {
- u32 flags;
u32 producer;
- dma_addr_t phys_addr;
u32 crb_rcv_producer; /* reg offset */
struct rcv_desc *desc_head; /* address of rx ring in Phantom */
- u32 max_rx_desc_count;
- u32 dma_size;
- u32 skb_size;
struct netxen_rx_buffer *rx_buf_arr; /* rx buffers for receive */
struct list_head free_list;
+ u32 num_desc;
+ u32 dma_size;
+ u32 skb_size;
+ u32 flags;
+ dma_addr_t phys_addr;
};
/*
@@ -1244,10 +1231,10 @@ struct netxen_adapter {
u32 crb_addr_cmd_producer;
u32 crb_addr_cmd_consumer;
- u32 max_tx_desc_count;
- u32 max_rx_desc_count;
- u32 max_jumbo_rx_desc_count;
- u32 max_lro_rx_desc_count;
+ u32 num_txd;
+ u32 num_rxd;
+ u32 num_jumbo_rxd;
+ u32 num_lro_rxd;
int max_rds_rings;
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index d125dca..2e66335 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -231,7 +231,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
rds_ring = &recv_ctx->rds_rings[i];
prq_rds[i].host_phys_addr = cpu_to_le64(rds_ring->phys_addr);
- prq_rds[i].ring_size = cpu_to_le32(rds_ring->max_rx_desc_count);
+ prq_rds[i].ring_size = cpu_to_le32(rds_ring->num_desc);
prq_rds[i].ring_kind = cpu_to_le32(i);
prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size);
}
@@ -241,7 +241,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
prq_sds[0].host_phys_addr =
cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
- prq_sds[0].ring_size = cpu_to_le32(adapter->max_rx_desc_count);
+ prq_sds[0].ring_size = cpu_to_le32(adapter->num_rxd);
/* only one msix vector for now */
prq_sds[0].msi_index = cpu_to_le16(0);
@@ -362,7 +362,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
prq_cds->host_phys_addr =
cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
- prq_cds->ring_size = cpu_to_le32(adapter->max_tx_desc_count);
+ prq_cds->ring_size = cpu_to_le32(adapter->num_txd);
phys_addr = rq_phys_addr;
err = netxen_issue_cmd(adapter,
@@ -494,7 +494,7 @@ netxen_init_old_ctx(struct netxen_adapter *adapter)
adapter->ctx_desc->cmd_ring_addr =
cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
adapter->ctx_desc->cmd_ring_size =
- cpu_to_le32(adapter->max_tx_desc_count);
+ cpu_to_le32(adapter->num_txd);
recv_ctx = &adapter->recv_ctx;
@@ -504,12 +504,12 @@ netxen_init_old_ctx(struct netxen_adapter *adapter)
adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
cpu_to_le64(rds_ring->phys_addr);
adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
- cpu_to_le32(rds_ring->max_rx_desc_count);
+ cpu_to_le32(rds_ring->num_desc);
}
adapter->ctx_desc->sts_ring_addr =
cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
adapter->ctx_desc->sts_ring_size =
- cpu_to_le32(adapter->max_rx_desc_count);
+ cpu_to_le32(adapter->num_rxd);
adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id),
lower32(adapter->ctx_desc_phys_addr));
@@ -562,7 +562,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
/* cmd desc ring */
addr = pci_alloc_consistent(adapter->pdev,
sizeof(struct cmd_desc_type0) *
- adapter->max_tx_desc_count,
+ adapter->num_txd,
&hw->cmd_desc_phys_addr);
if (addr == NULL) {
@@ -669,7 +669,7 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
if (adapter->ahw.cmd_desc_head != NULL) {
pci_free_consistent(adapter->pdev,
sizeof(struct cmd_desc_type0) *
- adapter->max_tx_desc_count,
+ adapter->num_txd,
adapter->ahw.cmd_desc_head,
adapter->ahw.cmd_desc_phys_addr);
adapter->ahw.cmd_desc_head = NULL;
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 8b4bdfd..a677ff8 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -477,10 +477,10 @@ netxen_nic_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring)
ring->rx_pending = 0;
ring->rx_jumbo_pending = 0;
ring->rx_pending += adapter->recv_ctx.
- rds_rings[RCV_DESC_NORMAL_CTXID].max_rx_desc_count;
+ rds_rings[RCV_RING_NORMAL].num_desc;
ring->rx_jumbo_pending += adapter->recv_ctx.
- rds_rings[RCV_DESC_JUMBO_CTXID].max_rx_desc_count;
- ring->tx_pending = adapter->max_tx_desc_count;
+ rds_rings[RCV_RING_JUMBO].num_desc;
+ ring->tx_pending = adapter->num_txd;
if (adapter->ahw.port_type == NETXEN_NIC_GBE)
ring->rx_max_pending = MAX_RCV_DESCRIPTORS_1G;
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index c8faa53..cea7300 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -515,7 +515,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
&cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
producer = get_next_index(producer,
- adapter->max_tx_desc_count);
+ adapter->num_txd);
i++;
} while (i != nr_elements);
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 120b480..d722589 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -153,7 +153,7 @@ void netxen_release_rx_buffers(struct netxen_adapter *adapter)
recv_ctx = &adapter->recv_ctx;
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
- for (i = 0; i < rds_ring->max_rx_desc_count; ++i) {
+ for (i = 0; i < rds_ring->num_desc; ++i) {
rx_buf = &(rds_ring->rx_buf_arr[i]);
if (rx_buf->state == NETXEN_BUFFER_FREE)
continue;
@@ -174,7 +174,7 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
int i, j;
cmd_buf = adapter->cmd_buf_arr;
- for (i = 0; i < adapter->max_tx_desc_count; i++) {
+ for (i = 0; i < adapter->num_txd; i++) {
buffrag = cmd_buf->frag_array;
if (buffrag->dma) {
pci_unmap_single(adapter->pdev, buffrag->dma,
@@ -190,7 +190,6 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
buffrag->dma = 0ULL;
}
}
- /* Free the skb we received in netxen_nic_xmit_frame */
if (cmd_buf->skb) {
dev_kfree_skb_any(cmd_buf->skb);
cmd_buf->skb = NULL;
@@ -241,11 +240,9 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
recv_ctx = &adapter->recv_ctx;
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &recv_ctx->rds_rings[ring];
- switch (RCV_DESC_TYPE(ring)) {
- case RCV_DESC_NORMAL:
- rds_ring->max_rx_desc_count =
- adapter->max_rx_desc_count;
- rds_ring->flags = RCV_DESC_NORMAL;
+ switch (ring) {
+ case RCV_RING_NORMAL:
+ rds_ring->num_desc = adapter->num_rxd;
if (adapter->ahw.cut_through) {
rds_ring->dma_size =
NX_CT_DEFAULT_RX_BUF_LEN;
@@ -258,10 +255,8 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
}
break;
- case RCV_DESC_JUMBO:
- rds_ring->max_rx_desc_count =
- adapter->max_jumbo_rx_desc_count;
- rds_ring->flags = RCV_DESC_JUMBO;
+ case RCV_RING_JUMBO:
+ rds_ring->num_desc = adapter->num_jumbo_rxd;
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
rds_ring->dma_size =
NX_P3_RX_JUMBO_BUF_MAX_LEN;
@@ -273,9 +268,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
break;
case RCV_RING_LRO:
- rds_ring->max_rx_desc_count =
- adapter->max_lro_rx_desc_count;
- rds_ring->flags = RCV_DESC_LRO;
+ rds_ring->num_desc = adapter->num_lro_rxd;
rds_ring->dma_size = RX_LRO_DMA_MAP_LEN;
rds_ring->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
break;
@@ -296,7 +289,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
* Now go through all of them, set reference handles
* and put them in the queues.
*/
- num_rx_bufs = rds_ring->max_rx_desc_count;
+ num_rx_bufs = rds_ring->num_desc;
rx_buf = rds_ring->rx_buf_arr;
for (i = 0; i < num_rx_bufs; i++) {
list_add_tail(&rx_buf->list,
@@ -848,16 +841,15 @@ static void netxen_process_rcv(struct netxen_adapter *adapter,
struct nx_host_rds_ring *rds_ring;
desc_ctx = netxen_get_sts_type(sts_data);
- if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) {
+ if (unlikely(desc_ctx >= adapter->max_rds_rings))
return;
- }
rds_ring = &recv_ctx->rds_rings[desc_ctx];
- if (unlikely(index > rds_ring->max_rx_desc_count)) {
+ if (unlikely(index > rds_ring->num_desc))
return;
- }
+
buffer = &rds_ring->rx_buf_arr[index];
- if (desc_ctx == RCV_DESC_LRO_CTXID) {
+ if (desc_ctx == RCV_RING_LRO) {
buffer->lro_current_frags++;
if (netxen_get_sts_desc_lro_last_frag(desc)) {
buffer->lro_expected_frags =
@@ -875,7 +867,7 @@ static void netxen_process_rcv(struct netxen_adapter *adapter,
if (!skb)
return;
- if (desc_ctx == RCV_DESC_LRO_CTXID) {
+ if (desc_ctx == RCV_RING_LRO) {
/* True length was only available on the last pkt */
skb_put(skb, buffer->lro_length);
} else {
@@ -921,8 +913,7 @@ netxen_process_rcv_ring(struct netxen_adapter *adapter, int max)
desc->status_desc_data = cpu_to_le64(STATUS_OWNER_PHANTOM);
- consumer = get_next_index(consumer,
- adapter->max_rx_desc_count);
+ consumer = get_next_index(consumer, adapter->num_rxd);
count++;
}
@@ -973,7 +964,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
}
last_consumer = get_next_index(last_consumer,
- adapter->max_tx_desc_count);
+ adapter->num_txd);
if (++count >= MAX_STATUS_HANDLE)
break;
}
@@ -1060,7 +1051,7 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid)
pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
- producer = get_next_index(producer, rds_ring->max_rx_desc_count);
+ producer = get_next_index(producer, rds_ring->num_desc);
}
/* if we did allocate buffers, then write the count to Phantom */
if (count) {
@@ -1068,7 +1059,7 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid)
/* Window = 1 */
adapter->pci_write_normalize(adapter,
rds_ring->crb_rcv_producer,
- (producer-1) & (rds_ring->max_rx_desc_count-1));
+ (producer-1) & (rds_ring->num_desc-1));
if (adapter->fw_major < 4) {
/*
@@ -1079,9 +1070,8 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid)
netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID);
netxen_set_msg_privid(msg);
netxen_set_msg_count(msg,
- ((producer -
- 1) & (rds_ring->
- max_rx_desc_count - 1)));
+ ((producer - 1) &
+ (rds_ring->num_desc - 1)));
netxen_set_msg_ctxid(msg, adapter->portnum);
netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
writel(msg,
@@ -1141,7 +1131,7 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ringid)
pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
pdesc->addr_buffer = cpu_to_le64(buffer->dma);
- producer = get_next_index(producer, rds_ring->max_rx_desc_count);
+ producer = get_next_index(producer, rds_ring->num_desc);
}
/* if we did allocate buffers, then write the count to Phantom */
@@ -1150,7 +1140,7 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ringid)
/* Window = 1 */
adapter->pci_write_normalize(adapter,
rds_ring->crb_rcv_producer,
- (producer-1) & (rds_ring->max_rx_desc_count-1));
+ (producer - 1) & (rds_ring->num_desc - 1));
wmb();
}
}
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 555b459..00eaeee 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -212,62 +212,19 @@ nx_update_dma_mask(struct netxen_adapter *adapter)
static void netxen_check_options(struct netxen_adapter *adapter)
{
- switch (adapter->ahw.board_type) {
- case NETXEN_BRDTYPE_P3_HMEZ:
- case NETXEN_BRDTYPE_P3_XG_LOM:
- case NETXEN_BRDTYPE_P3_10G_CX4:
- case NETXEN_BRDTYPE_P3_10G_CX4_LP:
- case NETXEN_BRDTYPE_P3_IMEZ:
- case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
- case NETXEN_BRDTYPE_P3_10G_SFP_QT:
- case NETXEN_BRDTYPE_P3_10G_SFP_CT:
- case NETXEN_BRDTYPE_P3_10G_XFP:
- case NETXEN_BRDTYPE_P3_10000_BASE_T:
- adapter->msix_supported = !!use_msi_x;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
- break;
-
- case NETXEN_BRDTYPE_P2_SB31_10G:
- case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
- case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
- case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
- adapter->msix_supported = 0;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
- break;
+ if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
+ adapter->num_rxd = MAX_RCV_DESCRIPTORS_10G;
+ else if (adapter->ahw.port_type == NETXEN_NIC_GBE)
+ adapter->num_rxd = MAX_RCV_DESCRIPTORS_1G;
- case NETXEN_BRDTYPE_P3_REF_QG:
- case NETXEN_BRDTYPE_P3_4_GB:
- case NETXEN_BRDTYPE_P3_4_GB_MM:
- adapter->msix_supported = !!use_msi_x;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
- break;
-
- case NETXEN_BRDTYPE_P2_SB35_4G:
- case NETXEN_BRDTYPE_P2_SB31_2G:
- adapter->msix_supported = 0;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
- break;
-
- case NETXEN_BRDTYPE_P3_10G_TP:
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
adapter->msix_supported = !!use_msi_x;
- if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
- else
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
- break;
-
- default:
+ else
adapter->msix_supported = 0;
- adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
-
- printk(KERN_WARNING "Unknown board type(0x%x)\n",
- adapter->ahw.board_type);
- break;
- }
- adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST;
- adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS;
- adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS;
+ adapter->num_txd = MAX_CMD_DESCRIPTORS_HOST;
+ adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS;
+ adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS;
adapter->max_possible_rss_rings = 1;
return;
@@ -983,12 +940,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
- /*
- * This call will setup various max rx/tx counts.
- * It must be done before any buffer/ring allocations.
- */
- netxen_check_options(adapter);
-
err = netxen_start_firmware(adapter);
if (err)
goto err_out_iounmap;
@@ -1008,9 +959,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
adapter->physical_port = i;
}
- adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
-
- netxen_set_msix_bit(pdev, 0);
+ netxen_check_options(adapter);
netxen_setup_intr(adapter);
@@ -1307,7 +1256,7 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
u32 producer, consumer;
int frag_count, no_of_desc;
- u32 num_txd = adapter->max_tx_desc_count;
+ u32 num_txd = adapter->num_txd;
bool is_tso = false;
frag_count = skb_shinfo(skb)->nr_frags + 1;
--
1.6.0.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [patch next 4/6] netxen: remove old lro code
2009-03-14 0:52 [patch next 0/6] netxen: bugfixes / enhancements Dhananjay Phadke
` (2 preceding siblings ...)
2009-03-14 0:52 ` [patch next 3/6] netxen: sanitize variable names Dhananjay Phadke
@ 2009-03-14 0:52 ` Dhananjay Phadke
2009-03-14 0:52 ` [patch next 5/6] netxen: add receive side scaling (rss) support Dhananjay Phadke
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-03-14 0:52 UTC (permalink / raw)
To: netdev; +Cc: davem
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
drivers/net/netxen/netxen_nic.h | 3 -
drivers/net/netxen/netxen_nic_init.c | 74 +++++++++++----------------------
2 files changed, 25 insertions(+), 52 deletions(-)
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index f00efe8..56fad22 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -766,9 +766,6 @@ struct netxen_rx_buffer {
u64 dma;
u16 ref_handle;
u16 state;
- u32 lro_expected_frags;
- u32 lro_current_frags;
- u32 lro_length;
};
/* Board types */
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index d722589..1b8f79f 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -820,66 +820,37 @@ static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter,
no_skb:
buffer->state = NETXEN_BUFFER_FREE;
- buffer->lro_current_frags = 0;
- buffer->lro_expected_frags = 0;
list_add_tail(&buffer->list, &rds_ring->free_list);
return skb;
}
-static void netxen_process_rcv(struct netxen_adapter *adapter,
- struct status_desc *desc)
+static void
+netxen_process_rcv(struct netxen_adapter *adapter,
+ int ring, int index, int length, int cksum, int pkt_offset)
{
struct net_device *netdev = adapter->netdev;
- u64 sts_data = le64_to_cpu(desc->status_desc_data);
- int index = netxen_get_sts_refhandle(sts_data);
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
struct netxen_rx_buffer *buffer;
struct sk_buff *skb;
- u32 length = netxen_get_sts_totallength(sts_data);
- u32 desc_ctx;
- u16 pkt_offset = 0, cksum;
- struct nx_host_rds_ring *rds_ring;
+ struct nx_host_rds_ring *rds_ring = &recv_ctx->rds_rings[ring];
- desc_ctx = netxen_get_sts_type(sts_data);
- if (unlikely(desc_ctx >= adapter->max_rds_rings))
- return;
-
- rds_ring = &recv_ctx->rds_rings[desc_ctx];
if (unlikely(index > rds_ring->num_desc))
return;
buffer = &rds_ring->rx_buf_arr[index];
- if (desc_ctx == RCV_RING_LRO) {
- buffer->lro_current_frags++;
- if (netxen_get_sts_desc_lro_last_frag(desc)) {
- buffer->lro_expected_frags =
- netxen_get_sts_desc_lro_cnt(desc);
- buffer->lro_length = length;
- }
- if (buffer->lro_current_frags != buffer->lro_expected_frags) {
- return;
- }
- }
-
- cksum = netxen_get_sts_status(sts_data);
skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum);
if (!skb)
return;
- if (desc_ctx == RCV_RING_LRO) {
- /* True length was only available on the last pkt */
- skb_put(skb, buffer->lro_length);
- } else {
- if (length > rds_ring->skb_size)
- skb_put(skb, rds_ring->skb_size);
- else
- skb_put(skb, length);
+ if (length > rds_ring->skb_size)
+ skb_put(skb, rds_ring->skb_size);
+ else
+ skb_put(skb, length);
- pkt_offset = netxen_get_sts_pkt_offset(sts_data);
- if (pkt_offset)
- skb_pull(skb, pkt_offset);
- }
+
+ if (pkt_offset)
+ skb_pull(skb, pkt_offset);
skb->protocol = eth_type_trans(skb, netdev);
@@ -896,9 +867,9 @@ netxen_process_rcv_ring(struct netxen_adapter *adapter, int max)
struct status_desc *desc_head = recv_ctx->rcv_status_desc_head;
struct status_desc *desc;
u32 consumer = recv_ctx->status_rx_consumer;
- int count = 0, ring;
+ int count = 0;
u64 sts_data;
- u16 opcode;
+ int opcode, ring, index, length, cksum, pkt_offset;
while (count < max) {
desc = &desc_head[consumer];
@@ -907,9 +878,19 @@ netxen_process_rcv_ring(struct netxen_adapter *adapter, int max)
if (!(sts_data & STATUS_OWNER_HOST))
break;
+ ring = netxen_get_sts_type(sts_data);
+ if (ring > RCV_RING_JUMBO)
+ continue;
+
opcode = netxen_get_sts_opcode(sts_data);
- netxen_process_rcv(adapter, desc);
+ index = netxen_get_sts_refhandle(sts_data);
+ length = netxen_get_sts_totallength(sts_data);
+ cksum = netxen_get_sts_status(sts_data);
+ pkt_offset = netxen_get_sts_pkt_offset(sts_data);
+
+ netxen_process_rcv(adapter, ring, index,
+ length, cksum, pkt_offset);
desc->status_desc_data = cpu_to_le64(STATUS_OWNER_PHANTOM);
@@ -1019,7 +1000,6 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid)
producer = rds_ring->producer;
head = &rds_ring->free_list;
- /* We can start writing rx descriptors into the phantom memory. */
while (!list_empty(head)) {
skb = dev_alloc_skb(rds_ring->skb_size);
@@ -1053,10 +1033,9 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid)
producer = get_next_index(producer, rds_ring->num_desc);
}
- /* if we did allocate buffers, then write the count to Phantom */
+
if (count) {
rds_ring->producer = producer;
- /* Window = 1 */
adapter->pci_write_normalize(adapter,
rds_ring->crb_rcv_producer,
(producer-1) & (rds_ring->num_desc-1));
@@ -1099,7 +1078,6 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ringid)
producer = rds_ring->producer;
head = &rds_ring->free_list;
- /* We can start writing rx descriptors into the phantom memory. */
while (!list_empty(head)) {
skb = dev_alloc_skb(rds_ring->skb_size);
@@ -1134,10 +1112,8 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ringid)
producer = get_next_index(producer, rds_ring->num_desc);
}
- /* if we did allocate buffers, then write the count to Phantom */
if (count) {
rds_ring->producer = producer;
- /* Window = 1 */
adapter->pci_write_normalize(adapter,
rds_ring->crb_rcv_producer,
(producer - 1) & (rds_ring->num_desc - 1));
--
1.6.0.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [patch next 5/6] netxen: add receive side scaling (rss) support
2009-03-14 0:52 [patch next 0/6] netxen: bugfixes / enhancements Dhananjay Phadke
` (3 preceding siblings ...)
2009-03-14 0:52 ` [patch next 4/6] netxen: remove old lro code Dhananjay Phadke
@ 2009-03-14 0:52 ` Dhananjay Phadke
2009-03-14 0:52 ` [patch next 6/6] netxen: update version to 4.0.30 Dhananjay Phadke
2009-03-14 21:06 ` [patch next 0/6] netxen: bugfixes / enhancements David Miller
6 siblings, 0 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-03-14 0:52 UTC (permalink / raw)
To: netdev; +Cc: davem
This patch enables the load balancing capability of firmware
and hardware to spray traffic into different cpus through
separate rx msix interrupts.
The feature is being enabled for NX3031, NX2031 (old) will be
enabled later. This depends on msi-x and compatibility with
msi and legacy is maintained by enabling single rx ring.
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
drivers/net/netxen/netxen_nic.h | 74 ++++++++-----
drivers/net/netxen/netxen_nic_ctx.c | 117 ++++++++++++--------
drivers/net/netxen/netxen_nic_hw.c | 47 ++++++++
drivers/net/netxen/netxen_nic_init.c | 201 +++++++++++++++++++++-------------
drivers/net/netxen/netxen_nic_main.c | 157 ++++++++++++++++++++-------
5 files changed, 404 insertions(+), 192 deletions(-)
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 56fad22..595171d 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -78,16 +78,17 @@
#define PHAN_VENDOR_ID 0x4040
-#define RCV_DESC_RINGSIZE \
- (sizeof(struct rcv_desc) * adapter->num_rxd)
-#define STATUS_DESC_RINGSIZE \
- (sizeof(struct status_desc) * adapter->num_rxd)
-#define LRO_DESC_RINGSIZE \
- (sizeof(rcvDesc_t) * adapter->num_lro_rxd)
-#define TX_RINGSIZE \
- (sizeof(struct netxen_cmd_buffer) * adapter->num_txd)
-#define RCV_BUFFSIZE \
+#define RCV_DESC_RINGSIZE(rds_ring) \
+ (sizeof(struct rcv_desc) * (rds_ring)->num_desc)
+#define RCV_BUFF_RINGSIZE(rds_ring) \
(sizeof(struct netxen_rx_buffer) * rds_ring->num_desc)
+#define STATUS_DESC_RINGSIZE(sds_ring) \
+ (sizeof(struct status_desc) * (sds_ring)->num_desc)
+#define TX_BUFF_RINGSIZE(adapter) \
+ (sizeof(struct netxen_cmd_buffer) * adapter->num_txd)
+#define TX_DESC_RINGSIZE(adapter) \
+ (sizeof(struct cmd_desc_type0) * adapter->num_txd)
+
#define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
#define NETXEN_RCV_PRODUCER_OFFSET 0
@@ -188,7 +189,8 @@
/* Host writes the following to notify that it has done the init-handshake */
#define PHAN_INITIALIZE_ACK 0xf00f
-#define NUM_RCV_DESC_RINGS 3 /* No of Rcv Descriptor contexts */
+#define NUM_RCV_DESC_RINGS 3
+#define NUM_STS_DESC_RINGS 4
#define RCV_RING_NORMAL 0
#define RCV_RING_JUMBO 1
@@ -722,7 +724,7 @@ extern char netxen_nic_driver_name[];
#endif
/* Number of status descriptors to handle per interrupt */
-#define MAX_STATUS_HANDLE (128)
+#define MAX_STATUS_HANDLE (64)
/*
* netxen_skb_frag{} is to contain mapping info for each SG list. This
@@ -827,17 +829,37 @@ struct netxen_adapter_stats {
*/
struct nx_host_rds_ring {
u32 producer;
- u32 crb_rcv_producer; /* reg offset */
- struct rcv_desc *desc_head; /* address of rx ring in Phantom */
- struct netxen_rx_buffer *rx_buf_arr; /* rx buffers for receive */
- struct list_head free_list;
+ u32 crb_rcv_producer;
u32 num_desc;
u32 dma_size;
u32 skb_size;
u32 flags;
+ struct rcv_desc *desc_head;
+ struct netxen_rx_buffer *rx_buf_arr;
+ struct list_head free_list;
+ spinlock_t lock;
dma_addr_t phys_addr;
};
+struct nx_host_sds_ring {
+ u32 consumer;
+ u32 crb_sts_consumer;
+ u32 crb_intr_mask;
+ u32 num_desc;
+
+ struct status_desc *desc_head;
+ struct netxen_adapter *adapter;
+ struct napi_struct napi;
+ struct list_head free_list[NUM_RCV_DESC_RINGS];
+
+ u16 clean_tx;
+ u16 post_rxd;
+ int irq;
+
+ dma_addr_t phys_addr;
+ char name[IFNAMSIZ+4];
+};
+
/*
* Receive context. There is one such structure per instance of the
* receive processing. Any state information that is relevant to
@@ -850,10 +872,7 @@ struct netxen_recv_context {
u16 virt_port;
struct nx_host_rds_ring rds_rings[NUM_RCV_DESC_RINGS];
- u32 status_rx_consumer;
- u32 crb_sts_consumer; /* reg offset */
- dma_addr_t rcv_status_desc_phys_addr;
- struct status_desc *rcv_status_desc_head;
+ struct nx_host_sds_ring sds_rings[NUM_STS_DESC_RINGS];
};
/* New HW context creation */
@@ -1179,13 +1198,13 @@ typedef struct {
#define NETXEN_IS_MSI_FAMILY(adapter) \
((adapter)->flags & (NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED))
-#define MSIX_ENTRIES_PER_ADAPTER 1
+#define MSIX_ENTRIES_PER_ADAPTER NUM_STS_DESC_RINGS
#define NETXEN_MSIX_TBL_SPACE 8192
#define NETXEN_PCI_REG_MSIX_TBL 0x44
#define NETXEN_DB_MAPSIZE_BYTES 0x1000
-#define NETXEN_NETDEV_WEIGHT 120
+#define NETXEN_NETDEV_WEIGHT 128
#define NETXEN_ADAPTER_UP_MAGIC 777
#define NETXEN_NIC_PEG_TUNE 0
@@ -1200,7 +1219,6 @@ struct netxen_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
int pci_using_dac;
- struct napi_struct napi;
struct net_device_stats net_stats;
int mtu;
int portnum;
@@ -1212,7 +1230,6 @@ struct netxen_adapter {
nx_mac_list_t *mac_list;
struct netxen_legacy_intr_set legacy_intr;
- u32 crb_intr_mask;
struct work_struct watchdog_task;
struct timer_list watchdog_timer;
@@ -1227,6 +1244,7 @@ struct netxen_adapter {
u32 last_cmd_consumer;
u32 crb_addr_cmd_producer;
u32 crb_addr_cmd_consumer;
+ spinlock_t tx_clean_lock;
u32 num_txd;
u32 num_rxd;
@@ -1234,6 +1252,7 @@ struct netxen_adapter {
u32 num_lro_rxd;
int max_rds_rings;
+ int max_sds_rings;
u32 flags;
u32 irq;
@@ -1243,8 +1262,7 @@ struct netxen_adapter {
u32 fw_major;
u32 fw_version;
- u8 msix_supported;
- u8 max_possible_rss_rings;
+ int msix_supported;
struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
struct netxen_adapter_stats stats;
@@ -1447,14 +1465,16 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter);
int netxen_init_firmware(struct netxen_adapter *adapter);
void netxen_nic_clear_stats(struct netxen_adapter *adapter);
void netxen_watchdog_task(struct work_struct *work);
-void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid);
+void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
+ struct nx_host_rds_ring *rds_ring);
int netxen_process_cmd_ring(struct netxen_adapter *adapter);
-int netxen_process_rcv_ring(struct netxen_adapter *adapter, int max);
+int netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max);
void netxen_p2_nic_set_multi(struct net_device *netdev);
void netxen_p3_nic_set_multi(struct net_device *netdev);
void netxen_p3_free_mac_list(struct netxen_adapter *adapter);
int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32);
int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
+int netxen_config_rss(struct netxen_adapter *adapter, int enable);
int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 2e66335..9234473 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -169,6 +169,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
nx_cardrsp_rds_ring_t *prsp_rds;
nx_cardrsp_sds_ring_t *prsp_sds;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_sds_ring *sds_ring;
dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
u64 phys_addr;
@@ -181,9 +182,8 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
- /* only one sds ring for now */
nrds_rings = adapter->max_rds_rings;
- nsds_rings = 1;
+ nsds_rings = adapter->max_sds_rings;
rq_size =
SIZEOF_HOSTRQ_RX(nx_hostrq_rx_ctx_t, nrds_rings, nsds_rings);
@@ -239,11 +239,14 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
prq_sds = (nx_hostrq_sds_ring_t *)(prq->data +
le32_to_cpu(prq->sds_ring_offset));
- prq_sds[0].host_phys_addr =
- cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
- prq_sds[0].ring_size = cpu_to_le32(adapter->num_rxd);
- /* only one msix vector for now */
- prq_sds[0].msi_index = cpu_to_le16(0);
+ for (i = 0; i < nsds_rings; i++) {
+
+ sds_ring = &recv_ctx->sds_rings[i];
+
+ prq_sds[i].host_phys_addr = cpu_to_le64(sds_ring->phys_addr);
+ prq_sds[i].ring_size = cpu_to_le32(sds_ring->num_desc);
+ prq_sds[i].msi_index = cpu_to_le16(i);
+ }
phys_addr = hostrq_phys_addr;
err = netxen_issue_cmd(adapter,
@@ -272,11 +275,16 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
prsp_sds = ((nx_cardrsp_sds_ring_t *)
&prsp->data[le32_to_cpu(prsp->sds_ring_offset)]);
- reg = le32_to_cpu(prsp_sds[0].host_consumer_crb);
- recv_ctx->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
- reg = le32_to_cpu(prsp_sds[0].interrupt_crb);
- adapter->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);
+ for (i = 0; i < le16_to_cpu(prsp->num_sds_rings); i++) {
+ sds_ring = &recv_ctx->sds_rings[i];
+
+ reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
+ sds_ring->crb_sts_consumer = NETXEN_NIC_REG(reg - 0x200);
+
+ reg = le32_to_cpu(prsp_sds[i].interrupt_crb);
+ sds_ring->crb_intr_mask = NETXEN_NIC_REG(reg - 0x200);
+ }
recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
recv_ctx->context_id = le16_to_cpu(prsp->context_id);
@@ -488,6 +496,7 @@ netxen_init_old_ctx(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_sds_ring *sds_ring;
int ring;
int func_id = adapter->portnum;
@@ -506,10 +515,9 @@ netxen_init_old_ctx(struct netxen_adapter *adapter)
adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
cpu_to_le32(rds_ring->num_desc);
}
- adapter->ctx_desc->sts_ring_addr =
- cpu_to_le64(recv_ctx->rcv_status_desc_phys_addr);
- adapter->ctx_desc->sts_ring_size =
- cpu_to_le32(adapter->num_rxd);
+ sds_ring = &recv_ctx->sds_rings[0];
+ adapter->ctx_desc->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr);
+ adapter->ctx_desc->sts_ring_size = cpu_to_le32(sds_ring->num_desc);
adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id),
lower32(adapter->ctx_desc_phys_addr));
@@ -534,6 +542,10 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
int ring;
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_sds_ring *sds_ring;
+
+ struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = adapter->netdev;
err = netxen_receive_peg_ready(adapter);
if (err) {
@@ -542,12 +554,12 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
return err;
}
- addr = pci_alloc_consistent(adapter->pdev,
+ addr = pci_alloc_consistent(pdev,
sizeof(struct netxen_ring_ctx) + sizeof(uint32_t),
&adapter->ctx_desc_phys_addr);
if (addr == NULL) {
- DPRINTK(ERR, "failed to allocate hw context\n");
+ dev_err(&pdev->dev, "failed to allocate hw context\n");
return -ENOMEM;
}
memset(addr, 0, sizeof(struct netxen_ring_ctx));
@@ -560,14 +572,13 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
(__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx));
/* cmd desc ring */
- addr = pci_alloc_consistent(adapter->pdev,
- sizeof(struct cmd_desc_type0) *
- adapter->num_txd,
+ addr = pci_alloc_consistent(pdev,
+ TX_DESC_RINGSIZE(adapter),
&hw->cmd_desc_phys_addr);
if (addr == NULL) {
- printk(KERN_ERR "%s failed to allocate tx desc ring\n",
- netxen_nic_driver_name);
+ dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n",
+ netdev->name);
return -ENOMEM;
}
@@ -576,15 +587,14 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
recv_ctx = &adapter->recv_ctx;
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
- /* rx desc ring */
rds_ring = &recv_ctx->rds_rings[ring];
addr = pci_alloc_consistent(adapter->pdev,
- RCV_DESC_RINGSIZE,
+ RCV_DESC_RINGSIZE(rds_ring),
&rds_ring->phys_addr);
if (addr == NULL) {
- printk(KERN_ERR "%s failed to allocate rx "
- "desc ring[%d]\n",
- netxen_nic_driver_name, ring);
+ dev_err(&pdev->dev,
+ "%s: failed to allocate rds ring [%d]\n",
+ netdev->name, ring);
err = -ENOMEM;
goto err_out_free;
}
@@ -596,22 +606,22 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
crb_rcv_producer[ring];
}
- /* status desc ring */
- addr = pci_alloc_consistent(adapter->pdev,
- STATUS_DESC_RINGSIZE,
- &recv_ctx->rcv_status_desc_phys_addr);
- if (addr == NULL) {
- printk(KERN_ERR "%s failed to allocate sts desc ring\n",
- netxen_nic_driver_name);
- err = -ENOMEM;
- goto err_out_free;
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+
+ addr = pci_alloc_consistent(adapter->pdev,
+ STATUS_DESC_RINGSIZE(sds_ring),
+ &sds_ring->phys_addr);
+ if (addr == NULL) {
+ dev_err(&pdev->dev,
+ "%s: failed to allocate sds ring [%d]\n",
+ netdev->name, ring);
+ err = -ENOMEM;
+ goto err_out_free;
+ }
+ sds_ring->desc_head = (struct status_desc *)addr;
}
- recv_ctx->rcv_status_desc_head = (struct status_desc *)addr;
- if (adapter->fw_major < 4)
- recv_ctx->crb_sts_consumer =
- recv_crb_registers[adapter->portnum].
- crb_sts_consumer;
if (adapter->fw_major >= 4) {
adapter->intr_scheme = INTR_SCHEME_PERPORT;
@@ -624,12 +634,16 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
if (err)
goto err_out_free;
} else {
+ sds_ring = &recv_ctx->sds_rings[0];
+ sds_ring->crb_sts_consumer =
+ recv_crb_registers[adapter->portnum].crb_sts_consumer;
adapter->intr_scheme = adapter->pci_read_normalize(adapter,
CRB_NIC_CAPABILITIES_FW);
adapter->msi_mode = adapter->pci_read_normalize(adapter,
CRB_NIC_MSI_MODE_FW);
- adapter->crb_intr_mask = sw_int_mask[adapter->portnum];
+ recv_ctx->sds_rings[0].crb_intr_mask =
+ sw_int_mask[adapter->portnum];
err = netxen_init_old_ctx(adapter);
if (err) {
@@ -650,6 +664,7 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_sds_ring *sds_ring;
int ring;
if (adapter->fw_major >= 4) {
@@ -681,19 +696,23 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
if (rds_ring->desc_head != NULL) {
pci_free_consistent(adapter->pdev,
- RCV_DESC_RINGSIZE,
+ RCV_DESC_RINGSIZE(rds_ring),
rds_ring->desc_head,
rds_ring->phys_addr);
rds_ring->desc_head = NULL;
}
}
- if (recv_ctx->rcv_status_desc_head != NULL) {
- pci_free_consistent(adapter->pdev,
- STATUS_DESC_RINGSIZE,
- recv_ctx->rcv_status_desc_head,
- recv_ctx->rcv_status_desc_phys_addr);
- recv_ctx->rcv_status_desc_head = NULL;
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+
+ if (sds_ring->desc_head != NULL) {
+ pci_free_consistent(adapter->pdev,
+ STATUS_DESC_RINGSIZE(sds_ring),
+ sds_ring->desc_head,
+ sds_ring->phys_addr);
+ sds_ring->desc_head = NULL;
+ }
}
}
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index cea7300..c89c791 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -670,6 +670,53 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
return rv;
}
+#define RSS_HASHTYPE_IP_TCP 0x3
+
+int netxen_config_rss(struct netxen_adapter *adapter, int enable)
+{
+ nx_nic_req_t req;
+ u64 word;
+ int i, rv;
+
+ u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
+ 0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
+ 0x255b0ec26d5a56daULL };
+
+
+ memset(&req, 0, sizeof(nx_nic_req_t));
+ req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+ word = NX_NIC_H2C_OPCODE_CONFIG_RSS | ((u64)adapter->portnum << 16);
+ req.req_hdr = cpu_to_le64(word);
+
+ /*
+ * RSS request:
+ * bits 3-0: hash_method
+ * 5-4: hash_type_ipv4
+ * 7-6: hash_type_ipv6
+ * 8: enable
+ * 9: use indirection table
+ * 47-10: reserved
+ * 63-48: indirection table mask
+ */
+ word = ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
+ ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
+ ((u64)(enable & 0x1) << 8) |
+ ((0x7ULL) << 48);
+ req.words[0] = cpu_to_le64(word);
+ for (i = 0; i < 5; i++)
+ req.words[i+1] = cpu_to_le64(key[i]);
+
+
+ rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+ if (rv != 0) {
+ printk(KERN_ERR "%s: could not configure RSS\n",
+ adapter->netdev->name);
+ }
+
+ return rv;
+}
+
/*
* netxen_nic_change_mtu - Change the Maximum Transfer Unit
* @returns 0 on success, negative on failure
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 1b8f79f..0759c35 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -50,7 +50,8 @@ static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
#define NETXEN_NIC_XDMA_RESET 0x8000ff
static void
-netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ringid);
+netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
+ struct nx_host_rds_ring *rds_ring);
static void crb_addr_transform_setup(void)
{
@@ -222,19 +223,21 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
{
struct netxen_recv_context *recv_ctx;
struct nx_host_rds_ring *rds_ring;
+ struct nx_host_sds_ring *sds_ring;
struct netxen_rx_buffer *rx_buf;
int ring, i, num_rx_bufs;
struct netxen_cmd_buffer *cmd_buf_arr;
struct net_device *netdev = adapter->netdev;
- cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
+ cmd_buf_arr =
+ (struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(adapter));
if (cmd_buf_arr == NULL) {
printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n",
netdev->name);
return -ENOMEM;
}
- memset(cmd_buf_arr, 0, TX_RINGSIZE);
+ memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(adapter));
adapter->cmd_buf_arr = cmd_buf_arr;
recv_ctx = &adapter->recv_ctx;
@@ -275,7 +278,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
}
rds_ring->rx_buf_arr = (struct netxen_rx_buffer *)
- vmalloc(RCV_BUFFSIZE);
+ vmalloc(RCV_BUFF_RINGSIZE(rds_ring));
if (rds_ring->rx_buf_arr == NULL) {
printk(KERN_ERR "%s: Failed to allocate "
"rx buffer ring %d\n",
@@ -283,7 +286,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
/* free whatever was already allocated */
goto err_out;
}
- memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE);
+ memset(rds_ring->rx_buf_arr, 0, RCV_BUFF_RINGSIZE(rds_ring));
INIT_LIST_HEAD(&rds_ring->free_list);
/*
* Now go through all of them, set reference handles
@@ -298,6 +301,19 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
rx_buf->state = NETXEN_BUFFER_FREE;
rx_buf++;
}
+ spin_lock_init(&rds_ring->lock);
+ }
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ 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->num_desc = adapter->num_rxd;
+
+ for (i = 0; i < NUM_RCV_DESC_RINGS; i++)
+ INIT_LIST_HEAD(&sds_ring->free_list[i]);
}
return 0;
@@ -793,6 +809,40 @@ int netxen_receive_peg_ready(struct netxen_adapter *adapter)
return 0;
}
+static int
+netxen_alloc_rx_skb(struct netxen_adapter *adapter,
+ struct nx_host_rds_ring *rds_ring,
+ struct netxen_rx_buffer *buffer)
+{
+ struct sk_buff *skb;
+ dma_addr_t dma;
+ struct pci_dev *pdev = adapter->pdev;
+
+ buffer->skb = dev_alloc_skb(rds_ring->skb_size);
+ if (!buffer->skb)
+ return 1;
+
+ skb = buffer->skb;
+
+ if (!adapter->ahw.cut_through)
+ skb_reserve(skb, 2);
+
+ dma = pci_map_single(pdev, skb->data,
+ rds_ring->dma_size, PCI_DMA_FROMDEVICE);
+
+ if (pci_dma_mapping_error(pdev, dma)) {
+ dev_kfree_skb_any(skb);
+ buffer->skb = NULL;
+ return 1;
+ }
+
+ buffer->skb = skb;
+ buffer->dma = dma;
+ buffer->state = NETXEN_BUFFER_BUSY;
+
+ return 0;
+}
+
static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter,
struct nx_host_rds_ring *rds_ring, u16 index, u16 cksum)
{
@@ -817,14 +867,12 @@ static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter,
skb->dev = adapter->netdev;
buffer->skb = NULL;
-
no_skb:
buffer->state = NETXEN_BUFFER_FREE;
- list_add_tail(&buffer->list, &rds_ring->free_list);
return skb;
}
-static void
+static struct netxen_rx_buffer *
netxen_process_rcv(struct netxen_adapter *adapter,
int ring, int index, int length, int cksum, int pkt_offset)
{
@@ -835,13 +883,13 @@ netxen_process_rcv(struct netxen_adapter *adapter,
struct nx_host_rds_ring *rds_ring = &recv_ctx->rds_rings[ring];
if (unlikely(index > rds_ring->num_desc))
- return;
+ return NULL;
buffer = &rds_ring->rx_buf_arr[index];
skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum);
if (!skb)
- return;
+ return buffer;
if (length > rds_ring->skb_size)
skb_put(skb, rds_ring->skb_size);
@@ -858,21 +906,31 @@ netxen_process_rcv(struct netxen_adapter *adapter,
adapter->stats.no_rcv++;
adapter->stats.rxbytes += length;
+
+ return buffer;
}
+#define netxen_merge_rx_buffers(list, head) \
+ do { list_splice_tail_init(list, head); } while (0);
+
int
-netxen_process_rcv_ring(struct netxen_adapter *adapter, int max)
+netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
{
- struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
- struct status_desc *desc_head = recv_ctx->rcv_status_desc_head;
+ struct netxen_adapter *adapter = sds_ring->adapter;
+
+ struct list_head *cur;
+
struct status_desc *desc;
- u32 consumer = recv_ctx->status_rx_consumer;
+ struct netxen_rx_buffer *rxbuf;
+
+ u32 consumer = sds_ring->consumer;
+
int count = 0;
u64 sts_data;
int opcode, ring, index, length, cksum, pkt_offset;
while (count < max) {
- desc = &desc_head[consumer];
+ desc = &sds_ring->desc_head[consumer];
sts_data = le64_to_cpu(desc->status_desc_data);
if (!(sts_data & STATUS_OWNER_HOST))
@@ -889,22 +947,41 @@ netxen_process_rcv_ring(struct netxen_adapter *adapter, int max)
cksum = netxen_get_sts_status(sts_data);
pkt_offset = netxen_get_sts_pkt_offset(sts_data);
- netxen_process_rcv(adapter, ring, index,
+ rxbuf = netxen_process_rcv(adapter, ring, index,
length, cksum, pkt_offset);
+ if (rxbuf)
+ list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
+
desc->status_desc_data = cpu_to_le64(STATUS_OWNER_PHANTOM);
- consumer = get_next_index(consumer, adapter->num_rxd);
+ consumer = get_next_index(consumer, sds_ring->num_desc);
count++;
}
- for (ring = 0; ring < adapter->max_rds_rings; ring++)
- netxen_post_rx_buffers_nodb(adapter, ring);
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ struct nx_host_rds_ring *rds_ring =
+ &adapter->recv_ctx.rds_rings[ring];
+
+ if (!list_empty(&sds_ring->free_list[ring])) {
+ list_for_each(cur, &sds_ring->free_list[ring]) {
+ rxbuf = list_entry(cur,
+ struct netxen_rx_buffer, list);
+ netxen_alloc_rx_skb(adapter, rds_ring, rxbuf);
+ }
+ spin_lock(&rds_ring->lock);
+ netxen_merge_rx_buffers(&sds_ring->free_list[ring],
+ &rds_ring->free_list);
+ spin_unlock(&rds_ring->lock);
+ }
+
+ netxen_post_rx_buffers_nodb(adapter, rds_ring);
+ }
if (count) {
- recv_ctx->status_rx_consumer = consumer;
+ sds_ring->consumer = consumer;
adapter->pci_write_normalize(adapter,
- recv_ctx->crb_sts_consumer, consumer);
+ sds_ring->crb_sts_consumer, consumer);
}
return count;
@@ -921,6 +998,9 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
struct netxen_skb_frag *frag;
int done = 0;
+ if (!spin_trylock(&adapter->tx_clean_lock))
+ return 1;
+
last_consumer = adapter->last_cmd_consumer;
barrier(); /* cmd_consumer can change underneath */
consumer = le32_to_cpu(*(adapter->cmd_consumer));
@@ -976,63 +1056,46 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
barrier(); /* cmd_consumer can change underneath */
consumer = le32_to_cpu(*(adapter->cmd_consumer));
done = (last_consumer == consumer);
+ spin_unlock(&adapter->tx_clean_lock);
return (done);
}
void
-netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid)
+netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
+ struct nx_host_rds_ring *rds_ring)
{
- struct pci_dev *pdev = adapter->pdev;
- struct sk_buff *skb;
- struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
- struct nx_host_rds_ring *rds_ring = NULL;
- uint producer;
struct rcv_desc *pdesc;
struct netxen_rx_buffer *buffer;
- int count = 0;
+ int producer, count = 0;
netxen_ctx_msg msg = 0;
- dma_addr_t dma;
struct list_head *head;
- rds_ring = &recv_ctx->rds_rings[ringid];
-
producer = rds_ring->producer;
- head = &rds_ring->free_list;
+ spin_lock(&rds_ring->lock);
+ head = &rds_ring->free_list;
while (!list_empty(head)) {
- skb = dev_alloc_skb(rds_ring->skb_size);
- if (unlikely(!skb)) {
- break;
- }
-
- if (!adapter->ahw.cut_through)
- skb_reserve(skb, 2);
+ buffer = list_entry(head->next, struct netxen_rx_buffer, list);
- dma = pci_map_single(pdev, skb->data,
- rds_ring->dma_size, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, dma)) {
- dev_kfree_skb_any(skb);
- break;
+ if (!buffer->skb) {
+ if (netxen_alloc_rx_skb(adapter, rds_ring, buffer))
+ break;
}
count++;
- buffer = list_entry(head->next, struct netxen_rx_buffer, list);
list_del(&buffer->list);
- buffer->skb = skb;
- buffer->state = NETXEN_BUFFER_BUSY;
- buffer->dma = dma;
-
/* make a rcv descriptor */
pdesc = &rds_ring->desc_head[producer];
- pdesc->addr_buffer = cpu_to_le64(dma);
+ pdesc->addr_buffer = cpu_to_le64(buffer->dma);
pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
producer = get_next_index(producer, rds_ring->num_desc);
}
+ spin_unlock(&rds_ring->lock);
if (count) {
rds_ring->producer = producer;
@@ -1061,48 +1124,31 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid)
}
static void
-netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ringid)
+netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
+ struct nx_host_rds_ring *rds_ring)
{
- struct pci_dev *pdev = adapter->pdev;
- struct sk_buff *skb;
- struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
- struct nx_host_rds_ring *rds_ring = NULL;
- u32 producer;
struct rcv_desc *pdesc;
struct netxen_rx_buffer *buffer;
- int count = 0;
+ int producer, count = 0;
struct list_head *head;
- dma_addr_t dma;
-
- rds_ring = &recv_ctx->rds_rings[ringid];
producer = rds_ring->producer;
+ if (!spin_trylock(&rds_ring->lock))
+ return;
+
head = &rds_ring->free_list;
while (!list_empty(head)) {
- skb = dev_alloc_skb(rds_ring->skb_size);
- if (unlikely(!skb)) {
- break;
- }
-
- if (!adapter->ahw.cut_through)
- skb_reserve(skb, 2);
+ buffer = list_entry(head->next, struct netxen_rx_buffer, list);
- dma = pci_map_single(pdev, skb->data,
- rds_ring->dma_size, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, dma)) {
- dev_kfree_skb_any(skb);
- break;
+ if (!buffer->skb) {
+ if (netxen_alloc_rx_skb(adapter, rds_ring, buffer))
+ break;
}
count++;
- buffer = list_entry(head->next, struct netxen_rx_buffer, list);
list_del(&buffer->list);
- buffer->skb = skb;
- buffer->state = NETXEN_BUFFER_BUSY;
- buffer->dma = dma;
-
/* make a rcv descriptor */
pdesc = &rds_ring->desc_head[producer];
pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
@@ -1119,6 +1165,7 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ringid)
(producer - 1) & (rds_ring->num_desc - 1));
wmb();
}
+ spin_unlock(&rds_ring->lock);
}
void netxen_nic_clear_stats(struct netxen_adapter *adapter)
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 00eaeee..274d1e0 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -135,20 +135,71 @@ static uint32_t msi_tgt_status[8] = {
static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
-static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring)
{
- adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0);
+ struct netxen_adapter *adapter = sds_ring->adapter;
+
+ adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0);
}
-static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring)
{
- adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1);
+ struct netxen_adapter *adapter = sds_ring->adapter;
+
+ adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0x1);
if (!NETXEN_IS_MSI_FAMILY(adapter))
adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_mask_reg, 0xfbff);
}
+static void
+netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev)
+{
+ int ring;
+ struct nx_host_sds_ring *sds_ring;
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+ if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
+ adapter->max_sds_rings = (num_online_cpus() >= 4) ? 4 : 2;
+ else
+ adapter->max_sds_rings = 1;
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ netif_napi_add(netdev, &sds_ring->napi,
+ netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
+ }
+}
+
+static void
+netxen_napi_enable(struct netxen_adapter *adapter)
+{
+ int ring;
+ struct nx_host_sds_ring *sds_ring;
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ napi_enable(&sds_ring->napi);
+ netxen_nic_enable_int(sds_ring);
+ }
+}
+
+static void
+netxen_napi_disable(struct netxen_adapter *adapter)
+{
+ int ring;
+ struct nx_host_sds_ring *sds_ring;
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ netxen_nic_disable_int(sds_ring);
+ napi_disable(&sds_ring->napi);
+ }
+}
+
static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
{
struct pci_dev *pdev = adapter->pdev;
@@ -226,7 +277,6 @@ static void netxen_check_options(struct netxen_adapter *adapter)
adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS;
adapter->num_lro_rxd = MAX_LRO_RCV_DESCRIPTORS;
- adapter->max_possible_rss_rings = 1;
return;
}
@@ -447,6 +497,7 @@ request_msi:
dev_info(&pdev->dev, "using msi interrupts\n");
} else
dev_info(&pdev->dev, "using legacy interrupts\n");
+ adapter->msix_entries[0].vector = pdev->irq;
}
}
@@ -671,8 +722,12 @@ static int
netxen_nic_request_irq(struct netxen_adapter *adapter)
{
irq_handler_t handler;
+ struct nx_host_sds_ring *sds_ring;
+ int err, ring;
+
unsigned long flags = IRQF_SAMPLE_RANDOM;
struct net_device *netdev = adapter->netdev;
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
(adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
@@ -693,8 +748,30 @@ netxen_nic_request_irq(struct netxen_adapter *adapter)
}
adapter->irq = netdev->irq;
- return request_irq(adapter->irq, handler,
- flags, netdev->name, adapter);
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ sprintf(sds_ring->name, "%16s[%d]", netdev->name, ring);
+ err = request_irq(sds_ring->irq, handler,
+ flags, sds_ring->name, sds_ring);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static void
+netxen_nic_free_irq(struct netxen_adapter *adapter)
+{
+ int ring;
+ struct nx_host_sds_ring *sds_ring;
+
+ struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+ for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+ sds_ring = &recv_ctx->sds_rings[ring];
+ free_irq(sds_ring->irq, sds_ring);
+ }
}
static int
@@ -719,8 +796,10 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
adapter->ahw.linkup = 0;
mod_timer(&adapter->watchdog_timer, jiffies);
- napi_enable(&adapter->napi);
- netxen_nic_enable_int(adapter);
+ netxen_napi_enable(adapter);
+
+ if (adapter->max_sds_rings > 1)
+ netxen_config_rss(adapter, 1);
return 0;
}
@@ -730,13 +809,11 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
{
netif_carrier_off(netdev);
netif_stop_queue(netdev);
- napi_disable(&adapter->napi);
+ netxen_napi_disable(adapter);
if (adapter->stop_port)
adapter->stop_port(adapter);
- netxen_nic_disable_int(adapter);
-
netxen_release_tx_buffers(adapter);
FLUSH_SCHEDULED_WORK();
@@ -750,6 +827,7 @@ netxen_nic_attach(struct netxen_adapter *adapter)
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
int err, ring;
+ struct nx_host_rds_ring *rds_ring;
err = netxen_init_firmware(adapter);
if (err != 0) {
@@ -788,8 +866,10 @@ netxen_nic_attach(struct netxen_adapter *adapter)
netxen_nic_update_cmd_consumer(adapter, 0);
}
- for (ring = 0; ring < adapter->max_rds_rings; ring++)
- netxen_post_rx_buffers(adapter, ring);
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &adapter->recv_ctx.rds_rings[ring];
+ netxen_post_rx_buffers(adapter, ring, rds_ring);
+ }
err = netxen_nic_request_irq(adapter);
if (err) {
@@ -812,8 +892,7 @@ err_out_free_sw:
static void
netxen_nic_detach(struct netxen_adapter *adapter)
{
- if (adapter->irq)
- free_irq(adapter->irq, adapter);
+ netxen_nic_free_irq(adapter);
netxen_release_rx_buffers(adapter);
netxen_free_hw_resources(adapter);
@@ -883,14 +962,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_free_netdev;
rwlock_init(&adapter->adapter_lock);
+ spin_lock_init(&adapter->tx_clean_lock);
err = netxen_setup_pci_map(adapter);
if (err)
goto err_out_free_netdev;
- netif_napi_add(netdev, &adapter->napi,
- netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
-
/* This will be reset for mezz cards */
adapter->portnum = pci_func_id;
adapter->rx_csum = 1;
@@ -963,10 +1040,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netxen_setup_intr(adapter);
- if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
- netdev->irq = adapter->msix_entries[0].vector;
- else
- netdev->irq = pdev->irq;
+ netdev->irq = adapter->msix_entries[0].vector;
+
+ netxen_napi_add(adapter, netdev);
err = netxen_receive_peg_ready(adapter);
if (err)
@@ -1520,13 +1596,11 @@ static void netxen_tx_timeout_task(struct work_struct *work)
printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
netxen_nic_driver_name, adapter->netdev->name);
- netxen_nic_disable_int(adapter);
- napi_disable(&adapter->napi);
+ netxen_napi_disable(adapter);
adapter->netdev->trans_start = jiffies;
- napi_enable(&adapter->napi);
- netxen_nic_enable_int(adapter);
+ netxen_napi_enable(adapter);
netif_wake_queue(adapter->netdev);
}
@@ -1564,7 +1638,8 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
static irqreturn_t netxen_intr(int irq, void *data)
{
- struct netxen_adapter *adapter = data;
+ struct nx_host_sds_ring *sds_ring = data;
+ struct netxen_adapter *adapter = sds_ring->adapter;
u32 status = 0;
status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
@@ -1595,7 +1670,7 @@ static irqreturn_t netxen_intr(int irq, void *data)
/* clear interrupt */
if (adapter->fw_major < 4)
- netxen_nic_disable_int(adapter);
+ netxen_nic_disable_int(sds_ring);
adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_status_reg,
@@ -1604,45 +1679,49 @@ static irqreturn_t netxen_intr(int irq, void *data)
adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
- napi_schedule(&adapter->napi);
+ napi_schedule(&sds_ring->napi);
return IRQ_HANDLED;
}
static irqreturn_t netxen_msi_intr(int irq, void *data)
{
- struct netxen_adapter *adapter = data;
+ struct nx_host_sds_ring *sds_ring = data;
+ struct netxen_adapter *adapter = sds_ring->adapter;
/* clear interrupt */
adapter->pci_write_immediate(adapter,
msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
- napi_schedule(&adapter->napi);
+ napi_schedule(&sds_ring->napi);
return IRQ_HANDLED;
}
static irqreturn_t netxen_msix_intr(int irq, void *data)
{
- struct netxen_adapter *adapter = data;
+ struct nx_host_sds_ring *sds_ring = data;
- napi_schedule(&adapter->napi);
+ napi_schedule(&sds_ring->napi);
return IRQ_HANDLED;
}
static int netxen_nic_poll(struct napi_struct *napi, int budget)
{
- struct netxen_adapter *adapter =
- container_of(napi, struct netxen_adapter, napi);
+ struct nx_host_sds_ring *sds_ring =
+ container_of(napi, struct nx_host_sds_ring, napi);
+
+ struct netxen_adapter *adapter = sds_ring->adapter;
+
int tx_complete;
int work_done;
tx_complete = netxen_process_cmd_ring(adapter);
- work_done = netxen_process_rcv_ring(adapter, budget);
+ work_done = netxen_process_rcv_ring(sds_ring, budget);
if ((work_done < budget) && tx_complete) {
- napi_complete(&adapter->napi);
- netxen_nic_enable_int(adapter);
+ napi_complete(&sds_ring->napi);
+ netxen_nic_enable_int(sds_ring);
}
return work_done;
--
1.6.0.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [patch next 6/6] netxen: update version to 4.0.30
2009-03-14 0:52 [patch next 0/6] netxen: bugfixes / enhancements Dhananjay Phadke
` (4 preceding siblings ...)
2009-03-14 0:52 ` [patch next 5/6] netxen: add receive side scaling (rss) support Dhananjay Phadke
@ 2009-03-14 0:52 ` Dhananjay Phadke
2009-03-14 21:06 ` [patch next 0/6] netxen: bugfixes / enhancements David Miller
6 siblings, 0 replies; 8+ messages in thread
From: Dhananjay Phadke @ 2009-03-14 0:52 UTC (permalink / raw)
To: netdev; +Cc: davem
To mark all features and bugfixes submitted since 4.0.11.
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
drivers/net/netxen/netxen_nic.h | 4 ++--
drivers/net/netxen/netxen_nic_main.c | 5 ++---
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 595171d..2544129 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -66,8 +66,8 @@
#define _NETXEN_NIC_LINUX_MAJOR 4
#define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 11
-#define NETXEN_NIC_LINUX_VERSIONID "4.0.11"
+#define _NETXEN_NIC_LINUX_SUBVERSION 30
+#define NETXEN_NIC_LINUX_VERSIONID "4.0.30"
#define NETXEN_VERSION_CODE(a, b, c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 274d1e0..1fb9bcf 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -910,9 +910,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int pci_func_id = PCI_FUNC(pdev->devfn);
uint8_t revision_id;
- if (pci_func_id == 0)
- printk(KERN_INFO "%s\n", netxen_nic_driver_string);
-
if (pdev->class != 0x020000) {
printk(KERN_DEBUG "NetXen function %d, class %x will not "
"be enabled.\n",pci_func_id, pdev->class);
@@ -1750,6 +1747,8 @@ static struct pci_driver netxen_driver = {
static int __init netxen_init_module(void)
{
+ printk(KERN_INFO "%s\n", netxen_nic_driver_string);
+
if ((netxen_workq = create_singlethread_workqueue("netxen")) == NULL)
return -ENOMEM;
--
1.6.0.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [patch next 0/6] netxen: bugfixes / enhancements
2009-03-14 0:52 [patch next 0/6] netxen: bugfixes / enhancements Dhananjay Phadke
` (5 preceding siblings ...)
2009-03-14 0:52 ` [patch next 6/6] netxen: update version to 4.0.30 Dhananjay Phadke
@ 2009-03-14 21:06 ` David Miller
6 siblings, 0 replies; 8+ messages in thread
From: David Miller @ 2009-03-14 21:06 UTC (permalink / raw)
To: dhananjay; +Cc: netdev
From: Dhananjay Phadke <dhananjay@netxen.com>
Date: Fri, 13 Mar 2009 17:52:00 -0700
> This 6 patch series is for net-next-2.6, containing minor bug
> fixes and enhancements / new features.
>
> Please apply, thanks.
All applied, thanks!
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-03-14 21:06 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-14 0:52 [patch next 0/6] netxen: bugfixes / enhancements Dhananjay Phadke
2009-03-14 0:52 ` [patch next 1/6] netxen: fix endianness in serial number Dhananjay Phadke
2009-03-14 0:52 ` [patch next 2/6] netxen: add suspend resume support Dhananjay Phadke
2009-03-14 0:52 ` [patch next 3/6] netxen: sanitize variable names Dhananjay Phadke
2009-03-14 0:52 ` [patch next 4/6] netxen: remove old lro code Dhananjay Phadke
2009-03-14 0:52 ` [patch next 5/6] netxen: add receive side scaling (rss) support Dhananjay Phadke
2009-03-14 0:52 ` [patch next 6/6] netxen: update version to 4.0.30 Dhananjay Phadke
2009-03-14 21:06 ` [patch next 0/6] netxen: bugfixes / enhancements David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).