Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset ab365c4 in mainline


Ignore:
Timestamp:
2015-02-13T12:15:00Z (6 years ago)
Author:
Jan Kolarik <kolarik@…>
Branches:
master
Children:
56c0930
Parents:
462054a
Message:

Created library for IEEE802.11 related stuff. Mostly done device startup initialization.

Location:
uspace
Files:
4 added
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/Makefile.common

    r462054a rab365c4  
    258258
    259259ifeq ($(CONFIG_DEBUG),y)
    260 #       GCC_CFLAGS += -Werror
     260        GCC_CFLAGS += -Werror
    261261        ICC_CFLAGS += -Werror
    262262endif
  • uspace/drv/bus/usb/ar9271/Makefile

    r462054a rab365c4  
    3333        $(LIBUSB_PREFIX)/libusb.a \
    3434        $(LIBDRV_PREFIX)/libdrv.a \
    35         $(LIBNIC_PREFIX)/libnic.a
     35        $(LIBNIC_PREFIX)/libnic.a \
     36        $(LIBNET_PREFIX)/libnet.a
    3637       
    3738EXTRA_CFLAGS += \
     
    4041        -I$(LIBUSBDEV_PREFIX)/include \
    4142        -I$(LIBDRV_PREFIX)/include \
    42         -I$(LIBNIC_PREFIX)/include
     43        -I$(LIBNIC_PREFIX)/include \
     44        -I$(LIBNET_PREFIX)/include \
    4345       
    4446BINARY = ar9271
  • uspace/drv/bus/usb/ar9271/ar9271.c

    r462054a rab365c4  
    3333 */
    3434
     35#include <ieee80211.h>
    3536#include <usb/classes/classes.h>
    3637#include <usb/dev/request.h>
     
    9596};
    9697
    97 /** Network interface options for AR9271 driver. */
    98 static nic_iface_t ar9271_nic_iface;
    99 
    100 /** Basic device operations for AR9271 NIC driver. */
    101 static ddf_dev_ops_t ar9271_nic_dev_ops;
    102 
    103 /** Basic driver operations for AR9271 NIC driver. */
    104 static driver_ops_t ar9271_nic_driver_ops;
    105 
    10698/* Callback when new device is to be controlled by this driver. */
    10799static int ar9271_add_device(ddf_dev_t *);
     100
     101/* IEEE802.11 callbacks */
     102static int ar9271_ieee80211_start(ieee80211_dev_t *ieee80211_dev);
    108103
    109104static driver_ops_t ar9271_driver_ops = {
     
    116111};
    117112
    118 /* The default implementation callbacks */
    119 static int ar9271_on_activating(nic_t *);
    120 static int ar9271_on_stopping(nic_t *);
    121 static void ar9271_send_frame(nic_t *, void *, size_t);
     113static ieee80211_ops_t ar9271_ieee80211_ops = {
     114        .start = ar9271_ieee80211_start
     115};
     116
     117static int ar9271_set_rx_filter(ar9271_t *ar9271)
     118{
     119        uint32_t filter_bits;
     120        int rc = wmi_reg_read(ar9271->htc_device, AR9271_RX_FILTER,
     121                &filter_bits);
     122        if(rc != EOK) {
     123                usb_log_error("Failed to read RX filter.\n");
     124                return EINVAL;
     125        }
     126       
     127        /* TODO: Do proper filtering here. */
     128       
     129        filter_bits |= AR9271_RX_FILTER_UNI | AR9271_RX_FILTER_MULTI |
     130                AR9271_RX_FILTER_BROAD | AR9271_RX_FILTER_PROMISCUOUS;
     131       
     132        rc = wmi_reg_write(ar9271->htc_device, AR9271_RX_FILTER, filter_bits);
     133        if(rc != EOK) {
     134                usb_log_error("Failed to write RX filter.\n");
     135                return EINVAL;
     136        }
     137       
     138        return EOK;
     139}
     140
     141static int ar9271_rx_init(ar9271_t *ar9271)
     142{
     143        int rc = wmi_reg_write(ar9271->htc_device, AR9271_COMMAND,
     144                AR9271_COMMAND_RX_ENABLE);
     145        if(rc != EOK) {
     146                usb_log_error("Failed to send RX enable command.\n");
     147                return EINVAL;
     148        }
     149       
     150        rc = ar9271_set_rx_filter(ar9271);
     151        if(rc != EOK) {
     152                usb_log_error("Failed to set RX filtering.\n");
     153                return EINVAL;
     154        }
     155       
     156        return EOK;
     157}
     158
     159static int ar9271_ieee80211_start(ieee80211_dev_t *ieee80211_dev)
     160{
     161        ar9271_t *ar9271 = (ar9271_t *) ieee80211_dev->driver_data;
     162       
     163        int rc = wmi_send_command(ar9271->htc_device, WMI_FLUSH_RECV, NULL, 0,
     164                NULL);
     165        if(rc != EOK) {
     166                usb_log_error("Failed to flush receiving buffer.\n");
     167                return EINVAL;
     168        }
     169       
     170        rc = hw_reset(ar9271);
     171        if(rc != EOK) {
     172                usb_log_error("Failed to do HW reset.\n");
     173                return EINVAL;
     174        }
     175       
     176        uint16_t htc_mode = host2uint16_t_be(1);
     177        rc = wmi_send_command(ar9271->htc_device, WMI_SET_MODE,
     178                (uint8_t *) &htc_mode, sizeof(htc_mode), NULL);
     179        if(rc != EOK) {
     180                usb_log_error("Failed to set HTC mode.\n");
     181                return EINVAL;
     182        }
     183       
     184        rc = wmi_send_command(ar9271->htc_device, WMI_ATH_INIT, NULL, 0,
     185                NULL);
     186        if(rc != EOK) {
     187                usb_log_error("Failed to send ath init command.\n");
     188                return EINVAL;
     189        }
     190       
     191        rc = wmi_send_command(ar9271->htc_device, WMI_START_RECV, NULL, 0,
     192                NULL);
     193        if(rc != EOK) {
     194                usb_log_error("Failed to send receiving init command.\n");
     195                return EINVAL;
     196        }
     197       
     198        rc = ar9271_rx_init(ar9271);
     199        if(rc != EOK) {
     200                usb_log_error("Failed to initialize RX.\n");
     201                return EINVAL;
     202        }
     203       
     204        return EOK;
     205}
    122206
    123207static int ar9271_init(ar9271_t *ar9271, usb_device_t *usb_device)
     
    125209        ar9271->usb_device = usb_device;
    126210       
    127         ath_t *ath_device = malloc(sizeof(ath_t));
    128         if (!ath_device) {
     211        ar9271->ath_device = calloc(1, sizeof(ath_t));
     212        if (!ar9271->ath_device) {
    129213                usb_log_error("Failed to allocate memory for ath device "
    130214                    "structure.\n");
     
    132216        }
    133217       
    134         int rc = ath_usb_init(ath_device, usb_device);
    135         if(rc != EOK) {
    136                 free(ath_device);
     218        int rc = ath_usb_init(ar9271->ath_device, usb_device);
     219        if(rc != EOK) {
     220                free(ar9271->ath_device);
    137221                usb_log_error("Failed to initialize ath device.\n");
    138222                return EINVAL;
     
    140224               
    141225        /* HTC device structure initialization. */
    142         ar9271->htc_device = malloc(sizeof(htc_device_t));
     226        ar9271->htc_device = calloc(1, sizeof(htc_device_t));
    143227        if(!ar9271->htc_device) {
    144                 free(ath_device);
     228                free(ar9271->ath_device);
    145229                usb_log_error("Failed to allocate memory for HTC device "
    146230                    "structure.\n");
     
    148232        }
    149233       
    150         memset(ar9271->htc_device, 0, sizeof(htc_device_t));
    151        
    152         rc = htc_device_init(ath_device, ar9271->htc_device);
     234        rc = htc_device_init(ar9271->ath_device, ar9271->htc_device);
    153235        if(rc != EOK) {
    154236                free(ar9271->htc_device);
    155                 free(ath_device);
    156                 usb_log_error("Failed to initialize HTC device.\n");
     237                free(ar9271->ath_device);
     238                usb_log_error("Failed to initialize HTC device structure.\n");
     239                return EINVAL;
     240        }
     241       
     242        /* IEEE 802.11 framework structure initialization. */
     243        ar9271->ieee80211_dev = calloc(1, sizeof(ieee80211_dev_t));
     244        if (!ar9271->ieee80211_dev) {
     245                free(ar9271->htc_device);
     246                free(ar9271->ath_device);
     247                usb_log_error("Failed to allocate memory for IEEE80211 device "
     248                    "structure.\n");
     249                return ENOMEM;
     250        }
     251       
     252        rc = ieee80211_device_init(ar9271->ieee80211_dev, ar9271,
     253                ar9271->ddf_dev);
     254        if(rc != EOK) {
     255                free(ar9271->ieee80211_dev);
     256                free(ar9271->htc_device);
     257                free(ar9271->ath_device);
     258                usb_log_error("Failed to initialize IEEE80211 device structure."
     259                        "\n");
    157260                return EINVAL;
    158261        }
     
    255358}
    256359
    257 /** Force receiving all frames in the receive buffer
    258  *
    259  * @param nic NIC data
    260  */
    261 static void ar9271_poll(nic_t *nic)
    262 {
    263         assert(nic);
    264 }
    265 
    266 /** Set polling mode
    267  *
    268  * @param device  Device to set
    269  * @param mode    Mode to set
    270  * @param period  Period for NIC_POLL_PERIODIC
    271  *
    272  * @return EOK if succeed, ENOTSUP if the mode is not supported
    273  */
    274 static int ar9271_poll_mode_change(nic_t *nic, nic_poll_mode_t mode,
    275     const struct timeval *period)
    276 {
    277         assert(nic);
    278         return EOK;
    279 }
    280 
    281 /** Set multicast frames acceptance mode
    282  *
    283  * @param nic      NIC device to update
    284  * @param mode     Mode to set
    285  * @param addr     Address list (used in mode = NIC_MULTICAST_LIST)
    286  * @param addr_cnt Length of address list (used in mode = NIC_MULTICAST_LIST)
    287  *
    288  * @return EOK if succeed, negative error code otherwise
    289  */
    290 static int ar9271_on_multicast_mode_change(nic_t *nic,
    291     nic_multicast_mode_t mode, const nic_address_t *addr, size_t addr_cnt)
    292 {
    293         assert(nic);
    294         return EOK;
    295 }
    296 
    297 /** Set unicast frames acceptance mode
    298  *
    299  * @param nic      NIC device to update
    300  * @param mode     Mode to set
    301  * @param addr     Address list (used in mode = NIC_MULTICAST_LIST)
    302  * @param addr_cnt Length of address list (used in mode = NIC_MULTICAST_LIST)
    303  *
    304  * @return EOK if succeed, negative error code otherwise
    305  */
    306 static int ar9271_on_unicast_mode_change(nic_t *nic, nic_unicast_mode_t mode,
    307     const nic_address_t *addr, size_t addr_cnt)
    308 {
    309         assert(nic);
    310         return EOK;
    311 }
    312 
    313 /** Set broadcast frames acceptance mode
    314  *
    315  * @param nic  NIC device to update
    316  * @param mode Mode to set
    317  *
    318  * @return EOK if succeed, negative error code otherwise
    319  */
    320 static int ar9271_on_broadcast_mode_change(nic_t *nic,
    321     nic_broadcast_mode_t mode)
    322 {
    323         assert(nic);
    324         return EOK;
    325 }
    326 
    327 /** Activate the device to receive and transmit frames
    328  *
    329  * @param nic NIC driver data
    330  *
    331  * @return EOK if activated successfully, negative error code otherwise
    332  */
    333 static int ar9271_on_activating(nic_t *nic)
    334 {
    335         assert(nic);
    336         return EOK;
    337 }
    338 
    339 /** Callback for NIC_STATE_STOPPED change
    340  *
    341  * @param nic NIC driver data
    342  *
    343  * @return EOK if succeed, negative error code otherwise
    344  */
    345 static int ar9271_on_stopping(nic_t *nic)
    346 {
    347         assert(nic);
    348         return EOK;
    349 }
    350 
    351 /** Send frame
    352  *
    353  * @param nic    NIC driver data structure
    354  * @param data   Frame data
    355  * @param size   Frame size in bytes
    356  */
    357 static void ar9271_send_frame(nic_t *nic, void *data, size_t size)
    358 {
    359         assert(nic);
    360 }
    361 
    362360/** Create driver data structure.
    363361 *
     
    385383       
    386384        /* AR9271 structure initialization. */
    387         ar9271_t *ar9271 = malloc(sizeof(ar9271_t));
     385        ar9271_t *ar9271 = calloc(1, sizeof(ar9271_t));
    388386        if (!ar9271) {
    389387                free(usb_device);
     
    393391        }
    394392       
    395         memset(ar9271, 0, sizeof(ar9271_t));
    396        
    397         ar9271->ddf_device = dev;
     393        ar9271->ddf_dev = dev;
    398394       
    399395        rc = ar9271_init(ar9271, usb_device);
     
    406402        }
    407403       
    408         /* NIC framework initialization. */
    409         nic_t *nic = nic_create_and_bind(dev);
    410         if (!nic) {
    411                 free(ar9271);
    412                 free(usb_device);
    413                 usb_log_error("Failed to create and bind NIC data.\n");
    414                 return NULL;
    415         }
    416        
    417         nic_set_specific(nic, ar9271);
    418         nic_set_send_frame_handler(nic, ar9271_send_frame);
    419         nic_set_state_change_handlers(nic, ar9271_on_activating,
    420             NULL, ar9271_on_stopping);
    421         nic_set_filtering_change_handlers(nic,
    422             ar9271_on_unicast_mode_change, ar9271_on_multicast_mode_change,
    423             ar9271_on_broadcast_mode_change, NULL, NULL);
    424         nic_set_poll_handlers(nic, ar9271_poll_mode_change, ar9271_poll);
    425        
    426404        return ar9271;
    427405}
     
    447425{
    448426        assert(dev);
    449         ddf_fun_t *fun;
    450427       
    451428        /* Allocate driver data for the device. */
     
    477454        }
    478455       
    479         nic_t *nic = nic_get_from_ddf_dev(dev);
    480        
    481         /* Create AR9271 function.*/
    482         fun = ddf_fun_create(nic_get_ddf_dev(nic), fun_exposed, "port0");
    483         if (fun == NULL) {
     456        /* Initialize AR9271 IEEE 802.11 framework. */
     457        rc = ieee80211_init(ar9271->ieee80211_dev, &ar9271_ieee80211_ops);
     458        if(rc != EOK) {
    484459                ar9271_delete_dev_data(ar9271);
    485                 usb_log_error("Failed creating device function.\n");
    486         }
    487        
    488         nic_set_ddf_fun(nic, fun);
    489         ddf_fun_set_ops(fun, &ar9271_nic_dev_ops);
    490        
    491         rc = ddf_fun_bind(fun);
    492         if (rc != EOK) {
    493                 ddf_fun_destroy(fun);
    494                 ar9271_delete_dev_data(ar9271);
    495                 usb_log_error("Failed binding device function.\n");
    496                 return rc;
    497         }
    498         rc = ddf_fun_add_to_category(fun, DEVICE_CATEGORY_NIC);
    499         if (rc != EOK) {
    500                 ddf_fun_unbind(fun);
    501                 ar9271_delete_dev_data(ar9271);
    502                 usb_log_error("Failed adding function to category.\n");
     460                usb_log_error("Failed to initialize IEEE80211 framework.\n");
    503461                return rc;
    504462        }
     
    516474                return 1;
    517475       
    518         nic_driver_implement(&ar9271_nic_driver_ops, &ar9271_nic_dev_ops,
    519             &ar9271_nic_iface);
    520 
    521476        usb_log_info("HelenOS AR9271 driver started.\n");
    522477
  • uspace/drv/bus/usb/ar9271/ar9271.h

    r462054a rab365c4  
    4040#include "htc.h"
    4141
     42/** Max supported channel frequency. */
     43#define AR9271_MAX_CHANNEL 2472
     44
     45/** Number of transmisson queues */
     46#define AR9271_QUEUES_COUNT 10
     47
    4248/** Number of GPIO pin used for handling led light */
    4349#define AR9271_LED_PIN 15
     
    4551/** AR9271 Registers */
    4652typedef enum {
     53        /* ATH command register */
     54        AR9271_COMMAND = 0x0008,
     55        AR9271_COMMAND_RX_ENABLE = 0x00000004,
     56       
     57        /* ATH config register */
     58        AR9271_CONFIG = 0x0014,
     59        AR9271_CONFIG_ADHOC = 0x00000020,
     60       
     61        AR9271_QUEUE_BASE_MASK = 0x1000,
     62       
    4763        /* EEPROM Addresses */
    4864        AR9271_EEPROM_BASE = 0x2100,
     
    6480        /* Wakeup related registers */
    6581        AR9271_RTC_RC = 0x7000,
     82        AR9271_RTC_RC_MAC_WARM = 0x00000001,
     83        AR9271_RTC_RC_MAC_COLD = 0x00000002,
    6684        AR9271_RTC_RC_MASK = 0x00000003,
    6785        AR9271_RTC_RESET = 0x7040,
    6886        AR9271_RTC_STATUS = 0x7044,
    6987        AR9271_RTC_STATUS_MASK = 0x0000000F,
     88        AR9271_RTC_STATUS_SHUTDOWN = 0x00000001,
    7089        AR9271_RTC_STATUS_ON = 0x00000002,
    7190        AR9271_RTC_FORCE_WAKE = 0x704C,
    7291        AR9271_RTC_FORCE_WAKE_ENABLE = 0x00000001,
    7392        AR9271_RTC_FORCE_WAKE_ON_INT = 0x00000002,
     93               
     94        AR9271_RX_FILTER = 0x803C,
     95        AR9271_RX_FILTER_UNI = 0x00000001,
     96        AR9271_RX_FILTER_MULTI = 0x00000002,
     97        AR9271_RX_FILTER_BROAD = 0x00000004,
     98        AR9271_RX_FILTER_CONTROL = 0x00000008,
     99        AR9271_RX_FILTER_BEACON = 0x00000010,
     100        AR9271_RX_FILTER_PROMISCUOUS = 0x00000020,
     101        AR9271_RX_FILTER_PROBEREQ = 0x00000080,
     102               
     103        AR9271_PHY_BASE = 0x9800,
     104        AR9271_PHY_ACTIVE = 0x981C,     
     105        AR9271_PHY_MODE = 0xA200,
     106        AR9271_PHY_MODE_2G = 0x02,
     107        AR9271_PHY_MODE_DYNAMIC = 0x04,
     108        AR9271_PHY_CCK_TX_CTRL = 0xA204,
     109        AR9271_PHY_CCK_TX_CTRL_JAPAN = 0x00000010,
     110               
     111        AR9271_OPMODE_STATION_AP_MASK = 0x00010000,
     112        AR9271_OPMODE_ADHOC_MASK = 0x00020000,
     113               
     114        AR9271_RESET_POWER_DOWN_CONTROL = 0x50044,
     115        AR9271_RADIO_RF_RESET = 0x20,
     116        AR9271_GATE_MAC_CONTROL = 0x4000,
    74117   
    75118        /* FW Addresses */
     
    78121       
    79122        /* MAC Registers */
    80         AR9271_MAC_PCU_STA_ADDR_L32 = 0x8000, /**< STA Address Lower 32 Bits */
    81         AR9271_MAC_PCU_STA_ADDR_U16 = 0x8004, /**< STA Address Upper 16 Bits */
    82         AR9271_MAC_PCU_BSSID_L32 = 0x8008, /**< BSSID Lower 32 Bits */
    83         AR9271_MAC_PCU_BSSID_U16 = 0x800C, /**< BSSID Upper 16 Bits */
     123        AR9271_STATION_ID0 = 0x8000, /**< STA Address Lower 32 Bits */
     124        AR9271_STATION_ID1 = 0x8004, /**< STA Address Upper 16 Bits */
     125        AR9271_STATION_BSSID0 = 0x8008, /**< BSSID Lower 32 Bits */
     126        AR9271_STATION_BSSID1 = 0x800C, /**< BSSID Upper 16 Bits */
    84127} ar9271_registers_t;
    85128
     
    92135/** AR9271 device data */
    93136typedef struct {
    94         /** DDF device pointer */
    95         ddf_dev_t *ddf_device;
     137        /** Backing DDF device */
     138        ddf_dev_t *ddf_dev;
    96139       
    97140        /** USB device data */
    98141        usb_device_t *usb_device;
     142       
     143        /** IEEE 802.11 device data */
     144        ieee80211_dev_t *ieee80211_dev;
     145       
     146        /** ATH device data */
     147        ath_t *ath_device;
    99148       
    100149        /** HTC device data */
  • uspace/drv/bus/usb/ar9271/htc.c

    r462054a rab365c4  
    3535#include <usb/debug.h>
    3636#include <byteorder.h>
     37#include <errno.h>
    3738
    3839#include "wmi.h"
  • uspace/drv/bus/usb/ar9271/htc.h

    r462054a rab365c4  
    3939#include <usb/dev/driver.h>
    4040#include <sys/types.h>
    41 #include <errno.h>
    4241
    4342#include "ath.h"
     
    171170
    172171extern int htc_device_init(ath_t *ath_device, htc_device_t *htc_device);
    173 extern int htc_init(htc_device_t* htc_device);
     172extern int htc_init(htc_device_t *htc_device);
    174173extern int htc_read_message(htc_device_t *htc_device, void *buffer,
    175174        size_t buffer_size, size_t *transferred_size);
     
    177176        size_t buffer_size, uint8_t endpoint_id);
    178177
    179 #endif  /* HTC_H */
     178#endif  /* ATHEROS_HTC_H */
    180179
  • uspace/drv/bus/usb/ar9271/hw.c

    r462054a rab365c4  
    3636#include <unistd.h>
    3737#include <nic.h>
     38#include <ieee80211.h>
    3839
    3940#include "hw.h"
     
    7677static int hw_reset_power_on(ar9271_t *ar9271)
    7778{
    78         int rc = wmi_reg_write(ar9271->htc_device, AR9271_RTC_FORCE_WAKE,
    79                 AR9271_RTC_FORCE_WAKE_ENABLE |  AR9271_RTC_FORCE_WAKE_ON_INT);
    80         if(rc != EOK) {
    81                 usb_log_error("Failed to bring up RTC register.\n");
    82                 return rc;
    83         }
    84        
    8579        wmi_reg_t buffer[] = {
    8680                {
     
    9993        };
    10094       
    101         rc = wmi_reg_buffer_write(ar9271->htc_device, buffer,
     95        int rc = wmi_reg_buffer_write(ar9271->htc_device, buffer,
    10296                sizeof(buffer) / sizeof(wmi_reg_t));
    10397        if(rc != EOK) {
     
    132126}
    133127
    134 static int hw_warm_reset(ar9271_t *ar9271)
    135 {
     128static int hw_set_reset(ar9271_t *ar9271, bool cold)
     129{
     130        uint32_t reset_value = AR9271_RTC_RC_MAC_WARM;
     131       
     132        if(cold) {
     133                reset_value |= AR9271_RTC_RC_MAC_COLD;
     134        }
     135       
    136136        wmi_reg_t buffer[] = {
    137137                {
     
    146146                {
    147147                        .offset = AR9271_RTC_RC,
    148                         .value = 1
     148                        .value = reset_value
    149149                }
    150150        };
     
    202202        }
    203203       
    204         nic_t *nic = nic_get_from_ddf_dev(ar9271->ddf_device);
     204        nic_t *nic = nic_get_from_ddf_dev(ar9271->ddf_dev);
    205205       
    206206        rc = nic_report_address(nic, &ar9271_address);
     
    269269
    270270/**
    271  * Hardware reset of AR9271 device.
     271 * Hardware init procedure of AR9271 device.
    272272 *
    273273 * @param ar9271 Device structure.
     
    275275 * @return EOK if succeed, negative error code otherwise.
    276276 */
    277 static int hw_reset(ar9271_t *ar9271)
     277static int hw_init_proc(ar9271_t *ar9271)
    278278{
    279279        int rc = hw_reset_power_on(ar9271);
     
    283283        }
    284284       
    285         rc = hw_warm_reset(ar9271);
     285        rc = hw_set_reset(ar9271, false);
    286286        if(rc != EOK) {
    287287                usb_log_error("Failed to HW warm reset.\n");
     
    310310        if(rc != EOK) {
    311311                usb_log_error("Failed to init bring up GPIO led.\n");
     312                return rc;
     313        }
     314       
     315        return EOK;
     316}
     317
     318static int hw_set_operating_mode(ar9271_t *ar9271,
     319        ieee80211_operating_mode_t opmode)
     320{
     321        uint32_t set_bit = 0x10000000;
     322       
     323        /* NOTICE: Fall-through switch statement! */
     324        switch(opmode) {
     325                case IEEE80211_OPMODE_ADHOC:
     326                        set_bit |= AR9271_OPMODE_ADHOC_MASK;
     327                case IEEE80211_OPMODE_MESH:
     328                case IEEE80211_OPMODE_AP:
     329                        set_bit |= AR9271_OPMODE_STATION_AP_MASK;
     330                case IEEE80211_OPMODE_STATION:
     331                        wmi_reg_clear_bit(ar9271->htc_device, AR9271_CONFIG,
     332                                AR9271_CONFIG_ADHOC);
     333        }
     334       
     335        wmi_reg_clear_set_bit(ar9271->htc_device, AR9271_STATION_ID1,
     336                set_bit,
     337                AR9271_OPMODE_STATION_AP_MASK | AR9271_OPMODE_ADHOC_MASK);
     338       
     339        return EOK;
     340}
     341
     342static uint32_t hw_reverse_bits(uint32_t value, uint32_t count)
     343{
     344        uint32_t ret_val = 0;
     345       
     346        for(size_t i = 0; i < count; i++) {
     347                ret_val = (ret_val << 1) | (value & 1);
     348                value >>= 1;
     349        }
     350       
     351        return ret_val;
     352}
     353
     354static int hw_set_channel(ar9271_t *ar9271, uint16_t freq)
     355{
     356        /* Not supported channel frequency. */
     357        if(freq < IEEE80211_FIRST_CHANNEL || freq > IEEE80211_MAX_CHANNEL) {
     358                return EINVAL;
     359        }
     360       
     361        /* Not supported channel frequency. */
     362        if((freq - IEEE80211_FIRST_CHANNEL) % IEEE80211_CHANNEL_GAP != 0) {
     363                return EINVAL;
     364        }
     365       
     366        uint32_t result;
     367        wmi_reg_read(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL, &result);
     368        wmi_reg_write(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL,
     369                result & ~AR9271_PHY_CCK_TX_CTRL_JAPAN);
     370       
     371        /* Some magic here. */
     372        uint32_t channel = hw_reverse_bits(
     373                (((((freq - 672) * 2 - 3040) / 10) << 2) & 0xFF), 8);
     374        uint32_t to_write = (channel << 8) | 33;
     375       
     376        wmi_reg_write(ar9271->htc_device, AR9271_PHY_BASE + (0x37 << 2),
     377                to_write);
     378       
     379        return EOK;
     380}
     381
     382int hw_reset(ar9271_t *ar9271)
     383{
     384        int rc = wmi_reg_write(ar9271->htc_device,
     385                AR9271_RESET_POWER_DOWN_CONTROL,
     386                AR9271_RADIO_RF_RESET);
     387        if(rc != EOK) {
     388                usb_log_error("Failed to reset radio rf.\n");
     389                return rc;
     390        }
     391       
     392        udelay(50);
     393       
     394        rc = wmi_reg_write(ar9271->htc_device,
     395                AR9271_RESET_POWER_DOWN_CONTROL,
     396                AR9271_GATE_MAC_CONTROL);
     397        if(rc != EOK) {
     398                usb_log_error("Failed to set the gate reset controls for MAC."
     399                        "\n");
     400                return rc;
     401        }
     402       
     403        udelay(50);
     404       
     405        /* Perform cold reset of device. */
     406        rc = hw_set_reset(ar9271, true);
     407        if(rc != EOK) {
     408                usb_log_error("Failed to HW cold reset.\n");
     409                return rc;
     410        }
     411       
     412        /* Set physical layer mode. */
     413        rc = wmi_reg_write(ar9271->htc_device, AR9271_PHY_MODE,
     414                AR9271_PHY_MODE_DYNAMIC | AR9271_PHY_MODE_2G);
     415        if(rc != EOK) {
     416                usb_log_error("Failed to set physical layer mode.\n");
     417                return rc;
     418        }
     419       
     420        /* Set device operating mode. */
     421        rc = hw_set_operating_mode(ar9271, IEEE80211_OPMODE_STATION);
     422        if(rc != EOK) {
     423                usb_log_error("Failed to set opmode to station.\n");
     424                return rc;
     425        }
     426       
     427        /* Set channel. */
     428        rc = hw_set_channel(ar9271, IEEE80211_FIRST_CHANNEL);
     429        if(rc != EOK) {
     430                usb_log_error("Failed to set channel.\n");
     431                return rc;
     432        }
     433       
     434        /* Initialize transmission queues. */
     435        for(int i = 0; i < AR9271_QUEUES_COUNT; i++) {
     436                rc = wmi_reg_write(ar9271->htc_device,
     437                        AR9271_QUEUE_BASE_MASK + (i << 2),
     438                        1 << i);
     439                if(rc != EOK) {
     440                        usb_log_error("Failed to initialize transmission queue."
     441                                "\n");
     442                        return rc;
     443                }
     444        }
     445       
     446        /* Activate physical layer. */
     447        rc = wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 1);
     448        if(rc != EOK) {
     449                usb_log_error("Failed to activate physical layer.\n");
    312450                return rc;
    313451        }
     
    325463int hw_init(ar9271_t *ar9271)
    326464{
    327         int rc = hw_reset(ar9271);
     465        int rc = hw_init_proc(ar9271);
    328466        if(rc != EOK) {
    329467                usb_log_error("Failed to HW reset device.\n");
  • uspace/drv/bus/usb/ar9271/hw.h

    r462054a rab365c4  
    4242
    4343extern int hw_init(ar9271_t *ar9271);
     44extern int hw_reset(ar9271_t *ar9271);
    4445
    4546#endif  /* ATHEROS_HW_H */
  • uspace/drv/bus/usb/ar9271/wmi.c

    r462054a rab365c4  
    250250        free(buffer);
    251251       
     252        bool clean_resp_buffer = false;
     253        if(response_buffer == NULL) {
     254                response_buffer = malloc(MAX_RESPONSE_LENGTH);
     255                clean_resp_buffer = true;
     256        }
     257       
    252258        /* Read response. */
    253259        rc = htc_read_message(htc_device, response_buffer, MAX_RESPONSE_LENGTH,
     
    260266        }
    261267       
    262         return rc;
    263 }
     268        if(clean_resp_buffer) {
     269                free(response_buffer);
     270        }
     271       
     272        return rc;
     273}
  • uspace/drv/bus/usb/ar9271/wmi.h

    r462054a rab365c4  
    102102        WMI_TX_STATS,
    103103        WMI_RX_STATS,
    104         WMI_BITRATE_MASK,
    105         WMI_REG_RMW,
     104        WMI_BITRATE_MASK
    106105} wmi_command_t;
    107106
  • uspace/lib/net/Makefile

    r462054a rab365c4  
    2929
    3030USPACE_PREFIX = ../..
    31 EXTRA_CFLAGS = -Iinclude
    3231LIBRARY = libnet
    3332
     33LIBS = \
     34        $(LIBDRV_PREFIX)/libdrv.a \
     35        $(LIBNIC_PREFIX)/libnic.a
     36
     37EXTRA_CFLAGS += \
     38        -Iinclude \
     39        -I$(LIBDRV_PREFIX)/include \
     40        -I$(LIBNIC_PREFIX)/include
     41
    3442SOURCES = \
    35         tl/socket_core.c
     43        tl/socket_core.c \
     44        ieee80211/ieee80211.c \
     45        ieee80211/ieee80211_impl.c
    3646
    3747include $(USPACE_PREFIX)/Makefile.common
Note: See TracChangeset for help on using the changeset viewer.