blob: c39f1984b84df33d35747f8badd7eff5ea266c7b [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
Daniel Drake74553ae2007-07-01 18:22:32 +010052static int scnprint_mac_oui(struct zd_chip *chip, char *buffer, size_t size)
Daniel Drakee85d0912006-06-02 17:11:32 +010053{
Daniel Drake74553ae2007-07-01 18:22:32 +010054 u8 *addr = zd_usb_to_netdev(&chip->usb)->dev_addr;
Daniel Drakee85d0912006-06-02 17:11:32 +010055 return scnprintf(buffer, size, "%02x-%02x-%02x",
56 addr[0], addr[1], addr[2]);
57}
58
59/* Prints an identifier line, which will support debugging. */
60static int scnprint_id(struct zd_chip *chip, char *buffer, size_t size)
61{
62 int i = 0;
63
64 i = scnprintf(buffer, size, "zd1211%s chip ",
Daniel Drake74553ae2007-07-01 18:22:32 +010065 zd_chip_is_zd1211b(chip) ? "b" : "");
Daniel Drakee85d0912006-06-02 17:11:32 +010066 i += zd_usb_scnprint_id(&chip->usb, buffer+i, size-i);
67 i += scnprintf(buffer+i, size-i, " ");
Daniel Drake74553ae2007-07-01 18:22:32 +010068 i += scnprint_mac_oui(chip, buffer+i, size-i);
Daniel Drakee85d0912006-06-02 17:11:32 +010069 i += scnprintf(buffer+i, size-i, " ");
70 i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i);
Daniel Drakef2a81a12007-03-11 19:54:28 +000071 i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c%c", chip->pa_type,
Daniel Drakee85d0912006-06-02 17:11:32 +010072 chip->patch_cck_gain ? 'g' : '-',
73 chip->patch_cr157 ? '7' : '-',
Daniel Drake20fe2172006-08-12 17:59:42 +010074 chip->patch_6m_band_edge ? '6' : '-',
Daniel Drakef2a81a12007-03-11 19:54:28 +000075 chip->new_phy_layout ? 'N' : '-',
76 chip->al2230s_bit ? 'S' : '-');
Daniel Drakee85d0912006-06-02 17:11:32 +010077 return i;
78}
79
80static void print_id(struct zd_chip *chip)
81{
82 char buffer[80];
83
84 scnprint_id(chip, buffer, sizeof(buffer));
85 buffer[sizeof(buffer)-1] = 0;
86 dev_info(zd_chip_dev(chip), "%s\n", buffer);
87}
88
Daniel Drake0ce34bc2006-12-12 01:26:11 +000089static zd_addr_t inc_addr(zd_addr_t addr)
90{
91 u16 a = (u16)addr;
92 /* Control registers use byte addressing, but everything else uses word
93 * addressing. */
94 if ((a & 0xf000) == CR_START)
95 a += 2;
96 else
97 a += 1;
98 return (zd_addr_t)a;
99}
100
Daniel Drakee85d0912006-06-02 17:11:32 +0100101/* Read a variable number of 32-bit values. Parameter count is not allowed to
102 * exceed USB_MAX_IOREAD32_COUNT.
103 */
104int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr,
105 unsigned int count)
106{
107 int r;
108 int i;
109 zd_addr_t *a16 = (zd_addr_t *)NULL;
110 u16 *v16;
111 unsigned int count16;
112
113 if (count > USB_MAX_IOREAD32_COUNT)
114 return -EINVAL;
115
116 /* Allocate a single memory block for values and addresses. */
117 count16 = 2*count;
Daniel Drake44956852007-02-10 01:27:18 +0000118 a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
Ulrich Kunitz35c34042007-02-18 20:28:23 +0000119 GFP_KERNEL);
Daniel Drakee85d0912006-06-02 17:11:32 +0100120 if (!a16) {
121 dev_dbg_f(zd_chip_dev(chip),
122 "error ENOMEM in allocation of a16\n");
123 r = -ENOMEM;
124 goto out;
125 }
126 v16 = (u16 *)(a16 + count16);
127
128 for (i = 0; i < count; i++) {
129 int j = 2*i;
130 /* We read the high word always first. */
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000131 a16[j] = inc_addr(addr[i]);
Daniel Drakee85d0912006-06-02 17:11:32 +0100132 a16[j+1] = addr[i];
133 }
134
135 r = zd_ioread16v_locked(chip, v16, a16, count16);
136 if (r) {
137 dev_dbg_f(zd_chip_dev(chip),
138 "error: zd_ioread16v_locked. Error number %d\n", r);
139 goto out;
140 }
141
142 for (i = 0; i < count; i++) {
143 int j = 2*i;
144 values[i] = (v16[j] << 16) | v16[j+1];
145 }
146
147out:
148 kfree((void *)a16);
149 return r;
150}
151
152int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
153 unsigned int count)
154{
155 int i, j, r;
156 struct zd_ioreq16 *ioreqs16;
157 unsigned int count16;
158
159 ZD_ASSERT(mutex_is_locked(&chip->mutex));
160
161 if (count == 0)
162 return 0;
163 if (count > USB_MAX_IOWRITE32_COUNT)
164 return -EINVAL;
165
166 /* Allocate a single memory block for values and addresses. */
167 count16 = 2*count;
Ulrich Kunitz35c34042007-02-18 20:28:23 +0000168 ioreqs16 = kmalloc(count16 * sizeof(struct zd_ioreq16), GFP_KERNEL);
Daniel Drakee85d0912006-06-02 17:11:32 +0100169 if (!ioreqs16) {
170 r = -ENOMEM;
171 dev_dbg_f(zd_chip_dev(chip),
172 "error %d in ioreqs16 allocation\n", r);
173 goto out;
174 }
175
176 for (i = 0; i < count; i++) {
177 j = 2*i;
178 /* We write the high word always first. */
179 ioreqs16[j].value = ioreqs[i].value >> 16;
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000180 ioreqs16[j].addr = inc_addr(ioreqs[i].addr);
Daniel Drakee85d0912006-06-02 17:11:32 +0100181 ioreqs16[j+1].value = ioreqs[i].value;
182 ioreqs16[j+1].addr = ioreqs[i].addr;
183 }
184
185 r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16);
186#ifdef DEBUG
187 if (r) {
188 dev_dbg_f(zd_chip_dev(chip),
189 "error %d in zd_usb_write16v\n", r);
190 }
191#endif /* DEBUG */
192out:
193 kfree(ioreqs16);
194 return r;
195}
196
197int zd_iowrite16a_locked(struct zd_chip *chip,
198 const struct zd_ioreq16 *ioreqs, unsigned int count)
199{
200 int r;
201 unsigned int i, j, t, max;
202
203 ZD_ASSERT(mutex_is_locked(&chip->mutex));
204 for (i = 0; i < count; i += j + t) {
205 t = 0;
206 max = count-i;
207 if (max > USB_MAX_IOWRITE16_COUNT)
208 max = USB_MAX_IOWRITE16_COUNT;
209 for (j = 0; j < max; j++) {
210 if (!ioreqs[i+j].addr) {
211 t = 1;
212 break;
213 }
214 }
215
216 r = zd_usb_iowrite16v(&chip->usb, &ioreqs[i], j);
217 if (r) {
218 dev_dbg_f(zd_chip_dev(chip),
219 "error zd_usb_iowrite16v. Error number %d\n",
220 r);
221 return r;
222 }
223 }
224
225 return 0;
226}
227
228/* Writes a variable number of 32 bit registers. The functions will split
229 * that in several USB requests. A split can be forced by inserting an IO
230 * request with an zero address field.
231 */
232int zd_iowrite32a_locked(struct zd_chip *chip,
233 const struct zd_ioreq32 *ioreqs, unsigned int count)
234{
235 int r;
236 unsigned int i, j, t, max;
237
238 for (i = 0; i < count; i += j + t) {
239 t = 0;
240 max = count-i;
241 if (max > USB_MAX_IOWRITE32_COUNT)
242 max = USB_MAX_IOWRITE32_COUNT;
243 for (j = 0; j < max; j++) {
244 if (!ioreqs[i+j].addr) {
245 t = 1;
246 break;
247 }
248 }
249
250 r = _zd_iowrite32v_locked(chip, &ioreqs[i], j);
251 if (r) {
252 dev_dbg_f(zd_chip_dev(chip),
253 "error _zd_iowrite32v_locked."
254 " Error number %d\n", r);
255 return r;
256 }
257 }
258
259 return 0;
260}
261
262int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value)
263{
264 int r;
265
Daniel Drakee85d0912006-06-02 17:11:32 +0100266 mutex_lock(&chip->mutex);
267 r = zd_ioread16_locked(chip, value, addr);
268 mutex_unlock(&chip->mutex);
269 return r;
270}
271
272int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value)
273{
274 int r;
275
Daniel Drakee85d0912006-06-02 17:11:32 +0100276 mutex_lock(&chip->mutex);
277 r = zd_ioread32_locked(chip, value, addr);
278 mutex_unlock(&chip->mutex);
279 return r;
280}
281
282int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value)
283{
284 int r;
285
Daniel Drakee85d0912006-06-02 17:11:32 +0100286 mutex_lock(&chip->mutex);
287 r = zd_iowrite16_locked(chip, value, addr);
288 mutex_unlock(&chip->mutex);
289 return r;
290}
291
292int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value)
293{
294 int r;
295
Daniel Drakee85d0912006-06-02 17:11:32 +0100296 mutex_lock(&chip->mutex);
297 r = zd_iowrite32_locked(chip, value, addr);
298 mutex_unlock(&chip->mutex);
299 return r;
300}
301
302int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses,
303 u32 *values, unsigned int count)
304{
305 int r;
306
Daniel Drakee85d0912006-06-02 17:11:32 +0100307 mutex_lock(&chip->mutex);
308 r = zd_ioread32v_locked(chip, values, addresses, count);
309 mutex_unlock(&chip->mutex);
310 return r;
311}
312
313int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
314 unsigned int count)
315{
316 int r;
317
Daniel Drakee85d0912006-06-02 17:11:32 +0100318 mutex_lock(&chip->mutex);
319 r = zd_iowrite32a_locked(chip, ioreqs, count);
320 mutex_unlock(&chip->mutex);
321 return r;
322}
323
324static int read_pod(struct zd_chip *chip, u8 *rf_type)
325{
326 int r;
327 u32 value;
328
329 ZD_ASSERT(mutex_is_locked(&chip->mutex));
330 r = zd_ioread32_locked(chip, &value, E2P_POD);
331 if (r)
332 goto error;
333 dev_dbg_f(zd_chip_dev(chip), "E2P_POD %#010x\n", value);
334
335 /* FIXME: AL2230 handling (Bit 7 in POD) */
336 *rf_type = value & 0x0f;
337 chip->pa_type = (value >> 16) & 0x0f;
338 chip->patch_cck_gain = (value >> 8) & 0x1;
339 chip->patch_cr157 = (value >> 13) & 0x1;
340 chip->patch_6m_band_edge = (value >> 21) & 0x1;
Daniel Drake20fe2172006-08-12 17:59:42 +0100341 chip->new_phy_layout = (value >> 31) & 0x1;
Daniel Drakeae6ead42007-03-11 19:54:11 +0000342 chip->al2230s_bit = (value >> 7) & 0x1;
Ulrich Kunitz583afd12006-09-13 02:42:38 +0100343 chip->link_led = ((value >> 4) & 1) ? LED1 : LED2;
344 chip->supports_tx_led = 1;
345 if (value & (1 << 24)) { /* LED scenario */
346 if (value & (1 << 29))
347 chip->supports_tx_led = 0;
348 }
Daniel Drakee85d0912006-06-02 17:11:32 +0100349
350 dev_dbg_f(zd_chip_dev(chip),
351 "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d "
Ulrich Kunitz583afd12006-09-13 02:42:38 +0100352 "patch 6M %d new PHY %d link LED%d tx led %d\n",
Daniel Drakee85d0912006-06-02 17:11:32 +0100353 zd_rf_name(*rf_type), *rf_type,
354 chip->pa_type, chip->patch_cck_gain,
Ulrich Kunitz583afd12006-09-13 02:42:38 +0100355 chip->patch_cr157, chip->patch_6m_band_edge,
356 chip->new_phy_layout,
357 chip->link_led == LED1 ? 1 : 2,
358 chip->supports_tx_led);
Daniel Drakee85d0912006-06-02 17:11:32 +0100359 return 0;
360error:
361 *rf_type = 0;
362 chip->pa_type = 0;
363 chip->patch_cck_gain = 0;
364 chip->patch_cr157 = 0;
365 chip->patch_6m_band_edge = 0;
Daniel Drake20fe2172006-08-12 17:59:42 +0100366 chip->new_phy_layout = 0;
Daniel Drakee85d0912006-06-02 17:11:32 +0100367 return r;
368}
369
Daniel Drakee85d0912006-06-02 17:11:32 +0100370/* MAC address: if custom mac addresses are to to be used CR_MAC_ADDR_P1 and
371 * CR_MAC_ADDR_P2 must be overwritten
372 */
Daniel Drakee85d0912006-06-02 17:11:32 +0100373int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
374{
375 int r;
376 struct zd_ioreq32 reqs[2] = {
377 [0] = { .addr = CR_MAC_ADDR_P1 },
378 [1] = { .addr = CR_MAC_ADDR_P2 },
379 };
380
381 reqs[0].value = (mac_addr[3] << 24)
382 | (mac_addr[2] << 16)
383 | (mac_addr[1] << 8)
384 | mac_addr[0];
385 reqs[1].value = (mac_addr[5] << 8)
386 | mac_addr[4];
387
388 dev_dbg_f(zd_chip_dev(chip),
389 "mac addr " MAC_FMT "\n", MAC_ARG(mac_addr));
390
391 mutex_lock(&chip->mutex);
392 r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
Daniel Drakee85d0912006-06-02 17:11:32 +0100393 mutex_unlock(&chip->mutex);
394 return r;
395}
396
397int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain)
398{
399 int r;
400 u32 value;
401
402 mutex_lock(&chip->mutex);
403 r = zd_ioread32_locked(chip, &value, E2P_SUBID);
404 mutex_unlock(&chip->mutex);
405 if (r)
406 return r;
407
408 *regdomain = value >> 16;
409 dev_dbg_f(zd_chip_dev(chip), "regdomain: %#04x\n", *regdomain);
410
411 return 0;
412}
413
414static int read_values(struct zd_chip *chip, u8 *values, size_t count,
415 zd_addr_t e2p_addr, u32 guard)
416{
417 int r;
418 int i;
419 u32 v;
420
421 ZD_ASSERT(mutex_is_locked(&chip->mutex));
422 for (i = 0;;) {
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000423 r = zd_ioread32_locked(chip, &v,
424 (zd_addr_t)((u16)e2p_addr+i/2));
Daniel Drakee85d0912006-06-02 17:11:32 +0100425 if (r)
426 return r;
427 v -= guard;
428 if (i+4 < count) {
429 values[i++] = v;
430 values[i++] = v >> 8;
431 values[i++] = v >> 16;
432 values[i++] = v >> 24;
433 continue;
434 }
435 for (;i < count; i++)
436 values[i] = v >> (8*(i%3));
437 return 0;
438 }
439}
440
441static int read_pwr_cal_values(struct zd_chip *chip)
442{
443 return read_values(chip, chip->pwr_cal_values,
444 E2P_CHANNEL_COUNT, E2P_PWR_CAL_VALUE1,
445 0);
446}
447
448static int read_pwr_int_values(struct zd_chip *chip)
449{
450 return read_values(chip, chip->pwr_int_values,
451 E2P_CHANNEL_COUNT, E2P_PWR_INT_VALUE1,
452 E2P_PWR_INT_GUARD);
453}
454
455static int read_ofdm_cal_values(struct zd_chip *chip)
456{
457 int r;
458 int i;
459 static const zd_addr_t addresses[] = {
460 E2P_36M_CAL_VALUE1,
461 E2P_48M_CAL_VALUE1,
462 E2P_54M_CAL_VALUE1,
463 };
464
465 for (i = 0; i < 3; i++) {
466 r = read_values(chip, chip->ofdm_cal_values[i],
467 E2P_CHANNEL_COUNT, addresses[i], 0);
468 if (r)
469 return r;
470 }
471 return 0;
472}
473
474static int read_cal_int_tables(struct zd_chip *chip)
475{
476 int r;
477
478 r = read_pwr_cal_values(chip);
479 if (r)
480 return r;
481 r = read_pwr_int_values(chip);
482 if (r)
483 return r;
484 r = read_ofdm_cal_values(chip);
485 if (r)
486 return r;
487 return 0;
488}
489
490/* phy means physical registers */
491int zd_chip_lock_phy_regs(struct zd_chip *chip)
492{
493 int r;
494 u32 tmp;
495
496 ZD_ASSERT(mutex_is_locked(&chip->mutex));
497 r = zd_ioread32_locked(chip, &tmp, CR_REG1);
498 if (r) {
499 dev_err(zd_chip_dev(chip), "error ioread32(CR_REG1): %d\n", r);
500 return r;
501 }
502
503 dev_dbg_f(zd_chip_dev(chip),
504 "CR_REG1: 0x%02x -> 0x%02x\n", tmp, tmp & ~UNLOCK_PHY_REGS);
505 tmp &= ~UNLOCK_PHY_REGS;
506
507 r = zd_iowrite32_locked(chip, tmp, CR_REG1);
508 if (r)
509 dev_err(zd_chip_dev(chip), "error iowrite32(CR_REG1): %d\n", r);
510 return r;
511}
512
513int zd_chip_unlock_phy_regs(struct zd_chip *chip)
514{
515 int r;
516 u32 tmp;
517
518 ZD_ASSERT(mutex_is_locked(&chip->mutex));
519 r = zd_ioread32_locked(chip, &tmp, CR_REG1);
520 if (r) {
521 dev_err(zd_chip_dev(chip),
522 "error ioread32(CR_REG1): %d\n", r);
523 return r;
524 }
525
526 dev_dbg_f(zd_chip_dev(chip),
527 "CR_REG1: 0x%02x -> 0x%02x\n", tmp, tmp | UNLOCK_PHY_REGS);
528 tmp |= UNLOCK_PHY_REGS;
529
530 r = zd_iowrite32_locked(chip, tmp, CR_REG1);
531 if (r)
532 dev_err(zd_chip_dev(chip), "error iowrite32(CR_REG1): %d\n", r);
533 return r;
534}
535
Daniel Drake92b3e2e2007-04-03 23:17:37 +0100536/* CR157 can be optionally patched by the EEPROM for original ZD1211 */
Daniel Drakee85d0912006-06-02 17:11:32 +0100537static int patch_cr157(struct zd_chip *chip)
538{
539 int r;
Daniel Drake92b3e2e2007-04-03 23:17:37 +0100540 u16 value;
Daniel Drakee85d0912006-06-02 17:11:32 +0100541
542 if (!chip->patch_cr157)
543 return 0;
544
Daniel Drake92b3e2e2007-04-03 23:17:37 +0100545 r = zd_ioread16_locked(chip, &value, E2P_PHY_REG);
Daniel Drakee85d0912006-06-02 17:11:32 +0100546 if (r)
547 return r;
548
549 dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value >> 8);
550 return zd_iowrite32_locked(chip, value >> 8, CR157);
551}
552
553/*
554 * 6M band edge can be optionally overwritten for certain RF's
555 * Vendor driver says: for FCC regulation, enabled per HWFeature 6M band edge
556 * bit (for AL2230, AL2230S)
557 */
Daniel Drake72018b222007-04-07 16:00:15 +0100558static int patch_6m_band_edge(struct zd_chip *chip, u8 channel)
559{
560 ZD_ASSERT(mutex_is_locked(&chip->mutex));
561 if (!chip->patch_6m_band_edge)
562 return 0;
563
564 return zd_rf_patch_6m_band_edge(&chip->rf, channel);
565}
566
567/* Generic implementation of 6M band edge patching, used by most RFs via
568 * zd_rf_generic_patch_6m() */
569int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel)
Daniel Drakee85d0912006-06-02 17:11:32 +0100570{
571 struct zd_ioreq16 ioreqs[] = {
572 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
573 { CR47, 0x1e },
574 };
575
Daniel Drakee85d0912006-06-02 17:11:32 +0100576 /* FIXME: Channel 11 is not the edge for all regulatory domains. */
577 if (channel == 1 || channel == 11)
578 ioreqs[0].value = 0x12;
579
580 dev_dbg_f(zd_chip_dev(chip), "patching for channel %d\n", channel);
581 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
582}
583
584static int zd1211_hw_reset_phy(struct zd_chip *chip)
585{
586 static const struct zd_ioreq16 ioreqs[] = {
587 { CR0, 0x0a }, { CR1, 0x06 }, { CR2, 0x26 },
588 { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xa0 },
589 { CR10, 0x81 }, { CR11, 0x00 }, { CR12, 0x7f },
590 { CR13, 0x8c }, { CR14, 0x80 }, { CR15, 0x3d },
591 { CR16, 0x20 }, { CR17, 0x1e }, { CR18, 0x0a },
592 { CR19, 0x48 }, { CR20, 0x0c }, { CR21, 0x0c },
593 { CR22, 0x23 }, { CR23, 0x90 }, { CR24, 0x14 },
594 { CR25, 0x40 }, { CR26, 0x10 }, { CR27, 0x19 },
595 { CR28, 0x7f }, { CR29, 0x80 }, { CR30, 0x4b },
596 { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 },
597 { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 },
598 { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },
599 { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 },
600 { CR43, 0x10 }, { CR44, 0x12 }, { CR46, 0xff },
601 { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b },
602 { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 },
603 { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 },
604 { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff },
605 { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 },
606 { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 },
607 { CR79, 0x68 }, { CR80, 0x64 }, { CR81, 0x64 },
608 { CR82, 0x00 }, { CR83, 0x00 }, { CR84, 0x00 },
609 { CR85, 0x02 }, { CR86, 0x00 }, { CR87, 0x00 },
610 { CR88, 0xff }, { CR89, 0xfc }, { CR90, 0x00 },
611 { CR91, 0x00 }, { CR92, 0x00 }, { CR93, 0x08 },
612 { CR94, 0x00 }, { CR95, 0x00 }, { CR96, 0xff },
613 { CR97, 0xe7 }, { CR98, 0x00 }, { CR99, 0x00 },
614 { CR100, 0x00 }, { CR101, 0xae }, { CR102, 0x02 },
615 { CR103, 0x00 }, { CR104, 0x03 }, { CR105, 0x65 },
616 { CR106, 0x04 }, { CR107, 0x00 }, { CR108, 0x0a },
617 { CR109, 0xaa }, { CR110, 0xaa }, { CR111, 0x25 },
618 { CR112, 0x25 }, { CR113, 0x00 }, { CR119, 0x1e },
619 { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
620 { },
621 { CR5, 0x00 }, { CR6, 0x00 }, { CR7, 0x00 },
622 { CR8, 0x00 }, { CR9, 0x20 }, { CR12, 0xf0 },
623 { CR20, 0x0e }, { CR21, 0x0e }, { CR27, 0x10 },
624 { CR44, 0x33 }, { CR47, 0x1E }, { CR83, 0x24 },
625 { CR84, 0x04 }, { CR85, 0x00 }, { CR86, 0x0C },
626 { CR87, 0x12 }, { CR88, 0x0C }, { CR89, 0x00 },
627 { CR90, 0x10 }, { CR91, 0x08 }, { CR93, 0x00 },
628 { CR94, 0x01 }, { CR95, 0x00 }, { CR96, 0x50 },
629 { CR97, 0x37 }, { CR98, 0x35 }, { CR101, 0x13 },
630 { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
631 { CR105, 0x12 }, { CR109, 0x27 }, { CR110, 0x27 },
632 { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
633 { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
634 { CR117, 0xfc }, { CR118, 0xfa }, { CR120, 0x4f },
Daniel Drakedc536a72007-04-03 23:17:10 +0100635 { CR125, 0xaa }, { CR127, 0x03 }, { CR128, 0x14 },
636 { CR129, 0x12 }, { CR130, 0x10 }, { CR131, 0x0C },
637 { CR136, 0xdf }, { CR137, 0x40 }, { CR138, 0xa0 },
638 { CR139, 0xb0 }, { CR140, 0x99 }, { CR141, 0x82 },
639 { CR142, 0x54 }, { CR143, 0x1c }, { CR144, 0x6c },
640 { CR147, 0x07 }, { CR148, 0x4c }, { CR149, 0x50 },
641 { CR150, 0x0e }, { CR151, 0x18 }, { CR160, 0xfe },
642 { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
643 { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
644 { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
645 { CR170, 0xba }, { CR171, 0xba },
Daniel Drakee85d0912006-06-02 17:11:32 +0100646 /* Note: CR204 must lead the CR203 */
647 { CR204, 0x7d },
648 { },
649 { CR203, 0x30 },
650 };
651
652 int r, t;
653
654 dev_dbg_f(zd_chip_dev(chip), "\n");
655
656 r = zd_chip_lock_phy_regs(chip);
657 if (r)
658 goto out;
659
660 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
661 if (r)
662 goto unlock;
663
664 r = patch_cr157(chip);
665unlock:
666 t = zd_chip_unlock_phy_regs(chip);
667 if (t && !r)
668 r = t;
669out:
670 return r;
671}
672
673static int zd1211b_hw_reset_phy(struct zd_chip *chip)
674{
675 static const struct zd_ioreq16 ioreqs[] = {
676 { CR0, 0x14 }, { CR1, 0x06 }, { CR2, 0x26 },
677 { CR3, 0x38 }, { CR4, 0x80 }, { CR9, 0xe0 },
678 { CR10, 0x81 },
679 /* power control { { CR11, 1 << 6 }, */
680 { CR11, 0x00 },
681 { CR12, 0xf0 }, { CR13, 0x8c }, { CR14, 0x80 },
682 { CR15, 0x3d }, { CR16, 0x20 }, { CR17, 0x1e },
683 { CR18, 0x0a }, { CR19, 0x48 },
684 { CR20, 0x10 }, /* Org:0x0E, ComTrend:RalLink AP */
685 { CR21, 0x0e }, { CR22, 0x23 }, { CR23, 0x90 },
686 { CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 },
687 { CR27, 0x10 }, { CR28, 0x7f }, { CR29, 0x80 },
Daniel Drakefe7215c2006-08-12 17:59:12 +0100688 { CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */
Daniel Drakee85d0912006-06-02 17:11:32 +0100689 { CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 },
690 { CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 },
691 { CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },
692 { CR40, 0x84 }, { CR41, 0x2a }, { CR42, 0x80 },
693 { CR43, 0x10 }, { CR44, 0x33 }, { CR46, 0xff },
694 { CR47, 0x1E }, { CR48, 0x26 }, { CR49, 0x5b },
695 { CR64, 0xd0 }, { CR65, 0x04 }, { CR66, 0x58 },
696 { CR67, 0xc9 }, { CR68, 0x88 }, { CR69, 0x41 },
697 { CR70, 0x23 }, { CR71, 0x10 }, { CR72, 0xff },
698 { CR73, 0x32 }, { CR74, 0x30 }, { CR75, 0x65 },
699 { CR76, 0x41 }, { CR77, 0x1b }, { CR78, 0x30 },
700 { CR79, 0xf0 }, { CR80, 0x64 }, { CR81, 0x64 },
701 { CR82, 0x00 }, { CR83, 0x24 }, { CR84, 0x04 },
702 { CR85, 0x00 }, { CR86, 0x0c }, { CR87, 0x12 },
703 { CR88, 0x0c }, { CR89, 0x00 }, { CR90, 0x58 },
704 { CR91, 0x04 }, { CR92, 0x00 }, { CR93, 0x00 },
705 { CR94, 0x01 },
706 { CR95, 0x20 }, /* ZD1211B */
707 { CR96, 0x50 }, { CR97, 0x37 }, { CR98, 0x35 },
708 { CR99, 0x00 }, { CR100, 0x01 }, { CR101, 0x13 },
709 { CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
710 { CR105, 0x12 }, { CR106, 0x04 }, { CR107, 0x00 },
711 { CR108, 0x0a }, { CR109, 0x27 }, { CR110, 0x27 },
712 { CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
713 { CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
714 { CR117, 0xfc }, { CR118, 0xfa }, { CR119, 0x1e },
715 { CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
716 { CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
717 { CR131, 0x0c }, { CR136, 0xdf }, { CR137, 0xa0 },
718 { CR138, 0xa8 }, { CR139, 0xb4 }, { CR140, 0x98 },
719 { CR141, 0x82 }, { CR142, 0x53 }, { CR143, 0x1c },
720 { CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x40 },
721 { CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */
722 { CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */
723 { CR151, 0x18 }, { CR159, 0x70 }, { CR160, 0xfe },
724 { CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
725 { CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
726 { CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
727 { CR170, 0xba }, { CR171, 0xba },
728 /* Note: CR204 must lead the CR203 */
729 { CR204, 0x7d },
730 {},
731 { CR203, 0x30 },
732 };
733
734 int r, t;
735
736 dev_dbg_f(zd_chip_dev(chip), "\n");
737
738 r = zd_chip_lock_phy_regs(chip);
739 if (r)
740 goto out;
741
742 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drakee85d0912006-06-02 17:11:32 +0100743 t = zd_chip_unlock_phy_regs(chip);
744 if (t && !r)
745 r = t;
746out:
747 return r;
748}
749
750static int hw_reset_phy(struct zd_chip *chip)
751{
Daniel Drake74553ae2007-07-01 18:22:32 +0100752 return zd_chip_is_zd1211b(chip) ? zd1211b_hw_reset_phy(chip) :
Daniel Drakee85d0912006-06-02 17:11:32 +0100753 zd1211_hw_reset_phy(chip);
754}
755
756static int zd1211_hw_init_hmac(struct zd_chip *chip)
757{
758 static const struct zd_ioreq32 ioreqs[] = {
Daniel Drakee85d0912006-06-02 17:11:32 +0100759 { CR_ZD1211_RETRY_MAX, 0x2 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100760 { CR_RX_THRESHOLD, 0x000c0640 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100761 };
762
Daniel Drakee85d0912006-06-02 17:11:32 +0100763 dev_dbg_f(zd_chip_dev(chip), "\n");
764 ZD_ASSERT(mutex_is_locked(&chip->mutex));
Daniel Drake34c4491262006-12-12 01:25:13 +0000765 return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drakee85d0912006-06-02 17:11:32 +0100766}
767
768static int zd1211b_hw_init_hmac(struct zd_chip *chip)
769{
770 static const struct zd_ioreq32 ioreqs[] = {
Daniel Drakee85d0912006-06-02 17:11:32 +0100771 { CR_ZD1211B_RETRY_MAX, 0x02020202 },
772 { CR_ZD1211B_TX_PWR_CTL4, 0x007f003f },
773 { CR_ZD1211B_TX_PWR_CTL3, 0x007f003f },
774 { CR_ZD1211B_TX_PWR_CTL2, 0x003f001f },
775 { CR_ZD1211B_TX_PWR_CTL1, 0x001f000f },
776 { CR_ZD1211B_AIFS_CTL1, 0x00280028 },
777 { CR_ZD1211B_AIFS_CTL2, 0x008C003C },
778 { CR_ZD1211B_TXOP, 0x01800824 },
Daniel Drake34c4491262006-12-12 01:25:13 +0000779 { CR_RX_THRESHOLD, 0x000c0eff, },
780 };
781
782 dev_dbg_f(zd_chip_dev(chip), "\n");
783 ZD_ASSERT(mutex_is_locked(&chip->mutex));
784 return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
785}
786
787static int hw_init_hmac(struct zd_chip *chip)
788{
789 int r;
790 static const struct zd_ioreq32 ioreqs[] = {
791 { CR_ACK_TIMEOUT_EXT, 0x20 },
792 { CR_ADDA_MBIAS_WARMTIME, 0x30000808 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100793 { CR_SNIFFER_ON, 0 },
Ulrich Kunitzfde627b2006-08-01 23:43:35 +0200794 { CR_RX_FILTER, STA_RX_FILTER },
Daniel Drakee85d0912006-06-02 17:11:32 +0100795 { CR_GROUP_HASH_P1, 0x00 },
796 { CR_GROUP_HASH_P2, 0x80000000 },
797 { CR_REG1, 0xa4 },
798 { CR_ADDA_PWR_DWN, 0x7f },
799 { CR_BCN_PLCP_CFG, 0x00f00401 },
800 { CR_PHY_DELAY, 0x00 },
801 { CR_ACK_TIMEOUT_EXT, 0x80 },
802 { CR_ADDA_PWR_DWN, 0x00 },
803 { CR_ACK_TIME_80211, 0x100 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100804 { CR_RX_PE_DELAY, 0x70 },
805 { CR_PS_CTRL, 0x10000000 },
806 { CR_RTS_CTS_RATE, 0x02030203 },
Daniel Drakee85d0912006-06-02 17:11:32 +0100807 { CR_AFTER_PNP, 0x1 },
808 { CR_WEP_PROTECT, 0x114 },
Daniel Drake34c4491262006-12-12 01:25:13 +0000809 { CR_IFS_VALUE, IFS_VALUE_DEFAULT },
Daniel Drakee85d0912006-06-02 17:11:32 +0100810 };
811
Daniel Drakee85d0912006-06-02 17:11:32 +0100812 ZD_ASSERT(mutex_is_locked(&chip->mutex));
813 r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drake34c4491262006-12-12 01:25:13 +0000814 if (r)
815 return r;
Daniel Drakee85d0912006-06-02 17:11:32 +0100816
Daniel Drake74553ae2007-07-01 18:22:32 +0100817 return zd_chip_is_zd1211b(chip) ?
Daniel Drakee85d0912006-06-02 17:11:32 +0100818 zd1211b_hw_init_hmac(chip) : zd1211_hw_init_hmac(chip);
819}
820
821struct aw_pt_bi {
822 u32 atim_wnd_period;
823 u32 pre_tbtt;
824 u32 beacon_interval;
825};
826
827static int get_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
828{
829 int r;
830 static const zd_addr_t aw_pt_bi_addr[] =
831 { CR_ATIM_WND_PERIOD, CR_PRE_TBTT, CR_BCN_INTERVAL };
832 u32 values[3];
833
834 r = zd_ioread32v_locked(chip, values, (const zd_addr_t *)aw_pt_bi_addr,
835 ARRAY_SIZE(aw_pt_bi_addr));
836 if (r) {
837 memset(s, 0, sizeof(*s));
838 return r;
839 }
840
841 s->atim_wnd_period = values[0];
842 s->pre_tbtt = values[1];
843 s->beacon_interval = values[2];
844 dev_dbg_f(zd_chip_dev(chip), "aw %u pt %u bi %u\n",
845 s->atim_wnd_period, s->pre_tbtt, s->beacon_interval);
846 return 0;
847}
848
849static int set_aw_pt_bi(struct zd_chip *chip, struct aw_pt_bi *s)
850{
851 struct zd_ioreq32 reqs[3];
852
853 if (s->beacon_interval <= 5)
854 s->beacon_interval = 5;
855 if (s->pre_tbtt < 4 || s->pre_tbtt >= s->beacon_interval)
856 s->pre_tbtt = s->beacon_interval - 1;
857 if (s->atim_wnd_period >= s->pre_tbtt)
858 s->atim_wnd_period = s->pre_tbtt - 1;
859
860 reqs[0].addr = CR_ATIM_WND_PERIOD;
861 reqs[0].value = s->atim_wnd_period;
862 reqs[1].addr = CR_PRE_TBTT;
863 reqs[1].value = s->pre_tbtt;
864 reqs[2].addr = CR_BCN_INTERVAL;
865 reqs[2].value = s->beacon_interval;
866
867 dev_dbg_f(zd_chip_dev(chip),
868 "aw %u pt %u bi %u\n", s->atim_wnd_period, s->pre_tbtt,
869 s->beacon_interval);
870 return zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
871}
872
873
874static int set_beacon_interval(struct zd_chip *chip, u32 interval)
875{
876 int r;
877 struct aw_pt_bi s;
878
879 ZD_ASSERT(mutex_is_locked(&chip->mutex));
880 r = get_aw_pt_bi(chip, &s);
881 if (r)
882 return r;
883 s.beacon_interval = interval;
884 return set_aw_pt_bi(chip, &s);
885}
886
887int zd_set_beacon_interval(struct zd_chip *chip, u32 interval)
888{
889 int r;
890
891 mutex_lock(&chip->mutex);
892 r = set_beacon_interval(chip, interval);
893 mutex_unlock(&chip->mutex);
894 return r;
895}
896
897static int hw_init(struct zd_chip *chip)
898{
899 int r;
900
901 dev_dbg_f(zd_chip_dev(chip), "\n");
902 ZD_ASSERT(mutex_is_locked(&chip->mutex));
903 r = hw_reset_phy(chip);
904 if (r)
905 return r;
906
907 r = hw_init_hmac(chip);
908 if (r)
909 return r;
Daniel Drake98227a92006-08-12 17:59:22 +0100910
Daniel Drake98227a92006-08-12 17:59:22 +0100911 return set_beacon_interval(chip, 100);
Daniel Drakee85d0912006-06-02 17:11:32 +0100912}
913
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000914static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset)
915{
916 return (zd_addr_t)((u16)chip->fw_regs_base + offset);
917}
918
Daniel Drakee85d0912006-06-02 17:11:32 +0100919#ifdef DEBUG
920static int dump_cr(struct zd_chip *chip, const zd_addr_t addr,
921 const char *addr_string)
922{
923 int r;
924 u32 value;
925
926 r = zd_ioread32_locked(chip, &value, addr);
927 if (r) {
928 dev_dbg_f(zd_chip_dev(chip),
929 "error reading %s. Error number %d\n", addr_string, r);
930 return r;
931 }
932
933 dev_dbg_f(zd_chip_dev(chip), "%s %#010x\n",
934 addr_string, (unsigned int)value);
935 return 0;
936}
937
938static int test_init(struct zd_chip *chip)
939{
940 int r;
941
942 r = dump_cr(chip, CR_AFTER_PNP, "CR_AFTER_PNP");
943 if (r)
944 return r;
945 r = dump_cr(chip, CR_GPI_EN, "CR_GPI_EN");
946 if (r)
947 return r;
948 return dump_cr(chip, CR_INTERRUPT, "CR_INTERRUPT");
949}
950
951static void dump_fw_registers(struct zd_chip *chip)
952{
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000953 const zd_addr_t addr[4] = {
954 fw_reg_addr(chip, FW_REG_FIRMWARE_VER),
955 fw_reg_addr(chip, FW_REG_USB_SPEED),
956 fw_reg_addr(chip, FW_REG_FIX_TX_RATE),
957 fw_reg_addr(chip, FW_REG_LED_LINK_STATUS),
Daniel Drakee85d0912006-06-02 17:11:32 +0100958 };
959
960 int r;
961 u16 values[4];
962
963 r = zd_ioread16v_locked(chip, values, (const zd_addr_t*)addr,
964 ARRAY_SIZE(addr));
965 if (r) {
966 dev_dbg_f(zd_chip_dev(chip), "error %d zd_ioread16v_locked\n",
967 r);
968 return;
969 }
970
971 dev_dbg_f(zd_chip_dev(chip), "FW_FIRMWARE_VER %#06hx\n", values[0]);
972 dev_dbg_f(zd_chip_dev(chip), "FW_USB_SPEED %#06hx\n", values[1]);
973 dev_dbg_f(zd_chip_dev(chip), "FW_FIX_TX_RATE %#06hx\n", values[2]);
974 dev_dbg_f(zd_chip_dev(chip), "FW_LINK_STATUS %#06hx\n", values[3]);
975}
976#endif /* DEBUG */
977
978static int print_fw_version(struct zd_chip *chip)
979{
980 int r;
981 u16 version;
982
Daniel Drake0ce34bc2006-12-12 01:26:11 +0000983 r = zd_ioread16_locked(chip, &version,
984 fw_reg_addr(chip, FW_REG_FIRMWARE_VER));
Daniel Drakee85d0912006-06-02 17:11:32 +0100985 if (r)
986 return r;
987
988 dev_info(zd_chip_dev(chip),"firmware version %04hx\n", version);
989 return 0;
990}
991
992static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std)
993{
994 u32 rates;
995 ZD_ASSERT(mutex_is_locked(&chip->mutex));
996 /* This sets the mandatory rates, which only depend from the standard
997 * that the device is supporting. Until further notice we should try
998 * to support 802.11g also for full speed USB.
999 */
1000 switch (std) {
1001 case IEEE80211B:
1002 rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M;
1003 break;
1004 case IEEE80211G:
1005 rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M|
1006 CR_RATE_6M|CR_RATE_12M|CR_RATE_24M;
1007 break;
1008 default:
1009 return -EINVAL;
1010 }
1011 return zd_iowrite32_locked(chip, rates, CR_MANDATORY_RATE_TBL);
1012}
1013
Daniel Drakeb1382ed2006-11-22 00:06:48 +00001014int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip,
1015 u8 rts_rate, int preamble)
1016{
1017 int rts_mod = ZD_RX_CCK;
1018 u32 value = 0;
1019
1020 /* Modulation bit */
1021 if (ZD_CS_TYPE(rts_rate) == ZD_CS_OFDM)
1022 rts_mod = ZD_RX_OFDM;
1023
1024 dev_dbg_f(zd_chip_dev(chip), "rts_rate=%x preamble=%x\n",
1025 rts_rate, preamble);
1026
1027 value |= rts_rate << RTSCTS_SH_RTS_RATE;
1028 value |= rts_mod << RTSCTS_SH_RTS_MOD_TYPE;
1029 value |= preamble << RTSCTS_SH_RTS_PMB_TYPE;
1030 value |= preamble << RTSCTS_SH_CTS_PMB_TYPE;
1031
1032 /* We always send 11M self-CTS messages, like the vendor driver. */
1033 value |= ZD_CCK_RATE_11M << RTSCTS_SH_CTS_RATE;
1034 value |= ZD_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE;
1035
1036 return zd_iowrite32_locked(chip, value, CR_RTS_CTS_RATE);
1037}
1038
Daniel Drakee85d0912006-06-02 17:11:32 +01001039int zd_chip_enable_hwint(struct zd_chip *chip)
1040{
1041 int r;
1042
1043 mutex_lock(&chip->mutex);
1044 r = zd_iowrite32_locked(chip, HWINT_ENABLED, CR_INTERRUPT);
1045 mutex_unlock(&chip->mutex);
1046 return r;
1047}
1048
1049static int disable_hwint(struct zd_chip *chip)
1050{
1051 return zd_iowrite32_locked(chip, HWINT_DISABLED, CR_INTERRUPT);
1052}
1053
1054int zd_chip_disable_hwint(struct zd_chip *chip)
1055{
1056 int r;
1057
1058 mutex_lock(&chip->mutex);
1059 r = disable_hwint(chip);
1060 mutex_unlock(&chip->mutex);
1061 return r;
1062}
1063
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001064static int read_fw_regs_offset(struct zd_chip *chip)
1065{
1066 int r;
1067
1068 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1069 r = zd_ioread16_locked(chip, (u16*)&chip->fw_regs_base,
1070 FWRAW_REGS_ADDR);
1071 if (r)
1072 return r;
1073 dev_dbg_f(zd_chip_dev(chip), "fw_regs_base: %#06hx\n",
1074 (u16)chip->fw_regs_base);
1075
1076 return 0;
1077}
1078
Daniel Drake74553ae2007-07-01 18:22:32 +01001079/* Read mac address using pre-firmware interface */
1080int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr)
1081{
1082 dev_dbg_f(zd_chip_dev(chip), "\n");
1083 return zd_usb_read_fw(&chip->usb, E2P_MAC_ADDR_P1, addr,
1084 ETH_ALEN);
1085}
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001086
Daniel Drake74553ae2007-07-01 18:22:32 +01001087int zd_chip_init_hw(struct zd_chip *chip)
Daniel Drakee85d0912006-06-02 17:11:32 +01001088{
1089 int r;
1090 u8 rf_type;
1091
1092 dev_dbg_f(zd_chip_dev(chip), "\n");
1093
1094 mutex_lock(&chip->mutex);
Daniel Drakee85d0912006-06-02 17:11:32 +01001095
1096#ifdef DEBUG
1097 r = test_init(chip);
1098 if (r)
1099 goto out;
1100#endif
1101 r = zd_iowrite32_locked(chip, 1, CR_AFTER_PNP);
1102 if (r)
1103 goto out;
1104
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001105 r = read_fw_regs_offset(chip);
Daniel Drakee85d0912006-06-02 17:11:32 +01001106 if (r)
1107 goto out;
1108
1109 /* GPI is always disabled, also in the other driver.
1110 */
1111 r = zd_iowrite32_locked(chip, 0, CR_GPI_EN);
1112 if (r)
1113 goto out;
1114 r = zd_iowrite32_locked(chip, CWIN_SIZE, CR_CWMIN_CWMAX);
1115 if (r)
1116 goto out;
1117 /* Currently we support IEEE 802.11g for full and high speed USB.
1118 * It might be discussed, whether we should suppport pure b mode for
1119 * full speed USB.
1120 */
1121 r = set_mandatory_rates(chip, IEEE80211G);
1122 if (r)
1123 goto out;
1124 /* Disabling interrupts is certainly a smart thing here.
1125 */
1126 r = disable_hwint(chip);
1127 if (r)
1128 goto out;
1129 r = read_pod(chip, &rf_type);
1130 if (r)
1131 goto out;
1132 r = hw_init(chip);
1133 if (r)
1134 goto out;
1135 r = zd_rf_init_hw(&chip->rf, rf_type);
1136 if (r)
1137 goto out;
1138
1139 r = print_fw_version(chip);
1140 if (r)
1141 goto out;
1142
1143#ifdef DEBUG
1144 dump_fw_registers(chip);
1145 r = test_init(chip);
1146 if (r)
1147 goto out;
1148#endif /* DEBUG */
1149
Daniel Drakee85d0912006-06-02 17:11:32 +01001150 r = read_cal_int_tables(chip);
1151 if (r)
1152 goto out;
1153
1154 print_id(chip);
1155out:
1156 mutex_unlock(&chip->mutex);
1157 return r;
1158}
1159
1160static int update_pwr_int(struct zd_chip *chip, u8 channel)
1161{
1162 u8 value = chip->pwr_int_values[channel - 1];
1163 dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_int %#04x\n",
1164 channel, value);
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001165 return zd_iowrite16_locked(chip, value, CR31);
Daniel Drakee85d0912006-06-02 17:11:32 +01001166}
1167
1168static int update_pwr_cal(struct zd_chip *chip, u8 channel)
1169{
1170 u8 value = chip->pwr_cal_values[channel-1];
1171 dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_cal %#04x\n",
1172 channel, value);
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001173 return zd_iowrite16_locked(chip, value, CR68);
Daniel Drakee85d0912006-06-02 17:11:32 +01001174}
1175
1176static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
1177{
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001178 struct zd_ioreq16 ioreqs[3];
Daniel Drakee85d0912006-06-02 17:11:32 +01001179
1180 ioreqs[0].addr = CR67;
1181 ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1];
1182 ioreqs[1].addr = CR66;
1183 ioreqs[1].value = chip->ofdm_cal_values[OFDM_48M_INDEX][channel-1];
1184 ioreqs[2].addr = CR65;
1185 ioreqs[2].value = chip->ofdm_cal_values[OFDM_54M_INDEX][channel-1];
1186
1187 dev_dbg_f(zd_chip_dev(chip),
1188 "channel %d ofdm_cal 36M %#04x 48M %#04x 54M %#04x\n",
1189 channel, ioreqs[0].value, ioreqs[1].value, ioreqs[2].value);
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001190 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drakee85d0912006-06-02 17:11:32 +01001191}
1192
1193static int update_channel_integration_and_calibration(struct zd_chip *chip,
1194 u8 channel)
1195{
1196 int r;
1197
Daniel Drake9c8fc712007-05-24 01:06:41 +01001198 if (!zd_rf_should_update_pwr_int(&chip->rf))
1199 return 0;
1200
Daniel Drakee85d0912006-06-02 17:11:32 +01001201 r = update_pwr_int(chip, channel);
1202 if (r)
1203 return r;
Daniel Drake74553ae2007-07-01 18:22:32 +01001204 if (zd_chip_is_zd1211b(chip)) {
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001205 static const struct zd_ioreq16 ioreqs[] = {
Daniel Drakee85d0912006-06-02 17:11:32 +01001206 { CR69, 0x28 },
1207 {},
1208 { CR69, 0x2a },
1209 };
1210
1211 r = update_ofdm_cal(chip, channel);
1212 if (r)
1213 return r;
1214 r = update_pwr_cal(chip, channel);
1215 if (r)
1216 return r;
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001217 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
Daniel Drakee85d0912006-06-02 17:11:32 +01001218 if (r)
1219 return r;
1220 }
1221
1222 return 0;
1223}
1224
1225/* The CCK baseband gain can be optionally patched by the EEPROM */
1226static int patch_cck_gain(struct zd_chip *chip)
1227{
1228 int r;
1229 u32 value;
1230
Daniel Drakeaaf83d42007-05-24 01:07:15 +01001231 if (!chip->patch_cck_gain || !zd_rf_should_patch_cck_gain(&chip->rf))
Daniel Drakee85d0912006-06-02 17:11:32 +01001232 return 0;
1233
1234 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1235 r = zd_ioread32_locked(chip, &value, E2P_PHY_REG);
1236 if (r)
1237 return r;
1238 dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff);
Ulrich Kunitzcbb5e6b2006-09-13 02:41:02 +01001239 return zd_iowrite16_locked(chip, value & 0xff, CR47);
Daniel Drakee85d0912006-06-02 17:11:32 +01001240}
1241
1242int zd_chip_set_channel(struct zd_chip *chip, u8 channel)
1243{
1244 int r, t;
1245
1246 mutex_lock(&chip->mutex);
1247 r = zd_chip_lock_phy_regs(chip);
1248 if (r)
1249 goto out;
1250 r = zd_rf_set_channel(&chip->rf, channel);
1251 if (r)
1252 goto unlock;
1253 r = update_channel_integration_and_calibration(chip, channel);
1254 if (r)
1255 goto unlock;
1256 r = patch_cck_gain(chip);
1257 if (r)
1258 goto unlock;
1259 r = patch_6m_band_edge(chip, channel);
1260 if (r)
1261 goto unlock;
1262 r = zd_iowrite32_locked(chip, 0, CR_CONFIG_PHILIPS);
1263unlock:
1264 t = zd_chip_unlock_phy_regs(chip);
1265 if (t && !r)
1266 r = t;
1267out:
1268 mutex_unlock(&chip->mutex);
1269 return r;
1270}
1271
1272u8 zd_chip_get_channel(struct zd_chip *chip)
1273{
1274 u8 channel;
1275
1276 mutex_lock(&chip->mutex);
1277 channel = chip->rf.channel;
1278 mutex_unlock(&chip->mutex);
1279 return channel;
1280}
1281
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001282int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
Daniel Drakee85d0912006-06-02 17:11:32 +01001283{
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001284 const zd_addr_t a[] = {
1285 fw_reg_addr(chip, FW_REG_LED_LINK_STATUS),
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001286 CR_LED,
1287 };
Daniel Drakee85d0912006-06-02 17:11:32 +01001288
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001289 int r;
1290 u16 v[ARRAY_SIZE(a)];
1291 struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = {
Daniel Drake0ce34bc2006-12-12 01:26:11 +00001292 [0] = { fw_reg_addr(chip, FW_REG_LED_LINK_STATUS) },
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001293 [1] = { CR_LED },
1294 };
1295 u16 other_led;
Daniel Drakee85d0912006-06-02 17:11:32 +01001296
Daniel Drakee85d0912006-06-02 17:11:32 +01001297 mutex_lock(&chip->mutex);
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001298 r = zd_ioread16v_locked(chip, v, (const zd_addr_t *)a, ARRAY_SIZE(a));
Daniel Drakee85d0912006-06-02 17:11:32 +01001299 if (r)
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001300 goto out;
1301
1302 other_led = chip->link_led == LED1 ? LED2 : LED1;
1303
Daniel Drakee85d0912006-06-02 17:11:32 +01001304 switch (status) {
Daniel Drakee85d0912006-06-02 17:11:32 +01001305 case LED_OFF:
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001306 ioreqs[0].value = FW_LINK_OFF;
1307 ioreqs[1].value = v[1] & ~(LED1|LED2);
Daniel Drakee85d0912006-06-02 17:11:32 +01001308 break;
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001309 case LED_SCANNING:
1310 ioreqs[0].value = FW_LINK_OFF;
1311 ioreqs[1].value = v[1] & ~other_led;
1312 if (get_seconds() % 3 == 0) {
1313 ioreqs[1].value &= ~chip->link_led;
1314 } else {
1315 ioreqs[1].value |= chip->link_led;
1316 }
Daniel Drakee85d0912006-06-02 17:11:32 +01001317 break;
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001318 case LED_ASSOCIATED:
1319 ioreqs[0].value = FW_LINK_TX;
1320 ioreqs[1].value = v[1] & ~other_led;
1321 ioreqs[1].value |= chip->link_led;
Daniel Drakee85d0912006-06-02 17:11:32 +01001322 break;
1323 default:
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001324 r = -EINVAL;
Daniel Drakee85d0912006-06-02 17:11:32 +01001325 goto out;
1326 }
Ulrich Kunitz583afd12006-09-13 02:42:38 +01001327
1328 if (v[0] != ioreqs[0].value || v[1] != ioreqs[1].value) {
1329 r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
1330 if (r)
1331 goto out;
1332 }
1333 r = 0;
Daniel Drakee85d0912006-06-02 17:11:32 +01001334out:
1335 mutex_unlock(&chip->mutex);
1336 return r;
1337}
1338
Daniel Drakeb1382ed2006-11-22 00:06:48 +00001339int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates)
Daniel Drakee85d0912006-06-02 17:11:32 +01001340{
Daniel Drakeb1382ed2006-11-22 00:06:48 +00001341 ZD_ASSERT((cr_rates & ~(CR_RATES_80211B | CR_RATES_80211G)) == 0);
1342 dev_dbg_f(zd_chip_dev(chip), "%x\n", cr_rates);
Daniel Drakee85d0912006-06-02 17:11:32 +01001343
Daniel Drakeb1382ed2006-11-22 00:06:48 +00001344 return zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL);
Daniel Drakee85d0912006-06-02 17:11:32 +01001345}
1346
1347static int ofdm_qual_db(u8 status_quality, u8 rate, unsigned int size)
1348{
1349 static const u16 constants[] = {
1350 715, 655, 585, 540, 470, 410, 360, 315,
1351 270, 235, 205, 175, 150, 125, 105, 85,
1352 65, 50, 40, 25, 15
1353 };
1354
1355 int i;
1356 u32 x;
1357
1358 /* It seems that their quality parameter is somehow per signal
1359 * and is now transferred per bit.
1360 */
1361 switch (rate) {
1362 case ZD_OFDM_RATE_6M:
1363 case ZD_OFDM_RATE_12M:
1364 case ZD_OFDM_RATE_24M:
1365 size *= 2;
1366 break;
1367 case ZD_OFDM_RATE_9M:
1368 case ZD_OFDM_RATE_18M:
1369 case ZD_OFDM_RATE_36M:
1370 case ZD_OFDM_RATE_54M:
1371 size *= 4;
1372 size /= 3;
1373 break;
1374 case ZD_OFDM_RATE_48M:
1375 size *= 3;
1376 size /= 2;
1377 break;
1378 default:
1379 return -EINVAL;
1380 }
1381
1382 x = (10000 * status_quality)/size;
1383 for (i = 0; i < ARRAY_SIZE(constants); i++) {
1384 if (x > constants[i])
1385 break;
1386 }
1387
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001388 switch (rate) {
1389 case ZD_OFDM_RATE_6M:
1390 case ZD_OFDM_RATE_9M:
1391 i += 3;
1392 break;
1393 case ZD_OFDM_RATE_12M:
1394 case ZD_OFDM_RATE_18M:
1395 i += 5;
1396 break;
1397 case ZD_OFDM_RATE_24M:
1398 case ZD_OFDM_RATE_36M:
1399 i += 9;
1400 break;
1401 case ZD_OFDM_RATE_48M:
1402 case ZD_OFDM_RATE_54M:
1403 i += 15;
1404 break;
1405 default:
1406 return -EINVAL;
1407 }
1408
Daniel Drakee85d0912006-06-02 17:11:32 +01001409 return i;
1410}
1411
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001412static int ofdm_qual_percent(u8 status_quality, u8 rate, unsigned int size)
1413{
1414 int r;
1415
1416 r = ofdm_qual_db(status_quality, rate, size);
1417 ZD_ASSERT(r >= 0);
1418 if (r < 0)
1419 r = 0;
1420
1421 r = (r * 100)/29;
1422 return r <= 100 ? r : 100;
1423}
1424
Daniel Drakee85d0912006-06-02 17:11:32 +01001425static unsigned int log10times100(unsigned int x)
1426{
1427 static const u8 log10[] = {
1428 0,
1429 0, 30, 47, 60, 69, 77, 84, 90, 95, 100,
1430 104, 107, 111, 114, 117, 120, 123, 125, 127, 130,
1431 132, 134, 136, 138, 139, 141, 143, 144, 146, 147,
1432 149, 150, 151, 153, 154, 155, 156, 157, 159, 160,
1433 161, 162, 163, 164, 165, 166, 167, 168, 169, 169,
1434 170, 171, 172, 173, 174, 174, 175, 176, 177, 177,
1435 178, 179, 179, 180, 181, 181, 182, 183, 183, 184,
1436 185, 185, 186, 186, 187, 188, 188, 189, 189, 190,
1437 190, 191, 191, 192, 192, 193, 193, 194, 194, 195,
1438 195, 196, 196, 197, 197, 198, 198, 199, 199, 200,
1439 200, 200, 201, 201, 202, 202, 202, 203, 203, 204,
1440 204, 204, 205, 205, 206, 206, 206, 207, 207, 207,
1441 208, 208, 208, 209, 209, 210, 210, 210, 211, 211,
1442 211, 212, 212, 212, 213, 213, 213, 213, 214, 214,
1443 214, 215, 215, 215, 216, 216, 216, 217, 217, 217,
1444 217, 218, 218, 218, 219, 219, 219, 219, 220, 220,
1445 220, 220, 221, 221, 221, 222, 222, 222, 222, 223,
1446 223, 223, 223, 224, 224, 224, 224,
1447 };
1448
1449 return x < ARRAY_SIZE(log10) ? log10[x] : 225;
1450}
1451
1452enum {
1453 MAX_CCK_EVM_DB = 45,
1454};
1455
1456static int cck_evm_db(u8 status_quality)
1457{
1458 return (20 * log10times100(status_quality)) / 100;
1459}
1460
1461static int cck_snr_db(u8 status_quality)
1462{
1463 int r = MAX_CCK_EVM_DB - cck_evm_db(status_quality);
1464 ZD_ASSERT(r >= 0);
1465 return r;
1466}
1467
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001468static int cck_qual_percent(u8 status_quality)
Daniel Drakee85d0912006-06-02 17:11:32 +01001469{
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001470 int r;
1471
1472 r = cck_snr_db(status_quality);
1473 r = (100*r)/17;
1474 return r <= 100 ? r : 100;
Daniel Drakee85d0912006-06-02 17:11:32 +01001475}
1476
1477u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size,
1478 const struct rx_status *status)
1479{
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001480 return (status->frame_status&ZD_RX_OFDM) ?
1481 ofdm_qual_percent(status->signal_quality_ofdm,
1482 zd_ofdm_plcp_header_rate(rx_frame),
1483 size) :
1484 cck_qual_percent(status->signal_quality_cck);
Daniel Drakee85d0912006-06-02 17:11:32 +01001485}
1486
1487u8 zd_rx_strength_percent(u8 rssi)
1488{
Ulrich Kunitzdb888ae2006-08-29 23:50:29 +01001489 int r = (rssi*100) / 41;
Daniel Drakee85d0912006-06-02 17:11:32 +01001490 if (r > 100)
1491 r = 100;
1492 return (u8) r;
1493}
1494
1495u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status)
1496{
1497 static const u16 ofdm_rates[] = {
1498 [ZD_OFDM_RATE_6M] = 60,
1499 [ZD_OFDM_RATE_9M] = 90,
1500 [ZD_OFDM_RATE_12M] = 120,
1501 [ZD_OFDM_RATE_18M] = 180,
1502 [ZD_OFDM_RATE_24M] = 240,
1503 [ZD_OFDM_RATE_36M] = 360,
1504 [ZD_OFDM_RATE_48M] = 480,
1505 [ZD_OFDM_RATE_54M] = 540,
1506 };
1507 u16 rate;
1508 if (status->frame_status & ZD_RX_OFDM) {
1509 u8 ofdm_rate = zd_ofdm_plcp_header_rate(rx_frame);
1510 rate = ofdm_rates[ofdm_rate & 0xf];
1511 } else {
1512 u8 cck_rate = zd_cck_plcp_header_rate(rx_frame);
1513 switch (cck_rate) {
1514 case ZD_CCK_SIGNAL_1M:
1515 rate = 10;
1516 break;
1517 case ZD_CCK_SIGNAL_2M:
1518 rate = 20;
1519 break;
1520 case ZD_CCK_SIGNAL_5M5:
1521 rate = 55;
1522 break;
1523 case ZD_CCK_SIGNAL_11M:
1524 rate = 110;
1525 break;
1526 default:
1527 rate = 0;
1528 }
1529 }
1530
1531 return rate;
1532}
1533
1534int zd_chip_switch_radio_on(struct zd_chip *chip)
1535{
1536 int r;
1537
1538 mutex_lock(&chip->mutex);
1539 r = zd_switch_radio_on(&chip->rf);
1540 mutex_unlock(&chip->mutex);
1541 return r;
1542}
1543
1544int zd_chip_switch_radio_off(struct zd_chip *chip)
1545{
1546 int r;
1547
1548 mutex_lock(&chip->mutex);
1549 r = zd_switch_radio_off(&chip->rf);
1550 mutex_unlock(&chip->mutex);
1551 return r;
1552}
1553
1554int zd_chip_enable_int(struct zd_chip *chip)
1555{
1556 int r;
1557
1558 mutex_lock(&chip->mutex);
1559 r = zd_usb_enable_int(&chip->usb);
1560 mutex_unlock(&chip->mutex);
1561 return r;
1562}
1563
1564void zd_chip_disable_int(struct zd_chip *chip)
1565{
1566 mutex_lock(&chip->mutex);
1567 zd_usb_disable_int(&chip->usb);
1568 mutex_unlock(&chip->mutex);
1569}
1570
1571int zd_chip_enable_rx(struct zd_chip *chip)
1572{
1573 int r;
1574
1575 mutex_lock(&chip->mutex);
1576 r = zd_usb_enable_rx(&chip->usb);
1577 mutex_unlock(&chip->mutex);
1578 return r;
1579}
1580
1581void zd_chip_disable_rx(struct zd_chip *chip)
1582{
1583 mutex_lock(&chip->mutex);
1584 zd_usb_disable_rx(&chip->usb);
1585 mutex_unlock(&chip->mutex);
1586}
1587
1588int zd_rfwritev_locked(struct zd_chip *chip,
1589 const u32* values, unsigned int count, u8 bits)
1590{
1591 int r;
1592 unsigned int i;
1593
1594 for (i = 0; i < count; i++) {
1595 r = zd_rfwrite_locked(chip, values[i], bits);
1596 if (r)
1597 return r;
1598 }
1599
1600 return 0;
1601}
Daniel Drake20fe2172006-08-12 17:59:42 +01001602
1603/*
1604 * We can optionally program the RF directly through CR regs, if supported by
1605 * the hardware. This is much faster than the older method.
1606 */
Daniel Drakeec62bd92006-08-12 17:59:46 +01001607int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
Daniel Drake20fe2172006-08-12 17:59:42 +01001608{
1609 struct zd_ioreq16 ioreqs[] = {
1610 { CR244, (value >> 16) & 0xff },
1611 { CR243, (value >> 8) & 0xff },
1612 { CR242, value & 0xff },
1613 };
1614 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1615 return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
1616}
1617
1618int zd_rfwritev_cr_locked(struct zd_chip *chip,
1619 const u32 *values, unsigned int count)
1620{
1621 int r;
1622 unsigned int i;
1623
1624 for (i = 0; i < count; i++) {
1625 r = zd_rfwrite_cr_locked(chip, values[i]);
1626 if (r)
1627 return r;
1628 }
1629
1630 return 0;
1631}
Ulrich Kunitz9cdac962006-12-01 00:58:07 +00001632
1633int zd_chip_set_multicast_hash(struct zd_chip *chip,
1634 struct zd_mc_hash *hash)
1635{
1636 struct zd_ioreq32 ioreqs[] = {
1637 { CR_GROUP_HASH_P1, hash->low },
1638 { CR_GROUP_HASH_P2, hash->high },
1639 };
1640
1641 dev_dbg_f(zd_chip_dev(chip), "hash l 0x%08x h 0x%08x\n",
1642 ioreqs[0].value, ioreqs[1].value);
1643 return zd_iowrite32a(chip, ioreqs, ARRAY_SIZE(ioreqs));
1644}