Changeset 1dcc0b9 in mainline for uspace/drv/nic/ar9271/hw.c
- Timestamp:
- 2015-04-06T10:47:51Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d7dadcb4
- Parents:
- 59fa7ab
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/nic/ar9271/hw.c
r59fa7ab r1dcc0b9 43 43 44 44 /** 45 * Try to wait for register value repeatedly until timeout defined by device 46 * is reached. 45 * Try to wait for register value repeatedly until timeout is reached. 47 46 * 48 47 * @param ar9271 Device structure. … … 264 263 } 265 264 265 static int hw_activate_phy(ar9271_t *ar9271) 266 { 267 wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 1); 268 udelay(1000); 269 270 return EOK; 271 } 272 266 273 static int hw_set_operating_mode(ar9271_t *ar9271, 267 274 ieee80211_operating_mode_t op_mode) … … 305 312 static int hw_noise_floor_calibration(ar9271_t *ar9271) 306 313 { 314 uint32_t value; 315 wmi_reg_read(ar9271->htc_device, AR9271_PHY_CAL, &value); 316 value &= 0xFFFFFE00; 317 value |= (((uint32_t) AR9271_CALIB_NOMINAL_VALUE_2GHZ << 1) & 0x1FF); 318 wmi_reg_write(ar9271->htc_device, AR9271_PHY_CAL, value); 319 320 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 321 AR9271_AGC_CONTROL_NF_CALIB_EN); 322 323 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 324 AR9271_AGC_CONTROL_NF_NOT_UPDATE); 325 326 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 327 AR9271_AGC_CONTROL_NF_CALIB); 328 329 int rc = hw_read_wait(ar9271, AR9271_AGC_CONTROL, 330 AR9271_AGC_CONTROL_NF_CALIB, 0); 331 if(rc != EOK) { 332 usb_log_error("Failed to wait for NF calibration.\n"); 333 return rc; 334 } 335 307 336 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 308 337 AR9271_AGC_CONTROL_NF_CALIB_EN); … … 348 377 } 349 378 379 int hw_wakeup(ar9271_t *ar9271) 380 { 381 int rc; 382 383 uint32_t rtc_status; 384 wmi_reg_read(ar9271->htc_device, AR9271_RTC_STATUS, &rtc_status); 385 if((rtc_status & AR9271_RTC_STATUS_MASK) == AR9271_RTC_STATUS_SHUTDOWN) { 386 rc = hw_reset_power_on(ar9271); 387 if(rc != EOK) { 388 usb_log_info("Failed to HW reset power on.\n"); 389 return rc; 390 } 391 392 rc = hw_set_reset(ar9271, false); 393 if(rc != EOK) { 394 usb_log_info("Failed to HW warm reset.\n"); 395 return rc; 396 } 397 } 398 399 wmi_reg_set_bit(ar9271->htc_device, AR9271_RTC_FORCE_WAKE, 400 AR9271_RTC_FORCE_WAKE_ENABLE); 401 402 size_t i; 403 for(i = 0; i < HW_WAIT_LOOPS; i++) { 404 wmi_reg_read(ar9271->htc_device, AR9271_RTC_STATUS, 405 &rtc_status); 406 if((rtc_status & AR9271_RTC_STATUS_MASK) == 407 AR9271_RTC_STATUS_ON) { 408 break; 409 } 410 wmi_reg_set_bit(ar9271->htc_device, AR9271_RTC_FORCE_WAKE, 411 AR9271_RTC_FORCE_WAKE_ENABLE); 412 udelay(50); 413 } 414 415 if(i == HW_WAIT_LOOPS) { 416 return EINVAL; 417 } else { 418 return EOK; 419 } 420 } 421 350 422 int hw_freq_switch(ar9271_t *ar9271, uint16_t freq) 351 423 { … … 361 433 if(rc != EOK) { 362 434 usb_log_error("Failed to HW set frequency.\n"); 435 return rc; 436 } 437 438 rc = hw_activate_phy(ar9271); 439 if(rc != EOK) { 440 usb_log_error("Failed to activate physical layer.\n"); 363 441 return rc; 364 442 } … … 376 454 } 377 455 378 static int hw_set_rx_filter(ar9271_t *ar9271)456 int hw_set_rx_filter(ar9271_t *ar9271, bool assoc) 379 457 { 380 458 uint32_t filter_bits; 381 459 382 /* TODO: Do proper filtering here. */ 460 uint32_t additional_bits = 0; 461 462 if(assoc) { 463 additional_bits |= AR9271_RX_FILTER_MYBEACON; 464 } else { 465 additional_bits |= AR9271_RX_FILTER_BEACON; 466 } 383 467 384 468 filter_bits = AR9271_RX_FILTER_UNI | AR9271_RX_FILTER_MULTI | 385 AR9271_RX_FILTER_BROAD | AR9271_RX_FILTER_BEACON;469 AR9271_RX_FILTER_BROAD | additional_bits; 386 470 387 471 wmi_reg_write(ar9271->htc_device, AR9271_RX_FILTER, filter_bits); 472 473 return EOK; 474 } 475 476 int hw_set_bssid(ar9271_t *ar9271) 477 { 478 ieee80211_dev_t *ieee80211_dev = ar9271->ieee80211_dev; 479 480 nic_address_t bssid; 481 ieee80211_query_bssid(ieee80211_dev, &bssid); 482 483 uint32_t *first_4bytes = (uint32_t *) &bssid.address; 484 uint16_t *last_2bytes = (uint16_t *) &bssid.address[4]; 485 486 wmi_reg_write(ar9271->htc_device, AR9271_BSSID0, 487 uint32_t_le2host(*first_4bytes)); 488 489 wmi_reg_write(ar9271->htc_device, AR9271_BSSID1, 490 uint16_t_le2host(*last_2bytes) | 491 ((ieee80211_get_aid(ieee80211_dev) & 0x3FFF) << 16)); 388 492 389 493 return EOK; … … 395 499 AR9271_COMMAND_RX_ENABLE); 396 500 397 int rc = hw_set_rx_filter(ar9271 );501 int rc = hw_set_rx_filter(ar9271, false); 398 502 if(rc != EOK) { 399 503 usb_log_error("Failed to set RX filtering.\n"); … … 410 514 } 411 515 412 static int hw_activate_phy(ar9271_t *ar9271)413 {414 wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 1);415 udelay(1000);416 417 return EOK;418 }419 420 516 static int hw_init_pll(ar9271_t *ar9271) 421 517 { … … 423 519 424 520 /* Some magic here (set for 2GHz channels). But VERY important :-) */ 425 pll = (0x5 << 10) & 0x00003C00; 426 pll |= 0x2C & 0x000003FF; 521 pll = (0x5 << 10) | 0x2C; 427 522 428 523 wmi_reg_write(ar9271->htc_device, AR9271_RTC_PLL_CONTROL, pll); 429 524 430 return EOK; 431 } 432 433 static int hw_set_init_values(ar9271_t *ar9271) 525 wmi_reg_write(ar9271->htc_device, AR9271_RTC_SLEEP_CLOCK, 526 AR9271_RTC_SLEEP_CLOCK_FORCE_DERIVED); 527 wmi_reg_set_bit(ar9271->htc_device, AR9271_RTC_FORCE_WAKE, 528 AR9271_RTC_FORCE_WAKE_ENABLE); 529 530 return EOK; 531 } 532 533 static void hw_set_init_values(ar9271_t *ar9271) 434 534 { 435 535 uint32_t reg_offset, reg_value; … … 458 558 wmi_reg_write(ar9271->htc_device, reg_offset, reg_value); 459 559 } 460 461 return EOK;462 560 } 463 561 … … 533 631 } 534 632 535 rc = hw_set_init_values(ar9271); 536 if(rc != EOK) { 537 usb_log_error("Failed to set device init values.\n"); 538 return rc; 539 } 633 hw_set_init_values(ar9271); 540 634 541 635 /* Set physical layer mode. */ … … 586 680 /* Byteswap TX and RX data buffer words. */ 587 681 wmi_reg_write(ar9271->htc_device, AR9271_CONFIG, 0xA); 588 589 usb_log_info("HW reset done.\n");590 682 591 683 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.