blob: 12dfc0b6efe6796b2f371b53a357e23dc1a558f6 [file] [log] [blame]
Daniel Drakee85d0912006-06-02 17:11:32 +01001/* zd_chip.c
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18/* This file implements all the hardware specific functions for the ZD1211
19 * and ZD1211B chips. Support for the ZD1211B was possible after Timothy
20 * Legge sent me a ZD1211B device. Thank you Tim. -- Uli
21 */
22
23#include <linux/kernel.h>
24#include <linux/errno.h>
25
26#include "zd_def.h"
27#include "zd_chip.h"
28#include "zd_ieee80211.h"
29#include "zd_mac.h"
30#include "zd_rf.h"
31#include "zd_util.h"
32
33void zd_chip_init(struct zd_chip *chip,
34 struct net_device *netdev,
35 struct usb_interface *intf)
36{
37 memset(chip, 0, sizeof(*chip));
38 mutex_init(&chip->mutex);
39 zd_usb_init(&chip->usb, netdev, intf);
40 zd_rf_init(&chip->rf);
41}
42
43void zd_chip_clear(struct zd_chip *chip)
44{
Ulrich Kunitzc48cf122006-08-12 18:00:17 +010045 ZD_ASSERT(!mutex_is_locked(&chip->mutex));
Daniel Drakee85d0912006-06-02 17:11:32 +010046 zd_usb_clear(&chip->usb);
47 zd_rf_clear(&chip->rf);
Daniel Drakee85d0912006-06-02 17:11:32 +010048 mutex_destroy(&chip->mutex);
Ulrich Kunitzc48cf122006-08-12 18:00:17 +010049 ZD_MEMCLEAR(chip, sizeof(*chip));
Daniel Drakee85d0912006-06-02 17:11:32 +010050}
51
52static int scnprint_mac_oui(const u8 *addr, char *buffer, size_t size)
53{
54 return scnprintf(buffer, size, "%02x-%02x-%02x",
55 addr[0], addr[1], addr[2]);
56}
57
58/* Prints an identifier line, which will support debugging. */
59static int scnprint_id(struct zd_chip *chip, char *buffer, size_t size)
60{
61 int i = 0;
62
63 i = scnprintf(buffer, size, "zd1211%s chip ",
64 chip->is_zd1211b ? "b" : "");
65 i += zd_usb_scnprint_id(&chip->usb, buffer+i, size-i);
66 i += scnprintf(buffer+i, size-i, " ");
67 i += scnprint_mac_oui(chip->e2p_mac, buffer+i, size-i);
68 i += scnprintf(buffer+i, size-i, " ");
69 i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i);
Daniel Drake20fe2172006-08-12 17:59:42 +010070 i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c", chip->pa_type,
Daniel Drakee85d0912006-06-02 17:11:32 +010071 chip->patch_cck_gain ? 'g' : '-',
72 chip->patch_cr157 ? '7' : '-',
Daniel Drake20fe2172006-08-12 17:59:42 +010073 chip->patch_6m_band_edge ? '6' : '-',
74 chip->new_phy_layout ? 'N' : '-');
Daniel Drakee85d0912006-06-02 17:11:32 +010075 return i;
76}
77
78static void print_id(struct zd_chip *chip)
79{
80 char buffer[80];
81
82 scnprint_id(chip, buffer, sizeof(buffer));
83 buffer[sizeof(buffer)-1] = 0;
84 dev_info(zd_chip_dev(chip), "%s\n", buffer);
85}
86
Daniel Drake0ce34bc2006-12-12 01:26:11 +000087static zd_addr_t inc_addr(zd_addr_t addr)
88{
89 u16 a = (u16)addr;
90 /* Control registers use byte addressing, but everything else uses word
91 * addressing. */
92 if ((a & 0xf000) == CR_START)
93 a += 2;
94 else
95 a += 1;
96 return (zd_addr_t)a;
97}
98
Daniel Drakee85d0912006-06-02 17:11:32 +010099/* Read a variable number of 32-bit values. Parameter count is not allowed to
100 * exceed USB_MAX_IOREAD32_COUNT.
101 */
102int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr,
103 unsigned int count)
104{
105 int r;
106 int i;
107 zd_addr_t *a16 = (zd_addr_t *)NULL;
108 u16 *v16;
109 unsigned int count16;
110
111 if (count > USB_MAX_IOREAD32_COUNT)
112 return -EINVAL;
113
114 /* Allocate a single memory block for values and addresses. */
115 count16 = 2*count;
Robert P. J. Day5cbded52006-12-13 00:35:56 -0800116 a16 = kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
Daniel Drakee85d0912006-06-02 17:11:32 +0100117 GFP_NOFS);
118 if (!a16) {
119 dev_dbg_f(zd_chip_dev(chip),
120 "error ENOMEM in allocation of a16\n");
121 r = -ENOMEM;
122 goto out;
123 }
124 v16 = (u16 *)(a16 + count16);
125
126 for (i = 0; i < count; i++) {
127 int j = 2*i;
128 /* We read the high word always first. */
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000129 a16[j] = inc_addr(addr[i]);
Daniel Drakee85d0912006-06-02 17:11:32 +0100130 a16[j+1] = addr[i];
131 }
132
133 r = zd_ioread16v_locked(chip, v16, a16, count16);
134 if (r) {
135 dev_dbg_f(zd_chip_dev(chip),
136 "error: zd_ioread16v_locked. Error number %d\n", r);
137 goto out;
138 }
139
140 for (i = 0; i < count; i++) {
141 int j = 2*i;
142 values[i] = (v16[j] << 16) | v16[j+1];
143 }
144
145out:
146 kfree((void *)a16);
147 return r;
148}
149
150int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
151 unsigned int count)
152{
153 int i, j, r;
154 struct zd_ioreq16 *ioreqs16;
155 unsigned int count16;
156
157 ZD_ASSERT(mutex_is_locked(&chip->mutex));
158
159 if (count == 0)
160 return 0;
161 if (count > USB_MAX_IOWRITE32_COUNT)
162 return -EINVAL;
163
164 /* Allocate a single memory block for values and addresses. */
165 count16 = 2*count;
166 ioreqs16 = kmalloc(count16 * sizeof(struct zd_ioreq16), GFP_NOFS);
167 if (!ioreqs16) {
168 r = -ENOMEM;
169 dev_dbg_f(zd_chip_dev(chip),
170 "error %d in ioreqs16 allocation\n", r);
171 goto out;
172 }
173
174 for (i = 0; i < count; i++) {
175 j = 2*i;
176 /* We write the high word always first. */
177 ioreqs16[j].value = ioreqs[i].value >> 16;
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000178 ioreqs16[j].addr = inc_addr(ioreqs[i].addr);
Daniel Drakee85d0912006-06-02 17:11:32 +0100179 ioreqs16[j+1].value = ioreqs[i].value;
180 ioreqs16[j+1].addr = ioreqs[i].addr;
181 }
182
183 r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16);
184#ifdef DEBUG
185 if (r) {
186 dev_dbg_f(zd_chip_dev(chip),
187 "error %d in zd_usb_write16v\n", r);
188 }
189#endif /* DEBUG */
190out:
191 kfree(ioreqs16);
192 return r;
193}
194
195int zd_iowrite16a_locked(struct zd_chip *chip,
196 const struct zd_ioreq16 *ioreqs, unsigned int count)
197{
198 int r;
199 unsigned int i, j, t, max;
200
201 ZD_ASSERT(mutex_is_locked(&chip->mutex));
202 for (i = 0; i < count; i += j + t) {
203 t = 0;
204 max = count-i;
205 if (max > USB_MAX_IOWRITE16_COUNT)
206 max = USB_MAX_IOWRITE16_COUNT;
207 for (j = 0; j < max; j++) {
208 if (!ioreqs[i+j].addr) {
209 t = 1;
210 break;
211 }
212 }
213
214 r = zd_usb_iowrite16v(&chip->usb, &ioreqs[i], j);
215 if (r) {
216 dev_dbg_f(zd_chip_dev(chip),
217 "error zd_usb_iowrite16v. Error number %d\n",
218 r);
219 return r;
220 }
221 }
222
223 return 0;
224}
225
226/* Writes a variable number of 32 bit registers. The functions will split
227 * that in several USB requests. A split can be forced by inserting an IO
228 * request with an zero address field.
229 */
230int zd_iowrite32a_locked(struct zd_chip *chip,
231 const struct zd_ioreq32 *ioreqs, unsigned int count)
232{
233 int r;
234 unsigned int i, j, t, max;
235
236 for (i = 0; i < count; i += j + t) {
237 t = 0;
238 max = count-i;
239 if (max > USB_MAX_IOWRITE32_COUNT)
240 max = USB_MAX_IOWRITE32_COUNT;
241 for (j = 0; j < max; j++) {
242 if (!ioreqs[i+j].addr) {
243 t = 1;
244 break;
245 }
246 }
247
248 r = _zd_iowrite32v_locked(chip, &ioreqs[i], j);
249 if (r) {
250 dev_dbg_f(zd_chip_dev(chip),
251 "error _zd_iowrite32v_locked."
252 " Error number %d\n", r);
253 return r;
254 }
255 }
256
257 return 0;
258}
259
260int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value)
261{
262 int r;
263
Daniel Drakee85d0912006-06-02 17:11:32 +0100264 mutex_lock(&chip->mutex);
265 r = zd_ioread16_locked(chip, value, addr);
266 mutex_unlock(&chip->mutex);
267 return r;
268}
269
270int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value)
271{
272 int r;
273
Daniel Drakee85d0912006-06-02 17:11:32 +0100274 mutex_lock(&chip->mutex);
275 r = zd_ioread32_locked(chip, value, addr);
276 mutex_unlock(&chip->mutex);
277 return r;
278}
279
280int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value)
281{
282 int r;
283
Daniel Drakee85d0912006-06-02 17:11:32 +0100284 mutex_lock(&chip->mutex);
285 r = zd_iowrite16_locked(chip, value, addr);
286 mutex_unlock(&chip->mutex);
287 return r;
288}
289
290int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value)
291{
292 int r;
293
Daniel Drakee85d0912006-06-02 17:11:32 +0100294 mutex_lock(&chip->mutex);
295 r = zd_iowrite32_locked(chip, value, addr);
296 mutex_unlock(&chip->mutex);
297 return r;
298}
299
300int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses,
301 u32 *values, unsigned int count)
302{
303 int r;
304
Daniel Drakee85d0912006-06-02 17:11:32 +0100305 mutex_lock(&chip->mutex);
306 r = zd_ioread32v_locked(chip, values, addresses, count);
307 mutex_unlock(&chip->mutex);
308 return r;
309}
310
311int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
312 unsigned int count)
313{
314 int r;
315
Daniel Drakee85d0912006-06-02 17:11:32 +0100316 mutex_lock(&chip->mutex);
317 r = zd_iowrite32a_locked(chip, ioreqs, count);
318 mutex_unlock(&chip->mutex);
319 return r;
320}
321
322static int read_pod(struct zd_chip *chip, u8 *rf_type)
323{
324 int r;
325 u32 value;
326
327 ZD_ASSERT(mutex_is_locked(&chip->mutex));
328 r = zd_ioread32_locked(chip, &value, E2P_POD);
329 if (r)
330 goto error;
331 dev_dbg_f(zd_chip_dev(chip), "E2P_POD %#010x\n", value);
332
333 /* FIXME: AL2230 handling (Bit 7 in POD) */
334 *rf_type = value & 0x0f;
335 chip->pa_type = (value >> 16) & 0x0f;
336 chip->patch_cck_gain = (value >> 8) & 0x1;
337 chip->patch_cr157 = (value >> 13) & 0x1;
338 chip->patch_6m_band_edge = (value >> 21) & 0x1;
Daniel Drake20fe2172006-08-12 17:59:42 +0100339 chip->new_phy_layout = (value >> 31) & 0x1;
Ulrich Kunitz583afd12006-09-13 02:42:38 +0100340 chip->link_led = ((value >> 4) & 1) ? LED1 : LED2;
341 chip->supports_tx_led = 1;
342 if (value & (1 << 24)) { /* LED scenario */
343 if (value & (1 << 29))
344 chip->supports_tx_led = 0;
345 }
Daniel Drakee85d0912006-06-02 17:11:32 +0100346
347 dev_dbg_f(zd_chip_dev(chip),
348 "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d "
Ulrich Kunitz583afd12006-09-13 02:42:38 +0100349 "patch 6M %d new PHY %d link LED%d tx led %d\n",
Daniel Drakee85d0912006-06-02 17:11:32 +0100350 zd_rf_name(*rf_type), *rf_type,
351 chip->pa_type, chip->patch_cck_gain,
Ulrich Kunitz583afd12006-09-13 02:42:38 +0100352 chip->patch_cr157, chip->patch_6m_band_edge,
353 chip->new_phy_layout,
354 chip->link_led == LED1 ? 1 : 2,
355 chip->supports_tx_led);
Daniel Drakee85d0912006-06-02 17:11:32 +0100356 return 0;
357error:
358 *rf_type = 0;
359 chip->pa_type = 0;
360 chip->patch_cck_gain = 0;
361 chip->patch_cr157 = 0;
362 chip->patch_6m_band_edge = 0;
Daniel Drake20fe2172006-08-12 17:59:42 +0100363 chip->new_phy_layout = 0;
Daniel Drakee85d0912006-06-02 17:11:32 +0100364 return r;
365}
366
367static int _read_mac_addr(struct zd_chip *chip, u8 *mac_addr,
368 const zd_addr_t *addr)
369{
370 int r;
371 u32 parts[2];
372
373 r = zd_ioread32v_locked(chip, parts, (const zd_addr_t *)addr, 2);
374 if (r) {
375 dev_dbg_f(zd_chip_dev(chip),
376 "error: couldn't read e2p macs. Error number %d\n", r);
377 return r;
378 }
379
380 mac_addr[0] = parts[0];
381 mac_addr[1] = parts[0] >> 8;
382 mac_addr[2] = parts[0] >> 16;
383 mac_addr[3] = parts[0] >> 24;
384 mac_addr[4] = parts[1];
385 mac_addr[5] = parts[1] >> 8;
386
387 return 0;
388}
389
390static int read_e2p_mac_addr(struct zd_chip *chip)
391{
392 static const zd_addr_t addr[2] = { E2P_MAC_ADDR_P1, E2P_MAC_ADDR_P2 };
393
394 ZD_ASSERT(mutex_is_locked(&chip->mutex));
395 return _read_mac_addr(chip, chip->e2p_mac, (const zd_addr_t *)addr);
396}
397
398/* MAC address: if custom mac addresses are to to be used CR_MAC_ADDR_P1 and
399 * CR_MAC_ADDR_P2 must be overwritten
400 */
401void zd_get_e2p_mac_addr(struct zd_chip *chip, u8 *mac_addr)
402{
403 mutex_lock(&chip->mutex);
404 memcpy(mac_addr, chip->e2p_mac, ETH_ALEN);
405 mutex_unlock(&chip->mutex);
406}
407
408static int read_mac_addr(struct zd_chip *chip, u8 *mac_addr)
409{
410 static const zd_addr_t addr[2] = { CR_MAC_ADDR_P1, CR_MAC_ADDR_P2 };
411 return _read_mac_addr(chip, mac_addr, (const zd_addr_t *)addr);
412}
413
414int zd_read_mac_addr(struct zd_chip *chip, u8 *mac_addr)
415{
416 int r;
417
418 dev_dbg_f(zd_chip_dev(chip), "\n");
419 mutex_lock(&chip->mutex);
420 r = read_mac_addr(chip, mac_addr);
421 mutex_unlock(&chip->mutex);
422 return r;
423}
424
425int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
426{
427 int r;
428 struct zd_ioreq32 reqs[2] = {
429 [0] = { .addr = CR_MAC_ADDR_P1 },
430 [1] = { .addr = CR_MAC_ADDR_P2 },
431 };
432
433 reqs[0].value = (mac_addr[3] << 24)
434 | (mac_addr[2] << 16)
435 | (mac_addr[1] << 8)
436 | mac_addr[0];
437 reqs[1].value = (mac_addr[5] << 8)
438 | mac_addr[4];
439
440 dev_dbg_f(zd_chip_dev(chip),
441 "mac addr " MAC_FMT "\n", MAC_ARG(mac_addr));
442
443 mutex_lock(&chip->mutex);
444 r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
445#ifdef DEBUG
446 {
447 u8 tmp[ETH_ALEN];
448 read_mac_addr(chip, tmp);
449 }
450#endif /* DEBUG */
451 mutex_unlock(&chip->mutex);
452 return r;
453}
454
455int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain)
456{
457 int r;
458 u32 value;
459
460 mutex_lock(&chip->mutex);
461 r = zd_ioread32_locked(chip, &value, E2P_SUBID);
462 mutex_unlock(&chip->mutex);
463 if (r)
464 return r;
465
466 *regdomain = value >> 16;
467 dev_dbg_f(zd_chip_dev(chip), "regdomain: %#04x\n", *regdomain);
468
469 return 0;
470}
471
472static int read_values(struct zd_chip *chip, u8 *values, size_t count,
473 zd_addr_t e2p_addr, u32 guard)
474{
475 int r;
476 int i;
477 u32 v;
478
479 ZD_ASSERT(mutex_is_locked(&chip->mutex));
480 for (i = 0;;) {
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000481 r = zd_ioread32_locked(chip, &v,
482 (zd_addr_t)((u16)e2p_addr+i/2));
Daniel Drakee85d0912006-06-02 17:11:32 +0100483 if (r)
484 return r;
485 v -= guard;
486 if (i+4 < count) {
487 values[i++] = v;
488 values[i++] = v >> 8;
489 values[i++] = v >> 16;
490 values[i++] = v >> 24;
491 continue;
492 }
493 for (;i < count; i++)
494 values[i] = v >> (8*(i%3));
495 return 0;
496 }
497}
498
499static int read_pwr_cal_values(struct zd_chip *chip)
500{
501 return read_values(chip, chip->pwr_cal_values,
502 E2P_CHANNEL_COUNT, E2P_PWR_CAL_VALUE1,
503 0);
504}
505
506static int read_pwr_int_values(struct zd_chip *chip)
507{
508 return read_values(chip, chip->pwr_int_values,
509 E2P_CHANNEL_COUNT, E2P_PWR_INT_VALUE1,
510 E2P_PWR_INT_GUARD);
511}
512
513static int read_ofdm_cal_values(struct zd_chip *chip)
514{
515 int r;
516 int i;
517 static const zd_addr_t addresses[] = {
518 E2P_36M_CAL_VALUE1,
519 E2P_48M_CAL_VALUE1,
520 E2P_54M_CAL_VALUE1,
521 };
522
523 for (i = 0; i < 3; i++) {
524 r = read_values(chip, chip->ofdm_cal_values[i],
525 E2P_CHANNEL_COUNT, addresses[i], 0);
526 if (r)
527 return r;
528 }
529 return 0;
530}
531
532static int read_cal_int_tables(struct zd_chip *chip)
533{
534 int r;
535
536 r = read_pwr_cal_values(chip);
537 if (r)
538 return r;
539 r = read_pwr_int_values(chip);
540 if (r)
541 return r;
542 r = read_ofdm_cal_values(chip);
543 if (r)
544 return r;
545 return 0;
546}
547
548/* phy means physical registers */
549int zd_chip_lock_phy_regs(struct zd_chip *chip)
550{
551 int r;
552 u32 tmp;
553
554 ZD_ASSERT(mutex_is_locked(&chip->mutex));
555 r = zd_ioread32_locked(chip, &tmp, CR_REG1);
556 if (r) {
557 dev_err(zd_chip_dev(chip), "error ioread32(CR_REG1): %d\n", r);
558 return r;
559 }
560
561 dev_dbg_f(zd_chip_dev(chip),
562 "CR_REG1: 0x%02x -> 0x%02x\n", tmp, tmp & ~UNLOCK_PHY_REGS);
563 tmp &= ~UNLOCK_PHY_REGS;
564
565 r = zd_iowrite32_locked(chip, tmp, CR_REG1);
566 if (r)
567 dev_err(zd_chip_dev(chip), "error iowrite32(CR_REG1): %d\n", r);
568 return r;
569}
570
571int zd_chip_unlock_phy_regs(struct zd_chip *chip)
572{
573 int r;
574 u32 tmp;
575
576 ZD_ASSERT(mutex_is_locked(&chip->mutex));
577 r = zd_ioread32_locked(chip, &tmp, CR_REG1);
578 if (r) {
579 dev_err(zd_chip_dev(chip),
580 "error ioread32(CR_REG1): %d\n", r);
581 return r;
582 }
583
584 dev_dbg_f(zd_chip_dev(chip),
585 "CR_REG1: 0x%02x -> 0x%02x\n", tmp, tmp | UNLOCK_PHY_REGS);
586 tmp |= UNLOCK_PHY_REGS;
587
588 r = zd_iowrite32_locked(chip, tmp, CR_REG1);
589 if (r)
590 dev_err(zd_chip_dev(chip), "error iowrite32(CR_REG1): %d\n", r);
591 return r;
592}
593
594/* CR157 can be optionally patched by the EEPROM */
595static int patch_cr157(struct zd_chip *chip)
596{
597 int r;
598 u32 value;
599
600 if (!chip->patch_cr157)
601 return 0;
602
603 r = zd_ioread32_locked(chip, &value, E2P_PHY_REG);
604 if (r)
605 return r;
606
607 dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value >> 8);
608 return zd_iowrite32_locked(chip, value >> 8, CR157);
609}
610
611/*
612 * 6M band edge can be optionally overwritten for certain RF's
613 * Vendor driver says: for FCC regulation, enabled per HWFeature 6M band edge
614 * bit (for AL2230, AL2230S)
615 */
616static int patch_6m_band_edge(struct zd_chip *chip, int channel)
617{
618 struct zd_ioreq16 ioreqs[] = {
619 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
620 { CR47, 0x1e },
621 };
622
623 if (!chip->patch_6m_band_edge || !chip->rf.patch_6m_band_edge)
624 return 0;
625
626 /* FIXME: Channel 11 is not the edge for all regulatory domains. */
627 if (channel == 1 || channel == 11)
628 ioreqs[0].value = 0x12;
629
630 dev_dbg_f(zd_chip_dev(chip), "patching for channel %d\n", channel);
631 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
632}
633
634static int zd1211_hw_reset_phy(struct zd_chip *chip)
635{
636 static const struct zd_ioreq16 ioreqs[] = {
637 { CR0, 0x0a }, { CR1, 0x06 }, { CR2, 0x26 },
638 { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xa0 },
639 { CR10, 0x81 }, { CR11, 0x00 }, { CR12, 0x7f },
640 { CR13, 0x8c }, { CR14, 0x80 }, { CR15, 0x3d },
641 { CR16, 0x20 }, { CR17, 0x1e }, { CR18, 0x0a },
642 { CR19, 0x48 }, { CR20, 0x0c }, { CR21, 0x0c },
643 { CR22, 0x23 }, { CR23, 0x90 }, { CR24, 0x14 },
644 { CR25, 0x40 }, { CR26, 0x10 }, { CR27, 0x19 },
645 { CR28, 0x7f }, { CR29, 0x80 }, { CR30, 0x4b },
646 { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 },
647 { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 },
648 { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },
649 { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 },
650 { CR43, 0x10 }, { CR44, 0x12 }, { CR46, 0xff },
651 { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b },
652 { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 },
653 { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 },
654 { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff },
655 { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 },
656 { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 },
657 { CR79, 0x68 }, { CR80, 0x64 }, { CR81, 0x64 },
658 { CR82, 0x00 }, { CR83, 0x00 }, { CR84, 0x00 },
659 { CR85, 0x02 }, { CR86, 0x00 }, { CR87, 0x00 },
660 { CR88, 0xff }, { CR89, 0xfc }, { CR90, 0x00 },
661 { CR91, 0x00 }, { CR92, 0x00 }, { CR93, 0x08 },
662 { CR94, 0x00 }, { CR95, 0x00 }, { CR96, 0xff },
663 { CR97, 0xe7 }, { CR98, 0x00 }, { CR99, 0x00 },
664 { CR100, 0x00 }, { CR101, 0xae }, { CR102, 0x02 },
665 { CR103, 0x00 }, { CR104, 0x03 }, { CR105, 0x65 },
666 { CR106, 0x04 }, { CR107, 0x00 }, { CR108, 0x0a },
667 { CR109, 0xaa }, { CR110, 0xaa }, { CR111, 0x25 },
668 { CR112, 0x25 }, { CR113, 0x00 }, { CR119, 0x1e },
669 { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
670 { },
671 { CR5, 0x00 }, { CR6, 0x00 }, { CR7, 0x00 },
672 { CR8, 0x00 }, { CR9, 0x20 }, { CR12, 0xf0 },
673 { CR20, 0x0e }, { CR21, 0x0e }, { CR27, 0x10 },
674 { CR44, 0x33 }, { CR47, 0x1E }, { CR83, 0x24 },
675 { CR84, 0x04 }, { CR85, 0x00 }, { CR86, 0x0C },
676 { CR87, 0x12 }, { CR88, 0x0C }, { CR89, 0x00 },
677 { CR90, 0x10 }, { CR91, 0x08 }, { CR93, 0x00 },
678 { CR94, 0x01 }, { CR95, 0x00 }, { CR96, 0x50 },
679 { CR97, 0x37 }, { CR98, 0x35 }, { CR101, 0x13 },
680 { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
681 { CR105, 0x12 }, { CR109, 0x27 }, { CR110, 0x27 },
682 { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
683 { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
684 { CR117, 0xfc }, { CR118, 0xfa }, { CR120, 0x4f },
685 { CR123, 0x27 }, { CR125, 0xaa }, { CR127, 0x03 },
686 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
687 { CR131, 0x0C }, { CR136, 0xdf }, { CR137, 0x40 },
688 { CR138, 0xa0 }, { CR139, 0xb0 }, { CR140, 0x99 },
689 { CR141, 0x82 }, { CR142, 0x54 }, { CR143, 0x1c },
690 { CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x4c },
691 { CR149, 0x50 }, { CR150, 0x0e }, { CR151, 0x18 },
692 { CR160, 0xfe }, { CR161, 0xee }, { CR162, 0xaa },
693 { CR163, 0xfa }, { CR164, 0xfa }, { CR165, 0xea },
694 { CR166, 0xbe }, { CR167, 0xbe }, { CR168, 0x6a },
695 { CR169, 0xba }, { CR170, 0xba }, { CR171, 0xba },
696 /* Note: CR204 must lead the CR203 */
697 { CR204, 0x7d },
698 { },
699 { CR203, 0x30 },
700 };
701
702 int r, t;
703
704 dev_dbg_f(zd_chip_dev(chip), "\n");
705
706 r = zd_chip_lock_phy_regs(chip);
707 if (r)
708 goto out;
709
710 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
711 if (r)
712 goto unlock;
713
714 r = patch_cr157(chip);
715unlock:
716 t = zd_chip_unlock_phy_regs(chip);
717 if (t && !r)
718 r = t;
719out:
720 return r;
721}
722
723static int zd1211b_hw_reset_phy(struct zd_chip *chip)
724{
725 static const struct zd_ioreq16 ioreqs[] = {
726 { CR0, 0x14 }, { CR1, 0x06 }, { CR2, 0x26 },
727 { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xe0 },
728 { CR10, 0x81 },
729 /* power control { { CR11, 1 << 6 }, */
730 { CR11, 0x00 },
731 { CR12, 0xf0 }, { CR13, 0x8c }, { CR14, 0x80 },
732 { CR15, 0x3d }, { CR16, 0x20 }, { CR17, 0x1e },
733 { CR18, 0x0a }, { CR19, 0x48 },
734 { CR20, 0x10 }, /* Org:0x0E, ComTrend:RalLink AP */
735 { CR21, 0x0e }, { CR22, 0x23 }, { CR23, 0x90 },
736 { CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 },
737 { CR27, 0x10 }, { CR28, 0x7f }, { CR29, 0x80 },
Daniel Drakefe7215c2006-08-12 17:59:12 +0100738 { CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */
Daniel Drakee85d0912006-06-02 17:11:32 +0100739 { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 },
740 { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 },
741 { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },
742 { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 },
743 { CR43, 0x10 }, { CR44, 0x33 }, { CR46, 0xff },
744 { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b },
745 { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 },
746 { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 },
747 { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff },
748 { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 },
749 { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 },
750 { CR79, 0xf0 }, { CR80, 0x64 }, { CR81, 0x64 },
751 { CR82, 0x00 }, { CR83, 0x24 }, { CR84, 0x04 },
752 { CR85, 0x00 }, { CR86, 0x0c }, { CR87, 0x12 },
753 { CR88, 0x0c }, { CR89, 0x00 }, { CR90, 0x58 },
754 { CR91, 0x04 }, { CR92, 0x00 }, { CR93, 0x00 },
755 { CR94, 0x01 },
756 { CR95, 0x20 }, /* ZD1211B */
757 { CR96, 0x50 }, { CR97, 0x37 }, { CR98, 0x35 },
758 { CR99, 0x00 }, { CR100, 0x01 }, { CR101, 0x13 },
759 { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
760 { CR105, 0x12 }, { CR106, 0x04 }, { CR107, 0x00 },
761 { CR108, 0x0a }, { CR109, 0x27 }, { CR110, 0x27 },
762 { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
763 { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
764 { CR117, 0xfc }, { CR118, 0xfa }, { CR119, 0x1e },
765 { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
766 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
767 { CR131, 0x0c }, { CR136, 0xdf }, { CR137, 0xa0 },
768 { CR138, 0xa8 }, { CR139, 0xb4 }, { CR140, 0x98 },
769 { CR141, 0x82 }, { CR142, 0x53 }, { CR143, 0x1c },
770 { CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x40 },
771 { CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */
772 { CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */
773 { CR151, 0x18 }, { CR159, 0x70 }, { CR160, 0xfe },
774 { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
775 { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
776 { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
777 { CR170, 0xba }, { CR171, 0xba },
778 /* Note: CR204 must lead the CR203 */
779 { CR204, 0x7d },
780 {},
781 { CR203, 0x30 },
782 };
783
784 int r, t;
785
786 dev_dbg_f(zd_chip_dev(chip), "\n");
787
788 r = zd_chip_lock_phy_regs(chip);
789 if (r)
790 goto out;
791
792 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
793 if (r)
794 goto unlock;
795
796 r = patch_cr157(chip);
797unlock:
798 t = zd_chip_unlock_phy_regs(chip);
799 if (t && !r)
800 r = t;
801out:
802 return r;
803}
804
805static int hw_reset_phy(struct zd_chip *chip)
806{
807 return chip->is_zd1211b ? zd1211b_hw_reset_phy(chip) :
808 zd1211_hw_reset_phy(chip);
809}
810
811static int zd1211_hw_init_hmac(struct zd_chip *chip)
812{
813 static const struct zd_ioreq32 ioreqs[] = {
Daniel Drakee85d0912006-06-02 17:11:32 +0100814 { CR_ZD1211_RETRY_MAX, 0x2 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100815 { CR_RX_THRESHOLD, 0x000c0640 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100816 };
817
Daniel Drakee85d0912006-06-02 17:11:32 +0100818 dev_dbg_f(zd_chip_dev(chip), "\n");
819 ZD_ASSERT(mutex_is_locked(&chip->mutex));
Daniel Drake34c4491262006-12-12 01:25:13 +0000820 return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drakee85d0912006-06-02 17:11:32 +0100821}
822
823static int zd1211b_hw_init_hmac(struct zd_chip *chip)
824{
825 static const struct zd_ioreq32 ioreqs[] = {
Daniel Drakee85d0912006-06-02 17:11:32 +0100826 { CR_ZD1211B_RETRY_MAX, 0x02020202 },
827 { CR_ZD1211B_TX_PWR_CTL4, 0x007f003f },
828 { CR_ZD1211B_TX_PWR_CTL3, 0x007f003f },
829 { CR_ZD1211B_TX_PWR_CTL2, 0x003f001f },
830 { CR_ZD1211B_TX_PWR_CTL1, 0x001f000f },
831 { CR_ZD1211B_AIFS_CTL1, 0x00280028 },
832 { CR_ZD1211B_AIFS_CTL2, 0x008C003C },
833 { CR_ZD1211B_TXOP, 0x01800824 },
Daniel Drake34c4491262006-12-12 01:25:13 +0000834 { CR_RX_THRESHOLD, 0x000c0eff, },
835 };
836
837 dev_dbg_f(zd_chip_dev(chip), "\n");
838 ZD_ASSERT(mutex_is_locked(&chip->mutex));
839 return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
840}
841
842static int hw_init_hmac(struct zd_chip *chip)
843{
844 int r;
845 static const struct zd_ioreq32 ioreqs[] = {
846 { CR_ACK_TIMEOUT_EXT, 0x20 },
847 { CR_ADDA_MBIAS_WARMTIME, 0x30000808 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100848 { CR_SNIFFER_ON, 0 },
Ulrich Kunitzfde627b2006-08-01 23:43:35 +0200849 { CR_RX_FILTER, STA_RX_FILTER },
Daniel Drakee85d0912006-06-02 17:11:32 +0100850 { CR_GROUP_HASH_P1, 0x00 },
851 { CR_GROUP_HASH_P2, 0x80000000 },
852 { CR_REG1, 0xa4 },
853 { CR_ADDA_PWR_DWN, 0x7f },
854 { CR_BCN_PLCP_CFG, 0x00f00401 },
855 { CR_PHY_DELAY, 0x00 },
856 { CR_ACK_TIMEOUT_EXT, 0x80 },
857 { CR_ADDA_PWR_DWN, 0x00 },
858 { CR_ACK_TIME_80211, 0x100 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100859 { CR_RX_PE_DELAY, 0x70 },
860 { CR_PS_CTRL, 0x10000000 },
861 { CR_RTS_CTS_RATE, 0x02030203 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100862 { CR_AFTER_PNP, 0x1 },
863 { CR_WEP_PROTECT, 0x114 },
Daniel Drake34c4491262006-12-12 01:25:13 +0000864 { CR_IFS_VALUE, IFS_VALUE_DEFAULT },
Daniel Drakee85d0912006-06-02 17:11:32 +0100865 };
866
Daniel Drakee85d0912006-06-02 17:11:32 +0100867 ZD_ASSERT(mutex_is_locked(&chip->mutex));
868 r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drake34c4491262006-12-12 01:25:13 +0000869 if (r)
870 return r;
Daniel Drakee85d0912006-06-02 17:11:32 +0100871
Daniel Drakee85d0912006-06-02 17:11:32 +0100872 return chip->is_zd1211b ?
873 zd1211b_hw_init_hmac(chip) : zd1211_hw_init_hmac(chip);
874}
875
876struct aw_pt_bi {
877 u32 atim_wnd_period;
878 u32 pre_tbtt;
879 u32 beacon_interval;
880};
881
882static int get_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
883{
884 int r;
885 static const zd_addr_t aw_pt_bi_addr[] =
886 { CR_ATIM_WND_PERIOD, CR_PRE_TBTT, CR_BCN_INTERVAL };
887 u32 values[3];
888
889 r = zd_ioread32v_locked(chip, values, (const zd_addr_t *)aw_pt_bi_addr,
890 ARRAY_SIZE(aw_pt_bi_addr));
891 if (r) {
892 memset(s, 0, sizeof(*s));
893 return r;
894 }
895
896 s->atim_wnd_period = values[0];
897 s->pre_tbtt = values[1];
898 s->beacon_interval = values[2];
899 dev_dbg_f(zd_chip_dev(chip), "aw %u pt %u bi %u\n",
900 s->atim_wnd_period, s->pre_tbtt, s->beacon_interval);
901 return 0;
902}
903
904static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
905{
906 struct zd_ioreq32 reqs[3];
907
908 if (s->beacon_interval <= 5)
909 s->beacon_interval = 5;
910 if (s->pre_tbtt < 4 || s->pre_tbtt >= s->beacon_interval)
911 s->pre_tbtt = s->beacon_interval - 1;
912 if (s->atim_wnd_period >= s->pre_tbtt)
913 s->atim_wnd_period = s->pre_tbtt - 1;
914
915 reqs[0].addr = CR_ATIM_WND_PERIOD;
916 reqs[0].value = s->atim_wnd_period;
917 reqs[1].addr = CR_PRE_TBTT;
918 reqs[1].value = s->pre_tbtt;
919 reqs[2].addr = CR_BCN_INTERVAL;
920 reqs[2].value = s->beacon_interval;
921
922 dev_dbg_f(zd_chip_dev(chip),
923 "aw %u pt %u bi %u\n", s->atim_wnd_period, s->pre_tbtt,
924 s->beacon_interval);
925 return zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
926}
927
928
929static int set_beacon_interval(struct zd_chip *chip, u32 interval)
930{
931 int r;
932 struct aw_pt_bi s;
933
934 ZD_ASSERT(mutex_is_locked(&chip->mutex));
935 r = get_aw_pt_bi(chip, &s);
936 if (r)
937 return r;
938 s.beacon_interval = interval;
939 return set_aw_pt_bi(chip, &s);
940}
941
942int zd_set_beacon_interval(struct zd_chip *chip, u32 interval)
943{
944 int r;
945
946 mutex_lock(&chip->mutex);
947 r = set_beacon_interval(chip, interval);
948 mutex_unlock(&chip->mutex);
949 return r;
950}
951
952static int hw_init(struct zd_chip *chip)
953{
954 int r;
955
956 dev_dbg_f(zd_chip_dev(chip), "\n");
957 ZD_ASSERT(mutex_is_locked(&chip->mutex));
958 r = hw_reset_phy(chip);
959 if (r)
960 return r;
961
962 r = hw_init_hmac(chip);
963 if (r)
964 return r;
Daniel Drake98227a92006-08-12 17:59:22 +0100965
Daniel Drake98227a92006-08-12 17:59:22 +0100966 return set_beacon_interval(chip, 100);
Daniel Drakee85d0912006-06-02 17:11:32 +0100967}
968
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000969static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset)
970{
971 return (zd_addr_t)((u16)chip->fw_regs_base + offset);
972}
973
Daniel Drakee85d0912006-06-02 17:11:32 +0100974#ifdef DEBUG
975static int dump_cr(struct zd_chip *chip, const zd_addr_t addr,
976 const char *addr_string)
977{
978 int r;
979 u32 value;
980
981 r = zd_ioread32_locked(chip, &value, addr);
982 if (r) {
983 dev_dbg_f(zd_chip_dev(chip),
984 "error reading %s. Error number %d\n", addr_string, r);
985 return r;
986 }
987
988 dev_dbg_f(zd_chip_dev(chip), "%s %#010x\n",
989 addr_string, (unsigned int)value);
990 return 0;
991}
992
993static int test_init(struct zd_chip *chip)
994{
995 int r;
996
997 r = dump_cr(chip, CR_AFTER_PNP, "CR_AFTER_PNP");
998 if (r)
999 return r;
1000 r = dump_cr(chip, CR_GPI_EN, "CR_GPI_EN");
1001 if (r)
1002 return r;
1003 return dump_cr(chip, CR_INTERRUPT, "CR_INTERRUPT");
1004}
1005
1006static void dump_fw_registers(struct zd_chip *chip)
1007{
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001008 const zd_addr_t addr[4] = {
1009 fw_reg_addr(chip, FW_REG_FIRMWARE_VER),
1010 fw_reg_addr(chip, FW_REG_USB_SPEED),
1011 fw_reg_addr(chip, FW_REG_FIX_TX_RATE),
1012 fw_reg_addr(chip, FW_REG_LED_LINK_STATUS),
Daniel Drakee85d0912006-06-02 17:11:32 +01001013 };
1014
1015 int r;
1016 u16 values[4];
1017
1018 r = zd_ioread16v_locked(chip, values, (const zd_addr_t*)addr,
1019 ARRAY_SIZE(addr));
1020 if (r) {
1021 dev_dbg_f(zd_chip_dev(chip), "error %d zd_ioread16v_locked\n",
1022 r);
1023 return;
1024 }
1025
1026 dev_dbg_f(zd_chip_dev(chip), "FW_FIRMWARE_VER %#06hx\n", values[0]);
1027 dev_dbg_f(zd_chip_dev(chip), "FW_USB_SPEED %#06hx\n", values[1]);
1028 dev_dbg_f(zd_chip_dev(chip), "FW_FIX_TX_RATE %#06hx\n", values[2]);
1029 dev_dbg_f(zd_chip_dev(chip), "FW_LINK_STATUS %#06hx\n", values[3]);
1030}
1031#endif /* DEBUG */
1032
1033static int print_fw_version(struct zd_chip *chip)
1034{
1035 int r;
1036 u16 version;
1037
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001038 r = zd_ioread16_locked(chip, &version,
1039 fw_reg_addr(chip, FW_REG_FIRMWARE_VER));
Daniel Drakee85d0912006-06-02 17:11:32 +01001040 if (r)
1041 return r;
1042
1043 dev_info(zd_chip_dev(chip),"firmware version %04hx\n", version);
1044 return 0;
1045}
1046
1047static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std)
1048{
1049 u32 rates;
1050 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1051 /* This sets the mandatory rates, which only depend from the standard
1052 * that the device is supporting. Until further notice we should try
1053 * to support 802.11g also for full speed USB.
1054 */
1055 switch (std) {
1056 case IEEE80211B:
1057 rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M;
1058 break;
1059 case IEEE80211G:
1060 rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M|
1061 CR_RATE_6M|CR_RATE_12M|CR_RATE_24M;
1062 break;
1063 default:
1064 return -EINVAL;
1065 }
1066 return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL);
1067}
1068
Daniel Drakeb1382ed2006-11-22 00:06:48 +00001069int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
1070 u8 rts_rate, int preamble)
1071{
1072 int rts_mod = ZD_RX_CCK;
1073 u32 value = 0;
1074
1075 /* Modulation bit */
1076 if (ZD_CS_TYPE(rts_rate) == ZD_CS_OFDM)
1077 rts_mod = ZD_RX_OFDM;
1078
1079 dev_dbg_f(zd_chip_dev(chip), "rts_rate=%x preamble=%x\n",
1080 rts_rate, preamble);
1081
1082 value |= rts_rate << RTSCTS_SH_RTS_RATE;
1083 value |= rts_mod << RTSCTS_SH_RTS_MOD_TYPE;
1084 value |= preamble << RTSCTS_SH_RTS_PMB_TYPE;
1085 value |= preamble << RTSCTS_SH_CTS_PMB_TYPE;
1086
1087 /* We always send 11M self-CTS messages, like the vendor driver. */
1088 value |= ZD_CCK_RATE_11M << RTSCTS_SH_CTS_RATE;
1089 value |= ZD_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE;
1090
1091 return zd_iowrite32_locked(chip, value, CR_RTS_CTS_RATE);
1092}
1093
Daniel Drakee85d0912006-06-02 17:11:32 +01001094int zd_chip_enable_hwint(struct zd_chip *chip)
1095{
1096 int r;
1097
1098 mutex_lock(&chip->mutex);
1099 r = zd_iowrite32_locked(chip, HWINT_ENABLED, CR_INTERRUPT);
1100 mutex_unlock(&chip->mutex);
1101 return r;
1102}
1103
1104static int disable_hwint(struct zd_chip *chip)
1105{
1106 return zd_iowrite32_locked(chip, HWINT_DISABLED, CR_INTERRUPT);
1107}
1108
1109int zd_chip_disable_hwint(struct zd_chip *chip)
1110{
1111 int r;
1112
1113 mutex_lock(&chip->mutex);
1114 r = disable_hwint(chip);
1115 mutex_unlock(&chip->mutex);
1116 return r;
1117}
1118
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001119static int read_fw_regs_offset(struct zd_chip *chip)
1120{
1121 int r;
1122
1123 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1124 r = zd_ioread16_locked(chip, (u16*)&chip->fw_regs_base,
1125 FWRAW_REGS_ADDR);
1126 if (r)
1127 return r;
1128 dev_dbg_f(zd_chip_dev(chip), "fw_regs_base: %#06hx\n",
1129 (u16)chip->fw_regs_base);
1130
1131 return 0;
1132}
1133
1134
Daniel Drakee85d0912006-06-02 17:11:32 +01001135int zd_chip_init_hw(struct zd_chip *chip, u8 device_type)
1136{
1137 int r;
1138 u8 rf_type;
1139
1140 dev_dbg_f(zd_chip_dev(chip), "\n");
1141
1142 mutex_lock(&chip->mutex);
1143 chip->is_zd1211b = (device_type == DEVICE_ZD1211B) != 0;
1144
1145#ifdef DEBUG
1146 r = test_init(chip);
1147 if (r)
1148 goto out;
1149#endif
1150 r = zd_iowrite32_locked(chip, 1, CR_AFTER_PNP);
1151 if (r)
1152 goto out;
1153
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001154 r = read_fw_regs_offset(chip);
Daniel Drakee85d0912006-06-02 17:11:32 +01001155 if (r)
1156 goto out;
1157
1158 /* GPI is always disabled, also in the other driver.
1159 */
1160 r = zd_iowrite32_locked(chip, 0, CR_GPI_EN);
1161 if (r)
1162 goto out;
1163 r = zd_iowrite32_locked(chip, CWIN_SIZE, CR_CWMIN_CWMAX);
1164 if (r)
1165 goto out;
1166 /* Currently we support IEEE 802.11g for full and high speed USB.
1167 * It might be discussed, whether we should suppport pure b mode for
1168 * full speed USB.
1169 */
1170 r = set_mandatory_rates(chip, IEEE80211G);
1171 if (r)
1172 goto out;
1173 /* Disabling interrupts is certainly a smart thing here.
1174 */
1175 r = disable_hwint(chip);
1176 if (r)
1177 goto out;
1178 r = read_pod(chip, &rf_type);
1179 if (r)
1180 goto out;
1181 r = hw_init(chip);
1182 if (r)
1183 goto out;
1184 r = zd_rf_init_hw(&chip->rf, rf_type);
1185 if (r)
1186 goto out;
1187
1188 r = print_fw_version(chip);
1189 if (r)
1190 goto out;
1191
1192#ifdef DEBUG
1193 dump_fw_registers(chip);
1194 r = test_init(chip);
1195 if (r)
1196 goto out;
1197#endif /* DEBUG */
1198
1199 r = read_e2p_mac_addr(chip);
1200 if (r)
1201 goto out;
1202
1203 r = read_cal_int_tables(chip);
1204 if (r)
1205 goto out;
1206
1207 print_id(chip);
1208out:
1209 mutex_unlock(&chip->mutex);
1210 return r;
1211}
1212
1213static int update_pwr_int(struct zd_chip *chip, u8 channel)
1214{
1215 u8 value = chip->pwr_int_values[channel - 1];
1216 dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_int %#04x\n",
1217 channel, value);
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001218 return zd_iowrite16_locked(chip, value, CR31);
Daniel Drakee85d0912006-06-02 17:11:32 +01001219}
1220
1221static int update_pwr_cal(struct zd_chip *chip, u8 channel)
1222{
1223 u8 value = chip->pwr_cal_values[channel-1];
1224 dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_cal %#04x\n",
1225 channel, value);
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001226 return zd_iowrite16_locked(chip, value, CR68);
Daniel Drakee85d0912006-06-02 17:11:32 +01001227}
1228
1229static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
1230{
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001231 struct zd_ioreq16 ioreqs[3];
Daniel Drakee85d0912006-06-02 17:11:32 +01001232
1233 ioreqs[0].addr = CR67;
1234 ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1];
1235 ioreqs[1].addr = CR66;
1236 ioreqs[1].value = chip->ofdm_cal_values[OFDM_48M_INDEX][channel-1];
1237 ioreqs[2].addr = CR65;
1238 ioreqs[2].value = chip->ofdm_cal_values[OFDM_54M_INDEX][channel-1];
1239
1240 dev_dbg_f(zd_chip_dev(chip),
1241 "channel %d ofdm_cal 36M %#04x 48M %#04x 54M %#04x\n",
1242 channel, ioreqs[0].value, ioreqs[1].value, ioreqs[2].value);
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001243 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drakee85d0912006-06-02 17:11:32 +01001244}
1245
1246static int update_channel_integration_and_calibration(struct zd_chip *chip,
1247 u8 channel)
1248{
1249 int r;
1250
1251 r = update_pwr_int(chip, channel);
1252 if (r)
1253 return r;
1254 if (chip->is_zd1211b) {
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001255 static const struct zd_ioreq16 ioreqs[] = {
Daniel Drakee85d0912006-06-02 17:11:32 +01001256 { CR69, 0x28 },
1257 {},
1258 { CR69, 0x2a },
1259 };
1260
1261 r = update_ofdm_cal(chip, channel);
1262 if (r)
1263 return r;
1264 r = update_pwr_cal(chip, channel);
1265 if (r)
1266 return r;
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001267 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drakee85d0912006-06-02 17:11:32 +01001268 if (r)
1269 return r;
1270 }
1271
1272 return 0;
1273}
1274
1275/* The CCK baseband gain can be optionally patched by the EEPROM */
1276static int patch_cck_gain(struct zd_chip *chip)
1277{
1278 int r;
1279 u32 value;
1280
1281 if (!chip->patch_cck_gain)
1282 return 0;
1283
1284 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1285 r = zd_ioread32_locked(chip, &value, E2P_PHY_REG);
1286 if (r)
1287 return r;
1288 dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff);
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001289 return zd_iowrite16_locked(chip, value & 0xff, CR47);
Daniel Drakee85d0912006-06-02 17:11:32 +01001290}
1291
1292int zd_chip_set_channel(struct zd_chip *chip, u8 channel)
1293{
1294 int r, t;
1295
1296 mutex_lock(&chip->mutex);
1297 r = zd_chip_lock_phy_regs(chip);
1298 if (r)
1299 goto out;
1300 r = zd_rf_set_channel(&chip->rf, channel);
1301 if (r)
1302 goto unlock;
1303 r = update_channel_integration_and_calibration(chip, channel);
1304 if (r)
1305 goto unlock;
1306 r = patch_cck_gain(chip);
1307 if (r)
1308 goto unlock;
1309 r = patch_6m_band_edge(chip, channel);
1310 if (r)
1311 goto unlock;
1312 r = zd_iowrite32_locked(chip, 0, CR_CONFIG_PHILIPS);
1313unlock:
1314 t = zd_chip_unlock_phy_regs(chip);
1315 if (t && !r)
1316 r = t;
1317out:
1318 mutex_unlock(&chip->mutex);
1319 return r;
1320}
1321
1322u8 zd_chip_get_channel(struct zd_chip *chip)
1323{
1324 u8 channel;
1325
1326 mutex_lock(&chip->mutex);
1327 channel = chip->rf.channel;
1328 mutex_unlock(&chip->mutex);
1329 return channel;
1330}
1331
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001332int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
Daniel Drakee85d0912006-06-02 17:11:32 +01001333{
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001334 const zd_addr_t a[] = {
1335 fw_reg_addr(chip, FW_REG_LED_LINK_STATUS),
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001336 CR_LED,
1337 };
Daniel Drakee85d0912006-06-02 17:11:32 +01001338
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001339 int r;
1340 u16 v[ARRAY_SIZE(a)];
1341 struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = {
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001342 [0] = { fw_reg_addr(chip, FW_REG_LED_LINK_STATUS) },
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001343 [1] = { CR_LED },
1344 };
1345 u16 other_led;
Daniel Drakee85d0912006-06-02 17:11:32 +01001346
Daniel Drakee85d0912006-06-02 17:11:32 +01001347 mutex_lock(&chip->mutex);
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001348 r = zd_ioread16v_locked(chip, v, (const zd_addr_t *)a, ARRAY_SIZE(a));
Daniel Drakee85d0912006-06-02 17:11:32 +01001349 if (r)
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001350 goto out;
1351
1352 other_led = chip->link_led == LED1 ? LED2 : LED1;
1353
Daniel Drakee85d0912006-06-02 17:11:32 +01001354 switch (status) {
Daniel Drakee85d0912006-06-02 17:11:32 +01001355 case LED_OFF:
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001356 ioreqs[0].value = FW_LINK_OFF;
1357 ioreqs[1].value = v[1] & ~(LED1|LED2);
Daniel Drakee85d0912006-06-02 17:11:32 +01001358 break;
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001359 case LED_SCANNING:
1360 ioreqs[0].value = FW_LINK_OFF;
1361 ioreqs[1].value = v[1] & ~other_led;
1362 if (get_seconds() % 3 == 0) {
1363 ioreqs[1].value &= ~chip->link_led;
1364 } else {
1365 ioreqs[1].value |= chip->link_led;
1366 }
Daniel Drakee85d0912006-06-02 17:11:32 +01001367 break;
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001368 case LED_ASSOCIATED:
1369 ioreqs[0].value = FW_LINK_TX;
1370 ioreqs[1].value = v[1] & ~other_led;
1371 ioreqs[1].value |= chip->link_led;
Daniel Drakee85d0912006-06-02 17:11:32 +01001372 break;
1373 default:
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001374 r = -EINVAL;
Daniel Drakee85d0912006-06-02 17:11:32 +01001375 goto out;
1376 }
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001377
1378 if (v[0] != ioreqs[0].value || v[1] != ioreqs[1].value) {
1379 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
1380 if (r)
1381 goto out;
1382 }
1383 r = 0;
Daniel Drakee85d0912006-06-02 17:11:32 +01001384out:
1385 mutex_unlock(&chip->mutex);
1386 return r;
1387}
1388
Daniel Drakeb1382ed2006-11-22 00:06:48 +00001389int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates)
Daniel Drakee85d0912006-06-02 17:11:32 +01001390{
Daniel Drakeb1382ed2006-11-22 00:06:48 +00001391 ZD_ASSERT((cr_rates & ~(CR_RATES_80211B | CR_RATES_80211G)) == 0);
1392 dev_dbg_f(zd_chip_dev(chip), "%x\n", cr_rates);
Daniel Drakee85d0912006-06-02 17:11:32 +01001393
Daniel Drakeb1382ed2006-11-22 00:06:48 +00001394 return zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
Daniel Drakee85d0912006-06-02 17:11:32 +01001395}
1396
1397static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size)
1398{
1399 static const u16 constants[] = {
1400 715, 655, 585, 540, 470, 410, 360, 315,
1401 270, 235, 205, 175, 150, 125, 105, 85,
1402 65, 50, 40, 25, 15
1403 };
1404
1405 int i;
1406 u32 x;
1407
1408 /* It seems that their quality parameter is somehow per signal
1409 * and is now transferred per bit.
1410 */
1411 switch (rate) {
1412 case ZD_OFDM_RATE_6M:
1413 case ZD_OFDM_RATE_12M:
1414 case ZD_OFDM_RATE_24M:
1415 size *= 2;
1416 break;
1417 case ZD_OFDM_RATE_9M:
1418 case ZD_OFDM_RATE_18M:
1419 case ZD_OFDM_RATE_36M:
1420 case ZD_OFDM_RATE_54M:
1421 size *= 4;
1422 size /= 3;
1423 break;
1424 case ZD_OFDM_RATE_48M:
1425 size *= 3;
1426 size /= 2;
1427 break;
1428 default:
1429 return -EINVAL;
1430 }
1431
1432 x = (10000 * status_quality)/size;
1433 for (i = 0; i < ARRAY_SIZE(constants); i++) {
1434 if (x > constants[i])
1435 break;
1436 }
1437
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001438 switch (rate) {
1439 case ZD_OFDM_RATE_6M:
1440 case ZD_OFDM_RATE_9M:
1441 i += 3;
1442 break;
1443 case ZD_OFDM_RATE_12M:
1444 case ZD_OFDM_RATE_18M:
1445 i += 5;
1446 break;
1447 case ZD_OFDM_RATE_24M:
1448 case ZD_OFDM_RATE_36M:
1449 i += 9;
1450 break;
1451 case ZD_OFDM_RATE_48M:
1452 case ZD_OFDM_RATE_54M:
1453 i += 15;
1454 break;
1455 default:
1456 return -EINVAL;
1457 }
1458
Daniel Drakee85d0912006-06-02 17:11:32 +01001459 return i;
1460}
1461
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001462static int ofdm_qual_percent(u8 status_quality, u8 rate, unsigned int size)
1463{
1464 int r;
1465
1466 r = ofdm_qual_db(status_quality, rate, size);
1467 ZD_ASSERT(r >= 0);
1468 if (r < 0)
1469 r = 0;
1470
1471 r = (r * 100)/29;
1472 return r <= 100 ? r : 100;
1473}
1474
Daniel Drakee85d0912006-06-02 17:11:32 +01001475static unsigned int log10times100(unsigned int x)
1476{
1477 static const u8 log10[] = {
1478 0,
1479 0, 30, 47, 60, 69, 77, 84, 90, 95, 100,
1480 104, 107, 111, 114, 117, 120, 123, 125, 127, 130,
1481 132, 134, 136, 138, 139, 141, 143, 144, 146, 147,
1482 149, 150, 151, 153, 154, 155, 156, 157, 159, 160,
1483 161, 162, 163, 164, 165, 166, 167, 168, 169, 169,
1484 170, 171, 172, 173, 174, 174, 175, 176, 177, 177,
1485 178, 179, 179, 180, 181, 181, 182, 183, 183, 184,
1486 185, 185, 186, 186, 187, 188, 188, 189, 189, 190,
1487 190, 191, 191, 192, 192, 193, 193, 194, 194, 195,
1488 195, 196, 196, 197, 197, 198, 198, 199, 199, 200,
1489 200, 200, 201, 201, 202, 202, 202, 203, 203, 204,
1490 204, 204, 205, 205, 206, 206, 206, 207, 207, 207,
1491 208, 208, 208, 209, 209, 210, 210, 210, 211, 211,
1492 211, 212, 212, 212, 213, 213, 213, 213, 214, 214,
1493 214, 215, 215, 215, 216, 216, 216, 217, 217, 217,
1494 217, 218, 218, 218, 219, 219, 219, 219, 220, 220,
1495 220, 220, 221, 221, 221, 222, 222, 222, 222, 223,
1496 223, 223, 223, 224, 224, 224, 224,
1497 };
1498
1499 return x < ARRAY_SIZE(log10) ? log10[x] : 225;
1500}
1501
1502enum {
1503 MAX_CCK_EVM_DB = 45,
1504};
1505
1506static int cck_evm_db(u8 status_quality)
1507{
1508 return (20 * log10times100(status_quality)) / 100;
1509}
1510
1511static int cck_snr_db(u8 status_quality)
1512{
1513 int r = MAX_CCK_EVM_DB - cck_evm_db(status_quality);
1514 ZD_ASSERT(r >= 0);
1515 return r;
1516}
1517
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001518static int cck_qual_percent(u8 status_quality)
Daniel Drakee85d0912006-06-02 17:11:32 +01001519{
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001520 int r;
1521
1522 r = cck_snr_db(status_quality);
1523 r = (100*r)/17;
1524 return r <= 100 ? r : 100;
Daniel Drakee85d0912006-06-02 17:11:32 +01001525}
1526
1527u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
1528 const struct rx_status *status)
1529{
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001530 return (status->frame_status&ZD_RX_OFDM) ?
1531 ofdm_qual_percent(status->signal_quality_ofdm,
1532 zd_ofdm_plcp_header_rate(rx_frame),
1533 size) :
1534 cck_qual_percent(status->signal_quality_cck);
Daniel Drakee85d0912006-06-02 17:11:32 +01001535}
1536
1537u8 zd_rx_strength_percent(u8 rssi)
1538{
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001539 int r = (rssi*100) / 41;
Daniel Drakee85d0912006-06-02 17:11:32 +01001540 if (r > 100)
1541 r = 100;
1542 return (u8) r;
1543}
1544
1545u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status)
1546{
1547 static const u16 ofdm_rates[] = {
1548 [ZD_OFDM_RATE_6M] = 60,
1549 [ZD_OFDM_RATE_9M] = 90,
1550 [ZD_OFDM_RATE_12M] = 120,
1551 [ZD_OFDM_RATE_18M] = 180,
1552 [ZD_OFDM_RATE_24M] = 240,
1553 [ZD_OFDM_RATE_36M] = 360,
1554 [ZD_OFDM_RATE_48M] = 480,
1555 [ZD_OFDM_RATE_54M] = 540,
1556 };
1557 u16 rate;
1558 if (status->frame_status & ZD_RX_OFDM) {
1559 u8 ofdm_rate = zd_ofdm_plcp_header_rate(rx_frame);
1560 rate = ofdm_rates[ofdm_rate & 0xf];
1561 } else {
1562 u8 cck_rate = zd_cck_plcp_header_rate(rx_frame);
1563 switch (cck_rate) {
1564 case ZD_CCK_SIGNAL_1M:
1565 rate = 10;
1566 break;
1567 case ZD_CCK_SIGNAL_2M:
1568 rate = 20;
1569 break;
1570 case ZD_CCK_SIGNAL_5M5:
1571 rate = 55;
1572 break;
1573 case ZD_CCK_SIGNAL_11M:
1574 rate = 110;
1575 break;
1576 default:
1577 rate = 0;
1578 }
1579 }
1580
1581 return rate;
1582}
1583
1584int zd_chip_switch_radio_on(struct zd_chip *chip)
1585{
1586 int r;
1587
1588 mutex_lock(&chip->mutex);
1589 r = zd_switch_radio_on(&chip->rf);
1590 mutex_unlock(&chip->mutex);
1591 return r;
1592}
1593
1594int zd_chip_switch_radio_off(struct zd_chip *chip)
1595{
1596 int r;
1597
1598 mutex_lock(&chip->mutex);
1599 r = zd_switch_radio_off(&chip->rf);
1600 mutex_unlock(&chip->mutex);
1601 return r;
1602}
1603
1604int zd_chip_enable_int(struct zd_chip *chip)
1605{
1606 int r;
1607
1608 mutex_lock(&chip->mutex);
1609 r = zd_usb_enable_int(&chip->usb);
1610 mutex_unlock(&chip->mutex);
1611 return r;
1612}
1613
1614void zd_chip_disable_int(struct zd_chip *chip)
1615{
1616 mutex_lock(&chip->mutex);
1617 zd_usb_disable_int(&chip->usb);
1618 mutex_unlock(&chip->mutex);
1619}
1620
1621int zd_chip_enable_rx(struct zd_chip *chip)
1622{
1623 int r;
1624
1625 mutex_lock(&chip->mutex);
1626 r = zd_usb_enable_rx(&chip->usb);
1627 mutex_unlock(&chip->mutex);
1628 return r;
1629}
1630
1631void zd_chip_disable_rx(struct zd_chip *chip)
1632{
1633 mutex_lock(&chip->mutex);
1634 zd_usb_disable_rx(&chip->usb);
1635 mutex_unlock(&chip->mutex);
1636}
1637
1638int zd_rfwritev_locked(struct zd_chip *chip,
1639 const u32* values, unsigned int count, u8 bits)
1640{
1641 int r;
1642 unsigned int i;
1643
1644 for (i = 0; i < count; i++) {
1645 r = zd_rfwrite_locked(chip, values[i], bits);
1646 if (r)
1647 return r;
1648 }
1649
1650 return 0;
1651}
Daniel Drake20fe2172006-08-12 17:59:42 +01001652
1653/*
1654 * We can optionally program the RF directly through CR regs, if supported by
1655 * the hardware. This is much faster than the older method.
1656 */
Daniel Drakeec62bd92006-08-12 17:59:46 +01001657int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
Daniel Drake20fe2172006-08-12 17:59:42 +01001658{
1659 struct zd_ioreq16 ioreqs[] = {
1660 { CR244, (value >> 16) & 0xff },
1661 { CR243, (value >> 8) & 0xff },
1662 { CR242, value & 0xff },
1663 };
1664 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1665 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
1666}
1667
1668int zd_rfwritev_cr_locked(struct zd_chip *chip,
1669 const u32 *values, unsigned int count)
1670{
1671 int r;
1672 unsigned int i;
1673
1674 for (i = 0; i < count; i++) {
1675 r = zd_rfwrite_cr_locked(chip, values[i]);
1676 if (r)
1677 return r;
1678 }
1679
1680 return 0;
1681}
Ulrich Kunitz9cdac962006-12-01 00:58:07 +00001682
1683int zd_chip_set_multicast_hash(struct zd_chip *chip,
1684 struct zd_mc_hash *hash)
1685{
1686 struct zd_ioreq32 ioreqs[] = {
1687 { CR_GROUP_HASH_P1, hash->low },
1688 { CR_GROUP_HASH_P2, hash->high },
1689 };
1690
1691 dev_dbg_f(zd_chip_dev(chip), "hash l 0x%08x h 0x%08x\n",
1692 ioreqs[0].value, ioreqs[1].value);
1693 return zd_iowrite32a(chip, ioreqs, ARRAY_SIZE(ioreqs));
1694}