aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/cfg80211.c
diff options
context:
space:
mode:
authorAmitkumar Karwar <akarwar@marvell.com>2011-08-10 21:53:57 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-08-12 13:45:05 -0400
commit7c6fa2a843c5ac0f8e3e4bf679cee9c93d5e3437 (patch)
tree360b31141b176026c64631fc0a7a21c4aa3ea258 /drivers/net/wireless/mwifiex/cfg80211.c
parent9af73cf7f356801e6e5837eb338d197de5c8f37c (diff)
mwifiex: use cfg80211 dynamic scan table and cfg80211_get_bss API
Instead of maintaining static scan table in driver, scan list is sent to cfg80211 stack (after parsing each scan command response). In assoc handler (for infra and ibss network) requested BSS information is retrieved using cfg80211_get_bss() API. With the changes above some redundant code are removed. Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwifiex/cfg80211.c')
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c207
1 files changed, 43 insertions, 164 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index c979a909303e..6fd53e4e3fe6 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -793,139 +793,6 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
793} 793}
794 794
795/* 795/*
796 * This function informs the CFG802.11 subsystem of a new BSS connection.
797 *
798 * The following information are sent to the CFG802.11 subsystem
799 * to register the new BSS connection. If we do not register the new BSS,
800 * a kernel panic will result.
801 * - MAC address
802 * - Capabilities
803 * - Beacon period
804 * - RSSI value
805 * - Channel
806 * - Supported rates IE
807 * - Extended capabilities IE
808 * - DS parameter set IE
809 * - HT Capability IE
810 * - Vendor Specific IE (221)
811 * - WPA IE
812 * - RSN IE
813 */
814static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
815 struct mwifiex_802_11_ssid *ssid)
816{
817 struct mwifiex_bssdescriptor *scan_table;
818 int i, j;
819 struct ieee80211_channel *chan;
820 u8 *ie, *ie_buf;
821 u32 ie_len;
822 u8 *beacon;
823 int beacon_size;
824 u8 element_id, element_len;
825
826#define MAX_IE_BUF 2048
827 ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL);
828 if (!ie_buf) {
829 dev_err(priv->adapter->dev, "%s: failed to alloc ie_buf\n",
830 __func__);
831 return -ENOMEM;
832 }
833
834 scan_table = priv->adapter->scan_table;
835 for (i = 0; i < priv->adapter->num_in_scan_table; i++) {
836 if (ssid) {
837 /* Inform specific BSS only */
838 if (memcmp(ssid->ssid, scan_table[i].ssid.ssid,
839 ssid->ssid_len))
840 continue;
841 }
842 memset(ie_buf, 0, MAX_IE_BUF);
843 ie_buf[0] = WLAN_EID_SSID;
844 ie_buf[1] = scan_table[i].ssid.ssid_len;
845 memcpy(&ie_buf[sizeof(struct ieee_types_header)],
846 scan_table[i].ssid.ssid, ie_buf[1]);
847
848 ie = ie_buf + ie_buf[1] + sizeof(struct ieee_types_header);
849 ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
850
851 ie[0] = WLAN_EID_SUPP_RATES;
852
853 for (j = 0; j < sizeof(scan_table[i].supported_rates); j++) {
854 if (!scan_table[i].supported_rates[j])
855 break;
856 else
857 ie[j + sizeof(struct ieee_types_header)] =
858 scan_table[i].supported_rates[j];
859 }
860
861 ie[1] = j;
862 ie_len += ie[1] + sizeof(struct ieee_types_header);
863
864 beacon = scan_table[i].beacon_buf;
865 beacon_size = scan_table[i].beacon_buf_size;
866
867 /* Skip time stamp, beacon interval and capability */
868
869 if (beacon) {
870 beacon += sizeof(scan_table[i].beacon_period)
871 + sizeof(scan_table[i].time_stamp) +
872 +sizeof(scan_table[i].cap_info_bitmap);
873
874 beacon_size -= sizeof(scan_table[i].beacon_period)
875 + sizeof(scan_table[i].time_stamp)
876 + sizeof(scan_table[i].cap_info_bitmap);
877 }
878
879 while (beacon_size >= sizeof(struct ieee_types_header)) {
880 ie = ie_buf + ie_len;
881 element_id = *beacon;
882 element_len = *(beacon + 1);
883 if (beacon_size < (int) element_len +
884 sizeof(struct ieee_types_header)) {
885 dev_err(priv->adapter->dev, "%s: in processing"
886 " IE, bytes left < IE length\n",
887 __func__);
888 break;
889 }
890 switch (element_id) {
891 case WLAN_EID_EXT_CAPABILITY:
892 case WLAN_EID_DS_PARAMS:
893 case WLAN_EID_HT_CAPABILITY:
894 case WLAN_EID_VENDOR_SPECIFIC:
895 case WLAN_EID_RSN:
896 case WLAN_EID_BSS_AC_ACCESS_DELAY:
897 ie[0] = element_id;
898 ie[1] = element_len;
899 memcpy(&ie[sizeof(struct ieee_types_header)],
900 (u8 *) beacon
901 + sizeof(struct ieee_types_header),
902 element_len);
903 ie_len += ie[1] +
904 sizeof(struct ieee_types_header);
905 break;
906 default:
907 break;
908 }
909 beacon += element_len +
910 sizeof(struct ieee_types_header);
911 beacon_size -= element_len +
912 sizeof(struct ieee_types_header);
913 }
914 chan = ieee80211_get_channel(priv->wdev->wiphy,
915 scan_table[i].freq);
916 cfg80211_inform_bss(priv->wdev->wiphy, chan,
917 scan_table[i].mac_address,
918 0, scan_table[i].cap_info_bitmap,
919 scan_table[i].beacon_period,
920 ie_buf, ie_len,
921 scan_table[i].rssi, GFP_KERNEL);
922 }
923
924 kfree(ie_buf);
925 return 0;
926}
927
928/*
929 * This function connects with a BSS. 796 * This function connects with a BSS.
930 * 797 *
931 * This function handles both Infra and Ad-Hoc modes. It also performs 798 * This function handles both Infra and Ad-Hoc modes. It also performs
@@ -937,8 +804,7 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
937 * For Infra mode, the function returns failure if the specified SSID 804 * For Infra mode, the function returns failure if the specified SSID
938 * is not found in scan table. However, for Ad-Hoc mode, it can create 805 * is not found in scan table. However, for Ad-Hoc mode, it can create
939 * the IBSS if it does not exist. On successful completion in either case, 806 * the IBSS if it does not exist. On successful completion in either case,
940 * the function notifies the CFG802.11 subsystem of the new BSS connection, 807 * the function notifies the CFG802.11 subsystem of the new BSS connection.
941 * otherwise the kernel will panic.
942 */ 808 */
943static int 809static int
944mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, 810mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
@@ -946,11 +812,11 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
946 struct cfg80211_connect_params *sme, bool privacy) 812 struct cfg80211_connect_params *sme, bool privacy)
947{ 813{
948 struct mwifiex_802_11_ssid req_ssid; 814 struct mwifiex_802_11_ssid req_ssid;
949 struct mwifiex_ssid_bssid ssid_bssid;
950 int ret, auth_type = 0; 815 int ret, auth_type = 0;
816 struct cfg80211_bss *bss = NULL;
817 u8 is_scanning_required = 0;
951 818
952 memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid)); 819 memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid));
953 memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
954 820
955 req_ssid.ssid_len = ssid_len; 821 req_ssid.ssid_len = ssid_len;
956 if (ssid_len > IEEE80211_MAX_SSID_LEN) { 822 if (ssid_len > IEEE80211_MAX_SSID_LEN) {
@@ -1028,30 +894,48 @@ done:
1028 return -EFAULT; 894 return -EFAULT;
1029 } 895 }
1030 896
897 /*
898 * Scan entries are valid for some time (15 sec). So we can save one
899 * active scan time if we just try cfg80211_get_bss first. If it fails
900 * then request scan and cfg80211_get_bss() again for final output.
901 */
902 while (1) {
903 if (is_scanning_required) {
904 /* Do specific SSID scanning */
905 if (mwifiex_request_scan(priv, &req_ssid)) {
906 dev_err(priv->adapter->dev, "scan error\n");
907 return -EFAULT;
908 }
909 }
1031 910
1032 memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid)); 911 /* Find the BSS we want using available scan results */
1033 912 if (mode == NL80211_IFTYPE_ADHOC)
1034 if (mode != NL80211_IFTYPE_ADHOC) { 913 bss = cfg80211_get_bss(priv->wdev->wiphy, channel,
1035 if (mwifiex_find_best_bss(priv, &ssid_bssid)) 914 bssid, ssid, ssid_len,
1036 return -EFAULT; 915 WLAN_CAPABILITY_IBSS,
1037 /* Inform the BSS information to kernel, otherwise 916 WLAN_CAPABILITY_IBSS);
1038 * kernel will give a panic after successful assoc */ 917 else
1039 if (mwifiex_inform_bss_from_scan_result(priv, &req_ssid)) 918 bss = cfg80211_get_bss(priv->wdev->wiphy, channel,
1040 return -EFAULT; 919 bssid, ssid, ssid_len,
920 WLAN_CAPABILITY_ESS,
921 WLAN_CAPABILITY_ESS);
922
923 if (!bss) {
924 if (is_scanning_required) {
925 dev_warn(priv->adapter->dev, "assoc: requested "
926 "bss not found in scan results\n");
927 break;
928 }
929 is_scanning_required = 1;
930 } else {
931 dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n",
932 (char *) req_ssid.ssid, bss->bssid);
933 memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
934 break;
935 }
1041 } 936 }
1042 937
1043 dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n", 938 if (mwifiex_bss_start(priv, bss, &req_ssid))
1044 (char *) req_ssid.ssid, ssid_bssid.bssid);
1045
1046 memcpy(&priv->cfg_bssid, ssid_bssid.bssid, 6);
1047
1048 /* Connect to BSS by ESSID */
1049 memset(&ssid_bssid.bssid, 0, ETH_ALEN);
1050
1051 if (!netif_queue_stopped(priv->netdev))
1052 netif_stop_queue(priv->netdev);
1053
1054 if (mwifiex_bss_start(priv, &ssid_bssid))
1055 return -EFAULT; 939 return -EFAULT;
1056 940
1057 if (mode == NL80211_IFTYPE_ADHOC) { 941 if (mode == NL80211_IFTYPE_ADHOC) {
@@ -1416,13 +1300,8 @@ mwifiex_cfg80211_results(struct work_struct *work)
1416 MWIFIEX_SCAN_TYPE_ACTIVE; 1300 MWIFIEX_SCAN_TYPE_ACTIVE;
1417 scan_req->chan_list[i].scan_time = 0; 1301 scan_req->chan_list[i].scan_time = 0;
1418 } 1302 }
1419 if (mwifiex_set_user_scan_ioctl(priv, scan_req)) { 1303 if (mwifiex_set_user_scan_ioctl(priv, scan_req))
1420 ret = -EFAULT; 1304 ret = -EFAULT;
1421 goto done;
1422 }
1423 if (mwifiex_inform_bss_from_scan_result(priv, NULL))
1424 ret = -EFAULT;
1425done:
1426 priv->scan_result_status = ret; 1305 priv->scan_result_status = ret;
1427 dev_dbg(priv->adapter->dev, "info: %s: sending scan results\n", 1306 dev_dbg(priv->adapter->dev, "info: %s: sending scan results\n",
1428 __func__); 1307 __func__);