Changeset 1dcc0b9 in mainline for uspace/drv/nic/ar9271/ar9271.c


Ignore:
Timestamp:
2015-04-06T10:47:51Z (9 years ago)
Author:
Jan Kolarik <kolarik@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d7dadcb4
Parents:
59fa7ab
Message:

Scanning whole 2.4GHz spectrum, created supplicant for managing connection between device STA and AP, finished association process between STA and AP, handling 4way handshake protocol used for key management, written needed cryptographic algorithms (AES, SHA1, HMAC, PBKDF2) for CCMP protocol, data communication on OPEN/CCMP networks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/nic/ar9271/ar9271.c

    r59fa7ab r1dcc0b9  
    105105static int ar9271_ieee80211_set_freq(ieee80211_dev_t *ieee80211_dev,
    106106        uint16_t freq);
     107static int ar9271_ieee80211_bssid_change(ieee80211_dev_t *ieee80211_dev);
     108static int ar9271_ieee80211_key_config(ieee80211_dev_t *ieee80211_dev,
     109        ieee80211_key_config_t *key_conf, bool insert);
    107110
    108111static driver_ops_t ar9271_driver_ops = {
     
    118121        .start = ar9271_ieee80211_start,
    119122        .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
    121126};
    122127
     
    186191 *
    187192 */
    188 static int ar9271_on_multicast_mode_change(nic_t *nic, nic_multicast_mode_t mode,
    189     const nic_address_t *addr, size_t addr_cnt)
     193static int ar9271_on_multicast_mode_change(nic_t *nic,
     194        nic_multicast_mode_t mode, const nic_address_t *addr, size_t addr_cnt)
    190195{
    191196        /*
     
    249254 *
    250255 */
    251 static int ar9271_on_broadcast_mode_change(nic_t *nic, nic_broadcast_mode_t mode)
     256static int ar9271_on_broadcast_mode_change(nic_t *nic,
     257        nic_broadcast_mode_t mode)
    252258{
    253259        /*
     
    271277}
    272278
     279static bool ar9271_rx_status_error(uint8_t status)
     280{
     281        return (status & AR9271_RX_ERROR_PHY) || (status & AR9271_RX_ERROR_CRC);
     282}
     283
    273284static int ar9271_data_polling(void *arg)
    274285{
     286        assert(arg);
     287       
    275288        ar9271_t *ar9271 = (ar9271_t *) arg;
    276289       
     
    282295                if(htc_read_data_message(ar9271->htc_device,
    283296                        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                        
    292297                        size_t strip_length =
    293298                                sizeof(ath_usb_data_header_t) +
    294299                                sizeof(htc_frame_header_t) +
    295                                 HTC_RX_HEADER_LENGTH;
     300                                sizeof(htc_rx_status_t);
    296301                       
    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                       
    298329                        void *strip_buffer = buffer + strip_length;
    299                        
     330
    300331                        ieee80211_rx_handler(ar9271->ieee80211_dev,
    301332                                strip_buffer,
    302                                 transferred_size - strip_length);
     333                                payload_length);
    303334                }
    304335        }
     
    316347        uint16_t freq)
    317348{
     349        assert(ieee80211_dev);
     350       
    318351        ar9271_t *ar9271 = (ar9271_t *) ieee80211_get_specific(ieee80211_dev);
     352       
     353        //hw_wakeup(ar9271);
    319354       
    320355        wmi_send_command(ar9271->htc_device, WMI_DISABLE_INTR, NULL, 0, NULL);
     
    344379}
    345380
     381static 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
     431static 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
    346528static int ar9271_ieee80211_tx_handler(ieee80211_dev_t *ieee80211_dev,
    347529        void *buffer, size_t buffer_size)
    348530{
     531        assert(ieee80211_dev);
     532       
    349533        size_t complete_size, offset;
    350534        void *complete_buffer;
     
    355539        uint16_t frame_ctrl = *((uint16_t *) buffer);
    356540        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);
    358543                complete_size = buffer_size + offset;
    359544                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               
    360585                endpoint = ar9271->htc_device->endpoints.data_be_endpoint;
    361586        } else {
     
    366591                memset(complete_buffer, 0, complete_size);
    367592               
     593                /*
     594                 * Because we handle just station mode yet, node ID and VIF ID
     595                 * are fixed.
     596                 */
    368597                htc_tx_management_header_t *mgmt_header =
    369598                        (htc_tx_management_header_t *)
    370599                        (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;
    371604                mgmt_header->keyix = 0xFF;
    372605               
     
    387620static int ar9271_ieee80211_start(ieee80211_dev_t *ieee80211_dev)
    388621{
     622        assert(ieee80211_dev);
     623       
    389624        ar9271_t *ar9271 = (ar9271_t *) ieee80211_get_specific(ieee80211_dev);
    390625       
     
    434669       
    435670        ar9271->starting_up = false;
     671        ieee80211_set_ready(ieee80211_dev, true);
     672       
     673        usb_log_info("Device fully initialized.\n");
    436674       
    437675        return EOK;
Note: See TracChangeset for help on using the changeset viewer.