main.c 170.3 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-only
L
Luciano Coelho 已提交
2
/*
3
 * This file is part of wlcore
L
Luciano Coelho 已提交
4
 *
J
Juuso Oikarinen 已提交
5
 * Copyright (C) 2008-2010 Nokia Corporation
6
 * Copyright (C) 2011-2013 Texas Instruments Inc.
L
Luciano Coelho 已提交
7 8 9 10 11
 */

#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/etherdevice.h>
12
#include <linux/vmalloc.h>
13
#include <linux/interrupt.h>
14
#include <linux/irq.h>
15
#include <linux/pm_runtime.h>
16
#include <linux/pm_wakeirq.h>
L
Luciano Coelho 已提交
17

18
#include "wlcore.h"
19
#include "debug.h"
L
Luciano Coelho 已提交
20
#include "wl12xx_80211.h"
S
Shahar Levi 已提交
21 22 23 24 25 26
#include "io.h"
#include "tx.h"
#include "ps.h"
#include "init.h"
#include "debugfs.h"
#include "testmode.h"
E
Eliad Peller 已提交
27
#include "vendor_cmd.h"
S
Shahar Levi 已提交
28
#include "scan.h"
29
#include "hw_ops.h"
30
#include "sysfs.h"
L
Luciano Coelho 已提交
31

32
#define WL1271_BOOT_RETRIES 3
33
#define WL1271_SUSPEND_SLEEP 100
34
#define WL1271_WAKEUP_TIMEOUT 500
35

36
static char *fwlog_param;
I
Ido Reis 已提交
37
static int fwlog_mem_blocks = -1;
38 39
static int bug_on_recovery = -1;
static int no_recovery     = -1;
40

41
static void __wl1271_op_remove_interface(struct wl1271 *wl,
E
Eliad Peller 已提交
42
					 struct ieee80211_vif *vif,
43
					 bool reset_tx_queues);
44
static void wlcore_op_stop_locked(struct wl1271 *wl);
45
static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif);
46

47
static int wl12xx_set_authorized(struct wl1271 *wl, struct wl12xx_vif *wlvif)
48 49
{
	int ret;
E
Eliad Peller 已提交
50

51 52 53 54
	if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
		return -EINVAL;

	if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
55 56
		return 0;

57
	if (test_and_set_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags))
58 59
		return 0;

60
	ret = wl12xx_cmd_set_peer_state(wl, wlvif, wlvif->sta.hlid);
61 62 63 64 65 66
	if (ret < 0)
		return ret;

	wl1271_info("Association completed.");
	return 0;
}
67

68 69
static void wl1271_reg_notify(struct wiphy *wiphy,
			      struct regulatory_request *request)
70
{
71 72
	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
	struct wl1271 *wl = hw->priv;
73

74 75 76 77
	/* copy the current dfs region */
	if (request)
		wl->dfs_region = request->dfs_region;

78
	wlcore_regdomain_config(wl);
79 80
}

E
Eliad Peller 已提交
81 82
static int wl1271_set_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
				   bool enable)
83 84 85 86
{
	int ret = 0;

	/* we should hold wl->mutex */
E
Eliad Peller 已提交
87
	ret = wl1271_acx_ps_rx_streaming(wl, wlvif, enable);
88 89 90 91
	if (ret < 0)
		goto out;

	if (enable)
92
		set_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags);
93
	else
94
		clear_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags);
95 96 97 98 99 100 101 102
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 已提交
103
int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif)
104 105 106 107 108
{
	int ret = 0;
	int period = wl->conf.rx_streaming.interval;

	/* don't reconfigure if rx_streaming is disabled */
109
	if (!test_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags))
110 111 112 113
		goto out;

	/* reconfigure/disable according to new streaming_period */
	if (period &&
114
	    test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
115 116
	    (wl->conf.rx_streaming.always ||
	     test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags)))
E
Eliad Peller 已提交
117
		ret = wl1271_set_rx_streaming(wl, wlvif, true);
118
	else {
E
Eliad Peller 已提交
119
		ret = wl1271_set_rx_streaming(wl, wlvif, false);
120
		/* don't cancel_work_sync since we might deadlock */
E
Eliad Peller 已提交
121
		del_timer_sync(&wlvif->rx_streaming_timer);
122 123 124 125 126 127 128 129
	}
out:
	return ret;
}

static void wl1271_rx_streaming_enable_work(struct work_struct *work)
{
	int ret;
E
Eliad Peller 已提交
130 131 132
	struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif,
						rx_streaming_enable_work);
	struct wl1271 *wl = wlvif->wl;
133 134 135

	mutex_lock(&wl->mutex);

136
	if (test_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags) ||
137
	    !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) ||
138 139 140 141 142 143 144
	    (!wl->conf.rx_streaming.always &&
	     !test_bit(WL1271_FLAG_SOFT_GEMINI, &wl->flags)))
		goto out;

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

145 146 147
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
148
		goto out;
149
	}
150

E
Eliad Peller 已提交
151
	ret = wl1271_set_rx_streaming(wl, wlvif, true);
152 153 154 155
	if (ret < 0)
		goto out_sleep;

	/* stop it after some time of inactivity */
E
Eliad Peller 已提交
156
	mod_timer(&wlvif->rx_streaming_timer,
157 158 159
		  jiffies + msecs_to_jiffies(wl->conf.rx_streaming.duration));

out_sleep:
160 161
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
162 163 164 165 166 167 168
out:
	mutex_unlock(&wl->mutex);
}

static void wl1271_rx_streaming_disable_work(struct work_struct *work)
{
	int ret;
E
Eliad Peller 已提交
169 170 171
	struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif,
						rx_streaming_disable_work);
	struct wl1271 *wl = wlvif->wl;
172 173 174

	mutex_lock(&wl->mutex);

175
	if (!test_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags))
176 177
		goto out;

178 179 180
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
181
		goto out;
182
	}
183

E
Eliad Peller 已提交
184
	ret = wl1271_set_rx_streaming(wl, wlvif, false);
185 186 187 188
	if (ret)
		goto out_sleep;

out_sleep:
189 190
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
191 192 193 194
out:
	mutex_unlock(&wl->mutex);
}

195
static void wl1271_rx_streaming_timer(struct timer_list *t)
196
{
197
	struct wl12xx_vif *wlvif = from_timer(wlvif, t, rx_streaming_timer);
E
Eliad Peller 已提交
198 199
	struct wl1271 *wl = wlvif->wl;
	ieee80211_queue_work(wl->hw, &wlvif->rx_streaming_disable_work);
200 201
}

A
Arik Nemtsov 已提交
202 203 204 205 206 207 208 209 210 211 212 213
/* wl->mutex must be taken */
void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl)
{
	/* if the watchdog is not armed, don't do anything */
	if (wl->tx_allocated_blocks == 0)
		return;

	cancel_delayed_work(&wl->tx_watchdog_work);
	ieee80211_queue_delayed_work(wl->hw, &wl->tx_watchdog_work,
		msecs_to_jiffies(wl->conf.tx.tx_watchdog_timeout));
}

214 215 216 217 218 219
static void wlcore_rc_update_work(struct work_struct *work)
{
	int ret;
	struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif,
						rc_update_work);
	struct wl1271 *wl = wlvif->wl;
220
	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
221 222 223 224 225 226

	mutex_lock(&wl->mutex);

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

227 228 229
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
230
		goto out;
231
	}
232

233 234 235 236 237 238 239 240
	if (ieee80211_vif_is_mesh(vif)) {
		ret = wl1271_acx_set_ht_capabilities(wl, &wlvif->rc_ht_cap,
						     true, wlvif->sta.hlid);
		if (ret < 0)
			goto out_sleep;
	} else {
		wlcore_hw_sta_rc_update(wl, wlvif);
	}
241

242
out_sleep:
243 244
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
245 246 247 248
out:
	mutex_unlock(&wl->mutex);
}

A
Arik Nemtsov 已提交
249 250 251 252 253
static void wl12xx_tx_watchdog_work(struct work_struct *work)
{
	struct delayed_work *dwork;
	struct wl1271 *wl;

G
Geliang Tang 已提交
254
	dwork = to_delayed_work(work);
A
Arik Nemtsov 已提交
255 256 257 258
	wl = container_of(dwork, struct wl1271, tx_watchdog_work);

	mutex_lock(&wl->mutex);

259
	if (unlikely(wl->state != WLCORE_STATE_ON))
A
Arik Nemtsov 已提交
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
		goto out;

	/* Tx went out in the meantime - everything is ok */
	if (unlikely(wl->tx_allocated_blocks == 0))
		goto out;

	/*
	 * if a ROC is in progress, we might not have any Tx for a long
	 * time (e.g. pending Tx on the non-ROC channels)
	 */
	if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) {
		wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to ROC",
			     wl->conf.tx.tx_watchdog_timeout);
		wl12xx_rearm_tx_watchdog_locked(wl);
		goto out;
	}

	/*
	 * if a scan is in progress, we might not have any Tx for a long
	 * time
	 */
	if (wl->scan.state != WL1271_SCAN_STATE_IDLE) {
		wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms due to scan",
			     wl->conf.tx.tx_watchdog_timeout);
		wl12xx_rearm_tx_watchdog_locked(wl);
		goto out;
	}

	/*
	* AP might cache a frame for a long time for a sleeping station,
	* so rearm the timer if there's an AP interface with stations. If
	* Tx is genuinely stuck we will most hopefully discover it when all
	* stations are removed due to inactivity.
	*/
	if (wl->active_sta_count) {
		wl1271_debug(DEBUG_TX, "No Tx (in FW) for %d ms. AP has "
			     " %d stations",
			      wl->conf.tx.tx_watchdog_timeout,
			      wl->active_sta_count);
		wl12xx_rearm_tx_watchdog_locked(wl);
		goto out;
	}

	wl1271_error("Tx stuck (in FW) for %d ms. Starting recovery",
		     wl->conf.tx.tx_watchdog_timeout);
	wl12xx_queue_recovery_work(wl);

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

311
static void wlcore_adjust_conf(struct wl1271 *wl)
312
{
I
Ido Reis 已提交
313

314 315 316
	if (fwlog_param) {
		if (!strcmp(fwlog_param, "continuous")) {
			wl->conf.fwlog.mode = WL12XX_FWLOG_CONTINUOUS;
S
Shahar Patury 已提交
317
			wl->conf.fwlog.output = WL12XX_FWLOG_OUTPUT_HOST;
318 319 320 321 322 323 324 325 326 327
		} 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);
		}
	}
328 329 330 331 332 333

	if (bug_on_recovery != -1)
		wl->conf.recovery.bug_on_recovery = (u8) bug_on_recovery;

	if (no_recovery != -1)
		wl->conf.recovery.no_recovery = (u8) no_recovery;
334
}
335

336 337 338
static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
					struct wl12xx_vif *wlvif,
					u8 hlid, u8 tx_pkts)
339
{
340
	bool fw_ps;
341

342
	fw_ps = test_bit(hlid, &wl->ap_fw_ps_map);
343 344 345

	/*
	 * Wake up from high level PS if the STA is asleep with too little
346
	 * packets in FW or if the STA is awake.
347
	 */
348
	if (!fw_ps || tx_pkts < WL1271_PS_STA_MAX_PACKETS)
349
		wl12xx_ps_link_end(wl, wlvif, hlid);
350

351 352
	/*
	 * Start high-level PS if the STA is asleep with enough blocks in FW.
353 354
	 * Make an exception if this is the only connected link. In this
	 * case FW-memory congestion is less of a problem.
355 356 357 358
	 * Note that a single connected STA means 2*ap_count + 1 active links,
	 * since we must account for the global and broadcast AP links
	 * for each AP. The "fw_ps" check assures us the other link is a STA
	 * connected to the AP. Otherwise the FW would not set the PSM bit.
359
	 */
360
	else if (wl->active_link_count > (wl->ap_count*2 + 1) && fw_ps &&
361
		 tx_pkts >= WL1271_PS_STA_MAX_PACKETS)
362
		wl12xx_ps_link_start(wl, wlvif, hlid, true);
363 364
}

365
static void wl12xx_irq_update_links_status(struct wl1271 *wl,
366
					   struct wl12xx_vif *wlvif,
367
					   struct wl_fw_status *status)
368
{
369
	unsigned long cur_fw_ps_map;
370
	u8 hlid;
371

372
	cur_fw_ps_map = status->link_ps_bitmap;
373 374
	if (wl->ap_fw_ps_map != cur_fw_ps_map) {
		wl1271_debug(DEBUG_PSM,
375
			     "link ps prev 0x%lx cur 0x%lx changed 0x%lx",
376 377 378 379 380 381
			     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;
	}

382
	for_each_set_bit(hlid, wlvif->ap.sta_hlid_map, wl->num_links)
383
		wl12xx_irq_ps_regulate_link(wl, wlvif, hlid,
384
					    wl->links[hlid].allocated_pkts);
385 386
}

387
static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status)
L
Luciano Coelho 已提交
388
{
389
	struct wl12xx_vif *wlvif;
390
	u32 old_tx_blk_count = wl->tx_blocks_available;
E
Eliad Peller 已提交
391
	int avail, freed_blocks;
392
	int i;
393
	int ret;
394
	struct wl1271_link *lnk;
395

396 397 398
	ret = wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR,
				   wl->raw_fw_status,
				   wl->fw_status_len, false);
399 400
	if (ret < 0)
		return ret;
401

402 403
	wlcore_hw_convert_fw_status(wl, wl->raw_fw_status, wl->fw_status);

L
Luciano Coelho 已提交
404 405
	wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
		     "drv_rx_counter = %d, tx_results_counter = %d)",
406 407 408 409
		     status->intr,
		     status->fw_rx_counter,
		     status->drv_rx_counter,
		     status->tx_results_counter);
L
Luciano Coelho 已提交
410

411 412
	for (i = 0; i < NUM_TX_QUEUES; i++) {
		/* prevent wrap-around in freed-packets counter */
413
		wl->tx_allocated_pkts[i] -=
414
				(status->counters.tx_released_pkts[i] -
415 416
				wl->tx_pkts_freed[i]) & 0xff;

417
		wl->tx_pkts_freed[i] = status->counters.tx_released_pkts[i];
418 419
	}

420

421
	for_each_set_bit(i, wl->links_map, wl->num_links) {
422
		u8 diff;
423
		lnk = &wl->links[i];
424

425
		/* prevent wrap-around in freed-packets counter */
426
		diff = (status->counters.tx_lnk_free_pkts[i] -
427 428 429 430
		       lnk->prev_freed_pkts) & 0xff;

		if (diff == 0)
			continue;
431

432
		lnk->allocated_pkts -= diff;
433
		lnk->prev_freed_pkts = status->counters.tx_lnk_free_pkts[i];
434 435 436

		/* accumulate the prev_freed_pkts counter */
		lnk->total_freed_pkts += diff;
437 438
	}

439
	/* prevent wrap-around in total blocks counter */
440 441
	if (likely(wl->tx_blocks_freed <= status->total_released_blks))
		freed_blocks = status->total_released_blks -
442 443 444
			       wl->tx_blocks_freed;
	else
		freed_blocks = 0x100000000LL - wl->tx_blocks_freed +
445
			       status->total_released_blks;
446

447
	wl->tx_blocks_freed = status->total_released_blks;
448

449 450
	wl->tx_allocated_blocks -= freed_blocks;

A
Arik Nemtsov 已提交
451 452 453 454 455 456 457 458 459 460 461 462
	/*
	 * If the FW freed some blocks:
	 * If we still have allocated blocks - re-arm the timer, Tx is
	 * not stuck. Otherwise, cancel the timer (no Tx currently).
	 */
	if (freed_blocks) {
		if (wl->tx_allocated_blocks)
			wl12xx_rearm_tx_watchdog_locked(wl);
		else
			cancel_delayed_work(&wl->tx_watchdog_work);
	}

463
	avail = status->tx_total - wl->tx_allocated_blocks;
464

E
Eliad Peller 已提交
465 466 467 468 469 470 471 472 473 474
	/*
	 * 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 已提交
475

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

E
Eliad Peller 已提交
480
	/* for AP update num of allocated TX blocks per link and ps status */
481
	wl12xx_for_each_wlvif_ap(wl, wlvif) {
482
		wl12xx_irq_update_links_status(wl, wlvif, status);
483
	}
E
Eliad Peller 已提交
484

L
Luciano Coelho 已提交
485
	/* update the host-chipset time offset */
486
	wl->time_offset = (ktime_get_boottime_ns() >> 10) -
487
		(s64)(status->fw_localtime);
488

489
	wl->fw_fast_lnk_map = status->link_fast_bitmap;
490

491
	return 0;
L
Luciano Coelho 已提交
492 493
}

494 495 496 497 498 499 500 501 502 503
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)))
504
		ieee80211_tx_status_ni(wl->hw, skb);
505 506 507 508 509 510 511 512 513 514 515
}

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));
}
516

517 518
#define WL1271_IRQ_MAX_LOOPS 256

519
static int wlcore_irq_locked(struct wl1271 *wl)
L
Luciano Coelho 已提交
520
{
521
	int ret = 0;
522
	u32 intr;
523
	int loopcount = WL1271_IRQ_MAX_LOOPS;
524 525
	bool done = false;
	unsigned int defer_count;
I
Ido Yariv 已提交
526 527
	unsigned long flags;

528 529 530 531
	/*
	 * In case edge triggered interrupt must be used, we cannot iterate
	 * more than once without introducing race conditions with the hardirq.
	 */
532
	if (wl->irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
533 534
		loopcount = 1;

L
Luciano Coelho 已提交
535 536
	wl1271_debug(DEBUG_IRQ, "IRQ work");

537
	if (unlikely(wl->state != WLCORE_STATE_ON))
L
Luciano Coelho 已提交
538 539
		goto out;

540 541 542
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
L
Luciano Coelho 已提交
543
		goto out;
544
	}
L
Luciano Coelho 已提交
545

546
	while (!done && loopcount--) {
547
		smp_mb__after_atomic();
548

549
		ret = wlcore_fw_status(wl, wl->fw_status);
550
		if (ret < 0)
551
			goto out;
552 553 554

		wlcore_hw_tx_immediate_compl(wl);

555
		intr = wl->fw_status->intr;
556
		intr &= WLCORE_ALL_INTR_MASK;
557
		if (!intr) {
558
			done = true;
559 560
			continue;
		}
L
Luciano Coelho 已提交
561

562
		if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) {
563 564
			wl1271_error("HW watchdog interrupt received! starting recovery.");
			wl->watchdog_recovery = true;
565
			ret = -EIO;
566 567 568 569 570 571 572

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

		if (unlikely(intr & WL1271_ACX_SW_INTR_WATCHDOG)) {
			wl1271_error("SW watchdog interrupt received! "
573
				     "starting recovery.");
574
			wl->watchdog_recovery = true;
575
			ret = -EIO;
576 577 578 579 580

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

581
		if (likely(intr & WL1271_ACX_INTR_DATA)) {
582
			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
583

584
			ret = wlcore_rx(wl, wl->fw_status);
585
			if (ret < 0)
586
				goto out;
L
Luciano Coelho 已提交
587

I
Ido Yariv 已提交
588
			/* Check if any tx blocks were freed */
I
Ido Yariv 已提交
589
			spin_lock_irqsave(&wl->wl_lock, flags);
I
Ido Yariv 已提交
590
			if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
591
			    wl1271_tx_total_queue_count(wl) > 0) {
I
Ido Yariv 已提交
592
				spin_unlock_irqrestore(&wl->wl_lock, flags);
I
Ido Yariv 已提交
593 594 595 596
				/*
				 * In order to avoid starvation of the TX path,
				 * call the work function directly.
				 */
597
				ret = wlcore_tx_work_locked(wl);
598
				if (ret < 0)
599
					goto out;
I
Ido Yariv 已提交
600 601
			} else {
				spin_unlock_irqrestore(&wl->wl_lock, flags);
I
Ido Yariv 已提交
602 603
			}

604
			/* check for tx results */
605
			ret = wlcore_hw_tx_delayed_compl(wl);
606
			if (ret < 0)
607
				goto out;
608 609 610 611 612 613

			/* 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);
614
		}
L
Luciano Coelho 已提交
615

616 617
		if (intr & WL1271_ACX_INTR_EVENT_A) {
			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A");
618
			ret = wl1271_event_handle(wl, 0);
619
			if (ret < 0)
620
				goto out;
621
		}
L
Luciano Coelho 已提交
622

623 624
		if (intr & WL1271_ACX_INTR_EVENT_B) {
			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B");
625
			ret = wl1271_event_handle(wl, 1);
626
			if (ret < 0)
627
				goto out;
628
		}
L
Luciano Coelho 已提交
629

630 631 632
		if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
			wl1271_debug(DEBUG_IRQ,
				     "WL1271_ACX_INTR_INIT_COMPLETE");
L
Luciano Coelho 已提交
633

634 635
		if (intr & WL1271_ACX_INTR_HW_AVAILABLE)
			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
636
	}
L
Luciano Coelho 已提交
637

638 639
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
L
Luciano Coelho 已提交
640 641

out:
642 643 644 645 646 647 648 649 650
	return ret;
}

static irqreturn_t wlcore_irq(int irq, void *cookie)
{
	int ret;
	unsigned long flags;
	struct wl1271 *wl = cookie;

651 652 653 654 655 656 657 658 659 660 661 662 663 664 665
	/* 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);
666
		goto out_handled;
667 668 669
	}
	spin_unlock_irqrestore(&wl->wl_lock, flags);

670 671 672 673 674 675 676 677 678 679
	/* TX might be handled here, avoid redundant work */
	set_bit(WL1271_FLAG_TX_PENDING, &wl->flags);
	cancel_work_sync(&wl->tx_work);

	mutex_lock(&wl->mutex);

	ret = wlcore_irq_locked(wl);
	if (ret)
		wl12xx_queue_recovery_work(wl);

I
Ido Yariv 已提交
680 681 682 683
	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) &&
684
	    wl1271_tx_total_queue_count(wl) > 0)
I
Ido Yariv 已提交
685 686 687
		ieee80211_queue_work(wl->hw, &wl->tx_work);
	spin_unlock_irqrestore(&wl->wl_lock, flags);

L
Luciano Coelho 已提交
688
	mutex_unlock(&wl->mutex);
689

690 691 692 693 694
out_handled:
	spin_lock_irqsave(&wl->wl_lock, flags);
	clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
	spin_unlock_irqrestore(&wl->wl_lock, flags);

695
	return IRQ_HANDLED;
L
Luciano Coelho 已提交
696 697
}

698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
struct vif_counter_data {
	u8 counter;

	struct ieee80211_vif *cur_vif;
	bool cur_vif_running;
};

static void wl12xx_vif_count_iter(void *data, u8 *mac,
				  struct ieee80211_vif *vif)
{
	struct vif_counter_data *counter = data;

	counter->counter++;
	if (counter->cur_vif == vif)
		counter->cur_vif_running = true;
}

/* caller must not hold wl->mutex, as it might deadlock */
static void wl12xx_get_vif_count(struct ieee80211_hw *hw,
			       struct ieee80211_vif *cur_vif,
			       struct vif_counter_data *data)
{
	memset(data, 0, sizeof(*data));
	data->cur_vif = cur_vif;

723
	ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
724 725 726
					    wl12xx_vif_count_iter, data);
}

727
static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
L
Luciano Coelho 已提交
728 729
{
	const struct firmware *fw;
730
	const char *fw_name;
731
	enum wl12xx_fw_type fw_type;
L
Luciano Coelho 已提交
732 733
	int ret;

734 735
	if (plt) {
		fw_type = WL12XX_FW_TYPE_PLT;
736
		fw_name = wl->plt_fw_name;
737
	} else {
738 739 740 741
		/*
		 * we can't call wl12xx_get_vif_count() here because
		 * wl->mutex is taken, so use the cached last_vif_count value
		 */
E
Eliad Peller 已提交
742
		if (wl->last_vif_count > 1 && wl->mr_fw_name) {
743
			fw_type = WL12XX_FW_TYPE_MULTI;
744
			fw_name = wl->mr_fw_name;
745 746
		} else {
			fw_type = WL12XX_FW_TYPE_NORMAL;
747
			fw_name = wl->sr_fw_name;
748
		}
749 750 751 752
	}

	if (wl->fw_type == fw_type)
		return 0;
753 754 755

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

756
	ret = request_firmware(&fw, fw_name, wl->dev);
L
Luciano Coelho 已提交
757 758

	if (ret < 0) {
759
		wl1271_error("could not get firmware %s: %d", fw_name, ret);
L
Luciano Coelho 已提交
760 761 762 763 764 765 766 767 768 769
		return ret;
	}

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

770
	vfree(wl->fw);
771
	wl->fw_type = WL12XX_FW_TYPE_NONE;
L
Luciano Coelho 已提交
772
	wl->fw_len = fw->size;
773
	wl->fw = vmalloc(wl->fw_len);
L
Luciano Coelho 已提交
774 775 776 777 778 779 780 781 782

	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;
783
	wl->fw_type = fw_type;
L
Luciano Coelho 已提交
784 785 786 787 788 789
out:
	release_firmware(fw);

	return ret;
}

790 791
void wl12xx_queue_recovery_work(struct wl1271 *wl)
{
792
	/* Avoid a recursive recovery */
I
Ido Yariv 已提交
793
	if (wl->state == WLCORE_STATE_ON) {
794 795 796
		WARN_ON(!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY,
				  &wl->flags));

797
		wl->state = WLCORE_STATE_RESTARTING;
I
Ido Yariv 已提交
798
		set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
799
		ieee80211_queue_work(wl->hw, &wl->recovery_work);
800
	}
801 802
}

803 804
size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
{
805
	size_t len;
806 807

	/* Make sure we have enough room */
S
Silvan Jegen 已提交
808
	len = min_t(size_t, maxlen, PAGE_SIZE - wl->fwlog_size);
809 810 811 812 813 814 815 816 817 818

	/* 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)
{
S
Shahar Patury 已提交
819
	u32 end_of_log = 0;
820
	int error;
821

S
Shahar Patury 已提交
822
	if (wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED)
823 824 825 826 827 828
		return;

	wl1271_info("Reading FW panic log");

	/*
	 * Make sure the chip is awake and the logger isn't active.
829 830
	 * Do not send a stop fwlog command if the fw is hanged or if
	 * dbgpins are used (due to some fw bug).
831
	 */
832 833 834
	error = pm_runtime_get_sync(wl->dev);
	if (error < 0) {
		pm_runtime_put_noidle(wl->dev);
S
Shahar Patury 已提交
835
		return;
836
	}
837 838
	if (!wl->watchdog_recovery &&
	    wl->conf.fwlog.output != WL12XX_FWLOG_OUTPUT_DBG_PINS)
839
		wl12xx_cmd_stop_fwlog(wl);
840 841 842

	/* Traverse the memory blocks linked list */
	do {
S
Shahar Patury 已提交
843 844 845 846
		end_of_log = wlcore_event_fw_logger(wl);
		if (end_of_log == 0) {
			msleep(100);
			end_of_log = wlcore_event_fw_logger(wl);
847
		}
S
Shahar Patury 已提交
848
	} while (end_of_log != 0);
849 850
}

851 852 853 854
static void wlcore_save_freed_pkts(struct wl1271 *wl, struct wl12xx_vif *wlvif,
				   u8 hlid, struct ieee80211_sta *sta)
{
	struct wl1271_station *wl_sta;
855
	u32 sqn_recovery_padding = WL1271_TX_SQN_POST_RECOVERY_PADDING;
856 857 858 859 860 861 862 863

	wl_sta = (void *)sta->drv_priv;
	wl_sta->total_freed_pkts = wl->links[hlid].total_freed_pkts;

	/*
	 * increment the initial seq number on recovery to account for
	 * transmitted packets that we haven't yet got in the FW status
	 */
864 865 866
	if (wlvif->encryption_type == KEY_GEM)
		sqn_recovery_padding = WL1271_TX_SQN_POST_RECOVERY_PADDING_GEM;

867
	if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
868
		wl_sta->total_freed_pkts += sqn_recovery_padding;
869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
}

static void wlcore_save_freed_pkts_addr(struct wl1271 *wl,
					struct wl12xx_vif *wlvif,
					u8 hlid, const u8 *addr)
{
	struct ieee80211_sta *sta;
	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);

	if (WARN_ON(hlid == WL12XX_INVALID_LINK_ID ||
		    is_zero_ether_addr(addr)))
		return;

	rcu_read_lock();
	sta = ieee80211_find_sta(vif, addr);
	if (sta)
		wlcore_save_freed_pkts(wl, wlvif, hlid, sta);
	rcu_read_unlock();
}

889 890 891 892 893 894 895 896 897 898
static void wlcore_print_recovery(struct wl1271 *wl)
{
	u32 pc = 0;
	u32 hint_sts = 0;
	int ret;

	wl1271_info("Hardware recovery in progress. FW ver: %s",
		    wl->chip.fw_ver_str);

	/* change partitions momentarily so we can read the FW pc */
899 900 901
	ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
	if (ret < 0)
		return;
902 903 904 905 906 907 908 909 910

	ret = wlcore_read_reg(wl, REG_PC_ON_RECOVERY, &pc);
	if (ret < 0)
		return;

	ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &hint_sts);
	if (ret < 0)
		return;

911 912
	wl1271_info("pc: 0x%x, hint_sts: 0x%08x count: %d",
				pc, hint_sts, ++wl->recovery_count);
913 914 915 916 917

	wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
}


918 919 920 921
static void wl1271_recovery_work(struct work_struct *work)
{
	struct wl1271 *wl =
		container_of(work, struct wl1271, recovery_work);
922
	struct wl12xx_vif *wlvif;
923
	struct ieee80211_vif *vif;
924
	int error;
925 926 927

	mutex_lock(&wl->mutex);

928
	if (wl->state == WLCORE_STATE_OFF || wl->plt)
E
Eliad Peller 已提交
929
		goto out_unlock;
930

931 932
	error = pm_runtime_get_sync(wl->dev);
	if (error < 0) {
933
		wl1271_warning("Enable for recovery failed");
934 935
		pm_runtime_put_noidle(wl->dev);
	}
936 937
	wlcore_disable_interrupts_nosync(wl);

938
	if (!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) {
939 940
		if (wl->conf.fwlog.output == WL12XX_FWLOG_OUTPUT_HOST)
			wl12xx_read_fwlog_panic(wl);
941 942
		wlcore_print_recovery(wl);
	}
943

944
	BUG_ON(wl->conf.recovery.bug_on_recovery &&
945
	       !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags));
946

947 948
	clear_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);

949
	if (wl->conf.recovery.no_recovery) {
950 951 952 953
		wl1271_info("No recovery (chosen on module load). Fw will remain stuck.");
		goto out_unlock;
	}

954
	/* Prevent spurious TX during FW restart */
955
	wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART);
956

957
	/* reboot the chipset */
958 959 960 961
	while (!list_empty(&wl->wlvif_list)) {
		wlvif = list_first_entry(&wl->wlvif_list,
				       struct wl12xx_vif, list);
		vif = wl12xx_wlvif_to_vif(wlvif);
962 963 964 965 966 967 968

		if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
		    test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
			wlcore_save_freed_pkts_addr(wl, wlvif, wlvif->sta.hlid,
						    vif->bss_conf.bssid);
		}

969 970
		__wl1271_op_remove_interface(wl, vif, false);
	}
971 972

	wlcore_op_stop_locked(wl);
973 974
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
975

976 977
	ieee80211_restart_hw(wl->hw);

978 979 980 981
	/*
	 * Its safe to enable TX now - the queues are stopped after a request
	 * to restart the HW.
	 */
982
	wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_FW_RESTART);
983

E
Eliad Peller 已提交
984
out_unlock:
985 986
	wl->watchdog_recovery = false;
	clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags);
987 988 989
	mutex_unlock(&wl->mutex);
}

990
static int wlcore_fw_wakeup(struct wl1271 *wl)
L
Luciano Coelho 已提交
991
{
992
	return wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
L
Luciano Coelho 已提交
993 994 995 996
}

static int wl1271_setup(struct wl1271 *wl)
{
997 998 999
	wl->raw_fw_status = kzalloc(wl->fw_status_len, GFP_KERNEL);
	if (!wl->raw_fw_status)
		goto err;
L
Luciano Coelho 已提交
1000

1001 1002 1003
	wl->fw_status = kzalloc(sizeof(*wl->fw_status), GFP_KERNEL);
	if (!wl->fw_status)
		goto err;
1004

1005
	wl->tx_res_if = kzalloc(sizeof(*wl->tx_res_if), GFP_KERNEL);
1006 1007
	if (!wl->tx_res_if)
		goto err;
L
Luciano Coelho 已提交
1008 1009

	return 0;
1010 1011 1012 1013
err:
	kfree(wl->fw_status);
	kfree(wl->raw_fw_status);
	return -ENOMEM;
L
Luciano Coelho 已提交
1014 1015
}

1016
static int wl12xx_set_power_on(struct wl1271 *wl)
L
Luciano Coelho 已提交
1017
{
1018
	int ret;
L
Luciano Coelho 已提交
1019

J
Juuso Oikarinen 已提交
1020
	msleep(WL1271_PRE_POWER_ON_SLEEP);
1021 1022 1023
	ret = wl1271_power_on(wl);
	if (ret < 0)
		goto out;
L
Luciano Coelho 已提交
1024
	msleep(WL1271_POWER_ON_SLEEP);
1025 1026
	wl1271_io_reset(wl);
	wl1271_io_init(wl);
L
Luciano Coelho 已提交
1027

1028 1029 1030
	ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
	if (ret < 0)
		goto fail;
L
Luciano Coelho 已提交
1031 1032

	/* ELP module wake up */
1033 1034 1035
	ret = wlcore_fw_wakeup(wl);
	if (ret < 0)
		goto fail;
L
Luciano Coelho 已提交
1036

1037 1038
out:
	return ret;
1039 1040 1041 1042

fail:
	wl1271_power_off(wl);
	return ret;
1043
}
L
Luciano Coelho 已提交
1044

1045
static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt)
1046 1047 1048 1049 1050 1051
{
	int ret = 0;

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

1053 1054 1055 1056 1057 1058 1059
	/*
	 * 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.
1060 1061 1062
	 *
	 * Check if the bus supports blocksize alignment and, if it
	 * doesn't, make sure we don't have the quirk.
1063
	 */
1064 1065
	if (!wl1271_set_block_size(wl))
		wl->quirks &= ~WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN;
L
Luciano Coelho 已提交
1066

1067
	/* TODO: make sure the lower driver has set things up correctly */
1068

1069 1070
	ret = wl1271_setup(wl);
	if (ret < 0)
1071
		goto out;
L
Luciano Coelho 已提交
1072

1073
	ret = wl12xx_fetch_firmware(wl, plt);
1074 1075 1076 1077 1078
	if (ret < 0) {
		kfree(wl->fw_status);
		kfree(wl->raw_fw_status);
		kfree(wl->tx_res_if);
	}
L
Luciano Coelho 已提交
1079 1080 1081 1082 1083

out:
	return ret;
}

1084
int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode)
L
Luciano Coelho 已提交
1085
{
1086
	int retries = WL1271_BOOT_RETRIES;
1087
	struct wiphy *wiphy = wl->hw->wiphy;
1088 1089 1090 1091

	static const char* const PLT_MODE[] = {
		"PLT_OFF",
		"PLT_ON",
1092 1093
		"PLT_FEM_DETECT",
		"PLT_CHIP_AWAKE"
1094 1095
	};

L
Luciano Coelho 已提交
1096 1097 1098 1099 1100 1101
	int ret;

	mutex_lock(&wl->mutex);

	wl1271_notice("power up");

1102
	if (wl->state != WLCORE_STATE_OFF) {
L
Luciano Coelho 已提交
1103 1104 1105 1106 1107 1108
		wl1271_error("cannot go into PLT state because not "
			     "in off state: %d", wl->state);
		ret = -EBUSY;
		goto out;
	}

1109 1110 1111 1112
	/* Indicate to lower levels that we are now in PLT mode */
	wl->plt = true;
	wl->plt_mode = plt_mode;

1113 1114
	while (retries) {
		retries--;
1115
		ret = wl12xx_chip_wakeup(wl, true);
1116 1117
		if (ret < 0)
			goto power_off;
L
Luciano Coelho 已提交
1118

1119 1120 1121 1122 1123
		if (plt_mode != PLT_CHIP_AWAKE) {
			ret = wl->ops->plt_init(wl);
			if (ret < 0)
				goto power_off;
		}
1124

1125
		wl->state = WLCORE_STATE_ON;
1126 1127
		wl1271_notice("firmware booted in PLT mode %s (%s)",
			      PLT_MODE[plt_mode],
L
Levi, Shahar 已提交
1128
			      wl->chip.fw_ver_str);
1129

1130 1131 1132 1133 1134
		/* 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));

1135
		goto out;
1136

1137 1138 1139
power_off:
		wl1271_power_off(wl);
	}
L
Luciano Coelho 已提交
1140

1141 1142 1143
	wl->plt = false;
	wl->plt_mode = PLT_OFF;

1144 1145
	wl1271_error("firmware boot in PLT mode failed despite %d retries",
		     WL1271_BOOT_RETRIES);
L
Luciano Coelho 已提交
1146 1147 1148 1149 1150 1151
out:
	mutex_unlock(&wl->mutex);

	return ret;
}

1152
int wl1271_plt_stop(struct wl1271 *wl)
L
Luciano Coelho 已提交
1153 1154 1155 1156 1157
{
	int ret = 0;

	wl1271_notice("power down");

1158 1159 1160 1161 1162
	/*
	 * Interrupts must be disabled before setting the state to OFF.
	 * Otherwise, the interrupt handler might be called and exit without
	 * reading the interrupt status.
	 */
1163
	wlcore_disable_interrupts(wl);
1164
	mutex_lock(&wl->mutex);
1165
	if (!wl->plt) {
1166
		mutex_unlock(&wl->mutex);
1167 1168 1169 1170 1171 1172

		/*
		 * 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().
		 */
1173
		wlcore_enable_interrupts(wl);
1174

L
Luciano Coelho 已提交
1175 1176 1177 1178 1179 1180 1181
		wl1271_error("cannot power down because not in PLT "
			     "state: %d", wl->state);
		ret = -EBUSY;
		goto out;
	}

	mutex_unlock(&wl->mutex);
1182

1183 1184
	wl1271_flush_deferred_work(wl);
	cancel_work_sync(&wl->netstack_work);
1185
	cancel_work_sync(&wl->recovery_work);
A
Arik Nemtsov 已提交
1186
	cancel_delayed_work_sync(&wl->tx_watchdog_work);
1187 1188 1189

	mutex_lock(&wl->mutex);
	wl1271_power_off(wl);
1190
	wl->flags = 0;
1191
	wl->sleep_auth = WL1271_PSM_ILLEGAL;
1192
	wl->state = WLCORE_STATE_OFF;
1193
	wl->plt = false;
1194
	wl->plt_mode = PLT_OFF;
1195
	wl->rx_counter = 0;
1196 1197
	mutex_unlock(&wl->mutex);

1198 1199 1200 1201
out:
	return ret;
}

1202 1203 1204
static void wl1271_op_tx(struct ieee80211_hw *hw,
			 struct ieee80211_tx_control *control,
			 struct sk_buff *skb)
L
Luciano Coelho 已提交
1205 1206
{
	struct wl1271 *wl = hw->priv;
1207 1208
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
	struct ieee80211_vif *vif = info->control.vif;
E
Eliad Peller 已提交
1209
	struct wl12xx_vif *wlvif = NULL;
1210
	unsigned long flags;
1211
	int q, mapping;
1212
	u8 hlid;
L
Luciano Coelho 已提交
1213

1214 1215 1216 1217 1218
	if (!vif) {
		wl1271_debug(DEBUG_TX, "DROP skb with no vif");
		ieee80211_free_txskb(hw, skb);
		return;
	}
E
Eliad Peller 已提交
1219

1220
	wlvif = wl12xx_vif_to_data(vif);
1221 1222
	mapping = skb_get_queue_mapping(skb);
	q = wl1271_tx_get_queue(mapping);
I
Ido Yariv 已提交
1223

1224
	hlid = wl12xx_tx_get_hlid(wl, wlvif, skb, control->sta);
I
Ido Yariv 已提交
1225

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

1228 1229 1230 1231 1232
	/*
	 * drop the packet if the link is invalid or the queue is stopped
	 * for any reason but watermark. Watermark is a "soft"-stop so we
	 * allow these packets through.
	 */
1233
	if (hlid == WL12XX_INVALID_LINK_ID ||
1234
	    (!test_bit(hlid, wlvif->links_map)) ||
1235 1236
	     (wlcore_is_queue_stopped_locked(wl, wlvif, q) &&
	      !wlcore_is_queue_stopped_by_reason_locked(wl, wlvif, q,
1237
			WLCORE_QUEUE_STOP_REASON_WATERMARK))) {
1238
		wl1271_debug(DEBUG_TX, "DROP skb hlid %d q %d", hlid, q);
E
Eliad Peller 已提交
1239
		ieee80211_free_txskb(hw, skb);
1240
		goto out;
1241
	}
L
Luciano Coelho 已提交
1242

E
Eliad Peller 已提交
1243 1244
	wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d len %d",
		     hlid, q, skb->len);
1245 1246
	skb_queue_tail(&wl->links[hlid].tx_queue[q], skb);

1247
	wl->tx_queue_count[q]++;
1248
	wlvif->tx_queue_count[q]++;
1249 1250 1251 1252 1253

	/*
	 * The workqueue is slow to process the tx_queue and we need stop
	 * the queue here, otherwise the queue will get too long.
	 */
1254
	if (wlvif->tx_queue_count[q] >= WL1271_TX_QUEUE_HIGH_WATERMARK &&
1255
	    !wlcore_is_queue_stopped_by_reason_locked(wl, wlvif, q,
1256
					WLCORE_QUEUE_STOP_REASON_WATERMARK)) {
1257
		wl1271_debug(DEBUG_TX, "op_tx: stopping queues for q %d", q);
1258
		wlcore_stop_queue_locked(wl, wlvif, q,
1259
					 WLCORE_QUEUE_STOP_REASON_WATERMARK);
1260 1261
	}

L
Luciano Coelho 已提交
1262 1263 1264 1265 1266
	/*
	 * The chip specific setup must run before the first TX packet -
	 * before that, the tx_work will not be initialized!
	 */

I
Ido Yariv 已提交
1267 1268
	if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
	    !test_bit(WL1271_FLAG_TX_PENDING, &wl->flags))
I
Ido Yariv 已提交
1269
		ieee80211_queue_work(wl->hw, &wl->tx_work);
I
Ido Yariv 已提交
1270

1271
out:
I
Ido Yariv 已提交
1272
	spin_unlock_irqrestore(&wl->wl_lock, flags);
L
Luciano Coelho 已提交
1273 1274
}

1275 1276
int wl1271_tx_dummy_packet(struct wl1271 *wl)
{
1277
	unsigned long flags;
1278 1279 1280 1281 1282 1283 1284
	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));
1285 1286 1287

	spin_lock_irqsave(&wl->wl_lock, flags);
	set_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags);
1288
	wl->tx_queue_count[q]++;
1289 1290 1291 1292
	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))
1293
		return wlcore_tx_work_locked(wl);
1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308

	/*
	 * 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))

1309
static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
1310 1311
{
	struct sk_buff *skb;
1312
	struct ieee80211_hdr_3addr *hdr;
1313 1314 1315 1316
	unsigned int dummy_packet_size;

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

1318
	skb = dev_alloc_skb(TOTAL_TX_DUMMY_PACKET_SIZE);
1319
	if (!skb) {
1320 1321
		wl1271_warning("Failed to allocate a dummy packet skb");
		return NULL;
1322 1323 1324 1325
	}

	skb_reserve(skb, sizeof(struct wl1271_tx_hw_descr));

1326
	hdr = skb_put_zero(skb, sizeof(*hdr));
1327
	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
1328 1329
					 IEEE80211_STYPE_NULLFUNC |
					 IEEE80211_FCTL_TODS);
1330

1331
	skb_put_zero(skb, dummy_packet_size);
1332

1333 1334
	/* Dummy packets require the TID to be management */
	skb->priority = WL1271_TID_MGMT;
1335

1336
	/* Initialize all fields that might be used */
1337
	skb_set_queue_mapping(skb, 0);
1338
	memset(IEEE80211_SKB_CB(skb), 0, sizeof(struct ieee80211_tx_info));
1339

1340
	return skb;
1341 1342
}

1343

1344
static int
1345
wl1271_validate_wowlan_pattern(struct cfg80211_pkt_pattern *p)
1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405
{
	int num_fields = 0, in_field = 0, fields_size = 0;
	int i, pattern_len = 0;

	if (!p->mask) {
		wl1271_warning("No mask in WoWLAN pattern");
		return -EINVAL;
	}

	/*
	 * The pattern is broken up into segments of bytes at different offsets
	 * that need to be checked by the FW filter. Each segment is called
	 * a field in the FW API. We verify that the total number of fields
	 * required for this pattern won't exceed FW limits (8)
	 * as well as the total fields buffer won't exceed the FW limit.
	 * Note that if there's a pattern which crosses Ethernet/IP header
	 * boundary a new field is required.
	 */
	for (i = 0; i < p->pattern_len; i++) {
		if (test_bit(i, (unsigned long *)p->mask)) {
			if (!in_field) {
				in_field = 1;
				pattern_len = 1;
			} else {
				if (i == WL1271_RX_FILTER_ETH_HEADER_SIZE) {
					num_fields++;
					fields_size += pattern_len +
						RX_FILTER_FIELD_OVERHEAD;
					pattern_len = 1;
				} else
					pattern_len++;
			}
		} else {
			if (in_field) {
				in_field = 0;
				fields_size += pattern_len +
					RX_FILTER_FIELD_OVERHEAD;
				num_fields++;
			}
		}
	}

	if (in_field) {
		fields_size += pattern_len + RX_FILTER_FIELD_OVERHEAD;
		num_fields++;
	}

	if (num_fields > WL1271_RX_FILTER_MAX_FIELDS) {
		wl1271_warning("RX Filter too complex. Too many segments");
		return -EINVAL;
	}

	if (fields_size > WL1271_RX_FILTER_MAX_FIELDS_SIZE) {
		wl1271_warning("RX filter pattern is too big");
		return -E2BIG;
	}

	return 0;
}

1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425
struct wl12xx_rx_filter *wl1271_rx_filter_alloc(void)
{
	return kzalloc(sizeof(struct wl12xx_rx_filter), GFP_KERNEL);
}

void wl1271_rx_filter_free(struct wl12xx_rx_filter *filter)
{
	int i;

	if (filter == NULL)
		return;

	for (i = 0; i < filter->num_fields; i++)
		kfree(filter->fields[i].pattern);

	kfree(filter);
}

int wl1271_rx_filter_alloc_field(struct wl12xx_rx_filter *filter,
				 u16 offset, u8 flags,
1426
				 const u8 *pattern, u8 len)
1427 1428 1429 1430 1431 1432 1433 1434 1435 1436
{
	struct wl12xx_rx_filter_field *field;

	if (filter->num_fields == WL1271_RX_FILTER_MAX_FIELDS) {
		wl1271_warning("Max fields per RX filter. can't alloc another");
		return -EINVAL;
	}

	field = &filter->fields[filter->num_fields];

1437
	field->pattern = kmemdup(pattern, len, GFP_KERNEL);
1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482
	if (!field->pattern) {
		wl1271_warning("Failed to allocate RX filter pattern");
		return -ENOMEM;
	}

	filter->num_fields++;

	field->offset = cpu_to_le16(offset);
	field->flags = flags;
	field->len = len;

	return 0;
}

int wl1271_rx_filter_get_fields_size(struct wl12xx_rx_filter *filter)
{
	int i, fields_size = 0;

	for (i = 0; i < filter->num_fields; i++)
		fields_size += filter->fields[i].len +
			sizeof(struct wl12xx_rx_filter_field) -
			sizeof(u8 *);

	return fields_size;
}

void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter,
				    u8 *buf)
{
	int i;
	struct wl12xx_rx_filter_field *field;

	for (i = 0; i < filter->num_fields; i++) {
		field = (struct wl12xx_rx_filter_field *)buf;

		field->offset = filter->fields[i].offset;
		field->flags = filter->fields[i].flags;
		field->len = filter->fields[i].len;

		memcpy(&field->pattern, filter->fields[i].pattern, field->len);
		buf += sizeof(struct wl12xx_rx_filter_field) -
			sizeof(u8 *) + field->len;
	}
}

1483 1484 1485 1486
/*
 * Allocates an RX filter returned through f
 * which needs to be freed using rx_filter_free()
 */
1487 1488 1489
static int
wl1271_convert_wowlan_pattern_to_rx_filter(struct cfg80211_pkt_pattern *p,
					   struct wl12xx_rx_filter **f)
1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556
{
	int i, j, ret = 0;
	struct wl12xx_rx_filter *filter;
	u16 offset;
	u8 flags, len;

	filter = wl1271_rx_filter_alloc();
	if (!filter) {
		wl1271_warning("Failed to alloc rx filter");
		ret = -ENOMEM;
		goto err;
	}

	i = 0;
	while (i < p->pattern_len) {
		if (!test_bit(i, (unsigned long *)p->mask)) {
			i++;
			continue;
		}

		for (j = i; j < p->pattern_len; j++) {
			if (!test_bit(j, (unsigned long *)p->mask))
				break;

			if (i < WL1271_RX_FILTER_ETH_HEADER_SIZE &&
			    j >= WL1271_RX_FILTER_ETH_HEADER_SIZE)
				break;
		}

		if (i < WL1271_RX_FILTER_ETH_HEADER_SIZE) {
			offset = i;
			flags = WL1271_RX_FILTER_FLAG_ETHERNET_HEADER;
		} else {
			offset = i - WL1271_RX_FILTER_ETH_HEADER_SIZE;
			flags = WL1271_RX_FILTER_FLAG_IP_HEADER;
		}

		len = j - i;

		ret = wl1271_rx_filter_alloc_field(filter,
						   offset,
						   flags,
						   &p->pattern[i], len);
		if (ret)
			goto err;

		i = j;
	}

	filter->action = FILTER_SIGNAL;

	*f = filter;
	return 0;

err:
	wl1271_rx_filter_free(filter);
	*f = NULL;

	return ret;
}

static int wl1271_configure_wowlan(struct wl1271 *wl,
				   struct cfg80211_wowlan *wow)
{
	int i, ret;

	if (!wow || wow->any || !wow->n_patterns) {
1557 1558 1559 1560 1561 1562 1563 1564 1565
		ret = wl1271_acx_default_rx_filter_enable(wl, 0,
							  FILTER_SIGNAL);
		if (ret)
			goto out;

		ret = wl1271_rx_filter_clear_all(wl);
		if (ret)
			goto out;

1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580
		return 0;
	}

	if (WARN_ON(wow->n_patterns > WL1271_MAX_RX_FILTERS))
		return -EINVAL;

	/* Validate all incoming patterns before clearing current FW state */
	for (i = 0; i < wow->n_patterns; i++) {
		ret = wl1271_validate_wowlan_pattern(&wow->patterns[i]);
		if (ret) {
			wl1271_warning("Bad wowlan pattern %d", i);
			return ret;
		}
	}

1581 1582 1583 1584 1585 1586 1587
	ret = wl1271_acx_default_rx_filter_enable(wl, 0, FILTER_SIGNAL);
	if (ret)
		goto out;

	ret = wl1271_rx_filter_clear_all(wl);
	if (ret)
		goto out;
1588 1589 1590

	/* Translate WoWLAN patterns into filters */
	for (i = 0; i < wow->n_patterns; i++) {
1591
		struct cfg80211_pkt_pattern *p;
1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615
		struct wl12xx_rx_filter *filter = NULL;

		p = &wow->patterns[i];

		ret = wl1271_convert_wowlan_pattern_to_rx_filter(p, &filter);
		if (ret) {
			wl1271_warning("Failed to create an RX filter from "
				       "wowlan pattern %d", i);
			goto out;
		}

		ret = wl1271_rx_filter_enable(wl, i, 1, filter);

		wl1271_rx_filter_free(filter);
		if (ret)
			goto out;
	}

	ret = wl1271_acx_default_rx_filter_enable(wl, 1, FILTER_DROP);

out:
	return ret;
}

1616
static int wl1271_configure_suspend_sta(struct wl1271 *wl,
1617 1618
					struct wl12xx_vif *wlvif,
					struct cfg80211_wowlan *wow)
1619 1620 1621 1622
{
	int ret = 0;

	if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1623
		goto out;
1624

1625 1626
	ret = wl1271_configure_wowlan(wl, wow);
	if (ret < 0)
1627
		goto out;
1628

1629 1630 1631 1632
	if ((wl->conf.conn.suspend_wake_up_event ==
	     wl->conf.conn.wake_up_event) &&
	    (wl->conf.conn.suspend_listen_interval ==
	     wl->conf.conn.listen_interval))
1633
		goto out;
1634

1635 1636 1637 1638 1639 1640
	ret = wl1271_acx_wake_up_conditions(wl, wlvif,
				    wl->conf.conn.suspend_wake_up_event,
				    wl->conf.conn.suspend_listen_interval);

	if (ret < 0)
		wl1271_error("suspend: set wake up conditions failed: %d", ret);
1641
out:
1642 1643 1644
	return ret;

}
1645

E
Eliad Peller 已提交
1646
static int wl1271_configure_suspend_ap(struct wl1271 *wl,
E
Eliad Peller 已提交
1647 1648
					struct wl12xx_vif *wlvif,
					struct cfg80211_wowlan *wow)
1649
{
1650
	int ret = 0;
1651

1652
	if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
1653
		goto out;
1654

E
Eliad Peller 已提交
1655
	ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true);
E
Eliad Peller 已提交
1656 1657 1658 1659 1660 1661
	if (ret < 0)
		goto out;

	ret = wl1271_configure_wowlan(wl, wow);
	if (ret < 0)
		goto out;
1662

1663
out:
1664 1665 1666 1667
	return ret;

}

E
Eliad Peller 已提交
1668
static int wl1271_configure_suspend(struct wl1271 *wl,
1669 1670
				    struct wl12xx_vif *wlvif,
				    struct cfg80211_wowlan *wow)
1671
{
1672
	if (wlvif->bss_type == BSS_TYPE_STA_BSS)
1673
		return wl1271_configure_suspend_sta(wl, wlvif, wow);
E
Eliad Peller 已提交
1674
	if (wlvif->bss_type == BSS_TYPE_AP_BSS)
E
Eliad Peller 已提交
1675
		return wl1271_configure_suspend_ap(wl, wlvif, wow);
1676 1677 1678
	return 0;
}

1679
static void wl1271_configure_resume(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1680
{
1681
	int ret = 0;
E
Eliad Peller 已提交
1682
	bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
1683
	bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
1684

1685
	if ((!is_ap) && (!is_sta))
1686 1687
		return;

E
Eliad Peller 已提交
1688 1689
	if ((is_sta && !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) ||
	    (is_ap && !test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)))
1690 1691
		return;

E
Eliad Peller 已提交
1692
	wl1271_configure_wowlan(wl, NULL);
1693

E
Eliad Peller 已提交
1694
	if (is_sta) {
1695 1696 1697 1698
		if ((wl->conf.conn.suspend_wake_up_event ==
		     wl->conf.conn.wake_up_event) &&
		    (wl->conf.conn.suspend_listen_interval ==
		     wl->conf.conn.listen_interval))
1699
			return;
1700

1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711
		ret = wl1271_acx_wake_up_conditions(wl, wlvif,
				    wl->conf.conn.wake_up_event,
				    wl->conf.conn.listen_interval);

		if (ret < 0)
			wl1271_error("resume: wake up conditions failed: %d",
				     ret);

	} else if (is_ap) {
		ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
	}
1712 1713
}

1714 1715
static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw,
					    struct cfg80211_wowlan *wow)
1716 1717
{
	struct wl1271 *wl = hw->priv;
1718
	struct wl12xx_vif *wlvif;
1719
	unsigned long flags;
1720 1721
	int ret;

1722
	wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow);
1723
	WARN_ON(!wow);
1724

1725 1726 1727 1728 1729 1730
	/* we want to perform the recovery before suspending */
	if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) {
		wl1271_warning("postponing suspend to perform recovery");
		return -EBUSY;
	}

1731 1732
	wl1271_tx_flush(wl);

1733
	mutex_lock(&wl->mutex);
1734

1735
	ret = pm_runtime_get_sync(wl->dev);
1736
	if (ret < 0) {
1737
		pm_runtime_put_noidle(wl->dev);
1738
		mutex_unlock(&wl->mutex);
1739
		return ret;
1740
	}
1741

1742
	wl->wow_enabled = true;
1743
	wl12xx_for_each_wlvif(wl, wlvif) {
E
Eliad Peller 已提交
1744 1745 1746
		if (wlcore_is_p2p_mgmt(wlvif))
			continue;

1747
		ret = wl1271_configure_suspend(wl, wlvif, wow);
1748
		if (ret < 0) {
1749
			mutex_unlock(&wl->mutex);
1750 1751 1752
			wl1271_warning("couldn't prepare device to suspend");
			return ret;
		}
1753
	}
1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766

	/* disable fast link flow control notifications from FW */
	ret = wlcore_hw_interrupt_notify(wl, false);
	if (ret < 0)
		goto out_sleep;

	/* if filtering is enabled, configure the FW to drop all RX BA frames */
	ret = wlcore_hw_rx_ba_filter(wl,
				     !!wl->conf.conn.suspend_rx_ba_activity);
	if (ret < 0)
		goto out_sleep;

out_sleep:
1767
	pm_runtime_put_noidle(wl->dev);
1768
	mutex_unlock(&wl->mutex);
1769 1770 1771 1772 1773 1774

	if (ret < 0) {
		wl1271_warning("couldn't prepare device to suspend");
		return ret;
	}

1775 1776
	/* flush any remaining work */
	wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
1777

1778
	flush_work(&wl->tx_work);
1779

1780 1781 1782 1783 1784 1785
	/*
	 * Cancel the watchdog even if above tx_flush failed. We will detect
	 * it on resume anyway.
	 */
	cancel_delayed_work(&wl->tx_watchdog_work);

1786
	/*
1787 1788
	 * set suspended flag to avoid triggering a new threaded_irq
	 * work.
1789
	 */
1790 1791 1792
	spin_lock_irqsave(&wl->wl_lock, flags);
	set_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
	spin_unlock_irqrestore(&wl->wl_lock, flags);
1793

1794
	return pm_runtime_force_suspend(wl->dev);
1795 1796
}

1797
static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw)
1798 1799
{
	struct wl1271 *wl = hw->priv;
1800
	struct wl12xx_vif *wlvif;
1801
	unsigned long flags;
1802
	bool run_irq_work = false, pending_recovery;
1803
	int ret;
1804

1805 1806
	wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d",
		     wl->wow_enabled);
1807
	WARN_ON(!wl->wow_enabled);
1808

1809 1810 1811 1812 1813 1814
	ret = pm_runtime_force_resume(wl->dev);
	if (ret < 0) {
		wl1271_error("ELP wakeup failure!");
		goto out_sleep;
	}

1815 1816 1817 1818
	/*
	 * re-enable irq_work enqueuing, and call irq_work directly if
	 * there is a pending work.
	 */
1819 1820 1821 1822 1823
	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);
1824

1825 1826
	mutex_lock(&wl->mutex);

1827 1828 1829 1830
	/* test the recovery flag before calling any SDIO functions */
	pending_recovery = test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS,
				    &wl->flags);

1831 1832 1833
	if (run_irq_work) {
		wl1271_debug(DEBUG_MAC80211,
			     "run postponed irq_work directly");
1834 1835

		/* don't talk to the HW if recovery is pending */
1836 1837 1838 1839 1840
		if (!pending_recovery) {
			ret = wlcore_irq_locked(wl);
			if (ret)
				wl12xx_queue_recovery_work(wl);
		}
1841

1842
		wlcore_enable_interrupts(wl);
1843
	}
1844

1845 1846 1847
	if (pending_recovery) {
		wl1271_warning("queuing forgotten recovery on resume");
		ieee80211_queue_work(wl->hw, &wl->recovery_work);
1848
		goto out_sleep;
1849 1850
	}

1851 1852 1853
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
1854
		goto out;
1855
	}
1856

1857
	wl12xx_for_each_wlvif(wl, wlvif) {
E
Eliad Peller 已提交
1858 1859 1860
		if (wlcore_is_p2p_mgmt(wlvif))
			continue;

1861 1862
		wl1271_configure_resume(wl, wlvif);
	}
1863

1864 1865 1866 1867 1868 1869 1870 1871 1872 1873
	ret = wlcore_hw_interrupt_notify(wl, true);
	if (ret < 0)
		goto out_sleep;

	/* if filtering is enabled, configure the FW to drop all RX BA frames */
	ret = wlcore_hw_rx_ba_filter(wl, false);
	if (ret < 0)
		goto out_sleep;

out_sleep:
1874 1875
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
1876

1877
out:
1878
	wl->wow_enabled = false;
1879 1880 1881 1882 1883 1884 1885

	/*
	 * Set a flag to re-init the watchdog on the first Tx after resume.
	 * That way we avoid possible conditions where Tx-complete interrupts
	 * fail to arrive and we perform a spurious recovery.
	 */
	set_bit(WL1271_FLAG_REINIT_TX_WDOG, &wl->flags);
1886
	mutex_unlock(&wl->mutex);
1887

1888 1889 1890
	return 0;
}

L
Luciano Coelho 已提交
1891
static int wl1271_op_start(struct ieee80211_hw *hw)
1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905
{
	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.
	 */

1906
	return 0;
1907 1908
}

1909
static void wlcore_op_stop_locked(struct wl1271 *wl)
1910
{
1911 1912
	int i;

1913
	if (wl->state == WLCORE_STATE_OFF) {
1914 1915 1916 1917
		if (test_and_clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS,
					&wl->flags))
			wlcore_enable_interrupts(wl);

1918 1919
		return;
	}
1920

1921 1922 1923 1924
	/*
	 * this must be before the cancel_work calls below, so that the work
	 * functions don't perform further work.
	 */
1925
	wl->state = WLCORE_STATE_OFF;
1926 1927 1928 1929 1930 1931 1932

	/*
	 * Use the nosync variant to disable interrupts, so the mutex could be
	 * held while doing so without deadlocking.
	 */
	wlcore_disable_interrupts_nosync(wl);

1933 1934
	mutex_unlock(&wl->mutex);

1935
	wlcore_synchronize_interrupts(wl);
1936 1937
	if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
		cancel_work_sync(&wl->recovery_work);
1938 1939 1940 1941
	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);
A
Arik Nemtsov 已提交
1942
	cancel_delayed_work_sync(&wl->tx_watchdog_work);
1943 1944 1945

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

	wl1271_power_off(wl);
1949 1950 1951 1952 1953 1954 1955
	/*
	 * In case a recovery was scheduled, interrupts were disabled to avoid
	 * an interrupt storm. Now that the power is down, it is safe to
	 * re-enable interrupts to balance the disable depth
	 */
	if (test_and_clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags))
		wlcore_enable_interrupts(wl);
1956

1957
	wl->band = NL80211_BAND_2GHZ;
1958 1959 1960

	wl->rx_counter = 0;
	wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
1961
	wl->channel_type = NL80211_CHAN_NO_HT;
1962 1963 1964 1965 1966 1967 1968
	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->ap_fw_ps_map = 0;
	wl->ap_ps_map = 0;
1969
	wl->sleep_auth = WL1271_PSM_ILLEGAL;
1970 1971 1972
	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));
E
Eliad Peller 已提交
1973
	memset(wl->session_ids, 0, sizeof(wl->session_ids));
1974
	memset(wl->rx_filter_enabled, 0, sizeof(wl->rx_filter_enabled));
1975
	wl->active_sta_count = 0;
1976
	wl->active_link_count = 0;
1977 1978

	/* The system link is always allocated */
1979 1980
	wl->links[WL12XX_SYSTEM_HLID].allocated_pkts = 0;
	wl->links[WL12XX_SYSTEM_HLID].prev_freed_pkts = 0;
1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998
	__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);

1999 2000 2001 2002
	kfree(wl->raw_fw_status);
	wl->raw_fw_status = NULL;
	kfree(wl->fw_status);
	wl->fw_status = NULL;
2003 2004 2005 2006
	kfree(wl->tx_res_if);
	wl->tx_res_if = NULL;
	kfree(wl->target_mem_map);
	wl->target_mem_map = NULL;
2007 2008 2009

	/*
	 * FW channels must be re-calibrated after recovery,
2010
	 * save current Reg-Domain channel configuration and clear it.
2011
	 */
2012 2013
	memcpy(wl->reg_ch_conf_pending, wl->reg_ch_conf_last,
	       sizeof(wl->reg_ch_conf_pending));
2014
	memset(wl->reg_ch_conf_last, 0, sizeof(wl->reg_ch_conf_last));
2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025
}

static void wlcore_op_stop(struct ieee80211_hw *hw)
{
	struct wl1271 *wl = hw->priv;

	wl1271_debug(DEBUG_MAC80211, "mac80211 stop");

	mutex_lock(&wl->mutex);

	wlcore_op_stop_locked(wl);
2026 2027

	mutex_unlock(&wl->mutex);
2028 2029
}

2030 2031 2032 2033 2034 2035 2036 2037
static void wlcore_channel_switch_work(struct work_struct *work)
{
	struct delayed_work *dwork;
	struct wl1271 *wl;
	struct ieee80211_vif *vif;
	struct wl12xx_vif *wlvif;
	int ret;

G
Geliang Tang 已提交
2038
	dwork = to_delayed_work(work);
2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055
	wlvif = container_of(dwork, struct wl12xx_vif, channel_switch_work);
	wl = wlvif->wl;

	wl1271_info("channel switch failed (role_id: %d).", wlvif->role_id);

	mutex_lock(&wl->mutex);

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

	/* check the channel switch is still ongoing */
	if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags))
		goto out;

	vif = wl12xx_wlvif_to_vif(wlvif);
	ieee80211_chswitch_done(vif, false);

2056 2057 2058
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
2059
		goto out;
2060
	}
2061 2062 2063

	wl12xx_cmd_stop_channel_switch(wl, wlvif);

2064 2065
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076
out:
	mutex_unlock(&wl->mutex);
}

static void wlcore_connection_loss_work(struct work_struct *work)
{
	struct delayed_work *dwork;
	struct wl1271 *wl;
	struct ieee80211_vif *vif;
	struct wl12xx_vif *wlvif;

G
Geliang Tang 已提交
2077
	dwork = to_delayed_work(work);
2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097
	wlvif = container_of(dwork, struct wl12xx_vif, connection_loss_work);
	wl = wlvif->wl;

	wl1271_info("Connection loss work (role_id: %d).", wlvif->role_id);

	mutex_lock(&wl->mutex);

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

	/* Call mac80211 connection loss */
	if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
		goto out;

	vif = wl12xx_wlvif_to_vif(wlvif);
	ieee80211_connection_loss(vif);
out:
	mutex_unlock(&wl->mutex);
}

2098 2099 2100 2101 2102 2103 2104 2105
static void wlcore_pending_auth_complete_work(struct work_struct *work)
{
	struct delayed_work *dwork;
	struct wl1271 *wl;
	struct wl12xx_vif *wlvif;
	unsigned long time_spare;
	int ret;

G
Geliang Tang 已提交
2106
	dwork = to_delayed_work(work);
2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126
	wlvif = container_of(dwork, struct wl12xx_vif,
			     pending_auth_complete_work);
	wl = wlvif->wl;

	mutex_lock(&wl->mutex);

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

	/*
	 * Make sure a second really passed since the last auth reply. Maybe
	 * a second auth reply arrived while we were stuck on the mutex.
	 * Check for a little less than the timeout to protect from scheduler
	 * irregularities.
	 */
	time_spare = jiffies +
			msecs_to_jiffies(WLCORE_PEND_AUTH_ROC_TIMEOUT - 50);
	if (!time_after(time_spare, wlvif->pending_auth_reply_time))
		goto out;

2127 2128 2129
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
2130
		goto out;
2131
	}
2132 2133 2134 2135

	/* cancel the ROC if active */
	wlcore_update_inconn_sta(wl, wlvif, NULL, false);

2136 2137
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
2138 2139 2140 2141
out:
	mutex_unlock(&wl->mutex);
}

E
Eliad Peller 已提交
2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162
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;
}

2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183
static int wlcore_allocate_klv_template(struct wl1271 *wl, u8 *idx)
{
	u8 policy = find_first_zero_bit(wl->klv_templates_map,
					WLCORE_MAX_KLV_TEMPLATES);
	if (policy >= WLCORE_MAX_KLV_TEMPLATES)
		return -EBUSY;

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

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

	__clear_bit(*idx, wl->klv_templates_map);
	*idx = WLCORE_MAX_KLV_TEMPLATES;
}

E
Eliad Peller 已提交
2184
static u8 wl12xx_get_role_type(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2185
{
2186 2187
	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);

E
Eliad Peller 已提交
2188
	switch (wlvif->bss_type) {
2189
	case BSS_TYPE_AP_BSS:
E
Eliad Peller 已提交
2190
		if (wlvif->p2p)
E
Eliad Peller 已提交
2191
			return WL1271_ROLE_P2P_GO;
2192 2193
		else if (ieee80211_vif_is_mesh(vif))
			return WL1271_ROLE_MESH_POINT;
E
Eliad Peller 已提交
2194 2195
		else
			return WL1271_ROLE_AP;
2196 2197

	case BSS_TYPE_STA_BSS:
E
Eliad Peller 已提交
2198
		if (wlvif->p2p)
E
Eliad Peller 已提交
2199 2200 2201
			return WL1271_ROLE_P2P_CL;
		else
			return WL1271_ROLE_STA;
2202

E
Eliad Peller 已提交
2203 2204 2205
	case BSS_TYPE_IBSS:
		return WL1271_ROLE_IBSS;

2206
	default:
E
Eliad Peller 已提交
2207
		wl1271_error("invalid bss_type: %d", wlvif->bss_type);
2208 2209 2210 2211
	}
	return WL12XX_INVALID_ROLE_TYPE;
}

2212
static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
E
Eliad Peller 已提交
2213
{
2214
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
E
Eliad Peller 已提交
2215
	int i;
2216

2217 2218
	/* clear everything but the persistent data */
	memset(wlvif, 0, offsetof(struct wl12xx_vif, persistent));
2219 2220 2221 2222 2223 2224

	switch (ieee80211_vif_type_p2p(vif)) {
	case NL80211_IFTYPE_P2P_CLIENT:
		wlvif->p2p = 1;
		/* fall-through */
	case NL80211_IFTYPE_STATION:
E
Eliad Peller 已提交
2225
	case NL80211_IFTYPE_P2P_DEVICE:
2226 2227 2228 2229 2230 2231 2232 2233 2234
		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:
2235
	case NL80211_IFTYPE_MESH_POINT:
2236 2237 2238 2239 2240 2241 2242
		wlvif->bss_type = BSS_TYPE_AP_BSS;
		break;
	default:
		wlvif->bss_type = MAX_BSS_TYPE;
		return -EOPNOTSUPP;
	}

E
Eliad Peller 已提交
2243
	wlvif->role_id = WL12XX_INVALID_ROLE_ID;
E
Eliad Peller 已提交
2244
	wlvif->dev_role_id = WL12XX_INVALID_ROLE_ID;
E
Eliad Peller 已提交
2245
	wlvif->dev_hlid = WL12XX_INVALID_LINK_ID;
2246

2247 2248 2249 2250
	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 已提交
2251 2252 2253
		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);
2254
		wlcore_allocate_klv_template(wl, &wlvif->sta.klv_template_id);
2255 2256 2257
		wlvif->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
		wlvif->basic_rate = CONF_TX_RATE_MASK_BASIC;
		wlvif->rate_set = CONF_TX_RATE_MASK_BASIC;
2258 2259 2260 2261
	} else {
		/* init ap data */
		wlvif->ap.bcast_hlid = WL12XX_INVALID_LINK_ID;
		wlvif->ap.global_hlid = WL12XX_INVALID_LINK_ID;
E
Eliad Peller 已提交
2262 2263 2264 2265 2266
		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]);
2267
		wlvif->basic_rate_set = CONF_TX_ENABLED_RATES;
2268 2269 2270 2271 2272
		/*
		 * TODO: check if basic_rate shouldn't be
		 * wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
		 * instead (the same thing for STA above).
		*/
2273
		wlvif->basic_rate = CONF_TX_ENABLED_RATES;
2274
		/* TODO: this seems to be used only for STA, check it */
2275
		wlvif->rate_set = CONF_TX_ENABLED_RATES;
2276
	}
2277

2278 2279
	wlvif->bitrate_masks[NL80211_BAND_2GHZ] = wl->conf.tx.basic_rate;
	wlvif->bitrate_masks[NL80211_BAND_5GHZ] = wl->conf.tx.basic_rate_5;
E
Eliad Peller 已提交
2280 2281
	wlvif->beacon_int = WL1271_DEFAULT_BEACON_INT;

E
Eliad Peller 已提交
2282 2283 2284 2285 2286
	/*
	 * 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 已提交
2287
	wlvif->channel = wl->channel;
2288
	wlvif->power_level = wl->power_level;
2289
	wlvif->channel_type = wl->channel_type;
E
Eliad Peller 已提交
2290

E
Eliad Peller 已提交
2291 2292 2293 2294
	INIT_WORK(&wlvif->rx_streaming_enable_work,
		  wl1271_rx_streaming_enable_work);
	INIT_WORK(&wlvif->rx_streaming_disable_work,
		  wl1271_rx_streaming_disable_work);
2295
	INIT_WORK(&wlvif->rc_update_work, wlcore_rc_update_work);
2296 2297 2298 2299
	INIT_DELAYED_WORK(&wlvif->channel_switch_work,
			  wlcore_channel_switch_work);
	INIT_DELAYED_WORK(&wlvif->connection_loss_work,
			  wlcore_connection_loss_work);
2300 2301
	INIT_DELAYED_WORK(&wlvif->pending_auth_complete_work,
			  wlcore_pending_auth_complete_work);
E
Eliad Peller 已提交
2302
	INIT_LIST_HEAD(&wlvif->list);
E
Eliad Peller 已提交
2303

2304
	timer_setup(&wlvif->rx_streaming_timer, wl1271_rx_streaming_timer, 0);
2305
	return 0;
E
Eliad Peller 已提交
2306 2307
}

2308
static int wl12xx_init_fw(struct wl1271 *wl)
L
Luciano Coelho 已提交
2309
{
2310
	int retries = WL1271_BOOT_RETRIES;
2311
	bool booted = false;
2312 2313
	struct wiphy *wiphy = wl->hw->wiphy;
	int ret;
L
Luciano Coelho 已提交
2314

2315 2316
	while (retries) {
		retries--;
2317
		ret = wl12xx_chip_wakeup(wl, false);
2318 2319
		if (ret < 0)
			goto power_off;
L
Luciano Coelho 已提交
2320

2321
		ret = wl->ops->boot(wl);
2322 2323
		if (ret < 0)
			goto power_off;
L
Luciano Coelho 已提交
2324

2325 2326 2327 2328
		ret = wl1271_hw_init(wl);
		if (ret < 0)
			goto irq_disable;

2329 2330
		booted = true;
		break;
2331

2332 2333 2334 2335 2336
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
2337
		   the system (and while we are WLCORE_STATE_OFF the IRQ
2338 2339 2340
		   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. */
2341
		wlcore_disable_interrupts(wl);
2342 2343
		wl1271_flush_deferred_work(wl);
		cancel_work_sync(&wl->netstack_work);
2344 2345 2346 2347
		mutex_lock(&wl->mutex);
power_off:
		wl1271_power_off(wl);
	}
2348

2349 2350 2351 2352 2353 2354
	if (!booted) {
		wl1271_error("firmware boot failed despite %d retries",
			     WL1271_BOOT_RETRIES);
		goto out;
	}

L
Levi, Shahar 已提交
2355
	wl1271_info("firmware booted (%s)", wl->chip.fw_ver_str);
2356 2357 2358

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

2362 2363 2364 2365 2366
	/*
	 * Now we know if 11a is supported (info from the NVS), so disable
	 * 11a channels if not supported
	 */
	if (!wl->enable_11a)
2367
		wiphy->bands[NL80211_BAND_5GHZ]->n_channels = 0;
2368 2369 2370 2371

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

2372
	wl->state = WLCORE_STATE_ON;
2373
out:
2374
	return ret;
2375 2376
}

2377 2378 2379 2380 2381
static bool wl12xx_dev_role_started(struct wl12xx_vif *wlvif)
{
	return wlvif->dev_hlid != WL12XX_INVALID_LINK_ID;
}

2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405
/*
 * Check whether a fw switch (i.e. moving from one loaded
 * fw to another) is needed. This function is also responsible
 * for updating wl->last_vif_count, so it must be called before
 * loading a non-plt fw (so the correct fw (single-role/multi-role)
 * will be used).
 */
static bool wl12xx_need_fw_change(struct wl1271 *wl,
				  struct vif_counter_data vif_counter_data,
				  bool add)
{
	enum wl12xx_fw_type current_fw = wl->fw_type;
	u8 vif_count = vif_counter_data.counter;

	if (test_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags))
		return false;

	/* increase the vif count if this is a new vif */
	if (add && !vif_counter_data.cur_vif_running)
		vif_count++;

	wl->last_vif_count = vif_count;

	/* no need for fw change if the device is OFF */
2406
	if (wl->state == WLCORE_STATE_OFF)
2407 2408
		return false;

E
Eliad Peller 已提交
2409 2410 2411 2412
	/* no need for fw change if a single fw is used */
	if (!wl->mr_fw_name)
		return false;

2413 2414 2415 2416 2417 2418 2419 2420
	if (vif_count > 1 && current_fw == WL12XX_FW_TYPE_NORMAL)
		return true;
	if (vif_count <= 1 && current_fw == WL12XX_FW_TYPE_MULTI)
		return true;

	return false;
}

2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433
/*
 * Enter "forced psm". Make sure the sta is in psm against the ap,
 * to make the fw switch a bit more disconnection-persistent.
 */
static void wl12xx_force_active_psm(struct wl1271 *wl)
{
	struct wl12xx_vif *wlvif;

	wl12xx_for_each_wlvif_sta(wl, wlvif) {
		wl1271_ps_set_mode(wl, wlvif, STATION_POWER_SAVE_MODE);
	}
}

2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446
struct wlcore_hw_queue_iter_data {
	unsigned long hw_queue_map[BITS_TO_LONGS(WLCORE_NUM_MAC_ADDRESSES)];
	/* current vif */
	struct ieee80211_vif *vif;
	/* is the current vif among those iterated */
	bool cur_running;
};

static void wlcore_hw_queue_iter(void *data, u8 *mac,
				 struct ieee80211_vif *vif)
{
	struct wlcore_hw_queue_iter_data *iter_data = data;

E
Eliad Peller 已提交
2447 2448
	if (vif->type == NL80211_IFTYPE_P2P_DEVICE ||
	    WARN_ON_ONCE(vif->hw_queue[0] == IEEE80211_INVAL_HW_QUEUE))
2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465
		return;

	if (iter_data->cur_running || vif == iter_data->vif) {
		iter_data->cur_running = true;
		return;
	}

	__set_bit(vif->hw_queue[0] / NUM_TX_QUEUES, iter_data->hw_queue_map);
}

static int wlcore_allocate_hw_queue_base(struct wl1271 *wl,
					 struct wl12xx_vif *wlvif)
{
	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
	struct wlcore_hw_queue_iter_data iter_data = {};
	int i, q_base;

E
Eliad Peller 已提交
2466 2467 2468 2469 2470
	if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
		vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
		return 0;
	}

2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514
	iter_data.vif = vif;

	/* mark all bits taken by active interfaces */
	ieee80211_iterate_active_interfaces_atomic(wl->hw,
					IEEE80211_IFACE_ITER_RESUME_ALL,
					wlcore_hw_queue_iter, &iter_data);

	/* the current vif is already running in mac80211 (resume/recovery) */
	if (iter_data.cur_running) {
		wlvif->hw_queue_base = vif->hw_queue[0];
		wl1271_debug(DEBUG_MAC80211,
			     "using pre-allocated hw queue base %d",
			     wlvif->hw_queue_base);

		/* interface type might have changed type */
		goto adjust_cab_queue;
	}

	q_base = find_first_zero_bit(iter_data.hw_queue_map,
				     WLCORE_NUM_MAC_ADDRESSES);
	if (q_base >= WLCORE_NUM_MAC_ADDRESSES)
		return -EBUSY;

	wlvif->hw_queue_base = q_base * NUM_TX_QUEUES;
	wl1271_debug(DEBUG_MAC80211, "allocating hw queue base: %d",
		     wlvif->hw_queue_base);

	for (i = 0; i < NUM_TX_QUEUES; i++) {
		wl->queue_stop_reasons[wlvif->hw_queue_base + i] = 0;
		/* register hw queues in mac80211 */
		vif->hw_queue[i] = wlvif->hw_queue_base + i;
	}

adjust_cab_queue:
	/* the last places are reserved for cab queues per interface */
	if (wlvif->bss_type == BSS_TYPE_AP_BSS)
		vif->cab_queue = NUM_TX_QUEUES * WLCORE_NUM_MAC_ADDRESSES +
				 wlvif->hw_queue_base / NUM_TX_QUEUES;
	else
		vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;

	return 0;
}

2515 2516 2517 2518 2519
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);
2520
	struct vif_counter_data vif_count;
2521 2522 2523
	int ret = 0;
	u8 role_type;

2524 2525 2526 2527 2528
	if (wl->plt) {
		wl1271_error("Adding Interface not allowed while in PLT mode");
		return -EBUSY;
	}

2529
	vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
2530
			     IEEE80211_VIF_SUPPORTS_UAPSD |
2531
			     IEEE80211_VIF_SUPPORTS_CQM_RSSI;
2532

2533 2534 2535
	wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
		     ieee80211_vif_type_p2p(vif), vif->addr);

2536 2537
	wl12xx_get_vif_count(hw, vif, &vif_count);

2538
	mutex_lock(&wl->mutex);
2539

2540 2541 2542 2543 2544
	/*
	 * 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.
	 */
2545 2546
	if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags) ||
	    test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) {
2547 2548 2549 2550
		ret = -EBUSY;
		goto out;
	}

2551

2552
	ret = wl12xx_init_vif_data(wl, vif);
2553 2554 2555 2556 2557 2558 2559 2560 2561 2562
	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;
	}

2563 2564 2565 2566
	ret = wlcore_allocate_hw_queue_base(wl, wlvif);
	if (ret < 0)
		goto out;

2567 2568 2569 2570
	/*
	 * TODO: after the nvs issue will be solved, move this block
	 * to start(), and make sure here the driver is ON.
	 */
2571
	if (wl->state == WLCORE_STATE_OFF) {
2572 2573 2574 2575
		/*
		 * we still need this in order to configure the fw
		 * while uploading the nvs
		 */
2576
		memcpy(wl->addresses[0].addr, vif->addr, ETH_ALEN);
2577

2578 2579
		ret = wl12xx_init_fw(wl);
		if (ret < 0)
2580 2581 2582
			goto out;
	}

2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600
	/*
	 * Call runtime PM only after possible wl12xx_init_fw() above
	 * is done. Otherwise we do not have interrupts enabled.
	 */
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
		goto out_unlock;
	}

	if (wl12xx_need_fw_change(wl, vif_count, true)) {
		wl12xx_force_active_psm(wl);
		set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
		mutex_unlock(&wl->mutex);
		wl1271_recovery_work(&wl->recovery_work);
		return 0;
	}

E
Eliad Peller 已提交
2601 2602 2603 2604 2605
	if (!wlcore_is_p2p_mgmt(wlvif)) {
		ret = wl12xx_cmd_role_enable(wl, vif->addr,
					     role_type, &wlvif->role_id);
		if (ret < 0)
			goto out;
2606

E
Eliad Peller 已提交
2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621
		ret = wl1271_init_vif_specific(wl, vif);
		if (ret < 0)
			goto out;

	} else {
		ret = wl12xx_cmd_role_enable(wl, vif->addr, WL1271_ROLE_DEVICE,
					     &wlvif->dev_role_id);
		if (ret < 0)
			goto out;

		/* needed mainly for configuring rate policies */
		ret = wl1271_sta_hw_init(wl, wlvif);
		if (ret < 0)
			goto out;
	}
2622

E
Eliad Peller 已提交
2623
	list_add(&wlvif->list, &wl->wlvif_list);
2624
	set_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags);
2625 2626 2627 2628 2629

	if (wlvif->bss_type == BSS_TYPE_AP_BSS)
		wl->ap_count++;
	else
		wl->sta_count++;
2630
out:
2631 2632
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
2633
out_unlock:
L
Luciano Coelho 已提交
2634 2635 2636 2637 2638
	mutex_unlock(&wl->mutex);

	return ret;
}

2639
static void __wl1271_op_remove_interface(struct wl1271 *wl,
E
Eliad Peller 已提交
2640
					 struct ieee80211_vif *vif,
2641
					 bool reset_tx_queues)
L
Luciano Coelho 已提交
2642
{
E
Eliad Peller 已提交
2643
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
E
Eliad Peller 已提交
2644
	int i, ret;
2645
	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
L
Luciano Coelho 已提交
2646

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

2649 2650 2651
	if (!test_and_clear_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
		return;

2652
	/* because of hardware recovery, we may get here twice */
2653
	if (wl->state == WLCORE_STATE_OFF)
2654 2655
		return;

2656
	wl1271_info("down");
L
Luciano Coelho 已提交
2657

2658
	if (wl->scan.state != WL1271_SCAN_STATE_IDLE &&
2659
	    wl->scan_wlvif == wlvif) {
2660 2661 2662 2663
		struct cfg80211_scan_info info = {
			.aborted = true,
		};

A
Arik Nemtsov 已提交
2664 2665 2666 2667 2668 2669
		/*
		 * Rearm the tx watchdog just before idling scan. This
		 * prevents just-finished scans from triggering the watchdog
		 */
		wl12xx_rearm_tx_watchdog_locked(wl);

L
Luciano Coelho 已提交
2670
		wl->scan.state = WL1271_SCAN_STATE_IDLE;
2671
		memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
2672
		wl->scan_wlvif = NULL;
2673
		wl->scan.req = NULL;
2674
		ieee80211_scan_completed(wl->hw, &info);
L
Luciano Coelho 已提交
2675 2676
	}

2677
	if (wl->sched_vif == wlvif)
2678 2679
		wl->sched_vif = NULL;

2680 2681 2682 2683 2684
	if (wl->roc_vif == vif) {
		wl->roc_vif = NULL;
		ieee80211_remain_on_channel_expired(wl->hw);
	}

2685 2686
	if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) {
		/* disable active roles */
2687 2688 2689
		ret = pm_runtime_get_sync(wl->dev);
		if (ret < 0) {
			pm_runtime_put_noidle(wl->dev);
2690
			goto deinit;
2691
		}
2692

2693 2694 2695 2696
		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 已提交
2697 2698
		}

E
Eliad Peller 已提交
2699 2700 2701 2702 2703 2704 2705 2706 2707
		if (!wlcore_is_p2p_mgmt(wlvif)) {
			ret = wl12xx_cmd_role_disable(wl, &wlvif->role_id);
			if (ret < 0)
				goto deinit;
		} else {
			ret = wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id);
			if (ret < 0)
				goto deinit;
		}
2708

2709 2710
		pm_runtime_mark_last_busy(wl->dev);
		pm_runtime_put_autosuspend(wl->dev);
2711 2712
	}
deinit:
2713 2714
	wl12xx_tx_reset_wlvif(wl, wlvif);

2715
	/* clear all hlids (except system_hlid) */
E
Eliad Peller 已提交
2716
	wlvif->dev_hlid = WL12XX_INVALID_LINK_ID;
E
Eliad Peller 已提交
2717 2718 2719 2720 2721 2722 2723

	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);
2724
		wlcore_free_klv_template(wl, &wlvif->sta.klv_template_id);
E
Eliad Peller 已提交
2725 2726 2727 2728 2729 2730 2731 2732
	} 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]);
2733
		wl1271_free_ap_keys(wl, wlvif);
E
Eliad Peller 已提交
2734
	}
2735

2736 2737
	dev_kfree_skb(wlvif->probereq);
	wlvif->probereq = NULL;
2738 2739
	if (wl->last_wlvif == wlvif)
		wl->last_wlvif = NULL;
E
Eliad Peller 已提交
2740
	list_del(&wlvif->list);
2741
	memset(wlvif->ap.sta_hlid_map, 0, sizeof(wlvif->ap.sta_hlid_map));
E
Eliad Peller 已提交
2742
	wlvif->role_id = WL12XX_INVALID_ROLE_ID;
E
Eliad Peller 已提交
2743
	wlvif->dev_role_id = WL12XX_INVALID_ROLE_ID;
2744

2745
	if (is_ap)
2746 2747 2748 2749
		wl->ap_count--;
	else
		wl->sta_count--;

2750 2751 2752 2753 2754 2755 2756 2757
	/*
	 * Last AP, have more stations. Configure sleep auth according to STA.
	 * Don't do thin on unintended recovery.
	 */
	if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags) &&
	    !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags))
		goto unlock;

E
Eliad Peller 已提交
2758 2759 2760 2761 2762 2763
	if (wl->ap_count == 0 && is_ap) {
		/* mask ap events */
		wl->event_mask &= ~wl->ap_event_mask;
		wl1271_event_unmask(wl);
	}

2764 2765 2766 2767 2768 2769 2770 2771 2772 2773
	if (wl->ap_count == 0 && is_ap && wl->sta_count) {
		u8 sta_auth = wl->conf.conn.sta_sleep_auth;
		/* Configure for power according to debugfs */
		if (sta_auth != WL1271_PSM_ILLEGAL)
			wl1271_acx_sleep_auth(wl, sta_auth);
		/* Configure for ELP power saving */
		else
			wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
	}

2774
unlock:
2775
	mutex_unlock(&wl->mutex);
E
Eyal Shapira 已提交
2776

E
Eliad Peller 已提交
2777 2778 2779
	del_timer_sync(&wlvif->rx_streaming_timer);
	cancel_work_sync(&wlvif->rx_streaming_enable_work);
	cancel_work_sync(&wlvif->rx_streaming_disable_work);
2780
	cancel_work_sync(&wlvif->rc_update_work);
2781
	cancel_delayed_work_sync(&wlvif->connection_loss_work);
2782
	cancel_delayed_work_sync(&wlvif->channel_switch_work);
2783
	cancel_delayed_work_sync(&wlvif->pending_auth_complete_work);
2784

2785
	mutex_lock(&wl->mutex);
2786
}
2787

2788 2789 2790 2791
static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
				       struct ieee80211_vif *vif)
{
	struct wl1271 *wl = hw->priv;
2792
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
2793
	struct wl12xx_vif *iter;
2794
	struct vif_counter_data vif_count;
2795

2796
	wl12xx_get_vif_count(hw, vif, &vif_count);
2797
	mutex_lock(&wl->mutex);
2798

2799
	if (wl->state == WLCORE_STATE_OFF ||
2800 2801 2802
	    !test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
		goto out;

2803 2804 2805 2806
	/*
	 * wl->vif can be null here if someone shuts down the interface
	 * just when hardware recovery has been started.
	 */
2807 2808 2809 2810
	wl12xx_for_each_wlvif(wl, iter) {
		if (iter != wlvif)
			continue;

E
Eliad Peller 已提交
2811
		__wl1271_op_remove_interface(wl, vif, true);
2812
		break;
2813
	}
2814
	WARN_ON(iter != wlvif);
2815
	if (wl12xx_need_fw_change(wl, vif_count, false)) {
2816
		wl12xx_force_active_psm(wl);
2817
		set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
2818 2819
		wl12xx_queue_recovery_work(wl);
	}
2820
out:
2821
	mutex_unlock(&wl->mutex);
L
Luciano Coelho 已提交
2822 2823
}

E
Eliad Peller 已提交
2824 2825 2826 2827
static int wl12xx_op_change_interface(struct ieee80211_hw *hw,
				      struct ieee80211_vif *vif,
				      enum nl80211_iftype new_type, bool p2p)
{
2828 2829 2830 2831
	struct wl1271 *wl = hw->priv;
	int ret;

	set_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags);
E
Eliad Peller 已提交
2832 2833
	wl1271_op_remove_interface(hw, vif);

2834
	vif->type = new_type;
E
Eliad Peller 已提交
2835
	vif->p2p = p2p;
2836 2837 2838 2839
	ret = wl1271_op_add_interface(hw, vif);

	clear_bit(WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, &wl->flags);
	return ret;
E
Eliad Peller 已提交
2840 2841
}

2842
static int wlcore_join(struct wl1271 *wl, struct wl12xx_vif *wlvif)
2843 2844
{
	int ret;
E
Eliad Peller 已提交
2845
	bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS);
2846

2847 2848 2849 2850
	/*
	 * 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.
2851 2852 2853 2854
	 * 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 :)
2855
	 */
2856
	if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
2857 2858
		wl1271_info("JOIN while associated.");

2859 2860 2861
	/* clear encryption type */
	wlvif->encryption_type = KEY_NONE;

E
Eliad Peller 已提交
2862
	if (is_ibss)
E
Eliad Peller 已提交
2863
		ret = wl12xx_cmd_role_start_ibss(wl, wlvif);
2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876
	else {
		if (wl->quirks & WLCORE_QUIRK_START_STA_FAILS) {
			/*
			 * TODO: this is an ugly workaround for wl12xx fw
			 * bug - we are not able to tx/rx after the first
			 * start_sta, so make dummy start+stop calls,
			 * and then call start_sta again.
			 * this should be fixed in the fw.
			 */
			wl12xx_cmd_role_start_sta(wl, wlvif);
			wl12xx_cmd_role_stop_sta(wl, wlvif);
		}

E
Eliad Peller 已提交
2877
		ret = wl12xx_cmd_role_start_sta(wl, wlvif);
2878
	}
2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928

	return ret;
}

static int wl1271_ssid_set(struct wl12xx_vif *wlvif, struct sk_buff *skb,
			    int offset)
{
	u8 ssid_len;
	const u8 *ptr = cfg80211_find_ie(WLAN_EID_SSID, skb->data + offset,
					 skb->len - offset);

	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;
	}

	wlvif->ssid_len = ssid_len;
	memcpy(wlvif->ssid, ptr+2, ssid_len);
	return 0;
}

static int wlcore_set_ssid(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{
	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
	struct sk_buff *skb;
	int ieoffset;

	/* we currently only support setting the ssid from the ap probe req */
	if (wlvif->bss_type != BSS_TYPE_STA_BSS)
		return -EINVAL;

	skb = ieee80211_ap_probereq_get(wl->hw, vif);
	if (!skb)
		return -EINVAL;

	ieoffset = offsetof(struct ieee80211_mgmt,
			    u.probe_req.variable);
	wl1271_ssid_set(wlvif, skb, ieoffset);
	dev_kfree_skb(skb);

	return 0;
}

static int wlcore_set_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif,
2929 2930
			    struct ieee80211_bss_conf *bss_conf,
			    u32 sta_rate_set)
2931 2932 2933 2934 2935
{
	int ieoffset;
	int ret;

	wlvif->aid = bss_conf->aid;
2936
	wlvif->channel_type = cfg80211_get_chandef_type(&bss_conf->chandef);
2937
	wlvif->beacon_int = bss_conf->beacon_int;
2938
	wlvif->wmm_enabled = bss_conf->qos;
2939 2940 2941 2942 2943 2944 2945 2946 2947 2948

	set_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags);

	/*
	 * 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.
	 */
	ret = wl1271_cmd_build_ps_poll(wl, wlvif, wlvif->aid);
2949
	if (ret < 0)
2950
		return ret;
2951

2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966
	/*
	 * Get a template for hardware connection maintenance
	 */
	dev_kfree_skb(wlvif->probereq);
	wlvif->probereq = wl1271_cmd_build_ap_probe_req(wl,
							wlvif,
							NULL);
	ieoffset = offsetof(struct ieee80211_mgmt,
			    u.probe_req.variable);
	wl1271_ssid_set(wlvif, wlvif->probereq, ieoffset);

	/* enable the connection monitoring feature */
	ret = wl1271_acx_conn_monit_params(wl, wlvif, true);
	if (ret < 0)
		return ret;
2967 2968 2969 2970 2971 2972 2973

	/*
	 * 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 已提交
2974
	ret = wl1271_acx_keep_alive_mode(wl, wlvif, true);
2975
	if (ret < 0)
2976
		return ret;
2977

E
Eliad Peller 已提交
2978
	ret = wl1271_acx_aid(wl, wlvif, wlvif->aid);
2979
	if (ret < 0)
2980
		return ret;
2981

E
Eliad Peller 已提交
2982
	ret = wl12xx_cmd_build_klv_null_data(wl, wlvif);
2983
	if (ret < 0)
2984
		return ret;
2985

E
Eliad Peller 已提交
2986
	ret = wl1271_acx_keep_alive_config(wl, wlvif,
2987
					   wlvif->sta.klv_template_id,
2988 2989
					   ACX_KEEP_ALIVE_TPL_VALID);
	if (ret < 0)
2990
		return ret;
2991

2992 2993 2994 2995 2996
	/*
	 * The default fw psm configuration is AUTO, while mac80211 default
	 * setting is off (ACTIVE), so sync the fw with the correct value.
	 */
	ret = wl1271_ps_set_mode(wl, wlvif, STATION_ACTIVE_MODE);
2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008
	if (ret < 0)
		return ret;

	if (sta_rate_set) {
		wlvif->rate_set =
			wl1271_tx_enabled_rates_get(wl,
						    sta_rate_set,
						    wlvif->band);
		ret = wl1271_acx_sta_rate_policies(wl, wlvif);
		if (ret < 0)
			return ret;
	}
3009 3010 3011 3012

	return ret;
}

3013
static int wlcore_unset_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
3014 3015
{
	int ret;
3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044
	bool sta = wlvif->bss_type == BSS_TYPE_STA_BSS;

	/* make sure we are connected (sta) joined */
	if (sta &&
	    !test_and_clear_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
		return false;

	/* make sure we are joined (ibss) */
	if (!sta &&
	    test_and_clear_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags))
		return false;

	if (sta) {
		/* use defaults when not associated */
		wlvif->aid = 0;

		/* free probe-request template */
		dev_kfree_skb(wlvif->probereq);
		wlvif->probereq = NULL;

		/* disable connection monitor features */
		ret = wl1271_acx_conn_monit_params(wl, wlvif, false);
		if (ret < 0)
			return ret;

		/* Disable the keep-alive feature */
		ret = wl1271_acx_keep_alive_mode(wl, wlvif, false);
		if (ret < 0)
			return ret;
3045 3046 3047 3048 3049

		/* disable beacon filtering */
		ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
		if (ret < 0)
			return ret;
3050
	}
3051

3052
	if (test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags)) {
3053 3054
		struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);

3055
		wl12xx_cmd_stop_channel_switch(wl, wlvif);
3056
		ieee80211_chswitch_done(vif, false);
3057
		cancel_delayed_work(&wlvif->channel_switch_work);
3058 3059
	}

3060 3061
	/* invalidate keep-alive template */
	wl1271_acx_keep_alive_config(wl, wlvif,
3062
				     wlvif->sta.klv_template_id,
3063 3064
				     ACX_KEEP_ALIVE_TPL_INVALID);

3065
	return 0;
3066 3067
}

E
Eliad Peller 已提交
3068
static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif)
3069
{
E
Eliad Peller 已提交
3070
	wlvif->basic_rate_set = wlvif->bitrate_masks[wlvif->band];
E
Eliad Peller 已提交
3071
	wlvif->rate_set = wlvif->basic_rate_set;
3072 3073
}

A
Arik Nemtsov 已提交
3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092
static void wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
				   bool idle)
{
	bool cur_idle = !test_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);

	if (idle == cur_idle)
		return;

	if (idle) {
		clear_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
	} else {
		/* The current firmware only supports sched_scan in idle */
		if (wl->sched_vif == wlvif)
			wl->ops->sched_scan_stop(wl, wlvif);

		set_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
	}
}

3093 3094
static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
			     struct ieee80211_conf *conf, u32 changed)
3095 3096 3097
{
	int ret;

E
Eliad Peller 已提交
3098 3099 3100
	if (wlcore_is_p2p_mgmt(wlvif))
		return 0;

3101
	if (conf->power_level != wlvif->power_level) {
E
Eliad Peller 已提交
3102
		ret = wl1271_acx_tx_power(wl, wlvif, conf->power_level);
3103
		if (ret < 0)
3104
			return ret;
3105

3106
		wlvif->power_level = conf->power_level;
3107 3108
	}

3109
	return 0;
3110 3111
}

3112
static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
L
Luciano Coelho 已提交
3113
{
3114 3115 3116
	struct wl1271 *wl = hw->priv;
	struct wl12xx_vif *wlvif;
	struct ieee80211_conf *conf = &hw->conf;
E
Eliad Peller 已提交
3117
	int ret = 0;
L
Luciano Coelho 已提交
3118

E
Eliad Peller 已提交
3119
	wl1271_debug(DEBUG_MAC80211, "mac80211 config psm %s power %d %s"
3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130
		     " changed 0x%x",
		     conf->flags & IEEE80211_CONF_PS ? "on" : "off",
		     conf->power_level,
		     conf->flags & IEEE80211_CONF_IDLE ? "idle" : "in use",
			 changed);

	mutex_lock(&wl->mutex);

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

3131
	if (unlikely(wl->state != WLCORE_STATE_ON))
3132 3133
		goto out;

3134 3135 3136
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
3137
		goto out;
3138
	}
3139 3140 3141 3142 3143 3144 3145 3146

	/* 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 已提交
3147
out_sleep:
3148 3149
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
L
Luciano Coelho 已提交
3150 3151 3152 3153 3154 3155 3156

out:
	mutex_unlock(&wl->mutex);

	return ret;
}

J
Juuso Oikarinen 已提交
3157 3158 3159 3160 3161 3162
struct wl1271_filter_params {
	bool enabled;
	int mc_list_length;
	u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN];
};

3163 3164
static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw,
				       struct netdev_hw_addr_list *mc_list)
3165 3166
{
	struct wl1271_filter_params *fp;
3167
	struct netdev_hw_addr *ha;
3168

3169
	fp = kzalloc(sizeof(*fp), GFP_ATOMIC);
3170 3171 3172 3173 3174 3175 3176
	if (!fp) {
		wl1271_error("Out of memory setting filters.");
		return 0;
	}

	/* update multicast filtering parameters */
	fp->mc_list_length = 0;
3177 3178 3179 3180 3181
	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) {
3182
			memcpy(fp->mc_list[fp->mc_list_length],
3183
					ha->addr, ETH_ALEN);
3184
			fp->mc_list_length++;
3185
		}
3186 3187
	}

J
Juuso Oikarinen 已提交
3188
	return (u64)(unsigned long)fp;
3189
}
L
Luciano Coelho 已提交
3190

3191
#define WL1271_SUPPORTED_FILTERS (FIF_ALLMULTI | \
J
Juuso Oikarinen 已提交
3192 3193 3194 3195 3196
				  FIF_FCSFAIL | \
				  FIF_BCN_PRBRESP_PROMISC | \
				  FIF_CONTROL | \
				  FIF_OTHER_BSS)

L
Luciano Coelho 已提交
3197 3198
static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
				       unsigned int changed,
3199
				       unsigned int *total, u64 multicast)
L
Luciano Coelho 已提交
3200
{
J
Juuso Oikarinen 已提交
3201
	struct wl1271_filter_params *fp = (void *)(unsigned long)multicast;
L
Luciano Coelho 已提交
3202
	struct wl1271 *wl = hw->priv;
3203
	struct wl12xx_vif *wlvif;
E
Eliad Peller 已提交
3204

J
Juuso Oikarinen 已提交
3205
	int ret;
L
Luciano Coelho 已提交
3206

3207 3208
	wl1271_debug(DEBUG_MAC80211, "mac80211 configure filter changed %x"
		     " total %x", changed, *total);
L
Luciano Coelho 已提交
3209

J
Juuso Oikarinen 已提交
3210 3211
	mutex_lock(&wl->mutex);

3212 3213 3214
	*total &= WL1271_SUPPORTED_FILTERS;
	changed &= WL1271_SUPPORTED_FILTERS;

3215
	if (unlikely(wl->state != WLCORE_STATE_ON))
J
Juuso Oikarinen 已提交
3216 3217
		goto out;

3218 3219 3220
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
J
Juuso Oikarinen 已提交
3221
		goto out;
3222
	}
J
Juuso Oikarinen 已提交
3223

3224
	wl12xx_for_each_wlvif(wl, wlvif) {
E
Eliad Peller 已提交
3225 3226 3227
		if (wlcore_is_p2p_mgmt(wlvif))
			continue;

3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240
		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;
		}
3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255

		/*
		 * If interface in AP mode and created with allmulticast then disable
		 * the firmware filters so that all multicast packets are passed
		 * This is mandatory for MDNS based discovery protocols 
		 */
 		if (wlvif->bss_type == BSS_TYPE_AP_BSS) {
 			if (*total & FIF_ALLMULTI) {
				ret = wl1271_acx_group_address_tbl(wl, wlvif,
							false,
							NULL, 0);
				if (ret < 0)
					goto out_sleep;
			}
		}
3256
	}
L
Luciano Coelho 已提交
3257

E
Eliad Peller 已提交
3258 3259 3260 3261 3262
	/*
	 * 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 已提交
3263 3264

out_sleep:
3265 3266
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
J
Juuso Oikarinen 已提交
3267 3268 3269

out:
	mutex_unlock(&wl->mutex);
3270
	kfree(fp);
L
Luciano Coelho 已提交
3271 3272
}

3273 3274 3275
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,
3276
				u16 tx_seq_16, bool is_pairwise)
3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290
{
	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++) {
3291
		if (wlvif->ap.recorded_keys[i] == NULL)
3292 3293
			break;

3294
		if (wlvif->ap.recorded_keys[i]->id == id) {
3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313
			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;
3314
	ap_key->is_pairwise = is_pairwise;
3315

3316
	wlvif->ap.recorded_keys[i] = ap_key;
3317 3318 3319
	return 0;
}

3320
static void wl1271_free_ap_keys(struct wl1271 *wl, struct wl12xx_vif *wlvif)
3321 3322 3323 3324
{
	int i;

	for (i = 0; i < MAX_NUM_KEYS; i++) {
3325 3326
		kfree(wlvif->ap.recorded_keys[i]);
		wlvif->ap.recorded_keys[i] = NULL;
3327 3328 3329
	}
}

3330
static int wl1271_ap_init_hwenc(struct wl1271 *wl, struct wl12xx_vif *wlvif)
3331 3332 3333 3334 3335 3336
{
	int i, ret = 0;
	struct wl1271_ap_key *key;
	bool wep_key_added = false;

	for (i = 0; i < MAX_NUM_KEYS; i++) {
3337
		u8 hlid;
3338
		if (wlvif->ap.recorded_keys[i] == NULL)
3339 3340
			break;

3341
		key = wlvif->ap.recorded_keys[i];
3342 3343
		hlid = key->hlid;
		if (hlid == WL12XX_INVALID_LINK_ID)
3344
			hlid = wlvif->ap.bcast_hlid;
3345

3346
		ret = wl1271_cmd_set_ap_key(wl, wlvif, KEY_ADD_OR_REPLACE,
3347 3348
					    key->id, key->key_type,
					    key->key_size, key->key,
3349
					    hlid, key->tx_seq_32,
3350
					    key->tx_seq_16, key->is_pairwise);
3351 3352 3353 3354 3355 3356 3357 3358
		if (ret < 0)
			goto out;

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

	if (wep_key_added) {
E
Eliad Peller 已提交
3359
		ret = wl12xx_cmd_set_default_wep_key(wl, wlvif->default_key,
3360
						     wlvif->ap.bcast_hlid);
3361 3362 3363 3364 3365
		if (ret < 0)
			goto out;
	}

out:
3366
	wl1271_free_ap_keys(wl, wlvif);
3367 3368 3369
	return ret;
}

E
Eliad Peller 已提交
3370 3371
static int wl1271_set_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
		       u16 action, u8 id, u8 key_type,
3372
		       u8 key_size, const u8 *key, u32 tx_seq_32,
3373 3374
		       u16 tx_seq_16, struct ieee80211_sta *sta,
		       bool is_pairwise)
3375 3376
{
	int ret;
E
Eliad Peller 已提交
3377
	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
3378 3379 3380 3381 3382 3383 3384 3385 3386

	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 {
3387
			hlid = wlvif->ap.bcast_hlid;
3388 3389
		}

3390
		if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
3391 3392 3393 3394 3395 3396 3397
			/*
			 * We do not support removing keys after AP shutdown.
			 * Pretend we do to make mac80211 happy.
			 */
			if (action != KEY_ADD_OR_REPLACE)
				return 0;

3398
			ret = wl1271_record_ap_key(wl, wlvif, id,
3399 3400
					     key_type, key_size,
					     key, hlid, tx_seq_32,
3401
					     tx_seq_16, is_pairwise);
3402
		} else {
3403
			ret = wl1271_cmd_set_ap_key(wl, wlvif, action,
3404 3405
					     id, key_type, key_size,
					     key, hlid, tx_seq_32,
3406
					     tx_seq_16, is_pairwise);
3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430
		}

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

		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;

3431 3432
		/* don't remove key if hlid was already deleted */
		if (action == KEY_REMOVE &&
E
Eliad Peller 已提交
3433
		    wlvif->sta.hlid == WL12XX_INVALID_LINK_ID)
3434 3435
			return 0;

3436
		ret = wl1271_cmd_set_sta_key(wl, wlvif, action,
3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447
					     id, key_type, key_size,
					     key, addr, tx_seq_32,
					     tx_seq_16);
		if (ret < 0)
			return ret;

	}

	return 0;
}

3448
static int wlcore_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
L
Luciano Coelho 已提交
3449 3450 3451 3452 3453
			     struct ieee80211_vif *vif,
			     struct ieee80211_sta *sta,
			     struct ieee80211_key_conf *key_conf)
{
	struct wl1271 *wl = hw->priv;
3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473
	int ret;
	bool might_change_spare =
		key_conf->cipher == WL1271_CIPHER_SUITE_GEM ||
		key_conf->cipher == WLAN_CIPHER_SUITE_TKIP;

	if (might_change_spare) {
		/*
		 * stop the queues and flush to ensure the next packets are
		 * in sync with FW spare block accounting
		 */
		wlcore_stop_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);
		wl1271_tx_flush(wl);
	}

	mutex_lock(&wl->mutex);

	if (unlikely(wl->state != WLCORE_STATE_ON)) {
		ret = -EAGAIN;
		goto out_wake_queues;
	}
3474

3475 3476 3477
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
3478
		goto out_wake_queues;
3479
	}
3480 3481 3482

	ret = wlcore_hw_set_key(wl, cmd, vif, sta, key_conf);

3483 3484
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
3485 3486 3487 3488 3489 3490 3491 3492

out_wake_queues:
	if (might_change_spare)
		wlcore_wake_queues(wl, WLCORE_QUEUE_STOP_REASON_SPARE_BLK);

	mutex_unlock(&wl->mutex);

	return ret;
3493 3494 3495 3496 3497 3498 3499
}

int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
		   struct ieee80211_vif *vif,
		   struct ieee80211_sta *sta,
		   struct ieee80211_key_conf *key_conf)
{
E
Eliad Peller 已提交
3500
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
L
Luciano Coelho 已提交
3501
	int ret;
3502 3503
	u32 tx_seq_32 = 0;
	u16 tx_seq_16 = 0;
L
Luciano Coelho 已提交
3504
	u8 key_type;
3505
	u8 hlid;
3506
	bool is_pairwise;
L
Luciano Coelho 已提交
3507 3508 3509

	wl1271_debug(DEBUG_MAC80211, "mac80211 set key");

3510
	wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x sta: %p", cmd, sta);
L
Luciano Coelho 已提交
3511
	wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
3512
		     key_conf->cipher, key_conf->keyidx,
L
Luciano Coelho 已提交
3513 3514 3515
		     key_conf->keylen, key_conf->flags);
	wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen);

3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531
	if (wlvif->bss_type == BSS_TYPE_AP_BSS)
		if (sta) {
			struct wl1271_station *wl_sta = (void *)sta->drv_priv;
			hlid = wl_sta->hlid;
		} else {
			hlid = wlvif->ap.bcast_hlid;
		}
	else
		hlid = wlvif->sta.hlid;

	if (hlid != WL12XX_INVALID_LINK_ID) {
		u64 tx_seq = wl->links[hlid].total_freed_pkts;
		tx_seq_32 = WL1271_TX_SECURITY_HI32(tx_seq);
		tx_seq_16 = WL1271_TX_SECURITY_LO16(tx_seq);
	}

3532 3533 3534
	switch (key_conf->cipher) {
	case WLAN_CIPHER_SUITE_WEP40:
	case WLAN_CIPHER_SUITE_WEP104:
L
Luciano Coelho 已提交
3535 3536 3537 3538
		key_type = KEY_WEP;

		key_conf->hw_key_idx = key_conf->keyidx;
		break;
3539
	case WLAN_CIPHER_SUITE_TKIP:
L
Luciano Coelho 已提交
3540 3541 3542
		key_type = KEY_TKIP;
		key_conf->hw_key_idx = key_conf->keyidx;
		break;
3543
	case WLAN_CIPHER_SUITE_CCMP:
L
Luciano Coelho 已提交
3544
		key_type = KEY_AES;
3545
		key_conf->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE;
L
Luciano Coelho 已提交
3546
		break;
3547 3548 3549
	case WL1271_CIPHER_SUITE_GEM:
		key_type = KEY_GEM;
		break;
3550 3551 3552
	case WLAN_CIPHER_SUITE_AES_CMAC:
		key_type = KEY_IGTK;
		break;
L
Luciano Coelho 已提交
3553
	default:
3554
		wl1271_error("Unknown key algo 0x%x", key_conf->cipher);
L
Luciano Coelho 已提交
3555

3556
		return -EOPNOTSUPP;
L
Luciano Coelho 已提交
3557 3558
	}

3559 3560
	is_pairwise = key_conf->flags & IEEE80211_KEY_FLAG_PAIRWISE;

L
Luciano Coelho 已提交
3561 3562
	switch (cmd) {
	case SET_KEY:
E
Eliad Peller 已提交
3563
		ret = wl1271_set_key(wl, wlvif, KEY_ADD_OR_REPLACE,
3564 3565
				 key_conf->keyidx, key_type,
				 key_conf->keylen, key_conf->key,
3566
				 tx_seq_32, tx_seq_16, sta, is_pairwise);
L
Luciano Coelho 已提交
3567 3568
		if (ret < 0) {
			wl1271_error("Could not add or replace key");
3569
			return ret;
L
Luciano Coelho 已提交
3570
		}
3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582

		/*
		 * reconfiguring arp response if the unicast (or common)
		 * encryption key type was changed
		 */
		if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
		    (sta || key_type == KEY_WEP) &&
		    wlvif->encryption_type != key_type) {
			wlvif->encryption_type = key_type;
			ret = wl1271_cmd_build_arp_rsp(wl, wlvif);
			if (ret < 0) {
				wl1271_warning("build arp rsp failed: %d", ret);
3583
				return ret;
3584 3585
			}
		}
L
Luciano Coelho 已提交
3586 3587 3588
		break;

	case DISABLE_KEY:
E
Eliad Peller 已提交
3589
		ret = wl1271_set_key(wl, wlvif, KEY_REMOVE,
3590 3591
				     key_conf->keyidx, key_type,
				     key_conf->keylen, key_conf->key,
3592
				     0, 0, sta, is_pairwise);
L
Luciano Coelho 已提交
3593 3594
		if (ret < 0) {
			wl1271_error("Could not remove key");
3595
			return ret;
L
Luciano Coelho 已提交
3596 3597 3598 3599 3600
		}
		break;

	default:
		wl1271_error("Unsupported key cmd 0x%x", cmd);
3601
		return -EOPNOTSUPP;
L
Luciano Coelho 已提交
3602 3603 3604 3605
	}

	return ret;
}
3606
EXPORT_SYMBOL_GPL(wlcore_set_key);
L
Luciano Coelho 已提交
3607

3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618
static void wl1271_op_set_default_key_idx(struct ieee80211_hw *hw,
					  struct ieee80211_vif *vif,
					  int key_idx)
{
	struct wl1271 *wl = hw->priv;
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
	int ret;

	wl1271_debug(DEBUG_MAC80211, "mac80211 set default key idx %d",
		     key_idx);

3619 3620 3621 3622
	/* we don't handle unsetting of default key */
	if (key_idx == -1)
		return;

3623 3624 3625 3626 3627 3628 3629
	mutex_lock(&wl->mutex);

	if (unlikely(wl->state != WLCORE_STATE_ON)) {
		ret = -EAGAIN;
		goto out_unlock;
	}

3630 3631 3632
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
3633
		goto out_unlock;
3634
	}
3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647

	wlvif->default_key = key_idx;

	/* the default WEP key needs to be configured at least once */
	if (wlvif->encryption_type == KEY_WEP) {
		ret = wl12xx_cmd_set_default_wep_key(wl,
				key_idx,
				wlvif->sta.hlid);
		if (ret < 0)
			goto out_sleep;
	}

out_sleep:
3648 3649
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
3650 3651 3652 3653 3654

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

3655 3656 3657 3658 3659 3660 3661 3662
void wlcore_regdomain_config(struct wl1271 *wl)
{
	int ret;

	if (!(wl->quirks & WLCORE_QUIRK_REGDOMAIN_CONF))
		return;

	mutex_lock(&wl->mutex);
3663 3664 3665 3666

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

3667
	ret = pm_runtime_get_sync(wl->dev);
3668 3669 3670 3671 3672 3673 3674 3675 3676
	if (ret < 0)
		goto out;

	ret = wlcore_cmd_regdomain_config_locked(wl);
	if (ret < 0) {
		wl12xx_queue_recovery_work(wl);
		goto out;
	}

3677 3678
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
3679 3680 3681 3682
out:
	mutex_unlock(&wl->mutex);
}

L
Luciano Coelho 已提交
3683
static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
3684
			     struct ieee80211_vif *vif,
3685
			     struct ieee80211_scan_request *hw_req)
L
Luciano Coelho 已提交
3686
{
3687
	struct cfg80211_scan_request *req = &hw_req->req;
L
Luciano Coelho 已提交
3688 3689 3690
	struct wl1271 *wl = hw->priv;
	int ret;
	u8 *ssid = NULL;
3691
	size_t len = 0;
L
Luciano Coelho 已提交
3692 3693 3694 3695 3696

	wl1271_debug(DEBUG_MAC80211, "mac80211 hw scan");

	if (req->n_ssids) {
		ssid = req->ssids[0].ssid;
3697
		len = req->ssids[0].ssid_len;
L
Luciano Coelho 已提交
3698 3699 3700 3701
	}

	mutex_lock(&wl->mutex);

3702
	if (unlikely(wl->state != WLCORE_STATE_ON)) {
3703 3704 3705 3706 3707 3708 3709 3710 3711
		/*
		 * 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;
	}

3712 3713 3714
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
L
Luciano Coelho 已提交
3715
		goto out;
3716
	}
L
Luciano Coelho 已提交
3717

3718 3719
	/* fail if there is any role in ROC */
	if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) {
3720 3721 3722 3723 3724
		/* don't allow scanning right now */
		ret = -EBUSY;
		goto out_sleep;
	}

3725
	ret = wlcore_scan(hw->priv, vif, ssid, len, req);
3726
out_sleep:
3727 3728
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
L
Luciano Coelho 已提交
3729 3730 3731 3732 3733 3734
out:
	mutex_unlock(&wl->mutex);

	return ret;
}

3735 3736 3737 3738
static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw,
				     struct ieee80211_vif *vif)
{
	struct wl1271 *wl = hw->priv;
3739
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3740 3741 3742
	struct cfg80211_scan_info info = {
		.aborted = true,
	};
3743 3744 3745 3746 3747 3748
	int ret;

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

	mutex_lock(&wl->mutex);

3749
	if (unlikely(wl->state != WLCORE_STATE_ON))
3750 3751 3752 3753 3754
		goto out;

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

3755 3756 3757
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
3758
		goto out;
3759
	}
3760 3761

	if (wl->scan.state != WL1271_SCAN_STATE_DONE) {
3762
		ret = wl->ops->scan_stop(wl, wlvif);
3763 3764 3765
		if (ret < 0)
			goto out_sleep;
	}
A
Arik Nemtsov 已提交
3766 3767 3768 3769 3770 3771 3772

	/*
	 * Rearm the tx watchdog just before idling scan. This
	 * prevents just-finished scans from triggering the watchdog
	 */
	wl12xx_rearm_tx_watchdog_locked(wl);

3773 3774
	wl->scan.state = WL1271_SCAN_STATE_IDLE;
	memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
3775
	wl->scan_wlvif = NULL;
3776
	wl->scan.req = NULL;
3777
	ieee80211_scan_completed(wl->hw, &info);
3778 3779

out_sleep:
3780 3781
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
3782 3783 3784 3785 3786 3787
out:
	mutex_unlock(&wl->mutex);

	cancel_delayed_work_sync(&wl->scan_complete_work);
}

3788 3789 3790
static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
				      struct ieee80211_vif *vif,
				      struct cfg80211_sched_scan_request *req,
D
David Spinadel 已提交
3791
				      struct ieee80211_scan_ies *ies)
3792 3793
{
	struct wl1271 *wl = hw->priv;
E
Eliad Peller 已提交
3794
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3795 3796 3797 3798 3799 3800
	int ret;

	wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_start");

	mutex_lock(&wl->mutex);

3801
	if (unlikely(wl->state != WLCORE_STATE_ON)) {
3802 3803 3804 3805
		ret = -EAGAIN;
		goto out;
	}

3806 3807 3808
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
3809
		goto out;
3810
	}
3811

3812
	ret = wl->ops->sched_scan_start(wl, wlvif, req, ies);
3813 3814 3815
	if (ret < 0)
		goto out_sleep;

3816
	wl->sched_vif = wlvif;
3817 3818

out_sleep:
3819 3820
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
3821 3822 3823 3824 3825
out:
	mutex_unlock(&wl->mutex);
	return ret;
}

3826 3827
static int wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
				     struct ieee80211_vif *vif)
3828 3829
{
	struct wl1271 *wl = hw->priv;
3830
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3831 3832 3833 3834 3835 3836
	int ret;

	wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_stop");

	mutex_lock(&wl->mutex);

3837
	if (unlikely(wl->state != WLCORE_STATE_ON))
3838 3839
		goto out;

3840 3841 3842
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
3843
		goto out;
3844
	}
3845

3846
	wl->ops->sched_scan_stop(wl, wlvif);
3847

3848 3849
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
3850 3851
out:
	mutex_unlock(&wl->mutex);
3852 3853

	return 0;
3854 3855
}

3856 3857 3858 3859 3860 3861 3862
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);

3863
	if (unlikely(wl->state != WLCORE_STATE_ON)) {
3864 3865 3866 3867
		ret = -EAGAIN;
		goto out;
	}

3868 3869 3870
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
3871
		goto out;
3872
	}
3873

3874
	ret = wl1271_acx_frag_threshold(wl, value);
3875 3876 3877
	if (ret < 0)
		wl1271_warning("wl1271_op_set_frag_threshold failed: %d", ret);

3878 3879
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
3880 3881 3882 3883 3884 3885 3886

out:
	mutex_unlock(&wl->mutex);

	return ret;
}

L
Luciano Coelho 已提交
3887 3888 3889
static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
{
	struct wl1271 *wl = hw->priv;
3890
	struct wl12xx_vif *wlvif;
3891
	int ret = 0;
L
Luciano Coelho 已提交
3892 3893 3894

	mutex_lock(&wl->mutex);

3895
	if (unlikely(wl->state != WLCORE_STATE_ON)) {
3896
		ret = -EAGAIN;
3897
		goto out;
3898
	}
3899

3900 3901 3902
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
L
Luciano Coelho 已提交
3903
		goto out;
3904
	}
L
Luciano Coelho 已提交
3905

3906 3907 3908 3909 3910
	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);
	}
3911 3912
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
L
Luciano Coelho 已提交
3913 3914 3915 3916 3917 3918 3919

out:
	mutex_unlock(&wl->mutex);

	return ret;
}

3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933
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);
}

3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950
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);
}

3951 3952
static int wl1271_ap_set_probe_resp_tmpl(struct wl1271 *wl, u32 rates,
					 struct ieee80211_vif *vif)
3953
{
3954
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
3955 3956 3957
	struct sk_buff *skb;
	int ret;

3958
	skb = ieee80211_proberesp_get(wl->hw, vif);
3959
	if (!skb)
3960
		return -EOPNOTSUPP;
3961

3962
	ret = wl1271_cmd_template_set(wl, wlvif->role_id,
3963 3964 3965 3966 3967
				      CMD_TEMPL_AP_PROBE_RESPONSE,
				      skb->data,
				      skb->len, 0,
				      rates);
	dev_kfree_skb(skb);
3968 3969 3970 3971 3972 3973 3974 3975

	if (ret < 0)
		goto out;

	wl1271_debug(DEBUG_AP, "probe response updated");
	set_bit(WLVIF_FLAG_AP_PROBE_RESP_SET, &wlvif->flags);

out:
3976 3977 3978 3979 3980 3981 3982 3983
	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)
3984
{
3985 3986
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
3987 3988 3989 3990 3991
	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 */
3992
	if (wlvif->ssid_len > 0)
3993
		return wl1271_cmd_template_set(wl, wlvif->role_id,
3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029
					       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);

4030
	return wl1271_cmd_template_set(wl, wlvif->role_id,
4031 4032 4033 4034 4035 4036
				       CMD_TEMPL_AP_PROBE_RESPONSE,
				       probe_rsp_templ,
				       templ_len, 0,
				       rates);
}

4037
static int wl1271_bss_erp_info_changed(struct wl1271 *wl,
E
Eliad Peller 已提交
4038
				       struct ieee80211_vif *vif,
L
Luciano Coelho 已提交
4039 4040 4041
				       struct ieee80211_bss_conf *bss_conf,
				       u32 changed)
{
E
Eliad Peller 已提交
4042
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4043
	int ret = 0;
L
Luciano Coelho 已提交
4044

4045 4046
	if (changed & BSS_CHANGED_ERP_SLOT) {
		if (bss_conf->use_short_slot)
E
Eliad Peller 已提交
4047
			ret = wl1271_acx_slot(wl, wlvif, SLOT_TIME_SHORT);
4048
		else
E
Eliad Peller 已提交
4049
			ret = wl1271_acx_slot(wl, wlvif, SLOT_TIME_LONG);
4050 4051 4052 4053 4054
		if (ret < 0) {
			wl1271_warning("Set slot time failed %d", ret);
			goto out;
		}
	}
L
Luciano Coelho 已提交
4055

4056 4057
	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
		if (bss_conf->use_short_preamble)
E
Eliad Peller 已提交
4058
			wl1271_acx_set_preamble(wl, wlvif, ACX_PREAMBLE_SHORT);
4059
		else
E
Eliad Peller 已提交
4060
			wl1271_acx_set_preamble(wl, wlvif, ACX_PREAMBLE_LONG);
4061
	}
L
Luciano Coelho 已提交
4062

4063 4064
	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
		if (bss_conf->use_cts_prot)
E
Eliad Peller 已提交
4065 4066
			ret = wl1271_acx_cts_protect(wl, wlvif,
						     CTSPROTECT_ENABLE);
4067
		else
E
Eliad Peller 已提交
4068 4069
			ret = wl1271_acx_cts_protect(wl, wlvif,
						     CTSPROTECT_DISABLE);
4070 4071 4072 4073 4074
		if (ret < 0) {
			wl1271_warning("Set ctsprotect failed %d", ret);
			goto out;
		}
	}
4075

4076 4077 4078
out:
	return ret;
}
L
Luciano Coelho 已提交
4079

4080 4081 4082 4083 4084 4085 4086 4087
static int wlcore_set_beacon_template(struct wl1271 *wl,
				      struct ieee80211_vif *vif,
				      bool is_ap)
{
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
	struct ieee80211_hdr *hdr;
	u32 min_rate;
	int ret;
4088
	int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
4089 4090 4091 4092 4093 4094 4095 4096 4097 4098
	struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif);
	u16 tmpl_id;

	if (!beacon) {
		ret = -EINVAL;
		goto out;
	}

	wl1271_debug(DEBUG_MASTER, "beacon updated");

4099
	ret = wl1271_ssid_set(wlvif, beacon, ieoffset);
4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115
	if (ret < 0) {
		dev_kfree_skb(beacon);
		goto out;
	}
	min_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
	tmpl_id = is_ap ? CMD_TEMPL_AP_BEACON :
		CMD_TEMPL_BEACON;
	ret = wl1271_cmd_template_set(wl, wlvif->role_id, tmpl_id,
				      beacon->data,
				      beacon->len, 0,
				      min_rate);
	if (ret < 0) {
		dev_kfree_skb(beacon);
		goto out;
	}

4116 4117 4118 4119 4120 4121
	wlvif->wmm_enabled =
		cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
					WLAN_OUI_TYPE_MICROSOFT_WMM,
					beacon->data + ieoffset,
					beacon->len - ieoffset);

4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165
	/*
	 * 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;

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

	/*
	 * 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);

	hdr = (struct ieee80211_hdr *) beacon->data;
	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					 IEEE80211_STYPE_PROBE_RESP);
	if (is_ap)
		ret = wl1271_ap_set_probe_resp_tmpl_legacy(wl, vif,
							   beacon->data,
							   beacon->len,
							   min_rate);
	else
		ret = wl1271_cmd_template_set(wl, wlvif->role_id,
					      CMD_TEMPL_PROBE_RESPONSE,
					      beacon->data,
					      beacon->len, 0,
					      min_rate);
end_bcn:
	dev_kfree_skb(beacon);
	if (ret < 0)
		goto out;

out:
	return ret;
}

4166 4167 4168 4169 4170
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 已提交
4171
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
E
Eliad Peller 已提交
4172
	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
4173 4174
	int ret = 0;

4175
	if (changed & BSS_CHANGED_BEACON_INT) {
4176
		wl1271_debug(DEBUG_MASTER, "beacon interval updated: %d",
4177 4178
			bss_conf->beacon_int);

E
Eliad Peller 已提交
4179
		wlvif->beacon_int = bss_conf->beacon_int;
4180 4181
	}

4182 4183
	if ((changed & BSS_CHANGED_AP_PROBE_RESP) && is_ap) {
		u32 rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set);
4184 4185

		wl1271_ap_set_probe_resp_tmpl(wl, rate, vif);
4186 4187
	}

4188
	if (changed & BSS_CHANGED_BEACON) {
4189
		ret = wlcore_set_beacon_template(wl, vif, is_ap);
4190 4191 4192
		if (ret < 0)
			goto out;

4193 4194 4195 4196 4197 4198 4199
		if (test_and_clear_bit(WLVIF_FLAG_BEACON_DISABLED,
				       &wlvif->flags)) {
			ret = wlcore_hw_dfs_master_restart(wl, wlvif);
			if (ret < 0)
				goto out;
		}
	}
4200
out:
4201 4202
	if (ret != 0)
		wl1271_error("beacon info change failed: %d", ret);
4203 4204 4205 4206 4207 4208 4209 4210 4211
	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 已提交
4212
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4213
	int ret = 0;
4214

E
Eliad Peller 已提交
4215
	if (changed & BSS_CHANGED_BASIC_RATES) {
4216
		u32 rates = bss_conf->basic_rates;
4217

E
Eliad Peller 已提交
4218
		wlvif->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates,
E
Eliad Peller 已提交
4219
								 wlvif->band);
E
Eliad Peller 已提交
4220
		wlvif->basic_rate = wl1271_tx_min_rate_get(wl,
E
Eliad Peller 已提交
4221
							wlvif->basic_rate_set);
4222

E
Eliad Peller 已提交
4223
		ret = wl1271_init_ap_rates(wl, wlvif);
4224
		if (ret < 0) {
4225
			wl1271_error("AP rate policy change failed %d", ret);
4226 4227
			goto out;
		}
4228

4229
		ret = wl1271_ap_init_templates(wl, vif);
4230 4231
		if (ret < 0)
			goto out;
4232

4233 4234 4235 4236 4237 4238 4239 4240
		/* No need to set probe resp template for mesh */
		if (!ieee80211_vif_is_mesh(vif)) {
			ret = wl1271_ap_set_probe_resp_tmpl(wl,
							    wlvif->basic_rate,
							    vif);
			if (ret < 0)
				goto out;
		}
4241 4242 4243 4244

		ret = wlcore_set_beacon_template(wl, vif, true);
		if (ret < 0)
			goto out;
4245
	}
4246

4247 4248 4249
	ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, changed);
	if (ret < 0)
		goto out;
4250

4251
	if (changed & BSS_CHANGED_BEACON_ENABLED) {
4252
		if (bss_conf->enable_beacon) {
4253
			if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
E
Eliad Peller 已提交
4254
				ret = wl12xx_cmd_role_start_ap(wl, wlvif);
4255 4256
				if (ret < 0)
					goto out;
4257

4258
				ret = wl1271_ap_init_hwenc(wl, wlvif);
4259 4260
				if (ret < 0)
					goto out;
4261

4262
				set_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags);
4263
				wl1271_debug(DEBUG_AP, "started AP");
4264
			}
4265
		} else {
4266
			if (test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
4267 4268 4269 4270 4271 4272 4273
				/*
				 * AP might be in ROC in case we have just
				 * sent auth reply. handle it.
				 */
				if (test_bit(wlvif->role_id, wl->roc_map))
					wl12xx_croc(wl, wlvif->role_id);

E
Eliad Peller 已提交
4274
				ret = wl12xx_cmd_role_stop_ap(wl, wlvif);
4275 4276
				if (ret < 0)
					goto out;
4277

4278
				clear_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags);
4279 4280
				clear_bit(WLVIF_FLAG_AP_PROBE_RESP_SET,
					  &wlvif->flags);
4281 4282 4283 4284
				wl1271_debug(DEBUG_AP, "stopped AP");
			}
		}
	}
4285

E
Eliad Peller 已提交
4286
	ret = wl1271_bss_erp_info_changed(wl, vif, bss_conf, changed);
4287 4288
	if (ret < 0)
		goto out;
4289 4290 4291

	/* Handle HT information change */
	if ((changed & BSS_CHANGED_HT) &&
4292
	    (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) {
E
Eliad Peller 已提交
4293
		ret = wl1271_acx_set_ht_information(wl, wlvif,
4294 4295 4296 4297 4298 4299 4300
					bss_conf->ht_operation_mode);
		if (ret < 0) {
			wl1271_warning("Set ht information failed %d", ret);
			goto out;
		}
	}

4301 4302 4303
out:
	return;
}
J
Juuso Oikarinen 已提交
4304

4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333
static int wlcore_set_bssid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
			    struct ieee80211_bss_conf *bss_conf,
			    u32 sta_rate_set)
{
	u32 rates;
	int ret;

	wl1271_debug(DEBUG_MAC80211,
	     "changed_bssid: %pM, aid: %d, bcn_int: %d, brates: 0x%x sta_rate_set: 0x%x",
	     bss_conf->bssid, bss_conf->aid,
	     bss_conf->beacon_int,
	     bss_conf->basic_rates, sta_rate_set);

	wlvif->beacon_int = bss_conf->beacon_int;
	rates = bss_conf->basic_rates;
	wlvif->basic_rate_set =
		wl1271_tx_enabled_rates_get(wl, rates,
					    wlvif->band);
	wlvif->basic_rate =
		wl1271_tx_min_rate_get(wl,
				       wlvif->basic_rate_set);

	if (sta_rate_set)
		wlvif->rate_set =
			wl1271_tx_enabled_rates_get(wl,
						sta_rate_set,
						wlvif->band);

	/* we only support sched_scan while not connected */
4334
	if (wl->sched_vif == wlvif)
4335
		wl->ops->sched_scan_stop(wl, wlvif);
4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377

	ret = wl1271_acx_sta_rate_policies(wl, wlvif);
	if (ret < 0)
		return ret;

	ret = wl12xx_cmd_build_null_data(wl, wlvif);
	if (ret < 0)
		return ret;

	ret = wl1271_build_qos_null_data(wl, wl12xx_wlvif_to_vif(wlvif));
	if (ret < 0)
		return ret;

	wlcore_set_ssid(wl, wlvif);

	set_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);

	return 0;
}

static int wlcore_clear_bssid(struct wl1271 *wl, struct wl12xx_vif *wlvif)
{
	int ret;

	/* revert back to minimum rates for the current band */
	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);
	if (ret < 0)
		return ret;

	if (wlvif->bss_type == BSS_TYPE_STA_BSS &&
	    test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) {
		ret = wl12xx_cmd_role_stop_sta(wl, wlvif);
		if (ret < 0)
			return ret;
	}

	clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags);
	return 0;
}
4378 4379 4380 4381 4382 4383
/* 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 已提交
4384
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4385
	bool do_join = false;
E
Eliad Peller 已提交
4386
	bool is_ibss = (wlvif->bss_type == BSS_TYPE_IBSS);
E
Eliad Peller 已提交
4387
	bool ibss_joined = false;
4388
	u32 sta_rate_set = 0;
4389
	int ret;
4390
	struct ieee80211_sta *sta;
4391 4392
	bool sta_exists = false;
	struct ieee80211_sta_ht_cap sta_ht_cap;
4393 4394 4395 4396 4397 4398

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

E
Eliad Peller 已提交
4401 4402
	if (changed & BSS_CHANGED_IBSS) {
		if (bss_conf->ibss_joined) {
4403
			set_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags);
E
Eliad Peller 已提交
4404 4405
			ibss_joined = true;
		} else {
4406 4407
			wlcore_unset_assoc(wl, wlvif);
			wl12xx_cmd_role_stop_sta(wl, wlvif);
E
Eliad Peller 已提交
4408 4409 4410 4411
		}
	}

	if ((changed & BSS_CHANGED_BEACON_INT) && ibss_joined)
4412 4413 4414
		do_join = true;

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

E
Eliad Peller 已提交
4418
	if ((changed & BSS_CHANGED_BEACON_ENABLED) && ibss_joined) {
4419 4420 4421 4422 4423 4424
		wl1271_debug(DEBUG_ADHOC, "ad-hoc beaconing: %s",
			     bss_conf->enable_beacon ? "enabled" : "disabled");

		do_join = true;
	}

A
Arik Nemtsov 已提交
4425 4426 4427
	if (changed & BSS_CHANGED_IDLE && !is_ibss)
		wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle);

4428
	if (changed & BSS_CHANGED_CQM) {
4429 4430 4431
		bool enable = false;
		if (bss_conf->cqm_rssi_thold)
			enable = true;
E
Eliad Peller 已提交
4432
		ret = wl1271_acx_rssi_snr_trigger(wl, wlvif, enable,
4433 4434 4435 4436
						  bss_conf->cqm_rssi_thold,
						  bss_conf->cqm_rssi_hyst);
		if (ret < 0)
			goto out;
4437
		wlvif->rssi_thold = bss_conf->cqm_rssi_thold;
4438 4439
	}

4440 4441
	if (changed & (BSS_CHANGED_BSSID | BSS_CHANGED_HT |
		       BSS_CHANGED_ASSOC)) {
4442 4443
		rcu_read_lock();
		sta = ieee80211_find_sta(vif, bss_conf->bssid);
4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456
		if (sta) {
			u8 *rx_mask = sta->ht_cap.mcs.rx_mask;

			/* save the supp_rates of the ap */
			sta_rate_set = sta->supp_rates[wlvif->band];
			if (sta->ht_cap.ht_supported)
				sta_rate_set |=
					(rx_mask[0] << HW_HT_RATES_OFFSET) |
					(rx_mask[1] << HW_MIMO_RATES_OFFSET);
			sta_ht_cap = sta->ht_cap;
			sta_exists = true;
		}

4457
		rcu_read_unlock();
4458 4459
	}

4460 4461 4462 4463
	if (changed & BSS_CHANGED_BSSID) {
		if (!is_zero_ether_addr(bss_conf->bssid)) {
			ret = wlcore_set_bssid(wl, wlvif, bss_conf,
					       sta_rate_set);
L
Luciano Coelho 已提交
4464
			if (ret < 0)
4465
				goto out;
L
Luciano Coelho 已提交
4466

4467 4468
			/* Need to update the BSSID (for filtering etc) */
			do_join = true;
J
Juuso Oikarinen 已提交
4469
		} else {
4470
			ret = wlcore_clear_bssid(wl, wlvif);
4471
			if (ret < 0)
4472
				goto out;
L
Luciano Coelho 已提交
4473 4474 4475
		}
	}

4476 4477 4478 4479 4480 4481
	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 已提交
4482
			wlvif->basic_rate_set =
4483
				wl1271_tx_enabled_rates_get(wl, rates,
E
Eliad Peller 已提交
4484
							    wlvif->band);
E
Eliad Peller 已提交
4485
			wlvif->basic_rate =
E
Eliad Peller 已提交
4486 4487
				wl1271_tx_min_rate_get(wl,
						       wlvif->basic_rate_set);
4488

4489
			/* by default, use 11b + OFDM rates */
E
Eliad Peller 已提交
4490 4491
			wlvif->rate_set = CONF_TX_IBSS_DEFAULT_RATES;
			ret = wl1271_acx_sta_rate_policies(wl, wlvif);
4492 4493 4494 4495 4496
			if (ret < 0)
				goto out;
		}
	}

4497 4498 4499 4500 4501 4502 4503
	if ((changed & BSS_CHANGED_BEACON_INFO) && bss_conf->dtim_period) {
		/* enable beacon filtering */
		ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true);
		if (ret < 0)
			goto out;
	}

E
Eliad Peller 已提交
4504
	ret = wl1271_bss_erp_info_changed(wl, vif, bss_conf, changed);
4505 4506
	if (ret < 0)
		goto out;
L
Luciano Coelho 已提交
4507

J
Juuso Oikarinen 已提交
4508
	if (do_join) {
4509
		ret = wlcore_join(wl, wlvif);
J
Juuso Oikarinen 已提交
4510 4511
		if (ret < 0) {
			wl1271_warning("cmd join failed %d", ret);
4512
			goto out;
J
Juuso Oikarinen 已提交
4513
		}
4514
	}
4515

4516 4517
	if (changed & BSS_CHANGED_ASSOC) {
		if (bss_conf->assoc) {
4518 4519
			ret = wlcore_set_assoc(wl, wlvif, bss_conf,
					       sta_rate_set);
4520 4521 4522
			if (ret < 0)
				goto out;

4523 4524
			if (test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags))
				wl12xx_set_authorized(wl, wlvif);
4525 4526
		} else {
			wlcore_unset_assoc(wl, wlvif);
4527
		}
4528 4529
	}

4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547
	if (changed & BSS_CHANGED_PS) {
		if ((bss_conf->ps) &&
		    test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) &&
		    !test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
			int ps_mode;
			char *ps_mode_str;

			if (wl->conf.conn.forced_ps) {
				ps_mode = STATION_POWER_SAVE_MODE;
				ps_mode_str = "forced";
			} else {
				ps_mode = STATION_AUTO_PS_MODE;
				ps_mode_str = "auto";
			}

			wl1271_debug(DEBUG_PSM, "%s ps enabled", ps_mode_str);

			ret = wl1271_ps_set_mode(wl, wlvif, ps_mode);
4548
			if (ret < 0)
4549 4550 4551 4552 4553 4554 4555 4556 4557 4558
				wl1271_warning("enter %s ps failed %d",
					       ps_mode_str, ret);
		} else if (!bss_conf->ps &&
			   test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) {
			wl1271_debug(DEBUG_PSM, "auto ps disabled");

			ret = wl1271_ps_set_mode(wl, wlvif,
						 STATION_ACTIVE_MODE);
			if (ret < 0)
				wl1271_warning("exit auto ps failed %d", ret);
4559
		}
4560 4561
	}

4562
	/* Handle new association with HT. Do this after join. */
4563
	if (sta_exists) {
4564
		bool enabled =
4565
			bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT;
4566

E
Eliad Peller 已提交
4567 4568 4569 4570 4571
		ret = wlcore_hw_set_peer_cap(wl,
					     &sta_ht_cap,
					     enabled,
					     wlvif->rate_set,
					     wlvif->sta.hlid);
4572 4573 4574 4575
		if (ret < 0) {
			wl1271_warning("Set ht cap failed %d", ret);
			goto out;

4576
		}
4577 4578 4579 4580

		if (enabled) {
			ret = wl1271_acx_set_ht_information(wl, wlvif,
						bss_conf->ht_operation_mode);
4581
			if (ret < 0) {
4582
				wl1271_warning("Set ht information failed %d",
4583 4584 4585 4586 4587 4588
					       ret);
				goto out;
			}
		}
	}

4589 4590 4591 4592 4593 4594 4595
	/* Handle arp filtering. Done after join. */
	if ((changed & BSS_CHANGED_ARP_FILTER) ||
	    (!is_ibss && (changed & BSS_CHANGED_QOS))) {
		__be32 addr = bss_conf->arp_addr_list[0];
		wlvif->sta.qos = bss_conf->qos;
		WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS);

4596
		if (bss_conf->arp_addr_cnt == 1 && bss_conf->assoc) {
4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622
			wlvif->ip_addr = addr;
			/*
			 * 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.
			 */
			ret = wl1271_cmd_build_arp_rsp(wl, wlvif);
			if (ret < 0) {
				wl1271_warning("build arp rsp failed: %d", ret);
				goto out;
			}

			ret = wl1271_acx_arp_ip_filter(wl, wlvif,
				(ACX_ARP_FILTER_ARP_FILTERING |
				 ACX_ARP_FILTER_AUTO_ARP),
				addr);
		} else {
			wlvif->ip_addr = 0;
			ret = wl1271_acx_arp_ip_filter(wl, wlvif, 0, addr);
		}

		if (ret < 0)
			goto out;
	}

4623 4624 4625 4626 4627 4628 4629 4630 4631 4632
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 已提交
4633 4634
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
	bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS);
4635 4636
	int ret;

4637 4638
	wl1271_debug(DEBUG_MAC80211, "mac80211 bss info role %d changed 0x%x",
		     wlvif->role_id, (int)changed);
4639

4640 4641 4642 4643 4644
	/*
	 * make sure to cancel pending disconnections if our association
	 * state changed
	 */
	if (!is_ap && (changed & BSS_CHANGED_ASSOC))
4645
		cancel_delayed_work_sync(&wlvif->connection_loss_work);
4646

E
Eliad Peller 已提交
4647 4648 4649 4650
	if (is_ap && (changed & BSS_CHANGED_BEACON_ENABLED) &&
	    !bss_conf->enable_beacon)
		wl1271_tx_flush(wl);

4651 4652
	mutex_lock(&wl->mutex);

4653
	if (unlikely(wl->state != WLCORE_STATE_ON))
4654 4655
		goto out;

4656 4657 4658
	if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)))
		goto out;

4659 4660 4661
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
4662
		goto out;
4663
	}
4664

A
Alex Gal 已提交
4665 4666 4667 4668 4669 4670 4671 4672 4673 4674
	if ((changed & BSS_CHANGED_TXPOWER) &&
	    bss_conf->txpower != wlvif->power_level) {

		ret = wl1271_acx_tx_power(wl, wlvif, bss_conf->txpower);
		if (ret < 0)
			goto out;

		wlvif->power_level = bss_conf->txpower;
	}

4675 4676 4677 4678 4679
	if (is_ap)
		wl1271_bss_info_changed_ap(wl, vif, bss_conf, changed);
	else
		wl1271_bss_info_changed_sta(wl, vif, bss_conf, changed);

4680 4681
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
L
Luciano Coelho 已提交
4682 4683 4684 4685 4686

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

E
Eliad Peller 已提交
4687 4688 4689 4690
static int wlcore_op_add_chanctx(struct ieee80211_hw *hw,
				 struct ieee80211_chanctx_conf *ctx)
{
	wl1271_debug(DEBUG_MAC80211, "mac80211 add chanctx %d (type %d)",
4691 4692
		     ieee80211_frequency_to_channel(ctx->def.chan->center_freq),
		     cfg80211_get_chandef_type(&ctx->def));
E
Eliad Peller 已提交
4693 4694 4695 4696 4697 4698 4699
	return 0;
}

static void wlcore_op_remove_chanctx(struct ieee80211_hw *hw,
				     struct ieee80211_chanctx_conf *ctx)
{
	wl1271_debug(DEBUG_MAC80211, "mac80211 remove chanctx %d (type %d)",
4700 4701
		     ieee80211_frequency_to_channel(ctx->def.chan->center_freq),
		     cfg80211_get_chandef_type(&ctx->def));
E
Eliad Peller 已提交
4702 4703 4704 4705 4706 4707
}

static void wlcore_op_change_chanctx(struct ieee80211_hw *hw,
				     struct ieee80211_chanctx_conf *ctx,
				     u32 changed)
{
4708 4709 4710 4711 4712 4713
	struct wl1271 *wl = hw->priv;
	struct wl12xx_vif *wlvif;
	int ret;
	int channel = ieee80211_frequency_to_channel(
		ctx->def.chan->center_freq);

E
Eliad Peller 已提交
4714 4715
	wl1271_debug(DEBUG_MAC80211,
		     "mac80211 change chanctx %d (type %d) changed 0x%x",
4716 4717 4718 4719
		     channel, cfg80211_get_chandef_type(&ctx->def), changed);

	mutex_lock(&wl->mutex);

4720 4721 4722
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
4723
		goto out;
4724
	}
4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746

	wl12xx_for_each_wlvif(wl, wlvif) {
		struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);

		rcu_read_lock();
		if (rcu_access_pointer(vif->chanctx_conf) != ctx) {
			rcu_read_unlock();
			continue;
		}
		rcu_read_unlock();

		/* start radar if needed */
		if (changed & IEEE80211_CHANCTX_CHANGE_RADAR &&
		    wlvif->bss_type == BSS_TYPE_AP_BSS &&
		    ctx->radar_enabled && !wlvif->radar_enabled &&
		    ctx->def.chan->dfs_state == NL80211_DFS_USABLE) {
			wl1271_debug(DEBUG_MAC80211, "Start radar detection");
			wlcore_hw_set_cac(wl, wlvif, true);
			wlvif->radar_enabled = true;
		}
	}

4747 4748
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
4749 4750
out:
	mutex_unlock(&wl->mutex);
E
Eliad Peller 已提交
4751 4752 4753 4754 4755 4756 4757 4758 4759
}

static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw,
					struct ieee80211_vif *vif,
					struct ieee80211_chanctx_conf *ctx)
{
	struct wl1271 *wl = hw->priv;
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
	int channel = ieee80211_frequency_to_channel(
4760
		ctx->def.chan->center_freq);
4761
	int ret = -EINVAL;
E
Eliad Peller 已提交
4762 4763

	wl1271_debug(DEBUG_MAC80211,
4764 4765 4766 4767
		     "mac80211 assign chanctx (role %d) %d (type %d) (radar %d dfs_state %d)",
		     wlvif->role_id, channel,
		     cfg80211_get_chandef_type(&ctx->def),
		     ctx->radar_enabled, ctx->def.chan->dfs_state);
E
Eliad Peller 已提交
4768 4769 4770

	mutex_lock(&wl->mutex);

4771 4772 4773 4774 4775 4776
	if (unlikely(wl->state != WLCORE_STATE_ON))
		goto out;

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

4777 4778 4779
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
4780
		goto out;
4781
	}
4782

4783
	wlvif->band = ctx->def.chan->band;
E
Eliad Peller 已提交
4784
	wlvif->channel = channel;
4785
	wlvif->channel_type = cfg80211_get_chandef_type(&ctx->def);
E
Eliad Peller 已提交
4786 4787 4788 4789

	/* update default rates according to the band */
	wl1271_set_band_rate(wl, wlvif);

4790 4791 4792 4793 4794 4795 4796
	if (ctx->radar_enabled &&
	    ctx->def.chan->dfs_state == NL80211_DFS_USABLE) {
		wl1271_debug(DEBUG_MAC80211, "Start radar detection");
		wlcore_hw_set_cac(wl, wlvif, true);
		wlvif->radar_enabled = true;
	}

4797 4798
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
4799
out:
E
Eliad Peller 已提交
4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810
	mutex_unlock(&wl->mutex);

	return 0;
}

static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
					   struct ieee80211_vif *vif,
					   struct ieee80211_chanctx_conf *ctx)
{
	struct wl1271 *wl = hw->priv;
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4811
	int ret;
E
Eliad Peller 已提交
4812 4813 4814 4815

	wl1271_debug(DEBUG_MAC80211,
		     "mac80211 unassign chanctx (role %d) %d (type %d)",
		     wlvif->role_id,
4816 4817
		     ieee80211_frequency_to_channel(ctx->def.chan->center_freq),
		     cfg80211_get_chandef_type(&ctx->def));
E
Eliad Peller 已提交
4818 4819

	wl1271_tx_flush(wl);
4820 4821 4822 4823 4824 4825 4826 4827 4828

	mutex_lock(&wl->mutex);

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

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

4829 4830 4831
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
4832
		goto out;
4833
	}
4834 4835 4836 4837 4838 4839 4840

	if (wlvif->radar_enabled) {
		wl1271_debug(DEBUG_MAC80211, "Stop radar detection");
		wlcore_hw_set_cac(wl, wlvif, false);
		wlvif->radar_enabled = false;
	}

4841 4842
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861
out:
	mutex_unlock(&wl->mutex);
}

static int __wlcore_switch_vif_chan(struct wl1271 *wl,
				    struct wl12xx_vif *wlvif,
				    struct ieee80211_chanctx_conf *new_ctx)
{
	int channel = ieee80211_frequency_to_channel(
		new_ctx->def.chan->center_freq);

	wl1271_debug(DEBUG_MAC80211,
		     "switch vif (role %d) %d -> %d chan_type: %d",
		     wlvif->role_id, wlvif->channel, channel,
		     cfg80211_get_chandef_type(&new_ctx->def));

	if (WARN_ON_ONCE(wlvif->bss_type != BSS_TYPE_AP_BSS))
		return 0;

4862 4863
	WARN_ON(!test_bit(WLVIF_FLAG_BEACON_DISABLED, &wlvif->flags));

4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898
	if (wlvif->radar_enabled) {
		wl1271_debug(DEBUG_MAC80211, "Stop radar detection");
		wlcore_hw_set_cac(wl, wlvif, false);
		wlvif->radar_enabled = false;
	}

	wlvif->band = new_ctx->def.chan->band;
	wlvif->channel = channel;
	wlvif->channel_type = cfg80211_get_chandef_type(&new_ctx->def);

	/* start radar if needed */
	if (new_ctx->radar_enabled) {
		wl1271_debug(DEBUG_MAC80211, "Start radar detection");
		wlcore_hw_set_cac(wl, wlvif, true);
		wlvif->radar_enabled = true;
	}

	return 0;
}

static int
wlcore_op_switch_vif_chanctx(struct ieee80211_hw *hw,
			     struct ieee80211_vif_chanctx_switch *vifs,
			     int n_vifs,
			     enum ieee80211_chanctx_switch_mode mode)
{
	struct wl1271 *wl = hw->priv;
	int i, ret;

	wl1271_debug(DEBUG_MAC80211,
		     "mac80211 switch chanctx n_vifs %d mode %d",
		     n_vifs, mode);

	mutex_lock(&wl->mutex);

4899 4900 4901
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
4902
		goto out;
4903
	}
4904 4905 4906 4907 4908 4909 4910 4911 4912

	for (i = 0; i < n_vifs; i++) {
		struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vifs[i].vif);

		ret = __wlcore_switch_vif_chan(wl, wlvif, vifs[i].new_ctx);
		if (ret)
			goto out_sleep;
	}
out_sleep:
4913 4914
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
4915 4916 4917 4918
out:
	mutex_unlock(&wl->mutex);

	return 0;
E
Eliad Peller 已提交
4919 4920
}

4921 4922
static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
			     struct ieee80211_vif *vif, u16 queue,
K
Kalle Valo 已提交
4923 4924 4925
			     const struct ieee80211_tx_queue_params *params)
{
	struct wl1271 *wl = hw->priv;
E
Eliad Peller 已提交
4926
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
K
Kalle Valo 已提交
4927
	u8 ps_scheme;
4928
	int ret = 0;
K
Kalle Valo 已提交
4929

E
Eliad Peller 已提交
4930 4931 4932
	if (wlcore_is_p2p_mgmt(wlvif))
		return 0;

K
Kalle Valo 已提交
4933 4934 4935 4936
	mutex_lock(&wl->mutex);

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

K
Kalle Valo 已提交
4937 4938 4939 4940 4941
	if (params->uapsd)
		ps_scheme = CONF_PS_SCHEME_UPSD_TRIGGER;
	else
		ps_scheme = CONF_PS_SCHEME_LEGACY;

4942
	if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
4943
		goto out;
4944

4945 4946 4947
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
4948
		goto out;
4949
	}
4950

4951 4952 4953 4954
	/*
	 * the txop is confed in units of 32us by the mac80211,
	 * we need us
	 */
E
Eliad Peller 已提交
4955
	ret = wl1271_acx_ac_cfg(wl, wlvif, wl1271_tx_get_queue(queue),
4956 4957 4958 4959 4960
				params->cw_min, params->cw_max,
				params->aifs, params->txop << 5);
	if (ret < 0)
		goto out_sleep;

E
Eliad Peller 已提交
4961
	ret = wl1271_acx_tid_cfg(wl, wlvif, wl1271_tx_get_queue(queue),
4962 4963 4964 4965
				 CONF_CHANNEL_TYPE_EDCF,
				 wl1271_tx_get_queue(queue),
				 ps_scheme, CONF_ACK_POLICY_LEGACY,
				 0, 0);
K
Kalle Valo 已提交
4966 4967

out_sleep:
4968 4969
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
K
Kalle Valo 已提交
4970 4971 4972 4973 4974 4975 4976

out:
	mutex_unlock(&wl->mutex);

	return ret;
}

4977 4978
static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw,
			     struct ieee80211_vif *vif)
J
Juuso Oikarinen 已提交
4979 4980 4981
{

	struct wl1271 *wl = hw->priv;
4982
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
J
Juuso Oikarinen 已提交
4983 4984 4985 4986 4987 4988 4989
	u64 mactime = ULLONG_MAX;
	int ret;

	wl1271_debug(DEBUG_MAC80211, "mac80211 get tsf");

	mutex_lock(&wl->mutex);

4990
	if (unlikely(wl->state != WLCORE_STATE_ON))
4991 4992
		goto out;

4993 4994 4995
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
J
Juuso Oikarinen 已提交
4996
		goto out;
4997
	}
J
Juuso Oikarinen 已提交
4998

4999
	ret = wl12xx_acx_tsf_info(wl, wlvif, &mactime);
J
Juuso Oikarinen 已提交
5000 5001 5002 5003
	if (ret < 0)
		goto out_sleep;

out_sleep:
5004 5005
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
J
Juuso Oikarinen 已提交
5006 5007 5008 5009 5010

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

5012 5013 5014 5015
static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx,
				struct survey_info *survey)
{
	struct ieee80211_conf *conf = &hw->conf;
5016

5017 5018
	if (idx != 0)
		return -ENOENT;
5019

5020
	survey->channel = conf->chandef.chan;
5021
	survey->filled = 0;
5022 5023 5024
	return 0;
}

5025
static int wl1271_allocate_sta(struct wl1271 *wl,
5026 5027
			     struct wl12xx_vif *wlvif,
			     struct ieee80211_sta *sta)
5028 5029
{
	struct wl1271_station *wl_sta;
5030
	int ret;
5031

5032

5033
	if (wl->active_sta_count >= wl->max_ap_stations) {
5034 5035 5036 5037 5038
		wl1271_warning("could not allocate HLID - too much stations");
		return -EBUSY;
	}

	wl_sta = (struct wl1271_station *)sta->drv_priv;
5039 5040 5041 5042 5043 5044
	ret = wl12xx_allocate_link(wl, wlvif, &wl_sta->hlid);
	if (ret < 0) {
		wl1271_warning("could not allocate HLID - too many links");
		return -EBUSY;
	}

5045 5046 5047
	/* use the previous security seq, if this is a recovery/resume */
	wl->links[wl_sta->hlid].total_freed_pkts = wl_sta->total_freed_pkts;

5048
	set_bit(wl_sta->hlid, wlvif->ap.sta_hlid_map);
5049
	memcpy(wl->links[wl_sta->hlid].addr, sta->addr, ETH_ALEN);
5050
	wl->active_sta_count++;
5051 5052 5053
	return 0;
}

5054
void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid)
5055
{
5056
	if (!test_bit(hlid, wlvif->ap.sta_hlid_map))
5057 5058
		return;

5059
	clear_bit(hlid, wlvif->ap.sta_hlid_map);
5060
	__clear_bit(hlid, &wl->ap_ps_map);
5061
	__clear_bit(hlid, &wl->ap_fw_ps_map);
5062 5063 5064 5065 5066

	/*
	 * save the last used PN in the private part of iee80211_sta,
	 * in case of recovery/suspend
	 */
5067
	wlcore_save_freed_pkts_addr(wl, wlvif, hlid, wl->links[hlid].addr);
5068

5069
	wl12xx_free_link(wl, wlvif, &hlid);
5070
	wl->active_sta_count--;
A
Arik Nemtsov 已提交
5071 5072 5073 5074 5075 5076 5077

	/*
	 * rearm the tx watchdog when the last STA is freed - give the FW a
	 * chance to return STA-buffered packets before complaining.
	 */
	if (wl->active_sta_count == 0)
		wl12xx_rearm_tx_watchdog_locked(wl);
5078 5079
}

5080 5081 5082
static int wl12xx_sta_add(struct wl1271 *wl,
			  struct wl12xx_vif *wlvif,
			  struct ieee80211_sta *sta)
5083
{
5084
	struct wl1271_station *wl_sta;
5085 5086 5087 5088 5089
	int ret = 0;
	u8 hlid;

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

5090
	ret = wl1271_allocate_sta(wl, wlvif, sta);
5091
	if (ret < 0)
5092
		return ret;
5093

5094 5095 5096
	wl_sta = (struct wl1271_station *)sta->drv_priv;
	hlid = wl_sta->hlid;

E
Eliad Peller 已提交
5097
	ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid);
5098
	if (ret < 0)
5099
		wl1271_free_sta(wl, wlvif, hlid);
5100

5101 5102
	return ret;
}
5103

5104 5105 5106 5107 5108 5109
static int wl12xx_sta_remove(struct wl1271 *wl,
			     struct wl12xx_vif *wlvif,
			     struct ieee80211_sta *sta)
{
	struct wl1271_station *wl_sta;
	int ret = 0, id;
5110

5111 5112 5113 5114 5115 5116
	wl1271_debug(DEBUG_MAC80211, "mac80211 remove sta %d", (int)sta->aid);

	wl_sta = (struct wl1271_station *)sta->drv_priv;
	id = wl_sta->hlid;
	if (WARN_ON(!test_bit(id, wlvif->ap.sta_hlid_map)))
		return -EINVAL;
5117

5118
	ret = wl12xx_cmd_remove_peer(wl, wlvif, wl_sta->hlid);
5119
	if (ret < 0)
5120
		return ret;
5121

5122
	wl1271_free_sta(wl, wlvif, wl_sta->hlid);
5123 5124 5125
	return ret;
}

5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138
static void wlcore_roc_if_possible(struct wl1271 *wl,
				   struct wl12xx_vif *wlvif)
{
	if (find_first_bit(wl->roc_map,
			   WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES)
		return;

	if (WARN_ON(wlvif->role_id == WL12XX_INVALID_ROLE_ID))
		return;

	wl12xx_roc(wl, wlvif, wlvif->role_id, wlvif->band, wlvif->channel);
}

5139 5140 5141 5142 5143 5144 5145 5146
/*
 * when wl_sta is NULL, we treat this call as if coming from a
 * pending auth reply.
 * wl->mutex must be taken and the FW must be awake when the call
 * takes place.
 */
void wlcore_update_inconn_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif,
			      struct wl1271_station *wl_sta, bool in_conn)
5147
{
5148 5149
	if (in_conn) {
		if (WARN_ON(wl_sta && wl_sta->in_connection))
5150
			return;
5151 5152 5153

		if (!wlvif->ap_pending_auth_reply &&
		    !wlvif->inconn_count)
5154
			wlcore_roc_if_possible(wl, wlvif);
5155 5156 5157 5158 5159 5160 5161

		if (wl_sta) {
			wl_sta->in_connection = true;
			wlvif->inconn_count++;
		} else {
			wlvif->ap_pending_auth_reply = true;
		}
5162
	} else {
5163
		if (wl_sta && !wl_sta->in_connection)
5164 5165
			return;

5166
		if (WARN_ON(!wl_sta && !wlvif->ap_pending_auth_reply))
5167 5168
			return;

5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181
		if (WARN_ON(wl_sta && !wlvif->inconn_count))
			return;

		if (wl_sta) {
			wl_sta->in_connection = false;
			wlvif->inconn_count--;
		} else {
			wlvif->ap_pending_auth_reply = false;
		}

		if (!wlvif->inconn_count && !wlvif->ap_pending_auth_reply &&
		    test_bit(wlvif->role_id, wl->roc_map))
			wl12xx_croc(wl, wlvif->role_id);
5182 5183 5184
	}
}

5185 5186 5187 5188 5189
static int wl12xx_update_sta_state(struct wl1271 *wl,
				   struct wl12xx_vif *wlvif,
				   struct ieee80211_sta *sta,
				   enum ieee80211_sta_state old_state,
				   enum ieee80211_sta_state new_state)
5190 5191
{
	struct wl1271_station *wl_sta;
5192 5193 5194
	bool is_ap = wlvif->bss_type == BSS_TYPE_AP_BSS;
	bool is_sta = wlvif->bss_type == BSS_TYPE_STA_BSS;
	int ret;
5195

5196
	wl_sta = (struct wl1271_station *)sta->drv_priv;
5197

5198 5199 5200
	/* Add station (AP mode) */
	if (is_ap &&
	    old_state == IEEE80211_STA_NOTEXIST &&
5201 5202 5203 5204
	    new_state == IEEE80211_STA_NONE) {
		ret = wl12xx_sta_add(wl, wlvif, sta);
		if (ret)
			return ret;
5205 5206

		wlcore_update_inconn_sta(wl, wlvif, wl_sta, true);
5207
	}
5208 5209 5210 5211 5212 5213 5214

	/* Remove station (AP mode) */
	if (is_ap &&
	    old_state == IEEE80211_STA_NONE &&
	    new_state == IEEE80211_STA_NOTEXIST) {
		/* must not fail */
		wl12xx_sta_remove(wl, wlvif, sta);
5215 5216

		wlcore_update_inconn_sta(wl, wlvif, wl_sta, false);
5217
	}
5218

5219 5220 5221
	/* Authorize station (AP mode) */
	if (is_ap &&
	    new_state == IEEE80211_STA_AUTHORIZED) {
5222
		ret = wl12xx_cmd_set_peer_state(wl, wlvif, wl_sta->hlid);
5223 5224
		if (ret < 0)
			return ret;
5225

5226 5227 5228 5229 5230
		/* reconfigure rates */
		ret = wl12xx_cmd_add_peer(wl, wlvif, sta, wl_sta->hlid);
		if (ret < 0)
			return ret;

5231
		ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true,
5232
						     wl_sta->hlid);
5233 5234
		if (ret)
			return ret;
5235 5236

		wlcore_update_inconn_sta(wl, wlvif, wl_sta, false);
5237
	}
5238

5239 5240 5241 5242
	/* Authorize station */
	if (is_sta &&
	    new_state == IEEE80211_STA_AUTHORIZED) {
		set_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
5243 5244 5245
		ret = wl12xx_set_authorized(wl, wlvif);
		if (ret)
			return ret;
5246 5247 5248 5249 5250 5251
	}

	if (is_sta &&
	    old_state == IEEE80211_STA_AUTHORIZED &&
	    new_state == IEEE80211_STA_ASSOC) {
		clear_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags);
5252
		clear_bit(WLVIF_FLAG_STA_STATE_SENT, &wlvif->flags);
5253 5254
	}

5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269
	/* save seq number on disassoc (suspend) */
	if (is_sta &&
	    old_state == IEEE80211_STA_ASSOC &&
	    new_state == IEEE80211_STA_AUTH) {
		wlcore_save_freed_pkts(wl, wlvif, wlvif->sta.hlid, sta);
		wlvif->total_freed_pkts = 0;
	}

	/* restore seq number on assoc (resume) */
	if (is_sta &&
	    old_state == IEEE80211_STA_AUTH &&
	    new_state == IEEE80211_STA_ASSOC) {
		wlvif->total_freed_pkts = wl_sta->total_freed_pkts;
	}

5270 5271 5272 5273 5274 5275
	/* clear ROCs on failure or authorization */
	if (is_sta &&
	    (new_state == IEEE80211_STA_AUTHORIZED ||
	     new_state == IEEE80211_STA_NOTEXIST)) {
		if (test_bit(wlvif->role_id, wl->roc_map))
			wl12xx_croc(wl, wlvif->role_id);
5276 5277
	}

5278 5279 5280 5281 5282 5283 5284 5285 5286 5287
	if (is_sta &&
	    old_state == IEEE80211_STA_NOTEXIST &&
	    new_state == IEEE80211_STA_NONE) {
		if (find_first_bit(wl->roc_map,
				   WL12XX_MAX_ROLES) >= WL12XX_MAX_ROLES) {
			WARN_ON(wlvif->role_id == WL12XX_INVALID_ROLE_ID);
			wl12xx_roc(wl, wlvif, wlvif->role_id,
				   wlvif->band, wlvif->channel);
		}
	}
5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305
	return 0;
}

static int wl12xx_op_sta_state(struct ieee80211_hw *hw,
			       struct ieee80211_vif *vif,
			       struct ieee80211_sta *sta,
			       enum ieee80211_sta_state old_state,
			       enum ieee80211_sta_state new_state)
{
	struct wl1271 *wl = hw->priv;
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
	int ret;

	wl1271_debug(DEBUG_MAC80211, "mac80211 sta %d state=%d->%d",
		     sta->aid, old_state, new_state);

	mutex_lock(&wl->mutex);

5306
	if (unlikely(wl->state != WLCORE_STATE_ON)) {
5307
		ret = -EBUSY;
5308
		goto out;
5309
	}
5310

5311 5312 5313
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
5314
		goto out;
5315
	}
5316

5317
	ret = wl12xx_update_sta_state(wl, wlvif, sta, old_state, new_state);
5318

5319 5320
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
5321 5322
out:
	mutex_unlock(&wl->mutex);
5323 5324
	if (new_state < old_state)
		return 0;
5325 5326 5327
	return ret;
}

5328 5329
static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
				  struct ieee80211_vif *vif,
5330
				  struct ieee80211_ampdu_params *params)
L
Levi, Shahar 已提交
5331 5332
{
	struct wl1271 *wl = hw->priv;
E
Eliad Peller 已提交
5333
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
L
Levi, Shahar 已提交
5334
	int ret;
5335
	u8 hlid, *ba_bitmap;
5336 5337 5338 5339
	struct ieee80211_sta *sta = params->sta;
	enum ieee80211_ampdu_mlme_action action = params->action;
	u16 tid = params->tid;
	u16 *ssn = &params->ssn;
5340 5341 5342 5343 5344 5345 5346

	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 已提交
5347 5348 5349

	mutex_lock(&wl->mutex);

5350
	if (unlikely(wl->state != WLCORE_STATE_ON)) {
L
Levi, Shahar 已提交
5351 5352 5353 5354
		ret = -EAGAIN;
		goto out;
	}

E
Eliad Peller 已提交
5355
	if (wlvif->bss_type == BSS_TYPE_STA_BSS) {
E
Eliad Peller 已提交
5356
		hlid = wlvif->sta.hlid;
E
Eliad Peller 已提交
5357
	} else if (wlvif->bss_type == BSS_TYPE_AP_BSS) {
5358 5359 5360 5361 5362 5363 5364 5365 5366
		struct wl1271_station *wl_sta;

		wl_sta = (struct wl1271_station *)sta->drv_priv;
		hlid = wl_sta->hlid;
	} else {
		ret = -EINVAL;
		goto out;
	}

5367 5368
	ba_bitmap = &wl->links[hlid].ba_bitmap;

5369 5370 5371
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
L
Levi, Shahar 已提交
5372
		goto out;
5373
	}
L
Levi, Shahar 已提交
5374

5375 5376 5377
	wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu: Rx tid %d action %d",
		     tid, action);

L
Levi, Shahar 已提交
5378 5379
	switch (action) {
	case IEEE80211_AMPDU_RX_START:
E
Eliad Peller 已提交
5380
		if (!wlvif->ba_support || !wlvif->ba_allowed) {
L
Levi, Shahar 已提交
5381
			ret = -ENOTSUPP;
5382 5383 5384
			break;
		}

5385
		if (wl->ba_rx_session_count >= wl->ba_rx_session_count_max) {
5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398
			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,
5399 5400 5401
				hlid,
				params->buf_size);

5402 5403 5404
		if (!ret) {
			*ba_bitmap |= BIT(tid);
			wl->ba_rx_session_count++;
L
Levi, Shahar 已提交
5405 5406 5407 5408
		}
		break;

	case IEEE80211_AMPDU_RX_STOP:
5409
		if (!(*ba_bitmap & BIT(tid))) {
5410 5411 5412 5413 5414 5415
			/*
			 * this happens on reconfig - so only output a debug
			 * message for now, and don't fail the function.
			 */
			wl1271_debug(DEBUG_MAC80211,
				     "no active RX BA session on tid: %d",
5416
				     tid);
5417
			ret = 0;
5418 5419 5420 5421
			break;
		}

		ret = wl12xx_acx_set_ba_receiver_session(wl, tid, 0, false,
5422
							 hlid, 0);
5423 5424 5425 5426
		if (!ret) {
			*ba_bitmap &= ~BIT(tid);
			wl->ba_rx_session_count--;
		}
L
Levi, Shahar 已提交
5427 5428 5429 5430 5431 5432 5433
		break;

	/*
	 * The BA initiator session management in FW independently.
	 * Falling break here on purpose for all TX APDU commands.
	 */
	case IEEE80211_AMPDU_TX_START:
5434 5435 5436
	case IEEE80211_AMPDU_TX_STOP_CONT:
	case IEEE80211_AMPDU_TX_STOP_FLUSH:
	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
L
Levi, Shahar 已提交
5437 5438 5439 5440 5441 5442 5443 5444 5445
	case IEEE80211_AMPDU_TX_OPERATIONAL:
		ret = -EINVAL;
		break;

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

5446 5447
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
L
Levi, Shahar 已提交
5448 5449 5450 5451 5452 5453 5454

out:
	mutex_unlock(&wl->mutex);

	return ret;
}

5455 5456 5457 5458
static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   const struct cfg80211_bitrate_mask *mask)
{
5459
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
5460
	struct wl1271 *wl = hw->priv;
5461
	int i, ret = 0;
5462 5463 5464 5465 5466 5467 5468

	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);

5469
	for (i = 0; i < WLCORE_NUM_BANDS; i++)
5470
		wlvif->bitrate_masks[i] =
5471 5472 5473
			wl1271_tx_enabled_rates_get(wl,
						    mask->control[i].legacy,
						    i);
5474

5475
	if (unlikely(wl->state != WLCORE_STATE_ON))
5476 5477 5478 5479 5480
		goto out;

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

5481 5482 5483
		ret = pm_runtime_get_sync(wl->dev);
		if (ret < 0) {
			pm_runtime_put_noidle(wl->dev);
5484
			goto out;
5485
		}
5486 5487 5488 5489 5490 5491

		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);

5492 5493
		pm_runtime_mark_last_busy(wl->dev);
		pm_runtime_put_autosuspend(wl->dev);
5494 5495
	}
out:
5496 5497
	mutex_unlock(&wl->mutex);

5498
	return ret;
5499 5500
}

5501
static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
5502
				     struct ieee80211_vif *vif,
5503 5504 5505
				     struct ieee80211_channel_switch *ch_switch)
{
	struct wl1271 *wl = hw->priv;
5506
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
5507 5508 5509 5510
	int ret;

	wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch");

5511 5512
	wl1271_tx_flush(wl);

5513 5514
	mutex_lock(&wl->mutex);

5515
	if (unlikely(wl->state == WLCORE_STATE_OFF)) {
5516
		if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
5517 5518
			ieee80211_chswitch_done(vif, false);
		goto out;
5519 5520
	} else if (unlikely(wl->state != WLCORE_STATE_ON)) {
		goto out;
5521 5522
	}

5523 5524 5525
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
5526
		goto out;
5527
	}
5528

5529
	/* TODO: change mac80211 to pass vif as param */
5530

5531 5532
	if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
		unsigned long delay_usec;
5533

5534
		ret = wl->ops->channel_switch(wl, wlvif, ch_switch);
5535 5536
		if (ret)
			goto out_sleep;
5537

5538 5539 5540 5541
		set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);

		/* indicate failure 5 seconds after channel switch time */
		delay_usec = ieee80211_tu_to_usec(wlvif->beacon_int) *
5542
			ch_switch->count;
5543
		ieee80211_queue_delayed_work(hw, &wlvif->channel_switch_work,
5544 5545
					     usecs_to_jiffies(delay_usec) +
					     msecs_to_jiffies(5000));
5546
	}
5547

5548
out_sleep:
5549 5550
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
5551 5552 5553 5554 5555

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

E
Eliad Peller 已提交
5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616
static const void *wlcore_get_beacon_ie(struct wl1271 *wl,
					struct wl12xx_vif *wlvif,
					u8 eid)
{
	int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
	struct sk_buff *beacon =
		ieee80211_beacon_get(wl->hw, wl12xx_wlvif_to_vif(wlvif));

	if (!beacon)
		return NULL;

	return cfg80211_find_ie(eid,
				beacon->data + ieoffset,
				beacon->len - ieoffset);
}

static int wlcore_get_csa_count(struct wl1271 *wl, struct wl12xx_vif *wlvif,
				u8 *csa_count)
{
	const u8 *ie;
	const struct ieee80211_channel_sw_ie *ie_csa;

	ie = wlcore_get_beacon_ie(wl, wlvif, WLAN_EID_CHANNEL_SWITCH);
	if (!ie)
		return -EINVAL;

	ie_csa = (struct ieee80211_channel_sw_ie *)&ie[2];
	*csa_count = ie_csa->count;

	return 0;
}

static void wlcore_op_channel_switch_beacon(struct ieee80211_hw *hw,
					    struct ieee80211_vif *vif,
					    struct cfg80211_chan_def *chandef)
{
	struct wl1271 *wl = hw->priv;
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
	struct ieee80211_channel_switch ch_switch = {
		.block_tx = true,
		.chandef = *chandef,
	};
	int ret;

	wl1271_debug(DEBUG_MAC80211,
		     "mac80211 channel switch beacon (role %d)",
		     wlvif->role_id);

	ret = wlcore_get_csa_count(wl, wlvif, &ch_switch.count);
	if (ret < 0) {
		wl1271_error("error getting beacon (for CSA counter)");
		return;
	}

	mutex_lock(&wl->mutex);

	if (unlikely(wl->state != WLCORE_STATE_ON)) {
		ret = -EBUSY;
		goto out;
	}

5617 5618 5619
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
E
Eliad Peller 已提交
5620
		goto out;
5621
	}
E
Eliad Peller 已提交
5622 5623 5624 5625 5626 5627 5628 5629

	ret = wl->ops->channel_switch(wl, wlvif, &ch_switch);
	if (ret)
		goto out_sleep;

	set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);

out_sleep:
5630 5631
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
E
Eliad Peller 已提交
5632 5633 5634 5635
out:
	mutex_unlock(&wl->mutex);
}

5636 5637
static void wlcore_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
			    u32 queues, bool drop)
E
Eliad Peller 已提交
5638 5639 5640 5641 5642 5643
{
	struct wl1271 *wl = hw->priv;

	wl1271_tx_flush(wl);
}

5644 5645 5646
static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw,
				       struct ieee80211_vif *vif,
				       struct ieee80211_channel *chan,
5647 5648
				       int duration,
				       enum ieee80211_roc_type type)
5649 5650 5651
{
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
	struct wl1271 *wl = hw->priv;
5652
	int channel, active_roc, ret = 0;
5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664

	channel = ieee80211_frequency_to_channel(chan->center_freq);

	wl1271_debug(DEBUG_MAC80211, "mac80211 roc %d (%d)",
		     channel, wlvif->role_id);

	mutex_lock(&wl->mutex);

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

	/* return EBUSY if we can't ROC right now */
5665 5666 5667
	active_roc = find_first_bit(wl->roc_map, WL12XX_MAX_ROLES);
	if (wl->roc_vif || active_roc < WL12XX_MAX_ROLES) {
		wl1271_warning("active roc on role %d", active_roc);
5668 5669 5670 5671
		ret = -EBUSY;
		goto out;
	}

5672 5673 5674
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
5675
		goto out;
5676
	}
5677 5678 5679 5680 5681 5682 5683 5684 5685

	ret = wl12xx_start_dev(wl, wlvif, chan->band, channel);
	if (ret < 0)
		goto out_sleep;

	wl->roc_vif = vif;
	ieee80211_queue_delayed_work(hw, &wl->roc_complete_work,
				     msecs_to_jiffies(duration));
out_sleep:
5686 5687
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728
out:
	mutex_unlock(&wl->mutex);
	return ret;
}

static int __wlcore_roc_completed(struct wl1271 *wl)
{
	struct wl12xx_vif *wlvif;
	int ret;

	/* already completed */
	if (unlikely(!wl->roc_vif))
		return 0;

	wlvif = wl12xx_vif_to_data(wl->roc_vif);

	if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))
		return -EBUSY;

	ret = wl12xx_stop_dev(wl, wlvif);
	if (ret < 0)
		return ret;

	wl->roc_vif = NULL;

	return 0;
}

static int wlcore_roc_completed(struct wl1271 *wl)
{
	int ret;

	wl1271_debug(DEBUG_MAC80211, "roc complete");

	mutex_lock(&wl->mutex);

	if (unlikely(wl->state != WLCORE_STATE_ON)) {
		ret = -EBUSY;
		goto out;
	}

5729 5730 5731
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
5732
		goto out;
5733
	}
5734 5735 5736

	ret = __wlcore_roc_completed(wl);

5737 5738
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750
out:
	mutex_unlock(&wl->mutex);

	return ret;
}

static void wlcore_roc_complete_work(struct work_struct *work)
{
	struct delayed_work *dwork;
	struct wl1271 *wl;
	int ret;

G
Geliang Tang 已提交
5751
	dwork = to_delayed_work(work);
5752 5753 5754 5755 5756 5757 5758
	wl = container_of(dwork, struct wl1271, roc_complete_work);

	ret = wlcore_roc_completed(wl);
	if (!ret)
		ieee80211_remain_on_channel_expired(wl->hw);
}

5759 5760
static int wlcore_op_cancel_remain_on_channel(struct ieee80211_hw *hw,
					      struct ieee80211_vif *vif)
5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778
{
	struct wl1271 *wl = hw->priv;

	wl1271_debug(DEBUG_MAC80211, "mac80211 croc");

	/* TODO: per-vif */
	wl1271_tx_flush(wl);

	/*
	 * we can't just flush_work here, because it might deadlock
	 * (as we might get called from the same workqueue)
	 */
	cancel_delayed_work_sync(&wl->roc_complete_work);
	wlcore_roc_completed(wl);

	return 0;
}

5779 5780 5781 5782 5783 5784 5785
static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
				    struct ieee80211_vif *vif,
				    struct ieee80211_sta *sta,
				    u32 changed)
{
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);

5786 5787 5788 5789 5790 5791 5792
	wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update");

	if (!(changed & IEEE80211_RC_BW_CHANGED))
		return;

	/* this callback is atomic, so schedule a new work */
	wlvif->rc_update_bw = sta->bandwidth;
5793
	memcpy(&wlvif->rc_ht_cap, &sta->ht_cap, sizeof(sta->ht_cap));
5794
	ieee80211_queue_work(hw, &wlvif->rc_update_work);
5795 5796
}

5797 5798 5799 5800
static void wlcore_op_sta_statistics(struct ieee80211_hw *hw,
				     struct ieee80211_vif *vif,
				     struct ieee80211_sta *sta,
				     struct station_info *sinfo)
5801 5802 5803
{
	struct wl1271 *wl = hw->priv;
	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
5804 5805
	s8 rssi_dbm;
	int ret;
5806 5807 5808 5809 5810 5811 5812 5813

	wl1271_debug(DEBUG_MAC80211, "mac80211 get_rssi");

	mutex_lock(&wl->mutex);

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

5814 5815 5816
	ret = pm_runtime_get_sync(wl->dev);
	if (ret < 0) {
		pm_runtime_put_noidle(wl->dev);
5817
		goto out_sleep;
5818
	}
5819

5820
	ret = wlcore_acx_average_rssi(wl, wlvif, &rssi_dbm);
5821 5822 5823
	if (ret < 0)
		goto out_sleep;

5824
	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
5825 5826
	sinfo->signal = rssi_dbm;

5827
out_sleep:
5828 5829
	pm_runtime_mark_last_busy(wl->dev);
	pm_runtime_put_autosuspend(wl->dev);
5830 5831 5832 5833 5834

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

5835 5836
static u32 wlcore_op_get_expected_throughput(struct ieee80211_hw *hw,
					     struct ieee80211_sta *sta)
5837 5838
{
	struct wl1271_station *wl_sta = (struct wl1271_station *)sta->drv_priv;
5839
	struct wl1271 *wl = hw->priv;
5840 5841 5842 5843 5844 5845
	u8 hlid = wl_sta->hlid;

	/* return in units of Kbps */
	return (wl->links[hlid].fw_rate_mbps * 1000);
}

5846 5847 5848 5849 5850 5851 5852
static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
{
	struct wl1271 *wl = hw->priv;
	bool ret = false;

	mutex_lock(&wl->mutex);

5853
	if (unlikely(wl->state != WLCORE_STATE_ON))
5854 5855 5856
		goto out;

	/* packets are considered pending if in the TX queue or the FW */
5857
	ret = (wl1271_tx_total_queue_count(wl) > 0) || (wl->tx_frames_cnt > 0);
5858 5859 5860 5861 5862 5863
out:
	mutex_unlock(&wl->mutex);

	return ret;
}

L
Luciano Coelho 已提交
5864 5865 5866
/* can't be const, mac80211 writes to this */
static struct ieee80211_rate wl1271_rates[] = {
	{ .bitrate = 10,
5867 5868
	  .hw_value = CONF_HW_BIT_RATE_1MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_1MBPS, },
L
Luciano Coelho 已提交
5869
	{ .bitrate = 20,
5870 5871
	  .hw_value = CONF_HW_BIT_RATE_2MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_2MBPS,
L
Luciano Coelho 已提交
5872 5873
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 55,
5874 5875
	  .hw_value = CONF_HW_BIT_RATE_5_5MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_5_5MBPS,
L
Luciano Coelho 已提交
5876 5877
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 110,
5878 5879
	  .hw_value = CONF_HW_BIT_RATE_11MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_11MBPS,
L
Luciano Coelho 已提交
5880 5881
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 60,
5882 5883
	  .hw_value = CONF_HW_BIT_RATE_6MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_6MBPS, },
L
Luciano Coelho 已提交
5884
	{ .bitrate = 90,
5885 5886
	  .hw_value = CONF_HW_BIT_RATE_9MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_9MBPS, },
L
Luciano Coelho 已提交
5887
	{ .bitrate = 120,
5888 5889
	  .hw_value = CONF_HW_BIT_RATE_12MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_12MBPS, },
L
Luciano Coelho 已提交
5890
	{ .bitrate = 180,
5891 5892
	  .hw_value = CONF_HW_BIT_RATE_18MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_18MBPS, },
L
Luciano Coelho 已提交
5893
	{ .bitrate = 240,
5894 5895
	  .hw_value = CONF_HW_BIT_RATE_24MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_24MBPS, },
L
Luciano Coelho 已提交
5896
	{ .bitrate = 360,
5897 5898
	 .hw_value = CONF_HW_BIT_RATE_36MBPS,
	 .hw_value_short = CONF_HW_BIT_RATE_36MBPS, },
L
Luciano Coelho 已提交
5899
	{ .bitrate = 480,
5900 5901
	  .hw_value = CONF_HW_BIT_RATE_48MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_48MBPS, },
L
Luciano Coelho 已提交
5902
	{ .bitrate = 540,
5903 5904
	  .hw_value = CONF_HW_BIT_RATE_54MBPS,
	  .hw_value_short = CONF_HW_BIT_RATE_54MBPS, },
L
Luciano Coelho 已提交
5905 5906
};

5907
/* can't be const, mac80211 writes to this */
L
Luciano Coelho 已提交
5908
static struct ieee80211_channel wl1271_channels[] = {
5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922
	{ .hw_value = 1, .center_freq = 2412, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 2, .center_freq = 2417, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 3, .center_freq = 2422, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 4, .center_freq = 2427, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 5, .center_freq = 2432, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 6, .center_freq = 2437, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 7, .center_freq = 2442, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 8, .center_freq = 2447, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 9, .center_freq = 2452, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 10, .center_freq = 2457, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 11, .center_freq = 2462, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 12, .center_freq = 2467, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 13, .center_freq = 2472, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 14, .center_freq = 2484, .max_power = WLCORE_MAX_TXPWR },
L
Luciano Coelho 已提交
5923 5924 5925 5926 5927 5928 5929 5930 5931 5932
};

/* 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),
};

5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960
/* 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, },
};

5961
/* 5 GHz band channels for WL1273 */
5962
static struct ieee80211_channel wl1271_channels_5ghz[] = {
5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993
	{ .hw_value = 8, .center_freq = 5040, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 12, .center_freq = 5060, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 16, .center_freq = 5080, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 34, .center_freq = 5170, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 36, .center_freq = 5180, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 38, .center_freq = 5190, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 40, .center_freq = 5200, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 42, .center_freq = 5210, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 44, .center_freq = 5220, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 46, .center_freq = 5230, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 48, .center_freq = 5240, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 52, .center_freq = 5260, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 56, .center_freq = 5280, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 60, .center_freq = 5300, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 64, .center_freq = 5320, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 100, .center_freq = 5500, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 104, .center_freq = 5520, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 108, .center_freq = 5540, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 112, .center_freq = 5560, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 116, .center_freq = 5580, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 120, .center_freq = 5600, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 124, .center_freq = 5620, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 128, .center_freq = 5640, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 132, .center_freq = 5660, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 136, .center_freq = 5680, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 140, .center_freq = 5700, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 149, .center_freq = 5745, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 153, .center_freq = 5765, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 157, .center_freq = 5785, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 161, .center_freq = 5805, .max_power = WLCORE_MAX_TXPWR },
	{ .hw_value = 165, .center_freq = 5825, .max_power = WLCORE_MAX_TXPWR },
5994 5995 5996 5997 5998 5999 6000
};

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),
6001 6002
};

L
Luciano Coelho 已提交
6003 6004
static const struct ieee80211_ops wl1271_ops = {
	.start = wl1271_op_start,
6005
	.stop = wlcore_op_stop,
L
Luciano Coelho 已提交
6006 6007
	.add_interface = wl1271_op_add_interface,
	.remove_interface = wl1271_op_remove_interface,
E
Eliad Peller 已提交
6008
	.change_interface = wl12xx_op_change_interface,
6009
#ifdef CONFIG_PM
6010 6011
	.suspend = wl1271_op_suspend,
	.resume = wl1271_op_resume,
6012
#endif
L
Luciano Coelho 已提交
6013
	.config = wl1271_op_config,
6014
	.prepare_multicast = wl1271_op_prepare_multicast,
L
Luciano Coelho 已提交
6015 6016
	.configure_filter = wl1271_op_configure_filter,
	.tx = wl1271_op_tx,
6017
	.set_key = wlcore_op_set_key,
L
Luciano Coelho 已提交
6018
	.hw_scan = wl1271_op_hw_scan,
6019
	.cancel_hw_scan = wl1271_op_cancel_hw_scan,
6020 6021
	.sched_scan_start = wl1271_op_sched_scan_start,
	.sched_scan_stop = wl1271_op_sched_scan_stop,
L
Luciano Coelho 已提交
6022
	.bss_info_changed = wl1271_op_bss_info_changed,
6023
	.set_frag_threshold = wl1271_op_set_frag_threshold,
L
Luciano Coelho 已提交
6024
	.set_rts_threshold = wl1271_op_set_rts_threshold,
K
Kalle Valo 已提交
6025
	.conf_tx = wl1271_op_conf_tx,
J
Juuso Oikarinen 已提交
6026
	.get_tsf = wl1271_op_get_tsf,
6027
	.get_survey = wl1271_op_get_survey,
6028
	.sta_state = wl12xx_op_sta_state,
L
Levi, Shahar 已提交
6029
	.ampdu_action = wl1271_op_ampdu_action,
6030
	.tx_frames_pending = wl1271_tx_frames_pending,
6031
	.set_bitrate_mask = wl12xx_set_bitrate_mask,
6032
	.set_default_unicast_key = wl1271_op_set_default_key_idx,
6033
	.channel_switch = wl12xx_op_channel_switch,
E
Eliad Peller 已提交
6034
	.channel_switch_beacon = wlcore_op_channel_switch_beacon,
E
Eliad Peller 已提交
6035
	.flush = wlcore_op_flush,
6036 6037
	.remain_on_channel = wlcore_op_remain_on_channel,
	.cancel_remain_on_channel = wlcore_op_cancel_remain_on_channel,
E
Eliad Peller 已提交
6038 6039 6040 6041 6042
	.add_chanctx = wlcore_op_add_chanctx,
	.remove_chanctx = wlcore_op_remove_chanctx,
	.change_chanctx = wlcore_op_change_chanctx,
	.assign_vif_chanctx = wlcore_op_assign_vif_chanctx,
	.unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx,
6043
	.switch_vif_chanctx = wlcore_op_switch_vif_chanctx,
6044
	.sta_rc_update = wlcore_op_sta_rc_update,
6045
	.sta_statistics = wlcore_op_sta_statistics,
6046
	.get_expected_throughput = wlcore_op_get_expected_throughput,
K
Kalle Valo 已提交
6047
	CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
L
Luciano Coelho 已提交
6048 6049
};

6050

6051
u8 wlcore_rate_to_idx(struct wl1271 *wl, u8 rate, enum nl80211_band band)
6052 6053 6054
{
	u8 idx;

6055
	BUG_ON(band >= 2);
6056

6057
	if (unlikely(rate >= wl->hw_tx_rate_tbl_size)) {
6058 6059 6060 6061
		wl1271_error("Illegal RX rate from HW: %d", rate);
		return 0;
	}

6062
	idx = wl->band_rate_to_idx[band][rate];
6063 6064 6065 6066 6067 6068 6069 6070
	if (unlikely(idx == CONF_HW_RXTX_RATE_UNSUPPORTED)) {
		wl1271_error("Unsupported RX rate from HW: %d", rate);
		return 0;
	}

	return idx;
}

6071
static void wl12xx_derive_mac_addresses(struct wl1271 *wl, u32 oui, u32 nic)
6072 6073 6074
{
	int i;

6075 6076
	wl1271_debug(DEBUG_PROBE, "base address: oui %06x nic %06x",
		     oui, nic);
6077

6078
	if (nic + WLCORE_NUM_MAC_ADDRESSES - wl->num_mac_addr > 0xffffff)
6079 6080
		wl1271_warning("NIC part of the MAC address wraps around!");

6081
	for (i = 0; i < wl->num_mac_addr; i++) {
6082 6083 6084 6085 6086 6087 6088 6089 6090
		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++;
	}

6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102
	/* we may be one address short at the most */
	WARN_ON(wl->num_mac_addr + 1 < WLCORE_NUM_MAC_ADDRESSES);

	/*
	 * turn on the LAA bit in the first address and use it as
	 * the last address.
	 */
	if (wl->num_mac_addr < WLCORE_NUM_MAC_ADDRESSES) {
		int idx = WLCORE_NUM_MAC_ADDRESSES - 1;
		memcpy(&wl->addresses[idx], &wl->addresses[0],
		       sizeof(wl->addresses[0]));
		/* LAA bit */
E
Eliad Peller 已提交
6103
		wl->addresses[idx].addr[0] |= BIT(1);
6104 6105 6106
	}

	wl->hw->wiphy->n_addresses = WLCORE_NUM_MAC_ADDRESSES;
6107 6108 6109
	wl->hw->wiphy->addresses = wl->addresses;
}

6110 6111 6112 6113
static int wl12xx_get_hw_info(struct wl1271 *wl)
{
	int ret;

6114 6115 6116
	ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &wl->chip.id);
	if (ret < 0)
		goto out;
6117

6118 6119
	wl->fuse_oui_addr = 0;
	wl->fuse_nic_addr = 0;
6120

6121 6122 6123
	ret = wl->ops->get_pg_ver(wl, &wl->hw_pg_ver);
	if (ret < 0)
		goto out;
6124

6125
	if (wl->ops->get_mac)
6126
		ret = wl->ops->get_mac(wl);
6127

6128 6129 6130 6131
out:
	return ret;
}

F
Felipe Balbi 已提交
6132
static int wl1271_register_hw(struct wl1271 *wl)
L
Luciano Coelho 已提交
6133 6134
{
	int ret;
6135
	u32 oui_addr = 0, nic_addr = 0;
6136 6137
	struct platform_device *pdev = wl->pdev;
	struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
L
Luciano Coelho 已提交
6138 6139 6140 6141

	if (wl->mac80211_registered)
		return 0;

6142
	if (wl->nvs_len >= 12) {
6143 6144 6145 6146 6147
		/* 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;
6148

6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159
		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;
6160 6161
	}

6162
	if (oui_addr == 0xdeadbe && nic_addr == 0xef0000) {
6163
		wl1271_warning("Detected unconfigured mac address in nvs, derive from fuse instead.");
6164
		if (!strcmp(pdev_data->family->name, "wl18xx")) {
6165
			wl1271_warning("This default nvs file can be removed from the file system");
6166
		} else {
6167 6168
			wl1271_warning("Your device performance is not optimized.");
			wl1271_warning("Please use the calibrator tool to configure your device.");
6169 6170 6171
		}

		if (wl->fuse_oui_addr == 0 && wl->fuse_nic_addr == 0) {
6172
			wl1271_warning("Fuse mac address is zero. using random mac");
6173 6174 6175 6176 6177 6178 6179 6180 6181 6182
			/* Use TI oui and a random nic */
			oui_addr = WLCORE_TI_OUI_ADDRESS;
			nic_addr = get_random_int();
		} else {
			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;
		}
	}

6183
	wl12xx_derive_mac_addresses(wl, oui_addr, nic_addr);
L
Luciano Coelho 已提交
6184 6185 6186 6187

	ret = ieee80211_register_hw(wl->hw);
	if (ret < 0) {
		wl1271_error("unable to register mac80211 hw: %d", ret);
6188
		goto out;
L
Luciano Coelho 已提交
6189 6190 6191 6192
	}

	wl->mac80211_registered = true;

6193 6194
	wl1271_debugfs_init(wl);

L
Luciano Coelho 已提交
6195 6196
	wl1271_notice("loaded");

6197 6198
out:
	return ret;
L
Luciano Coelho 已提交
6199 6200
}

F
Felipe Balbi 已提交
6201
static void wl1271_unregister_hw(struct wl1271 *wl)
6202
{
6203
	if (wl->plt)
6204
		wl1271_plt_stop(wl);
6205

6206 6207 6208 6209 6210
	ieee80211_unregister_hw(wl->hw);
	wl->mac80211_registered = false;

}

F
Felipe Balbi 已提交
6211
static int wl1271_init_ieee80211(struct wl1271 *wl)
L
Luciano Coelho 已提交
6212
{
6213
	int i;
6214 6215 6216 6217 6218 6219
	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,
6220
		WLAN_CIPHER_SUITE_AES_CMAC,
6221 6222
	};

6223 6224 6225 6226 6227
	/* The tx descriptor buffer */
	wl->hw->extra_tx_headroom = sizeof(struct wl1271_tx_hw_descr);

	if (wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE)
		wl->hw->extra_tx_headroom += WL1271_EXTRA_SPACE_TKIP;
L
Luciano Coelho 已提交
6228 6229 6230

	/* unit us */
	/* FIXME: find a proper value */
6231
	wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval;
L
Luciano Coelho 已提交
6232

6233 6234
	ieee80211_hw_set(wl->hw, SUPPORT_FAST_XMIT);
	ieee80211_hw_set(wl->hw, CHANCTX_STA_CSA);
6235
	ieee80211_hw_set(wl->hw, SUPPORTS_PER_STA_GTK);
6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246
	ieee80211_hw_set(wl->hw, QUEUE_CONTROL);
	ieee80211_hw_set(wl->hw, TX_AMPDU_SETUP_IN_HW);
	ieee80211_hw_set(wl->hw, AMPDU_AGGREGATION);
	ieee80211_hw_set(wl->hw, AP_LINK_PS);
	ieee80211_hw_set(wl->hw, SPECTRUM_MGMT);
	ieee80211_hw_set(wl->hw, REPORTS_TX_ACK_STATUS);
	ieee80211_hw_set(wl->hw, CONNECTION_MONITOR);
	ieee80211_hw_set(wl->hw, HAS_RATE_CONTROL);
	ieee80211_hw_set(wl->hw, SUPPORTS_DYNAMIC_PS);
	ieee80211_hw_set(wl->hw, SIGNAL_DBM);
	ieee80211_hw_set(wl->hw, SUPPORTS_PS);
6247
	ieee80211_hw_set(wl->hw, SUPPORTS_TX_FRAG);
L
Luciano Coelho 已提交
6248

6249 6250 6251
	wl->hw->wiphy->cipher_suites = cipher_suites;
	wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);

6252
	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
E
Eliad Peller 已提交
6253 6254 6255
					 BIT(NL80211_IFTYPE_AP) |
					 BIT(NL80211_IFTYPE_P2P_DEVICE) |
					 BIT(NL80211_IFTYPE_P2P_CLIENT) |
6256 6257 6258
#ifdef CONFIG_MAC80211_MESH
					 BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
E
Eliad Peller 已提交
6259
					 BIT(NL80211_IFTYPE_P2P_GO);
6260

L
Luciano Coelho 已提交
6261
	wl->hw->wiphy->max_scan_ssids = 1;
6262 6263
	wl->hw->wiphy->max_sched_scan_ssids = 16;
	wl->hw->wiphy->max_match_sets = 16;
6264 6265 6266 6267 6268
	/*
	 * 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
	 */
6269
	wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
6270
			sizeof(struct ieee80211_header);
6271

6272
	wl->hw->wiphy->max_sched_scan_reqs = 1;
6273
	wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
6274 6275
		sizeof(struct ieee80211_header);

6276
	wl->hw->wiphy->max_remain_on_channel_duration = 30000;
6277

6278
	wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD |
6279
				WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
6280
				WIPHY_FLAG_HAS_CHANNEL_SWITCH |
J
Johannes Berg 已提交
6281
				WIPHY_FLAG_IBSS_RSN;
6282

J
James Minor 已提交
6283 6284
	wl->hw->wiphy->features |= NL80211_FEATURE_AP_SCAN;

6285 6286 6287 6288
	/* 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);
6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304
	/*
	* clear channel flags from the previous usage
	* and restore max_power & max_antenna_gain values.
	*/
	for (i = 0; i < ARRAY_SIZE(wl1271_channels); i++) {
		wl1271_band_2ghz.channels[i].flags = 0;
		wl1271_band_2ghz.channels[i].max_power = WLCORE_MAX_TXPWR;
		wl1271_band_2ghz.channels[i].max_antenna_gain = 0;
	}

	for (i = 0; i < ARRAY_SIZE(wl1271_channels_5ghz); i++) {
		wl1271_band_5ghz.channels[i].flags = 0;
		wl1271_band_5ghz.channels[i].max_power = WLCORE_MAX_TXPWR;
		wl1271_band_5ghz.channels[i].max_antenna_gain = 0;
	}

6305 6306 6307 6308
	/*
	 * We keep local copies of the band structs because we need to
	 * modify them on a per-device basis.
	 */
6309
	memcpy(&wl->bands[NL80211_BAND_2GHZ], &wl1271_band_2ghz,
6310
	       sizeof(wl1271_band_2ghz));
6311 6312
	memcpy(&wl->bands[NL80211_BAND_2GHZ].ht_cap,
	       &wl->ht_cap[NL80211_BAND_2GHZ],
E
Eliad Peller 已提交
6313
	       sizeof(*wl->ht_cap));
6314
	memcpy(&wl->bands[NL80211_BAND_5GHZ], &wl1271_band_5ghz,
6315
	       sizeof(wl1271_band_5ghz));
6316 6317
	memcpy(&wl->bands[NL80211_BAND_5GHZ].ht_cap,
	       &wl->ht_cap[NL80211_BAND_5GHZ],
E
Eliad Peller 已提交
6318
	       sizeof(*wl->ht_cap));
6319

6320 6321 6322 6323
	wl->hw->wiphy->bands[NL80211_BAND_2GHZ] =
		&wl->bands[NL80211_BAND_2GHZ];
	wl->hw->wiphy->bands[NL80211_BAND_5GHZ] =
		&wl->bands[NL80211_BAND_5GHZ];
6324

6325 6326 6327 6328 6329 6330 6331 6332
	/*
	 * allow 4 queues per mac address we support +
	 * 1 cab queue per mac + one global offchannel Tx queue
	 */
	wl->hw->queues = (NUM_TX_QUEUES + 1) * WLCORE_NUM_MAC_ADDRESSES + 1;

	/* the last queue is the offchannel queue */
	wl->hw->offchannel_tx_hw_queue = wl->hw->queues - 1;
J
Juuso Oikarinen 已提交
6333
	wl->hw->max_rates = 1;
K
Kalle Valo 已提交
6334

6335 6336
	wl->hw->wiphy->reg_notifier = wl1271_reg_notify;

6337 6338 6339 6340 6341 6342 6343
	/* 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;

6344
	/* allowed interface combinations */
6345 6346
	wl->hw->wiphy->iface_combinations = wl->iface_combinations;
	wl->hw->wiphy->n_iface_combinations = wl->n_iface_combinations;
6347

E
Eliad Peller 已提交
6348 6349 6350
	/* register vendor commands */
	wlcore_set_vendor_commands(wl->hw->wiphy);

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

6353
	wl->hw->sta_data_size = sizeof(struct wl1271_station);
E
Eliad Peller 已提交
6354
	wl->hw->vif_data_size = sizeof(struct wl12xx_vif);
6355

6356
	wl->hw->max_rx_aggregation_subframes = wl->conf.ht.rx_ba_win_size;
6357

L
Luciano Coelho 已提交
6358 6359 6360
	return 0;
}

6361 6362
struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size,
				     u32 mbox_size)
L
Luciano Coelho 已提交
6363 6364 6365
{
	struct ieee80211_hw *hw;
	struct wl1271 *wl;
6366
	int i, j, ret;
6367
	unsigned int order;
L
Luciano Coelho 已提交
6368 6369 6370 6371

	hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
	if (!hw) {
		wl1271_error("could not alloc ieee80211_hw");
6372
		ret = -ENOMEM;
6373 6374 6375
		goto err_hw_alloc;
	}

L
Luciano Coelho 已提交
6376 6377 6378
	wl = hw->priv;
	memset(wl, 0, sizeof(*wl));

6379 6380 6381 6382 6383 6384 6385
	wl->priv = kzalloc(priv_size, GFP_KERNEL);
	if (!wl->priv) {
		wl1271_error("could not alloc wl priv");
		ret = -ENOMEM;
		goto err_priv_alloc;
	}

E
Eliad Peller 已提交
6386
	INIT_LIST_HEAD(&wl->wlvif_list);
6387

L
Luciano Coelho 已提交
6388 6389
	wl->hw = hw;

6390 6391 6392 6393
	/*
	 * wl->num_links is not configured yet, so just use WLCORE_MAX_LINKS.
	 * we don't allocate any additional resource here, so that's fine.
	 */
6394
	for (i = 0; i < NUM_TX_QUEUES; i++)
6395
		for (j = 0; j < WLCORE_MAX_LINKS; j++)
6396 6397
			skb_queue_head_init(&wl->links[j].tx_queue[i]);

6398 6399 6400 6401
	skb_queue_head_init(&wl->deferred_rx_queue);
	skb_queue_head_init(&wl->deferred_tx_queue);

	INIT_WORK(&wl->netstack_work, wl1271_netstack_work);
6402 6403 6404
	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);
6405
	INIT_DELAYED_WORK(&wl->roc_complete_work, wlcore_roc_complete_work);
A
Arik Nemtsov 已提交
6406
	INIT_DELAYED_WORK(&wl->tx_watchdog_work, wl12xx_tx_watchdog_work);
6407

6408 6409 6410 6411 6412 6413
	wl->freezable_wq = create_freezable_workqueue("wl12xx_wq");
	if (!wl->freezable_wq) {
		ret = -ENOMEM;
		goto err_hw;
	}

6414
	wl->channel = 0;
L
Luciano Coelho 已提交
6415 6416
	wl->rx_counter = 0;
	wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
6417
	wl->band = NL80211_BAND_2GHZ;
6418
	wl->channel_type = NL80211_CHAN_NO_HT;
6419
	wl->flags = 0;
6420
	wl->sg_enabled = true;
6421
	wl->sleep_auth = WL1271_PSM_ILLEGAL;
6422
	wl->recovery_count = 0;
6423
	wl->hw_pg_ver = -1;
6424 6425
	wl->ap_ps_map = 0;
	wl->ap_fw_ps_map = 0;
6426
	wl->quirks = 0;
E
Eliad Peller 已提交
6427
	wl->system_hlid = WL12XX_SYSTEM_HLID;
6428
	wl->active_sta_count = 0;
6429
	wl->active_link_count = 0;
6430
	wl->fwlog_size = 0;
L
Luciano Coelho 已提交
6431

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

6435
	memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
6436
	for (i = 0; i < wl->num_tx_desc; i++)
L
Luciano Coelho 已提交
6437 6438 6439 6440
		wl->tx_frames[i] = NULL;

	spin_lock_init(&wl->wl_lock);

6441
	wl->state = WLCORE_STATE_OFF;
6442
	wl->fw_type = WL12XX_FW_TYPE_NONE;
L
Luciano Coelho 已提交
6443
	mutex_init(&wl->mutex);
A
Arik Nemtsov 已提交
6444
	mutex_init(&wl->flush_mutex);
6445
	init_completion(&wl->nvs_loading_complete);
L
Luciano Coelho 已提交
6446

6447
	order = get_order(aggr_buf_size);
6448 6449 6450
	wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
	if (!wl->aggr_buf) {
		ret = -ENOMEM;
6451
		goto err_wq;
6452
	}
6453
	wl->aggr_buf_size = aggr_buf_size;
6454

6455 6456 6457 6458 6459 6460
	wl->dummy_packet = wl12xx_alloc_dummy_packet(wl);
	if (!wl->dummy_packet) {
		ret = -ENOMEM;
		goto err_aggr;
	}

6461 6462 6463 6464 6465 6466 6467
	/* Allocate one page for the FW log */
	wl->fwlog = (u8 *)get_zeroed_page(GFP_KERNEL);
	if (!wl->fwlog) {
		ret = -ENOMEM;
		goto err_dummy_packet;
	}

6468 6469
	wl->mbox_size = mbox_size;
	wl->mbox = kmalloc(wl->mbox_size, GFP_KERNEL | GFP_DMA);
6470 6471 6472 6473 6474
	if (!wl->mbox) {
		ret = -ENOMEM;
		goto err_fwlog;
	}

6475 6476 6477 6478 6479 6480
	wl->buffer_32 = kmalloc(sizeof(*wl->buffer_32), GFP_KERNEL);
	if (!wl->buffer_32) {
		ret = -ENOMEM;
		goto err_mbox;
	}

6481
	return hw;
6482

6483 6484 6485
err_mbox:
	kfree(wl->mbox);

6486 6487 6488
err_fwlog:
	free_page((unsigned long)wl->fwlog);

6489 6490 6491
err_dummy_packet:
	dev_kfree_skb(wl->dummy_packet);

6492 6493 6494
err_aggr:
	free_pages((unsigned long)wl->aggr_buf, order);

6495 6496 6497
err_wq:
	destroy_workqueue(wl->freezable_wq);

6498
err_hw:
6499
	wl1271_debugfs_exit(wl);
6500 6501 6502
	kfree(wl->priv);

err_priv_alloc:
6503 6504 6505
	ieee80211_free_hw(hw);

err_hw_alloc:
6506 6507

	return ERR_PTR(ret);
6508
}
6509
EXPORT_SYMBOL_GPL(wlcore_alloc_hw);
6510

6511
int wlcore_free_hw(struct wl1271 *wl)
6512
{
6513 6514 6515 6516 6517
	/* Unblock any fwlog readers */
	mutex_lock(&wl->mutex);
	wl->fwlog_size = -1;
	mutex_unlock(&wl->mutex);

6518
	wlcore_sysfs_free(wl);
6519

6520
	kfree(wl->buffer_32);
E
Eliad Peller 已提交
6521
	kfree(wl->mbox);
6522
	free_page((unsigned long)wl->fwlog);
6523
	dev_kfree_skb(wl->dummy_packet);
6524
	free_pages((unsigned long)wl->aggr_buf, get_order(wl->aggr_buf_size));
6525 6526 6527 6528 6529

	wl1271_debugfs_exit(wl);

	vfree(wl->fw);
	wl->fw = NULL;
6530
	wl->fw_type = WL12XX_FW_TYPE_NONE;
6531 6532 6533
	kfree(wl->nvs);
	wl->nvs = NULL;

6534 6535
	kfree(wl->raw_fw_status);
	kfree(wl->fw_status);
6536
	kfree(wl->tx_res_if);
6537
	destroy_workqueue(wl->freezable_wq);
6538

6539
	kfree(wl->priv);
6540 6541 6542 6543
	ieee80211_free_hw(wl->hw);

	return 0;
}
6544
EXPORT_SYMBOL_GPL(wlcore_free_hw);
6545

6546 6547 6548 6549 6550 6551 6552 6553 6554
#ifdef CONFIG_PM
static const struct wiphy_wowlan_support wlcore_wowlan_support = {
	.flags = WIPHY_WOWLAN_ANY,
	.n_patterns = WL1271_MAX_RX_FILTERS,
	.pattern_min_len = 1,
	.pattern_max_len = WL1271_RX_FILTER_MAX_PATTERN_SIZE,
};
#endif

6555 6556 6557 6558 6559
static irqreturn_t wlcore_hardirq(int irq, void *cookie)
{
	return IRQ_WAKE_THREAD;
}

6560
static void wlcore_nvs_cb(const struct firmware *fw, void *context)
6561
{
6562 6563
	struct wl1271 *wl = context;
	struct platform_device *pdev = wl->pdev;
6564
	struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
6565 6566
	struct resource *res;

6567
	int ret;
6568
	irq_handler_t hardirq_fn = NULL;
6569

6570 6571 6572 6573 6574 6575 6576
	if (fw) {
		wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL);
		if (!wl->nvs) {
			wl1271_error("Could not allocate nvs data");
			goto out;
		}
		wl->nvs_len = fw->size;
6577
	} else if (pdev_data->family->nvs_name) {
6578
		wl1271_debug(DEBUG_BOOT, "Could not get nvs file %s",
6579 6580 6581 6582
			     pdev_data->family->nvs_name);
		wl->nvs = NULL;
		wl->nvs_len = 0;
	} else {
6583 6584
		wl->nvs = NULL;
		wl->nvs_len = 0;
6585 6586
	}

I
Ido Yariv 已提交
6587 6588
	ret = wl->ops->setup(wl);
	if (ret < 0)
6589
		goto out_free_nvs;
I
Ido Yariv 已提交
6590

6591 6592
	BUG_ON(wl->num_tx_desc > WLCORE_MAX_TX_DESCRIPTORS);

6593 6594 6595
	/* adjust some runtime configuration parameters */
	wlcore_adjust_conf(wl);

6596 6597 6598 6599 6600 6601 6602 6603
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		wl1271_error("Could not get IRQ resource");
		goto out_free_nvs;
	}

	wl->irq = res->start;
	wl->irq_flags = res->flags & IRQF_TRIGGER_MASK;
6604
	wl->if_ops = pdev_data->if_ops;
6605

6606
	if (wl->irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
6607
		hardirq_fn = wlcore_hardirq;
6608 6609
	else
		wl->irq_flags |= IRQF_ONESHOT;
6610

6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621
	ret = wl12xx_set_power_on(wl);
	if (ret < 0)
		goto out_free_nvs;

	ret = wl12xx_get_hw_info(wl);
	if (ret < 0) {
		wl1271_error("couldn't get hw info");
		wl1271_power_off(wl);
		goto out_free_nvs;
	}

6622
	ret = request_threaded_irq(wl->irq, hardirq_fn, wlcore_irq,
6623
				   wl->irq_flags, pdev->name, wl);
6624
	if (ret < 0) {
6625 6626
		wl1271_error("interrupt configuration failed");
		wl1271_power_off(wl);
6627
		goto out_free_nvs;
6628 6629
	}

6630
#ifdef CONFIG_PM
6631 6632
	device_init_wakeup(wl->dev, true);

6633 6634 6635
	ret = enable_irq_wake(wl->irq);
	if (!ret) {
		wl->irq_wake_enabled = true;
6636
		if (pdev_data->pwr_in_suspend)
6637
			wl->hw->wiphy->wowlan = &wlcore_wowlan_support;
6638
	}
6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
	if (res) {
		wl->wakeirq = res->start;
		wl->wakeirq_flags = res->flags & IRQF_TRIGGER_MASK;
		ret = dev_pm_set_dedicated_wake_irq(wl->dev, wl->wakeirq);
		if (ret)
			wl->wakeirq = -ENODEV;
	} else {
		wl->wakeirq = -ENODEV;
	}
6650
#endif
6651
	disable_irq(wl->irq);
6652
	wl1271_power_off(wl);
6653 6654 6655

	ret = wl->ops->identify_chip(wl);
	if (ret < 0)
6656
		goto out_irq;
6657

6658 6659 6660 6661 6662 6663 6664 6665
	ret = wl1271_init_ieee80211(wl);
	if (ret)
		goto out_irq;

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

6666 6667
	ret = wlcore_sysfs_init(wl);
	if (ret)
6668
		goto out_unreg;
F
Felipe Balbi 已提交
6669

6670
	wl->initialized = true;
6671
	goto out;
6672

6673 6674 6675
out_unreg:
	wl1271_unregister_hw(wl);

6676
out_irq:
6677 6678 6679
	if (wl->wakeirq >= 0)
		dev_pm_clear_wake_irq(wl->dev);
	device_init_wakeup(wl->dev, false);
6680 6681
	free_irq(wl->irq, wl);

6682 6683 6684
out_free_nvs:
	kfree(wl->nvs);

6685
out:
6686 6687 6688 6689
	release_firmware(fw);
	complete_all(&wl->nvs_loading_complete);
}

6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730
static int __maybe_unused wlcore_runtime_suspend(struct device *dev)
{
	struct wl1271 *wl = dev_get_drvdata(dev);
	struct wl12xx_vif *wlvif;
	int error;

	/* We do not enter elp sleep in PLT mode */
	if (wl->plt)
		return 0;

	/* Nothing to do if no ELP mode requested */
	if (wl->sleep_auth != WL1271_PSM_ELP)
		return 0;

	wl12xx_for_each_wlvif(wl, wlvif) {
		if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) &&
		    test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
			return -EBUSY;
	}

	wl1271_debug(DEBUG_PSM, "chip to elp");
	error = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP);
	if (error < 0) {
		wl12xx_queue_recovery_work(wl);

		return error;
	}

	set_bit(WL1271_FLAG_IN_ELP, &wl->flags);

	return 0;
}

static int __maybe_unused wlcore_runtime_resume(struct device *dev)
{
	struct wl1271 *wl = dev_get_drvdata(dev);
	DECLARE_COMPLETION_ONSTACK(compl);
	unsigned long flags;
	int ret;
	unsigned long start_time = jiffies;
	bool pending = false;
6731
	bool recovery = false;
6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747

	/* Nothing to do if no ELP mode requested */
	if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags))
		return 0;

	wl1271_debug(DEBUG_PSM, "waking up chip from elp");

	spin_lock_irqsave(&wl->wl_lock, flags);
	if (test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags))
		pending = true;
	else
		wl->elp_compl = &compl;
	spin_unlock_irqrestore(&wl->wl_lock, flags);

	ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
	if (ret < 0) {
6748
		recovery = true;
6749 6750 6751 6752 6753 6754 6755
		goto err;
	}

	if (!pending) {
		ret = wait_for_completion_timeout(&compl,
			msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT));
		if (ret == 0) {
6756
			wl1271_warning("ELP wakeup timeout!");
6757 6758

			/* Return no error for runtime PM for recovery */
6759 6760 6761
			ret = 0;
			recovery = true;
			goto err;
6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775
		}
	}

	clear_bit(WL1271_FLAG_IN_ELP, &wl->flags);

	wl1271_debug(DEBUG_PSM, "wakeup time: %u ms",
		     jiffies_to_msecs(jiffies - start_time));

	return 0;

err:
	spin_lock_irqsave(&wl->wl_lock, flags);
	wl->elp_compl = NULL;
	spin_unlock_irqrestore(&wl->wl_lock, flags);
6776 6777 6778 6779 6780 6781

	if (recovery) {
		set_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags);
		wl12xx_queue_recovery_work(wl);
	}

6782 6783 6784 6785 6786 6787 6788 6789 6790
	return ret;
}

static const struct dev_pm_ops wlcore_pm_ops = {
	SET_RUNTIME_PM_OPS(wlcore_runtime_suspend,
			   wlcore_runtime_resume,
			   NULL)
};

6791
int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
6792
{
6793 6794 6795
	struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
	const char *nvs_name;
	int ret = 0;
6796

6797
	if (!wl->ops || !wl->ptable || !pdev_data)
6798 6799 6800 6801 6802 6803
		return -EINVAL;

	wl->dev = &pdev->dev;
	wl->pdev = pdev;
	platform_set_drvdata(pdev, wl);

6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815
	if (pdev_data->family && pdev_data->family->nvs_name) {
		nvs_name = pdev_data->family->nvs_name;
		ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
					      nvs_name, &pdev->dev, GFP_KERNEL,
					      wl, wlcore_nvs_cb);
		if (ret < 0) {
			wl1271_error("request_firmware_nowait failed for %s: %d",
				     nvs_name, ret);
			complete_all(&wl->nvs_loading_complete);
		}
	} else {
		wlcore_nvs_cb(NULL, wl);
6816 6817
	}

6818
	wl->dev->driver->pm = &wlcore_pm_ops;
6819 6820
	pm_runtime_set_autosuspend_delay(wl->dev, 50);
	pm_runtime_use_autosuspend(wl->dev);
6821 6822
	pm_runtime_enable(wl->dev);

6823
	return ret;
6824
}
6825
EXPORT_SYMBOL_GPL(wlcore_probe);
6826

6827
int wlcore_remove(struct platform_device *pdev)
6828
{
6829
	struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev);
6830
	struct wl1271 *wl = platform_get_drvdata(pdev);
6831 6832 6833 6834 6835 6836 6837
	int error;

	error = pm_runtime_get_sync(wl->dev);
	if (error < 0)
		dev_warn(wl->dev, "PM runtime failed: %i\n", error);

	wl->dev->driver->pm = NULL;
6838

6839 6840
	if (pdev_data->family && pdev_data->family->nvs_name)
		wait_for_completion(&wl->nvs_loading_complete);
6841 6842 6843
	if (!wl->initialized)
		return 0;

6844 6845 6846
	if (wl->wakeirq >= 0) {
		dev_pm_clear_wake_irq(wl->dev);
		wl->wakeirq = -ENODEV;
6847
	}
6848 6849 6850 6851 6852 6853

	device_init_wakeup(wl->dev, false);

	if (wl->irq_wake_enabled)
		disable_irq_wake(wl->irq);

6854
	wl1271_unregister_hw(wl);
6855 6856

	pm_runtime_put_sync(wl->dev);
6857
	pm_runtime_dont_use_autosuspend(wl->dev);
6858 6859
	pm_runtime_disable(wl->dev);

6860
	free_irq(wl->irq, wl);
6861
	wlcore_free_hw(wl);
6862

6863 6864
	return 0;
}
6865
EXPORT_SYMBOL_GPL(wlcore_remove);
6866

6867
u32 wl12xx_debug_level = DEBUG_NONE;
6868
EXPORT_SYMBOL_GPL(wl12xx_debug_level);
6869
module_param_named(debug_level, wl12xx_debug_level, uint, 0600);
6870 6871
MODULE_PARM_DESC(debug_level, "wl12xx debugging level");

6872
module_param_named(fwlog, fwlog_param, charp, 0);
6873
MODULE_PARM_DESC(fwlog,
S
Shahar Patury 已提交
6874
		 "FW logger options: continuous, dbgpins or disable");
6875

6876
module_param(fwlog_mem_blocks, int, 0600);
I
Ido Reis 已提交
6877 6878
MODULE_PARM_DESC(fwlog_mem_blocks, "fwlog mem_blocks");

6879
module_param(bug_on_recovery, int, 0600);
6880 6881
MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery");

6882
module_param(no_recovery, int, 0600);
6883 6884
MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck.");

6885
MODULE_LICENSE("GPL");
6886
MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
6887
MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");