wl1251_main.c 29.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
 *
 * 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 34
#include "wl12xx_80211.h"
#include "reg.h"
35
#include "wl1251_ops.h"
36
#include "wl1251_io.h"
37
#include "wl1251_cmd.h"
38
#include "wl1251_event.h"
39
#include "wl1251_tx.h"
40 41 42 43
#include "wl1251_rx.h"
#include "wl1251_ps.h"
#include "wl1251_init.h"
#include "wl1251_debugfs.h"
K
Kalle Valo 已提交
44

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

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

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

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

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

	wl = cookie;

	schedule_work(&wl->irq_work);

	return IRQ_HANDLED;
}

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

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

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

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

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

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

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

	ret = 0;

out:
	release_firmware(fw);

	return ret;
}

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

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

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

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

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

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

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

	ret = 0;

out:
	release_firmware(fw);

	return ret;
}

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

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

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

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

167
	wl1251_power_on(wl);
K
Kalle Valo 已提交
168
	msleep(wl->chip.power_on_sleep);
169
	wl->if_ops->reset(wl);
K
Kalle Valo 已提交
170 171 172

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

	/* ELP module wake up */
180
	wl1251_fw_wakeup(wl);
K
Kalle Valo 已提交
181 182 183 184

	/* whal_FwCtrl_BootSm() */

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

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

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

		wl1251_setup(wl);

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

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

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

out:
	return ret;
}

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

	mutex_lock(&wl->mutex);

230
	if (wl->state == WL1251_STATE_OFF)
K
Kalle Valo 已提交
231 232
		goto out;

233
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
234 235
	if (ret < 0)
		goto out;
236

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

K
Kalle Valo 已提交
242
out_sleep:
243
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
244 245

out:
K
Kalle Valo 已提交
246 247 248
	mutex_unlock(&wl->mutex);
}

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

	skb_queue_tail(&wl->tx_queue, skb);

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

K
Kalle Valo 已提交
260 261 262 263 264 265
	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.
	 */
266
	if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) {
K
Kalle Valo 已提交
267 268 269 270 271 272 273 274 275 276 277 278 279
		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;
}

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

285
	wl1251_debug(DEBUG_MAC80211, "mac80211 start");
K
Kalle Valo 已提交
286 287 288

	mutex_lock(&wl->mutex);

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

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

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

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

308
	ret = wl1251_acx_station_id(wl);
K
Kalle Valo 已提交
309 310 311
	if (ret < 0)
		goto out;

312
	wl->state = WL1251_STATE_ON;
K
Kalle Valo 已提交
313

314
	wl1251_info("firmware booted (%s)", wl->chip.fw_ver);
K
Kalle Valo 已提交
315 316 317

out:
	if (ret < 0)
318
		wl1251_power_off(wl);
K
Kalle Valo 已提交
319 320 321 322 323 324

	mutex_unlock(&wl->mutex);

	return ret;
}

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

329
	wl1251_info("down");
K
Kalle Valo 已提交
330

331
	wl1251_debug(DEBUG_MAC80211, "mac80211 stop");
K
Kalle Valo 已提交
332 333 334

	mutex_lock(&wl->mutex);

335
	WARN_ON(wl->state != WL1251_STATE_ON);
K
Kalle Valo 已提交
336 337 338 339 340 341 342 343

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

344
	wl->state = WL1251_STATE_OFF;
K
Kalle Valo 已提交
345

346
	wl1251_disable_interrupts(wl);
K
Kalle Valo 已提交
347 348 349 350 351 352 353 354 355 356

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

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

375
	wl1251_debugfs_reset(wl);
K
Kalle Valo 已提交
376 377 378 379

	mutex_unlock(&wl->mutex);
}

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

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

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

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

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

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

438
	return wl1251_cmd_template_set(wl, CMD_NULL_DATA, &template,
K
Kalle Valo 已提交
439 440 441 442
				       sizeof(template));

}

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

452
	return wl1251_cmd_template_set(wl, CMD_PS_POLL, &template,
K
Kalle Valo 已提交
453 454 455 456
				       sizeof(template));

}

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

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

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

	mutex_lock(&wl->mutex);

472
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
473 474
	if (ret < 0)
		goto out;
475

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

		wl->channel = channel;
	}

485
	ret = wl1251_build_null_data(wl);
K
Kalle Valo 已提交
486
	if (ret < 0)
K
Kalle Valo 已提交
487
		goto out_sleep;
K
Kalle Valo 已提交
488 489

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

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

		wl->psm_requested = false;

		if (wl->psm)
507
			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
K
Kalle Valo 已提交
508 509 510
	}

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

		wl->power_level = conf->power_level;
	}

K
Kalle Valo 已提交
518
out_sleep:
519
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
520 521

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

K
Kalle Valo 已提交
524 525 526
	return ret;
}

527
#define WL1251_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
K
Kalle Valo 已提交
528 529 530 531 532 533
				  FIF_ALLMULTI | \
				  FIF_FCSFAIL | \
				  FIF_BCN_PRBRESP_PROMISC | \
				  FIF_CONTROL | \
				  FIF_OTHER_BSS)

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

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

544 545
	*total &= WL1251_SUPPORTED_FILTERS;
	changed &= WL1251_SUPPORTED_FILTERS;
K
Kalle Valo 已提交
546 547 548 549 550 551 552

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

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

553 554
	wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
	wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
K
Kalle Valo 已提交
555 556 557 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

	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 */
586 587
static int wl1251_set_key_type(struct wl1251 *wl,
			       struct wl1251_cmd_set_keys *key,
K
Kalle Valo 已提交
588 589 590 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
			       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:
617
		wl1251_error("Unknown key algo 0x%x", mac80211_key->alg);
K
Kalle Valo 已提交
618 619 620 621 622 623
		return -EOPNOTSUPP;
	}

	return 0;
}

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

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

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

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

	addr = sta ? sta->addr : bcast_addr;

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

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

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

661
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
662 663
	if (ret < 0)
		goto out_unlock;
664

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

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

683 684
	if (wl_cmd->key_type != KEY_WEP_DEFAULT)
		memcpy(wl_cmd->addr, addr, ETH_ALEN);
K
Kalle Valo 已提交
685

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

	} else {
699
		memcpy(wl_cmd->key, key->key, key->keylen);
K
Kalle Valo 已提交
700
	}
701
	wl_cmd->key_size = key->keylen;
K
Kalle Valo 已提交
702

703 704
	wl_cmd->id = key->keyidx;
	wl_cmd->ssid_profile = 0;
K
Kalle Valo 已提交
705

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

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

K
Kalle Valo 已提交
714
out_sleep:
715
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
716 717

out_unlock:
K
Kalle Valo 已提交
718
	mutex_unlock(&wl->mutex);
719 720 721 722

out:
	kfree(wl_cmd);

K
Kalle Valo 已提交
723 724 725
	return ret;
}

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

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


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

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

794
	return wl1251_cmd_template_set(wl, CMD_PROBE_REQ, &template,
K
Kalle Valo 已提交
795 796 797
				      size);
}

798
static int wl1251_hw_scan(struct wl1251 *wl, u8 *ssid, size_t len,
K
Kalle Valo 已提交
799 800 801
			  u8 active_scan, u8 high_prio, u8 num_channels,
			  u8 probe_requests)
{
802
	struct wl1251_cmd_trigger_scan_to *trigger = NULL;
803
	struct cmd_scan *params = NULL;
K
Kalle Valo 已提交
804 805 806 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
	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);
	}

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

859 860 861 862 863 864
	trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
	if (!trigger)
		goto out;

	trigger->timeout = 0;

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

872
	wl1251_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
K
Kalle Valo 已提交
873 874 875

	wl->scanning = true;

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

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

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

out:
	kfree(params);
	return ret;

}

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

904
	wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
K
Kalle Valo 已提交
905 906 907 908 909 910 911

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

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

913
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
914 915
	if (ret < 0)
		goto out;
916

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

919
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
920 921

out:
K
Kalle Valo 已提交
922 923 924 925 926
	mutex_unlock(&wl->mutex);

	return ret;
}

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

932 933
	mutex_lock(&wl->mutex);

934
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
935 936
	if (ret < 0)
		goto out;
937

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

942
	wl1251_ps_elp_sleep(wl);
943

K
Kalle Valo 已提交
944
out:
945 946
	mutex_unlock(&wl->mutex);

K
Kalle Valo 已提交
947 948 949
	return ret;
}

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

960
	wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
K
Kalle Valo 已提交
961 962 963

	mutex_lock(&wl->mutex);

964
	ret = wl1251_ps_elp_wakeup(wl);
K
Kalle Valo 已提交
965 966
	if (ret < 0)
		goto out;
967

K
Kalle Valo 已提交
968 969 970 971
	if (changed & BSS_CHANGED_ASSOC) {
		if (bss_conf->assoc) {
			wl->aid = bss_conf->aid;

972
			ret = wl1251_build_ps_poll(wl, wl->aid);
K
Kalle Valo 已提交
973
			if (ret < 0)
K
Kalle Valo 已提交
974
				goto out_sleep;
K
Kalle Valo 已提交
975

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

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

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

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

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

1021
		ret = wl1251_build_null_data(wl);
K
Kalle Valo 已提交
1022 1023 1024 1025
		if (ret < 0)
			goto out;

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

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

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

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

		dev_kfree_skb(beacon);

		if (ret < 0)
			goto out;

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

		if (ret < 0)
			goto out;
	}

K
Kalle Valo 已提交
1058
out_sleep:
1059
	wl1251_ps_elp_sleep(wl);
K
Kalle Valo 已提交
1060 1061

out:
K
Kalle Valo 已提交
1062 1063 1064 1065 1066
	mutex_unlock(&wl->mutex);
}


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

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

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

	wl->mac80211_registered = true;

1165
	wl1251_notice("loaded");
K
Kalle Valo 已提交
1166 1167 1168 1169

	return 0;
}

1170
int wl1251_init_ieee80211(struct wl1251 *wl)
K
Kalle Valo 已提交
1171
{
1172 1173
	int ret;

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

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

1189 1190 1191
	ret = wl1251_register_hw(wl);
	if (ret)
		goto out;
K
Kalle Valo 已提交
1192

1193 1194
	wl1251_debugfs_init(wl);
	wl1251_notice("initialized");
K
Kalle Valo 已提交
1195

1196 1197 1198 1199 1200
	ret = 0;

out:
	return ret;
}
1201

1202
#define WL1251_DEFAULT_CHANNEL 1
1203
struct ieee80211_hw *wl1251_alloc_hw(void)
K
Kalle Valo 已提交
1204 1205
{
	struct ieee80211_hw *hw;
1206
	struct wl1251 *wl;
1207
	int i;
K
Kalle Valo 已提交
1208 1209
	static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};

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

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

	wl->hw = hw;

	wl->data_in_count = 0;

	skb_queue_head_init(&wl->tx_queue);

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

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

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

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

1271
	return hw;
K
Kalle Valo 已提交
1272 1273
}

1274
int wl1251_free_hw(struct wl1251 *wl)
K
Kalle Valo 已提交
1275 1276 1277
{
	ieee80211_unregister_hw(wl->hw);

1278
	wl1251_debugfs_exit(wl);
K
Kalle Valo 已提交
1279 1280 1281 1282 1283 1284 1285 1286

	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 已提交
1287 1288 1289 1290

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

K
Kalle Valo 已提交
1291 1292 1293 1294
	ieee80211_free_hw(wl->hw);

	return 0;
}