main.c 134.7 KB
Newer Older
1

L
Luciano Coelho 已提交
2 3 4
/*
 * This file is part of wl1271
 *
J
Juuso Oikarinen 已提交
5
 * Copyright (C) 2008-2010 Nokia Corporation
L
Luciano Coelho 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
 *
 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/crc32.h>
#include <linux/etherdevice.h>
31
#include <linux/vmalloc.h>
32
#include <linux/platform_device.h>
33
#include <linux/slab.h>
34
#include <linux/wl12xx.h>
35
#include <linux/sched.h>
36
#include <linux/interrupt.h>
L
Luciano Coelho 已提交
37

S
Shahar Levi 已提交
38
#include "wl12xx.h"
39
#include "debug.h"
L
Luciano Coelho 已提交
40
#include "wl12xx_80211.h"
S
Shahar Levi 已提交
41 42 43 44 45 46 47 48 49 50 51 52
#include "reg.h"
#include "io.h"
#include "event.h"
#include "tx.h"
#include "rx.h"
#include "ps.h"
#include "init.h"
#include "debugfs.h"
#include "cmd.h"
#include "boot.h"
#include "testmode.h"
#include "scan.h"
L
Luciano Coelho 已提交
53

54 55
#define WL1271_BOOT_RETRIES 3

56 57
static struct conf_drv_settings default_conf = {
	.sg = {
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
		.params = {
			[CONF_SG_ACL_BT_MASTER_MIN_BR] = 10,
			[CONF_SG_ACL_BT_MASTER_MAX_BR] = 180,
			[CONF_SG_ACL_BT_SLAVE_MIN_BR] = 10,
			[CONF_SG_ACL_BT_SLAVE_MAX_BR] = 180,
			[CONF_SG_ACL_BT_MASTER_MIN_EDR] = 10,
			[CONF_SG_ACL_BT_MASTER_MAX_EDR] = 80,
			[CONF_SG_ACL_BT_SLAVE_MIN_EDR] = 10,
			[CONF_SG_ACL_BT_SLAVE_MAX_EDR] = 80,
			[CONF_SG_ACL_WLAN_PS_MASTER_BR] = 8,
			[CONF_SG_ACL_WLAN_PS_SLAVE_BR] = 8,
			[CONF_SG_ACL_WLAN_PS_MASTER_EDR] = 20,
			[CONF_SG_ACL_WLAN_PS_SLAVE_EDR] = 20,
			[CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_BR] = 20,
			[CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_BR] = 35,
			[CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_BR] = 16,
			[CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_BR] = 35,
			[CONF_SG_ACL_WLAN_ACTIVE_MASTER_MIN_EDR] = 32,
			[CONF_SG_ACL_WLAN_ACTIVE_MASTER_MAX_EDR] = 50,
			[CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MIN_EDR] = 28,
			[CONF_SG_ACL_WLAN_ACTIVE_SLAVE_MAX_EDR] = 50,
			[CONF_SG_ACL_ACTIVE_SCAN_WLAN_BR] = 10,
			[CONF_SG_ACL_ACTIVE_SCAN_WLAN_EDR] = 20,
			[CONF_SG_ACL_PASSIVE_SCAN_BT_BR] = 75,
			[CONF_SG_ACL_PASSIVE_SCAN_WLAN_BR] = 15,
			[CONF_SG_ACL_PASSIVE_SCAN_BT_EDR] = 27,
			[CONF_SG_ACL_PASSIVE_SCAN_WLAN_EDR] = 17,
			/* active scan params */
			[CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
			[CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
			[CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
			/* passive scan params */
			[CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_BR] = 800,
			[CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP_EDR] = 200,
			[CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
			/* passive scan in dual antenna params */
			[CONF_SG_CONSECUTIVE_HV3_IN_PASSIVE_SCAN] = 0,
			[CONF_SG_BCN_HV3_COLLISION_THRESH_IN_PASSIVE_SCAN] = 0,
			[CONF_SG_TX_RX_PROTECTION_BWIDTH_IN_PASSIVE_SCAN] = 0,
			/* general params */
			[CONF_SG_STA_FORCE_PS_IN_BT_SCO] = 1,
			[CONF_SG_ANTENNA_CONFIGURATION] = 0,
			[CONF_SG_BEACON_MISS_PERCENT] = 60,
			[CONF_SG_DHCP_TIME] = 5000,
			[CONF_SG_RXT] = 1200,
			[CONF_SG_TXT] = 1000,
			[CONF_SG_ADAPTIVE_RXT_TXT] = 1,
			[CONF_SG_GENERAL_USAGE_BIT_MAP] = 3,
			[CONF_SG_HV3_MAX_SERVED] = 6,
			[CONF_SG_PS_POLL_TIMEOUT] = 10,
			[CONF_SG_UPSD_TIMEOUT] = 10,
			[CONF_SG_CONSECUTIVE_CTS_THRESHOLD] = 2,
			[CONF_SG_STA_RX_WINDOW_AFTER_DTIM] = 5,
			[CONF_SG_STA_CONNECTION_PROTECTION_TIME] = 30,
			/* AP params */
			[CONF_AP_BEACON_MISS_TX] = 3,
			[CONF_AP_RX_WINDOW_AFTER_BEACON] = 10,
			[CONF_AP_BEACON_WINDOW_INTERVAL] = 2,
			[CONF_AP_CONNECTION_PROTECTION_TIME] = 0,
			[CONF_AP_BT_ACL_VAL_BT_SERVE_TIME] = 25,
			[CONF_AP_BT_ACL_VAL_WL_SERVE_TIME] = 25,
A
Arik Nemtsov 已提交
119
		},
120
		.state = CONF_SG_PROTECTIVE,
121 122 123 124 125 126
	},
	.rx = {
		.rx_msdu_life_time           = 512000,
		.packet_detection_threshold  = 0,
		.ps_poll_timeout             = 15,
		.upsd_timeout                = 15,
127
		.rts_threshold               = IEEE80211_MAX_RTS_THRESHOLD,
128 129 130 131
		.rx_cca_threshold            = 0,
		.irq_blk_threshold           = 0xFFFF,
		.irq_pkt_threshold           = 0,
		.irq_timeout                 = 600,
132 133 134 135
		.queue_type                  = CONF_RX_QUEUE_TYPE_LOW_PRIORITY,
	},
	.tx = {
		.tx_energy_detection         = 0,
136
		.sta_rc_conf                 = {
137
			.enabled_rates       = 0,
138 139
			.short_retry_limit   = 10,
			.long_retry_limit    = 10,
140
			.aflags              = 0,
141
		},
142 143
		.ac_conf_count               = 4,
		.ac_conf                     = {
144
			[CONF_TX_AC_BE] = {
145 146 147 148 149
				.ac          = CONF_TX_AC_BE,
				.cw_min      = 15,
				.cw_max      = 63,
				.aifsn       = 3,
				.tx_op_limit = 0,
150
			},
151
			[CONF_TX_AC_BK] = {
152 153 154 155 156
				.ac          = CONF_TX_AC_BK,
				.cw_min      = 15,
				.cw_max      = 63,
				.aifsn       = 7,
				.tx_op_limit = 0,
157
			},
158
			[CONF_TX_AC_VI] = {
159 160 161 162 163 164
				.ac          = CONF_TX_AC_VI,
				.cw_min      = 15,
				.cw_max      = 63,
				.aifsn       = CONF_TX_AIFS_PIFS,
				.tx_op_limit = 3008,
			},
165
			[CONF_TX_AC_VO] = {
166 167 168 169 170
				.ac          = CONF_TX_AC_VO,
				.cw_min      = 15,
				.cw_max      = 63,
				.aifsn       = CONF_TX_AIFS_PIFS,
				.tx_op_limit = 1504,
171
			},
172
		},
173 174
		.max_tx_retries = 100,
		.ap_aging_period = 300,
175
		.tid_conf_count = 4,
176
		.tid_conf = {
177 178 179
			[CONF_TX_AC_BE] = {
				.queue_id    = CONF_TX_AC_BE,
				.channel_type = CONF_CHANNEL_TYPE_EDCF,
180 181 182 183
				.tsid        = CONF_TX_AC_BE,
				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
				.ack_policy  = CONF_ACK_POLICY_LEGACY,
				.apsd_conf   = {0, 0},
184
			},
185 186 187 188
			[CONF_TX_AC_BK] = {
				.queue_id    = CONF_TX_AC_BK,
				.channel_type = CONF_CHANNEL_TYPE_EDCF,
				.tsid        = CONF_TX_AC_BK,
189 190 191 192
				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
				.ack_policy  = CONF_ACK_POLICY_LEGACY,
				.apsd_conf   = {0, 0},
			},
193 194 195 196
			[CONF_TX_AC_VI] = {
				.queue_id    = CONF_TX_AC_VI,
				.channel_type = CONF_CHANNEL_TYPE_EDCF,
				.tsid        = CONF_TX_AC_VI,
197 198 199 200
				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
				.ack_policy  = CONF_ACK_POLICY_LEGACY,
				.apsd_conf   = {0, 0},
			},
201 202 203 204
			[CONF_TX_AC_VO] = {
				.queue_id    = CONF_TX_AC_VO,
				.channel_type = CONF_CHANNEL_TYPE_EDCF,
				.tsid        = CONF_TX_AC_VO,
205 206 207 208 209 210
				.ps_scheme   = CONF_PS_SCHEME_LEGACY,
				.ack_policy  = CONF_ACK_POLICY_LEGACY,
				.apsd_conf   = {0, 0},
			},
		},
		.frag_threshold              = IEEE80211_MAX_FRAG_THRESHOLD,
211
		.tx_compl_timeout            = 700,
212 213 214
		.tx_compl_threshold          = 4,
		.basic_rate                  = CONF_HW_BIT_RATE_1MBPS,
		.basic_rate_5                = CONF_HW_BIT_RATE_6MBPS,
215 216
		.tmpl_short_retry_limit      = 10,
		.tmpl_long_retry_limit       = 10,
217 218 219
	},
	.conn = {
		.wake_up_event               = CONF_WAKE_UP_EVENT_DTIM,
220
		.listen_interval             = 1,
221
		.bcn_filt_mode               = CONF_BCN_FILT_MODE_ENABLED,
222
		.bcn_filt_ie_count           = 2,
223 224 225 226
		.bcn_filt_ie = {
			[0] = {
				.ie          = WLAN_EID_CHANNEL_SWITCH,
				.rule        = CONF_BCN_RULE_PASS_ON_APPEARANCE,
227 228 229 230 231
			},
			[1] = {
				.ie          = WLAN_EID_HT_INFORMATION,
				.rule        = CONF_BCN_RULE_PASS_ON_CHANGE,
			},
232
		},
233
		.synch_fail_thold            = 10,
234 235 236 237
		.bss_lose_timeout            = 100,
		.beacon_rx_timeout           = 10000,
		.broadcast_timeout           = 20000,
		.rx_broadcast_in_ps          = 1,
238
		.ps_poll_threshold           = 10,
239
		.bet_enable                  = CONF_BET_MODE_ENABLE,
240
		.bet_max_consecutive         = 50,
241
		.psm_entry_retries           = 8,
242
		.psm_exit_retries            = 16,
243
		.psm_entry_nullfunc_retries  = 3,
244
		.dynamic_ps_timeout          = 100,
245 246
		.keep_alive_interval         = 55000,
		.max_listen_interval         = 20,
247
	},
248 249 250
	.itrim = {
		.enable = false,
		.timeout = 50000,
251 252 253 254
	},
	.pm_config = {
		.host_clk_settling_time = 5000,
		.host_fast_wakeup_support = false
255 256 257 258 259 260
	},
	.roam_trigger = {
		.trigger_pacing               = 1,
		.avg_weight_rssi_beacon       = 20,
		.avg_weight_rssi_data         = 10,
		.avg_weight_snr_beacon        = 20,
L
Levi, Shahar 已提交
261
		.avg_weight_snr_data          = 10,
J
Juuso Oikarinen 已提交
262 263 264 265
	},
	.scan = {
		.min_dwell_time_active        = 7500,
		.max_dwell_time_active        = 30000,
266 267
		.min_dwell_time_passive       = 100000,
		.max_dwell_time_passive       = 100000,
J
Juuso Oikarinen 已提交
268 269
		.num_probe_reqs               = 2,
	},
270 271
	.sched_scan = {
		/* sched_scan requires dwell times in TU instead of TU/1000 */
272 273
		.min_dwell_time_active = 30,
		.max_dwell_time_active = 60,
274
		.dwell_time_passive    = 100,
275
		.dwell_time_dfs        = 150,
276 277 278 279
		.num_probe_reqs        = 2,
		.rssi_threshold        = -90,
		.snr_threshold         = 0,
	},
280 281 282 283 284 285 286 287 288 289
	.rf = {
		.tx_per_channel_power_compensation_2 = {
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		},
		.tx_per_channel_power_compensation_5 = {
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		},
	},
L
Levi, Shahar 已提交
290
	.ht = {
291
		.rx_ba_win_size = 8,
L
Levi, Shahar 已提交
292 293
		.tx_ba_win_size = 64,
		.inactivity_timeout = 10000,
294
		.tx_ba_tid_bitmap = CONF_TX_BA_ENABLED_TID_BITMAP,
L
Levi, Shahar 已提交
295
	},
296
	.mem_wl127x = {
297 298 299 300
		.num_stations                 = 1,
		.ssid_profiles                = 1,
		.rx_block_num                 = 70,
		.tx_min_block_num             = 40,
301
		.dynamic_memory               = 1,
302
		.min_req_tx_blocks            = 100,
303 304
		.min_req_rx_blocks            = 22,
		.tx_min                       = 27,
305 306 307 308 309 310 311 312 313 314 315
	},
	.mem_wl128x = {
		.num_stations                 = 1,
		.ssid_profiles                = 1,
		.rx_block_num                 = 40,
		.tx_min_block_num             = 40,
		.dynamic_memory               = 1,
		.min_req_tx_blocks            = 45,
		.min_req_rx_blocks            = 22,
		.tx_min                       = 27,
	},
S
Shahar Levi 已提交
316 317 318 319 320 321 322 323 324 325 326 327
	.fm_coex = {
		.enable                       = true,
		.swallow_period               = 5,
		.n_divider_fref_set_1         = 0xff,       /* default */
		.n_divider_fref_set_2         = 12,
		.m_divider_fref_set_1         = 148,
		.m_divider_fref_set_2         = 0xffff,     /* default */
		.coex_pll_stabilization_time  = 0xffffffff, /* default */
		.ldo_stabilization_time       = 0xffff,     /* default */
		.fm_disturbed_band_margin     = 0xff,       /* default */
		.swallow_clk_diff             = 0xff,       /* default */
	},
328 329 330 331
	.rx_streaming = {
		.duration                      = 150,
		.queues                        = 0x1,
		.interval                      = 20,
332
		.always                        = 0,
333
	},
334 335 336 337 338 339 340 341
	.fwlog = {
		.mode                         = WL12XX_FWLOG_ON_DEMAND,
		.mem_blocks                   = 2,
		.severity                     = 0,
		.timestamp                    = WL12XX_FWLOG_TIMESTAMP_DISABLED,
		.output                       = WL12XX_FWLOG_OUTPUT_HOST,
		.threshold                    = 0,
	},
342
	.hci_io_ds = HCI_IO_DS_6MA,
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
	.rate = {
		.rate_retry_score = 32000,
		.per_add = 8192,
		.per_th1 = 2048,
		.per_th2 = 4096,
		.max_per = 8100,
		.inverse_curiosity_factor = 5,
		.tx_fail_low_th = 4,
		.tx_fail_high_th = 10,
		.per_alpha_shift = 4,
		.per_add_shift = 13,
		.per_beta1_shift = 10,
		.per_beta2_shift = 8,
		.rate_check_up = 2,
		.rate_check_down = 12,
		.rate_retry_policy = {
			0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00, 0x00, 0x00,
			0x00, 0x00, 0x00,
		},
	},
364 365 366 367 368 369 370 371 372 373 374 375 376
	.hangover = {
		.recover_time               = 0,
		.hangover_period            = 20,
		.dynamic_mode               = 1,
		.early_termination_mode     = 1,
		.max_period                 = 20,
		.min_period                 = 1,
		.increase_delta             = 1,
		.decrease_delta             = 2,
		.quiet_time                 = 4,
		.increase_time              = 1,
		.window_size                = 16,
	},
377 378
};

379
static char *fwlog_param;
380
static bool bug_on_recovery;
381

382
static void __wl1271_op_remove_interface(struct wl1271 *wl,
E
Eliad Peller 已提交
383
					 struct ieee80211_vif *vif,
384
					 bool reset_tx_queues);
E
Eliad Peller 已提交
385
static void wl1271_op_stop(struct ieee80211_hw *hw);
386
static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif);
387

388
static DEFINE_MUTEX(wl_list_mutex);
389 390
static LIST_HEAD(wl_list);

391 392
static int wl1271_check_operstate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
				  unsigned char operstate)
393 394
{
	int ret;
E
Eliad Peller 已提交
395

396 397 398
	if (operstate != IF_OPER_UP)
		return 0;

399
	if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags))
400 401
		return 0;

E
Eliad Peller 已提交
402
	ret = wl12xx_cmd_set_peer_state(wl, wlvif->sta.hlid);
403 404 405
	if (ret < 0)
		return ret;

E
Eliad Peller 已提交
406
	wl12xx_croc(wl, wlvif->role_id);
407

408 409 410
	wl1271_info("Association completed.");
	return 0;
}
411 412 413 414 415 416 417 418 419
static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
			     void *arg)
{
	struct net_device *dev = arg;
	struct wireless_dev *wdev;
	struct wiphy *wiphy;
	struct ieee80211_hw *hw;
	struct wl1271 *wl;
	struct wl1271 *wl_temp;
420
	struct wl12xx_vif *wlvif;
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
	int ret = 0;

	/* Check that this notification is for us. */
	if (what != NETDEV_CHANGE)
		return NOTIFY_DONE;

	wdev = dev->ieee80211_ptr;
	if (wdev == NULL)
		return NOTIFY_DONE;

	wiphy = wdev->wiphy;
	if (wiphy == NULL)
		return NOTIFY_DONE;

	hw = wiphy_priv(wiphy);
	if (hw == NULL)
		return NOTIFY_DONE;

	wl_temp = hw->priv;
440
	mutex_lock(&wl_list_mutex);
441 442 443 444
	list_for_each_entry(wl, &wl_list, list) {
		if (wl == wl_temp)
			break;
	}
445
	mutex_unlock(&wl_list_mutex);
446 447 448 449 450 451 452 453
	if (wl != wl_temp)
		return NOTIFY_DONE;

	mutex_lock(&wl->mutex);

	if (wl->state == WL1271_STATE_OFF)
		goto out;

454 455 456 457 458 459 460
	if (dev->operstate != IF_OPER_UP)
		goto out;
	/*
	 * The correct behavior should be just getting the appropriate wlvif
	 * from the given dev, but currently we don't have a mac80211
	 * interface for it.
	 */
461
	wl12xx_for_each_wlvif_sta(wl, wlvif) {
462 463
		struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);

464 465
		if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
			continue;
466

467 468 469
		ret = wl1271_ps_elp_wakeup(wl);
		if (ret < 0)
			goto out;
470

471 472
		wl1271_check_operstate(wl, wlvif,
				       ieee80211_get_operstate(vif));
473

474 475
		wl1271_ps_elp_sleep(wl);
	}
476 477 478 479 480 481
out:
	mutex_unlock(&wl->mutex);

	return NOTIFY_OK;
}

482
static int wl1271_reg_notify(struct wiphy *wiphy,
483 484
			     struct regulatory_request *request)
{
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
	struct ieee80211_supported_band *band;
	struct ieee80211_channel *ch;
	int i;

	band = wiphy->bands[IEEE80211_BAND_5GHZ];
	for (i = 0; i < band->n_channels; i++) {
		ch = &band->channels[i];
		if (ch->flags & IEEE80211_CHAN_DISABLED)
			continue;

		if (ch->flags & IEEE80211_CHAN_RADAR)
			ch->flags |= IEEE80211_CHAN_NO_IBSS |
				     IEEE80211_CHAN_PASSIVE_SCAN;

	}

	return 0;
}

E
Eliad Peller 已提交
504 505
static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
				   bool enable)
506 507 508 509
{
	int ret = 0;

	/* we should hold wl->mutex */
E
Eliad Peller 已提交
510
	ret = wl1271_acx_ps_rx_streaming(wl, wlvif, enable);
511 512 513 514
	if (ret < 0)
		goto out;

	if (enable)
515
		set_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags);
516
	else
517
		clear_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags);
518 519 520 521 522 523 524 525
out:
	return ret;
}

/*
 * this function is being called when the rx_streaming interval
 * has beed changed or rx_streaming should be disabled
 */
E
Eliad Peller 已提交
526
int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif)
527 528 529 530 531
{
	int ret = 0;
	int period = wl->conf.rx_streaming.interval;

	/* don't reconfigure if rx_streaming is disabled */
532
	if (!test_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags))
533 534 535 536
		goto out;

	/* reconfigure/disable according to new streaming_period */
	if (period &&
537
	    test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
538 539
	    (wl->conf.rx_streaming.always ||
	     test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags)))
E
Eliad Peller 已提交
540
		ret = wl1271_set_rx_streaming(wl, wlvif, true);
541
	else {
E
Eliad Peller 已提交
542
		ret = wl1271_set_rx_streaming(wl, wlvif, false);
543
		/* don't cancel_work_sync since we might deadlock */
E
Eliad Peller 已提交
544
		del_timer_sync(&wlvif->rx_streaming_timer);
545 546 547 548 549 550 551 552
	}
out:
	return ret;
}

static void wl1271_rx_streaming_enable_work(struct work_struct *work)
{
	int ret;
E
Eliad Peller 已提交
553 554 555
	struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif,
						rx_streaming_enable_work);
	struct wl1271 *wl = wlvif->wl;
556 557 558

	mutex_lock(&wl->mutex);

559
	if (test_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags) ||
560
	    !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) ||
561 562 563 564 565 566 567 568 569 570 571
	    (!wl->conf.rx_streaming.always &&
	     !test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags)))
		goto out;

	if (!wl->conf.rx_streaming.interval)
		goto out;

	ret = wl1271_ps_elp_wakeup(wl);
	if (ret < 0)
		goto out;

E
Eliad Peller 已提交
572
	ret = wl1271_set_rx_streaming(wl, wlvif, true);
573 574 575 576
	if (ret < 0)
		goto out_sleep;

	/* stop it after some time of inactivity */
E
Eliad Peller 已提交
577
	mod_timer(&wlvif->rx_streaming_timer,
578 579 580 581 582 583 584 585 586 587 588
		  jiffies + msecs_to_jiffies(wl->conf.rx_streaming.duration));

out_sleep:
	wl1271_ps_elp_sleep(wl);
out:
	mutex_unlock(&wl->mutex);
}

static void wl1271_rx_streaming_disable_work(struct work_struct *work)
{
	int ret;
E
Eliad Peller 已提交
589 590 591
	struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif,
						rx_streaming_disable_work);
	struct wl1271 *wl = wlvif->wl;
592 593 594

	mutex_lock(&wl->mutex);

595
	if (!test_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags))
596 597 598 599 600 601
		goto out;

	ret = wl1271_ps_elp_wakeup(wl);
	if (ret < 0)
		goto out;

E
Eliad Peller 已提交
602
	ret = wl1271_set_rx_streaming(wl, wlvif, false);
603 604 605 606 607 608 609 610 611 612 613
	if (ret)
		goto out_sleep;

out_sleep:
	wl1271_ps_elp_sleep(wl);
out:
	mutex_unlock(&wl->mutex);
}

static void wl1271_rx_streaming_timer(unsigned long data)
{
E
Eliad Peller 已提交
614 615 616
	struct wl12xx_vif *wlvif = (struct wl12xx_vif *)data;
	struct wl1271 *wl = wlvif->wl;
	ieee80211_queue_work(wl->hw, &wlvif->rx_streaming_disable_work);
617 618
}

619 620
static void wl1271_conf_init(struct wl1271 *wl)
{
621 622 623 624 625 626 627 628 629 630 631 632

	/*
	 * This function applies the default configuration to the driver. This
	 * function is invoked upon driver load (spi probe.)
	 *
	 * The configuration is stored in a run-time structure in order to
	 * facilitate for run-time adjustment of any of the parameters. Making
	 * changes to the configuration structure will apply the new values on
	 * the next interface up (wl1271_op_start.)
	 */

	/* apply driver default configuration */
633
	memcpy(&wl->conf, &default_conf, sizeof(default_conf));
634

635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
	/* Adjust settings according to optional module parameters */
	if (fwlog_param) {
		if (!strcmp(fwlog_param, "continuous")) {
			wl->conf.fwlog.mode = WL12XX_FWLOG_CONTINUOUS;
		} else if (!strcmp(fwlog_param, "ondemand")) {
			wl->conf.fwlog.mode = WL12XX_FWLOG_ON_DEMAND;
		} else if (!strcmp(fwlog_param, "dbgpins")) {
			wl->conf.fwlog.mode = WL12XX_FWLOG_CONTINUOUS;
			wl->conf.fwlog.output = WL12XX_FWLOG_OUTPUT_DBG_PINS;
		} else if (!strcmp(fwlog_param, "disable")) {
			wl->conf.fwlog.mem_blocks = 0;
			wl->conf.fwlog.output = WL12XX_FWLOG_OUTPUT_NONE;
		} else {
			wl1271_error("Unknown fwlog parameter %s", fwlog_param);
		}
	}
}
652

L
Luciano Coelho 已提交
653 654
static int wl1271_plt_init(struct wl1271 *wl)
{
655
	int ret;
L
Luciano Coelho 已提交
656

657 658 659 660
	if (wl->chip.id == CHIP_ID_1283_PG20)
		ret = wl128x_cmd_general_parms(wl);
	else
		ret = wl1271_cmd_general_parms(wl);
661
	if (ret < 0)
662 663
		return ret;

664 665 666 667
	if (wl->chip.id == CHIP_ID_1283_PG20)
		ret = wl128x_cmd_radio_parms(wl);
	else
		ret = wl1271_cmd_radio_parms(wl);
668
	if (ret < 0)
669 670
		return ret;

671 672 673 674 675
	if (wl->chip.id != CHIP_ID_1283_PG20) {
		ret = wl1271_cmd_ext_radio_parms(wl);
		if (ret < 0)
			return ret;
	}
676 677 678
	if (ret < 0)
		return ret;

679 680 681 682 683
	/* Chip-specific initializations */
	ret = wl1271_chip_specific_init(wl);
	if (ret < 0)
		return ret;

L
Luciano Coelho 已提交
684 685 686 687
	ret = wl1271_acx_init_mem_config(wl);
	if (ret < 0)
		return ret;

E
Eliad Peller 已提交
688
	ret = wl12xx_acx_mem_cfg(wl);
689 690 691
	if (ret < 0)
		goto out_free_memmap;

692
	/* Enable data path */
693
	ret = wl1271_cmd_data_path(wl, 1);
L
Luciano Coelho 已提交
694
	if (ret < 0)
695 696 697 698 699 700 701 702 703 704 705
		goto out_free_memmap;

	/* Configure for CAM power saving (ie. always active) */
	ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
	if (ret < 0)
		goto out_free_memmap;

	/* configure PM */
	ret = wl1271_acx_pm_config(wl);
	if (ret < 0)
		goto out_free_memmap;
L
Luciano Coelho 已提交
706 707

	return 0;
708 709 710 711 712 713

 out_free_memmap:
	kfree(wl->target_mem_map);
	wl->target_mem_map = NULL;

	return ret;
L
Luciano Coelho 已提交
714 715
}

716 717 718
static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
					struct wl12xx_vif *wlvif,
					u8 hlid, u8 tx_pkts)
719
{
720
	bool fw_ps, single_sta;
721 722

	fw_ps = test_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
723
	single_sta = (wl->active_sta_count == 1);
724 725 726

	/*
	 * Wake up from high level PS if the STA is asleep with too little
727
	 * packets in FW or if the STA is awake.
728
	 */
729
	if (!fw_ps || tx_pkts < WL1271_PS_STA_MAX_PACKETS)
730
		wl12xx_ps_link_end(wl, wlvif, hlid);
731

732 733 734 735 736 737
	/*
	 * Start high-level PS if the STA is asleep with enough blocks in FW.
	 * Make an exception if this is the only connected station. In this
	 * case FW-memory congestion is not a problem.
	 */
	else if (!single_sta && fw_ps && tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
738
		wl12xx_ps_link_start(wl, wlvif, hlid, true);
739 740
}

741
static void wl12xx_irq_update_links_status(struct wl1271 *wl,
742
					   struct wl12xx_vif *wlvif,
743
					   struct wl12xx_fw_status *status)
744
{
745
	struct wl1271_link *lnk;
746
	u32 cur_fw_ps_map;
747 748 749
	u8 hlid, cnt;

	/* TODO: also use link_fast_bitmap here */
750 751 752 753 754 755 756 757 758 759 760

	cur_fw_ps_map = le32_to_cpu(status->link_ps_bitmap);
	if (wl->ap_fw_ps_map != cur_fw_ps_map) {
		wl1271_debug(DEBUG_PSM,
			     "link ps prev 0x%x cur 0x%x changed 0x%x",
			     wl->ap_fw_ps_map, cur_fw_ps_map,
			     wl->ap_fw_ps_map ^ cur_fw_ps_map);

		wl->ap_fw_ps_map = cur_fw_ps_map;
	}

761 762 763
	for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, WL12XX_MAX_LINKS) {
		lnk = &wl->links[hlid];
		cnt = status->tx_lnk_free_pkts[hlid] - lnk->prev_freed_pkts;
764

765 766
		lnk->prev_freed_pkts = status->tx_lnk_free_pkts[hlid];
		lnk->allocated_pkts -= cnt;
767

768 769
		wl12xx_irq_ps_regulate_link(wl, wlvif, hlid,
					    lnk->allocated_pkts);
770 771 772
	}
}

E
Eliad Peller 已提交
773 774
static void wl12xx_fw_status(struct wl1271 *wl,
			     struct wl12xx_fw_status *status)
L
Luciano Coelho 已提交
775
{
776
	struct wl12xx_vif *wlvif;
777
	struct timespec ts;
778
	u32 old_tx_blk_count = wl->tx_blocks_available;
E
Eliad Peller 已提交
779
	int avail, freed_blocks;
780
	int i;
L
Luciano Coelho 已提交
781

E
Eliad Peller 已提交
782
	wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false);
783

L
Luciano Coelho 已提交
784 785 786 787 788 789 790
	wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
		     "drv_rx_counter = %d, tx_results_counter = %d)",
		     status->intr,
		     status->fw_rx_counter,
		     status->drv_rx_counter,
		     status->tx_results_counter);

791 792
	for (i = 0; i < NUM_TX_QUEUES; i++) {
		/* prevent wrap-around in freed-packets counter */
793
		wl->tx_allocated_pkts[i] -=
794 795 796 797 798 799
				(status->tx_released_pkts[i] -
				wl->tx_pkts_freed[i]) & 0xff;

		wl->tx_pkts_freed[i] = status->tx_released_pkts[i];
	}

800 801 802 803 804 805 806 807 808
	/* prevent wrap-around in total blocks counter */
	if (likely(wl->tx_blocks_freed <=
		   le32_to_cpu(status->total_released_blks)))
		freed_blocks = le32_to_cpu(status->total_released_blks) -
			       wl->tx_blocks_freed;
	else
		freed_blocks = 0x100000000LL - wl->tx_blocks_freed +
			       le32_to_cpu(status->total_released_blks);

E
Eliad Peller 已提交
809
	wl->tx_blocks_freed = le32_to_cpu(status->total_released_blks);
810

811 812
	wl->tx_allocated_blocks -= freed_blocks;

E
Eliad Peller 已提交
813
	avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks;
814

E
Eliad Peller 已提交
815 816 817 818 819 820 821 822 823 824
	/*
	 * The FW might change the total number of TX memblocks before
	 * we get a notification about blocks being released. Thus, the
	 * available blocks calculation might yield a temporary result
	 * which is lower than the actual available blocks. Keeping in
	 * mind that only blocks that were allocated can be moved from
	 * TX to RX, tx_blocks_available should never decrease here.
	 */
	wl->tx_blocks_available = max((int)wl->tx_blocks_available,
				      avail);
L
Luciano Coelho 已提交
825

I
Ido Yariv 已提交
826
	/* if more blocks are available now, tx work can be scheduled */
827
	if (wl->tx_blocks_available > old_tx_blk_count)
I
Ido Yariv 已提交
828
		clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
L
Luciano Coelho 已提交
829

E
Eliad Peller 已提交
830
	/* for AP update num of allocated TX blocks per link and ps status */
831
	wl12xx_for_each_wlvif_ap(wl, wlvif) {
832
		wl12xx_irq_update_links_status(wl, wlvif, status);
833
	}
E
Eliad Peller 已提交
834

L
Luciano Coelho 已提交
835
	/* update the host-chipset time offset */
836 837 838
	getnstimeofday(&ts);
	wl->time_offset = (timespec_to_ns(&ts) >> 10) -
		(s64)le32_to_cpu(status->fw_localtime);
L
Luciano Coelho 已提交
839 840
}

841 842 843 844 845 846 847 848 849 850
static void wl1271_flush_deferred_work(struct wl1271 *wl)
{
	struct sk_buff *skb;

	/* Pass all received frames to the network stack */
	while ((skb = skb_dequeue(&wl->deferred_rx_queue)))
		ieee80211_rx_ni(wl->hw, skb);

	/* Return sent skbs to the network stack */
	while ((skb = skb_dequeue(&wl->deferred_tx_queue)))
851
		ieee80211_tx_status_ni(wl->hw, skb);
852 853 854 855 856 857 858 859 860 861 862
}

static void wl1271_netstack_work(struct work_struct *work)
{
	struct wl1271 *wl =
		container_of(work, struct wl1271, netstack_work);

	do {
		wl1271_flush_deferred_work(wl);
	} while (skb_queue_len(&wl->deferred_rx_queue));
}
863

864 865
#define WL1271_IRQ_MAX_LOOPS 256

F
Felipe Balbi 已提交
866
static irqreturn_t wl1271_irq(int irq, void *cookie)
L
Luciano Coelho 已提交
867 868
{
	int ret;
869
	u32 intr;
870
	int loopcount = WL1271_IRQ_MAX_LOOPS;
871 872 873
	struct wl1271 *wl = (struct wl1271 *)cookie;
	bool done = false;
	unsigned int defer_count;
I
Ido Yariv 已提交
874 875 876 877 878
	unsigned long flags;

	/* TX might be handled here, avoid redundant work */
	set_bit(WL1271_FLAG_TX_PENDING, &wl->flags);
	cancel_work_sync(&wl->tx_work);
L
Luciano Coelho 已提交
879

880 881 882 883 884 885 886
	/*
	 * In case edge triggered interrupt must be used, we cannot iterate
	 * more than once without introducing race conditions with the hardirq.
	 */
	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
		loopcount = 1;

L
Luciano Coelho 已提交
887 888 889 890
	mutex_lock(&wl->mutex);

	wl1271_debug(DEBUG_IRQ, "IRQ work");

891
	if (unlikely(wl->state == WL1271_STATE_OFF))
L
Luciano Coelho 已提交
892 893
		goto out;

894
	ret = wl1271_ps_elp_wakeup(wl);
L
Luciano Coelho 已提交
895 896 897
	if (ret < 0)
		goto out;

898 899 900 901 902 903 904 905
	while (!done && loopcount--) {
		/*
		 * In order to avoid a race with the hardirq, clear the flag
		 * before acknowledging the chip. Since the mutex is held,
		 * wl1271_ps_elp_wakeup cannot be called concurrently.
		 */
		clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
		smp_mb__after_clear_bit();
906

E
Eliad Peller 已提交
907 908
		wl12xx_fw_status(wl, wl->fw_status);
		intr = le32_to_cpu(wl->fw_status->intr);
909
		intr &= WL1271_INTR_MASK;
910
		if (!intr) {
911
			done = true;
912 913
			continue;
		}
L
Luciano Coelho 已提交
914

915 916 917
		if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) {
			wl1271_error("watchdog interrupt received! "
				     "starting recovery.");
918
			wl12xx_queue_recovery_work(wl);
919 920 921 922 923

			/* restarting the chip. ignore any other interrupt. */
			goto out;
		}

924
		if (likely(intr & WL1271_ACX_INTR_DATA)) {
925
			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
926

E
Eliad Peller 已提交
927
			wl12xx_rx(wl, wl->fw_status);
L
Luciano Coelho 已提交
928

I
Ido Yariv 已提交
929
			/* Check if any tx blocks were freed */
I
Ido Yariv 已提交
930
			spin_lock_irqsave(&wl->wl_lock, flags);
I
Ido Yariv 已提交
931
			if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
932
			    wl1271_tx_total_queue_count(wl) > 0) {
I
Ido Yariv 已提交
933
				spin_unlock_irqrestore(&wl->wl_lock, flags);
I
Ido Yariv 已提交
934 935 936 937
				/*
				 * In order to avoid starvation of the TX path,
				 * call the work function directly.
				 */
938
				wl1271_tx_work_locked(wl);
I
Ido Yariv 已提交
939 940
			} else {
				spin_unlock_irqrestore(&wl->wl_lock, flags);
I
Ido Yariv 已提交
941 942
			}

943
			/* check for tx results */
E
Eliad Peller 已提交
944
			if (wl->fw_status->tx_results_counter !=
945 946
			    (wl->tx_results_count & 0xff))
				wl1271_tx_complete(wl);
947 948 949 950 951 952

			/* Make sure the deferred queues don't get too long */
			defer_count = skb_queue_len(&wl->deferred_tx_queue) +
				      skb_queue_len(&wl->deferred_rx_queue);
			if (defer_count > WL1271_DEFERRED_QUEUE_LIMIT)
				wl1271_flush_deferred_work(wl);
953
		}
L
Luciano Coelho 已提交
954

955 956 957 958
		if (intr & WL1271_ACX_INTR_EVENT_A) {
			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A");
			wl1271_event_handle(wl, 0);
		}
L
Luciano Coelho 已提交
959

960 961 962 963
		if (intr & WL1271_ACX_INTR_EVENT_B) {
			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B");
			wl1271_event_handle(wl, 1);
		}
L
Luciano Coelho 已提交
964

965 966 967
		if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
			wl1271_debug(DEBUG_IRQ,
				     "WL1271_ACX_INTR_INIT_COMPLETE");
L
Luciano Coelho 已提交
968

969 970
		if (intr & WL1271_ACX_INTR_HW_AVAILABLE)
			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
971
	}
L
Luciano Coelho 已提交
972 973 974 975

	wl1271_ps_elp_sleep(wl);

out:
I
Ido Yariv 已提交
976 977 978 979
	spin_lock_irqsave(&wl->wl_lock, flags);
	/* In case TX was not handled here, queue TX work */
	clear_bit(WL1271_FLAG_TX_PENDING, &wl->flags);
	if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
980
	    wl1271_tx_total_queue_count(wl) > 0)
I
Ido Yariv 已提交
981 982 983
		ieee80211_queue_work(wl->hw, &wl->tx_work);
	spin_unlock_irqrestore(&wl->wl_lock, flags);

L
Luciano Coelho 已提交
984
	mutex_unlock(&wl->mutex);
985 986

	return IRQ_HANDLED;
L
Luciano Coelho 已提交
987 988 989 990 991
}

static int wl1271_fetch_firmware(struct wl1271 *wl)
{
	const struct firmware *fw;
992
	const char *fw_name;
L
Luciano Coelho 已提交
993 994
	int ret;

995 996 997 998
	if (wl->chip.id == CHIP_ID_1283_PG20)
		fw_name = WL128X_FW_NAME;
	else
		fw_name	= WL127X_FW_NAME;
999 1000 1001

	wl1271_debug(DEBUG_BOOT, "booting firmware %s", fw_name);

1002
	ret = request_firmware(&fw, fw_name, wl->dev);
L
Luciano Coelho 已提交
1003 1004

	if (ret < 0) {
1005
		wl1271_error("could not get firmware %s: %d", fw_name, ret);
L
Luciano Coelho 已提交
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015
		return ret;
	}

	if (fw->size % 4) {
		wl1271_error("firmware size is not multiple of 32 bits: %zu",
			     fw->size);
		ret = -EILSEQ;
		goto out;
	}

1016
	vfree(wl->fw);
L
Luciano Coelho 已提交
1017
	wl->fw_len = fw->size;
1018
	wl->fw = vmalloc(wl->fw_len);
L
Luciano Coelho 已提交
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039

	if (!wl->fw) {
		wl1271_error("could not allocate memory for the firmware");
		ret = -ENOMEM;
		goto out;
	}

	memcpy(wl->fw, fw->data, wl->fw_len);
	ret = 0;

out:
	release_firmware(fw);

	return ret;
}

static int wl1271_fetch_nvs(struct wl1271 *wl)
{
	const struct firmware *fw;
	int ret;

1040
	ret = request_firmware(&fw, WL12XX_NVS_NAME, wl->dev);
L
Luciano Coelho 已提交
1041 1042

	if (ret < 0) {
1043 1044
		wl1271_error("could not get nvs file %s: %d", WL12XX_NVS_NAME,
			     ret);
L
Luciano Coelho 已提交
1045 1046 1047
		return ret;
	}

1048
	wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL);
L
Luciano Coelho 已提交
1049 1050 1051 1052 1053 1054 1055

	if (!wl->nvs) {
		wl1271_error("could not allocate memory for the nvs file");
		ret = -ENOMEM;
		goto out;
	}

1056 1057
	wl->nvs_len = fw->size;

L
Luciano Coelho 已提交
1058 1059 1060 1061 1062 1063
out:
	release_firmware(fw);

	return ret;
}

1064 1065 1066 1067 1068 1069
void wl12xx_queue_recovery_work(struct wl1271 *wl)
{
	if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
		ieee80211_queue_work(wl->hw, &wl->recovery_work);
}

1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117
size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
{
	size_t len = 0;

	/* The FW log is a length-value list, find where the log end */
	while (len < maxlen) {
		if (memblock[len] == 0)
			break;
		if (len + memblock[len] + 1 > maxlen)
			break;
		len += memblock[len] + 1;
	}

	/* Make sure we have enough room */
	len = min(len, (size_t)(PAGE_SIZE - wl->fwlog_size));

	/* Fill the FW log file, consumed by the sysfs fwlog entry */
	memcpy(wl->fwlog + wl->fwlog_size, memblock, len);
	wl->fwlog_size += len;

	return len;
}

static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
{
	u32 addr;
	u32 first_addr;
	u8 *block;

	if ((wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED) ||
	    (wl->conf.fwlog.mode != WL12XX_FWLOG_ON_DEMAND) ||
	    (wl->conf.fwlog.mem_blocks == 0))
		return;

	wl1271_info("Reading FW panic log");

	block = kmalloc(WL12XX_HW_BLOCK_SIZE, GFP_KERNEL);
	if (!block)
		return;

	/*
	 * Make sure the chip is awake and the logger isn't active.
	 * This might fail if the firmware hanged.
	 */
	if (!wl1271_ps_elp_wakeup(wl))
		wl12xx_cmd_stop_fwlog(wl);

	/* Read the first memory block address */
E
Eliad Peller 已提交
1118 1119
	wl12xx_fw_status(wl, wl->fw_status);
	first_addr = le32_to_cpu(wl->fw_status->log_start_addr);
1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
	if (!first_addr)
		goto out;

	/* Traverse the memory blocks linked list */
	addr = first_addr;
	do {
		memset(block, 0, WL12XX_HW_BLOCK_SIZE);
		wl1271_read_hwaddr(wl, addr, block, WL12XX_HW_BLOCK_SIZE,
				   false);

		/*
		 * Memory blocks are linked to one another. The first 4 bytes
		 * of each memory block hold the hardware address of the next
		 * one. The last memory block points to the first one.
		 */
E
Eliad Peller 已提交
1135
		addr = le32_to_cpup((__le32 *)block);
1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
		if (!wl12xx_copy_fwlog(wl, block + sizeof(addr),
				       WL12XX_HW_BLOCK_SIZE - sizeof(addr)))
			break;
	} while (addr && (addr != first_addr));

	wake_up_interruptible(&wl->fwlog_waitq);

out:
	kfree(block);
}

1147 1148 1149 1150
static void wl1271_recovery_work(struct work_struct *work)
{
	struct wl1271 *wl =
		container_of(work, struct wl1271, recovery_work);
1151
	struct wl12xx_vif *wlvif;
1152
	struct ieee80211_vif *vif;
1153 1154 1155 1156

	mutex_lock(&wl->mutex);

	if (wl->state != WL1271_STATE_ON)
E
Eliad Peller 已提交
1157
		goto out_unlock;
1158

1159 1160 1161
	/* Avoid a recursive recovery */
	set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);

1162 1163
	wl12xx_read_fwlog_panic(wl);

1164 1165
	wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x",
		    wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4));
1166

1167 1168
	BUG_ON(bug_on_recovery);

1169 1170 1171 1172 1173
	/*
	 * Advance security sequence number to overcome potential progress
	 * in the firmware during recovery. This doens't hurt if the network is
	 * not encrypted.
	 */
1174
	wl12xx_for_each_wlvif(wl, wlvif) {
1175
		if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) ||
1176
		    test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
1177 1178 1179
			wlvif->tx_security_seq +=
				WL1271_TX_SQN_POST_RECOVERY_PADDING;
	}
1180

1181 1182 1183
	/* Prevent spurious TX during FW restart */
	ieee80211_stop_queues(wl->hw);

1184 1185 1186 1187 1188
	if (wl->sched_scanning) {
		ieee80211_sched_scan_stopped(wl->hw);
		wl->sched_scanning = false;
	}

1189
	/* reboot the chipset */
1190 1191 1192 1193 1194 1195
	while (!list_empty(&wl->wlvif_list)) {
		wlvif = list_first_entry(&wl->wlvif_list,
				       struct wl12xx_vif, list);
		vif = wl12xx_wlvif_to_vif(wlvif);
		__wl1271_op_remove_interface(wl, vif, false);
	}
E
Eliad Peller 已提交
1196 1197
	mutex_unlock(&wl->mutex);
	wl1271_op_stop(wl->hw);
1198 1199 1200

	clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);

1201 1202
	ieee80211_restart_hw(wl->hw);

1203 1204 1205 1206 1207
	/*
	 * Its safe to enable TX now - the queues are stopped after a request
	 * to restart the HW.
	 */
	ieee80211_wake_queues(wl->hw);
E
Eliad Peller 已提交
1208 1209
	return;
out_unlock:
1210 1211 1212
	mutex_unlock(&wl->mutex);
}

L
Luciano Coelho 已提交
1213 1214 1215 1216 1217
static void wl1271_fw_wakeup(struct wl1271 *wl)
{
	u32 elp_reg;

	elp_reg = ELPCTRL_WAKE_UP;
1218
	wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
L
Luciano Coelho 已提交
1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235
}

static int wl1271_setup(struct wl1271 *wl)
{
	wl->fw_status = kmalloc(sizeof(*wl->fw_status), GFP_KERNEL);
	if (!wl->fw_status)
		return -ENOMEM;

	wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL);
	if (!wl->tx_res_if) {
		kfree(wl->fw_status);
		return -ENOMEM;
	}

	return 0;
}

1236
static int wl12xx_set_power_on(struct wl1271 *wl)
L
Luciano Coelho 已提交
1237
{
1238
	int ret;
L
Luciano Coelho 已提交
1239

J
Juuso Oikarinen 已提交
1240
	msleep(WL1271_PRE_POWER_ON_SLEEP);
1241 1242 1243
	ret = wl1271_power_on(wl);
	if (ret < 0)
		goto out;
L
Luciano Coelho 已提交
1244
	msleep(WL1271_POWER_ON_SLEEP);
1245 1246
	wl1271_io_reset(wl);
	wl1271_io_init(wl);
L
Luciano Coelho 已提交
1247

1248
	wl1271_set_partition(wl, &wl12xx_part_table[PART_DOWN]);
L
Luciano Coelho 已提交
1249 1250 1251 1252

	/* ELP module wake up */
	wl1271_fw_wakeup(wl);

1253 1254 1255
out:
	return ret;
}
L
Luciano Coelho 已提交
1256

1257 1258 1259 1260 1261 1262 1263
static int wl1271_chip_wakeup(struct wl1271 *wl)
{
	int ret = 0;

	ret = wl12xx_set_power_on(wl);
	if (ret < 0)
		goto out;
L
Luciano Coelho 已提交
1264

1265 1266 1267 1268 1269 1270 1271 1272 1273 1274
	/*
	 * For wl127x based devices we could use the default block
	 * size (512 bytes), but due to a bug in the sdio driver, we
	 * need to set it explicitly after the chip is powered on.  To
	 * simplify the code and since the performance impact is
	 * negligible, we use the same block size for all different
	 * chip types.
	 */
	if (!wl1271_set_block_size(wl))
		wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
L
Luciano Coelho 已提交
1275 1276 1277 1278 1279 1280 1281 1282

	switch (wl->chip.id) {
	case CHIP_ID_1271_PG10:
		wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
			       wl->chip.id);

		ret = wl1271_setup(wl);
		if (ret < 0)
1283
			goto out;
1284
		wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
L
Luciano Coelho 已提交
1285
		break;
1286

L
Luciano Coelho 已提交
1287 1288 1289 1290 1291 1292
	case CHIP_ID_1271_PG20:
		wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
			     wl->chip.id);

		ret = wl1271_setup(wl);
		if (ret < 0)
1293
			goto out;
1294
		wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
L
Luciano Coelho 已提交
1295
		break;
1296

1297 1298 1299 1300 1301 1302 1303 1304 1305
	case CHIP_ID_1283_PG20:
		wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
			     wl->chip.id);

		ret = wl1271_setup(wl);
		if (ret < 0)
			goto out;
		break;
	case CHIP_ID_1283_PG10:
L
Luciano Coelho 已提交
1306
	default:
1307
		wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
L
Luciano Coelho 已提交
1308
		ret = -ENODEV;
1309
		goto out;
L
Luciano Coelho 已提交
1310 1311
	}

1312
	if (wl->fw == NULL) {
L
Luciano Coelho 已提交
1313 1314
		ret = wl1271_fetch_firmware(wl);
		if (ret < 0)
1315
			goto out;
L
Luciano Coelho 已提交
1316 1317 1318 1319 1320 1321
	}

	/* No NVS from netlink, try to get it from the filesystem */
	if (wl->nvs == NULL) {
		ret = wl1271_fetch_nvs(wl);
		if (ret < 0)
1322
			goto out;
L
Luciano Coelho 已提交
1323 1324 1325 1326 1327 1328 1329 1330
	}

out:
	return ret;
}

int wl1271_plt_start(struct wl1271 *wl)
{
1331
	int retries = WL1271_BOOT_RETRIES;
1332
	struct wiphy *wiphy = wl->hw->wiphy;
L
Luciano Coelho 已提交
1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
	int ret;

	mutex_lock(&wl->mutex);

	wl1271_notice("power up");

	if (wl->state != WL1271_STATE_OFF) {
		wl1271_error("cannot go into PLT state because not "
			     "in off state: %d", wl->state);
		ret = -EBUSY;
		goto out;
	}

1346 1347 1348 1349 1350
	while (retries) {
		retries--;
		ret = wl1271_chip_wakeup(wl);
		if (ret < 0)
			goto power_off;
L
Luciano Coelho 已提交
1351

1352 1353 1354
		ret = wl1271_boot(wl);
		if (ret < 0)
			goto power_off;
1355

1356 1357 1358
		ret = wl1271_plt_init(wl);
		if (ret < 0)
			goto irq_disable;
1359

1360 1361
		wl->state = WL1271_STATE_PLT;
		wl1271_notice("firmware booted in PLT mode (%s)",
L
Levi, Shahar 已提交
1362
			      wl->chip.fw_ver_str);
1363

1364 1365 1366 1367 1368
		/* update hw/fw version info in wiphy struct */
		wiphy->hw_version = wl->chip.id;
		strncpy(wiphy->fw_version, wl->chip.fw_ver_str,
			sizeof(wiphy->fw_version));

1369
		goto out;
1370

1371 1372 1373 1374 1375 1376 1377 1378 1379
irq_disable:
		mutex_unlock(&wl->mutex);
		/* Unlocking the mutex in the middle of handling is
		   inherently unsafe. In this case we deem it safe to do,
		   because we need to let any possibly pending IRQ out of
		   the system (and while we are WL1271_STATE_OFF the IRQ
		   work function will not do anything.) Also, any other
		   possible concurrent operations will fail due to the
		   current state, hence the wl1271 struct should be safe. */
1380 1381 1382
		wl1271_disable_interrupts(wl);
		wl1271_flush_deferred_work(wl);
		cancel_work_sync(&wl->netstack_work);
1383 1384 1385 1386
		mutex_lock(&wl->mutex);
power_off:
		wl1271_power_off(wl);
	}
L
Luciano Coelho 已提交
1387

1388 1389
	wl1271_error("firmware boot in PLT mode failed despite %d retries",
		     WL1271_BOOT_RETRIES);
L
Luciano Coelho 已提交
1390 1391 1392 1393 1394 1395
out:
	mutex_unlock(&wl->mutex);

	return ret;
}

1396
int wl1271_plt_stop(struct wl1271 *wl)
L
Luciano Coelho 已提交
1397 1398 1399 1400 1401
{
	int ret = 0;

	wl1271_notice("power down");

1402 1403 1404 1405 1406 1407
	/*
	 * Interrupts must be disabled before setting the state to OFF.
	 * Otherwise, the interrupt handler might be called and exit without
	 * reading the interrupt status.
	 */
	wl1271_disable_interrupts(wl);
1408
	mutex_lock(&wl->mutex);
L
Luciano Coelho 已提交
1409
	if (wl->state != WL1271_STATE_PLT) {
1410
		mutex_unlock(&wl->mutex);
1411 1412 1413 1414 1415 1416 1417 1418

		/*
		 * This will not necessarily enable interrupts as interrupts
		 * may have been disabled when op_stop was called. It will,
		 * however, balance the above call to disable_interrupts().
		 */
		wl1271_enable_interrupts(wl);

L
Luciano Coelho 已提交
1419 1420 1421 1422 1423 1424 1425
		wl1271_error("cannot power down because not in PLT "
			     "state: %d", wl->state);
		ret = -EBUSY;
		goto out;
	}

	mutex_unlock(&wl->mutex);
1426

1427 1428
	wl1271_flush_deferred_work(wl);
	cancel_work_sync(&wl->netstack_work);
1429
	cancel_work_sync(&wl->recovery_work);
1430
	cancel_delayed_work_sync(&wl->elp_work);
1431 1432 1433

	mutex_lock(&wl->mutex);
	wl1271_power_off(wl);
1434 1435 1436
	wl->flags = 0;
	wl->state = WL1271_STATE_OFF;
	wl->rx_counter = 0;
1437 1438
	mutex_unlock(&wl->mutex);

1439 1440 1441 1442
out:
	return ret;
}

1443
static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
L
Luciano Coelho 已提交
1444 1445
{
	struct wl1271 *wl = hw->priv;
1446 1447
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	struct ieee80211_vif *vif = info->control.vif;
E
Eliad Peller 已提交
1448
	struct wl12xx_vif *wlvif = NULL;
1449
	unsigned long flags;
1450
	int q, mapping;
1451
	u8 hlid;
L
Luciano Coelho 已提交
1452

E
Eliad Peller 已提交
1453 1454 1455
	if (vif)
		wlvif = wl12xx_vif_to_data(vif);

1456 1457
	mapping = skb_get_queue_mapping(skb);
	q = wl1271_tx_get_queue(mapping);
I
Ido Yariv 已提交
1458

1459
	hlid = wl12xx_tx_get_hlid(wl, wlvif, skb);
I
Ido Yariv 已提交
1460

1461
	spin_lock_irqsave(&wl->wl_lock, flags);
I
Ido Yariv 已提交
1462

1463
	/* queue the packet */
1464
	if (hlid == WL12XX_INVALID_LINK_ID ||
E
Eliad Peller 已提交
1465
	    (wlvif && !test_bit(hlid, wlvif->links_map))) {
1466
		wl1271_debug(DEBUG_TX, "DROP skb hlid %d q %d", hlid, q);
E
Eliad Peller 已提交
1467
		ieee80211_free_txskb(hw, skb);
1468
		goto out;
1469
	}
L
Luciano Coelho 已提交
1470

1471 1472 1473
	wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q);
	skb_queue_tail(&wl->links[hlid].tx_queue[q], skb);

1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485
	wl->tx_queue_count[q]++;

	/*
	 * The workqueue is slow to process the tx_queue and we need stop
	 * the queue here, otherwise the queue will get too long.
	 */
	if (wl->tx_queue_count[q] >= WL1271_TX_QUEUE_HIGH_WATERMARK) {
		wl1271_debug(DEBUG_TX, "op_tx: stopping queues for q %d", q);
		ieee80211_stop_queue(wl->hw, mapping);
		set_bit(q, &wl->stopped_queues_map);
	}

L
Luciano Coelho 已提交
1486 1487 1488 1489 1490
	/*
	 * The chip specific setup must run before the first TX packet -
	 * before that, the tx_work will not be initialized!
	 */

I
Ido Yariv 已提交
1491 1492
	if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
	    !test_bit(WL1271_FLAG_TX_PENDING, &wl->flags))
I
Ido Yariv 已提交
1493
		ieee80211_queue_work(wl->hw, &wl->tx_work);
I
Ido Yariv 已提交
1494

1495
out:
I
Ido Yariv 已提交
1496
	spin_unlock_irqrestore(&wl->wl_lock, flags);
L
Luciano Coelho 已提交
1497 1498
}

1499 1500
int wl1271_tx_dummy_packet(struct wl1271 *wl)
{
1501
	unsigned long flags;
1502 1503 1504 1505 1506 1507 1508
	int q;

	/* no need to queue a new dummy packet if one is already pending */
	if (test_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags))
		return 0;

	q = wl1271_tx_get_queue(skb_get_queue_mapping(wl->dummy_packet));
1509 1510 1511

	spin_lock_irqsave(&wl->wl_lock, flags);
	set_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags);
1512
	wl->tx_queue_count[q]++;
1513 1514 1515 1516
	spin_unlock_irqrestore(&wl->wl_lock, flags);

	/* The FW is low on RX memory blocks, so send the dummy packet asap */
	if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags))
1517
		wl1271_tx_work_locked(wl);
1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532

	/*
	 * If the FW TX is busy, TX work will be scheduled by the threaded
	 * interrupt handler function
	 */
	return 0;
}

/*
 * The size of the dummy packet should be at least 1400 bytes. However, in
 * order to minimize the number of bus transactions, aligning it to 512 bytes
 * boundaries could be beneficial, performance wise
 */
#define TOTAL_TX_DUMMY_PACKET_SIZE (ALIGN(1400, 512))

1533
static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
1534 1535
{
	struct sk_buff *skb;
1536
	struct ieee80211_hdr_3addr *hdr;
1537 1538 1539 1540
	unsigned int dummy_packet_size;

	dummy_packet_size = TOTAL_TX_DUMMY_PACKET_SIZE -
			    sizeof(struct wl1271_tx_hw_descr) - sizeof(*hdr);
1541

1542
	skb = dev_alloc_skb(TOTAL_TX_DUMMY_PACKET_SIZE);
1543
	if (!skb) {
1544 1545
		wl1271_warning("Failed to allocate a dummy packet skb");
		return NULL;
1546 1547 1548 1549 1550 1551 1552
	}

	skb_reserve(skb, sizeof(struct wl1271_tx_hw_descr));

	hdr = (struct ieee80211_hdr_3addr *) skb_put(skb, sizeof(*hdr));
	memset(hdr, 0, sizeof(*hdr));
	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
1553 1554
					 IEEE80211_STYPE_NULLFUNC |
					 IEEE80211_FCTL_TODS);
1555

1556
	memset(skb_put(skb, dummy_packet_size), 0, dummy_packet_size);
1557

1558 1559
	/* Dummy packets require the TID to be management */
	skb->priority = WL1271_TID_MGMT;
1560

1561
	/* Initialize all fields that might be used */
1562
	skb_set_queue_mapping(skb, 0);
1563
	memset(IEEE80211_SKB_CB(skb), 0, sizeof(struct ieee80211_tx_info));
1564

1565
	return skb;
1566 1567
}

1568

1569 1570 1571 1572
static struct notifier_block wl1271_dev_notifier = {
	.notifier_call = wl1271_dev_notify,
};

1573
#ifdef CONFIG_PM
1574

E
Eliad Peller 已提交
1575 1576
static int wl1271_configure_suspend_ap(struct wl1271 *wl,
				       struct wl12xx_vif *wlvif)
1577
{
1578
	int ret = 0;
1579 1580 1581

	mutex_lock(&wl->mutex);

1582
	if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
1583 1584
		goto out_unlock;

1585 1586 1587 1588
	ret = wl1271_ps_elp_wakeup(wl);
	if (ret < 0)
		goto out_unlock;

E
Eliad Peller 已提交
1589
	ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true);
1590 1591 1592 1593 1594 1595 1596 1597

	wl1271_ps_elp_sleep(wl);
out_unlock:
	mutex_unlock(&wl->mutex);
	return ret;

}

E
Eliad Peller 已提交
1598 1599
static int wl1271_configure_suspend(struct wl1271 *wl,
				    struct wl12xx_vif *wlvif)
1600
{
E
Eliad Peller 已提交
1601
	if (wlvif->bss_type == BSS_TYPE_AP_BSS)
E
Eliad Peller 已提交
1602
		return wl1271_configure_suspend_ap(wl, wlvif);
1603 1604 1605
	return 0;
}

E
Eliad Peller 已提交
1606 1607
static void wl1271_configure_resume(struct wl1271 *wl,
				    struct wl12xx_vif *wlvif)
1608 1609
{
	int ret;
E
Eliad Peller 已提交
1610
	bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
1611

E
Eyal Shapira 已提交
1612
	if (!is_ap)
1613 1614 1615 1616 1617 1618 1619
		return;

	mutex_lock(&wl->mutex);
	ret = wl1271_ps_elp_wakeup(wl);
	if (ret < 0)
		goto out;

E
Eyal Shapira 已提交
1620
	wl1271_acx_beacon_filter_opt(wl, wlvif, false);
1621 1622 1623 1624 1625 1626

	wl1271_ps_elp_sleep(wl);
out:
	mutex_unlock(&wl->mutex);
}

1627 1628 1629 1630
static int wl1271_op_suspend(struct ieee80211_hw *hw,
			    struct cfg80211_wowlan *wow)
{
	struct wl1271 *wl = hw->priv;
1631
	struct wl12xx_vif *wlvif;
1632 1633
	int ret;

1634
	wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow);
1635
	WARN_ON(!wow || !wow->any);
1636

1637
	wl->wow_enabled = true;
1638 1639 1640 1641 1642 1643
	wl12xx_for_each_wlvif(wl, wlvif) {
		ret = wl1271_configure_suspend(wl, wlvif);
		if (ret < 0) {
			wl1271_warning("couldn't prepare device to suspend");
			return ret;
		}
1644 1645 1646
	}
	/* flush any remaining work */
	wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
1647

1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662
	/*
	 * disable and re-enable interrupts in order to flush
	 * the threaded_irq
	 */
	wl1271_disable_interrupts(wl);

	/*
	 * set suspended flag to avoid triggering a new threaded_irq
	 * work. no need for spinlock as interrupts are disabled.
	 */
	set_bit(WL1271_FLAG_SUSPENDED, &wl->flags);

	wl1271_enable_interrupts(wl);
	flush_work(&wl->tx_work);
	flush_delayed_work(&wl->elp_work);
1663

1664 1665 1666 1667 1668 1669
	return 0;
}

static int wl1271_op_resume(struct ieee80211_hw *hw)
{
	struct wl1271 *wl = hw->priv;
1670
	struct wl12xx_vif *wlvif;
1671 1672 1673
	unsigned long flags;
	bool run_irq_work = false;

1674 1675
	wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d",
		     wl->wow_enabled);
1676
	WARN_ON(!wl->wow_enabled);
1677 1678 1679 1680 1681

	/*
	 * re-enable irq_work enqueuing, and call irq_work directly if
	 * there is a pending work.
	 */
1682 1683 1684 1685 1686
	spin_lock_irqsave(&wl->wl_lock, flags);
	clear_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
	if (test_and_clear_bit(WL1271_FLAG_PENDING_WORK, &wl->flags))
		run_irq_work = true;
	spin_unlock_irqrestore(&wl->wl_lock, flags);
1687

1688 1689 1690 1691 1692
	if (run_irq_work) {
		wl1271_debug(DEBUG_MAC80211,
			     "run postponed irq_work directly");
		wl1271_irq(0, wl);
		wl1271_enable_interrupts(wl);
1693
	}
1694 1695 1696
	wl12xx_for_each_wlvif(wl, wlvif) {
		wl1271_configure_resume(wl, wlvif);
	}
1697
	wl->wow_enabled = false;
1698

1699 1700
	return 0;
}
1701
#endif
1702

L
Luciano Coelho 已提交
1703
static int wl1271_op_start(struct ieee80211_hw *hw)
1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717
{
	wl1271_debug(DEBUG_MAC80211, "mac80211 start");

	/*
	 * We have to delay the booting of the hardware because
	 * we need to know the local MAC address before downloading and
	 * initializing the firmware. The MAC address cannot be changed
	 * after boot, and without the proper MAC address, the firmware
	 * will not function properly.
	 *
	 * The MAC address is first known when the corresponding interface
	 * is added. That is where we will initialize the hardware.
	 */

1718
	return 0;
1719 1720 1721 1722
}

static void wl1271_op_stop(struct ieee80211_hw *hw)
{
1723 1724 1725
	struct wl1271 *wl = hw->priv;
	int i;

1726
	wl1271_debug(DEBUG_MAC80211, "mac80211 stop");
1727

1728 1729 1730 1731 1732 1733
	/*
	 * Interrupts must be disabled before setting the state to OFF.
	 * Otherwise, the interrupt handler might be called and exit without
	 * reading the interrupt status.
	 */
	wl1271_disable_interrupts(wl);
1734 1735 1736
	mutex_lock(&wl->mutex);
	if (wl->state == WL1271_STATE_OFF) {
		mutex_unlock(&wl->mutex);
1737 1738 1739 1740 1741 1742 1743

		/*
		 * This will not necessarily enable interrupts as interrupts
		 * may have been disabled when op_stop was called. It will,
		 * however, balance the above call to disable_interrupts().
		 */
		wl1271_enable_interrupts(wl);
1744 1745
		return;
	}
1746

1747 1748 1749 1750 1751
	/*
	 * this must be before the cancel_work calls below, so that the work
	 * functions don't perform further work.
	 */
	wl->state = WL1271_STATE_OFF;
1752 1753 1754 1755
	mutex_unlock(&wl->mutex);

	mutex_lock(&wl_list_mutex);
	list_del(&wl->list);
1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814
	mutex_unlock(&wl_list_mutex);

	wl1271_flush_deferred_work(wl);
	cancel_delayed_work_sync(&wl->scan_complete_work);
	cancel_work_sync(&wl->netstack_work);
	cancel_work_sync(&wl->tx_work);
	cancel_delayed_work_sync(&wl->elp_work);

	/* let's notify MAC80211 about the remaining pending TX frames */
	wl12xx_tx_reset(wl, true);
	mutex_lock(&wl->mutex);

	wl1271_power_off(wl);

	wl->band = IEEE80211_BAND_2GHZ;

	wl->rx_counter = 0;
	wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
	wl->tx_blocks_available = 0;
	wl->tx_allocated_blocks = 0;
	wl->tx_results_count = 0;
	wl->tx_packets_count = 0;
	wl->time_offset = 0;
	wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
	wl->ap_fw_ps_map = 0;
	wl->ap_ps_map = 0;
	wl->sched_scanning = false;
	memset(wl->roles_map, 0, sizeof(wl->roles_map));
	memset(wl->links_map, 0, sizeof(wl->links_map));
	memset(wl->roc_map, 0, sizeof(wl->roc_map));
	wl->active_sta_count = 0;

	/* The system link is always allocated */
	__set_bit(WL12XX_SYSTEM_HLID, wl->links_map);

	/*
	 * this is performed after the cancel_work calls and the associated
	 * mutex_lock, so that wl1271_op_add_interface does not accidentally
	 * get executed before all these vars have been reset.
	 */
	wl->flags = 0;

	wl->tx_blocks_freed = 0;

	for (i = 0; i < NUM_TX_QUEUES; i++) {
		wl->tx_pkts_freed[i] = 0;
		wl->tx_allocated_pkts[i] = 0;
	}

	wl1271_debugfs_reset(wl);

	kfree(wl->fw_status);
	wl->fw_status = NULL;
	kfree(wl->tx_res_if);
	wl->tx_res_if = NULL;
	kfree(wl->target_mem_map);
	wl->target_mem_map = NULL;

	mutex_unlock(&wl->mutex);
1815 1816
}

E
Eliad Peller 已提交
1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837
static int wl12xx_allocate_rate_policy(struct wl1271 *wl, u8 *idx)
{
	u8 policy = find_first_zero_bit(wl->rate_policies_map,
					WL12XX_MAX_RATE_POLICIES);
	if (policy >= WL12XX_MAX_RATE_POLICIES)
		return -EBUSY;

	__set_bit(policy, wl->rate_policies_map);
	*idx = policy;
	return 0;
}

static void wl12xx_free_rate_policy(struct wl1271 *wl, u8 *idx)
{
	if (WARN_ON(*idx >= WL12XX_MAX_RATE_POLICIES))
		return;

	__clear_bit(*idx, wl->rate_policies_map);
	*idx = WL12XX_MAX_RATE_POLICIES;
}

E
Eliad Peller 已提交
1838
static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1839
{
E
Eliad Peller 已提交
1840
	switch (wlvif->bss_type) {
1841
	case BSS_TYPE_AP_BSS:
E
Eliad Peller 已提交
1842
		if (wlvif->p2p)
E
Eliad Peller 已提交
1843 1844 1845
			return WL1271_ROLE_P2P_GO;
		else
			return WL1271_ROLE_AP;
1846 1847

	case BSS_TYPE_STA_BSS:
E
Eliad Peller 已提交
1848
		if (wlvif->p2p)
E
Eliad Peller 已提交
1849 1850 1851
			return WL1271_ROLE_P2P_CL;
		else
			return WL1271_ROLE_STA;
1852

E
Eliad Peller 已提交
1853 1854 1855
	case BSS_TYPE_IBSS:
		return WL1271_ROLE_IBSS;

1856
	default:
E
Eliad Peller 已提交
1857
		wl1271_error("invalid bss_type: %d", wlvif->bss_type);
1858 1859 1860 1861
	}
	return WL12XX_INVALID_ROLE_TYPE;
}

1862
static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
E
Eliad Peller 已提交
1863
{
1864
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
E
Eliad Peller 已提交
1865
	int i;
1866

1867 1868
	/* clear everything but the persistent data */
	memset(wlvif, 0, offsetof(struct wl12xx_vif, persistent));
1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890

	switch (ieee80211_vif_type_p2p(vif)) {
	case NL80211_IFTYPE_P2P_CLIENT:
		wlvif->p2p = 1;
		/* fall-through */
	case NL80211_IFTYPE_STATION:
		wlvif->bss_type = BSS_TYPE_STA_BSS;
		break;
	case NL80211_IFTYPE_ADHOC:
		wlvif->bss_type = BSS_TYPE_IBSS;
		break;
	case NL80211_IFTYPE_P2P_GO:
		wlvif->p2p = 1;
		/* fall-through */
	case NL80211_IFTYPE_AP:
		wlvif->bss_type = BSS_TYPE_AP_BSS;
		break;
	default:
		wlvif->bss_type = MAX_BSS_TYPE;
		return -EOPNOTSUPP;
	}

E
Eliad Peller 已提交
1891
	wlvif->role_id = WL12XX_INVALID_ROLE_ID;
E
Eliad Peller 已提交
1892
	wlvif->dev_role_id = WL12XX_INVALID_ROLE_ID;
E
Eliad Peller 已提交
1893
	wlvif->dev_hlid = WL12XX_INVALID_LINK_ID;
1894

1895 1896 1897 1898
	if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
	    wlvif->bss_type == BSS_TYPE_IBSS) {
		/* init sta/ibss data */
		wlvif->sta.hlid = WL12XX_INVALID_LINK_ID;
E
Eliad Peller 已提交
1899 1900 1901
		wl12xx_allocate_rate_policy(wl, &wlvif->sta.basic_rate_idx);
		wl12xx_allocate_rate_policy(wl, &wlvif->sta.ap_rate_idx);
		wl12xx_allocate_rate_policy(wl, &wlvif->sta.p2p_rate_idx);
1902 1903 1904 1905
	} else {
		/* init ap data */
		wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID;
		wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID;
E
Eliad Peller 已提交
1906 1907 1908 1909 1910
		wl12xx_allocate_rate_policy(wl, &wlvif->ap.mgmt_rate_idx);
		wl12xx_allocate_rate_policy(wl, &wlvif->ap.bcast_rate_idx);
		for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++)
			wl12xx_allocate_rate_policy(wl,
						&wlvif->ap.ucast_rate_idx[i]);
1911
	}
1912

1913 1914
	wlvif->bitrate_masks[IEEE80211_BAND_2GHZ] = wl->conf.tx.basic_rate;
	wlvif->bitrate_masks[IEEE80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5;
E
Eliad Peller 已提交
1915
	wlvif->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
E
Eliad Peller 已提交
1916
	wlvif->basic_rate = CONF_TX_RATE_MASK_BASIC;
E
Eliad Peller 已提交
1917
	wlvif->rate_set = CONF_TX_RATE_MASK_BASIC;
E
Eliad Peller 已提交
1918 1919
	wlvif->beacon_int = WL1271_DEFAULT_BEACON_INT;

E
Eliad Peller 已提交
1920 1921 1922 1923 1924
	/*
	 * mac80211 configures some values globally, while we treat them
	 * per-interface. thus, on init, we have to copy them from wl
	 */
	wlvif->band = wl->band;
E
Eliad Peller 已提交
1925
	wlvif->channel = wl->channel;
1926
	wlvif->power_level = wl->power_level;
E
Eliad Peller 已提交
1927

E
Eliad Peller 已提交
1928 1929 1930 1931
	INIT_WORK(&wlvif->rx_streaming_enable_work,
		  wl1271_rx_streaming_enable_work);
	INIT_WORK(&wlvif->rx_streaming_disable_work,
		  wl1271_rx_streaming_disable_work);
E
Eliad Peller 已提交
1932
	INIT_LIST_HEAD(&wlvif->list);
E
Eliad Peller 已提交
1933

E
Eliad Peller 已提交
1934 1935
	setup_timer(&wlvif->rx_streaming_timer, wl1271_rx_streaming_timer,
		    (unsigned long) wlvif);
1936
	return 0;
E
Eliad Peller 已提交
1937 1938
}

1939
static bool wl12xx_init_fw(struct wl1271 *wl)
L
Luciano Coelho 已提交
1940
{
1941
	int retries = WL1271_BOOT_RETRIES;
1942
	bool booted = false;
1943 1944
	struct wiphy *wiphy = wl->hw->wiphy;
	int ret;
L
Luciano Coelho 已提交
1945

1946 1947 1948 1949 1950
	while (retries) {
		retries--;
		ret = wl1271_chip_wakeup(wl);
		if (ret < 0)
			goto power_off;
L
Luciano Coelho 已提交
1951

1952 1953 1954
		ret = wl1271_boot(wl);
		if (ret < 0)
			goto power_off;
L
Luciano Coelho 已提交
1955

1956 1957 1958 1959
		ret = wl1271_hw_init(wl);
		if (ret < 0)
			goto irq_disable;

1960 1961
		booted = true;
		break;
1962

1963 1964 1965 1966 1967 1968 1969 1970 1971
irq_disable:
		mutex_unlock(&wl->mutex);
		/* Unlocking the mutex in the middle of handling is
		   inherently unsafe. In this case we deem it safe to do,
		   because we need to let any possibly pending IRQ out of
		   the system (and while we are WL1271_STATE_OFF the IRQ
		   work function will not do anything.) Also, any other
		   possible concurrent operations will fail due to the
		   current state, hence the wl1271 struct should be safe. */
1972 1973 1974
		wl1271_disable_interrupts(wl);
		wl1271_flush_deferred_work(wl);
		cancel_work_sync(&wl->netstack_work);
1975 1976 1977 1978
		mutex_lock(&wl->mutex);
power_off:
		wl1271_power_off(wl);
	}
1979

1980 1981 1982 1983 1984 1985
	if (!booted) {
		wl1271_error("firmware boot failed despite %d retries",
			     WL1271_BOOT_RETRIES);
		goto out;
	}

L
Levi, Shahar 已提交
1986
	wl1271_info("firmware booted (%s)", wl->chip.fw_ver_str);
1987 1988 1989

	/* update hw/fw version info in wiphy struct */
	wiphy->hw_version = wl->chip.id;
L
Levi, Shahar 已提交
1990
	strncpy(wiphy->fw_version, wl->chip.fw_ver_str,
1991 1992
		sizeof(wiphy->fw_version));

1993 1994 1995 1996 1997 1998 1999 2000 2001 2002
	/*
	 * Now we know if 11a is supported (info from the NVS), so disable
	 * 11a channels if not supported
	 */
	if (!wl->enable_11a)
		wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels = 0;

	wl1271_debug(DEBUG_MAC80211, "11a is %ssupported",
		     wl->enable_11a ? "" : "not ");

2003 2004 2005 2006 2007
	wl->state = WL1271_STATE_ON;
out:
	return booted;
}

2008 2009 2010 2011 2012
static bool wl12xx_dev_role_started(struct wl12xx_vif *wlvif)
{
	return wlvif->dev_hlid != WL12XX_INVALID_LINK_ID;
}

2013 2014 2015 2016 2017 2018 2019 2020 2021
static int wl1271_op_add_interface(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif)
{
	struct wl1271 *wl = hw->priv;
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
	int ret = 0;
	u8 role_type;
	bool booted = false;

2022 2023
	vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
			     IEEE80211_VIF_SUPPORTS_CQM_RSSI;
2024

2025 2026 2027 2028
	wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
		     ieee80211_vif_type_p2p(vif), vif->addr);

	mutex_lock(&wl->mutex);
2029 2030 2031 2032
	ret = wl1271_ps_elp_wakeup(wl);
	if (ret < 0)
		goto out_unlock;

2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044
	if (wl->vif) {
		wl1271_debug(DEBUG_MAC80211,
			     "multiple vifs are not supported yet");
		ret = -EBUSY;
		goto out;
	}

	/*
	 * in some very corner case HW recovery scenarios its possible to
	 * get here before __wl1271_op_remove_interface is complete, so
	 * opt out if that is the case.
	 */
2045 2046
	if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags) ||
	    test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) {
2047 2048 2049 2050
		ret = -EBUSY;
		goto out;
	}

2051
	ret = wl12xx_init_vif_data(wl, vif);
2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070
	if (ret < 0)
		goto out;

	wlvif->wl = wl;
	role_type = wl12xx_get_role_type(wl, wlvif);
	if (role_type == WL12XX_INVALID_ROLE_TYPE) {
		ret = -EINVAL;
		goto out;
	}

	/*
	 * TODO: after the nvs issue will be solved, move this block
	 * to start(), and make sure here the driver is ON.
	 */
	if (wl->state == WL1271_STATE_OFF) {
		/*
		 * we still need this in order to configure the fw
		 * while uploading the nvs
		 */
2071
		memcpy(wl->addresses[0].addr, vif->addr, ETH_ALEN);
2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104

		booted = wl12xx_init_fw(wl);
		if (!booted) {
			ret = -EINVAL;
			goto out;
		}
	}

	if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
	    wlvif->bss_type == BSS_TYPE_IBSS) {
		/*
		 * The device role is a special role used for
		 * rx and tx frames prior to association (as
		 * the STA role can get packets only from
		 * its associated bssid)
		 */
		ret = wl12xx_cmd_role_enable(wl, vif->addr,
						 WL1271_ROLE_DEVICE,
						 &wlvif->dev_role_id);
		if (ret < 0)
			goto out;
	}

	ret = wl12xx_cmd_role_enable(wl, vif->addr,
				     role_type, &wlvif->role_id);
	if (ret < 0)
		goto out;

	ret = wl1271_init_vif_specific(wl, vif);
	if (ret < 0)
		goto out;

	wl->vif = vif;
E
Eliad Peller 已提交
2105
	list_add(&wlvif->list, &wl->wlvif_list);
2106
	set_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags);
2107 2108 2109 2110 2111

	if (wlvif->bss_type == BSS_TYPE_AP_BSS)
		wl->ap_count++;
	else
		wl->sta_count++;
2112
out:
2113 2114
	wl1271_ps_elp_sleep(wl);
out_unlock:
L
Luciano Coelho 已提交
2115 2116
	mutex_unlock(&wl->mutex);

2117
	mutex_lock(&wl_list_mutex);
2118
	if (!ret)
2119
		list_add(&wl->list, &wl_list);
2120
	mutex_unlock(&wl_list_mutex);
2121

L
Luciano Coelho 已提交
2122 2123 2124
	return ret;
}

2125
static void __wl1271_op_remove_interface(struct wl1271 *wl,
E
Eliad Peller 已提交
2126
					 struct ieee80211_vif *vif,
2127
					 bool reset_tx_queues)
L
Luciano Coelho 已提交
2128
{
E
Eliad Peller 已提交
2129
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
E
Eliad Peller 已提交
2130
	int i, ret;
L
Luciano Coelho 已提交
2131

2132
	wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
L
Luciano Coelho 已提交
2133

2134 2135 2136
	if (!test_and_clear_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
		return;

2137 2138
	wl->vif = NULL;

2139 2140 2141 2142
	/* because of hardware recovery, we may get here twice */
	if (wl->state != WL1271_STATE_ON)
		return;

2143
	wl1271_info("down");
L
Luciano Coelho 已提交
2144

2145 2146
	if (wl->scan.state != WL1271_SCAN_STATE_IDLE &&
	    wl->scan_vif == vif) {
L
Luciano Coelho 已提交
2147
		wl->scan.state = WL1271_SCAN_STATE_IDLE;
2148
		memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
2149
		wl->scan_vif = NULL;
2150
		wl->scan.req = NULL;
2151
		ieee80211_scan_completed(wl->hw, true);
L
Luciano Coelho 已提交
2152 2153
	}

2154 2155 2156 2157 2158 2159
	if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) {
		/* disable active roles */
		ret = wl1271_ps_elp_wakeup(wl);
		if (ret < 0)
			goto deinit;

2160 2161 2162 2163 2164
		if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
		    wlvif->bss_type == BSS_TYPE_IBSS) {
			if (wl12xx_dev_role_started(wlvif))
				wl12xx_stop_dev(wl, wlvif);

E
Eliad Peller 已提交
2165
			ret = wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id);
E
Eliad Peller 已提交
2166 2167 2168 2169
			if (ret < 0)
				goto deinit;
		}

E
Eliad Peller 已提交
2170
		ret = wl12xx_cmd_role_disable(wl, &wlvif->role_id);
2171 2172 2173 2174 2175 2176
		if (ret < 0)
			goto deinit;

		wl1271_ps_elp_sleep(wl);
	}
deinit:
2177
	/* clear all hlids (except system_hlid) */
E
Eliad Peller 已提交
2178
	wlvif->dev_hlid = WL12XX_INVALID_LINK_ID;
E
Eliad Peller 已提交
2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194

	if (wlvif->bss_type == BSS_TYPE_STA_BSS ||
	    wlvif->bss_type == BSS_TYPE_IBSS) {
		wlvif->sta.hlid = WL12XX_INVALID_LINK_ID;
		wl12xx_free_rate_policy(wl, &wlvif->sta.basic_rate_idx);
		wl12xx_free_rate_policy(wl, &wlvif->sta.ap_rate_idx);
		wl12xx_free_rate_policy(wl, &wlvif->sta.p2p_rate_idx);
	} else {
		wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID;
		wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID;
		wl12xx_free_rate_policy(wl, &wlvif->ap.mgmt_rate_idx);
		wl12xx_free_rate_policy(wl, &wlvif->ap.bcast_rate_idx);
		for (i = 0; i < CONF_TX_MAX_AC_COUNT; i++)
			wl12xx_free_rate_policy(wl,
						&wlvif->ap.ucast_rate_idx[i]);
	}
2195

2196
	wl12xx_tx_reset_wlvif(wl, wlvif);
2197
	wl1271_free_ap_keys(wl, wlvif);
2198 2199
	if (wl->last_wlvif == wlvif)
		wl->last_wlvif = NULL;
E
Eliad Peller 已提交
2200
	list_del(&wlvif->list);
2201
	memset(wlvif->ap.sta_hlid_map, 0, sizeof(wlvif->ap.sta_hlid_map));
E
Eliad Peller 已提交
2202
	wlvif->role_id = WL12XX_INVALID_ROLE_ID;
E
Eliad Peller 已提交
2203
	wlvif->dev_role_id = WL12XX_INVALID_ROLE_ID;
2204

2205 2206 2207 2208 2209
	if (wlvif->bss_type == BSS_TYPE_AP_BSS)
		wl->ap_count--;
	else
		wl->sta_count--;

2210
	mutex_unlock(&wl->mutex);
E
Eyal Shapira 已提交
2211

E
Eliad Peller 已提交
2212 2213 2214
	del_timer_sync(&wlvif->rx_streaming_timer);
	cancel_work_sync(&wlvif->rx_streaming_enable_work);
	cancel_work_sync(&wlvif->rx_streaming_disable_work);
2215

2216
	mutex_lock(&wl->mutex);
2217
}
2218

2219 2220 2221 2222
static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
				       struct ieee80211_vif *vif)
{
	struct wl1271 *wl = hw->priv;
2223
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
2224
	struct wl12xx_vif *iter;
2225 2226

	mutex_lock(&wl->mutex);
2227 2228 2229 2230 2231

	if (wl->state == WL1271_STATE_OFF ||
	    !test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
		goto out;

2232 2233 2234 2235
	/*
	 * wl->vif can be null here if someone shuts down the interface
	 * just when hardware recovery has been started.
	 */
2236 2237 2238 2239
	wl12xx_for_each_wlvif(wl, iter) {
		if (iter != wlvif)
			continue;

E
Eliad Peller 已提交
2240
		__wl1271_op_remove_interface(wl, vif, true);
2241
		break;
2242
	}
2243
	WARN_ON(iter != wlvif);
2244
out:
2245
	mutex_unlock(&wl->mutex);
2246
	cancel_work_sync(&wl->recovery_work);
L
Luciano Coelho 已提交
2247 2248
}

E
Eliad Peller 已提交
2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259
static int wl12xx_op_change_interface(struct ieee80211_hw *hw,
				      struct ieee80211_vif *vif,
				      enum nl80211_iftype new_type, bool p2p)
{
	wl1271_op_remove_interface(hw, vif);

	vif->type = ieee80211_iftype_p2p(new_type, p2p);
	vif->p2p = p2p;
	return wl1271_op_add_interface(hw, vif);
}

E
Eliad Peller 已提交
2260 2261
static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif,
			  bool set_assoc)
2262 2263
{
	int ret;
E
Eliad Peller 已提交
2264
	bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS);
2265

2266 2267 2268 2269
	/*
	 * One of the side effects of the JOIN command is that is clears
	 * WPA/WPA2 keys from the chipset. Performing a JOIN while associated
	 * to a WPA/WPA2 access point will therefore kill the data-path.
2270 2271 2272 2273
	 * Currently the only valid scenario for JOIN during association
	 * is on roaming, in which case we will also be given new keys.
	 * Keep the below message for now, unless it starts bothering
	 * users who really like to roam a lot :)
2274
	 */
2275
	if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
2276 2277 2278
		wl1271_info("JOIN while associated.");

	if (set_assoc)
2279
		set_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags);
2280

E
Eliad Peller 已提交
2281
	if (is_ibss)
E
Eliad Peller 已提交
2282
		ret = wl12xx_cmd_role_start_ibss(wl, wlvif);
E
Eliad Peller 已提交
2283
	else
E
Eliad Peller 已提交
2284
		ret = wl12xx_cmd_role_start_sta(wl, wlvif);
2285 2286 2287
	if (ret < 0)
		goto out;

2288
	if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
2289 2290 2291 2292 2293 2294 2295 2296
		goto out;

	/*
	 * The join command disable the keep-alive mode, shut down its process,
	 * and also clear the template config, so we need to reset it all after
	 * the join. The acx_aid starts the keep-alive process, and the order
	 * of the commands below is relevant.
	 */
E
Eliad Peller 已提交
2297
	ret = wl1271_acx_keep_alive_mode(wl, wlvif, true);
2298 2299 2300
	if (ret < 0)
		goto out;

E
Eliad Peller 已提交
2301
	ret = wl1271_acx_aid(wl, wlvif, wlvif->aid);
2302 2303 2304
	if (ret < 0)
		goto out;

E
Eliad Peller 已提交
2305
	ret = wl12xx_cmd_build_klv_null_data(wl, wlvif);
2306 2307 2308
	if (ret < 0)
		goto out;

E
Eliad Peller 已提交
2309 2310
	ret = wl1271_acx_keep_alive_config(wl, wlvif,
					   CMD_TEMPL_KLV_IDX_NULL_DATA,
2311 2312 2313 2314 2315 2316 2317 2318
					   ACX_KEEP_ALIVE_TPL_VALID);
	if (ret < 0)
		goto out;

out:
	return ret;
}

E
Eliad Peller 已提交
2319
static int wl1271_unjoin(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2320 2321 2322
{
	int ret;

2323
	if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) {
2324 2325
		struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);

2326
		wl12xx_cmd_stop_channel_switch(wl);
2327
		ieee80211_chswitch_done(vif, false);
2328 2329
	}

2330
	/* to stop listening to a channel, we disconnect */
E
Eliad Peller 已提交
2331
	ret = wl12xx_cmd_role_stop_sta(wl, wlvif);
2332 2333 2334
	if (ret < 0)
		goto out;

2335
	/* reset TX security counters on a clean disconnect */
2336 2337
	wlvif->tx_security_last_seq_lsb = 0;
	wlvif->tx_security_seq = 0;
2338

2339 2340 2341 2342
out:
	return ret;
}

E
Eliad Peller 已提交
2343
static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2344
{
E
Eliad Peller 已提交
2345
	wlvif->basic_rate_set = wlvif->bitrate_masks[wlvif->band];
E
Eliad Peller 已提交
2346
	wlvif->rate_set = wlvif->basic_rate_set;
2347 2348
}

E
Eliad Peller 已提交
2349 2350
static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
				  bool idle)
2351 2352
{
	int ret;
2353 2354 2355 2356
	bool cur_idle = !test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);

	if (idle == cur_idle)
		return 0;
2357 2358

	if (idle) {
2359
		/* no need to croc if we weren't busy (e.g. during boot) */
2360
		if (wl12xx_dev_role_started(wlvif)) {
2361
			ret = wl12xx_stop_dev(wl, wlvif);
2362 2363 2364
			if (ret < 0)
				goto out;
		}
E
Eliad Peller 已提交
2365 2366 2367
		wlvif->rate_set =
			wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
		ret = wl1271_acx_sta_rate_policies(wl, wlvif);
2368 2369 2370
		if (ret < 0)
			goto out;
		ret = wl1271_acx_keep_alive_config(
E
Eliad Peller 已提交
2371
			wl, wlvif, CMD_TEMPL_KLV_IDX_NULL_DATA,
2372 2373 2374
			ACX_KEEP_ALIVE_TPL_INVALID);
		if (ret < 0)
			goto out;
2375
		clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
2376
	} else {
2377 2378 2379 2380 2381 2382
		/* The current firmware only supports sched_scan in idle */
		if (wl->sched_scanning) {
			wl1271_scan_sched_scan_stop(wl);
			ieee80211_sched_scan_stopped(wl->hw);
		}

2383
		ret = wl12xx_start_dev(wl, wlvif);
2384 2385
		if (ret < 0)
			goto out;
2386
		set_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
2387 2388 2389 2390 2391 2392
	}

out:
	return ret;
}

2393 2394
static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
			     struct ieee80211_conf *conf, u32 changed)
L
Luciano Coelho 已提交
2395
{
2396 2397
	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
	int channel, ret;
L
Luciano Coelho 已提交
2398 2399 2400

	channel = ieee80211_frequency_to_channel(conf->channel->center_freq);

2401
	/* if the channel changes while joined, join again */
2402
	if (changed & IEEE80211_CONF_CHANGE_CHANNEL &&
E
Eliad Peller 已提交
2403
	    ((wlvif->band != conf->channel->band) ||
E
Eliad Peller 已提交
2404
	     (wlvif->channel != channel))) {
2405
		/* send all pending packets */
2406
		wl1271_tx_work_locked(wl);
E
Eliad Peller 已提交
2407 2408
		wlvif->band = conf->channel->band;
		wlvif->channel = channel;
2409

2410 2411 2412 2413 2414 2415 2416
		if (!is_ap) {
			/*
			 * FIXME: the mac80211 should really provide a fixed
			 * rate to use here. for now, just use the smallest
			 * possible rate for the band as a fixed rate for
			 * association frames and other control messages.
			 */
2417
			if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
E
Eliad Peller 已提交
2418
				wl1271_set_band_rate(wl, wlvif);
2419

E
Eliad Peller 已提交
2420
			wlvif->basic_rate =
E
Eliad Peller 已提交
2421 2422
				wl1271_tx_min_rate_get(wl,
						       wlvif->basic_rate_set);
E
Eliad Peller 已提交
2423
			ret = wl1271_acx_sta_rate_policies(wl, wlvif);
2424
			if (ret < 0)
2425
				wl1271_warning("rate policy for channel "
2426
					       "failed %d", ret);
2427

2428 2429
			if (test_bit(WLVIF_FLAG_STA_ASSOCIATED,
				     &wlvif->flags)) {
2430
				if (wl12xx_dev_role_started(wlvif)) {
2431
					/* roaming */
E
Eliad Peller 已提交
2432 2433
					ret = wl12xx_croc(wl,
							  wlvif->dev_role_id);
2434
					if (ret < 0)
2435
						return ret;
2436
				}
E
Eliad Peller 已提交
2437
				ret = wl1271_join(wl, wlvif, false);
2438 2439 2440
				if (ret < 0)
					wl1271_warning("cmd join on channel "
						       "failed %d", ret);
2441 2442 2443 2444 2445 2446
			} else {
				/*
				 * change the ROC channel. do it only if we are
				 * not idle. otherwise, CROC will be called
				 * anyway.
				 */
2447
				if (wl12xx_dev_role_started(wlvif) &&
2448
				    !(conf->flags & IEEE80211_CONF_IDLE)) {
2449
					ret = wl12xx_stop_dev(wl, wlvif);
2450
					if (ret < 0)
2451
						return ret;
2452

2453
					ret = wl12xx_start_dev(wl, wlvif);
2454
					if (ret < 0)
2455
						return ret;
2456
				}
2457
			}
2458 2459 2460
		}
	}

2461 2462 2463 2464 2465 2466 2467
	if ((changed & IEEE80211_CONF_CHANGE_PS) && !is_ap) {

		if ((conf->flags & IEEE80211_CONF_PS) &&
		    test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
		    !test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags)) {

			wl1271_debug(DEBUG_PSM, "auto ps enabled");
L
Luciano Coelho 已提交
2468

E
Eliad Peller 已提交
2469
			ret = wl1271_ps_set_mode(wl, wlvif,
2470
						 STATION_AUTO_PS_MODE);
2471 2472
			if (ret < 0)
				wl1271_warning("enter auto ps failed %d", ret);
L
Luciano Coelho 已提交
2473

2474 2475 2476 2477
		} else if (!(conf->flags & IEEE80211_CONF_PS) &&
			   test_bit(WLVIF_FLAG_IN_AUTO_PS, &wlvif->flags)) {

			wl1271_debug(DEBUG_PSM, "auto ps disabled");
L
Luciano Coelho 已提交
2478

E
Eliad Peller 已提交
2479
			ret = wl1271_ps_set_mode(wl, wlvif,
2480
						 STATION_ACTIVE_MODE);
2481 2482 2483
			if (ret < 0)
				wl1271_warning("exit auto ps failed %d", ret);
		}
L
Luciano Coelho 已提交
2484 2485
	}

2486
	if (conf->power_level != wlvif->power_level) {
E
Eliad Peller 已提交
2487
		ret = wl1271_acx_tx_power(wl, wlvif, conf->power_level);
L
Luciano Coelho 已提交
2488
		if (ret < 0)
2489
			return ret;
L
Luciano Coelho 已提交
2490

2491
		wlvif->power_level = conf->power_level;
L
Luciano Coelho 已提交
2492 2493
	}

2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547
	return 0;
}

static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
{
	struct wl1271 *wl = hw->priv;
	struct wl12xx_vif *wlvif;
	struct ieee80211_conf *conf = &hw->conf;
	int channel, ret = 0;

	channel = ieee80211_frequency_to_channel(conf->channel->center_freq);

	wl1271_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d %s"
		     " changed 0x%x",
		     channel,
		     conf->flags & IEEE80211_CONF_PS ? "on" : "off",
		     conf->power_level,
		     conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use",
			 changed);

	/*
	 * mac80211 will go to idle nearly immediately after transmitting some
	 * frames, such as the deauth. To make sure those frames reach the air,
	 * wait here until the TX queue is fully flushed.
	 */
	if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
	    (conf->flags & IEEE80211_CONF_IDLE))
		wl1271_tx_flush(wl);

	mutex_lock(&wl->mutex);

	/* we support configuring the channel and band even while off */
	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
		wl->band = conf->channel->band;
		wl->channel = channel;
	}

	if (changed & IEEE80211_CONF_CHANGE_POWER)
		wl->power_level = conf->power_level;

	if (unlikely(wl->state == WL1271_STATE_OFF))
		goto out;

	ret = wl1271_ps_elp_wakeup(wl);
	if (ret < 0)
		goto out;

	/* configure each interface */
	wl12xx_for_each_wlvif(wl, wlvif) {
		ret = wl12xx_config_vif(wl, wlvif, conf, changed);
		if (ret < 0)
			goto out_sleep;
	}

L
Luciano Coelho 已提交
2548 2549 2550 2551 2552 2553 2554 2555 2556
out_sleep:
	wl1271_ps_elp_sleep(wl);

out:
	mutex_unlock(&wl->mutex);

	return ret;
}

J
Juuso Oikarinen 已提交
2557 2558 2559 2560 2561 2562
struct wl1271_filter_params {
	bool enabled;
	int mc_list_length;
	u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN];
};

2563 2564
static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw,
				       struct netdev_hw_addr_list *mc_list)
2565 2566
{
	struct wl1271_filter_params *fp;
2567
	struct netdev_hw_addr *ha;
2568
	struct wl1271 *wl = hw->priv;
2569

2570 2571
	if (unlikely(wl->state == WL1271_STATE_OFF))
		return 0;
2572

2573
	fp = kzalloc(sizeof(*fp), GFP_ATOMIC);
2574 2575 2576 2577 2578 2579 2580
	if (!fp) {
		wl1271_error("Out of memory setting filters.");
		return 0;
	}

	/* update multicast filtering parameters */
	fp->mc_list_length = 0;
2581 2582 2583 2584 2585
	if (netdev_hw_addr_list_count(mc_list) > ACX_MC_ADDRESS_GROUP_MAX) {
		fp->enabled = false;
	} else {
		fp->enabled = true;
		netdev_hw_addr_list_for_each(ha, mc_list) {
2586
			memcpy(fp->mc_list[fp->mc_list_length],
2587
					ha->addr, ETH_ALEN);
2588
			fp->mc_list_length++;
2589
		}
2590 2591
	}

J
Juuso Oikarinen 已提交
2592
	return (u64)(unsigned long)fp;
2593
}
L
Luciano Coelho 已提交
2594

J
Juuso Oikarinen 已提交
2595 2596 2597 2598 2599 2600 2601
#define WL1271_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
				  FIF_ALLMULTI | \
				  FIF_FCSFAIL | \
				  FIF_BCN_PRBRESP_PROMISC | \
				  FIF_CONTROL | \
				  FIF_OTHER_BSS)

L
Luciano Coelho 已提交
2602 2603
static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
				       unsigned int changed,
2604
				       unsigned int *total, u64 multicast)
L
Luciano Coelho 已提交
2605
{
J
Juuso Oikarinen 已提交
2606
	struct wl1271_filter_params *fp = (void *)(unsigned long)multicast;
L
Luciano Coelho 已提交
2607
	struct wl1271 *wl = hw->priv;
2608
	struct wl12xx_vif *wlvif;
E
Eliad Peller 已提交
2609

J
Juuso Oikarinen 已提交
2610
	int ret;
L
Luciano Coelho 已提交
2611

2612 2613
	wl1271_debug(DEBUG_MAC80211, "mac80211 configure filter changed %x"
		     " total %x", changed, *total);
L
Luciano Coelho 已提交
2614

J
Juuso Oikarinen 已提交
2615 2616
	mutex_lock(&wl->mutex);

2617 2618 2619 2620
	*total &= WL1271_SUPPORTED_FILTERS;
	changed &= WL1271_SUPPORTED_FILTERS;

	if (unlikely(wl->state == WL1271_STATE_OFF))
J
Juuso Oikarinen 已提交
2621 2622
		goto out;

2623
	ret = wl1271_ps_elp_wakeup(wl);
J
Juuso Oikarinen 已提交
2624 2625 2626
	if (ret < 0)
		goto out;

2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640
	wl12xx_for_each_wlvif(wl, wlvif) {
		if (wlvif->bss_type != BSS_TYPE_AP_BSS) {
			if (*total & FIF_ALLMULTI)
				ret = wl1271_acx_group_address_tbl(wl, wlvif,
								   false,
								   NULL, 0);
			else if (fp)
				ret = wl1271_acx_group_address_tbl(wl, wlvif,
							fp->enabled,
							fp->mc_list,
							fp->mc_list_length);
			if (ret < 0)
				goto out_sleep;
		}
2641
	}
L
Luciano Coelho 已提交
2642

E
Eliad Peller 已提交
2643 2644 2645 2646 2647
	/*
	 * the fw doesn't provide an api to configure the filters. instead,
	 * the filters configuration is based on the active roles / ROC
	 * state.
	 */
J
Juuso Oikarinen 已提交
2648 2649 2650 2651 2652 2653

out_sleep:
	wl1271_ps_elp_sleep(wl);

out:
	mutex_unlock(&wl->mutex);
2654
	kfree(fp);
L
Luciano Coelho 已提交
2655 2656
}

2657 2658 2659 2660
static int wl1271_record_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
				u8 id, u8 key_type, u8 key_size,
				const u8 *key, u8 hlid, u32 tx_seq_32,
				u16 tx_seq_16)
2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674
{
	struct wl1271_ap_key *ap_key;
	int i;

	wl1271_debug(DEBUG_CRYPT, "record ap key id %d", (int)id);

	if (key_size > MAX_KEY_SIZE)
		return -EINVAL;

	/*
	 * Find next free entry in ap_keys. Also check we are not replacing
	 * an existing key.
	 */
	for (i = 0; i < MAX_NUM_KEYS; i++) {
2675
		if (wlvif->ap.recorded_keys[i] == NULL)
2676 2677
			break;

2678
		if (wlvif->ap.recorded_keys[i]->id == id) {
2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698
			wl1271_warning("trying to record key replacement");
			return -EINVAL;
		}
	}

	if (i == MAX_NUM_KEYS)
		return -EBUSY;

	ap_key = kzalloc(sizeof(*ap_key), GFP_KERNEL);
	if (!ap_key)
		return -ENOMEM;

	ap_key->id = id;
	ap_key->key_type = key_type;
	ap_key->key_size = key_size;
	memcpy(ap_key->key, key, key_size);
	ap_key->hlid = hlid;
	ap_key->tx_seq_32 = tx_seq_32;
	ap_key->tx_seq_16 = tx_seq_16;

2699
	wlvif->ap.recorded_keys[i] = ap_key;
2700 2701 2702
	return 0;
}

2703
static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2704 2705 2706 2707
{
	int i;

	for (i = 0; i < MAX_NUM_KEYS; i++) {
2708 2709
		kfree(wlvif->ap.recorded_keys[i]);
		wlvif->ap.recorded_keys[i] = NULL;
2710 2711 2712
	}
}

2713
static int wl1271_ap_init_hwenc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2714 2715 2716 2717 2718 2719
{
	int i, ret = 0;
	struct wl1271_ap_key *key;
	bool wep_key_added = false;

	for (i = 0; i < MAX_NUM_KEYS; i++) {
2720
		u8 hlid;
2721
		if (wlvif->ap.recorded_keys[i] == NULL)
2722 2723
			break;

2724
		key = wlvif->ap.recorded_keys[i];
2725 2726
		hlid = key->hlid;
		if (hlid == WL12XX_INVALID_LINK_ID)
2727
			hlid = wlvif->ap.bcast_hlid;
2728

2729
		ret = wl1271_cmd_set_ap_key(wl, wlvif, KEY_ADD_OR_REPLACE,
2730 2731
					    key->id, key->key_type,
					    key->key_size, key->key,
2732
					    hlid, key->tx_seq_32,
2733 2734 2735 2736 2737 2738 2739 2740 2741
					    key->tx_seq_16);
		if (ret < 0)
			goto out;

		if (key->key_type == KEY_WEP)
			wep_key_added = true;
	}

	if (wep_key_added) {
E
Eliad Peller 已提交
2742
		ret = wl12xx_cmd_set_default_wep_key(wl, wlvif->default_key,
2743
						     wlvif->ap.bcast_hlid);
2744 2745 2746 2747 2748
		if (ret < 0)
			goto out;
	}

out:
2749
	wl1271_free_ap_keys(wl, wlvif);
2750 2751 2752
	return ret;
}

E
Eliad Peller 已提交
2753 2754
static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
		       u16 action, u8 id, u8 key_type,
2755 2756 2757 2758
		       u8 key_size, const u8 *key, u32 tx_seq_32,
		       u16 tx_seq_16, struct ieee80211_sta *sta)
{
	int ret;
E
Eliad Peller 已提交
2759
	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
2760 2761 2762 2763 2764 2765 2766 2767 2768

	if (is_ap) {
		struct wl1271_station *wl_sta;
		u8 hlid;

		if (sta) {
			wl_sta = (struct wl1271_station *)sta->drv_priv;
			hlid = wl_sta->hlid;
		} else {
2769
			hlid = wlvif->ap.bcast_hlid;
2770 2771
		}

2772
		if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
2773 2774 2775 2776 2777 2778 2779
			/*
			 * We do not support removing keys after AP shutdown.
			 * Pretend we do to make mac80211 happy.
			 */
			if (action != KEY_ADD_OR_REPLACE)
				return 0;

2780
			ret = wl1271_record_ap_key(wl, wlvif, id,
2781 2782 2783 2784
					     key_type, key_size,
					     key, hlid, tx_seq_32,
					     tx_seq_16);
		} else {
2785
			ret = wl1271_cmd_set_ap_key(wl, wlvif, action,
2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798
					     id, key_type, key_size,
					     key, hlid, tx_seq_32,
					     tx_seq_16);
		}

		if (ret < 0)
			return ret;
	} else {
		const u8 *addr;
		static const u8 bcast_addr[ETH_ALEN] = {
			0xff, 0xff, 0xff, 0xff, 0xff, 0xff
		};

2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809
		/*
		 * A STA set to GEM cipher requires 2 tx spare blocks.
		 * Return to default value when GEM cipher key is removed
		 */
		if (key_type == KEY_GEM) {
			if (action == KEY_ADD_OR_REPLACE)
				wl->tx_spare_blocks = 2;
			else if (action == KEY_REMOVE)
				wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
		}

2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823
		addr = sta ? sta->addr : bcast_addr;

		if (is_zero_ether_addr(addr)) {
			/* We dont support TX only encryption */
			return -EOPNOTSUPP;
		}

		/* The wl1271 does not allow to remove unicast keys - they
		   will be cleared automatically on next CMD_JOIN. Ignore the
		   request silently, as we dont want the mac80211 to emit
		   an error message. */
		if (action == KEY_REMOVE && !is_broadcast_ether_addr(addr))
			return 0;

2824 2825
		/* don't remove key if hlid was already deleted */
		if (action == KEY_REMOVE &&
E
Eliad Peller 已提交
2826
		    wlvif->sta.hlid == WL12XX_INVALID_LINK_ID)
2827 2828
			return 0;

2829
		ret = wl1271_cmd_set_sta_key(wl, wlvif, action,
2830 2831 2832 2833 2834 2835 2836 2837
					     id, key_type, key_size,
					     key, addr, tx_seq_32,
					     tx_seq_16);
		if (ret < 0)
			return ret;

		/* the default WEP key needs to be configured at least once */
		if (key_type == KEY_WEP) {
E
Eliad Peller 已提交
2838
			ret = wl12xx_cmd_set_default_wep_key(wl,
E
Eliad Peller 已提交
2839 2840
							wlvif->default_key,
							wlvif->sta.hlid);
2841 2842 2843 2844 2845 2846 2847 2848
			if (ret < 0)
				return ret;
		}
	}

	return 0;
}

L
Luciano Coelho 已提交
2849 2850 2851 2852 2853 2854
static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
			     struct ieee80211_vif *vif,
			     struct ieee80211_sta *sta,
			     struct ieee80211_key_conf *key_conf)
{
	struct wl1271 *wl = hw->priv;
E
Eliad Peller 已提交
2855
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
L
Luciano Coelho 已提交
2856
	int ret;
2857 2858
	u32 tx_seq_32 = 0;
	u16 tx_seq_16 = 0;
L
Luciano Coelho 已提交
2859 2860 2861 2862
	u8 key_type;

	wl1271_debug(DEBUG_MAC80211, "mac80211 set key");

2863
	wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x sta: %p", cmd, sta);
L
Luciano Coelho 已提交
2864
	wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
2865
		     key_conf->cipher, key_conf->keyidx,
L
Luciano Coelho 已提交
2866 2867 2868 2869 2870
		     key_conf->keylen, key_conf->flags);
	wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen);

	mutex_lock(&wl->mutex);

2871 2872 2873 2874 2875
	if (unlikely(wl->state == WL1271_STATE_OFF)) {
		ret = -EAGAIN;
		goto out_unlock;
	}

2876
	ret = wl1271_ps_elp_wakeup(wl);
L
Luciano Coelho 已提交
2877 2878 2879
	if (ret < 0)
		goto out_unlock;

2880 2881 2882
	switch (key_conf->cipher) {
	case WLAN_CIPHER_SUITE_WEP40:
	case WLAN_CIPHER_SUITE_WEP104:
L
Luciano Coelho 已提交
2883 2884 2885 2886
		key_type = KEY_WEP;

		key_conf->hw_key_idx = key_conf->keyidx;
		break;
2887
	case WLAN_CIPHER_SUITE_TKIP:
L
Luciano Coelho 已提交
2888 2889 2890
		key_type = KEY_TKIP;

		key_conf->hw_key_idx = key_conf->keyidx;
2891 2892
		tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
		tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
L
Luciano Coelho 已提交
2893
		break;
2894
	case WLAN_CIPHER_SUITE_CCMP:
L
Luciano Coelho 已提交
2895 2896
		key_type = KEY_AES;

2897
		key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
2898 2899
		tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
		tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
L
Luciano Coelho 已提交
2900
		break;
2901 2902
	case WL1271_CIPHER_SUITE_GEM:
		key_type = KEY_GEM;
2903 2904
		tx_seq_32 = WL1271_TX_SECURITY_HI32(wlvif->tx_security_seq);
		tx_seq_16 = WL1271_TX_SECURITY_LO16(wlvif->tx_security_seq);
2905
		break;
L
Luciano Coelho 已提交
2906
	default:
2907
		wl1271_error("Unknown key algo 0x%x", key_conf->cipher);
L
Luciano Coelho 已提交
2908 2909 2910 2911 2912 2913 2914

		ret = -EOPNOTSUPP;
		goto out_sleep;
	}

	switch (cmd) {
	case SET_KEY:
E
Eliad Peller 已提交
2915
		ret = wl1271_set_key(wl, wlvif, KEY_ADD_OR_REPLACE,
2916 2917 2918
				 key_conf->keyidx, key_type,
				 key_conf->keylen, key_conf->key,
				 tx_seq_32, tx_seq_16, sta);
L
Luciano Coelho 已提交
2919 2920 2921 2922 2923 2924 2925
		if (ret < 0) {
			wl1271_error("Could not add or replace key");
			goto out_sleep;
		}
		break;

	case DISABLE_KEY:
E
Eliad Peller 已提交
2926
		ret = wl1271_set_key(wl, wlvif, KEY_REMOVE,
2927 2928 2929
				     key_conf->keyidx, key_type,
				     key_conf->keylen, key_conf->key,
				     0, 0, sta);
L
Luciano Coelho 已提交
2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951
		if (ret < 0) {
			wl1271_error("Could not remove key");
			goto out_sleep;
		}
		break;

	default:
		wl1271_error("Unsupported key cmd 0x%x", cmd);
		ret = -EOPNOTSUPP;
		break;
	}

out_sleep:
	wl1271_ps_elp_sleep(wl);

out_unlock:
	mutex_unlock(&wl->mutex);

	return ret;
}

static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
2952
			     struct ieee80211_vif *vif,
L
Luciano Coelho 已提交
2953 2954 2955
			     struct cfg80211_scan_request *req)
{
	struct wl1271 *wl = hw->priv;
E
Eliad Peller 已提交
2956 2957
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);

L
Luciano Coelho 已提交
2958 2959
	int ret;
	u8 *ssid = NULL;
2960
	size_t len = 0;
L
Luciano Coelho 已提交
2961 2962 2963 2964 2965

	wl1271_debug(DEBUG_MAC80211, "mac80211 hw scan");

	if (req->n_ssids) {
		ssid = req->ssids[0].ssid;
2966
		len = req->ssids[0].ssid_len;
L
Luciano Coelho 已提交
2967 2968 2969 2970
	}

	mutex_lock(&wl->mutex);

2971 2972 2973 2974 2975 2976 2977 2978 2979 2980
	if (wl->state == WL1271_STATE_OFF) {
		/*
		 * We cannot return -EBUSY here because cfg80211 will expect
		 * a call to ieee80211_scan_completed if we do - in this case
		 * there won't be any call.
		 */
		ret = -EAGAIN;
		goto out;
	}

2981
	ret = wl1271_ps_elp_wakeup(wl);
L
Luciano Coelho 已提交
2982 2983 2984
	if (ret < 0)
		goto out;

2985 2986 2987 2988 2989 2990 2991
	if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
	    test_bit(wlvif->role_id, wl->roc_map)) {
		/* don't allow scanning right now */
		ret = -EBUSY;
		goto out_sleep;
	}

2992
	/* cancel ROC before scanning */
2993
	if (wl12xx_dev_role_started(wlvif))
E
Eliad Peller 已提交
2994
		wl12xx_croc(wl, wlvif->dev_role_id);
L
Luciano Coelho 已提交
2995

2996
	ret = wl1271_scan(hw->priv, vif, ssid, len, req);
2997
out_sleep:
L
Luciano Coelho 已提交
2998 2999 3000 3001 3002 3003 3004
	wl1271_ps_elp_sleep(wl);
out:
	mutex_unlock(&wl->mutex);

	return ret;
}

3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031
static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
				     struct ieee80211_vif *vif)
{
	struct wl1271 *wl = hw->priv;
	int ret;

	wl1271_debug(DEBUG_MAC80211, "mac80211 cancel hw scan");

	mutex_lock(&wl->mutex);

	if (wl->state == WL1271_STATE_OFF)
		goto out;

	if (wl->scan.state == WL1271_SCAN_STATE_IDLE)
		goto out;

	ret = wl1271_ps_elp_wakeup(wl);
	if (ret < 0)
		goto out;

	if (wl->scan.state != WL1271_SCAN_STATE_DONE) {
		ret = wl1271_scan_stop(wl);
		if (ret < 0)
			goto out_sleep;
	}
	wl->scan.state = WL1271_SCAN_STATE_IDLE;
	memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
3032
	wl->scan_vif = NULL;
3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043
	wl->scan.req = NULL;
	ieee80211_scan_completed(wl->hw, true);

out_sleep:
	wl1271_ps_elp_sleep(wl);
out:
	mutex_unlock(&wl->mutex);

	cancel_delayed_work_sync(&wl->scan_complete_work);
}

3044 3045 3046 3047 3048 3049
static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
				      struct ieee80211_vif *vif,
				      struct cfg80211_sched_scan_request *req,
				      struct ieee80211_sched_scan_ies *ies)
{
	struct wl1271 *wl = hw->priv;
E
Eliad Peller 已提交
3050
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3051 3052 3053 3054 3055 3056
	int ret;

	wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_start");

	mutex_lock(&wl->mutex);

3057 3058 3059 3060 3061
	if (wl->state == WL1271_STATE_OFF) {
		ret = -EAGAIN;
		goto out;
	}

3062 3063 3064 3065
	ret = wl1271_ps_elp_wakeup(wl);
	if (ret < 0)
		goto out;

E
Eliad Peller 已提交
3066
	ret = wl1271_scan_sched_scan_config(wl, wlvif, req, ies);
3067 3068 3069
	if (ret < 0)
		goto out_sleep;

E
Eliad Peller 已提交
3070
	ret = wl1271_scan_sched_scan_start(wl, wlvif);
3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092
	if (ret < 0)
		goto out_sleep;

	wl->sched_scanning = true;

out_sleep:
	wl1271_ps_elp_sleep(wl);
out:
	mutex_unlock(&wl->mutex);
	return ret;
}

static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
				      struct ieee80211_vif *vif)
{
	struct wl1271 *wl = hw->priv;
	int ret;

	wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_stop");

	mutex_lock(&wl->mutex);

3093 3094 3095
	if (wl->state == WL1271_STATE_OFF)
		goto out;

3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106
	ret = wl1271_ps_elp_wakeup(wl);
	if (ret < 0)
		goto out;

	wl1271_scan_sched_scan_stop(wl);

	wl1271_ps_elp_sleep(wl);
out:
	mutex_unlock(&wl->mutex);
}

3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118
static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
{
	struct wl1271 *wl = hw->priv;
	int ret = 0;

	mutex_lock(&wl->mutex);

	if (unlikely(wl->state == WL1271_STATE_OFF)) {
		ret = -EAGAIN;
		goto out;
	}

3119
	ret = wl1271_ps_elp_wakeup(wl);
3120 3121 3122
	if (ret < 0)
		goto out;

3123
	ret = wl1271_acx_frag_threshold(wl, value);
3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134
	if (ret < 0)
		wl1271_warning("wl1271_op_set_frag_threshold failed: %d", ret);

	wl1271_ps_elp_sleep(wl);

out:
	mutex_unlock(&wl->mutex);

	return ret;
}

L
Luciano Coelho 已提交
3135 3136 3137
static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
{
	struct wl1271 *wl = hw->priv;
3138
	struct wl12xx_vif *wlvif;
3139
	int ret = 0;
L
Luciano Coelho 已提交
3140 3141 3142

	mutex_lock(&wl->mutex);

3143 3144
	if (unlikely(wl->state == WL1271_STATE_OFF)) {
		ret = -EAGAIN;
3145
		goto out;
3146
	}
3147

3148
	ret = wl1271_ps_elp_wakeup(wl);
L
Luciano Coelho 已提交
3149 3150 3151
	if (ret < 0)
		goto out;

3152 3153 3154 3155 3156
	wl12xx_for_each_wlvif(wl, wlvif) {
		ret = wl1271_acx_rts_threshold(wl, wlvif, value);
		if (ret < 0)
			wl1271_warning("set rts threshold failed: %d", ret);
	}
L
Luciano Coelho 已提交
3157 3158 3159 3160 3161 3162 3163 3164
	wl1271_ps_elp_sleep(wl);

out:
	mutex_unlock(&wl->mutex);

	return ret;
}

3165
static int wl1271_ssid_set(struct ieee80211_vif *vif, struct sk_buff *skb,
3166
			    int offset)
3167
{
3168
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3169 3170 3171
	u8 ssid_len;
	const u8 *ptr = cfg80211_find_ie(WLAN_EID_SSID, skb->data + offset,
					 skb->len - offset);
3172

3173 3174 3175 3176 3177 3178 3179 3180 3181
	if (!ptr) {
		wl1271_error("No SSID in IEs!");
		return -ENOENT;
	}

	ssid_len = ptr[1];
	if (ssid_len > IEEE80211_MAX_SSID_LEN) {
		wl1271_error("SSID is too long!");
		return -EINVAL;
3182
	}
3183

3184 3185
	wlvif->ssid_len = ssid_len;
	memcpy(wlvif->ssid, ptr+2, ssid_len);
3186
	return 0;
3187 3188
}

3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202
static void wl12xx_remove_ie(struct sk_buff *skb, u8 eid, int ieoffset)
{
	int len;
	const u8 *next, *end = skb->data + skb->len;
	u8 *ie = (u8 *)cfg80211_find_ie(eid, skb->data + ieoffset,
					skb->len - ieoffset);
	if (!ie)
		return;
	len = ie[1] + 2;
	next = ie + len;
	memmove(ie, next, end - next);
	skb_trim(skb, skb->len - len);
}

3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219
static void wl12xx_remove_vendor_ie(struct sk_buff *skb,
					    unsigned int oui, u8 oui_type,
					    int ieoffset)
{
	int len;
	const u8 *next, *end = skb->data + skb->len;
	u8 *ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
					       skb->data + ieoffset,
					       skb->len - ieoffset);
	if (!ie)
		return;
	len = ie[1] + 2;
	next = ie + len;
	memmove(ie, next, end - next);
	skb_trim(skb, skb->len - len);
}

3220 3221
static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates,
					 struct ieee80211_vif *vif)
3222
{
3223
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3224 3225 3226
	struct sk_buff *skb;
	int ret;

3227
	skb = ieee80211_proberesp_get(wl->hw, vif);
3228
	if (!skb)
3229
		return -EOPNOTSUPP;
3230

3231
	ret = wl1271_cmd_template_set(wl, wlvif->role_id,
3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245
				      CMD_TEMPL_AP_PROBE_RESPONSE,
				      skb->data,
				      skb->len, 0,
				      rates);

	dev_kfree_skb(skb);
	return ret;
}

static int wl1271_ap_set_probe_resp_tmpl_legacy(struct wl1271 *wl,
					     struct ieee80211_vif *vif,
					     u8 *probe_rsp_data,
					     size_t probe_rsp_len,
					     u32 rates)
3246
{
3247 3248
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
3249 3250 3251 3252 3253
	u8 probe_rsp_templ[WL1271_CMD_TEMPL_MAX_SIZE];
	int ssid_ie_offset, ie_offset, templ_len;
	const u8 *ptr;

	/* no need to change probe response if the SSID is set correctly */
3254
	if (wlvif->ssid_len > 0)
3255
		return wl1271_cmd_template_set(wl, wlvif->role_id,
3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291
					       CMD_TEMPL_AP_PROBE_RESPONSE,
					       probe_rsp_data,
					       probe_rsp_len, 0,
					       rates);

	if (probe_rsp_len + bss_conf->ssid_len > WL1271_CMD_TEMPL_MAX_SIZE) {
		wl1271_error("probe_rsp template too big");
		return -EINVAL;
	}

	/* start searching from IE offset */
	ie_offset = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);

	ptr = cfg80211_find_ie(WLAN_EID_SSID, probe_rsp_data + ie_offset,
			       probe_rsp_len - ie_offset);
	if (!ptr) {
		wl1271_error("No SSID in beacon!");
		return -EINVAL;
	}

	ssid_ie_offset = ptr - probe_rsp_data;
	ptr += (ptr[1] + 2);

	memcpy(probe_rsp_templ, probe_rsp_data, ssid_ie_offset);

	/* insert SSID from bss_conf */
	probe_rsp_templ[ssid_ie_offset] = WLAN_EID_SSID;
	probe_rsp_templ[ssid_ie_offset + 1] = bss_conf->ssid_len;
	memcpy(probe_rsp_templ + ssid_ie_offset + 2,
	       bss_conf->ssid, bss_conf->ssid_len);
	templ_len = ssid_ie_offset + 2 + bss_conf->ssid_len;

	memcpy(probe_rsp_templ + ssid_ie_offset + 2 + bss_conf->ssid_len,
	       ptr, probe_rsp_len - (ptr - probe_rsp_data));
	templ_len += probe_rsp_len - (ptr - probe_rsp_data);

3292
	return wl1271_cmd_template_set(wl, wlvif->role_id,
3293 3294 3295 3296 3297 3298
				       CMD_TEMPL_AP_PROBE_RESPONSE,
				       probe_rsp_templ,
				       templ_len, 0,
				       rates);
}

3299
static int wl1271_bss_erp_info_changed(struct wl1271 *wl,
E
Eliad Peller 已提交
3300
				       struct ieee80211_vif *vif,
L
Luciano Coelho 已提交
3301 3302 3303
				       struct ieee80211_bss_conf *bss_conf,
				       u32 changed)
{
E
Eliad Peller 已提交
3304
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3305
	int ret = 0;
L
Luciano Coelho 已提交
3306

3307 3308
	if (changed & BSS_CHANGED_ERP_SLOT) {
		if (bss_conf->use_short_slot)
E
Eliad Peller 已提交
3309
			ret = wl1271_acx_slot(wl, wlvif, SLOT_TIME_SHORT);
3310
		else
E
Eliad Peller 已提交
3311
			ret = wl1271_acx_slot(wl, wlvif, SLOT_TIME_LONG);
3312 3313 3314 3315 3316
		if (ret < 0) {
			wl1271_warning("Set slot time failed %d", ret);
			goto out;
		}
	}
L
Luciano Coelho 已提交
3317

3318 3319
	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
		if (bss_conf->use_short_preamble)
E
Eliad Peller 已提交
3320
			wl1271_acx_set_preamble(wl, wlvif, ACX_PREAMBLE_SHORT);
3321
		else
E
Eliad Peller 已提交
3322
			wl1271_acx_set_preamble(wl, wlvif, ACX_PREAMBLE_LONG);
3323
	}
L
Luciano Coelho 已提交
3324

3325 3326
	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
		if (bss_conf->use_cts_prot)
E
Eliad Peller 已提交
3327 3328
			ret = wl1271_acx_cts_protect(wl, wlvif,
						     CTSPROTECT_ENABLE);
3329
		else
E
Eliad Peller 已提交
3330 3331
			ret = wl1271_acx_cts_protect(wl, wlvif,
						     CTSPROTECT_DISABLE);
3332 3333 3334 3335 3336
		if (ret < 0) {
			wl1271_warning("Set ctsprotect failed %d", ret);
			goto out;
		}
	}
3337

3338 3339 3340
out:
	return ret;
}
L
Luciano Coelho 已提交
3341

3342 3343 3344 3345 3346
static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
					  struct ieee80211_vif *vif,
					  struct ieee80211_bss_conf *bss_conf,
					  u32 changed)
{
E
Eliad Peller 已提交
3347
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
E
Eliad Peller 已提交
3348
	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
3349 3350 3351 3352
	int ret = 0;

	if ((changed & BSS_CHANGED_BEACON_INT)) {
		wl1271_debug(DEBUG_MASTER, "beacon interval updated: %d",
3353 3354
			bss_conf->beacon_int);

E
Eliad Peller 已提交
3355
		wlvif->beacon_int = bss_conf->beacon_int;
3356 3357
	}

3358 3359
	if ((changed & BSS_CHANGED_AP_PROBE_RESP) && is_ap) {
		u32 rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
3360 3361 3362 3363
		if (!wl1271_ap_set_probe_resp_tmpl(wl, rate, vif)) {
			wl1271_debug(DEBUG_AP, "probe response updated");
			set_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags);
		}
3364 3365
	}

3366 3367
	if ((changed & BSS_CHANGED_BEACON)) {
		struct ieee80211_hdr *hdr;
3368
		u32 min_rate;
3369 3370 3371 3372 3373
		int ieoffset = offsetof(struct ieee80211_mgmt,
					u.beacon.variable);
		struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif);
		u16 tmpl_id;

3374 3375
		if (!beacon) {
			ret = -EINVAL;
3376
			goto out;
3377
		}
3378 3379 3380

		wl1271_debug(DEBUG_MASTER, "beacon updated");

3381
		ret = wl1271_ssid_set(vif, beacon, ieoffset);
3382 3383 3384 3385
		if (ret < 0) {
			dev_kfree_skb(beacon);
			goto out;
		}
E
Eliad Peller 已提交
3386
		min_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
3387 3388
		tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON :
				  CMD_TEMPL_BEACON;
3389
		ret = wl1271_cmd_template_set(wl, wlvif->role_id, tmpl_id,
3390 3391
					      beacon->data,
					      beacon->len, 0,
3392
					      min_rate);
3393 3394 3395 3396 3397
		if (ret < 0) {
			dev_kfree_skb(beacon);
			goto out;
		}

3398 3399 3400 3401 3402 3403 3404
		/*
		 * In case we already have a probe-resp beacon set explicitly
		 * by usermode, don't use the beacon data.
		 */
		if (test_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags))
			goto end_bcn;

3405 3406 3407
		/* remove TIM ie from probe response */
		wl12xx_remove_ie(beacon, WLAN_EID_TIM, ieoffset);

3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418
		/*
		 * remove p2p ie from probe response.
		 * the fw reponds to probe requests that don't include
		 * the p2p ie. probe requests with p2p ie will be passed,
		 * and will be responded by the supplicant (the spec
		 * forbids including the p2p ie when responding to probe
		 * requests that didn't include it).
		 */
		wl12xx_remove_vendor_ie(beacon, WLAN_OUI_WFA,
					WLAN_OUI_TYPE_WFA_P2P, ieoffset);

3419 3420 3421
		hdr = (struct ieee80211_hdr *) beacon->data;
		hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						 IEEE80211_STYPE_PROBE_RESP);
3422
		if (is_ap)
3423
			ret = wl1271_ap_set_probe_resp_tmpl_legacy(wl, vif,
3424 3425
						beacon->data,
						beacon->len,
3426
						min_rate);
3427
		else
3428
			ret = wl1271_cmd_template_set(wl, wlvif->role_id,
3429 3430 3431
						CMD_TEMPL_PROBE_RESPONSE,
						beacon->data,
						beacon->len, 0,
3432
						min_rate);
3433
end_bcn:
3434 3435 3436 3437 3438 3439
		dev_kfree_skb(beacon);
		if (ret < 0)
			goto out;
	}

out:
3440 3441
	if (ret != 0)
		wl1271_error("beacon info change failed: %d", ret);
3442 3443 3444 3445 3446 3447 3448 3449 3450
	return ret;
}

/* AP mode changes */
static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
				       struct ieee80211_vif *vif,
				       struct ieee80211_bss_conf *bss_conf,
				       u32 changed)
{
E
Eliad Peller 已提交
3451
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3452
	int ret = 0;
3453

3454 3455
	if ((changed & BSS_CHANGED_BASIC_RATES)) {
		u32 rates = bss_conf->basic_rates;
3456

E
Eliad Peller 已提交
3457
		wlvif->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates,
E
Eliad Peller 已提交
3458
								 wlvif->band);
E
Eliad Peller 已提交
3459
		wlvif->basic_rate = wl1271_tx_min_rate_get(wl,
E
Eliad Peller 已提交
3460
							wlvif->basic_rate_set);
3461

E
Eliad Peller 已提交
3462
		ret = wl1271_init_ap_rates(wl, wlvif);
3463
		if (ret < 0) {
3464
			wl1271_error("AP rate policy change failed %d", ret);
3465 3466
			goto out;
		}
3467

3468
		ret = wl1271_ap_init_templates(wl, vif);
3469 3470
		if (ret < 0)
			goto out;
3471
	}
3472

3473 3474 3475
	ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, changed);
	if (ret < 0)
		goto out;
3476

3477 3478
	if ((changed & BSS_CHANGED_BEACON_ENABLED)) {
		if (bss_conf->enable_beacon) {
3479
			if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
E
Eliad Peller 已提交
3480
				ret = wl12xx_cmd_role_start_ap(wl, wlvif);
3481 3482
				if (ret < 0)
					goto out;
3483

3484
				ret = wl1271_ap_init_hwenc(wl, wlvif);
3485 3486
				if (ret < 0)
					goto out;
3487

3488
				set_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags);
3489
				wl1271_debug(DEBUG_AP, "started AP");
3490
			}
3491
		} else {
3492
			if (test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
E
Eliad Peller 已提交
3493
				ret = wl12xx_cmd_role_stop_ap(wl, wlvif);
3494 3495
				if (ret < 0)
					goto out;
3496

3497
				clear_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags);
3498 3499
				clear_bit(WLVIF_FLAG_AP_PROBE_RESP_SET,
					  &wlvif->flags);
3500 3501 3502 3503
				wl1271_debug(DEBUG_AP, "stopped AP");
			}
		}
	}
3504

E
Eliad Peller 已提交
3505
	ret = wl1271_bss_erp_info_changed(wl, vif, bss_conf, changed);
3506 3507
	if (ret < 0)
		goto out;
3508 3509 3510 3511

	/* Handle HT information change */
	if ((changed & BSS_CHANGED_HT) &&
	    (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
E
Eliad Peller 已提交
3512
		ret = wl1271_acx_set_ht_information(wl, wlvif,
3513 3514 3515 3516 3517 3518 3519
					bss_conf->ht_operation_mode);
		if (ret < 0) {
			wl1271_warning("Set ht information failed %d", ret);
			goto out;
		}
	}

3520 3521 3522
out:
	return;
}
J
Juuso Oikarinen 已提交
3523

3524 3525 3526 3527 3528 3529
/* STA/IBSS mode changes */
static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
					struct ieee80211_vif *vif,
					struct ieee80211_bss_conf *bss_conf,
					u32 changed)
{
E
Eliad Peller 已提交
3530
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3531
	bool do_join = false, set_assoc = false;
E
Eliad Peller 已提交
3532
	bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS);
E
Eliad Peller 已提交
3533
	bool ibss_joined = false;
3534
	u32 sta_rate_set = 0;
3535
	int ret;
3536
	struct ieee80211_sta *sta;
3537 3538
	bool sta_exists = false;
	struct ieee80211_sta_ht_cap sta_ht_cap;
3539 3540 3541 3542 3543 3544

	if (is_ibss) {
		ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf,
						     changed);
		if (ret < 0)
			goto out;
3545 3546
	}

E
Eliad Peller 已提交
3547 3548
	if (changed & BSS_CHANGED_IBSS) {
		if (bss_conf->ibss_joined) {
3549
			set_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags);
E
Eliad Peller 已提交
3550 3551
			ibss_joined = true;
		} else {
3552 3553
			if (test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED,
					       &wlvif->flags)) {
E
Eliad Peller 已提交
3554
				wl1271_unjoin(wl, wlvif);
3555
				wl12xx_start_dev(wl, wlvif);
E
Eliad Peller 已提交
3556 3557 3558 3559 3560
			}
		}
	}

	if ((changed & BSS_CHANGED_BEACON_INT) && ibss_joined)
3561 3562 3563
		do_join = true;

	/* Need to update the SSID (for filtering etc) */
E
Eliad Peller 已提交
3564
	if ((changed & BSS_CHANGED_BEACON) && ibss_joined)
3565 3566
		do_join = true;

E
Eliad Peller 已提交
3567
	if ((changed & BSS_CHANGED_BEACON_ENABLED) && ibss_joined) {
3568 3569 3570 3571 3572 3573
		wl1271_debug(DEBUG_ADHOC, "ad-hoc beaconing: %s",
			     bss_conf->enable_beacon ? "enabled" : "disabled");

		do_join = true;
	}

3574 3575 3576 3577 3578 3579
	if (changed & BSS_CHANGED_IDLE) {
		ret = wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle);
		if (ret < 0)
			wl1271_warning("idle mode change failed %d", ret);
	}

3580
	if ((changed & BSS_CHANGED_CQM)) {
3581 3582 3583
		bool enable = false;
		if (bss_conf->cqm_rssi_thold)
			enable = true;
E
Eliad Peller 已提交
3584
		ret = wl1271_acx_rssi_snr_trigger(wl, wlvif, enable,
3585 3586 3587 3588
						  bss_conf->cqm_rssi_thold,
						  bss_conf->cqm_rssi_hyst);
		if (ret < 0)
			goto out;
3589
		wlvif->rssi_thold = bss_conf->cqm_rssi_thold;
3590 3591
	}

3592 3593
	if (changed & BSS_CHANGED_BSSID &&
	    (is_ibss || bss_conf->assoc))
3594
		if (!is_zero_ether_addr(bss_conf->bssid)) {
E
Eliad Peller 已提交
3595
			ret = wl12xx_cmd_build_null_data(wl, wlvif);
3596 3597
			if (ret < 0)
				goto out;
3598

3599
			ret = wl1271_build_qos_null_data(wl, vif);
3600 3601
			if (ret < 0)
				goto out;
3602

3603 3604 3605
			/* Need to update the BSSID (for filtering etc) */
			do_join = true;
		}
3606

3607 3608 3609 3610 3611 3612
	if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) {
		rcu_read_lock();
		sta = ieee80211_find_sta(vif, bss_conf->bssid);
		if (!sta)
			goto sta_not_found;

3613 3614 3615 3616 3617
		/* save the supp_rates of the ap */
		sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band];
		if (sta->ht_cap.ht_supported)
			sta_rate_set |=
			    (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
3618 3619
		sta_ht_cap = sta->ht_cap;
		sta_exists = true;
3620

3621 3622
sta_not_found:
		rcu_read_unlock();
3623 3624
	}

3625
	if ((changed & BSS_CHANGED_ASSOC)) {
L
Luciano Coelho 已提交
3626
		if (bss_conf->assoc) {
3627
			u32 rates;
3628
			int ieoffset;
E
Eliad Peller 已提交
3629
			wlvif->aid = bss_conf->aid;
3630
			set_assoc = true;
L
Luciano Coelho 已提交
3631

3632 3633 3634 3635 3636
			/*
			 * use basic rates from AP, and determine lowest rate
			 * to use with control frames.
			 */
			rates = bss_conf->basic_rates;
E
Eliad Peller 已提交
3637
			wlvif->basic_rate_set =
3638
				wl1271_tx_enabled_rates_get(wl, rates,
E
Eliad Peller 已提交
3639
							    wlvif->band);
E
Eliad Peller 已提交
3640
			wlvif->basic_rate =
E
Eliad Peller 已提交
3641 3642
				wl1271_tx_min_rate_get(wl,
						       wlvif->basic_rate_set);
3643
			if (sta_rate_set)
E
Eliad Peller 已提交
3644 3645
				wlvif->rate_set =
					wl1271_tx_enabled_rates_get(wl,
3646
								sta_rate_set,
E
Eliad Peller 已提交
3647
								wlvif->band);
E
Eliad Peller 已提交
3648
			ret = wl1271_acx_sta_rate_policies(wl, wlvif);
3649
			if (ret < 0)
3650
				goto out;
3651

3652 3653 3654 3655 3656 3657
			/*
			 * with wl1271, we don't need to update the
			 * beacon_int and dtim_period, because the firmware
			 * updates it by itself when the first beacon is
			 * received after a join.
			 */
E
Eliad Peller 已提交
3658
			ret = wl1271_cmd_build_ps_poll(wl, wlvif, wlvif->aid);
L
Luciano Coelho 已提交
3659
			if (ret < 0)
3660
				goto out;
L
Luciano Coelho 已提交
3661

3662
			/*
3663
			 * Get a template for hardware connection maintenance
3664
			 */
E
Eliad Peller 已提交
3665 3666
			dev_kfree_skb(wlvif->probereq);
			wlvif->probereq = wl1271_cmd_build_ap_probe_req(wl,
3667
									wlvif,
E
Eliad Peller 已提交
3668
									NULL);
3669 3670
			ieoffset = offsetof(struct ieee80211_mgmt,
					    u.probe_req.variable);
E
Eliad Peller 已提交
3671
			wl1271_ssid_set(vif, wlvif->probereq, ieoffset);
3672

3673
			/* enable the connection monitoring feature */
E
Eliad Peller 已提交
3674
			ret = wl1271_acx_conn_monit_params(wl, wlvif, true);
L
Luciano Coelho 已提交
3675
			if (ret < 0)
3676
				goto out;
J
Juuso Oikarinen 已提交
3677 3678
		} else {
			/* use defaults when not associated */
3679
			bool was_assoc =
3680 3681
			    !!test_and_clear_bit(WLVIF_FLAG_STA_ASSOCIATED,
						 &wlvif->flags);
3682
			bool was_ifup =
3683 3684
			    !!test_and_clear_bit(WLVIF_FLAG_STA_STATE_SENT,
						 &wlvif->flags);
E
Eliad Peller 已提交
3685
			wlvif->aid = 0;
3686

3687
			/* free probe-request template */
E
Eliad Peller 已提交
3688 3689
			dev_kfree_skb(wlvif->probereq);
			wlvif->probereq = NULL;
3690

3691
			/* revert back to minimum rates for the current band */
E
Eliad Peller 已提交
3692
			wl1271_set_band_rate(wl, wlvif);
E
Eliad Peller 已提交
3693
			wlvif->basic_rate =
E
Eliad Peller 已提交
3694 3695
				wl1271_tx_min_rate_get(wl,
						       wlvif->basic_rate_set);
E
Eliad Peller 已提交
3696
			ret = wl1271_acx_sta_rate_policies(wl, wlvif);
3697
			if (ret < 0)
3698
				goto out;
3699

3700
			/* disable connection monitor features */
E
Eliad Peller 已提交
3701
			ret = wl1271_acx_conn_monit_params(wl, wlvif, false);
3702 3703

			/* Disable the keep-alive feature */
E
Eliad Peller 已提交
3704
			ret = wl1271_acx_keep_alive_mode(wl, wlvif, false);
3705
			if (ret < 0)
3706
				goto out;
3707 3708

			/* restore the bssid filter and go to dummy bssid */
3709
			if (was_assoc) {
3710 3711 3712 3713 3714 3715
				u32 conf_flags = wl->hw->conf.flags;
				/*
				 * we might have to disable roc, if there was
				 * no IF_OPER_UP notification.
				 */
				if (!was_ifup) {
E
Eliad Peller 已提交
3716
					ret = wl12xx_croc(wl, wlvif->role_id);
3717 3718 3719 3720 3721 3722 3723 3724
					if (ret < 0)
						goto out;
				}
				/*
				 * (we also need to disable roc in case of
				 * roaming on the same channel. until we will
				 * have a better flow...)
				 */
E
Eliad Peller 已提交
3725 3726 3727
				if (test_bit(wlvif->dev_role_id, wl->roc_map)) {
					ret = wl12xx_croc(wl,
							  wlvif->dev_role_id);
3728 3729 3730 3731
					if (ret < 0)
						goto out;
				}

E
Eliad Peller 已提交
3732
				wl1271_unjoin(wl, wlvif);
3733 3734
				if (!(conf_flags & IEEE80211_CONF_IDLE))
					wl12xx_start_dev(wl, wlvif);
3735
			}
L
Luciano Coelho 已提交
3736 3737 3738
		}
	}

3739 3740 3741 3742 3743 3744
	if (changed & BSS_CHANGED_IBSS) {
		wl1271_debug(DEBUG_ADHOC, "ibss_joined: %d",
			     bss_conf->ibss_joined);

		if (bss_conf->ibss_joined) {
			u32 rates = bss_conf->basic_rates;
E
Eliad Peller 已提交
3745
			wlvif->basic_rate_set =
3746
				wl1271_tx_enabled_rates_get(wl, rates,
E
Eliad Peller 已提交
3747
							    wlvif->band);
E
Eliad Peller 已提交
3748
			wlvif->basic_rate =
E
Eliad Peller 已提交
3749 3750
				wl1271_tx_min_rate_get(wl,
						       wlvif->basic_rate_set);
3751

3752
			/* by default, use 11b + OFDM rates */
E
Eliad Peller 已提交
3753 3754
			wlvif->rate_set = CONF_TX_IBSS_DEFAULT_RATES;
			ret = wl1271_acx_sta_rate_policies(wl, wlvif);
3755 3756 3757 3758 3759
			if (ret < 0)
				goto out;
		}
	}

E
Eliad Peller 已提交
3760
	ret = wl1271_bss_erp_info_changed(wl, vif, bss_conf, changed);
3761 3762
	if (ret < 0)
		goto out;
L
Luciano Coelho 已提交
3763

3764 3765
	if (changed & BSS_CHANGED_ARP_FILTER) {
		__be32 addr = bss_conf->arp_addr_list[0];
E
Eliad Peller 已提交
3766
		WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS);
3767

E
Eliad Peller 已提交
3768 3769 3770 3771 3772 3773 3774 3775
		if (bss_conf->arp_addr_cnt == 1 &&
		    bss_conf->arp_filter_enabled) {
			/*
			 * The template should have been configured only upon
			 * association. however, it seems that the correct ip
			 * isn't being set (when sending), so we have to
			 * reconfigure the template upon every ip change.
			 */
E
Eliad Peller 已提交
3776
			ret = wl1271_cmd_build_arp_rsp(wl, wlvif, addr);
E
Eliad Peller 已提交
3777 3778
			if (ret < 0) {
				wl1271_warning("build arp rsp failed: %d", ret);
3779
				goto out;
E
Eliad Peller 已提交
3780 3781
			}

E
Eliad Peller 已提交
3782
			ret = wl1271_acx_arp_ip_filter(wl, wlvif,
E
Eliad Peller 已提交
3783
				ACX_ARP_FILTER_ARP_FILTERING,
E
Eliad Peller 已提交
3784 3785
				addr);
		} else
E
Eliad Peller 已提交
3786
			ret = wl1271_acx_arp_ip_filter(wl, wlvif, 0, addr);
3787 3788

		if (ret < 0)
3789
			goto out;
3790 3791
	}

J
Juuso Oikarinen 已提交
3792
	if (do_join) {
E
Eliad Peller 已提交
3793
		ret = wl1271_join(wl, wlvif, set_assoc);
J
Juuso Oikarinen 已提交
3794 3795
		if (ret < 0) {
			wl1271_warning("cmd join failed %d", ret);
3796
			goto out;
J
Juuso Oikarinen 已提交
3797
		}
3798 3799 3800

		/* ROC until connected (after EAPOL exchange) */
		if (!is_ibss) {
E
Eliad Peller 已提交
3801
			ret = wl12xx_roc(wl, wlvif, wlvif->role_id);
3802 3803 3804
			if (ret < 0)
				goto out;

3805
			wl1271_check_operstate(wl, wlvif,
3806 3807 3808 3809
					       ieee80211_get_operstate(vif));
		}
		/*
		 * stop device role if started (we might already be in
3810
		 * STA/IBSS role).
3811
		 */
3812
		if (wl12xx_dev_role_started(wlvif)) {
3813
			ret = wl12xx_stop_dev(wl, wlvif);
3814 3815 3816
			if (ret < 0)
				goto out;
		}
3817 3818
	}

3819
	/* Handle new association with HT. Do this after join. */
3820 3821 3822
	if (sta_exists) {
		if ((changed & BSS_CHANGED_HT) &&
		    (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
3823 3824 3825
			ret = wl1271_acx_set_ht_capabilities(wl,
							     &sta_ht_cap,
							     true,
E
Eliad Peller 已提交
3826
							     wlvif->sta.hlid);
3827 3828 3829 3830 3831 3832 3833 3834
			if (ret < 0) {
				wl1271_warning("Set ht cap true failed %d",
					       ret);
				goto out;
			}
		}
		/* handle new association without HT and disassociation */
		else if (changed & BSS_CHANGED_ASSOC) {
3835 3836 3837
			ret = wl1271_acx_set_ht_capabilities(wl,
							     &sta_ht_cap,
							     false,
E
Eliad Peller 已提交
3838
							     wlvif->sta.hlid);
3839 3840 3841 3842 3843 3844 3845 3846
			if (ret < 0) {
				wl1271_warning("Set ht cap false failed %d",
					       ret);
				goto out;
			}
		}
	}

3847 3848
	/* Handle HT information change. Done after join. */
	if ((changed & BSS_CHANGED_HT) &&
3849
	    (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
E
Eliad Peller 已提交
3850
		ret = wl1271_acx_set_ht_information(wl, wlvif,
3851 3852 3853 3854 3855 3856 3857
					bss_conf->ht_operation_mode);
		if (ret < 0) {
			wl1271_warning("Set ht information failed %d", ret);
			goto out;
		}
	}

3858 3859 3860 3861 3862 3863 3864 3865 3866 3867
out:
	return;
}

static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
				       struct ieee80211_vif *vif,
				       struct ieee80211_bss_conf *bss_conf,
				       u32 changed)
{
	struct wl1271 *wl = hw->priv;
E
Eliad Peller 已提交
3868 3869
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
3870 3871 3872 3873 3874 3875 3876 3877 3878 3879
	int ret;

	wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed 0x%x",
		     (int)changed);

	mutex_lock(&wl->mutex);

	if (unlikely(wl->state == WL1271_STATE_OFF))
		goto out;

3880 3881 3882
	if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)))
		goto out;

3883
	ret = wl1271_ps_elp_wakeup(wl);
3884 3885 3886 3887 3888 3889 3890 3891
	if (ret < 0)
		goto out;

	if (is_ap)
		wl1271_bss_info_changed_ap(wl, vif, bss_conf, changed);
	else
		wl1271_bss_info_changed_sta(wl, vif, bss_conf, changed);

L
Luciano Coelho 已提交
3892 3893 3894 3895 3896 3897
	wl1271_ps_elp_sleep(wl);

out:
	mutex_unlock(&wl->mutex);
}

3898 3899
static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
			     struct ieee80211_vif *vif, u16 queue,
K
Kalle Valo 已提交
3900 3901 3902
			     const struct ieee80211_tx_queue_params *params)
{
	struct wl1271 *wl = hw->priv;
E
Eliad Peller 已提交
3903
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
K
Kalle Valo 已提交
3904
	u8 ps_scheme;
3905
	int ret = 0;
K
Kalle Valo 已提交
3906 3907 3908 3909 3910

	mutex_lock(&wl->mutex);

	wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);

K
Kalle Valo 已提交
3911 3912 3913 3914 3915
	if (params->uapsd)
		ps_scheme = CONF_PS_SCHEME_UPSD_TRIGGER;
	else
		ps_scheme = CONF_PS_SCHEME_LEGACY;

3916
	if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
3917
		goto out;
3918

3919 3920 3921
	ret = wl1271_ps_elp_wakeup(wl);
	if (ret < 0)
		goto out;
3922

3923 3924 3925 3926
	/*
	 * the txop is confed in units of 32us by the mac80211,
	 * we need us
	 */
E
Eliad Peller 已提交
3927
	ret = wl1271_acx_ac_cfg(wl, wlvif, wl1271_tx_get_queue(queue),
3928 3929 3930 3931 3932
				params->cw_min, params->cw_max,
				params->aifs, params->txop << 5);
	if (ret < 0)
		goto out_sleep;

E
Eliad Peller 已提交
3933
	ret = wl1271_acx_tid_cfg(wl, wlvif, wl1271_tx_get_queue(queue),
3934 3935 3936 3937
				 CONF_CHANNEL_TYPE_EDCF,
				 wl1271_tx_get_queue(queue),
				 ps_scheme, CONF_ACK_POLICY_LEGACY,
				 0, 0);
K
Kalle Valo 已提交
3938 3939

out_sleep:
3940
	wl1271_ps_elp_sleep(wl);
K
Kalle Valo 已提交
3941 3942 3943 3944 3945 3946 3947

out:
	mutex_unlock(&wl->mutex);

	return ret;
}

3948 3949
static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw,
			     struct ieee80211_vif *vif)
J
Juuso Oikarinen 已提交
3950 3951 3952
{

	struct wl1271 *wl = hw->priv;
3953
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
J
Juuso Oikarinen 已提交
3954 3955 3956 3957 3958 3959 3960
	u64 mactime = ULLONG_MAX;
	int ret;

	wl1271_debug(DEBUG_MAC80211, "mac80211 get tsf");

	mutex_lock(&wl->mutex);

3961 3962 3963
	if (unlikely(wl->state == WL1271_STATE_OFF))
		goto out;

3964
	ret = wl1271_ps_elp_wakeup(wl);
J
Juuso Oikarinen 已提交
3965 3966 3967
	if (ret < 0)
		goto out;

3968
	ret = wl12xx_acx_tsf_info(wl, wlvif, &mactime);
J
Juuso Oikarinen 已提交
3969 3970 3971 3972 3973 3974 3975 3976 3977 3978
	if (ret < 0)
		goto out_sleep;

out_sleep:
	wl1271_ps_elp_sleep(wl);

out:
	mutex_unlock(&wl->mutex);
	return mactime;
}
L
Luciano Coelho 已提交
3979

3980 3981 3982 3983 3984
static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx,
				struct survey_info *survey)
{
	struct wl1271 *wl = hw->priv;
	struct ieee80211_conf *conf = &hw->conf;
3985

3986 3987
	if (idx != 0)
		return -ENOENT;
3988

3989 3990 3991
	survey->channel = conf->channel;
	survey->filled = SURVEY_INFO_NOISE_DBM;
	survey->noise = wl->noise;
3992

3993 3994 3995
	return 0;
}

3996
static int wl1271_allocate_sta(struct wl1271 *wl,
3997 3998
			     struct wl12xx_vif *wlvif,
			     struct ieee80211_sta *sta)
3999 4000
{
	struct wl1271_station *wl_sta;
4001
	int ret;
4002

4003 4004

	if (wl->active_sta_count >= AP_MAX_STATIONS) {
4005 4006 4007 4008 4009
		wl1271_warning("could not allocate HLID - too much stations");
		return -EBUSY;
	}

	wl_sta = (struct wl1271_station *)sta->drv_priv;
4010 4011 4012 4013 4014 4015 4016
	ret = wl12xx_allocate_link(wl, wlvif, &wl_sta->hlid);
	if (ret < 0) {
		wl1271_warning("could not allocate HLID - too many links");
		return -EBUSY;
	}

	set_bit(wl_sta->hlid, wlvif->ap.sta_hlid_map);
4017
	memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN);
4018
	wl->active_sta_count++;
4019 4020 4021
	return 0;
}

4022
void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
4023
{
4024
	if (!test_bit(hlid, wlvif->ap.sta_hlid_map))
4025 4026
		return;

4027
	clear_bit(hlid, wlvif->ap.sta_hlid_map);
4028
	memset(wl->links[hlid].addr, 0, ETH_ALEN);
4029
	wl->links[hlid].ba_bitmap = 0;
4030
	wl1271_tx_reset_link_queues(wl, hlid);
4031 4032
	__clear_bit(hlid, &wl->ap_ps_map);
	__clear_bit(hlid, (unsigned long *)&wl->ap_fw_ps_map);
4033
	wl12xx_free_link(wl, wlvif, &hlid);
4034
	wl->active_sta_count--;
4035 4036 4037 4038 4039 4040 4041
}

static int wl1271_op_sta_add(struct ieee80211_hw *hw,
			     struct ieee80211_vif *vif,
			     struct ieee80211_sta *sta)
{
	struct wl1271 *wl = hw->priv;
E
Eliad Peller 已提交
4042
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4043
	struct wl1271_station *wl_sta;
4044 4045 4046 4047 4048 4049 4050 4051
	int ret = 0;
	u8 hlid;

	mutex_lock(&wl->mutex);

	if (unlikely(wl->state == WL1271_STATE_OFF))
		goto out;

E
Eliad Peller 已提交
4052
	if (wlvif->bss_type != BSS_TYPE_AP_BSS)
4053 4054 4055 4056
		goto out;

	wl1271_debug(DEBUG_MAC80211, "mac80211 add sta %d", (int)sta->aid);

4057
	ret = wl1271_allocate_sta(wl, wlvif, sta);
4058 4059 4060
	if (ret < 0)
		goto out;

4061 4062 4063
	wl_sta = (struct wl1271_station *)sta->drv_priv;
	hlid = wl_sta->hlid;

4064
	ret = wl1271_ps_elp_wakeup(wl);
4065
	if (ret < 0)
4066
		goto out_free_sta;
4067

E
Eliad Peller 已提交
4068
	ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid);
4069 4070 4071
	if (ret < 0)
		goto out_sleep;

4072 4073 4074 4075
	ret = wl12xx_cmd_set_peer_state(wl, hlid);
	if (ret < 0)
		goto out_sleep;

4076 4077 4078 4079
	ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, hlid);
	if (ret < 0)
		goto out_sleep;

4080 4081 4082
out_sleep:
	wl1271_ps_elp_sleep(wl);

4083 4084
out_free_sta:
	if (ret < 0)
4085
		wl1271_free_sta(wl, wlvif, hlid);
4086

4087 4088 4089 4090 4091 4092 4093 4094 4095 4096
out:
	mutex_unlock(&wl->mutex);
	return ret;
}

static int wl1271_op_sta_remove(struct ieee80211_hw *hw,
				struct ieee80211_vif *vif,
				struct ieee80211_sta *sta)
{
	struct wl1271 *wl = hw->priv;
E
Eliad Peller 已提交
4097
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4098 4099 4100 4101 4102 4103 4104 4105
	struct wl1271_station *wl_sta;
	int ret = 0, id;

	mutex_lock(&wl->mutex);

	if (unlikely(wl->state == WL1271_STATE_OFF))
		goto out;

E
Eliad Peller 已提交
4106
	if (wlvif->bss_type != BSS_TYPE_AP_BSS)
4107 4108 4109 4110 4111
		goto out;

	wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid);

	wl_sta = (struct wl1271_station *)sta->drv_priv;
4112 4113
	id = wl_sta->hlid;
	if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map)))
4114 4115
		goto out;

4116
	ret = wl1271_ps_elp_wakeup(wl);
4117 4118 4119
	if (ret < 0)
		goto out;

E
Eliad Peller 已提交
4120
	ret = wl12xx_cmd_remove_peer(wl, wl_sta->hlid);
4121 4122 4123
	if (ret < 0)
		goto out_sleep;

4124
	wl1271_free_sta(wl, wlvif, wl_sta->hlid);
4125 4126 4127 4128 4129 4130 4131 4132 4133

out_sleep:
	wl1271_ps_elp_sleep(wl);

out:
	mutex_unlock(&wl->mutex);
	return ret;
}

4134 4135 4136 4137 4138
static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
				  struct ieee80211_vif *vif,
				  enum ieee80211_ampdu_mlme_action action,
				  struct ieee80211_sta *sta, u16 tid, u16 *ssn,
				  u8 buf_size)
L
Levi, Shahar 已提交
4139 4140
{
	struct wl1271 *wl = hw->priv;
E
Eliad Peller 已提交
4141
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
L
Levi, Shahar 已提交
4142
	int ret;
4143 4144 4145 4146 4147 4148 4149 4150
	u8 hlid, *ba_bitmap;

	wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu action %d tid %d", action,
		     tid);

	/* sanity check - the fields in FW are only 8bits wide */
	if (WARN_ON(tid > 0xFF))
		return -ENOTSUPP;
L
Levi, Shahar 已提交
4151 4152 4153 4154 4155 4156 4157 4158

	mutex_lock(&wl->mutex);

	if (unlikely(wl->state == WL1271_STATE_OFF)) {
		ret = -EAGAIN;
		goto out;
	}

E
Eliad Peller 已提交
4159
	if (wlvif->bss_type == BSS_TYPE_STA_BSS) {
E
Eliad Peller 已提交
4160
		hlid = wlvif->sta.hlid;
E
Eliad Peller 已提交
4161
		ba_bitmap = &wlvif->sta.ba_rx_bitmap;
E
Eliad Peller 已提交
4162
	} else if (wlvif->bss_type == BSS_TYPE_AP_BSS) {
4163 4164 4165 4166 4167 4168 4169 4170 4171 4172
		struct wl1271_station *wl_sta;

		wl_sta = (struct wl1271_station *)sta->drv_priv;
		hlid = wl_sta->hlid;
		ba_bitmap = &wl->links[hlid].ba_bitmap;
	} else {
		ret = -EINVAL;
		goto out;
	}

4173
	ret = wl1271_ps_elp_wakeup(wl);
L
Levi, Shahar 已提交
4174 4175 4176
	if (ret < 0)
		goto out;

4177 4178 4179
	wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu: Rx tid %d action %d",
		     tid, action);

L
Levi, Shahar 已提交
4180 4181
	switch (action) {
	case IEEE80211_AMPDU_RX_START:
E
Eliad Peller 已提交
4182
		if (!wlvif->ba_support || !wlvif->ba_allowed) {
L
Levi, Shahar 已提交
4183
			ret = -ENOTSUPP;
4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204
			break;
		}

		if (wl->ba_rx_session_count >= RX_BA_MAX_SESSIONS) {
			ret = -EBUSY;
			wl1271_error("exceeded max RX BA sessions");
			break;
		}

		if (*ba_bitmap & BIT(tid)) {
			ret = -EINVAL;
			wl1271_error("cannot enable RX BA session on active "
				     "tid: %d", tid);
			break;
		}

		ret = wl12xx_acx_set_ba_receiver_session(wl, tid, *ssn, true,
							 hlid);
		if (!ret) {
			*ba_bitmap |= BIT(tid);
			wl->ba_rx_session_count++;
L
Levi, Shahar 已提交
4205 4206 4207 4208
		}
		break;

	case IEEE80211_AMPDU_RX_STOP:
4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221
		if (!(*ba_bitmap & BIT(tid))) {
			ret = -EINVAL;
			wl1271_error("no active RX BA session on tid: %d",
				     tid);
			break;
		}

		ret = wl12xx_acx_set_ba_receiver_session(wl, tid, 0, false,
							 hlid);
		if (!ret) {
			*ba_bitmap &= ~BIT(tid);
			wl->ba_rx_session_count--;
		}
L
Levi, Shahar 已提交
4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246
		break;

	/*
	 * The BA initiator session management in FW independently.
	 * Falling break here on purpose for all TX APDU commands.
	 */
	case IEEE80211_AMPDU_TX_START:
	case IEEE80211_AMPDU_TX_STOP:
	case IEEE80211_AMPDU_TX_OPERATIONAL:
		ret = -EINVAL;
		break;

	default:
		wl1271_error("Incorrect ampdu action id=%x\n", action);
		ret = -EINVAL;
	}

	wl1271_ps_elp_sleep(wl);

out:
	mutex_unlock(&wl->mutex);

	return ret;
}

4247 4248 4249 4250
static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   const struct cfg80211_bitrate_mask *mask)
{
4251
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4252
	struct wl1271 *wl = hw->priv;
4253
	int i, ret = 0;
4254 4255 4256 4257 4258 4259 4260 4261

	wl1271_debug(DEBUG_MAC80211, "mac80211 set_bitrate_mask 0x%x 0x%x",
		mask->control[NL80211_BAND_2GHZ].legacy,
		mask->control[NL80211_BAND_5GHZ].legacy);

	mutex_lock(&wl->mutex);

	for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4262
		wlvif->bitrate_masks[i] =
4263 4264 4265
			wl1271_tx_enabled_rates_get(wl,
						    mask->control[i].legacy,
						    i);
4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284

	if (unlikely(wl->state == WL1271_STATE_OFF))
		goto out;

	if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
	    !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {

		ret = wl1271_ps_elp_wakeup(wl);
		if (ret < 0)
			goto out;

		wl1271_set_band_rate(wl, wlvif);
		wlvif->basic_rate =
			wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
		ret = wl1271_acx_sta_rate_policies(wl, wlvif);

		wl1271_ps_elp_sleep(wl);
	}
out:
4285 4286
	mutex_unlock(&wl->mutex);

4287
	return ret;
4288 4289
}

4290 4291 4292 4293
static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
				     struct ieee80211_channel_switch *ch_switch)
{
	struct wl1271 *wl = hw->priv;
4294
	struct wl12xx_vif *wlvif;
4295 4296 4297 4298 4299 4300 4301
	int ret;

	wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch");

	mutex_lock(&wl->mutex);

	if (unlikely(wl->state == WL1271_STATE_OFF)) {
4302 4303 4304 4305 4306
		wl12xx_for_each_wlvif_sta(wl, wlvif) {
			struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
			ieee80211_chswitch_done(vif, false);
		}
		goto out;
4307 4308 4309 4310 4311 4312
	}

	ret = wl1271_ps_elp_wakeup(wl);
	if (ret < 0)
		goto out;

4313 4314
	/* TODO: change mac80211 to pass vif as param */
	wl12xx_for_each_wlvif_sta(wl, wlvif) {
4315
		ret = wl12xx_cmd_channel_switch(wl, wlvif, ch_switch);
4316

4317 4318 4319
		if (!ret)
			set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);
	}
4320 4321 4322 4323 4324 4325 4326

	wl1271_ps_elp_sleep(wl);

out:
	mutex_unlock(&wl->mutex);
}

4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337
static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
{
	struct wl1271 *wl = hw->priv;
	bool ret = false;

	mutex_lock(&wl->mutex);

	if (unlikely(wl->state == WL1271_STATE_OFF))
		goto out;

	/* packets are considered pending if in the TX queue or the FW */
4338
	ret = (wl1271_tx_total_queue_count(wl) > 0) || (wl->tx_frames_cnt > 0);
4339 4340 4341 4342 4343 4344
out:
	mutex_unlock(&wl->mutex);

	return ret;
}

L
Luciano Coelho 已提交
4345 4346 4347
/* can't be const, mac80211 writes to this */
static struct ieee80211_rate wl1271_rates[] = {
	{ .bitrate = 10,
4348 4349
	  .hw_value = CONF_HW_BIT_RATE_1MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_1MBPS, },
L
Luciano Coelho 已提交
4350
	{ .bitrate = 20,
4351 4352
	  .hw_value = CONF_HW_BIT_RATE_2MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_2MBPS,
L
Luciano Coelho 已提交
4353 4354
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 55,
4355 4356
	  .hw_value = CONF_HW_BIT_RATE_5_5MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_5_5MBPS,
L
Luciano Coelho 已提交
4357 4358
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 110,
4359 4360
	  .hw_value = CONF_HW_BIT_RATE_11MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_11MBPS,
L
Luciano Coelho 已提交
4361 4362
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 60,
4363 4364
	  .hw_value = CONF_HW_BIT_RATE_6MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_6MBPS, },
L
Luciano Coelho 已提交
4365
	{ .bitrate = 90,
4366 4367
	  .hw_value = CONF_HW_BIT_RATE_9MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_9MBPS, },
L
Luciano Coelho 已提交
4368
	{ .bitrate = 120,
4369 4370
	  .hw_value = CONF_HW_BIT_RATE_12MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_12MBPS, },
L
Luciano Coelho 已提交
4371
	{ .bitrate = 180,
4372 4373
	  .hw_value = CONF_HW_BIT_RATE_18MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_18MBPS, },
L
Luciano Coelho 已提交
4374
	{ .bitrate = 240,
4375 4376
	  .hw_value = CONF_HW_BIT_RATE_24MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_24MBPS, },
L
Luciano Coelho 已提交
4377
	{ .bitrate = 360,
4378 4379
	 .hw_value = CONF_HW_BIT_RATE_36MBPS,
	 .hw_value_short = CONF_HW_BIT_RATE_36MBPS, },
L
Luciano Coelho 已提交
4380
	{ .bitrate = 480,
4381 4382
	  .hw_value = CONF_HW_BIT_RATE_48MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_48MBPS, },
L
Luciano Coelho 已提交
4383
	{ .bitrate = 540,
4384 4385
	  .hw_value = CONF_HW_BIT_RATE_54MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
L
Luciano Coelho 已提交
4386 4387
};

4388
/* can't be const, mac80211 writes to this */
L
Luciano Coelho 已提交
4389
static struct ieee80211_channel wl1271_channels[] = {
4390
	{ .hw_value = 1, .center_freq = 2412, .max_power = 25 },
4391
	{ .hw_value = 2, .center_freq = 2417, .max_power = 25 },
4392 4393 4394
	{ .hw_value = 3, .center_freq = 2422, .max_power = 25 },
	{ .hw_value = 4, .center_freq = 2427, .max_power = 25 },
	{ .hw_value = 5, .center_freq = 2432, .max_power = 25 },
4395
	{ .hw_value = 6, .center_freq = 2437, .max_power = 25 },
4396 4397 4398
	{ .hw_value = 7, .center_freq = 2442, .max_power = 25 },
	{ .hw_value = 8, .center_freq = 2447, .max_power = 25 },
	{ .hw_value = 9, .center_freq = 2452, .max_power = 25 },
4399
	{ .hw_value = 10, .center_freq = 2457, .max_power = 25 },
4400 4401 4402
	{ .hw_value = 11, .center_freq = 2462, .max_power = 25 },
	{ .hw_value = 12, .center_freq = 2467, .max_power = 25 },
	{ .hw_value = 13, .center_freq = 2472, .max_power = 25 },
4403
	{ .hw_value = 14, .center_freq = 2484, .max_power = 25 },
L
Luciano Coelho 已提交
4404 4405
};

4406
/* mapping to indexes for wl1271_rates */
4407
static const u8 wl1271_rate_to_idx_2ghz[] = {
4408
	/* MCS rates are used only with 11n */
4409 4410 4411 4412 4413 4414 4415 4416
	7,                            /* CONF_HW_RXTX_RATE_MCS7 */
	6,                            /* CONF_HW_RXTX_RATE_MCS6 */
	5,                            /* CONF_HW_RXTX_RATE_MCS5 */
	4,                            /* CONF_HW_RXTX_RATE_MCS4 */
	3,                            /* CONF_HW_RXTX_RATE_MCS3 */
	2,                            /* CONF_HW_RXTX_RATE_MCS2 */
	1,                            /* CONF_HW_RXTX_RATE_MCS1 */
	0,                            /* CONF_HW_RXTX_RATE_MCS0 */
4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435

	11,                            /* CONF_HW_RXTX_RATE_54   */
	10,                            /* CONF_HW_RXTX_RATE_48   */
	9,                             /* CONF_HW_RXTX_RATE_36   */
	8,                             /* CONF_HW_RXTX_RATE_24   */

	/* TI-specific rate */
	CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22   */

	7,                             /* CONF_HW_RXTX_RATE_18   */
	6,                             /* CONF_HW_RXTX_RATE_12   */
	3,                             /* CONF_HW_RXTX_RATE_11   */
	5,                             /* CONF_HW_RXTX_RATE_9    */
	4,                             /* CONF_HW_RXTX_RATE_6    */
	2,                             /* CONF_HW_RXTX_RATE_5_5  */
	1,                             /* CONF_HW_RXTX_RATE_2    */
	0                              /* CONF_HW_RXTX_RATE_1    */
};

S
Shahar Levi 已提交
4436 4437 4438
/* 11n STA capabilities */
#define HW_RX_HIGHEST_RATE	72

S
Shahar Levi 已提交
4439
#define WL12XX_HT_CAP { \
4440 4441
	.cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | \
	       (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT), \
S
Shahar Levi 已提交
4442 4443 4444 4445 4446 4447 4448 4449 4450 4451
	.ht_supported = true, \
	.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \
	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \
	.mcs = { \
		.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
		.rx_highest = cpu_to_le16(HW_RX_HIGHEST_RATE), \
		.tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
		}, \
}

L
Luciano Coelho 已提交
4452 4453 4454 4455 4456 4457
/* can't be const, mac80211 writes to this */
static struct ieee80211_supported_band wl1271_band_2ghz = {
	.channels = wl1271_channels,
	.n_channels = ARRAY_SIZE(wl1271_channels),
	.bitrates = wl1271_rates,
	.n_bitrates = ARRAY_SIZE(wl1271_rates),
S
Shahar Levi 已提交
4458
	.ht_cap	= WL12XX_HT_CAP,
L
Luciano Coelho 已提交
4459 4460
};

4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488
/* 5 GHz data rates for WL1273 */
static struct ieee80211_rate wl1271_rates_5ghz[] = {
	{ .bitrate = 60,
	  .hw_value = CONF_HW_BIT_RATE_6MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_6MBPS, },
	{ .bitrate = 90,
	  .hw_value = CONF_HW_BIT_RATE_9MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_9MBPS, },
	{ .bitrate = 120,
	  .hw_value = CONF_HW_BIT_RATE_12MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_12MBPS, },
	{ .bitrate = 180,
	  .hw_value = CONF_HW_BIT_RATE_18MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_18MBPS, },
	{ .bitrate = 240,
	  .hw_value = CONF_HW_BIT_RATE_24MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_24MBPS, },
	{ .bitrate = 360,
	 .hw_value = CONF_HW_BIT_RATE_36MBPS,
	 .hw_value_short = CONF_HW_BIT_RATE_36MBPS, },
	{ .bitrate = 480,
	  .hw_value = CONF_HW_BIT_RATE_48MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_48MBPS, },
	{ .bitrate = 540,
	  .hw_value = CONF_HW_BIT_RATE_54MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
};

4489
/* 5 GHz band channels for WL1273 */
4490
static struct ieee80211_channel wl1271_channels_5ghz[] = {
4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524
	{ .hw_value = 7, .center_freq = 5035, .max_power = 25 },
	{ .hw_value = 8, .center_freq = 5040, .max_power = 25 },
	{ .hw_value = 9, .center_freq = 5045, .max_power = 25 },
	{ .hw_value = 11, .center_freq = 5055, .max_power = 25 },
	{ .hw_value = 12, .center_freq = 5060, .max_power = 25 },
	{ .hw_value = 16, .center_freq = 5080, .max_power = 25 },
	{ .hw_value = 34, .center_freq = 5170, .max_power = 25 },
	{ .hw_value = 36, .center_freq = 5180, .max_power = 25 },
	{ .hw_value = 38, .center_freq = 5190, .max_power = 25 },
	{ .hw_value = 40, .center_freq = 5200, .max_power = 25 },
	{ .hw_value = 42, .center_freq = 5210, .max_power = 25 },
	{ .hw_value = 44, .center_freq = 5220, .max_power = 25 },
	{ .hw_value = 46, .center_freq = 5230, .max_power = 25 },
	{ .hw_value = 48, .center_freq = 5240, .max_power = 25 },
	{ .hw_value = 52, .center_freq = 5260, .max_power = 25 },
	{ .hw_value = 56, .center_freq = 5280, .max_power = 25 },
	{ .hw_value = 60, .center_freq = 5300, .max_power = 25 },
	{ .hw_value = 64, .center_freq = 5320, .max_power = 25 },
	{ .hw_value = 100, .center_freq = 5500, .max_power = 25 },
	{ .hw_value = 104, .center_freq = 5520, .max_power = 25 },
	{ .hw_value = 108, .center_freq = 5540, .max_power = 25 },
	{ .hw_value = 112, .center_freq = 5560, .max_power = 25 },
	{ .hw_value = 116, .center_freq = 5580, .max_power = 25 },
	{ .hw_value = 120, .center_freq = 5600, .max_power = 25 },
	{ .hw_value = 124, .center_freq = 5620, .max_power = 25 },
	{ .hw_value = 128, .center_freq = 5640, .max_power = 25 },
	{ .hw_value = 132, .center_freq = 5660, .max_power = 25 },
	{ .hw_value = 136, .center_freq = 5680, .max_power = 25 },
	{ .hw_value = 140, .center_freq = 5700, .max_power = 25 },
	{ .hw_value = 149, .center_freq = 5745, .max_power = 25 },
	{ .hw_value = 153, .center_freq = 5765, .max_power = 25 },
	{ .hw_value = 157, .center_freq = 5785, .max_power = 25 },
	{ .hw_value = 161, .center_freq = 5805, .max_power = 25 },
	{ .hw_value = 165, .center_freq = 5825, .max_power = 25 },
4525 4526
};

4527
/* mapping to indexes for wl1271_rates_5ghz */
4528
static const u8 wl1271_rate_to_idx_5ghz[] = {
4529
	/* MCS rates are used only with 11n */
4530 4531 4532 4533 4534 4535 4536 4537
	7,                            /* CONF_HW_RXTX_RATE_MCS7 */
	6,                            /* CONF_HW_RXTX_RATE_MCS6 */
	5,                            /* CONF_HW_RXTX_RATE_MCS5 */
	4,                            /* CONF_HW_RXTX_RATE_MCS4 */
	3,                            /* CONF_HW_RXTX_RATE_MCS3 */
	2,                            /* CONF_HW_RXTX_RATE_MCS2 */
	1,                            /* CONF_HW_RXTX_RATE_MCS1 */
	0,                            /* CONF_HW_RXTX_RATE_MCS0 */
4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555

	7,                             /* CONF_HW_RXTX_RATE_54   */
	6,                             /* CONF_HW_RXTX_RATE_48   */
	5,                             /* CONF_HW_RXTX_RATE_36   */
	4,                             /* CONF_HW_RXTX_RATE_24   */

	/* TI-specific rate */
	CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_22   */

	3,                             /* CONF_HW_RXTX_RATE_18   */
	2,                             /* CONF_HW_RXTX_RATE_12   */
	CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_11   */
	1,                             /* CONF_HW_RXTX_RATE_9    */
	0,                             /* CONF_HW_RXTX_RATE_6    */
	CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_5_5  */
	CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_2    */
	CONF_HW_RXTX_RATE_UNSUPPORTED  /* CONF_HW_RXTX_RATE_1    */
};
4556 4557 4558 4559 4560 4561

static struct ieee80211_supported_band wl1271_band_5ghz = {
	.channels = wl1271_channels_5ghz,
	.n_channels = ARRAY_SIZE(wl1271_channels_5ghz),
	.bitrates = wl1271_rates_5ghz,
	.n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
S
Shahar Levi 已提交
4562
	.ht_cap	= WL12XX_HT_CAP,
4563 4564
};

4565
static const u8 *wl1271_band_rate_to_idx[] = {
4566 4567 4568 4569
	[IEEE80211_BAND_2GHZ] = wl1271_rate_to_idx_2ghz,
	[IEEE80211_BAND_5GHZ] = wl1271_rate_to_idx_5ghz
};

L
Luciano Coelho 已提交
4570 4571 4572 4573 4574
static const struct ieee80211_ops wl1271_ops = {
	.start = wl1271_op_start,
	.stop = wl1271_op_stop,
	.add_interface = wl1271_op_add_interface,
	.remove_interface = wl1271_op_remove_interface,
E
Eliad Peller 已提交
4575
	.change_interface = wl12xx_op_change_interface,
4576
#ifdef CONFIG_PM
4577 4578
	.suspend = wl1271_op_suspend,
	.resume = wl1271_op_resume,
4579
#endif
L
Luciano Coelho 已提交
4580
	.config = wl1271_op_config,
4581
	.prepare_multicast = wl1271_op_prepare_multicast,
L
Luciano Coelho 已提交
4582 4583 4584 4585
	.configure_filter = wl1271_op_configure_filter,
	.tx = wl1271_op_tx,
	.set_key = wl1271_op_set_key,
	.hw_scan = wl1271_op_hw_scan,
4586
	.cancel_hw_scan = wl1271_op_cancel_hw_scan,
4587 4588
	.sched_scan_start = wl1271_op_sched_scan_start,
	.sched_scan_stop = wl1271_op_sched_scan_stop,
L
Luciano Coelho 已提交
4589
	.bss_info_changed = wl1271_op_bss_info_changed,
4590
	.set_frag_threshold = wl1271_op_set_frag_threshold,
L
Luciano Coelho 已提交
4591
	.set_rts_threshold = wl1271_op_set_rts_threshold,
K
Kalle Valo 已提交
4592
	.conf_tx = wl1271_op_conf_tx,
J
Juuso Oikarinen 已提交
4593
	.get_tsf = wl1271_op_get_tsf,
4594
	.get_survey = wl1271_op_get_survey,
4595 4596
	.sta_add = wl1271_op_sta_add,
	.sta_remove = wl1271_op_sta_remove,
L
Levi, Shahar 已提交
4597
	.ampdu_action = wl1271_op_ampdu_action,
4598
	.tx_frames_pending = wl1271_tx_frames_pending,
4599
	.set_bitrate_mask = wl12xx_set_bitrate_mask,
4600
	.channel_switch = wl12xx_op_channel_switch,
K
Kalle Valo 已提交
4601
	CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
L
Luciano Coelho 已提交
4602 4603
};

4604

4605
u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band)
4606 4607 4608
{
	u8 idx;

4609
	BUG_ON(band >= sizeof(wl1271_band_rate_to_idx)/sizeof(u8 *));
4610 4611 4612 4613 4614 4615

	if (unlikely(rate >= CONF_HW_RXTX_RATE_MAX)) {
		wl1271_error("Illegal RX rate from HW: %d", rate);
		return 0;
	}

4616
	idx = wl1271_band_rate_to_idx[band][rate];
4617 4618 4619 4620 4621 4622 4623 4624
	if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) {
		wl1271_error("Unsupported RX rate from HW: %d", rate);
		return 0;
	}

	return idx;
}

4625 4626 4627 4628 4629 4630 4631
static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev,
					       struct device_attribute *attr,
					       char *buf)
{
	struct wl1271 *wl = dev_get_drvdata(dev);
	ssize_t len;

4632
	len = PAGE_SIZE;
4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650

	mutex_lock(&wl->mutex);
	len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n",
		       wl->sg_enabled);
	mutex_unlock(&wl->mutex);

	return len;

}

static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev,
						struct device_attribute *attr,
						const char *buf, size_t count)
{
	struct wl1271 *wl = dev_get_drvdata(dev);
	unsigned long res;
	int ret;

L
Luciano Coelho 已提交
4651
	ret = kstrtoul(buf, 10, &res);
4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668
	if (ret < 0) {
		wl1271_warning("incorrect value written to bt_coex_mode");
		return count;
	}

	mutex_lock(&wl->mutex);

	res = !!res;

	if (res == wl->sg_enabled)
		goto out;

	wl->sg_enabled = res;

	if (wl->state == WL1271_STATE_OFF)
		goto out;

4669
	ret = wl1271_ps_elp_wakeup(wl);
4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684
	if (ret < 0)
		goto out;

	wl1271_acx_sg_enable(wl, wl->sg_enabled);
	wl1271_ps_elp_sleep(wl);

 out:
	mutex_unlock(&wl->mutex);
	return count;
}

static DEVICE_ATTR(bt_coex_state, S_IRUGO | S_IWUSR,
		   wl1271_sysfs_show_bt_coex_state,
		   wl1271_sysfs_store_bt_coex_state);

4685 4686 4687 4688 4689 4690 4691
static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev,
					   struct device_attribute *attr,
					   char *buf)
{
	struct wl1271 *wl = dev_get_drvdata(dev);
	ssize_t len;

4692
	len = PAGE_SIZE;
4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703

	mutex_lock(&wl->mutex);
	if (wl->hw_pg_ver >= 0)
		len = snprintf(buf, len, "%d\n", wl->hw_pg_ver);
	else
		len = snprintf(buf, len, "n/a\n");
	mutex_unlock(&wl->mutex);

	return len;
}

4704
static DEVICE_ATTR(hw_pg_ver, S_IRUGO,
4705 4706
		   wl1271_sysfs_show_hw_pg_ver, NULL);

4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769
static ssize_t wl1271_sysfs_read_fwlog(struct file *filp, struct kobject *kobj,
				       struct bin_attribute *bin_attr,
				       char *buffer, loff_t pos, size_t count)
{
	struct device *dev = container_of(kobj, struct device, kobj);
	struct wl1271 *wl = dev_get_drvdata(dev);
	ssize_t len;
	int ret;

	ret = mutex_lock_interruptible(&wl->mutex);
	if (ret < 0)
		return -ERESTARTSYS;

	/* Let only one thread read the log at a time, blocking others */
	while (wl->fwlog_size == 0) {
		DEFINE_WAIT(wait);

		prepare_to_wait_exclusive(&wl->fwlog_waitq,
					  &wait,
					  TASK_INTERRUPTIBLE);

		if (wl->fwlog_size != 0) {
			finish_wait(&wl->fwlog_waitq, &wait);
			break;
		}

		mutex_unlock(&wl->mutex);

		schedule();
		finish_wait(&wl->fwlog_waitq, &wait);

		if (signal_pending(current))
			return -ERESTARTSYS;

		ret = mutex_lock_interruptible(&wl->mutex);
		if (ret < 0)
			return -ERESTARTSYS;
	}

	/* Check if the fwlog is still valid */
	if (wl->fwlog_size < 0) {
		mutex_unlock(&wl->mutex);
		return 0;
	}

	/* Seeking is not supported - old logs are not kept. Disregard pos. */
	len = min(count, (size_t)wl->fwlog_size);
	wl->fwlog_size -= len;
	memcpy(buffer, wl->fwlog, len);

	/* Make room for new messages */
	memmove(wl->fwlog, wl->fwlog + len, wl->fwlog_size);

	mutex_unlock(&wl->mutex);

	return len;
}

static struct bin_attribute fwlog_attr = {
	.attr = {.name = "fwlog", .mode = S_IRUSR},
	.read = wl1271_sysfs_read_fwlog,
};

4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839
static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
{
	bool supported = false;
	u8 major, minor;

	if (wl->chip.id == CHIP_ID_1283_PG20) {
		major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
		minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);

		/* in wl128x we have the MAC address if the PG is >= (2, 1) */
		if (major > 2 || (major == 2 && minor >= 1))
			supported = true;
	} else {
		major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver);
		minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver);

		/* in wl127x we have the MAC address if the PG is >= (3, 1) */
		if (major == 3 && minor >= 1)
			supported = true;
	}

	wl1271_debug(DEBUG_PROBE,
		     "PG Ver major = %d minor = %d, MAC %s present",
		     major, minor, supported ? "is" : "is not");

	return supported;
}

static void wl12xx_derive_mac_addresses(struct wl1271 *wl,
					u32 oui, u32 nic, int n)
{
	int i;

	wl1271_debug(DEBUG_PROBE, "base address: oui %06x nic %06x, n %d",
		     oui, nic, n);

	if (nic + n - 1 > 0xffffff)
		wl1271_warning("NIC part of the MAC address wraps around!");

	for (i = 0; i < n; i++) {
		wl->addresses[i].addr[0] = (u8)(oui >> 16);
		wl->addresses[i].addr[1] = (u8)(oui >> 8);
		wl->addresses[i].addr[2] = (u8) oui;
		wl->addresses[i].addr[3] = (u8)(nic >> 16);
		wl->addresses[i].addr[4] = (u8)(nic >> 8);
		wl->addresses[i].addr[5] = (u8) nic;
		nic++;
	}

	wl->hw->wiphy->n_addresses = n;
	wl->hw->wiphy->addresses = wl->addresses;
}

static void wl12xx_get_fuse_mac(struct wl1271 *wl)
{
	u32 mac1, mac2;

	wl1271_set_partition(wl, &wl12xx_part_table[PART_DRPW]);

	mac1 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1);
	mac2 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2);

	/* these are the two parts of the BD_ADDR */
	wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
		((mac1 & 0xff000000) >> 24);
	wl->fuse_nic_addr = mac1 & 0xffffff;

	wl1271_set_partition(wl, &wl12xx_part_table[PART_DOWN]);
}

4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857
static int wl12xx_get_hw_info(struct wl1271 *wl)
{
	int ret;
	u32 die_info;

	ret = wl12xx_set_power_on(wl);
	if (ret < 0)
		goto out;

	wl->chip.id = wl1271_read32(wl, CHIP_ID_B);

	if (wl->chip.id == CHIP_ID_1283_PG20)
		die_info = wl1271_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1);
	else
		die_info = wl1271_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1);

	wl->hw_pg_ver = (s8) (die_info & PG_VER_MASK) >> PG_VER_OFFSET;

4858 4859 4860 4861 4862 4863 4864
	if (!wl12xx_mac_in_fuse(wl)) {
		wl->fuse_oui_addr = 0;
		wl->fuse_nic_addr = 0;
	} else {
		wl12xx_get_fuse_mac(wl);
	}

4865 4866 4867 4868 4869
	wl1271_power_off(wl);
out:
	return ret;
}

F
Felipe Balbi 已提交
4870
static int wl1271_register_hw(struct wl1271 *wl)
L
Luciano Coelho 已提交
4871 4872
{
	int ret;
4873
	u32 oui_addr = 0, nic_addr = 0;
L
Luciano Coelho 已提交
4874 4875 4876 4877

	if (wl->mac80211_registered)
		return 0;

4878 4879 4880 4881 4882 4883
	ret = wl12xx_get_hw_info(wl);
	if (ret < 0) {
		wl1271_error("couldn't get hw info");
		goto out;
	}

4884 4885
	ret = wl1271_fetch_nvs(wl);
	if (ret == 0) {
4886 4887 4888 4889 4890
		/* NOTE: The wl->nvs->nvs element must be first, in
		 * order to simplify the casting, we assume it is at
		 * the beginning of the wl->nvs structure.
		 */
		u8 *nvs_ptr = (u8 *)wl->nvs;
4891

4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902
		oui_addr =
			(nvs_ptr[11] << 16) + (nvs_ptr[10] << 8) + nvs_ptr[6];
		nic_addr =
			(nvs_ptr[5] << 16) + (nvs_ptr[4] << 8) + nvs_ptr[3];
	}

	/* if the MAC address is zeroed in the NVS derive from fuse */
	if (oui_addr == 0 && nic_addr == 0) {
		oui_addr = wl->fuse_oui_addr;
		/* fuse has the BD_ADDR, the WLAN addresses are the next two */
		nic_addr = wl->fuse_nic_addr + 1;
4903 4904
	}

4905
	wl12xx_derive_mac_addresses(wl, oui_addr, nic_addr, 2);
L
Luciano Coelho 已提交
4906 4907 4908 4909

	ret = ieee80211_register_hw(wl->hw);
	if (ret < 0) {
		wl1271_error("unable to register mac80211 hw: %d", ret);
4910
		goto out;
L
Luciano Coelho 已提交
4911 4912 4913 4914
	}

	wl->mac80211_registered = true;

4915 4916
	wl1271_debugfs_init(wl);

4917 4918
	register_netdevice_notifier(&wl1271_dev_notifier);

L
Luciano Coelho 已提交
4919 4920
	wl1271_notice("loaded");

4921 4922
out:
	return ret;
L
Luciano Coelho 已提交
4923 4924
}

F
Felipe Balbi 已提交
4925
static void wl1271_unregister_hw(struct wl1271 *wl)
4926
{
4927
	if (wl->state == WL1271_STATE_PLT)
4928
		wl1271_plt_stop(wl);
4929

4930
	unregister_netdevice_notifier(&wl1271_dev_notifier);
4931 4932 4933 4934 4935
	ieee80211_unregister_hw(wl->hw);
	wl->mac80211_registered = false;

}

F
Felipe Balbi 已提交
4936
static int wl1271_init_ieee80211(struct wl1271 *wl)
L
Luciano Coelho 已提交
4937
{
4938 4939 4940 4941 4942 4943 4944 4945
	static const u32 cipher_suites[] = {
		WLAN_CIPHER_SUITE_WEP40,
		WLAN_CIPHER_SUITE_WEP104,
		WLAN_CIPHER_SUITE_TKIP,
		WLAN_CIPHER_SUITE_CCMP,
		WL1271_CIPHER_SUITE_GEM,
	};

4946 4947 4948
	/* The tx descriptor buffer and the TKIP space. */
	wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE +
		sizeof(struct wl1271_tx_hw_descr);
L
Luciano Coelho 已提交
4949 4950 4951 4952

	/* unit us */
	/* FIXME: find a proper value */
	wl->hw->channel_change_time = 10000;
4953
	wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval;
L
Luciano Coelho 已提交
4954 4955

	wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
4956
		IEEE80211_HW_SUPPORTS_PS |
4957
		IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
K
Kalle Valo 已提交
4958
		IEEE80211_HW_SUPPORTS_UAPSD |
4959
		IEEE80211_HW_HAS_RATE_CONTROL |
4960
		IEEE80211_HW_CONNECTION_MONITOR |
4961
		IEEE80211_HW_REPORTS_TX_ACK_STATUS |
4962
		IEEE80211_HW_SPECTRUM_MGMT |
4963 4964 4965
		IEEE80211_HW_AP_LINK_PS |
		IEEE80211_HW_AMPDU_AGGREGATION |
		IEEE80211_HW_TX_AMPDU_SETUP_IN_HW;
L
Luciano Coelho 已提交
4966

4967 4968 4969
	wl->hw->wiphy->cipher_suites = cipher_suites;
	wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);

4970
	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
E
Eliad Peller 已提交
4971 4972
		BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) |
		BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO);
L
Luciano Coelho 已提交
4973
	wl->hw->wiphy->max_scan_ssids = 1;
4974 4975
	wl->hw->wiphy->max_sched_scan_ssids = 16;
	wl->hw->wiphy->max_match_sets = 16;
4976 4977 4978 4979 4980
	/*
	 * Maximum length of elements in scanning probe request templates
	 * should be the maximum length possible for a template, without
	 * the IEEE80211 header of the template
	 */
4981
	wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_DFLT_SIZE -
4982
			sizeof(struct ieee80211_header);
4983

4984 4985 4986
	wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_DFLT_SIZE -
		sizeof(struct ieee80211_header);

4987 4988
	wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;

4989 4990 4991 4992
	/* make sure all our channels fit in the scanned_ch bitmask */
	BUILD_BUG_ON(ARRAY_SIZE(wl1271_channels) +
		     ARRAY_SIZE(wl1271_channels_5ghz) >
		     WL1271_MAX_CHANNELS);
4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005
	/*
	 * We keep local copies of the band structs because we need to
	 * modify them on a per-device basis.
	 */
	memcpy(&wl->bands[IEEE80211_BAND_2GHZ], &wl1271_band_2ghz,
	       sizeof(wl1271_band_2ghz));
	memcpy(&wl->bands[IEEE80211_BAND_5GHZ], &wl1271_band_5ghz,
	       sizeof(wl1271_band_5ghz));

	wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
		&wl->bands[IEEE80211_BAND_2GHZ];
	wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
		&wl->bands[IEEE80211_BAND_5GHZ];
5006

K
Kalle Valo 已提交
5007
	wl->hw->queues = 4;
J
Juuso Oikarinen 已提交
5008
	wl->hw->max_rates = 1;
K
Kalle Valo 已提交
5009

5010 5011
	wl->hw->wiphy->reg_notifier = wl1271_reg_notify;

5012 5013 5014 5015 5016 5017 5018
	/* the FW answers probe-requests in AP-mode */
	wl->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
	wl->hw->wiphy->probe_resp_offload =
		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
		NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;

5019
	SET_IEEE80211_DEV(wl->hw, wl->dev);
L
Luciano Coelho 已提交
5020

5021
	wl->hw->sta_data_size = sizeof(struct wl1271_station);
E
Eliad Peller 已提交
5022
	wl->hw->vif_data_size = sizeof(struct wl12xx_vif);
5023

5024 5025
	wl->hw->max_rx_aggregation_subframes = 8;

L
Luciano Coelho 已提交
5026 5027 5028 5029
	return 0;
}

#define WL1271_DEFAULT_CHANNEL 0
5030

F
Felipe Balbi 已提交
5031
static struct ieee80211_hw *wl1271_alloc_hw(void)
L
Luciano Coelho 已提交
5032 5033 5034
{
	struct ieee80211_hw *hw;
	struct wl1271 *wl;
5035
	int i, j, ret;
5036
	unsigned int order;
L
Luciano Coelho 已提交
5037

5038
	BUILD_BUG_ON(AP_MAX_STATIONS > WL12XX_MAX_LINKS);
5039

L
Luciano Coelho 已提交
5040 5041 5042
	hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
	if (!hw) {
		wl1271_error("could not alloc ieee80211_hw");
5043
		ret = -ENOMEM;
5044 5045 5046
		goto err_hw_alloc;
	}

L
Luciano Coelho 已提交
5047 5048 5049
	wl = hw->priv;
	memset(wl, 0, sizeof(*wl));

5050
	INIT_LIST_HEAD(&wl->list);
E
Eliad Peller 已提交
5051
	INIT_LIST_HEAD(&wl->wlvif_list);
5052

L
Luciano Coelho 已提交
5053 5054
	wl->hw = hw;

5055
	for (i = 0; i < NUM_TX_QUEUES; i++)
5056
		for (j = 0; j < WL12XX_MAX_LINKS; j++)
5057 5058
			skb_queue_head_init(&wl->links[j].tx_queue[i]);

5059 5060 5061
	skb_queue_head_init(&wl->deferred_rx_queue);
	skb_queue_head_init(&wl->deferred_tx_queue);

5062
	INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
5063
	INIT_WORK(&wl->netstack_work, wl1271_netstack_work);
5064 5065 5066
	INIT_WORK(&wl->tx_work, wl1271_tx_work);
	INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
	INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
5067

5068 5069 5070 5071 5072 5073
	wl->freezable_wq = create_freezable_workqueue("wl12xx_wq");
	if (!wl->freezable_wq) {
		ret = -ENOMEM;
		goto err_hw;
	}

L
Luciano Coelho 已提交
5074 5075 5076
	wl->channel = WL1271_DEFAULT_CHANNEL;
	wl->rx_counter = 0;
	wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
5077
	wl->band = IEEE80211_BAND_2GHZ;
5078
	wl->vif = NULL;
5079
	wl->flags = 0;
5080
	wl->sg_enabled = true;
5081
	wl->hw_pg_ver = -1;
5082 5083
	wl->ap_ps_map = 0;
	wl->ap_fw_ps_map = 0;
5084
	wl->quirks = 0;
5085
	wl->platform_quirks = 0;
5086
	wl->sched_scanning = false;
5087
	wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
E
Eliad Peller 已提交
5088
	wl->system_hlid = WL12XX_SYSTEM_HLID;
5089
	wl->active_sta_count = 0;
5090 5091
	wl->fwlog_size = 0;
	init_waitqueue_head(&wl->fwlog_waitq);
L
Luciano Coelho 已提交
5092

E
Eliad Peller 已提交
5093 5094 5095
	/* The system link is always allocated */
	__set_bit(WL12XX_SYSTEM_HLID, wl->links_map);

5096
	memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
J
Juuso Oikarinen 已提交
5097
	for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
L
Luciano Coelho 已提交
5098 5099 5100 5101 5102 5103 5104
		wl->tx_frames[i] = NULL;

	spin_lock_init(&wl->wl_lock);

	wl->state = WL1271_STATE_OFF;
	mutex_init(&wl->mutex);

5105 5106 5107
	/* Apply default driver configuration. */
	wl1271_conf_init(wl);

5108 5109 5110 5111
	order = get_order(WL1271_AGGR_BUFFER_SIZE);
	wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
	if (!wl->aggr_buf) {
		ret = -ENOMEM;
5112
		goto err_wq;
5113 5114
	}

5115 5116 5117 5118 5119 5120
	wl->dummy_packet = wl12xx_alloc_dummy_packet(wl);
	if (!wl->dummy_packet) {
		ret = -ENOMEM;
		goto err_aggr;
	}

5121 5122 5123 5124 5125 5126 5127
	/* Allocate one page for the FW log */
	wl->fwlog = (u8 *)get_zeroed_page(GFP_KERNEL);
	if (!wl->fwlog) {
		ret = -ENOMEM;
		goto err_dummy_packet;
	}

5128
	return hw;
5129

5130 5131 5132
err_dummy_packet:
	dev_kfree_skb(wl->dummy_packet);

5133 5134 5135
err_aggr:
	free_pages((unsigned long)wl->aggr_buf, order);

5136 5137 5138
err_wq:
	destroy_workqueue(wl->freezable_wq);

5139
err_hw:
5140 5141 5142 5143
	wl1271_debugfs_exit(wl);
	ieee80211_free_hw(hw);

err_hw_alloc:
5144 5145

	return ERR_PTR(ret);
5146 5147
}

F
Felipe Balbi 已提交
5148
static int wl1271_free_hw(struct wl1271 *wl)
5149
{
5150 5151 5152 5153 5154 5155
	/* Unblock any fwlog readers */
	mutex_lock(&wl->mutex);
	wl->fwlog_size = -1;
	wake_up_interruptible_all(&wl->fwlog_waitq);
	mutex_unlock(&wl->mutex);

F
Felipe Balbi 已提交
5156
	device_remove_bin_file(wl->dev, &fwlog_attr);
5157

F
Felipe Balbi 已提交
5158
	device_remove_file(wl->dev, &dev_attr_hw_pg_ver);
5159

F
Felipe Balbi 已提交
5160
	device_remove_file(wl->dev, &dev_attr_bt_coex_state);
5161
	free_page((unsigned long)wl->fwlog);
5162
	dev_kfree_skb(wl->dummy_packet);
5163 5164
	free_pages((unsigned long)wl->aggr_buf,
			get_order(WL1271_AGGR_BUFFER_SIZE));
5165 5166 5167 5168 5169 5170 5171 5172 5173 5174

	wl1271_debugfs_exit(wl);

	vfree(wl->fw);
	wl->fw = NULL;
	kfree(wl->nvs);
	wl->nvs = NULL;

	kfree(wl->fw_status);
	kfree(wl->tx_res_if);
5175
	destroy_workqueue(wl->freezable_wq);
5176 5177 5178 5179 5180

	ieee80211_free_hw(wl->hw);

	return 0;
}
5181

5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210
static irqreturn_t wl12xx_hardirq(int irq, void *cookie)
{
	struct wl1271 *wl = cookie;
	unsigned long flags;

	wl1271_debug(DEBUG_IRQ, "IRQ");

	/* complete the ELP completion */
	spin_lock_irqsave(&wl->wl_lock, flags);
	set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
	if (wl->elp_compl) {
		complete(wl->elp_compl);
		wl->elp_compl = NULL;
	}

	if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
		/* don't enqueue a work right now. mark it as pending */
		set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
		wl1271_debug(DEBUG_IRQ, "should not enqueue work");
		disable_irq_nosync(wl->irq);
		pm_wakeup_event(wl->dev, 0);
		spin_unlock_irqrestore(&wl->wl_lock, flags);
		return IRQ_HANDLED;
	}
	spin_unlock_irqrestore(&wl->wl_lock, flags);

	return IRQ_WAKE_THREAD;
}

5211 5212
static int __devinit wl12xx_probe(struct platform_device *pdev)
{
5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267
	struct wl12xx_platform_data *pdata = pdev->dev.platform_data;
	struct ieee80211_hw *hw;
	struct wl1271 *wl;
	unsigned long irqflags;
	int ret = -ENODEV;

	hw = wl1271_alloc_hw();
	if (IS_ERR(hw)) {
		wl1271_error("can't allocate hw");
		ret = PTR_ERR(hw);
		goto out;
	}

	wl = hw->priv;
	wl->irq = platform_get_irq(pdev, 0);
	wl->ref_clock = pdata->board_ref_clock;
	wl->tcxo_clock = pdata->board_tcxo_clock;
	wl->platform_quirks = pdata->platform_quirks;
	wl->set_power = pdata->set_power;
	wl->dev = &pdev->dev;
	wl->if_ops = pdata->ops;

	platform_set_drvdata(pdev, wl);

	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
		irqflags = IRQF_TRIGGER_RISING;
	else
		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;

	ret = request_threaded_irq(wl->irq, wl12xx_hardirq, wl1271_irq,
				   irqflags,
				   pdev->name, wl);
	if (ret < 0) {
		wl1271_error("request_irq() failed: %d", ret);
		goto out_free_hw;
	}

	ret = enable_irq_wake(wl->irq);
	if (!ret) {
		wl->irq_wake_enabled = true;
		device_init_wakeup(wl->dev, 1);
		if (pdata->pwr_in_suspend)
			hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;

	}
	disable_irq(wl->irq);

	ret = wl1271_init_ieee80211(wl);
	if (ret)
		goto out_irq;

	ret = wl1271_register_hw(wl);
	if (ret)
		goto out_irq;

F
Felipe Balbi 已提交
5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288
	/* Create sysfs file to control bt coex state */
	ret = device_create_file(wl->dev, &dev_attr_bt_coex_state);
	if (ret < 0) {
		wl1271_error("failed to create sysfs file bt_coex_state");
		goto out_irq;
	}

	/* Create sysfs file to get HW PG version */
	ret = device_create_file(wl->dev, &dev_attr_hw_pg_ver);
	if (ret < 0) {
		wl1271_error("failed to create sysfs file hw_pg_ver");
		goto out_bt_coex_state;
	}

	/* Create sysfs file for the FW log */
	ret = device_create_bin_file(wl->dev, &fwlog_attr);
	if (ret < 0) {
		wl1271_error("failed to create sysfs file fwlog");
		goto out_hw_pg_ver;
	}

5289
	return 0;
5290

F
Felipe Balbi 已提交
5291 5292 5293 5294 5295 5296
out_hw_pg_ver:
	device_remove_file(wl->dev, &dev_attr_hw_pg_ver);

out_bt_coex_state:
	device_remove_file(wl->dev, &dev_attr_bt_coex_state);

5297 5298 5299 5300 5301 5302 5303 5304
out_irq:
	free_irq(wl->irq, wl);

out_free_hw:
	wl1271_free_hw(wl);

out:
	return ret;
5305 5306 5307 5308
}

static int __devexit wl12xx_remove(struct platform_device *pdev)
{
5309 5310 5311 5312 5313 5314 5315 5316 5317 5318
	struct wl1271 *wl = platform_get_drvdata(pdev);

	if (wl->irq_wake_enabled) {
		device_init_wakeup(wl->dev, 0);
		disable_irq_wake(wl->irq);
	}
	wl1271_unregister_hw(wl);
	free_irq(wl->irq, wl);
	wl1271_free_hw(wl);

5319 5320 5321 5322
	return 0;
}

static const struct platform_device_id wl12xx_id_table[] __devinitconst = {
5323
	{ "wl12xx", 0 },
5324 5325 5326 5327 5328 5329 5330 5331 5332
	{  } /* Terminating Entry */
};
MODULE_DEVICE_TABLE(platform, wl12xx_id_table);

static struct platform_driver wl12xx_driver = {
	.probe		= wl12xx_probe,
	.remove		= __devexit_p(wl12xx_remove),
	.id_table	= wl12xx_id_table,
	.driver = {
5333
		.name	= "wl12xx_driver",
5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349
		.owner	= THIS_MODULE,
	}
};

static int __init wl12xx_init(void)
{
	return platform_driver_register(&wl12xx_driver);
}
module_init(wl12xx_init);

static void __exit wl12xx_exit(void)
{
	platform_driver_unregister(&wl12xx_driver);
}
module_exit(wl12xx_exit);

5350
u32 wl12xx_debug_level = DEBUG_NONE;
5351
EXPORT_SYMBOL_GPL(wl12xx_debug_level);
5352
module_param_named(debug_level, wl12xx_debug_level, uint, S_IRUSR | S_IWUSR);
5353 5354
MODULE_PARM_DESC(debug_level, "wl12xx debugging level");

5355
module_param_named(fwlog, fwlog_param, charp, 0);
5356
MODULE_PARM_DESC(fwlog,
5357 5358
		 "FW logger options: continuous, ondemand, dbgpins or disable");

5359 5360 5361
module_param(bug_on_recovery, bool, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery");

5362
MODULE_LICENSE("GPL");
5363
MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
5364
MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");