Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 Apr 2008 21:47:10 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 139244 for review
Message-ID:  <200804022147.m32LlAfU069894@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=139244

Change 139244 by sam@sam_ebb on 2008/04/02 21:47:04

	Tweak ioctl handling to give driver more control on parameter changes:
	o move iv_reset callback up into set80211 so we can pass the
	  IEEE80211_IOC_* code to the driver; doing this in the top-level
	  was pretty pointless as drivers don't get access to the indirect
	  cmd block and so cannot identify what parameter was changed
	o change some parameters from doing ENETRESET (clock state machine)
	  to ERESTART (pass through iv_reset): IEEE80211_IOC_WPA,
	  IEEE80211_IOC_WME, IEEE80211_IOC_FF, IEEE80211_IOC_FRAGTHRESHOLD,
	  IEEE80211_IOC_BURST, IEEE80211_IOC_BMISSTHRESHOLD; this list is
	  tentative and needs more review

Affected files ...

.. //depot/projects/vap/sys/net80211/ieee80211_ioctl.c#51 edit

Differences ...

==== //depot/projects/vap/sys/net80211/ieee80211_ioctl.c#51 (text+ko) ====

@@ -2611,12 +2611,14 @@
 			vap->iv_flags |= IEEE80211_F_PRIVACY;
 		} else
 			vap->iv_flags &= ~IEEE80211_F_PRIVACY;
+		/* XXX ERESTART? */
 		break;
 	case IEEE80211_IOC_DROPUNENCRYPTED:
 		if (ireq->i_val)
 			vap->iv_flags |= IEEE80211_F_DROPUNENC;
 		else
 			vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
+		/* XXX ERESTART? */
 		break;
 	case IEEE80211_IOC_WPAKEY:
 		error = ieee80211_ioctl_setkey(vap, ireq);
@@ -2634,6 +2636,7 @@
 			vap->iv_flags |= IEEE80211_F_COUNTERM;
 		} else
 			vap->iv_flags &= ~IEEE80211_F_COUNTERM;
+		/* XXX ERESTART? */
 		break;
 	case IEEE80211_IOC_WPA:
 		if (ireq->i_val > 3)
@@ -2651,7 +2654,7 @@
 			vap->iv_flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2;
 			break;
 		}
-		error = ENETRESET;		/* XXX optimize */
+		error = ERESTART;	/* NB: can change beacon frame */
 		break;
 	case IEEE80211_IOC_WME:
 		if (ireq->i_val) {
@@ -2660,7 +2663,7 @@
 			ieee80211_syncflag(vap, IEEE80211_F_WME);
 		} else
 			ieee80211_syncflag(vap, -IEEE80211_F_WME);
-		error = ENETRESET;
+		error = ERESTART;	/* NB: can change beacon frame */
 		break;
 	case IEEE80211_IOC_HIDESSID:
 		if (ireq->i_val)
@@ -2793,7 +2796,7 @@
 			vap->iv_flags |= IEEE80211_F_FF;
 		} else
 			vap->iv_flags &= ~IEEE80211_F_FF;
-		error = ENETRESET;
+		error = ERESTART;
 		break;
 	case IEEE80211_IOC_TURBOP:
 		if (ireq->i_val) {
@@ -2838,7 +2841,7 @@
 		      ireq->i_val <= IEEE80211_FRAG_MAX))
 			return EINVAL;
 		vap->iv_fragthreshold = ireq->i_val;
-		error = ENETRESET;
+		error = ERESTART;
 		break;
 	case IEEE80211_IOC_BURST:
 		if (ireq->i_val) {
@@ -2847,14 +2850,14 @@
 			ieee80211_syncflag(vap, IEEE80211_F_BURST);
 		} else
 			ieee80211_syncflag(vap, -IEEE80211_F_BURST);
-		error = ENETRESET;		/* XXX maybe not for station? */
+		error = ERESTART;
 		break;
 	case IEEE80211_IOC_BMISSTHRESHOLD:
 		if (!(IEEE80211_HWBMISS_MIN <= ireq->i_val &&
 		      ireq->i_val <= IEEE80211_HWBMISS_MAX))
 			return EINVAL;
 		vap->iv_bmissthreshold = ireq->i_val;
-		error = ENETRESET;
+		error = ERESTART;
 		break;
 	case IEEE80211_IOC_CURCHAN:
 		error = ieee80211_ioctl_setcurchan(vap, ireq);
@@ -2873,7 +2876,7 @@
 		} else
 			vap->iv_flags_ext &=
 			    ~(IEEE80211_FEXT_SHORTGI20 | IEEE80211_FEXT_SHORTGI40);
-		error = ERESTART;		/* XXX ENETRESET? */
+		error = ERESTART;
 		break;
 	case IEEE80211_IOC_AMPDU:
 		if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMPDU) == 0)
@@ -2888,7 +2891,7 @@
 			vap->iv_flags_ext &= ~IEEE80211_FEXT_AMPDU_RX;
 		/* NB: reset only if we're operating on an 11n channel */
 		if (isvapht(vap))
-			error = ERESTART;		/* XXX ENETRESET? */
+			error = ERESTART;
 		break;
 	case IEEE80211_IOC_AMPDU_LIMIT:
 		if (!(IEEE80211_HTCAP_MAXRXAMPDU_8K <= ireq->i_val &&
@@ -2898,14 +2901,14 @@
 			vap->iv_ampdu_rxmax = ireq->i_val;
 		else
 			vap->iv_ampdu_limit = ireq->i_val;
-		error = ERESTART;		/* XXX ENETRESET? */
+		error = ERESTART;
 		break;
 	case IEEE80211_IOC_AMPDU_DENSITY:
 		if (!(IEEE80211_HTCAP_MPDUDENSITY_NA <= ireq->i_val &&
 		      ireq->i_val <= IEEE80211_HTCAP_MPDUDENSITY_16))
 			return EINVAL;
 		vap->iv_ampdu_density = ireq->i_val;
-		error = ERESTART;		/* XXX ENETRESET? */
+		error = ERESTART;
 		break;
 	case IEEE80211_IOC_AMSDU:
 		if (ireq->i_val && (vap->iv_htcaps & IEEE80211_HTC_AMSDU) == 0)
@@ -2920,7 +2923,7 @@
 			vap->iv_flags_ext &= ~IEEE80211_FEXT_AMSDU_RX;
 		/* NB: reset only if we're operating on an 11n channel */
 		if (isvapht(vap))
-			error = ERESTART;		/* XXX ENETRESET? */
+			error = ERESTART;
 		break;
 	case IEEE80211_IOC_AMSDU_LIMIT:
 		/* XXX validate */
@@ -2935,7 +2938,7 @@
 			vap->iv_flags_ext &= ~IEEE80211_FEXT_PUREN;
 		/* NB: reset only if we're operating on an 11n channel */
 		if (isvapht(vap))
-			error = ERESTART;		/* XXX ENETRESET? */
+			error = ERESTART;
 		break;
 	case IEEE80211_IOC_DOTH:
 		if (ireq->i_val) {
@@ -2967,7 +2970,7 @@
 			vap->iv_flags_ext &= ~IEEE80211_FEXT_HTCOMPAT;
 		/* NB: reset only if we're operating on an 11n channel */
 		if (isvapht(vap))
-			error = ERESTART;		/* XXX ENETRESET? */
+			error = ERESTART;
 		break;
 	case IEEE80211_IOC_DWDS:
 		if (ireq->i_val) {
@@ -3048,6 +3051,22 @@
 		error = EINVAL;
 		break;
 	}
+	/*
+	 * The convention is that ENETRESET means an operation
+	 * requires a complete re-initialization of the device (e.g.
+	 * changing something that affects the association state).
+	 * ERESTART means the request may be handled with only a
+	 * reload of the hardware state.  We hand ERESTART requests
+	 * to the iv_reset callback so the driver can decide.  If
+	 * a device does not fillin iv_reset then it defaults to one
+	 * that returns ENETRESET.  Otherwise a driver may return
+	 * ENETRESET (in which case a full reset will be done) or
+	 * 0 to mean there's no need to do anything (e.g. when the
+	 * change has no effect on the driver/device).
+	 */
+	if (error == ERESTART)
+		error = IFNET_IS_UP_RUNNING(vap->iv_ifp) ?
+		    vap->iv_reset(vap, ireq->i_type) : 0;
 	if (error == ENETRESET && !IS_UP_AUTO(vap))
 		error = 0;
 	return error;
@@ -3217,14 +3236,7 @@
 	 * The convention is to return ENETRESET when an operation
 	 * requires a complete re-initialization of the device (e.g.
 	 * changing something that affects the association state).
-	 * If ERESTART is returned then the operation requires a
-	 * reload of the hardware state but not a complete re-init;
-	 * in that case we use the iv_reset callback.  If a device
-	 * does not fillin iv_reset then it defaults to one that
-	 * returns ENETRESET--which may be suboptimal.
 	 */
-	if (error == ERESTART)
-		error = IFNET_IS_UP_RUNNING(ifp) ? vap->iv_reset(vap, cmd) : 0;
 	if (error == ENETRESET) {
 		if (IFNET_IS_UP_RUNNING(ifp))
 			ieee80211_init(vap);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200804022147.m32LlAfU069894>