Changeset 56c0930 in mainline for uspace/drv/bus/usb/ar9271/hw.c
- Timestamp:
- 2015-02-20T14:33:29Z (9 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4cb0148
- Parents:
- ab365c4
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ar9271/hw.c
rab365c4 r56c0930 245 245 gpio_shift = 2 * gpio; 246 246 247 rc = wmi_reg_ clear_set_bit(ar9271->htc_device, AR9271_GPIO_OE_OUT,247 rc = wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_GPIO_OE_OUT, 248 248 AR9271_GPIO_OE_OUT_ALWAYS << gpio_shift, 249 249 AR9271_GPIO_OE_OUT_ALWAYS << gpio_shift); … … 258 258 static int hw_gpio_set_value(ar9271_t *ar9271, uint32_t gpio, uint32_t value) 259 259 { 260 int rc = wmi_reg_ clear_set_bit(ar9271->htc_device, AR9271_GPIO_IN_OUT,260 int rc = wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_GPIO_IN_OUT, 261 261 (~value & 1) << gpio, 1 << gpio); 262 262 if(rc != EOK) { … … 317 317 318 318 static int hw_set_operating_mode(ar9271_t *ar9271, 319 ieee80211_operating_mode_t op mode)319 ieee80211_operating_mode_t op_mode) 320 320 { 321 321 uint32_t set_bit = 0x10000000; 322 322 323 323 /* NOTICE: Fall-through switch statement! */ 324 switch(op mode) {324 switch(op_mode) { 325 325 case IEEE80211_OPMODE_ADHOC: 326 326 set_bit |= AR9271_OPMODE_ADHOC_MASK; … … 333 333 } 334 334 335 wmi_reg_ clear_set_bit(ar9271->htc_device, AR9271_STATION_ID1,335 wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_STATION_ID1, 336 336 set_bit, 337 337 AR9271_OPMODE_STATION_AP_MASK | AR9271_OPMODE_ADHOC_MASK); 338 339 ar9271->ieee80211_dev->current_op_mode = op_mode; 338 340 339 341 return EOK; … … 352 354 } 353 355 354 static int hw_set_ channel(ar9271_t *ar9271, uint16_t freq)356 static int hw_set_freq(ar9271_t *ar9271, uint16_t freq) 355 357 { 356 358 /* Not supported channel frequency. */ 357 if(freq < IEEE80211_FIRST_ CHANNEL || freq > IEEE80211_MAX_CHANNEL) {359 if(freq < IEEE80211_FIRST_FREQ || freq > IEEE80211_MAX_FREQ) { 358 360 return EINVAL; 359 361 } 360 362 361 363 /* Not supported channel frequency. */ 362 if((freq - IEEE80211_FIRST_ CHANNEL) % IEEE80211_CHANNEL_GAP != 0) {364 if((freq - IEEE80211_FIRST_FREQ) % IEEE80211_CHANNEL_GAP != 0) { 363 365 return EINVAL; 364 366 } 365 367 366 uint32_t result;367 wmi_reg_read(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL, & result);368 uint32_t tx_control; 369 wmi_reg_read(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL, &tx_control); 368 370 wmi_reg_write(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL, 369 result& ~AR9271_PHY_CCK_TX_CTRL_JAPAN);371 tx_control & ~AR9271_PHY_CCK_TX_CTRL_JAPAN); 370 372 371 373 /* Some magic here. */ … … 377 379 to_write); 378 380 381 ar9271->ieee80211_dev->current_freq = freq; 382 383 return EOK; 384 } 385 386 static int hw_set_rx_filter(ar9271_t *ar9271) 387 { 388 uint32_t filter_bits; 389 int rc = wmi_reg_read(ar9271->htc_device, AR9271_RX_FILTER, 390 &filter_bits); 391 if(rc != EOK) { 392 usb_log_error("Failed to read RX filter.\n"); 393 return EINVAL; 394 } 395 396 /* TODO: Do proper filtering here. */ 397 398 filter_bits |= AR9271_RX_FILTER_UNI | AR9271_RX_FILTER_MULTI | 399 AR9271_RX_FILTER_BROAD | AR9271_RX_FILTER_BEACON | 400 AR9271_RX_FILTER_MYBEACON | AR9271_RX_FILTER_PROMISCUOUS; 401 402 rc = wmi_reg_write(ar9271->htc_device, AR9271_RX_FILTER, filter_bits); 403 if(rc != EOK) { 404 usb_log_error("Failed to write RX filter.\n"); 405 return EINVAL; 406 } 407 408 return EOK; 409 } 410 411 int hw_rx_init(ar9271_t *ar9271) 412 { 413 int rc = wmi_reg_write(ar9271->htc_device, AR9271_COMMAND, 414 AR9271_COMMAND_RX_ENABLE); 415 if(rc != EOK) { 416 usb_log_error("Failed to send RX enable command.\n"); 417 return EINVAL; 418 } 419 420 rc = hw_set_rx_filter(ar9271); 421 if(rc != EOK) { 422 usb_log_error("Failed to set RX filtering.\n"); 423 return EINVAL; 424 } 425 426 return EOK; 427 } 428 429 static int hw_activate_phy(ar9271_t *ar9271) 430 { 431 int rc = wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 1); 432 if(rc != EOK) { 433 usb_log_error("Failed to activate set PHY active.\n"); 434 return rc; 435 } 436 437 udelay(1000); 438 439 return EOK; 440 } 441 442 static int hw_init_pll(ar9271_t *ar9271) 443 { 444 uint32_t pll; 445 446 /* Some magic here. */ 447 pll = (0x5 << 10) & 0x00003C00; 448 pll |= (0x2 << 14) & 0x0000C000; /**< 0x2 ~ quarter rate (0x1 half) */ 449 pll |= 0x58 & 0x000003FF; 450 451 return wmi_reg_write(ar9271->htc_device, AR9271_RTC_PLL_CONTROL, pll); 452 } 453 454 static int hw_calibrate(ar9271_t *ar9271) 455 { 456 wmi_reg_set_bit(ar9271->htc_device, AR9271_CARRIER_LEAK_CONTROL, 457 AR9271_CARRIER_LEAK_CALIB); 458 wmi_reg_clear_bit(ar9271->htc_device, AR9271_ADC_CONTROL, 459 AR9271_ADC_CONTROL_OFF_PWDADC); 460 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 461 AR9271_AGC_CONTROL_TX_CALIB); 462 wmi_reg_set_bit(ar9271->htc_device, AR9271_PHY_TPCRG1, 463 AR9271_PHY_TPCRG1_PD_CALIB); 464 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 465 AR9271_AGC_CONTROL_CALIB); 466 467 int rc = hw_read_wait(ar9271, AR9271_AGC_CONTROL, 468 AR9271_AGC_CONTROL_CALIB, 0); 469 if(rc != EOK) { 470 usb_log_error("Failed to wait on calibrate completion.\n"); 471 return rc; 472 } 473 474 wmi_reg_set_bit(ar9271->htc_device, AR9271_ADC_CONTROL, 475 AR9271_ADC_CONTROL_OFF_PWDADC); 476 wmi_reg_clear_bit(ar9271->htc_device, AR9271_CARRIER_LEAK_CONTROL, 477 AR9271_CARRIER_LEAK_CALIB); 478 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 479 AR9271_AGC_CONTROL_TX_CALIB); 480 481 return EOK; 482 } 483 484 static int hw_set_init_values(ar9271_t *ar9271) 485 { 486 int size = sizeof(ar9271_init_array) / sizeof(ar9271_init_array[0]); 487 488 for(int i = 0; i < size; i++) { 489 uint32_t reg_offset = ar9271_init_array[i][0]; 490 uint32_t reg_value = ar9271_init_array[i][1]; 491 wmi_reg_write(ar9271->htc_device, reg_offset, reg_value); 492 } 493 379 494 return EOK; 380 495 } … … 382 497 int hw_reset(ar9271_t *ar9271) 383 498 { 384 int rc = wmi_reg_write(ar9271->htc_device, 499 /* Set physical layer as deactivated. */ 500 int rc = wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 0); 501 if(rc != EOK) { 502 usb_log_error("Failed to set PHY deactivated.\n"); 503 return rc; 504 } 505 506 rc = wmi_reg_write(ar9271->htc_device, 385 507 AR9271_RESET_POWER_DOWN_CONTROL, 386 508 AR9271_RADIO_RF_RESET); … … 391 513 392 514 udelay(50); 515 516 /* TODO: There should be cold reset only if RX or TX is enabled. */ 517 518 rc = hw_init_pll(ar9271); 519 if(rc != EOK) { 520 usb_log_error("Failed to init PLL.\n"); 521 return rc; 522 } 523 524 udelay(500); 525 526 rc = wmi_reg_write(ar9271->htc_device, 527 AR9271_CLOCK_CONTROL, 528 AR9271_MAX_CPU_CLOCK); 529 if(rc != EOK) { 530 usb_log_error("Failed to set CPU clock.\n"); 531 return rc; 532 } 533 534 udelay(100); 393 535 394 536 rc = wmi_reg_write(ar9271->htc_device, … … 403 545 udelay(50); 404 546 405 /* Perform cold reset of device. */ 406 rc = hw_set_reset(ar9271, true); 407 if(rc != EOK) { 408 usb_log_error("Failed to HW cold reset.\n"); 409 return rc; 410 } 547 rc = hw_set_init_values(ar9271); 548 if(rc != EOK) { 549 usb_log_error("Failed to set device init values.\n"); 550 return rc; 551 } 552 553 /* TODO: There should probably be TX power settings. */ 411 554 412 555 /* Set physical layer mode. */ … … 418 561 } 419 562 563 /* TODO: Init EEPROM here. */ 564 420 565 /* Set device operating mode. */ 421 566 rc = hw_set_operating_mode(ar9271, IEEE80211_OPMODE_STATION); … … 425 570 } 426 571 427 /* Set channel . */428 rc = hw_set_ channel(ar9271, IEEE80211_FIRST_CHANNEL);572 /* Set channel frequency. */ 573 rc = hw_set_freq(ar9271, IEEE80211_FIRST_FREQ); 429 574 if(rc != EOK) { 430 575 usb_log_error("Failed to set channel.\n"); … … 444 589 } 445 590 591 /* TODO: Maybe resetting TX queues will be necessary afterwards here. */ 592 593 /* TODO: Setting RX, TX timeouts and others may be necessary here. */ 594 446 595 /* Activate physical layer. */ 447 rc = wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE,1);596 rc = hw_activate_phy(ar9271); 448 597 if(rc != EOK) { 449 598 usb_log_error("Failed to activate physical layer.\n"); 450 599 return rc; 451 600 } 601 602 /* Calibration. */ 603 rc = hw_calibrate(ar9271); 604 if(rc != EOK) { 605 usb_log_error("Failed to calibrate device.\n"); 606 return rc; 607 } 608 609 usb_log_info("HW reset done.\n"); 452 610 453 611 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.