wl1251_main.c 31.1 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 32 33
 *
 * 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/spi/spi.h>
#include <linux/crc32.h>
#include <linux/etherdevice.h>
#include <linux/spi/wl12xx.h>

K
Kalle Valo 已提交
34
#include "wl1251.h"
K
Kalle Valo 已提交
35 36
#include "wl12xx_80211.h"
#include "reg.h"
37
#include "wl1251_ops.h"
38
#include "wl1251_io.h"
39 40
#include "wl1251_spi.h"
#include "wl1251_event.h"
41
#include "wl1251_tx.h"
42 43 44 45
#include "wl1251_rx.h"
#include "wl1251_ps.h"
#include "wl1251_init.h"
#include "wl1251_debugfs.h"
K
Kalle Valo 已提交
46

47
static void wl1251_disable_interrupts(struct wl1251 *wl)
K
Kalle Valo 已提交
48 49 50 51
{
	disable_irq(wl->irq);
}

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

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

62
static irqreturn_t wl1251_irq(int irq, void *cookie)
K
Kalle Valo 已提交
63
{
64
	struct wl1251 *wl;
K
Kalle Valo 已提交
65

66
	wl1251_debug(DEBUG_IRQ, "IRQ");
K
Kalle Valo 已提交
67 68 69 70 71 72 73 74

	wl = cookie;

	schedule_work(&wl->irq_work);

	return IRQ_HANDLED;
}

75
static int wl1251_fetch_firmware(struct wl1251 *wl)
K
Kalle Valo 已提交
76 77
{
	const struct firmware *fw;
78
	struct device *dev = wiphy_dev(wl->hw->wiphy);
K
Kalle Valo 已提交
79 80
	int ret;

81
	ret = request_firmware(&fw, wl->chip.fw_filename, dev);
K
Kalle Valo 已提交
82 83

	if (ret < 0) {
84
		wl1251_error("could not get firmware: %d", ret);
K
Kalle Valo 已提交
85 86 87 88
		return ret;
	}

	if (fw->size % 4) {
89
		wl1251_error("firmware size is not multiple of 32 bits: %zu",
K
Kalle Valo 已提交
90 91 92 93 94 95 96 97 98
			     fw->size);
		ret = -EILSEQ;
		goto out;
	}

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

	if (!wl->fw) {
99
		wl1251_error("could not allocate memory for the firmware");
K
Kalle Valo 已提交
100 101 102 103 104 105 106 107 108 109 110 111 112 113
		ret = -ENOMEM;
		goto out;
	}

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

	ret = 0;

out:
	release_firmware(fw);

	return ret;
}

114
static int wl1251_fetch_nvs(struct wl1251 *wl)
K
Kalle Valo 已提交
115 116
{
	const struct firmware *fw;
117
	struct device *dev = wiphy_dev(wl->hw->wiphy);
K
Kalle Valo 已提交
118 119
	int ret;

120
	ret = request_firmware(&fw, wl->chip.nvs_filename, dev);
K
Kalle Valo 已提交
121 122

	if (ret < 0) {
123
		wl1251_error("could not get nvs file: %d", ret);
K
Kalle Valo 已提交
124 125 126 127
		return ret;
	}

	if (fw->size % 4) {
128
		wl1251_error("nvs size is not multiple of 32 bits: %zu",
K
Kalle Valo 已提交
129 130 131 132 133 134 135 136 137
			     fw->size);
		ret = -EILSEQ;
		goto out;
	}

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

	if (!wl->nvs) {
138
		wl1251_error("could not allocate memory for the nvs file");
K
Kalle Valo 已提交
139 140 141 142 143 144 145 146 147 148 149 150 151 152
		ret = -ENOMEM;
		goto out;
	}

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

	ret = 0;

out:
	release_firmware(fw);

	return ret;
}

153
static void wl1251_fw_wakeup(struct wl1251 *wl)
K
Kalle Valo 已提交
154 155 156 157
{
	u32 elp_reg;

	elp_reg = ELPCTRL_WAKE_UP;
158 159
	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 已提交
160

K
Kalle Valo 已提交
161
	if (!(elp_reg & ELPCTRL_WLAN_READY))
162
		wl1251_warning("WLAN not ready");
K
Kalle Valo 已提交
163 164
}

165
static int wl1251_chip_wakeup(struct wl1251 *wl)
K
Kalle Valo 已提交
166 167 168
{
	int ret = 0;

169
	wl1251_power_on(wl);
K
Kalle Valo 已提交
170
	msleep(wl->chip.power_on_sleep);
171 172
	wl1251_spi_reset(wl);
	wl1251_spi_init(wl);
K
Kalle Valo 已提交
173 174 175

	/* We don't need a real memory partition here, because we only want
	 * to use the registers at this point. */
176
	wl1251_set_partition(wl,
K
Kalle Valo 已提交
177 178 179 180 181 182
			     0x00000000,
			     0x00000000,
			     REGISTERS_BASE,
			     REGISTERS_DOWN_SIZE);

	/* ELP module wake up */
183
	wl1251_fw_wakeup(wl);
K
Kalle Valo 已提交
184 185 186 187

	/* whal_FwCtrl_BootSm() */

	/* 0. read chip id from CHIP_ID */
188
	wl->chip.id = wl1251_reg_read32(wl, CHIP_ID_B);
K
Kalle Valo 已提交
189 190 191 192 193

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

	switch (wl->chip.id) {
	case CHIP_ID_1251_PG12:
194
		wl1251_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)",
K
Kalle Valo 已提交
195 196 197 198 199 200 201 202
			     wl->chip.id);

		wl1251_setup(wl);

		break;
	case CHIP_ID_1251_PG10:
	case CHIP_ID_1251_PG11:
	default:
203
		wl1251_error("unsupported chip id: 0x%x", wl->chip.id);
K
Kalle Valo 已提交
204 205 206 207 208
		ret = -ENODEV;
		goto out;
	}

	if (wl->fw == NULL) {
209
		ret = wl1251_fetch_firmware(wl);
K
Kalle Valo 已提交
210 211 212 213 214 215
		if (ret < 0)
			goto out;
	}

	/* No NVS from netlink, try to get it from the filesystem */
	if (wl->nvs == NULL) {
216
		ret = wl1251_fetch_nvs(wl);
K
Kalle Valo 已提交
217 218 219 220 221 222 223 224
		if (ret < 0)
			goto out;
	}

out:
	return ret;
}

225
static void wl1251_filter_work(struct work_struct *work)
K
Kalle Valo 已提交
226
{
227 228
	struct wl1251 *wl =
		container_of(work, struct wl1251, filter_work);
K
Kalle Valo 已提交
229 230 231 232
	int ret;

	mutex_lock(&wl->mutex);

233
	if (wl->state == WL1251_STATE_OFF)
K
Kalle Valo 已提交
234 235
		goto out;

236
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
237 238
	if (ret < 0)
		goto out;
239

240 241
	/* FIXME: replace the magic numbers with proper definitions */
	ret = wl->chip.op_cmd_join(wl, wl->bss_type, 1, 100, 0);
K
Kalle Valo 已提交
242
	if (ret < 0)
K
Kalle Valo 已提交
243
		goto out_sleep;
K
Kalle Valo 已提交
244

K
Kalle Valo 已提交
245
out_sleep:
246
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
247 248

out:
K
Kalle Valo 已提交
249 250 251
	mutex_unlock(&wl->mutex);
}

252
static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
K
Kalle Valo 已提交
253
{
254
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
255 256 257

	skb_queue_tail(&wl->tx_queue, skb);

258 259 260 261 262
	/*
	 * The chip specific setup must run before the first TX packet -
	 * before that, the tx_work will not be initialized!
	 */

K
Kalle Valo 已提交
263 264 265 266 267 268
	schedule_work(&wl->tx_work);

	/*
	 * The workqueue is slow to process the tx_queue and we need stop
	 * the queue here, otherwise the queue will get too long.
	 */
269
	if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) {
K
Kalle Valo 已提交
270 271 272 273 274 275 276 277 278 279 280 281 282
		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;
}

283
static int wl1251_op_start(struct ieee80211_hw *hw)
K
Kalle Valo 已提交
284
{
285
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
286 287
	int ret = 0;

288
	wl1251_debug(DEBUG_MAC80211, "mac80211 start");
K
Kalle Valo 已提交
289 290 291

	mutex_lock(&wl->mutex);

292 293
	if (wl->state != WL1251_STATE_OFF) {
		wl1251_error("cannot start because not in off state: %d",
K
Kalle Valo 已提交
294 295 296 297 298
			     wl->state);
		ret = -EBUSY;
		goto out;
	}

299
	ret = wl1251_chip_wakeup(wl);
K
Kalle Valo 已提交
300
	if (ret < 0)
301
		goto out;
K
Kalle Valo 已提交
302 303 304 305 306 307 308 309 310

	ret = wl->chip.op_boot(wl);
	if (ret < 0)
		goto out;

	ret = wl->chip.op_hw_init(wl);
	if (ret < 0)
		goto out;

311
	ret = wl1251_acx_station_id(wl);
K
Kalle Valo 已提交
312 313 314
	if (ret < 0)
		goto out;

315
	wl->state = WL1251_STATE_ON;
K
Kalle Valo 已提交
316

317
	wl1251_info("firmware booted (%s)", wl->chip.fw_ver);
K
Kalle Valo 已提交
318 319 320

out:
	if (ret < 0)
321
		wl1251_power_off(wl);
K
Kalle Valo 已提交
322 323 324 325 326 327

	mutex_unlock(&wl->mutex);

	return ret;
}

328
static void wl1251_op_stop(struct ieee80211_hw *hw)
K
Kalle Valo 已提交
329
{
330
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
331

332
	wl1251_info("down");
K
Kalle Valo 已提交
333

334
	wl1251_debug(DEBUG_MAC80211, "mac80211 stop");
K
Kalle Valo 已提交
335 336 337

	mutex_lock(&wl->mutex);

338
	WARN_ON(wl->state != WL1251_STATE_ON);
K
Kalle Valo 已提交
339 340 341 342 343 344 345 346

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

347
	wl->state = WL1251_STATE_OFF;
K
Kalle Valo 已提交
348

349
	wl1251_disable_interrupts(wl);
K
Kalle Valo 已提交
350 351 352 353 354 355 356 357 358 359

	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 */
360
	wl->chip.op_tx_flush(wl);
361
	wl1251_power_off(wl);
K
Kalle Valo 已提交
362 363 364 365 366 367 368 369 370 371 372 373 374 375

	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;
376
	wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
K
Kalle Valo 已提交
377

378
	wl1251_debugfs_reset(wl);
K
Kalle Valo 已提交
379 380 381 382

	mutex_unlock(&wl->mutex);
}

383
static int wl1251_op_add_interface(struct ieee80211_hw *hw,
K
Kalle Valo 已提交
384 385
				   struct ieee80211_if_init_conf *conf)
{
386
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
387 388
	int ret = 0;

J
Johannes Berg 已提交
389 390
	wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
		     conf->type, conf->mac_addr);
K
Kalle Valo 已提交
391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408

	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);
409
		ret = wl1251_acx_station_id(wl);
K
Kalle Valo 已提交
410 411 412 413 414 415 416 417 418
		if (ret < 0)
			goto out;
	}

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

419
static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
K
Kalle Valo 已提交
420 421
					 struct ieee80211_if_init_conf *conf)
{
422
	wl1251_debug(DEBUG_MAC80211, "mac80211 remove interface");
K
Kalle Valo 已提交
423 424
}

425
static int wl1251_build_null_data(struct wl1251 *wl)
K
Kalle Valo 已提交
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
{
	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);

441
	return wl1251_cmd_template_set(wl, CMD_NULL_DATA, &template,
K
Kalle Valo 已提交
442 443 444 445
				       sizeof(template));

}

446
static int wl1251_build_ps_poll(struct wl1251 *wl, u16 aid)
K
Kalle Valo 已提交
447 448 449 450 451 452 453 454
{
	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);

455
	return wl1251_cmd_template_set(wl, CMD_PS_POLL, &template,
K
Kalle Valo 已提交
456 457 458 459
				       sizeof(template));

}

460
static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
K
Kalle Valo 已提交
461
{
462
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
463 464 465 466 467
	struct ieee80211_conf *conf = &hw->conf;
	int channel, ret = 0;

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

468
	wl1251_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
K
Kalle Valo 已提交
469 470 471 472 473 474
		     channel,
		     conf->flags & IEEE80211_CONF_PS ? "on" : "off",
		     conf->power_level);

	mutex_lock(&wl->mutex);

475
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
476 477
	if (ret < 0)
		goto out;
478

K
Kalle Valo 已提交
479 480
	if (channel != wl->channel) {
		/* FIXME: use beacon interval provided by mac80211 */
481
		ret = wl->chip.op_cmd_join(wl, wl->bss_type, 1, 100, 0);
K
Kalle Valo 已提交
482
		if (ret < 0)
K
Kalle Valo 已提交
483
			goto out_sleep;
K
Kalle Valo 已提交
484 485 486 487

		wl->channel = channel;
	}

488
	ret = wl1251_build_null_data(wl);
K
Kalle Valo 已提交
489
	if (ret < 0)
K
Kalle Valo 已提交
490
		goto out_sleep;
K
Kalle Valo 已提交
491 492

	if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
493
		wl1251_debug(DEBUG_PSM, "psm enabled");
K
Kalle Valo 已提交
494 495 496 497 498 499 500 501

		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.
		 */
502
		ret = wl1251_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
K
Kalle Valo 已提交
503 504
	} else if (!(conf->flags & IEEE80211_CONF_PS) &&
		   wl->psm_requested) {
505
		wl1251_debug(DEBUG_PSM, "psm disabled");
K
Kalle Valo 已提交
506 507 508 509

		wl->psm_requested = false;

		if (wl->psm)
510
			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
K
Kalle Valo 已提交
511 512 513
	}

	if (conf->power_level != wl->power_level) {
514
		ret = wl1251_acx_tx_power(wl, conf->power_level);
K
Kalle Valo 已提交
515 516 517 518 519 520
		if (ret < 0)
			goto out;

		wl->power_level = conf->power_level;
	}

K
Kalle Valo 已提交
521
out_sleep:
522
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
523 524

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

K
Kalle Valo 已提交
527 528 529
	return ret;
}

530
#define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
K
Kalle Valo 已提交
531 532 533 534 535 536
				  FIF_ALLMULTI | \
				  FIF_FCSFAIL | \
				  FIF_BCN_PRBRESP_PROMISC | \
				  FIF_CONTROL | \
				  FIF_OTHER_BSS)

537
static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
K
Kalle Valo 已提交
538 539 540 541 542
				       unsigned int changed,
				       unsigned int *total,
				       int mc_count,
				       struct dev_addr_list *mc_list)
{
543
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
544

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

547 548
	*total &= WL1251_SUPPORTED_FILTERS;
	changed &= WL1251_SUPPORTED_FILTERS;
K
Kalle Valo 已提交
549 550 551 552 553 554 555

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

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

556 557
	wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
	wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
K
Kalle Valo 已提交
558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588

	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 */
589 590
static int wl1251_set_key_type(struct wl1251 *wl,
			       struct wl1251_cmd_set_keys *key,
K
Kalle Valo 已提交
591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619
			       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:
620
		wl1251_error("Unknown key algo 0x%x", mac80211_key->alg);
K
Kalle Valo 已提交
621 622 623 624 625 626
		return -EOPNOTSUPP;
	}

	return 0;
}

627
static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
K
Kalle Valo 已提交
628 629 630 631
			     struct ieee80211_vif *vif,
			     struct ieee80211_sta *sta,
			     struct ieee80211_key_conf *key)
{
632 633
	struct wl1251 *wl = hw->priv;
	struct wl1251_cmd_set_keys *wl_cmd;
K
Kalle Valo 已提交
634 635 636 637 638 639
	const u8 *addr;
	int ret;

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

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

642 643 644 645 646
	wl_cmd = kzalloc(sizeof(*wl_cmd), GFP_KERNEL);
	if (!wl_cmd) {
		ret = -ENOMEM;
		goto out;
	}
K
Kalle Valo 已提交
647 648 649

	addr = sta ? sta->addr : bcast_addr;

650 651 652
	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 已提交
653
		     key->alg, key->keyidx, key->keylen, key->flags);
654
	wl1251_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
K
Kalle Valo 已提交
655

656 657 658 659 660 661
	if (is_zero_ether_addr(addr)) {
		/* We dont support TX only encryption */
		ret = -EOPNOTSUPP;
		goto out;
	}

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

664
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
665 666
	if (ret < 0)
		goto out_unlock;
667

K
Kalle Valo 已提交
668 669
	switch (cmd) {
	case SET_KEY:
670
		wl_cmd->key_action = KEY_ADD_OR_REPLACE;
K
Kalle Valo 已提交
671 672
		break;
	case DISABLE_KEY:
673
		wl_cmd->key_action = KEY_REMOVE;
K
Kalle Valo 已提交
674 675
		break;
	default:
676
		wl1251_error("Unsupported key cmd 0x%x", cmd);
K
Kalle Valo 已提交
677 678 679
		break;
	}

680
	ret = wl1251_set_key_type(wl, wl_cmd, cmd, key, addr);
K
Kalle Valo 已提交
681
	if (ret < 0) {
682
		wl1251_error("Set KEY type failed");
K
Kalle Valo 已提交
683
		goto out_sleep;
K
Kalle Valo 已提交
684 685
	}

686 687
	if (wl_cmd->key_type != KEY_WEP_DEFAULT)
		memcpy(wl_cmd->addr, addr, ETH_ALEN);
K
Kalle Valo 已提交
688

689 690
	if ((wl_cmd->key_type == KEY_TKIP_MIC_GROUP) ||
	    (wl_cmd->key_type == KEY_TKIP_MIC_PAIRWISE)) {
K
Kalle Valo 已提交
691 692 693 694 695 696
		/*
		 * 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
		 */
697 698 699
		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 已提交
700 701

	} else {
702
		memcpy(wl_cmd->key, key->key, key->keylen);
K
Kalle Valo 已提交
703
	}
704
	wl_cmd->key_size = key->keylen;
K
Kalle Valo 已提交
705

706 707
	wl_cmd->id = key->keyidx;
	wl_cmd->ssid_profile = 0;
K
Kalle Valo 已提交
708

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

711
	ret = wl1251_cmd_send(wl, CMD_SET_KEYS, wl_cmd, sizeof(*wl_cmd));
712
	if (ret < 0) {
713
		wl1251_warning("could not set keys");
K
Kalle Valo 已提交
714
		goto out_sleep;
K
Kalle Valo 已提交
715 716
	}

K
Kalle Valo 已提交
717
out_sleep:
718
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
719 720

out_unlock:
K
Kalle Valo 已提交
721
	mutex_unlock(&wl->mutex);
722 723 724 725

out:
	kfree(wl_cmd);

K
Kalle Valo 已提交
726 727 728
	return ret;
}

729
static int wl1251_build_basic_rates(char *rates)
K
Kalle Valo 已提交
730 731 732 733 734 735 736 737 738 739 740
{
	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;
}

741
static int wl1251_build_extended_rates(char *rates)
K
Kalle Valo 已提交
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
{
	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;
}


758
static int wl1251_build_probe_req(struct wl1251 *wl, u8 *ssid, size_t ssid_len)
K
Kalle Valo 已提交
759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
{
	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;
785
	rates->header.len = wl1251_build_basic_rates(rates->rates);
K
Kalle Valo 已提交
786 787 788 789 790 791
	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;
792
	rates->header.len = wl1251_build_extended_rates(rates->rates);
K
Kalle Valo 已提交
793 794
	size += sizeof(struct wl12xx_ie_header) + rates->header.len;

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

797
	return wl1251_cmd_template_set(wl, CMD_PROBE_REQ, &template,
K
Kalle Valo 已提交
798 799 800
				      size);
}

801
static int wl1251_hw_scan(struct wl1251 *wl, u8 *ssid, size_t len,
K
Kalle Valo 已提交
802 803 804
			  u8 active_scan, u8 high_prio, u8 num_channels,
			  u8 probe_requests)
{
805
	struct wl1251_cmd_trigger_scan_to *trigger = NULL;
806
	struct cmd_scan *params = NULL;
K
Kalle Valo 已提交
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855
	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);
	}

856
	ret = wl1251_build_probe_req(wl, ssid, len);
K
Kalle Valo 已提交
857
	if (ret < 0) {
858
		wl1251_error("PROBE request template failed");
K
Kalle Valo 已提交
859 860 861
		goto out;
	}

862 863 864 865 866 867
	trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
	if (!trigger)
		goto out;

	trigger->timeout = 0;

868
	ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
869
			      sizeof(*trigger));
K
Kalle Valo 已提交
870
	if (ret < 0) {
871
		wl1251_error("trigger scan to failed for hw scan");
K
Kalle Valo 已提交
872 873 874
		goto out;
	}

875
	wl1251_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
K
Kalle Valo 已提交
876 877 878

	wl->scanning = true;

879
	ret = wl1251_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
K
Kalle Valo 已提交
880
	if (ret < 0)
881
		wl1251_error("SCAN failed");
K
Kalle Valo 已提交
882

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

885
	if (params->header.status != CMD_STATUS_SUCCESS) {
886
		wl1251_error("TEST command answer error: %d",
887
			     params->header.status);
K
Kalle Valo 已提交
888 889 890 891 892 893 894 895 896 897 898
		wl->scanning = false;
		ret = -EIO;
		goto out;
	}

out:
	kfree(params);
	return ret;

}

899
static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
K
Kalle Valo 已提交
900 901
			     struct cfg80211_scan_request *req)
{
902
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
903 904 905 906
	int ret;
	u8 *ssid = NULL;
	size_t ssid_len = 0;

907
	wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
K
Kalle Valo 已提交
908 909 910 911 912 913 914

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

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

916
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
917 918
	if (ret < 0)
		goto out;
919

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

922
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
923 924

out:
K
Kalle Valo 已提交
925 926 927 928 929
	mutex_unlock(&wl->mutex);

	return ret;
}

930
static int wl1251_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
K
Kalle Valo 已提交
931
{
932
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
933 934
	int ret;

935 936
	mutex_lock(&wl->mutex);

937
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
938 939
	if (ret < 0)
		goto out;
940

941
	ret = wl1251_acx_rts_threshold(wl, (u16) value);
K
Kalle Valo 已提交
942
	if (ret < 0)
943
		wl1251_warning("wl1251_op_set_rts_threshold failed: %d", ret);
K
Kalle Valo 已提交
944

945
	wl1251_ps_elp_sleep(wl);
946

K
Kalle Valo 已提交
947
out:
948 949
	mutex_unlock(&wl->mutex);

K
Kalle Valo 已提交
950 951 952
	return ret;
}

953
static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
K
Kalle Valo 已提交
954 955 956 957
				       struct ieee80211_vif *vif,
				       struct ieee80211_bss_conf *bss_conf,
				       u32 changed)
{
958 959
	enum wl1251_cmd_ps_mode mode;
	struct wl1251 *wl = hw->priv;
K
Kalle Valo 已提交
960 961 962
	struct sk_buff *beacon;
	int ret;

963
	wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
K
Kalle Valo 已提交
964 965 966

	mutex_lock(&wl->mutex);

967
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
968 969
	if (ret < 0)
		goto out;
970

K
Kalle Valo 已提交
971 972 973 974
	if (changed & BSS_CHANGED_ASSOC) {
		if (bss_conf->assoc) {
			wl->aid = bss_conf->aid;

975
			ret = wl1251_build_ps_poll(wl, wl->aid);
K
Kalle Valo 已提交
976
			if (ret < 0)
K
Kalle Valo 已提交
977
				goto out_sleep;
K
Kalle Valo 已提交
978

979
			ret = wl1251_acx_aid(wl, wl->aid);
K
Kalle Valo 已提交
980
			if (ret < 0)
K
Kalle Valo 已提交
981
				goto out_sleep;
K
Kalle Valo 已提交
982 983 984 985

			/* If we want to go in PSM but we're not there yet */
			if (wl->psm_requested && !wl->psm) {
				mode = STATION_POWER_SAVE_MODE;
986
				ret = wl1251_ps_set_mode(wl, mode);
K
Kalle Valo 已提交
987
				if (ret < 0)
K
Kalle Valo 已提交
988
					goto out_sleep;
K
Kalle Valo 已提交
989 990 991 992 993
			}
		}
	}
	if (changed & BSS_CHANGED_ERP_SLOT) {
		if (bss_conf->use_short_slot)
994
			ret = wl1251_acx_slot(wl, SLOT_TIME_SHORT);
K
Kalle Valo 已提交
995
		else
996
			ret = wl1251_acx_slot(wl, SLOT_TIME_LONG);
K
Kalle Valo 已提交
997
		if (ret < 0) {
998
			wl1251_warning("Set slot time failed %d", ret);
K
Kalle Valo 已提交
999
			goto out_sleep;
K
Kalle Valo 已提交
1000 1001 1002 1003 1004
		}
	}

	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
		if (bss_conf->use_short_preamble)
1005
			wl1251_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
K
Kalle Valo 已提交
1006
		else
1007
			wl1251_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
K
Kalle Valo 已提交
1008 1009 1010 1011
	}

	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
		if (bss_conf->use_cts_prot)
1012
			ret = wl1251_acx_cts_protect(wl, CTSPROTECT_ENABLE);
K
Kalle Valo 已提交
1013
		else
1014
			ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE);
K
Kalle Valo 已提交
1015
		if (ret < 0) {
1016 1017
			wl1251_warning("Set ctsprotect failed %d", ret);
			goto out;
K
Kalle Valo 已提交
1018 1019 1020 1021 1022 1023
		}
	}

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

1024
		ret = wl1251_build_null_data(wl);
K
Kalle Valo 已提交
1025 1026 1027 1028
		if (ret < 0)
			goto out;

		if (wl->bss_type != BSS_TYPE_IBSS) {
1029
			ret = wl1251_cmd_join(wl, wl->bss_type, 5, 100, 1);
K
Kalle Valo 已提交
1030
			if (ret < 0)
1031 1032 1033
				goto out_sleep;
			wl1251_warning("Set ctsprotect failed %d", ret);
			goto out_sleep;
K
Kalle Valo 已提交
1034 1035 1036 1037 1038
		}
	}

	if (changed & BSS_CHANGED_BEACON) {
		beacon = ieee80211_beacon_get(hw, vif);
1039
		ret = wl1251_cmd_template_set(wl, CMD_BEACON, beacon->data,
K
Kalle Valo 已提交
1040 1041 1042 1043 1044 1045 1046
					      beacon->len);

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

1047
		ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
K
Kalle Valo 已提交
1048 1049 1050 1051 1052 1053 1054
					      beacon->len);

		dev_kfree_skb(beacon);

		if (ret < 0)
			goto out;

1055
		ret = wl->chip.op_cmd_join(wl, wl->bss_type, 1, 100, 0);
K
Kalle Valo 已提交
1056 1057 1058 1059 1060

		if (ret < 0)
			goto out;
	}

K
Kalle Valo 已提交
1061
out_sleep:
1062
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
1063 1064

out:
K
Kalle Valo 已提交
1065 1066 1067 1068 1069
	mutex_unlock(&wl->mutex);
}


/* can't be const, mac80211 writes to this */
1070
static struct ieee80211_rate wl1251_rates[] = {
K
Kalle Valo 已提交
1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
	{ .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 */
1113
static struct ieee80211_channel wl1251_channels[] = {
K
Kalle Valo 已提交
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129
	{ .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 */
1130 1131 1132 1133 1134
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 已提交
1135 1136
};

1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148
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 已提交
1149 1150
};

1151
static int wl1251_register_hw(struct wl1251 *wl)
K
Kalle Valo 已提交
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161
{
	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) {
1162
		wl1251_error("unable to register mac80211 hw: %d", ret);
K
Kalle Valo 已提交
1163 1164 1165 1166 1167
		return ret;
	}

	wl->mac80211_registered = true;

1168
	wl1251_notice("loaded");
K
Kalle Valo 已提交
1169 1170 1171 1172

	return 0;
}

1173
static int wl1251_init_ieee80211(struct wl1251 *wl)
K
Kalle Valo 已提交
1174 1175 1176
{
	/* The tx descriptor buffer and the TKIP space */
	wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
1177
		+ WL1251_TKIP_IV_SPACE;
K
Kalle Valo 已提交
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187

	/* 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;
1188
	wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1251_band_2ghz;
K
Kalle Valo 已提交
1189 1190 1191 1192 1193 1194

	SET_IEEE80211_DEV(wl->hw, &wl->spi->dev);

	return 0;
}

1195 1196
#define WL1251_DEFAULT_CHANNEL 1
static int __devinit wl1251_probe(struct spi_device *spi)
K
Kalle Valo 已提交
1197 1198 1199
{
	struct wl12xx_platform_data *pdata;
	struct ieee80211_hw *hw;
1200
	struct wl1251 *wl;
K
Kalle Valo 已提交
1201 1202 1203 1204 1205
	int ret, i;
	static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};

	pdata = spi->dev.platform_data;
	if (!pdata) {
1206
		wl1251_error("no platform data");
K
Kalle Valo 已提交
1207 1208 1209
		return -ENODEV;
	}

1210
	hw = ieee80211_alloc_hw(sizeof(*wl), &wl1251_ops);
K
Kalle Valo 已提交
1211
	if (!hw) {
1212
		wl1251_error("could not alloc ieee80211_hw");
K
Kalle Valo 已提交
1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226
		return -ENOMEM;
	}

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

	wl->hw = hw;
	dev_set_drvdata(&spi->dev, wl);
	wl->spi = spi;

	wl->data_in_count = 0;

	skb_queue_head_init(&wl->tx_queue);

1227 1228
	INIT_WORK(&wl->filter_work, wl1251_filter_work);
	wl->channel = WL1251_DEFAULT_CHANNEL;
K
Kalle Valo 已提交
1229 1230 1231 1232 1233 1234 1235
	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;
1236 1237
	wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
	wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
K
Kalle Valo 已提交
1238 1239 1240 1241
	wl->elp = false;
	wl->psm = 0;
	wl->psm_requested = false;
	wl->tx_queue_stopped = false;
1242
	wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
K
Kalle Valo 已提交
1243 1244 1245

	/* We use the default power on sleep time until we know which chip
	 * we're using */
1246
	wl->chip.power_on_sleep = WL1251_DEFAULT_POWER_ON_SLEEP;
K
Kalle Valo 已提交
1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259

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

	wl->next_tx_complete = 0;

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

1260
	wl->state = WL1251_STATE_OFF;
K
Kalle Valo 已提交
1261 1262 1263 1264 1265
	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 已提交
1266 1267
	wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL);
	if (!wl->rx_descriptor) {
1268
		wl1251_error("could not allocate memory for rx descriptor");
K
Kalle Valo 已提交
1269 1270 1271 1272
		ret = -ENOMEM;
		goto out_free;
	}

K
Kalle Valo 已提交
1273 1274 1275 1276 1277 1278
	/* This is the only SPI value that we need to set here, the rest
	 * comes from the board-peripherals file */
	spi->bits_per_word = 32;

	ret = spi_setup(spi);
	if (ret < 0) {
1279
		wl1251_error("spi_setup failed");
K
Kalle Valo 已提交
1280 1281 1282 1283 1284
		goto out_free;
	}

	wl->set_power = pdata->set_power;
	if (!wl->set_power) {
1285
		wl1251_error("set power function missing in platform data");
1286 1287
		ret = -ENODEV;
		goto out_free;
K
Kalle Valo 已提交
1288 1289 1290 1291
	}

	wl->irq = spi->irq;
	if (wl->irq < 0) {
1292
		wl1251_error("irq missing in platform data");
1293 1294
		ret = -ENODEV;
		goto out_free;
K
Kalle Valo 已提交
1295 1296
	}

1297
	ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl);
K
Kalle Valo 已提交
1298
	if (ret < 0) {
1299
		wl1251_error("request_irq() failed: %d", ret);
K
Kalle Valo 已提交
1300 1301 1302 1303 1304 1305 1306
		goto out_free;
	}

	set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);

	disable_irq(wl->irq);

1307
	ret = wl1251_init_ieee80211(wl);
K
Kalle Valo 已提交
1308 1309 1310
	if (ret)
		goto out_irq;

1311
	ret = wl1251_register_hw(wl);
K
Kalle Valo 已提交
1312 1313 1314
	if (ret)
		goto out_irq;

1315
	wl1251_debugfs_init(wl);
K
Kalle Valo 已提交
1316

1317
	wl1251_notice("initialized");
K
Kalle Valo 已提交
1318 1319 1320 1321 1322 1323 1324

	return 0;

 out_irq:
	free_irq(wl->irq, wl);

 out_free:
K
Kalle Valo 已提交
1325 1326 1327
	kfree(wl->rx_descriptor);
	wl->rx_descriptor = NULL;

K
Kalle Valo 已提交
1328 1329 1330 1331 1332
	ieee80211_free_hw(hw);

	return ret;
}

1333
static int __devexit wl1251_remove(struct spi_device *spi)
K
Kalle Valo 已提交
1334
{
1335
	struct wl1251 *wl = dev_get_drvdata(&spi->dev);
K
Kalle Valo 已提交
1336 1337 1338

	ieee80211_unregister_hw(wl->hw);

1339
	wl1251_debugfs_exit(wl);
K
Kalle Valo 已提交
1340 1341 1342 1343 1344 1345 1346 1347

	free_irq(wl->irq, wl);
	kfree(wl->target_mem_map);
	kfree(wl->data_path);
	kfree(wl->fw);
	wl->fw = NULL;
	kfree(wl->nvs);
	wl->nvs = NULL;
K
Kalle Valo 已提交
1348 1349 1350 1351

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

K
Kalle Valo 已提交
1352 1353 1354 1355 1356 1357
	ieee80211_free_hw(wl->hw);

	return 0;
}


1358
static struct spi_driver wl1251_spi_driver = {
K
Kalle Valo 已提交
1359
	.driver = {
1360
		/* FIXME: use wl12xx name to not break the user space */
K
Kalle Valo 已提交
1361 1362 1363 1364 1365
		.name		= "wl12xx",
		.bus		= &spi_bus_type,
		.owner		= THIS_MODULE,
	},

1366 1367
	.probe		= wl1251_probe,
	.remove		= __devexit_p(wl1251_remove),
K
Kalle Valo 已提交
1368 1369
};

1370
static int __init wl1251_init(void)
K
Kalle Valo 已提交
1371 1372 1373
{
	int ret;

1374
	ret = spi_register_driver(&wl1251_spi_driver);
K
Kalle Valo 已提交
1375
	if (ret < 0) {
1376
		wl1251_error("failed to register spi driver: %d", ret);
K
Kalle Valo 已提交
1377 1378 1379 1380 1381 1382 1383
		goto out;
	}

out:
	return ret;
}

1384
static void __exit wl1251_exit(void)
K
Kalle Valo 已提交
1385
{
1386
	spi_unregister_driver(&wl1251_spi_driver);
K
Kalle Valo 已提交
1387

1388
	wl1251_notice("unloaded");
K
Kalle Valo 已提交
1389 1390
}

1391 1392
module_init(wl1251_init);
module_exit(wl1251_exit);
K
Kalle Valo 已提交
1393 1394 1395 1396

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kalle Valo <Kalle.Valo@nokia.com>, "
		"Luciano Coelho <luciano.coelho@nokia.com>");