Changeset a35b458 in mainline for uspace/drv/nic/ar9271/hw.c
- Timestamp:
- 2018-03-02T20:10:49Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/nic/ar9271/hw.c
r3061bc1 ra35b458 57 57 for (size_t i = 0; i < HW_WAIT_LOOPS; i++) { 58 58 udelay(HW_WAIT_TIME_US); 59 59 60 60 uint32_t result; 61 61 wmi_reg_read(ar9271->htc_device, offset, &result); … … 63 63 return EOK; 64 64 } 65 65 66 66 return ETIMEOUT; 67 67 } … … 84 84 } 85 85 }; 86 86 87 87 wmi_reg_buffer_write(ar9271->htc_device, buffer, 88 88 sizeof(buffer) / sizeof(wmi_reg_t)); 89 89 90 90 udelay(2); 91 91 92 92 wmi_reg_write(ar9271->htc_device, AR9271_RC, 0); 93 93 wmi_reg_write(ar9271->htc_device, AR9271_RTC_RESET, 1); 94 94 95 95 errno_t rc = hw_read_wait(ar9271, 96 96 AR9271_RTC_STATUS, … … 101 101 return rc; 102 102 } 103 103 104 104 return EOK; 105 105 } … … 108 108 { 109 109 uint32_t reset_value = AR9271_RTC_RC_MAC_WARM; 110 110 111 111 if (cold) 112 112 reset_value |= AR9271_RTC_RC_MAC_COLD; 113 113 114 114 wmi_reg_t buffer[] = { 115 115 { … … 127 127 } 128 128 }; 129 129 130 130 wmi_reg_buffer_write(ar9271->htc_device, buffer, 131 131 sizeof(buffer) / sizeof(wmi_reg_t)); 132 132 133 133 udelay(100); 134 134 135 135 wmi_reg_write(ar9271->htc_device, AR9271_RTC_RC, 0); 136 136 137 137 errno_t rc = hw_read_wait(ar9271, AR9271_RTC_RC, AR9271_RTC_RC_MASK, 0); 138 138 if (rc != EOK) { … … 140 140 return rc; 141 141 } 142 142 143 143 wmi_reg_write(ar9271->htc_device, AR9271_RC, 0); 144 144 wmi_reg_clear_bit(ar9271->htc_device, AR9271_STATION_ID1, 145 145 AR9271_STATION_ID1_POWER_SAVING); 146 146 147 147 return EOK; 148 148 } … … 152 152 uint32_t value; 153 153 nic_address_t ar9271_address; 154 154 155 155 for (unsigned int i = 0; i < 3; i++) { 156 156 wmi_reg_read(ar9271->htc_device, 157 157 AR9271_EEPROM_MAC_ADDR_START + i * 4, &value); 158 158 159 159 uint16_t two_bytes = uint16_t_be2host(value); 160 160 ar9271_address.address[2*i] = two_bytes >> 8; 161 161 ar9271_address.address[2*i+1] = two_bytes & 0xff; 162 162 } 163 163 164 164 nic_t *nic = nic_get_from_ddf_dev(ar9271->ddf_dev); 165 165 166 166 errno_t rc = nic_report_address(nic, &ar9271_address); 167 167 if (rc != EOK) { … … 169 169 return rc; 170 170 } 171 171 172 172 return EOK; 173 173 } … … 176 176 { 177 177 uint32_t address; 178 178 179 179 if (gpio > 11) 180 180 address = AR9271_GPIO_OUT_MUX3; … … 183 183 else 184 184 address = AR9271_GPIO_OUT_MUX1; 185 185 186 186 uint32_t gpio_shift = (gpio % 6) * 5; 187 187 188 188 uint32_t temp; 189 189 wmi_reg_read(ar9271->htc_device, address, &temp); 190 190 191 191 temp = ((temp & 0x1f0) << 1) | (temp & ~0x1f0); 192 192 temp &= ~(0x1f << gpio_shift); 193 193 temp |= (type << gpio_shift); 194 194 195 195 wmi_reg_write(ar9271->htc_device, address, temp); 196 196 197 197 gpio_shift = 2 * gpio; 198 198 199 199 wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_GPIO_OE_OUT, 200 200 AR9271_GPIO_OE_OUT_ALWAYS << gpio_shift, 201 201 AR9271_GPIO_OE_OUT_ALWAYS << gpio_shift); 202 202 203 203 return EOK; 204 204 } … … 225 225 return rc; 226 226 } 227 227 228 228 rc = hw_set_reset(ar9271, false); 229 229 if (rc != EOK) { … … 231 231 return rc; 232 232 } 233 233 234 234 rc = hw_addr_init(ar9271); 235 235 if (rc != EOK) { … … 237 237 return rc; 238 238 } 239 239 240 240 return EOK; 241 241 } … … 249 249 return rc; 250 250 } 251 251 252 252 rc = hw_gpio_set_value(ar9271, AR9271_LED_PIN, 0); 253 253 if (rc != EOK) { … … 255 255 return rc; 256 256 } 257 257 258 258 return EOK; 259 259 } … … 263 263 wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 1); 264 264 udelay(1000); 265 265 266 266 return EOK; 267 267 } … … 271 271 { 272 272 uint32_t set_bit = 0x10000000; 273 273 274 274 switch(op_mode) { 275 275 case IEEE80211_OPMODE_ADHOC: … … 286 286 AR9271_CONFIG_ADHOC); 287 287 } 288 288 289 289 wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_STATION_ID1, 290 290 set_bit, AR9271_OPMODE_STATION_AP_MASK | AR9271_OPMODE_ADHOC_MASK); 291 291 292 292 ieee80211_report_current_op_mode(ar9271->ieee80211_dev, op_mode); 293 293 294 294 return EOK; 295 295 } … … 302 302 return rc; 303 303 } 304 304 305 305 return EOK; 306 306 } … … 310 310 uint32_t value; 311 311 wmi_reg_read(ar9271->htc_device, AR9271_PHY_CAL, &value); 312 312 313 313 value &= 0xfffffe00; 314 314 value |= (((uint32_t) AR9271_CALIB_NOMINAL_VALUE_2GHZ << 1) & 0x1ff); 315 315 316 316 wmi_reg_write(ar9271->htc_device, AR9271_PHY_CAL, value); 317 317 318 318 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 319 319 AR9271_AGC_CONTROL_NF_CALIB_EN); 320 320 321 321 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 322 322 AR9271_AGC_CONTROL_NF_NOT_UPDATE); 323 323 324 324 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 325 325 AR9271_AGC_CONTROL_NF_CALIB); 326 326 327 327 errno_t rc = hw_read_wait(ar9271, AR9271_AGC_CONTROL, 328 328 AR9271_AGC_CONTROL_NF_CALIB, 0); … … 331 331 return rc; 332 332 } 333 333 334 334 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 335 335 AR9271_AGC_CONTROL_NF_CALIB_EN); 336 336 337 337 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 338 338 AR9271_AGC_CONTROL_NF_NOT_UPDATE); 339 339 340 340 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 341 341 AR9271_AGC_CONTROL_NF_CALIB); 342 342 343 343 return EOK; 344 344 } … … 349 349 if ((freq < IEEE80211_FIRST_FREQ) || (freq > IEEE80211_MAX_FREQ)) 350 350 return EINVAL; 351 351 352 352 /* Not supported channel frequency. */ 353 353 if ((freq - IEEE80211_FIRST_FREQ) % IEEE80211_CHANNEL_GAP != 0) 354 354 return EINVAL; 355 355 356 356 uint32_t tx_control; 357 357 wmi_reg_read(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL, &tx_control); 358 358 wmi_reg_write(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL, 359 359 tx_control & ~AR9271_PHY_CCK_TX_CTRL_JAPAN); 360 360 361 361 /* Some magic here. */ 362 362 uint32_t synth_ctl; … … 365 365 uint32_t channel_select = (freq * 0x10000) / 15; 366 366 synth_ctl = synth_ctl | (1 << 29) | (1 << 28) | channel_select; 367 367 368 368 wmi_reg_write(ar9271->htc_device, AR9271_PHY_SYNTH_CONTROL, synth_ctl); 369 369 370 370 ieee80211_report_current_freq(ar9271->ieee80211_dev, freq); 371 371 372 372 return EOK; 373 373 } … … 376 376 { 377 377 wmi_reg_write(ar9271->htc_device, AR9271_PHY_RFBUS_KILL, 0x1); 378 378 379 379 errno_t rc = hw_read_wait(ar9271, AR9271_PHY_RFBUS_GRANT, 0x1, 0x1); 380 380 if (rc != EOK) { … … 382 382 return rc; 383 383 } 384 384 385 385 rc = hw_set_freq(ar9271, freq); 386 386 if (rc != EOK) { … … 388 388 return rc; 389 389 } 390 390 391 391 rc = hw_activate_phy(ar9271); 392 392 if (rc != EOK) { … … 394 394 return rc; 395 395 } 396 396 397 397 udelay(1000); 398 398 wmi_reg_write(ar9271->htc_device, AR9271_PHY_RFBUS_KILL, 0x0); 399 399 400 400 rc = hw_noise_floor_calibration(ar9271); 401 401 if (rc != EOK) { … … 403 403 return rc; 404 404 } 405 405 406 406 return EOK; 407 407 } … … 410 410 { 411 411 uint32_t additional_bits = 0; 412 412 413 413 if (assoc) 414 414 additional_bits |= AR9271_RX_FILTER_MYBEACON; 415 415 else 416 416 additional_bits |= AR9271_RX_FILTER_BEACON; 417 417 418 418 uint32_t filter_bits = AR9271_RX_FILTER_UNI | 419 419 AR9271_RX_FILTER_MULTI | AR9271_RX_FILTER_BROAD | 420 420 additional_bits; 421 421 422 422 wmi_reg_write(ar9271->htc_device, AR9271_RX_FILTER, filter_bits); 423 423 424 424 return EOK; 425 425 } … … 428 428 { 429 429 ieee80211_dev_t *ieee80211_dev = ar9271->ieee80211_dev; 430 430 431 431 nic_address_t bssid; 432 432 ieee80211_query_bssid(ieee80211_dev, &bssid); 433 433 434 434 uint32_t *first_4bytes = (uint32_t *) &bssid.address; 435 435 uint16_t *last_2bytes = (uint16_t *) &bssid.address[4]; 436 436 437 437 wmi_reg_write(ar9271->htc_device, AR9271_BSSID0, 438 438 uint32_t_le2host(*first_4bytes)); 439 439 440 440 wmi_reg_write(ar9271->htc_device, AR9271_BSSID1, 441 441 uint16_t_le2host(*last_2bytes) | 442 442 ((ieee80211_get_aid(ieee80211_dev) & 0x3fff) << 16)); 443 443 444 444 return EOK; 445 445 } … … 449 449 wmi_reg_write(ar9271->htc_device, AR9271_COMMAND, 450 450 AR9271_COMMAND_RX_ENABLE); 451 451 452 452 errno_t rc = hw_set_rx_filter(ar9271, false); 453 453 if (rc != EOK) { … … 455 455 return rc; 456 456 } 457 457 458 458 wmi_reg_write(ar9271->htc_device, AR9271_MULTICAST_FILTER1, ~0); 459 459 wmi_reg_write(ar9271->htc_device, AR9271_MULTICAST_FILTER2, ~0); 460 460 461 461 /* Disable RX blocking. */ 462 462 wmi_reg_clear_bit(ar9271->htc_device, AR9271_DIAG, (0x20 | 0x02000000)); 463 463 464 464 return EOK; 465 465 } … … 469 469 /* Some magic here (set for 2GHz channels). But VERY important :-) */ 470 470 uint32_t pll = (0x5 << 10) | 0x2c; 471 471 472 472 wmi_reg_write(ar9271->htc_device, AR9271_RTC_PLL_CONTROL, pll); 473 473 474 474 wmi_reg_write(ar9271->htc_device, AR9271_RTC_SLEEP_CLOCK, 475 475 AR9271_RTC_SLEEP_CLOCK_FORCE_DERIVED); 476 476 wmi_reg_set_bit(ar9271->htc_device, AR9271_RTC_FORCE_WAKE, 477 477 AR9271_RTC_FORCE_WAKE_ENABLE); 478 478 479 479 return EOK; 480 480 } … … 484 484 uint32_t reg_offset; 485 485 uint32_t reg_value; 486 486 487 487 size_t size = ARRAY_SIZE(ar9271_2g_mode_array); 488 488 489 489 for (size_t i = 0; i < size; i++) { 490 490 reg_offset = ar9271_2g_mode_array[i][0]; … … 492 492 wmi_reg_write(ar9271->htc_device, reg_offset, reg_value); 493 493 } 494 494 495 495 size = ARRAY_SIZE(ar9271_2g_tx_array); 496 496 497 497 for (size_t i = 0; i < size; i++) { 498 498 reg_offset = ar9271_2g_tx_array[i][0]; … … 500 500 wmi_reg_write(ar9271->htc_device, reg_offset, reg_value); 501 501 } 502 502 503 503 size = ARRAY_SIZE(ar9271_init_array); 504 504 505 505 for (size_t i = 0; i < size; i++) { 506 506 reg_offset = ar9271_init_array[i][0]; … … 522 522 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 523 523 AR9271_AGC_CONTROL_CALIB); 524 524 525 525 errno_t rc = hw_read_wait(ar9271, AR9271_AGC_CONTROL, 526 526 AR9271_AGC_CONTROL_CALIB, 0); … … 529 529 return rc; 530 530 } 531 531 532 532 wmi_reg_set_bit(ar9271->htc_device, AR9271_ADC_CONTROL, 533 533 AR9271_ADC_CONTROL_OFF_PWDADC); … … 536 536 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 537 537 AR9271_AGC_CONTROL_TX_CALIB); 538 538 539 539 return EOK; 540 540 } … … 544 544 /* Set physical layer as deactivated. */ 545 545 wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 0); 546 546 547 547 if(ar9271->starting_up) { 548 548 wmi_reg_write(ar9271->htc_device, 549 549 AR9271_RESET_POWER_DOWN_CONTROL, 550 550 AR9271_RADIO_RF_RESET); 551 551 552 552 udelay(50); 553 553 } 554 554 555 555 /* Cold reset when RX is enabled. */ 556 556 uint32_t config_reg; … … 558 558 if (config_reg & AR9271_COMMAND_RX_ENABLE) 559 559 hw_set_reset(ar9271, true); 560 560 561 561 errno_t rc = hw_init_pll(ar9271); 562 562 if (rc != EOK) { … … 564 564 return rc; 565 565 } 566 566 567 567 udelay(500); 568 568 569 569 wmi_reg_write(ar9271->htc_device, AR9271_CLOCK_CONTROL, 570 570 AR9271_MAX_CPU_CLOCK); 571 571 572 572 udelay(100); 573 573 574 574 if (ar9271->starting_up) { 575 575 wmi_reg_write(ar9271->htc_device, 576 576 AR9271_RESET_POWER_DOWN_CONTROL, 577 577 AR9271_GATE_MAC_CONTROL); 578 578 579 579 udelay(50); 580 580 } 581 581 582 582 hw_set_init_values(ar9271); 583 583 584 584 /* Set physical layer mode. */ 585 585 wmi_reg_write(ar9271->htc_device, AR9271_PHY_MODE, 586 586 AR9271_PHY_MODE_DYNAMIC); 587 587 588 588 /* Reset device operating mode. */ 589 589 rc = hw_reset_operating_mode(ar9271); … … 592 592 return rc; 593 593 } 594 594 595 595 /* Set initial channel frequency. */ 596 596 rc = hw_set_freq(ar9271, IEEE80211_FIRST_FREQ); … … 599 599 return rc; 600 600 } 601 601 602 602 /* Initialize transmission queues. */ 603 603 for (unsigned int i = 0; i < AR9271_QUEUES_COUNT; i++) { … … 605 605 AR9271_QUEUE_BASE_MASK + (i << 2), 1 << i); 606 606 } 607 607 608 608 /* Activate physical layer. */ 609 609 rc = hw_activate_phy(ar9271); … … 612 612 return rc; 613 613 } 614 614 615 615 /* Calibration. */ 616 616 rc = hw_calibration(ar9271); … … 619 619 return rc; 620 620 } 621 621 622 622 rc = hw_noise_floor_calibration(ar9271); 623 623 if (rc != EOK) { … … 625 625 return rc; 626 626 } 627 627 628 628 /* Byteswap TX and RX data buffer words. */ 629 629 wmi_reg_write(ar9271->htc_device, AR9271_CONFIG, 0xA); 630 630 631 631 return EOK; 632 632 } … … 645 645 return rc; 646 646 } 647 647 648 648 rc = hw_init_led(ar9271); 649 649 if (rc != EOK) { … … 651 651 return rc; 652 652 } 653 653 654 654 usb_log_info("HW initialization finished successfully.\n"); 655 656 return EOK; 657 } 655 656 return EOK; 657 }
Note:
See TracChangeset
for help on using the changeset viewer.