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