Retry fix

This enables modifying retry limits on madwifi via Wext. While the
implementation on the ioctl adds support (ieee80211_wireless.c) for
short retry, long retry and even retry lifetime the HAL only allows us
currently to modify one simple retry limit.

Signed-Off by: Luis Rodriguez <mcgrof@winlab.rutgers.edu>

diff -Naurp madwifi-0.9.3.3.old.2/ath/if_ath.c madwifi-0.9.3.3/ath/if_ath.c
--- madwifi-0.9.3.3.old.2/ath/if_ath.c	2007-11-07 16:41:13.000000000 -0500
+++ madwifi-0.9.3.3/ath/if_ath.c	2007-11-07 16:41:40.000000000 -0500
@@ -6887,6 +6887,12 @@ ath_tx_start(struct net_device *dev, str
 			sc->sc_rc->ops->findrate(sc, an, shortPreamble, skb->len,
 				&rix, &try0, &txrate);
 
+			/* Note: HAL does not support distinguishing between short
+ 			 * and long retry. These both are set via try0 here then.
+ 			 * In the openhal we'll fix this ;) */
+			if (vap->iv_flags & IEEE80211_F_SWRETRY && vap->iv_txmax != try0)
+				try0 = vap->iv_txmax;
+
 			/* Ratecontrol sometimes returns invalid rate index */
 			if (rix != 0xff)
 				an->an_prevdatarix = rix;
diff -Naurp madwifi-0.9.3.3.old.2/ath/if_ath.c.orig madwifi-0.9.3.3/ath/if_ath.c.orig
--- madwifi-0.9.3.3.old.2/ath/if_ath.c.orig	2007-11-07 16:40:51.000000000 -0500
+++ madwifi-0.9.3.3/ath/if_ath.c.orig	2007-11-07 16:41:13.000000000 -0500
@@ -6887,12 +6887,6 @@ ath_tx_start(struct net_device *dev, str
 			sc->sc_rc->ops->findrate(sc, an, shortPreamble, skb->len,
 				&rix, &try0, &txrate);
 
-			/* Note: HAL does not support distinguishing between short
- 			 * and long retry. These both are set via try0 here then.
- 			 * In the openhal we'll fix this ;) */
-			if (vap->iv_flags & IEEE80211_F_SWRETRY && vap->iv_txmax != try0)
-				try0 = vap->iv_txmax;
-
 			/* Ratecontrol sometimes returns invalid rate index */
 			if (rix != 0xff)
 				an->an_prevdatarix = rix;
diff -Naurp madwifi-0.9.3.3.old.2/net80211/ieee80211.c madwifi-0.9.3.3/net80211/ieee80211.c
--- madwifi-0.9.3.3.old.2/net80211/ieee80211.c	2007-11-07 16:41:13.000000000 -0500
+++ madwifi-0.9.3.3/net80211/ieee80211.c	2007-11-07 16:41:40.000000000 -0500
@@ -452,14 +452,17 @@ ieee80211_vap_setup(struct ieee80211com 
 	vap->iv_mcast_rate = 1000;
 #endif
 	vap->iv_caps = ic->ic_caps &~ IEEE80211_C_OPMODE;
+	/* Means its unset yet via WE SIOCSIWRETRY ioctl */
+	vap->iv_flags &= ~IEEE80211_F_SWRETRY;
 	switch (opmode) {
 	case IEEE80211_M_STA:
 		/* WDS/Repeater */
 		if (flags & IEEE80211_NO_STABEACONS)
 			vap->iv_flags_ext |= IEEE80211_FEXT_SWBMISS;
+		vap->iv_caps |= IEEE80211_C_SWRETRY;
 		break;
 	case IEEE80211_M_IBSS:
-		vap->iv_caps |= IEEE80211_C_IBSS;
+		vap->iv_caps |= IEEE80211_C_IBSS | IEEE80211_C_SWRETRY;
 		vap->iv_ath_cap &= ~IEEE80211_ATHC_XR;
 		break;
 	case IEEE80211_M_AHDEMO:
diff -Naurp madwifi-0.9.3.3.old.2/net80211/ieee80211_wireless.c madwifi-0.9.3.3/net80211/ieee80211_wireless.c
--- madwifi-0.9.3.3.old.2/net80211/ieee80211_wireless.c	2007-11-07 16:41:13.000000000 -0500
+++ madwifi-0.9.3.3/net80211/ieee80211_wireless.c	2007-11-07 16:41:40.000000000 -0500
@@ -1288,6 +1288,19 @@ ieee80211_ioctl_giwpower(struct net_devi
 	return 0;
 }
 
+/* WE-21 added support for IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers 
+ * Note: IW_RETRY_SHORT/IW_RETRY_LONG was just a userspace improvement so
+ * we can just add the defines required for its support here and a user
+ * with an older kernel but new WE will still be able to benefit from this */
+#if WIRELESS_EXT < 21
+/* Retry limits and lifetime flags available */
+#ifndef IW_RETRY_LIFETIME /* Can't pinpoint when this guy was introduced */
+#define IW_RETRY_LIFETIME       0x2000  /* Maximum duration of retries in us */
+#endif /* IW_RETRY_LIFETIME */
+#define IW_RETRY_SHORT          0x0010  /* Value is for short packets  */
+#define IW_RETRY_LONG           0x0020  /* Value is for long packets */
+#endif /* WIRELESS_EXT < 21 */
+
 static int
 ieee80211_ioctl_siwretry(struct net_device *dev, struct iw_request_info *info,
 	struct iw_param *rrq, char *extra)
@@ -1300,24 +1313,32 @@ ieee80211_ioctl_siwretry(struct net_devi
 			vap->iv_flags &= ~IEEE80211_F_SWRETRY;
 			goto done;
 		}
+		/* Already disabled in iv_flags, nothing to do */
 		return 0;
 	}
-
 	if ((vap->iv_caps & IEEE80211_C_SWRETRY) == 0)
 		return -EOPNOTSUPP;
+	if (rrq->value < 0)
+		return -EINVAL;
 	if (rrq->flags == IW_RETRY_LIMIT) {
 		if (rrq->value >= 0) {
-			vap->iv_txmin = rrq->value;
-			vap->iv_txmax = rrq->value;	/* XXX */
-			vap->iv_txlifetime = 0;		/* XXX */
+			if (rrq->flags & IW_RETRY_SHORT)
+				vap->iv_txmin = rrq->value;
+			else if (rrq->flags & IW_RETRY_LONG)
+				vap->iv_txmax = rrq->value;
+			else {
+				vap->iv_txmin = rrq->value;
+				vap->iv_txmax = rrq->value;
+			}
 			vap->iv_flags |= IEEE80211_F_SWRETRY;
 		} else {
 			vap->iv_flags &= ~IEEE80211_F_SWRETRY;
 		}
-		return 0;
 	}
+	if (rrq->flags & IW_RETRY_LIFETIME)
+		vap->iv_txlifetime = 0;
 done:
-	return IS_UP(vap->iv_dev) ? ic->ic_reset(vap->iv_dev) : 0;
+	return IS_UP(ic->ic_dev) ? ic->ic_reset(ic->ic_dev) : 0;
 }
 
 static int
diff -Naurp madwifi-0.9.3.3.old.2/net80211/ieee80211_wireless.c.orig madwifi-0.9.3.3/net80211/ieee80211_wireless.c.orig
--- madwifi-0.9.3.3.old.2/net80211/ieee80211_wireless.c.orig	2007-11-07 16:40:51.000000000 -0500
+++ madwifi-0.9.3.3/net80211/ieee80211_wireless.c.orig	2007-11-07 16:41:13.000000000 -0500
@@ -1288,19 +1288,6 @@ ieee80211_ioctl_giwpower(struct net_devi
 	return 0;
 }
 
-/* WE-21 added support for IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers 
- * Note: IW_RETRY_SHORT/IW_RETRY_LONG was just a userspace improvement so
- * we can just add the defines required for its support here and a user
- * with an older kernel but new WE will still be able to benefit from this */
-#if WIRELESS_EXT < 21
-/* Retry limits and lifetime flags available */
-#ifndef IW_RETRY_LIFETIME /* Can't pinpoint when this guy was introduced */
-#define IW_RETRY_LIFETIME       0x2000  /* Maximum duration of retries in us */
-#endif /* IW_RETRY_LIFETIME */
-#define IW_RETRY_SHORT          0x0010  /* Value is for short packets  */
-#define IW_RETRY_LONG           0x0020  /* Value is for long packets */
-#endif /* WIRELESS_EXT < 21 */
-
 static int
 ieee80211_ioctl_siwretry(struct net_device *dev, struct iw_request_info *info,
 	struct iw_param *rrq, char *extra)
@@ -1313,32 +1300,24 @@ ieee80211_ioctl_siwretry(struct net_devi
 			vap->iv_flags &= ~IEEE80211_F_SWRETRY;
 			goto done;
 		}
-		/* Already disabled in iv_flags, nothing to do */
 		return 0;
 	}
+
 	if ((vap->iv_caps & IEEE80211_C_SWRETRY) == 0)
 		return -EOPNOTSUPP;
-	if (rrq->value < 0)
-		return -EINVAL;
 	if (rrq->flags == IW_RETRY_LIMIT) {
 		if (rrq->value >= 0) {
-			if (rrq->flags & IW_RETRY_SHORT)
-				vap->iv_txmin = rrq->value;
-			else if (rrq->flags & IW_RETRY_LONG)
-				vap->iv_txmax = rrq->value;
-			else {
-				vap->iv_txmin = rrq->value;
-				vap->iv_txmax = rrq->value;
-			}
+			vap->iv_txmin = rrq->value;
+			vap->iv_txmax = rrq->value;	/* XXX */
+			vap->iv_txlifetime = 0;		/* XXX */
 			vap->iv_flags |= IEEE80211_F_SWRETRY;
 		} else {
 			vap->iv_flags &= ~IEEE80211_F_SWRETRY;
 		}
+		return 0;
 	}
-	if (rrq->flags & IW_RETRY_LIFETIME)
-		vap->iv_txlifetime = 0;
 done:
-	return IS_UP(ic->ic_dev) ? ic->ic_reset(ic->ic_dev) : 0;
+	return IS_UP(vap->iv_dev) ? ic->ic_reset(vap->iv_dev) : 0;
 }
 
 static int
