[ewg] [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, ®ion->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 ewg
mailing list