Changeset 9e5a51c in mainline for uspace/drv


Ignore:
Timestamp:
2015-03-08T22:20:34Z (10 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/drv/bus/usb/ar9271
Files:
8 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);
Note: See TracChangeset for help on using the changeset viewer.