aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/scan.c
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2007-05-25 16:25:21 -0400
committerJohn W. Linville <linville@tuxdriver.com>2007-06-11 14:28:41 -0400
commiteb8f7330e7edf655176c51a62cd2e34de91a1eba (patch)
tree383f19fd3741a2f240c976ee7dc89368581ac1f0 /drivers/net/wireless/libertas/scan.c
parentfcdb53dbc743f288bf72e485fefb3a967b733686 (diff)
[PATCH] libertas: fix 'keep previous scan' behavior
Do not clear the scan list except under specific conditions, such as when (a) user-requested, or (b) joining/starting an adhoc network. Furthermore, only clear entries which match the SSID or BSSID of the request, not the whole scan list. Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas/scan.c')
-rw-r--r--drivers/net/wireless/libertas/scan.c131
1 files changed, 77 insertions, 54 deletions
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index b2919a6876e6..437a1e98671f 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -59,6 +59,9 @@
59//! Scan time specified in the channel TLV for each channel for active scans 59//! Scan time specified in the channel TLV for each channel for active scans
60#define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100 60#define MRVDRV_ACTIVE_SCAN_CHAN_TIME 100
61 61
62const u8 zeromac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
63const u8 bcastmac[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
64
62static inline void clear_bss_descriptor (struct bss_descriptor * bss) 65static inline void clear_bss_descriptor (struct bss_descriptor * bss)
63{ 66{
64 /* Don't blow away ->list, just BSS data */ 67 /* Don't blow away ->list, just BSS data */
@@ -409,13 +412,11 @@ wlan_scan_setup_scan_config(wlan_private * priv,
409 u8 * pscancurrentonly) 412 u8 * pscancurrentonly)
410{ 413{
411 wlan_adapter *adapter = priv->adapter; 414 wlan_adapter *adapter = priv->adapter;
412 const u8 zeromac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
413 struct mrvlietypes_numprobes *pnumprobestlv; 415 struct mrvlietypes_numprobes *pnumprobestlv;
414 struct mrvlietypes_ssidparamset *pssidtlv; 416 struct mrvlietypes_ssidparamset *pssidtlv;
415 struct wlan_scan_cmd_config * pscancfgout = NULL; 417 struct wlan_scan_cmd_config * pscancfgout = NULL;
416 u8 *ptlvpos; 418 u8 *ptlvpos;
417 u16 numprobes; 419 u16 numprobes;
418 u16 ssidlen;
419 int chanidx; 420 int chanidx;
420 int scantype; 421 int scantype;
421 int scandur; 422 int scandur;
@@ -472,21 +473,18 @@ wlan_scan_setup_scan_config(wlan_private * priv,
472 * Set the BSSID filter to the incoming configuration, 473 * Set the BSSID filter to the incoming configuration,
473 * if non-zero. If not set, it will remain disabled (all zeros). 474 * if non-zero. If not set, it will remain disabled (all zeros).
474 */ 475 */
475 memcpy(pscancfgout->specificBSSID, 476 memcpy(pscancfgout->bssid, puserscanin->bssid,
476 puserscanin->specificBSSID, 477 sizeof(pscancfgout->bssid));
477 sizeof(pscancfgout->specificBSSID));
478
479 ssidlen = strlen(puserscanin->specificSSID);
480 478
481 if (ssidlen) { 479 if (puserscanin->ssid_len) {
482 pssidtlv = 480 pssidtlv =
483 (struct mrvlietypes_ssidparamset *) pscancfgout-> 481 (struct mrvlietypes_ssidparamset *) pscancfgout->
484 tlvbuffer; 482 tlvbuffer;
485 pssidtlv->header.type = cpu_to_le16(TLV_TYPE_SSID); 483 pssidtlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
486 pssidtlv->header.len = cpu_to_le16(ssidlen); 484 pssidtlv->header.len = cpu_to_le16(puserscanin->ssid_len);
487 memcpy(pssidtlv->ssid, puserscanin->specificSSID, 485 memcpy(pssidtlv->ssid, puserscanin->ssid,
488 ssidlen); 486 puserscanin->ssid_len);
489 ptlvpos += sizeof(pssidtlv->header) + ssidlen; 487 ptlvpos += sizeof(pssidtlv->header) + puserscanin->ssid_len;
490 } 488 }
491 489
492 /* 490 /*
@@ -495,8 +493,8 @@ wlan_scan_setup_scan_config(wlan_private * priv,
495 * scan results. That is not an issue with an SSID or BSSID 493 * scan results. That is not an issue with an SSID or BSSID
496 * filter applied to the scan results in the firmware. 494 * filter applied to the scan results in the firmware.
497 */ 495 */
498 if (ssidlen || (memcmp(pscancfgout->specificBSSID, 496 if ( puserscanin->ssid_len
499 &zeromac, sizeof(zeromac)) != 0)) { 497 || (compare_ether_addr(pscancfgout->bssid, &zeromac[0]) != 0)) {
500 *pmaxchanperscan = MRVDRV_MAX_CHANNELS_PER_SCAN; 498 *pmaxchanperscan = MRVDRV_MAX_CHANNELS_PER_SCAN;
501 *pfilteredscan = 1; 499 *pfilteredscan = 1;
502 } 500 }
@@ -743,6 +741,53 @@ done:
743 return ret; 741 return ret;
744} 742}
745 743
744static void
745clear_selected_scan_list_entries(wlan_adapter * adapter,
746 const struct wlan_ioctl_user_scan_cfg * scan_cfg)
747{
748 struct bss_descriptor * bss;
749 struct bss_descriptor * safe;
750 u32 clear_ssid_flag = 0, clear_bssid_flag = 0;
751
752 if (!scan_cfg)
753 return;
754
755 if (scan_cfg->clear_ssid && scan_cfg->ssid_len)
756 clear_ssid_flag = 1;
757
758 if (scan_cfg->clear_bssid
759 && (compare_ether_addr(scan_cfg->bssid, &zeromac[0]) != 0)
760 && (compare_ether_addr(scan_cfg->bssid, &bcastmac[0]) != 0)) {
761 clear_bssid_flag = 1;
762 }
763
764 if (!clear_ssid_flag && !clear_bssid_flag)
765 return;
766
767 mutex_lock(&adapter->lock);
768 list_for_each_entry_safe (bss, safe, &adapter->network_list, list) {
769 u32 clear = 0;
770
771 /* Check for an SSID match */
772 if ( clear_ssid_flag
773 && (bss->ssid.ssidlength == scan_cfg->ssid_len)
774 && !memcmp(bss->ssid.ssid, scan_cfg->ssid, bss->ssid.ssidlength))
775 clear = 1;
776
777 /* Check for a BSSID match */
778 if ( clear_bssid_flag
779 && !compare_ether_addr(bss->bssid, scan_cfg->bssid))
780 clear = 1;
781
782 if (clear) {
783 list_move_tail (&bss->list, &adapter->network_free_list);
784 clear_bss_descriptor(bss);
785 }
786 }
787 mutex_unlock(&adapter->lock);
788}
789
790
746/** 791/**
747 * @brief Internal function used to start a scan based on an input config 792 * @brief Internal function used to start a scan based on an input config
748 * 793 *
@@ -760,11 +805,10 @@ int wlan_scan_networks(wlan_private * priv,
760 const struct wlan_ioctl_user_scan_cfg * puserscanin, 805 const struct wlan_ioctl_user_scan_cfg * puserscanin,
761 int full_scan) 806 int full_scan)
762{ 807{
763 wlan_adapter *adapter = priv->adapter; 808 wlan_adapter * adapter = priv->adapter;
764 struct mrvlietypes_chanlistparamset *pchantlvout; 809 struct mrvlietypes_chanlistparamset *pchantlvout;
765 struct chanscanparamset * scan_chan_list = NULL; 810 struct chanscanparamset * scan_chan_list = NULL;
766 struct wlan_scan_cmd_config * scan_cfg = NULL; 811 struct wlan_scan_cmd_config * scan_cfg = NULL;
767 u8 keeppreviousscan;
768 u8 filteredscan; 812 u8 filteredscan;
769 u8 scancurrentchanonly; 813 u8 scancurrentchanonly;
770 int maxchanperscan; 814 int maxchanperscan;
@@ -791,28 +835,7 @@ int wlan_scan_networks(wlan_private * priv,
791 goto out; 835 goto out;
792 } 836 }
793 837
794 keeppreviousscan = 0; 838 clear_selected_scan_list_entries(adapter, puserscanin);
795
796 if (puserscanin) {
797 keeppreviousscan = puserscanin->keeppreviousscan;
798 }
799
800 if (adapter->last_scanned_channel)
801 keeppreviousscan = 1;
802
803 if (!keeppreviousscan) {
804 struct bss_descriptor * iter_bss;
805 struct bss_descriptor * safe;
806
807 mutex_lock(&adapter->lock);
808 list_for_each_entry_safe (iter_bss, safe,
809 &adapter->network_list, list) {
810 list_move_tail (&iter_bss->list,
811 &adapter->network_free_list);
812 clear_bss_descriptor(iter_bss);
813 }
814 mutex_unlock(&adapter->lock);
815 }
816 839
817 /* Keep the data path active if we are only scanning our current channel */ 840 /* Keep the data path active if we are only scanning our current channel */
818 if (!scancurrentchanonly) { 841 if (!scancurrentchanonly) {
@@ -1434,30 +1457,30 @@ int libertas_set_scan(struct net_device *dev, struct iw_request_info *info,
1434 */ 1457 */
1435int libertas_send_specific_SSID_scan(wlan_private * priv, 1458int libertas_send_specific_SSID_scan(wlan_private * priv,
1436 struct WLAN_802_11_SSID *prequestedssid, 1459 struct WLAN_802_11_SSID *prequestedssid,
1437 u8 keeppreviousscan) 1460 u8 clear_ssid)
1438{ 1461{
1439 wlan_adapter *adapter = priv->adapter; 1462 wlan_adapter *adapter = priv->adapter;
1440 struct wlan_ioctl_user_scan_cfg scancfg; 1463 struct wlan_ioctl_user_scan_cfg scancfg;
1464 int ret = 0;
1441 1465
1442 lbs_deb_enter(LBS_DEB_ASSOC); 1466 lbs_deb_enter(LBS_DEB_ASSOC);
1443 1467
1444 if (prequestedssid == NULL) { 1468 if (prequestedssid == NULL)
1445 return -1; 1469 goto out;
1446 }
1447 1470
1448 memset(&scancfg, 0x00, sizeof(scancfg)); 1471 memset(&scancfg, 0x00, sizeof(scancfg));
1449 1472 memcpy(scancfg.ssid, prequestedssid->ssid, prequestedssid->ssidlength);
1450 memcpy(scancfg.specificSSID, prequestedssid->ssid, 1473 scancfg.ssid_len = prequestedssid->ssidlength;
1451 prequestedssid->ssidlength); 1474 scancfg.clear_ssid = clear_ssid;
1452 scancfg.keeppreviousscan = keeppreviousscan;
1453 1475
1454 wlan_scan_networks(priv, &scancfg, 1); 1476 wlan_scan_networks(priv, &scancfg, 1);
1455 if (adapter->surpriseremoved) 1477 if (adapter->surpriseremoved)
1456 return -1; 1478 return -1;
1457 wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending); 1479 wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending);
1458 1480
1481out:
1459 lbs_deb_leave(LBS_DEB_ASSOC); 1482 lbs_deb_leave(LBS_DEB_ASSOC);
1460 return 0; 1483 return ret;
1461} 1484}
1462 1485
1463/** 1486/**
@@ -1469,19 +1492,18 @@ int libertas_send_specific_SSID_scan(wlan_private * priv,
1469 * 1492 *
1470 * @return 0-success, otherwise fail 1493 * @return 0-success, otherwise fail
1471 */ 1494 */
1472int libertas_send_specific_BSSID_scan(wlan_private * priv, u8 * bssid, u8 keeppreviousscan) 1495int libertas_send_specific_BSSID_scan(wlan_private * priv, u8 * bssid, u8 clear_bssid)
1473{ 1496{
1474 struct wlan_ioctl_user_scan_cfg scancfg; 1497 struct wlan_ioctl_user_scan_cfg scancfg;
1475 1498
1476 lbs_deb_enter(LBS_DEB_ASSOC); 1499 lbs_deb_enter(LBS_DEB_ASSOC);
1477 1500
1478 if (bssid == NULL) { 1501 if (bssid == NULL)
1479 return -1; 1502 goto out;
1480 }
1481 1503
1482 memset(&scancfg, 0x00, sizeof(scancfg)); 1504 memset(&scancfg, 0x00, sizeof(scancfg));
1483 memcpy(scancfg.specificBSSID, bssid, sizeof(scancfg.specificBSSID)); 1505 memcpy(scancfg.bssid, bssid, ETH_ALEN);
1484 scancfg.keeppreviousscan = keeppreviousscan; 1506 scancfg.clear_bssid = clear_bssid;
1485 1507
1486 wlan_scan_networks(priv, &scancfg, 1); 1508 wlan_scan_networks(priv, &scancfg, 1);
1487 if (priv->adapter->surpriseremoved) 1509 if (priv->adapter->surpriseremoved)
@@ -1489,6 +1511,7 @@ int libertas_send_specific_BSSID_scan(wlan_private * priv, u8 * bssid, u8 keeppr
1489 wait_event_interruptible(priv->adapter->cmd_pending, 1511 wait_event_interruptible(priv->adapter->cmd_pending,
1490 !priv->adapter->nr_cmd_pending); 1512 !priv->adapter->nr_cmd_pending);
1491 1513
1514out:
1492 lbs_deb_leave(LBS_DEB_ASSOC); 1515 lbs_deb_leave(LBS_DEB_ASSOC);
1493 return 0; 1516 return 0;
1494} 1517}
@@ -1727,7 +1750,7 @@ int libertas_cmd_80211_scan(wlan_private * priv,
1727 1750
1728 /* Set fixed field variables in scan command */ 1751 /* Set fixed field variables in scan command */
1729 pscan->bsstype = pscancfg->bsstype; 1752 pscan->bsstype = pscancfg->bsstype;
1730 memcpy(pscan->BSSID, pscancfg->specificBSSID, sizeof(pscan->BSSID)); 1753 memcpy(pscan->BSSID, pscancfg->bssid, sizeof(pscan->BSSID));
1731 memcpy(pscan->tlvbuffer, pscancfg->tlvbuffer, pscancfg->tlvbufferlen); 1754 memcpy(pscan->tlvbuffer, pscancfg->tlvbuffer, pscancfg->tlvbufferlen);
1732 1755
1733 cmd->command = cpu_to_le16(cmd_802_11_scan); 1756 cmd->command = cpu_to_le16(cmd_802_11_scan);