Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Implement cfg80211 ("iw") support.
0004  *
0005  * Copyright (C) 2009 M&N Solutions GmbH, 61191 Rosbach, Germany
0006  * Holger Schurig <hs4233@mail.mn-solutions.de>
0007  *
0008  */
0009 
0010 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0011 
0012 #include <linux/hardirq.h>
0013 #include <linux/sched.h>
0014 #include <linux/wait.h>
0015 #include <linux/slab.h>
0016 #include <linux/ieee80211.h>
0017 #include <net/cfg80211.h>
0018 #include <asm/unaligned.h>
0019 
0020 #include "decl.h"
0021 #include "cfg.h"
0022 #include "cmd.h"
0023 #include "mesh.h"
0024 
0025 
0026 #define CHAN2G(_channel, _freq, _flags) {        \
0027     .band             = NL80211_BAND_2GHZ, \
0028     .center_freq      = (_freq),             \
0029     .hw_value         = (_channel),          \
0030     .flags            = (_flags),            \
0031     .max_antenna_gain = 0,                   \
0032     .max_power        = 30,                  \
0033 }
0034 
0035 static struct ieee80211_channel lbs_2ghz_channels[] = {
0036     CHAN2G(1,  2412, 0),
0037     CHAN2G(2,  2417, 0),
0038     CHAN2G(3,  2422, 0),
0039     CHAN2G(4,  2427, 0),
0040     CHAN2G(5,  2432, 0),
0041     CHAN2G(6,  2437, 0),
0042     CHAN2G(7,  2442, 0),
0043     CHAN2G(8,  2447, 0),
0044     CHAN2G(9,  2452, 0),
0045     CHAN2G(10, 2457, 0),
0046     CHAN2G(11, 2462, 0),
0047     CHAN2G(12, 2467, 0),
0048     CHAN2G(13, 2472, 0),
0049     CHAN2G(14, 2484, 0),
0050 };
0051 
0052 #define RATETAB_ENT(_rate, _hw_value, _flags) { \
0053     .bitrate  = (_rate),                    \
0054     .hw_value = (_hw_value),                \
0055     .flags    = (_flags),                   \
0056 }
0057 
0058 
0059 /* Table 6 in section 3.2.1.1 */
0060 static struct ieee80211_rate lbs_rates[] = {
0061     RATETAB_ENT(10,  0,  0),
0062     RATETAB_ENT(20,  1,  0),
0063     RATETAB_ENT(55,  2,  0),
0064     RATETAB_ENT(110, 3,  0),
0065     RATETAB_ENT(60,  9,  0),
0066     RATETAB_ENT(90,  6,  0),
0067     RATETAB_ENT(120, 7,  0),
0068     RATETAB_ENT(180, 8,  0),
0069     RATETAB_ENT(240, 9,  0),
0070     RATETAB_ENT(360, 10, 0),
0071     RATETAB_ENT(480, 11, 0),
0072     RATETAB_ENT(540, 12, 0),
0073 };
0074 
0075 static struct ieee80211_supported_band lbs_band_2ghz = {
0076     .channels = lbs_2ghz_channels,
0077     .n_channels = ARRAY_SIZE(lbs_2ghz_channels),
0078     .bitrates = lbs_rates,
0079     .n_bitrates = ARRAY_SIZE(lbs_rates),
0080 };
0081 
0082 
0083 static const u32 cipher_suites[] = {
0084     WLAN_CIPHER_SUITE_WEP40,
0085     WLAN_CIPHER_SUITE_WEP104,
0086     WLAN_CIPHER_SUITE_TKIP,
0087     WLAN_CIPHER_SUITE_CCMP,
0088 };
0089 
0090 /* Time to stay on the channel */
0091 #define LBS_DWELL_PASSIVE 100
0092 #define LBS_DWELL_ACTIVE  40
0093 
0094 
0095 /***************************************************************************
0096  * Misc utility functions
0097  *
0098  * TLVs are Marvell specific. They are very similar to IEs, they have the
0099  * same structure: type, length, data*. The only difference: for IEs, the
0100  * type and length are u8, but for TLVs they're __le16.
0101  */
0102 
0103 /*
0104  * Convert NL80211's auth_type to the one from Libertas, see chapter 5.9.1
0105  * in the firmware spec
0106  */
0107 static int lbs_auth_to_authtype(enum nl80211_auth_type auth_type)
0108 {
0109     int ret = -ENOTSUPP;
0110 
0111     switch (auth_type) {
0112     case NL80211_AUTHTYPE_OPEN_SYSTEM:
0113     case NL80211_AUTHTYPE_SHARED_KEY:
0114         ret = auth_type;
0115         break;
0116     case NL80211_AUTHTYPE_AUTOMATIC:
0117         ret = NL80211_AUTHTYPE_OPEN_SYSTEM;
0118         break;
0119     case NL80211_AUTHTYPE_NETWORK_EAP:
0120         ret = 0x80;
0121         break;
0122     default:
0123         /* silence compiler */
0124         break;
0125     }
0126     return ret;
0127 }
0128 
0129 
0130 /*
0131  * Various firmware commands need the list of supported rates, but with
0132  * the hight-bit set for basic rates
0133  */
0134 static int lbs_add_rates(u8 *rates)
0135 {
0136     size_t i;
0137 
0138     for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) {
0139         u8 rate = lbs_rates[i].bitrate / 5;
0140         if (rate == 0x02 || rate == 0x04 ||
0141             rate == 0x0b || rate == 0x16)
0142             rate |= 0x80;
0143         rates[i] = rate;
0144     }
0145     return ARRAY_SIZE(lbs_rates);
0146 }
0147 
0148 
0149 /***************************************************************************
0150  * TLV utility functions
0151  *
0152  * TLVs are Marvell specific. They are very similar to IEs, they have the
0153  * same structure: type, length, data*. The only difference: for IEs, the
0154  * type and length are u8, but for TLVs they're __le16.
0155  */
0156 
0157 
0158 /*
0159  * Add ssid TLV
0160  */
0161 #define LBS_MAX_SSID_TLV_SIZE           \
0162     (sizeof(struct mrvl_ie_header)      \
0163      + IEEE80211_MAX_SSID_LEN)
0164 
0165 static int lbs_add_ssid_tlv(u8 *tlv, const u8 *ssid, int ssid_len)
0166 {
0167     struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv;
0168 
0169     /*
0170      * TLV-ID SSID  00 00
0171      * length       06 00
0172      * ssid         4d 4e 54 45 53 54
0173      */
0174     ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
0175     ssid_tlv->header.len = cpu_to_le16(ssid_len);
0176     memcpy(ssid_tlv->ssid, ssid, ssid_len);
0177     return sizeof(ssid_tlv->header) + ssid_len;
0178 }
0179 
0180 
0181 /*
0182  * Add channel list TLV (section 8.4.2)
0183  *
0184  * Actual channel data comes from priv->wdev->wiphy->channels.
0185  */
0186 #define LBS_MAX_CHANNEL_LIST_TLV_SIZE                   \
0187     (sizeof(struct mrvl_ie_header)                  \
0188      + (LBS_SCAN_BEFORE_NAP * sizeof(struct chanscanparamset)))
0189 
0190 static int lbs_add_channel_list_tlv(struct lbs_private *priv, u8 *tlv,
0191                     int last_channel, int active_scan)
0192 {
0193     int chanscanparamsize = sizeof(struct chanscanparamset) *
0194         (last_channel - priv->scan_channel);
0195 
0196     struct mrvl_ie_header *header = (void *) tlv;
0197 
0198     /*
0199      * TLV-ID CHANLIST  01 01
0200      * length           0e 00
0201      * channel          00 01 00 00 00 64 00
0202      *   radio type     00
0203      *   channel           01
0204      *   scan type            00
0205      *   min scan time           00 00
0206      *   max scan time                 64 00
0207      * channel 2        00 02 00 00 00 64 00
0208      *
0209      */
0210 
0211     header->type = cpu_to_le16(TLV_TYPE_CHANLIST);
0212     header->len  = cpu_to_le16(chanscanparamsize);
0213     tlv += sizeof(struct mrvl_ie_header);
0214 
0215     /* lbs_deb_scan("scan: channels %d to %d\n", priv->scan_channel,
0216              last_channel); */
0217     memset(tlv, 0, chanscanparamsize);
0218 
0219     while (priv->scan_channel < last_channel) {
0220         struct chanscanparamset *param = (void *) tlv;
0221 
0222         param->radiotype = CMD_SCAN_RADIO_TYPE_BG;
0223         param->channumber =
0224             priv->scan_req->channels[priv->scan_channel]->hw_value;
0225         if (active_scan) {
0226             param->maxscantime = cpu_to_le16(LBS_DWELL_ACTIVE);
0227         } else {
0228             param->chanscanmode.passivescan = 1;
0229             param->maxscantime = cpu_to_le16(LBS_DWELL_PASSIVE);
0230         }
0231         tlv += sizeof(struct chanscanparamset);
0232         priv->scan_channel++;
0233     }
0234     return sizeof(struct mrvl_ie_header) + chanscanparamsize;
0235 }
0236 
0237 
0238 /*
0239  * Add rates TLV
0240  *
0241  * The rates are in lbs_bg_rates[], but for the 802.11b
0242  * rates the high bit is set. We add this TLV only because
0243  * there's a firmware which otherwise doesn't report all
0244  * APs in range.
0245  */
0246 #define LBS_MAX_RATES_TLV_SIZE          \
0247     (sizeof(struct mrvl_ie_header)      \
0248      + (ARRAY_SIZE(lbs_rates)))
0249 
0250 /* Adds a TLV with all rates the hardware supports */
0251 static int lbs_add_supported_rates_tlv(u8 *tlv)
0252 {
0253     size_t i;
0254     struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
0255 
0256     /*
0257      * TLV-ID RATES  01 00
0258      * length        0e 00
0259      * rates         82 84 8b 96 0c 12 18 24 30 48 60 6c
0260      */
0261     rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
0262     tlv += sizeof(rate_tlv->header);
0263     i = lbs_add_rates(tlv);
0264     tlv += i;
0265     rate_tlv->header.len = cpu_to_le16(i);
0266     return sizeof(rate_tlv->header) + i;
0267 }
0268 
0269 /* Add common rates from a TLV and return the new end of the TLV */
0270 static u8 *
0271 add_ie_rates(u8 *tlv, const u8 *ie, int *nrates)
0272 {
0273     int hw, ap, ap_max = ie[1];
0274     u8 hw_rate;
0275 
0276     if (ap_max > MAX_RATES) {
0277         lbs_deb_assoc("invalid rates\n");
0278         return tlv;
0279     }
0280     /* Advance past IE header */
0281     ie += 2;
0282 
0283     lbs_deb_hex(LBS_DEB_ASSOC, "AP IE Rates", (u8 *) ie, ap_max);
0284 
0285     for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
0286         hw_rate = lbs_rates[hw].bitrate / 5;
0287         for (ap = 0; ap < ap_max; ap++) {
0288             if (hw_rate == (ie[ap] & 0x7f)) {
0289                 *tlv++ = ie[ap];
0290                 *nrates = *nrates + 1;
0291             }
0292         }
0293     }
0294     return tlv;
0295 }
0296 
0297 /*
0298  * Adds a TLV with all rates the hardware *and* BSS supports.
0299  */
0300 static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
0301 {
0302     struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
0303     const u8 *rates_eid, *ext_rates_eid;
0304     int n = 0;
0305 
0306     rcu_read_lock();
0307     rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
0308     ext_rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
0309 
0310     /*
0311      * 01 00                   TLV_TYPE_RATES
0312      * 04 00                   len
0313      * 82 84 8b 96             rates
0314      */
0315     rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
0316     tlv += sizeof(rate_tlv->header);
0317 
0318     /* Add basic rates */
0319     if (rates_eid) {
0320         tlv = add_ie_rates(tlv, rates_eid, &n);
0321 
0322         /* Add extended rates, if any */
0323         if (ext_rates_eid)
0324             tlv = add_ie_rates(tlv, ext_rates_eid, &n);
0325     } else {
0326         lbs_deb_assoc("assoc: bss had no basic rate IE\n");
0327         /* Fallback: add basic 802.11b rates */
0328         *tlv++ = 0x82;
0329         *tlv++ = 0x84;
0330         *tlv++ = 0x8b;
0331         *tlv++ = 0x96;
0332         n = 4;
0333     }
0334     rcu_read_unlock();
0335 
0336     rate_tlv->header.len = cpu_to_le16(n);
0337     return sizeof(rate_tlv->header) + n;
0338 }
0339 
0340 
0341 /*
0342  * Add auth type TLV.
0343  *
0344  * This is only needed for newer firmware (V9 and up).
0345  */
0346 #define LBS_MAX_AUTH_TYPE_TLV_SIZE \
0347     sizeof(struct mrvl_ie_auth_type)
0348 
0349 static int lbs_add_auth_type_tlv(u8 *tlv, enum nl80211_auth_type auth_type)
0350 {
0351     struct mrvl_ie_auth_type *auth = (void *) tlv;
0352 
0353     /*
0354      * 1f 01  TLV_TYPE_AUTH_TYPE
0355      * 01 00  len
0356      * 01     auth type
0357      */
0358     auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
0359     auth->header.len = cpu_to_le16(sizeof(*auth)-sizeof(auth->header));
0360     auth->auth = cpu_to_le16(lbs_auth_to_authtype(auth_type));
0361     return sizeof(*auth);
0362 }
0363 
0364 
0365 /*
0366  * Add channel (phy ds) TLV
0367  */
0368 #define LBS_MAX_CHANNEL_TLV_SIZE \
0369     sizeof(struct mrvl_ie_header)
0370 
0371 static int lbs_add_channel_tlv(u8 *tlv, u8 channel)
0372 {
0373     struct mrvl_ie_ds_param_set *ds = (void *) tlv;
0374 
0375     /*
0376      * 03 00  TLV_TYPE_PHY_DS
0377      * 01 00  len
0378      * 06     channel
0379      */
0380     ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
0381     ds->header.len = cpu_to_le16(sizeof(*ds)-sizeof(ds->header));
0382     ds->channel = channel;
0383     return sizeof(*ds);
0384 }
0385 
0386 
0387 /*
0388  * Add (empty) CF param TLV of the form:
0389  */
0390 #define LBS_MAX_CF_PARAM_TLV_SIZE       \
0391     sizeof(struct mrvl_ie_header)
0392 
0393 static int lbs_add_cf_param_tlv(u8 *tlv)
0394 {
0395     struct mrvl_ie_cf_param_set *cf = (void *)tlv;
0396 
0397     /*
0398      * 04 00  TLV_TYPE_CF
0399      * 06 00  len
0400      * 00     cfpcnt
0401      * 00     cfpperiod
0402      * 00 00  cfpmaxduration
0403      * 00 00  cfpdurationremaining
0404      */
0405     cf->header.type = cpu_to_le16(TLV_TYPE_CF);
0406     cf->header.len = cpu_to_le16(sizeof(*cf)-sizeof(cf->header));
0407     return sizeof(*cf);
0408 }
0409 
0410 /*
0411  * Add WPA TLV
0412  */
0413 #define LBS_MAX_WPA_TLV_SIZE            \
0414     (sizeof(struct mrvl_ie_header)      \
0415      + 128 /* TODO: I guessed the size */)
0416 
0417 static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
0418 {
0419     size_t tlv_len;
0420 
0421     /*
0422      * We need just convert an IE to an TLV. IEs use u8 for the header,
0423      *   u8      type
0424      *   u8      len
0425      *   u8[]    data
0426      * but TLVs use __le16 instead:
0427      *   __le16  type
0428      *   __le16  len
0429      *   u8[]    data
0430      */
0431     *tlv++ = *ie++;
0432     *tlv++ = 0;
0433     tlv_len = *tlv++ = *ie++;
0434     *tlv++ = 0;
0435     while (tlv_len--)
0436         *tlv++ = *ie++;
0437     /* the TLV is two bytes larger than the IE */
0438     return ie_len + 2;
0439 }
0440 
0441 /*
0442  * Set Channel
0443  */
0444 
0445 static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy,
0446                        struct cfg80211_chan_def *chandef)
0447 {
0448     struct lbs_private *priv = wiphy_priv(wiphy);
0449     int ret = -ENOTSUPP;
0450 
0451     if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT)
0452         goto out;
0453 
0454     ret = lbs_set_channel(priv, chandef->chan->hw_value);
0455 
0456  out:
0457     return ret;
0458 }
0459 
0460 static int lbs_cfg_set_mesh_channel(struct wiphy *wiphy,
0461                     struct net_device *netdev,
0462                     struct ieee80211_channel *channel)
0463 {
0464     struct lbs_private *priv = wiphy_priv(wiphy);
0465     int ret = -ENOTSUPP;
0466 
0467     if (netdev != priv->mesh_dev)
0468         goto out;
0469 
0470     ret = lbs_mesh_set_channel(priv, channel->hw_value);
0471 
0472  out:
0473     return ret;
0474 }
0475 
0476 
0477 
0478 /*
0479  * Scanning
0480  */
0481 
0482 /*
0483  * When scanning, the firmware doesn't send a nul packet with the power-safe
0484  * bit to the AP. So we cannot stay away from our current channel too long,
0485  * otherwise we loose data. So take a "nap" while scanning every other
0486  * while.
0487  */
0488 #define LBS_SCAN_BEFORE_NAP 4
0489 
0490 
0491 /*
0492  * When the firmware reports back a scan-result, it gives us an "u8 rssi",
0493  * which isn't really an RSSI, as it becomes larger when moving away from
0494  * the AP. Anyway, we need to convert that into mBm.
0495  */
0496 #define LBS_SCAN_RSSI_TO_MBM(rssi) \
0497     ((-(int)rssi + 3)*100)
0498 
0499 static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
0500     struct cmd_header *resp)
0501 {
0502     struct cfg80211_bss *bss;
0503     struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp;
0504     int bsssize;
0505     const u8 *pos;
0506     const u8 *tsfdesc;
0507     int tsfsize;
0508     int i;
0509     int ret = -EILSEQ;
0510 
0511     bsssize = get_unaligned_le16(&scanresp->bssdescriptsize);
0512 
0513     lbs_deb_scan("scan response: %d BSSs (%d bytes); resp size %d bytes\n",
0514             scanresp->nr_sets, bsssize, le16_to_cpu(resp->size));
0515 
0516     if (scanresp->nr_sets == 0) {
0517         ret = 0;
0518         goto done;
0519     }
0520 
0521     /*
0522      * The general layout of the scan response is described in chapter
0523      * 5.7.1. Basically we have a common part, then any number of BSS
0524      * descriptor sections. Finally we have section with the same number
0525      * of TSFs.
0526      *
0527      * cmd_ds_802_11_scan_rsp
0528      *   cmd_header
0529      *   pos_size
0530      *   nr_sets
0531      *   bssdesc 1
0532      *     bssid
0533      *     rssi
0534      *     timestamp
0535      *     intvl
0536      *     capa
0537      *     IEs
0538      *   bssdesc 2
0539      *   bssdesc n
0540      *   MrvlIEtypes_TsfFimestamp_t
0541      *     TSF for BSS 1
0542      *     TSF for BSS 2
0543      *     TSF for BSS n
0544      */
0545 
0546     pos = scanresp->bssdesc_and_tlvbuffer;
0547 
0548     lbs_deb_hex(LBS_DEB_SCAN, "SCAN_RSP", scanresp->bssdesc_and_tlvbuffer,
0549             scanresp->bssdescriptsize);
0550 
0551     tsfdesc = pos + bsssize;
0552     tsfsize = 4 + 8 * scanresp->nr_sets;
0553     lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TSF", (u8 *) tsfdesc, tsfsize);
0554 
0555     /* Validity check: we expect a Marvell-Local TLV */
0556     i = get_unaligned_le16(tsfdesc);
0557     tsfdesc += 2;
0558     if (i != TLV_TYPE_TSFTIMESTAMP) {
0559         lbs_deb_scan("scan response: invalid TSF Timestamp %d\n", i);
0560         goto done;
0561     }
0562 
0563     /*
0564      * Validity check: the TLV holds TSF values with 8 bytes each, so
0565      * the size in the TLV must match the nr_sets value
0566      */
0567     i = get_unaligned_le16(tsfdesc);
0568     tsfdesc += 2;
0569     if (i / 8 != scanresp->nr_sets) {
0570         lbs_deb_scan("scan response: invalid number of TSF timestamp "
0571                  "sets (expected %d got %d)\n", scanresp->nr_sets,
0572                  i / 8);
0573         goto done;
0574     }
0575 
0576     for (i = 0; i < scanresp->nr_sets; i++) {
0577         const u8 *bssid;
0578         const u8 *ie;
0579         int left;
0580         int ielen;
0581         int rssi;
0582         u16 intvl;
0583         u16 capa;
0584         int chan_no = -1;
0585         const u8 *ssid = NULL;
0586         u8 ssid_len = 0;
0587 
0588         int len = get_unaligned_le16(pos);
0589         pos += 2;
0590 
0591         /* BSSID */
0592         bssid = pos;
0593         pos += ETH_ALEN;
0594         /* RSSI */
0595         rssi = *pos++;
0596         /* Packet time stamp */
0597         pos += 8;
0598         /* Beacon interval */
0599         intvl = get_unaligned_le16(pos);
0600         pos += 2;
0601         /* Capabilities */
0602         capa = get_unaligned_le16(pos);
0603         pos += 2;
0604 
0605         /* To find out the channel, we must parse the IEs */
0606         ie = pos;
0607         /*
0608          * 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon
0609          * interval, capabilities
0610          */
0611         ielen = left = len - (6 + 1 + 8 + 2 + 2);
0612         while (left >= 2) {
0613             u8 id, elen;
0614             id = *pos++;
0615             elen = *pos++;
0616             left -= 2;
0617             if (elen > left) {
0618                 lbs_deb_scan("scan response: invalid IE fmt\n");
0619                 goto done;
0620             }
0621 
0622             if (id == WLAN_EID_DS_PARAMS)
0623                 chan_no = *pos;
0624             if (id == WLAN_EID_SSID) {
0625                 ssid = pos;
0626                 ssid_len = elen;
0627             }
0628             left -= elen;
0629             pos += elen;
0630         }
0631 
0632         /* No channel, no luck */
0633         if (chan_no != -1) {
0634             struct wiphy *wiphy = priv->wdev->wiphy;
0635             int freq = ieee80211_channel_to_frequency(chan_no,
0636                             NL80211_BAND_2GHZ);
0637             struct ieee80211_channel *channel =
0638                 ieee80211_get_channel(wiphy, freq);
0639 
0640             lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %*pE, %d dBm\n",
0641                      bssid, capa, chan_no, ssid_len, ssid,
0642                      LBS_SCAN_RSSI_TO_MBM(rssi)/100);
0643 
0644             if (channel &&
0645                 !(channel->flags & IEEE80211_CHAN_DISABLED)) {
0646                 bss = cfg80211_inform_bss(wiphy, channel,
0647                     CFG80211_BSS_FTYPE_UNKNOWN,
0648                     bssid, get_unaligned_le64(tsfdesc),
0649                     capa, intvl, ie, ielen,
0650                     LBS_SCAN_RSSI_TO_MBM(rssi),
0651                     GFP_KERNEL);
0652                 cfg80211_put_bss(wiphy, bss);
0653             }
0654         } else
0655             lbs_deb_scan("scan response: missing BSS channel IE\n");
0656 
0657         tsfdesc += 8;
0658     }
0659     ret = 0;
0660 
0661  done:
0662     return ret;
0663 }
0664 
0665 
0666 /*
0667  * Our scan command contains a TLV, consting of a SSID TLV, a channel list
0668  * TLV and a rates TLV. Determine the maximum size of them:
0669  */
0670 #define LBS_SCAN_MAX_CMD_SIZE           \
0671     (sizeof(struct cmd_ds_802_11_scan)  \
0672      + LBS_MAX_SSID_TLV_SIZE        \
0673      + LBS_MAX_CHANNEL_LIST_TLV_SIZE    \
0674      + LBS_MAX_RATES_TLV_SIZE)
0675 
0676 /*
0677  * Assumes priv->scan_req is initialized and valid
0678  * Assumes priv->scan_channel is initialized
0679  */
0680 static void lbs_scan_worker(struct work_struct *work)
0681 {
0682     struct lbs_private *priv =
0683         container_of(work, struct lbs_private, scan_work.work);
0684     struct cmd_ds_802_11_scan *scan_cmd;
0685     u8 *tlv; /* pointer into our current, growing TLV storage area */
0686     int last_channel;
0687     int running, carrier;
0688 
0689     scan_cmd = kzalloc(LBS_SCAN_MAX_CMD_SIZE, GFP_KERNEL);
0690     if (scan_cmd == NULL)
0691         return;
0692 
0693     /* prepare fixed part of scan command */
0694     scan_cmd->bsstype = CMD_BSS_TYPE_ANY;
0695 
0696     /* stop network while we're away from our main channel */
0697     running = !netif_queue_stopped(priv->dev);
0698     carrier = netif_carrier_ok(priv->dev);
0699     if (running)
0700         netif_stop_queue(priv->dev);
0701     if (carrier)
0702         netif_carrier_off(priv->dev);
0703 
0704     /* prepare fixed part of scan command */
0705     tlv = scan_cmd->tlvbuffer;
0706 
0707     /* add SSID TLV */
0708     if (priv->scan_req->n_ssids && priv->scan_req->ssids[0].ssid_len > 0)
0709         tlv += lbs_add_ssid_tlv(tlv,
0710                     priv->scan_req->ssids[0].ssid,
0711                     priv->scan_req->ssids[0].ssid_len);
0712 
0713     /* add channel TLVs */
0714     last_channel = priv->scan_channel + LBS_SCAN_BEFORE_NAP;
0715     if (last_channel > priv->scan_req->n_channels)
0716         last_channel = priv->scan_req->n_channels;
0717     tlv += lbs_add_channel_list_tlv(priv, tlv, last_channel,
0718         priv->scan_req->n_ssids);
0719 
0720     /* add rates TLV */
0721     tlv += lbs_add_supported_rates_tlv(tlv);
0722 
0723     if (priv->scan_channel < priv->scan_req->n_channels) {
0724         cancel_delayed_work(&priv->scan_work);
0725         if (netif_running(priv->dev))
0726             queue_delayed_work(priv->work_thread, &priv->scan_work,
0727                 msecs_to_jiffies(300));
0728     }
0729 
0730     /* This is the final data we are about to send */
0731     scan_cmd->hdr.size = cpu_to_le16(tlv - (u8 *)scan_cmd);
0732     lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd,
0733             sizeof(*scan_cmd));
0734     lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer,
0735             tlv - scan_cmd->tlvbuffer);
0736 
0737     __lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr,
0738         le16_to_cpu(scan_cmd->hdr.size),
0739         lbs_ret_scan, 0);
0740 
0741     if (priv->scan_channel >= priv->scan_req->n_channels) {
0742         /* Mark scan done */
0743         cancel_delayed_work(&priv->scan_work);
0744         lbs_scan_done(priv);
0745     }
0746 
0747     /* Restart network */
0748     if (carrier)
0749         netif_carrier_on(priv->dev);
0750     if (running && !priv->tx_pending_len)
0751         netif_wake_queue(priv->dev);
0752 
0753     kfree(scan_cmd);
0754 
0755     /* Wake up anything waiting on scan completion */
0756     if (priv->scan_req == NULL) {
0757         lbs_deb_scan("scan: waking up waiters\n");
0758         wake_up_all(&priv->scan_q);
0759     }
0760 }
0761 
0762 static void _internal_start_scan(struct lbs_private *priv, bool internal,
0763     struct cfg80211_scan_request *request)
0764 {
0765     lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n",
0766         request->n_ssids, request->n_channels, request->ie_len);
0767 
0768     priv->scan_channel = 0;
0769     priv->scan_req = request;
0770     priv->internal_scan = internal;
0771 
0772     queue_delayed_work(priv->work_thread, &priv->scan_work,
0773         msecs_to_jiffies(50));
0774 }
0775 
0776 /*
0777  * Clean up priv->scan_req.  Should be used to handle the allocation details.
0778  */
0779 void lbs_scan_done(struct lbs_private *priv)
0780 {
0781     WARN_ON(!priv->scan_req);
0782 
0783     if (priv->internal_scan) {
0784         kfree(priv->scan_req);
0785     } else {
0786         struct cfg80211_scan_info info = {
0787             .aborted = false,
0788         };
0789 
0790         cfg80211_scan_done(priv->scan_req, &info);
0791     }
0792 
0793     priv->scan_req = NULL;
0794 }
0795 
0796 static int lbs_cfg_scan(struct wiphy *wiphy,
0797     struct cfg80211_scan_request *request)
0798 {
0799     struct lbs_private *priv = wiphy_priv(wiphy);
0800     int ret = 0;
0801 
0802     if (priv->scan_req || delayed_work_pending(&priv->scan_work)) {
0803         /* old scan request not yet processed */
0804         ret = -EAGAIN;
0805         goto out;
0806     }
0807 
0808     _internal_start_scan(priv, false, request);
0809 
0810     if (priv->surpriseremoved)
0811         ret = -EIO;
0812 
0813  out:
0814     return ret;
0815 }
0816 
0817 
0818 
0819 
0820 /*
0821  * Events
0822  */
0823 
0824 void lbs_send_disconnect_notification(struct lbs_private *priv,
0825                       bool locally_generated)
0826 {
0827     cfg80211_disconnected(priv->dev, 0, NULL, 0, locally_generated,
0828                   GFP_KERNEL);
0829 }
0830 
0831 void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event)
0832 {
0833     cfg80211_michael_mic_failure(priv->dev,
0834         priv->assoc_bss,
0835         event == MACREG_INT_CODE_MIC_ERR_MULTICAST ?
0836             NL80211_KEYTYPE_GROUP :
0837             NL80211_KEYTYPE_PAIRWISE,
0838         -1,
0839         NULL,
0840         GFP_KERNEL);
0841 }
0842 
0843 
0844 
0845 
0846 /*
0847  * Connect/disconnect
0848  */
0849 
0850 
0851 /*
0852  * This removes all WEP keys
0853  */
0854 static int lbs_remove_wep_keys(struct lbs_private *priv)
0855 {
0856     struct cmd_ds_802_11_set_wep cmd;
0857     int ret;
0858 
0859     memset(&cmd, 0, sizeof(cmd));
0860     cmd.hdr.size = cpu_to_le16(sizeof(cmd));
0861     cmd.keyindex = cpu_to_le16(priv->wep_tx_key);
0862     cmd.action = cpu_to_le16(CMD_ACT_REMOVE);
0863 
0864     ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
0865 
0866     return ret;
0867 }
0868 
0869 /*
0870  * Set WEP keys
0871  */
0872 static int lbs_set_wep_keys(struct lbs_private *priv)
0873 {
0874     struct cmd_ds_802_11_set_wep cmd;
0875     int i;
0876     int ret;
0877 
0878     /*
0879      * command         13 00
0880      * size            50 00
0881      * sequence        xx xx
0882      * result          00 00
0883      * action          02 00     ACT_ADD
0884      * transmit key    00 00
0885      * type for key 1  01        WEP40
0886      * type for key 2  00
0887      * type for key 3  00
0888      * type for key 4  00
0889      * key 1           39 39 39 39 39 00 00 00
0890      *                 00 00 00 00 00 00 00 00
0891      * key 2           00 00 00 00 00 00 00 00
0892      *                 00 00 00 00 00 00 00 00
0893      * key 3           00 00 00 00 00 00 00 00
0894      *                 00 00 00 00 00 00 00 00
0895      * key 4           00 00 00 00 00 00 00 00
0896      */
0897     if (priv->wep_key_len[0] || priv->wep_key_len[1] ||
0898         priv->wep_key_len[2] || priv->wep_key_len[3]) {
0899         /* Only set wep keys if we have at least one of them */
0900         memset(&cmd, 0, sizeof(cmd));
0901         cmd.hdr.size = cpu_to_le16(sizeof(cmd));
0902         cmd.keyindex = cpu_to_le16(priv->wep_tx_key);
0903         cmd.action = cpu_to_le16(CMD_ACT_ADD);
0904 
0905         for (i = 0; i < 4; i++) {
0906             switch (priv->wep_key_len[i]) {
0907             case WLAN_KEY_LEN_WEP40:
0908                 cmd.keytype[i] = CMD_TYPE_WEP_40_BIT;
0909                 break;
0910             case WLAN_KEY_LEN_WEP104:
0911                 cmd.keytype[i] = CMD_TYPE_WEP_104_BIT;
0912                 break;
0913             default:
0914                 cmd.keytype[i] = 0;
0915                 break;
0916             }
0917             memcpy(cmd.keymaterial[i], priv->wep_key[i],
0918                    priv->wep_key_len[i]);
0919         }
0920 
0921         ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
0922     } else {
0923         /* Otherwise remove all wep keys */
0924         ret = lbs_remove_wep_keys(priv);
0925     }
0926 
0927     return ret;
0928 }
0929 
0930 
0931 /*
0932  * Enable/Disable RSN status
0933  */
0934 static int lbs_enable_rsn(struct lbs_private *priv, int enable)
0935 {
0936     struct cmd_ds_802_11_enable_rsn cmd;
0937     int ret;
0938 
0939     /*
0940      * cmd       2f 00
0941      * size      0c 00
0942      * sequence  xx xx
0943      * result    00 00
0944      * action    01 00    ACT_SET
0945      * enable    01 00
0946      */
0947     memset(&cmd, 0, sizeof(cmd));
0948     cmd.hdr.size = cpu_to_le16(sizeof(cmd));
0949     cmd.action = cpu_to_le16(CMD_ACT_SET);
0950     cmd.enable = cpu_to_le16(enable);
0951 
0952     ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd);
0953 
0954     return ret;
0955 }
0956 
0957 
0958 /*
0959  * Set WPA/WPA key material
0960  */
0961 
0962 /*
0963  * like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we
0964  * get rid of WEXT, this should go into host.h
0965  */
0966 
0967 struct cmd_key_material {
0968     struct cmd_header hdr;
0969 
0970     __le16 action;
0971     struct MrvlIEtype_keyParamSet param;
0972 } __packed;
0973 
0974 static int lbs_set_key_material(struct lbs_private *priv,
0975                 int key_type, int key_info,
0976                 const u8 *key, u16 key_len)
0977 {
0978     struct cmd_key_material cmd;
0979     int ret;
0980 
0981     /*
0982      * Example for WPA (TKIP):
0983      *
0984      * cmd       5e 00
0985      * size      34 00
0986      * sequence  xx xx
0987      * result    00 00
0988      * action    01 00
0989      * TLV type  00 01    key param
0990      * length    00 26
0991      * key type  01 00    TKIP
0992      * key info  06 00    UNICAST | ENABLED
0993      * key len   20 00
0994      * key       32 bytes
0995      */
0996     memset(&cmd, 0, sizeof(cmd));
0997     cmd.hdr.size = cpu_to_le16(sizeof(cmd));
0998     cmd.action = cpu_to_le16(CMD_ACT_SET);
0999     cmd.param.type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
1000     cmd.param.length = cpu_to_le16(sizeof(cmd.param) - 4);
1001     cmd.param.keytypeid = cpu_to_le16(key_type);
1002     cmd.param.keyinfo = cpu_to_le16(key_info);
1003     cmd.param.keylen = cpu_to_le16(key_len);
1004     if (key && key_len)
1005         memcpy(cmd.param.key, key, key_len);
1006 
1007     ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd);
1008 
1009     return ret;
1010 }
1011 
1012 
1013 /*
1014  * Sets the auth type (open, shared, etc) in the firmware. That
1015  * we use CMD_802_11_AUTHENTICATE is misleading, this firmware
1016  * command doesn't send an authentication frame at all, it just
1017  * stores the auth_type.
1018  */
1019 static int lbs_set_authtype(struct lbs_private *priv,
1020                 struct cfg80211_connect_params *sme)
1021 {
1022     struct cmd_ds_802_11_authenticate cmd;
1023     int ret;
1024 
1025     /*
1026      * cmd        11 00
1027      * size       19 00
1028      * sequence   xx xx
1029      * result     00 00
1030      * BSS id     00 13 19 80 da 30
1031      * auth type  00
1032      * reserved   00 00 00 00 00 00 00 00 00 00
1033      */
1034     memset(&cmd, 0, sizeof(cmd));
1035     cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1036     if (sme->bssid)
1037         memcpy(cmd.bssid, sme->bssid, ETH_ALEN);
1038     /* convert auth_type */
1039     ret = lbs_auth_to_authtype(sme->auth_type);
1040     if (ret < 0)
1041         goto done;
1042 
1043     cmd.authtype = ret;
1044     ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd);
1045 
1046  done:
1047     return ret;
1048 }
1049 
1050 
1051 /*
1052  * Create association request
1053  */
1054 #define LBS_ASSOC_MAX_CMD_SIZE                     \
1055     (sizeof(struct cmd_ds_802_11_associate)    \
1056      + LBS_MAX_SSID_TLV_SIZE                   \
1057      + LBS_MAX_CHANNEL_TLV_SIZE                \
1058      + LBS_MAX_CF_PARAM_TLV_SIZE               \
1059      + LBS_MAX_AUTH_TYPE_TLV_SIZE              \
1060      + LBS_MAX_WPA_TLV_SIZE)
1061 
1062 static int lbs_associate(struct lbs_private *priv,
1063         struct cfg80211_bss *bss,
1064         struct cfg80211_connect_params *sme)
1065 {
1066     struct cmd_ds_802_11_associate_response *resp;
1067     struct cmd_ds_802_11_associate *cmd = kzalloc(LBS_ASSOC_MAX_CMD_SIZE,
1068                               GFP_KERNEL);
1069     const u8 *ssid_eid;
1070     size_t len, resp_ie_len;
1071     int status;
1072     int ret;
1073     u8 *pos;
1074     u8 *tmp;
1075 
1076     if (!cmd) {
1077         ret = -ENOMEM;
1078         goto done;
1079     }
1080     pos = &cmd->iebuf[0];
1081 
1082     /*
1083      * cmd              50 00
1084      * length           34 00
1085      * sequence         xx xx
1086      * result           00 00
1087      * BSS id           00 13 19 80 da 30
1088      * capabilities     11 00
1089      * listen interval  0a 00
1090      * beacon interval  00 00
1091      * DTIM period      00
1092      * TLVs             xx   (up to 512 bytes)
1093      */
1094     cmd->hdr.command = cpu_to_le16(CMD_802_11_ASSOCIATE);
1095 
1096     /* Fill in static fields */
1097     memcpy(cmd->bssid, bss->bssid, ETH_ALEN);
1098     cmd->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
1099     cmd->capability = cpu_to_le16(bss->capability);
1100 
1101     /* add SSID TLV */
1102     rcu_read_lock();
1103     ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
1104     if (ssid_eid)
1105         pos += lbs_add_ssid_tlv(pos, ssid_eid + 2, ssid_eid[1]);
1106     else
1107         lbs_deb_assoc("no SSID\n");
1108     rcu_read_unlock();
1109 
1110     /* add DS param TLV */
1111     if (bss->channel)
1112         pos += lbs_add_channel_tlv(pos, bss->channel->hw_value);
1113     else
1114         lbs_deb_assoc("no channel\n");
1115 
1116     /* add (empty) CF param TLV */
1117     pos += lbs_add_cf_param_tlv(pos);
1118 
1119     /* add rates TLV */
1120     tmp = pos + 4; /* skip Marvell IE header */
1121     pos += lbs_add_common_rates_tlv(pos, bss);
1122     lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp);
1123 
1124     /* add auth type TLV */
1125     if (MRVL_FW_MAJOR_REV(priv->fwrelease) >= 9)
1126         pos += lbs_add_auth_type_tlv(pos, sme->auth_type);
1127 
1128     /* add WPA/WPA2 TLV */
1129     if (sme->ie && sme->ie_len)
1130         pos += lbs_add_wpa_tlv(pos, sme->ie, sme->ie_len);
1131 
1132     len = sizeof(*cmd) + (u16)(pos - (u8 *) &cmd->iebuf);
1133     cmd->hdr.size = cpu_to_le16(len);
1134 
1135     lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_CMD", (u8 *) cmd,
1136             le16_to_cpu(cmd->hdr.size));
1137 
1138     /* store for later use */
1139     memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN);
1140 
1141     ret = lbs_cmd_with_response(priv, CMD_802_11_ASSOCIATE, cmd);
1142     if (ret)
1143         goto done;
1144 
1145     /* generate connect message to cfg80211 */
1146 
1147     resp = (void *) cmd; /* recast for easier field access */
1148     status = le16_to_cpu(resp->statuscode);
1149 
1150     /* Older FW versions map the IEEE 802.11 Status Code in the association
1151      * response to the following values returned in resp->statuscode:
1152      *
1153      *    IEEE Status Code                Marvell Status Code
1154      *    0                       ->      0x0000 ASSOC_RESULT_SUCCESS
1155      *    13                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
1156      *    14                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
1157      *    15                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
1158      *    16                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
1159      *    others                  ->      0x0003 ASSOC_RESULT_REFUSED
1160      *
1161      * Other response codes:
1162      *    0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
1163      *    0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
1164      *                                    association response from the AP)
1165      */
1166     if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
1167         switch (status) {
1168         case 0:
1169             break;
1170         case 1:
1171             lbs_deb_assoc("invalid association parameters\n");
1172             status = WLAN_STATUS_CAPS_UNSUPPORTED;
1173             break;
1174         case 2:
1175             lbs_deb_assoc("timer expired while waiting for AP\n");
1176             status = WLAN_STATUS_AUTH_TIMEOUT;
1177             break;
1178         case 3:
1179             lbs_deb_assoc("association refused by AP\n");
1180             status = WLAN_STATUS_ASSOC_DENIED_UNSPEC;
1181             break;
1182         case 4:
1183             lbs_deb_assoc("authentication refused by AP\n");
1184             status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1185             break;
1186         default:
1187             lbs_deb_assoc("association failure %d\n", status);
1188             /* v5 OLPC firmware does return the AP status code if
1189              * it's not one of the values above.  Let that through.
1190              */
1191             break;
1192         }
1193     }
1194 
1195     lbs_deb_assoc("status %d, statuscode 0x%04x, capability 0x%04x, "
1196               "aid 0x%04x\n", status, le16_to_cpu(resp->statuscode),
1197               le16_to_cpu(resp->capability), le16_to_cpu(resp->aid));
1198 
1199     resp_ie_len = le16_to_cpu(resp->hdr.size)
1200         - sizeof(resp->hdr)
1201         - 6;
1202     cfg80211_connect_result(priv->dev,
1203                 priv->assoc_bss,
1204                 sme->ie, sme->ie_len,
1205                 resp->iebuf, resp_ie_len,
1206                 status,
1207                 GFP_KERNEL);
1208 
1209     if (status == 0) {
1210         /* TODO: get rid of priv->connect_status */
1211         priv->connect_status = LBS_CONNECTED;
1212         netif_carrier_on(priv->dev);
1213         if (!priv->tx_pending_len)
1214             netif_tx_wake_all_queues(priv->dev);
1215     }
1216 
1217     kfree(cmd);
1218 done:
1219     return ret;
1220 }
1221 
1222 static struct cfg80211_scan_request *
1223 _new_connect_scan_req(struct wiphy *wiphy, struct cfg80211_connect_params *sme)
1224 {
1225     struct cfg80211_scan_request *creq = NULL;
1226     int i, n_channels = ieee80211_get_num_supported_channels(wiphy);
1227     enum nl80211_band band;
1228 
1229     creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
1230                n_channels * sizeof(void *),
1231                GFP_ATOMIC);
1232     if (!creq)
1233         return NULL;
1234 
1235     /* SSIDs come after channels */
1236     creq->ssids = (void *)&creq->channels[n_channels];
1237     creq->n_channels = n_channels;
1238     creq->n_ssids = 1;
1239 
1240     /* Scan all available channels */
1241     i = 0;
1242     for (band = 0; band < NUM_NL80211_BANDS; band++) {
1243         int j;
1244 
1245         if (!wiphy->bands[band])
1246             continue;
1247 
1248         for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
1249             /* ignore disabled channels */
1250             if (wiphy->bands[band]->channels[j].flags &
1251                         IEEE80211_CHAN_DISABLED)
1252                 continue;
1253 
1254             creq->channels[i] = &wiphy->bands[band]->channels[j];
1255             i++;
1256         }
1257     }
1258     if (i) {
1259         /* Set real number of channels specified in creq->channels[] */
1260         creq->n_channels = i;
1261 
1262         /* Scan for the SSID we're going to connect to */
1263         memcpy(creq->ssids[0].ssid, sme->ssid, sme->ssid_len);
1264         creq->ssids[0].ssid_len = sme->ssid_len;
1265     } else {
1266         /* No channels found... */
1267         kfree(creq);
1268         creq = NULL;
1269     }
1270 
1271     return creq;
1272 }
1273 
1274 static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
1275                struct cfg80211_connect_params *sme)
1276 {
1277     struct lbs_private *priv = wiphy_priv(wiphy);
1278     struct cfg80211_bss *bss = NULL;
1279     int ret = 0;
1280     u8 preamble = RADIO_PREAMBLE_SHORT;
1281 
1282     if (dev == priv->mesh_dev)
1283         return -EOPNOTSUPP;
1284 
1285     if (!sme->bssid) {
1286         struct cfg80211_scan_request *creq;
1287 
1288         /*
1289          * Scan for the requested network after waiting for existing
1290          * scans to finish.
1291          */
1292         lbs_deb_assoc("assoc: waiting for existing scans\n");
1293         wait_event_interruptible_timeout(priv->scan_q,
1294                          (priv->scan_req == NULL),
1295                          (15 * HZ));
1296 
1297         creq = _new_connect_scan_req(wiphy, sme);
1298         if (!creq) {
1299             ret = -EINVAL;
1300             goto done;
1301         }
1302 
1303         lbs_deb_assoc("assoc: scanning for compatible AP\n");
1304         _internal_start_scan(priv, true, creq);
1305 
1306         lbs_deb_assoc("assoc: waiting for scan to complete\n");
1307         wait_event_interruptible_timeout(priv->scan_q,
1308                          (priv->scan_req == NULL),
1309                          (15 * HZ));
1310         lbs_deb_assoc("assoc: scanning completed\n");
1311     }
1312 
1313     /* Find the BSS we want using available scan results */
1314     bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
1315         sme->ssid, sme->ssid_len, IEEE80211_BSS_TYPE_ESS,
1316         IEEE80211_PRIVACY_ANY);
1317     if (!bss) {
1318         wiphy_err(wiphy, "assoc: bss %pM not in scan results\n",
1319               sme->bssid);
1320         ret = -ENOENT;
1321         goto done;
1322     }
1323     lbs_deb_assoc("trying %pM\n", bss->bssid);
1324     lbs_deb_assoc("cipher 0x%x, key index %d, key len %d\n",
1325               sme->crypto.cipher_group,
1326               sme->key_idx, sme->key_len);
1327 
1328     /* As this is a new connection, clear locally stored WEP keys */
1329     priv->wep_tx_key = 0;
1330     memset(priv->wep_key, 0, sizeof(priv->wep_key));
1331     memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1332 
1333     /* set/remove WEP keys */
1334     switch (sme->crypto.cipher_group) {
1335     case WLAN_CIPHER_SUITE_WEP40:
1336     case WLAN_CIPHER_SUITE_WEP104:
1337         /* Store provided WEP keys in priv-> */
1338         priv->wep_tx_key = sme->key_idx;
1339         priv->wep_key_len[sme->key_idx] = sme->key_len;
1340         memcpy(priv->wep_key[sme->key_idx], sme->key, sme->key_len);
1341         /* Set WEP keys and WEP mode */
1342         lbs_set_wep_keys(priv);
1343         priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE;
1344         lbs_set_mac_control(priv);
1345         /* No RSN mode for WEP */
1346         lbs_enable_rsn(priv, 0);
1347         break;
1348     case 0: /* there's no WLAN_CIPHER_SUITE_NONE definition */
1349         /*
1350          * If we don't have no WEP, no WPA and no WPA2,
1351          * we remove all keys like in the WPA/WPA2 setup,
1352          * we just don't set RSN.
1353          *
1354          * Therefore: fall-through
1355          */
1356     case WLAN_CIPHER_SUITE_TKIP:
1357     case WLAN_CIPHER_SUITE_CCMP:
1358         /* Remove WEP keys and WEP mode */
1359         lbs_remove_wep_keys(priv);
1360         priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE;
1361         lbs_set_mac_control(priv);
1362 
1363         /* clear the WPA/WPA2 keys */
1364         lbs_set_key_material(priv,
1365             KEY_TYPE_ID_WEP, /* doesn't matter */
1366             KEY_INFO_WPA_UNICAST,
1367             NULL, 0);
1368         lbs_set_key_material(priv,
1369             KEY_TYPE_ID_WEP, /* doesn't matter */
1370             KEY_INFO_WPA_MCAST,
1371             NULL, 0);
1372         /* RSN mode for WPA/WPA2 */
1373         lbs_enable_rsn(priv, sme->crypto.cipher_group != 0);
1374         break;
1375     default:
1376         wiphy_err(wiphy, "unsupported cipher group 0x%x\n",
1377               sme->crypto.cipher_group);
1378         ret = -ENOTSUPP;
1379         goto done;
1380     }
1381 
1382     ret = lbs_set_authtype(priv, sme);
1383     if (ret == -ENOTSUPP) {
1384         wiphy_err(wiphy, "unsupported authtype 0x%x\n", sme->auth_type);
1385         goto done;
1386     }
1387 
1388     lbs_set_radio(priv, preamble, 1);
1389 
1390     /* Do the actual association */
1391     ret = lbs_associate(priv, bss, sme);
1392 
1393  done:
1394     if (bss)
1395         cfg80211_put_bss(wiphy, bss);
1396     return ret;
1397 }
1398 
1399 int lbs_disconnect(struct lbs_private *priv, u16 reason)
1400 {
1401     struct cmd_ds_802_11_deauthenticate cmd;
1402     int ret;
1403 
1404     memset(&cmd, 0, sizeof(cmd));
1405     cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1406     /* Mildly ugly to use a locally store my own BSSID ... */
1407     memcpy(cmd.macaddr, &priv->assoc_bss, ETH_ALEN);
1408     cmd.reasoncode = cpu_to_le16(reason);
1409 
1410     ret = lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd);
1411     if (ret)
1412         return ret;
1413 
1414     cfg80211_disconnected(priv->dev,
1415             reason,
1416             NULL, 0, true,
1417             GFP_KERNEL);
1418     priv->connect_status = LBS_DISCONNECTED;
1419 
1420     return 0;
1421 }
1422 
1423 static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
1424     u16 reason_code)
1425 {
1426     struct lbs_private *priv = wiphy_priv(wiphy);
1427 
1428     if (dev == priv->mesh_dev)
1429         return -EOPNOTSUPP;
1430 
1431     /* store for lbs_cfg_ret_disconnect() */
1432     priv->disassoc_reason = reason_code;
1433 
1434     return lbs_disconnect(priv, reason_code);
1435 }
1436 
1437 static int lbs_cfg_set_default_key(struct wiphy *wiphy,
1438                    struct net_device *netdev,
1439                    u8 key_index, bool unicast,
1440                    bool multicast)
1441 {
1442     struct lbs_private *priv = wiphy_priv(wiphy);
1443 
1444     if (netdev == priv->mesh_dev)
1445         return -EOPNOTSUPP;
1446 
1447     if (key_index != priv->wep_tx_key) {
1448         lbs_deb_assoc("set_default_key: to %d\n", key_index);
1449         priv->wep_tx_key = key_index;
1450         lbs_set_wep_keys(priv);
1451     }
1452 
1453     return 0;
1454 }
1455 
1456 
1457 static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
1458                u8 idx, bool pairwise, const u8 *mac_addr,
1459                struct key_params *params)
1460 {
1461     struct lbs_private *priv = wiphy_priv(wiphy);
1462     u16 key_info;
1463     u16 key_type;
1464     int ret = 0;
1465 
1466     if (netdev == priv->mesh_dev)
1467         return -EOPNOTSUPP;
1468 
1469     lbs_deb_assoc("add_key: cipher 0x%x, mac_addr %pM\n",
1470               params->cipher, mac_addr);
1471     lbs_deb_assoc("add_key: key index %d, key len %d\n",
1472               idx, params->key_len);
1473     if (params->key_len)
1474         lbs_deb_hex(LBS_DEB_CFG80211, "KEY",
1475                 params->key, params->key_len);
1476 
1477     lbs_deb_assoc("add_key: seq len %d\n", params->seq_len);
1478     if (params->seq_len)
1479         lbs_deb_hex(LBS_DEB_CFG80211, "SEQ",
1480                 params->seq, params->seq_len);
1481 
1482     switch (params->cipher) {
1483     case WLAN_CIPHER_SUITE_WEP40:
1484     case WLAN_CIPHER_SUITE_WEP104:
1485         /* actually compare if something has changed ... */
1486         if ((priv->wep_key_len[idx] != params->key_len) ||
1487             memcmp(priv->wep_key[idx],
1488                    params->key, params->key_len) != 0) {
1489             priv->wep_key_len[idx] = params->key_len;
1490             memcpy(priv->wep_key[idx],
1491                    params->key, params->key_len);
1492             lbs_set_wep_keys(priv);
1493         }
1494         break;
1495     case WLAN_CIPHER_SUITE_TKIP:
1496     case WLAN_CIPHER_SUITE_CCMP:
1497         key_info = KEY_INFO_WPA_ENABLED | ((idx == 0)
1498                            ? KEY_INFO_WPA_UNICAST
1499                            : KEY_INFO_WPA_MCAST);
1500         key_type = (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1501             ? KEY_TYPE_ID_TKIP
1502             : KEY_TYPE_ID_AES;
1503         lbs_set_key_material(priv,
1504                      key_type,
1505                      key_info,
1506                      params->key, params->key_len);
1507         break;
1508     default:
1509         wiphy_err(wiphy, "unhandled cipher 0x%x\n", params->cipher);
1510         ret = -ENOTSUPP;
1511         break;
1512     }
1513 
1514     return ret;
1515 }
1516 
1517 
1518 static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev,
1519                u8 key_index, bool pairwise, const u8 *mac_addr)
1520 {
1521 
1522     lbs_deb_assoc("del_key: key_idx %d, mac_addr %pM\n",
1523               key_index, mac_addr);
1524 
1525 #ifdef TODO
1526     struct lbs_private *priv = wiphy_priv(wiphy);
1527     /*
1528      * I think can keep this a NO-OP, because:
1529 
1530      * - we clear all keys whenever we do lbs_cfg_connect() anyway
1531      * - neither "iw" nor "wpa_supplicant" won't call this during
1532      *   an ongoing connection
1533      * - TODO: but I have to check if this is still true when
1534      *   I set the AP to periodic re-keying
1535      * - we've not kzallec() something when we've added a key at
1536      *   lbs_cfg_connect() or lbs_cfg_add_key().
1537      *
1538      * This causes lbs_cfg_del_key() only called at disconnect time,
1539      * where we'd just waste time deleting a key that is not going
1540      * to be used anyway.
1541      */
1542     if (key_index < 3 && priv->wep_key_len[key_index]) {
1543         priv->wep_key_len[key_index] = 0;
1544         lbs_set_wep_keys(priv);
1545     }
1546 #endif
1547 
1548     return 0;
1549 }
1550 
1551 
1552 /*
1553  * Get station
1554  */
1555 
1556 static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
1557                    const u8 *mac, struct station_info *sinfo)
1558 {
1559     struct lbs_private *priv = wiphy_priv(wiphy);
1560     s8 signal, noise;
1561     int ret;
1562     size_t i;
1563 
1564     sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
1565              BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
1566              BIT_ULL(NL80211_STA_INFO_RX_BYTES) |
1567              BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
1568     sinfo->tx_bytes = priv->dev->stats.tx_bytes;
1569     sinfo->tx_packets = priv->dev->stats.tx_packets;
1570     sinfo->rx_bytes = priv->dev->stats.rx_bytes;
1571     sinfo->rx_packets = priv->dev->stats.rx_packets;
1572 
1573     /* Get current RSSI */
1574     ret = lbs_get_rssi(priv, &signal, &noise);
1575     if (ret == 0) {
1576         sinfo->signal = signal;
1577         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
1578     }
1579 
1580     /* Convert priv->cur_rate from hw_value to NL80211 value */
1581     for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) {
1582         if (priv->cur_rate == lbs_rates[i].hw_value) {
1583             sinfo->txrate.legacy = lbs_rates[i].bitrate;
1584             sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
1585             break;
1586         }
1587     }
1588 
1589     return 0;
1590 }
1591 
1592 
1593 
1594 
1595 /*
1596  * Change interface
1597  */
1598 
1599 static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,
1600     enum nl80211_iftype type,
1601            struct vif_params *params)
1602 {
1603     struct lbs_private *priv = wiphy_priv(wiphy);
1604     int ret = 0;
1605 
1606     if (dev == priv->mesh_dev)
1607         return -EOPNOTSUPP;
1608 
1609     switch (type) {
1610     case NL80211_IFTYPE_MONITOR:
1611     case NL80211_IFTYPE_STATION:
1612     case NL80211_IFTYPE_ADHOC:
1613         break;
1614     default:
1615         return -EOPNOTSUPP;
1616     }
1617 
1618     if (priv->iface_running)
1619         ret = lbs_set_iface_type(priv, type);
1620 
1621     if (!ret)
1622         priv->wdev->iftype = type;
1623 
1624     return ret;
1625 }
1626 
1627 
1628 
1629 /*
1630  * IBSS (Ad-Hoc)
1631  */
1632 
1633 /*
1634  * The firmware needs the following bits masked out of the beacon-derived
1635  * capability field when associating/joining to a BSS:
1636  *  9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused)
1637  */
1638 #define CAPINFO_MASK (~(0xda00))
1639 
1640 
1641 static void lbs_join_post(struct lbs_private *priv,
1642               struct cfg80211_ibss_params *params,
1643               u8 *bssid, u16 capability)
1644 {
1645     u8 fake_ie[2 + IEEE80211_MAX_SSID_LEN + /* ssid */
1646            2 + 4 +                      /* basic rates */
1647            2 + 1 +                      /* DS parameter */
1648            2 + 2 +                      /* atim */
1649            2 + 8];                      /* extended rates */
1650     u8 *fake = fake_ie;
1651     struct cfg80211_bss *bss;
1652 
1653     /*
1654      * For cfg80211_inform_bss, we'll need a fake IE, as we can't get
1655      * the real IE from the firmware. So we fabricate a fake IE based on
1656      * what the firmware actually sends (sniffed with wireshark).
1657      */
1658     /* Fake SSID IE */
1659     *fake++ = WLAN_EID_SSID;
1660     *fake++ = params->ssid_len;
1661     memcpy(fake, params->ssid, params->ssid_len);
1662     fake += params->ssid_len;
1663     /* Fake supported basic rates IE */
1664     *fake++ = WLAN_EID_SUPP_RATES;
1665     *fake++ = 4;
1666     *fake++ = 0x82;
1667     *fake++ = 0x84;
1668     *fake++ = 0x8b;
1669     *fake++ = 0x96;
1670     /* Fake DS channel IE */
1671     *fake++ = WLAN_EID_DS_PARAMS;
1672     *fake++ = 1;
1673     *fake++ = params->chandef.chan->hw_value;
1674     /* Fake IBSS params IE */
1675     *fake++ = WLAN_EID_IBSS_PARAMS;
1676     *fake++ = 2;
1677     *fake++ = 0; /* ATIM=0 */
1678     *fake++ = 0;
1679     /* Fake extended rates IE, TODO: don't add this for 802.11b only,
1680      * but I don't know how this could be checked */
1681     *fake++ = WLAN_EID_EXT_SUPP_RATES;
1682     *fake++ = 8;
1683     *fake++ = 0x0c;
1684     *fake++ = 0x12;
1685     *fake++ = 0x18;
1686     *fake++ = 0x24;
1687     *fake++ = 0x30;
1688     *fake++ = 0x48;
1689     *fake++ = 0x60;
1690     *fake++ = 0x6c;
1691     lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie);
1692 
1693     bss = cfg80211_inform_bss(priv->wdev->wiphy,
1694                   params->chandef.chan,
1695                   CFG80211_BSS_FTYPE_UNKNOWN,
1696                   bssid,
1697                   0,
1698                   capability,
1699                   params->beacon_interval,
1700                   fake_ie, fake - fake_ie,
1701                   0, GFP_KERNEL);
1702     cfg80211_put_bss(priv->wdev->wiphy, bss);
1703 
1704     cfg80211_ibss_joined(priv->dev, bssid, params->chandef.chan,
1705                  GFP_KERNEL);
1706 
1707     /* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */
1708     priv->connect_status = LBS_CONNECTED;
1709     netif_carrier_on(priv->dev);
1710     if (!priv->tx_pending_len)
1711         netif_wake_queue(priv->dev);
1712 }
1713 
1714 static int lbs_ibss_join_existing(struct lbs_private *priv,
1715     struct cfg80211_ibss_params *params,
1716     struct cfg80211_bss *bss)
1717 {
1718     const u8 *rates_eid;
1719     struct cmd_ds_802_11_ad_hoc_join cmd;
1720     u8 preamble = RADIO_PREAMBLE_SHORT;
1721     int ret = 0;
1722     int hw, i;
1723     u8 rates_max;
1724     u8 *rates;
1725 
1726     /* TODO: set preamble based on scan result */
1727     ret = lbs_set_radio(priv, preamble, 1);
1728     if (ret)
1729         goto out;
1730 
1731     /*
1732      * Example CMD_802_11_AD_HOC_JOIN command:
1733      *
1734      * command         2c 00         CMD_802_11_AD_HOC_JOIN
1735      * size            65 00
1736      * sequence        xx xx
1737      * result          00 00
1738      * bssid           02 27 27 97 2f 96
1739      * ssid            49 42 53 53 00 00 00 00
1740      *                 00 00 00 00 00 00 00 00
1741      *                 00 00 00 00 00 00 00 00
1742      *                 00 00 00 00 00 00 00 00
1743      * type            02            CMD_BSS_TYPE_IBSS
1744      * beacon period   64 00
1745      * dtim period     00
1746      * timestamp       00 00 00 00 00 00 00 00
1747      * localtime       00 00 00 00 00 00 00 00
1748      * IE DS           03
1749      * IE DS len       01
1750      * IE DS channel   01
1751      * reserveed       00 00 00 00
1752      * IE IBSS         06
1753      * IE IBSS len     02
1754      * IE IBSS atim    00 00
1755      * reserved        00 00 00 00
1756      * capability      02 00
1757      * rates           82 84 8b 96 0c 12 18 24 30 48 60 6c 00
1758      * fail timeout    ff 00
1759      * probe delay     00 00
1760      */
1761     memset(&cmd, 0, sizeof(cmd));
1762     cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1763 
1764     memcpy(cmd.bss.bssid, bss->bssid, ETH_ALEN);
1765     memcpy(cmd.bss.ssid, params->ssid, params->ssid_len);
1766     cmd.bss.type = CMD_BSS_TYPE_IBSS;
1767     cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval);
1768     cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS;
1769     cmd.bss.ds.header.len = 1;
1770     cmd.bss.ds.channel = params->chandef.chan->hw_value;
1771     cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS;
1772     cmd.bss.ibss.header.len = 2;
1773     cmd.bss.ibss.atimwindow = 0;
1774     cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
1775 
1776     /* set rates to the intersection of our rates and the rates in the
1777        bss */
1778     rcu_read_lock();
1779     rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
1780     if (!rates_eid) {
1781         lbs_add_rates(cmd.bss.rates);
1782     } else {
1783         rates_max = rates_eid[1];
1784         if (rates_max > MAX_RATES) {
1785             lbs_deb_join("invalid rates");
1786             rcu_read_unlock();
1787             ret = -EINVAL;
1788             goto out;
1789         }
1790         rates = cmd.bss.rates;
1791         for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
1792             u8 hw_rate = lbs_rates[hw].bitrate / 5;
1793             for (i = 0; i < rates_max; i++) {
1794                 if (hw_rate == (rates_eid[i+2] & 0x7f)) {
1795                     u8 rate = rates_eid[i+2];
1796                     if (rate == 0x02 || rate == 0x04 ||
1797                         rate == 0x0b || rate == 0x16)
1798                         rate |= 0x80;
1799                     *rates++ = rate;
1800                 }
1801             }
1802         }
1803     }
1804     rcu_read_unlock();
1805 
1806     /* Only v8 and below support setting this */
1807     if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
1808         cmd.failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
1809         cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1810     }
1811     ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd);
1812     if (ret)
1813         goto out;
1814 
1815     /*
1816      * This is a sample response to CMD_802_11_AD_HOC_JOIN:
1817      *
1818      * response        2c 80
1819      * size            09 00
1820      * sequence        xx xx
1821      * result          00 00
1822      * reserved        00
1823      */
1824     lbs_join_post(priv, params, bss->bssid, bss->capability);
1825 
1826  out:
1827     return ret;
1828 }
1829 
1830 
1831 
1832 static int lbs_ibss_start_new(struct lbs_private *priv,
1833     struct cfg80211_ibss_params *params)
1834 {
1835     struct cmd_ds_802_11_ad_hoc_start cmd;
1836     struct cmd_ds_802_11_ad_hoc_result *resp =
1837         (struct cmd_ds_802_11_ad_hoc_result *) &cmd;
1838     u8 preamble = RADIO_PREAMBLE_SHORT;
1839     int ret = 0;
1840     u16 capability;
1841 
1842     ret = lbs_set_radio(priv, preamble, 1);
1843     if (ret)
1844         goto out;
1845 
1846     /*
1847      * Example CMD_802_11_AD_HOC_START command:
1848      *
1849      * command         2b 00         CMD_802_11_AD_HOC_START
1850      * size            b1 00
1851      * sequence        xx xx
1852      * result          00 00
1853      * ssid            54 45 53 54 00 00 00 00
1854      *                 00 00 00 00 00 00 00 00
1855      *                 00 00 00 00 00 00 00 00
1856      *                 00 00 00 00 00 00 00 00
1857      * bss type        02
1858      * beacon period   64 00
1859      * dtim period     00
1860      * IE IBSS         06
1861      * IE IBSS len     02
1862      * IE IBSS atim    00 00
1863      * reserved        00 00 00 00
1864      * IE DS           03
1865      * IE DS len       01
1866      * IE DS channel   01
1867      * reserved        00 00 00 00
1868      * probe delay     00 00
1869      * capability      02 00
1870      * rates           82 84 8b 96   (basic rates with have bit 7 set)
1871      *                 0c 12 18 24 30 48 60 6c
1872      * padding         100 bytes
1873      */
1874     memset(&cmd, 0, sizeof(cmd));
1875     cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1876     memcpy(cmd.ssid, params->ssid, params->ssid_len);
1877     cmd.bsstype = CMD_BSS_TYPE_IBSS;
1878     cmd.beaconperiod = cpu_to_le16(params->beacon_interval);
1879     cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS;
1880     cmd.ibss.header.len = 2;
1881     cmd.ibss.atimwindow = 0;
1882     cmd.ds.header.id = WLAN_EID_DS_PARAMS;
1883     cmd.ds.header.len = 1;
1884     cmd.ds.channel = params->chandef.chan->hw_value;
1885     /* Only v8 and below support setting probe delay */
1886     if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8)
1887         cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1888     /* TODO: mix in WLAN_CAPABILITY_PRIVACY */
1889     capability = WLAN_CAPABILITY_IBSS;
1890     cmd.capability = cpu_to_le16(capability);
1891     lbs_add_rates(cmd.rates);
1892 
1893 
1894     ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd);
1895     if (ret)
1896         goto out;
1897 
1898     /*
1899      * This is a sample response to CMD_802_11_AD_HOC_JOIN:
1900      *
1901      * response        2b 80
1902      * size            14 00
1903      * sequence        xx xx
1904      * result          00 00
1905      * reserved        00
1906      * bssid           02 2b 7b 0f 86 0e
1907      */
1908     lbs_join_post(priv, params, resp->bssid, capability);
1909 
1910  out:
1911     return ret;
1912 }
1913 
1914 
1915 static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1916         struct cfg80211_ibss_params *params)
1917 {
1918     struct lbs_private *priv = wiphy_priv(wiphy);
1919     int ret = 0;
1920     struct cfg80211_bss *bss;
1921 
1922     if (dev == priv->mesh_dev)
1923         return -EOPNOTSUPP;
1924 
1925     if (!params->chandef.chan) {
1926         ret = -ENOTSUPP;
1927         goto out;
1928     }
1929 
1930     ret = lbs_set_channel(priv, params->chandef.chan->hw_value);
1931     if (ret)
1932         goto out;
1933 
1934     /* Search if someone is beaconing. This assumes that the
1935      * bss list is populated already */
1936     bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid,
1937         params->ssid, params->ssid_len,
1938         IEEE80211_BSS_TYPE_IBSS, IEEE80211_PRIVACY_ANY);
1939 
1940     if (bss) {
1941         ret = lbs_ibss_join_existing(priv, params, bss);
1942         cfg80211_put_bss(wiphy, bss);
1943     } else
1944         ret = lbs_ibss_start_new(priv, params);
1945 
1946 
1947  out:
1948     return ret;
1949 }
1950 
1951 
1952 static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1953 {
1954     struct lbs_private *priv = wiphy_priv(wiphy);
1955     struct cmd_ds_802_11_ad_hoc_stop cmd;
1956     int ret = 0;
1957 
1958     if (dev == priv->mesh_dev)
1959         return -EOPNOTSUPP;
1960 
1961     memset(&cmd, 0, sizeof(cmd));
1962     cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1963     ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_STOP, &cmd);
1964 
1965     /* TODO: consider doing this at MACREG_INT_CODE_ADHOC_BCN_LOST time */
1966     lbs_mac_event_disconnected(priv, true);
1967 
1968     return ret;
1969 }
1970 
1971 
1972 
1973 static int lbs_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1974                   bool enabled, int timeout)
1975 {
1976     struct lbs_private *priv = wiphy_priv(wiphy);
1977 
1978     if  (!(priv->fwcapinfo & FW_CAPINFO_PS)) {
1979         if (!enabled)
1980             return 0;
1981         else
1982             return -EINVAL;
1983     }
1984     /* firmware does not work well with too long latency with power saving
1985      * enabled, so do not enable it if there is only polling, no
1986      * interrupts (like in some sdio hosts which can only
1987      * poll for sdio irqs)
1988      */
1989     if  (priv->is_polling) {
1990         if (!enabled)
1991             return 0;
1992         else
1993             return -EINVAL;
1994     }
1995     if (!enabled) {
1996         priv->psmode = LBS802_11POWERMODECAM;
1997         if (priv->psstate != PS_STATE_FULL_POWER)
1998             lbs_set_ps_mode(priv,
1999                     PS_MODE_ACTION_EXIT_PS,
2000                     true);
2001         return 0;
2002     }
2003     if (priv->psmode != LBS802_11POWERMODECAM)
2004         return 0;
2005     priv->psmode = LBS802_11POWERMODEMAX_PSP;
2006     if (priv->connect_status == LBS_CONNECTED)
2007         lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS, true);
2008     return 0;
2009 }
2010 
2011 /*
2012  * Initialization
2013  */
2014 
2015 static const struct cfg80211_ops lbs_cfg80211_ops = {
2016     .set_monitor_channel = lbs_cfg_set_monitor_channel,
2017     .libertas_set_mesh_channel = lbs_cfg_set_mesh_channel,
2018     .scan = lbs_cfg_scan,
2019     .connect = lbs_cfg_connect,
2020     .disconnect = lbs_cfg_disconnect,
2021     .add_key = lbs_cfg_add_key,
2022     .del_key = lbs_cfg_del_key,
2023     .set_default_key = lbs_cfg_set_default_key,
2024     .get_station = lbs_cfg_get_station,
2025     .change_virtual_intf = lbs_change_intf,
2026     .join_ibss = lbs_join_ibss,
2027     .leave_ibss = lbs_leave_ibss,
2028     .set_power_mgmt = lbs_set_power_mgmt,
2029 };
2030 
2031 
2032 /*
2033  * At this time lbs_private *priv doesn't even exist, so we just allocate
2034  * memory and don't initialize the wiphy further. This is postponed until we
2035  * can talk to the firmware and happens at registration time in
2036  * lbs_cfg_wiphy_register().
2037  */
2038 struct wireless_dev *lbs_cfg_alloc(struct device *dev)
2039 {
2040     int ret = 0;
2041     struct wireless_dev *wdev;
2042 
2043     wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2044     if (!wdev)
2045         return ERR_PTR(-ENOMEM);
2046 
2047     wdev->wiphy = wiphy_new(&lbs_cfg80211_ops, sizeof(struct lbs_private));
2048     if (!wdev->wiphy) {
2049         dev_err(dev, "cannot allocate wiphy\n");
2050         ret = -ENOMEM;
2051         goto err_wiphy_new;
2052     }
2053 
2054     return wdev;
2055 
2056  err_wiphy_new:
2057     kfree(wdev);
2058     return ERR_PTR(ret);
2059 }
2060 
2061 
2062 static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv)
2063 {
2064     struct region_code_mapping {
2065         const char *cn;
2066         int code;
2067     };
2068 
2069     /* Section 5.17.2 */
2070     static const struct region_code_mapping regmap[] = {
2071         {"US ", 0x10}, /* US FCC */
2072         {"CA ", 0x20}, /* Canada */
2073         {"EU ", 0x30}, /* ETSI   */
2074         {"ES ", 0x31}, /* Spain  */
2075         {"FR ", 0x32}, /* France */
2076         {"JP ", 0x40}, /* Japan  */
2077     };
2078     size_t i;
2079 
2080     for (i = 0; i < ARRAY_SIZE(regmap); i++)
2081         if (regmap[i].code == priv->regioncode) {
2082             regulatory_hint(priv->wdev->wiphy, regmap[i].cn);
2083             break;
2084         }
2085 }
2086 
2087 static void lbs_reg_notifier(struct wiphy *wiphy,
2088                  struct regulatory_request *request)
2089 {
2090     struct lbs_private *priv = wiphy_priv(wiphy);
2091 
2092     memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2));
2093     if (lbs_iface_active(priv))
2094         lbs_set_11d_domain_info(priv);
2095 }
2096 
2097 /*
2098  * This function get's called after lbs_setup_firmware() determined the
2099  * firmware capabities. So we can setup the wiphy according to our
2100  * hardware/firmware.
2101  */
2102 int lbs_cfg_register(struct lbs_private *priv)
2103 {
2104     struct wireless_dev *wdev = priv->wdev;
2105     int ret;
2106 
2107     wdev->wiphy->max_scan_ssids = 1;
2108     wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2109 
2110     wdev->wiphy->interface_modes =
2111             BIT(NL80211_IFTYPE_STATION) |
2112             BIT(NL80211_IFTYPE_ADHOC);
2113     if (lbs_rtap_supported(priv))
2114         wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
2115     if (lbs_mesh_activated(priv))
2116         wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MESH_POINT);
2117 
2118     wdev->wiphy->bands[NL80211_BAND_2GHZ] = &lbs_band_2ghz;
2119 
2120     /*
2121      * We could check priv->fwcapinfo && FW_CAPINFO_WPA, but I have
2122      * never seen a firmware without WPA
2123      */
2124     wdev->wiphy->cipher_suites = cipher_suites;
2125     wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2126     wdev->wiphy->reg_notifier = lbs_reg_notifier;
2127 
2128     ret = wiphy_register(wdev->wiphy);
2129     if (ret < 0)
2130         pr_err("cannot register wiphy device\n");
2131 
2132     priv->wiphy_registered = true;
2133 
2134     ret = register_netdev(priv->dev);
2135     if (ret)
2136         pr_err("cannot register network device\n");
2137 
2138     INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
2139 
2140     lbs_cfg_set_regulatory_hint(priv);
2141 
2142     return ret;
2143 }
2144 
2145 void lbs_scan_deinit(struct lbs_private *priv)
2146 {
2147     cancel_delayed_work_sync(&priv->scan_work);
2148 }
2149 
2150 
2151 void lbs_cfg_free(struct lbs_private *priv)
2152 {
2153     struct wireless_dev *wdev = priv->wdev;
2154 
2155     if (!wdev)
2156         return;
2157 
2158     if (priv->wiphy_registered)
2159         wiphy_unregister(wdev->wiphy);
2160 
2161     if (wdev->wiphy)
2162         wiphy_free(wdev->wiphy);
2163 
2164     kfree(wdev);
2165 }