netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv2 0/7] netxen bugfixes
@ 2009-01-13 19:52 Dhananjay Phadke
  2009-01-13 19:52 ` [PATCHv2 1/7] netxen: fix endianness in firmware commands Dhananjay Phadke
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Dhananjay Phadke @ 2009-01-13 19:52 UTC (permalink / raw)
  To: netdev; +Cc: davem

>> Sending set of 13 bug fixes, cleanups and enhancements, generated on
>> net-2.6.
> 
> Since the merge window is closed, you will need to seperate
> out the pure bug fixes and just submit those for now.

Alright, here's the bugfix series [7 patches]. There's one sparse
annotation patch besides this, I will submit it seprarately if
bugfix windows allows that.

Thanks,
-Dhananjay



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCHv2 1/7] netxen: fix endianness in firmware commands
  2009-01-13 19:52 [PATCHv2 0/7] netxen bugfixes Dhananjay Phadke
@ 2009-01-13 19:52 ` Dhananjay Phadke
  2009-01-13 19:52 ` [PATCHv2 2/7] netxen: fix ipv6 offload and tx cleanup Dhananjay Phadke
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Dhananjay Phadke @ 2009-01-13 19:52 UTC (permalink / raw)
  To: netdev; +Cc: davem

o Set restricted (little endian) data types in firmware command
  requests and responses.
o Remove unnecessary conversion to LE when writing registers.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic.h      |   98 +++++++++++++++++-----------------
 drivers/net/netxen/netxen_nic_ctx.c  |   50 +++++++----------
 drivers/net/netxen/netxen_nic_hw.c   |   42 ++++++++------
 drivers/net/netxen/netxen_nic_init.c |    2 +-
 4 files changed, 95 insertions(+), 97 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index f8e601c..31311cc 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -995,31 +995,31 @@ struct netxen_recv_context {
  */
 
 typedef struct {
-	u64 host_phys_addr;	/* Ring base addr */
-	u32 ring_size;		/* Ring entries */
-	u16 msi_index;
-	u16 rsvd;		/* Padding */
+	__le64 host_phys_addr;	/* Ring base addr */
+	__le32 ring_size;		/* Ring entries */
+	__le16 msi_index;
+	__le16 rsvd;		/* Padding */
 } nx_hostrq_sds_ring_t;
 
 typedef struct {
-	u64 host_phys_addr;	/* Ring base addr */
-	u64 buff_size;		/* Packet buffer size */
-	u32 ring_size;		/* Ring entries */
-	u32 ring_kind;		/* Class of ring */
+	__le64 host_phys_addr;	/* Ring base addr */
+	__le64 buff_size;		/* Packet buffer size */
+	__le32 ring_size;		/* Ring entries */
+	__le32 ring_kind;		/* Class of ring */
 } nx_hostrq_rds_ring_t;
 
 typedef struct {
-	u64 host_rsp_dma_addr;	/* Response dma'd here */
-	u32 capabilities[4];	/* Flag bit vector */
-	u32 host_int_crb_mode;	/* Interrupt crb usage */
-	u32 host_rds_crb_mode;	/* RDS crb usage */
+	__le64 host_rsp_dma_addr;	/* Response dma'd here */
+	__le32 capabilities[4];	/* Flag bit vector */
+	__le32 host_int_crb_mode;	/* Interrupt crb usage */
+	__le32 host_rds_crb_mode;	/* RDS crb usage */
 	/* These ring offsets are relative to data[0] below */
-	u32 rds_ring_offset;	/* Offset to RDS config */
-	u32 sds_ring_offset;	/* Offset to SDS config */
-	u16 num_rds_rings;	/* Count of RDS rings */
-	u16 num_sds_rings;	/* Count of SDS rings */
-	u16 rsvd1;		/* Padding */
-	u16 rsvd2;		/* Padding */
+	__le32 rds_ring_offset;	/* Offset to RDS config */
+	__le32 sds_ring_offset;	/* Offset to SDS config */
+	__le16 num_rds_rings;	/* Count of RDS rings */
+	__le16 num_sds_rings;	/* Count of SDS rings */
+	__le16 rsvd1;		/* Padding */
+	__le16 rsvd2;		/* Padding */
 	u8  reserved[128]; 	/* reserve space for future expansion*/
 	/* MUST BE 64-bit aligned.
 	   The following is packed:
@@ -1029,24 +1029,24 @@ typedef struct {
 } nx_hostrq_rx_ctx_t;
 
 typedef struct {
-	u32 host_producer_crb;	/* Crb to use */
-	u32 rsvd1;		/* Padding */
+	__le32 host_producer_crb;	/* Crb to use */
+	__le32 rsvd1;		/* Padding */
 } nx_cardrsp_rds_ring_t;
 
 typedef struct {
-	u32 host_consumer_crb;	/* Crb to use */
-	u32 interrupt_crb;	/* Crb to use */
+	__le32 host_consumer_crb;	/* Crb to use */
+	__le32 interrupt_crb;	/* Crb to use */
 } nx_cardrsp_sds_ring_t;
 
 typedef struct {
 	/* These ring offsets are relative to data[0] below */
-	u32 rds_ring_offset;	/* Offset to RDS config */
-	u32 sds_ring_offset;	/* Offset to SDS config */
-	u32 host_ctx_state;	/* Starting State */
-	u32 num_fn_per_port;	/* How many PCI fn share the port */
-	u16 num_rds_rings;	/* Count of RDS rings */
-	u16 num_sds_rings;	/* Count of SDS rings */
-	u16 context_id;		/* Handle for context */
+	__le32 rds_ring_offset;	/* Offset to RDS config */
+	__le32 sds_ring_offset;	/* Offset to SDS config */
+	__le32 host_ctx_state;	/* Starting State */
+	__le32 num_fn_per_port;	/* How many PCI fn share the port */
+	__le16 num_rds_rings;	/* Count of RDS rings */
+	__le16 num_sds_rings;	/* Count of SDS rings */
+	__le16 context_id;		/* Handle for context */
 	u8  phys_port;		/* Physical id of port */
 	u8  virt_port;		/* Virtual/Logical id of port */
 	u8  reserved[128];	/* save space for future expansion */
@@ -1072,34 +1072,34 @@ typedef struct {
  */
 
 typedef struct {
-	u64 host_phys_addr;	/* Ring base addr */
-	u32 ring_size;		/* Ring entries */
-	u32 rsvd;		/* Padding */
+	__le64 host_phys_addr;	/* Ring base addr */
+	__le32 ring_size;		/* Ring entries */
+	__le32 rsvd;		/* Padding */
 } nx_hostrq_cds_ring_t;
 
 typedef struct {
-	u64 host_rsp_dma_addr;	/* Response dma'd here */
-	u64 cmd_cons_dma_addr;	/*  */
-	u64 dummy_dma_addr;	/*  */
-	u32 capabilities[4];	/* Flag bit vector */
-	u32 host_int_crb_mode;	/* Interrupt crb usage */
-	u32 rsvd1;		/* Padding */
-	u16 rsvd2;		/* Padding */
-	u16 interrupt_ctl;
-	u16 msi_index;
-	u16 rsvd3;		/* Padding */
+	__le64 host_rsp_dma_addr;	/* Response dma'd here */
+	__le64 cmd_cons_dma_addr;	/*  */
+	__le64 dummy_dma_addr;	/*  */
+	__le32 capabilities[4];	/* Flag bit vector */
+	__le32 host_int_crb_mode;	/* Interrupt crb usage */
+	__le32 rsvd1;		/* Padding */
+	__le16 rsvd2;		/* Padding */
+	__le16 interrupt_ctl;
+	__le16 msi_index;
+	__le16 rsvd3;		/* Padding */
 	nx_hostrq_cds_ring_t cds_ring;	/* Desc of cds ring */
 	u8  reserved[128];	/* future expansion */
 } nx_hostrq_tx_ctx_t;
 
 typedef struct {
-	u32 host_producer_crb;	/* Crb to use */
-	u32 interrupt_crb;	/* Crb to use */
+	__le32 host_producer_crb;	/* Crb to use */
+	__le32 interrupt_crb;	/* Crb to use */
 } nx_cardrsp_cds_ring_t;
 
 typedef struct {
-	u32 host_ctx_state;	/* Starting state */
-	u16 context_id;		/* Handle for context */
+	__le32 host_ctx_state;	/* Starting state */
+	__le16 context_id;		/* Handle for context */
 	u8  phys_port;		/* Physical id of port */
 	u8  virt_port;		/* Virtual/Logical id of port */
 	nx_cardrsp_cds_ring_t cds_ring;	/* Card cds settings */
@@ -1202,9 +1202,9 @@ enum {
 #define VPORT_MISS_MODE_ACCEPT_MULTI	2 /* accept unmatched multicast */
 
 typedef struct {
-	u64 qhdr;
-	u64 req_hdr;
-	u64 words[6];
+	__le64 qhdr;
+	__le64 req_hdr;
+	__le64 words[6];
 } nx_nic_req_t;
 
 typedef struct {
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 64b5164..746bdb4 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -76,7 +76,7 @@ netxen_api_unlock(struct netxen_adapter *adapter)
 static u32
 netxen_poll_rsp(struct netxen_adapter *adapter)
 {
-	u32 raw_rsp, rsp = NX_CDRP_RSP_OK;
+	u32 rsp = NX_CDRP_RSP_OK;
 	int	timeout = 0;
 
 	do {
@@ -86,10 +86,7 @@ netxen_poll_rsp(struct netxen_adapter *adapter)
 		if (++timeout > NX_OS_CRB_RETRY_COUNT)
 			return NX_CDRP_RSP_TIMEOUT;
 
-		netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET,
-				&raw_rsp);
-
-		rsp = le32_to_cpu(raw_rsp);
+		netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET, &rsp);
 	} while (!NX_CDRP_IS_RSP(rsp));
 
 	return rsp;
@@ -109,20 +106,16 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
 	if (netxen_api_lock(adapter))
 		return NX_RCODE_TIMEOUT;
 
-	netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET,
-			cpu_to_le32(signature));
+	netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET, signature);
 
-	netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET,
-			cpu_to_le32(arg1));
+	netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, arg1);
 
-	netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET,
-			cpu_to_le32(arg2));
+	netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, arg2);
 
-	netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET,
-			cpu_to_le32(arg3));
+	netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, arg3);
 
 	netxen_nic_write_w1(adapter, NX_CDRP_CRB_OFFSET,
-			cpu_to_le32(NX_CDRP_FORM_CMD(cmd)));
+			NX_CDRP_FORM_CMD(cmd));
 
 	rsp = netxen_poll_rsp(adapter);
 
@@ -133,7 +126,6 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
 		rcode = NX_RCODE_TIMEOUT;
 	} else if (rsp == NX_CDRP_RSP_FAIL) {
 		netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET, &rcode);
-		rcode = le32_to_cpu(rcode);
 
 		printk(KERN_ERR "%s: failed card response code:0x%x\n",
 				netxen_nic_driver_name, rcode);
@@ -183,7 +175,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
 
 	int i, nrds_rings, nsds_rings;
 	size_t rq_size, rsp_size;
-	u32 cap, reg;
+	u32 cap, reg, val;
 
 	int err;
 
@@ -225,11 +217,14 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
 
 	prq->num_rds_rings = cpu_to_le16(nrds_rings);
 	prq->num_sds_rings = cpu_to_le16(nsds_rings);
-	prq->rds_ring_offset = 0;
-	prq->sds_ring_offset = prq->rds_ring_offset +
+	prq->rds_ring_offset = cpu_to_le32(0);
+
+	val = le32_to_cpu(prq->rds_ring_offset) +
 		(sizeof(nx_hostrq_rds_ring_t) * nrds_rings);
+	prq->sds_ring_offset = cpu_to_le32(val);
 
-	prq_rds = (nx_hostrq_rds_ring_t *)(prq->data + prq->rds_ring_offset);
+	prq_rds = (nx_hostrq_rds_ring_t *)(prq->data +
+			le32_to_cpu(prq->rds_ring_offset));
 
 	for (i = 0; i < nrds_rings; i++) {
 
@@ -241,17 +236,14 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
 		prq_rds[i].buff_size = cpu_to_le64(rds_ring->dma_size);
 	}
 
-	prq_sds = (nx_hostrq_sds_ring_t *)(prq->data + prq->sds_ring_offset);
+	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->max_rx_desc_count);
 	/* only one msix vector for now */
-	prq_sds[0].msi_index = cpu_to_le32(0);
-
-	/* now byteswap offsets */
-	prq->rds_ring_offset = cpu_to_le32(prq->rds_ring_offset);
-	prq->sds_ring_offset = cpu_to_le32(prq->sds_ring_offset);
+	prq_sds[0].msi_index = cpu_to_le16(0);
 
 	phys_addr = hostrq_phys_addr;
 	err = netxen_issue_cmd(adapter,
@@ -269,9 +261,9 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
 
 
 	prsp_rds = ((nx_cardrsp_rds_ring_t *)
-			 &prsp->data[prsp->rds_ring_offset]);
+			 &prsp->data[le32_to_cpu(prsp->rds_ring_offset)]);
 
-	for (i = 0; i < le32_to_cpu(prsp->num_rds_rings); i++) {
+	for (i = 0; i < le16_to_cpu(prsp->num_rds_rings); i++) {
 		rds_ring = &recv_ctx->rds_rings[i];
 
 		reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
@@ -279,7 +271,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
 	}
 
 	prsp_sds = ((nx_cardrsp_sds_ring_t *)
-			&prsp->data[prsp->sds_ring_offset]);
+			&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);
 
@@ -288,7 +280,7 @@ nx_fw_cmd_create_rx_ctx(struct netxen_adapter *adapter)
 
 	recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
 	recv_ctx->context_id = le16_to_cpu(prsp->context_id);
-	recv_ctx->virt_port = le16_to_cpu(prsp->virt_port);
+	recv_ctx->virt_port = prsp->virt_port;
 
 out_free_rsp:
 	pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr);
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index aa6e603..e8a0eed 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -539,16 +539,19 @@ static int nx_p3_sre_macaddr_change(struct net_device *dev,
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
 	nx_nic_req_t req;
-	nx_mac_req_t mac_req;
+	nx_mac_req_t *mac_req;
+	u64 word;
 	int rv;
 
 	memset(&req, 0, sizeof(nx_nic_req_t));
-	req.qhdr |= (NX_NIC_REQUEST << 23);
-	req.req_hdr |= NX_MAC_EVENT;
-	req.req_hdr |= ((u64)adapter->portnum << 16);
-	mac_req.op = op;
-	memcpy(&mac_req.mac_addr, addr, 6);
-	req.words[0] = cpu_to_le64(*(u64 *)&mac_req);
+	req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23);
+
+	word = NX_MAC_EVENT | ((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+
+	mac_req = (nx_mac_req_t *)&req.words[0];
+	mac_req->op = op;
+	memcpy(mac_req->mac_addr, addr, 6);
 
 	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
 	if (rv != 0) {
@@ -612,12 +615,16 @@ send_fw_cmd:
 int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
 {
 	nx_nic_req_t req;
+	u64 word;
 
 	memset(&req, 0, sizeof(nx_nic_req_t));
 
-	req.qhdr |= (NX_HOST_REQUEST << 23);
-	req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE;
-	req.req_hdr |= ((u64)adapter->portnum << 16);
+	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+	word = NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE |
+			((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
+
 	req.words[0] = cpu_to_le64(mode);
 
 	return netxen_send_cmd_descs(adapter,
@@ -632,13 +639,15 @@ int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
 int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
 {
 	nx_nic_req_t req;
+	u64 word;
 	int rv;
 
 	memset(&req, 0, sizeof(nx_nic_req_t));
 
-	req.qhdr |= (NX_NIC_REQUEST << 23);
-	req.req_hdr |= NETXEN_CONFIG_INTR_COALESCE;
-	req.req_hdr |= ((u64)adapter->portnum << 16);
+	req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23);
+
+	word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16);
+	req.req_hdr = cpu_to_le64(word);
 
 	memcpy(&req.words[0], &adapter->coal, sizeof(adapter->coal));
 
@@ -772,13 +781,10 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
 	adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4);
 	adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4);
 
-	mac_hi = cpu_to_le32(mac_hi);
-	mac_lo = cpu_to_le32(mac_lo);
-
 	if (pci_func & 1)
-		*mac = ((mac_lo >> 16) | ((u64)mac_hi << 16));
+		*mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16));
 	else
-		*mac = ((mac_lo) | ((u64)mac_hi << 32));
+		*mac = le64_to_cpu((u64)mac_lo | ((u64)mac_hi << 32));
 
 	return 0;
 }
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index d924468..c0e06a6 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -1277,7 +1277,7 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
 
 		dev_kfree_skb_any(skb);
 		for (i = 0; i < nr_frags; i++) {
-			index = frag_desc->frag_handles[i];
+			index = le16_to_cpu(frag_desc->frag_handles[i]);
 			skb = netxen_process_rxbuf(adapter,
 					rds_ring, index, cksum);
 			if (skb)
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCHv2 2/7] netxen: fix ipv6 offload and tx cleanup
  2009-01-13 19:52 [PATCHv2 0/7] netxen bugfixes Dhananjay Phadke
  2009-01-13 19:52 ` [PATCHv2 1/7] netxen: fix endianness in firmware commands Dhananjay Phadke
@ 2009-01-13 19:52 ` Dhananjay Phadke
  2009-01-13 19:52 ` [PATCHv2 3/7] netxen: fix link speed reporting for some boards Dhananjay Phadke
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Dhananjay Phadke @ 2009-01-13 19:52 UTC (permalink / raw)
  To: netdev; +Cc: davem

o fix the ip/tcp hdr offset in tx descriptors for ipv6.
o cleanup xmit function, move the tso checks into separate function,
  this reduces unnecessary endian conversions back and forth.
o optimize macros to initialize tx descriptors.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic.h      |   43 ++++----------
 drivers/net/netxen/netxen_nic_hw.c   |    4 -
 drivers/net/netxen/netxen_nic_main.c |  101 +++++++++++++++-------------------
 3 files changed, 57 insertions(+), 91 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 31311cc..acb2ac9 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -308,27 +308,16 @@ struct netxen_ring_ctx {
 #define netxen_set_cmd_desc_ctxid(cmd_desc, var)	\
 	((cmd_desc)->port_ctxid |= ((var) << 4 & 0xF0))
 
-#define netxen_set_cmd_desc_flags(cmd_desc, val)	\
-	(cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \
-		~cpu_to_le16(0x7f)) | cpu_to_le16((val) & 0x7f)
-#define netxen_set_cmd_desc_opcode(cmd_desc, val)	\
-	(cmd_desc)->flags_opcode = ((cmd_desc)->flags_opcode & \
-		~cpu_to_le16((u16)0x3f << 7)) | cpu_to_le16(((val) & 0x3f) << 7)
-
-#define netxen_set_cmd_desc_num_of_buff(cmd_desc, val)	\
-	(cmd_desc)->num_of_buffers_total_length = \
-		((cmd_desc)->num_of_buffers_total_length & \
-		~cpu_to_le32(0xff)) | cpu_to_le32((val) & 0xff)
-#define netxen_set_cmd_desc_totallength(cmd_desc, val)	\
-	(cmd_desc)->num_of_buffers_total_length = \
-		((cmd_desc)->num_of_buffers_total_length & \
-		~cpu_to_le32((u32)0xffffff << 8)) | \
-		cpu_to_le32(((val) & 0xffffff) << 8)
-
-#define netxen_get_cmd_desc_opcode(cmd_desc)	\
-	((le16_to_cpu((cmd_desc)->flags_opcode) >> 7) & 0x003f)
-#define netxen_get_cmd_desc_totallength(cmd_desc)	\
-	((le32_to_cpu((cmd_desc)->num_of_buffers_total_length) >> 8) & 0xffffff)
+#define netxen_set_tx_port(_desc, _port) \
+	(_desc)->port_ctxid = ((_port) & 0xf) | (((_port) << 4) & 0xf0)
+
+#define netxen_set_tx_flags_opcode(_desc, _flags, _opcode) \
+	(_desc)->flags_opcode = \
+	cpu_to_le16(((_flags) & 0x7f) | (((_opcode) & 0x3f) << 7))
+
+#define netxen_set_tx_frags_len(_desc, _frags, _len) \
+	(_desc)->num_of_buffers_total_length = \
+	cpu_to_le32(((_frags) & 0xff) | (((_len) & 0xffffff) << 8))
 
 struct cmd_desc_type0 {
 	u8 tcp_hdr_offset;	/* For LSO only */
@@ -757,7 +746,7 @@ extern char netxen_nic_driver_name[];
  */
 struct netxen_skb_frag {
 	u64 dma;
-	u32 length;
+	ulong length;
 };
 
 #define _netxen_set_bits(config_word, start, bits, val)	{\
@@ -783,13 +772,7 @@ struct netxen_skb_frag {
 struct netxen_cmd_buffer {
 	struct sk_buff *skb;
 	struct netxen_skb_frag frag_array[MAX_BUFFERS_PER_CMD + 1];
-	u32 total_length;
-	u32 mss;
-	u16 port;
-	u8 cmd;
-	u8 frag_count;
-	unsigned long time_stamp;
-	u32 state;
+	u32 frag_count;
 };
 
 /* In rx_buffer, we do not need multiple fragments as is a single buffer */
@@ -1486,8 +1469,6 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter);
 
 void netxen_initialize_adapter_ops(struct netxen_adapter *adapter);
 int netxen_init_firmware(struct netxen_adapter *adapter);
-void netxen_tso_check(struct netxen_adapter *adapter,
-		      struct cmd_desc_type0 *desc, struct sk_buff *skb);
 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 ctx,
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index e8a0eed..98d0bcd 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -508,12 +508,8 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
 		cmd_desc = &cmd_desc_arr[i];
 
 		pbuf = &adapter->cmd_buf_arr[producer];
-		pbuf->mss = 0;
-		pbuf->total_length = 0;
 		pbuf->skb = NULL;
-		pbuf->cmd = 0;
 		pbuf->frag_count = 0;
-		pbuf->port = 0;
 
 		/* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */
 		memcpy(&adapter->ahw.cmd_desc_head[producer],
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index ba01524..cb39123 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -39,6 +39,7 @@
 #include "netxen_nic_phan_reg.h"
 
 #include <linux/dma-mapping.h>
+#include <linux/if_vlan.h>
 #include <net/ip.h>
 
 MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
@@ -1137,29 +1138,46 @@ static int netxen_nic_close(struct net_device *netdev)
 	return 0;
 }
 
-void netxen_tso_check(struct netxen_adapter *adapter,
+static bool netxen_tso_check(struct net_device *netdev,
 		      struct cmd_desc_type0 *desc, struct sk_buff *skb)
 {
-	if (desc->mss) {
-		desc->total_hdr_length = (sizeof(struct ethhdr) +
-					  ip_hdrlen(skb) + tcp_hdrlen(skb));
+	bool tso = false;
+	u8 opcode = TX_ETHER_PKT;
 
-		if ((NX_IS_REVISION_P3(adapter->ahw.revision_id)) &&
-				(skb->protocol == htons(ETH_P_IPV6)))
-			netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO6);
-		else
-			netxen_set_cmd_desc_opcode(desc, TX_TCP_LSO);
+	if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
+			skb_shinfo(skb)->gso_size > 0) {
+
+		desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
+		desc->total_hdr_length =
+			skb_transport_offset(skb) + tcp_hdrlen(skb);
+
+		opcode = (skb->protocol == htons(ETH_P_IPV6)) ?
+				TX_TCP_LSO6 : TX_TCP_LSO;
+		tso = true;
 
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		if (ip_hdr(skb)->protocol == IPPROTO_TCP)
-			netxen_set_cmd_desc_opcode(desc, TX_TCP_PKT);
-		else if (ip_hdr(skb)->protocol == IPPROTO_UDP)
-			netxen_set_cmd_desc_opcode(desc, TX_UDP_PKT);
-		else
-			return;
+		u8 l4proto;
+
+		if (skb->protocol == htons(ETH_P_IP)) {
+			l4proto = ip_hdr(skb)->protocol;
+
+			if (l4proto == IPPROTO_TCP)
+				opcode = TX_TCP_PKT;
+			else if(l4proto == IPPROTO_UDP)
+				opcode = TX_UDP_PKT;
+		} else if (skb->protocol == htons(ETH_P_IPV6)) {
+			l4proto = ipv6_hdr(skb)->nexthdr;
+
+			if (l4proto == IPPROTO_TCP)
+				opcode = TX_TCPV6_PKT;
+			else if(l4proto == IPPROTO_UDP)
+				opcode = TX_UDPV6_PKT;
+		}
 	}
 	desc->tcp_hdr_offset = skb_transport_offset(skb);
 	desc->ip_hdr_offset = skb_network_offset(skb);
+	netxen_set_tx_flags_opcode(desc, 0, opcode);
+	return tso;
 }
 
 static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
@@ -1167,33 +1185,20 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	struct netxen_adapter *adapter = netdev_priv(netdev);
 	struct netxen_hardware_context *hw = &adapter->ahw;
 	unsigned int first_seg_len = skb->len - skb->data_len;
+	struct netxen_cmd_buffer *pbuf;
 	struct netxen_skb_frag *buffrag;
-	unsigned int i;
+	struct cmd_desc_type0 *hwdesc;
+	int i, k;
 
 	u32 producer, consumer;
-	u32 saved_producer = 0;
-	struct cmd_desc_type0 *hwdesc;
-	int k;
-	struct netxen_cmd_buffer *pbuf = NULL;
-	int frag_count;
-	int no_of_desc;
+	int frag_count, no_of_desc;
 	u32 num_txd = adapter->max_tx_desc_count;
+	bool is_tso = false;
 
 	frag_count = skb_shinfo(skb)->nr_frags + 1;
 
 	/* There 4 fragments per descriptor */
 	no_of_desc = (frag_count + 3) >> 2;
-	if (netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) {
-		if (skb_shinfo(skb)->gso_size > 0) {
-
-			no_of_desc++;
-			if ((ip_hdrlen(skb) + tcp_hdrlen(skb) +
-			     sizeof(struct ethhdr)) >
-			    (sizeof(struct cmd_desc_type0) - 2)) {
-				no_of_desc++;
-			}
-		}
-	}
 
 	producer = adapter->cmd_producer;
 	smp_mb();
@@ -1205,34 +1210,22 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	}
 
 	/* Copy the descriptors into the hardware    */
-	saved_producer = producer;
 	hwdesc = &hw->cmd_desc_head[producer];
 	memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
 	/* Take skb->data itself */
 	pbuf = &adapter->cmd_buf_arr[producer];
-	if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
-			skb_shinfo(skb)->gso_size > 0) {
-		pbuf->mss = skb_shinfo(skb)->gso_size;
-		hwdesc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
-	} else {
-		pbuf->mss = 0;
-		hwdesc->mss = 0;
-	}
-	pbuf->total_length = skb->len;
+
+	is_tso = netxen_tso_check(netdev, hwdesc, skb);
+
 	pbuf->skb = skb;
-	pbuf->cmd = TX_ETHER_PKT;
 	pbuf->frag_count = frag_count;
-	pbuf->port = adapter->portnum;
 	buffrag = &pbuf->frag_array[0];
 	buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len,
 				      PCI_DMA_TODEVICE);
 	buffrag->length = first_seg_len;
-	netxen_set_cmd_desc_totallength(hwdesc, skb->len);
-	netxen_set_cmd_desc_num_of_buff(hwdesc, frag_count);
-	netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT);
+	netxen_set_tx_frags_len(hwdesc, frag_count, skb->len);
+	netxen_set_tx_port(hwdesc, adapter->portnum);
 
-	netxen_set_cmd_desc_port(hwdesc, adapter->portnum);
-	netxen_set_cmd_desc_ctxid(hwdesc, adapter->portnum);
 	hwdesc->buffer1_length = cpu_to_le16(first_seg_len);
 	hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
 
@@ -1285,16 +1278,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	}
 	producer = get_next_index(producer, num_txd);
 
-	/* might change opcode to TX_TCP_LSO */
-	netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb);
-
 	/* For LSO, we need to copy the MAC/IP/TCP headers into
 	 * the descriptor ring
 	 */
-	if (netxen_get_cmd_desc_opcode(&hw->cmd_desc_head[saved_producer])
-	    == TX_TCP_LSO) {
+	if (is_tso) {
 		int hdr_len, first_hdr_len, more_hdr;
-		hdr_len = hw->cmd_desc_head[saved_producer].total_hdr_length;
+		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
 		if (hdr_len > (sizeof(struct cmd_desc_type0) - 2)) {
 			first_hdr_len = sizeof(struct cmd_desc_type0) - 2;
 			more_hdr = 1;
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCHv2 3/7] netxen: fix link speed reporting for some boards
  2009-01-13 19:52 [PATCHv2 0/7] netxen bugfixes Dhananjay Phadke
  2009-01-13 19:52 ` [PATCHv2 1/7] netxen: fix endianness in firmware commands Dhananjay Phadke
  2009-01-13 19:52 ` [PATCHv2 2/7] netxen: fix ipv6 offload and tx cleanup Dhananjay Phadke
@ 2009-01-13 19:52 ` Dhananjay Phadke
  2009-01-13 19:52 ` [PATCHv2 4/7] netxen: firmware init fix Dhananjay Phadke
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Dhananjay Phadke @ 2009-01-13 19:52 UTC (permalink / raw)
  To: netdev; +Cc: davem

o Read negotiated link speed when link state changes.
o Fix link speed reporting for hybrid nic boards, which have both 1Gbps and
  10Gbps ports.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic.h         |    3 ++-
 drivers/net/netxen/netxen_nic_ethtool.c |   31 +++++++++++++++++++++++--------
 drivers/net/netxen/netxen_nic_hw.c      |   28 ++++++++++++++++++++--------
 drivers/net/netxen/netxen_nic_main.c    |   14 +++++++++++++-
 4 files changed, 58 insertions(+), 18 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index acb2ac9..a674a23 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -499,7 +499,8 @@ typedef enum {
 	NETXEN_BRDTYPE_P3_10G_SFP_CT = 0x002a,
 	NETXEN_BRDTYPE_P3_10G_SFP_QT = 0x002b,
 	NETXEN_BRDTYPE_P3_10G_CX4 = 0x0031,
-	NETXEN_BRDTYPE_P3_10G_XFP = 0x0032
+	NETXEN_BRDTYPE_P3_10G_XFP = 0x0032,
+	NETXEN_BRDTYPE_P3_10G_TP = 0x0080
 
 } netxen_brdtype_t;
 
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index e45ce29..c0bd40f 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -136,11 +136,9 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 
 		ecmd->port = PORT_TP;
 
-		if (netif_running(dev)) {
-			ecmd->speed = adapter->link_speed;
-			ecmd->duplex = adapter->link_duplex;
-			ecmd->autoneg = adapter->link_autoneg;
-		}
+		ecmd->speed = adapter->link_speed;
+		ecmd->duplex = adapter->link_duplex;
+		ecmd->autoneg = adapter->link_autoneg;
 
 	} else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
 		u32 val;
@@ -171,7 +169,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 	} else
 		return -EIO;
 
-	ecmd->phy_address = adapter->portnum;
+	ecmd->phy_address = adapter->physical_port;
 	ecmd->transceiver = XCVR_EXTERNAL;
 
 	switch ((netxen_brdtype_t) boardinfo->board_type) {
@@ -180,13 +178,13 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 	case NETXEN_BRDTYPE_P3_REF_QG:
 	case NETXEN_BRDTYPE_P3_4_GB:
 	case NETXEN_BRDTYPE_P3_4_GB_MM:
-	case NETXEN_BRDTYPE_P3_10000_BASE_T:
 
 		ecmd->supported |= SUPPORTED_Autoneg;
 		ecmd->advertising |= ADVERTISED_Autoneg;
 	case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
 	case NETXEN_BRDTYPE_P3_10G_CX4:
 	case NETXEN_BRDTYPE_P3_10G_CX4_LP:
+	case NETXEN_BRDTYPE_P3_10000_BASE_T:
 		ecmd->supported |= SUPPORTED_TP;
 		ecmd->advertising |= ADVERTISED_TP;
 		ecmd->port = PORT_TP;
@@ -204,16 +202,33 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 		ecmd->port = PORT_FIBRE;
 		ecmd->autoneg = AUTONEG_DISABLE;
 		break;
-	case NETXEN_BRDTYPE_P2_SB31_10G:
 	case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
 	case NETXEN_BRDTYPE_P3_10G_SFP_CT:
 	case NETXEN_BRDTYPE_P3_10G_SFP_QT:
+		ecmd->advertising |= ADVERTISED_TP;
+		ecmd->supported |= SUPPORTED_TP;
+	case NETXEN_BRDTYPE_P2_SB31_10G:
 	case NETXEN_BRDTYPE_P3_10G_XFP:
 		ecmd->supported |= SUPPORTED_FIBRE;
 		ecmd->advertising |= ADVERTISED_FIBRE;
 		ecmd->port = PORT_FIBRE;
 		ecmd->autoneg = AUTONEG_DISABLE;
 		break;
+	case NETXEN_BRDTYPE_P3_10G_TP:
+		if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
+			ecmd->autoneg = AUTONEG_DISABLE;
+			ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
+			ecmd->advertising |=
+				(ADVERTISED_FIBRE | ADVERTISED_TP);
+			ecmd->port = PORT_FIBRE;
+		} else {
+			ecmd->autoneg = AUTONEG_ENABLE;
+			ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg);
+			ecmd->advertising |=
+				(ADVERTISED_TP | ADVERTISED_Autoneg);
+			ecmd->port = PORT_TP;
+		}
+		break;
 	default:
 		printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
 		       (netxen_brdtype_t) boardinfo->board_type);
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 98d0bcd..4276f7f 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -2036,7 +2036,13 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 		rv = -1;
 	}
 
-	DPRINTK(INFO, "Discovered board type:0x%x  ", boardinfo->board_type);
+	if (boardinfo->board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
+		u32 gpio = netxen_nic_reg_read(adapter,
+				NETXEN_ROMUSB_GLB_PAD_GPIO_I);
+		if ((gpio & 0x8000) == 0)
+			boardinfo->board_type = NETXEN_BRDTYPE_P3_10G_TP;
+	}
+
 	switch ((netxen_brdtype_t) boardinfo->board_type) {
 	case NETXEN_BRDTYPE_P2_SB35_4G:
 		adapter->ahw.board_type = NETXEN_NIC_GBE;
@@ -2055,7 +2061,6 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 	case NETXEN_BRDTYPE_P3_10G_SFP_QT:
 	case NETXEN_BRDTYPE_P3_10G_XFP:
 	case NETXEN_BRDTYPE_P3_10000_BASE_T:
-
 		adapter->ahw.board_type = NETXEN_NIC_XGBE;
 		break;
 	case NETXEN_BRDTYPE_P1_BD:
@@ -2065,9 +2070,12 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 	case NETXEN_BRDTYPE_P3_REF_QG:
 	case NETXEN_BRDTYPE_P3_4_GB:
 	case NETXEN_BRDTYPE_P3_4_GB_MM:
-
 		adapter->ahw.board_type = NETXEN_NIC_GBE;
 		break;
+	case NETXEN_BRDTYPE_P3_10G_TP:
+		adapter->ahw.board_type = (adapter->portnum < 2) ?
+			NETXEN_NIC_XGBE : NETXEN_NIC_GBE;
+		break;
 	default:
 		printk("%s: Unknown(%x)\n", netxen_nic_driver_name,
 		       boardinfo->board_type);
@@ -2112,12 +2120,16 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
 {
 	__u32 status;
 	__u32 autoneg;
-	__u32 mode;
 	__u32 port_mode;
 
-	netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode);
-	if (netxen_get_niu_enable_ge(mode)) {	/* Gb 10/100/1000 Mbps mode */
+	if (!netif_carrier_ok(adapter->netdev)) {
+		adapter->link_speed   = 0;
+		adapter->link_duplex  = -1;
+		adapter->link_autoneg = AUTONEG_ENABLE;
+		return;
+	}
 
+	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
 		adapter->hw_read_wx(adapter,
 				NETXEN_PORT_MODE_ADDR, &port_mode, 4);
 		if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
@@ -2143,7 +2155,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
 					adapter->link_speed = SPEED_1000;
 					break;
 				default:
-					adapter->link_speed = -1;
+					adapter->link_speed = 0;
 					break;
 				}
 				switch (netxen_get_phy_duplex(status)) {
@@ -2166,7 +2178,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
 				goto link_down;
 		} else {
 		      link_down:
-			adapter->link_speed = -1;
+			adapter->link_speed = 0;
 			adapter->link_duplex = -1;
 		}
 	}
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index cb39123..2c6ce6f 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -243,7 +243,7 @@ static void netxen_check_options(struct netxen_adapter *adapter)
 	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_10G;
+		adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
 		break;
 
 	case NETXEN_BRDTYPE_P2_SB35_4G:
@@ -252,6 +252,14 @@ static void netxen_check_options(struct netxen_adapter *adapter)
 		adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
 		break;
 
+	case NETXEN_BRDTYPE_P3_10G_TP:
+		adapter->msix_supported = !!use_msi_x;
+		if (adapter->ahw.board_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:
 		adapter->msix_supported = 0;
 		adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G;
@@ -1396,6 +1404,8 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
 			netif_carrier_off(netdev);
 			netif_stop_queue(netdev);
 		}
+
+		netxen_nic_set_link_parameters(adapter);
 	} else if (!adapter->ahw.linkup && linkup) {
 		printk(KERN_INFO "%s: %s NIC Link is up\n",
 		       netxen_nic_driver_name, netdev->name);
@@ -1404,6 +1414,8 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
 			netif_carrier_on(netdev);
 			netif_wake_queue(netdev);
 		}
+
+		netxen_nic_set_link_parameters(adapter);
 	}
 }
 
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCHv2 4/7] netxen: firmware init fix
  2009-01-13 19:52 [PATCHv2 0/7] netxen bugfixes Dhananjay Phadke
                   ` (2 preceding siblings ...)
  2009-01-13 19:52 ` [PATCHv2 3/7] netxen: fix link speed reporting for some boards Dhananjay Phadke
@ 2009-01-13 19:52 ` Dhananjay Phadke
  2009-01-13 19:52 ` [PATCHv2 5/7] netxen: cleanup mac list on driver unload Dhananjay Phadke
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Dhananjay Phadke @ 2009-01-13 19:52 UTC (permalink / raw)
  To: netdev; +Cc: davem

o Fix order or rom register writes.
o Reduce udelays when writing rom registers.

This cuts the firmware init time by 40%.

o Do not reset core/memory clocks when reinitializing driver.
  Firmware willl handle this when initialized.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic_hw.c   |    6 +---
 drivers/net/netxen/netxen_nic_init.c |   35 +++++++++++++++----------
 drivers/net/netxen/netxen_nic_main.c |   47 ++++++++++++++++++++-------------
 3 files changed, 51 insertions(+), 37 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 4276f7f..511db2a 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -939,7 +939,7 @@ int netxen_load_firmware(struct netxen_adapter *adapter)
 {
 	int i;
 	u32 data, size = 0;
-	u32 flashaddr = NETXEN_BOOTLD_START, memaddr = NETXEN_BOOTLD_START;
+	u32 flashaddr = NETXEN_BOOTLD_START;
 
 	size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START)/4;
 
@@ -951,10 +951,8 @@ int netxen_load_firmware(struct netxen_adapter *adapter)
 		if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0)
 			return -EIO;
 
-		adapter->pci_mem_write(adapter, memaddr, &data, 4);
+		adapter->pci_mem_write(adapter, flashaddr, &data, 4);
 		flashaddr += 4;
-		memaddr += 4;
-		cond_resched();
 	}
 	msleep(1);
 
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index c0e06a6..a320364 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -439,6 +439,8 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
 	long timeout = 0;
 	long done = 0;
 
+	cond_resched();
+
 	while (done == 0) {
 		done = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_GLB_STATUS);
 		done &= 2;
@@ -533,12 +535,9 @@ static int do_rom_fast_write(struct netxen_adapter *adapter, int addr,
 static int do_rom_fast_read(struct netxen_adapter *adapter,
 			    int addr, int *valp)
 {
-	cond_resched();
-
 	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
-	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
-	udelay(100);		/* prevent bursting on CRB */
 	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
 	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
 	if (netxen_wait_rom_done(adapter)) {
 		printk("Error waiting for rom done\n");
@@ -546,7 +545,7 @@ static int do_rom_fast_read(struct netxen_adapter *adapter,
 	}
 	/* reset abyte_cnt and dummy_byte_cnt */
 	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
-	udelay(100);		/* prevent bursting on CRB */
+	udelay(10);
 	netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
 
 	*valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA);
@@ -884,14 +883,16 @@ int netxen_flash_unlock(struct netxen_adapter *adapter)
 int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 {
 	int addr, val;
-	int i, init_delay = 0;
+	int i, n, init_delay = 0;
 	struct crb_addr_pair *buf;
-	unsigned offset, n;
+	unsigned offset;
 	u32 off;
 
 	/* resetall */
+	rom_lock(adapter);
 	netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
 				    0xffffffff);
+	netxen_rom_unlock(adapter);
 
 	if (verbose) {
 		if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0)
@@ -910,7 +911,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 
 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
 		if (netxen_rom_fast_read(adapter, 0, &n) != 0 ||
-			(n != 0xcafecafeUL) ||
+			(n != 0xcafecafe) ||
 			netxen_rom_fast_read(adapter, 4, &n) != 0) {
 			printk(KERN_ERR "%s: ERROR Reading crb_init area: "
 					"n: %08x\n", netxen_nic_driver_name, n);
@@ -975,6 +976,14 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 			/* do not reset PCI */
 			if (off == (ROMUSB_GLB + 0xbc))
 				continue;
+			if (off == (ROMUSB_GLB + 0xa8))
+				continue;
+			if (off == (ROMUSB_GLB + 0xc8)) /* core clock */
+				continue;
+			if (off == (ROMUSB_GLB + 0x24)) /* MN clock */
+				continue;
+			if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */
+				continue;
 			if (off == (NETXEN_CRB_PEG_NET_1 + 0x18))
 				buf[i].data = 0x1020;
 			/* skip the function enable register */
@@ -992,23 +1001,21 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 			continue;
 		}
 
+		init_delay = 1;
 		/* After writing this register, HW needs time for CRB */
 		/* to quiet down (else crb_window returns 0xffffffff) */
 		if (off == NETXEN_ROMUSB_GLB_SW_RESET) {
-			init_delay = 1;
+			init_delay = 1000;
 			if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
 				/* hold xdma in reset also */
 				buf[i].data = NETXEN_NIC_XDMA_RESET;
+				buf[i].data = 0x8000ff;
 			}
 		}
 
 		adapter->hw_write_wx(adapter, off, &buf[i].data, 4);
 
-		if (init_delay == 1) {
-			msleep(1000);
-			init_delay = 0;
-		}
-		msleep(1);
+		msleep(init_delay);
 	}
 	kfree(buf);
 
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 2c6ce6f..cbe2b3e 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -280,10 +280,15 @@ static void netxen_check_options(struct netxen_adapter *adapter)
 static int
 netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot)
 {
-	int ret = 0;
+	u32 val, timeout;
 
 	if (first_boot == 0x55555555) {
 		/* This is the first boot after power up */
+		adapter->pci_write_normalize(adapter,
+			NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
+
+		if (!NX_IS_REVISION_P2(adapter->ahw.revision_id))
+			return 0;
 
 		/* PCI bus master workaround */
 		adapter->hw_read_wx(adapter,
@@ -303,18 +308,26 @@ netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot)
 			/* clear the register for future unloads/loads */
 			adapter->pci_write_normalize(adapter,
 					NETXEN_CAM_RAM(0x1fc), 0);
-			ret = -1;
+			return -EIO;
 		}
 
-		if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-			/* Start P2 boot loader */
-			adapter->pci_write_normalize(adapter,
-				NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
-			adapter->pci_write_normalize(adapter,
-					NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1);
-		}
+		/* Start P2 boot loader */
+		val = adapter->pci_read_normalize(adapter,
+				NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
+		adapter->pci_write_normalize(adapter,
+				NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1);
+		timeout = 0;
+		do {
+			msleep(1);
+			val = adapter->pci_read_normalize(adapter,
+					NETXEN_CAM_RAM(0x1fc));
+
+			if (++timeout > 5000)
+				return -EIO;
+
+		} while (val == NETXEN_BDINFO_MAGIC);
 	}
-	return ret;
+	return 0;
 }
 
 static void netxen_set_port_mode(struct netxen_adapter *adapter)
@@ -793,8 +806,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 						CRB_CMDPEG_STATE, 0);
 			netxen_pinit_from_rom(adapter, 0);
 			msleep(1);
-			netxen_load_firmware(adapter);
 		}
+		netxen_load_firmware(adapter);
 
 		if (NX_IS_REVISION_P3(revision_id))
 			netxen_pcie_strap_init(adapter);
@@ -810,13 +823,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 		}
 
-		if ((first_boot == 0x55555555) &&
-			(NX_IS_REVISION_P2(revision_id))) {
-			/* Unlock the HW, prompting the boot sequence */
-			adapter->pci_write_normalize(adapter,
-					NETXEN_ROMUSB_GLB_PEGTUNE_DONE, 1);
-		}
-
 		err = netxen_initialize_adapter_offload(adapter);
 		if (err)
 			goto err_out_iounmap;
@@ -830,7 +836,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, i);
 
 		/* Handshake with the card before we register the devices. */
-		netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
+		err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
+		if (err)
+			goto err_out_free_offload;
 
 	}	/* first_driver */
 
@@ -934,6 +942,7 @@ err_out_disable_msi:
 	if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
 		pci_disable_msi(pdev);
 
+err_out_free_offload:
 	if (first_driver)
 		netxen_free_adapter_offload(adapter);
 
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCHv2 5/7] netxen: cleanup mac list on driver unload
  2009-01-13 19:52 [PATCHv2 0/7] netxen bugfixes Dhananjay Phadke
                   ` (3 preceding siblings ...)
  2009-01-13 19:52 ` [PATCHv2 4/7] netxen: firmware init fix Dhananjay Phadke
@ 2009-01-13 19:52 ` Dhananjay Phadke
  2009-01-13 19:52 ` [PATCHv2 6/7] netxen: hold tx lock while sending firmware commands Dhananjay Phadke
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Dhananjay Phadke @ 2009-01-13 19:52 UTC (permalink / raw)
  To: netdev; +Cc: davem

This fixes a tiny memory leak when driver is unloaded. The mac
address list maintained in netxen_adapter needs to deleted when
driver is going down.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic.h      |    1 +
 drivers/net/netxen/netxen_nic_hw.c   |   13 +++++++++++++
 drivers/net/netxen/netxen_nic_main.c |    3 +++
 3 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index a674a23..6598a34 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1478,6 +1478,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter);
 u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, 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);
 
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 511db2a..e2d2a2f 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -627,6 +627,19 @@ int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
 				(struct cmd_desc_type0 *)&req, 1);
 }
 
+void netxen_p3_free_mac_list(struct netxen_adapter *adapter)
+{
+	nx_mac_list_t *cur, *next;
+
+	cur = adapter->mac_list;
+
+	while (cur) {
+		next = cur->next;
+		kfree(cur);
+		cur = next;
+	}
+}
+
 #define	NETXEN_CONFIG_INTR_COALESCE	3
 
 /*
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index cbe2b3e..9268fd2 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -986,6 +986,9 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 		netxen_free_hw_resources(adapter);
 		netxen_release_rx_buffers(adapter);
 		netxen_free_sw_resources(adapter);
+
+		if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+			netxen_p3_free_mac_list(adapter);
 	}
 
 	if (adapter->portnum == 0)
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCHv2 6/7] netxen: hold tx lock while sending firmware commands
  2009-01-13 19:52 [PATCHv2 0/7] netxen bugfixes Dhananjay Phadke
                   ` (4 preceding siblings ...)
  2009-01-13 19:52 ` [PATCHv2 5/7] netxen: cleanup mac list on driver unload Dhananjay Phadke
@ 2009-01-13 19:52 ` Dhananjay Phadke
  2009-01-13 19:52 ` [PATCHv2 7/7] netxen: handle dma mapping failures Dhananjay Phadke
  2009-01-15  4:50 ` [PATCHv2 0/7] netxen bugfixes David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: Dhananjay Phadke @ 2009-01-13 19:52 UTC (permalink / raw)
  To: netdev; +Cc: davem

Some firmware commands like mac address addition/deletion are sent
on the transmit ring. So need to hold the tx lock before touching
tx producer/consumer indices.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic_hw.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index e2d2a2f..821cff6 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -503,6 +503,8 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
 
 	i = 0;
 
+	netif_tx_lock_bh(adapter->netdev);
+
 	producer = adapter->cmd_producer;
 	do {
 		cmd_desc = &cmd_desc_arr[i];
@@ -527,6 +529,8 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
 
 	netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer);
 
+	netif_tx_unlock_bh(adapter->netdev);
+
 	return 0;
 }
 
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCHv2 7/7] netxen: handle dma mapping failures
  2009-01-13 19:52 [PATCHv2 0/7] netxen bugfixes Dhananjay Phadke
                   ` (5 preceding siblings ...)
  2009-01-13 19:52 ` [PATCHv2 6/7] netxen: hold tx lock while sending firmware commands Dhananjay Phadke
@ 2009-01-13 19:52 ` Dhananjay Phadke
  2009-01-15  4:50 ` [PATCHv2 0/7] netxen bugfixes David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: Dhananjay Phadke @ 2009-01-13 19:52 UTC (permalink / raw)
  To: netdev; +Cc: davem

o Bail out if pci_map_single() fails while replenishing rx ring.
o Drop packet if pci_map_{single,page}() fail in tx.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
---
 drivers/net/netxen/netxen_nic.h      |    1 -
 drivers/net/netxen/netxen_nic_init.c |   68 ++++++++++++++++------------------
 drivers/net/netxen/netxen_nic_main.c |   38 +++++++++++++++++-
 3 files changed, 67 insertions(+), 40 deletions(-)

diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 6598a34..c11c568 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -860,7 +860,6 @@ struct nx_host_rds_ring {
 	u32 skb_size;
 	struct netxen_rx_buffer *rx_buf_arr;	/* rx buffers for receive   */
 	struct list_head free_list;
-	int begin_alloc;
 };
 
 /*
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index a320364..ca7c8d8 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -308,7 +308,6 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
 			}
 			memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE);
 			INIT_LIST_HEAD(&rds_ring->free_list);
-			rds_ring->begin_alloc = 0;
 			/*
 			 * Now go through all of them, set reference handles
 			 * and put them in the queues.
@@ -1435,7 +1434,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
 	struct rcv_desc *pdesc;
 	struct netxen_rx_buffer *buffer;
 	int count = 0;
-	int index = 0;
 	netxen_ctx_msg msg = 0;
 	dma_addr_t dma;
 	struct list_head *head;
@@ -1443,7 +1441,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
 	rds_ring = &recv_ctx->rds_rings[ringid];
 
 	producer = rds_ring->producer;
-	index = rds_ring->begin_alloc;
 	head = &rds_ring->free_list;
 
 	/* We can start writing rx descriptors into the phantom memory. */
@@ -1451,39 +1448,37 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
 
 		skb = dev_alloc_skb(rds_ring->skb_size);
 		if (unlikely(!skb)) {
-			rds_ring->begin_alloc = index;
 			break;
 		}
 
+		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);
+			break;
+		}
+
+		count++;
 		buffer = list_entry(head->next, struct netxen_rx_buffer, list);
 		list_del(&buffer->list);
 
-		count++;	/* now there should be no failure */
-		pdesc = &rds_ring->desc_head[producer];
-
-		if (!adapter->ahw.cut_through)
-			skb_reserve(skb, 2);
-		/* This will be setup when we receive the
-		 * buffer after it has been filled  FSL  TBD TBD
-		 * skb->dev = netdev;
-		 */
-		dma = pci_map_single(pdev, skb->data, rds_ring->dma_size,
-				     PCI_DMA_FROMDEVICE);
-		pdesc->addr_buffer = cpu_to_le64(dma);
 		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->reference_handle = cpu_to_le16(buffer->ref_handle);
 		pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
-		DPRINTK(INFO, "done writing descripter\n");
-		producer =
-		    get_next_index(producer, rds_ring->max_rx_desc_count);
-		index = get_next_index(index, rds_ring->max_rx_desc_count);
+
+		producer = get_next_index(producer, rds_ring->max_rx_desc_count);
 	}
 	/* if we did allocate buffers, then write the count to Phantom */
 	if (count) {
-		rds_ring->begin_alloc = index;
 		rds_ring->producer = producer;
 			/* Window = 1 */
 		adapter->pci_write_normalize(adapter,
@@ -1522,49 +1517,50 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
 	struct rcv_desc *pdesc;
 	struct netxen_rx_buffer *buffer;
 	int count = 0;
-	int index = 0;
 	struct list_head *head;
+	dma_addr_t dma;
 
 	rds_ring = &recv_ctx->rds_rings[ringid];
 
 	producer = rds_ring->producer;
-	index = rds_ring->begin_alloc;
 	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);
 		if (unlikely(!skb)) {
-			rds_ring->begin_alloc = index;
 			break;
 		}
 
+		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);
+			break;
+		}
+
+		count++;
 		buffer = list_entry(head->next, struct netxen_rx_buffer, list);
 		list_del(&buffer->list);
 
-		count++;	/* now there should be no failure */
-		pdesc = &rds_ring->desc_head[producer];
-		if (!adapter->ahw.cut_through)
-			skb_reserve(skb, 2);
 		buffer->skb = skb;
 		buffer->state = NETXEN_BUFFER_BUSY;
-		buffer->dma = pci_map_single(pdev, skb->data,
-					     rds_ring->dma_size,
-					     PCI_DMA_FROMDEVICE);
+		buffer->dma = dma;
 
 		/* make a rcv descriptor  */
+		pdesc = &rds_ring->desc_head[producer];
 		pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
 		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);
-		index = get_next_index(index, rds_ring->max_rx_desc_count);
-		buffer = &rds_ring->rx_buf_arr[index];
+
+		producer = get_next_index(producer, rds_ring->max_rx_desc_count);
 	}
 
 	/* if we did allocate buffers, then write the count to Phantom */
 	if (count) {
-		rds_ring->begin_alloc = index;
 		rds_ring->producer = producer;
 			/* Window = 1 */
 		adapter->pci_write_normalize(adapter,
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 9268fd2..8686740 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -1200,6 +1200,24 @@ static bool netxen_tso_check(struct net_device *netdev,
 	return tso;
 }
 
+static void
+netxen_clean_tx_dma_mapping(struct pci_dev *pdev,
+		struct netxen_cmd_buffer *pbuf, int last)
+{
+	int k;
+	struct netxen_skb_frag *buffrag;
+
+	buffrag = &pbuf->frag_array[0];
+	pci_unmap_single(pdev, buffrag->dma,
+			buffrag->length, PCI_DMA_TODEVICE);
+
+	for (k = 1; k < last; k++) {
+		buffrag = &pbuf->frag_array[k];
+		pci_unmap_page(pdev, buffrag->dma,
+			buffrag->length, PCI_DMA_TODEVICE);
+	}
+}
+
 static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct netxen_adapter *adapter = netdev_priv(netdev);
@@ -1208,6 +1226,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	struct netxen_cmd_buffer *pbuf;
 	struct netxen_skb_frag *buffrag;
 	struct cmd_desc_type0 *hwdesc;
+	struct pci_dev *pdev = adapter->pdev;
+	dma_addr_t temp_dma;
 	int i, k;
 
 	u32 producer, consumer;
@@ -1240,8 +1260,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	pbuf->skb = skb;
 	pbuf->frag_count = frag_count;
 	buffrag = &pbuf->frag_array[0];
-	buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len,
+	temp_dma = pci_map_single(pdev, skb->data, first_seg_len,
 				      PCI_DMA_TODEVICE);
+	if (pci_dma_mapping_error(pdev, temp_dma))
+		goto drop_packet;
+
+	buffrag->dma = temp_dma;
 	buffrag->length = first_seg_len;
 	netxen_set_tx_frags_len(hwdesc, frag_count, skb->len);
 	netxen_set_tx_port(hwdesc, adapter->portnum);
@@ -1253,7 +1277,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		struct skb_frag_struct *frag;
 		int len, temp_len;
 		unsigned long offset;
-		dma_addr_t temp_dma;
 
 		/* move to next desc. if there is a need */
 		if ((i & 0x3) == 0) {
@@ -1269,8 +1292,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		offset = frag->page_offset;
 
 		temp_len = len;
-		temp_dma = pci_map_page(adapter->pdev, frag->page, offset,
+		temp_dma = pci_map_page(pdev, frag->page, offset,
 					len, PCI_DMA_TODEVICE);
+		if (pci_dma_mapping_error(pdev, temp_dma)) {
+			netxen_clean_tx_dma_mapping(pdev, pbuf, i);
+			goto drop_packet;
+		}
 
 		buffrag++;
 		buffrag->dma = temp_dma;
@@ -1345,6 +1372,11 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	netdev->trans_start = jiffies;
 
 	return NETDEV_TX_OK;
+
+drop_packet:
+	adapter->stats.txdropped++;
+	dev_kfree_skb_any(skb);
+	return NETDEV_TX_OK;
 }
 
 static int netxen_nic_check_temp(struct netxen_adapter *adapter)
-- 
1.6.0.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCHv2 0/7] netxen bugfixes
  2009-01-13 19:52 [PATCHv2 0/7] netxen bugfixes Dhananjay Phadke
                   ` (6 preceding siblings ...)
  2009-01-13 19:52 ` [PATCHv2 7/7] netxen: handle dma mapping failures Dhananjay Phadke
@ 2009-01-15  4:50 ` David Miller
  7 siblings, 0 replies; 9+ messages in thread
From: David Miller @ 2009-01-15  4:50 UTC (permalink / raw)
  To: dhananjay; +Cc: netdev

From: Dhananjay Phadke <dhananjay@netxen.com>
Date: Tue, 13 Jan 2009 11:52:37 -0800

> >> Sending set of 13 bug fixes, cleanups and enhancements, generated on
> >> net-2.6.
> > 
> > Since the merge window is closed, you will need to seperate
> > out the pure bug fixes and just submit those for now.
> 
> Alright, here's the bugfix series [7 patches]. There's one sparse
> annotation patch besides this, I will submit it seprarately if
> bugfix windows allows that.

All applied to net-2.6, thank you.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2009-01-15  4:50 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-13 19:52 [PATCHv2 0/7] netxen bugfixes Dhananjay Phadke
2009-01-13 19:52 ` [PATCHv2 1/7] netxen: fix endianness in firmware commands Dhananjay Phadke
2009-01-13 19:52 ` [PATCHv2 2/7] netxen: fix ipv6 offload and tx cleanup Dhananjay Phadke
2009-01-13 19:52 ` [PATCHv2 3/7] netxen: fix link speed reporting for some boards Dhananjay Phadke
2009-01-13 19:52 ` [PATCHv2 4/7] netxen: firmware init fix Dhananjay Phadke
2009-01-13 19:52 ` [PATCHv2 5/7] netxen: cleanup mac list on driver unload Dhananjay Phadke
2009-01-13 19:52 ` [PATCHv2 6/7] netxen: hold tx lock while sending firmware commands Dhananjay Phadke
2009-01-13 19:52 ` [PATCHv2 7/7] netxen: handle dma mapping failures Dhananjay Phadke
2009-01-15  4:50 ` [PATCHv2 0/7] netxen bugfixes 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).