Changeset ab365c4 in mainline for uspace/drv/bus/usb/ar9271/hw.c
- Timestamp:
- 2015-02-13T12:15:00Z (9 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 56c0930
- Parents:
- 462054a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ar9271/hw.c
r462054a rab365c4 36 36 #include <unistd.h> 37 37 #include <nic.h> 38 #include <ieee80211.h> 38 39 39 40 #include "hw.h" … … 76 77 static int hw_reset_power_on(ar9271_t *ar9271) 77 78 { 78 int rc = wmi_reg_write(ar9271->htc_device, AR9271_RTC_FORCE_WAKE,79 AR9271_RTC_FORCE_WAKE_ENABLE | AR9271_RTC_FORCE_WAKE_ON_INT);80 if(rc != EOK) {81 usb_log_error("Failed to bring up RTC register.\n");82 return rc;83 }84 85 79 wmi_reg_t buffer[] = { 86 80 { … … 99 93 }; 100 94 101 rc = wmi_reg_buffer_write(ar9271->htc_device, buffer,95 int rc = wmi_reg_buffer_write(ar9271->htc_device, buffer, 102 96 sizeof(buffer) / sizeof(wmi_reg_t)); 103 97 if(rc != EOK) { … … 132 126 } 133 127 134 static int hw_warm_reset(ar9271_t *ar9271) 135 { 128 static int hw_set_reset(ar9271_t *ar9271, bool cold) 129 { 130 uint32_t reset_value = AR9271_RTC_RC_MAC_WARM; 131 132 if(cold) { 133 reset_value |= AR9271_RTC_RC_MAC_COLD; 134 } 135 136 136 wmi_reg_t buffer[] = { 137 137 { … … 146 146 { 147 147 .offset = AR9271_RTC_RC, 148 .value = 1148 .value = reset_value 149 149 } 150 150 }; … … 202 202 } 203 203 204 nic_t *nic = nic_get_from_ddf_dev(ar9271->ddf_dev ice);204 nic_t *nic = nic_get_from_ddf_dev(ar9271->ddf_dev); 205 205 206 206 rc = nic_report_address(nic, &ar9271_address); … … 269 269 270 270 /** 271 * Hardware resetof AR9271 device.271 * Hardware init procedure of AR9271 device. 272 272 * 273 273 * @param ar9271 Device structure. … … 275 275 * @return EOK if succeed, negative error code otherwise. 276 276 */ 277 static int hw_ reset(ar9271_t *ar9271)277 static int hw_init_proc(ar9271_t *ar9271) 278 278 { 279 279 int rc = hw_reset_power_on(ar9271); … … 283 283 } 284 284 285 rc = hw_ warm_reset(ar9271);285 rc = hw_set_reset(ar9271, false); 286 286 if(rc != EOK) { 287 287 usb_log_error("Failed to HW warm reset.\n"); … … 310 310 if(rc != EOK) { 311 311 usb_log_error("Failed to init bring up GPIO led.\n"); 312 return rc; 313 } 314 315 return EOK; 316 } 317 318 static int hw_set_operating_mode(ar9271_t *ar9271, 319 ieee80211_operating_mode_t opmode) 320 { 321 uint32_t set_bit = 0x10000000; 322 323 /* NOTICE: Fall-through switch statement! */ 324 switch(opmode) { 325 case IEEE80211_OPMODE_ADHOC: 326 set_bit |= AR9271_OPMODE_ADHOC_MASK; 327 case IEEE80211_OPMODE_MESH: 328 case IEEE80211_OPMODE_AP: 329 set_bit |= AR9271_OPMODE_STATION_AP_MASK; 330 case IEEE80211_OPMODE_STATION: 331 wmi_reg_clear_bit(ar9271->htc_device, AR9271_CONFIG, 332 AR9271_CONFIG_ADHOC); 333 } 334 335 wmi_reg_clear_set_bit(ar9271->htc_device, AR9271_STATION_ID1, 336 set_bit, 337 AR9271_OPMODE_STATION_AP_MASK | AR9271_OPMODE_ADHOC_MASK); 338 339 return EOK; 340 } 341 342 static uint32_t hw_reverse_bits(uint32_t value, uint32_t count) 343 { 344 uint32_t ret_val = 0; 345 346 for(size_t i = 0; i < count; i++) { 347 ret_val = (ret_val << 1) | (value & 1); 348 value >>= 1; 349 } 350 351 return ret_val; 352 } 353 354 static int hw_set_channel(ar9271_t *ar9271, uint16_t freq) 355 { 356 /* Not supported channel frequency. */ 357 if(freq < IEEE80211_FIRST_CHANNEL || freq > IEEE80211_MAX_CHANNEL) { 358 return EINVAL; 359 } 360 361 /* Not supported channel frequency. */ 362 if((freq - IEEE80211_FIRST_CHANNEL) % IEEE80211_CHANNEL_GAP != 0) { 363 return EINVAL; 364 } 365 366 uint32_t result; 367 wmi_reg_read(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL, &result); 368 wmi_reg_write(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL, 369 result & ~AR9271_PHY_CCK_TX_CTRL_JAPAN); 370 371 /* Some magic here. */ 372 uint32_t channel = hw_reverse_bits( 373 (((((freq - 672) * 2 - 3040) / 10) << 2) & 0xFF), 8); 374 uint32_t to_write = (channel << 8) | 33; 375 376 wmi_reg_write(ar9271->htc_device, AR9271_PHY_BASE + (0x37 << 2), 377 to_write); 378 379 return EOK; 380 } 381 382 int hw_reset(ar9271_t *ar9271) 383 { 384 int rc = wmi_reg_write(ar9271->htc_device, 385 AR9271_RESET_POWER_DOWN_CONTROL, 386 AR9271_RADIO_RF_RESET); 387 if(rc != EOK) { 388 usb_log_error("Failed to reset radio rf.\n"); 389 return rc; 390 } 391 392 udelay(50); 393 394 rc = wmi_reg_write(ar9271->htc_device, 395 AR9271_RESET_POWER_DOWN_CONTROL, 396 AR9271_GATE_MAC_CONTROL); 397 if(rc != EOK) { 398 usb_log_error("Failed to set the gate reset controls for MAC." 399 "\n"); 400 return rc; 401 } 402 403 udelay(50); 404 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 } 411 412 /* Set physical layer mode. */ 413 rc = wmi_reg_write(ar9271->htc_device, AR9271_PHY_MODE, 414 AR9271_PHY_MODE_DYNAMIC | AR9271_PHY_MODE_2G); 415 if(rc != EOK) { 416 usb_log_error("Failed to set physical layer mode.\n"); 417 return rc; 418 } 419 420 /* Set device operating mode. */ 421 rc = hw_set_operating_mode(ar9271, IEEE80211_OPMODE_STATION); 422 if(rc != EOK) { 423 usb_log_error("Failed to set opmode to station.\n"); 424 return rc; 425 } 426 427 /* Set channel. */ 428 rc = hw_set_channel(ar9271, IEEE80211_FIRST_CHANNEL); 429 if(rc != EOK) { 430 usb_log_error("Failed to set channel.\n"); 431 return rc; 432 } 433 434 /* Initialize transmission queues. */ 435 for(int i = 0; i < AR9271_QUEUES_COUNT; i++) { 436 rc = wmi_reg_write(ar9271->htc_device, 437 AR9271_QUEUE_BASE_MASK + (i << 2), 438 1 << i); 439 if(rc != EOK) { 440 usb_log_error("Failed to initialize transmission queue." 441 "\n"); 442 return rc; 443 } 444 } 445 446 /* Activate physical layer. */ 447 rc = wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 1); 448 if(rc != EOK) { 449 usb_log_error("Failed to activate physical layer.\n"); 312 450 return rc; 313 451 } … … 325 463 int hw_init(ar9271_t *ar9271) 326 464 { 327 int rc = hw_ reset(ar9271);465 int rc = hw_init_proc(ar9271); 328 466 if(rc != EOK) { 329 467 usb_log_error("Failed to HW reset device.\n");
Note:
See TracChangeset
for help on using the changeset viewer.