libertas: sort and categorize entries in decl.h
[safe/jmp/linux-2.6] / drivers / net / wireless / libertas / scan.c
index d8fc2b8..c6a6c04 100644 (file)
 #include <net/lib80211.h>
 
 #include "host.h"
-#include "decl.h"
 #include "dev.h"
 #include "scan.h"
+#include "assoc.h"
+#include "wext.h"
 #include "cmd.h"
 
 //! Approximate amount of data needed to pass a scan result back to iwlist
 #define MAX_SCAN_CELL_SIZE  (IW_EV_ADDR_LEN             \
-                             + IW_ESSID_MAX_SIZE        \
+                             + IEEE80211_MAX_SSID_LEN   \
                              + IW_EV_UINT_LEN           \
                              + IW_EV_FREQ_LEN           \
                              + IW_EV_QUAL_LEN           \
-                             + IW_ESSID_MAX_SIZE        \
+                             + IEEE80211_MAX_SSID_LEN   \
                              + IW_EV_PARAM_LEN          \
                              + 40)     /* 40 for WPAIE */
 
@@ -121,6 +122,189 @@ static inline int is_same_network(struct bss_descriptor *src,
 
 
 
+/*********************************************************************/
+/*                                                                   */
+/* Region channel support                                            */
+/*                                                                   */
+/*********************************************************************/
+
+#define LBS_TX_PWR_DEFAULT             20      /*100mW */
+#define LBS_TX_PWR_US_DEFAULT          20      /*100mW */
+#define LBS_TX_PWR_JP_DEFAULT          16      /*50mW */
+#define LBS_TX_PWR_FR_DEFAULT          20      /*100mW */
+#define LBS_TX_PWR_EMEA_DEFAULT        20      /*100mW */
+
+/* Format { channel, frequency (MHz), maxtxpower } */
+/* band: 'B/G', region: USA FCC/Canada IC */
+static struct chan_freq_power channel_freq_power_US_BG[] = {
+       {1, 2412, LBS_TX_PWR_US_DEFAULT},
+       {2, 2417, LBS_TX_PWR_US_DEFAULT},
+       {3, 2422, LBS_TX_PWR_US_DEFAULT},
+       {4, 2427, LBS_TX_PWR_US_DEFAULT},
+       {5, 2432, LBS_TX_PWR_US_DEFAULT},
+       {6, 2437, LBS_TX_PWR_US_DEFAULT},
+       {7, 2442, LBS_TX_PWR_US_DEFAULT},
+       {8, 2447, LBS_TX_PWR_US_DEFAULT},
+       {9, 2452, LBS_TX_PWR_US_DEFAULT},
+       {10, 2457, LBS_TX_PWR_US_DEFAULT},
+       {11, 2462, LBS_TX_PWR_US_DEFAULT}
+};
+
+/* band: 'B/G', region: Europe ETSI */
+static struct chan_freq_power channel_freq_power_EU_BG[] = {
+       {1, 2412, LBS_TX_PWR_EMEA_DEFAULT},
+       {2, 2417, LBS_TX_PWR_EMEA_DEFAULT},
+       {3, 2422, LBS_TX_PWR_EMEA_DEFAULT},
+       {4, 2427, LBS_TX_PWR_EMEA_DEFAULT},
+       {5, 2432, LBS_TX_PWR_EMEA_DEFAULT},
+       {6, 2437, LBS_TX_PWR_EMEA_DEFAULT},
+       {7, 2442, LBS_TX_PWR_EMEA_DEFAULT},
+       {8, 2447, LBS_TX_PWR_EMEA_DEFAULT},
+       {9, 2452, LBS_TX_PWR_EMEA_DEFAULT},
+       {10, 2457, LBS_TX_PWR_EMEA_DEFAULT},
+       {11, 2462, LBS_TX_PWR_EMEA_DEFAULT},
+       {12, 2467, LBS_TX_PWR_EMEA_DEFAULT},
+       {13, 2472, LBS_TX_PWR_EMEA_DEFAULT}
+};
+
+/* band: 'B/G', region: Spain */
+static struct chan_freq_power channel_freq_power_SPN_BG[] = {
+       {10, 2457, LBS_TX_PWR_DEFAULT},
+       {11, 2462, LBS_TX_PWR_DEFAULT}
+};
+
+/* band: 'B/G', region: France */
+static struct chan_freq_power channel_freq_power_FR_BG[] = {
+       {10, 2457, LBS_TX_PWR_FR_DEFAULT},
+       {11, 2462, LBS_TX_PWR_FR_DEFAULT},
+       {12, 2467, LBS_TX_PWR_FR_DEFAULT},
+       {13, 2472, LBS_TX_PWR_FR_DEFAULT}
+};
+
+/* band: 'B/G', region: Japan */
+static struct chan_freq_power channel_freq_power_JPN_BG[] = {
+       {1, 2412, LBS_TX_PWR_JP_DEFAULT},
+       {2, 2417, LBS_TX_PWR_JP_DEFAULT},
+       {3, 2422, LBS_TX_PWR_JP_DEFAULT},
+       {4, 2427, LBS_TX_PWR_JP_DEFAULT},
+       {5, 2432, LBS_TX_PWR_JP_DEFAULT},
+       {6, 2437, LBS_TX_PWR_JP_DEFAULT},
+       {7, 2442, LBS_TX_PWR_JP_DEFAULT},
+       {8, 2447, LBS_TX_PWR_JP_DEFAULT},
+       {9, 2452, LBS_TX_PWR_JP_DEFAULT},
+       {10, 2457, LBS_TX_PWR_JP_DEFAULT},
+       {11, 2462, LBS_TX_PWR_JP_DEFAULT},
+       {12, 2467, LBS_TX_PWR_JP_DEFAULT},
+       {13, 2472, LBS_TX_PWR_JP_DEFAULT},
+       {14, 2484, LBS_TX_PWR_JP_DEFAULT}
+};
+
+/**
+ * the structure for channel, frequency and power
+ */
+struct region_cfp_table {
+       u8 region;
+       struct chan_freq_power *cfp_BG;
+       int cfp_no_BG;
+};
+
+/**
+ * the structure for the mapping between region and CFP
+ */
+static struct region_cfp_table region_cfp_table[] = {
+       {0x10,                  /*US FCC */
+        channel_freq_power_US_BG,
+        ARRAY_SIZE(channel_freq_power_US_BG),
+        }
+       ,
+       {0x20,                  /*CANADA IC */
+        channel_freq_power_US_BG,
+        ARRAY_SIZE(channel_freq_power_US_BG),
+        }
+       ,
+       {0x30, /*EU*/ channel_freq_power_EU_BG,
+        ARRAY_SIZE(channel_freq_power_EU_BG),
+        }
+       ,
+       {0x31, /*SPAIN*/ channel_freq_power_SPN_BG,
+        ARRAY_SIZE(channel_freq_power_SPN_BG),
+        }
+       ,
+       {0x32, /*FRANCE*/ channel_freq_power_FR_BG,
+        ARRAY_SIZE(channel_freq_power_FR_BG),
+        }
+       ,
+       {0x40, /*JAPAN*/ channel_freq_power_JPN_BG,
+        ARRAY_SIZE(channel_freq_power_JPN_BG),
+        }
+       ,
+/*Add new region here */
+};
+
+/**
+ *  @brief This function finds the CFP in
+ *  region_cfp_table based on region and band parameter.
+ *
+ *  @param region  The region code
+ *  @param band           The band
+ *  @param cfp_no  A pointer to CFP number
+ *  @return       A pointer to CFP
+ */
+static struct chan_freq_power *lbs_get_region_cfp_table(u8 region, int *cfp_no)
+{
+       int i, end;
+
+       lbs_deb_enter(LBS_DEB_MAIN);
+
+       end = ARRAY_SIZE(region_cfp_table);
+
+       for (i = 0; i < end ; i++) {
+               lbs_deb_main("region_cfp_table[i].region=%d\n",
+                       region_cfp_table[i].region);
+               if (region_cfp_table[i].region == region) {
+                       *cfp_no = region_cfp_table[i].cfp_no_BG;
+                       lbs_deb_leave(LBS_DEB_MAIN);
+                       return region_cfp_table[i].cfp_BG;
+               }
+       }
+
+       lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL");
+       return NULL;
+}
+
+int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band)
+{
+       int ret = 0;
+       int i = 0;
+
+       struct chan_freq_power *cfp;
+       int cfp_no;
+
+       lbs_deb_enter(LBS_DEB_MAIN);
+
+       memset(priv->region_channel, 0, sizeof(priv->region_channel));
+
+       cfp = lbs_get_region_cfp_table(region, &cfp_no);
+       if (cfp != NULL) {
+               priv->region_channel[i].nrcfp = cfp_no;
+               priv->region_channel[i].CFP = cfp;
+       } else {
+               lbs_deb_main("wrong region code %#x in band B/G\n",
+                      region);
+               ret = -1;
+               goto out;
+       }
+       priv->region_channel[i].valid = 1;
+       priv->region_channel[i].region = region;
+       priv->region_channel[i].band = band;
+       i++;
+out:
+       lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
+       return ret;
+}
+
+
+
 
 /*********************************************************************/
 /*                                                                   */
@@ -161,31 +345,15 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv,
        scantype = CMD_SCAN_TYPE_ACTIVE;
 
        for (rgnidx = 0; rgnidx < ARRAY_SIZE(priv->region_channel); rgnidx++) {
-               if (priv->enable11d && (priv->connect_status != LBS_CONNECTED)
-                   && (priv->mesh_connect_status != LBS_CONNECTED)) {
-                       /* Scan all the supported chan for the first scan */
-                       if (!priv->universal_channel[rgnidx].valid)
-                               continue;
-                       scanregion = &priv->universal_channel[rgnidx];
-
-                       /* clear the parsed_region_chan for the first scan */
-                       memset(&priv->parsed_region_chan, 0x00,
-                              sizeof(priv->parsed_region_chan));
-               } else {
-                       if (!priv->region_channel[rgnidx].valid)
-                               continue;
-                       scanregion = &priv->region_channel[rgnidx];
-               }
+               if (!priv->region_channel[rgnidx].valid)
+                       continue;
+               scanregion = &priv->region_channel[rgnidx];
 
                for (nextchan = 0; nextchan < scanregion->nrcfp; nextchan++, chanidx++) {
                        struct chanscanparamset *chan = &scanchanlist[chanidx];
 
                        cfp = scanregion->CFP + nextchan;
 
-                       if (priv->enable11d)
-                               scantype = lbs_get_scan_type_11d(cfp->channel,
-                                                                &priv->parsed_region_chan);
-
                        if (scanregion->band == BAND_B || scanregion->band == BAND_G)
                                chan->radiotype = CMD_SCAN_RADIO_TYPE_BG;
 
@@ -519,7 +687,6 @@ static int lbs_process_bss(struct bss_descriptor *bss,
        struct ieee_ie_cf_param_set *cf;
        struct ieee_ie_ibss_param_set *ibss;
        DECLARE_SSID_BUF(ssid);
-       struct ieee_ie_country_info_set *pcountryinfo;
        uint8_t *pos, *end, *p;
        uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0;
        uint16_t beaconsize = 0;
@@ -642,26 +809,6 @@ static int lbs_process_bss(struct bss_descriptor *bss,
                        lbs_deb_scan("got IBSS IE\n");
                        break;
 
-               case WLAN_EID_COUNTRY:
-                       pcountryinfo = (struct ieee_ie_country_info_set *) pos;
-                       lbs_deb_scan("got COUNTRY IE\n");
-                       if (pcountryinfo->header.len < sizeof(pcountryinfo->countrycode)
-                           || pcountryinfo->header.len > 254) {
-                               lbs_deb_scan("%s: 11D- Err CountryInfo len %d, min %zd, max 254\n",
-                                            __func__,
-                                            pcountryinfo->header.len,
-                                            sizeof(pcountryinfo->countrycode));
-                               ret = -1;
-                               goto done;
-                       }
-
-                       memcpy(&bss->countryinfo, pcountryinfo,
-                               pcountryinfo->header.len + 2);
-                       lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo",
-                                   (uint8_t *) pcountryinfo,
-                                   (int) (pcountryinfo->header.len + 2));
-                       break;
-
                case WLAN_EID_EXT_SUPP_RATES:
                        /* only process extended supported rate if data rate is
                         * already found. Data rate IE should come before
@@ -812,7 +959,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
        /* SSID */
        iwe.cmd = SIOCGIWESSID;
        iwe.u.data.flags = 1;
-       iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IW_ESSID_MAX_SIZE);
+       iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IEEE80211_MAX_SSID_LEN);
        start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
 
        /* Mode */
@@ -1144,11 +1291,11 @@ static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
        /* The size of the TLV buffer is equal to the entire command response
         *   size (scanrespsize) minus the fixed fields (sizeof()'s), the
         *   BSS Descriptions (bssdescriptsize as bytesLef) and the command
-        *   response header (S_DS_GEN)
+        *   response header (sizeof(struct cmd_header))
         */
        tlvbufsize = scanrespsize - (bytesleft + sizeof(scanresp->bssdescriptsize)
                                     + sizeof(scanresp->nr_sets)
-                                    + S_DS_GEN);
+                                    + sizeof(struct cmd_header));
 
        /*
         *  Process each scan response returned (scanresp->nr_sets). Save