zd_mac.c 27.6 KB
Newer Older
Daniel Drake's avatar
Daniel Drake committed
1
/* ZD1211 USB-WLAN driver for Linux
Daniel Drake's avatar
Daniel Drake committed
2
 *
Daniel Drake's avatar
Daniel Drake committed
3 4 5
 * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
 * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
 * Copyright (C) 2006-2007 Michael Wu <flamingice@sourmilk.net>
6
 * Copyright (C) 2007-2008 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
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
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/usb.h>
#include <linux/jiffies.h>
#include <net/ieee80211_radiotap.h>

#include "zd_def.h"
#include "zd_chip.h"
#include "zd_mac.h"
#include "zd_rf.h"

34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
struct zd_reg_alpha2_map {
	u32 reg;
	char alpha2[2];
};

static struct zd_reg_alpha2_map reg_alpha2_map[] = {
	{ ZD_REGDOMAIN_FCC, "US" },
	{ ZD_REGDOMAIN_IC, "CA" },
	{ ZD_REGDOMAIN_ETSI, "DE" }, /* Generic ETSI, use most restrictive */
	{ ZD_REGDOMAIN_JAPAN, "JP" },
	{ ZD_REGDOMAIN_JAPAN_ADD, "JP" },
	{ ZD_REGDOMAIN_SPAIN, "ES" },
	{ ZD_REGDOMAIN_FRANCE, "FR" },
};

Daniel Drake's avatar
Daniel Drake committed
49 50
/* This table contains the hardware specific values for the modulation rates. */
static const struct ieee80211_rate zd_rates[] = {
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
	{ .bitrate = 10,
	  .hw_value = ZD_CCK_RATE_1M, },
	{ .bitrate = 20,
	  .hw_value = ZD_CCK_RATE_2M,
	  .hw_value_short = ZD_CCK_RATE_2M | ZD_CCK_PREA_SHORT,
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 55,
	  .hw_value = ZD_CCK_RATE_5_5M,
	  .hw_value_short = ZD_CCK_RATE_5_5M | ZD_CCK_PREA_SHORT,
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 110,
	  .hw_value = ZD_CCK_RATE_11M,
	  .hw_value_short = ZD_CCK_RATE_11M | ZD_CCK_PREA_SHORT,
	  .flags = IEEE80211_RATE_SHORT_PREAMBLE },
	{ .bitrate = 60,
	  .hw_value = ZD_OFDM_RATE_6M,
	  .flags = 0 },
	{ .bitrate = 90,
	  .hw_value = ZD_OFDM_RATE_9M,
	  .flags = 0 },
	{ .bitrate = 120,
	  .hw_value = ZD_OFDM_RATE_12M,
	  .flags = 0 },
	{ .bitrate = 180,
	  .hw_value = ZD_OFDM_RATE_18M,
	  .flags = 0 },
	{ .bitrate = 240,
	  .hw_value = ZD_OFDM_RATE_24M,
	  .flags = 0 },
	{ .bitrate = 360,
	  .hw_value = ZD_OFDM_RATE_36M,
	  .flags = 0 },
	{ .bitrate = 480,
	  .hw_value = ZD_OFDM_RATE_48M,
	  .flags = 0 },
	{ .bitrate = 540,
	  .hw_value = ZD_OFDM_RATE_54M,
	  .flags = 0 },
Daniel Drake's avatar
Daniel Drake committed
89 90 91
};

static const struct ieee80211_channel zd_channels[] = {
92 93 94 95 96 97 98 99 100 101 102 103 104 105
	{ .center_freq = 2412, .hw_value = 1 },
	{ .center_freq = 2417, .hw_value = 2 },
	{ .center_freq = 2422, .hw_value = 3 },
	{ .center_freq = 2427, .hw_value = 4 },
	{ .center_freq = 2432, .hw_value = 5 },
	{ .center_freq = 2437, .hw_value = 6 },
	{ .center_freq = 2442, .hw_value = 7 },
	{ .center_freq = 2447, .hw_value = 8 },
	{ .center_freq = 2452, .hw_value = 9 },
	{ .center_freq = 2457, .hw_value = 10 },
	{ .center_freq = 2462, .hw_value = 11 },
	{ .center_freq = 2467, .hw_value = 12 },
	{ .center_freq = 2472, .hw_value = 13 },
	{ .center_freq = 2484, .hw_value = 14 },
Daniel Drake's avatar
Daniel Drake committed
106
};
107

108 109 110 111
static void housekeeping_init(struct zd_mac *mac);
static void housekeeping_enable(struct zd_mac *mac);
static void housekeeping_disable(struct zd_mac *mac);

112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
static int zd_reg2alpha2(u8 regdomain, char *alpha2)
{
	unsigned int i;
	struct zd_reg_alpha2_map *reg_map;
	for (i = 0; i < ARRAY_SIZE(reg_alpha2_map); i++) {
		reg_map = &reg_alpha2_map[i];
		if (regdomain == reg_map->reg) {
			alpha2[0] = reg_map->alpha2[0];
			alpha2[1] = reg_map->alpha2[1];
			return 0;
		}
	}
	return 1;
}

Daniel Drake's avatar
Daniel Drake committed
127
int zd_mac_preinit_hw(struct ieee80211_hw *hw)
128 129 130
{
	int r;
	u8 addr[ETH_ALEN];
Daniel Drake's avatar
Daniel Drake committed
131
	struct zd_mac *mac = zd_hw_mac(hw);
132 133 134 135 136

	r = zd_chip_read_mac_addr_fw(&mac->chip, addr);
	if (r)
		return r;

Daniel Drake's avatar
Daniel Drake committed
137 138
	SET_IEEE80211_PERM_ADDR(hw, addr);

139 140 141
	return 0;
}

Daniel Drake's avatar
Daniel Drake committed
142
int zd_mac_init_hw(struct ieee80211_hw *hw)
143 144
{
	int r;
Daniel Drake's avatar
Daniel Drake committed
145
	struct zd_mac *mac = zd_hw_mac(hw);
146
	struct zd_chip *chip = &mac->chip;
147
	char alpha2[2];
148 149 150 151 152
	u8 default_regdomain;

	r = zd_chip_enable_int(chip);
	if (r)
		goto out;
153
	r = zd_chip_init_hw(chip);
154 155 156 157 158 159 160 161 162 163 164 165
	if (r)
		goto disable_int;

	ZD_ASSERT(!irqs_disabled());

	r = zd_read_regdomain(chip, &default_regdomain);
	if (r)
		goto disable_int;
	spin_lock_irq(&mac->lock);
	mac->regdomain = mac->default_regdomain = default_regdomain;
	spin_unlock_irq(&mac->lock);

166 167 168
	/* We must inform the device that we are doing encryption/decryption in
	 * software at the moment. */
	r = zd_set_encryption_type(chip, ENC_SNIFFER);
169 170 171
	if (r)
		goto disable_int;

172
	r = zd_reg2alpha2(mac->regdomain, alpha2);
173 174
	if (r)
		goto disable_int;
175

176
	r = regulatory_hint(hw->wiphy, alpha2);
177 178 179 180 181 182 183 184
disable_int:
	zd_chip_disable_int(chip);
out:
	return r;
}

void zd_mac_clear(struct zd_mac *mac)
{
185
	flush_workqueue(zd_workqueue);
186
	zd_chip_clear(&mac->chip);
Ulrich Kunitz's avatar
Ulrich Kunitz committed
187 188
	ZD_ASSERT(!spin_is_locked(&mac->lock));
	ZD_MEMCLEAR(mac, sizeof(struct zd_mac));
189 190
}

191
static int set_rx_filter(struct zd_mac *mac)
192
{
Daniel Drake's avatar
Daniel Drake committed
193 194
	unsigned long flags;
	u32 filter = STA_RX_FILTER;
195

Daniel Drake's avatar
Daniel Drake committed
196 197 198 199 200 201
	spin_lock_irqsave(&mac->lock, flags);
	if (mac->pass_ctrl)
		filter |= RX_FILTER_CTRL;
	spin_unlock_irqrestore(&mac->lock, flags);

	return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter);
202 203 204 205 206 207 208 209 210
}

static int set_mc_hash(struct zd_mac *mac)
{
	struct zd_mc_hash hash;
	zd_mc_clear(&hash);
	return zd_chip_set_multicast_hash(&mac->chip, &hash);
}

Daniel Drake's avatar
Daniel Drake committed
211
static int zd_op_start(struct ieee80211_hw *hw)
212
{
Daniel Drake's avatar
Daniel Drake committed
213
	struct zd_mac *mac = zd_hw_mac(hw);
214
	struct zd_chip *chip = &mac->chip;
215
	struct zd_usb *usb = &chip->usb;
216 217
	int r;

218 219 220 221 222 223
	if (!usb->initialized) {
		r = zd_usb_init_hw(usb);
		if (r)
			goto out;
	}

224 225 226 227 228 229 230
	r = zd_chip_enable_int(chip);
	if (r < 0)
		goto out;

	r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G);
	if (r < 0)
		goto disable_int;
231 232 233 234
	r = set_rx_filter(mac);
	if (r)
		goto disable_int;
	r = set_mc_hash(mac);
235 236 237 238 239
	if (r)
		goto disable_int;
	r = zd_chip_switch_radio_on(chip);
	if (r < 0)
		goto disable_int;
Daniel Drake's avatar
Daniel Drake committed
240
	r = zd_chip_enable_rxtx(chip);
241 242 243 244
	if (r < 0)
		goto disable_radio;
	r = zd_chip_enable_hwint(chip);
	if (r < 0)
Daniel Drake's avatar
Daniel Drake committed
245
		goto disable_rxtx;
246

247
	housekeeping_enable(mac);
248
	return 0;
Daniel Drake's avatar
Daniel Drake committed
249 250
disable_rxtx:
	zd_chip_disable_rxtx(chip);
251 252 253 254 255 256 257 258
disable_radio:
	zd_chip_switch_radio_off(chip);
disable_int:
	zd_chip_disable_int(chip);
out:
	return r;
}

Daniel Drake's avatar
Daniel Drake committed
259 260 261 262 263 264
static void zd_op_stop(struct ieee80211_hw *hw)
{
	struct zd_mac *mac = zd_hw_mac(hw);
	struct zd_chip *chip = &mac->chip;
	struct sk_buff *skb;
	struct sk_buff_head *ack_wait_queue = &mac->ack_wait_queue;
265

Daniel Drake's avatar
Daniel Drake committed
266
	/* The order here deliberately is a little different from the open()
267
	 * method, since we need to make sure there is no opportunity for RX
Daniel Drake's avatar
Daniel Drake committed
268
	 * frames to be processed by mac80211 after we have stopped it.
269 270
	 */

Daniel Drake's avatar
Daniel Drake committed
271
	zd_chip_disable_rxtx(chip);
272
	housekeeping_disable(mac);
273 274
	flush_workqueue(zd_workqueue);

275 276 277 278 279
	zd_chip_disable_hwint(chip);
	zd_chip_switch_radio_off(chip);
	zd_chip_disable_int(chip);


Daniel Drake's avatar
Daniel Drake committed
280
	while ((skb = skb_dequeue(ack_wait_queue)))
281
		dev_kfree_skb_any(skb);
282 283
}

Daniel Drake's avatar
Daniel Drake committed
284 285 286 287
/**
 * tx_status - reports tx status of a packet if required
 * @hw - a &struct ieee80211_hw pointer
 * @skb - a sk-buffer
288 289
 * @flags: extra flags to set in the TX status info
 * @ackssi: ACK signal strength
Coly Li's avatar
Coly Li committed
290
 * @success - True for successful transmission of the frame
Daniel Drake's avatar
Daniel Drake committed
291 292 293 294 295 296 297 298
 *
 * This information calls ieee80211_tx_status_irqsafe() if required by the
 * control information. It copies the control information into the status
 * information.
 *
 * If no status information has been requested, the skb is freed.
 */
static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
299
		      int ackssi, bool success)
300
{
301 302
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);

303
	ieee80211_tx_info_clear_status(info);
304

305 306
	if (success)
		info->flags |= IEEE80211_TX_STAT_ACK;
307 308
	info->status.ack_signal = ackssi;
	ieee80211_tx_status_irqsafe(hw, skb);
309 310
}

Daniel Drake's avatar
Daniel Drake committed
311 312 313 314 315 316 317 318 319
/**
 * zd_mac_tx_failed - callback for failed frames
 * @dev: the mac80211 wireless device
 *
 * This function is called if a frame couldn't be succesfully be
 * transferred. The first frame from the tx queue, will be selected and
 * reported as error to the upper layers.
 */
void zd_mac_tx_failed(struct ieee80211_hw *hw)
320
{
Daniel Drake's avatar
Daniel Drake committed
321 322
	struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue;
	struct sk_buff *skb;
323

Daniel Drake's avatar
Daniel Drake committed
324 325 326
	skb = skb_dequeue(q);
	if (skb == NULL)
		return;
Johannes Berg's avatar
Johannes Berg committed
327

328
	tx_status(hw, skb, 0, 0);
329 330
}

Daniel Drake's avatar
Daniel Drake committed
331 332 333 334 335 336 337 338 339 340 341 342
/**
 * zd_mac_tx_to_dev - callback for USB layer
 * @skb: a &sk_buff pointer
 * @error: error value, 0 if transmission successful
 *
 * Informs the MAC layer that the frame has successfully transferred to the
 * device. If an ACK is required and the transfer to the device has been
 * successful, the packets are put on the @ack_wait_queue with
 * the control set removed.
 */
void zd_mac_tx_to_dev(struct sk_buff *skb, int error)
{
343
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
344
	struct ieee80211_hw *hw = info->rate_driver_data[0];
345

346 347 348
	skb_pull(skb, sizeof(struct zd_ctrlset));
	if (unlikely(error ||
	    (info->flags & IEEE80211_TX_CTL_NO_ACK))) {
349
		tx_status(hw, skb, 0, !error);
Daniel Drake's avatar
Daniel Drake committed
350
	} else {
351 352 353 354 355 356
		struct sk_buff_head *q =
			&zd_hw_mac(hw)->ack_wait_queue;

		skb_queue_tail(q, skb);
		while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS)
			zd_mac_tx_failed(hw);
357 358 359
	}
}

360
static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length)
361
{
362
	/* ZD_PURE_RATE() must be used to remove the modulation type flag of
Daniel Drake's avatar
Daniel Drake committed
363 364
	 * the zd-rate values.
	 */
365
	static const u8 rate_divisor[] = {
Daniel Drake's avatar
Daniel Drake committed
366 367 368 369 370 371 372 373 374 375 376 377 378
		[ZD_PURE_RATE(ZD_CCK_RATE_1M)]   =  1,
		[ZD_PURE_RATE(ZD_CCK_RATE_2M)]	 =  2,
		/* Bits must be doubled. */
		[ZD_PURE_RATE(ZD_CCK_RATE_5_5M)] = 11,
		[ZD_PURE_RATE(ZD_CCK_RATE_11M)]	 = 11,
		[ZD_PURE_RATE(ZD_OFDM_RATE_6M)]  =  6,
		[ZD_PURE_RATE(ZD_OFDM_RATE_9M)]  =  9,
		[ZD_PURE_RATE(ZD_OFDM_RATE_12M)] = 12,
		[ZD_PURE_RATE(ZD_OFDM_RATE_18M)] = 18,
		[ZD_PURE_RATE(ZD_OFDM_RATE_24M)] = 24,
		[ZD_PURE_RATE(ZD_OFDM_RATE_36M)] = 36,
		[ZD_PURE_RATE(ZD_OFDM_RATE_48M)] = 48,
		[ZD_PURE_RATE(ZD_OFDM_RATE_54M)] = 54,
379 380 381 382 383
	};

	u32 bits = (u32)tx_length * 8;
	u32 divisor;

384
	divisor = rate_divisor[ZD_PURE_RATE(zd_rate)];
385 386 387
	if (divisor == 0)
		return -EINVAL;

388 389
	switch (zd_rate) {
	case ZD_CCK_RATE_5_5M:
390 391
		bits = (2*bits) + 10; /* round up to the next integer */
		break;
392
	case ZD_CCK_RATE_11M:
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
		if (service) {
			u32 t = bits % 11;
			*service &= ~ZD_PLCP_SERVICE_LENGTH_EXTENSION;
			if (0 < t && t <= 3) {
				*service |= ZD_PLCP_SERVICE_LENGTH_EXTENSION;
			}
		}
		bits += 10; /* round up to the next integer */
		break;
	}

	return bits/divisor;
}

static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
408 409
	                   struct ieee80211_hdr *header,
	                   struct ieee80211_tx_info *info)
410 411
{
	/*
412
	 * CONTROL TODO:
413 414 415 416 417 418 419
	 * - if backoff needed, enable bit 0
	 * - if burst (backoff not needed) disable bit 0
	 */

	cs->control = 0;

	/* First fragment */
420
	if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
421 422
		cs->control |= ZD_CS_NEED_RANDOM_BACKOFF;

423 424 425
	/* No ACK expected (multicast, etc.) */
	if (info->flags & IEEE80211_TX_CTL_NO_ACK)
		cs->control |= ZD_CS_NO_ACK;
426 427

	/* PS-POLL */
428
	if (ieee80211_is_pspoll(header->frame_control))
429 430
		cs->control |= ZD_CS_PS_POLL_FRAME;

431
	if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
432 433
		cs->control |= ZD_CS_RTS;

434
	if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
435
		cs->control |= ZD_CS_SELF_CTS;
436 437 438 439

	/* FIXME: Management frame? */
}

440
static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
441 442
{
	struct zd_mac *mac = zd_hw_mac(hw);
443
	int r;
444 445 446
	u32 tmp, j = 0;
	/* 4 more bytes for tail CRC */
	u32 full_len = beacon->len + 4;
447 448 449 450 451 452 453 454

	r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0);
	if (r < 0)
		return r;
	r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
	if (r < 0)
		return r;

455
	while (tmp & 0x2) {
456 457 458
		r = zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
		if (r < 0)
			return r;
459 460 461 462
		if ((++j % 100) == 0) {
			printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n");
			if (j >= 500)  {
				printk(KERN_ERR "Giving up beacon config.\n");
463
				return -ETIMEDOUT;
464 465 466 467 468
			}
		}
		msleep(1);
	}

469 470 471 472 473 474 475 476
	r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1);
	if (r < 0)
		return r;
	if (zd_chip_is_zd1211b(&mac->chip)) {
		r = zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1);
		if (r < 0)
			return r;
	}
477

478 479
	for (j = 0 ; j < beacon->len; j++) {
		r = zd_iowrite32(&mac->chip, CR_BCN_FIFO,
480
				*((u8 *)(beacon->data + j)));
481 482 483
		if (r < 0)
			return r;
	}
484

485 486 487 488 489 490 491 492 493
	for (j = 0; j < 4; j++) {
		r = zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0);
		if (r < 0)
			return r;
	}

	r = zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1);
	if (r < 0)
		return r;
494 495 496 497 498

	/* 802.11b/g 2.4G CCK 1Mb
	 * 802.11a, not yet implemented, uses different values (see GPL vendor
	 * driver)
	 */
499
	return zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 |
500 501 502
			(full_len << 19));
}

503
static int fill_ctrlset(struct zd_mac *mac,
504
			struct sk_buff *skb)
505 506
{
	int r;
Daniel Drake's avatar
Daniel Drake committed
507 508
	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
	unsigned int frag_len = skb->len + FCS_LEN;
509
	unsigned int packet_length;
510
	struct ieee80211_rate *txrate;
511 512
	struct zd_ctrlset *cs = (struct zd_ctrlset *)
		skb_push(skb, sizeof(struct zd_ctrlset));
513
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
514 515 516

	ZD_ASSERT(frag_len <= 0xffff);

517
	txrate = ieee80211_get_tx_rate(mac->hw, info);
518 519

	cs->modulation = txrate->hw_value;
520
	if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
521
		cs->modulation = txrate->hw_value_short;
522 523 524

	cs->tx_length = cpu_to_le16(frag_len);

525
	cs_set_control(mac, cs, hdr, info);
526 527 528 529 530 531

	packet_length = frag_len + sizeof(struct zd_ctrlset) + 10;
	ZD_ASSERT(packet_length <= 0xffff);
	/* ZD1211B: Computing the length difference this way, gives us
	 * flexibility to compute the packet length.
	 */
532
	cs->packet_length = cpu_to_le16(zd_chip_is_zd1211b(&mac->chip) ?
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
			packet_length - frag_len : packet_length);

	/*
	 * CURRENT LENGTH:
	 * - transmit frame length in microseconds
	 * - seems to be derived from frame length
	 * - see Cal_Us_Service() in zdinlinef.h
	 * - if macp->bTxBurstEnable is enabled, then multiply by 4
	 *  - bTxBurstEnable is never set in the vendor driver
	 *
	 * SERVICE:
	 * - "for PLCP configuration"
	 * - always 0 except in some situations at 802.11b 11M
	 * - see line 53 of zdinlinef.h
	 */
	cs->service = 0;
549
	r = zd_calc_tx_length_us(&cs->service, ZD_RATE(cs->modulation),
550 551 552 553
		                 le16_to_cpu(cs->tx_length));
	if (r < 0)
		return r;
	cs->current_length = cpu_to_le16(r);
Daniel Drake's avatar
Daniel Drake committed
554
	cs->next_frame_length = 0;
555 556 557 558

	return 0;
}

Daniel Drake's avatar
Daniel Drake committed
559 560 561 562 563 564 565 566 567 568 569
/**
 * zd_op_tx - transmits a network frame to the device
 *
 * @dev: mac80211 hardware device
 * @skb: socket buffer
 * @control: the control structure
 *
 * This function transmit an IEEE 802.11 network frame to the device. The
 * control block of the skbuff will be initialized. If necessary the incoming
 * mac80211 queues will be stopped.
 */
570
static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
571
{
Daniel Drake's avatar
Daniel Drake committed
572
	struct zd_mac *mac = zd_hw_mac(hw);
573
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
Daniel Drake's avatar
Daniel Drake committed
574
	int r;
575

576
	r = fill_ctrlset(mac, skb);
Daniel Drake's avatar
Daniel Drake committed
577
	if (r)
578
		goto fail;
579

580
	info->rate_driver_data[0] = hw;
581

Daniel Drake's avatar
Daniel Drake committed
582
	r = zd_usb_tx(&mac->chip.usb, skb);
583
	if (r)
584 585 586 587 588
		goto fail;
	return 0;

fail:
	dev_kfree_skb(skb);
589 590 591
	return 0;
}

Daniel Drake's avatar
Daniel Drake committed
592 593 594 595 596
/**
 * filter_ack - filters incoming packets for acknowledgements
 * @dev: the mac80211 device
 * @rx_hdr: received header
 * @stats: the status for the received packet
Ulrich Kunitz's avatar
Ulrich Kunitz committed
597
 *
Daniel Drake's avatar
Daniel Drake committed
598 599 600 601 602
 * This functions looks for ACK packets and tries to match them with the
 * frames in the tx queue. If a match is found the frame will be dequeued and
 * the upper layers is informed about the successful transmission. If
 * mac80211 queues have been stopped and the number of frames still to be
 * transmitted is low the queues will be opened again.
603
 *
Daniel Drake's avatar
Daniel Drake committed
604
 * Returns 1 if the frame was an ACK, 0 if it was ignored.
605
 */
Daniel Drake's avatar
Daniel Drake committed
606 607
static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
		      struct ieee80211_rx_status *stats)
608
{
Daniel Drake's avatar
Daniel Drake committed
609 610 611
	struct sk_buff *skb;
	struct sk_buff_head *q;
	unsigned long flags;
612

613
	if (!ieee80211_is_ack(rx_hdr->frame_control))
614 615
		return 0;

Daniel Drake's avatar
Daniel Drake committed
616 617
	q = &zd_hw_mac(hw)->ack_wait_queue;
	spin_lock_irqsave(&q->lock, flags);
618
	skb_queue_walk(q, skb) {
Daniel Drake's avatar
Daniel Drake committed
619 620 621
		struct ieee80211_hdr *tx_hdr;

		tx_hdr = (struct ieee80211_hdr *)skb->data;
622
		if (likely(!memcmp(tx_hdr->addr2, rx_hdr->addr1, ETH_ALEN)))
Daniel Drake's avatar
Daniel Drake committed
623 624
		{
			__skb_unlink(skb, q);
625
			tx_status(hw, skb, stats->signal, 1);
Daniel Drake's avatar
Daniel Drake committed
626 627 628 629 630 631
			goto out;
		}
	}
out:
	spin_unlock_irqrestore(&q->lock, flags);
	return 1;
632 633
}

Daniel Drake's avatar
Daniel Drake committed
634
int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
635
{
Daniel Drake's avatar
Daniel Drake committed
636 637 638 639 640
	struct zd_mac *mac = zd_hw_mac(hw);
	struct ieee80211_rx_status stats;
	const struct rx_status *status;
	struct sk_buff *skb;
	int bad_frame = 0;
641 642
	__le16 fc;
	int need_padding;
643 644
	int i;
	u8 rate;
645

Daniel Drake's avatar
Daniel Drake committed
646 647 648
	if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ +
	             FCS_LEN + sizeof(struct rx_status))
		return -EINVAL;
649

Daniel Drake's avatar
Daniel Drake committed
650
	memset(&stats, 0, sizeof(stats));
651

Daniel Drake's avatar
Daniel Drake committed
652 653 654 655 656 657 658 659
	/* Note about pass_failed_fcs and pass_ctrl access below:
	 * mac locking intentionally omitted here, as this is the only unlocked
	 * reader and the only writer is configure_filter. Plus, if there were
	 * any races accessing these variables, it wouldn't really matter.
	 * If mac80211 ever provides a way for us to access filter flags
	 * from outside configure_filter, we could improve on this. Also, this
	 * situation may change once we implement some kind of DMA-into-skb
	 * RX path. */
660

Daniel Drake's avatar
Daniel Drake committed
661 662
	/* Caller has to ensure that length >= sizeof(struct rx_status). */
	status = (struct rx_status *)
663
		(buffer + (length - sizeof(struct rx_status)));
664
	if (status->frame_status & ZD_RX_ERROR) {
Daniel Drake's avatar
Daniel Drake committed
665 666 667 668 669 670
		if (mac->pass_failed_fcs &&
				(status->frame_status & ZD_RX_CRC32_ERROR)) {
			stats.flag |= RX_FLAG_FAILED_FCS_CRC;
			bad_frame = 1;
		} else {
			return -EINVAL;
671
		}
672
	}
673

674 675
	stats.freq = zd_channels[_zd_chip_get_channel(&mac->chip) - 1].center_freq;
	stats.band = IEEE80211_BAND_2GHZ;
676 677
	stats.signal = status->signal_strength;
	stats.qual = zd_rx_qual_percent(buffer,
678 679
		                          length - sizeof(struct rx_status),
		                          status);
680 681 682 683 684 685 686

	rate = zd_rx_rate(buffer, status);

	/* todo: return index in the big switches in zd_rx_rate instead */
	for (i = 0; i < mac->band.n_bitrates; i++)
		if (rate == mac->band.bitrates[i].hw_value)
			stats.rate_idx = i;
Daniel Drake's avatar
Daniel Drake committed
687 688 689 690 691 692 693 694 695 696 697 698 699

	length -= ZD_PLCP_HEADER_SIZE + sizeof(struct rx_status);
	buffer += ZD_PLCP_HEADER_SIZE;

	/* Except for bad frames, filter each frame to see if it is an ACK, in
	 * which case our internal TX tracking is updated. Normally we then
	 * bail here as there's no need to pass ACKs on up to the stack, but
	 * there is also the case where the stack has requested us to pass
	 * control frames on up (pass_ctrl) which we must consider. */
	if (!bad_frame &&
			filter_ack(hw, (struct ieee80211_hdr *)buffer, &stats)
			&& !mac->pass_ctrl)
		return 0;
700

701 702
	fc = *(__le16 *)buffer;
	need_padding = ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc);
703 704

	skb = dev_alloc_skb(length + (need_padding ? 2 : 0));
Daniel Drake's avatar
Daniel Drake committed
705 706
	if (skb == NULL)
		return -ENOMEM;
707 708 709 710 711
	if (need_padding) {
		/* Make sure the the payload data is 4 byte aligned. */
		skb_reserve(skb, 2);
	}

Daniel Drake's avatar
Daniel Drake committed
712 713
	memcpy(skb_put(skb, length), buffer, length);

714 715
	memcpy(IEEE80211_SKB_RXCB(skb), &stats, sizeof(stats));
	ieee80211_rx_irqsafe(hw, skb);
716 717 718
	return 0;
}

Daniel Drake's avatar
Daniel Drake committed
719 720
static int zd_op_add_interface(struct ieee80211_hw *hw,
				struct ieee80211_if_init_conf *conf)
721
{
Daniel Drake's avatar
Daniel Drake committed
722
	struct zd_mac *mac = zd_hw_mac(hw);
723

724 725
	/* using NL80211_IFTYPE_UNSPECIFIED to indicate no mode selected */
	if (mac->type != NL80211_IFTYPE_UNSPECIFIED)
Daniel Drake's avatar
Daniel Drake committed
726
		return -EOPNOTSUPP;
727

Daniel Drake's avatar
Daniel Drake committed
728
	switch (conf->type) {
729 730 731 732
	case NL80211_IFTYPE_MONITOR:
	case NL80211_IFTYPE_MESH_POINT:
	case NL80211_IFTYPE_STATION:
	case NL80211_IFTYPE_ADHOC:
Daniel Drake's avatar
Daniel Drake committed
733 734 735 736
		mac->type = conf->type;
		break;
	default:
		return -EOPNOTSUPP;
737
	}
738

Daniel Drake's avatar
Daniel Drake committed
739 740
	return zd_write_mac_addr(&mac->chip, conf->mac_addr);
}
741

Daniel Drake's avatar
Daniel Drake committed
742 743 744 745
static void zd_op_remove_interface(struct ieee80211_hw *hw,
				    struct ieee80211_if_init_conf *conf)
{
	struct zd_mac *mac = zd_hw_mac(hw);
746
	mac->type = NL80211_IFTYPE_UNSPECIFIED;
747
	zd_set_beacon_interval(&mac->chip, 0);
Daniel Drake's avatar
Daniel Drake committed
748 749
	zd_write_mac_addr(&mac->chip, NULL);
}
750

751
static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
Daniel Drake's avatar
Daniel Drake committed
752 753
{
	struct zd_mac *mac = zd_hw_mac(hw);
754 755
	struct ieee80211_conf *conf = &hw->conf;

756
	return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
Daniel Drake's avatar
Daniel Drake committed
757
}
758

759
static void zd_process_intr(struct work_struct *work)
760 761 762 763
{
	u16 int_status;
	struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);

Al Viro's avatar
Al Viro committed
764
	int_status = le16_to_cpu(*(__le16 *)(mac->intr_buffer+4));
765 766 767
	if (int_status & INT_CFG_NEXT_BCN)
		dev_dbg_f_limit(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
	else
768 769 770 771 772 773
		dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");

	zd_chip_enable_hwint(&mac->chip);
}


Daniel Drake's avatar
Daniel Drake committed
774
static void set_multicast_hash_handler(struct work_struct *work)
775
{
Daniel Drake's avatar
Daniel Drake committed
776 777 778
	struct zd_mac *mac =
		container_of(work, struct zd_mac, set_multicast_hash_work);
	struct zd_mc_hash hash;
779

Daniel Drake's avatar
Daniel Drake committed
780 781 782
	spin_lock_irq(&mac->lock);
	hash = mac->multicast_hash;
	spin_unlock_irq(&mac->lock);
783

Daniel Drake's avatar
Daniel Drake committed
784
	zd_chip_set_multicast_hash(&mac->chip, &hash);
785 786
}

Daniel Drake's avatar
Daniel Drake committed
787
static void set_rx_filter_handler(struct work_struct *work)
788
{
Daniel Drake's avatar
Daniel Drake committed
789 790 791 792 793 794 795 796
	struct zd_mac *mac =
		container_of(work, struct zd_mac, set_rx_filter_work);
	int r;

	dev_dbg_f(zd_mac_dev(mac), "\n");
	r = set_rx_filter(mac);
	if (r)
		dev_err(zd_mac_dev(mac), "set_rx_filter_handler error %d\n", r);
797 798
}

Daniel Drake's avatar
Daniel Drake committed
799 800
#define SUPPORTED_FIF_FLAGS \
	(FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \
801
	FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)
Daniel Drake's avatar
Daniel Drake committed
802 803 804 805
static void zd_op_configure_filter(struct ieee80211_hw *hw,
			unsigned int changed_flags,
			unsigned int *new_flags,
			int mc_count, struct dev_mc_list *mclist)
806
{
Daniel Drake's avatar
Daniel Drake committed
807 808 809 810
	struct zd_mc_hash hash;
	struct zd_mac *mac = zd_hw_mac(hw);
	unsigned long flags;
	int i;
811

Daniel Drake's avatar
Daniel Drake committed
812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828
	/* Only deal with supported flags */
	changed_flags &= SUPPORTED_FIF_FLAGS;
	*new_flags &= SUPPORTED_FIF_FLAGS;

	/* changed_flags is always populated but this driver
	 * doesn't support all FIF flags so its possible we don't
	 * need to do anything */
	if (!changed_flags)
		return;

	if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) {
		zd_mc_add_all(&hash);
	} else {
		zd_mc_clear(&hash);
		for (i = 0; i < mc_count; i++) {
			if (!mclist)
				break;
Johannes Berg's avatar
Johannes Berg committed
829 830
			dev_dbg_f(zd_mac_dev(mac), "mc addr %pM\n",
				  mclist->dmi_addr);
Daniel Drake's avatar
Daniel Drake committed
831 832 833
			zd_mc_add_addr(&hash, mclist->dmi_addr);
			mclist = mclist->next;
		}
834
	}
Daniel Drake's avatar
Daniel Drake committed
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853

	spin_lock_irqsave(&mac->lock, flags);
	mac->pass_failed_fcs = !!(*new_flags & FIF_FCSFAIL);
	mac->pass_ctrl = !!(*new_flags & FIF_CONTROL);
	mac->multicast_hash = hash;
	spin_unlock_irqrestore(&mac->lock, flags);
	queue_work(zd_workqueue, &mac->set_multicast_hash_work);

	if (changed_flags & FIF_CONTROL)
		queue_work(zd_workqueue, &mac->set_rx_filter_work);

	/* no handling required for FIF_OTHER_BSS as we don't currently
	 * do BSSID filtering */
	/* FIXME: in future it would be nice to enable the probe response
	 * filter (so that the driver doesn't see them) until
	 * FIF_BCN_PRBRESP_PROMISC is set. however due to atomicity here, we'd
	 * have to schedule work to enable prbresp reception, which might
	 * happen too late. For now we'll just listen and forward them all the
	 * time. */
854 855
}

Daniel Drake's avatar
Daniel Drake committed
856
static void set_rts_cts_work(struct work_struct *work)
857
{
Daniel Drake's avatar
Daniel Drake committed
858 859 860 861 862 863 864 865 866 867 868 869 870 871
	struct zd_mac *mac =
		container_of(work, struct zd_mac, set_rts_cts_work);
	unsigned long flags;
	unsigned int short_preamble;

	mutex_lock(&mac->chip.mutex);

	spin_lock_irqsave(&mac->lock, flags);
	mac->updating_rts_rate = 0;
	short_preamble = mac->short_preamble;
	spin_unlock_irqrestore(&mac->lock, flags);

	zd_chip_set_rts_cts_rate_locked(&mac->chip, short_preamble);
	mutex_unlock(&mac->chip.mutex);
872 873
}

874 875 876 877
static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
				   struct ieee80211_vif *vif,
				   struct ieee80211_bss_conf *bss_conf,
				   u32 changes)
878
{
Daniel Drake's avatar
Daniel Drake committed
879 880
	struct zd_mac *mac = zd_hw_mac(hw);
	unsigned long flags;
881
	int associated;
Daniel Drake's avatar
Daniel Drake committed
882 883 884

	dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);

885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916
	if (mac->type == NL80211_IFTYPE_MESH_POINT ||
	    mac->type == NL80211_IFTYPE_ADHOC) {
		associated = true;
		if (changes & BSS_CHANGED_BEACON) {
			struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);

			if (beacon) {
				zd_mac_config_beacon(hw, beacon);
				kfree_skb(beacon);
			}
		}

		if (changes & BSS_CHANGED_BEACON_ENABLED) {
			u32 interval;

			if (bss_conf->enable_beacon)
				interval = BCN_MODE_IBSS |
						bss_conf->beacon_int;
			else
				interval = 0;

			zd_set_beacon_interval(&mac->chip, interval);
		}
	} else
		associated = is_valid_ether_addr(bss_conf->bssid);

	spin_lock_irq(&mac->lock);
	mac->associated = associated;
	spin_unlock_irq(&mac->lock);

	/* TODO: do hardware bssid filtering */

917
	if (changes & BSS_CHANGED_ERP_PREAMBLE) {
Daniel Drake's avatar
Daniel Drake committed
918
		spin_lock_irqsave(&mac->lock, flags);
919
		mac->short_preamble = bss_conf->use_short_preamble;
Daniel Drake's avatar
Daniel Drake committed
920 921 922 923 924 925 926 927
		if (!mac->updating_rts_rate) {
			mac->updating_rts_rate = 1;
			/* FIXME: should disable TX here, until work has
			 * completed and RTS_CTS reg is updated */
			queue_work(zd_workqueue, &mac->set_rts_cts_work);
		}
		spin_unlock_irqrestore(&mac->lock, flags);
	}
928 929
}

930 931 932 933 934 935
static u64 zd_op_get_tsf(struct ieee80211_hw *hw)
{
	struct zd_mac *mac = zd_hw_mac(hw);
	return zd_chip_get_tsf(&mac->chip);
}

Daniel Drake's avatar
Daniel Drake committed
936 937 938 939 940 941 942 943
static const struct ieee80211_ops zd_ops = {
	.tx			= zd_op_tx,
	.start			= zd_op_start,
	.stop			= zd_op_stop,
	.add_interface		= zd_op_add_interface,
	.remove_interface	= zd_op_remove_interface,
	.config			= zd_op_config,
	.configure_filter	= zd_op_configure_filter,
944
	.bss_info_changed	= zd_op_bss_info_changed,
945
	.get_tsf		= zd_op_get_tsf,
Daniel Drake's avatar
Daniel Drake committed
946 947 948
};

struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
949
{
Daniel Drake's avatar
Daniel Drake committed
950 951
	struct zd_mac *mac;
	struct ieee80211_hw *hw;
952

Daniel Drake's avatar
Daniel Drake committed
953 954 955 956
	hw = ieee80211_alloc_hw(sizeof(struct zd_mac), &zd_ops);
	if (!hw) {
		dev_dbg_f(&intf->dev, "out of memory\n");
		return NULL;
957
	}
Daniel Drake's avatar
Daniel Drake committed
958 959 960 961 962 963 964

	mac = zd_hw_mac(hw);

	memset(mac, 0, sizeof(*mac));
	spin_lock_init(&mac->lock);
	mac->hw = hw;

965
	mac->type = NL80211_IFTYPE_UNSPECIFIED;
Daniel Drake's avatar
Daniel Drake committed
966 967 968

	memcpy(mac->channels, zd_channels, sizeof(zd_channels));
	memcpy(mac->rates, zd_rates, sizeof(zd_rates));
969 970 971 972 973 974 975
	mac->band.n_bitrates = ARRAY_SIZE(zd_rates);
	mac->band.bitrates = mac->rates;
	mac->band.n_channels = ARRAY_SIZE(zd_channels);
	mac->band.channels = mac->channels;

	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;

976
	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
Johannes Berg's avatar
Johannes Berg committed
977
		    IEEE80211_HW_SIGNAL_UNSPEC;
Daniel Drake's avatar
Daniel Drake committed
978

979 980 981 982 983
	hw->wiphy->interface_modes =
		BIT(NL80211_IFTYPE_MESH_POINT) |
		BIT(NL80211_IFTYPE_STATION) |
		BIT(NL80211_IFTYPE_ADHOC);

984
	hw->max_signal = 100;
Daniel Drake's avatar
Daniel Drake committed
985 986 987 988 989 990 991 992 993 994
	hw->queues = 1;
	hw->extra_tx_headroom = sizeof(struct zd_ctrlset);

	skb_queue_head_init(&mac->ack_wait_queue);

	zd_chip_init(&mac->chip, hw, intf);
	housekeeping_init(mac);
	INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler);
	INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work);
	INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler);
995
	INIT_WORK(&mac->process_intr, zd_process_intr);
Daniel Drake's avatar
Daniel Drake committed
996 997 998

	SET_IEEE80211_DEV(hw, &intf->dev);
	return hw;
Daniel Drake's avatar