cvs commit: src/sys/i386/i386 nexus.c src/sys/i386/include atomic.h src/sys/kern kern_poll.c lwkt_serialize.c src/sys/net if.c if_var.h rtsock.c src/sbin/ifconfig ifconfig.c src/sys/dev/netif/dc if_dc.c src/sys/dev/netif/em if_em.c if_em.h ...

Joerg Sonnenberger joerg at britannica.bec.de
Thu May 26 12:28:35 PDT 2005


On Wed, May 25, 2005 at 11:18:51AM -0700, Matthew Dillon wrote:
>     My main desire is to simplify the APIs.  e.g. Having the driver's
>     *interrupt* routine try to register the poll really complicates the
>     poll registration code.

Attached is a better patch. The change to if_re illustrate the idea
how to handle some capabitilities specially and others not. I think
we can do the same for the checksum support in most drivers, they
can still override it if they want / have to. Even the up/down handling
could be implemented that way.

Joerg
Index: sbin/ifconfig/ifconfig.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.24
diff -u -r1.24 ifconfig.c
--- sbin/ifconfig/ifconfig.c	26 May 2005 09:06:40 -0000	1.24
+++ sbin/ifconfig/ifconfig.c	26 May 2005 19:05:45 -0000
@@ -193,8 +193,6 @@
 } cmds[] = {
 	{ "up",		IFF_UP,		setifflags,	NULL },
 	{ "down",	-IFF_UP,	setifflags,	NULL },
-	{ "polling",	IFF_POLLING,	setifflags,	NULL },
-	{ "-polling",	-IFF_POLLING,	setifflags,	NULL },
 	{ "arp",	-IFF_NOARP,	setifflags,	NULL },
 	{ "-arp",	IFF_NOARP,	setifflags,	NULL },
 	{ "debug",	IFF_DEBUG,	setifflags,	NULL },
@@ -291,6 +289,8 @@
 	{ "-txcsum",	-IFCAP_TXCSUM,	setifcap,	NULL },
 	{ "netcons",	IFCAP_NETCONS,	setifcap,	NULL },
 	{ "-netcons",	-IFCAP_NETCONS,	setifcap,	NULL },
+	{ "polling",	IFCAP_POLLING,	setifcap,	NULL },
+	{ "-polling",	-IFCAP_POLLING,	setifcap,	NULL },
 	{ "vlanmtu",	IFCAP_VLAN_MTU,		setifcap,	NULL },
 	{ "-vlanmtu",	-IFCAP_VLAN_MTU,	setifcap,	NULL },
 	{ "vlanhwtag",	IFCAP_VLAN_HWTAGGING,	setifcap,	NULL },
Index: sys/dev/netif/dc/if_dc.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/dc/if_dc.c,v
retrieving revision 1.27
diff -u -r1.27 if_dc.c
--- sys/dev/netif/dc/if_dc.c	25 May 2005 01:44:20 -0000	1.27
+++ sys/dev/netif/dc/if_dc.c	26 May 2005 19:08:20 -0000
@@ -2060,7 +2060,9 @@
 	ifp->if_start = dc_start;
 #ifdef DEVICE_POLLING
 	ifp->if_poll = dc_poll;
+	ifp->if_capabilities |= IFCAP_POLLING;
 #endif
+	ifp->if_capenable = ifp->if_capabilities;
 	ifp->if_watchdog = dc_watchdog;
 	ifp->if_init = dc_init;
 	ifp->if_baudrate = 10000000;
@@ -3328,11 +3330,6 @@
 	s = splimp();
 
 	switch(command) {
-	case SIOCSIFADDR:
-	case SIOCGIFADDR:
-	case SIOCSIFMTU:
-		error = ether_ioctl(ifp, command, data);
-		break;
 	case SIOCSIFFLAGS:
 		if (ifp->if_flags & IFF_UP) {
 			int need_setfilt = (ifp->if_flags ^ sc->dc_if_flags) &
@@ -3362,7 +3359,7 @@
 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
 		break;
 	default:
-		error = EINVAL;
+		error = ether_ioctl(ifp, command, data);
 		break;
 	}
 
Index: sys/dev/netif/em/if_em.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/em/if_em.c,v
retrieving revision 1.33
diff -u -r1.33 if_em.c
--- sys/dev/netif/em/if_em.c	26 May 2005 09:10:36 -0000	1.33
+++ sys/dev/netif/em/if_em.c	26 May 2005 19:05:57 -0000
@@ -730,6 +730,11 @@
 		break;
 	case SIOCSIFCAP:
 		IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFCAP (Set Capabilities)");
+#ifdef DEVICE_POLLING
+		ifp->if_capenable &= ~IFCAP_POLLING;
+		ifp->if_capenable |= ifr->ifr_reqcap & IFCAP_POLLING;
+		ether_poll_update(ifp);
+#endif
 		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
 		if (mask & IFCAP_HWCSUM) {
 			if (IFCAP_HWCSUM & ifp->if_capenable)
@@ -1654,6 +1659,7 @@
 	ifp->if_start = em_start;
 #ifdef DEVICE_POLLING
 	ifp->if_poll = em_poll;
+	ifp->if_capabilities |= IFCAP_POLLING;
 #endif
 	ifp->if_watchdog = em_watchdog;
 	ifq_set_maxlen(&ifp->if_snd, adapter->num_tx_desc - 1);
@@ -1661,16 +1667,15 @@
 
 	ether_ifattach(ifp, adapter->hw.mac_addr);
 
-	if (adapter->hw.mac_type >= em_82543) {
-		ifp->if_capabilities = IFCAP_HWCSUM;
-		ifp->if_capenable = ifp->if_capabilities;
-	}
+	if (adapter->hw.mac_type >= em_82543)
+		ifp->if_capabilities |= IFCAP_HWCSUM;
 
 	/*
 	 * Tell the upper layer(s) we support long frames.
 	 */
 	ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
         ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
+	ifp->if_capenable = ifp->if_capabilities;
 
 	/* 
 	 * Specify the media types supported by this adapter and register
Index: sys/dev/netif/fwe/if_fwe.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/fwe/if_fwe.c,v
retrieving revision 1.16
diff -u -r1.16 if_fwe.c
--- sys/dev/netif/fwe/if_fwe.c	25 May 2005 13:12:22 -0000	1.16
+++ sys/dev/netif/fwe/if_fwe.c	26 May 2005 19:08:46 -0000
@@ -204,6 +204,7 @@
 	ifp->if_capabilities = IFCAP_VLAN_MTU;
 #ifdef DEVICE_POLLING
 	ifp->if_poll = fwe_poll;
+	ifp->if_capabilities |= DEVICE_POLLING;
 #endif
 	ifp->if_mtu = ETHERMTU;
 	ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST);
Index: sys/dev/netif/fxp/if_fxp.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/fxp/if_fxp.c,v
retrieving revision 1.27
diff -u -r1.27 if_fxp.c
--- sys/dev/netif/fxp/if_fxp.c	25 May 2005 01:44:24 -0000	1.27
+++ sys/dev/netif/fxp/if_fxp.c	26 May 2005 19:09:12 -0000
@@ -662,7 +662,9 @@
 	ifp->if_start = fxp_start;
 #ifdef DEVICE_POLLING
 	ifp->if_poll = fxp_poll;
+	ifp->if_capabilities |= IFCAP_POLLING;
 #endif
+	ifp->if_capenable = ifp->if_capabilities;
 	ifp->if_watchdog = fxp_watchdog;
 
 	/*
@@ -1979,12 +1981,6 @@
 	s = splimp();
 
 	switch (command) {
-	case SIOCSIFADDR:
-	case SIOCGIFADDR:
-	case SIOCSIFMTU:
-		error = ether_ioctl(ifp, command, data);
-		break;
-
 	case SIOCSIFFLAGS:
 		if (ifp->if_flags & IFF_ALLMULTI)
 			sc->flags |= FXP_FLAG_ALL_MCAST;
@@ -2038,7 +2034,8 @@
 		break;
 
 	default:
-		error = EINVAL;
+		error = ether_ioctl(ifp, command, data);
+		break;
 	}
 	splx(s);
 	return (error);
Index: sys/dev/netif/nge/if_nge.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/nge/if_nge.c,v
retrieving revision 1.25
diff -u -r1.25 if_nge.c
--- sys/dev/netif/nge/if_nge.c	25 May 2005 12:37:29 -0000	1.25
+++ sys/dev/netif/nge/if_nge.c	26 May 2005 19:09:50 -0000
@@ -865,9 +865,6 @@
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_ioctl = nge_ioctl;
 	ifp->if_start = nge_start;
-#ifdef DEVICE_POLLING
-	ifp->if_poll = nge_poll;
-#endif
 	ifp->if_watchdog = nge_watchdog;
 	ifp->if_init = nge_init;
 	ifp->if_baudrate = 1000000000;
@@ -875,6 +872,10 @@
 	ifq_set_ready(&ifp->if_snd);
 	ifp->if_hwassist = NGE_CSUM_FEATURES;
 	ifp->if_capabilities = IFCAP_HWCSUM;
+#ifdef DEVICE_POLLING
+	ifp->if_poll = nge_poll;
+	ifp->if_capabilities |= IFCAP_POLLING;
+#endif
 	ifp->if_capenable = ifp->if_capabilities;
 
 	/*
@@ -1954,10 +1955,6 @@
 	s = splimp();
 
 	switch(command) {
-	case SIOCSIFADDR:
-	case SIOCGIFADDR:
-		error = ether_ioctl(ifp, command, data);
-		break;
 	case SIOCSIFMTU:
 		if (ifr->ifr_mtu > NGE_JUMBO_MTU) {
 			error = EINVAL;
@@ -2017,8 +2014,9 @@
 					      command);
 		}
 		break;
+
 	default:
-		error = EINVAL;
+		error = ether_ioctl(ifp, command, data);
 		break;
 	}
 
Index: sys/dev/netif/re/if_re.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/re/if_re.c,v
retrieving revision 1.12
diff -u -r1.12 if_re.c
--- sys/dev/netif/re/if_re.c	25 May 2005 01:44:27 -0000	1.12
+++ sys/dev/netif/re/if_re.c	26 May 2005 19:23:45 -0000
@@ -1131,11 +1131,12 @@
 	ifp->if_mtu = ETHERMTU;
 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 	ifp->if_ioctl = re_ioctl;
-	ifp->if_capabilities = IFCAP_VLAN_MTU;
+	ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_HWCSUM |
+	    IFCAP_VLAN_HWTAGGING;
 	ifp->if_start = re_start;
-	ifp->if_capabilities |= IFCAP_HWCSUM|IFCAP_VLAN_HWTAGGING;
 #ifdef DEVICE_POLLING
 	ifp->if_poll = re_poll;
+	ifp->if_capabilities |= IFCAP_POLLING;
 #endif
 	ifp->if_watchdog = re_watchdog;
 	ifp->if_init = re_init;
@@ -2114,15 +2115,15 @@
 		break;
 	case SIOCSIFCAP:
 		ifp->if_capenable &= ~(IFCAP_HWCSUM);
-		ifp->if_capenable |=
-		    ifr->ifr_reqcap & (IFCAP_HWCSUM);
+		ifp->if_capenable |= ifr->ifr_reqcap & (IFCAP_HWCSUM);
 		if (ifp->if_capenable & IFCAP_TXCSUM)
 			ifp->if_hwassist = RE_CSUM_FEATURES;
 		else
 			ifp->if_hwassist = 0;
 		if (ifp->if_flags & IFF_RUNNING)
 			re_init(sc);
-		break;
+		ifr->ifrq_reqcap &= ~ IFCAP_HWCSUM;
+		/* FALLTHROUGH */
 	default:
 		error = ether_ioctl(ifp, command, data);
 		break;
Index: sys/dev/netif/rl/if_rl.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/rl/if_rl.c,v
retrieving revision 1.22
diff -u -r1.22 if_rl.c
--- sys/dev/netif/rl/if_rl.c	25 May 2005 01:44:28 -0000	1.22
+++ sys/dev/netif/rl/if_rl.c	26 May 2005 19:10:25 -0000
@@ -930,7 +930,9 @@
 	ifp->if_capabilities = IFCAP_VLAN_MTU;
 #ifdef DEVICE_POLLING
 	ifp->if_poll = rl_poll;
+	ifp->if_capabilities |= IFCAP_POLLING;
 #endif
+	ifp->if_capenable = ifp->if_capabilities;
 	ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
 	ifq_set_ready(&ifp->if_snd);
 
@@ -1604,8 +1606,6 @@
 		mii = device_get_softc(sc->rl_miibus);
 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
 		break;
-	case SIOCSIFCAP:
-		break;
 	default:
 		error = ether_ioctl(ifp, command, data);
 		break;
Index: sys/dev/netif/sis/if_sis.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/sis/if_sis.c,v
retrieving revision 1.23
diff -u -r1.23 if_sis.c
--- sys/dev/netif/sis/if_sis.c	25 May 2005 01:44:29 -0000	1.23
+++ sys/dev/netif/sis/if_sis.c	26 May 2005 19:10:31 -0000
@@ -1285,6 +1285,7 @@
 	ifq_set_ready(&ifp->if_snd);
 #ifdef DEVICE_POLLING
 	ifp->if_poll = sis_poll;
+	ifp->if_capabilities |= IFCAP_POLLING;
 #endif
 	ifp->if_capenable = ifp->if_capabilities;
 
Index: sys/dev/netif/vr/if_vr.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/vr/if_vr.c,v
retrieving revision 1.23
diff -u -r1.23 if_vr.c
--- sys/dev/netif/vr/if_vr.c	25 May 2005 01:44:31 -0000	1.23
+++ sys/dev/netif/vr/if_vr.c	26 May 2005 19:06:46 -0000
@@ -840,7 +840,9 @@
 	ifp->if_start = vr_start;
 #ifdef DEVICE_POLLING
 	ifp->if_poll = vr_poll;
+	ifp->if_capabilities |= IFCAP_POLLING;
 #endif
+	ifp->if_capenable = ifp->if_capabilities;
 	ifp->if_watchdog = vr_watchdog;
 	ifp->if_init = vr_init;
 	ifp->if_baudrate = 10000000;
@@ -1575,11 +1577,6 @@
 	s = splimp();
 
 	switch(command) {
-	case SIOCSIFADDR:
-	case SIOCGIFADDR:
-	case SIOCSIFMTU:
-		error = ether_ioctl(ifp, command, data);
-		break;
 	case SIOCSIFFLAGS:
 		if (ifp->if_flags & IFF_UP) {
 			vr_init(sc);
@@ -1600,7 +1597,7 @@
 		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
 		break;
 	default:
-		error = EINVAL;
+		error = ether_ioctl(ifp, command, data);
 		break;
 	}
 
Index: sys/dev/netif/wi/if_wi.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/dev/netif/wi/if_wi.c,v
retrieving revision 1.22
diff -u -r1.22 if_wi.c
--- sys/dev/netif/wi/if_wi.c	25 May 2005 01:44:32 -0000	1.22
+++ sys/dev/netif/wi/if_wi.c	26 May 2005 19:06:17 -0000
@@ -299,6 +299,7 @@
 	ifq_set_ready(&ifp->if_snd);
 #ifdef DEVICE_POLLING
 	ifp->if_poll = wi_poll;
+	ifp->if_capenable |= IFCAP_POLLING;
 #endif
 	ifp->if_capenable = ifp->if_capabilities;
 
@@ -1177,10 +1178,6 @@
 			break;
 		}
 		break;
-	case SIOCSIFCAP:
-		if (ifp->if_flags & IFF_RUNNING)
-			wi_init(sc);
-		break;
 	default:
 		error = ieee80211_ioctl(ifp, cmd, data, cr);
 		break;
Index: sys/kern/kern_poll.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/kern/kern_poll.c,v
retrieving revision 1.15
diff -u -r1.15 kern_poll.c
--- sys/kern/kern_poll.c	25 May 2005 01:44:14 -0000	1.15
+++ sys/kern/kern_poll.c	25 May 2005 14:41:54 -0000
@@ -157,13 +157,7 @@
 SYSCTL_UINT(_kern_polling, OID_AUTO, stalled, CTLFLAG_RW,
 	&stalled, 0, "potential stalls");
 
-
-#define POLL_LIST_LEN  128
-struct pollrec {
-	struct ifnet	*ifp;
-};
-
-static struct pollrec pr[POLL_LIST_LEN];
+static LIST_HEAD(, ifnet) poll_list = LIST_HEAD_INITIALIZER(poll_list);
 
 /*
  * register relevant netisr. Called from kern_clock.c:
@@ -306,10 +300,10 @@
 static int
 netisr_poll(struct netmsg *msg)
 {
+	struct ifnet *ifp, *tmp_ifp;
 	static int reg_frac_count;
-	int i, cycles;
+	int cycles, s;
 	enum poll_cmd arg = POLL_ONLY;
-	int s;
 
 	lwkt_replymsg(&msg->nm_lmsg, 0);
 	s = splimp();
@@ -352,24 +346,16 @@
 	residual_burst -= cycles;
 
 	if (polling) {
-		for (i = 0 ; i < poll_handlers ; i++) {
-			struct pollrec *p = &pr[i];
-			if ((p->ifp->if_flags & (IFF_UP|IFF_RUNNING|IFF_POLLING)) == (IFF_UP|IFF_RUNNING|IFF_POLLING)) {
-				p->ifp->if_poll(p->ifp, arg, cycles);
-			}
+		LIST_FOREACH_MUTABLE(ifp, &poll_list, if_poll_link, tmp_ifp) {
+			if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
+			    (IFF_UP | IFF_RUNNING))
+				ifp->if_poll(ifp, arg, cycles);
 		}
 	} else {	/* unregister */
-		for (i = 0 ; i < poll_handlers ; i++) {
-			struct pollrec *p = &pr[i];
-			if (p->ifp->if_flags & IFF_POLLING) {
-				p->ifp->if_flags &= ~IFF_POLLING;
-				/*
-				 * Only call the interface deregistration
-				 * function if the interface is still 
-				 * running.
-				 */
-				if (p->ifp->if_flags & IFF_RUNNING)
-					p->ifp->if_poll(p->ifp, POLL_DEREGISTER, 1);
+		LIST_FOREACH_MUTABLE(ifp, &poll_list, if_poll_link, tmp_ifp) {
+			if (ifp->if_flags & IFF_RUNNING) {
+				ifp->if_flags &= ~IFF_POLLING;
+				ifp->if_poll(ifp, POLL_DEREGISTER, 1);
 			}
 		}
 		residual_burst = 0;
@@ -405,38 +391,16 @@
 	 * Attempt to register.  Interlock with IFF_POLLING.
 	 */
 	crit_enter();	/* XXX MP - not mp safe */
+	LIST_INSERT_HEAD(&poll_list, ifp, if_poll_link);
 	ifp->if_flags |= IFF_POLLING;
 	ifp->if_poll(ifp, POLL_REGISTER, 0);
+	poll_handlers++;
 	if ((ifp->if_flags & IFF_POLLING) == 0) {
 		crit_exit();
 		return 0;
 	}
+	rc = 1;
 
-	/*
-	 * Check if there is room.  If there isn't, deregister.
-	 */
-	if (poll_handlers >= POLL_LIST_LEN) {
-		/*
-		 * List full, cannot register more entries.
-		 * This should never happen; if it does, it is probably a
-		 * broken driver trying to register multiple times. Checking
-		 * this at runtime is expensive, and won't solve the problem
-		 * anyways, so just report a few times and then give up.
-		 */
-		static int verbose = 10 ;
-		if (verbose >0) {
-			printf("poll handlers list full, "
-				"maybe a broken driver ?\n");
-			verbose--;
-		}
-		ifp->if_flags &= ~IFF_POLLING;
-		ifp->if_poll(ifp, POLL_DEREGISTER, 0);
-		rc = 0;
-	} else {
-		pr[poll_handlers].ifp = ifp;
-		poll_handlers++;
-		rc = 1;
-	}
 	crit_exit();
 	return (rc);
 }
@@ -448,27 +412,14 @@
 int
 ether_poll_deregister(struct ifnet *ifp)
 {
-	int i;
-
 	crit_enter();
 	if (ifp == NULL || (ifp->if_flags & IFF_POLLING) == 0) {
 		crit_exit();
 		return 0;
 	}
-	for (i = 0 ; i < poll_handlers ; i++) {
-		if (pr[i].ifp == ifp) /* found it */
-			break;
-	}
-	ifp->if_flags &= ~IFF_POLLING; /* found or not... */
-	if (i == poll_handlers) {
-		crit_exit();
-		printf("ether_poll_deregister: ifp not found!!!\n");
-		return 0;
-	}
+	LIST_REMOVE(ifp, if_poll_link);
+	ifp->if_flags &= ~IFF_POLLING;
 	poll_handlers--;
-	if (i < poll_handlers) { /* Last entry replaces this one. */
-		pr[i].ifp = pr[poll_handlers].ifp;
-	}
 	crit_exit();
 
 	/*
@@ -488,3 +439,15 @@
 		printf("%s forced polling on\n", name);
 	}
 }
+
+void
+ether_poll_update(struct ifnet *ifp)
+{
+	if ((ifp->if_flags & IFF_POLLING) &&
+	    (ifp->if_capenable & IFCAP_POLLING) == 0) {
+		ether_poll_deregister(ifp);
+	} else if ((ifp->if_flags & (IFF_POLLING | IFF_UP)) == IFF_UP &&
+	    (ifp->if_capenable & IFCAP_POLLING)) {
+		ether_poll_register(ifp);
+	}
+}
Index: sys/net/if.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/net/if.c,v
retrieving revision 1.36
diff -u -r1.36 if.c
--- sys/net/if.c	25 May 2005 21:26:52 -0000	1.36
+++ sys/net/if.c	26 May 2005 19:02:25 -0000
@@ -318,10 +318,6 @@
 	 * Remove routes and flush queues.
 	 */
 	s = splnet();
-#ifdef DEVICE_POLLING
-	if (ifp->if_flags & IFF_POLLING)
-		ether_poll_deregister(ifp);
-#endif
 	if_down(ifp);
 
 	if (ifq_is_enabled(&ifp->if_snd))
@@ -942,6 +938,10 @@
 void
 if_down(struct ifnet *ifp)
 {
+#ifdef DEVICE_POLLING
+	if (ifp->if_flags & IFF_POLLING)
+		ether_poll_deregister(ifp);
+#endif
 	if_unroute(ifp, IFF_UP, AF_UNSPEC);
 	netmsg_service_sync();
 }
@@ -954,7 +954,9 @@
 void
 if_up(struct ifnet *ifp)
 {
-
+#ifdef DEVICE_POLLING
+	ether_poll_update(ifp);
+#endif
 	if_route(ifp, IFF_UP, AF_UNSPEC);
 }
 
@@ -1026,7 +1028,6 @@
 	return ifunit(ifname);
 }
 
-
 /*
  * Interface ioctls.
  */
@@ -1112,16 +1113,6 @@
 			splx(s);
 		}
 
-#ifdef DEVICE_POLLING
-		if ((new_flags ^ ifp->if_flags) & IFF_POLLING) {
-			if (new_flags & IFF_POLLING) {
-				ether_poll_register(ifp);
-			} else {
-				ether_poll_deregister(ifp);
-			}
-		}
-#endif
-
 		ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
 			(new_flags &~ IFF_CANTCHANGE);
 		if (new_flags & IFF_PPROMISC) {
Index: sys/net/if.h
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/net/if.h,v
retrieving revision 1.13
diff -u -r1.13 if.h
--- sys/net/if.h	25 May 2005 14:59:05 -0000	1.13
+++ sys/net/if.h	26 May 2005 19:03:17 -0000
@@ -163,6 +163,7 @@
 #define IFCAP_VLAN_MTU		0x0008	/* VLAN-compatible MTU */
 #define IFCAP_VLAN_HWTAGGING	0x0010	/* hardware VLAN tag support */
 #define IFCAP_JUMBO_MTU		0x0020	/* 9000 byte MTU support */
+#define	IFCAP_POLLING		0x0040	/* driver supports polling */
 
 #define IFCAP_HWCSUM		(IFCAP_RXCSUM | IFCAP_TXCSUM)
 
Index: sys/net/if_ethersubr.c
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/net/if_ethersubr.c,v
retrieving revision 1.30
diff -u -r1.30 if_ethersubr.c
--- sys/net/if_ethersubr.c	18 Apr 2005 14:26:57 -0000	1.30
+++ sys/net/if_ethersubr.c	26 May 2005 19:11:28 -0000
@@ -940,6 +940,15 @@
 			ifp->if_mtu = ifr->ifr_mtu;
 		}
 		break;
+	case SIOCSIFCAP:
+#ifdef DEVICE_POLLING
+		if (ifp->if_capabilities & IFCAP_POLLING) {
+			ifp->if_capenable &= ~IFCAP_POLLING;
+			ifp->if_capenable |= ifr->ifr_reqcap & IFCAP_POLLING;
+			ether_poll_update(ifp);
+		}
+#endif
+		break;
 	default:
 		error = EINVAL;
 		break;
Index: sys/net/if_var.h
===================================================================
RCS file: /home/joerg/wd/repository/dragonflybsd/src/sys/net/if_var.h,v
retrieving revision 1.25
diff -u -r1.25 if_var.h
--- sys/net/if_var.h	25 May 2005 01:44:16 -0000	1.25
+++ sys/net/if_var.h	25 May 2005 14:48:32 -0000
@@ -179,11 +179,12 @@
 	int	(*if_resolvemulti)	/* validate/resolve multicast */
 		(struct ifnet *, struct sockaddr **, struct sockaddr *);
 #ifdef DEVICE_POLLING
-	void	(*if_poll)		/* IFF_POLLING support */
+	void	(*if_poll)		/* DEVICE_POLLING support */
 		(struct ifnet *, enum poll_cmd, int);
 #else
 	void	(*if_poll_unused)(void); /* placeholder */
 #endif
+	LIST_ENTRY(ifnet) if_poll_link;
 	struct	ifaltq if_snd;		/* output queue (includes altq) */
 	struct	ifprefixhead if_prefixhead; /* list of prefixes per if */
 	const uint8_t	*if_broadcastaddr;
@@ -454,8 +455,8 @@
     LLADDR((struct sockaddr_dl *) ifnet_addrs[ifp->if_index - 1]->ifa_addr)
 
 #ifdef DEVICE_POLLING
-typedef	void poll_handler_t (struct ifnet *ifp,
-		enum poll_cmd cmd, int count);
+typedef	void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count);
+void	ether_poll_update(struct ifnet *ifp);
 int	ether_poll_register(struct ifnet *ifp);
 int	ether_poll_deregister(struct ifnet *ifp);
 void	emergency_poll_enable(const char *name);




More information about the Commits mailing list