[ofa-general] [PATCH 5/5] nes: napi interface fix

Glenn Grundstrom NetEffect glenn at lists.openfabrics.org
Fri Nov 30 10:37:05 PST 2007


Modified the driver to support the 2.6.24 napi interface changes.
The napi interface is now used by default.

Signed-off-by: Glenn Grundstrom <ggrundstrom at neteffect.com>

---

diff --git a/drivers/infiniband/hw/nes/Makefile b/drivers/infiniband/hw/nes/Makefile
index 3514851..15a1a13 100644
--- a/drivers/infiniband/hw/nes/Makefile
+++ b/drivers/infiniband/hw/nes/Makefile
@@ -1,3 +1,5 @@
+EXTRA_CFLAGS += -DNES_NAPI
+
 obj-$(CONFIG_INFINIBAND_NES) += iw_nes.o
 
 iw_nes-objs := nes.o nes_hw.o nes_nic.o nes_utils.o nes_verbs.o nes_cm.o
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 623037d..d101117 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -2102,7 +2102,6 @@ int nes_cm_disconn_true(struct nes_qp *nesqp)
 	struct iw_cm_id *cm_id;
 	struct iw_cm_event cm_event;
 	struct nes_vnic *nesvnic;
-	/* struct nes_cm_node *cm_node = NULL; */
 	u16 last_ae;
 	u8 original_hw_tcp_state;
 	u8 original_ibqp_state;
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c
index 8b0193d..3a21a08 100644
--- a/drivers/infiniband/hw/nes/nes_hw.c
+++ b/drivers/infiniband/hw/nes/nes_hw.c
@@ -1232,6 +1232,12 @@ static void nes_replenish_nic_rq(struct nes_vnic *nesvnic)
 	nesnic = &nesvnic->nic;
 	nesdev = nesvnic->nesdev;
 	spin_lock_irqsave(&nesnic->rq_lock, flags);
+	if (nesnic->replenishing_rq !=0) {
+		spin_unlock_irqrestore(&nesnic->rq_lock, flags);
+		return;
+	}
+	nesnic->replenishing_rq = 1;
+	spin_unlock_irqrestore(&nesnic->rq_lock, flags);
 	do {
 		skb = dev_alloc_skb(nesvnic->max_frame_size);
 		if (skb) {
@@ -1275,7 +1281,7 @@ static void nes_replenish_nic_rq(struct nes_vnic *nesvnic)
 	if (rx_wqes_posted) {
 		nes_write32(nesdev->regs+NES_WQE_ALLOC, (rx_wqes_posted << 24) | nesnic->qp_id);
 	}
-	spin_unlock_irqrestore(&nesnic->rq_lock, flags);
+	nesnic->replenishing_rq = 0;
 }
 
 
@@ -2121,10 +2127,11 @@ void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq
 {
 	struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq);
 
-	netif_rx_schedule(nesdev->netdev[nesvnic->netdev_index]);
+	netif_rx_schedule(nesdev->netdev[nesvnic->netdev_index], &nesvnic->napi);
 }
 #endif
 
+
 /* The MAX_RQES_TO_PROCESS defines how many max read requests to complete before
 * getting out of nic_ce_handler
 */
@@ -2160,7 +2167,7 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
 	head = cq->cq_head;
 	cq_size = cq->cq_size;
 #ifdef NES_NAPI
-	nesvnic->cqes_pending = 1;
+	cq->cqes_pending = 1;
 #endif
 	do {
 		if (le32_to_cpu(cq->cq_vbase[head].cqe_words[NES_NIC_CQE_MISC_IDX]) &
@@ -2210,7 +2217,8 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
 			} else {
 				rqes_processed ++;
 #ifdef NES_NAPI
-				nesvnic->rx_cqes_completed++;
+				cq->rx_cqes_completed++;
+				cq->rx_pkts_indicated++;
 #endif
 				rx_pkt_size = cqe_misc & 0x0000ffff;
 				nic_rqe = &nesnic->rq_vbase[nesnic->rq_tail];
@@ -2281,18 +2289,9 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
 								>> 16);
 						nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n",
 								nesvnic->netdev->name, vlan_tag);
-
-#ifdef NES_NAPI
-						vlan_hwaccel_receive_skb(rx_skb, nesvnic->vlan_grp, vlan_tag);
-#else
-						vlan_hwaccel_rx(rx_skb, nesvnic->vlan_grp, vlan_tag);
-#endif
+						nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag);
 					} else {
-#ifdef NES_NAPI
-						netif_receive_skb(rx_skb);
-#else
-						netif_rx(rx_skb);
-#endif
+						nes_netif_rx(rx_skb);
 					}
 				}
 
@@ -2314,11 +2313,11 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
 				cqe_count = 0;
 			}
 #ifdef NES_NAPI
-			if (nesvnic->rx_cqes_completed >= nesvnic->budget)
+			if (cq->rx_cqes_completed >= nesvnic->budget)
 				break;
 #endif
 		} else {
-			nesvnic->cqes_pending = 0;
+			cq->cqes_pending = 0;
 			break;
 		}
 #ifndef NES_NAPI
@@ -2332,7 +2331,7 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
 	/* nes_debug(NES_DBG_CQ, "CQ%u Processed = %u cqes, new head = %u.\n",
 			cq->cq_number, cqe_count, cq->cq_head); */
 #ifdef NES_NAPI
-	nesvnic->cqe_allocs_pending = cqe_count;
+	cq->cqe_allocs_pending = cqe_count;
 #else
 	/* Arm the CCQ */
 	nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h
index 21ec22c..51bb87f 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -361,6 +361,7 @@ enum nes_cqe_opcode_bits {
 	NES_CQE_VALID = (1<<31),
 };
 
+
 enum nes_cqe_word_idx {
 	NES_CQE_PAYLOAD_LENGTH_IDX = 0,
 	NES_CQE_COMP_COMP_CTX_LOW_IDX = 2,
@@ -810,6 +811,7 @@ struct nes_hw_aeqe {
 	__le32 aeqe_words[4];
 };
 
+
 struct nes_cqp_request {
 	wait_queue_head_t     waitq;
 	struct nes_hw_cqp_wqe cqp_wqe;
@@ -857,6 +859,8 @@ struct nes_hw_nic {
 	u16 rq_head;
 	u16 rq_tail;
 	u16 rq_size;
+	u8 replenishing_rq;
+	u8 reserved;
 
 	spinlock_t sq_lock;
 	spinlock_t rq_lock;
@@ -866,9 +870,13 @@ struct nes_hw_nic_cq {
 	struct nes_hw_nic_cqe volatile *cq_vbase;	/* PCI memory for host rings */
 	void (*ce_handler)(struct nes_device *nesdev, struct nes_hw_nic_cq *cq);
 	dma_addr_t cq_pbase;	/* PCI memory for host rings */
+	int rx_cqes_completed;
+	int cqe_allocs_pending;
+	int rx_pkts_indicated;
 	u16 cq_head;
 	u16 cq_size;
 	u16 cq_number;
+	u8  cqes_pending;
 };
 
 struct nes_hw_qp {
@@ -1131,12 +1139,12 @@ struct nes_vnic {
 	atomic_t          rx_skbs_needed;
 	atomic_t          rx_skb_timer_running;
 	int               budget;
-	int               rx_cqes_completed;
-	int               cqe_allocs_pending;
 	u32               msg_enable;
 	/* u32 tx_avail; */
 	__be32            local_ipaddr;
-
+#ifdef NES_NAPI
+	struct napi_struct   napi;
+#endif
 	spinlock_t           tx_lock;	/* could use netdev tx lock? */
 	struct timer_list    rq_wqes_timer;
 	u32                  nic_mem_size;
@@ -1159,7 +1167,6 @@ struct nes_vnic {
 	u8  next_qp_nic_index;
 	u8  of_device_registered;
 	u8  rdma_enabled;
-	u8  cqes_pending;
 	u8  rx_checksum_disabled;
 };
 
@@ -1178,5 +1185,13 @@ struct nes_ib_device {
 	u32 num_pd;
 };
 
+#ifdef NES_NAPI
+#define nes_vlan_rx vlan_hwaccel_receive_skb
+#define nes_netif_rx netif_receive_skb
+#else
+#define nes_vlan_rx vlan_hwaccel_rx
+#define nes_netif_rx netif_rx
+#endif
+
 #endif 		/* __NES_HW_H */
 
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index 5c9ab37..4133a44 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -139,37 +139,36 @@ static int nes_netdev_change_mtu(struct net_device *, int);
 /**
  * nes_netdev_poll
  */
-static int nes_netdev_poll(struct net_device* netdev, int* budget)
+static int nes_netdev_poll(struct napi_struct *napi, int budget)
 {
-	struct nes_vnic *nesvnic = netdev_priv(netdev);
+	struct nes_vnic *nesvnic = container_of(napi, struct nes_vnic, napi);
+	struct net_device *netdev = nesvnic->netdev;
 	struct nes_device *nesdev = nesvnic->nesdev;
 	struct nes_hw_nic_cq *nescq = &nesvnic->nic_cq;
 
-	nesvnic->budget = *budget;
-	nesvnic->cqes_pending = 0;
-	nesvnic->rx_cqes_completed = 0;
-	nesvnic->cqe_allocs_pending = 0;
+	nesvnic->budget = budget;
+	nescq->cqes_pending = 0;
+	nescq->rx_cqes_completed = 0;
+	nescq->cqe_allocs_pending = 0;
+	nescq->rx_pkts_indicated = 0;
 
 	nes_nic_ce_handler(nesdev, nescq);
 
-	netdev->quota -= nesvnic->rx_cqes_completed;
-	*budget -= nesvnic->rx_cqes_completed;
-
-	if (nesvnic->cqes_pending == 0) {
-		netif_rx_complete(netdev);
+	if (nescq->cqes_pending == 0) {
+		netif_rx_complete(netdev, napi);
 		/* clear out completed cqes and arm */
 		nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
-				nescq->cq_number | (nesvnic->cqe_allocs_pending << 16));
+				nescq->cq_number | (nescq->cqe_allocs_pending << 16));
 		nes_read32(nesdev->regs+NES_CQE_ALLOC);
 	} else {
 		/* clear out completed cqes but don't arm */
 		nes_write32(nesdev->regs+NES_CQE_ALLOC,
-				nescq->cq_number | (nesvnic->cqe_allocs_pending << 16));
+				nescq->cq_number | (nescq->cqe_allocs_pending << 16));
 		nes_debug(NES_DBG_NETDEV, "%s: exiting with work pending\n",
 				nesvnic->netdev->name);
 	}
 
-	return (nesvnic->cqes_pending == 0) ? 0 : 1;
+	return nescq->rx_pkts_indicated;
 }
 #endif
 
@@ -277,9 +276,11 @@ static int nes_netdev_open(struct net_device *netdev)
 		/* Enable network packets */
 		nesvnic->linkup = 1;
 		netif_start_queue(netdev);
-	} else {
-		netif_carrier_off(netdev);
+		netif_carrier_on(netdev);
 	}
+#ifdef NES_NAPI
+	napi_enable(&nesvnic->napi);
+#endif
 	nesvnic->netdev_open = 1;
 
 	return 0;
@@ -305,6 +306,9 @@ static int nes_netdev_stop(struct net_device *netdev)
 		printk(KERN_INFO PFX "%s: disabling interface\n", netdev->name);
 
 	/* Disable network packets */
+#ifdef NES_NAPI
+	napi_disable(&nesvnic->napi);
+#endif
 	netif_stop_queue(netdev);
 	if ((nesdev->netdev[0] == netdev) & (nesvnic->logical_port == nesdev->mac_index)) {
 		nes_write_indexed(nesdev,
@@ -1548,6 +1552,9 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
 
 	SET_NETDEV_DEV(netdev, &nesdev->pcidev->dev);
 
+	nesvnic = netdev_priv(netdev);
+	memset(nesvnic, 0, sizeof(*nesvnic));
+
 	netdev->open = nes_netdev_open;
 	netdev->stop = nes_netdev_stop;
 	netdev->hard_start_xmit = nes_netdev_start_xmit;
@@ -1567,8 +1574,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
 	netdev->features = NETIF_F_HIGHDMA;
 	netdev->ethtool_ops = &nes_ethtool_ops;
 #ifdef NES_NAPI
-	netdev->poll = nes_netdev_poll;
-	netdev->weight = 128;
+	netif_napi_add(netdev, &nesvnic->napi, nes_netdev_poll, 128);
 #endif
 #ifdef NETIF_F_HW_VLAN_TX
 	nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n");
@@ -1580,9 +1586,6 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
 #endif
 
 	/* Fill in the port structure */
-	nesvnic = netdev_priv(netdev);
-
-	memset(nesvnic, 0, sizeof(*nesvnic));
 	nesvnic->netdev = netdev;
 	nesvnic->nesdev = nesdev;
 	nesvnic->msg_enable = netif_msg_init(debug, default_msg);
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c
index 5fb241a..36d34f4 100644
--- a/drivers/infiniband/hw/nes/nes_verbs.c
+++ b/drivers/infiniband/hw/nes/nes_verbs.c
@@ -1099,8 +1099,6 @@ static int nes_setup_virt_qp(struct nes_qp *nesqp, struct nes_pbl *nespbl,
 
 	nesqp->hwqp.sq_vbase = kmap(nespbl->page);
 	nesqp->page = nespbl->page;
-
-	nesqp->hwqp.sq_vbase = ioremap(nesqp->hwqp.sq_pbase, PAGE_SIZE);
 	if (!nesqp->hwqp.sq_vbase) {
 		nes_debug(NES_DBG_QP, "QP sq_vbase kmap failed\n");
 		kfree(nespbl);
@@ -2712,7 +2710,6 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
 			list_for_each_entry(chunk, &region->chunk_list, list) {
 				for (nmap_index = 0; nmap_index < chunk->nmap; ++nmap_index) {
 					chunk_pages = sg_dma_len(&chunk->page_list[nmap_index]) >> PAGE_SHIFT;
-					/* nespbl->page = chunk->page_list[0].page; */
 					nespbl->page = sg_page(&chunk->page_list[0]);
 					for (page_index=0; page_index<chunk_pages; page_index++) {
 						((u32 *)pbl)[0] = cpu_to_le32((u32)



More information about the general mailing list