Changeset 1dcc0b9 in mainline for uspace/drv/nic


Ignore:
Timestamp:
2015-04-06T10:47:51Z (11 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.

Location:
uspace/drv/nic/ar9271
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/nic/ar9271/Makefile

    r59fa7ab r1dcc0b9  
    3434        $(LIBDRV_PREFIX)/libdrv.a \
    3535        $(LIBNIC_PREFIX)/libnic.a \
    36         $(LIBIEEE80211_PREFIX)/libieee80211.a
     36        $(LIBIEEE80211_PREFIX)/libieee80211.a \
     37        $(LIBCRYPTO_PREFIX)/libcrypto.a
    3738       
    3839EXTRA_CFLAGS += \
     
    4344        -I$(LIBNIC_PREFIX)/include \
    4445        -I$(LIBIEEE80211_PREFIX)/include \
     46        -I$(LIBCRYPTO_PREFIX)
    4547       
    4648BINARY = ar9271
  • 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;
  • uspace/drv/nic/ar9271/ar9271.h

    r59fa7ab r1dcc0b9  
    4646#define AR9271_LED_PIN 15
    4747
     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. */
     59enum 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
    4866/** AR9271 Registers */
    4967typedef enum {
     
    7593        AR9271_GPIO_OUT_MUX_AS_OUT = 0x0,       /**< GPIO set mux as output */
    7694   
    77         /* Wakeup related registers */
     95        /* RTC related registers */
    7896        AR9271_RTC_RC = 0x7000,
    7997        AR9271_RTC_RC_MAC_WARM = 0x00000001,
     
    86104        AR9271_RTC_STATUS_SHUTDOWN = 0x00000001,
    87105        AR9271_RTC_STATUS_ON = 0x00000002,
     106        AR9271_RTC_SLEEP_CLOCK = 0x7048,
     107        AR9271_RTC_SLEEP_CLOCK_FORCE_DERIVED = 0x2,
    88108        AR9271_RTC_FORCE_WAKE = 0x704C,
    89109        AR9271_RTC_FORCE_WAKE_ENABLE = 0x00000001,
     
    93113        AR9271_STATION_ID0 = 0x8000,    /**< STA Address Lower 32 Bits */
    94114        AR9271_STATION_ID1 = 0x8004,    /**< STA Address Upper 16 Bits */
    95         AR9271_BSSID0 = 0x8008,                 /**< BSSID Lower 32 Bits */
    96         AR9271_BSSID1 = 0x800C,                 /**< BSSID Upper 16 Bits */
    97         AR9271_BSSID_MASK0 = 0x80E0,            /**< BSSID Mask Lower 32 Bits */
    98         AR9271_BSSID_MASK1 = 0x80E4,            /**< BSSID Mask Upper 16 Bits */
     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 */
    99119        AR9271_STATION_ID1_MASK = 0x0000FFFF,
    100120        AR9271_STATION_ID1_POWER_SAVING = 0x00040000,
     121        AR9271_MULTICAST_FILTER1 = 0x8040,
     122        AR9271_MULTICAST_FILTER2 = 0x8044,     
     123        AR9271_DIAG = 0x8048,
    101124               
    102125        /* RX filtering register */
     
    110133        AR9271_RX_FILTER_PROBEREQ = 0x00000080,
    111134        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,
    115144               
    116145        /* Physical layer registers */
     
    118147        AR9271_ADC_CONTROL = 0x982C,
    119148        AR9271_AGC_CONTROL = 0x9860,
     149        AR9271_PHY_CAL = 0x9864,
    120150        AR9271_PHY_SYNTH_CONTROL = 0x9874,
    121151        AR9271_PHY_SPECTRAL_SCAN = 0x9910,
  • uspace/drv/nic/ar9271/ath_usb.h

    r59fa7ab r1dcc0b9  
    5757typedef struct {
    5858        uint16_t length;                /**< Little Endian value! */
    59         uint16_t tag;           /**< Little Endian value! */
     59        uint16_t tag;                   /**< Little Endian value! */
    6060} ath_usb_data_header_t;
    6161
  • uspace/drv/nic/ar9271/htc.c

    r59fa7ab r1dcc0b9  
    7575       
    7676        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                );
    7881        nic_query_address(nic, &addr);
    7982       
     
    128131        wmi_reg_write(htc_device, AR9271_STATION_ID1, id1);
    129132       
    130         /* TODO: Set BSSID mask for AP mode. */
    131        
    132133        return EOK;
    133134}
  • uspace/drv/nic/ar9271/htc.h

    r59fa7ab r1dcc0b9  
    4545
    4646#define HTC_RTS_THRESHOLD 2304
    47 #define HTC_RX_HEADER_LENGTH 40
    48 
    49 /**
    50  * HTC message IDs
     47#define HTC_RATES_MAX_LENGTH 30
     48
     49/**
     50 * HTC message IDs.
    5151 */
    5252typedef enum {
     
    5959
    6060/**
    61  * HTC response message status codes
     61 * HTC response message status codes.
    6262 */
    6363typedef enum {
     
    7070
    7171/**
    72  * HTC operating mode definition
     72 * HTC operating mode definition.
    7373 */
    7474typedef enum {
     
    8080
    8181/**
    82  * HTC endpoint numbers
     82 * HTC data type indicator.
     83 */
     84typedef 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.
    8393 */
    8494typedef struct {
     
    96106
    97107/**
    98  * HTC device data
     108 * HTC device data.
    99109 */
    100110typedef struct {
     
    119129
    120130/**
    121  * HTC frame header structure 
     131 * HTC frame header structure.
    122132 */
    123133typedef struct {
     
    126136        uint16_t  payload_length;       /**< Big Endian value! */
    127137        uint8_t   control_bytes[4];
    128    
    129         /* Message payload starts after the header. */
    130138} __attribute__((packed)) htc_frame_header_t;
    131139
    132140/**
    133  * HTC management TX frame header structure 
     141 * HTC management TX frame header structure.
    134142 */
    135143typedef struct {
     
    145153
    146154/**
    147  * HTC ready message structure
     155 * HTC data TX frame header structure.
     156 */
     157typedef 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.
    148171 */
    149172typedef struct {
     
    157180
    158181/**
    159  * HTC service message structure 
     182 * HTC service message structure.
    160183 */
    161184typedef struct {
     
    171194
    172195/**
    173  * HTC service response message structure 
     196 * HTC service response message structure.
    174197 */
    175198typedef struct {
     
    184207
    185208/**
    186  * HTC credits config message structure
     209 * HTC credits config message structure.
    187210 */
    188211typedef struct {
     
    193216
    194217/**
    195  * HTC new virtual interface message
     218 * HTC new virtual interface message.
    196219 */
    197220typedef struct {
     
    205228
    206229/**
    207  * HTC new station message
     230 * HTC new station message.
    208231 */
    209232typedef struct {
     
    231254        uint8_t pad;
    232255} __attribute__((packed)) htc_cap_msg_t;
     256
     257typedef 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 */
     269typedef 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;
    233290
    234291/**
  • uspace/drv/nic/ar9271/hw.c

    r59fa7ab r1dcc0b9  
    4343
    4444/**
    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.
    4746 *
    4847 * @param ar9271 Device structure.
     
    264263}
    265264
     265static 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
    266273static int hw_set_operating_mode(ar9271_t *ar9271,
    267274        ieee80211_operating_mode_t op_mode)
     
    305312static int hw_noise_floor_calibration(ar9271_t *ar9271)
    306313{
     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       
    307336        wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
    308337                AR9271_AGC_CONTROL_NF_CALIB_EN);
     
    348377}
    349378
     379int 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
    350422int hw_freq_switch(ar9271_t *ar9271, uint16_t freq)
    351423{
     
    361433        if(rc != EOK) {
    362434                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");
    363441                return rc;
    364442        }
     
    376454}
    377455
    378 static int hw_set_rx_filter(ar9271_t *ar9271)
     456int hw_set_rx_filter(ar9271_t *ar9271, bool assoc)
    379457{
    380458        uint32_t filter_bits;
    381459       
    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        }
    383467       
    384468        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;
    386470       
    387471        wmi_reg_write(ar9271->htc_device, AR9271_RX_FILTER, filter_bits);
     472       
     473        return EOK;
     474}
     475
     476int 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));
    388492       
    389493        return EOK;
     
    395499                AR9271_COMMAND_RX_ENABLE);
    396500       
    397         int rc = hw_set_rx_filter(ar9271);
     501        int rc = hw_set_rx_filter(ar9271, false);
    398502        if(rc != EOK) {
    399503                usb_log_error("Failed to set RX filtering.\n");
     
    410514}
    411515
    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 
    420516static int hw_init_pll(ar9271_t *ar9271)
    421517{
     
    423519       
    424520        /* Some magic here (set for 2GHz channels). But VERY important :-) */
    425         pll = (0x5 << 10) & 0x00003C00;
    426         pll |= 0x2C & 0x000003FF;
     521        pll = (0x5 << 10) | 0x2C;
    427522       
    428523        wmi_reg_write(ar9271->htc_device, AR9271_RTC_PLL_CONTROL, pll);
    429524       
    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
     533static void hw_set_init_values(ar9271_t *ar9271)
    434534{
    435535        uint32_t reg_offset, reg_value;
     
    458558                wmi_reg_write(ar9271->htc_device, reg_offset, reg_value);
    459559        }
    460        
    461         return EOK;
    462560}
    463561
     
    533631        }
    534632       
    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);
    540634       
    541635        /* Set physical layer mode. */
     
    586680        /* Byteswap TX and RX data buffer words. */
    587681        wmi_reg_write(ar9271->htc_device, AR9271_CONFIG, 0xA);
    588        
    589         usb_log_info("HW reset done.\n");
    590682       
    591683        return EOK;
  • uspace/drv/nic/ar9271/hw.h

    r59fa7ab r1dcc0b9  
    4545extern int hw_rx_init(ar9271_t *ar9271);
    4646extern int hw_reset(ar9271_t *ar9271);
     47extern int hw_wakeup(ar9271_t *ar9271);
     48extern int hw_set_bssid(ar9271_t *ar9271);
     49extern int hw_set_rx_filter(ar9271_t *ar9271, bool assoc);
    4750
    4851#endif  /* ATHEROS_HW_H */
  • uspace/drv/nic/ar9271/wmi.c

    r59fa7ab r1dcc0b9  
    231231        size_t buffer_size = header_size + command_length;
    232232        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        }
    234237       
    235238        /* Set up WMI header */
     
    261264       
    262265        /* 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);
    271289       
    272290        if(clean_resp_buffer) {
  • uspace/drv/nic/ar9271/wmi.h

    r59fa7ab r1dcc0b9  
    4242#define WMI_SERVICE_GROUP 1
    4343#define CREATE_SERVICE_ID(group, i) (int) (((int) group << 8) | (int) (i))
     44
     45#define WMI_MGMT_CMD_MASK 0x1000
    4446
    4547/**
     
    117119extern int wmi_reg_write(htc_device_t *htc_device, uint32_t reg_offset,
    118120        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);
     121extern int wmi_reg_set_clear_bit(htc_device_t *htc_device,
     122        uint32_t reg_offset, uint32_t set_bit, uint32_t clear_bit);
    121123extern int wmi_reg_set_bit(htc_device_t *htc_device, uint32_t reg_offset,
    122124        uint32_t set_bit);
Note: See TracChangeset for help on using the changeset viewer.