Changeset 1dcc0b9 in mainline for uspace/drv/nic
- Timestamp:
- 2015-04-06T10:47:51Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d7dadcb4
- Parents:
- 59fa7ab
- Location:
- uspace/drv/nic/ar9271
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/nic/ar9271/Makefile
r59fa7ab r1dcc0b9 34 34 $(LIBDRV_PREFIX)/libdrv.a \ 35 35 $(LIBNIC_PREFIX)/libnic.a \ 36 $(LIBIEEE80211_PREFIX)/libieee80211.a 36 $(LIBIEEE80211_PREFIX)/libieee80211.a \ 37 $(LIBCRYPTO_PREFIX)/libcrypto.a 37 38 38 39 EXTRA_CFLAGS += \ … … 43 44 -I$(LIBNIC_PREFIX)/include \ 44 45 -I$(LIBIEEE80211_PREFIX)/include \ 46 -I$(LIBCRYPTO_PREFIX) 45 47 46 48 BINARY = ar9271 -
uspace/drv/nic/ar9271/ar9271.c
r59fa7ab r1dcc0b9 105 105 static int ar9271_ieee80211_set_freq(ieee80211_dev_t *ieee80211_dev, 106 106 uint16_t freq); 107 static int ar9271_ieee80211_bssid_change(ieee80211_dev_t *ieee80211_dev); 108 static int ar9271_ieee80211_key_config(ieee80211_dev_t *ieee80211_dev, 109 ieee80211_key_config_t *key_conf, bool insert); 107 110 108 111 static driver_ops_t ar9271_driver_ops = { … … 118 121 .start = ar9271_ieee80211_start, 119 122 .tx_handler = ar9271_ieee80211_tx_handler, 120 .set_freq = ar9271_ieee80211_set_freq 123 .set_freq = ar9271_ieee80211_set_freq, 124 .bssid_change = ar9271_ieee80211_bssid_change, 125 .key_config = ar9271_ieee80211_key_config 121 126 }; 122 127 … … 186 191 * 187 192 */ 188 static int ar9271_on_multicast_mode_change(nic_t *nic, nic_multicast_mode_t mode,189 193 static int ar9271_on_multicast_mode_change(nic_t *nic, 194 nic_multicast_mode_t mode, const nic_address_t *addr, size_t addr_cnt) 190 195 { 191 196 /* … … 249 254 * 250 255 */ 251 static int ar9271_on_broadcast_mode_change(nic_t *nic, nic_broadcast_mode_t mode) 256 static int ar9271_on_broadcast_mode_change(nic_t *nic, 257 nic_broadcast_mode_t mode) 252 258 { 253 259 /* … … 271 277 } 272 278 279 static bool ar9271_rx_status_error(uint8_t status) 280 { 281 return (status & AR9271_RX_ERROR_PHY) || (status & AR9271_RX_ERROR_CRC); 282 } 283 273 284 static int ar9271_data_polling(void *arg) 274 285 { 286 assert(arg); 287 275 288 ar9271_t *ar9271 = (ar9271_t *) arg; 276 289 … … 282 295 if(htc_read_data_message(ar9271->htc_device, 283 296 buffer, buffer_size, &transferred_size) == EOK) { 284 ath_usb_data_header_t *data_header =285 (ath_usb_data_header_t *) buffer;286 287 /* Invalid packet. */288 if(data_header->tag != uint16_t_le2host(RX_TAG)) {289 continue;290 }291 292 297 size_t strip_length = 293 298 sizeof(ath_usb_data_header_t) + 294 299 sizeof(htc_frame_header_t) + 295 HTC_RX_HEADER_LENGTH;300 sizeof(htc_rx_status_t); 296 301 297 /* TODO: RX header inspection. */ 302 if(transferred_size < strip_length) 303 continue; 304 305 ath_usb_data_header_t *data_header = 306 (ath_usb_data_header_t *) buffer; 307 308 /* Invalid packet. */ 309 if(data_header->tag != uint16_t_le2host(RX_TAG)) 310 continue; 311 312 htc_rx_status_t *rx_status = 313 (htc_rx_status_t *) ((void *) buffer + 314 sizeof(ath_usb_data_header_t) + 315 sizeof(htc_frame_header_t)); 316 317 uint16_t data_length = 318 uint16_t_be2host(rx_status->data_length); 319 320 int16_t payload_length = 321 transferred_size - strip_length; 322 323 if(payload_length - data_length < 0) 324 continue; 325 326 if(ar9271_rx_status_error(rx_status->status)) 327 continue; 328 298 329 void *strip_buffer = buffer + strip_length; 299 330 300 331 ieee80211_rx_handler(ar9271->ieee80211_dev, 301 332 strip_buffer, 302 transferred_size - strip_length);333 payload_length); 303 334 } 304 335 } … … 316 347 uint16_t freq) 317 348 { 349 assert(ieee80211_dev); 350 318 351 ar9271_t *ar9271 = (ar9271_t *) ieee80211_get_specific(ieee80211_dev); 352 353 //hw_wakeup(ar9271); 319 354 320 355 wmi_send_command(ar9271->htc_device, WMI_DISABLE_INTR, NULL, 0, NULL); … … 344 379 } 345 380 381 static int ar9271_ieee80211_bssid_change(ieee80211_dev_t *ieee80211_dev) 382 { 383 assert(ieee80211_dev); 384 385 ar9271_t *ar9271 = (ar9271_t *) ieee80211_get_specific(ieee80211_dev); 386 387 /* Check if we are connected or disconnected. */ 388 if(ieee80211_is_connected(ieee80211_dev)) { 389 nic_address_t bssid; 390 ieee80211_query_bssid(ieee80211_dev, &bssid); 391 392 htc_sta_msg_t sta_msg; 393 memset(&sta_msg, 0, sizeof(htc_sta_msg_t)); 394 sta_msg.is_vif_sta = 0; 395 sta_msg.max_ampdu = 396 host2uint16_t_be(1 << IEEE80211_MAX_AMPDU_FACTOR); 397 sta_msg.sta_index = 1; 398 sta_msg.vif_index = 0; 399 memcpy(&sta_msg.addr, bssid.address, ETH_ADDR); 400 401 wmi_send_command(ar9271->htc_device, WMI_NODE_CREATE, 402 (uint8_t *) &sta_msg, sizeof(sta_msg), NULL); 403 404 htc_rate_msg_t rate_msg; 405 memset(&rate_msg, 0, sizeof(htc_rate_msg_t)); 406 rate_msg.sta_index = 1; 407 rate_msg.is_new = 1; 408 rate_msg.legacy_rates_count = 409 ARRAY_SIZE(ieee80211bg_data_rates); 410 memcpy(&rate_msg.legacy_rates, 411 ieee80211bg_data_rates, 412 ARRAY_SIZE(ieee80211bg_data_rates)); 413 414 wmi_send_command(ar9271->htc_device, WMI_RC_RATE_UPDATE, 415 (uint8_t *) &rate_msg, sizeof(rate_msg), NULL); 416 417 hw_set_rx_filter(ar9271, true); 418 } else { 419 uint8_t station_id = 1; 420 wmi_send_command(ar9271->htc_device, WMI_NODE_REMOVE, 421 &station_id, sizeof(station_id), NULL); 422 423 hw_set_rx_filter(ar9271, false); 424 } 425 426 hw_set_bssid(ar9271); 427 428 return EOK; 429 } 430 431 static int ar9271_ieee80211_key_config(ieee80211_dev_t *ieee80211_dev, 432 ieee80211_key_config_t *key_conf, bool insert) 433 { 434 assert(ieee80211_dev); 435 assert(key_conf); 436 437 ar9271_t *ar9271 = (ar9271_t *) ieee80211_get_specific(ieee80211_dev); 438 439 uint32_t key[5]; 440 uint32_t key_type; 441 uint32_t reg_ptr; 442 void *data_start; 443 444 if(insert) { 445 nic_address_t bssid; 446 ieee80211_query_bssid(ieee80211_dev, &bssid); 447 448 switch(key_conf->suite) { 449 case IEEE80211_SECURITY_SUITE_WEP40: 450 key_type = AR9271_KEY_TABLE_TYPE_WEP40; 451 break; 452 case IEEE80211_SECURITY_SUITE_WEP104: 453 key_type = AR9271_KEY_TABLE_TYPE_WEP104; 454 break; 455 case IEEE80211_SECURITY_SUITE_TKIP: 456 key_type = AR9271_KEY_TABLE_TYPE_TKIP; 457 break; 458 case IEEE80211_SECURITY_SUITE_CCMP: 459 key_type = AR9271_KEY_TABLE_TYPE_CCMP; 460 break; 461 default: 462 key_type = -1; 463 } 464 465 if(key_conf->flags & IEEE80211_KEY_FLAG_TYPE_PAIRWISE) { 466 reg_ptr = AR9271_KEY_TABLE_STA; 467 } else { 468 reg_ptr = AR9271_KEY_TABLE_GRP; 469 } 470 471 if(key_conf->suite == IEEE80211_SECURITY_SUITE_TKIP) { 472 // TODO 473 } else { 474 data_start = (void *) key_conf->data; 475 476 key[0] = uint32_t_le2host( 477 *((uint32_t *) data_start)); 478 key[1] = uint16_t_le2host( 479 *((uint16_t *) (data_start + 4))); 480 key[2] = uint32_t_le2host( 481 *((uint32_t *) (data_start + 6))); 482 key[3] = uint16_t_le2host( 483 *((uint16_t *) (data_start + 10))); 484 key[4] = uint32_t_le2host( 485 *((uint32_t *) (data_start + 12))); 486 487 if(key_conf->suite == IEEE80211_SECURITY_SUITE_WEP40 || 488 key_conf->suite == IEEE80211_SECURITY_SUITE_WEP104) { 489 key[4] &= 0xFF; 490 } 491 492 wmi_reg_write(ar9271->htc_device, reg_ptr + 0, key[0]); 493 wmi_reg_write(ar9271->htc_device, reg_ptr + 4, key[1]); 494 wmi_reg_write(ar9271->htc_device, reg_ptr + 8, key[2]); 495 wmi_reg_write(ar9271->htc_device, reg_ptr + 12, key[3]); 496 wmi_reg_write(ar9271->htc_device, reg_ptr + 16, key[4]); 497 wmi_reg_write(ar9271->htc_device, reg_ptr + 20, 498 key_type); 499 } 500 501 uint32_t macL, macH; 502 if(key_conf->flags & IEEE80211_KEY_FLAG_TYPE_PAIRWISE) { 503 data_start = (void *) bssid.address; 504 macL = uint32_t_le2host(*((uint32_t *) data_start)); 505 macH = uint16_t_le2host(*((uint16_t *) 506 (data_start + 4))); 507 } else { 508 macL = macH = 0; 509 } 510 511 macL >>= 1; 512 macL |= (macH & 1) << 31; 513 macH >>= 1; 514 macH |= 0x8000; 515 516 wmi_reg_write(ar9271->htc_device, reg_ptr + 24, macL); 517 wmi_reg_write(ar9271->htc_device, reg_ptr + 28, macH); 518 519 if(key_conf->flags & IEEE80211_KEY_FLAG_TYPE_GROUP) 520 ieee80211_setup_key_confirm(ieee80211_dev, true); 521 } else { 522 // TODO 523 } 524 525 return EOK; 526 } 527 346 528 static int ar9271_ieee80211_tx_handler(ieee80211_dev_t *ieee80211_dev, 347 529 void *buffer, size_t buffer_size) 348 530 { 531 assert(ieee80211_dev); 532 349 533 size_t complete_size, offset; 350 534 void *complete_buffer; … … 355 539 uint16_t frame_ctrl = *((uint16_t *) buffer); 356 540 if(ieee80211_is_data_frame(frame_ctrl)) { 357 offset = sizeof(htc_frame_header_t); 541 offset = sizeof(htc_tx_data_header_t) + 542 sizeof(htc_frame_header_t); 358 543 complete_size = buffer_size + offset; 359 544 complete_buffer = malloc(complete_size); 545 memset(complete_buffer, 0, complete_size); 546 547 /* 548 * Because we handle just station mode yet, node ID and VIF ID 549 * are fixed. 550 */ 551 htc_tx_data_header_t *data_header = 552 (htc_tx_data_header_t *) 553 (complete_buffer + sizeof(htc_frame_header_t)); 554 /* TODO: Distinguish data type. */ 555 data_header->data_type = HTC_DATA_NORMAL; 556 data_header->node_idx = 1; 557 data_header->vif_idx = 0; 558 /* TODO: There I should probably handle slot number. */ 559 data_header->cookie = 0; 560 561 if(ieee80211_query_using_key(ieee80211_dev)) { 562 data_header->keyix = AR9271_STA_KEY_INDEX; 563 int sec_suite = 564 ieee80211_get_security_suite(ieee80211_dev); 565 switch(sec_suite) { 566 case IEEE80211_SECURITY_SUITE_WEP40: 567 case IEEE80211_SECURITY_SUITE_WEP104: 568 data_header->key_type = 569 AR9271_KEY_TYPE_WEP; 570 break; 571 case IEEE80211_SECURITY_SUITE_TKIP: 572 data_header->key_type = 573 AR9271_KEY_TYPE_TKIP; 574 break; 575 case IEEE80211_SECURITY_SUITE_CCMP: 576 data_header->key_type = 577 AR9271_KEY_TYPE_AES; 578 break; 579 } 580 } else { 581 data_header->key_type = 0; 582 data_header->keyix = 0xFF; 583 } 584 360 585 endpoint = ar9271->htc_device->endpoints.data_be_endpoint; 361 586 } else { … … 366 591 memset(complete_buffer, 0, complete_size); 367 592 593 /* 594 * Because we handle just station mode yet, node ID and VIF ID 595 * are fixed. 596 */ 368 597 htc_tx_management_header_t *mgmt_header = 369 598 (htc_tx_management_header_t *) 370 599 (complete_buffer + sizeof(htc_frame_header_t)); 600 mgmt_header->node_idx = 0; 601 mgmt_header->vif_idx = 0; 602 /* TODO: There I should probably handle slot number. */ 603 mgmt_header->cookie = 0; 371 604 mgmt_header->keyix = 0xFF; 372 605 … … 387 620 static int ar9271_ieee80211_start(ieee80211_dev_t *ieee80211_dev) 388 621 { 622 assert(ieee80211_dev); 623 389 624 ar9271_t *ar9271 = (ar9271_t *) ieee80211_get_specific(ieee80211_dev); 390 625 … … 434 669 435 670 ar9271->starting_up = false; 671 ieee80211_set_ready(ieee80211_dev, true); 672 673 usb_log_info("Device fully initialized.\n"); 436 674 437 675 return EOK; -
uspace/drv/nic/ar9271/ar9271.h
r59fa7ab r1dcc0b9 46 46 #define AR9271_LED_PIN 15 47 47 48 /** Nominal value for AR9271 noise floor calibration. */ 49 #define AR9271_CALIB_NOMINAL_VALUE_2GHZ -118 50 51 /** RX errors values. */ 52 #define AR9271_RX_ERROR_CRC 0x01 53 #define AR9271_RX_ERROR_PHY 0x02 54 55 /** Key index used for device in station mode. */ 56 #define AR9271_STA_KEY_INDEX 4 57 58 /* HW encryption key indicator. */ 59 enum ath9k_key_type { 60 AR9271_KEY_TYPE_CLEAR, 61 AR9271_KEY_TYPE_WEP, 62 AR9271_KEY_TYPE_AES, 63 AR9271_KEY_TYPE_TKIP, 64 }; 65 48 66 /** AR9271 Registers */ 49 67 typedef enum { … … 75 93 AR9271_GPIO_OUT_MUX_AS_OUT = 0x0, /**< GPIO set mux as output */ 76 94 77 /* Wakeuprelated registers */95 /* RTC related registers */ 78 96 AR9271_RTC_RC = 0x7000, 79 97 AR9271_RTC_RC_MAC_WARM = 0x00000001, … … 86 104 AR9271_RTC_STATUS_SHUTDOWN = 0x00000001, 87 105 AR9271_RTC_STATUS_ON = 0x00000002, 106 AR9271_RTC_SLEEP_CLOCK = 0x7048, 107 AR9271_RTC_SLEEP_CLOCK_FORCE_DERIVED = 0x2, 88 108 AR9271_RTC_FORCE_WAKE = 0x704C, 89 109 AR9271_RTC_FORCE_WAKE_ENABLE = 0x00000001, … … 93 113 AR9271_STATION_ID0 = 0x8000, /**< STA Address Lower 32 Bits */ 94 114 AR9271_STATION_ID1 = 0x8004, /**< STA Address Upper 16 Bits */ 95 AR9271_BSSID0 = 0x8008, 96 AR9271_BSSID1 = 0x800C, 97 AR9271_BSSID_MASK0 = 0x80E0, 98 AR9271_BSSID_MASK1 = 0x80E4, 115 AR9271_BSSID0 = 0x8008, /**< BSSID Lower 32 Bits */ 116 AR9271_BSSID1 = 0x800C, /**< BSSID Upper 16 Bits */ 117 AR9271_BSSID_MASK0 = 0x80E0, /**< BSSID Mask Lower 32 Bits */ 118 AR9271_BSSID_MASK1 = 0x80E4, /**< BSSID Mask Upper 16 Bits */ 99 119 AR9271_STATION_ID1_MASK = 0x0000FFFF, 100 120 AR9271_STATION_ID1_POWER_SAVING = 0x00040000, 121 AR9271_MULTICAST_FILTER1 = 0x8040, 122 AR9271_MULTICAST_FILTER2 = 0x8044, 123 AR9271_DIAG = 0x8048, 101 124 102 125 /* RX filtering register */ … … 110 133 AR9271_RX_FILTER_PROBEREQ = 0x00000080, 111 134 AR9271_RX_FILTER_MYBEACON = 0x00000200, 112 AR9271_MULTICAST_FILTER1 = 0x8040, 113 AR9271_MULTICAST_FILTER2 = 0x8044, 114 AR9271_DIAG = 0x8048, 135 AR9271_RX_FILTER_MCAST_BCAST_ALL = 0x00008000, 136 137 /* Key related registers */ 138 AR9271_KEY_TABLE_GRP = 0x8820, 139 AR9271_KEY_TABLE_STA = 0x8880, 140 AR9271_KEY_TABLE_TYPE_WEP40 = 0x0, 141 AR9271_KEY_TABLE_TYPE_WEP104 = 0x1, 142 AR9271_KEY_TABLE_TYPE_TKIP = 0x4, 143 AR9271_KEY_TABLE_TYPE_CCMP = 0x6, 115 144 116 145 /* Physical layer registers */ … … 118 147 AR9271_ADC_CONTROL = 0x982C, 119 148 AR9271_AGC_CONTROL = 0x9860, 149 AR9271_PHY_CAL = 0x9864, 120 150 AR9271_PHY_SYNTH_CONTROL = 0x9874, 121 151 AR9271_PHY_SPECTRAL_SCAN = 0x9910, -
uspace/drv/nic/ar9271/ath_usb.h
r59fa7ab r1dcc0b9 57 57 typedef struct { 58 58 uint16_t length; /**< Little Endian value! */ 59 uint16_t tag; /**< Little Endian value! */59 uint16_t tag; /**< Little Endian value! */ 60 60 } ath_usb_data_header_t; 61 61 -
uspace/drv/nic/ar9271/htc.c
r59fa7ab r1dcc0b9 75 75 76 76 nic_address_t addr; 77 nic_t *nic = nic_get_from_ddf_dev(ieee80211_get_ddf_dev(htc_device->ieee80211_dev)); 77 nic_t *nic = 78 nic_get_from_ddf_dev( 79 ieee80211_get_ddf_dev(htc_device->ieee80211_dev) 80 ); 78 81 nic_query_address(nic, &addr); 79 82 … … 128 131 wmi_reg_write(htc_device, AR9271_STATION_ID1, id1); 129 132 130 /* TODO: Set BSSID mask for AP mode. */131 132 133 return EOK; 133 134 } -
uspace/drv/nic/ar9271/htc.h
r59fa7ab r1dcc0b9 45 45 46 46 #define HTC_RTS_THRESHOLD 2304 47 #define HTC_R X_HEADER_LENGTH 4048 49 /** 50 * HTC message IDs 47 #define HTC_RATES_MAX_LENGTH 30 48 49 /** 50 * HTC message IDs. 51 51 */ 52 52 typedef enum { … … 59 59 60 60 /** 61 * HTC response message status codes 61 * HTC response message status codes. 62 62 */ 63 63 typedef enum { … … 70 70 71 71 /** 72 * HTC operating mode definition 72 * HTC operating mode definition. 73 73 */ 74 74 typedef enum { … … 80 80 81 81 /** 82 * HTC endpoint numbers 82 * HTC data type indicator. 83 */ 84 typedef enum { 85 HTC_DATA_AMPDU = 1, 86 HTC_DATA_NORMAL = 2, 87 HTC_DATA_BEACON = 3, 88 HTC_DATA_MGMT = 4 89 } htc_data_type_t; 90 91 /** 92 * HTC endpoint numbers. 83 93 */ 84 94 typedef struct { … … 96 106 97 107 /** 98 * HTC device data 108 * HTC device data. 99 109 */ 100 110 typedef struct { … … 119 129 120 130 /** 121 * HTC frame header structure 131 * HTC frame header structure. 122 132 */ 123 133 typedef struct { … … 126 136 uint16_t payload_length; /**< Big Endian value! */ 127 137 uint8_t control_bytes[4]; 128 129 /* Message payload starts after the header. */130 138 } __attribute__((packed)) htc_frame_header_t; 131 139 132 140 /** 133 * HTC management TX frame header structure 141 * HTC management TX frame header structure. 134 142 */ 135 143 typedef struct { … … 145 153 146 154 /** 147 * HTC ready message structure 155 * HTC data TX frame header structure. 156 */ 157 typedef struct { 158 uint8_t data_type; 159 uint8_t node_idx; 160 uint8_t vif_idx; 161 uint8_t tidno; 162 uint32_t flags; /**< Big Endian value! */ 163 uint8_t key_type; 164 uint8_t keyix; 165 uint8_t cookie; 166 uint8_t pad; 167 } __attribute__((packed)) htc_tx_data_header_t; 168 169 /** 170 * HTC ready message structure. 148 171 */ 149 172 typedef struct { … … 157 180 158 181 /** 159 * HTC service message structure 182 * HTC service message structure. 160 183 */ 161 184 typedef struct { … … 171 194 172 195 /** 173 * HTC service response message structure 196 * HTC service response message structure. 174 197 */ 175 198 typedef struct { … … 184 207 185 208 /** 186 * HTC credits config message structure 209 * HTC credits config message structure. 187 210 */ 188 211 typedef struct { … … 193 216 194 217 /** 195 * HTC new virtual interface message 218 * HTC new virtual interface message. 196 219 */ 197 220 typedef struct { … … 205 228 206 229 /** 207 * HTC new station message 230 * HTC new station message. 208 231 */ 209 232 typedef struct { … … 231 254 uint8_t pad; 232 255 } __attribute__((packed)) htc_cap_msg_t; 256 257 typedef struct { 258 uint8_t sta_index; 259 uint8_t is_new; 260 uint32_t cap_flags; /**< Big Endian value! */ 261 uint8_t legacy_rates_count; 262 uint8_t legacy_rates[HTC_RATES_MAX_LENGTH]; 263 uint16_t pad; 264 } htc_rate_msg_t; 265 266 /** 267 * HTC RX status structure used in incoming HTC data messages. 268 */ 269 typedef struct { 270 uint64_t timestamp; /**< Big Endian value! */ 271 uint16_t data_length; /**< Big Endian value! */ 272 uint8_t status; 273 uint8_t phy_err; 274 int8_t rssi; 275 int8_t rssi_ctl[3]; 276 int8_t rssi_ext[3]; 277 uint8_t keyix; 278 uint8_t rate; 279 uint8_t antenna; 280 uint8_t more; 281 uint8_t is_aggr; 282 uint8_t more_aggr; 283 uint8_t num_delims; 284 uint8_t flags; 285 uint8_t dummy; 286 uint32_t evm0; /**< Big Endian value! */ 287 uint32_t evm1; /**< Big Endian value! */ 288 uint32_t evm2; /**< Big Endian value! */ 289 } htc_rx_status_t; 233 290 234 291 /** -
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; -
uspace/drv/nic/ar9271/hw.h
r59fa7ab r1dcc0b9 45 45 extern int hw_rx_init(ar9271_t *ar9271); 46 46 extern int hw_reset(ar9271_t *ar9271); 47 extern int hw_wakeup(ar9271_t *ar9271); 48 extern int hw_set_bssid(ar9271_t *ar9271); 49 extern int hw_set_rx_filter(ar9271_t *ar9271, bool assoc); 47 50 48 51 #endif /* ATHEROS_HW_H */ -
uspace/drv/nic/ar9271/wmi.c
r59fa7ab r1dcc0b9 231 231 size_t buffer_size = header_size + command_length; 232 232 void *buffer = malloc(buffer_size); 233 memcpy(buffer+header_size, command_buffer, command_length); 233 234 if(command_buffer != NULL) { 235 memcpy(buffer+header_size, command_buffer, command_length); 236 } 234 237 235 238 /* Set up WMI header */ … … 261 264 262 265 /* Read response. */ 263 rc = htc_read_control_message(htc_device, response_buffer, 264 response_buffer_size, NULL); 265 if(rc != EOK) { 266 free(buffer); 267 usb_log_error("Failed to receive WMI message response. " 268 "Error: %d\n", rc); 269 return rc; 270 } 266 /* TODO: Ignoring WMI management RX messages ~ TX statuses etc. */ 267 uint16_t cmd_id; 268 do { 269 rc = htc_read_control_message(htc_device, response_buffer, 270 response_buffer_size, NULL); 271 if(rc != EOK) { 272 free(buffer); 273 usb_log_error("Failed to receive WMI message response. " 274 "Error: %d\n", rc); 275 return rc; 276 } 277 278 if(response_buffer_size < sizeof(htc_frame_header_t) + 279 sizeof(wmi_command_header_t)) { 280 free(buffer); 281 usb_log_error("Corrupted response received.\n"); 282 return EINVAL; 283 } 284 285 wmi_command_header_t *wmi_hdr = (wmi_command_header_t *) 286 ((void*) response_buffer + sizeof(htc_frame_header_t)); 287 cmd_id = uint16_t_be2host(wmi_hdr->command_id); 288 } while(cmd_id & WMI_MGMT_CMD_MASK); 271 289 272 290 if(clean_resp_buffer) { -
uspace/drv/nic/ar9271/wmi.h
r59fa7ab r1dcc0b9 42 42 #define WMI_SERVICE_GROUP 1 43 43 #define CREATE_SERVICE_ID(group, i) (int) (((int) group << 8) | (int) (i)) 44 45 #define WMI_MGMT_CMD_MASK 0x1000 44 46 45 47 /** … … 117 119 extern int wmi_reg_write(htc_device_t *htc_device, uint32_t reg_offset, 118 120 uint32_t val); 119 extern int wmi_reg_set_clear_bit(htc_device_t *htc_device, uint32_t reg_offset,120 uint32_t set_bit, uint32_t clear_bit);121 extern int wmi_reg_set_clear_bit(htc_device_t *htc_device, 122 uint32_t reg_offset, uint32_t set_bit, uint32_t clear_bit); 121 123 extern int wmi_reg_set_bit(htc_device_t *htc_device, uint32_t reg_offset, 122 124 uint32_t set_bit);
Note:
See TracChangeset
for help on using the changeset viewer.