1 2/*- 3 * Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com> 4 * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <dev/rt2860/rt2860_read_eeprom.h> 20#include <dev/rt2860/rt2860_reg.h> 21#include <dev/rt2860/rt2860_eeprom.h> 22#include <dev/rt2860/rt2860_io.h> 23#include <dev/rt2860/rt2860_debug.h> 24 25/* 26 * rt2860_read_eeprom 27 */ 28void rt2860_read_eeprom(struct rt2860_softc *sc) 29{ 30 uint32_t tmp; 31 uint16_t val; 32 int i; 33 34 /* read EEPROM address number */ 35 36 tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR); 37 38 if((tmp & 0x30) == 0) 39 sc->eeprom_addr_num = 6; 40 else if((tmp & 0x30) == 0x10) 41 sc->eeprom_addr_num = 8; 42 else 43 sc->eeprom_addr_num = 8; 44 45 /* read EEPROM version */ 46 47 sc->eeprom_rev = rt2860_io_eeprom_read(sc, RT2860_EEPROM_VERSION); 48 49 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 50 "%s: EEPROM rev=0x%04x\n", 51 device_get_nameunit(sc->dev), sc->eeprom_rev); 52 53 /* read MAC address */ 54 55 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_ADDRESS01); 56 57 sc->mac_addr[0] = (val & 0xff); 58 sc->mac_addr[1] = (val >> 8); 59 60 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_ADDRESS23); 61 62 sc->mac_addr[2] = (val & 0xff); 63 sc->mac_addr[3] = (val >> 8); 64 65 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_ADDRESS45); 66 67 sc->mac_addr[4] = (val & 0xff); 68 sc->mac_addr[5] = (val >> 8); 69 70 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 71 "%s: EEPROM mac address=%s\n", 72 device_get_nameunit(sc->dev), ether_sprintf(sc->mac_addr)); 73 74 /* read RF information */ 75 76 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_ANTENNA); 77 if (val == 0xffff) 78 { 79 printf("%s: invalid EEPROM antenna info\n", 80 device_get_nameunit(sc->dev)); 81 82 sc->rf_rev = RT2860_EEPROM_RF_2820; 83 sc->ntxpath = 1; 84 sc->nrxpath = 2; 85 } 86 else 87 { 88 sc->rf_rev = (val >> 8) & 0xf; 89 sc->ntxpath = (val >> 4) & 0xf; 90 sc->nrxpath = (val & 0xf); 91 } 92 93 if ((sc->mac_rev != 0x28830300) && (sc->nrxpath > 2)) 94 { 95 /* only 2 Rx streams for RT2860 series */ 96 97 sc->nrxpath = 2; 98 } 99 100 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 101 "%s: EEPROM RF rev=0x%04x, paths=%dT%dR\n", 102 device_get_nameunit(sc->dev), sc->rf_rev, sc->ntxpath, sc->nrxpath); 103 104 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_NIC_CONFIG); 105 if ((val & 0xff00) != 0xff00) 106 sc->patch_dac = (val >> 15) & 1; 107 108 sc->hw_radio_cntl = ((val & RT2860_EEPROM_HW_RADIO_CNTL) ? 1 : 0); 109 sc->tx_agc_cntl = ((val & RT2860_EEPROM_TX_AGC_CNTL) ? 1 : 0); 110 sc->ext_lna_2ghz = ((val & RT2860_EEPROM_EXT_LNA_2GHZ) ? 1 : 0); 111 sc->ext_lna_5ghz = ((val & RT2860_EEPROM_EXT_LNA_5GHZ) ? 1 : 0); 112 113 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 114 "%s: EEPROM NIC config: HW radio cntl=%d, Tx AGC cntl=%d, ext LNA gains=%d/%d\n", 115 device_get_nameunit(sc->dev), 116 sc->hw_radio_cntl, sc->tx_agc_cntl, sc->ext_lna_2ghz, sc->ext_lna_5ghz); 117 118 /* read country code */ 119 120 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_COUNTRY); 121 122 sc->country_2ghz = (val >> 8) & 0xff; 123 sc->country_5ghz = (val & 0xff); 124 125 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 126 "%s: EEPROM country code=%d/%d\n", 127 device_get_nameunit(sc->dev), sc->country_2ghz, sc->country_5ghz); 128 129 /* read RF frequency offset */ 130 131 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RF_FREQ_OFF); 132 133 if ((val & 0xff) != 0xff) 134 { 135 sc->rf_freq_off = (val & 0xff); 136 } 137 else 138 { 139 printf("%s: invalid EEPROM RF freq offset\n", 140 device_get_nameunit(sc->dev)); 141 142 sc->rf_freq_off = 0; 143 } 144 145 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 146 "%s: EEPROM freq offset=0x%02x\n", 147 device_get_nameunit(sc->dev), sc->rf_freq_off); 148 149 /* read LEDs operating mode */ 150 151 if (((val >> 8) & 0xff) != 0xff) 152 { 153 sc->led_cntl = ((val >> 8) & 0xff); 154 sc->led_off[0] = rt2860_io_eeprom_read(sc, RT2860_EEPROM_LED1_OFF); 155 sc->led_off[1] = rt2860_io_eeprom_read(sc, RT2860_EEPROM_LED2_OFF); 156 sc->led_off[2] = rt2860_io_eeprom_read(sc, RT2860_EEPROM_LED3_OFF); 157 } 158 else 159 { 160 printf("%s: invalid EEPROM LED settings\n", 161 device_get_nameunit(sc->dev)); 162 163 sc->led_cntl = RT2860_EEPROM_LED_CNTL_DEFAULT; 164 sc->led_off[0] = RT2860_EEPROM_LED1_OFF_DEFAULT; 165 sc->led_off[1] = RT2860_EEPROM_LED2_OFF_DEFAULT; 166 sc->led_off[2] = RT2860_EEPROM_LED3_OFF_DEFAULT; 167 } 168 169 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 170 "%s: EEPROM LED cntl=0x%02x, LEDs=0x%04x/0x%04x/0x%04x\n", 171 device_get_nameunit(sc->dev), sc->led_cntl, 172 sc->led_off[0], sc->led_off[1], sc->led_off[2]); 173 174 /* read RSSI offsets and LNA gains */ 175 176 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_LNA_GAIN); 177 if ((sc->mac_rev & 0xffff0000) >= 0x30710000) 178 sc->lna_gain[0] = RT3090_DEF_LNA; 179 else /* channel group 0 */ 180 sc->lna_gain[0] = val & 0xff; 181 182// sc->lna_gain[0] = (val & 0xff); 183 sc->lna_gain[1] = (val >> 8) & 0xff; 184 185 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RSSI_OFF_2GHZ_BASE); 186 187 sc->rssi_off_2ghz[0] = (val & 0xff); 188 sc->rssi_off_2ghz[1] = (val >> 8) & 0xff; 189 190 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RSSI_OFF_2GHZ_BASE + 2); 191 192 //sc->rssi_off_2ghz[2] = (val & 0xff); 193 sc->lna_gain[2] = (val >> 8) & 0xff; 194 if ((sc->mac_rev & 0xffff0000) >= 0x30710000) { 195 /* 196 * On RT3090 chips (limited to 2 Rx chains), this ROM 197 * field contains the Tx mixer gain for the 2GHz band. 198 */ 199 if ((val & 0xff) != 0xff) 200 sc->txmixgain_2ghz = val & 0x7; 201 //DPRINTF(("tx mixer gain=%u (2GHz)\n", sc->txmixgain_2ghz)); 202 } else 203 sc->rssi_off_2ghz[2] = val & 0xff; /* Ant C */ 204 205 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RSSI_OFF_5GHZ_BASE); 206 207 sc->rssi_off_5ghz[0] = (val & 0xff); 208 sc->rssi_off_5ghz[1] = (val >> 8) & 0xff; 209 210 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RSSI_OFF_5GHZ_BASE + 2); 211 212 sc->rssi_off_5ghz[2] = (val & 0xff); 213 sc->lna_gain[3] = (val >> 8) & 0xff; 214 215 for (i = 2; i < RT2860_SOFTC_LNA_GAIN_COUNT; i++) 216 { 217 if (sc->lna_gain[i] == 0x00 || sc->lna_gain[i] == (int8_t) 0xff) 218 { 219 printf("%s: invalid EEPROM LNA gain #%d: 0x%02x\n", 220 device_get_nameunit(sc->dev), i, sc->lna_gain[i]); 221 222 sc->lna_gain[i] = sc->lna_gain[1]; 223 } 224 } 225 226 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 227 "%s: EEPROM LNA gains=0x%02x/0x%02x/0x%02x/0x%02x\n", 228 device_get_nameunit(sc->dev), 229 sc->lna_gain[0], sc->lna_gain[1], sc->lna_gain[2], sc->lna_gain[3]); 230 231 for (i = 0; i < RT2860_SOFTC_RSSI_OFF_COUNT; i++) 232 { 233 if (sc->rssi_off_2ghz[i] < RT2860_EEPROM_RSSI_OFF_MIN || 234 sc->rssi_off_2ghz[i] > RT2860_EEPROM_RSSI_OFF_MAX) 235 { 236 printf("%s: invalid EEPROM RSSI offset #%d (2GHz): 0x%02x\n", 237 device_get_nameunit(sc->dev), i, sc->rssi_off_2ghz[i]); 238 239 sc->rssi_off_2ghz[i] = 0; 240 } 241 242 if (sc->rssi_off_5ghz[i] < RT2860_EEPROM_RSSI_OFF_MIN || 243 sc->rssi_off_5ghz[i] > RT2860_EEPROM_RSSI_OFF_MAX) 244 { 245 printf("%s: invalid EEPROM RSSI offset #%d (5GHz): 0x%02x\n", 246 device_get_nameunit(sc->dev), i, sc->rssi_off_5ghz[i]); 247 248 sc->rssi_off_5ghz[i] = 0; 249 } 250 } 251 252 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 253 "%s: EEPROM RSSI offsets 2GHz=%d/%d/%d\n", 254 device_get_nameunit(sc->dev), 255 sc->rssi_off_2ghz[0], sc->rssi_off_2ghz[1], sc->rssi_off_2ghz[2]); 256 257 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 258 "%s: EEPROM RSSI offsets 5GHz=%d/%d/%d\n", 259 device_get_nameunit(sc->dev), 260 sc->rssi_off_5ghz[0], sc->rssi_off_5ghz[1], sc->rssi_off_5ghz[2]); 261 262 /* read Tx power settings for 2GHz channels */ 263 264 for (i = 0; i < 14; i += 2) 265 { 266 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW1_2GHZ_BASE + i / 2); 267 268 sc->txpow1[i + 0] = (int8_t) (val & 0xff); 269 sc->txpow1[i + 1] = (int8_t) (val >> 8); 270 271 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW2_2GHZ_BASE + i / 2); 272 273 sc->txpow2[i + 0] = (int8_t) (val & 0xff); 274 sc->txpow2[i + 1] = (int8_t) (val >> 8); 275 } 276 277 /* read Tx power settings for 5GHz channels */ 278 279 for (; i < RT2860_SOFTC_TXPOW_COUNT; i += 2) 280 { 281 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW1_5GHZ_BASE + i / 2); 282 283 sc->txpow1[i + 0] = (int8_t) (val & 0xff); 284 sc->txpow1[i + 1] = (int8_t) (val >> 8); 285 286 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW2_5GHZ_BASE + i / 2); 287 288 sc->txpow2[i + 0] = (int8_t) (val & 0xff); 289 sc->txpow2[i + 1] = (int8_t) (val >> 8); 290 } 291 292 /* fix broken Tx power settings */ 293 294 for (i = 0; i < 14; i++) 295 { 296 if (sc->txpow1[i] < RT2860_EEPROM_TXPOW_2GHZ_MIN || 297 sc->txpow1[i] > RT2860_EEPROM_TXPOW_2GHZ_MAX) 298 { 299 printf("%s: invalid EEPROM Tx power1 #%d (2GHz): 0x%02x\n", 300 device_get_nameunit(sc->dev), i, sc->txpow1[i]); 301 302 sc->txpow1[i] = RT2860_EEPROM_TXPOW_2GHZ_DEFAULT; 303 } 304 305 if (sc->txpow2[i] < RT2860_EEPROM_TXPOW_2GHZ_MIN || 306 sc->txpow2[i] > RT2860_EEPROM_TXPOW_2GHZ_MAX) 307 { 308 printf("%s: invalid EEPROM Tx power2 #%d (2GHz): 0x%02x\n", 309 device_get_nameunit(sc->dev), i, sc->txpow2[i]); 310 311 sc->txpow2[i] = RT2860_EEPROM_TXPOW_2GHZ_DEFAULT; 312 } 313 } 314 315 for (; i < RT2860_SOFTC_TXPOW_COUNT; i++) 316 { 317 if (sc->txpow1[i] < RT2860_EEPROM_TXPOW_5GHZ_MIN || 318 sc->txpow1[i] > RT2860_EEPROM_TXPOW_5GHZ_MAX) 319 { 320 printf("%s: invalid EEPROM Tx power1 #%d (5GHz): 0x%02x\n", 321 device_get_nameunit(sc->dev), i, sc->txpow1[i]); 322 323 sc->txpow1[i] = RT2860_EEPROM_TXPOW_5GHZ_DEFAULT; 324 } 325 326 if (sc->txpow2[i] < RT2860_EEPROM_TXPOW_5GHZ_MIN || 327 sc->txpow2[i] > RT2860_EEPROM_TXPOW_5GHZ_MAX) 328 { 329 printf("%s: invalid EEPROM Tx power2 #%d (5GHz): 0x%02x\n", 330 device_get_nameunit(sc->dev), i, sc->txpow2[i]); 331 332 sc->txpow2[i] = RT2860_EEPROM_TXPOW_5GHZ_DEFAULT; 333 } 334 } 335 336 /* read Tx power per rate deltas */ 337 338 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW_RATE_DELTA); 339 340 sc->txpow_rate_delta_2ghz = 0; 341 sc->txpow_rate_delta_5ghz = 0; 342 343 if ((val & 0xff) != 0xff) 344 { 345 if (val & 0x80) 346 sc->txpow_rate_delta_2ghz = (val & 0xf); 347 348 if (!(val & 0x40)) 349 sc->txpow_rate_delta_2ghz = -sc->txpow_rate_delta_2ghz; 350 } 351 352 val >>= 8; 353 354 if ((val & 0xff) != 0xff) 355 { 356 if (val & 0x80) 357 sc->txpow_rate_delta_5ghz = (val & 0xf); 358 359 if (!(val & 0x40)) 360 sc->txpow_rate_delta_5ghz = -sc->txpow_rate_delta_5ghz; 361 } 362 363 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 364 "%s: EEPROM Tx power per rate deltas=%d(2MHz), %d(5MHz)\n", 365 device_get_nameunit(sc->dev), 366 sc->txpow_rate_delta_2ghz, sc->txpow_rate_delta_5ghz); 367 368 /* read Tx power per rate */ 369 370 for (i = 0; i < RT2860_SOFTC_TXPOW_RATE_COUNT; i++) 371 { 372 rt2860_io_eeprom_read_multi(sc, RT2860_EEPROM_TXPOW_RATE_BASE + i * sizeof(uint32_t), 373 &tmp, sizeof(uint32_t)); 374 375 sc->txpow_rate_20mhz[i] = tmp; 376 sc->txpow_rate_40mhz_2ghz[i] = 377 rt2860_read_eeprom_txpow_rate_add_delta(tmp, sc->txpow_rate_delta_2ghz); 378 sc->txpow_rate_40mhz_5ghz[i] = 379 rt2860_read_eeprom_txpow_rate_add_delta(tmp, sc->txpow_rate_delta_5ghz); 380 381 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 382 "%s: EEPROM Tx power per rate #%d=0x%08x(20MHz), 0x%08x(40MHz/2GHz), 0x%08x(40MHz/5GHz)\n", 383 device_get_nameunit(sc->dev), i, 384 sc->txpow_rate_20mhz[i], sc->txpow_rate_40mhz_2ghz[i], sc->txpow_rate_40mhz_5ghz[i]); 385 } 386 387 if (sc->tx_agc_cntl) 388 sc->tx_agc_cntl_2ghz = sc->tx_agc_cntl_5ghz = 1; 389 390 /* read factory-calibrated samples for temperature compensation */ 391 392 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE); 393 394 sc->tssi_2ghz[0] = (val & 0xff); /* [-4] */ 395 sc->tssi_2ghz[1] = (val >> 8); /* [-3] */ 396 397 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE + 2); 398 399 sc->tssi_2ghz[2] = (val & 0xff); /* [-2] */ 400 sc->tssi_2ghz[3] = (val >> 8); /* [-1] */ 401 402 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE + 2 * 2); 403 404 sc->tssi_2ghz[4] = (val & 0xff); /* [0] */ 405 sc->tssi_2ghz[5] = (val >> 8); /* [+1] */ 406 407 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE + 3 * 2); 408 409 sc->tssi_2ghz[6] = (val & 0xff); /* [+2] */ 410 sc->tssi_2ghz[7] = (val >> 8); /* [+3] */ 411 412 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE + 4 * 2); 413 414 sc->tssi_2ghz[8] = (val & 0xff); /* [+4] */ 415 sc->tssi_step_2ghz = (val >> 8); 416 417 if (sc->tssi_2ghz[4] == 0xff) 418 sc->tx_agc_cntl_2ghz = 0; 419 420 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 421 "%s: EEPROM TSSI 2GHz: 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, " 422 "0x%02x, 0x%02x, step=%d\n", 423 device_get_nameunit(sc->dev), 424 sc->tssi_2ghz[0], sc->tssi_2ghz[1], sc->tssi_2ghz[2], 425 sc->tssi_2ghz[3], sc->tssi_2ghz[4], sc->tssi_2ghz[5], 426 sc->tssi_2ghz[6], sc->tssi_2ghz[7], sc->tssi_2ghz[8], 427 sc->tssi_step_2ghz); 428 429 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE); 430 431 sc->tssi_5ghz[0] = (val & 0xff); /* [-4] */ 432 sc->tssi_5ghz[1] = (val >> 8); /* [-3] */ 433 434 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE + 2); 435 436 sc->tssi_5ghz[2] = (val & 0xff); /* [-2] */ 437 sc->tssi_5ghz[3] = (val >> 8); /* [-1] */ 438 439 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE + 2 * 2); 440 441 sc->tssi_5ghz[4] = (val & 0xff); /* [0] */ 442 sc->tssi_5ghz[5] = (val >> 8); /* [+1] */ 443 444 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE + 3 * 2); 445 446 sc->tssi_5ghz[6] = (val & 0xff); /* [+2] */ 447 sc->tssi_5ghz[7] = (val >> 8); /* [+3] */ 448 449 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE + 4 * 2); 450 451 sc->tssi_5ghz[8] = (val & 0xff); /* [+4] */ 452 sc->tssi_step_5ghz = (val >> 8); 453 454 if (sc->tssi_5ghz[4] == 0xff) 455 sc->tx_agc_cntl_5ghz = 0; 456 457 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 458 "%s: EEPROM TSSI 5GHz: 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, " 459 "0x%02x, 0x%02x, step=%d\n", 460 device_get_nameunit(sc->dev), 461 sc->tssi_5ghz[0], sc->tssi_5ghz[1], sc->tssi_5ghz[2], 462 sc->tssi_5ghz[3], sc->tssi_5ghz[4], sc->tssi_5ghz[5], 463 sc->tssi_5ghz[6], sc->tssi_5ghz[7], sc->tssi_5ghz[8], 464 sc->tssi_step_5ghz); 465 466 /* read default BBP settings */ 467 468 rt2860_io_eeprom_read_multi(sc, RT2860_EEPROM_BBP_BASE, 469 sc->bbp_eeprom, RT2860_SOFTC_BBP_EEPROM_COUNT * 2); 470 471 if ((sc->mac_rev & 0xffff0000) >= 0x30710000) { 472 /* read vendor RF settings */ 473 for (i = 0; i < 10; i++) { 474 val = rt2860_io_eeprom_read(sc, RT3071_EEPROM_RF_BASE + i); 475 sc->rf[i].val = val & 0xff; 476 sc->rf[i].reg = val >> 8; 477// DPRINTF(("RF%d=0x%02x\n", sc->rf[i].reg, 478// sc->rf[i].val)); 479 } 480 } 481 /* read powersave level */ 482 483 val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_POWERSAVE_LEVEL); 484 485 sc->powersave_level = val & 0xff; 486 487 if ((sc->powersave_level & 0xff) == 0xff) 488 printf("%s: invalid EEPROM powersave level\n", 489 device_get_nameunit(sc->dev)); 490 491 RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM, 492 "%s: EEPROM powersave level=0x%02x\n", 493 device_get_nameunit(sc->dev), sc->powersave_level); 494} 495 496/* 497 * rt2860_read_eeprom_txpow_rate_add_delta 498 */ 499uint32_t rt2860_read_eeprom_txpow_rate_add_delta(uint32_t txpow_rate, 500 int8_t delta) 501{ 502 int8_t b4; 503 int i; 504 505 for (i = 0; i < 8; i++) 506 { 507 b4 = txpow_rate & 0xf; 508 b4 += delta; 509 510 if (b4 < 0) 511 b4 = 0; 512 else if (b4 > 0xf) 513 b4 = 0xf; 514 515 txpow_rate = (txpow_rate >> 4) | (b4 << 28); 516 } 517 518 return txpow_rate; 519} 520