aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Kilroy <kilroyd@googlemail.com>2010-04-19 03:16:21 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-19 16:41:42 -0400
commitc3d415030c1a00cc21935c38f8761db46ef1d7ff (patch)
tree86fe257df362d102e0b327c0e4fa3220c70b305b
parent3393a608c4979a94d1887efc05b792849d361a65 (diff)
orinoco: implement set_wiphy_params
... to set fragmentation and RTS thresholds. Also report RTS retry settings during wiphy init. Note that the existing semantics for enabling microwave robustness are preserved on firmwares that have it. Signed-off-by: David Kilroy <kilroyd@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/orinoco/cfg.c88
-rw-r--r--drivers/net/wireless/orinoco/hw.c26
-rw-r--r--drivers/net/wireless/orinoco/orinoco.h2
-rw-r--r--drivers/net/wireless/orinoco/wext.c183
4 files changed, 120 insertions, 179 deletions
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index 27f2d3342645..90dd4d0595c3 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -88,7 +88,9 @@ int orinoco_wiphy_register(struct wiphy *wiphy)
88 88
89 wiphy->rts_threshold = priv->rts_thresh; 89 wiphy->rts_threshold = priv->rts_thresh;
90 if (!priv->has_mwo) 90 if (!priv->has_mwo)
91 wiphy->frag_threshold = priv->frag_thresh; 91 wiphy->frag_threshold = priv->frag_thresh + 1;
92 wiphy->retry_short = priv->short_retry_limit;
93 wiphy->retry_long = priv->long_retry_limit;
92 94
93 return wiphy_register(wiphy); 95 return wiphy_register(wiphy);
94} 96}
@@ -196,8 +198,92 @@ static int orinoco_set_channel(struct wiphy *wiphy,
196 return err; 198 return err;
197} 199}
198 200
201static int orinoco_set_wiphy_params(struct wiphy *wiphy, u32 changed)
202{
203 struct orinoco_private *priv = wiphy_priv(wiphy);
204 int frag_value = -1;
205 int rts_value = -1;
206 int err = 0;
207
208 if (changed & WIPHY_PARAM_RETRY_SHORT) {
209 /* Setting short retry not supported */
210 err = -EINVAL;
211 }
212
213 if (changed & WIPHY_PARAM_RETRY_LONG) {
214 /* Setting long retry not supported */
215 err = -EINVAL;
216 }
217
218 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
219 /* Set fragmentation */
220 if (priv->has_mwo) {
221 if (wiphy->frag_threshold < 0)
222 frag_value = 0;
223 else {
224 printk(KERN_WARNING "%s: Fixed fragmentation "
225 "is not supported on this firmware. "
226 "Using MWO robust instead.\n",
227 priv->ndev->name);
228 frag_value = 1;
229 }
230 } else {
231 if (wiphy->frag_threshold < 0)
232 frag_value = 2346;
233 else if ((wiphy->frag_threshold < 257) ||
234 (wiphy->frag_threshold > 2347))
235 err = -EINVAL;
236 else
237 /* cfg80211 value is 257-2347 (odd only)
238 * orinoco rid has range 256-2346 (even only) */
239 frag_value = wiphy->frag_threshold & ~0x1;
240 }
241 }
242
243 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
244 /* Set RTS.
245 *
246 * Prism documentation suggests default of 2432,
247 * and a range of 0-3000.
248 *
249 * Current implementation uses 2347 as the default and
250 * the upper limit.
251 */
252
253 if (wiphy->rts_threshold < 0)
254 rts_value = 2347;
255 else if (wiphy->rts_threshold > 2347)
256 err = -EINVAL;
257 else
258 rts_value = wiphy->rts_threshold;
259 }
260
261 if (!err) {
262 unsigned long flags;
263
264 if (orinoco_lock(priv, &flags) != 0)
265 return -EBUSY;
266
267 if (frag_value >= 0) {
268 if (priv->has_mwo)
269 priv->mwo_robust = frag_value;
270 else
271 priv->frag_thresh = frag_value;
272 }
273 if (rts_value >= 0)
274 priv->rts_thresh = rts_value;
275
276 err = orinoco_commit(priv);
277
278 orinoco_unlock(priv, &flags);
279 }
280
281 return err;
282}
283
199const struct cfg80211_ops orinoco_cfg_ops = { 284const struct cfg80211_ops orinoco_cfg_ops = {
200 .change_virtual_intf = orinoco_change_vif, 285 .change_virtual_intf = orinoco_change_vif,
201 .set_channel = orinoco_set_channel, 286 .set_channel = orinoco_set_channel,
202 .scan = orinoco_scan, 287 .scan = orinoco_scan,
288 .set_wiphy_params = orinoco_set_wiphy_params,
203}; 289};
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 883b8f868626..24ea4b4d487e 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -374,6 +374,32 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
374 err = hermes_read_wordrec(hw, USER_BAP, 374 err = hermes_read_wordrec(hw, USER_BAP,
375 HERMES_RID_CNFPREAMBLE_SYMBOL, 375 HERMES_RID_CNFPREAMBLE_SYMBOL,
376 &priv->preamble); 376 &priv->preamble);
377 if (err) {
378 dev_err(dev, "Failed to read preamble setup\n");
379 goto out;
380 }
381 }
382
383 /* Retry settings */
384 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
385 &priv->short_retry_limit);
386 if (err) {
387 dev_err(dev, "Failed to read short retry limit\n");
388 goto out;
389 }
390
391 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
392 &priv->long_retry_limit);
393 if (err) {
394 dev_err(dev, "Failed to read long retry limit\n");
395 goto out;
396 }
397
398 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
399 &priv->retry_lifetime);
400 if (err) {
401 dev_err(dev, "Failed to read max retry lifetime\n");
402 goto out;
377 } 403 }
378 404
379out: 405out:
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 665ef56f8382..ff6b7b1d421d 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -131,6 +131,8 @@ struct orinoco_private {
131 u16 ap_density, rts_thresh; 131 u16 ap_density, rts_thresh;
132 u16 pm_on, pm_mcast, pm_period, pm_timeout; 132 u16 pm_on, pm_mcast, pm_period, pm_timeout;
133 u16 preamble; 133 u16 preamble;
134 u16 short_retry_limit, long_retry_limit;
135 u16 retry_lifetime;
134#ifdef WIRELESS_SPY 136#ifdef WIRELESS_SPY
135 struct iw_spy_data spy_data; /* iwspy support */ 137 struct iw_spy_data spy_data; /* iwspy support */
136 struct iw_public_data wireless_data; 138 struct iw_public_data wireless_data;
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 29f9bc03190a..d261423ecf62 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -537,125 +537,6 @@ static int orinoco_ioctl_setsens(struct net_device *dev,
537 return -EINPROGRESS; /* Call commit handler */ 537 return -EINPROGRESS; /* Call commit handler */
538} 538}
539 539
540static int orinoco_ioctl_setrts(struct net_device *dev,
541 struct iw_request_info *info,
542 struct iw_param *rrq,
543 char *extra)
544{
545 struct orinoco_private *priv = ndev_priv(dev);
546 int val = rrq->value;
547 unsigned long flags;
548
549 if (rrq->disabled)
550 val = 2347;
551
552 if ((val < 0) || (val > 2347))
553 return -EINVAL;
554
555 if (orinoco_lock(priv, &flags) != 0)
556 return -EBUSY;
557
558 priv->rts_thresh = val;
559 orinoco_unlock(priv, &flags);
560
561 return -EINPROGRESS; /* Call commit handler */
562}
563
564static int orinoco_ioctl_getrts(struct net_device *dev,
565 struct iw_request_info *info,
566 struct iw_param *rrq,
567 char *extra)
568{
569 struct orinoco_private *priv = ndev_priv(dev);
570
571 rrq->value = priv->rts_thresh;
572 rrq->disabled = (rrq->value == 2347);
573 rrq->fixed = 1;
574
575 return 0;
576}
577
578static int orinoco_ioctl_setfrag(struct net_device *dev,
579 struct iw_request_info *info,
580 struct iw_param *frq,
581 char *extra)
582{
583 struct orinoco_private *priv = ndev_priv(dev);
584 int err = -EINPROGRESS; /* Call commit handler */
585 unsigned long flags;
586
587 if (orinoco_lock(priv, &flags) != 0)
588 return -EBUSY;
589
590 if (priv->has_mwo) {
591 if (frq->disabled)
592 priv->mwo_robust = 0;
593 else {
594 if (frq->fixed)
595 printk(KERN_WARNING "%s: Fixed fragmentation "
596 "is not supported on this firmware. "
597 "Using MWO robust instead.\n",
598 dev->name);
599 priv->mwo_robust = 1;
600 }
601 } else {
602 if (frq->disabled)
603 priv->frag_thresh = 2346;
604 else {
605 if ((frq->value < 256) || (frq->value > 2346))
606 err = -EINVAL;
607 else
608 /* must be even */
609 priv->frag_thresh = frq->value & ~0x1;
610 }
611 }
612
613 orinoco_unlock(priv, &flags);
614
615 return err;
616}
617
618static int orinoco_ioctl_getfrag(struct net_device *dev,
619 struct iw_request_info *info,
620 struct iw_param *frq,
621 char *extra)
622{
623 struct orinoco_private *priv = ndev_priv(dev);
624 hermes_t *hw = &priv->hw;
625 int err;
626 u16 val;
627 unsigned long flags;
628
629 if (orinoco_lock(priv, &flags) != 0)
630 return -EBUSY;
631
632 if (priv->has_mwo) {
633 err = hermes_read_wordrec(hw, USER_BAP,
634 HERMES_RID_CNFMWOROBUST_AGERE,
635 &val);
636 if (err)
637 val = 0;
638
639 frq->value = val ? 2347 : 0;
640 frq->disabled = !val;
641 frq->fixed = 0;
642 } else {
643 err = hermes_read_wordrec(hw, USER_BAP,
644 HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
645 &val);
646 if (err)
647 val = 0;
648
649 frq->value = val;
650 frq->disabled = (val >= 2346);
651 frq->fixed = 1;
652 }
653
654 orinoco_unlock(priv, &flags);
655
656 return err;
657}
658
659static int orinoco_ioctl_setrate(struct net_device *dev, 540static int orinoco_ioctl_setrate(struct net_device *dev,
660 struct iw_request_info *info, 541 struct iw_request_info *info,
661 struct iw_param *rrq, 542 struct iw_param *rrq,
@@ -1200,60 +1081,6 @@ static int orinoco_ioctl_set_mlme(struct net_device *dev,
1200 return ret; 1081 return ret;
1201} 1082}
1202 1083
1203static int orinoco_ioctl_getretry(struct net_device *dev,
1204 struct iw_request_info *info,
1205 struct iw_param *rrq,
1206 char *extra)
1207{
1208 struct orinoco_private *priv = ndev_priv(dev);
1209 hermes_t *hw = &priv->hw;
1210 int err = 0;
1211 u16 short_limit, long_limit, lifetime;
1212 unsigned long flags;
1213
1214 if (orinoco_lock(priv, &flags) != 0)
1215 return -EBUSY;
1216
1217 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
1218 &short_limit);
1219 if (err)
1220 goto out;
1221
1222 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
1223 &long_limit);
1224 if (err)
1225 goto out;
1226
1227 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
1228 &lifetime);
1229 if (err)
1230 goto out;
1231
1232 rrq->disabled = 0; /* Can't be disabled */
1233
1234 /* Note : by default, display the retry number */
1235 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1236 rrq->flags = IW_RETRY_LIFETIME;
1237 rrq->value = lifetime * 1000; /* ??? */
1238 } else {
1239 /* By default, display the min number */
1240 if ((rrq->flags & IW_RETRY_LONG)) {
1241 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
1242 rrq->value = long_limit;
1243 } else {
1244 rrq->flags = IW_RETRY_LIMIT;
1245 rrq->value = short_limit;
1246 if (short_limit != long_limit)
1247 rrq->flags |= IW_RETRY_SHORT;
1248 }
1249 }
1250
1251 out:
1252 orinoco_unlock(priv, &flags);
1253
1254 return err;
1255}
1256
1257static int orinoco_ioctl_reset(struct net_device *dev, 1084static int orinoco_ioctl_reset(struct net_device *dev,
1258 struct iw_request_info *info, 1085 struct iw_request_info *info,
1259 void *wrqu, 1086 void *wrqu,
@@ -1527,11 +1354,11 @@ static const iw_handler orinoco_handler[] = {
1527 IW_HANDLER(SIOCGIWESSID, (iw_handler)orinoco_ioctl_getessid), 1354 IW_HANDLER(SIOCGIWESSID, (iw_handler)orinoco_ioctl_getessid),
1528 IW_HANDLER(SIOCSIWRATE, (iw_handler)orinoco_ioctl_setrate), 1355 IW_HANDLER(SIOCSIWRATE, (iw_handler)orinoco_ioctl_setrate),
1529 IW_HANDLER(SIOCGIWRATE, (iw_handler)orinoco_ioctl_getrate), 1356 IW_HANDLER(SIOCGIWRATE, (iw_handler)orinoco_ioctl_getrate),
1530 IW_HANDLER(SIOCSIWRTS, (iw_handler)orinoco_ioctl_setrts), 1357 IW_HANDLER(SIOCSIWRTS, (iw_handler)cfg80211_wext_siwrts),
1531 IW_HANDLER(SIOCGIWRTS, (iw_handler)orinoco_ioctl_getrts), 1358 IW_HANDLER(SIOCGIWRTS, (iw_handler)cfg80211_wext_giwrts),
1532 IW_HANDLER(SIOCSIWFRAG, (iw_handler)orinoco_ioctl_setfrag), 1359 IW_HANDLER(SIOCSIWFRAG, (iw_handler)cfg80211_wext_siwfrag),
1533 IW_HANDLER(SIOCGIWFRAG, (iw_handler)orinoco_ioctl_getfrag), 1360 IW_HANDLER(SIOCGIWFRAG, (iw_handler)cfg80211_wext_giwfrag),
1534 IW_HANDLER(SIOCGIWRETRY, (iw_handler)orinoco_ioctl_getretry), 1361 IW_HANDLER(SIOCGIWRETRY, (iw_handler)cfg80211_wext_giwretry),
1535 IW_HANDLER(SIOCSIWENCODE, (iw_handler)orinoco_ioctl_setiwencode), 1362 IW_HANDLER(SIOCSIWENCODE, (iw_handler)orinoco_ioctl_setiwencode),
1536 IW_HANDLER(SIOCGIWENCODE, (iw_handler)orinoco_ioctl_getiwencode), 1363 IW_HANDLER(SIOCGIWENCODE, (iw_handler)orinoco_ioctl_getiwencode),
1537 IW_HANDLER(SIOCSIWPOWER, (iw_handler)orinoco_ioctl_setpower), 1364 IW_HANDLER(SIOCSIWPOWER, (iw_handler)orinoco_ioctl_setpower),