1 /*
2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /*
7 * Copyright (c) 2008 by Ben Taylor <bentaylor.solx86@gmail.com>
8 * Copyright (c) 2007 by Lukas Turek <turek@ksvi.mff.cuni.cz>
9 * Copyright (c) 2007 by Jiri Svoboda <jirik.svoboda@seznam.cz>
10 * Copyright (c) 2007 by Martin Krulis <martin.krulis@matfyz.cz>
11 * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
12 * Copyright (c) 2006 by Florian Stoehr <ich@florian-stoehr.de>
13 *
14 * Permission to use, copy, modify, and distribute this software for any
15 * purpose with or without fee is hereby granted, provided that the above
16 * copyright notice and this permission notice appear in all copies.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
19 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
21 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
23 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
24 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 *
26 */
27
28 /*
29 * ZD1211 wLAN driver
30 * Device hardware control
31 *
32 * Control the ZD1211 chip and the RF chip.
33 */
34
35 #include <sys/byteorder.h>
36 #include <sys/strsun.h>
37
38 #include "zyd.h"
39 #include "zyd_reg.h"
40
41 static zyd_res zyd_hw_configure(struct zyd_softc *sc);
42 static zyd_res zyd_al2230_rf_init(struct zyd_softc *);
43 static zyd_res zyd_al2230_rf_init_b(struct zyd_softc *);
44 static zyd_res zyd_al2230_switch_radio(struct zyd_softc *, boolean_t);
45 static zyd_res zyd_al2230_set_channel(struct zyd_softc *, uint8_t);
46 static zyd_res zyd_rfmd_rf_init(struct zyd_softc *);
47 static zyd_res zyd_rfmd_switch_radio(struct zyd_softc *, boolean_t);
48 static zyd_res zyd_rfmd_set_channel(struct zyd_softc *, uint8_t);
49
50 /* io write sequences to initialize RF-independent PHY registers */
51 static const struct zyd_iowrite16 zyd_def_phy[] = ZYD_DEF_PHY;
52 static const struct zyd_iowrite16 zyd_def_phyB[] = ZYD_DEF_PHYB;
zyd_rf_name(uint8_t type)53 static const char *zyd_rf_name(uint8_t type)
54 {
55 static const char *const zyd_rfs[] = {
56 "unknown", "unknown", "UW2451", "UCHIP", "AL2230",
57 "AL7230B", "THETA", "AL2210", "MAXIM_NEW", "GCT",
58 "PV2000", "RALINK", "INTERSIL", "RFMD", "MAXIM_NEW2",
59 "PHILIPS"
60 };
61 return (zyd_rfs[(type > 15) ? 0 : type]);
62 }
63
64 /*
65 * Read a 32-bit I/O register.
66 *
67 * sc soft state
68 * reg register number
69 * *val place to store the value
70 */
71 zyd_res
zyd_read32(struct zyd_softc * sc,uint16_t reg,uint32_t * val)72 zyd_read32(struct zyd_softc *sc, uint16_t reg, uint32_t *val)
73 {
74 zyd_res result;
75 uint16_t tmp[4];
76 uint16_t regs[2];
77
78 regs[0] = LE_16(ZYD_REG32_HI(reg));
79 regs[1] = LE_16(ZYD_REG32_LO(reg));
80
81 result = zyd_usb_ioread_req(&sc->usb, regs, sizeof (regs),
82 tmp, sizeof (tmp));
83
84 if (result != USB_SUCCESS)
85 return (ZYD_FAILURE);
86
87 if (tmp[0] != regs[0] || tmp[2] != regs[1]) {
88 ZYD_WARN("ioread response doesn't match request\n");
89 ZYD_WARN("requested regs %04x, %04x; got %04x, %04x\n",
90 LE_16(regs[0]), LE_16(regs[1]),
91 LE_16(tmp[0]), LE_16(tmp[2]));
92 return (ZYD_FAILURE);
93 }
94
95 *val = ((uint32_t)LE_16(tmp[1]) << 16) | (uint32_t)LE_16(tmp[3]);
96
97 return (ZYD_SUCCESS);
98 }
99
100 /*
101 * Write a 32-bit I/O register.
102 *
103 * sc soft state
104 * reg register number
105 * val value to write
106 */
107 zyd_res
zyd_write32(struct zyd_softc * sc,uint16_t reg,uint32_t val)108 zyd_write32(struct zyd_softc *sc, uint16_t reg, uint32_t val)
109 {
110 zyd_res result;
111 uint16_t tmp[4];
112
113 tmp[0] = LE_16(ZYD_REG32_HI(reg));
114 tmp[1] = LE_16(val >> 16);
115 tmp[2] = LE_16(ZYD_REG32_LO(reg));
116 tmp[3] = LE_16(val & 0xffff);
117
118 result = zyd_usb_cmd_send(&sc->usb, ZYD_CMD_IOWR, tmp, sizeof (tmp));
119
120 return (result);
121 }
122
123 /*
124 * Read a 16-bit I/O register.
125 *
126 * sc soft state
127 * reg register number
128 * *val place to store the value
129 */
130 zyd_res
zyd_read16(struct zyd_softc * sc,uint16_t reg,uint16_t * val)131 zyd_read16(struct zyd_softc *sc, uint16_t reg, uint16_t *val)
132 {
133 zyd_res result;
134 uint16_t tmp[2];
135 uint16_t regbuf;
136
137 regbuf = LE_16(reg);
138
139 result = zyd_usb_ioread_req(&sc->usb, ®buf, sizeof (regbuf),
140 tmp, sizeof (tmp));
141
142 if (result != USB_SUCCESS)
143 return (ZYD_FAILURE);
144
145 if (tmp[0] != regbuf) {
146 ZYD_WARN("ioread response doesn't match request\n");
147 ZYD_WARN("requested reg %04x; got %04x\n",
148 LE_16(regbuf), LE_16(tmp[0]));
149 return (ZYD_FAILURE);
150 }
151
152 if (result != USB_SUCCESS)
153 return (ZYD_FAILURE);
154
155 *val = LE_16(tmp[1]);
156
157 return (ZYD_SUCCESS);
158 }
159
160 /*
161 * Write a 16-bit I/O register.
162 *
163 * sc soft state
164 * reg register number
165 * val value to write
166 */
167 zyd_res
zyd_write16(struct zyd_softc * sc,uint16_t reg,uint16_t val)168 zyd_write16(struct zyd_softc *sc, uint16_t reg, uint16_t val)
169 {
170 zyd_res result;
171 uint16_t tmp[2];
172
173 tmp[0] = LE_16(ZYD_REG32_LO(reg));
174 tmp[1] = LE_16(val & 0xffff);
175
176 result = zyd_usb_cmd_send(&sc->usb, ZYD_CMD_IOWR, tmp, sizeof (tmp));
177
178 return (result);
179 }
180
181 /*
182 * Write an array of 16-bit registers.
183 *
184 * sc soft state
185 * *reqa array of register-value pairs
186 * n number of registers
187 */
188 zyd_res
zyd_write16a(struct zyd_softc * sc,const struct zyd_iowrite16 * reqa,int n)189 zyd_write16a(struct zyd_softc *sc, const struct zyd_iowrite16 *reqa, int n)
190 {
191 zyd_res res;
192 int i;
193
194 for (i = 0; i < n; i++) {
195 res = zyd_write16(sc, reqa[i].reg, reqa[i].value);
196 if (res != ZYD_SUCCESS)
197 return (ZYD_FAILURE);
198 }
199
200 return (ZYD_SUCCESS);
201 }
202
203 /*
204 * Lock PHY registers.
205 */
206 static void
zyd_lock_phy(struct zyd_softc * sc)207 zyd_lock_phy(struct zyd_softc *sc)
208 {
209 uint32_t tmp;
210
211 (void) zyd_read32(sc, ZYD_MAC_MISC, &tmp);
212 tmp &= ~ZYD_UNLOCK_PHY_REGS;
213 (void) zyd_write32(sc, ZYD_MAC_MISC, tmp);
214 }
215
216 /*
217 * Unlock PHY registers.
218 */
219 static void
zyd_unlock_phy(struct zyd_softc * sc)220 zyd_unlock_phy(struct zyd_softc *sc)
221 {
222 uint32_t tmp;
223
224 (void) zyd_read32(sc, ZYD_MAC_MISC, &tmp);
225 tmp |= ZYD_UNLOCK_PHY_REGS;
226 (void) zyd_write32(sc, ZYD_MAC_MISC, tmp);
227 }
228
229 /*
230 * Read MAC address from EEPROM.
231 */
232 static zyd_res
zyd_read_mac(struct zyd_softc * sc)233 zyd_read_mac(struct zyd_softc *sc)
234 {
235 uint32_t tmp;
236
237 if (zyd_read32(sc, ZYD_EEPROM_MAC_ADDR_P1, &tmp) != ZYD_SUCCESS)
238 return (ZYD_FAILURE);
239
240 sc->macaddr[0] = tmp & 0xff;
241 sc->macaddr[1] = tmp >> 8;
242 sc->macaddr[2] = tmp >> 16;
243 sc->macaddr[3] = tmp >> 24;
244
245 if (zyd_read32(sc, ZYD_EEPROM_MAC_ADDR_P2, &tmp) != ZYD_SUCCESS)
246 return (ZYD_FAILURE);
247
248 sc->macaddr[4] = tmp & 0xff;
249 sc->macaddr[5] = tmp >> 8;
250
251 return (ZYD_SUCCESS);
252 }
253
254 /*
255 * Write bits to RF configuration register.
256 */
257 static zyd_res
zyd_rfwrite(struct zyd_softc * sc,uint32_t val,int bits)258 zyd_rfwrite(struct zyd_softc *sc, uint32_t val, int bits)
259 {
260 uint16_t cr203;
261 struct zyd_rfwrite req;
262 uint16_t tmp;
263 int bit;
264 zyd_res res;
265 int i;
266
267 if (zyd_read16(sc, ZYD_CR203, &cr203) != ZYD_SUCCESS)
268 return (ZYD_FAILURE);
269
270 cr203 &= ~(ZYD_RF_IF_LE | ZYD_RF_CLK | ZYD_RF_DATA);
271
272 req.code = LE_16(ZYD_RFCFG_VALUE);
273 req.width = LE_16((uint16_t)bits);
274
275 for (i = 0; i < bits; i++) {
276 bit = (val & (1 << (bits - i - 1))) != 0;
277 tmp = LE_16(cr203) | (bit ? LE_16(ZYD_RF_DATA) : 0);
278 req.bit[i] = tmp;
279 }
280 res = zyd_usb_cmd_send(&sc->usb, ZYD_CMD_RFCFG, &req,
281 sizeof (uint16_t) * (2 + bits));
282
283 if (res != ZYD_SUCCESS) {
284 ZYD_WARN("failed configuring rf register\n");
285 return (ZYD_FAILURE);
286 }
287
288 return (ZYD_SUCCESS);
289 }
290
291 /*
292 * Control the LEDs.
293 */
294 static void
zyd_set_led(struct zyd_softc * sc,int which,boolean_t on)295 zyd_set_led(struct zyd_softc *sc, int which, boolean_t on)
296 {
297 uint32_t tmp;
298
299 (void) zyd_read32(sc, ZYD_MAC_TX_PE_CONTROL, &tmp);
300 tmp &= ~which;
301 if (on == B_TRUE)
302 tmp |= which;
303 (void) zyd_write32(sc, ZYD_MAC_TX_PE_CONTROL, tmp);
304 }
305
306 /*
307 * Set MAC address.
308 */
309 static void
zyd_set_macaddr(struct zyd_softc * sc,const uint8_t * addr)310 zyd_set_macaddr(struct zyd_softc *sc, const uint8_t *addr)
311 {
312 uint32_t tmp;
313
314 tmp = addr[3] << 24 | addr[2] << 16 | addr[1] << 8 | addr[0];
315 (void) zyd_write32(sc, ZYD_MAC_MACADRL, tmp);
316
317 tmp = addr[5] << 8 | addr[4];
318 (void) zyd_write32(sc, ZYD_MAC_MACADRH, tmp);
319 }
320
321 /*
322 * Read data from EEPROM.
323 */
324 static void
zyd_read_eeprom(struct zyd_softc * sc)325 zyd_read_eeprom(struct zyd_softc *sc)
326 {
327 uint32_t tmp;
328 uint16_t val;
329 int i;
330
331 /* read RF chip type */
332 (void) zyd_read32(sc, ZYD_EEPROM_POD, &tmp);
333 sc->rf_rev = tmp & 0x0f;
334 sc->pa_rev = (tmp >> 16) & 0x0f;
335 sc->fix_cr47 = (tmp >> 8) & 0x01;
336 sc->fix_cr157 = (tmp >> 13) & 0x01;
337
338 ZYD_DEBUG((ZYD_DBG_HW, "fix cr47: 0x%x\n", sc->fix_cr47));
339 ZYD_DEBUG((ZYD_DBG_HW, "fix cr157: 0x%x\n", sc->fix_cr157));
340 ZYD_DEBUG((ZYD_DBG_HW, "found RF chip %s, rev 0x%x\n",
341 zyd_rf_name(sc->rf_rev), sc->rf_rev));
342
343 /* read regulatory domain (currently unused) */
344 (void) zyd_read32(sc, ZYD_EEPROM_SUBID, &tmp);
345 sc->regdomain = tmp >> 16;
346
347 ZYD_DEBUG((ZYD_DBG_HW, "regulatory domain: %x\n", sc->regdomain));
348
349 /* read Tx power calibration tables */
350 for (i = 0; i < 7; i++) {
351 (void) zyd_read16(sc, ZYD_EEPROM_PWR_CAL + i, &val);
352 sc->pwr_cal[i * 2] = val >> 8;
353 sc->pwr_cal[i * 2 + 1] = val & 0xff;
354
355 (void) zyd_read16(sc, ZYD_EEPROM_PWR_INT + i, &val);
356 sc->pwr_int[i * 2] = val >> 8;
357 sc->pwr_int[i * 2 + 1] = val & 0xff;
358
359 (void) zyd_read16(sc, ZYD_EEPROM_36M_CAL + i, &val);
360 sc->ofdm36_cal[i * 2] = val >> 8;
361 sc->ofdm36_cal[i * 2 + 1] = val & 0xff;
362
363 (void) zyd_read16(sc, ZYD_EEPROM_48M_CAL + i, &val);
364 sc->ofdm48_cal[i * 2] = val >> 8;
365 sc->ofdm48_cal[i * 2 + 1] = val & 0xff;
366
367 (void) zyd_read16(sc, ZYD_EEPROM_54M_CAL + i, &val);
368 sc->ofdm54_cal[i * 2] = val >> 8;
369 sc->ofdm54_cal[i * 2 + 1] = val & 0xff;
370 }
371 }
372
373 zyd_res
zyd_hw_init(struct zyd_softc * sc)374 zyd_hw_init(struct zyd_softc *sc)
375 {
376 struct zyd_usb *uc = &sc->usb;
377 int ures;
378 zyd_res res;
379
380 sc->mac_rev = zyd_usb_mac_rev(uc->cdata->dev_descr->idVendor,
381 uc->cdata->dev_descr->idProduct);
382 if (sc->mac_rev == ZYD_ZD1211) {
383 res = zyd_usb_loadfirmware(uc, zd1211_firmware,
384 zd1211_firmware_size);
385 } else {
386 res = zyd_usb_loadfirmware(uc, zd1211b_firmware,
387 zd1211b_firmware_size);
388 }
389 if (res != ZYD_SUCCESS) {
390 ZYD_WARN("failed to load firmware\n");
391 goto fail1;
392 }
393
394 /* set configuration 1 - required for later communication */
395 ures = usb_set_cfg(uc->dip, 0, USB_FLAGS_SLEEP, NULL, NULL);
396 if (ures != USB_SUCCESS) {
397 ZYD_WARN("failed to set configuration 1 (%d)\n", ures);
398 goto fail1;
399 }
400
401 if (zyd_usb_open_pipes(uc) != ZYD_SUCCESS) {
402 ZYD_WARN("failed to open pipes\n");
403 goto fail1;
404 }
405
406 if (zyd_usb_cmd_in_start_polling(uc) != ZYD_SUCCESS) {
407 ZYD_WARN("failed to start command IN polling\n");
408 goto fail2;
409 }
410
411 if (zyd_read_mac(sc) != ZYD_SUCCESS) {
412 ZYD_WARN("failed to read MAC address\n");
413 goto fail3;
414 }
415
416 zyd_read_eeprom(sc);
417 switch (sc->rf_rev) {
418 case ZYD_RF_AL2230:
419 case ZYD_RF_RFMD:
420 break;
421 default:
422 ZYD_WARN("unsupported RF %s, chip type 0x%x\n",
423 zyd_rf_name(sc->rf_rev), sc->rf_rev);
424 goto fail3;
425 }
426
427 if (zyd_hw_configure(sc) != ZYD_SUCCESS) {
428 ZYD_WARN("failed to configure hardware\n");
429 goto fail3;
430 }
431
432 /* RF chip init */
433 zyd_lock_phy(sc);
434 switch (sc->rf_rev) {
435 case ZYD_RF_AL2230:
436 if (sc->mac_rev == ZYD_ZD1211) {
437 res = zyd_al2230_rf_init(sc);
438 } else {
439 res = zyd_al2230_rf_init_b(sc);
440 }
441 break;
442 case ZYD_RF_RFMD:
443 res = zyd_rfmd_rf_init(sc);
444 break;
445 default:
446 ZYD_WARN("unsupported Radio %s, code = 0x%x\n",
447 zyd_rf_name(sc->rf_rev), sc->rf_rev);
448 res = ZYD_FAILURE;
449 break;
450 }
451 zyd_unlock_phy(sc);
452
453 if (res != ZYD_SUCCESS) {
454 ZYD_WARN("failed to configure RF chip\n");
455 goto fail3;
456 }
457
458 ZYD_DEBUG((ZYD_DBG_HW, "MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
459 sc->macaddr[0], sc->macaddr[1], sc->macaddr[2],
460 sc->macaddr[3], sc->macaddr[4], sc->macaddr[5]));
461
462 return (ZYD_SUCCESS);
463
464 fail3:
465 zyd_usb_cmd_in_stop_polling(uc);
466 fail2:
467 zyd_usb_close_pipes(uc);
468 fail1:
469 return (ZYD_FAILURE);
470 }
471
472 void
zyd_hw_deinit(struct zyd_softc * sc)473 zyd_hw_deinit(struct zyd_softc *sc)
474 {
475 struct zyd_usb *uc = &sc->usb;
476
477 zyd_usb_cmd_in_stop_polling(uc);
478 zyd_usb_close_pipes(uc);
479 }
480
481 /*
482 * Finish ZD chip initialization.
483 */
484 static zyd_res
zyd_hw_configure(struct zyd_softc * sc)485 zyd_hw_configure(struct zyd_softc *sc)
486 {
487 zyd_res res;
488 uint32_t tmp;
489
490 /* specify that the plug and play is finished */
491 (void) zyd_write32(sc, ZYD_MAC_AFTER_PNP, 1);
492 (void) zyd_read16(sc, ZYD_FIRMWARE_BASE_ADDR, &sc->fwbase);
493 ZYD_DEBUG((ZYD_DBG_FW, "firmware base address: 0x%04x\n", sc->fwbase));
494
495 /* retrieve firmware revision number */
496 (void) zyd_read16(sc, sc->fwbase + ZYD_FW_FIRMWARE_REV, &sc->fw_rev);
497 ZYD_DEBUG((ZYD_DBG_FW, "firmware revision: x0x%4x\n", sc->fw_rev));
498
499 (void) zyd_write32(sc, ZYD_CR_GPI_EN, 0);
500 (void) zyd_write32(sc, ZYD_MAC_CONT_WIN_LIMIT, 0x7f043f);
501
502 /* disable interrupts */
503 (void) zyd_write32(sc, ZYD_CR_INTERRUPT, 0);
504
505 /* Init RF chip-independent PHY registers */
506 zyd_lock_phy(sc);
507 if (sc->mac_rev == ZYD_ZD1211) {
508 res = zyd_write16a(sc, zyd_def_phy,
509 ZYD_ARRAY_LENGTH(zyd_def_phy));
510 } else {
511 res = zyd_write16a(sc, zyd_def_phyB,
512 ZYD_ARRAY_LENGTH(zyd_def_phyB));
513 }
514 if (sc->fix_cr157) {
515 if (zyd_read32(sc, ZYD_EEPROM_PHY_REG, &tmp) == 0)
516 (void) zyd_write32(sc, ZYD_CR157, tmp >> 8);
517 }
518 zyd_unlock_phy(sc);
519
520 if (res != ZYD_SUCCESS)
521 return (ZYD_FAILURE);
522
523 /* HMAC initialization magic */
524 if (sc->mac_rev == ZYD_ZD1211) {
525 (void) zyd_write32(sc, ZYD_MAC_RETRY, 0x00000002);
526 } else {
527 (void) zyd_write32(sc, ZYD_MACB_MAX_RETRY, 0x02020202);
528 (void) zyd_write32(sc, ZYD_MACB_TXPWR_CTL4, 0x007f003f);
529 (void) zyd_write32(sc, ZYD_MACB_TXPWR_CTL3, 0x007f003f);
530 (void) zyd_write32(sc, ZYD_MACB_TXPWR_CTL2, 0x003f001f);
531 (void) zyd_write32(sc, ZYD_MACB_TXPWR_CTL1, 0x001f000f);
532 (void) zyd_write32(sc, ZYD_MACB_AIFS_CTL1, 0x00280028);
533 (void) zyd_write32(sc, ZYD_MACB_AIFS_CTL2, 0x008C003c);
534 (void) zyd_write32(sc, ZYD_MACB_TXOP, 0x01800824);
535 }
536 (void) zyd_write32(sc, ZYD_MAC_ACK_EXT, 0x00000020);
537 (void) zyd_write32(sc, ZYD_CR_ADDA_MBIAS_WT, 0x30000808);
538 (void) zyd_write32(sc, ZYD_MAC_SNIFFER, 0x00000000);
539 (void) zyd_write32(sc, ZYD_MAC_RXFILTER, 0x00000000);
540 (void) zyd_write32(sc, ZYD_MAC_GHTBL, 0x00000000);
541 (void) zyd_write32(sc, ZYD_MAC_GHTBH, 0x80000000);
542 (void) zyd_write32(sc, ZYD_MAC_MISC, 0x000000a4);
543 (void) zyd_write32(sc, ZYD_CR_ADDA_PWR_DWN, 0x0000007f);
544 (void) zyd_write32(sc, ZYD_MAC_BCNCFG, 0x00f00401);
545 (void) zyd_write32(sc, ZYD_MAC_PHY_DELAY2, 0x00000000);
546 (void) zyd_write32(sc, ZYD_MAC_ACK_EXT, 0x00000080);
547 (void) zyd_write32(sc, ZYD_CR_ADDA_PWR_DWN, 0x00000000);
548 (void) zyd_write32(sc, ZYD_MAC_SIFS_ACK_TIME, 0x00000100);
549 (void) zyd_write32(sc, ZYD_MAC_DIFS_EIFS_SIFS, 0x0547c032);
550 (void) zyd_write32(sc, ZYD_CR_RX_PE_DELAY, 0x00000070);
551 (void) zyd_write32(sc, ZYD_CR_PS_CTRL, 0x10000000);
552 (void) zyd_write32(sc, ZYD_MAC_RTSCTSRATE, 0x02030203);
553 (void) zyd_write32(sc, ZYD_MAC_RX_THRESHOLD, 0x000c0640);
554 (void) zyd_write32(sc, ZYD_MAC_BACKOFF_PROTECT, 0x00000114);
555
556 return (ZYD_SUCCESS);
557 }
558
559 /*
560 * Set active channel number.
561 */
562 void
zyd_hw_set_channel(struct zyd_softc * sc,uint8_t chan)563 zyd_hw_set_channel(struct zyd_softc *sc, uint8_t chan)
564 {
565 uint32_t tmp;
566
567 zyd_lock_phy(sc);
568
569 ZYD_DEBUG((ZYD_DBG_HW, "setting channel %d\n", chan));
570
571 switch (sc->rf_rev) {
572 case ZYD_RF_AL2230:
573 (void) zyd_al2230_set_channel(sc, chan);
574 break;
575 case ZYD_RF_RFMD:
576 (void) zyd_rfmd_set_channel(sc, chan);
577 break;
578 }
579
580 /* update Tx power */
581 ZYD_DEBUG((ZYD_DBG_HW, "updating tx power table\n"));
582
583 (void) zyd_write16(sc, ZYD_CR31, sc->pwr_int[chan - 1]);
584 if (sc->mac_rev == ZYD_ZD1211B) {
585 (void) zyd_write16(sc, ZYD_CR67, sc->ofdm36_cal[chan - 1]);
586 (void) zyd_write16(sc, ZYD_CR66, sc->ofdm48_cal[chan - 1]);
587 (void) zyd_write16(sc, ZYD_CR65, sc->ofdm54_cal[chan - 1]);
588 (void) zyd_write16(sc, ZYD_CR68, sc->pwr_cal[chan - 1]);
589 (void) zyd_write16(sc, ZYD_CR69, 0x28);
590 (void) zyd_write16(sc, ZYD_CR69, 0x2a);
591 }
592
593 if (sc->fix_cr47) {
594 /* set CCK baseband gain from EEPROM */
595 if (zyd_read32(sc, ZYD_EEPROM_PHY_REG, &tmp) == 0)
596 (void) zyd_write16(sc, ZYD_CR47, tmp & 0xff);
597 }
598
599 (void) zyd_write32(sc, ZYD_CR_CONFIG_PHILIPS, 0);
600
601 zyd_unlock_phy(sc);
602 }
603
604 /*
605 * Activate the device.
606 */
607 zyd_res
zyd_hw_start(struct zyd_softc * sc)608 zyd_hw_start(struct zyd_softc *sc)
609 {
610 struct zyd_usb *uc = &sc->usb;
611 struct ieee80211com *ic = &sc->ic;
612 zyd_res res;
613
614 if (zyd_usb_data_in_enable(&sc->usb) != ZYD_SUCCESS) {
615 ZYD_WARN("error starting rx transfer\n");
616 goto fail1;
617 }
618
619 ZYD_DEBUG((ZYD_DBG_HW, "setting MAC address\n"));
620 zyd_set_macaddr(sc, sc->macaddr);
621
622 /* we'll do software WEP decryption for now */
623 ZYD_DEBUG((ZYD_DBG_HW, "setting encryption mode\n"));
624 res = zyd_write32(sc, ZYD_MAC_ENCRYPTION_TYPE, ZYD_ENC_SNIFFER);
625 if (res != ZYD_SUCCESS)
626 goto fail2;
627
628 /* promiscuous mode */
629 (void) zyd_write32(sc, ZYD_MAC_SNIFFER, 0);
630
631 /* try to catch all packets */
632 (void) zyd_write32(sc, ZYD_MAC_RXFILTER, ZYD_FILTER_BSS);
633
634 /* switch radio transmitter ON */
635 switch (sc->rf_rev) {
636 case ZYD_RF_AL2230:
637 (void) zyd_al2230_switch_radio(sc, B_TRUE);
638 break;
639 case ZYD_RF_RFMD:
640 (void) zyd_rfmd_switch_radio(sc, B_TRUE);
641 break;
642 }
643
644 /* set basic rates */
645 ZYD_DEBUG((ZYD_DBG_HW, "setting basic rates\n"));
646 if (ic->ic_curmode == IEEE80211_MODE_11B)
647 (void) zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x0003);
648 else if (ic->ic_curmode == IEEE80211_MODE_11A)
649 (void) zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x1500);
650 else /* assumes 802.11b/g */
651 (void) zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x000f);
652
653 /* set mandatory rates */
654 ZYD_DEBUG((ZYD_DBG_HW, "setting mandatory rates\n"));
655 if (ic->ic_curmode == IEEE80211_MODE_11B)
656 (void) zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x000f);
657 else if (ic->ic_curmode == IEEE80211_MODE_11A)
658 (void) zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x1500);
659 else /* assumes 802.11b/g */
660 (void) zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x150f);
661
662 /* enable interrupts */
663 (void) zyd_write32(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK);
664
665 zyd_set_led(sc, ZYD_LED2, B_TRUE);
666
667 return (ZYD_SUCCESS);
668
669 fail2:
670 zyd_usb_data_in_disable(uc);
671 fail1:
672 return (ZYD_FAILURE);
673 }
674
675 /*
676 * Deactivate the device.
677 */
678 void
zyd_hw_stop(struct zyd_softc * sc)679 zyd_hw_stop(struct zyd_softc *sc)
680 {
681 struct zyd_usb *uc = &sc->usb;
682
683 if (uc->connected) {
684 /* switch radio transmitter OFF */
685 switch (sc->rf_rev) {
686 case ZYD_RF_AL2230:
687 (void) zyd_al2230_switch_radio(sc, B_FALSE);
688 break;
689 case ZYD_RF_RFMD:
690 (void) zyd_rfmd_switch_radio(sc, B_FALSE);
691 break;
692 }
693
694 /* disable reception */
695 (void) zyd_write32(sc, ZYD_MAC_RXFILTER, 0);
696
697 /* disable interrupts */
698 (void) zyd_write32(sc, ZYD_CR_INTERRUPT, 0);
699
700 zyd_set_led(sc, ZYD_LED2, B_FALSE);
701 } else {
702 ZYD_DEBUG((ZYD_DBG_HW, "stop: device absent\n"));
703
704 }
705
706 zyd_usb_data_in_disable(uc);
707 sc->tx_queued = 0;
708 }
709
710 /*
711 * ZD1211 AL2230 Radio control
712 * Init the AL2230 RF chip.
713 */
714 static zyd_res
zyd_al2230_rf_init(struct zyd_softc * sc)715 zyd_al2230_rf_init(struct zyd_softc *sc)
716 {
717 const struct zyd_iowrite16 phyini[] = ZYD_AL2230_PHY;
718 const uint32_t rfini[] = ZYD_AL2230_RF;
719
720 zyd_res res;
721 int i;
722
723 zyd_lock_phy(sc);
724
725 /* init RF-dependent PHY registers */
726 res = zyd_write16a(sc, phyini, ZYD_ARRAY_LENGTH(phyini));
727 if (res != ZYD_SUCCESS) {
728 zyd_unlock_phy(sc);
729 return (ZYD_FAILURE);
730 }
731
732 /* init AL2230 radio */
733 for (i = 0; i < ZYD_ARRAY_LENGTH(rfini); i++) {
734 res = zyd_rfwrite(sc, rfini[i], ZYD_AL2230_RF_BITS);
735 if (res != ZYD_SUCCESS) {
736 zyd_unlock_phy(sc);
737 return (ZYD_FAILURE);
738 }
739 }
740
741 zyd_unlock_phy(sc);
742
743 ZYD_DEBUG((ZYD_DBG_HW, "RF chip AL2230 initialized\n"));
744
745 return (ZYD_SUCCESS);
746 }
747
748 /*
749 * Init the AL2230B RF chip (11b).
750 */
751 static zyd_res
zyd_al2230_rf_init_b(struct zyd_softc * sc)752 zyd_al2230_rf_init_b(struct zyd_softc *sc)
753 {
754 const struct zyd_iowrite16 phyini[] = ZYD_AL2230_PHY_B;
755 const uint32_t rfini[] = ZYD_AL2230_RF_B;
756 zyd_res res;
757 int i;
758
759 zyd_lock_phy(sc);
760 /* init RF-dependent PHY registers */
761 res = zyd_write16a(sc, phyini, ZYD_ARRAY_LENGTH(phyini));
762 if (res != ZYD_SUCCESS) {
763 zyd_unlock_phy(sc);
764 return (ZYD_FAILURE);
765 }
766
767 /* init AL2230 radio */
768 for (i = 0; i < ZYD_ARRAY_LENGTH(rfini); i++) {
769 res = zyd_rfwrite(sc, rfini[i], ZYD_AL2230_RF_BITS);
770 if (res != ZYD_SUCCESS) {
771 zyd_unlock_phy(sc);
772 return (ZYD_FAILURE);
773 }
774 }
775 zyd_unlock_phy(sc);
776 ZYD_DEBUG((ZYD_DBG_HW, "RF chip AL2230 (11b) initialized\n"));
777
778 return (ZYD_SUCCESS);
779 }
780
781 /*
782 * Tune RF chip to a specified channel.
783 */
784 static zyd_res
zyd_al2230_set_channel(struct zyd_softc * sc,uint8_t chan)785 zyd_al2230_set_channel(struct zyd_softc *sc, uint8_t chan)
786 {
787 static const struct {
788 uint32_t r1, r2, r3;
789 } rfprog[] = ZYD_AL2230_CHANTABLE;
790
791 (void) zyd_rfwrite(sc, rfprog[chan - 1].r1, ZYD_AL2230_RF_BITS);
792 (void) zyd_rfwrite(sc, rfprog[chan - 1].r2, ZYD_AL2230_RF_BITS);
793 (void) zyd_rfwrite(sc, rfprog[chan - 1].r3, ZYD_AL2230_RF_BITS);
794
795 (void) zyd_write16(sc, ZYD_CR138, 0x28);
796 (void) zyd_write16(sc, ZYD_CR203, 0x06);
797
798 return (ZYD_SUCCESS);
799 }
800
801 /*
802 * Turn the radio transciever on/off.
803 */
804 static zyd_res
zyd_al2230_switch_radio(struct zyd_softc * sc,boolean_t on)805 zyd_al2230_switch_radio(struct zyd_softc *sc, boolean_t on)
806 {
807 int on251 = (sc->mac_rev == ZYD_ZD1211) ? 0x3f : 0x7f;
808
809 zyd_lock_phy(sc);
810
811 (void) zyd_write16(sc, ZYD_CR11, (on == B_TRUE) ? 0x00 : 0x04);
812 (void) zyd_write16(sc, ZYD_CR251, (on == B_TRUE) ? on251 : 0x2f);
813
814 zyd_unlock_phy(sc);
815
816 return (ZYD_SUCCESS);
817 }
818
819
820 /*
821 * RFMD RF methods.
822 */
823 static zyd_res
zyd_rfmd_rf_init(struct zyd_softc * sc)824 zyd_rfmd_rf_init(struct zyd_softc *sc)
825 {
826 static const struct zyd_iowrite16 phyini[] = ZYD_RFMD_PHY;
827 static const uint32_t rfini[] = ZYD_RFMD_RF;
828 zyd_res res;
829 int i;
830
831 /* init RF-dependent PHY registers */
832 zyd_lock_phy(sc);
833 res = zyd_write16a(sc, phyini, ZYD_ARRAY_LENGTH(phyini));
834 if (res != ZYD_SUCCESS) {
835 zyd_unlock_phy(sc);
836 return (ZYD_FAILURE);
837 }
838 /* init RFMD radio */
839 for (i = 0; i < ZYD_ARRAY_LENGTH(rfini); i++) {
840 res = zyd_rfwrite(sc, rfini[i], ZYD_RFMD_RF_BITS);
841 if (res != ZYD_SUCCESS) {
842 zyd_unlock_phy(sc);
843 return (ZYD_FAILURE);
844 }
845 }
846 zyd_unlock_phy(sc);
847 ZYD_DEBUG((ZYD_DBG_HW, "RF chip RFMD initialized\n"));
848
849 return (ZYD_SUCCESS);
850 }
851
852 static zyd_res
zyd_rfmd_switch_radio(struct zyd_softc * sc,boolean_t on)853 zyd_rfmd_switch_radio(struct zyd_softc *sc, boolean_t on)
854 {
855
856 (void) zyd_write16(sc, ZYD_CR10, on ? 0x89 : 0x15);
857 (void) zyd_write16(sc, ZYD_CR11, on ? 0x00 : 0x81);
858
859 return (ZYD_SUCCESS);
860 }
861
862 static zyd_res
zyd_rfmd_set_channel(struct zyd_softc * sc,uint8_t chan)863 zyd_rfmd_set_channel(struct zyd_softc *sc, uint8_t chan)
864 {
865 static const struct {
866 uint32_t r1, r2;
867 } rfprog[] = ZYD_RFMD_CHANTABLE;
868
869 (void) zyd_rfwrite(sc, rfprog[chan - 1].r1, ZYD_RFMD_RF_BITS);
870 (void) zyd_rfwrite(sc, rfprog[chan - 1].r2, ZYD_RFMD_RF_BITS);
871
872 return (ZYD_SUCCESS);
873 }
874