Changeset 1dcc0b9 in mainline for uspace/drv/nic/ar9271/ar9271.c
- Timestamp:
- 2015-04-06T10:47:51Z (9 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/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;
Note:
See TracChangeset
for help on using the changeset viewer.