Changeset 9e5a51c in mainline


Ignore:
Timestamp:
2015-03-08T22:20:34Z (9 years ago)
Author:
Jan Kolarik <kolarik@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
864762a
Parents:
4cb0148
Message:

Fixed PLL initialization value that blocked communication with external devices. Started implementing IEEE802.11 scanning and authentication functions.

Location:
uspace
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ar9271/ar9271.c

    r4cb0148 r9e5a51c  
    9999static int ar9271_add_device(ddf_dev_t *);
    100100
    101 /* IEEE802.11 callbacks */
     101/* IEEE 802.11 callbacks */
    102102static int ar9271_ieee80211_start(ieee80211_dev_t *ieee80211_dev);
    103103static int ar9271_ieee80211_tx_handler(ieee80211_dev_t *ieee80211_dev,
    104104        void *buffer, size_t buffer_size);
     105static int ar9271_ieee80211_set_freq(ieee80211_dev_t *ieee80211_dev,
     106        uint16_t freq);
    105107
    106108static driver_ops_t ar9271_driver_ops = {
     
    115117static ieee80211_ops_t ar9271_ieee80211_ops = {
    116118        .start = ar9271_ieee80211_start,
    117         .tx_handler = ar9271_ieee80211_tx_handler
    118 };
    119 
    120 static int ar9271_ieee80211_tx_handler(ieee80211_dev_t *ieee80211_dev,
    121         void *buffer, size_t buffer_size)
    122 {
    123         /* TODO: Process TX message properly */
    124        
    125         size_t complete_size, offset;
    126         void *complete_buffer;
    127         int endpoint;
    128        
    129         ar9271_t *ar9271 = (ar9271_t *) ieee80211_dev->driver_data;
    130        
    131         ieee80211_header_t *ieee80211_header = (ieee80211_header_t *) buffer;
    132        
    133         if(ieee80211_is_data_frame(ieee80211_header)) {
    134                 offset = sizeof(htc_frame_header_t);
    135                 complete_size = buffer_size + offset;
    136                 complete_buffer = malloc(complete_size);
    137                 endpoint = ar9271->htc_device->endpoints.data_be_endpoint;
    138         } else {
    139                 offset = sizeof(htc_tx_management_header_t) +
    140                         sizeof(htc_frame_header_t);
    141                 complete_size = buffer_size + offset;
    142                 complete_buffer = malloc(complete_size);
    143                 endpoint = ar9271->htc_device->endpoints.mgmt_endpoint;
    144         }
    145        
    146         /* Copy IEEE802.11 data to new allocated buffer with HTC headers. */
    147         memcpy(complete_buffer + offset, buffer, buffer_size);
    148        
    149         htc_send_data_message(ar9271->htc_device, complete_buffer,
    150                 complete_size, endpoint);
    151        
    152         free(complete_buffer);
    153        
    154         return EOK;
    155 }
     119        .tx_handler = ar9271_ieee80211_tx_handler,
     120        .set_freq = ar9271_ieee80211_set_freq
     121};
    156122
    157123static int ar9271_data_polling(void *arg)
     
    162128       
    163129        while(true) {
    164                 int rc =
    165130                htc_read_data_message(ar9271->htc_device, buffer, buffer_size,
    166131                        NULL);
    167                 usb_log_info("XXXXXXXXXXXXXXXXXXXXXXXXXXXX RC is %d.\n", rc);
     132                usb_log_info("Incoming data message.\n");
    168133               
    169134                /* TODO: Process RX message */
     
    173138}
    174139
     140/*
    175141static int ar9271_diag_polling(void *arg)
    176142{
     
    183149                wmi_reg_read(ar9271->htc_device, 0x782C, &result);
    184150                usb_log_info("0x782C: %x\n", result);
    185                 wmi_reg_read(ar9271->htc_device, 0x8048, &result);
     151                wmi_reg_read(ar9271->htc_device, AR9271_DIAG, &result);
    186152                usb_log_info("Diag reg.: %x\n", result);
    187153                wmi_reg_read(ar9271->htc_device, 0x8088, &result);
     
    204170        return EOK;
    205171}
     172 */
    206173
    207174static int ar9271_register_polling_fibrils(ar9271_t *ar9271)
     
    215182       
    216183        /* Add debug polling fibril. */
     184        /*
    217185        fibril = fibril_create(ar9271_diag_polling, ar9271);
    218186        if (fibril == 0) {
     
    220188        }
    221189        fibril_add_ready(fibril);
     190         */
     191       
     192        return EOK;
     193}
     194
     195/**
     196 * IEEE 802.11 handlers.
     197 */
     198
     199static int ar9271_ieee80211_set_freq(ieee80211_dev_t *ieee80211_dev,
     200        uint16_t freq)
     201{
     202        ar9271_t *ar9271 = (ar9271_t *) ieee80211_dev->driver_data;
     203       
     204        wmi_send_command(ar9271->htc_device, WMI_DISABLE_INTR, NULL, 0, NULL);
     205        wmi_send_command(ar9271->htc_device, WMI_DRAIN_TXQ_ALL, NULL, 0, NULL);
     206        wmi_send_command(ar9271->htc_device, WMI_STOP_RECV, NULL, 0, NULL);
     207       
     208        int rc = hw_freq_switch(ar9271, freq);
     209        if(rc != EOK) {
     210                usb_log_error("Failed to HW switch frequency.\n");
     211                return rc;
     212        }
     213       
     214        wmi_send_command(ar9271->htc_device, WMI_START_RECV, NULL, 0, NULL);
     215       
     216        rc = hw_rx_init(ar9271);
     217        if(rc != EOK) {
     218                usb_log_error("Failed to initialize RX.\n");
     219                return rc;
     220        }
     221       
     222        uint16_t htc_mode = host2uint16_t_be(1);
     223        wmi_send_command(ar9271->htc_device, WMI_SET_MODE,
     224                (uint8_t *) &htc_mode, sizeof(htc_mode), NULL);
     225        wmi_send_command(ar9271->htc_device, WMI_ENABLE_INTR, NULL, 0, NULL);
     226       
     227        return EOK;
     228}
     229
     230static int ar9271_ieee80211_tx_handler(ieee80211_dev_t *ieee80211_dev,
     231        void *buffer, size_t buffer_size)
     232{
     233        size_t complete_size, offset;
     234        void *complete_buffer;
     235        int endpoint;
     236       
     237        ar9271_t *ar9271 = (ar9271_t *) ieee80211_dev->driver_data;
     238       
     239        uint16_t frame_ctrl = uint16_t_le2host(*((uint16_t *) buffer));
     240        if(frame_ctrl & IEEE80211_DATA_FRAME) {
     241                offset = sizeof(htc_frame_header_t);
     242                complete_size = buffer_size + offset;
     243                complete_buffer = malloc(complete_size);
     244                endpoint = ar9271->htc_device->endpoints.data_be_endpoint;
     245        } else {
     246                offset = sizeof(htc_tx_management_header_t) +
     247                        sizeof(htc_frame_header_t);
     248                complete_size = buffer_size + offset;
     249                complete_buffer = malloc(complete_size);
     250                memset(complete_buffer, 0, complete_size);
     251               
     252                htc_tx_management_header_t *mgmt_header =
     253                        (htc_tx_management_header_t *)
     254                        (complete_buffer + sizeof(htc_frame_header_t));
     255                mgmt_header->keyix = 0xFF;
     256               
     257                endpoint = ar9271->htc_device->endpoints.mgmt_endpoint;
     258        }
     259       
     260        /* Copy IEEE802.11 data to new allocated buffer with HTC headers. */
     261        memcpy(complete_buffer + offset, buffer, buffer_size);
     262       
     263        htc_send_data_message(ar9271->htc_device, complete_buffer,
     264                complete_size, endpoint);
     265       
     266        free(complete_buffer);
    222267       
    223268        return EOK;
     
    228273        ar9271_t *ar9271 = (ar9271_t *) ieee80211_dev->driver_data;
    229274       
    230         int rc = wmi_send_command(ar9271->htc_device, WMI_FLUSH_RECV, NULL, 0,
    231                 NULL);
    232         if(rc != EOK) {
    233                 usb_log_error("Failed to flush receiving buffer.\n");
    234                 return rc;
    235         }
    236        
    237         rc = hw_reset(ar9271);
     275        wmi_send_command(ar9271->htc_device, WMI_FLUSH_RECV, NULL, 0, NULL);
     276       
     277        int rc = hw_reset(ar9271);
    238278        if(rc != EOK) {
    239279                usb_log_error("Failed to do HW reset.\n");
     
    242282       
    243283        uint16_t htc_mode = host2uint16_t_be(1);
    244         rc = wmi_send_command(ar9271->htc_device, WMI_SET_MODE,
     284        wmi_send_command(ar9271->htc_device, WMI_SET_MODE,
    245285                (uint8_t *) &htc_mode, sizeof(htc_mode), NULL);
    246         if(rc != EOK) {
    247                 usb_log_error("Failed to set HTC mode.\n");
    248                 return rc;
    249         }
    250        
    251         rc = wmi_send_command(ar9271->htc_device, WMI_ATH_INIT, NULL, 0,
    252                 NULL);
    253         if(rc != EOK) {
    254                 usb_log_error("Failed to send ath init command.\n");
    255                 return rc;
    256         }
    257        
    258         rc = wmi_send_command(ar9271->htc_device, WMI_START_RECV, NULL, 0,
    259                 NULL);
    260         if(rc != EOK) {
    261                 usb_log_error("Failed to send receiving init command.\n");
    262                 return rc;
    263         }
     286        wmi_send_command(ar9271->htc_device, WMI_ATH_INIT, NULL, 0, NULL);
     287        wmi_send_command(ar9271->htc_device, WMI_START_RECV, NULL, 0, NULL);
     288        wmi_send_command(ar9271->htc_device, WMI_ENABLE_INTR, NULL, 0, NULL);
    264289       
    265290        rc = hw_rx_init(ar9271);
     
    269294        }
    270295       
     296        /* Send capability message to target. */
     297        htc_cap_msg_t cap_msg;
     298        cap_msg.ampdu_limit = host2uint32_t_be(0xFFFF);
     299        cap_msg.ampdu_subframes = 0xFF;
     300        cap_msg.enable_coex = 0;
     301        cap_msg.tx_chainmask = 0x1;
     302       
     303        wmi_send_command(ar9271->htc_device, WMI_TARGET_IC_UPDATE,
     304                (uint8_t *) &cap_msg, sizeof(cap_msg), NULL);
     305       
    271306        rc = htc_init_new_vif(ar9271->htc_device);
    272307        if(rc != EOK) {
     
    281316        }
    282317       
     318        ar9271->starting_up = false;
     319       
    283320        return EOK;
    284321}
     
    286323static int ar9271_init(ar9271_t *ar9271, usb_device_t *usb_device)
    287324{
     325        ar9271->starting_up = true;
    288326        ar9271->usb_device = usb_device;
    289327       
  • uspace/drv/bus/usb/ar9271/ar9271.h

    r4cb0148 r9e5a51c  
    9898        AR9271_BSSID_MASK1 = 0x80E4,            /**< BSSID Mask Upper 16 Bits */
    9999        AR9271_STATION_ID1_MASK = 0x0000FFFF,
     100        AR9271_STATION_ID1_POWER_SAVING = 0x00040000,
    100101               
    101102        /* RX filtering register */
     
    111112        AR9271_MULTICAST_FILTER1 = 0x8040,
    112113        AR9271_MULTICAST_FILTER2 = 0x8044,     
     114        AR9271_DIAG = 0x8048,
    113115               
    114116        /* Physical layer registers */
     117               
    115118        AR9271_PHY_ACTIVE = 0x981C,
    116119        AR9271_ADC_CONTROL = 0x982C,
    117120        AR9271_AGC_CONTROL = 0x9860,
    118121        AR9271_PHY_SYNTH_CONTROL = 0x9874,
     122        AR9271_PHY_SPECTRAL_SCAN = 0x9910,
     123        AR9271_PHY_RADAR0 = 0x9954,
     124        AR9271_PHY_RADAR0_FFT_ENABLED = 0x80000000,
     125        AR9271_PHY_RFBUS_KILL = 0x997C,
     126        AR9271_PHY_RFBUS_GRANT = 0x9C20,
    119127        AR9271_PHY_MODE = 0xA200,
    120128        AR9271_PHY_CCK_TX_CTRL = 0xA204,
     
    127135        AR9271_AGC_CONTROL_TX_CALIB = 0x00010000,
    128136        AR9271_AGC_CONTROL_NF_NOT_UPDATE = 0x00020000,
    129         AR9271_PHY_MODE_2G = 0x02,
    130137        AR9271_PHY_MODE_DYNAMIC = 0x04,
    131138        AR9271_PHY_CCK_TX_CTRL_JAPAN = 0x00000010,
     
    156163/** AR9271 device data */
    157164typedef struct {
     165        /** Whether device is starting up. */
     166        bool starting_up;
     167       
    158168        /** Backing DDF device */
    159169        ddf_dev_t *ddf_dev;
     
    187197        {0x0000801c, 0x12e0002b},
    188198        {0x00008318, 0x00003440},
    189         {0x00009804, 0x00000300},
     199        {0x00009804, 0x000003c0},/*< note: overridden */
    190200        {0x00009820, 0x02020200},
    191201        {0x00009824, 0x01000e0e},
    192         {0x00009828, 0x3a020001},
     202        {0x00009828, 0x0a020001},/*< note: overridden */
    193203        {0x00009834, 0x00000e0e},
    194204        {0x00009838, 0x00000007},
     
    486496
    487497/**
     498 * AR9271 TX init values for 2GHz mode operation.
     499 *
     500 * Taken from Linux sources.
     501 */
     502static const uint32_t ar9271_2g_tx_array[][2] = {
     503        {0x0000a300, 0x00010000},
     504        {0x0000a304, 0x00016200},
     505        {0x0000a308, 0x00018201},
     506        {0x0000a30c, 0x0001b240},
     507        {0x0000a310, 0x0001d241},
     508        {0x0000a314, 0x0001f600},
     509        {0x0000a318, 0x00022800},
     510        {0x0000a31c, 0x00026802},
     511        {0x0000a320, 0x0002b805},
     512        {0x0000a324, 0x0002ea41},
     513        {0x0000a328, 0x00038b00},
     514        {0x0000a32c, 0x0003ab40},
     515        {0x0000a330, 0x0003cd80},
     516        {0x0000a334, 0x000368de},
     517        {0x0000a338, 0x0003891e},
     518        {0x0000a33c, 0x0003a95e},
     519        {0x0000a340, 0x0003e9df},
     520        {0x0000a344, 0x0003e9df},
     521        {0x0000a348, 0x0003e9df},
     522        {0x0000a34c, 0x0003e9df},
     523        {0x0000a350, 0x0003e9df},
     524        {0x0000a354, 0x0003e9df},
     525        {0x00007838, 0x0000002b},
     526        {0x00007824, 0x00d8a7ff},
     527        {0x0000786c, 0x08609eba},
     528        {0x00007820, 0x00000c00},
     529        {0x0000a274, 0x0a214652},
     530        {0x0000a278, 0x0e739ce7},
     531        {0x0000a27c, 0x05018063},
     532        {0x0000a394, 0x06318c63},
     533        {0x0000a398, 0x00000063},
     534        {0x0000a3dc, 0x06318c63},
     535        {0x0000a3e0, 0x00000063}
     536};
     537
     538/**
    488539 * AR9271 hardware init values.
    489540 *
     
    584635        {0x00008058, 0x00000000},
    585636        {0x0000805c, 0x000fc78f},
    586         {0x00008060, 0x0000000f},
     637        {0x00008060, 0xc7ff000f},
    587638        {0x00008064, 0x00000000},
    588639        {0x00008070, 0x00000000},
     
    680731        {0x0000833c, 0x00000000},
    681732        {0x00008340, 0x00010380},
    682         {0x00008344, 0x00581003},/*< note: disabled ADHOC_MCAST_KEYID feature */
     733        {0x00008344, 0x00481083},/*< note: disabled ADHOC_MCAST_KEYID feature */
    683734        {0x00007010, 0x00000030},
    684735        {0x00007034, 0x00000002},
  • uspace/drv/bus/usb/ar9271/ath_usb.c

    r4cb0148 r9e5a51c  
    145145        size_t buffer_size)
    146146{
     147        size_t complete_buffer_size = buffer_size + DATA_HEADER_SIZE;
     148        void *complete_buffer = malloc(buffer_size + DATA_HEADER_SIZE);
     149        memcpy(complete_buffer + DATA_HEADER_SIZE, buffer, buffer_size);
     150       
     151        uint16_t *it = (uint16_t *) complete_buffer;
     152        *it++ = host2uint16_t_le(buffer_size);
     153        *it++ = host2uint16_t_le(TX_STREAM_MODE_TAG);
     154       
    147155        ath_usb_t *ath_usb = (ath_usb_t *) ath->specific_data;
    148156        usb_pipe_t *pipe =
     
    150158                pipe;
    151159       
    152         return usb_pipe_write(pipe, buffer, buffer_size);
     160        int ret_val = usb_pipe_write(pipe, complete_buffer,
     161                complete_buffer_size);
     162       
     163        free(complete_buffer);
     164       
     165        return ret_val;
    153166}
    154167
  • uspace/drv/bus/usb/ar9271/ath_usb.h

    r4cb0148 r9e5a51c  
    4040#include "ath.h"
    4141
     42#define DATA_HEADER_SIZE 4
     43#define RX_STREAM_MODE_TAG 0x4e00
     44#define TX_STREAM_MODE_TAG 0x697e
     45
    4246/** Atheros USB wifi device structure */
    4347typedef struct {
  • uspace/drv/bus/usb/ar9271/htc.c

    r4cb0148 r9e5a51c  
    7171        htc_sta_msg_t sta_msg;
    7272       
     73        memset(&vif_msg, 0, sizeof(htc_vif_msg_t));
     74        memset(&sta_msg, 0, sizeof(htc_sta_msg_t));
     75       
    7376        nic_address_t addr;
    7477        nic_t *nic = nic_get_from_ddf_dev(htc_device->ieee80211_dev->ddf_dev);
     
    99102        vif_msg.rts_thres = host2uint16_t_be(HTC_RTS_THRESHOLD);
    100103       
    101         int rc = wmi_send_command(htc_device, WMI_VAP_CREATE,
    102                 (uint8_t *) &vif_msg, sizeof(vif_msg), NULL);
    103         if(rc != EOK) {
    104                 usb_log_error("Failed to send VAP create command.\n");
    105                 return rc;
    106         }
     104        wmi_send_command(htc_device, WMI_VAP_CREATE, (uint8_t *) &vif_msg,
     105                sizeof(vif_msg), NULL);
    107106       
    108107        sta_msg.is_vif_sta = 1;
    109         sta_msg.max_ampdu = host2uint16_t_be(HTC_MAX_AMPDU);
     108        sta_msg.max_ampdu = host2uint16_t_be(0xFFFF);
    110109        sta_msg.sta_index = 0;
    111110        sta_msg.vif_index = 0;
    112111       
    113         rc = wmi_send_command(htc_device, WMI_NODE_CREATE,
    114                 (uint8_t *) &sta_msg, sizeof(sta_msg), NULL);
    115         if(rc != EOK) {
    116                 usb_log_error("Failed to send NODE create command.\n");
    117                 return rc;
    118         }
     112        wmi_send_command(htc_device, WMI_NODE_CREATE, (uint8_t *) &sta_msg,
     113                sizeof(sta_msg), NULL);
    119114       
    120115        /* Write first 4 bytes of MAC address. */
     
    122117        memcpy(&id0, &addr.address, 4);
    123118        id0 = host2uint32_t_le(id0);
    124         rc = wmi_reg_write(htc_device, AR9271_STATION_ID0, id0);
    125         if(rc != EOK)
    126                 return rc;
    127        
     119        wmi_reg_write(htc_device, AR9271_STATION_ID0, id0);
     120
    128121        /* Write last 2 bytes of MAC address (and preserve existing data). */
    129122        uint32_t id1;
    130         rc = wmi_reg_read(htc_device, AR9271_STATION_ID1, &id1);
    131         if(rc != EOK)
    132                 return rc;
     123        wmi_reg_read(htc_device, AR9271_STATION_ID1, &id1);
     124
    133125        uint16_t id1_addr;
    134126        memcpy(&id1_addr, &addr.address[4], 2);
    135127        id1 = (id1 & ~AR9271_STATION_ID1_MASK) | host2uint16_t_le(id1_addr);
    136         rc = wmi_reg_write(htc_device, AR9271_STATION_ID1, id1);
    137         if(rc != EOK)
    138                 return rc;
     128        wmi_reg_write(htc_device, AR9271_STATION_ID1, id1);
    139129       
    140130        /* TODO: Set BSSID mask for AP mode. */
     
    146136        size_t buffer_size, uint8_t endpoint_id)
    147137{
     138        memset(header, 0, sizeof(htc_frame_header_t));
     139       
    148140        header->endpoint_id = endpoint_id;
    149         header->flags = 0;
    150141        header->payload_length =
    151142                host2uint16_t_be(buffer_size - sizeof(htc_frame_header_t));
    152        
    153         header->control_bytes[0] = 0x02;
    154         header->control_bytes[1] = 0x88;
    155         header->control_bytes[2] = 0xFF;
    156         header->control_bytes[3] = 0xFF;
    157143}
    158144
     
    257243                sizeof(htc_service_msg_t);
    258244        void *buffer = malloc(buffer_size);
     245        memset(buffer, 0, buffer_size);
    259246       
    260247        /* Fill service message structure. */
  • uspace/drv/bus/usb/ar9271/htc.h

    r4cb0148 r9e5a51c  
    4545
    4646#define HTC_RTS_THRESHOLD 2304
    47 #define HTC_MAX_AMPDU 0xFFFF
    4847
    4948/**
     
    220219        uint8_t pad;
    221220} __attribute__((packed)) htc_sta_msg_t;
     221
     222/**
     223 * HTC message to inform target about available capabilities.
     224 */
     225typedef struct {
     226        uint32_t ampdu_limit;   /**< Big Endian value! */
     227        uint8_t ampdu_subframes;
     228        uint8_t enable_coex;
     229        uint8_t tx_chainmask;
     230        uint8_t pad;
     231} __attribute__((packed)) htc_cap_msg_t;
    222232
    223233/**
  • uspace/drv/bus/usb/ar9271/hw.c

    r4cb0148 r9e5a51c  
    6060                udelay(HW_WAIT_TIME_US);
    6161
    62                 int rc = wmi_reg_read(ar9271->htc_device, offset, &result);
    63                 if(rc != EOK) {
    64                         usb_log_debug("Failed to read register. Error %d\n",
    65                                 rc);
    66                         continue;
    67                 }
    68                
     62                wmi_reg_read(ar9271->htc_device, offset, &result);
    6963                if((result & mask) == value) {
    7064                        return EOK;
     
    9387        };
    9488       
    95         int rc = wmi_reg_buffer_write(ar9271->htc_device, buffer,
     89        wmi_reg_buffer_write(ar9271->htc_device, buffer,
    9690                sizeof(buffer) / sizeof(wmi_reg_t));
    97         if(rc != EOK) {
    98                 usb_log_error("Failed to set RT FORCE WAKE register.\n");
    99                 return rc;
    100         }
    10191       
    10292        udelay(2);
    10393       
    104         rc = wmi_reg_write(ar9271->htc_device, AR9271_RC, 0);
    105         if(rc != EOK) {
    106                 usb_log_error("Failed to reset MAC AHB register.\n");
    107                 return rc;
    108         }
    109        
    110         rc = wmi_reg_write(ar9271->htc_device, AR9271_RTC_RESET, 1);
    111         if(rc != EOK) {
    112                 usb_log_error("Failed to bring up RTC register.\n");
    113                 return rc;
    114         }
    115        
    116         rc = hw_read_wait(ar9271,
     94        wmi_reg_write(ar9271->htc_device, AR9271_RC, 0);
     95        wmi_reg_write(ar9271->htc_device, AR9271_RTC_RESET, 1);
     96       
     97        int rc = hw_read_wait(ar9271,
    11798                AR9271_RTC_STATUS,
    11899                AR9271_RTC_STATUS_MASK,
    119100                AR9271_RTC_STATUS_ON);
    120101        if(rc != EOK) {
    121                 usb_log_error("Failed to read wake up RTC register.\n");
     102                usb_log_error("Failed to wait for RTC wake up register.\n");
    122103                return rc;
    123104        }
     
    150131        };
    151132       
    152         int rc = wmi_reg_buffer_write(ar9271->htc_device, buffer,
     133        wmi_reg_buffer_write(ar9271->htc_device, buffer,
    153134                sizeof(buffer) / sizeof(wmi_reg_t));
    154         if(rc != EOK) {
    155                 usb_log_error("Failed to set warm reset register.\n");
    156                 return rc;
    157         }
    158135       
    159136        udelay(100);
    160137       
    161         rc = wmi_reg_write(ar9271->htc_device, AR9271_RTC_RC, 0);
    162         if(rc != EOK) {
    163                 usb_log_error("Failed to reset RTC RC register.\n");
    164                 return rc;
    165         }
    166        
    167         rc = hw_read_wait(ar9271, AR9271_RTC_RC, AR9271_RTC_RC_MASK, 0);
    168         if(rc != EOK) {
    169                 usb_log_error("Failed to read RTC RC register.\n");
    170                 return rc;
    171         }
    172        
    173         rc = wmi_reg_write(ar9271->htc_device, AR9271_RC, 0);
    174         if(rc != EOK) {
    175                 usb_log_error("Failed to reset MAC AHB register.\n");
    176                 return rc;
    177         }
     138        wmi_reg_write(ar9271->htc_device, AR9271_RTC_RC, 0);
     139       
     140        int rc = hw_read_wait(ar9271, AR9271_RTC_RC, AR9271_RTC_RC_MASK, 0);
     141        if(rc != EOK) {
     142                usb_log_error("Failed to wait for RTC RC register.\n");
     143                return rc;
     144        }
     145       
     146        wmi_reg_write(ar9271->htc_device, AR9271_RC, 0);
     147        wmi_reg_clear_bit(ar9271->htc_device, AR9271_STATION_ID1,
     148                AR9271_STATION_ID1_POWER_SAVING);
    178149       
    179150        return EOK;
     
    182153static int hw_addr_init(ar9271_t *ar9271)
    183154{
    184         int rc;
    185155        uint32_t value;
    186156        nic_address_t ar9271_address;
    187157       
    188158        for(int i = 0; i < 3; i++) {
    189                 rc = wmi_reg_read(ar9271->htc_device,
     159                wmi_reg_read(ar9271->htc_device,
    190160                        AR9271_EEPROM_MAC_ADDR_START + i*4,
    191161                        &value);
    192                
    193                 if(rc != EOK) {
    194                         usb_log_error("Failed to read %d. byte of MAC address."
    195                                 "\n", i);
    196                         return rc;
    197                 }
    198162               
    199163                uint16_t two_bytes = uint16_t_be2host(value);
     
    204168        nic_t *nic = nic_get_from_ddf_dev(ar9271->ddf_dev);
    205169       
    206         rc = nic_report_address(nic, &ar9271_address);
     170        int rc = nic_report_address(nic, &ar9271_address);
    207171        if(rc != EOK) {
    208172                usb_log_error("Failed to report NIC HW address.\n");
    209                         return rc;
     173                return rc;
    210174        }
    211175       
     
    227191        gpio_shift = (gpio % 6) * 5;
    228192       
    229         int rc = wmi_reg_read(ar9271->htc_device, address, &temp);
    230         if(rc != EOK) {
    231                 usb_log_error("Failed to read GPIO output mux.\n");
    232                 return rc;
    233         }
    234        
     193        wmi_reg_read(ar9271->htc_device, address, &temp);
     194
    235195        temp = ((temp & 0x1F0) << 1) | (temp & ~0x1F0);
    236196        temp &= ~(0x1f << gpio_shift);
    237197        temp |= (type << gpio_shift);
    238        
    239         rc = wmi_reg_write(ar9271->htc_device, address, temp);
    240         if(rc != EOK) {
    241                 usb_log_error("Failed to write GPIO output mux.\n");
    242                 return rc;
    243         }
     198
     199        wmi_reg_write(ar9271->htc_device, address, temp);
    244200       
    245201        gpio_shift = 2 * gpio;
    246202       
    247         rc = wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_GPIO_OE_OUT,
     203        wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_GPIO_OE_OUT,
    248204                AR9271_GPIO_OE_OUT_ALWAYS << gpio_shift,
    249205                AR9271_GPIO_OE_OUT_ALWAYS << gpio_shift);
    250         if(rc != EOK) {
    251                 usb_log_error("Failed to config GPIO as output.\n");
    252                 return rc;
    253         }
    254206       
    255207        return EOK;
     
    258210static int hw_gpio_set_value(ar9271_t *ar9271, uint32_t gpio, uint32_t value)
    259211{
    260         int rc = wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_GPIO_IN_OUT,
     212        wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_GPIO_IN_OUT,
    261213                (~value & 1) << gpio, 1 << gpio);
    262         if(rc != EOK) {
    263                 usb_log_error("Failed to set GPIO.\n");
    264                 return rc;
    265         }
    266        
    267214        return EOK;
    268215}
     
    321268        uint32_t set_bit = 0x10000000;
    322269       
    323         /* NOTICE: Fall-through switch statement! */
    324270        switch(op_mode) {
    325271                case IEEE80211_OPMODE_ADHOC:
    326272                        set_bit |= AR9271_OPMODE_ADHOC_MASK;
     273                        wmi_reg_set_bit(ar9271->htc_device, AR9271_CONFIG,
     274                                AR9271_CONFIG_ADHOC);
     275                        break;
    327276                case IEEE80211_OPMODE_MESH:
    328277                case IEEE80211_OPMODE_AP:
     
    342291}
    343292
     293static int hw_reset_operating_mode(ar9271_t *ar9271)
     294{
     295        int rc = hw_set_operating_mode(ar9271, IEEE80211_OPMODE_STATION);
     296        if(rc != EOK) {
     297                usb_log_error("Failed to set opmode to station.\n");
     298                return rc;
     299        }
     300       
     301        return EOK;
     302}
     303
     304static int hw_noise_floor_calibration(ar9271_t *ar9271)
     305{
     306        wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
     307                AR9271_AGC_CONTROL_NF_CALIB_EN);
     308       
     309        wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
     310                AR9271_AGC_CONTROL_NF_NOT_UPDATE);
     311       
     312        wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
     313                AR9271_AGC_CONTROL_NF_CALIB);
     314       
     315        return EOK;
     316}
     317
    344318static int hw_set_freq(ar9271_t *ar9271, uint16_t freq)
    345319{
     
    373347}
    374348
     349int hw_freq_switch(ar9271_t *ar9271, uint16_t freq)
     350{
     351        wmi_reg_write(ar9271->htc_device, AR9271_PHY_RFBUS_KILL, 0x1);
     352       
     353        int rc = hw_read_wait(ar9271, AR9271_PHY_RFBUS_GRANT, 0x1, 0x1);
     354        if(rc != EOK) {
     355                usb_log_error("Failed to kill RF bus.\n");
     356                return rc;
     357        }
     358       
     359        rc = hw_set_freq(ar9271, freq);
     360        if(rc != EOK) {
     361                usb_log_error("Failed to HW set frequency.\n");
     362                return rc;
     363        }
     364       
     365        udelay(1000);
     366        wmi_reg_write(ar9271->htc_device, AR9271_PHY_RFBUS_KILL, 0x0);
     367       
     368        rc = hw_noise_floor_calibration(ar9271);
     369        if(rc != EOK) {
     370                usb_log_error("Failed to do NF calibration.\n");
     371                return rc;
     372        }
     373       
     374        return EOK;
     375}
     376
    375377static int hw_set_rx_filter(ar9271_t *ar9271)
    376378{
    377379        uint32_t filter_bits;
    378         int rc = wmi_reg_read(ar9271->htc_device, AR9271_RX_FILTER,
    379                 &filter_bits);
    380         if(rc != EOK) {
    381                 usb_log_error("Failed to read RX filter.\n");
    382                 return EINVAL;
    383         }
    384380       
    385381        /* TODO: Do proper filtering here. */
    386382       
    387         filter_bits |= AR9271_RX_FILTER_UNI | AR9271_RX_FILTER_MULTI |
    388                 AR9271_RX_FILTER_BROAD | AR9271_RX_FILTER_PROMISCUOUS;
    389        
    390         rc = wmi_reg_write(ar9271->htc_device, AR9271_RX_FILTER, filter_bits);
    391         if(rc != EOK) {
    392                 usb_log_error("Failed to write RX filter.\n");
    393                 return EINVAL;
    394         }
     383        filter_bits = AR9271_RX_FILTER_UNI | AR9271_RX_FILTER_MULTI |
     384                AR9271_RX_FILTER_BROAD | AR9271_RX_FILTER_BEACON;
     385       
     386        wmi_reg_write(ar9271->htc_device, AR9271_RX_FILTER, filter_bits);
    395387       
    396388        return EOK;
     
    399391int hw_rx_init(ar9271_t *ar9271)
    400392{
    401         int rc = wmi_reg_write(ar9271->htc_device, AR9271_COMMAND,
     393        wmi_reg_write(ar9271->htc_device, AR9271_COMMAND,
    402394                AR9271_COMMAND_RX_ENABLE);
    403         if(rc != EOK) {
    404                 usb_log_error("Failed to send RX enable command.\n");
    405                 return EINVAL;
    406         }
    407        
    408         rc = hw_set_rx_filter(ar9271);
     395       
     396        int rc = hw_set_rx_filter(ar9271);
    409397        if(rc != EOK) {
    410398                usb_log_error("Failed to set RX filtering.\n");
    411                 return EINVAL;
     399                return rc;
    412400        }
    413401       
     
    415403        wmi_reg_write(ar9271->htc_device, AR9271_MULTICAST_FILTER2, ~0);
    416404       
     405        /* Disable RX blocking. */
     406        wmi_reg_clear_bit(ar9271->htc_device, AR9271_DIAG, (0x20 | 0x02000000));
     407       
    417408        return EOK;
    418409}
     
    420411static int hw_activate_phy(ar9271_t *ar9271)
    421412{
    422         int rc = wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 1);
    423         if(rc != EOK) {
    424                 usb_log_error("Failed to activate set PHY active.\n");
    425                 return rc;
    426         }
    427        
     413        wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 1);
    428414        udelay(1000);
    429415       
     
    435421        uint32_t pll;
    436422       
    437         /* Some magic here. */
     423        /* Some magic here (set for 2GHz channels). But VERY important :-) */
    438424        pll = (0x5 << 10) & 0x00003C00;
    439         pll |= (0x2 << 14) & 0x0000C000; /**< 0x2 ~ quarter rate (0x1 half) */
    440425        pll |= 0x2C & 0x000003FF;
    441426       
    442         return wmi_reg_write(ar9271->htc_device, AR9271_RTC_PLL_CONTROL, pll);
     427        wmi_reg_write(ar9271->htc_device, AR9271_RTC_PLL_CONTROL, pll);
     428       
     429        return EOK;
    443430}
    444431
     
    453440                reg_offset = ar9271_2g_mode_array[i][0];
    454441                reg_value = ar9271_2g_mode_array[i][1];
     442                wmi_reg_write(ar9271->htc_device, reg_offset, reg_value);
     443        }
     444       
     445        size = sizeof(ar9271_2g_tx_array) / sizeof(ar9271_2g_tx_array[0]);
     446       
     447        for(int i = 0; i < size; i++) {
     448                reg_offset = ar9271_2g_tx_array[i][0];
     449                reg_value = ar9271_2g_tx_array[i][1];
    455450                wmi_reg_write(ar9271->htc_device, reg_offset, reg_value);
    456451        }
     
    497492}
    498493
    499 static int hw_noise_floor_calibration(ar9271_t *ar9271)
    500 {
    501         wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
    502                 AR9271_AGC_CONTROL_NF_CALIB_EN);
    503        
    504         wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
    505                 AR9271_AGC_CONTROL_NF_NOT_UPDATE);
    506        
    507         wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
    508                 AR9271_AGC_CONTROL_NF_CALIB);
    509        
    510         return EOK;
    511 }
    512 
    513494int hw_reset(ar9271_t *ar9271)
    514495{
    515496        /* Set physical layer as deactivated. */
    516         int rc = wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 0);
    517         if(rc != EOK) {
    518                 usb_log_error("Failed to set PHY deactivated.\n");
    519                 return rc;
    520         }
    521        
    522         rc = wmi_reg_write(ar9271->htc_device,
    523                 AR9271_RESET_POWER_DOWN_CONTROL,
    524                 AR9271_RADIO_RF_RESET);
    525         if(rc != EOK) {
    526                 usb_log_error("Failed to reset radio rf.\n");
    527                 return rc;
    528         }
    529        
    530         udelay(50);
    531        
    532         /* TODO: There should be cold reset only if RX or TX is enabled. */
    533        
    534         rc = hw_init_pll(ar9271);
     497        wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 0);
     498       
     499        if(ar9271->starting_up) {
     500                wmi_reg_write(ar9271->htc_device,
     501                        AR9271_RESET_POWER_DOWN_CONTROL,
     502                        AR9271_RADIO_RF_RESET);
     503
     504                udelay(50);
     505        }
     506       
     507        /* Cold reset when RX is enabled. */
     508        uint32_t config_reg;
     509        wmi_reg_read(ar9271->htc_device, AR9271_COMMAND, &config_reg);
     510        if(config_reg & AR9271_COMMAND_RX_ENABLE) {
     511                hw_set_reset(ar9271, true);
     512        }
     513       
     514        int rc = hw_init_pll(ar9271);
    535515        if(rc != EOK) {
    536516                usb_log_error("Failed to init PLL.\n");
     
    540520        udelay(500);
    541521       
    542         rc = wmi_reg_write(ar9271->htc_device,
    543                 AR9271_CLOCK_CONTROL,
     522        wmi_reg_write(ar9271->htc_device, AR9271_CLOCK_CONTROL,
    544523                AR9271_MAX_CPU_CLOCK);
    545         if(rc != EOK) {
    546                 usb_log_error("Failed to set CPU clock.\n");
    547                 return rc;
    548         }
    549524       
    550525        udelay(100);
    551526       
    552         rc = wmi_reg_write(ar9271->htc_device,
    553                 AR9271_RESET_POWER_DOWN_CONTROL,
    554                 AR9271_GATE_MAC_CONTROL);
    555         if(rc != EOK) {
    556                 usb_log_error("Failed to set the gate reset controls for MAC."
    557                         "\n");
    558                 return rc;
    559         }
    560        
    561         udelay(50);
     527        if(ar9271->starting_up) {
     528                wmi_reg_write(ar9271->htc_device,
     529                        AR9271_RESET_POWER_DOWN_CONTROL,
     530                        AR9271_GATE_MAC_CONTROL);
     531
     532                udelay(50);
     533        }
    562534       
    563535        rc = hw_set_init_values(ar9271);
     
    567539        }
    568540       
    569         /* TODO: There should probably be TX power settings. */
    570        
    571541        /* Set physical layer mode. */
    572         rc = wmi_reg_write(ar9271->htc_device, AR9271_PHY_MODE,
     542        wmi_reg_write(ar9271->htc_device, AR9271_PHY_MODE,
    573543                AR9271_PHY_MODE_DYNAMIC);
    574         if(rc != EOK) {
    575                 usb_log_error("Failed to set physical layer mode.\n");
    576                 return rc;
    577         }
    578        
    579         /* Set device operating mode. */
    580         rc = hw_set_operating_mode(ar9271, IEEE80211_OPMODE_STATION);
    581         if(rc != EOK) {
    582                 usb_log_error("Failed to set opmode to station.\n");
    583                 return rc;
    584         }
    585        
    586         /* Set channel frequency. */
    587         rc = hw_set_freq(ar9271, 2437);
     544       
     545        /* Reset device operating mode. */
     546        rc = hw_reset_operating_mode(ar9271);
     547        if(rc != EOK) {
     548                usb_log_error("Failed to reset operating mode.\n");
     549                return rc;
     550        }
     551       
     552        /* Set initial channel frequency. */
     553        rc = hw_set_freq(ar9271, IEEE80211_FIRST_FREQ);
    588554        if(rc != EOK) {
    589555                usb_log_error("Failed to set channel.\n");
     
    593559        /* Initialize transmission queues. */
    594560        for(int i = 0; i < AR9271_QUEUES_COUNT; i++) {
    595                 rc = wmi_reg_write(ar9271->htc_device,
     561                wmi_reg_write(ar9271->htc_device,
    596562                        AR9271_QUEUE_BASE_MASK + (i << 2),
    597563                        1 << i);
    598                 if(rc != EOK) {
    599                         usb_log_error("Failed to initialize transmission queue."
    600                                 "\n");
    601                         return rc;
    602                 }
    603         }
    604        
    605         /* TODO: Maybe resetting TX queues will be necessary afterwards here. */
     564        }
    606565       
    607566        /* Activate physical layer. */
     
    624583                return rc;
    625584        }
     585       
     586        /* Byteswap TX and RX data buffer words. */
     587        wmi_reg_write(ar9271->htc_device, AR9271_CONFIG, 0xA);
    626588       
    627589        usb_log_info("HW reset done.\n");
  • uspace/drv/bus/usb/ar9271/hw.h

    r4cb0148 r9e5a51c  
    4242
    4343extern int hw_init(ar9271_t *ar9271);
     44extern int hw_freq_switch(ar9271_t *, uint16_t freq);
    4445extern int hw_rx_init(ar9271_t *ar9271);
    4546extern int hw_reset(ar9271_t *ar9271);
  • uspace/lib/net/ieee80211/ieee80211.c

    r4cb0148 r9e5a51c  
    4242#include <ieee80211.h>
    4343
     44/** Broadcast MAC address used to spread probe request through channel. */
     45static const uint8_t ieee80211_broadcast_mac_addr[] = {
     46        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
     47};
     48
     49/** IEEE 802.11 b/g supported data rates in units of 500 kb/s. */
     50static const uint8_t ieee80211bg_data_rates[] = {
     51        2, 4, 11, 12, 18, 22, 24, 36
     52};
     53
     54/** IEEE 802.11 b/g extended supported data rates in units of 500 kb/s.
     55 *
     56 *  These are defined separately, because probe request message can
     57 *  only handle up to 8 data rates in supported rates IE.
     58 */
     59static const uint8_t ieee80211bg_ext_data_rates[] = {
     60        48, 72, 96, 108
     61};
     62
    4463/** Network interface options for IEEE 802.11 driver. */
    4564static nic_iface_t ieee80211_nic_iface;
     
    4766/** Basic driver operations for IEEE 802.11 NIC driver. */
    4867static driver_ops_t ieee80211_nic_driver_ops;
    49 
    50 bool ieee80211_is_data_frame(ieee80211_header_t *header)
    51 {
    52         return (header->frame_ctrl &
    53                 host2uint16_t_le(IEEE80211_FRAME_CTRL_FRAME_TYPE)) ==
    54                 host2uint16_t_le(IEEE80211_FRAME_CTRL_DATA_FRAME);
    55 }
    5668
    5769static int ieee80211_open(ddf_fun_t *fun)
     
    7082                return rc;
    7183       
    72         /*
    7384        rc = ieee80211_dev->ops->scan(ieee80211_dev);
    7485        if(rc != EOK)
    7586                return rc;
    76          */
    7787       
    7888        return EOK;
     
    93103        /* IEEE802.11 TX handler must be implemented. */
    94104        if(!ieee80211_ops->tx_handler)
     105                return EINVAL;
     106       
     107        /* IEEE802.11 set frequency handler must be implemented. */
     108        if(!ieee80211_ops->set_freq)
    95109                return EINVAL;
    96110       
     
    119133        ieee80211_dev->current_op_mode = IEEE80211_OPMODE_STATION;
    120134       
     135        memcpy(ieee80211_dev->bssid_mask, ieee80211_broadcast_mac_addr,
     136                ETH_ADDR);
     137       
    121138        /* Bind NIC to device */
    122139        nic_t *nic = nic_create_and_bind(ddf_dev);
     
    175192}
    176193
     194static uint8_t ieee80211_freq_to_channel(uint16_t freq)
     195{
     196        return (freq - IEEE80211_FIRST_FREQ) / IEEE80211_CHANNEL_GAP + 1;
     197}
     198
     199int ieee80211_probe_request(ieee80211_dev_t *ieee80211_dev)
     200{
     201        nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev);
     202        nic_address_t nic_address;
     203        nic_query_address(nic, &nic_address);
     204       
     205        size_t data_rates_size =
     206                sizeof(ieee80211bg_data_rates) /
     207                sizeof(ieee80211bg_data_rates[0]);
     208       
     209        size_t ext_data_rates_size =
     210                sizeof(ieee80211bg_ext_data_rates) /
     211                sizeof(ieee80211bg_ext_data_rates[0]);
     212       
     213        /* 3 headers - (rates, ext rates, current channel) and their data
     214         * lengths + pad.
     215         */
     216        size_t payload_size =
     217                sizeof(ieee80211_ie_header_t) * 3 +
     218                data_rates_size + ext_data_rates_size + sizeof(uint8_t) + 2;
     219       
     220        size_t buffer_size = sizeof(ieee80211_mgmt_header_t) + payload_size;
     221        void *buffer = malloc(buffer_size);
     222        memset(buffer, 0, buffer_size);
     223       
     224        ieee80211_mgmt_header_t *mgmt_header =
     225                (ieee80211_mgmt_header_t *) buffer;
     226       
     227        mgmt_header->frame_ctrl = host2uint16_t_le(
     228                IEEE80211_MGMT_FRAME |
     229                IEEE80211_MGMT_PROBE_REQ_FRAME
     230                );
     231        memcpy(mgmt_header->dest_addr, ieee80211_broadcast_mac_addr, ETH_ADDR);
     232        memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR);
     233        memcpy(mgmt_header->bssid, ieee80211_broadcast_mac_addr, ETH_ADDR);
     234       
     235        /* Jump to payload -> header + padding. */
     236        uint8_t *it = buffer + sizeof(ieee80211_mgmt_header_t) + 2;
     237       
     238        *it++ = IEEE80211_RATES_IE;
     239        *it++ = data_rates_size;
     240        memcpy(it, ieee80211bg_data_rates, data_rates_size);
     241        it += data_rates_size;
     242       
     243        *it++ = IEEE80211_EXT_RATES_IE;
     244        *it++ = ext_data_rates_size;
     245        memcpy(it, ieee80211bg_ext_data_rates, ext_data_rates_size);
     246        it += ext_data_rates_size;
     247       
     248        *it++ = IEEE80211_CHANNEL_IE;
     249        *it++ = 1;
     250        *it = ieee80211_freq_to_channel(ieee80211_dev->current_freq);
     251       
     252        ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size);
     253       
     254        free(buffer);
     255       
     256        return EOK;
     257}
     258
     259int ieee80211_probe_auth(ieee80211_dev_t *ieee80211_dev)
     260{
     261        uint8_t test_bssid[] = {0x14, 0xF6, 0x5A, 0xAF, 0x5E, 0xB7};
     262       
     263        nic_t *nic = nic_get_from_ddf_dev(ieee80211_dev->ddf_dev);
     264        nic_address_t nic_address;
     265        nic_query_address(nic, &nic_address);
     266       
     267        size_t buffer_size = sizeof(ieee80211_mgmt_header_t) +
     268                sizeof(ieee80211_auth_body_t);
     269        void *buffer = malloc(buffer_size);
     270        memset(buffer, 0, buffer_size);
     271       
     272        ieee80211_mgmt_header_t *mgmt_header =
     273                (ieee80211_mgmt_header_t *) buffer;
     274       
     275        mgmt_header->frame_ctrl = host2uint16_t_le(
     276                IEEE80211_MGMT_FRAME |
     277                IEEE80211_MGMT_AUTH_FRAME
     278                );
     279        memcpy(mgmt_header->dest_addr, test_bssid, ETH_ADDR);
     280        memcpy(mgmt_header->src_addr, nic_address.address, ETH_ADDR);
     281        memcpy(mgmt_header->bssid, test_bssid, ETH_ADDR);
     282       
     283        ieee80211_auth_body_t *auth_body =
     284                (ieee80211_auth_body_t *)
     285                (buffer + sizeof(ieee80211_mgmt_header_t));
     286        auth_body->auth_alg = host2uint16_t_le(0);
     287        auth_body->auth_trans_no = host2uint16_t_le(0);
     288       
     289        ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size);
     290       
     291        free(buffer);
     292       
     293        return EOK;
     294}
     295
    177296/** @}
    178297 */
  • uspace/lib/net/ieee80211/ieee80211_impl.c

    r4cb0148 r9e5a51c  
    4040#include <ieee80211_impl.h>
    4141
    42 static int ieee80211_freq_to_channel(uint16_t freq)
    43 {
    44         return (freq - IEEE80211_FIRST_FREQ) / IEEE80211_CHANNEL_GAP + 1;
    45 }
    46 
    47 static int ieee80211_probe_request(ieee80211_dev_t *ieee80211_dev)
    48 {
    49         size_t buffer_size = sizeof(ieee80211_header_t);
    50         void *buffer = malloc(buffer_size);
    51        
    52         /* TODO */
    53        
    54         ieee80211_freq_to_channel(ieee80211_dev->current_freq);
    55        
    56         ieee80211_dev->ops->tx_handler(ieee80211_dev, buffer, buffer_size);
    57        
    58         free(buffer);
    59        
    60         return EOK;
    61 }
    62 
    6342/**
    6443 * Default implementation of IEEE802.11 scan function.
     
    7049int ieee80211_scan_impl(ieee80211_dev_t *ieee80211_dev)
    7150{
    72         /* TODO */
    73         int rc = ieee80211_probe_request(ieee80211_dev);
    74         if(rc != EOK)
    75                 return rc;
     51        uint16_t orig_freq = ieee80211_dev->current_freq;
     52       
     53        for(uint16_t freq = IEEE80211_FIRST_FREQ;
     54                freq <= IEEE80211_MAX_FREQ;
     55                freq += IEEE80211_CHANNEL_GAP) {
     56                ieee80211_dev->ops->set_freq(ieee80211_dev, freq);
     57                ieee80211_probe_request(ieee80211_dev);
     58               
     59                /* Wait for probe responses. */
     60                usleep(100000);
     61        }
     62       
     63        ieee80211_dev->ops->set_freq(ieee80211_dev, orig_freq);
     64       
     65        /* TODO: Collect results. */
    7666       
    7767        return EOK;
  • uspace/lib/net/include/ieee80211.h

    r4cb0148 r9e5a51c  
    5252#define IEEE80211_CHANNEL_GAP 5
    5353
    54 #define IEEE80211_FRAME_CTRL_FRAME_TYPE 0x000C
    55 #define IEEE80211_FRAME_CTRL_DATA_FRAME 0x0008
    56 
    5754struct ieee80211_dev;
    5855
     
    6562} ieee80211_operating_mode_t;
    6663
     64/** IEEE 802.11 frame types. */
     65typedef enum {
     66        IEEE80211_MGMT_FRAME = 0x0,
     67        IEEE80211_CTRL_FRAME = 0x4,
     68        IEEE80211_DATA_FRAME = 0x8,
     69        IEEE80211_EXT_FRAME = 0xC
     70} ieee80211_frame_type_t;
     71
     72/** IEEE 802.11 frame subtypes. */
     73typedef enum {
     74        IEEE80211_MGMT_ASSOC_REQ_FRAME = 0x00,
     75        IEEE80211_MGMT_ASSOC_RESP_FRAME = 0x10,
     76        IEEE80211_MGMT_REASSOC_REQ_FRAME = 0x20,
     77        IEEE80211_MGMT_REASSOC_RESP_FRAME = 0x30,
     78        IEEE80211_MGMT_PROBE_REQ_FRAME = 0x40,
     79        IEEE80211_MGMT_PROBE_RESP_FRAME = 0x50,
     80        IEEE80211_MGMT_BEACON_FRAME = 0x80,
     81        IEEE80211_MGMT_DIASSOC_FRAME = 0xA0,
     82        IEEE80211_MGMT_AUTH_FRAME = 0xB0,
     83        IEEE80211_MGMT_DEAUTH_FRAME = 0xC0,
     84} ieee80211_frame_subtype_t;
     85
     86/** IEEE 802.11 information element types. */
     87typedef enum {
     88        IEEE80211_SSID_IE = 0,          /**< Target SSID. */
     89        IEEE80211_RATES_IE = 1,         /**< Supported data rates. */
     90        IEEE80211_CHANNEL_IE = 3,       /**< Current channel number. */
     91        IEEE80211_EXT_RATES_IE = 50     /**< Extended data rates. */
     92} ieee80211_ie_type_t;
     93
    6794/** IEEE 802.11 functions. */
    6895typedef struct {
     
    7097        int (*scan)(struct ieee80211_dev *);
    7198        int (*tx_handler)(struct ieee80211_dev *, void *, size_t);
     99        int (*set_freq)(struct ieee80211_dev *, uint16_t);
    72100} ieee80211_ops_t;
    73101
     
    89117        ieee80211_operating_mode_t current_op_mode;
    90118       
     119        /** BSSIDs we listen to. */
     120        uint8_t bssid_mask[ETH_ADDR];
     121       
    91122        /* TODO: Probably to be removed later - nic.open function is now
    92123         * executed multiple times, have to find out reason and fix it.
     
    96127} ieee80211_dev_t;
    97128
    98 /** IEEE 802.11 header structure. */
     129/** IEEE 802.11 management header structure. */
     130typedef struct {
     131        uint16_t frame_ctrl;            /**< Little Endian value! */
     132        uint16_t duration_id;           /**< Little Endian value! */
     133        uint8_t dest_addr[ETH_ADDR];
     134        uint8_t src_addr[ETH_ADDR];
     135        uint8_t bssid[ETH_ADDR];
     136        uint16_t seq_ctrl;              /**< Little Endian value! */
     137} __attribute__((packed)) __attribute__ ((aligned(2))) ieee80211_mgmt_header_t;
     138
     139/** IEEE 802.11 data header structure. */
    99140typedef struct {
    100141        uint16_t frame_ctrl;            /**< Little Endian value! */
     
    105146        uint16_t seq_ctrl;              /**< Little Endian value! */
    106147        uint8_t address4[ETH_ADDR];
    107 } __attribute__((packed)) __attribute__ ((aligned(2))) ieee80211_header_t;
     148        uint16_t qos_ctrl;              /**< Little Endian value! */
     149} __attribute__((packed)) __attribute__ ((aligned(2))) ieee80211_data_header_t;
    108150
    109 extern bool ieee80211_is_data_frame(ieee80211_header_t *header);
     151/** IEEE 802.11 information element header. */
     152typedef struct {
     153        uint8_t element_id;
     154        uint8_t length;
     155} __attribute__((packed)) __attribute__ ((aligned(2))) ieee80211_ie_header_t;
     156
     157/** IEEE 802.11 authentication frame body. */
     158typedef struct {
     159        uint16_t auth_alg;              /**< Little Endian value! */
     160        uint16_t auth_trans_no;         /**< Little Endian value! */
     161        uint16_t status;                /**< Little Endian value! */
     162} __attribute__((packed)) __attribute__ ((aligned(2))) ieee80211_auth_body_t;
     163
     164typedef struct {
     165        uint8_t bssid[ETH_ADDR];
     166        uint16_t auth_alg;
     167} __attribute__((packed)) __attribute__ ((aligned(2))) ieee80211_auth_data_t;
     168
    110169extern int ieee80211_device_init(ieee80211_dev_t *ieee80211_dev,
    111170        void *driver_data, ddf_dev_t *ddf_dev);
    112171extern int ieee80211_init(ieee80211_dev_t *ieee80211_dev,
    113172        ieee80211_ops_t *ieee80211_ops);
     173extern int ieee80211_probe_request(ieee80211_dev_t *ieee80211_dev);
     174extern int ieee80211_probe_auth(ieee80211_dev_t *ieee80211_dev);
    114175
    115176#endif /* LIBNET_IEEE80211_H */
Note: See TracChangeset for help on using the changeset viewer.