blob: 0acb5c345734760645025d36a7d289504ec93611 [file] [log] [blame]
Daniel Drake66bb42f2007-11-19 16:20:12 +00001/* ZD1211 USB-WLAN driver for Linux
2 *
3 * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
4 * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
Daniel Drakee85d0912006-06-02 17:11:32 +01005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/* This file implements all the hardware specific functions for the ZD1211
22 * and ZD1211B chips. Support for the ZD1211B was possible after Timothy
23 * Legge sent me a ZD1211B device. Thank you Tim. -- Uli
24 */
25
26#include <linux/kernel.h>
27#include <linux/errno.h>
28
29#include "zd_def.h"
30#include "zd_chip.h"
31#include "zd_ieee80211.h"
32#include "zd_mac.h"
33#include "zd_rf.h"
Daniel Drakee85d0912006-06-02 17:11:32 +010034
35void zd_chip_init(struct zd_chip *chip,
Daniel Drake459c51a2007-11-19 15:00:29 +000036 struct ieee80211_hw *hw,
Daniel Drakee85d0912006-06-02 17:11:32 +010037 struct usb_interface *intf)
38{
39 memset(chip, 0, sizeof(*chip));
40 mutex_init(&chip->mutex);
Daniel Drake459c51a2007-11-19 15:00:29 +000041 zd_usb_init(&chip->usb, hw, intf);
Daniel Drakee85d0912006-06-02 17:11:32 +010042 zd_rf_init(&chip->rf);
43}
44
45void zd_chip_clear(struct zd_chip *chip)
46{
Ulrich Kunitzc48cf122006-08-12 18:00:17 +010047 ZD_ASSERT(!mutex_is_locked(&chip->mutex));
Daniel Drakee85d0912006-06-02 17:11:32 +010048 zd_usb_clear(&chip->usb);
49 zd_rf_clear(&chip->rf);
Daniel Drakee85d0912006-06-02 17:11:32 +010050 mutex_destroy(&chip->mutex);
Ulrich Kunitzc48cf122006-08-12 18:00:17 +010051 ZD_MEMCLEAR(chip, sizeof(*chip));
Daniel Drakee85d0912006-06-02 17:11:32 +010052}
53
Daniel Drake74553ae2007-07-01 18:22:32 +010054static int scnprint_mac_oui(struct zd_chip *chip, char *buffer, size_t size)
Daniel Drakee85d0912006-06-02 17:11:32 +010055{
Daniel Drake459c51a2007-11-19 15:00:29 +000056 u8 *addr = zd_mac_get_perm_addr(zd_chip_to_mac(chip));
Daniel Drakee85d0912006-06-02 17:11:32 +010057 return scnprintf(buffer, size, "%02x-%02x-%02x",
58 addr[0], addr[1], addr[2]);
59}
60
61/* Prints an identifier line, which will support debugging. */
62static int scnprint_id(struct zd_chip *chip, char *buffer, size_t size)
63{
64 int i = 0;
65
66 i = scnprintf(buffer, size, "zd1211%s chip ",
Daniel Drake74553ae2007-07-01 18:22:32 +010067 zd_chip_is_zd1211b(chip) ? "b" : "");
Daniel Drakee85d0912006-06-02 17:11:32 +010068 i += zd_usb_scnprint_id(&chip->usb, buffer+i, size-i);
69 i += scnprintf(buffer+i, size-i, " ");
Daniel Drake74553ae2007-07-01 18:22:32 +010070 i += scnprint_mac_oui(chip, buffer+i, size-i);
Daniel Drakee85d0912006-06-02 17:11:32 +010071 i += scnprintf(buffer+i, size-i, " ");
72 i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i);
Daniel Drakef2a81a12007-03-11 19:54:28 +000073 i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c%c", chip->pa_type,
Daniel Drakee85d0912006-06-02 17:11:32 +010074 chip->patch_cck_gain ? 'g' : '-',
75 chip->patch_cr157 ? '7' : '-',
Daniel Drake20fe2172006-08-12 17:59:42 +010076 chip->patch_6m_band_edge ? '6' : '-',
Daniel Drakef2a81a12007-03-11 19:54:28 +000077 chip->new_phy_layout ? 'N' : '-',
78 chip->al2230s_bit ? 'S' : '-');
Daniel Drakee85d0912006-06-02 17:11:32 +010079 return i;
80}
81
82static void print_id(struct zd_chip *chip)
83{
84 char buffer[80];
85
86 scnprint_id(chip, buffer, sizeof(buffer));
87 buffer[sizeof(buffer)-1] = 0;
88 dev_info(zd_chip_dev(chip), "%s\n", buffer);
89}
90
Daniel Drake0ce34bc2006-12-12 01:26:11 +000091static zd_addr_t inc_addr(zd_addr_t addr)
92{
93 u16 a = (u16)addr;
94 /* Control registers use byte addressing, but everything else uses word
95 * addressing. */
96 if ((a & 0xf000) == CR_START)
97 a += 2;
98 else
99 a += 1;
100 return (zd_addr_t)a;
101}
102
Daniel Drakee85d0912006-06-02 17:11:32 +0100103/* Read a variable number of 32-bit values. Parameter count is not allowed to
104 * exceed USB_MAX_IOREAD32_COUNT.
105 */
106int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr,
107 unsigned int count)
108{
109 int r;
110 int i;
Jesper Juhlfa460812007-08-31 00:30:31 +0200111 zd_addr_t *a16;
Daniel Drakee85d0912006-06-02 17:11:32 +0100112 u16 *v16;
113 unsigned int count16;
114
115 if (count > USB_MAX_IOREAD32_COUNT)
116 return -EINVAL;
117
118 /* Allocate a single memory block for values and addresses. */
119 count16 = 2*count;
Daniel Drake44956852007-02-10 01:27:18 +0000120 a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
Ulrich Kunitz35c34042007-02-18 20:28:23 +0000121 GFP_KERNEL);
Daniel Drakee85d0912006-06-02 17:11:32 +0100122 if (!a16) {
123 dev_dbg_f(zd_chip_dev(chip),
124 "error ENOMEM in allocation of a16\n");
125 r = -ENOMEM;
126 goto out;
127 }
128 v16 = (u16 *)(a16 + count16);
129
130 for (i = 0; i < count; i++) {
131 int j = 2*i;
132 /* We read the high word always first. */
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000133 a16[j] = inc_addr(addr[i]);
Daniel Drakee85d0912006-06-02 17:11:32 +0100134 a16[j+1] = addr[i];
135 }
136
137 r = zd_ioread16v_locked(chip, v16, a16, count16);
138 if (r) {
139 dev_dbg_f(zd_chip_dev(chip),
140 "error: zd_ioread16v_locked. Error number %d\n", r);
141 goto out;
142 }
143
144 for (i = 0; i < count; i++) {
145 int j = 2*i;
146 values[i] = (v16[j] << 16) | v16[j+1];
147 }
148
149out:
150 kfree((void *)a16);
151 return r;
152}
153
154int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
155 unsigned int count)
156{
157 int i, j, r;
158 struct zd_ioreq16 *ioreqs16;
159 unsigned int count16;
160
161 ZD_ASSERT(mutex_is_locked(&chip->mutex));
162
163 if (count == 0)
164 return 0;
165 if (count > USB_MAX_IOWRITE32_COUNT)
166 return -EINVAL;
167
168 /* Allocate a single memory block for values and addresses. */
169 count16 = 2*count;
Ulrich Kunitz35c34042007-02-18 20:28:23 +0000170 ioreqs16 = kmalloc(count16 * sizeof(struct zd_ioreq16), GFP_KERNEL);
Daniel Drakee85d0912006-06-02 17:11:32 +0100171 if (!ioreqs16) {
172 r = -ENOMEM;
173 dev_dbg_f(zd_chip_dev(chip),
174 "error %d in ioreqs16 allocation\n", r);
175 goto out;
176 }
177
178 for (i = 0; i < count; i++) {
179 j = 2*i;
180 /* We write the high word always first. */
181 ioreqs16[j].value = ioreqs[i].value >> 16;
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000182 ioreqs16[j].addr = inc_addr(ioreqs[i].addr);
Daniel Drakee85d0912006-06-02 17:11:32 +0100183 ioreqs16[j+1].value = ioreqs[i].value;
184 ioreqs16[j+1].addr = ioreqs[i].addr;
185 }
186
187 r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16);
188#ifdef DEBUG
189 if (r) {
190 dev_dbg_f(zd_chip_dev(chip),
191 "error %d in zd_usb_write16v\n", r);
192 }
193#endif /* DEBUG */
194out:
195 kfree(ioreqs16);
196 return r;
197}
198
199int zd_iowrite16a_locked(struct zd_chip *chip,
200 const struct zd_ioreq16 *ioreqs, unsigned int count)
201{
202 int r;
203 unsigned int i, j, t, max;
204
205 ZD_ASSERT(mutex_is_locked(&chip->mutex));
206 for (i = 0; i < count; i += j + t) {
207 t = 0;
208 max = count-i;
209 if (max > USB_MAX_IOWRITE16_COUNT)
210 max = USB_MAX_IOWRITE16_COUNT;
211 for (j = 0; j < max; j++) {
212 if (!ioreqs[i+j].addr) {
213 t = 1;
214 break;
215 }
216 }
217
218 r = zd_usb_iowrite16v(&chip->usb, &ioreqs[i], j);
219 if (r) {
220 dev_dbg_f(zd_chip_dev(chip),
221 "error zd_usb_iowrite16v. Error number %d\n",
222 r);
223 return r;
224 }
225 }
226
227 return 0;
228}
229
230/* Writes a variable number of 32 bit registers. The functions will split
231 * that in several USB requests. A split can be forced by inserting an IO
232 * request with an zero address field.
233 */
234int zd_iowrite32a_locked(struct zd_chip *chip,
235 const struct zd_ioreq32 *ioreqs, unsigned int count)
236{
237 int r;
238 unsigned int i, j, t, max;
239
240 for (i = 0; i < count; i += j + t) {
241 t = 0;
242 max = count-i;
243 if (max > USB_MAX_IOWRITE32_COUNT)
244 max = USB_MAX_IOWRITE32_COUNT;
245 for (j = 0; j < max; j++) {
246 if (!ioreqs[i+j].addr) {
247 t = 1;
248 break;
249 }
250 }
251
252 r = _zd_iowrite32v_locked(chip, &ioreqs[i], j);
253 if (r) {
254 dev_dbg_f(zd_chip_dev(chip),
255 "error _zd_iowrite32v_locked."
256 " Error number %d\n", r);
257 return r;
258 }
259 }
260
261 return 0;
262}
263
264int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value)
265{
266 int r;
267
Daniel Drakee85d0912006-06-02 17:11:32 +0100268 mutex_lock(&chip->mutex);
269 r = zd_ioread16_locked(chip, value, addr);
270 mutex_unlock(&chip->mutex);
271 return r;
272}
273
274int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value)
275{
276 int r;
277
Daniel Drakee85d0912006-06-02 17:11:32 +0100278 mutex_lock(&chip->mutex);
279 r = zd_ioread32_locked(chip, value, addr);
280 mutex_unlock(&chip->mutex);
281 return r;
282}
283
284int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value)
285{
286 int r;
287
Daniel Drakee85d0912006-06-02 17:11:32 +0100288 mutex_lock(&chip->mutex);
289 r = zd_iowrite16_locked(chip, value, addr);
290 mutex_unlock(&chip->mutex);
291 return r;
292}
293
294int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value)
295{
296 int r;
297
Daniel Drakee85d0912006-06-02 17:11:32 +0100298 mutex_lock(&chip->mutex);
299 r = zd_iowrite32_locked(chip, value, addr);
300 mutex_unlock(&chip->mutex);
301 return r;
302}
303
304int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses,
305 u32 *values, unsigned int count)
306{
307 int r;
308
Daniel Drakee85d0912006-06-02 17:11:32 +0100309 mutex_lock(&chip->mutex);
310 r = zd_ioread32v_locked(chip, values, addresses, count);
311 mutex_unlock(&chip->mutex);
312 return r;
313}
314
315int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
316 unsigned int count)
317{
318 int r;
319
Daniel Drakee85d0912006-06-02 17:11:32 +0100320 mutex_lock(&chip->mutex);
321 r = zd_iowrite32a_locked(chip, ioreqs, count);
322 mutex_unlock(&chip->mutex);
323 return r;
324}
325
326static int read_pod(struct zd_chip *chip, u8 *rf_type)
327{
328 int r;
329 u32 value;
330
331 ZD_ASSERT(mutex_is_locked(&chip->mutex));
332 r = zd_ioread32_locked(chip, &value, E2P_POD);
333 if (r)
334 goto error;
335 dev_dbg_f(zd_chip_dev(chip), "E2P_POD %#010x\n", value);
336
337 /* FIXME: AL2230 handling (Bit 7 in POD) */
338 *rf_type = value & 0x0f;
339 chip->pa_type = (value >> 16) & 0x0f;
340 chip->patch_cck_gain = (value >> 8) & 0x1;
341 chip->patch_cr157 = (value >> 13) & 0x1;
342 chip->patch_6m_band_edge = (value >> 21) & 0x1;
Daniel Drake20fe2172006-08-12 17:59:42 +0100343 chip->new_phy_layout = (value >> 31) & 0x1;
Daniel Drakeae6ead42007-03-11 19:54:11 +0000344 chip->al2230s_bit = (value >> 7) & 0x1;
Ulrich Kunitz583afd12006-09-13 02:42:38 +0100345 chip->link_led = ((value >> 4) & 1) ? LED1 : LED2;
346 chip->supports_tx_led = 1;
347 if (value & (1 << 24)) { /* LED scenario */
348 if (value & (1 << 29))
349 chip->supports_tx_led = 0;
350 }
Daniel Drakee85d0912006-06-02 17:11:32 +0100351
352 dev_dbg_f(zd_chip_dev(chip),
353 "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d "
Ulrich Kunitz583afd12006-09-13 02:42:38 +0100354 "patch 6M %d new PHY %d link LED%d tx led %d\n",
Daniel Drakee85d0912006-06-02 17:11:32 +0100355 zd_rf_name(*rf_type), *rf_type,
356 chip->pa_type, chip->patch_cck_gain,
Ulrich Kunitz583afd12006-09-13 02:42:38 +0100357 chip->patch_cr157, chip->patch_6m_band_edge,
358 chip->new_phy_layout,
359 chip->link_led == LED1 ? 1 : 2,
360 chip->supports_tx_led);
Daniel Drakee85d0912006-06-02 17:11:32 +0100361 return 0;
362error:
363 *rf_type = 0;
364 chip->pa_type = 0;
365 chip->patch_cck_gain = 0;
366 chip->patch_cr157 = 0;
367 chip->patch_6m_band_edge = 0;
Daniel Drake20fe2172006-08-12 17:59:42 +0100368 chip->new_phy_layout = 0;
Daniel Drakee85d0912006-06-02 17:11:32 +0100369 return r;
370}
371
Daniel Drakee85d0912006-06-02 17:11:32 +0100372/* MAC address: if custom mac addresses are to to be used CR_MAC_ADDR_P1 and
373 * CR_MAC_ADDR_P2 must be overwritten
374 */
Daniel Drakee85d0912006-06-02 17:11:32 +0100375int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
376{
377 int r;
378 struct zd_ioreq32 reqs[2] = {
379 [0] = { .addr = CR_MAC_ADDR_P1 },
380 [1] = { .addr = CR_MAC_ADDR_P2 },
381 };
Joe Perches0795af52007-10-03 17:59:30 -0700382 DECLARE_MAC_BUF(mac);
Daniel Drakee85d0912006-06-02 17:11:32 +0100383
Daniel Drake459c51a2007-11-19 15:00:29 +0000384 if (mac_addr) {
385 reqs[0].value = (mac_addr[3] << 24)
386 | (mac_addr[2] << 16)
387 | (mac_addr[1] << 8)
388 | mac_addr[0];
389 reqs[1].value = (mac_addr[5] << 8)
390 | mac_addr[4];
391 dev_dbg_f(zd_chip_dev(chip),
392 "mac addr %s\n", print_mac(mac, mac_addr));
393 } else {
394 dev_dbg_f(zd_chip_dev(chip), "set NULL mac\n");
395 }
Daniel Drakee85d0912006-06-02 17:11:32 +0100396
397 mutex_lock(&chip->mutex);
398 r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
Daniel Drakee85d0912006-06-02 17:11:32 +0100399 mutex_unlock(&chip->mutex);
400 return r;
401}
402
403int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain)
404{
405 int r;
406 u32 value;
407
408 mutex_lock(&chip->mutex);
409 r = zd_ioread32_locked(chip, &value, E2P_SUBID);
410 mutex_unlock(&chip->mutex);
411 if (r)
412 return r;
413
414 *regdomain = value >> 16;
415 dev_dbg_f(zd_chip_dev(chip), "regdomain: %#04x\n", *regdomain);
416
417 return 0;
418}
419
420static int read_values(struct zd_chip *chip, u8 *values, size_t count,
421 zd_addr_t e2p_addr, u32 guard)
422{
423 int r;
424 int i;
425 u32 v;
426
427 ZD_ASSERT(mutex_is_locked(&chip->mutex));
428 for (i = 0;;) {
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000429 r = zd_ioread32_locked(chip, &v,
430 (zd_addr_t)((u16)e2p_addr+i/2));
Daniel Drakee85d0912006-06-02 17:11:32 +0100431 if (r)
432 return r;
433 v -= guard;
434 if (i+4 < count) {
435 values[i++] = v;
436 values[i++] = v >> 8;
437 values[i++] = v >> 16;
438 values[i++] = v >> 24;
439 continue;
440 }
441 for (;i < count; i++)
442 values[i] = v >> (8*(i%3));
443 return 0;
444 }
445}
446
447static int read_pwr_cal_values(struct zd_chip *chip)
448{
449 return read_values(chip, chip->pwr_cal_values,
450 E2P_CHANNEL_COUNT, E2P_PWR_CAL_VALUE1,
451 0);
452}
453
454static int read_pwr_int_values(struct zd_chip *chip)
455{
456 return read_values(chip, chip->pwr_int_values,
457 E2P_CHANNEL_COUNT, E2P_PWR_INT_VALUE1,
458 E2P_PWR_INT_GUARD);
459}
460
461static int read_ofdm_cal_values(struct zd_chip *chip)
462{
463 int r;
464 int i;
465 static const zd_addr_t addresses[] = {
466 E2P_36M_CAL_VALUE1,
467 E2P_48M_CAL_VALUE1,
468 E2P_54M_CAL_VALUE1,
469 };
470
471 for (i = 0; i < 3; i++) {
472 r = read_values(chip, chip->ofdm_cal_values[i],
473 E2P_CHANNEL_COUNT, addresses[i], 0);
474 if (r)
475 return r;
476 }
477 return 0;
478}
479
480static int read_cal_int_tables(struct zd_chip *chip)
481{
482 int r;
483
484 r = read_pwr_cal_values(chip);
485 if (r)
486 return r;
487 r = read_pwr_int_values(chip);
488 if (r)
489 return r;
490 r = read_ofdm_cal_values(chip);
491 if (r)
492 return r;
493 return 0;
494}
495
496/* phy means physical registers */
497int zd_chip_lock_phy_regs(struct zd_chip *chip)
498{
499 int r;
500 u32 tmp;
501
502 ZD_ASSERT(mutex_is_locked(&chip->mutex));
503 r = zd_ioread32_locked(chip, &tmp, CR_REG1);
504 if (r) {
505 dev_err(zd_chip_dev(chip), "error ioread32(CR_REG1): %d\n", r);
506 return r;
507 }
508
Daniel Drakee85d0912006-06-02 17:11:32 +0100509 tmp &= ~UNLOCK_PHY_REGS;
510
511 r = zd_iowrite32_locked(chip, tmp, CR_REG1);
512 if (r)
513 dev_err(zd_chip_dev(chip), "error iowrite32(CR_REG1): %d\n", r);
514 return r;
515}
516
517int zd_chip_unlock_phy_regs(struct zd_chip *chip)
518{
519 int r;
520 u32 tmp;
521
522 ZD_ASSERT(mutex_is_locked(&chip->mutex));
523 r = zd_ioread32_locked(chip, &tmp, CR_REG1);
524 if (r) {
525 dev_err(zd_chip_dev(chip),
526 "error ioread32(CR_REG1): %d\n", r);
527 return r;
528 }
529
Daniel Drakee85d0912006-06-02 17:11:32 +0100530 tmp |= UNLOCK_PHY_REGS;
531
532 r = zd_iowrite32_locked(chip, tmp, CR_REG1);
533 if (r)
534 dev_err(zd_chip_dev(chip), "error iowrite32(CR_REG1): %d\n", r);
535 return r;
536}
537
Daniel Drake92b3e2e2007-04-03 23:17:37 +0100538/* CR157 can be optionally patched by the EEPROM for original ZD1211 */
Daniel Drakee85d0912006-06-02 17:11:32 +0100539static int patch_cr157(struct zd_chip *chip)
540{
541 int r;
Daniel Drake92b3e2e2007-04-03 23:17:37 +0100542 u16 value;
Daniel Drakee85d0912006-06-02 17:11:32 +0100543
544 if (!chip->patch_cr157)
545 return 0;
546
Daniel Drake92b3e2e2007-04-03 23:17:37 +0100547 r = zd_ioread16_locked(chip, &value, E2P_PHY_REG);
Daniel Drakee85d0912006-06-02 17:11:32 +0100548 if (r)
549 return r;
550
551 dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value >> 8);
552 return zd_iowrite32_locked(chip, value >> 8, CR157);
553}
554
555/*
556 * 6M band edge can be optionally overwritten for certain RF's
557 * Vendor driver says: for FCC regulation, enabled per HWFeature 6M band edge
558 * bit (for AL2230, AL2230S)
559 */
Daniel Drake72018b22007-04-07 16:00:15 +0100560static int patch_6m_band_edge(struct zd_chip *chip, u8 channel)
561{
562 ZD_ASSERT(mutex_is_locked(&chip->mutex));
563 if (!chip->patch_6m_band_edge)
564 return 0;
565
566 return zd_rf_patch_6m_band_edge(&chip->rf, channel);
567}
568
569/* Generic implementation of 6M band edge patching, used by most RFs via
570 * zd_rf_generic_patch_6m() */
571int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel)
Daniel Drakee85d0912006-06-02 17:11:32 +0100572{
573 struct zd_ioreq16 ioreqs[] = {
574 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
575 { CR47, 0x1e },
576 };
577
Daniel Drakee85d0912006-06-02 17:11:32 +0100578 /* FIXME: Channel 11 is not the edge for all regulatory domains. */
579 if (channel == 1 || channel == 11)
580 ioreqs[0].value = 0x12;
581
582 dev_dbg_f(zd_chip_dev(chip), "patching for channel %d\n", channel);
583 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
584}
585
586static int zd1211_hw_reset_phy(struct zd_chip *chip)
587{
588 static const struct zd_ioreq16 ioreqs[] = {
589 { CR0, 0x0a }, { CR1, 0x06 }, { CR2, 0x26 },
590 { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xa0 },
591 { CR10, 0x81 }, { CR11, 0x00 }, { CR12, 0x7f },
592 { CR13, 0x8c }, { CR14, 0x80 }, { CR15, 0x3d },
593 { CR16, 0x20 }, { CR17, 0x1e }, { CR18, 0x0a },
594 { CR19, 0x48 }, { CR20, 0x0c }, { CR21, 0x0c },
595 { CR22, 0x23 }, { CR23, 0x90 }, { CR24, 0x14 },
596 { CR25, 0x40 }, { CR26, 0x10 }, { CR27, 0x19 },
597 { CR28, 0x7f }, { CR29, 0x80 }, { CR30, 0x4b },
598 { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 },
599 { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 },
600 { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },
601 { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 },
602 { CR43, 0x10 }, { CR44, 0x12 }, { CR46, 0xff },
603 { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b },
604 { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 },
605 { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 },
606 { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff },
607 { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 },
608 { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 },
609 { CR79, 0x68 }, { CR80, 0x64 }, { CR81, 0x64 },
610 { CR82, 0x00 }, { CR83, 0x00 }, { CR84, 0x00 },
611 { CR85, 0x02 }, { CR86, 0x00 }, { CR87, 0x00 },
612 { CR88, 0xff }, { CR89, 0xfc }, { CR90, 0x00 },
613 { CR91, 0x00 }, { CR92, 0x00 }, { CR93, 0x08 },
614 { CR94, 0x00 }, { CR95, 0x00 }, { CR96, 0xff },
615 { CR97, 0xe7 }, { CR98, 0x00 }, { CR99, 0x00 },
616 { CR100, 0x00 }, { CR101, 0xae }, { CR102, 0x02 },
617 { CR103, 0x00 }, { CR104, 0x03 }, { CR105, 0x65 },
618 { CR106, 0x04 }, { CR107, 0x00 }, { CR108, 0x0a },
619 { CR109, 0xaa }, { CR110, 0xaa }, { CR111, 0x25 },
620 { CR112, 0x25 }, { CR113, 0x00 }, { CR119, 0x1e },
621 { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
622 { },
623 { CR5, 0x00 }, { CR6, 0x00 }, { CR7, 0x00 },
624 { CR8, 0x00 }, { CR9, 0x20 }, { CR12, 0xf0 },
625 { CR20, 0x0e }, { CR21, 0x0e }, { CR27, 0x10 },
626 { CR44, 0x33 }, { CR47, 0x1E }, { CR83, 0x24 },
627 { CR84, 0x04 }, { CR85, 0x00 }, { CR86, 0x0C },
628 { CR87, 0x12 }, { CR88, 0x0C }, { CR89, 0x00 },
629 { CR90, 0x10 }, { CR91, 0x08 }, { CR93, 0x00 },
630 { CR94, 0x01 }, { CR95, 0x00 }, { CR96, 0x50 },
631 { CR97, 0x37 }, { CR98, 0x35 }, { CR101, 0x13 },
632 { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
633 { CR105, 0x12 }, { CR109, 0x27 }, { CR110, 0x27 },
634 { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
635 { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
636 { CR117, 0xfc }, { CR118, 0xfa }, { CR120, 0x4f },
Daniel Drakedc536a72007-04-03 23:17:10 +0100637 { CR125, 0xaa }, { CR127, 0x03 }, { CR128, 0x14 },
638 { CR129, 0x12 }, { CR130, 0x10 }, { CR131, 0x0C },
639 { CR136, 0xdf }, { CR137, 0x40 }, { CR138, 0xa0 },
640 { CR139, 0xb0 }, { CR140, 0x99 }, { CR141, 0x82 },
641 { CR142, 0x54 }, { CR143, 0x1c }, { CR144, 0x6c },
642 { CR147, 0x07 }, { CR148, 0x4c }, { CR149, 0x50 },
643 { CR150, 0x0e }, { CR151, 0x18 }, { CR160, 0xfe },
644 { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
645 { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
646 { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
647 { CR170, 0xba }, { CR171, 0xba },
Daniel Drakee85d0912006-06-02 17:11:32 +0100648 /* Note: CR204 must lead the CR203 */
649 { CR204, 0x7d },
650 { },
651 { CR203, 0x30 },
652 };
653
654 int r, t;
655
656 dev_dbg_f(zd_chip_dev(chip), "\n");
657
658 r = zd_chip_lock_phy_regs(chip);
659 if (r)
660 goto out;
661
662 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
663 if (r)
664 goto unlock;
665
666 r = patch_cr157(chip);
667unlock:
668 t = zd_chip_unlock_phy_regs(chip);
669 if (t && !r)
670 r = t;
671out:
672 return r;
673}
674
675static int zd1211b_hw_reset_phy(struct zd_chip *chip)
676{
677 static const struct zd_ioreq16 ioreqs[] = {
678 { CR0, 0x14 }, { CR1, 0x06 }, { CR2, 0x26 },
679 { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xe0 },
680 { CR10, 0x81 },
681 /* power control { { CR11, 1 << 6 }, */
682 { CR11, 0x00 },
683 { CR12, 0xf0 }, { CR13, 0x8c }, { CR14, 0x80 },
684 { CR15, 0x3d }, { CR16, 0x20 }, { CR17, 0x1e },
685 { CR18, 0x0a }, { CR19, 0x48 },
686 { CR20, 0x10 }, /* Org:0x0E, ComTrend:RalLink AP */
687 { CR21, 0x0e }, { CR22, 0x23 }, { CR23, 0x90 },
688 { CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 },
689 { CR27, 0x10 }, { CR28, 0x7f }, { CR29, 0x80 },
Daniel Drakefe7215c2006-08-12 17:59:12 +0100690 { CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */
Daniel Drakee85d0912006-06-02 17:11:32 +0100691 { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 },
692 { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 },
693 { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },
694 { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 },
695 { CR43, 0x10 }, { CR44, 0x33 }, { CR46, 0xff },
696 { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b },
697 { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 },
698 { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 },
699 { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff },
700 { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 },
701 { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 },
702 { CR79, 0xf0 }, { CR80, 0x64 }, { CR81, 0x64 },
703 { CR82, 0x00 }, { CR83, 0x24 }, { CR84, 0x04 },
704 { CR85, 0x00 }, { CR86, 0x0c }, { CR87, 0x12 },
705 { CR88, 0x0c }, { CR89, 0x00 }, { CR90, 0x58 },
706 { CR91, 0x04 }, { CR92, 0x00 }, { CR93, 0x00 },
707 { CR94, 0x01 },
708 { CR95, 0x20 }, /* ZD1211B */
709 { CR96, 0x50 }, { CR97, 0x37 }, { CR98, 0x35 },
710 { CR99, 0x00 }, { CR100, 0x01 }, { CR101, 0x13 },
711 { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
712 { CR105, 0x12 }, { CR106, 0x04 }, { CR107, 0x00 },
713 { CR108, 0x0a }, { CR109, 0x27 }, { CR110, 0x27 },
714 { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
715 { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
716 { CR117, 0xfc }, { CR118, 0xfa }, { CR119, 0x1e },
717 { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
718 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
719 { CR131, 0x0c }, { CR136, 0xdf }, { CR137, 0xa0 },
720 { CR138, 0xa8 }, { CR139, 0xb4 }, { CR140, 0x98 },
721 { CR141, 0x82 }, { CR142, 0x53 }, { CR143, 0x1c },
722 { CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x40 },
723 { CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */
724 { CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */
725 { CR151, 0x18 }, { CR159, 0x70 }, { CR160, 0xfe },
726 { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
727 { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
728 { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
729 { CR170, 0xba }, { CR171, 0xba },
730 /* Note: CR204 must lead the CR203 */
731 { CR204, 0x7d },
732 {},
733 { CR203, 0x30 },
734 };
735
736 int r, t;
737
738 dev_dbg_f(zd_chip_dev(chip), "\n");
739
740 r = zd_chip_lock_phy_regs(chip);
741 if (r)
742 goto out;
743
744 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drakee85d0912006-06-02 17:11:32 +0100745 t = zd_chip_unlock_phy_regs(chip);
746 if (t && !r)
747 r = t;
748out:
749 return r;
750}
751
752static int hw_reset_phy(struct zd_chip *chip)
753{
Daniel Drake74553ae2007-07-01 18:22:32 +0100754 return zd_chip_is_zd1211b(chip) ? zd1211b_hw_reset_phy(chip) :
Daniel Drakee85d0912006-06-02 17:11:32 +0100755 zd1211_hw_reset_phy(chip);
756}
757
758static int zd1211_hw_init_hmac(struct zd_chip *chip)
759{
760 static const struct zd_ioreq32 ioreqs[] = {
Daniel Drakee85d0912006-06-02 17:11:32 +0100761 { CR_ZD1211_RETRY_MAX, 0x2 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100762 { CR_RX_THRESHOLD, 0x000c0640 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100763 };
764
Daniel Drakee85d0912006-06-02 17:11:32 +0100765 dev_dbg_f(zd_chip_dev(chip), "\n");
766 ZD_ASSERT(mutex_is_locked(&chip->mutex));
Daniel Drake34c44912006-12-12 01:25:13 +0000767 return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drakee85d0912006-06-02 17:11:32 +0100768}
769
770static int zd1211b_hw_init_hmac(struct zd_chip *chip)
771{
772 static const struct zd_ioreq32 ioreqs[] = {
Daniel Drakee85d0912006-06-02 17:11:32 +0100773 { CR_ZD1211B_RETRY_MAX, 0x02020202 },
Javier Cardonae51c6832008-02-08 18:41:17 -0800774 { CR_ZD1211B_CWIN_MAX_MIN_AC0, 0x007f003f },
775 { CR_ZD1211B_CWIN_MAX_MIN_AC1, 0x007f003f },
776 { CR_ZD1211B_CWIN_MAX_MIN_AC2, 0x003f001f },
777 { CR_ZD1211B_CWIN_MAX_MIN_AC3, 0x001f000f },
Daniel Drakee85d0912006-06-02 17:11:32 +0100778 { CR_ZD1211B_AIFS_CTL1, 0x00280028 },
779 { CR_ZD1211B_AIFS_CTL2, 0x008C003C },
780 { CR_ZD1211B_TXOP, 0x01800824 },
Daniel Drake34c44912006-12-12 01:25:13 +0000781 { CR_RX_THRESHOLD, 0x000c0eff, },
782 };
783
784 dev_dbg_f(zd_chip_dev(chip), "\n");
785 ZD_ASSERT(mutex_is_locked(&chip->mutex));
786 return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
787}
788
789static int hw_init_hmac(struct zd_chip *chip)
790{
791 int r;
792 static const struct zd_ioreq32 ioreqs[] = {
793 { CR_ACK_TIMEOUT_EXT, 0x20 },
794 { CR_ADDA_MBIAS_WARMTIME, 0x30000808 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100795 { CR_SNIFFER_ON, 0 },
Ulrich Kunitzfde627b2006-08-01 23:43:35 +0200796 { CR_RX_FILTER, STA_RX_FILTER },
Daniel Drakee85d0912006-06-02 17:11:32 +0100797 { CR_GROUP_HASH_P1, 0x00 },
798 { CR_GROUP_HASH_P2, 0x80000000 },
799 { CR_REG1, 0xa4 },
800 { CR_ADDA_PWR_DWN, 0x7f },
801 { CR_BCN_PLCP_CFG, 0x00f00401 },
802 { CR_PHY_DELAY, 0x00 },
803 { CR_ACK_TIMEOUT_EXT, 0x80 },
804 { CR_ADDA_PWR_DWN, 0x00 },
805 { CR_ACK_TIME_80211, 0x100 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100806 { CR_RX_PE_DELAY, 0x70 },
807 { CR_PS_CTRL, 0x10000000 },
808 { CR_RTS_CTS_RATE, 0x02030203 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100809 { CR_AFTER_PNP, 0x1 },
810 { CR_WEP_PROTECT, 0x114 },
Daniel Drake34c44912006-12-12 01:25:13 +0000811 { CR_IFS_VALUE, IFS_VALUE_DEFAULT },
Luis Carlos Cobo72e77a82008-03-03 12:32:15 -0800812 { CR_CAM_MODE, MODE_AP_WDS},
Daniel Drakee85d0912006-06-02 17:11:32 +0100813 };
814
Daniel Drakee85d0912006-06-02 17:11:32 +0100815 ZD_ASSERT(mutex_is_locked(&chip->mutex));
816 r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drake34c44912006-12-12 01:25:13 +0000817 if (r)
818 return r;
Daniel Drakee85d0912006-06-02 17:11:32 +0100819
Daniel Drake74553ae2007-07-01 18:22:32 +0100820 return zd_chip_is_zd1211b(chip) ?
Daniel Drakee85d0912006-06-02 17:11:32 +0100821 zd1211b_hw_init_hmac(chip) : zd1211_hw_init_hmac(chip);
822}
823
824struct aw_pt_bi {
825 u32 atim_wnd_period;
826 u32 pre_tbtt;
827 u32 beacon_interval;
828};
829
830static int get_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
831{
832 int r;
833 static const zd_addr_t aw_pt_bi_addr[] =
834 { CR_ATIM_WND_PERIOD, CR_PRE_TBTT, CR_BCN_INTERVAL };
835 u32 values[3];
836
837 r = zd_ioread32v_locked(chip, values, (const zd_addr_t *)aw_pt_bi_addr,
838 ARRAY_SIZE(aw_pt_bi_addr));
839 if (r) {
840 memset(s, 0, sizeof(*s));
841 return r;
842 }
843
844 s->atim_wnd_period = values[0];
845 s->pre_tbtt = values[1];
846 s->beacon_interval = values[2];
Daniel Drakee85d0912006-06-02 17:11:32 +0100847 return 0;
848}
849
850static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
851{
852 struct zd_ioreq32 reqs[3];
853
854 if (s->beacon_interval <= 5)
855 s->beacon_interval = 5;
856 if (s->pre_tbtt < 4 || s->pre_tbtt >= s->beacon_interval)
857 s->pre_tbtt = s->beacon_interval - 1;
858 if (s->atim_wnd_period >= s->pre_tbtt)
859 s->atim_wnd_period = s->pre_tbtt - 1;
860
861 reqs[0].addr = CR_ATIM_WND_PERIOD;
862 reqs[0].value = s->atim_wnd_period;
863 reqs[1].addr = CR_PRE_TBTT;
864 reqs[1].value = s->pre_tbtt;
865 reqs[2].addr = CR_BCN_INTERVAL;
866 reqs[2].value = s->beacon_interval;
867
Daniel Drakee85d0912006-06-02 17:11:32 +0100868 return zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
869}
870
871
872static int set_beacon_interval(struct zd_chip *chip, u32 interval)
873{
874 int r;
875 struct aw_pt_bi s;
876
877 ZD_ASSERT(mutex_is_locked(&chip->mutex));
878 r = get_aw_pt_bi(chip, &s);
879 if (r)
880 return r;
881 s.beacon_interval = interval;
882 return set_aw_pt_bi(chip, &s);
883}
884
885int zd_set_beacon_interval(struct zd_chip *chip, u32 interval)
886{
887 int r;
888
889 mutex_lock(&chip->mutex);
890 r = set_beacon_interval(chip, interval);
891 mutex_unlock(&chip->mutex);
892 return r;
893}
894
895static int hw_init(struct zd_chip *chip)
896{
897 int r;
898
899 dev_dbg_f(zd_chip_dev(chip), "\n");
900 ZD_ASSERT(mutex_is_locked(&chip->mutex));
901 r = hw_reset_phy(chip);
902 if (r)
903 return r;
904
905 r = hw_init_hmac(chip);
906 if (r)
907 return r;
Daniel Drake98227a92006-08-12 17:59:22 +0100908
Daniel Drake98227a92006-08-12 17:59:22 +0100909 return set_beacon_interval(chip, 100);
Daniel Drakee85d0912006-06-02 17:11:32 +0100910}
911
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000912static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset)
913{
914 return (zd_addr_t)((u16)chip->fw_regs_base + offset);
915}
916
Daniel Drakee85d0912006-06-02 17:11:32 +0100917#ifdef DEBUG
918static int dump_cr(struct zd_chip *chip, const zd_addr_t addr,
919 const char *addr_string)
920{
921 int r;
922 u32 value;
923
924 r = zd_ioread32_locked(chip, &value, addr);
925 if (r) {
926 dev_dbg_f(zd_chip_dev(chip),
927 "error reading %s. Error number %d\n", addr_string, r);
928 return r;
929 }
930
931 dev_dbg_f(zd_chip_dev(chip), "%s %#010x\n",
932 addr_string, (unsigned int)value);
933 return 0;
934}
935
936static int test_init(struct zd_chip *chip)
937{
938 int r;
939
940 r = dump_cr(chip, CR_AFTER_PNP, "CR_AFTER_PNP");
941 if (r)
942 return r;
943 r = dump_cr(chip, CR_GPI_EN, "CR_GPI_EN");
944 if (r)
945 return r;
946 return dump_cr(chip, CR_INTERRUPT, "CR_INTERRUPT");
947}
948
949static void dump_fw_registers(struct zd_chip *chip)
950{
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000951 const zd_addr_t addr[4] = {
952 fw_reg_addr(chip, FW_REG_FIRMWARE_VER),
953 fw_reg_addr(chip, FW_REG_USB_SPEED),
954 fw_reg_addr(chip, FW_REG_FIX_TX_RATE),
955 fw_reg_addr(chip, FW_REG_LED_LINK_STATUS),
Daniel Drakee85d0912006-06-02 17:11:32 +0100956 };
957
958 int r;
959 u16 values[4];
960
961 r = zd_ioread16v_locked(chip, values, (const zd_addr_t*)addr,
962 ARRAY_SIZE(addr));
963 if (r) {
964 dev_dbg_f(zd_chip_dev(chip), "error %d zd_ioread16v_locked\n",
965 r);
966 return;
967 }
968
969 dev_dbg_f(zd_chip_dev(chip), "FW_FIRMWARE_VER %#06hx\n", values[0]);
970 dev_dbg_f(zd_chip_dev(chip), "FW_USB_SPEED %#06hx\n", values[1]);
971 dev_dbg_f(zd_chip_dev(chip), "FW_FIX_TX_RATE %#06hx\n", values[2]);
972 dev_dbg_f(zd_chip_dev(chip), "FW_LINK_STATUS %#06hx\n", values[3]);
973}
974#endif /* DEBUG */
975
976static int print_fw_version(struct zd_chip *chip)
977{
978 int r;
979 u16 version;
980
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000981 r = zd_ioread16_locked(chip, &version,
982 fw_reg_addr(chip, FW_REG_FIRMWARE_VER));
Daniel Drakee85d0912006-06-02 17:11:32 +0100983 if (r)
984 return r;
985
986 dev_info(zd_chip_dev(chip),"firmware version %04hx\n", version);
987 return 0;
988}
989
Johannes Berg8318d782008-01-24 19:38:38 +0100990static int set_mandatory_rates(struct zd_chip *chip, int gmode)
Daniel Drakee85d0912006-06-02 17:11:32 +0100991{
992 u32 rates;
993 ZD_ASSERT(mutex_is_locked(&chip->mutex));
994 /* This sets the mandatory rates, which only depend from the standard
995 * that the device is supporting. Until further notice we should try
996 * to support 802.11g also for full speed USB.
997 */
Johannes Berg8318d782008-01-24 19:38:38 +0100998 if (!gmode)
Daniel Drakee85d0912006-06-02 17:11:32 +0100999 rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M;
Johannes Berg8318d782008-01-24 19:38:38 +01001000 else
Daniel Drakee85d0912006-06-02 17:11:32 +01001001 rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M|
1002 CR_RATE_6M|CR_RATE_12M|CR_RATE_24M;
Johannes Berg8318d782008-01-24 19:38:38 +01001003
Daniel Drakee85d0912006-06-02 17:11:32 +01001004 return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL);
1005}
1006
Daniel Drakeb1382ed2006-11-22 00:06:48 +00001007int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
Daniel Drake459c51a2007-11-19 15:00:29 +00001008 int preamble)
Daniel Drakeb1382ed2006-11-22 00:06:48 +00001009{
Daniel Drakeb1382ed2006-11-22 00:06:48 +00001010 u32 value = 0;
1011
Daniel Drake459c51a2007-11-19 15:00:29 +00001012 dev_dbg_f(zd_chip_dev(chip), "preamble=%x\n", preamble);
Daniel Drakeb1382ed2006-11-22 00:06:48 +00001013 value |= preamble << RTSCTS_SH_RTS_PMB_TYPE;
1014 value |= preamble << RTSCTS_SH_CTS_PMB_TYPE;
1015
Daniel Drake459c51a2007-11-19 15:00:29 +00001016 /* We always send 11M RTS/self-CTS messages, like the vendor driver. */
1017 value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_RTS_RATE;
1018 value |= ZD_RX_CCK << RTSCTS_SH_RTS_MOD_TYPE;
Ulrich Kunitz64f222c2007-08-06 01:24:31 +01001019 value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_CTS_RATE;
Daniel Drakeb1382ed2006-11-22 00:06:48 +00001020 value |= ZD_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE;
1021
1022 return zd_iowrite32_locked(chip, value, CR_RTS_CTS_RATE);
1023}
1024
Daniel Drakee85d0912006-06-02 17:11:32 +01001025int zd_chip_enable_hwint(struct zd_chip *chip)
1026{
1027 int r;
1028
1029 mutex_lock(&chip->mutex);
1030 r = zd_iowrite32_locked(chip, HWINT_ENABLED, CR_INTERRUPT);
1031 mutex_unlock(&chip->mutex);
1032 return r;
1033}
1034
1035static int disable_hwint(struct zd_chip *chip)
1036{
1037 return zd_iowrite32_locked(chip, HWINT_DISABLED, CR_INTERRUPT);
1038}
1039
1040int zd_chip_disable_hwint(struct zd_chip *chip)
1041{
1042 int r;
1043
1044 mutex_lock(&chip->mutex);
1045 r = disable_hwint(chip);
1046 mutex_unlock(&chip->mutex);
1047 return r;
1048}
1049
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001050static int read_fw_regs_offset(struct zd_chip *chip)
1051{
1052 int r;
1053
1054 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1055 r = zd_ioread16_locked(chip, (u16*)&chip->fw_regs_base,
1056 FWRAW_REGS_ADDR);
1057 if (r)
1058 return r;
1059 dev_dbg_f(zd_chip_dev(chip), "fw_regs_base: %#06hx\n",
1060 (u16)chip->fw_regs_base);
1061
1062 return 0;
1063}
1064
Daniel Drake74553ae2007-07-01 18:22:32 +01001065/* Read mac address using pre-firmware interface */
1066int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr)
1067{
1068 dev_dbg_f(zd_chip_dev(chip), "\n");
1069 return zd_usb_read_fw(&chip->usb, E2P_MAC_ADDR_P1, addr,
1070 ETH_ALEN);
1071}
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001072
Daniel Drake74553ae2007-07-01 18:22:32 +01001073int zd_chip_init_hw(struct zd_chip *chip)
Daniel Drakee85d0912006-06-02 17:11:32 +01001074{
1075 int r;
1076 u8 rf_type;
1077
1078 dev_dbg_f(zd_chip_dev(chip), "\n");
1079
1080 mutex_lock(&chip->mutex);
Daniel Drakee85d0912006-06-02 17:11:32 +01001081
1082#ifdef DEBUG
1083 r = test_init(chip);
1084 if (r)
1085 goto out;
1086#endif
1087 r = zd_iowrite32_locked(chip, 1, CR_AFTER_PNP);
1088 if (r)
1089 goto out;
1090
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001091 r = read_fw_regs_offset(chip);
Daniel Drakee85d0912006-06-02 17:11:32 +01001092 if (r)
1093 goto out;
1094
1095 /* GPI is always disabled, also in the other driver.
1096 */
1097 r = zd_iowrite32_locked(chip, 0, CR_GPI_EN);
1098 if (r)
1099 goto out;
1100 r = zd_iowrite32_locked(chip, CWIN_SIZE, CR_CWMIN_CWMAX);
1101 if (r)
1102 goto out;
1103 /* Currently we support IEEE 802.11g for full and high speed USB.
1104 * It might be discussed, whether we should suppport pure b mode for
1105 * full speed USB.
1106 */
Johannes Berg8318d782008-01-24 19:38:38 +01001107 r = set_mandatory_rates(chip, 1);
Daniel Drakee85d0912006-06-02 17:11:32 +01001108 if (r)
1109 goto out;
1110 /* Disabling interrupts is certainly a smart thing here.
1111 */
1112 r = disable_hwint(chip);
1113 if (r)
1114 goto out;
1115 r = read_pod(chip, &rf_type);
1116 if (r)
1117 goto out;
1118 r = hw_init(chip);
1119 if (r)
1120 goto out;
1121 r = zd_rf_init_hw(&chip->rf, rf_type);
1122 if (r)
1123 goto out;
1124
1125 r = print_fw_version(chip);
1126 if (r)
1127 goto out;
1128
1129#ifdef DEBUG
1130 dump_fw_registers(chip);
1131 r = test_init(chip);
1132 if (r)
1133 goto out;
1134#endif /* DEBUG */
1135
Daniel Drakee85d0912006-06-02 17:11:32 +01001136 r = read_cal_int_tables(chip);
1137 if (r)
1138 goto out;
1139
1140 print_id(chip);
1141out:
1142 mutex_unlock(&chip->mutex);
1143 return r;
1144}
1145
1146static int update_pwr_int(struct zd_chip *chip, u8 channel)
1147{
1148 u8 value = chip->pwr_int_values[channel - 1];
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001149 return zd_iowrite16_locked(chip, value, CR31);
Daniel Drakee85d0912006-06-02 17:11:32 +01001150}
1151
1152static int update_pwr_cal(struct zd_chip *chip, u8 channel)
1153{
1154 u8 value = chip->pwr_cal_values[channel-1];
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001155 return zd_iowrite16_locked(chip, value, CR68);
Daniel Drakee85d0912006-06-02 17:11:32 +01001156}
1157
1158static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
1159{
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001160 struct zd_ioreq16 ioreqs[3];
Daniel Drakee85d0912006-06-02 17:11:32 +01001161
1162 ioreqs[0].addr = CR67;
1163 ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1];
1164 ioreqs[1].addr = CR66;
1165 ioreqs[1].value = chip->ofdm_cal_values[OFDM_48M_INDEX][channel-1];
1166 ioreqs[2].addr = CR65;
1167 ioreqs[2].value = chip->ofdm_cal_values[OFDM_54M_INDEX][channel-1];
1168
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001169 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drakee85d0912006-06-02 17:11:32 +01001170}
1171
1172static int update_channel_integration_and_calibration(struct zd_chip *chip,
1173 u8 channel)
1174{
1175 int r;
1176
Daniel Drake9c8fc712007-05-24 01:06:41 +01001177 if (!zd_rf_should_update_pwr_int(&chip->rf))
1178 return 0;
1179
Daniel Drakee85d0912006-06-02 17:11:32 +01001180 r = update_pwr_int(chip, channel);
1181 if (r)
1182 return r;
Daniel Drake74553ae2007-07-01 18:22:32 +01001183 if (zd_chip_is_zd1211b(chip)) {
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001184 static const struct zd_ioreq16 ioreqs[] = {
Daniel Drakee85d0912006-06-02 17:11:32 +01001185 { CR69, 0x28 },
1186 {},
1187 { CR69, 0x2a },
1188 };
1189
1190 r = update_ofdm_cal(chip, channel);
1191 if (r)
1192 return r;
1193 r = update_pwr_cal(chip, channel);
1194 if (r)
1195 return r;
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001196 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drakee85d0912006-06-02 17:11:32 +01001197 if (r)
1198 return r;
1199 }
1200
1201 return 0;
1202}
1203
1204/* The CCK baseband gain can be optionally patched by the EEPROM */
1205static int patch_cck_gain(struct zd_chip *chip)
1206{
1207 int r;
1208 u32 value;
1209
Daniel Drakeaaf83d42007-05-24 01:07:15 +01001210 if (!chip->patch_cck_gain || !zd_rf_should_patch_cck_gain(&chip->rf))
Daniel Drakee85d0912006-06-02 17:11:32 +01001211 return 0;
1212
1213 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1214 r = zd_ioread32_locked(chip, &value, E2P_PHY_REG);
1215 if (r)
1216 return r;
1217 dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff);
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001218 return zd_iowrite16_locked(chip, value & 0xff, CR47);
Daniel Drakee85d0912006-06-02 17:11:32 +01001219}
1220
1221int zd_chip_set_channel(struct zd_chip *chip, u8 channel)
1222{
1223 int r, t;
1224
1225 mutex_lock(&chip->mutex);
1226 r = zd_chip_lock_phy_regs(chip);
1227 if (r)
1228 goto out;
1229 r = zd_rf_set_channel(&chip->rf, channel);
1230 if (r)
1231 goto unlock;
1232 r = update_channel_integration_and_calibration(chip, channel);
1233 if (r)
1234 goto unlock;
1235 r = patch_cck_gain(chip);
1236 if (r)
1237 goto unlock;
1238 r = patch_6m_band_edge(chip, channel);
1239 if (r)
1240 goto unlock;
1241 r = zd_iowrite32_locked(chip, 0, CR_CONFIG_PHILIPS);
1242unlock:
1243 t = zd_chip_unlock_phy_regs(chip);
1244 if (t && !r)
1245 r = t;
1246out:
1247 mutex_unlock(&chip->mutex);
1248 return r;
1249}
1250
1251u8 zd_chip_get_channel(struct zd_chip *chip)
1252{
1253 u8 channel;
1254
1255 mutex_lock(&chip->mutex);
1256 channel = chip->rf.channel;
1257 mutex_unlock(&chip->mutex);
1258 return channel;
1259}
1260
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001261int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
Daniel Drakee85d0912006-06-02 17:11:32 +01001262{
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001263 const zd_addr_t a[] = {
1264 fw_reg_addr(chip, FW_REG_LED_LINK_STATUS),
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001265 CR_LED,
1266 };
Daniel Drakee85d0912006-06-02 17:11:32 +01001267
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001268 int r;
1269 u16 v[ARRAY_SIZE(a)];
1270 struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = {
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001271 [0] = { fw_reg_addr(chip, FW_REG_LED_LINK_STATUS) },
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001272 [1] = { CR_LED },
1273 };
1274 u16 other_led;
Daniel Drakee85d0912006-06-02 17:11:32 +01001275
Daniel Drakee85d0912006-06-02 17:11:32 +01001276 mutex_lock(&chip->mutex);
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001277 r = zd_ioread16v_locked(chip, v, (const zd_addr_t *)a, ARRAY_SIZE(a));
Daniel Drakee85d0912006-06-02 17:11:32 +01001278 if (r)
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001279 goto out;
1280
1281 other_led = chip->link_led == LED1 ? LED2 : LED1;
1282
Daniel Drakee85d0912006-06-02 17:11:32 +01001283 switch (status) {
Daniel Drakee85d0912006-06-02 17:11:32 +01001284 case LED_OFF:
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001285 ioreqs[0].value = FW_LINK_OFF;
1286 ioreqs[1].value = v[1] & ~(LED1|LED2);
Daniel Drakee85d0912006-06-02 17:11:32 +01001287 break;
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001288 case LED_SCANNING:
1289 ioreqs[0].value = FW_LINK_OFF;
1290 ioreqs[1].value = v[1] & ~other_led;
1291 if (get_seconds() % 3 == 0) {
1292 ioreqs[1].value &= ~chip->link_led;
1293 } else {
1294 ioreqs[1].value |= chip->link_led;
1295 }
Daniel Drakee85d0912006-06-02 17:11:32 +01001296 break;
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001297 case LED_ASSOCIATED:
1298 ioreqs[0].value = FW_LINK_TX;
1299 ioreqs[1].value = v[1] & ~other_led;
1300 ioreqs[1].value |= chip->link_led;
Daniel Drakee85d0912006-06-02 17:11:32 +01001301 break;
1302 default:
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001303 r = -EINVAL;
Daniel Drakee85d0912006-06-02 17:11:32 +01001304 goto out;
1305 }
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001306
1307 if (v[0] != ioreqs[0].value || v[1] != ioreqs[1].value) {
1308 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
1309 if (r)
1310 goto out;
1311 }
1312 r = 0;
Daniel Drakee85d0912006-06-02 17:11:32 +01001313out:
1314 mutex_unlock(&chip->mutex);
1315 return r;
1316}
1317
Daniel Drake459c51a2007-11-19 15:00:29 +00001318int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates)
Daniel Drakee85d0912006-06-02 17:11:32 +01001319{
Daniel Drake459c51a2007-11-19 15:00:29 +00001320 int r;
Daniel Drakee85d0912006-06-02 17:11:32 +01001321
Daniel Drake459c51a2007-11-19 15:00:29 +00001322 if (cr_rates & ~(CR_RATES_80211B|CR_RATES_80211G))
1323 return -EINVAL;
1324
1325 mutex_lock(&chip->mutex);
1326 r = zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
1327 mutex_unlock(&chip->mutex);
1328 return r;
Daniel Drakee85d0912006-06-02 17:11:32 +01001329}
1330
Ulrich Kunitz64f222c2007-08-06 01:24:31 +01001331static int ofdm_qual_db(u8 status_quality, u8 zd_rate, unsigned int size)
Daniel Drakee85d0912006-06-02 17:11:32 +01001332{
1333 static const u16 constants[] = {
1334 715, 655, 585, 540, 470, 410, 360, 315,
1335 270, 235, 205, 175, 150, 125, 105, 85,
1336 65, 50, 40, 25, 15
1337 };
1338
1339 int i;
1340 u32 x;
1341
1342 /* It seems that their quality parameter is somehow per signal
1343 * and is now transferred per bit.
1344 */
Ulrich Kunitz64f222c2007-08-06 01:24:31 +01001345 switch (zd_rate) {
Daniel Drakee85d0912006-06-02 17:11:32 +01001346 case ZD_OFDM_RATE_6M:
1347 case ZD_OFDM_RATE_12M:
1348 case ZD_OFDM_RATE_24M:
1349 size *= 2;
1350 break;
1351 case ZD_OFDM_RATE_9M:
1352 case ZD_OFDM_RATE_18M:
1353 case ZD_OFDM_RATE_36M:
1354 case ZD_OFDM_RATE_54M:
1355 size *= 4;
1356 size /= 3;
1357 break;
1358 case ZD_OFDM_RATE_48M:
1359 size *= 3;
1360 size /= 2;
1361 break;
1362 default:
1363 return -EINVAL;
1364 }
1365
1366 x = (10000 * status_quality)/size;
1367 for (i = 0; i < ARRAY_SIZE(constants); i++) {
1368 if (x > constants[i])
1369 break;
1370 }
1371
Ulrich Kunitz64f222c2007-08-06 01:24:31 +01001372 switch (zd_rate) {
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001373 case ZD_OFDM_RATE_6M:
1374 case ZD_OFDM_RATE_9M:
1375 i += 3;
1376 break;
1377 case ZD_OFDM_RATE_12M:
1378 case ZD_OFDM_RATE_18M:
1379 i += 5;
1380 break;
1381 case ZD_OFDM_RATE_24M:
1382 case ZD_OFDM_RATE_36M:
1383 i += 9;
1384 break;
1385 case ZD_OFDM_RATE_48M:
1386 case ZD_OFDM_RATE_54M:
1387 i += 15;
1388 break;
1389 default:
1390 return -EINVAL;
1391 }
1392
Daniel Drakee85d0912006-06-02 17:11:32 +01001393 return i;
1394}
1395
Ulrich Kunitz64f222c2007-08-06 01:24:31 +01001396static int ofdm_qual_percent(u8 status_quality, u8 zd_rate, unsigned int size)
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001397{
1398 int r;
1399
Ulrich Kunitz64f222c2007-08-06 01:24:31 +01001400 r = ofdm_qual_db(status_quality, zd_rate, size);
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001401 ZD_ASSERT(r >= 0);
1402 if (r < 0)
1403 r = 0;
1404
1405 r = (r * 100)/29;
1406 return r <= 100 ? r : 100;
1407}
1408
Daniel Drakee85d0912006-06-02 17:11:32 +01001409static unsigned int log10times100(unsigned int x)
1410{
1411 static const u8 log10[] = {
1412 0,
1413 0, 30, 47, 60, 69, 77, 84, 90, 95, 100,
1414 104, 107, 111, 114, 117, 120, 123, 125, 127, 130,
1415 132, 134, 136, 138, 139, 141, 143, 144, 146, 147,
1416 149, 150, 151, 153, 154, 155, 156, 157, 159, 160,
1417 161, 162, 163, 164, 165, 166, 167, 168, 169, 169,
1418 170, 171, 172, 173, 174, 174, 175, 176, 177, 177,
1419 178, 179, 179, 180, 181, 181, 182, 183, 183, 184,
1420 185, 185, 186, 186, 187, 188, 188, 189, 189, 190,
1421 190, 191, 191, 192, 192, 193, 193, 194, 194, 195,
1422 195, 196, 196, 197, 197, 198, 198, 199, 199, 200,
1423 200, 200, 201, 201, 202, 202, 202, 203, 203, 204,
1424 204, 204, 205, 205, 206, 206, 206, 207, 207, 207,
1425 208, 208, 208, 209, 209, 210, 210, 210, 211, 211,
1426 211, 212, 212, 212, 213, 213, 213, 213, 214, 214,
1427 214, 215, 215, 215, 216, 216, 216, 217, 217, 217,
1428 217, 218, 218, 218, 219, 219, 219, 219, 220, 220,
1429 220, 220, 221, 221, 221, 222, 222, 222, 222, 223,
1430 223, 223, 223, 224, 224, 224, 224,
1431 };
1432
1433 return x < ARRAY_SIZE(log10) ? log10[x] : 225;
1434}
1435
1436enum {
1437 MAX_CCK_EVM_DB = 45,
1438};
1439
1440static int cck_evm_db(u8 status_quality)
1441{
1442 return (20 * log10times100(status_quality)) / 100;
1443}
1444
1445static int cck_snr_db(u8 status_quality)
1446{
1447 int r = MAX_CCK_EVM_DB - cck_evm_db(status_quality);
1448 ZD_ASSERT(r >= 0);
1449 return r;
1450}
1451
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001452static int cck_qual_percent(u8 status_quality)
Daniel Drakee85d0912006-06-02 17:11:32 +01001453{
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001454 int r;
1455
1456 r = cck_snr_db(status_quality);
1457 r = (100*r)/17;
1458 return r <= 100 ? r : 100;
Daniel Drakee85d0912006-06-02 17:11:32 +01001459}
1460
Ulrich Kunitz64f222c2007-08-06 01:24:31 +01001461static inline u8 zd_rate_from_ofdm_plcp_header(const void *rx_frame)
1462{
1463 return ZD_OFDM | zd_ofdm_plcp_header_rate(rx_frame);
1464}
1465
Daniel Drakee85d0912006-06-02 17:11:32 +01001466u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
1467 const struct rx_status *status)
1468{
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001469 return (status->frame_status&ZD_RX_OFDM) ?
1470 ofdm_qual_percent(status->signal_quality_ofdm,
Daniel Drake459c51a2007-11-19 15:00:29 +00001471 zd_rate_from_ofdm_plcp_header(rx_frame),
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001472 size) :
1473 cck_qual_percent(status->signal_quality_cck);
Daniel Drakee85d0912006-06-02 17:11:32 +01001474}
1475
Daniel Drake459c51a2007-11-19 15:00:29 +00001476/**
1477 * zd_rx_rate - report zd-rate
1478 * @rx_frame - received frame
1479 * @rx_status - rx_status as given by the device
1480 *
1481 * This function converts the rate as encoded in the received packet to the
1482 * zd-rate, we are using on other places in the driver.
1483 */
1484u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status)
Daniel Drakee85d0912006-06-02 17:11:32 +01001485{
Daniel Drake459c51a2007-11-19 15:00:29 +00001486 u8 zd_rate;
Daniel Drakee85d0912006-06-02 17:11:32 +01001487 if (status->frame_status & ZD_RX_OFDM) {
Daniel Drake459c51a2007-11-19 15:00:29 +00001488 zd_rate = zd_rate_from_ofdm_plcp_header(rx_frame);
Daniel Drakee85d0912006-06-02 17:11:32 +01001489 } else {
Ulrich Kunitz64f222c2007-08-06 01:24:31 +01001490 switch (zd_cck_plcp_header_signal(rx_frame)) {
1491 case ZD_CCK_PLCP_SIGNAL_1M:
Daniel Drake459c51a2007-11-19 15:00:29 +00001492 zd_rate = ZD_CCK_RATE_1M;
Daniel Drakee85d0912006-06-02 17:11:32 +01001493 break;
Ulrich Kunitz64f222c2007-08-06 01:24:31 +01001494 case ZD_CCK_PLCP_SIGNAL_2M:
Daniel Drake459c51a2007-11-19 15:00:29 +00001495 zd_rate = ZD_CCK_RATE_2M;
Daniel Drakee85d0912006-06-02 17:11:32 +01001496 break;
Ulrich Kunitz64f222c2007-08-06 01:24:31 +01001497 case ZD_CCK_PLCP_SIGNAL_5M5:
Daniel Drake459c51a2007-11-19 15:00:29 +00001498 zd_rate = ZD_CCK_RATE_5_5M;
Daniel Drakee85d0912006-06-02 17:11:32 +01001499 break;
Ulrich Kunitz64f222c2007-08-06 01:24:31 +01001500 case ZD_CCK_PLCP_SIGNAL_11M:
Daniel Drake459c51a2007-11-19 15:00:29 +00001501 zd_rate = ZD_CCK_RATE_11M;
Daniel Drakee85d0912006-06-02 17:11:32 +01001502 break;
1503 default:
Daniel Drake459c51a2007-11-19 15:00:29 +00001504 zd_rate = 0;
Daniel Drakee85d0912006-06-02 17:11:32 +01001505 }
1506 }
1507
Daniel Drake459c51a2007-11-19 15:00:29 +00001508 return zd_rate;
Daniel Drakee85d0912006-06-02 17:11:32 +01001509}
1510
1511int zd_chip_switch_radio_on(struct zd_chip *chip)
1512{
1513 int r;
1514
1515 mutex_lock(&chip->mutex);
1516 r = zd_switch_radio_on(&chip->rf);
1517 mutex_unlock(&chip->mutex);
1518 return r;
1519}
1520
1521int zd_chip_switch_radio_off(struct zd_chip *chip)
1522{
1523 int r;
1524
1525 mutex_lock(&chip->mutex);
1526 r = zd_switch_radio_off(&chip->rf);
1527 mutex_unlock(&chip->mutex);
1528 return r;
1529}
1530
1531int zd_chip_enable_int(struct zd_chip *chip)
1532{
1533 int r;
1534
1535 mutex_lock(&chip->mutex);
1536 r = zd_usb_enable_int(&chip->usb);
1537 mutex_unlock(&chip->mutex);
1538 return r;
1539}
1540
1541void zd_chip_disable_int(struct zd_chip *chip)
1542{
1543 mutex_lock(&chip->mutex);
1544 zd_usb_disable_int(&chip->usb);
1545 mutex_unlock(&chip->mutex);
1546}
1547
Daniel Drake459c51a2007-11-19 15:00:29 +00001548int zd_chip_enable_rxtx(struct zd_chip *chip)
Daniel Drakee85d0912006-06-02 17:11:32 +01001549{
1550 int r;
1551
1552 mutex_lock(&chip->mutex);
Daniel Drake459c51a2007-11-19 15:00:29 +00001553 zd_usb_enable_tx(&chip->usb);
Daniel Drakee85d0912006-06-02 17:11:32 +01001554 r = zd_usb_enable_rx(&chip->usb);
1555 mutex_unlock(&chip->mutex);
1556 return r;
1557}
1558
Daniel Drake459c51a2007-11-19 15:00:29 +00001559void zd_chip_disable_rxtx(struct zd_chip *chip)
Daniel Drakee85d0912006-06-02 17:11:32 +01001560{
1561 mutex_lock(&chip->mutex);
1562 zd_usb_disable_rx(&chip->usb);
Daniel Drake459c51a2007-11-19 15:00:29 +00001563 zd_usb_disable_tx(&chip->usb);
Daniel Drakee85d0912006-06-02 17:11:32 +01001564 mutex_unlock(&chip->mutex);
1565}
1566
1567int zd_rfwritev_locked(struct zd_chip *chip,
1568 const u32* values, unsigned int count, u8 bits)
1569{
1570 int r;
1571 unsigned int i;
1572
1573 for (i = 0; i < count; i++) {
1574 r = zd_rfwrite_locked(chip, values[i], bits);
1575 if (r)
1576 return r;
1577 }
1578
1579 return 0;
1580}
Daniel Drake20fe2172006-08-12 17:59:42 +01001581
1582/*
1583 * We can optionally program the RF directly through CR regs, if supported by
1584 * the hardware. This is much faster than the older method.
1585 */
Daniel Drakeec62bd92006-08-12 17:59:46 +01001586int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
Daniel Drake20fe2172006-08-12 17:59:42 +01001587{
1588 struct zd_ioreq16 ioreqs[] = {
1589 { CR244, (value >> 16) & 0xff },
1590 { CR243, (value >> 8) & 0xff },
1591 { CR242, value & 0xff },
1592 };
1593 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1594 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
1595}
1596
1597int zd_rfwritev_cr_locked(struct zd_chip *chip,
1598 const u32 *values, unsigned int count)
1599{
1600 int r;
1601 unsigned int i;
1602
1603 for (i = 0; i < count; i++) {
1604 r = zd_rfwrite_cr_locked(chip, values[i]);
1605 if (r)
1606 return r;
1607 }
1608
1609 return 0;
1610}
Ulrich Kunitz9cdac962006-12-01 00:58:07 +00001611
1612int zd_chip_set_multicast_hash(struct zd_chip *chip,
1613 struct zd_mc_hash *hash)
1614{
1615 struct zd_ioreq32 ioreqs[] = {
1616 { CR_GROUP_HASH_P1, hash->low },
1617 { CR_GROUP_HASH_P2, hash->high },
1618 };
1619
Ulrich Kunitz9cdac962006-12-01 00:58:07 +00001620 return zd_iowrite32a(chip, ioreqs, ARRAY_SIZE(ioreqs));
1621}