svn commit: r236428 - in user/np/toe_iwarp/sys: dev/cxgbe dev/cxgbe/tom net netinet

Navdeep Parhar np at FreeBSD.org
Sat Jun 2 00:29:43 UTC 2012


Author: np
Date: Sat Jun  2 00:29:42 2012
New Revision: 236428
URL: http://svn.freebsd.org/changeset/base/236428

Log:
  TOE + VLAN support.
  
  - Move the TOEDEV macro to if_var.h
  - A VLAN interface inherits the TOE capabilities (and TOEDEV) of its parent.
  - Add VLAN support to the T4 TOE driver.  VLAN_TRUNKDEV, which acquires
    a sleepable lock, cannot be called directly in tod_connect so we use
    other means to reach the parent cxgbe ifnet from the VLAN interface.

Modified:
  user/np/toe_iwarp/sys/dev/cxgbe/adapter.h
  user/np/toe_iwarp/sys/dev/cxgbe/t4_main.c
  user/np/toe_iwarp/sys/dev/cxgbe/tom/t4_connect.c
  user/np/toe_iwarp/sys/dev/cxgbe/tom/t4_listen.c
  user/np/toe_iwarp/sys/net/if_var.h
  user/np/toe_iwarp/sys/net/if_vlan.c
  user/np/toe_iwarp/sys/netinet/toecore.h

Modified: user/np/toe_iwarp/sys/dev/cxgbe/adapter.h
==============================================================================
--- user/np/toe_iwarp/sys/dev/cxgbe/adapter.h	Fri Jun  1 23:29:48 2012	(r236427)
+++ user/np/toe_iwarp/sys/dev/cxgbe/adapter.h	Sat Jun  2 00:29:42 2012	(r236428)
@@ -213,6 +213,9 @@ struct port_info {
 	struct link_config link_cfg;
 	struct port_stats stats;
 
+	eventhandler_tag vlan_c;
+	eventhandler_tag vlan_u;
+
 	struct callout tick;
 	struct sysctl_ctx_list ctx;	/* from ifconfig up to driver detach */
 

Modified: user/np/toe_iwarp/sys/dev/cxgbe/t4_main.c
==============================================================================
--- user/np/toe_iwarp/sys/dev/cxgbe/t4_main.c	Fri Jun  1 23:29:48 2012	(r236427)
+++ user/np/toe_iwarp/sys/dev/cxgbe/t4_main.c	Sat Jun  2 00:29:42 2012	(r236428)
@@ -301,6 +301,8 @@ static void reg_block_dump(struct adapte
     unsigned int);
 static void t4_get_regs(struct adapter *, struct t4_regdump *, uint8_t *);
 static void cxgbe_tick(void *);
+static void cxgbe_vlan_config(void *, struct ifnet *, uint16_t);
+static void cxgbe_vlan_unconfig(void *, struct ifnet *, uint16_t);
 static int cpl_not_handled(struct sge_iq *, const struct rss_header *,
     struct mbuf *);
 static int t4_sysctls(struct adapter *);
@@ -850,6 +852,11 @@ cxgbe_attach(device_t dev)
 	    cxgbe_media_status);
 	build_medialist(pi);
 
+	pi->vlan_c = EVENTHANDLER_REGISTER(vlan_config, cxgbe_vlan_config, ifp,
+	    EVENTHANDLER_PRI_ANY);
+	pi->vlan_u = EVENTHANDLER_REGISTER(vlan_unconfig, cxgbe_vlan_unconfig,
+	    ifp, EVENTHANDLER_PRI_ANY);
+
 	ether_ifattach(ifp, pi->hw_addr);
 
 #ifdef TCP_OFFLOAD
@@ -882,6 +889,11 @@ cxgbe_detach(device_t dev)
 	SET_BUSY(sc);
 	ADAPTER_UNLOCK(sc);
 
+	if (pi->vlan_c)
+		EVENTHANDLER_DEREGISTER(vlan_config, pi->vlan_c);
+	if (pi->vlan_u)
+		EVENTHANDLER_DEREGISTER(vlan_unconfig, pi->vlan_u);
+
 	PORT_LOCK(pi);
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 	callout_stop(&pi->tick);
@@ -2892,6 +2904,30 @@ cxgbe_tick(void *arg)
 	PORT_UNLOCK(pi);
 }
 
+static void
+cxgbe_vlan_config(void *arg, struct ifnet *ifp, uint16_t vid)
+{
+	struct ifnet *vlan;
+
+	if (arg != ifp)
+		return;
+
+	vlan = VLAN_DEVAT(ifp, vid);
+	VLAN_SETCOOKIE(vlan, ifp);
+}
+
+static void
+cxgbe_vlan_unconfig(void *arg, struct ifnet *ifp, uint16_t vid)
+{
+	struct ifnet *vlan;
+
+	if (arg != ifp)
+		return;
+
+	vlan = VLAN_DEVAT(ifp, vid);
+	VLAN_SETCOOKIE(vlan, NULL);
+}
+
 static int
 cpl_not_handled(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m)
 {

Modified: user/np/toe_iwarp/sys/dev/cxgbe/tom/t4_connect.c
==============================================================================
--- user/np/toe_iwarp/sys/dev/cxgbe/tom/t4_connect.c	Fri Jun  1 23:29:48 2012	(r236427)
+++ user/np/toe_iwarp/sys/dev/cxgbe/tom/t4_connect.c	Sat Jun  2 00:29:42 2012	(r236428)
@@ -39,6 +39,10 @@ __FBSDID("$FreeBSD$");
 #include <sys/domain.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/if_vlan_var.h>
 #include <net/route.h>
 #include <netinet/in.h>
 #include <netinet/in_pcb.h>
@@ -273,8 +277,8 @@ t4_connect(struct toedev *tod, struct so
 	struct wrqe *wr = NULL;
 	struct cpl_act_open_req *cpl;
 	struct l2t_entry *e = NULL;
-	struct ifnet *ifp = rt->rt_ifp;		/* XXX: may not be cxgbe */
-	struct port_info *pi = ifp->if_softc;	/* XXX: wrong for VLAN etc. */
+	struct ifnet *rt_ifp = rt->rt_ifp;
+	struct port_info *pi;
 	int atid = -1, mtu_idx, rscale, qid_atid, rc = ENOMEM;
 	struct inpcb *inp = sotoinpcb(so);
 	struct tcpcb *tp = intotcpcb(inp);
@@ -284,6 +288,17 @@ t4_connect(struct toedev *tod, struct so
 	if (nam->sa_family != AF_INET)
 		CXGBE_UNIMPLEMENTED("IPv6 connect");
 
+	if (rt_ifp->if_type == IFT_ETHER)
+		pi = rt_ifp->if_softc;
+	else if (rt_ifp->if_type == IFT_L2VLAN) {
+		struct ifnet *ifp = VLAN_COOKIE(rt_ifp);
+
+		pi = ifp->if_softc;
+	} else if (rt_ifp->if_type == IFT_IEEE8023ADLAG)
+		return (ENOSYS);	/* XXX: implement lagg support */
+	else
+		return (ENOTSUP);
+
 	toep = alloc_toepcb(pi, -1, -1, M_NOWAIT);
 	if (toep == NULL)
 		goto failed;
@@ -292,7 +307,7 @@ t4_connect(struct toedev *tod, struct so
 	if (atid < 0)
 		goto failed;
 
-	e = t4_l2t_get(pi, rt->rt_ifp,
+	e = t4_l2t_get(pi, rt_ifp,
 	    rt->rt_flags & RTF_GATEWAY ? rt->rt_gateway : nam);
 	if (e == NULL)
 		goto failed;

Modified: user/np/toe_iwarp/sys/dev/cxgbe/tom/t4_listen.c
==============================================================================
--- user/np/toe_iwarp/sys/dev/cxgbe/tom/t4_listen.c	Fri Jun  1 23:29:48 2012	(r236427)
+++ user/np/toe_iwarp/sys/dev/cxgbe/tom/t4_listen.c	Sat Jun  2 00:29:42 2012	(r236428)
@@ -41,6 +41,10 @@ __FBSDID("$FreeBSD$");
 #include <sys/fnv_hash.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/if_vlan_var.h>
 #include <net/route.h>
 #include <netinet/in.h>
 #include <netinet/in_pcb.h>
@@ -976,13 +980,14 @@ do_pass_accept_req(struct sge_iq *iq, co
 	struct tcphdr th;
 	struct tcpopt to;
 	struct port_info *pi;
-	struct ifnet *ifp;
+	struct ifnet *ifp, *ifp_vlan = NULL;
 	struct l2t_entry *e = NULL;
 	struct rtentry *rt;
 	struct sockaddr_in nam;
 	int rscale, mtu_idx, rx_credits, rxqid;
 	struct synq_entry *synqe = NULL;
 	int reject_reason;
+	uint16_t vid;
 #ifdef INVARIANTS
 	unsigned int opcode = G_CPL_OPCODE(be32toh(OPCODE_TID(cpl)));
 #endif
@@ -1014,6 +1019,17 @@ do_pass_accept_req(struct sge_iq *iq, co
 		REJECT_PASS_ACCEPT();
 
 	/*
+	 * Don't offload if the SYN had a VLAN tag and the vid doesn't match
+	 * anything on this interface.
+	 */
+	vid = EVL_VLANOFTAG(be16toh(cpl->vlan));
+	if (vid != 0xfff) {
+		ifp_vlan = VLAN_DEVAT(ifp, vid);
+		if (ifp_vlan == NULL)
+			REJECT_PASS_ACCEPT();
+	}
+
+	/*
 	 * Don't offload if the peer requested a TCP option that's not known to
 	 * the silicon.
 	 */
@@ -1037,7 +1053,8 @@ do_pass_accept_req(struct sge_iq *iq, co
 		RT_UNLOCK(rt);
 		nexthop = rt->rt_flags & RTF_GATEWAY ? rt->rt_gateway :
 		    (struct sockaddr *)&nam;
-		if (rt->rt_ifp == ifp)
+		if (rt->rt_ifp == ifp ||
+		    (ifp_vlan != NULL && rt->rt_ifp == ifp_vlan))
 			e = t4_l2t_get(pi, rt->rt_ifp, nexthop);
 		RTFREE(rt);
 		if (e == NULL)
@@ -1188,7 +1205,6 @@ reject:
 	release_tid(sc, tid, lctx->ctrlq);
 
 	if (__predict_true(m != NULL)) {
-		m->m_pkthdr.rcvif = ifp;	/* yes, again */
 		m_adj(m, sizeof(*cpl));
 		m->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID |
 		    CSUM_DATA_VALID | CSUM_PSEUDO_HDR);

Modified: user/np/toe_iwarp/sys/net/if_var.h
==============================================================================
--- user/np/toe_iwarp/sys/net/if_var.h	Fri Jun  1 23:29:48 2012	(r236427)
+++ user/np/toe_iwarp/sys/net/if_var.h	Sat Jun  2 00:29:42 2012	(r236428)
@@ -209,6 +209,8 @@ struct ifnet {
 	void	*if_pspare[8];		/* 1 netmap, 7 TDB */
 };
 
+#define	TOEDEV(ifp)	((ifp)->if_llsoftc)
+
 typedef void if_init_f_t(void *);
 
 /*

Modified: user/np/toe_iwarp/sys/net/if_vlan.c
==============================================================================
--- user/np/toe_iwarp/sys/net/if_vlan.c	Fri Jun  1 23:29:48 2012	(r236427)
+++ user/np/toe_iwarp/sys/net/if_vlan.c	Sat Jun  2 00:29:42 2012	(r236428)
@@ -746,8 +746,8 @@ vlan_modevent(module_t mod, int type, vo
 		vlan_trunk_cap_p = NULL;
 		vlan_trunkdev_p = NULL;
 		vlan_tag_p = NULL;
-		vlan_cookie_p = vlan_cookie;
-		vlan_setcookie_p = vlan_setcookie;
+		vlan_cookie_p = NULL;
+		vlan_setcookie_p = NULL;
 		vlan_devat_p = NULL;
 		VLAN_LOCK_DESTROY();
 		if (bootverbose)
@@ -1503,6 +1503,22 @@ vlan_capabilities(struct ifvlan *ifv)
 		ifp->if_capenable &= ~(p->if_capenable & IFCAP_TSO);
 		ifp->if_hwassist &= ~(p->if_hwassist & CSUM_TSO);
 	}
+
+	/*
+	 * If the parent interface can offload TCP connections over VLANs then
+	 * propagate its TOE capability to the VLAN interface.
+	 *
+	 * All TOE drivers in the tree today can deal with VLANs.  If this
+	 * changes then IFCAP_VLAN_TOE should be promoted to a full capability
+	 * with its own bit.
+	 */
+#define IFCAP_VLAN_TOE IFCAP_TOE
+	if (p->if_capabilities & IFCAP_VLAN_TOE)
+		ifp->if_capabilities |= p->if_capabilities & IFCAP_TOE;
+	if (p->if_capenable & IFCAP_VLAN_TOE) {
+		TOEDEV(ifp) = TOEDEV(p);
+		ifp->if_capenable |= p->if_capenable & IFCAP_TOE;
+	}
 }
 
 static void

Modified: user/np/toe_iwarp/sys/netinet/toecore.h
==============================================================================
--- user/np/toe_iwarp/sys/netinet/toecore.h	Fri Jun  1 23:29:48 2012	(r236427)
+++ user/np/toe_iwarp/sys/netinet/toecore.h	Sat Jun  2 00:29:42 2012	(r236428)
@@ -86,8 +86,6 @@ struct toedev {
 	void (*tod_ctloutput)(struct toedev *, struct tcpcb *, int, int);
 };
 
-#define TOEDEV(ifp) ((ifp)->if_llsoftc)
-
 #include <sys/eventhandler.h>
 typedef	void (*tcp_offload_listen_start_fn)(void *, struct tcpcb *);
 typedef	void (*tcp_offload_listen_stop_fn)(void *, struct tcpcb *);


More information about the svn-src-user mailing list