wl1251_main.c 32.3 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 29 30 31
 *
 * Copyright (C) 2008-2009 Nokia Corporation
 *
 * Contact: Kalle Valo <kalle.valo@nokia.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/crc32.h>
#include <linux/etherdevice.h>

K
Kalle Valo 已提交
32
#include "wl1251.h"
K
Kalle Valo 已提交
33
#include "wl12xx_80211.h"
34
#include "wl1251_reg.h"
35
#include "wl1251_io.h"
36
#include "wl1251_cmd.h"
37
#include "wl1251_event.h"
38
#include "wl1251_tx.h"
39 40 41 42
#include "wl1251_rx.h"
#include "wl1251_ps.h"
#include "wl1251_init.h"
#include "wl1251_debugfs.h"
K
Kalle Valo 已提交
43
#include "wl1251_boot.h"
K
Kalle Valo 已提交
44

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

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

55
static void wl1251_power_off(struct wl1251 *wl)
K
Kalle Valo 已提交
56 57 58 59
{
	wl->set_power(false);
}

60
static void wl1251_power_on(struct wl1251 *wl)
K
Kalle Valo 已提交
61 62 63 64
{
	wl->set_power(true);
}

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

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

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

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

	wl->fw_len = fw->size;
	wl->fw = kmalloc(wl->fw_len, GFP_KERNEL);

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

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

	ret = 0;

out:
	release_firmware(fw);

	return ret;
}

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

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

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

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

	wl->nvs_len = fw->size;
	wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL);

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

	memcpy(wl->nvs, fw->data, wl->nvs_len);

	ret = 0;

out:
	release_firmware(fw);

	return ret;
}

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

	elp_reg = ELPCTRL_WAKE_UP;
148 149
	wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
	elp_reg = wl1251_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
K
Kalle Valo 已提交
150

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

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

159
	wl1251_power_on(wl);
K
Kalle Valo 已提交
160
	msleep(WL1251_POWER_ON_SLEEP);
161
	wl->if_ops->reset(wl);
K
Kalle Valo 已提交
162 163 164

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

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

	/* whal_FwCtrl_BootSm() */

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

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

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

	if (wl->fw == NULL) {
195
		ret = wl1251_fetch_firmware(wl);
K
Kalle Valo 已提交
196 197 198 199 200 201
		if (ret < 0)
			goto out;
	}

	/* No NVS from netlink, try to get it from the filesystem */
	if (wl->nvs == NULL) {
202
		ret = wl1251_fetch_nvs(wl);
K
Kalle Valo 已提交
203 204 205 206 207 208 209 210
		if (ret < 0)
			goto out;
	}

out:
	return ret;
}

K
Kalle Valo 已提交
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 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 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 311
static void wl1251_irq_work(struct work_struct *work)
{
	u32 intr;
	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);

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

	intr &= wl->intr_mask;

	if (intr == 0) {
		wl1251_debug(DEBUG_IRQ, "INTR is 0");
		wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
				   ~(wl->intr_mask));

		goto out_sleep;
	}

	if (intr & WL1251_ACX_INTR_RX0_DATA) {
		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
		wl1251_rx(wl);
	}

	if (intr & WL1251_ACX_INTR_RX1_DATA) {
		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
		wl1251_rx(wl);
	}

	if (intr & WL1251_ACX_INTR_TX_RESULT) {
		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
		wl1251_tx_complete(wl);
	}

	if (intr & (WL1251_ACX_INTR_EVENT_A | WL1251_ACX_INTR_EVENT_B)) {
		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", intr);
		if (intr & WL1251_ACX_INTR_EVENT_A)
			wl1251_event_handle(wl, 0);
		else
			wl1251_event_handle(wl, 1);
	}

	if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
		wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_INIT_COMPLETE");

	wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));

out_sleep:
	wl1251_ps_elp_sleep(wl);

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

K
Kalle Valo 已提交
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
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;


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

	/*
	 * FIXME: we should wait for JOIN_EVENT_COMPLETE_ID but to simplify
	 * locking we just sleep instead, for now
	 */
	msleep(10);

out:
	return ret;
}

340
static void wl1251_filter_work(struct work_struct *work)
K
Kalle Valo 已提交
341
{
342 343
	struct wl1251 *wl =
		container_of(work, struct wl1251, filter_work);
K
Kalle Valo 已提交
344 345 346 347
	int ret;

	mutex_lock(&wl->mutex);

348
	if (wl->state == WL1251_STATE_OFF)
K
Kalle Valo 已提交
349 350
		goto out;

351
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
352 353
	if (ret < 0)
		goto out;
354

K
Kalle Valo 已提交
355 356
	ret = wl1251_join(wl, wl->bss_type, wl->channel, wl->beacon_int,
			  wl->dtim_period);
K
Kalle Valo 已提交
357
	if (ret < 0)
K
Kalle Valo 已提交
358
		goto out_sleep;
K
Kalle Valo 已提交
359

K
Kalle Valo 已提交
360
out_sleep:
361
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
362 363

out:
K
Kalle Valo 已提交
364 365 366
	mutex_unlock(&wl->mutex);
}

367
static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
K
Kalle Valo 已提交
368
{
369
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
370 371 372

	skb_queue_tail(&wl->tx_queue, skb);

373 374 375 376 377
	/*
	 * The chip specific setup must run before the first TX packet -
	 * before that, the tx_work will not be initialized!
	 */

378
	ieee80211_queue_work(wl->hw, &wl->tx_work);
K
Kalle Valo 已提交
379 380 381 382 383

	/*
	 * The workqueue is slow to process the tx_queue and we need stop
	 * the queue here, otherwise the queue will get too long.
	 */
384
	if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) {
K
Kalle Valo 已提交
385 386 387 388 389 390 391 392 393 394 395 396 397
		ieee80211_stop_queues(wl->hw);

		/*
		 * FIXME: this is racy, the variable is not properly
		 * protected. Maybe fix this by removing the stupid
		 * variable altogether and checking the real queue state?
		 */
		wl->tx_queue_stopped = true;
	}

	return NETDEV_TX_OK;
}

398
static int wl1251_op_start(struct ieee80211_hw *hw)
K
Kalle Valo 已提交
399
{
400
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
401 402
	int ret = 0;

403
	wl1251_debug(DEBUG_MAC80211, "mac80211 start");
K
Kalle Valo 已提交
404 405 406

	mutex_lock(&wl->mutex);

407 408
	if (wl->state != WL1251_STATE_OFF) {
		wl1251_error("cannot start because not in off state: %d",
K
Kalle Valo 已提交
409 410 411 412 413
			     wl->state);
		ret = -EBUSY;
		goto out;
	}

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

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

K
Kalle Valo 已提交
422
	ret = wl1251_hw_init(wl);
K
Kalle Valo 已提交
423 424 425
	if (ret < 0)
		goto out;

426
	ret = wl1251_acx_station_id(wl);
K
Kalle Valo 已提交
427 428 429
	if (ret < 0)
		goto out;

430
	wl->state = WL1251_STATE_ON;
K
Kalle Valo 已提交
431

K
Kalle Valo 已提交
432
	wl1251_info("firmware booted (%s)", wl->fw_ver);
K
Kalle Valo 已提交
433 434 435

out:
	if (ret < 0)
436
		wl1251_power_off(wl);
K
Kalle Valo 已提交
437 438 439 440 441 442

	mutex_unlock(&wl->mutex);

	return ret;
}

443
static void wl1251_op_stop(struct ieee80211_hw *hw)
K
Kalle Valo 已提交
444
{
445
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
446

447
	wl1251_info("down");
K
Kalle Valo 已提交
448

449
	wl1251_debug(DEBUG_MAC80211, "mac80211 stop");
K
Kalle Valo 已提交
450 451 452

	mutex_lock(&wl->mutex);

453
	WARN_ON(wl->state != WL1251_STATE_ON);
K
Kalle Valo 已提交
454 455 456 457 458 459 460 461

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

462
	wl->state = WL1251_STATE_OFF;
K
Kalle Valo 已提交
463

464
	wl1251_disable_interrupts(wl);
K
Kalle Valo 已提交
465 466 467 468 469 470 471 472 473 474

	mutex_unlock(&wl->mutex);

	cancel_work_sync(&wl->irq_work);
	cancel_work_sync(&wl->tx_work);
	cancel_work_sync(&wl->filter_work);

	mutex_lock(&wl->mutex);

	/* let's notify MAC80211 about the remaining pending TX frames */
K
Kalle Valo 已提交
475
	wl1251_tx_flush(wl);
476
	wl1251_power_off(wl);
K
Kalle Valo 已提交
477 478 479 480 481 482 483 484 485 486 487 488 489 490

	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;
	wl->psm = 0;
	wl->tx_queue_stopped = false;
491
	wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
492
	wl->channel = WL1251_DEFAULT_CHANNEL;
K
Kalle Valo 已提交
493

494
	wl1251_debugfs_reset(wl);
K
Kalle Valo 已提交
495 496 497 498

	mutex_unlock(&wl->mutex);
}

499
static int wl1251_op_add_interface(struct ieee80211_hw *hw,
K
Kalle Valo 已提交
500 501
				   struct ieee80211_if_init_conf *conf)
{
502
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
503 504
	int ret = 0;

J
Johannes Berg 已提交
505 506
	wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
		     conf->type, conf->mac_addr);
K
Kalle Valo 已提交
507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524

	mutex_lock(&wl->mutex);

	switch (conf->type) {
	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;
	}

	if (memcmp(wl->mac_addr, conf->mac_addr, ETH_ALEN)) {
		memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
		SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
525
		ret = wl1251_acx_station_id(wl);
K
Kalle Valo 已提交
526 527 528 529 530 531 532 533 534
		if (ret < 0)
			goto out;
	}

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

535
static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
K
Kalle Valo 已提交
536 537
					 struct ieee80211_if_init_conf *conf)
{
538
	wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface");
K
Kalle Valo 已提交
539 540
}

541
static int wl1251_build_null_data(struct wl1251 *wl)
K
Kalle Valo 已提交
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556
{
	struct wl12xx_null_data_template template;

	if (!is_zero_ether_addr(wl->bssid)) {
		memcpy(template.header.da, wl->bssid, ETH_ALEN);
		memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
	} else {
		memset(template.header.da, 0xff, ETH_ALEN);
		memset(template.header.bssid, 0xff, ETH_ALEN);
	}

	memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
	template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
						IEEE80211_STYPE_NULLFUNC);

557
	return wl1251_cmd_template_set(wl, CMD_NULL_DATA, &template,
K
Kalle Valo 已提交
558 559 560 561
				       sizeof(template));

}

562
static int wl1251_build_ps_poll(struct wl1251 *wl, u16 aid)
K
Kalle Valo 已提交
563 564 565 566 567 568 569 570
{
	struct wl12xx_ps_poll_template template;

	memcpy(template.bssid, wl->bssid, ETH_ALEN);
	memcpy(template.ta, wl->mac_addr, ETH_ALEN);
	template.aid = aid;
	template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);

571
	return wl1251_cmd_template_set(wl, CMD_PS_POLL, &template,
K
Kalle Valo 已提交
572 573 574 575
				       sizeof(template));

}

576
static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
K
Kalle Valo 已提交
577
{
578
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
579 580 581 582 583
	struct ieee80211_conf *conf = &hw->conf;
	int channel, ret = 0;

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

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

	mutex_lock(&wl->mutex);

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

K
Kalle Valo 已提交
595
	if (channel != wl->channel) {
596 597
		wl->channel = channel;

K
Kalle Valo 已提交
598 599
		ret = wl1251_join(wl, wl->bss_type, wl->channel,
				  wl->beacon_int, wl->dtim_period);
K
Kalle Valo 已提交
600
		if (ret < 0)
K
Kalle Valo 已提交
601
			goto out_sleep;
K
Kalle Valo 已提交
602 603
	}

604
	ret = wl1251_build_null_data(wl);
K
Kalle Valo 已提交
605
	if (ret < 0)
K
Kalle Valo 已提交
606
		goto out_sleep;
K
Kalle Valo 已提交
607 608

	if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
609
		wl1251_debug(DEBUG_PSM, "psm enabled");
K
Kalle Valo 已提交
610 611 612 613 614 615 616 617

		wl->psm_requested = true;

		/*
		 * We enter PSM only if we're already associated.
		 * If we're not, we'll enter it when joining an SSID,
		 * through the bss_info_changed() hook.
		 */
618
		ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
K
Kalle Valo 已提交
619 620
	} else if (!(conf->flags & IEEE80211_CONF_PS) &&
		   wl->psm_requested) {
621
		wl1251_debug(DEBUG_PSM, "psm disabled");
K
Kalle Valo 已提交
622 623 624 625

		wl->psm_requested = false;

		if (wl->psm)
626
			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
K
Kalle Valo 已提交
627 628 629
	}

	if (conf->power_level != wl->power_level) {
630
		ret = wl1251_acx_tx_power(wl, conf->power_level);
K
Kalle Valo 已提交
631 632 633 634 635 636
		if (ret < 0)
			goto out;

		wl->power_level = conf->power_level;
	}

K
Kalle Valo 已提交
637
out_sleep:
638
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
639 640

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

K
Kalle Valo 已提交
643 644 645
	return ret;
}

646
#define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
K
Kalle Valo 已提交
647 648 649 650 651 652
				  FIF_ALLMULTI | \
				  FIF_FCSFAIL | \
				  FIF_BCN_PRBRESP_PROMISC | \
				  FIF_CONTROL | \
				  FIF_OTHER_BSS)

653
static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
K
Kalle Valo 已提交
654
				       unsigned int changed,
655
				       unsigned int *total,u64 multicast)
K
Kalle Valo 已提交
656
{
657
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
658

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

661 662
	*total &= WL1251_SUPPORTED_FILTERS;
	changed &= WL1251_SUPPORTED_FILTERS;
K
Kalle Valo 已提交
663 664 665 666 667 668 669

	if (changed == 0)
		/* no filters which we support changed */
		return;

	/* FIXME: wl->rx_config and wl->rx_filter are not protected */

670 671
	wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
	wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
K
Kalle Valo 已提交
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702

	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;
	if (*total & FIF_OTHER_BSS)
		wl->rx_filter &= ~CFG_BSSID_FILTER_EN;

	/*
	 * FIXME: workqueues need to be properly cancelled on stop(), for
	 * now let's just disable changing the filter settings. They will
	 * be updated any on config().
	 */
	/* schedule_work(&wl->filter_work); */
}

/* HW encryption */
703 704
static int wl1251_set_key_type(struct wl1251 *wl,
			       struct wl1251_cmd_set_keys *key,
K
Kalle Valo 已提交
705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733
			       enum set_key_cmd cmd,
			       struct ieee80211_key_conf *mac80211_key,
			       const u8 *addr)
{
	switch (mac80211_key->alg) {
	case ALG_WEP:
		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;
	case ALG_TKIP:
		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;
	case ALG_CCMP:
		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:
734
		wl1251_error("Unknown key algo 0x%x", mac80211_key->alg);
K
Kalle Valo 已提交
735 736 737 738 739 740
		return -EOPNOTSUPP;
	}

	return 0;
}

741
static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
K
Kalle Valo 已提交
742 743 744 745
			     struct ieee80211_vif *vif,
			     struct ieee80211_sta *sta,
			     struct ieee80211_key_conf *key)
{
746 747
	struct wl1251 *wl = hw->priv;
	struct wl1251_cmd_set_keys *wl_cmd;
K
Kalle Valo 已提交
748 749 750 751 752 753
	const u8 *addr;
	int ret;

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

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

756 757 758 759 760
	wl_cmd = kzalloc(sizeof(*wl_cmd), GFP_KERNEL);
	if (!wl_cmd) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
761 762 763

	addr = sta ? sta->addr : bcast_addr;

764 765 766
	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",
K
Kalle Valo 已提交
767
		     key->alg, key->keyidx, key->keylen, key->flags);
768
	wl1251_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
K
Kalle Valo 已提交
769

770 771 772 773 774 775
	if (is_zero_ether_addr(addr)) {
		/* We dont support TX only encryption */
		ret = -EOPNOTSUPP;
		goto out;
	}

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

778
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
779 780
	if (ret < 0)
		goto out_unlock;
781

K
Kalle Valo 已提交
782 783
	switch (cmd) {
	case SET_KEY:
784
		wl_cmd->key_action = KEY_ADD_OR_REPLACE;
K
Kalle Valo 已提交
785 786
		break;
	case DISABLE_KEY:
787
		wl_cmd->key_action = KEY_REMOVE;
K
Kalle Valo 已提交
788 789
		break;
	default:
790
		wl1251_error("Unsupported key cmd 0x%x", cmd);
K
Kalle Valo 已提交
791 792 793
		break;
	}

794
	ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr);
K
Kalle Valo 已提交
795
	if (ret < 0) {
796
		wl1251_error("Set KEY type failed");
K
Kalle Valo 已提交
797
		goto out_sleep;
K
Kalle Valo 已提交
798 799
	}

800 801
	if (wl_cmd->key_type != KEY_WEP_DEFAULT)
		memcpy(wl_cmd->addr, addr, ETH_ALEN);
K
Kalle Valo 已提交
802

803 804
	if ((wl_cmd->key_type == KEY_TKIP_MIC_GROUP) ||
	    (wl_cmd->key_type == KEY_TKIP_MIC_PAIRWISE)) {
K
Kalle Valo 已提交
805 806 807 808 809 810
		/*
		 * 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
		 */
811 812 813
		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 已提交
814 815

	} else {
816
		memcpy(wl_cmd->key, key->key, key->keylen);
K
Kalle Valo 已提交
817
	}
818
	wl_cmd->key_size = key->keylen;
K
Kalle Valo 已提交
819

820 821
	wl_cmd->id = key->keyidx;
	wl_cmd->ssid_profile = 0;
K
Kalle Valo 已提交
822

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

825
	ret = wl1251_cmd_send(wl, CMD_SET_KEYS, wl_cmd, sizeof(*wl_cmd));
826
	if (ret < 0) {
827
		wl1251_warning("could not set keys");
K
Kalle Valo 已提交
828
		goto out_sleep;
K
Kalle Valo 已提交
829 830
	}

K
Kalle Valo 已提交
831
out_sleep:
832
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
833 834

out_unlock:
K
Kalle Valo 已提交
835
	mutex_unlock(&wl->mutex);
836 837 838 839

out:
	kfree(wl_cmd);

K
Kalle Valo 已提交
840 841 842
	return ret;
}

843
static int wl1251_build_basic_rates(char *rates)
K
Kalle Valo 已提交
844 845 846 847 848 849 850 851 852 853 854
{
	u8 index = 0;

	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
	rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;

	return index;
}

855
static int wl1251_build_extended_rates(char *rates)
K
Kalle Valo 已提交
856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871
{
	u8 index = 0;

	rates[index++] = IEEE80211_OFDM_RATE_6MB;
	rates[index++] = IEEE80211_OFDM_RATE_9MB;
	rates[index++] = IEEE80211_OFDM_RATE_12MB;
	rates[index++] = IEEE80211_OFDM_RATE_18MB;
	rates[index++] = IEEE80211_OFDM_RATE_24MB;
	rates[index++] = IEEE80211_OFDM_RATE_36MB;
	rates[index++] = IEEE80211_OFDM_RATE_48MB;
	rates[index++] = IEEE80211_OFDM_RATE_54MB;

	return index;
}


872
static int wl1251_build_probe_req(struct wl1251 *wl, u8 *ssid, size_t ssid_len)
K
Kalle Valo 已提交
873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898
{
	struct wl12xx_probe_req_template template;
	struct wl12xx_ie_rates *rates;
	char *ptr;
	u16 size;

	ptr = (char *)&template;
	size = sizeof(struct ieee80211_header);

	memset(template.header.da, 0xff, ETH_ALEN);
	memset(template.header.bssid, 0xff, ETH_ALEN);
	memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
	template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);

	/* IEs */
	/* SSID */
	template.ssid.header.id = WLAN_EID_SSID;
	template.ssid.header.len = ssid_len;
	if (ssid_len && ssid)
		memcpy(template.ssid.ssid, ssid, ssid_len);
	size += sizeof(struct wl12xx_ie_header) + ssid_len;
	ptr += size;

	/* Basic Rates */
	rates = (struct wl12xx_ie_rates *)ptr;
	rates->header.id = WLAN_EID_SUPP_RATES;
899
	rates->header.len = wl1251_build_basic_rates(rates->rates);
K
Kalle Valo 已提交
900 901 902 903 904 905
	size += sizeof(struct wl12xx_ie_header) + rates->header.len;
	ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;

	/* Extended rates */
	rates = (struct wl12xx_ie_rates *)ptr;
	rates->header.id = WLAN_EID_EXT_SUPP_RATES;
906
	rates->header.len = wl1251_build_extended_rates(rates->rates);
K
Kalle Valo 已提交
907 908
	size += sizeof(struct wl12xx_ie_header) + rates->header.len;

909
	wl1251_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
K
Kalle Valo 已提交
910

911
	return wl1251_cmd_template_set(wl, CMD_PROBE_REQ, &template,
K
Kalle Valo 已提交
912 913 914
				      size);
}

915
static int wl1251_hw_scan(struct wl1251 *wl, u8 *ssid, size_t len,
K
Kalle Valo 已提交
916 917 918
			  u8 active_scan, u8 high_prio, u8 num_channels,
			  u8 probe_requests)
{
919
	struct wl1251_cmd_trigger_scan_to *trigger = NULL;
920
	struct cmd_scan *params = NULL;
K
Kalle Valo 已提交
921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969
	int i, ret;
	u16 scan_options = 0;

	if (wl->scanning)
		return -EINVAL;

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

	params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
	params->params.rx_filter_options =
		cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);

	/* High priority scan */
	if (!active_scan)
		scan_options |= SCAN_PASSIVE;
	if (high_prio)
		scan_options |= SCAN_PRIORITY_HIGH;
	params->params.scan_options = scan_options;

	params->params.num_channels = num_channels;
	params->params.num_probe_requests = probe_requests;
	params->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
	params->params.tid_trigger = 0;

	for (i = 0; i < num_channels; i++) {
		params->channels[i].min_duration = cpu_to_le32(30000);
		params->channels[i].max_duration = cpu_to_le32(60000);
		memset(&params->channels[i].bssid_lsb, 0xff, 4);
		memset(&params->channels[i].bssid_msb, 0xff, 2);
		params->channels[i].early_termination = 0;
		params->channels[i].tx_power_att = 0;
		params->channels[i].channel = i + 1;
		memset(params->channels[i].pad, 0, 3);
	}

	for (i = num_channels; i < SCAN_MAX_NUM_OF_CHANNELS; i++)
		memset(&params->channels[i], 0,
		       sizeof(struct basic_scan_channel_parameters));

	if (len && ssid) {
		params->params.ssid_len = len;
		memcpy(params->params.ssid, ssid, len);
	} else {
		params->params.ssid_len = 0;
		memset(params->params.ssid, 0, 32);
	}

970
	ret = wl1251_build_probe_req(wl, ssid, len);
K
Kalle Valo 已提交
971
	if (ret < 0) {
972
		wl1251_error("PROBE request template failed");
K
Kalle Valo 已提交
973 974 975
		goto out;
	}

976 977 978 979 980 981
	trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
	if (!trigger)
		goto out;

	trigger->timeout = 0;

982
	ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
983
			      sizeof(*trigger));
K
Kalle Valo 已提交
984
	if (ret < 0) {
985
		wl1251_error("trigger scan to failed for hw scan");
K
Kalle Valo 已提交
986 987 988
		goto out;
	}

989
	wl1251_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
K
Kalle Valo 已提交
990 991 992

	wl->scanning = true;

993
	ret = wl1251_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
K
Kalle Valo 已提交
994
	if (ret < 0)
995
		wl1251_error("SCAN failed");
K
Kalle Valo 已提交
996

997
	wl1251_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
K
Kalle Valo 已提交
998

999
	if (params->header.status != CMD_STATUS_SUCCESS) {
1000
		wl1251_error("TEST command answer error: %d",
1001
			     params->header.status);
K
Kalle Valo 已提交
1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
		wl->scanning = false;
		ret = -EIO;
		goto out;
	}

out:
	kfree(params);
	return ret;

}

1013
static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
K
Kalle Valo 已提交
1014 1015
			     struct cfg80211_scan_request *req)
{
1016
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
1017 1018 1019 1020
	int ret;
	u8 *ssid = NULL;
	size_t ssid_len = 0;

1021
	wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
K
Kalle Valo 已提交
1022 1023 1024 1025 1026 1027 1028

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

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

1030
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
1031 1032
	if (ret < 0)
		goto out;
1033

1034
	ret = wl1251_hw_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
1035

1036
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
1037 1038

out:
K
Kalle Valo 已提交
1039 1040 1041 1042 1043
	mutex_unlock(&wl->mutex);

	return ret;
}

1044
static int wl1251_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
K
Kalle Valo 已提交
1045
{
1046
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
1047 1048
	int ret;

1049 1050
	mutex_lock(&wl->mutex);

1051
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
1052 1053
	if (ret < 0)
		goto out;
1054

1055
	ret = wl1251_acx_rts_threshold(wl, (u16) value);
K
Kalle Valo 已提交
1056
	if (ret < 0)
1057
		wl1251_warning("wl1251_op_set_rts_threshold failed: %d", ret);
K
Kalle Valo 已提交
1058

1059
	wl1251_ps_elp_sleep(wl);
1060

K
Kalle Valo 已提交
1061
out:
1062 1063
	mutex_unlock(&wl->mutex);

K
Kalle Valo 已提交
1064 1065 1066
	return ret;
}

1067
static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
K
Kalle Valo 已提交
1068 1069 1070 1071
				       struct ieee80211_vif *vif,
				       struct ieee80211_bss_conf *bss_conf,
				       u32 changed)
{
1072 1073
	enum wl1251_cmd_ps_mode mode;
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
1074 1075 1076
	struct sk_buff *beacon;
	int ret;

1077
	wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
K
Kalle Valo 已提交
1078 1079 1080

	mutex_lock(&wl->mutex);

1081
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
1082 1083
	if (ret < 0)
		goto out;
1084

K
Kalle Valo 已提交
1085 1086
	if (changed & BSS_CHANGED_ASSOC) {
		if (bss_conf->assoc) {
1087 1088 1089 1090 1091
			wl->beacon_int = bss_conf->beacon_int;
			wl->dtim_period = bss_conf->dtim_period;

			/* FIXME: call join */

K
Kalle Valo 已提交
1092 1093
			wl->aid = bss_conf->aid;

1094
			ret = wl1251_build_ps_poll(wl, wl->aid);
K
Kalle Valo 已提交
1095
			if (ret < 0)
K
Kalle Valo 已提交
1096
				goto out_sleep;
K
Kalle Valo 已提交
1097

1098
			ret = wl1251_acx_aid(wl, wl->aid);
K
Kalle Valo 已提交
1099
			if (ret < 0)
K
Kalle Valo 已提交
1100
				goto out_sleep;
K
Kalle Valo 已提交
1101 1102 1103 1104

			/* If we want to go in PSM but we're not there yet */
			if (wl->psm_requested && !wl->psm) {
				mode = STATION_POWER_SAVE_MODE;
1105
				ret = wl1251_ps_set_mode(wl, mode);
K
Kalle Valo 已提交
1106
				if (ret < 0)
K
Kalle Valo 已提交
1107
					goto out_sleep;
K
Kalle Valo 已提交
1108
			}
1109 1110 1111 1112
		} else {
			/* use defaults when not associated */
			wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
			wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
K
Kalle Valo 已提交
1113 1114 1115 1116
		}
	}
	if (changed & BSS_CHANGED_ERP_SLOT) {
		if (bss_conf->use_short_slot)
1117
			ret = wl1251_acx_slot(wl, SLOT_TIME_SHORT);
K
Kalle Valo 已提交
1118
		else
1119
			ret = wl1251_acx_slot(wl, SLOT_TIME_LONG);
K
Kalle Valo 已提交
1120
		if (ret < 0) {
1121
			wl1251_warning("Set slot time failed %d", ret);
K
Kalle Valo 已提交
1122
			goto out_sleep;
K
Kalle Valo 已提交
1123 1124 1125 1126 1127
		}
	}

	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
		if (bss_conf->use_short_preamble)
1128
			wl1251_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
K
Kalle Valo 已提交
1129
		else
1130
			wl1251_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
K
Kalle Valo 已提交
1131 1132 1133 1134
	}

	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
		if (bss_conf->use_cts_prot)
1135
			ret = wl1251_acx_cts_protect(wl, CTSPROTECT_ENABLE);
K
Kalle Valo 已提交
1136
		else
1137
			ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE);
K
Kalle Valo 已提交
1138
		if (ret < 0) {
1139 1140
			wl1251_warning("Set ctsprotect failed %d", ret);
			goto out;
K
Kalle Valo 已提交
1141 1142 1143 1144 1145 1146
		}
	}

	if (changed & BSS_CHANGED_BSSID) {
		memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);

1147
		ret = wl1251_build_null_data(wl);
K
Kalle Valo 已提交
1148 1149 1150 1151
		if (ret < 0)
			goto out;

		if (wl->bss_type != BSS_TYPE_IBSS) {
K
Kalle Valo 已提交
1152 1153
			ret = wl1251_join(wl, wl->bss_type, wl->channel,
					  wl->beacon_int, wl->dtim_period);
K
Kalle Valo 已提交
1154
			if (ret < 0)
1155 1156 1157
				goto out_sleep;
			wl1251_warning("Set ctsprotect failed %d", ret);
			goto out_sleep;
K
Kalle Valo 已提交
1158 1159 1160 1161 1162
		}
	}

	if (changed & BSS_CHANGED_BEACON) {
		beacon = ieee80211_beacon_get(hw, vif);
1163
		ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data,
K
Kalle Valo 已提交
1164 1165 1166 1167 1168 1169 1170
					      beacon->len);

		if (ret < 0) {
			dev_kfree_skb(beacon);
			goto out;
		}

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

		dev_kfree_skb(beacon);

		if (ret < 0)
			goto out;

K
Kalle Valo 已提交
1179 1180
		ret = wl1251_join(wl, wl->bss_type, wl->beacon_int,
				  wl->channel, wl->dtim_period);
K
Kalle Valo 已提交
1181 1182 1183 1184 1185

		if (ret < 0)
			goto out;
	}

K
Kalle Valo 已提交
1186
out_sleep:
1187
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
1188 1189

out:
K
Kalle Valo 已提交
1190 1191 1192 1193 1194
	mutex_unlock(&wl->mutex);
}


/* can't be const, mac80211 writes to this */
1195
static struct ieee80211_rate wl1251_rates[] = {
K
Kalle Valo 已提交
1196 1197 1198 1199 1200 1201 1202 1203 1204 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
	{ .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 */
1238
static struct ieee80211_channel wl1251_channels[] = {
K
Kalle Valo 已提交
1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254
	{ .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},
};

/* can't be const, mac80211 writes to this */
1255 1256 1257 1258 1259
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 已提交
1260 1261
};

1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273
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,
	.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,
K
Kalle Valo 已提交
1274 1275
};

1276
static int wl1251_register_hw(struct wl1251 *wl)
K
Kalle Valo 已提交
1277 1278 1279 1280 1281 1282 1283 1284 1285 1286
{
	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) {
1287
		wl1251_error("unable to register mac80211 hw: %d", ret);
K
Kalle Valo 已提交
1288 1289 1290 1291 1292
		return ret;
	}

	wl->mac80211_registered = true;

1293
	wl1251_notice("loaded");
K
Kalle Valo 已提交
1294 1295 1296 1297

	return 0;
}

1298
int wl1251_init_ieee80211(struct wl1251 *wl)
K
Kalle Valo 已提交
1299
{
1300 1301
	int ret;

K
Kalle Valo 已提交
1302 1303
	/* The tx descriptor buffer and the TKIP space */
	wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
1304
		+ WL1251_TKIP_IV_SPACE;
K
Kalle Valo 已提交
1305 1306 1307 1308 1309 1310 1311 1312 1313 1314

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

	wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
		IEEE80211_HW_NOISE_DBM;

	wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
	wl->hw->wiphy->max_scan_ssids = 1;
1315
	wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
K
Kalle Valo 已提交
1316

1317 1318 1319
	ret = wl1251_register_hw(wl);
	if (ret)
		goto out;
K
Kalle Valo 已提交
1320

1321 1322
	wl1251_debugfs_init(wl);
	wl1251_notice("initialized");
K
Kalle Valo 已提交
1323

1324 1325 1326 1327 1328
	ret = 0;

out:
	return ret;
}
1329
EXPORT_SYMBOL_GPL(wl1251_init_ieee80211);
1330

1331
struct ieee80211_hw *wl1251_alloc_hw(void)
K
Kalle Valo 已提交
1332 1333
{
	struct ieee80211_hw *hw;
1334
	struct wl1251 *wl;
1335
	int i;
K
Kalle Valo 已提交
1336 1337
	static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};

1338
	hw = ieee80211_alloc_hw(sizeof(*wl), &wl1251_ops);
K
Kalle Valo 已提交
1339
	if (!hw) {
1340
		wl1251_error("could not alloc ieee80211_hw");
1341
		return ERR_PTR(-ENOMEM);
K
Kalle Valo 已提交
1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352
	}

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

	wl->hw = hw;

	wl->data_in_count = 0;

	skb_queue_head_init(&wl->tx_queue);

1353 1354
	INIT_WORK(&wl->filter_work, wl1251_filter_work);
	wl->channel = WL1251_DEFAULT_CHANNEL;
K
Kalle Valo 已提交
1355 1356 1357 1358 1359 1360 1361
	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;
1362 1363
	wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
	wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
K
Kalle Valo 已提交
1364 1365 1366 1367
	wl->elp = false;
	wl->psm = 0;
	wl->psm_requested = false;
	wl->tx_queue_stopped = false;
1368
	wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
1369 1370
	wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
	wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
K
Kalle Valo 已提交
1371 1372 1373 1374 1375 1376

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

	wl->next_tx_complete = 0;

K
Kalle Valo 已提交
1377 1378 1379
	INIT_WORK(&wl->irq_work, wl1251_irq_work);
	INIT_WORK(&wl->tx_work, wl1251_tx_work);

K
Kalle Valo 已提交
1380 1381 1382 1383 1384 1385 1386
	/*
	 * 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);

1387
	wl->state = WL1251_STATE_OFF;
K
Kalle Valo 已提交
1388 1389 1390 1391 1392
	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 已提交
1393 1394
	wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL);
	if (!wl->rx_descriptor) {
1395
		wl1251_error("could not allocate memory for rx descriptor");
1396 1397
		ieee80211_free_hw(hw);
		return ERR_PTR(-ENOMEM);
K
Kalle Valo 已提交
1398 1399
	}

1400
	return hw;
K
Kalle Valo 已提交
1401
}
1402
EXPORT_SYMBOL_GPL(wl1251_alloc_hw);
K
Kalle Valo 已提交
1403

1404
int wl1251_free_hw(struct wl1251 *wl)
K
Kalle Valo 已提交
1405 1406 1407
{
	ieee80211_unregister_hw(wl->hw);

1408
	wl1251_debugfs_exit(wl);
K
Kalle Valo 已提交
1409 1410 1411 1412 1413 1414 1415

	kfree(wl->target_mem_map);
	kfree(wl->data_path);
	kfree(wl->fw);
	wl->fw = NULL;
	kfree(wl->nvs);
	wl->nvs = NULL;
K
Kalle Valo 已提交
1416 1417 1418 1419

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

K
Kalle Valo 已提交
1420 1421 1422 1423
	ieee80211_free_hw(wl->hw);

	return 0;
}
1424 1425 1426 1427
EXPORT_SYMBOL_GPL(wl1251_free_hw);

MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core");
MODULE_LICENSE("GPL");
1428
MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
1429
MODULE_ALIAS("spi:wl12xx");