main.c 34.8 KB
Newer Older
K
Kalle Valo 已提交
1
/*
2
 * This file is part of wl1251
K
Kalle Valo 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *
 * Copyright (C) 2008-2009 Nokia Corporation
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/crc32.h>
#include <linux/etherdevice.h>
29
#include <linux/vmalloc.h>
30
#include <linux/slab.h>
31
#include <linux/netdevice.h>
K
Kalle Valo 已提交
32

K
Kalle Valo 已提交
33
#include "wl1251.h"
K
Kalle Valo 已提交
34
#include "wl12xx_80211.h"
K
Kalle Valo 已提交
35 36 37 38 39 40 41 42 43 44
#include "reg.h"
#include "io.h"
#include "cmd.h"
#include "event.h"
#include "tx.h"
#include "rx.h"
#include "ps.h"
#include "init.h"
#include "debugfs.h"
#include "boot.h"
K
Kalle Valo 已提交
45

46
void wl1251_enable_interrupts(struct wl1251 *wl)
K
Kalle Valo 已提交
47
{
48 49 50 51 52 53
	wl->if_ops->enable_irq(wl);
}

void wl1251_disable_interrupts(struct wl1251 *wl)
{
	wl->if_ops->disable_irq(wl);
K
Kalle Valo 已提交
54 55
}

56
static int wl1251_power_off(struct wl1251 *wl)
K
Kalle Valo 已提交
57
{
58
	return wl->if_ops->power(wl, false);
K
Kalle Valo 已提交
59 60
}

61
static int wl1251_power_on(struct wl1251 *wl)
K
Kalle Valo 已提交
62
{
63
	return wl->if_ops->power(wl, true);
K
Kalle Valo 已提交
64 65
}

66
static int wl1251_fetch_firmware(struct wl1251 *wl)
K
Kalle Valo 已提交
67 68
{
	const struct firmware *fw;
69
	struct device *dev = wiphy_dev(wl->hw->wiphy);
K
Kalle Valo 已提交
70 71
	int ret;

K
Kalle Valo 已提交
72
	ret = request_firmware(&fw, WL1251_FW_NAME, dev);
K
Kalle Valo 已提交
73 74

	if (ret < 0) {
75
		wl1251_error("could not get firmware: %d", ret);
K
Kalle Valo 已提交
76 77 78 79
		return ret;
	}

	if (fw->size % 4) {
80
		wl1251_error("firmware size is not multiple of 32 bits: %zu",
K
Kalle Valo 已提交
81 82 83 84 85 86
			     fw->size);
		ret = -EILSEQ;
		goto out;
	}

	wl->fw_len = fw->size;
87
	wl->fw = vmalloc(wl->fw_len);
K
Kalle Valo 已提交
88 89

	if (!wl->fw) {
90
		wl1251_error("could not allocate memory for the firmware");
K
Kalle Valo 已提交
91 92 93 94 95 96 97 98 99 100 101 102 103 104
		ret = -ENOMEM;
		goto out;
	}

	memcpy(wl->fw, fw->data, wl->fw_len);

	ret = 0;

out:
	release_firmware(fw);

	return ret;
}

105
static int wl1251_fetch_nvs(struct wl1251 *wl)
K
Kalle Valo 已提交
106 107
{
	const struct firmware *fw;
108
	struct device *dev = wiphy_dev(wl->hw->wiphy);
K
Kalle Valo 已提交
109 110
	int ret;

K
Kalle Valo 已提交
111
	ret = request_firmware(&fw, WL1251_NVS_NAME, dev);
K
Kalle Valo 已提交
112 113

	if (ret < 0) {
114
		wl1251_error("could not get nvs file: %d", ret);
K
Kalle Valo 已提交
115 116 117 118
		return ret;
	}

	if (fw->size % 4) {
119
		wl1251_error("nvs size is not multiple of 32 bits: %zu",
K
Kalle Valo 已提交
120 121 122 123 124 125
			     fw->size);
		ret = -EILSEQ;
		goto out;
	}

	wl->nvs_len = fw->size;
126
	wl->nvs = kmemdup(fw->data, wl->nvs_len, GFP_KERNEL);
K
Kalle Valo 已提交
127 128

	if (!wl->nvs) {
129
		wl1251_error("could not allocate memory for the nvs file");
K
Kalle Valo 已提交
130 131 132 133 134 135 136 137 138 139 140 141
		ret = -ENOMEM;
		goto out;
	}

	ret = 0;

out:
	release_firmware(fw);

	return ret;
}

142
static void wl1251_fw_wakeup(struct wl1251 *wl)
K
Kalle Valo 已提交
143 144 145 146
{
	u32 elp_reg;

	elp_reg = ELPCTRL_WAKE_UP;
147 148
	wl1251_write_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
	elp_reg = wl1251_read_elp(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
K
Kalle Valo 已提交
149

K
Kalle Valo 已提交
150
	if (!(elp_reg & ELPCTRL_WLAN_READY))
151
		wl1251_warning("WLAN not ready");
K
Kalle Valo 已提交
152 153
}

154
static int wl1251_chip_wakeup(struct wl1251 *wl)
K
Kalle Valo 已提交
155
{
156 157 158 159 160
	int ret;

	ret = wl1251_power_on(wl);
	if (ret < 0)
		return ret;
K
Kalle Valo 已提交
161

K
Kalle Valo 已提交
162
	msleep(WL1251_POWER_ON_SLEEP);
163
	wl->if_ops->reset(wl);
K
Kalle Valo 已提交
164 165 166

	/* We don't need a real memory partition here, because we only want
	 * to use the registers at this point. */
167
	wl1251_set_partition(wl,
K
Kalle Valo 已提交
168 169 170 171 172 173
			     0x00000000,
			     0x00000000,
			     REGISTERS_BASE,
			     REGISTERS_DOWN_SIZE);

	/* ELP module wake up */
174
	wl1251_fw_wakeup(wl);
K
Kalle Valo 已提交
175 176 177 178

	/* whal_FwCtrl_BootSm() */

	/* 0. read chip id from CHIP_ID */
K
Kalle Valo 已提交
179
	wl->chip_id = wl1251_reg_read32(wl, CHIP_ID_B);
K
Kalle Valo 已提交
180 181 182

	/* 1. check if chip id is valid */

K
Kalle Valo 已提交
183
	switch (wl->chip_id) {
K
Kalle Valo 已提交
184
	case CHIP_ID_1251_PG12:
185
		wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)",
K
Kalle Valo 已提交
186
			     wl->chip_id);
K
Kalle Valo 已提交
187 188
		break;
	case CHIP_ID_1251_PG11:
189 190 191
		wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG11)",
			     wl->chip_id);
		break;
J
John W. Linville 已提交
192
	case CHIP_ID_1251_PG10:
K
Kalle Valo 已提交
193
	default:
K
Kalle Valo 已提交
194
		wl1251_error("unsupported chip id: 0x%x", wl->chip_id);
K
Kalle Valo 已提交
195 196 197 198 199
		ret = -ENODEV;
		goto out;
	}

	if (wl->fw == NULL) {
200
		ret = wl1251_fetch_firmware(wl);
K
Kalle Valo 已提交
201 202 203 204
		if (ret < 0)
			goto out;
	}

205 206
	if (wl->nvs == NULL && !wl->use_eeprom) {
		/* No NVS from netlink, try to get it from the filesystem */
207
		ret = wl1251_fetch_nvs(wl);
K
Kalle Valo 已提交
208 209 210 211 212 213 214 215
		if (ret < 0)
			goto out;
	}

out:
	return ret;
}

J
Janne Ylalehto 已提交
216
#define WL1251_IRQ_LOOP_COUNT 10
K
Kalle Valo 已提交
217 218
static void wl1251_irq_work(struct work_struct *work)
{
J
Janne Ylalehto 已提交
219
	u32 intr, ctr = WL1251_IRQ_LOOP_COUNT;
K
Kalle Valo 已提交
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
	struct wl1251 *wl =
		container_of(work, struct wl1251, irq_work);
	int ret;

	mutex_lock(&wl->mutex);

	wl1251_debug(DEBUG_IRQ, "IRQ work");

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

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

	wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1251_ACX_INTR_ALL);

	intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
	wl1251_debug(DEBUG_IRQ, "intr: 0x%x", intr);

J
Janne Ylalehto 已提交
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
	do {
		if (wl->data_path) {
			wl->rx_counter = wl1251_mem_read32(
				wl, wl->data_path->rx_control_addr);

			/* We handle a frmware bug here */
			switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
			case 0:
				wl1251_debug(DEBUG_IRQ,
					     "RX: FW and host in sync");
				intr &= ~WL1251_ACX_INTR_RX0_DATA;
				intr &= ~WL1251_ACX_INTR_RX1_DATA;
				break;
			case 1:
				wl1251_debug(DEBUG_IRQ, "RX: FW +1");
				intr |= WL1251_ACX_INTR_RX0_DATA;
				intr &= ~WL1251_ACX_INTR_RX1_DATA;
				break;
			case 2:
				wl1251_debug(DEBUG_IRQ, "RX: FW +2");
				intr |= WL1251_ACX_INTR_RX0_DATA;
				intr |= WL1251_ACX_INTR_RX1_DATA;
				break;
			default:
				wl1251_warning(
					"RX: FW and host out of sync: %d",
					wl->rx_counter - wl->rx_handled);
				break;
			}

			wl->rx_handled = wl->rx_counter;

			wl1251_debug(DEBUG_IRQ, "RX counter: %d",
				     wl->rx_counter);
K
Kalle Valo 已提交
274 275
		}

J
Janne Ylalehto 已提交
276
		intr &= wl->intr_mask;
K
Kalle Valo 已提交
277

J
Janne Ylalehto 已提交
278 279 280 281
		if (intr == 0) {
			wl1251_debug(DEBUG_IRQ, "INTR is 0");
			goto out_sleep;
		}
K
Kalle Valo 已提交
282

J
Janne Ylalehto 已提交
283 284 285 286
		if (intr & WL1251_ACX_INTR_RX0_DATA) {
			wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
			wl1251_rx(wl);
		}
K
Kalle Valo 已提交
287

J
Janne Ylalehto 已提交
288 289 290 291
		if (intr & WL1251_ACX_INTR_RX1_DATA) {
			wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
			wl1251_rx(wl);
		}
K
Kalle Valo 已提交
292

J
Janne Ylalehto 已提交
293 294 295 296
		if (intr & WL1251_ACX_INTR_TX_RESULT) {
			wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
			wl1251_tx_complete(wl);
		}
K
Kalle Valo 已提交
297

298 299 300 301 302 303 304 305
		if (intr & WL1251_ACX_INTR_EVENT_A) {
			wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_A");
			wl1251_event_handle(wl, 0);
		}

		if (intr & WL1251_ACX_INTR_EVENT_B) {
			wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_B");
			wl1251_event_handle(wl, 1);
J
Janne Ylalehto 已提交
306
		}
K
Kalle Valo 已提交
307

J
Janne Ylalehto 已提交
308 309 310
		if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
			wl1251_debug(DEBUG_IRQ,
				     "WL1251_ACX_INTR_INIT_COMPLETE");
K
Kalle Valo 已提交
311

312 313
		if (--ctr == 0)
			break;
K
Kalle Valo 已提交
314

315 316
		intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
	} while (intr);
K
Kalle Valo 已提交
317 318

out_sleep:
J
Janne Ylalehto 已提交
319
	wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
K
Kalle Valo 已提交
320 321 322 323 324 325
	wl1251_ps_elp_sleep(wl);

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

K
Kalle Valo 已提交
326 327 328 329 330 331 332 333 334 335 336 337
static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel,
		       u16 beacon_interval, u8 dtim_period)
{
	int ret;

	ret = wl1251_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE,
				     DEFAULT_HW_GEN_MODULATION_TYPE,
				     wl->tx_mgmt_frm_rate,
				     wl->tx_mgmt_frm_mod);
	if (ret < 0)
		goto out;

338 339 340 341 342 343
	/*
	 * Join command applies filters, and if we are not associated,
	 * BSSID filter must be disabled for association to work.
	 */
	if (is_zero_ether_addr(wl->bssid))
		wl->rx_config &= ~CFG_BSSID_FILTER_EN;
K
Kalle Valo 已提交
344 345 346 347 348 349

	ret = wl1251_cmd_join(wl, bss_type, channel, beacon_interval,
			      dtim_period);
	if (ret < 0)
		goto out;

350 351 352
	ret = wl1251_event_wait(wl, JOIN_EVENT_COMPLETE_ID, 100);
	if (ret < 0)
		wl1251_warning("join timeout");
K
Kalle Valo 已提交
353 354 355 356 357

out:
	return ret;
}

358 359 360
static void wl1251_op_tx(struct ieee80211_hw *hw,
			 struct ieee80211_tx_control *control,
			 struct sk_buff *skb)
K
Kalle Valo 已提交
361
{
362
	struct wl1251 *wl = hw->priv;
363
	unsigned long flags;
K
Kalle Valo 已提交
364 365 366

	skb_queue_tail(&wl->tx_queue, skb);

367 368 369 370 371
	/*
	 * The chip specific setup must run before the first TX packet -
	 * before that, the tx_work will not be initialized!
	 */

372
	ieee80211_queue_work(wl->hw, &wl->tx_work);
K
Kalle Valo 已提交
373 374 375 376 377

	/*
	 * The workqueue is slow to process the tx_queue and we need stop
	 * the queue here, otherwise the queue will get too long.
	 */
378
	if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_HIGH_WATERMARK) {
379
		wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues");
K
Kalle Valo 已提交
380

381 382
		spin_lock_irqsave(&wl->wl_lock, flags);
		ieee80211_stop_queues(wl->hw);
K
Kalle Valo 已提交
383
		wl->tx_queue_stopped = true;
384
		spin_unlock_irqrestore(&wl->wl_lock, flags);
K
Kalle Valo 已提交
385 386 387
	}
}

388
static int wl1251_op_start(struct ieee80211_hw *hw)
K
Kalle Valo 已提交
389
{
390
	struct wl1251 *wl = hw->priv;
391
	struct wiphy *wiphy = hw->wiphy;
K
Kalle Valo 已提交
392 393
	int ret = 0;

394
	wl1251_debug(DEBUG_MAC80211, "mac80211 start");
K
Kalle Valo 已提交
395 396 397

	mutex_lock(&wl->mutex);

398 399
	if (wl->state != WL1251_STATE_OFF) {
		wl1251_error("cannot start because not in off state: %d",
K
Kalle Valo 已提交
400 401 402 403 404
			     wl->state);
		ret = -EBUSY;
		goto out;
	}

405
	ret = wl1251_chip_wakeup(wl);
K
Kalle Valo 已提交
406
	if (ret < 0)
407
		goto out;
K
Kalle Valo 已提交
408

K
Kalle Valo 已提交
409
	ret = wl1251_boot(wl);
K
Kalle Valo 已提交
410 411 412
	if (ret < 0)
		goto out;

K
Kalle Valo 已提交
413
	ret = wl1251_hw_init(wl);
K
Kalle Valo 已提交
414 415 416
	if (ret < 0)
		goto out;

417
	ret = wl1251_acx_station_id(wl);
K
Kalle Valo 已提交
418 419 420
	if (ret < 0)
		goto out;

421
	wl->state = WL1251_STATE_ON;
K
Kalle Valo 已提交
422

K
Kalle Valo 已提交
423
	wl1251_info("firmware booted (%s)", wl->fw_ver);
K
Kalle Valo 已提交
424

425 426 427 428
	/* update hw/fw version info in wiphy struct */
	wiphy->hw_version = wl->chip_id;
	strncpy(wiphy->fw_version, wl->fw_ver, sizeof(wiphy->fw_version));

K
Kalle Valo 已提交
429 430
out:
	if (ret < 0)
431
		wl1251_power_off(wl);
K
Kalle Valo 已提交
432 433 434 435 436 437

	mutex_unlock(&wl->mutex);

	return ret;
}

438
static void wl1251_op_stop(struct ieee80211_hw *hw)
K
Kalle Valo 已提交
439
{
440
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
441

442
	wl1251_info("down");
K
Kalle Valo 已提交
443

444
	wl1251_debug(DEBUG_MAC80211, "mac80211 stop");
K
Kalle Valo 已提交
445 446 447

	mutex_lock(&wl->mutex);

448
	WARN_ON(wl->state != WL1251_STATE_ON);
K
Kalle Valo 已提交
449 450 451 452 453 454

	if (wl->scanning) {
		ieee80211_scan_completed(wl->hw, true);
		wl->scanning = false;
	}

455
	wl->state = WL1251_STATE_OFF;
K
Kalle Valo 已提交
456

457
	wl1251_disable_interrupts(wl);
K
Kalle Valo 已提交
458 459 460 461 462

	mutex_unlock(&wl->mutex);

	cancel_work_sync(&wl->irq_work);
	cancel_work_sync(&wl->tx_work);
463
	cancel_delayed_work_sync(&wl->elp_work);
K
Kalle Valo 已提交
464 465 466 467

	mutex_lock(&wl->mutex);

	/* let's notify MAC80211 about the remaining pending TX frames */
K
Kalle Valo 已提交
468
	wl1251_tx_flush(wl);
469
	wl1251_power_off(wl);
K
Kalle Valo 已提交
470 471 472 473 474 475 476 477 478 479 480 481

	memset(wl->bssid, 0, ETH_ALEN);
	wl->listen_int = 1;
	wl->bss_type = MAX_BSS_TYPE;

	wl->data_in_count = 0;
	wl->rx_counter = 0;
	wl->rx_handled = 0;
	wl->rx_current_buffer = 0;
	wl->rx_last_id = 0;
	wl->next_tx_complete = 0;
	wl->elp = false;
482
	wl->station_mode = STATION_ACTIVE_MODE;
D
David Gnedt 已提交
483
	wl->psm_entry_retry = 0;
K
Kalle Valo 已提交
484
	wl->tx_queue_stopped = false;
485
	wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
486
	wl->rssi_thold = 0;
487
	wl->channel = WL1251_DEFAULT_CHANNEL;
488
	wl->monitor_present = false;
K
Kalle Valo 已提交
489

490
	wl1251_debugfs_reset(wl);
K
Kalle Valo 已提交
491 492 493 494

	mutex_unlock(&wl->mutex);
}

495
static int wl1251_op_add_interface(struct ieee80211_hw *hw,
496
				   struct ieee80211_vif *vif)
K
Kalle Valo 已提交
497
{
498
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
499 500
	int ret = 0;

501 502
	vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
			     IEEE80211_VIF_SUPPORTS_CQM_RSSI;
503

J
Johannes Berg 已提交
504
	wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
505
		     vif->type, vif->addr);
K
Kalle Valo 已提交
506 507

	mutex_lock(&wl->mutex);
508 509 510 511 512
	if (wl->vif) {
		ret = -EBUSY;
		goto out;
	}

513
	wl->vif = vif;
K
Kalle Valo 已提交
514

515
	switch (vif->type) {
K
Kalle Valo 已提交
516 517 518 519 520 521 522 523 524 525 526
	case NL80211_IFTYPE_STATION:
		wl->bss_type = BSS_TYPE_STA_BSS;
		break;
	case NL80211_IFTYPE_ADHOC:
		wl->bss_type = BSS_TYPE_IBSS;
		break;
	default:
		ret = -EOPNOTSUPP;
		goto out;
	}

527 528
	if (memcmp(wl->mac_addr, vif->addr, ETH_ALEN)) {
		memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
K
Kalle Valo 已提交
529
		SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
530
		ret = wl1251_acx_station_id(wl);
K
Kalle Valo 已提交
531 532 533 534 535 536 537 538 539
		if (ret < 0)
			goto out;
	}

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

540
static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
541
					 struct ieee80211_vif *vif)
K
Kalle Valo 已提交
542
{
543 544 545
	struct wl1251 *wl = hw->priv;

	mutex_lock(&wl->mutex);
546
	wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface");
547 548
	wl->vif = NULL;
	mutex_unlock(&wl->mutex);
K
Kalle Valo 已提交
549 550
}

551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571
static int wl1251_build_qos_null_data(struct wl1251 *wl)
{
	struct ieee80211_qos_hdr template;

	memset(&template, 0, sizeof(template));

	memcpy(template.addr1, wl->bssid, ETH_ALEN);
	memcpy(template.addr2, wl->mac_addr, ETH_ALEN);
	memcpy(template.addr3, wl->bssid, ETH_ALEN);

	template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
					     IEEE80211_STYPE_QOS_NULLFUNC |
					     IEEE80211_FCTL_TODS);

	/* FIXME: not sure what priority to use here */
	template.qos_ctrl = cpu_to_le16(0);

	return wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, &template,
				       sizeof(template));
}

572
static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
K
Kalle Valo 已提交
573
{
574
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
575 576 577
	struct ieee80211_conf *conf = &hw->conf;
	int channel, ret = 0;

578 579
	channel = ieee80211_frequency_to_channel(
			conf->chandef.chan->center_freq);
K
Kalle Valo 已提交
580

581 582
	wl1251_debug(DEBUG_MAC80211,
		     "mac80211 config ch %d monitor %s psm %s power %d",
K
Kalle Valo 已提交
583
		     channel,
584
		     conf->flags & IEEE80211_CONF_MONITOR ? "on" : "off",
K
Kalle Valo 已提交
585 586 587 588 589
		     conf->flags & IEEE80211_CONF_PS ? "on" : "off",
		     conf->power_level);

	mutex_lock(&wl->mutex);

590
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
591 592
	if (ret < 0)
		goto out;
593

594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
	if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
		u32 mode;

		if (conf->flags & IEEE80211_CONF_MONITOR) {
			wl->monitor_present = true;
			mode = DF_SNIFF_MODE_ENABLE | DF_ENCRYPTION_DISABLE;
		} else {
			wl->monitor_present = false;
			mode = 0;
		}

		ret = wl1251_acx_feature_cfg(wl, mode);
		if (ret < 0)
			goto out_sleep;
	}

K
Kalle Valo 已提交
610
	if (channel != wl->channel) {
611 612
		wl->channel = channel;

K
Kalle Valo 已提交
613 614
		ret = wl1251_join(wl, wl->bss_type, wl->channel,
				  wl->beacon_int, wl->dtim_period);
K
Kalle Valo 已提交
615
		if (ret < 0)
K
Kalle Valo 已提交
616
			goto out_sleep;
K
Kalle Valo 已提交
617 618 619
	}

	if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
620
		wl1251_debug(DEBUG_PSM, "psm enabled");
K
Kalle Valo 已提交
621 622 623

		wl->psm_requested = true;

624 625 626 627 628
		wl->dtim_period = conf->ps_dtim_period;

		ret = wl1251_acx_wr_tbtt_and_dtim(wl, wl->beacon_int,
						  wl->dtim_period);

K
Kalle Valo 已提交
629
		/*
630
		 * mac80211 enables PSM only if we're already associated.
K
Kalle Valo 已提交
631
		 */
632
		ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
633 634
		if (ret < 0)
			goto out_sleep;
K
Kalle Valo 已提交
635 636
	} else if (!(conf->flags & IEEE80211_CONF_PS) &&
		   wl->psm_requested) {
637
		wl1251_debug(DEBUG_PSM, "psm disabled");
K
Kalle Valo 已提交
638 639 640

		wl->psm_requested = false;

641
		if (wl->station_mode != STATION_ACTIVE_MODE) {
642
			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
643 644 645
			if (ret < 0)
				goto out_sleep;
		}
K
Kalle Valo 已提交
646 647
	}

648
	if (changed & IEEE80211_CONF_CHANGE_IDLE && !wl->scanning) {
649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
		if (conf->flags & IEEE80211_CONF_IDLE) {
			ret = wl1251_ps_set_mode(wl, STATION_IDLE);
			if (ret < 0)
				goto out_sleep;
		} else {
			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
			if (ret < 0)
				goto out_sleep;
			ret = wl1251_join(wl, wl->bss_type, wl->channel,
					  wl->beacon_int, wl->dtim_period);
			if (ret < 0)
				goto out_sleep;
		}
	}

K
Kalle Valo 已提交
664
	if (conf->power_level != wl->power_level) {
665
		ret = wl1251_acx_tx_power(wl, conf->power_level);
K
Kalle Valo 已提交
666
		if (ret < 0)
667
			goto out_sleep;
K
Kalle Valo 已提交
668 669 670 671

		wl->power_level = conf->power_level;
	}

K
Kalle Valo 已提交
672
out_sleep:
673
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
674 675

out:
K
Kalle Valo 已提交
676
	mutex_unlock(&wl->mutex);
K
Kalle Valo 已提交
677

K
Kalle Valo 已提交
678 679 680
	return ret;
}

681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718
struct wl1251_filter_params {
	bool enabled;
	int mc_list_length;
	u8 mc_list[ACX_MC_ADDRESS_GROUP_MAX][ETH_ALEN];
};

static u64 wl1251_op_prepare_multicast(struct ieee80211_hw *hw,
				       struct netdev_hw_addr_list *mc_list)
{
	struct wl1251_filter_params *fp;
	struct netdev_hw_addr *ha;
	struct wl1251 *wl = hw->priv;

	if (unlikely(wl->state == WL1251_STATE_OFF))
		return 0;

	fp = kzalloc(sizeof(*fp), GFP_ATOMIC);
	if (!fp) {
		wl1251_error("Out of memory setting filters.");
		return 0;
	}

	/* update multicast filtering parameters */
	fp->mc_list_length = 0;
	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) {
			memcpy(fp->mc_list[fp->mc_list_length],
					ha->addr, ETH_ALEN);
			fp->mc_list_length++;
		}
	}

	return (u64)(unsigned long)fp;
}

719
#define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
K
Kalle Valo 已提交
720 721 722 723
				  FIF_ALLMULTI | \
				  FIF_FCSFAIL | \
				  FIF_BCN_PRBRESP_PROMISC | \
				  FIF_CONTROL | \
724 725
				  FIF_OTHER_BSS | \
				  FIF_PROBE_REQ)
K
Kalle Valo 已提交
726

727
static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
K
Kalle Valo 已提交
728
				       unsigned int changed,
729
				       unsigned int *total, u64 multicast)
K
Kalle Valo 已提交
730
{
731
	struct wl1251_filter_params *fp = (void *)(unsigned long)multicast;
732
	struct wl1251 *wl = hw->priv;
733
	int ret;
K
Kalle Valo 已提交
734

735
	wl1251_debug(DEBUG_MAC80211, "mac80211 configure filter");
K
Kalle Valo 已提交
736

737 738
	*total &= WL1251_SUPPORTED_FILTERS;
	changed &= WL1251_SUPPORTED_FILTERS;
K
Kalle Valo 已提交
739

740
	if (changed == 0) {
K
Kalle Valo 已提交
741
		/* no filters which we support changed */
742
		kfree(fp);
K
Kalle Valo 已提交
743
		return;
744
	}
K
Kalle Valo 已提交
745

746
	mutex_lock(&wl->mutex);
K
Kalle Valo 已提交
747

748 749
	wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
	wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
K
Kalle Valo 已提交
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768

	if (*total & FIF_PROMISC_IN_BSS) {
		wl->rx_config |= CFG_BSSID_FILTER_EN;
		wl->rx_config |= CFG_RX_ALL_GOOD;
	}
	if (*total & FIF_ALLMULTI)
		/*
		 * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive
		 * all multicast frames
		 */
		wl->rx_config &= ~CFG_MC_FILTER_EN;
	if (*total & FIF_FCSFAIL)
		wl->rx_filter |= CFG_RX_FCS_ERROR;
	if (*total & FIF_BCN_PRBRESP_PROMISC) {
		wl->rx_config &= ~CFG_BSSID_FILTER_EN;
		wl->rx_config &= ~CFG_SSID_FILTER_EN;
	}
	if (*total & FIF_CONTROL)
		wl->rx_filter |= CFG_RX_CTL_EN;
769 770 771 772 773 774 775 776 777 778 779 780
	if (*total & FIF_OTHER_BSS || is_zero_ether_addr(wl->bssid))
		wl->rx_config &= ~CFG_BSSID_FILTER_EN;
	if (*total & FIF_PROBE_REQ)
		wl->rx_filter |= CFG_RX_PREQ_EN;

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

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

781 782 783 784 785 786 787 788 789
	if (*total & FIF_ALLMULTI || *total & FIF_PROMISC_IN_BSS)
		ret = wl1251_acx_group_address_tbl(wl, false, NULL, 0);
	else if (fp)
		ret = wl1251_acx_group_address_tbl(wl, fp->enabled,
						   fp->mc_list,
						   fp->mc_list_length);
	if (ret < 0)
		goto out;

790 791 792 793 794 795 796
	/* send filters to firmware */
	wl1251_acx_rx_config(wl, wl->rx_config, wl->rx_filter);

	wl1251_ps_elp_sleep(wl);

out:
	mutex_unlock(&wl->mutex);
797
	kfree(fp);
K
Kalle Valo 已提交
798 799 800
}

/* HW encryption */
801 802
static int wl1251_set_key_type(struct wl1251 *wl,
			       struct wl1251_cmd_set_keys *key,
K
Kalle Valo 已提交
803 804 805 806
			       enum set_key_cmd cmd,
			       struct ieee80211_key_conf *mac80211_key,
			       const u8 *addr)
{
807 808 809
	switch (mac80211_key->cipher) {
	case WLAN_CIPHER_SUITE_WEP40:
	case WLAN_CIPHER_SUITE_WEP104:
K
Kalle Valo 已提交
810 811 812 813 814 815 816
		if (is_broadcast_ether_addr(addr))
			key->key_type = KEY_WEP_DEFAULT;
		else
			key->key_type = KEY_WEP_ADDR;

		mac80211_key->hw_key_idx = mac80211_key->keyidx;
		break;
817
	case WLAN_CIPHER_SUITE_TKIP:
K
Kalle Valo 已提交
818 819 820 821 822 823 824
		if (is_broadcast_ether_addr(addr))
			key->key_type = KEY_TKIP_MIC_GROUP;
		else
			key->key_type = KEY_TKIP_MIC_PAIRWISE;

		mac80211_key->hw_key_idx = mac80211_key->keyidx;
		break;
825
	case WLAN_CIPHER_SUITE_CCMP:
K
Kalle Valo 已提交
826 827 828 829 830 831 832
		if (is_broadcast_ether_addr(addr))
			key->key_type = KEY_AES_GROUP;
		else
			key->key_type = KEY_AES_PAIRWISE;
		mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
		break;
	default:
833
		wl1251_error("Unknown key cipher 0x%x", mac80211_key->cipher);
K
Kalle Valo 已提交
834 835 836 837 838 839
		return -EOPNOTSUPP;
	}

	return 0;
}

840
static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
K
Kalle Valo 已提交
841 842 843 844
			     struct ieee80211_vif *vif,
			     struct ieee80211_sta *sta,
			     struct ieee80211_key_conf *key)
{
845 846
	struct wl1251 *wl = hw->priv;
	struct wl1251_cmd_set_keys *wl_cmd;
K
Kalle Valo 已提交
847 848 849 850 851 852
	const u8 *addr;
	int ret;

	static const u8 bcast_addr[ETH_ALEN] =
		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };

853
	wl1251_debug(DEBUG_MAC80211, "mac80211 set key");
K
Kalle Valo 已提交
854

855 856 857 858 859
	wl_cmd = kzalloc(sizeof(*wl_cmd), GFP_KERNEL);
	if (!wl_cmd) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
860 861 862

	addr = sta ? sta->addr : bcast_addr;

863 864 865
	wl1251_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
	wl1251_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
	wl1251_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
866
		     key->cipher, key->keyidx, key->keylen, key->flags);
867
	wl1251_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
K
Kalle Valo 已提交
868

869 870 871 872 873 874
	if (is_zero_ether_addr(addr)) {
		/* We dont support TX only encryption */
		ret = -EOPNOTSUPP;
		goto out;
	}

K
Kalle Valo 已提交
875 876 877 878
	mutex_lock(&wl->mutex);

	switch (cmd) {
	case SET_KEY:
879 880 881 882
		if (wl->monitor_present) {
			ret = -EOPNOTSUPP;
			goto out_unlock;
		}
883
		wl_cmd->key_action = KEY_ADD_OR_REPLACE;
K
Kalle Valo 已提交
884 885
		break;
	case DISABLE_KEY:
886
		wl_cmd->key_action = KEY_REMOVE;
K
Kalle Valo 已提交
887 888
		break;
	default:
889
		wl1251_error("Unsupported key cmd 0x%x", cmd);
K
Kalle Valo 已提交
890 891 892
		break;
	}

893 894 895 896
	ret = wl1251_ps_elp_wakeup(wl);
	if (ret < 0)
		goto out_unlock;

897
	ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr);
K
Kalle Valo 已提交
898
	if (ret < 0) {
899
		wl1251_error("Set KEY type failed");
K
Kalle Valo 已提交
900
		goto out_sleep;
K
Kalle Valo 已提交
901 902
	}

903 904
	if (wl_cmd->key_type != KEY_WEP_DEFAULT)
		memcpy(wl_cmd->addr, addr, ETH_ALEN);
K
Kalle Valo 已提交
905

906 907
	if ((wl_cmd->key_type == KEY_TKIP_MIC_GROUP) ||
	    (wl_cmd->key_type == KEY_TKIP_MIC_PAIRWISE)) {
K
Kalle Valo 已提交
908 909 910 911 912 913
		/*
		 * We get the key in the following form:
		 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
		 * but the target is expecting:
		 * TKIP - RX MIC - TX MIC
		 */
914 915 916
		memcpy(wl_cmd->key, key->key, 16);
		memcpy(wl_cmd->key + 16, key->key + 24, 8);
		memcpy(wl_cmd->key + 24, key->key + 16, 8);
K
Kalle Valo 已提交
917 918

	} else {
919
		memcpy(wl_cmd->key, key->key, key->keylen);
K
Kalle Valo 已提交
920
	}
921
	wl_cmd->key_size = key->keylen;
K
Kalle Valo 已提交
922

923 924
	wl_cmd->id = key->keyidx;
	wl_cmd->ssid_profile = 0;
K
Kalle Valo 已提交
925

926
	wl1251_dump(DEBUG_CRYPT, "TARGET KEY: ", wl_cmd, sizeof(*wl_cmd));
K
Kalle Valo 已提交
927

928
	ret = wl1251_cmd_send(wl, CMD_SET_KEYS, wl_cmd, sizeof(*wl_cmd));
929
	if (ret < 0) {
930
		wl1251_warning("could not set keys");
K
Kalle Valo 已提交
931
		goto out_sleep;
K
Kalle Valo 已提交
932 933
	}

K
Kalle Valo 已提交
934
out_sleep:
935
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
936 937

out_unlock:
K
Kalle Valo 已提交
938
	mutex_unlock(&wl->mutex);
939 940 941 942

out:
	kfree(wl_cmd);

K
Kalle Valo 已提交
943 944 945
	return ret;
}

946
static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
947
			     struct ieee80211_vif *vif,
K
Kalle Valo 已提交
948 949
			     struct cfg80211_scan_request *req)
{
950
	struct wl1251 *wl = hw->priv;
951
	struct sk_buff *skb;
K
Kalle Valo 已提交
952
	size_t ssid_len = 0;
K
Kalle Valo 已提交
953 954
	u8 *ssid = NULL;
	int ret;
K
Kalle Valo 已提交
955

956
	wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
K
Kalle Valo 已提交
957 958 959 960 961 962 963

	if (req->n_ssids) {
		ssid = req->ssids[0].ssid;
		ssid_len = req->ssids[0].ssid_len;
	}

	mutex_lock(&wl->mutex);
K
Kalle Valo 已提交
964

K
Kalle Valo 已提交
965 966 967 968 969 970
	if (wl->scanning) {
		wl1251_debug(DEBUG_SCAN, "scan already in progress");
		ret = -EINVAL;
		goto out;
	}

971
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
972 973
	if (ret < 0)
		goto out;
974

975 976 977 978 979 980 981 982 983 984
	if (hw->conf.flags & IEEE80211_CONF_IDLE) {
		ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
		if (ret < 0)
			goto out_sleep;
		ret = wl1251_join(wl, wl->bss_type, wl->channel,
				  wl->beacon_int, wl->dtim_period);
		if (ret < 0)
			goto out_sleep;
	}

985
	skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
986
				     req->ie_len);
987 988
	if (!skb) {
		ret = -ENOMEM;
989
		goto out_idle;
990
	}
991 992
	if (req->ie_len)
		memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len);
993 994 995 996

	ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data,
				      skb->len);
	dev_kfree_skb(skb);
K
Kalle Valo 已提交
997
	if (ret < 0)
998
		goto out_idle;
K
Kalle Valo 已提交
999 1000 1001

	ret = wl1251_cmd_trigger_scan_to(wl, 0);
	if (ret < 0)
1002
		goto out_idle;
K
Kalle Valo 已提交
1003 1004

	wl->scanning = true;
1005

1006 1007
	ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels,
			      req->n_channels, WL1251_SCAN_NUM_PROBES);
K
Kalle Valo 已提交
1008
	if (ret < 0) {
1009
		wl1251_debug(DEBUG_SCAN, "scan failed %d", ret);
K
Kalle Valo 已提交
1010
		wl->scanning = false;
1011
		goto out_idle;
K
Kalle Valo 已提交
1012
	}
1013
	goto out_sleep;
K
Kalle Valo 已提交
1014

1015 1016 1017
out_idle:
	if (hw->conf.flags & IEEE80211_CONF_IDLE)
		ret = wl1251_ps_set_mode(wl, STATION_IDLE);
K
Kalle Valo 已提交
1018
out_sleep:
1019
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
1020 1021

out:
K
Kalle Valo 已提交
1022 1023 1024 1025 1026
	mutex_unlock(&wl->mutex);

	return ret;
}

1027
static int wl1251_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
K
Kalle Valo 已提交
1028
{
1029
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
1030 1031
	int ret;

1032 1033
	mutex_lock(&wl->mutex);

1034
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
1035 1036
	if (ret < 0)
		goto out;
1037

1038
	ret = wl1251_acx_rts_threshold(wl, (u16) value);
K
Kalle Valo 已提交
1039
	if (ret < 0)
1040
		wl1251_warning("wl1251_op_set_rts_threshold failed: %d", ret);
K
Kalle Valo 已提交
1041

1042
	wl1251_ps_elp_sleep(wl);
1043

K
Kalle Valo 已提交
1044
out:
1045 1046
	mutex_unlock(&wl->mutex);

K
Kalle Valo 已提交
1047 1048 1049
	return ret;
}

1050
static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
K
Kalle Valo 已提交
1051 1052 1053 1054
				       struct ieee80211_vif *vif,
				       struct ieee80211_bss_conf *bss_conf,
				       u32 changed)
{
1055
	struct wl1251 *wl = hw->priv;
1056
	struct sk_buff *beacon, *skb;
1057
	bool enable;
K
Kalle Valo 已提交
1058 1059
	int ret;

1060
	wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
K
Kalle Valo 已提交
1061 1062 1063

	mutex_lock(&wl->mutex);

1064
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
1065 1066
	if (ret < 0)
		goto out;
1067

1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
	if (changed & BSS_CHANGED_CQM) {
		ret = wl1251_acx_low_rssi(wl, bss_conf->cqm_rssi_thold,
					  WL1251_DEFAULT_LOW_RSSI_WEIGHT,
					  WL1251_DEFAULT_LOW_RSSI_DEPTH,
					  WL1251_ACX_LOW_RSSI_TYPE_EDGE);
		if (ret < 0)
			goto out;
		wl->rssi_thold = bss_conf->cqm_rssi_thold;
	}

K
Kalle Valo 已提交
1078 1079 1080
	if (changed & BSS_CHANGED_BSSID) {
		memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);

1081 1082 1083 1084 1085 1086 1087
		skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
		if (!skb)
			goto out_sleep;

		ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA,
					      skb->data, skb->len);
		dev_kfree_skb(skb);
K
Kalle Valo 已提交
1088
		if (ret < 0)
1089
			goto out_sleep;
K
Kalle Valo 已提交
1090

1091 1092 1093 1094
		ret = wl1251_build_qos_null_data(wl);
		if (ret < 0)
			goto out;

K
Kalle Valo 已提交
1095 1096 1097 1098 1099 1100 1101 1102
		if (wl->bss_type != BSS_TYPE_IBSS) {
			ret = wl1251_join(wl, wl->bss_type, wl->channel,
					  wl->beacon_int, wl->dtim_period);
			if (ret < 0)
				goto out_sleep;
		}
	}

K
Kalle Valo 已提交
1103 1104
	if (changed & BSS_CHANGED_ASSOC) {
		if (bss_conf->assoc) {
1105
			wl->beacon_int = bss_conf->beacon_int;
K
Kalle Valo 已提交
1106

1107 1108 1109 1110 1111 1112 1113 1114
			skb = ieee80211_pspoll_get(wl->hw, wl->vif);
			if (!skb)
				goto out_sleep;

			ret = wl1251_cmd_template_set(wl, CMD_PS_POLL,
						      skb->data,
						      skb->len);
			dev_kfree_skb(skb);
K
Kalle Valo 已提交
1115
			if (ret < 0)
K
Kalle Valo 已提交
1116
				goto out_sleep;
K
Kalle Valo 已提交
1117

1118
			ret = wl1251_acx_aid(wl, bss_conf->aid);
K
Kalle Valo 已提交
1119
			if (ret < 0)
K
Kalle Valo 已提交
1120
				goto out_sleep;
1121 1122 1123 1124
		} else {
			/* use defaults when not associated */
			wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
			wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
K
Kalle Valo 已提交
1125 1126 1127 1128
		}
	}
	if (changed & BSS_CHANGED_ERP_SLOT) {
		if (bss_conf->use_short_slot)
1129
			ret = wl1251_acx_slot(wl, SLOT_TIME_SHORT);
K
Kalle Valo 已提交
1130
		else
1131
			ret = wl1251_acx_slot(wl, SLOT_TIME_LONG);
K
Kalle Valo 已提交
1132
		if (ret < 0) {
1133
			wl1251_warning("Set slot time failed %d", ret);
K
Kalle Valo 已提交
1134
			goto out_sleep;
K
Kalle Valo 已提交
1135 1136 1137 1138 1139
		}
	}

	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
		if (bss_conf->use_short_preamble)
1140
			wl1251_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
K
Kalle Valo 已提交
1141
		else
1142
			wl1251_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
K
Kalle Valo 已提交
1143 1144 1145 1146
	}

	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
		if (bss_conf->use_cts_prot)
1147
			ret = wl1251_acx_cts_protect(wl, CTSPROTECT_ENABLE);
K
Kalle Valo 已提交
1148
		else
1149
			ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE);
K
Kalle Valo 已提交
1150
		if (ret < 0) {
1151
			wl1251_warning("Set ctsprotect failed %d", ret);
1152
			goto out_sleep;
K
Kalle Valo 已提交
1153 1154 1155
		}
	}

1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166
	if (changed & BSS_CHANGED_ARP_FILTER) {
		__be32 addr = bss_conf->arp_addr_list[0];
		WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);

		enable = bss_conf->arp_addr_cnt == 1 && bss_conf->assoc;
		wl1251_acx_arp_ip_filter(wl, enable, addr);

		if (ret < 0)
			goto out_sleep;
	}

K
Kalle Valo 已提交
1167 1168
	if (changed & BSS_CHANGED_BEACON) {
		beacon = ieee80211_beacon_get(hw, vif);
1169 1170 1171
		if (!beacon)
			goto out_sleep;

1172
		ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data,
K
Kalle Valo 已提交
1173 1174 1175 1176
					      beacon->len);

		if (ret < 0) {
			dev_kfree_skb(beacon);
1177
			goto out_sleep;
K
Kalle Valo 已提交
1178 1179
		}

1180
		ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
K
Kalle Valo 已提交
1181 1182 1183 1184 1185
					      beacon->len);

		dev_kfree_skb(beacon);

		if (ret < 0)
1186
			goto out_sleep;
K
Kalle Valo 已提交
1187

K
Kalle Valo 已提交
1188 1189
		ret = wl1251_join(wl, wl->bss_type, wl->beacon_int,
				  wl->channel, wl->dtim_period);
K
Kalle Valo 已提交
1190 1191

		if (ret < 0)
1192
			goto out_sleep;
K
Kalle Valo 已提交
1193 1194
	}

K
Kalle Valo 已提交
1195
out_sleep:
1196
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
1197 1198

out:
K
Kalle Valo 已提交
1199 1200 1201 1202 1203
	mutex_unlock(&wl->mutex);
}


/* can't be const, mac80211 writes to this */
1204
static struct ieee80211_rate wl1251_rates[] = {
K
Kalle Valo 已提交
1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246
	{ .bitrate = 10,
	  .hw_value = 0x1,
	  .hw_value_short = 0x1, },
	{ .bitrate = 20,
	  .hw_value = 0x2,
	  .hw_value_short = 0x2,
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 55,
	  .hw_value = 0x4,
	  .hw_value_short = 0x4,
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 110,
	  .hw_value = 0x20,
	  .hw_value_short = 0x20,
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 60,
	  .hw_value = 0x8,
	  .hw_value_short = 0x8, },
	{ .bitrate = 90,
	  .hw_value = 0x10,
	  .hw_value_short = 0x10, },
	{ .bitrate = 120,
	  .hw_value = 0x40,
	  .hw_value_short = 0x40, },
	{ .bitrate = 180,
	  .hw_value = 0x80,
	  .hw_value_short = 0x80, },
	{ .bitrate = 240,
	  .hw_value = 0x200,
	  .hw_value_short = 0x200, },
	{ .bitrate = 360,
	 .hw_value = 0x400,
	 .hw_value_short = 0x400, },
	{ .bitrate = 480,
	  .hw_value = 0x800,
	  .hw_value_short = 0x800, },
	{ .bitrate = 540,
	  .hw_value = 0x1000,
	  .hw_value_short = 0x1000, },
};

/* can't be const, mac80211 writes to this */
1247
static struct ieee80211_channel wl1251_channels[] = {
K
Kalle Valo 已提交
1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262
	{ .hw_value = 1, .center_freq = 2412},
	{ .hw_value = 2, .center_freq = 2417},
	{ .hw_value = 3, .center_freq = 2422},
	{ .hw_value = 4, .center_freq = 2427},
	{ .hw_value = 5, .center_freq = 2432},
	{ .hw_value = 6, .center_freq = 2437},
	{ .hw_value = 7, .center_freq = 2442},
	{ .hw_value = 8, .center_freq = 2447},
	{ .hw_value = 9, .center_freq = 2452},
	{ .hw_value = 10, .center_freq = 2457},
	{ .hw_value = 11, .center_freq = 2462},
	{ .hw_value = 12, .center_freq = 2467},
	{ .hw_value = 13, .center_freq = 2472},
};

1263 1264
static int wl1251_op_conf_tx(struct ieee80211_hw *hw,
			     struct ieee80211_vif *vif, u16 queue,
1265 1266
			     const struct ieee80211_tx_queue_params *params)
{
K
Kalle Valo 已提交
1267
	enum wl1251_acx_ps_scheme ps_scheme;
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278
	struct wl1251 *wl = hw->priv;
	int ret;

	mutex_lock(&wl->mutex);

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

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

K
Kalle Valo 已提交
1279
	/* mac80211 uses units of 32 usec */
1280 1281
	ret = wl1251_acx_ac_cfg(wl, wl1251_tx_get_queue(queue),
				params->cw_min, params->cw_max,
K
Kalle Valo 已提交
1282
				params->aifs, params->txop * 32);
1283 1284 1285
	if (ret < 0)
		goto out_sleep;

K
Kalle Valo 已提交
1286 1287 1288 1289 1290
	if (params->uapsd)
		ps_scheme = WL1251_ACX_PS_SCHEME_UPSD_TRIGGER;
	else
		ps_scheme = WL1251_ACX_PS_SCHEME_LEGACY;

1291
	ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue),
K
Kalle Valo 已提交
1292
				 CHANNEL_TYPE_EDCF,
K
Kalle Valo 已提交
1293
				 wl1251_tx_get_queue(queue), ps_scheme,
1294 1295 1296
				 WL1251_ACX_ACK_POLICY_LEGACY);
	if (ret < 0)
		goto out_sleep;
1297

1298
out_sleep:
1299 1300 1301 1302 1303 1304 1305 1306
	wl1251_ps_elp_sleep(wl);

out:
	mutex_unlock(&wl->mutex);

	return ret;
}

1307 1308 1309 1310 1311 1312 1313 1314 1315
static int wl1251_op_get_survey(struct ieee80211_hw *hw, int idx,
				struct survey_info *survey)
{
	struct wl1251 *wl = hw->priv;
	struct ieee80211_conf *conf = &hw->conf;
 
	if (idx != 0)
		return -ENOENT;
 
1316
	survey->channel = conf->chandef.chan;
1317 1318 1319 1320 1321 1322
	survey->filled = SURVEY_INFO_NOISE_DBM;
	survey->noise = wl->noise;
 
	return 0;
}

K
Kalle Valo 已提交
1323
/* can't be const, mac80211 writes to this */
1324 1325 1326 1327 1328
static struct ieee80211_supported_band wl1251_band_2ghz = {
	.channels = wl1251_channels,
	.n_channels = ARRAY_SIZE(wl1251_channels),
	.bitrates = wl1251_rates,
	.n_bitrates = ARRAY_SIZE(wl1251_rates),
K
Kalle Valo 已提交
1329 1330
};

1331 1332 1333 1334 1335 1336
static const struct ieee80211_ops wl1251_ops = {
	.start = wl1251_op_start,
	.stop = wl1251_op_stop,
	.add_interface = wl1251_op_add_interface,
	.remove_interface = wl1251_op_remove_interface,
	.config = wl1251_op_config,
1337
	.prepare_multicast = wl1251_op_prepare_multicast,
1338 1339 1340 1341 1342 1343
	.configure_filter = wl1251_op_configure_filter,
	.tx = wl1251_op_tx,
	.set_key = wl1251_op_set_key,
	.hw_scan = wl1251_op_hw_scan,
	.bss_info_changed = wl1251_op_bss_info_changed,
	.set_rts_threshold = wl1251_op_set_rts_threshold,
1344
	.conf_tx = wl1251_op_conf_tx,
1345
	.get_survey = wl1251_op_get_survey,
K
Kalle Valo 已提交
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 1406 1407
static int wl1251_read_eeprom_byte(struct wl1251 *wl, off_t offset, u8 *data)
{
	unsigned long timeout;

	wl1251_reg_write32(wl, EE_ADDR, offset);
	wl1251_reg_write32(wl, EE_CTL, EE_CTL_READ);

	/* EE_CTL_READ clears when data is ready */
	timeout = jiffies + msecs_to_jiffies(100);
	while (1) {
		if (!(wl1251_reg_read32(wl, EE_CTL) & EE_CTL_READ))
			break;

		if (time_after(jiffies, timeout))
			return -ETIMEDOUT;

		msleep(1);
	}

	*data = wl1251_reg_read32(wl, EE_DATA);
	return 0;
}

static int wl1251_read_eeprom(struct wl1251 *wl, off_t offset,
			      u8 *data, size_t len)
{
	size_t i;
	int ret;

	wl1251_reg_write32(wl, EE_START, 0);

	for (i = 0; i < len; i++) {
		ret = wl1251_read_eeprom_byte(wl, offset + i, &data[i]);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int wl1251_read_eeprom_mac(struct wl1251 *wl)
{
	u8 mac[ETH_ALEN];
	int i, ret;

	wl1251_set_partition(wl, 0, 0, REGISTERS_BASE, REGISTERS_DOWN_SIZE);

	ret = wl1251_read_eeprom(wl, 0x1c, mac, sizeof(mac));
	if (ret < 0) {
		wl1251_warning("failed to read MAC address from EEPROM");
		return ret;
	}

	/* MAC is stored in reverse order */
	for (i = 0; i < ETH_ALEN; i++)
		wl->mac_addr[i] = mac[ETH_ALEN - i - 1];

	return 0;
}

1408
static int wl1251_register_hw(struct wl1251 *wl)
K
Kalle Valo 已提交
1409 1410 1411 1412 1413 1414 1415 1416 1417 1418
{
	int ret;

	if (wl->mac80211_registered)
		return 0;

	SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);

	ret = ieee80211_register_hw(wl->hw);
	if (ret < 0) {
1419
		wl1251_error("unable to register mac80211 hw: %d", ret);
K
Kalle Valo 已提交
1420 1421 1422 1423 1424
		return ret;
	}

	wl->mac80211_registered = true;

1425
	wl1251_notice("loaded");
K
Kalle Valo 已提交
1426 1427 1428 1429

	return 0;
}

1430
int wl1251_init_ieee80211(struct wl1251 *wl)
K
Kalle Valo 已提交
1431
{
1432 1433
	int ret;

K
Kalle Valo 已提交
1434 1435
	/* The tx descriptor buffer and the TKIP space */
	wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
1436
		+ WL1251_TKIP_IV_SPACE;
K
Kalle Valo 已提交
1437 1438 1439 1440 1441 1442

	/* unit us */
	/* FIXME: find a proper value */
	wl->hw->channel_change_time = 10000;

	wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
1443
		IEEE80211_HW_SUPPORTS_PS |
1444
		IEEE80211_HW_SUPPORTS_UAPSD;
K
Kalle Valo 已提交
1445

D
David Gnedt 已提交
1446 1447
	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
					 BIT(NL80211_IFTYPE_ADHOC);
K
Kalle Valo 已提交
1448
	wl->hw->wiphy->max_scan_ssids = 1;
1449
	wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
K
Kalle Valo 已提交
1450

K
Kalle Valo 已提交
1451 1452
	wl->hw->queues = 4;

1453 1454 1455
	if (wl->use_eeprom)
		wl1251_read_eeprom_mac(wl);

1456 1457 1458
	ret = wl1251_register_hw(wl);
	if (ret)
		goto out;
K
Kalle Valo 已提交
1459

1460 1461
	wl1251_debugfs_init(wl);
	wl1251_notice("initialized");
K
Kalle Valo 已提交
1462

1463 1464 1465 1466 1467
	ret = 0;

out:
	return ret;
}
1468
EXPORT_SYMBOL_GPL(wl1251_init_ieee80211);
1469

1470
struct ieee80211_hw *wl1251_alloc_hw(void)
K
Kalle Valo 已提交
1471 1472
{
	struct ieee80211_hw *hw;
1473
	struct wl1251 *wl;
1474
	int i;
K
Kalle Valo 已提交
1475 1476
	static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};

1477
	hw = ieee80211_alloc_hw(sizeof(*wl), &wl1251_ops);
K
Kalle Valo 已提交
1478
	if (!hw) {
1479
		wl1251_error("could not alloc ieee80211_hw");
1480
		return ERR_PTR(-ENOMEM);
K
Kalle Valo 已提交
1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491
	}

	wl = hw->priv;
	memset(wl, 0, sizeof(*wl));

	wl->hw = hw;

	wl->data_in_count = 0;

	skb_queue_head_init(&wl->tx_queue);

1492
	INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work);
1493
	wl->channel = WL1251_DEFAULT_CHANNEL;
1494
	wl->monitor_present = false;
K
Kalle Valo 已提交
1495 1496 1497 1498 1499 1500 1501
	wl->scanning = false;
	wl->default_key = 0;
	wl->listen_int = 1;
	wl->rx_counter = 0;
	wl->rx_handled = 0;
	wl->rx_current_buffer = 0;
	wl->rx_last_id = 0;
1502 1503
	wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
	wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
K
Kalle Valo 已提交
1504
	wl->elp = false;
1505
	wl->station_mode = STATION_ACTIVE_MODE;
K
Kalle Valo 已提交
1506
	wl->psm_requested = false;
D
David Gnedt 已提交
1507
	wl->psm_entry_retry = 0;
K
Kalle Valo 已提交
1508
	wl->tx_queue_stopped = false;
1509
	wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
1510
	wl->rssi_thold = 0;
1511 1512
	wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
	wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
1513
	wl->vif = NULL;
K
Kalle Valo 已提交
1514 1515 1516 1517 1518 1519

	for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
		wl->tx_frames[i] = NULL;

	wl->next_tx_complete = 0;

K
Kalle Valo 已提交
1520 1521 1522
	INIT_WORK(&wl->irq_work, wl1251_irq_work);
	INIT_WORK(&wl->tx_work, wl1251_tx_work);

K
Kalle Valo 已提交
1523 1524 1525 1526 1527 1528 1529
	/*
	 * In case our MAC address is not correctly set,
	 * we use a random but Nokia MAC.
	 */
	memcpy(wl->mac_addr, nokia_oui, 3);
	get_random_bytes(wl->mac_addr + 3, 3);

1530
	wl->state = WL1251_STATE_OFF;
K
Kalle Valo 已提交
1531 1532 1533 1534 1535
	mutex_init(&wl->mutex);

	wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
	wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;

K
Kalle Valo 已提交
1536 1537
	wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL);
	if (!wl->rx_descriptor) {
1538
		wl1251_error("could not allocate memory for rx descriptor");
1539 1540
		ieee80211_free_hw(hw);
		return ERR_PTR(-ENOMEM);
K
Kalle Valo 已提交
1541 1542
	}

1543
	return hw;
K
Kalle Valo 已提交
1544
}
1545
EXPORT_SYMBOL_GPL(wl1251_alloc_hw);
K
Kalle Valo 已提交
1546

1547
int wl1251_free_hw(struct wl1251 *wl)
K
Kalle Valo 已提交
1548 1549 1550
{
	ieee80211_unregister_hw(wl->hw);

1551
	wl1251_debugfs_exit(wl);
K
Kalle Valo 已提交
1552 1553 1554

	kfree(wl->target_mem_map);
	kfree(wl->data_path);
1555
	vfree(wl->fw);
K
Kalle Valo 已提交
1556 1557 1558
	wl->fw = NULL;
	kfree(wl->nvs);
	wl->nvs = NULL;
K
Kalle Valo 已提交
1559 1560 1561 1562

	kfree(wl->rx_descriptor);
	wl->rx_descriptor = NULL;

K
Kalle Valo 已提交
1563 1564 1565 1566
	ieee80211_free_hw(wl->hw);

	return 0;
}
1567 1568 1569 1570
EXPORT_SYMBOL_GPL(wl1251_free_hw);

MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
MODULE_LICENSE("GPL");
K
Kalle Valo 已提交
1571
MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
B
Ben Hutchings 已提交
1572
MODULE_FIRMWARE(WL1251_FW_NAME);