Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
   1/*
   2 * Implement cfg80211 ("iw") support.
   3 *
   4 * Copyright (C) 2009 M&N Solutions GmbH, 61191 Rosbach, Germany
   5 * Holger Schurig <hs4233@mail.mn-solutions.de>
   6 *
   7 */
   8
   9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  10
  11#include <linux/hardirq.h>
  12#include <linux/sched.h>
  13#include <linux/wait.h>
  14#include <linux/slab.h>
  15#include <linux/ieee80211.h>
  16#include <net/cfg80211.h>
  17#include <asm/unaligned.h>
  18
  19#include "decl.h"
  20#include "cfg.h"
  21#include "cmd.h"
  22
  23
  24#define CHAN2G(_channel, _freq, _flags) {        \
  25	.band             = IEEE80211_BAND_2GHZ, \
  26	.center_freq      = (_freq),             \
  27	.hw_value         = (_channel),          \
  28	.flags            = (_flags),            \
  29	.max_antenna_gain = 0,                   \
  30	.max_power        = 30,                  \
  31}
  32
  33static struct ieee80211_channel lbs_2ghz_channels[] = {
  34	CHAN2G(1,  2412, 0),
  35	CHAN2G(2,  2417, 0),
  36	CHAN2G(3,  2422, 0),
  37	CHAN2G(4,  2427, 0),
  38	CHAN2G(5,  2432, 0),
  39	CHAN2G(6,  2437, 0),
  40	CHAN2G(7,  2442, 0),
  41	CHAN2G(8,  2447, 0),
  42	CHAN2G(9,  2452, 0),
  43	CHAN2G(10, 2457, 0),
  44	CHAN2G(11, 2462, 0),
  45	CHAN2G(12, 2467, 0),
  46	CHAN2G(13, 2472, 0),
  47	CHAN2G(14, 2484, 0),
  48};
  49
  50#define RATETAB_ENT(_rate, _hw_value, _flags) { \
  51	.bitrate  = (_rate),                    \
  52	.hw_value = (_hw_value),                \
  53	.flags    = (_flags),                   \
  54}
  55
  56
  57/* Table 6 in section 3.2.1.1 */
  58static struct ieee80211_rate lbs_rates[] = {
  59	RATETAB_ENT(10,  0,  0),
  60	RATETAB_ENT(20,  1,  0),
  61	RATETAB_ENT(55,  2,  0),
  62	RATETAB_ENT(110, 3,  0),
  63	RATETAB_ENT(60,  9,  0),
  64	RATETAB_ENT(90,  6,  0),
  65	RATETAB_ENT(120, 7,  0),
  66	RATETAB_ENT(180, 8,  0),
  67	RATETAB_ENT(240, 9,  0),
  68	RATETAB_ENT(360, 10, 0),
  69	RATETAB_ENT(480, 11, 0),
  70	RATETAB_ENT(540, 12, 0),
  71};
  72
  73static struct ieee80211_supported_band lbs_band_2ghz = {
  74	.channels = lbs_2ghz_channels,
  75	.n_channels = ARRAY_SIZE(lbs_2ghz_channels),
  76	.bitrates = lbs_rates,
  77	.n_bitrates = ARRAY_SIZE(lbs_rates),
  78};
  79
  80
  81static const u32 cipher_suites[] = {
  82	WLAN_CIPHER_SUITE_WEP40,
  83	WLAN_CIPHER_SUITE_WEP104,
  84	WLAN_CIPHER_SUITE_TKIP,
  85	WLAN_CIPHER_SUITE_CCMP,
  86};
  87
  88/* Time to stay on the channel */
  89#define LBS_DWELL_PASSIVE 100
  90#define LBS_DWELL_ACTIVE  40
  91
  92
  93/***************************************************************************
  94 * Misc utility functions
  95 *
  96 * TLVs are Marvell specific. They are very similar to IEs, they have the
  97 * same structure: type, length, data*. The only difference: for IEs, the
  98 * type and length are u8, but for TLVs they're __le16.
  99 */
 100
 101/*
 102 * Convert NL80211's auth_type to the one from Libertas, see chapter 5.9.1
 103 * in the firmware spec
 104 */
 105static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type)
 106{
 107	int ret = -ENOTSUPP;
 108
 109	switch (auth_type) {
 110	case NL80211_AUTHTYPE_OPEN_SYSTEM:
 111	case NL80211_AUTHTYPE_SHARED_KEY:
 112		ret = auth_type;
 113		break;
 114	case NL80211_AUTHTYPE_AUTOMATIC:
 115		ret = NL80211_AUTHTYPE_OPEN_SYSTEM;
 116		break;
 117	case NL80211_AUTHTYPE_NETWORK_EAP:
 118		ret = 0x80;
 119		break;
 120	default:
 121		/* silence compiler */
 122		break;
 123	}
 124	return ret;
 125}
 126
 127
 128/*
 129 * Various firmware commands need the list of supported rates, but with
 130 * the hight-bit set for basic rates
 131 */
 132static int lbs_add_rates(u8 *rates)
 133{
 134	size_t i;
 135
 136	for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) {
 137		u8 rate = lbs_rates[i].bitrate / 5;
 138		if (rate == 0x02 || rate == 0x04 ||
 139		    rate == 0x0b || rate == 0x16)
 140			rate |= 0x80;
 141		rates[i] = rate;
 142	}
 143	return ARRAY_SIZE(lbs_rates);
 144}
 145
 146
 147/***************************************************************************
 148 * TLV utility functions
 149 *
 150 * TLVs are Marvell specific. They are very similar to IEs, they have the
 151 * same structure: type, length, data*. The only difference: for IEs, the
 152 * type and length are u8, but for TLVs they're __le16.
 153 */
 154
 155
 156/*
 157 * Add ssid TLV
 158 */
 159#define LBS_MAX_SSID_TLV_SIZE			\
 160	(sizeof(struct mrvl_ie_header)		\
 161	 + IEEE80211_MAX_SSID_LEN)
 162
 163static int lbs_add_ssid_tlv(u8 *tlv, const u8 *ssid, int ssid_len)
 164{
 165	struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv;
 166
 167	/*
 168	 * TLV-ID SSID  00 00
 169	 * length       06 00
 170	 * ssid         4d 4e 54 45 53 54
 171	 */
 172	ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
 173	ssid_tlv->header.len = cpu_to_le16(ssid_len);
 174	memcpy(ssid_tlv->ssid, ssid, ssid_len);
 175	return sizeof(ssid_tlv->header) + ssid_len;
 176}
 177
 178
 179/*
 180 * Add channel list TLV (section 8.4.2)
 181 *
 182 * Actual channel data comes from priv->wdev->wiphy->channels.
 183 */
 184#define LBS_MAX_CHANNEL_LIST_TLV_SIZE					\
 185	(sizeof(struct mrvl_ie_header)					\
 186	 + (LBS_SCAN_BEFORE_NAP * sizeof(struct chanscanparamset)))
 187
 188static int lbs_add_channel_list_tlv(struct lbs_private *priv, u8 *tlv,
 189				    int last_channel, int active_scan)
 190{
 191	int chanscanparamsize = sizeof(struct chanscanparamset) *
 192		(last_channel - priv->scan_channel);
 193
 194	struct mrvl_ie_header *header = (void *) tlv;
 195
 196	/*
 197	 * TLV-ID CHANLIST  01 01
 198	 * length           0e 00
 199	 * channel          00 01 00 00 00 64 00
 200	 *   radio type     00
 201	 *   channel           01
 202	 *   scan type            00
 203	 *   min scan time           00 00
 204	 *   max scan time                 64 00
 205	 * channel 2        00 02 00 00 00 64 00
 206	 *
 207	 */
 208
 209	header->type = cpu_to_le16(TLV_TYPE_CHANLIST);
 210	header->len  = cpu_to_le16(chanscanparamsize);
 211	tlv += sizeof(struct mrvl_ie_header);
 212
 213	/* lbs_deb_scan("scan: channels %d to %d\n", priv->scan_channel,
 214		     last_channel); */
 215	memset(tlv, 0, chanscanparamsize);
 216
 217	while (priv->scan_channel < last_channel) {
 218		struct chanscanparamset *param = (void *) tlv;
 219
 220		param->radiotype = CMD_SCAN_RADIO_TYPE_BG;
 221		param->channumber =
 222			priv->scan_req->channels[priv->scan_channel]->hw_value;
 223		if (active_scan) {
 224			param->maxscantime = cpu_to_le16(LBS_DWELL_ACTIVE);
 225		} else {
 226			param->chanscanmode.passivescan = 1;
 227			param->maxscantime = cpu_to_le16(LBS_DWELL_PASSIVE);
 228		}
 229		tlv += sizeof(struct chanscanparamset);
 230		priv->scan_channel++;
 231	}
 232	return sizeof(struct mrvl_ie_header) + chanscanparamsize;
 233}
 234
 235
 236/*
 237 * Add rates TLV
 238 *
 239 * The rates are in lbs_bg_rates[], but for the 802.11b
 240 * rates the high bit is set. We add this TLV only because
 241 * there's a firmware which otherwise doesn't report all
 242 * APs in range.
 243 */
 244#define LBS_MAX_RATES_TLV_SIZE			\
 245	(sizeof(struct mrvl_ie_header)		\
 246	 + (ARRAY_SIZE(lbs_rates)))
 247
 248/* Adds a TLV with all rates the hardware supports */
 249static int lbs_add_supported_rates_tlv(u8 *tlv)
 250{
 251	size_t i;
 252	struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
 253
 254	/*
 255	 * TLV-ID RATES  01 00
 256	 * length        0e 00
 257	 * rates         82 84 8b 96 0c 12 18 24 30 48 60 6c
 258	 */
 259	rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
 260	tlv += sizeof(rate_tlv->header);
 261	i = lbs_add_rates(tlv);
 262	tlv += i;
 263	rate_tlv->header.len = cpu_to_le16(i);
 264	return sizeof(rate_tlv->header) + i;
 265}
 266
 267/* Add common rates from a TLV and return the new end of the TLV */
 268static u8 *
 269add_ie_rates(u8 *tlv, const u8 *ie, int *nrates)
 270{
 271	int hw, ap, ap_max = ie[1];
 272	u8 hw_rate;
 273
 274	/* Advance past IE header */
 275	ie += 2;
 276
 277	lbs_deb_hex(LBS_DEB_ASSOC, "AP IE Rates", (u8 *) ie, ap_max);
 278
 279	for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
 280		hw_rate = lbs_rates[hw].bitrate / 5;
 281		for (ap = 0; ap < ap_max; ap++) {
 282			if (hw_rate == (ie[ap] & 0x7f)) {
 283				*tlv++ = ie[ap];
 284				*nrates = *nrates + 1;
 285			}
 286		}
 287	}
 288	return tlv;
 289}
 290
 291/*
 292 * Adds a TLV with all rates the hardware *and* BSS supports.
 293 */
 294static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
 295{
 296	struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
 297	const u8 *rates_eid, *ext_rates_eid;
 298	int n = 0;
 299
 300	rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
 301	ext_rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
 302
 303	/*
 304	 * 01 00                   TLV_TYPE_RATES
 305	 * 04 00                   len
 306	 * 82 84 8b 96             rates
 307	 */
 308	rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
 309	tlv += sizeof(rate_tlv->header);
 310
 311	/* Add basic rates */
 312	if (rates_eid) {
 313		tlv = add_ie_rates(tlv, rates_eid, &n);
 314
 315		/* Add extended rates, if any */
 316		if (ext_rates_eid)
 317			tlv = add_ie_rates(tlv, ext_rates_eid, &n);
 318	} else {
 319		lbs_deb_assoc("assoc: bss had no basic rate IE\n");
 320		/* Fallback: add basic 802.11b rates */
 321		*tlv++ = 0x82;
 322		*tlv++ = 0x84;
 323		*tlv++ = 0x8b;
 324		*tlv++ = 0x96;
 325		n = 4;
 326	}
 327
 328	rate_tlv->header.len = cpu_to_le16(n);
 329	return sizeof(rate_tlv->header) + n;
 330}
 331
 332
 333/*
 334 * Add auth type TLV.
 335 *
 336 * This is only needed for newer firmware (V9 and up).
 337 */
 338#define LBS_MAX_AUTH_TYPE_TLV_SIZE \
 339	sizeof(struct mrvl_ie_auth_type)
 340
 341static int lbs_add_auth_type_tlv(u8 *tlv, enum nl80211_auth_type auth_type)
 342{
 343	struct mrvl_ie_auth_type *auth = (void *) tlv;
 344
 345	/*
 346	 * 1f 01  TLV_TYPE_AUTH_TYPE
 347	 * 01 00  len
 348	 * 01     auth type
 349	 */
 350	auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
 351	auth->header.len = cpu_to_le16(sizeof(*auth)-sizeof(auth->header));
 352	auth->auth = cpu_to_le16(lbs_auth_to_authtype(auth_type));
 353	return sizeof(*auth);
 354}
 355
 356
 357/*
 358 * Add channel (phy ds) TLV
 359 */
 360#define LBS_MAX_CHANNEL_TLV_SIZE \
 361	sizeof(struct mrvl_ie_header)
 362
 363static int lbs_add_channel_tlv(u8 *tlv, u8 channel)
 364{
 365	struct mrvl_ie_ds_param_set *ds = (void *) tlv;
 366
 367	/*
 368	 * 03 00  TLV_TYPE_PHY_DS
 369	 * 01 00  len
 370	 * 06     channel
 371	 */
 372	ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
 373	ds->header.len = cpu_to_le16(sizeof(*ds)-sizeof(ds->header));
 374	ds->channel = channel;
 375	return sizeof(*ds);
 376}
 377
 378
 379/*
 380 * Add (empty) CF param TLV of the form:
 381 */
 382#define LBS_MAX_CF_PARAM_TLV_SIZE		\
 383	sizeof(struct mrvl_ie_header)
 384
 385static int lbs_add_cf_param_tlv(u8 *tlv)
 386{
 387	struct mrvl_ie_cf_param_set *cf = (void *)tlv;
 388
 389	/*
 390	 * 04 00  TLV_TYPE_CF
 391	 * 06 00  len
 392	 * 00     cfpcnt
 393	 * 00     cfpperiod
 394	 * 00 00  cfpmaxduration
 395	 * 00 00  cfpdurationremaining
 396	 */
 397	cf->header.type = cpu_to_le16(TLV_TYPE_CF);
 398	cf->header.len = cpu_to_le16(sizeof(*cf)-sizeof(cf->header));
 399	return sizeof(*cf);
 400}
 401
 402/*
 403 * Add WPA TLV
 404 */
 405#define LBS_MAX_WPA_TLV_SIZE			\
 406	(sizeof(struct mrvl_ie_header)		\
 407	 + 128 /* TODO: I guessed the size */)
 408
 409static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
 410{
 411	size_t tlv_len;
 412
 413	/*
 414	 * We need just convert an IE to an TLV. IEs use u8 for the header,
 415	 *   u8      type
 416	 *   u8      len
 417	 *   u8[]    data
 418	 * but TLVs use __le16 instead:
 419	 *   __le16  type
 420	 *   __le16  len
 421	 *   u8[]    data
 422	 */
 423	*tlv++ = *ie++;
 424	*tlv++ = 0;
 425	tlv_len = *tlv++ = *ie++;
 426	*tlv++ = 0;
 427	while (tlv_len--)
 428		*tlv++ = *ie++;
 429	/* the TLV is two bytes larger than the IE */
 430	return ie_len + 2;
 431}
 432
 433/*
 434 * Set Channel
 435 */
 436
 437static int lbs_cfg_set_channel(struct wiphy *wiphy,
 438	struct net_device *netdev,
 439	struct ieee80211_channel *channel,
 440	enum nl80211_channel_type channel_type)
 441{
 442	struct lbs_private *priv = wiphy_priv(wiphy);
 443	int ret = -ENOTSUPP;
 444
 445	lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d",
 446			   channel->center_freq, channel_type);
 447
 448	if (channel_type != NL80211_CHAN_NO_HT)
 449		goto out;
 450
 451	ret = lbs_set_channel(priv, channel->hw_value);
 452
 453 out:
 454	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
 455	return ret;
 456}
 457
 458
 459
 460/*
 461 * Scanning
 462 */
 463
 464/*
 465 * When scanning, the firmware doesn't send a nul packet with the power-safe
 466 * bit to the AP. So we cannot stay away from our current channel too long,
 467 * otherwise we loose data. So take a "nap" while scanning every other
 468 * while.
 469 */
 470#define LBS_SCAN_BEFORE_NAP 4
 471
 472
 473/*
 474 * When the firmware reports back a scan-result, it gives us an "u8 rssi",
 475 * which isn't really an RSSI, as it becomes larger when moving away from
 476 * the AP. Anyway, we need to convert that into mBm.
 477 */
 478#define LBS_SCAN_RSSI_TO_MBM(rssi) \
 479	((-(int)rssi + 3)*100)
 480
 481static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
 482	struct cmd_header *resp)
 483{
 484	struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp;
 485	int bsssize;
 486	const u8 *pos;
 487	const u8 *tsfdesc;
 488	int tsfsize;
 489	int i;
 490	int ret = -EILSEQ;
 491
 492	lbs_deb_enter(LBS_DEB_CFG80211);
 493
 494	bsssize = get_unaligned_le16(&scanresp->bssdescriptsize);
 495
 496	lbs_deb_scan("scan response: %d BSSs (%d bytes); resp size %d bytes\n",
 497			scanresp->nr_sets, bsssize, le16_to_cpu(resp->size));
 498
 499	if (scanresp->nr_sets == 0) {
 500		ret = 0;
 501		goto done;
 502	}
 503
 504	/*
 505	 * The general layout of the scan response is described in chapter
 506	 * 5.7.1. Basically we have a common part, then any number of BSS
 507	 * descriptor sections. Finally we have section with the same number
 508	 * of TSFs.
 509	 *
 510	 * cmd_ds_802_11_scan_rsp
 511	 *   cmd_header
 512	 *   pos_size
 513	 *   nr_sets
 514	 *   bssdesc 1
 515	 *     bssid
 516	 *     rssi
 517	 *     timestamp
 518	 *     intvl
 519	 *     capa
 520	 *     IEs
 521	 *   bssdesc 2
 522	 *   bssdesc n
 523	 *   MrvlIEtypes_TsfFimestamp_t
 524	 *     TSF for BSS 1
 525	 *     TSF for BSS 2
 526	 *     TSF for BSS n
 527	 */
 528
 529	pos = scanresp->bssdesc_and_tlvbuffer;
 530
 531	lbs_deb_hex(LBS_DEB_SCAN, "SCAN_RSP", scanresp->bssdesc_and_tlvbuffer,
 532			scanresp->bssdescriptsize);
 533
 534	tsfdesc = pos + bsssize;
 535	tsfsize = 4 + 8 * scanresp->nr_sets;
 536	lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TSF", (u8 *) tsfdesc, tsfsize);
 537
 538	/* Validity check: we expect a Marvell-Local TLV */
 539	i = get_unaligned_le16(tsfdesc);
 540	tsfdesc += 2;
 541	if (i != TLV_TYPE_TSFTIMESTAMP) {
 542		lbs_deb_scan("scan response: invalid TSF Timestamp %d\n", i);
 543		goto done;
 544	}
 545
 546	/*
 547	 * Validity check: the TLV holds TSF values with 8 bytes each, so
 548	 * the size in the TLV must match the nr_sets value
 549	 */
 550	i = get_unaligned_le16(tsfdesc);
 551	tsfdesc += 2;
 552	if (i / 8 != scanresp->nr_sets) {
 553		lbs_deb_scan("scan response: invalid number of TSF timestamp "
 554			     "sets (expected %d got %d)\n", scanresp->nr_sets,
 555			     i / 8);
 556		goto done;
 557	}
 558
 559	for (i = 0; i < scanresp->nr_sets; i++) {
 560		const u8 *bssid;
 561		const u8 *ie;
 562		int left;
 563		int ielen;
 564		int rssi;
 565		u16 intvl;
 566		u16 capa;
 567		int chan_no = -1;
 568		const u8 *ssid = NULL;
 569		u8 ssid_len = 0;
 570		DECLARE_SSID_BUF(ssid_buf);
 571
 572		int len = get_unaligned_le16(pos);
 573		pos += 2;
 574
 575		/* BSSID */
 576		bssid = pos;
 577		pos += ETH_ALEN;
 578		/* RSSI */
 579		rssi = *pos++;
 580		/* Packet time stamp */
 581		pos += 8;
 582		/* Beacon interval */
 583		intvl = get_unaligned_le16(pos);
 584		pos += 2;
 585		/* Capabilities */
 586		capa = get_unaligned_le16(pos);
 587		pos += 2;
 588
 589		/* To find out the channel, we must parse the IEs */
 590		ie = pos;
 591		/*
 592		 * 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon
 593		 * interval, capabilities
 594		 */
 595		ielen = left = len - (6 + 1 + 8 + 2 + 2);
 596		while (left >= 2) {
 597			u8 id, elen;
 598			id = *pos++;
 599			elen = *pos++;
 600			left -= 2;
 601			if (elen > left || elen == 0) {
 602				lbs_deb_scan("scan response: invalid IE fmt\n");
 603				goto done;
 604			}
 605
 606			if (id == WLAN_EID_DS_PARAMS)
 607				chan_no = *pos;
 608			if (id == WLAN_EID_SSID) {
 609				ssid = pos;
 610				ssid_len = elen;
 611			}
 612			left -= elen;
 613			pos += elen;
 614		}
 615
 616		/* No channel, no luck */
 617		if (chan_no != -1) {
 618			struct wiphy *wiphy = priv->wdev->wiphy;
 619			int freq = ieee80211_channel_to_frequency(chan_no,
 620							IEEE80211_BAND_2GHZ);
 621			struct ieee80211_channel *channel =
 622				ieee80211_get_channel(wiphy, freq);
 623
 624			lbs_deb_scan("scan: %pM, capa %04x, chan %2d, %s, "
 625				     "%d dBm\n",
 626				     bssid, capa, chan_no,
 627				     print_ssid(ssid_buf, ssid, ssid_len),
 628				     LBS_SCAN_RSSI_TO_MBM(rssi)/100);
 629
 630			if (channel &&
 631			    !(channel->flags & IEEE80211_CHAN_DISABLED))
 632				cfg80211_inform_bss(wiphy, channel,
 633					bssid, le64_to_cpu(*(__le64 *)tsfdesc),
 634					capa, intvl, ie, ielen,
 635					LBS_SCAN_RSSI_TO_MBM(rssi),
 636					GFP_KERNEL);
 637		} else
 638			lbs_deb_scan("scan response: missing BSS channel IE\n");
 639
 640		tsfdesc += 8;
 641	}
 642	ret = 0;
 643
 644 done:
 645	lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
 646	return ret;
 647}
 648
 649
 650/*
 651 * Our scan command contains a TLV, consting of a SSID TLV, a channel list
 652 * TLV and a rates TLV. Determine the maximum size of them:
 653 */
 654#define LBS_SCAN_MAX_CMD_SIZE			\
 655	(sizeof(struct cmd_ds_802_11_scan)	\
 656	 + LBS_MAX_SSID_TLV_SIZE		\
 657	 + LBS_MAX_CHANNEL_LIST_TLV_SIZE	\
 658	 + LBS_MAX_RATES_TLV_SIZE)
 659
 660/*
 661 * Assumes priv->scan_req is initialized and valid
 662 * Assumes priv->scan_channel is initialized
 663 */
 664static void lbs_scan_worker(struct work_struct *work)
 665{
 666	struct lbs_private *priv =
 667		container_of(work, struct lbs_private, scan_work.work);
 668	struct cmd_ds_802_11_scan *scan_cmd;
 669	u8 *tlv; /* pointer into our current, growing TLV storage area */
 670	int last_channel;
 671	int running, carrier;
 672
 673	lbs_deb_enter(LBS_DEB_SCAN);
 674
 675	scan_cmd = kzalloc(LBS_SCAN_MAX_CMD_SIZE, GFP_KERNEL);
 676	if (scan_cmd == NULL)
 677		goto out_no_scan_cmd;
 678
 679	/* prepare fixed part of scan command */
 680	scan_cmd->bsstype = CMD_BSS_TYPE_ANY;
 681
 682	/* stop network while we're away from our main channel */
 683	running = !netif_queue_stopped(priv->dev);
 684	carrier = netif_carrier_ok(priv->dev);
 685	if (running)
 686		netif_stop_queue(priv->dev);
 687	if (carrier)
 688		netif_carrier_off(priv->dev);
 689
 690	/* prepare fixed part of scan command */
 691	tlv = scan_cmd->tlvbuffer;
 692
 693	/* add SSID TLV */
 694	if (priv->scan_req->n_ssids)
 695		tlv += lbs_add_ssid_tlv(tlv,
 696					priv->scan_req->ssids[0].ssid,
 697					priv->scan_req->ssids[0].ssid_len);
 698
 699	/* add channel TLVs */
 700	last_channel = priv->scan_channel + LBS_SCAN_BEFORE_NAP;
 701	if (last_channel > priv->scan_req->n_channels)
 702		last_channel = priv->scan_req->n_channels;
 703	tlv += lbs_add_channel_list_tlv(priv, tlv, last_channel,
 704		priv->scan_req->n_ssids);
 705
 706	/* add rates TLV */
 707	tlv += lbs_add_supported_rates_tlv(tlv);
 708
 709	if (priv->scan_channel < priv->scan_req->n_channels) {
 710		cancel_delayed_work(&priv->scan_work);
 711		if (!priv->stopping)
 712			queue_delayed_work(priv->work_thread, &priv->scan_work,
 713				msecs_to_jiffies(300));
 714	}
 715
 716	/* This is the final data we are about to send */
 717	scan_cmd->hdr.size = cpu_to_le16(tlv - (u8 *)scan_cmd);
 718	lbs_deb_hex(LBS_DEB_SCAN, "SCAN_CMD", (void *)scan_cmd,
 719		    sizeof(*scan_cmd));
 720	lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TLV", scan_cmd->tlvbuffer,
 721		    tlv - scan_cmd->tlvbuffer);
 722
 723	__lbs_cmd(priv, CMD_802_11_SCAN, &scan_cmd->hdr,
 724		le16_to_cpu(scan_cmd->hdr.size),
 725		lbs_ret_scan, 0);
 726
 727	if (priv->scan_channel >= priv->scan_req->n_channels) {
 728		/* Mark scan done */
 729		if (priv->internal_scan)
 730			kfree(priv->scan_req);
 731		else
 732			cfg80211_scan_done(priv->scan_req, false);
 733
 734		priv->scan_req = NULL;
 735		priv->last_scan = jiffies;
 736	}
 737
 738	/* Restart network */
 739	if (carrier)
 740		netif_carrier_on(priv->dev);
 741	if (running && !priv->tx_pending_len)
 742		netif_wake_queue(priv->dev);
 743
 744	kfree(scan_cmd);
 745
 746	/* Wake up anything waiting on scan completion */
 747	if (priv->scan_req == NULL) {
 748		lbs_deb_scan("scan: waking up waiters\n");
 749		wake_up_all(&priv->scan_q);
 750	}
 751
 752 out_no_scan_cmd:
 753	lbs_deb_leave(LBS_DEB_SCAN);
 754}
 755
 756static void _internal_start_scan(struct lbs_private *priv, bool internal,
 757	struct cfg80211_scan_request *request)
 758{
 759	lbs_deb_enter(LBS_DEB_CFG80211);
 760
 761	lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n",
 762		request->n_ssids, request->n_channels, request->ie_len);
 763
 764	priv->scan_channel = 0;
 765	queue_delayed_work(priv->work_thread, &priv->scan_work,
 766		msecs_to_jiffies(50));
 767
 768	priv->scan_req = request;
 769	priv->internal_scan = internal;
 770
 771	lbs_deb_leave(LBS_DEB_CFG80211);
 772}
 773
 774static int lbs_cfg_scan(struct wiphy *wiphy,
 775	struct net_device *dev,
 776	struct cfg80211_scan_request *request)
 777{
 778	struct lbs_private *priv = wiphy_priv(wiphy);
 779	int ret = 0;
 780
 781	lbs_deb_enter(LBS_DEB_CFG80211);
 782
 783	if (priv->scan_req || delayed_work_pending(&priv->scan_work)) {
 784		/* old scan request not yet processed */
 785		ret = -EAGAIN;
 786		goto out;
 787	}
 788
 789	_internal_start_scan(priv, false, request);
 790
 791	if (priv->surpriseremoved)
 792		ret = -EIO;
 793
 794 out:
 795	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
 796	return ret;
 797}
 798
 799
 800
 801
 802/*
 803 * Events
 804 */
 805
 806void lbs_send_disconnect_notification(struct lbs_private *priv)
 807{
 808	lbs_deb_enter(LBS_DEB_CFG80211);
 809
 810	cfg80211_disconnected(priv->dev,
 811		0,
 812		NULL, 0,
 813		GFP_KERNEL);
 814
 815	lbs_deb_leave(LBS_DEB_CFG80211);
 816}
 817
 818void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event)
 819{
 820	lbs_deb_enter(LBS_DEB_CFG80211);
 821
 822	cfg80211_michael_mic_failure(priv->dev,
 823		priv->assoc_bss,
 824		event == MACREG_INT_CODE_MIC_ERR_MULTICAST ?
 825			NL80211_KEYTYPE_GROUP :
 826			NL80211_KEYTYPE_PAIRWISE,
 827		-1,
 828		NULL,
 829		GFP_KERNEL);
 830
 831	lbs_deb_leave(LBS_DEB_CFG80211);
 832}
 833
 834
 835
 836
 837/*
 838 * Connect/disconnect
 839 */
 840
 841
 842/*
 843 * This removes all WEP keys
 844 */
 845static int lbs_remove_wep_keys(struct lbs_private *priv)
 846{
 847	struct cmd_ds_802_11_set_wep cmd;
 848	int ret;
 849
 850	lbs_deb_enter(LBS_DEB_CFG80211);
 851
 852	memset(&cmd, 0, sizeof(cmd));
 853	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
 854	cmd.keyindex = cpu_to_le16(priv->wep_tx_key);
 855	cmd.action = cpu_to_le16(CMD_ACT_REMOVE);
 856
 857	ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
 858
 859	lbs_deb_leave(LBS_DEB_CFG80211);
 860	return ret;
 861}
 862
 863/*
 864 * Set WEP keys
 865 */
 866static int lbs_set_wep_keys(struct lbs_private *priv)
 867{
 868	struct cmd_ds_802_11_set_wep cmd;
 869	int i;
 870	int ret;
 871
 872	lbs_deb_enter(LBS_DEB_CFG80211);
 873
 874	/*
 875	 * command         13 00
 876	 * size            50 00
 877	 * sequence        xx xx
 878	 * result          00 00
 879	 * action          02 00     ACT_ADD
 880	 * transmit key    00 00
 881	 * type for key 1  01        WEP40
 882	 * type for key 2  00
 883	 * type for key 3  00
 884	 * type for key 4  00
 885	 * key 1           39 39 39 39 39 00 00 00
 886	 *                 00 00 00 00 00 00 00 00
 887	 * key 2           00 00 00 00 00 00 00 00
 888	 *                 00 00 00 00 00 00 00 00
 889	 * key 3           00 00 00 00 00 00 00 00
 890	 *                 00 00 00 00 00 00 00 00
 891	 * key 4           00 00 00 00 00 00 00 00
 892	 */
 893	if (priv->wep_key_len[0] || priv->wep_key_len[1] ||
 894	    priv->wep_key_len[2] || priv->wep_key_len[3]) {
 895		/* Only set wep keys if we have at least one of them */
 896		memset(&cmd, 0, sizeof(cmd));
 897		cmd.hdr.size = cpu_to_le16(sizeof(cmd));
 898		cmd.keyindex = cpu_to_le16(priv->wep_tx_key);
 899		cmd.action = cpu_to_le16(CMD_ACT_ADD);
 900
 901		for (i = 0; i < 4; i++) {
 902			switch (priv->wep_key_len[i]) {
 903			case WLAN_KEY_LEN_WEP40:
 904				cmd.keytype[i] = CMD_TYPE_WEP_40_BIT;
 905				break;
 906			case WLAN_KEY_LEN_WEP104:
 907				cmd.keytype[i] = CMD_TYPE_WEP_104_BIT;
 908				break;
 909			default:
 910				cmd.keytype[i] = 0;
 911				break;
 912			}
 913			memcpy(cmd.keymaterial[i], priv->wep_key[i],
 914			       priv->wep_key_len[i]);
 915		}
 916
 917		ret = lbs_cmd_with_response(priv, CMD_802_11_SET_WEP, &cmd);
 918	} else {
 919		/* Otherwise remove all wep keys */
 920		ret = lbs_remove_wep_keys(priv);
 921	}
 922
 923	lbs_deb_leave(LBS_DEB_CFG80211);
 924	return ret;
 925}
 926
 927
 928/*
 929 * Enable/Disable RSN status
 930 */
 931static int lbs_enable_rsn(struct lbs_private *priv, int enable)
 932{
 933	struct cmd_ds_802_11_enable_rsn cmd;
 934	int ret;
 935
 936	lbs_deb_enter_args(LBS_DEB_CFG80211, "%d", enable);
 937
 938	/*
 939	 * cmd       2f 00
 940	 * size      0c 00
 941	 * sequence  xx xx
 942	 * result    00 00
 943	 * action    01 00    ACT_SET
 944	 * enable    01 00
 945	 */
 946	memset(&cmd, 0, sizeof(cmd));
 947	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
 948	cmd.action = cpu_to_le16(CMD_ACT_SET);
 949	cmd.enable = cpu_to_le16(enable);
 950
 951	ret = lbs_cmd_with_response(priv, CMD_802_11_ENABLE_RSN, &cmd);
 952
 953	lbs_deb_leave(LBS_DEB_CFG80211);
 954	return ret;
 955}
 956
 957
 958/*
 959 * Set WPA/WPA key material
 960 */
 961
 962/*
 963 * like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we
 964 * get rid of WEXT, this should go into host.h
 965 */
 966
 967struct cmd_key_material {
 968	struct cmd_header hdr;
 969
 970	__le16 action;
 971	struct MrvlIEtype_keyParamSet param;
 972} __packed;
 973
 974static int lbs_set_key_material(struct lbs_private *priv,
 975				int key_type,
 976				int key_info,
 977				u8 *key, u16 key_len)
 978{
 979	struct cmd_key_material cmd;
 980	int ret;
 981
 982	lbs_deb_enter(LBS_DEB_CFG80211);
 983
 984	/*
 985	 * Example for WPA (TKIP):
 986	 *
 987	 * cmd       5e 00
 988	 * size      34 00
 989	 * sequence  xx xx
 990	 * result    00 00
 991	 * action    01 00
 992	 * TLV type  00 01    key param
 993	 * length    00 26
 994	 * key type  01 00    TKIP
 995	 * key info  06 00    UNICAST | ENABLED
 996	 * key len   20 00
 997	 * key       32 bytes
 998	 */
 999	memset(&cmd, 0, sizeof(cmd));
1000	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1001	cmd.action = cpu_to_le16(CMD_ACT_SET);
1002	cmd.param.type = cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
1003	cmd.param.length = cpu_to_le16(sizeof(cmd.param) - 4);
1004	cmd.param.keytypeid = cpu_to_le16(key_type);
1005	cmd.param.keyinfo = cpu_to_le16(key_info);
1006	cmd.param.keylen = cpu_to_le16(key_len);
1007	if (key && key_len)
1008		memcpy(cmd.param.key, key, key_len);
1009
1010	ret = lbs_cmd_with_response(priv, CMD_802_11_KEY_MATERIAL, &cmd);
1011
1012	lbs_deb_leave(LBS_DEB_CFG80211);
1013	return ret;
1014}
1015
1016
1017/*
1018 * Sets the auth type (open, shared, etc) in the firmware. That
1019 * we use CMD_802_11_AUTHENTICATE is misleading, this firmware
1020 * command doesn't send an authentication frame at all, it just
1021 * stores the auth_type.
1022 */
1023static int lbs_set_authtype(struct lbs_private *priv,
1024			    struct cfg80211_connect_params *sme)
1025{
1026	struct cmd_ds_802_11_authenticate cmd;
1027	int ret;
1028
1029	lbs_deb_enter_args(LBS_DEB_CFG80211, "%d", sme->auth_type);
1030
1031	/*
1032	 * cmd        11 00
1033	 * size       19 00
1034	 * sequence   xx xx
1035	 * result     00 00
1036	 * BSS id     00 13 19 80 da 30
1037	 * auth type  00
1038	 * reserved   00 00 00 00 00 00 00 00 00 00
1039	 */
1040	memset(&cmd, 0, sizeof(cmd));
1041	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1042	if (sme->bssid)
1043		memcpy(cmd.bssid, sme->bssid, ETH_ALEN);
1044	/* convert auth_type */
1045	ret = lbs_auth_to_authtype(sme->auth_type);
1046	if (ret < 0)
1047		goto done;
1048
1049	cmd.authtype = ret;
1050	ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd);
1051
1052 done:
1053	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1054	return ret;
1055}
1056
1057
1058/*
1059 * Create association request
1060 */
1061#define LBS_ASSOC_MAX_CMD_SIZE                     \
1062	(sizeof(struct cmd_ds_802_11_associate)    \
1063	 - 512 /* cmd_ds_802_11_associate.iebuf */ \
1064	 + LBS_MAX_SSID_TLV_SIZE                   \
1065	 + LBS_MAX_CHANNEL_TLV_SIZE                \
1066	 + LBS_MAX_CF_PARAM_TLV_SIZE               \
1067	 + LBS_MAX_AUTH_TYPE_TLV_SIZE              \
1068	 + LBS_MAX_WPA_TLV_SIZE)
1069
1070static int lbs_associate(struct lbs_private *priv,
1071		struct cfg80211_bss *bss,
1072		struct cfg80211_connect_params *sme)
1073{
1074	struct cmd_ds_802_11_associate_response *resp;
1075	struct cmd_ds_802_11_associate *cmd = kzalloc(LBS_ASSOC_MAX_CMD_SIZE,
1076						      GFP_KERNEL);
1077	const u8 *ssid_eid;
1078	size_t len, resp_ie_len;
1079	int status;
1080	int ret;
1081	u8 *pos = &(cmd->iebuf[0]);
1082	u8 *tmp;
1083
1084	lbs_deb_enter(LBS_DEB_CFG80211);
1085
1086	if (!cmd) {
1087		ret = -ENOMEM;
1088		goto done;
1089	}
1090
1091	/*
1092	 * cmd              50 00
1093	 * length           34 00
1094	 * sequence         xx xx
1095	 * result           00 00
1096	 * BSS id           00 13 19 80 da 30
1097	 * capabilities     11 00
1098	 * listen interval  0a 00
1099	 * beacon interval  00 00
1100	 * DTIM period      00
1101	 * TLVs             xx   (up to 512 bytes)
1102	 */
1103	cmd->hdr.command = cpu_to_le16(CMD_802_11_ASSOCIATE);
1104
1105	/* Fill in static fields */
1106	memcpy(cmd->bssid, bss->bssid, ETH_ALEN);
1107	cmd->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
1108	cmd->capability = cpu_to_le16(bss->capability);
1109
1110	/* add SSID TLV */
1111	ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
1112	if (ssid_eid)
1113		pos += lbs_add_ssid_tlv(pos, ssid_eid + 2, ssid_eid[1]);
1114	else
1115		lbs_deb_assoc("no SSID\n");
1116
1117	/* add DS param TLV */
1118	if (bss->channel)
1119		pos += lbs_add_channel_tlv(pos, bss->channel->hw_value);
1120	else
1121		lbs_deb_assoc("no channel\n");
1122
1123	/* add (empty) CF param TLV */
1124	pos += lbs_add_cf_param_tlv(pos);
1125
1126	/* add rates TLV */
1127	tmp = pos + 4; /* skip Marvell IE header */
1128	pos += lbs_add_common_rates_tlv(pos, bss);
1129	lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp);
1130
1131	/* add auth type TLV */
1132	if (MRVL_FW_MAJOR_REV(priv->fwrelease) >= 9)
1133		pos += lbs_add_auth_type_tlv(pos, sme->auth_type);
1134
1135	/* add WPA/WPA2 TLV */
1136	if (sme->ie && sme->ie_len)
1137		pos += lbs_add_wpa_tlv(pos, sme->ie, sme->ie_len);
1138
1139	len = (sizeof(*cmd) - sizeof(cmd->iebuf)) +
1140		(u16)(pos - (u8 *) &cmd->iebuf);
1141	cmd->hdr.size = cpu_to_le16(len);
1142
1143	lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_CMD", (u8 *) cmd,
1144			le16_to_cpu(cmd->hdr.size));
1145
1146	/* store for later use */
1147	memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN);
1148
1149	ret = lbs_cmd_with_response(priv, CMD_802_11_ASSOCIATE, cmd);
1150	if (ret)
1151		goto done;
1152
1153	/* generate connect message to cfg80211 */
1154
1155	resp = (void *) cmd; /* recast for easier field access */
1156	status = le16_to_cpu(resp->statuscode);
1157
1158	/* Older FW versions map the IEEE 802.11 Status Code in the association
1159	 * response to the following values returned in resp->statuscode:
1160	 *
1161	 *    IEEE Status Code                Marvell Status Code
1162	 *    0                       ->      0x0000 ASSOC_RESULT_SUCCESS
1163	 *    13                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
1164	 *    14                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
1165	 *    15                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
1166	 *    16                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
1167	 *    others                  ->      0x0003 ASSOC_RESULT_REFUSED
1168	 *
1169	 * Other response codes:
1170	 *    0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
1171	 *    0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
1172	 *                                    association response from the AP)
1173	 */
1174	if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
1175		switch (status) {
1176		case 0:
1177			break;
1178		case 1:
1179			lbs_deb_assoc("invalid association parameters\n");
1180			status = WLAN_STATUS_CAPS_UNSUPPORTED;
1181			break;
1182		case 2:
1183			lbs_deb_assoc("timer expired while waiting for AP\n");
1184			status = WLAN_STATUS_AUTH_TIMEOUT;
1185			break;
1186		case 3:
1187			lbs_deb_assoc("association refused by AP\n");
1188			status = WLAN_STATUS_ASSOC_DENIED_UNSPEC;
1189			break;
1190		case 4:
1191			lbs_deb_assoc("authentication refused by AP\n");
1192			status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1193			break;
1194		default:
1195			lbs_deb_assoc("association failure %d\n", status);
1196			/* v5 OLPC firmware does return the AP status code if
1197			 * it's not one of the values above.  Let that through.
1198			 */
1199			break;
1200		}
1201	}
1202
1203	lbs_deb_assoc("status %d, statuscode 0x%04x, capability 0x%04x, "
1204		      "aid 0x%04x\n", status, le16_to_cpu(resp->statuscode),
1205		      le16_to_cpu(resp->capability), le16_to_cpu(resp->aid));
1206
1207	resp_ie_len = le16_to_cpu(resp->hdr.size)
1208		- sizeof(resp->hdr)
1209		- 6;
1210	cfg80211_connect_result(priv->dev,
1211				priv->assoc_bss,
1212				sme->ie, sme->ie_len,
1213				resp->iebuf, resp_ie_len,
1214				status,
1215				GFP_KERNEL);
1216
1217	if (status == 0) {
1218		/* TODO: get rid of priv->connect_status */
1219		priv->connect_status = LBS_CONNECTED;
1220		netif_carrier_on(priv->dev);
1221		if (!priv->tx_pending_len)
1222			netif_tx_wake_all_queues(priv->dev);
1223	}
1224
1225done:
1226	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1227	return ret;
1228}
1229
1230static struct cfg80211_scan_request *
1231_new_connect_scan_req(struct wiphy *wiphy, struct cfg80211_connect_params *sme)
1232{
1233	struct cfg80211_scan_request *creq = NULL;
1234	int i, n_channels = 0;
1235	enum ieee80211_band band;
1236
1237	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1238		if (wiphy->bands[band])
1239			n_channels += wiphy->bands[band]->n_channels;
1240	}
1241
1242	creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
1243		       n_channels * sizeof(void *),
1244		       GFP_ATOMIC);
1245	if (!creq)
1246		return NULL;
1247
1248	/* SSIDs come after channels */
1249	creq->ssids = (void *)&creq->channels[n_channels];
1250	creq->n_channels = n_channels;
1251	creq->n_ssids = 1;
1252
1253	/* Scan all available channels */
1254	i = 0;
1255	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1256		int j;
1257
1258		if (!wiphy->bands[band])
1259			continue;
1260
1261		for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
1262			/* ignore disabled channels */
1263			if (wiphy->bands[band]->channels[j].flags &
1264						IEEE80211_CHAN_DISABLED)
1265				continue;
1266
1267			creq->channels[i] = &wiphy->bands[band]->channels[j];
1268			i++;
1269		}
1270	}
1271	if (i) {
1272		/* Set real number of channels specified in creq->channels[] */
1273		creq->n_channels = i;
1274
1275		/* Scan for the SSID we're going to connect to */
1276		memcpy(creq->ssids[0].ssid, sme->ssid, sme->ssid_len);
1277		creq->ssids[0].ssid_len = sme->ssid_len;
1278	} else {
1279		/* No channels found... */
1280		kfree(creq);
1281		creq = NULL;
1282	}
1283
1284	return creq;
1285}
1286
1287static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
1288			   struct cfg80211_connect_params *sme)
1289{
1290	struct lbs_private *priv = wiphy_priv(wiphy);
1291	struct cfg80211_bss *bss = NULL;
1292	int ret = 0;
1293	u8 preamble = RADIO_PREAMBLE_SHORT;
1294
1295	lbs_deb_enter(LBS_DEB_CFG80211);
1296
1297	if (!sme->bssid) {
1298		/* Run a scan if one isn't in-progress already and if the last
1299		 * scan was done more than 2 seconds ago.
1300		 */
1301		if (priv->scan_req == NULL &&
1302		    time_after(jiffies, priv->last_scan + (2 * HZ))) {
1303			struct cfg80211_scan_request *creq;
1304
1305			creq = _new_connect_scan_req(wiphy, sme);
1306			if (!creq) {
1307				ret = -EINVAL;
1308				goto done;
1309			}
1310
1311			lbs_deb_assoc("assoc: scanning for compatible AP\n");
1312			_internal_start_scan(priv, true, creq);
1313		}
1314
1315		/* Wait for any in-progress scan to complete */
1316		lbs_deb_assoc("assoc: waiting for scan to complete\n");
1317		wait_event_interruptible_timeout(priv->scan_q,
1318						 (priv->scan_req == NULL),
1319						 (15 * HZ));
1320		lbs_deb_assoc("assoc: scanning competed\n");
1321	}
1322
1323	/* Find the BSS we want using available scan results */
1324	bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
1325		sme->ssid, sme->ssid_len,
1326		WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
1327	if (!bss) {
1328		wiphy_err(wiphy, "assoc: bss %pM not in scan results\n",
1329			  sme->bssid);
1330		ret = -ENOENT;
1331		goto done;
1332	}
1333	lbs_deb_assoc("trying %pM\n", bss->bssid);
1334	lbs_deb_assoc("cipher 0x%x, key index %d, key len %d\n",
1335		      sme->crypto.cipher_group,
1336		      sme->key_idx, sme->key_len);
1337
1338	/* As this is a new connection, clear locally stored WEP keys */
1339	priv->wep_tx_key = 0;
1340	memset(priv->wep_key, 0, sizeof(priv->wep_key));
1341	memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1342
1343	/* set/remove WEP keys */
1344	switch (sme->crypto.cipher_group) {
1345	case WLAN_CIPHER_SUITE_WEP40:
1346	case WLAN_CIPHER_SUITE_WEP104:
1347		/* Store provided WEP keys in priv-> */
1348		priv->wep_tx_key = sme->key_idx;
1349		priv->wep_key_len[sme->key_idx] = sme->key_len;
1350		memcpy(priv->wep_key[sme->key_idx], sme->key, sme->key_len);
1351		/* Set WEP keys and WEP mode */
1352		lbs_set_wep_keys(priv);
1353		priv->mac_control |= CMD_ACT_MAC_WEP_ENABLE;
1354		lbs_set_mac_control(priv);
1355		/* No RSN mode for WEP */
1356		lbs_enable_rsn(priv, 0);
1357		break;
1358	case 0: /* there's no WLAN_CIPHER_SUITE_NONE definition */
1359		/*
1360		 * If we don't have no WEP, no WPA and no WPA2,
1361		 * we remove all keys like in the WPA/WPA2 setup,
1362		 * we just don't set RSN.
1363		 *
1364		 * Therefore: fall-through
1365		 */
1366	case WLAN_CIPHER_SUITE_TKIP:
1367	case WLAN_CIPHER_SUITE_CCMP:
1368		/* Remove WEP keys and WEP mode */
1369		lbs_remove_wep_keys(priv);
1370		priv->mac_control &= ~CMD_ACT_MAC_WEP_ENABLE;
1371		lbs_set_mac_control(priv);
1372
1373		/* clear the WPA/WPA2 keys */
1374		lbs_set_key_material(priv,
1375			KEY_TYPE_ID_WEP, /* doesn't matter */
1376			KEY_INFO_WPA_UNICAST,
1377			NULL, 0);
1378		lbs_set_key_material(priv,
1379			KEY_TYPE_ID_WEP, /* doesn't matter */
1380			KEY_INFO_WPA_MCAST,
1381			NULL, 0);
1382		/* RSN mode for WPA/WPA2 */
1383		lbs_enable_rsn(priv, sme->crypto.cipher_group != 0);
1384		break;
1385	default:
1386		wiphy_err(wiphy, "unsupported cipher group 0x%x\n",
1387			  sme->crypto.cipher_group);
1388		ret = -ENOTSUPP;
1389		goto done;
1390	}
1391
1392	lbs_set_authtype(priv, sme);
1393	lbs_set_radio(priv, preamble, 1);
1394
1395	/* Do the actual association */
1396	ret = lbs_associate(priv, bss, sme);
1397
1398 done:
1399	if (bss)
1400		cfg80211_put_bss(bss);
1401	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1402	return ret;
1403}
1404
1405static int lbs_cfg_disconnect(struct wiphy *wiphy, struct net_device *dev,
1406	u16 reason_code)
1407{
1408	struct lbs_private *priv = wiphy_priv(wiphy);
1409	struct cmd_ds_802_11_deauthenticate cmd;
1410
1411	lbs_deb_enter_args(LBS_DEB_CFG80211, "reason_code %d", reason_code);
1412
1413	/* store for lbs_cfg_ret_disconnect() */
1414	priv->disassoc_reason = reason_code;
1415
1416	memset(&cmd, 0, sizeof(cmd));
1417	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1418	/* Mildly ugly to use a locally store my own BSSID ... */
1419	memcpy(cmd.macaddr, &priv->assoc_bss, ETH_ALEN);
1420	cmd.reasoncode = cpu_to_le16(reason_code);
1421
1422	if (lbs_cmd_with_response(priv, CMD_802_11_DEAUTHENTICATE, &cmd))
1423		return -EFAULT;
1424
1425	cfg80211_disconnected(priv->dev,
1426			priv->disassoc_reason,
1427			NULL, 0,
1428			GFP_KERNEL);
1429	priv->connect_status = LBS_DISCONNECTED;
1430
1431	return 0;
1432}
1433
1434
1435static int lbs_cfg_set_default_key(struct wiphy *wiphy,
1436				   struct net_device *netdev,
1437				   u8 key_index, bool unicast,
1438				   bool multicast)
1439{
1440	struct lbs_private *priv = wiphy_priv(wiphy);
1441
1442	lbs_deb_enter(LBS_DEB_CFG80211);
1443
1444	if (key_index != priv->wep_tx_key) {
1445		lbs_deb_assoc("set_default_key: to %d\n", key_index);
1446		priv->wep_tx_key = key_index;
1447		lbs_set_wep_keys(priv);
1448	}
1449
1450	return 0;
1451}
1452
1453
1454static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev,
1455			   u8 idx, bool pairwise, const u8 *mac_addr,
1456			   struct key_params *params)
1457{
1458	struct lbs_private *priv = wiphy_priv(wiphy);
1459	u16 key_info;
1460	u16 key_type;
1461	int ret = 0;
1462
1463	lbs_deb_enter(LBS_DEB_CFG80211);
1464
1465	lbs_deb_assoc("add_key: cipher 0x%x, mac_addr %pM\n",
1466		      params->cipher, mac_addr);
1467	lbs_deb_assoc("add_key: key index %d, key len %d\n",
1468		      idx, params->key_len);
1469	if (params->key_len)
1470		lbs_deb_hex(LBS_DEB_CFG80211, "KEY",
1471			    params->key, params->key_len);
1472
1473	lbs_deb_assoc("add_key: seq len %d\n", params->seq_len);
1474	if (params->seq_len)
1475		lbs_deb_hex(LBS_DEB_CFG80211, "SEQ",
1476			    params->seq, params->seq_len);
1477
1478	switch (params->cipher) {
1479	case WLAN_CIPHER_SUITE_WEP40:
1480	case WLAN_CIPHER_SUITE_WEP104:
1481		/* actually compare if something has changed ... */
1482		if ((priv->wep_key_len[idx] != params->key_len) ||
1483			memcmp(priv->wep_key[idx],
1484			       params->key, params->key_len) != 0) {
1485			priv->wep_key_len[idx] = params->key_len;
1486			memcpy(priv->wep_key[idx],
1487			       params->key, params->key_len);
1488			lbs_set_wep_keys(priv);
1489		}
1490		break;
1491	case WLAN_CIPHER_SUITE_TKIP:
1492	case WLAN_CIPHER_SUITE_CCMP:
1493		key_info = KEY_INFO_WPA_ENABLED | ((idx == 0)
1494						   ? KEY_INFO_WPA_UNICAST
1495						   : KEY_INFO_WPA_MCAST);
1496		key_type = (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1497			? KEY_TYPE_ID_TKIP
1498			: KEY_TYPE_ID_AES;
1499		lbs_set_key_material(priv,
1500				     key_type,
1501				     key_info,
1502				     params->key, params->key_len);
1503		break;
1504	default:
1505		wiphy_err(wiphy, "unhandled cipher 0x%x\n", params->cipher);
1506		ret = -ENOTSUPP;
1507		break;
1508	}
1509
1510	return ret;
1511}
1512
1513
1514static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev,
1515			   u8 key_index, bool pairwise, const u8 *mac_addr)
1516{
1517
1518	lbs_deb_enter(LBS_DEB_CFG80211);
1519
1520	lbs_deb_assoc("del_key: key_idx %d, mac_addr %pM\n",
1521		      key_index, mac_addr);
1522
1523#ifdef TODO
1524	struct lbs_private *priv = wiphy_priv(wiphy);
1525	/*
1526	 * I think can keep this a NO-OP, because:
1527
1528	 * - we clear all keys whenever we do lbs_cfg_connect() anyway
1529	 * - neither "iw" nor "wpa_supplicant" won't call this during
1530	 *   an ongoing connection
1531	 * - TODO: but I have to check if this is still true when
1532	 *   I set the AP to periodic re-keying
1533	 * - we've not kzallec() something when we've added a key at
1534	 *   lbs_cfg_connect() or lbs_cfg_add_key().
1535	 *
1536	 * This causes lbs_cfg_del_key() only called at disconnect time,
1537	 * where we'd just waste time deleting a key that is not going
1538	 * to be used anyway.
1539	 */
1540	if (key_index < 3 && priv->wep_key_len[key_index]) {
1541		priv->wep_key_len[key_index] = 0;
1542		lbs_set_wep_keys(priv);
1543	}
1544#endif
1545
1546	return 0;
1547}
1548
1549
1550/*
1551 * Get station
1552 */
1553
1554static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
1555			      u8 *mac, struct station_info *sinfo)
1556{
1557	struct lbs_private *priv = wiphy_priv(wiphy);
1558	s8 signal, noise;
1559	int ret;
1560	size_t i;
1561
1562	lbs_deb_enter(LBS_DEB_CFG80211);
1563
1564	sinfo->filled |= STATION_INFO_TX_BYTES |
1565			 STATION_INFO_TX_PACKETS |
1566			 STATION_INFO_RX_BYTES |
1567			 STATION_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 |= STATION_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 |= STATION_INFO_TX_BITRATE;
1585			break;
1586		}
1587	}
1588
1589	return 0;
1590}
1591
1592
1593
1594
1595/*
1596 * "Site survey", here just current channel and noise level
1597 */
1598
1599static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev,
1600	int idx, struct survey_info *survey)
1601{
1602	struct lbs_private *priv = wiphy_priv(wiphy);
1603	s8 signal, noise;
1604	int ret;
1605
1606	if (idx != 0)
1607		ret = -ENOENT;
1608
1609	lbs_deb_enter(LBS_DEB_CFG80211);
1610
1611	survey->channel = ieee80211_get_channel(wiphy,
1612		ieee80211_channel_to_frequency(priv->channel,
1613					       IEEE80211_BAND_2GHZ));
1614
1615	ret = lbs_get_rssi(priv, &signal, &noise);
1616	if (ret == 0) {
1617		survey->filled = SURVEY_INFO_NOISE_DBM;
1618		survey->noise = noise;
1619	}
1620
1621	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1622	return ret;
1623}
1624
1625
1626
1627
1628/*
1629 * Change interface
1630 */
1631
1632static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,
1633	enum nl80211_iftype type, u32 *flags,
1634	       struct vif_params *params)
1635{
1636	struct lbs_private *priv = wiphy_priv(wiphy);
1637	int ret = 0;
1638
1639	lbs_deb_enter(LBS_DEB_CFG80211);
1640
1641	switch (type) {
1642	case NL80211_IFTYPE_MONITOR:
1643		ret = lbs_set_monitor_mode(priv, 1);
1644		break;
1645	case NL80211_IFTYPE_STATION:
1646		if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
1647			ret = lbs_set_monitor_mode(priv, 0);
1648		if (!ret)
1649			ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1);
1650		break;
1651	case NL80211_IFTYPE_ADHOC:
1652		if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
1653			ret = lbs_set_monitor_mode(priv, 0);
1654		if (!ret)
1655			ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2);
1656		break;
1657	default:
1658		ret = -ENOTSUPP;
1659	}
1660
1661	if (!ret)
1662		priv->wdev->iftype = type;
1663
1664	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1665	return ret;
1666}
1667
1668
1669
1670/*
1671 * IBSS (Ad-Hoc)
1672 */
1673
1674/*
1675 * The firmware needs the following bits masked out of the beacon-derived
1676 * capability field when associating/joining to a BSS:
1677 *  9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused)
1678 */
1679#define CAPINFO_MASK (~(0xda00))
1680
1681
1682static void lbs_join_post(struct lbs_private *priv,
1683			  struct cfg80211_ibss_params *params,
1684			  u8 *bssid, u16 capability)
1685{
1686	u8 fake_ie[2 + IEEE80211_MAX_SSID_LEN + /* ssid */
1687		   2 + 4 +                      /* basic rates */
1688		   2 + 1 +                      /* DS parameter */
1689		   2 + 2 +                      /* atim */
1690		   2 + 8];                      /* extended rates */
1691	u8 *fake = fake_ie;
1692
1693	lbs_deb_enter(LBS_DEB_CFG80211);
1694
1695	/*
1696	 * For cfg80211_inform_bss, we'll need a fake IE, as we can't get
1697	 * the real IE from the firmware. So we fabricate a fake IE based on
1698	 * what the firmware actually sends (sniffed with wireshark).
1699	 */
1700	/* Fake SSID IE */
1701	*fake++ = WLAN_EID_SSID;
1702	*fake++ = params->ssid_len;
1703	memcpy(fake, params->ssid, params->ssid_len);
1704	fake += params->ssid_len;
1705	/* Fake supported basic rates IE */
1706	*fake++ = WLAN_EID_SUPP_RATES;
1707	*fake++ = 4;
1708	*fake++ = 0x82;
1709	*fake++ = 0x84;
1710	*fake++ = 0x8b;
1711	*fake++ = 0x96;
1712	/* Fake DS channel IE */
1713	*fake++ = WLAN_EID_DS_PARAMS;
1714	*fake++ = 1;
1715	*fake++ = params->channel->hw_value;
1716	/* Fake IBSS params IE */
1717	*fake++ = WLAN_EID_IBSS_PARAMS;
1718	*fake++ = 2;
1719	*fake++ = 0; /* ATIM=0 */
1720	*fake++ = 0;
1721	/* Fake extended rates IE, TODO: don't add this for 802.11b only,
1722	 * but I don't know how this could be checked */
1723	*fake++ = WLAN_EID_EXT_SUPP_RATES;
1724	*fake++ = 8;
1725	*fake++ = 0x0c;
1726	*fake++ = 0x12;
1727	*fake++ = 0x18;
1728	*fake++ = 0x24;
1729	*fake++ = 0x30;
1730	*fake++ = 0x48;
1731	*fake++ = 0x60;
1732	*fake++ = 0x6c;
1733	lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie);
1734
1735	cfg80211_inform_bss(priv->wdev->wiphy,
1736			    params->channel,
1737			    bssid,
1738			    0,
1739			    capability,
1740			    params->beacon_interval,
1741			    fake_ie, fake - fake_ie,
1742			    0, GFP_KERNEL);
1743
1744	memcpy(priv->wdev->ssid, params->ssid, params->ssid_len);
1745	priv->wdev->ssid_len = params->ssid_len;
1746
1747	cfg80211_ibss_joined(priv->dev, bssid, GFP_KERNEL);
1748
1749	/* TODO: consider doing this at MACREG_INT_CODE_LINK_SENSED time */
1750	priv->connect_status = LBS_CONNECTED;
1751	netif_carrier_on(priv->dev);
1752	if (!priv->tx_pending_len)
1753		netif_wake_queue(priv->dev);
1754
1755	lbs_deb_leave(LBS_DEB_CFG80211);
1756}
1757
1758static int lbs_ibss_join_existing(struct lbs_private *priv,
1759	struct cfg80211_ibss_params *params,
1760	struct cfg80211_bss *bss)
1761{
1762	const u8 *rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
1763	struct cmd_ds_802_11_ad_hoc_join cmd;
1764	u8 preamble = RADIO_PREAMBLE_SHORT;
1765	int ret = 0;
1766
1767	lbs_deb_enter(LBS_DEB_CFG80211);
1768
1769	/* TODO: set preamble based on scan result */
1770	ret = lbs_set_radio(priv, preamble, 1);
1771	if (ret)
1772		goto out;
1773
1774	/*
1775	 * Example CMD_802_11_AD_HOC_JOIN command:
1776	 *
1777	 * command         2c 00         CMD_802_11_AD_HOC_JOIN
1778	 * size            65 00
1779	 * sequence        xx xx
1780	 * result          00 00
1781	 * bssid           02 27 27 97 2f 96
1782	 * ssid            49 42 53 53 00 00 00 00
1783	 *                 00 00 00 00 00 00 00 00
1784	 *                 00 00 00 00 00 00 00 00
1785	 *                 00 00 00 00 00 00 00 00
1786	 * type            02            CMD_BSS_TYPE_IBSS
1787	 * beacon period   64 00
1788	 * dtim period     00
1789	 * timestamp       00 00 00 00 00 00 00 00
1790	 * localtime       00 00 00 00 00 00 00 00
1791	 * IE DS           03
1792	 * IE DS len       01
1793	 * IE DS channel   01
1794	 * reserveed       00 00 00 00
1795	 * IE IBSS         06
1796	 * IE IBSS len     02
1797	 * IE IBSS atim    00 00
1798	 * reserved        00 00 00 00
1799	 * capability      02 00
1800	 * rates           82 84 8b 96 0c 12 18 24 30 48 60 6c 00
1801	 * fail timeout    ff 00
1802	 * probe delay     00 00
1803	 */
1804	memset(&cmd, 0, sizeof(cmd));
1805	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1806
1807	memcpy(cmd.bss.bssid, bss->bssid, ETH_ALEN);
1808	memcpy(cmd.bss.ssid, params->ssid, params->ssid_len);
1809	cmd.bss.type = CMD_BSS_TYPE_IBSS;
1810	cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval);
1811	cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS;
1812	cmd.bss.ds.header.len = 1;
1813	cmd.bss.ds.channel = params->channel->hw_value;
1814	cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS;
1815	cmd.bss.ibss.header.len = 2;
1816	cmd.bss.ibss.atimwindow = 0;
1817	cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
1818
1819	/* set rates to the intersection of our rates and the rates in the
1820	   bss */
1821	if (!rates_eid) {
1822		lbs_add_rates(cmd.bss.rates);
1823	} else {
1824		int hw, i;
1825		u8 rates_max = rates_eid[1];
1826		u8 *rates = cmd.bss.rates;
1827		for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
1828			u8 hw_rate = lbs_rates[hw].bitrate / 5;
1829			for (i = 0; i < rates_max; i++) {
1830				if (hw_rate == (rates_eid[i+2] & 0x7f)) {
1831					u8 rate = rates_eid[i+2];
1832					if (rate == 0x02 || rate == 0x04 ||
1833					    rate == 0x0b || rate == 0x16)
1834						rate |= 0x80;
1835					*rates++ = rate;
1836				}
1837			}
1838		}
1839	}
1840
1841	/* Only v8 and below support setting this */
1842	if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
1843		cmd.failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
1844		cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1845	}
1846	ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd);
1847	if (ret)
1848		goto out;
1849
1850	/*
1851	 * This is a sample response to CMD_802_11_AD_HOC_JOIN:
1852	 *
1853	 * response        2c 80
1854	 * size            09 00
1855	 * sequence        xx xx
1856	 * result          00 00
1857	 * reserved        00
1858	 */
1859	lbs_join_post(priv, params, bss->bssid, bss->capability);
1860
1861 out:
1862	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1863	return ret;
1864}
1865
1866
1867
1868static int lbs_ibss_start_new(struct lbs_private *priv,
1869	struct cfg80211_ibss_params *params)
1870{
1871	struct cmd_ds_802_11_ad_hoc_start cmd;
1872	struct cmd_ds_802_11_ad_hoc_result *resp =
1873		(struct cmd_ds_802_11_ad_hoc_result *) &cmd;
1874	u8 preamble = RADIO_PREAMBLE_SHORT;
1875	int ret = 0;
1876	u16 capability;
1877
1878	lbs_deb_enter(LBS_DEB_CFG80211);
1879
1880	ret = lbs_set_radio(priv, preamble, 1);
1881	if (ret)
1882		goto out;
1883
1884	/*
1885	 * Example CMD_802_11_AD_HOC_START command:
1886	 *
1887	 * command         2b 00         CMD_802_11_AD_HOC_START
1888	 * size            b1 00
1889	 * sequence        xx xx
1890	 * result          00 00
1891	 * ssid            54 45 53 54 00 00 00 00
1892	 *                 00 00 00 00 00 00 00 00
1893	 *                 00 00 00 00 00 00 00 00
1894	 *                 00 00 00 00 00 00 00 00
1895	 * bss type        02
1896	 * beacon period   64 00
1897	 * dtim period     00
1898	 * IE IBSS         06
1899	 * IE IBSS len     02
1900	 * IE IBSS atim    00 00
1901	 * reserved        00 00 00 00
1902	 * IE DS           03
1903	 * IE DS len       01
1904	 * IE DS channel   01
1905	 * reserved        00 00 00 00
1906	 * probe delay     00 00
1907	 * capability      02 00
1908	 * rates           82 84 8b 96   (basic rates with have bit 7 set)
1909	 *                 0c 12 18 24 30 48 60 6c
1910	 * padding         100 bytes
1911	 */
1912	memset(&cmd, 0, sizeof(cmd));
1913	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1914	memcpy(cmd.ssid, params->ssid, params->ssid_len);
1915	cmd.bsstype = CMD_BSS_TYPE_IBSS;
1916	cmd.beaconperiod = cpu_to_le16(params->beacon_interval);
1917	cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS;
1918	cmd.ibss.header.len = 2;
1919	cmd.ibss.atimwindow = 0;
1920	cmd.ds.header.id = WLAN_EID_DS_PARAMS;
1921	cmd.ds.header.len = 1;
1922	cmd.ds.channel = params->channel->hw_value;
1923	/* Only v8 and below support setting probe delay */
1924	if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8)
1925		cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME);
1926	/* TODO: mix in WLAN_CAPABILITY_PRIVACY */
1927	capability = WLAN_CAPABILITY_IBSS;
1928	cmd.capability = cpu_to_le16(capability);
1929	lbs_add_rates(cmd.rates);
1930
1931
1932	ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd);
1933	if (ret)
1934		goto out;
1935
1936	/*
1937	 * This is a sample response to CMD_802_11_AD_HOC_JOIN:
1938	 *
1939	 * response        2b 80
1940	 * size            14 00
1941	 * sequence        xx xx
1942	 * result          00 00
1943	 * reserved        00
1944	 * bssid           02 2b 7b 0f 86 0e
1945	 */
1946	lbs_join_post(priv, params, resp->bssid, capability);
1947
1948 out:
1949	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1950	return ret;
1951}
1952
1953
1954static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1955		struct cfg80211_ibss_params *params)
1956{
1957	struct lbs_private *priv = wiphy_priv(wiphy);
1958	int ret = 0;
1959	struct cfg80211_bss *bss;
1960	DECLARE_SSID_BUF(ssid_buf);
1961
1962	lbs_deb_enter(LBS_DEB_CFG80211);
1963
1964	if (!params->channel) {
1965		ret = -ENOTSUPP;
1966		goto out;
1967	}
1968
1969	ret = lbs_set_channel(priv, params->channel->hw_value);
1970	if (ret)
1971		goto out;
1972
1973	/* Search if someone is beaconing. This assumes that the
1974	 * bss list is populated already */
1975	bss = cfg80211_get_bss(wiphy, params->channel, params->bssid,
1976		params->ssid, params->ssid_len,
1977		WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
1978
1979	if (bss) {
1980		ret = lbs_ibss_join_existing(priv, params, bss);
1981		cfg80211_put_bss(bss);
1982	} else
1983		ret = lbs_ibss_start_new(priv, params);
1984
1985
1986 out:
1987	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
1988	return ret;
1989}
1990
1991
1992static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1993{
1994	struct lbs_private *priv = wiphy_priv(wiphy);
1995	struct cmd_ds_802_11_ad_hoc_stop cmd;
1996	int ret = 0;
1997
1998	lbs_deb_enter(LBS_DEB_CFG80211);
1999
2000	memset(&cmd, 0, sizeof(cmd));
2001	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
2002	ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_STOP, &cmd);
2003
2004	/* TODO: consider doing this at MACREG_INT_CODE_ADHOC_BCN_LOST time */
2005	lbs_mac_event_disconnected(priv);
2006
2007	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
2008	return ret;
2009}
2010
2011
2012
2013
2014/*
2015 * Initialization
2016 */
2017
2018static struct cfg80211_ops lbs_cfg80211_ops = {
2019	.set_channel = lbs_cfg_set_channel,
2020	.scan = lbs_cfg_scan,
2021	.connect = lbs_cfg_connect,
2022	.disconnect = lbs_cfg_disconnect,
2023	.add_key = lbs_cfg_add_key,
2024	.del_key = lbs_cfg_del_key,
2025	.set_default_key = lbs_cfg_set_default_key,
2026	.get_station = lbs_cfg_get_station,
2027	.dump_survey = lbs_get_survey,
2028	.change_virtual_intf = lbs_change_intf,
2029	.join_ibss = lbs_join_ibss,
2030	.leave_ibss = lbs_leave_ibss,
2031};
2032
2033
2034/*
2035 * At this time lbs_private *priv doesn't even exist, so we just allocate
2036 * memory and don't initialize the wiphy further. This is postponed until we
2037 * can talk to the firmware and happens at registration time in
2038 * lbs_cfg_wiphy_register().
2039 */
2040struct wireless_dev *lbs_cfg_alloc(struct device *dev)
2041{
2042	int ret = 0;
2043	struct wireless_dev *wdev;
2044
2045	lbs_deb_enter(LBS_DEB_CFG80211);
2046
2047	wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2048	if (!wdev) {
2049		dev_err(dev, "cannot allocate wireless device\n");
2050		return ERR_PTR(-ENOMEM);
2051	}
2052
2053	wdev->wiphy = wiphy_new(&lbs_cfg80211_ops, sizeof(struct lbs_private));
2054	if (!wdev->wiphy) {
2055		dev_err(dev, "cannot allocate wiphy\n");
2056		ret = -ENOMEM;
2057		goto err_wiphy_new;
2058	}
2059
2060	lbs_deb_leave(LBS_DEB_CFG80211);
2061	return wdev;
2062
2063 err_wiphy_new:
2064	kfree(wdev);
2065	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
2066	return ERR_PTR(ret);
2067}
2068
2069
2070static void lbs_cfg_set_regulatory_hint(struct lbs_private *priv)
2071{
2072	struct region_code_mapping {
2073		const char *cn;
2074		int code;
2075	};
2076
2077	/* Section 5.17.2 */
2078	static const struct region_code_mapping regmap[] = {
2079		{"US ", 0x10}, /* US FCC */
2080		{"CA ", 0x20}, /* Canada */
2081		{"EU ", 0x30}, /* ETSI   */
2082		{"ES ", 0x31}, /* Spain  */
2083		{"FR ", 0x32}, /* France */
2084		{"JP ", 0x40}, /* Japan  */
2085	};
2086	size_t i;
2087
2088	lbs_deb_enter(LBS_DEB_CFG80211);
2089
2090	for (i = 0; i < ARRAY_SIZE(regmap); i++)
2091		if (regmap[i].code == priv->regioncode) {
2092			regulatory_hint(priv->wdev->wiphy, regmap[i].cn);
2093			break;
2094		}
2095
2096	lbs_deb_leave(LBS_DEB_CFG80211);
2097}
2098
2099
2100/*
2101 * This function get's called after lbs_setup_firmware() determined the
2102 * firmware capabities. So we can setup the wiphy according to our
2103 * hardware/firmware.
2104 */
2105int lbs_cfg_register(struct lbs_private *priv)
2106{
2107	struct wireless_dev *wdev = priv->wdev;
2108	int ret;
2109
2110	lbs_deb_enter(LBS_DEB_CFG80211);
2111
2112	wdev->wiphy->max_scan_ssids = 1;
2113	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2114
2115	wdev->wiphy->interface_modes =
2116			BIT(NL80211_IFTYPE_STATION) |
2117			BIT(NL80211_IFTYPE_ADHOC);
2118	if (lbs_rtap_supported(priv))
2119		wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
2120
2121	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &lbs_band_2ghz;
2122
2123	/*
2124	 * We could check priv->fwcapinfo && FW_CAPINFO_WPA, but I have
2125	 * never seen a firmware without WPA
2126	 */
2127	wdev->wiphy->cipher_suites = cipher_suites;
2128	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2129	wdev->wiphy->reg_notifier = lbs_reg_notifier;
2130
2131	ret = wiphy_register(wdev->wiphy);
2132	if (ret < 0)
2133		pr_err("cannot register wiphy device\n");
2134
2135	priv->wiphy_registered = true;
2136
2137	ret = register_netdev(priv->dev);
2138	if (ret)
2139		pr_err("cannot register network device\n");
2140
2141	INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
2142
2143	lbs_cfg_set_regulatory_hint(priv);
2144
2145	lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
2146	return ret;
2147}
2148
2149int lbs_reg_notifier(struct wiphy *wiphy,
2150		struct regulatory_request *request)
2151{
2152	struct lbs_private *priv = wiphy_priv(wiphy);
2153	int ret;
2154
2155	lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain "
2156			"callback for domain %c%c\n", request->alpha2[0],
2157			request->alpha2[1]);
2158
2159	ret = lbs_set_11d_domain_info(priv, request, wiphy->bands);
2160
2161	lbs_deb_leave(LBS_DEB_CFG80211);
2162	return ret;
2163}
2164
2165void lbs_scan_deinit(struct lbs_private *priv)
2166{
2167	lbs_deb_enter(LBS_DEB_CFG80211);
2168	cancel_delayed_work_sync(&priv->scan_work);
2169}
2170
2171
2172void lbs_cfg_free(struct lbs_private *priv)
2173{
2174	struct wireless_dev *wdev = priv->wdev;
2175
2176	lbs_deb_enter(LBS_DEB_CFG80211);
2177
2178	if (!wdev)
2179		return;
2180
2181	if (priv->wiphy_registered)
2182		wiphy_unregister(wdev->wiphy);
2183
2184	if (wdev->wiphy)
2185		wiphy_free(wdev->wiphy);
2186
2187	kfree(wdev);
2188}