PERFORCE change 128493 for review

Kip Macy kmacy at FreeBSD.org
Thu Nov 1 18:31:54 PDT 2007


http://perforce.freebsd.org/chv.cgi?CH=128493

Change 128493 by kmacy at freefall_kmacy_iwarp on 2007/11/02 01:31:35

	IFtoestack #128449

Affected files ...

.. //depot/projects/iwarp/sys/amd64/conf/MULTIQ#2 integrate
.. //depot/projects/iwarp/sys/conf/files#3 integrate
.. //depot/projects/iwarp/sys/dev/cxgb/cxgb_adapter.h#3 integrate
.. //depot/projects/iwarp/sys/dev/cxgb/cxgb_l2t.c#3 integrate
.. //depot/projects/iwarp/sys/dev/cxgb/cxgb_l2t.h#3 integrate
.. //depot/projects/iwarp/sys/dev/cxgb/cxgb_main.c#3 integrate
.. //depot/projects/iwarp/sys/dev/cxgb/cxgb_multiq.c#3 integrate
.. //depot/projects/iwarp/sys/dev/cxgb/cxgb_offload.c#3 integrate
.. //depot/projects/iwarp/sys/dev/cxgb/cxgb_offload.h#3 integrate
.. //depot/projects/iwarp/sys/dev/cxgb/cxgb_sge.c#3 integrate
.. //depot/projects/iwarp/sys/dev/cxgb/sys/mvec.h#2 integrate
.. //depot/projects/iwarp/sys/dev/cxgb/t3cdev.h#2 integrate
.. //depot/projects/iwarp/sys/dev/cxgb/ulp/toecore/toedev.c#1 branch
.. //depot/projects/iwarp/sys/dev/cxgb/ulp/toecore/toedev.h#2 integrate
.. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#1 branch
.. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_cpl_socket.c#1 branch
.. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_defs.h#1 branch
.. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_listen.c#1 branch
.. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_t3_ddp.h#1 branch
.. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_tom.c#1 branch
.. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_tom.h#1 branch
.. //depot/projects/iwarp/sys/dev/cxgb/ulp/tom/cxgb_tom_sysctl.c#1 branch
.. //depot/projects/iwarp/sys/modules/cxgb/Makefile#2 integrate
.. //depot/projects/iwarp/sys/modules/cxgb/toecore/Makefile#1 branch
.. //depot/projects/iwarp/sys/modules/cxgb/tom/Makefile#1 branch
.. //depot/projects/iwarp/sys/net/if.h#2 integrate
.. //depot/projects/iwarp/sys/net/route.c#3 integrate
.. //depot/projects/iwarp/sys/net/route.h#2 integrate
.. //depot/projects/iwarp/sys/netinet/if_ether.c#3 integrate
.. //depot/projects/iwarp/sys/netinet/ip_icmp.c#3 integrate
.. //depot/projects/iwarp/sys/netinet/tcp_ofld.c#1 branch
.. //depot/projects/iwarp/sys/netinet/tcp_ofld.h#1 branch
.. //depot/projects/iwarp/sys/netinet/tcp_subr.c#3 integrate
.. //depot/projects/iwarp/sys/netinet/tcp_usrreq.c#3 integrate
.. //depot/projects/iwarp/sys/netinet/tcp_var.h#2 integrate
.. //depot/projects/iwarp/sys/sys/param.h#3 integrate
.. //depot/projects/iwarp/sys/sys/socket.h#2 integrate

Differences ...

==== //depot/projects/iwarp/sys/amd64/conf/MULTIQ#2 (text+ko) ====

@@ -80,6 +80,8 @@
 # CPU frequency control
 device		cpufreq
 
+options HWPMC_HOOKS
+
 # Bus support.
 device		acpi
 device		pci

==== //depot/projects/iwarp/sys/conf/files#3 (text+ko) ====

@@ -1893,6 +1893,7 @@
 netinet/tcp_timer.c		optional inet
 netinet/tcp_timewait.c		optional inet
 netinet/tcp_usrreq.c		optional inet
+netinet/tcp_ofld.c		optional inet
 netinet/udp_usrreq.c		optional inet
 netinet/libalias/alias.c	optional libalias | netgraph_nat
 netinet/libalias/alias_db.c	optional libalias | netgraph_nat

==== //depot/projects/iwarp/sys/dev/cxgb/cxgb_adapter.h#3 (text+ko) ====

@@ -151,11 +151,9 @@
 #define RSPQ_Q_SIZE	1024
 #define TX_ETH_Q_SIZE	1024
 
-/*
- * Types of Tx queues in each queue set.  Order here matters, do not change.
- * XXX TOE is not implemented yet, so the extra queues are just placeholders.
- */
-enum { TXQ_ETH, TXQ_OFLD, TXQ_CTRL };
+enum { TXQ_ETH = 0,
+       TXQ_OFLD = 1,
+       TXQ_CTRL = 2, };
 
 
 /* careful, the following are set on priv_flags and must not collide with

==== //depot/projects/iwarp/sys/dev/cxgb/cxgb_l2t.c#3 (text+ko) ====

@@ -59,7 +59,7 @@
 
 #define VLAN_NONE 0xfff
 #define SDL(s) ((struct sockaddr_dl *)s) 
-#define RT_ENADDR(rt)  ((u_char *)LLADDR(SDL((rt))))
+#define RT_ENADDR(sa)  ((u_char *)LLADDR(SDL((sa))))
 #define rt_expire rt_rmx.rmx_expire 
 
 struct llinfo_arp { 
@@ -103,11 +103,8 @@
 	RT_ADDREF(rt);
 	RT_UNLOCK(rt);
 	
-	if (e->neigh) {
-		RT_LOCK(e->neigh);
-		RT_REMREF(e->neigh);
-		RT_UNLOCK(e->neigh);
-	}
+	if (e->neigh)
+		RTFREE(e->neigh);
 	e->neigh = rt;
 }
 
@@ -130,13 +127,14 @@
 	 * XXX MH_ALIGN
 	 */
 	req = mtod(m, struct cpl_l2t_write_req *);
+	m->m_pkthdr.len = m->m_len = sizeof(*req);
+	
 	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, e->idx));
 	req->params = htonl(V_L2T_W_IDX(e->idx) | V_L2T_W_IFF(e->smt_idx) |
 			    V_L2T_W_VLAN(e->vlan & EVL_VLID_MASK) |
 			    V_L2T_W_PRIO(vlan_prio(e)));
 
-	memcpy(e->dmac, RT_ENADDR(e->neigh), sizeof(e->dmac));
 	memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac));
 	m_set_priority(m, CPL_PRIORITY_CONTROL);
 	cxgb_ofld_send(dev, m);
@@ -172,17 +170,14 @@
 		     struct l2t_entry *e)
 {
 	struct rtentry *rt;
-	struct mbuf *m0;
 	
-	if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
-		return (ENOMEM);
-
 	rt = e->neigh;
+	printf("send slow on rt=%p\n", rt);
 	
 again:
 	switch (e->state) {
 	case L2T_STATE_STALE:     /* entry is stale, kick off revalidation */
-		arpresolve(rt->rt_ifp, rt, m0, rt->rt_gateway, RT_ENADDR(rt));
+		arpresolve(rt->rt_ifp, rt, NULL, rt_key(rt), e->dmac);
 		mtx_lock(&e->lock);
 		if (e->state == L2T_STATE_STALE)
 			e->state = L2T_STATE_VALID;
@@ -197,9 +192,8 @@
 		}
 		arpq_enqueue(e, m);
 		mtx_unlock(&e->lock);
-
-		if ((m0 = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
-			return (ENOMEM);
+		printf("enqueueing arp request\n");
+		
 		/*
 		 * Only the first packet added to the arpq should kick off
 		 * resolution.  However, because the m_gethdr below can fail,
@@ -208,7 +202,10 @@
 		 * A better way would be to use a work request to retry L2T
 		 * entries when there's no memory.
 		 */
-		if (arpresolve(rt->rt_ifp, rt, m0, rt->rt_gateway, RT_ENADDR(rt)) == 0) {
+		printf("doing arpresolve\n");
+		if (arpresolve(rt->rt_ifp, rt, NULL, rt_key(rt), e->dmac) == 0) {
+			if ((m = m_gethdr(M_NOWAIT, MT_DATA)) == NULL)
+				return (ENOMEM);
 
 			mtx_lock(&e->lock);
 			if (e->arpq_head) 
@@ -216,7 +213,8 @@
 			else
 				m_freem(m);
 			mtx_unlock(&e->lock);
-		}
+		} else
+			printf("arpresolve returned non-zero\n");
 	}
 	return 0;
 }
@@ -234,7 +232,7 @@
 again:
 	switch (e->state) {
 	case L2T_STATE_STALE:     /* entry is stale, kick off revalidation */
-		arpresolve(rt->rt_ifp, rt, m0, rt->rt_gateway, RT_ENADDR(rt));
+		arpresolve(rt->rt_ifp, rt, m0, rt_key(rt), e->dmac);
 		mtx_lock(&e->lock);
 		if (e->state == L2T_STATE_STALE) {
 			e->state = L2T_STATE_VALID;
@@ -261,7 +259,7 @@
 		 * A better way would be to use a work request to retry L2T
 		 * entries when there's no memory.
 		 */
-		arpresolve(rt->rt_ifp, rt, m0, rt->rt_gateway, RT_ENADDR(rt));
+		arpresolve(rt->rt_ifp, rt, m0, rt_key(rt), e->dmac);
 
 	}
 	return;
@@ -301,6 +299,7 @@
 			}
 		e->state = L2T_STATE_UNUSED;
 	}
+	
 	return e;
 }
 
@@ -318,19 +317,21 @@
 void
 t3_l2e_free(struct l2t_data *d, struct l2t_entry *e)
 {
+	struct rtentry *rt = NULL;
+	
 	mtx_lock(&e->lock);
 	if (atomic_load_acq_int(&e->refcnt) == 0) {  /* hasn't been recycled */
-		if (e->neigh) {
-			RT_LOCK(e->neigh);
-			RT_REMREF(e->neigh);
-			RT_UNLOCK(e->neigh);
-			e->neigh = NULL;
-		}
+		rt = e->neigh;
+		e->neigh = NULL;
 	}
+	
 	mtx_unlock(&e->lock);
 	atomic_add_int(&d->nfree, 1);
+	if (rt)
+		RTFREE(rt);
 }
 
+
 /*
  * Update an L2T entry that was previously used for the same next hop as neigh.
  * Must be called with softirqs disabled.
@@ -346,7 +347,7 @@
 	if (neigh != e->neigh)
 		neigh_replace(e, neigh);
 	
-	if (memcmp(e->dmac, RT_ENADDR(neigh), sizeof(e->dmac)) ||
+	if (memcmp(e->dmac, RT_ENADDR(neigh->rt_gateway), sizeof(e->dmac)) ||
 	    (neigh->rt_expire > time_uptime))
 		e->state = L2T_STATE_RESOLVING;
 	else if (la->la_hold == NULL)
@@ -379,14 +380,20 @@
 	/* Need to allocate a new entry */
 	e = alloc_l2e(d);
 	if (e) {
+		printf("initializing new entry\n");
+		
 		mtx_lock(&e->lock);          /* avoid race with t3_l2t_free */
 		e->next = d->l2tab[hash].first;
 		d->l2tab[hash].first = e;
+		rw_wunlock(&d->lock);
+		
 		e->state = L2T_STATE_RESOLVING;
 		e->addr = addr;
 		e->ifindex = ifidx;
 		e->smt_idx = smt_idx;
 		atomic_store_rel_int(&e->refcnt, 1);
+		e->neigh = NULL;
+		
 		neigh_replace(e, neigh);
 #ifdef notyet
 		/* 
@@ -398,7 +405,10 @@
 #endif			    
 			e->vlan = VLAN_NONE;
 		mtx_unlock(&e->lock);
+
+		return (e);
 	}
+	
 done:
 	rw_wunlock(&d->lock);
 	return e;
@@ -433,11 +443,6 @@
 
 }
 
-#if defined(NETEVENT) || !defined(CONFIG_CHELSIO_T3_MODULE)
-/*
- * Called when the host's ARP layer makes a change to some entry that is
- * loaded into the HW L2 table.
- */
 void
 t3_l2t_update(struct t3cdev *dev, struct rtentry *neigh)
 {
@@ -448,7 +453,11 @@
 	int ifidx = neigh->rt_ifp->if_index;
 	int hash = arp_hash(addr, ifidx, d);
 	struct llinfo_arp *la;
+	u_char edst[ETHER_ADDR_LEN];
 	
+
+	arpresolve(neigh->rt_ifp, neigh, NULL, rt_key(neigh), edst);
+	
 	rw_rlock(&d->lock);
 	for (e = d->l2tab[hash].first; e; e = e->next)
 		if (e->addr == addr && e->ifindex == ifidx) {
@@ -460,6 +469,8 @@
 
 found:
 	rw_runlock(&d->lock);
+	memcpy(e->dmac, edst, ETHER_ADDR_LEN);
+	
 	if (atomic_load_acq_int(&e->refcnt)) {
 		if (neigh != e->neigh)
 			neigh_replace(e, neigh);
@@ -470,12 +481,11 @@
 			if (la->la_asked >= 5 /* arp_maxtries */) {
 				arpq = e->arpq_head;
 				e->arpq_head = e->arpq_tail = NULL;
-			} else if (la->la_hold == NULL)
+			} else
 				setup_l2e_send_pending(dev, NULL, e);
 		} else {
-			e->state = (la->la_hold == NULL) ?
-				L2T_STATE_VALID : L2T_STATE_STALE;
-			if (memcmp(e->dmac, RT_ENADDR(neigh), 6))
+			e->state = L2T_STATE_VALID;
+			if (memcmp(e->dmac, RT_ENADDR(neigh->rt_gateway), 6))
 				setup_l2e_send_pending(dev, NULL, e);
 		}
 	}
@@ -484,72 +494,7 @@
 	if (arpq)
 		handle_failed_resolution(dev, arpq);
 }
-#else
-/*
- * Called from a kprobe, interrupts are off.
- */
-void
-t3_l2t_update(struct t3cdev *dev, struct rtentry *neigh)
-{
-	struct l2t_entry *e;
-	struct l2t_data *d = L2DATA(dev);
-	u32 addr = *(u32 *) rt_key(neigh);
-	int ifidx = neigh->dev->ifindex;
-	int hash = arp_hash(addr, ifidx, d);
-
-	rw_rlock(&d->lock);
-	for (e = d->l2tab[hash].first; e; e = e->next)
-		if (e->addr == addr && e->ifindex == ifidx) {
-			mtx_lock(&e->lock);
-			if (atomic_load_acq_int(&e->refcnt)) {
-				if (neigh != e->neigh)
-					neigh_replace(e, neigh);
-				e->tdev = dev;
-				mod_timer(&e->update_timer, jiffies + 1);
-			}
-			mtx_unlock(&e->lock);
-			break;
-		}
-	rw_runlock(&d->lock);
-}
-
-static void
-update_timer_cb(unsigned long data)
-{
-	struct mbuf *arpq = NULL;
-	struct l2t_entry *e = (struct l2t_entry *)data;
-	struct rtentry *neigh = e->neigh;
-	struct t3cdev *dev = e->tdev;
 
-	barrier();
-	if (!atomic_load_acq_int(&e->refcnt))
-		return;
-
-	rw_rlock(&neigh->lock);
-	mtx_lock(&e->lock);
-
-	if (atomic_load_acq_int(&e->refcnt)) {
-		if (e->state == L2T_STATE_RESOLVING) {
-			if (neigh->nud_state & NUD_FAILED) {
-				arpq = e->arpq_head;
-				e->arpq_head = e->arpq_tail = NULL;
-			} else if (neigh_is_connected(neigh) && e->arpq_head)
-				setup_l2e_send_pending(dev, NULL, e);
-		} else {
-			e->state = neigh_is_connected(neigh) ?
-				L2T_STATE_VALID : L2T_STATE_STALE;
-			if (memcmp(e->dmac, RT_ENADDR(neigh), sizeof(e->dmac)))
-				setup_l2e_send_pending(dev, NULL, e);
-		}
-	}
-	mtx_unlock(&e->lock);
-	rw_runlock(&neigh->lock);
-
-	if (arpq)
-		handle_failed_resolution(dev, arpq);
-}
-#endif
-
 struct l2t_data *
 t3_init_l2t(unsigned int l2t_capacity)
 {
@@ -570,12 +515,6 @@
 		d->l2tab[i].state = L2T_STATE_UNUSED;
 		mtx_init(&d->l2tab[i].lock, "L2TAB", NULL, MTX_DEF);
 		atomic_store_rel_int(&d->l2tab[i].refcnt, 0);
-#ifndef NETEVENT
-#ifdef CONFIG_CHELSIO_T3_MODULE
-		setup_timer(&d->l2tab[i].update_timer, update_timer_cb,
-			    (unsigned long)&d->l2tab[i]);
-#endif
-#endif
 	}
 	return d;
 }
@@ -583,86 +522,6 @@
 void
 t3_free_l2t(struct l2t_data *d)
 {
-#ifndef NETEVENT
-#ifdef CONFIG_CHELSIO_T3_MODULE
-	int i;
-
-	/* Stop all L2T timers */
-	for (i = 0; i < d->nentries; ++i)
-		del_timer_sync(&d->l2tab[i].update_timer);
-#endif
-#endif
 	cxgb_free_mem(d);
 }
 
-#ifdef CONFIG_PROC_FS
-#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-
-static inline void *
-l2t_get_idx(struct seq_file *seq, loff_t pos)
-{
-	struct l2t_data *d = seq->private;
-
-	return pos >= d->nentries ? NULL : &d->l2tab[pos];
-}
-
-static void *
-l2t_seq_start(struct seq_file *seq, loff_t *pos)
-{
-	return *pos ? l2t_get_idx(seq, *pos) : SEQ_START_TOKEN;
-}
-
-static void *
-l2t_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
-	v = l2t_get_idx(seq, *pos + 1);
-	if (v)
-		++*pos;
-	return v;
-}
-
-static void
-l2t_seq_stop(struct seq_file *seq, void *v)
-{
-}
-
-static char
-l2e_state(const struct l2t_entry *e)
-{
-	switch (e->state) {
-	case L2T_STATE_VALID: return 'V';  /* valid, fast-path entry */
-	case L2T_STATE_STALE: return 'S';  /* needs revalidation, but usable */
-	case L2T_STATE_RESOLVING:
-		return e->arpq_head ? 'A' : 'R';
-	default:
-		return 'U';
-	}
-}
-
-static int
-l2t_seq_show(struct seq_file *seq, void *v)
-{
-	if (v == SEQ_START_TOKEN)
-		seq_puts(seq, "Index IP address      Ethernet address   VLAN  "
-			 "Prio  State   Users SMTIDX  Port\n");
-	else {
-		char ip[20];
-		struct l2t_entry *e = v;
-
-		mtx_lock(&e->lock);
-		sprintf(ip, "%u.%u.%u.%u", NIPQUAD(e->addr));
-		seq_printf(seq, "%-5u %-15s %02x:%02x:%02x:%02x:%02x:%02x  %4d"
-			   "  %3u     %c   %7u   %4u %s\n",
-			   e->idx, ip, e->dmac[0], e->dmac[1], e->dmac[2],
-			   e->dmac[3], e->dmac[4], e->dmac[5],
-			   e->vlan & EVL_VLID_MASK, vlan_prio(e),
-			   l2e_state(e), atomic_load_acq_int(&e->refcnt), e->smt_idx,
-			   e->neigh ? e->neigh->dev->name : "");
-		mtx_unlock(&e->lock);
-	}
-	return 0;
-}
-
-#endif

==== //depot/projects/iwarp/sys/dev/cxgb/cxgb_l2t.h#3 (text+ko) ====

@@ -76,12 +76,6 @@
 	struct mtx lock;
 	volatile uint32_t refcnt;     /* entry reference count */
 	uint8_t dmac[6];              /* neighbour's MAC address */
-#ifndef NETEVENT
-#ifdef CONFIG_CHELSIO_T3_MODULE
-	struct timer_list update_timer;
-	struct t3cdev *tdev;
-#endif
-#endif
 };
 
 struct l2t_data {
@@ -95,6 +89,9 @@
 typedef void (*arp_failure_handler_func)(struct t3cdev *dev,
 					 struct mbuf *m);
 
+typedef void (*opaque_arp_failure_handler_func)(void *dev,
+					 struct mbuf *m);
+
 /*
  * Callback stored in an skb to handle address resolution failure.
  */
@@ -111,10 +108,10 @@
 static __inline void set_arp_failure_handler(struct mbuf *m,
 					   arp_failure_handler_func hnd)
 {
-#if 0
-	L2T_SKB_CB(skb)->arp_failure_handler = hnd;
-#endif
-	panic("implement me");
+	struct toe_mbuf *tm = (struct toe_mbuf *)m;
+	
+	tm->m_toe.mt_arp_fail = (opaque_arp_failure_handler_func)hnd;
+
 }
 
 /*
@@ -145,9 +142,14 @@
 static inline int l2t_send(struct t3cdev *dev, struct mbuf *m,
 			   struct l2t_entry *e)
 {
-	if (__predict_true(e->state == L2T_STATE_VALID))
-		return cxgb_ofld_send(dev, m);
-	return t3_l2t_send_slow(dev, m, e);
+	if (__predict_true(e->state == L2T_STATE_VALID)) {
+		printf ("l2t_entry state is valid\n");
+		
+		return cxgb_ofld_send(dev, (struct mbuf *)m);
+	}
+	printf("send slow\n");
+	
+	return t3_l2t_send_slow(dev, (struct mbuf *)m, e);
 }
 
 static inline void l2t_release(struct l2t_data *d, struct l2t_entry *e)

==== //depot/projects/iwarp/sys/dev/cxgb/cxgb_main.c#3 (text+ko) ====

@@ -120,10 +120,7 @@
 static int cxgb_get_regs_len(void);
 static int offload_open(struct port_info *pi);
 static void touch_bars(device_t dev);
-
-#ifdef notyet
 static int offload_close(struct t3cdev *tdev);
-#endif
 
 static device_method_t cxgb_controller_methods[] = {
 	DEVMETHOD(device_probe,		cxgb_controller_probe),
@@ -694,14 +691,14 @@
 	bus_generic_detach(sc->dev);
 	if (sc->tq != NULL) 
 		taskqueue_free(sc->tq);
-#ifdef notyet
 	if (is_offload(sc)) {
 		cxgb_adapter_unofld(sc);
 		if (isset(&sc->open_device_map,	OFFLOAD_DEVMAP_BIT))
 			offload_close(&sc->tdev);
-	}
-#endif
-
+		else
+			printf("cxgb_free: DEVMAP_BIT not set\n");
+	} else
+		printf("not offloading set\n");	
 #ifndef IFNET_MULTIQUEUE
 	t3_free_sge_resources(sc);
 #endif
@@ -1039,7 +1036,7 @@
 
 	ether_ifdetach(p->ifp);
 	printf("waiting for callout to stop ...");
-	DELAY(100000);
+	DELAY(1000000);
 	printf("done\n");
 	/*
 	 * the lock may be acquired in ifdetach
@@ -1289,9 +1286,7 @@
 {
 	int ret;
 
-	critical_enter();
 	ret = t3_offload_tx(tdev, m);
-	critical_exit();
 	return (ret);
 }
 
@@ -1306,6 +1301,8 @@
 		return (ENOMEM);
 
 	req = mtod(m, struct cpl_smt_write_req *);
+	m->m_pkthdr.len = m->m_len = sizeof(struct cpl_smt_write_req);
+	
 	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, idx));
 	req->mtu_idx = NMTUS - 1;  /* should be 0 but there's a T3 bug */
@@ -1592,6 +1589,8 @@
 		cxgb_teardown_msix(sc);
 	ADAPTER_UNLOCK(sc);
 
+	callout_stop(&sc->cxgb_tick_ch);
+	callout_stop(&sc->sge_timer_ch);
 	callout_drain(&sc->cxgb_tick_ch);
 	callout_drain(&sc->sge_timer_ch);
 	
@@ -1606,15 +1605,22 @@
 offload_open(struct port_info *pi)
 {
 	struct adapter *adapter = pi->adapter;
-	struct t3cdev *tdev = T3CDEV(pi->ifp);
+	struct t3cdev *tdev = &adapter->tdev;
+#ifdef notyet	
+	    T3CDEV(pi->ifp);
+#endif	
 	int adap_up = adapter->open_device_map & PORT_MASK;
 	int err = 0;
 
+	printf("device_map=0x%x\n", adapter->open_device_map); 
 	if (atomic_cmpset_int(&adapter->open_device_map,
-		(adapter->open_device_map & ~OFFLOAD_DEVMAP_BIT),
-		(adapter->open_device_map | OFFLOAD_DEVMAP_BIT)) == 0)
+		(adapter->open_device_map & ~(1<<OFFLOAD_DEVMAP_BIT)),
+		(adapter->open_device_map | (1<<OFFLOAD_DEVMAP_BIT))) == 0)
 		return (0);
 
+       
+	if (!isset(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT)) 
+		printf("offload_open: DEVMAP_BIT did not get set 0x%x\n", adapter->open_device_map);
 	ADAPTER_LOCK(pi->adapter); 
 	if (!adap_up)
 		err = cxgb_up(adapter);
@@ -1623,7 +1629,7 @@
 		return (err);
 
 	t3_tp_set_offload_mode(adapter, 1);
-	tdev->lldev = adapter->port[0].ifp;
+	tdev->lldev = pi->ifp;
 	err = cxgb_offload_activate(adapter);
 	if (err)
 		goto out;
@@ -1647,15 +1653,18 @@
 	}
 	return (err);
 }
-#ifdef notyet
+
 static int
 offload_close(struct t3cdev *tdev)
 {
 	struct adapter *adapter = tdev2adap(tdev);
 
-	if (!isset(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT))
+	if (!isset(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT)) {
+		printf("offload_close: DEVMAP_BIT not set\n");
+	
 		return (0);
-
+	}
+	
 	/* Call back all registered clients */
 	cxgb_remove_clients(tdev);
 	tdev->lldev = NULL;
@@ -1663,13 +1672,15 @@
 	t3_tp_set_offload_mode(adapter, 0);
 	clrbit(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT);
 
+	ADAPTER_LOCK(adapter);
 	if (!adapter->open_device_map)
-		cxgb_down(adapter);
-
+		cxgb_down_locked(adapter);
+	else
+		ADAPTER_UNLOCK(adapter);
 	cxgb_offload_deactivate(adapter);
 	return (0);
 }
-#endif
+
 
 static void
 cxgb_init(void *arg)
@@ -1709,6 +1720,8 @@
 		if (err)
 			log(LOG_WARNING,
 			    "Could not initialize offload capabilities\n");
+		else
+			printf("offload opened\n");
 	}
 	cxgb_link_start(p);
 	t3_link_changed(sc, p->port_id);
@@ -1752,7 +1765,6 @@
 	ADAPTER_LOCK(p->adapter);
 	clrbit(&p->adapter->open_device_map, p->port_id);
 
-	
 	if (p->adapter->open_device_map == 0) {
 		cxgb_down_locked(p->adapter);
 	} else 
@@ -1941,7 +1953,7 @@
 	struct sge_qset *qs;
 	struct sge_txq *txq;
 	struct port_info *p = ifp->if_softc;
-	int err, qsidx = 0;
+	int err;
 	
 	if (!p->link_config.link_ok)
 		return (ENXIO);
@@ -1950,10 +1962,7 @@
 		return (ENOBUFS);
 	}
 	
-	if (p->adapter->params.nports <= 2)
-		qsidx = p->first_qset;
-	
-	qs = &p->adapter->sge.qs[qsidx];
+	qs = &p->adapter->sge.qs[p->first_qset];
 	txq = &qs->txq[TXQ_ETH];
 	err = 0;
 

==== //depot/projects/iwarp/sys/dev/cxgb/cxgb_multiq.c#3 (text+ko) ====

@@ -489,7 +489,7 @@
 		qs = &pi->adapter->sge.qs[qidx];
 	} else 
 		qs = &pi->adapter->sge.qs[pi->first_qset];
-	
+
 	txq = &qs->txq[TXQ_ETH];
 
 	if (((sc->tunq_coalesce == 0) || (buf_ring_count(&txq->txq_mr) > TX_WR_COUNT_MAX)) && mtx_trylock(&txq->lock)) {
@@ -638,9 +638,6 @@
 	int qidx;
 	uint32_t tmp;
 	
-	 /*
-	 * Will probably need to be changed for 4-port XXX
-	 */
 	tmp = pi->tx_chan ? cookie : cookie & ((RSS_TABLE_SIZE>>1)-1);
 	DPRINTF(" tmp=%d ", tmp);
 	qidx = (tmp & (pi->nqsets -1)) + pi->first_qset;
@@ -681,6 +678,7 @@
 	for (i = 0; i < sc->params.nports; i++) {
 		struct port_info *pi = &sc->port[i];
 		int first = pi->first_qset;
+		
 		for (j = 0; j < pi->nqsets; j++) {
 			struct sge_qset *qs = &sc->sge.qs[first + j];
 

==== //depot/projects/iwarp/sys/dev/cxgb/cxgb_offload.c#3 (text+ko) ====

@@ -108,9 +108,14 @@
 	TAILQ_INSERT_TAIL(&client_list, client, client_entry);
 
 	if (client->add) {
-		TAILQ_FOREACH(tdev, &ofld_dev_list, ofld_entry) {
+		printf("client->add set\n");
+		
+		TAILQ_FOREACH(tdev, &ofld_dev_list, entry) {
 			if (offload_activated(tdev))
 				client->add(tdev);
+			else
+				printf("%p not activated\n", tdev);
+			
 		}
 	}
 	mtx_unlock(&cxgb_db_lock);
@@ -132,7 +137,7 @@
 	TAILQ_REMOVE(&client_list, client, client_entry);
 
 	if (client->remove) {
-		TAILQ_FOREACH(tdev, &ofld_dev_list, ofld_entry) {
+		TAILQ_FOREACH(tdev, &ofld_dev_list, entry) {
 			if (offload_activated(tdev))
 				client->remove(tdev);
 		}
@@ -480,7 +485,7 @@
 cxgb_set_dummy_ops(struct t3cdev *dev)
 {
 	dev->recv         = rx_offload_blackhole;
-	dev->neigh_update = dummy_neigh_update;
+	dev->arp_update = dummy_neigh_update;
 }
 
 /*
@@ -539,6 +544,7 @@
 
 	m_set_priority(m, CPL_PRIORITY_SETUP);
 	req = mtod(m, struct cpl_tid_release *);
+	m->m_pkthdr.len = m->m_len = sizeof(*req);
 	req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
 	OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, tid));
 }
@@ -818,6 +824,8 @@
 	}
 }
 
+
+
 static int
 do_set_tcb_rpl(struct t3cdev *dev, struct mbuf *m)
 {
@@ -865,225 +873,57 @@
 	return (0);
 }
 
-#if defined(FOO)
-#include <linux/config.h> 
-#include <linux/kallsyms.h> 
-#include <linux/kprobes.h> 
-#include <net/arp.h> 
-
-static int (*orig_arp_constructor)(struct ifnet *);
-
 static void
-neigh_suspect(struct ifnet *neigh)
+cxgb_route_event(void *unused, int event, struct rtentry *rt0, struct rtentry *rt1)
 {
-	struct hh_cache *hh;
+	struct toedev *tdev0, *tdev1 = NULL;
 
-	neigh->output = neigh->ops->output;
-
-	for (hh = neigh->hh; hh; hh = hh->hh_next)
-		hh->hh_output = neigh->ops->output;
-}
-
-static void
-neigh_connect(struct ifnet *neigh)
-{
-	struct hh_cache *hh;
-
-	neigh->output = neigh->ops->connected_output;
-
-	for (hh = neigh->hh; hh; hh = hh->hh_next)
-		hh->hh_output = neigh->ops->hh_output;
-}
-
-static inline int
-neigh_max_probes(const struct neighbour *n)
-{
-	const struct neigh_parms *p = n->parms;
-	return (n->nud_state & NUD_PROBE ?
-		p->ucast_probes :
-		p->ucast_probes + p->app_probes + p->mcast_probes);
-}
-
-static void
-neigh_timer_handler_offload(unsigned long arg)
-{
-	unsigned long now, next;
-	struct neighbour *neigh = (struct neighbour *)arg;
-	unsigned state;
-	int notify = 0;
-
-	write_lock(&neigh->lock);
-
-	state = neigh->nud_state;
-	now = jiffies;
-	next = now + HZ;
-
-	if (!(state & NUD_IN_TIMER)) {
-#ifndef CONFIG_SMP
-		log(LOG_WARNING, "neigh: timer & !nud_in_timer\n");
-#endif
-		goto out;
+	/* 
+	 * ignore events on non-offloaded interfaces
+	 */
+	
+	tdev0 = TOEDEV(rt0->rt_ifp);
+	if (rt1)
+		tdev1 = TOEDEV(rt1->rt_ifp);
+	if (tdev0 == NULL && tdev1 == NULL)
+		return;
+        /*
+	 * avoid LORs by dropping the route lock but keeping a reference
+	 * 
+	 */
+	RT_ADDREF(rt0);
+	RT_UNLOCK(rt0);
+	if (rt1) {
+		RT_ADDREF(rt1);
+		RT_UNLOCK(rt1);
 	}
 
-	if (state & NUD_REACHABLE) {
-		if (time_before_eq(now,
-				   neigh->confirmed + 
-				   neigh->parms->reachable_time)) {
-			next = neigh->confirmed + neigh->parms->reachable_time;
-		} else if (time_before_eq(now,
-					  neigh->used + 
-					  neigh->parms->delay_probe_time)) {
-			neigh->nud_state = NUD_DELAY;
-			neigh->updated = jiffies;
-			neigh_suspect(neigh);
-			next = now + neigh->parms->delay_probe_time;
-		} else {
-			neigh->nud_state = NUD_STALE;
-			neigh->updated = jiffies;
-			neigh_suspect(neigh);
-			cxgb_neigh_update(neigh);
+	switch (event) {
+		case RTEVENT_ARP_UPDATE: {
+			cxgb_neigh_update(rt0);
+			break;
 		}
-	} else if (state & NUD_DELAY) {
-		if (time_before_eq(now,
-				   neigh->confirmed +
-				   neigh->parms->delay_probe_time)) {
-			neigh->nud_state = NUD_REACHABLE;
-			neigh->updated = jiffies;
-			neigh_connect(neigh);
-			cxgb_neigh_update(neigh);
-			next = neigh->confirmed + neigh->parms->reachable_time;
-		} else {
-			neigh->nud_state = NUD_PROBE;
-			neigh->updated = jiffies;
-			atomic_set_int(&neigh->probes, 0);
-			next = now + neigh->parms->retrans_time;
+		case RTEVENT_REDIRECT_UPDATE: {
+			cxgb_redirect(rt0, rt1);
+			cxgb_neigh_update(rt1);
+	
+			break;
 		}
-	} else {
-		/* NUD_PROBE|NUD_INCOMPLETE */
-		next = now + neigh->parms->retrans_time;
+		case RTEVENT_PMTU_UPDATE:
+		default:
+			break;
 	}
-	/*
-	 * Needed for read of probes
-	 */
-	mb();
-	if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) &&
-	    neigh->probes >= neigh_max_probes(neigh)) {
-		struct mbuf *m;
 
-		neigh->nud_state = NUD_FAILED;
-		neigh->updated = jiffies;
-		notify = 1;
-		cxgb_neigh_update(neigh);
-		NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
-
-		/* It is very thin place. report_unreachable is very 
-		   complicated routine. Particularly, it can hit the same 
-		   neighbour entry!
-		   So that, we try to be accurate and avoid dead loop. --ANK
-		 */
-		while (neigh->nud_state == NUD_FAILED &&
-		       (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) {
-			write_unlock(&neigh->lock);
-			neigh->ops->error_report(neigh, skb);
-			write_lock(&neigh->lock);
-		}
-		skb_queue_purge(&neigh->arp_queue);
+	RT_LOCK(rt0);
+	RT_REMREF(rt0);
+	if (rt1) {
+		RT_LOCK(rt1);
+		RT_REMREF(rt1);
 	}
-
-	if (neigh->nud_state & NUD_IN_TIMER) {
-		if (time_before(next, jiffies + HZ/2))
-			next = jiffies + HZ/2;
-		if (!mod_timer(&neigh->timer, next))
-			neigh_hold(neigh);
-	}
-	if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) {
-		struct mbuf *m = skb_peek(&neigh->arp_queue);

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list