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


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

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

File:
1 edited

Legend:

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

    r59fa7ab r1dcc0b9  
    4343
    4444/**
    45  * Try to wait for register value repeatedly until timeout defined by device
    46  * is reached.
     45 * Try to wait for register value repeatedly until timeout is reached.
    4746 *
    4847 * @param ar9271 Device structure.
     
    264263}
    265264
     265static int hw_activate_phy(ar9271_t *ar9271)
     266{
     267        wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 1);
     268        udelay(1000);
     269       
     270        return EOK;
     271}
     272
    266273static int hw_set_operating_mode(ar9271_t *ar9271,
    267274        ieee80211_operating_mode_t op_mode)
     
    305312static int hw_noise_floor_calibration(ar9271_t *ar9271)
    306313{
     314        uint32_t value;
     315        wmi_reg_read(ar9271->htc_device, AR9271_PHY_CAL, &value);
     316        value &= 0xFFFFFE00;
     317        value |= (((uint32_t) AR9271_CALIB_NOMINAL_VALUE_2GHZ << 1) & 0x1FF);
     318        wmi_reg_write(ar9271->htc_device, AR9271_PHY_CAL, value);
     319       
     320        wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
     321                AR9271_AGC_CONTROL_NF_CALIB_EN);
     322       
     323        wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
     324                AR9271_AGC_CONTROL_NF_NOT_UPDATE);
     325       
     326        wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
     327                AR9271_AGC_CONTROL_NF_CALIB);
     328       
     329        int rc = hw_read_wait(ar9271, AR9271_AGC_CONTROL,
     330                AR9271_AGC_CONTROL_NF_CALIB, 0);
     331        if(rc != EOK) {
     332                usb_log_error("Failed to wait for NF calibration.\n");
     333                return rc;
     334        }
     335       
    307336        wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
    308337                AR9271_AGC_CONTROL_NF_CALIB_EN);
     
    348377}
    349378
     379int hw_wakeup(ar9271_t *ar9271)
     380{
     381        int rc;
     382       
     383        uint32_t rtc_status;
     384        wmi_reg_read(ar9271->htc_device, AR9271_RTC_STATUS, &rtc_status);
     385        if((rtc_status & AR9271_RTC_STATUS_MASK) == AR9271_RTC_STATUS_SHUTDOWN) {
     386                rc = hw_reset_power_on(ar9271);
     387                if(rc != EOK) {
     388                        usb_log_info("Failed to HW reset power on.\n");
     389                        return rc;
     390                }
     391
     392                rc = hw_set_reset(ar9271, false);
     393                if(rc != EOK) {
     394                        usb_log_info("Failed to HW warm reset.\n");
     395                        return rc;
     396                }
     397        }
     398       
     399        wmi_reg_set_bit(ar9271->htc_device, AR9271_RTC_FORCE_WAKE,
     400                AR9271_RTC_FORCE_WAKE_ENABLE);
     401       
     402        size_t i;
     403        for(i = 0; i < HW_WAIT_LOOPS; i++) {
     404                wmi_reg_read(ar9271->htc_device, AR9271_RTC_STATUS,
     405                        &rtc_status);
     406                if((rtc_status & AR9271_RTC_STATUS_MASK) ==
     407                        AR9271_RTC_STATUS_ON) {
     408                        break;
     409                }
     410                wmi_reg_set_bit(ar9271->htc_device, AR9271_RTC_FORCE_WAKE,
     411                        AR9271_RTC_FORCE_WAKE_ENABLE);
     412                udelay(50);
     413        }       
     414       
     415        if(i == HW_WAIT_LOOPS) {
     416                return EINVAL;
     417        } else {
     418                return EOK;
     419        }
     420}
     421
    350422int hw_freq_switch(ar9271_t *ar9271, uint16_t freq)
    351423{
     
    361433        if(rc != EOK) {
    362434                usb_log_error("Failed to HW set frequency.\n");
     435                return rc;
     436        }
     437       
     438        rc = hw_activate_phy(ar9271);
     439        if(rc != EOK) {
     440                usb_log_error("Failed to activate physical layer.\n");
    363441                return rc;
    364442        }
     
    376454}
    377455
    378 static int hw_set_rx_filter(ar9271_t *ar9271)
     456int hw_set_rx_filter(ar9271_t *ar9271, bool assoc)
    379457{
    380458        uint32_t filter_bits;
    381459       
    382         /* TODO: Do proper filtering here. */
     460        uint32_t additional_bits = 0;
     461       
     462        if(assoc) {
     463                additional_bits |= AR9271_RX_FILTER_MYBEACON;
     464        } else {
     465                additional_bits |= AR9271_RX_FILTER_BEACON;
     466        }
    383467       
    384468        filter_bits = AR9271_RX_FILTER_UNI | AR9271_RX_FILTER_MULTI |
    385                 AR9271_RX_FILTER_BROAD | AR9271_RX_FILTER_BEACON;
     469                AR9271_RX_FILTER_BROAD | additional_bits;
    386470       
    387471        wmi_reg_write(ar9271->htc_device, AR9271_RX_FILTER, filter_bits);
     472       
     473        return EOK;
     474}
     475
     476int hw_set_bssid(ar9271_t *ar9271)
     477{
     478        ieee80211_dev_t *ieee80211_dev = ar9271->ieee80211_dev;
     479       
     480        nic_address_t bssid;
     481        ieee80211_query_bssid(ieee80211_dev, &bssid);
     482       
     483        uint32_t *first_4bytes = (uint32_t *) &bssid.address;
     484        uint16_t *last_2bytes = (uint16_t *) &bssid.address[4];
     485       
     486        wmi_reg_write(ar9271->htc_device, AR9271_BSSID0,
     487                uint32_t_le2host(*first_4bytes));
     488       
     489        wmi_reg_write(ar9271->htc_device, AR9271_BSSID1,
     490                uint16_t_le2host(*last_2bytes) |
     491                ((ieee80211_get_aid(ieee80211_dev) & 0x3FFF) << 16));
    388492       
    389493        return EOK;
     
    395499                AR9271_COMMAND_RX_ENABLE);
    396500       
    397         int rc = hw_set_rx_filter(ar9271);
     501        int rc = hw_set_rx_filter(ar9271, false);
    398502        if(rc != EOK) {
    399503                usb_log_error("Failed to set RX filtering.\n");
     
    410514}
    411515
    412 static int hw_activate_phy(ar9271_t *ar9271)
    413 {
    414         wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 1);
    415         udelay(1000);
    416        
    417         return EOK;
    418 }
    419 
    420516static int hw_init_pll(ar9271_t *ar9271)
    421517{
     
    423519       
    424520        /* Some magic here (set for 2GHz channels). But VERY important :-) */
    425         pll = (0x5 << 10) & 0x00003C00;
    426         pll |= 0x2C & 0x000003FF;
     521        pll = (0x5 << 10) | 0x2C;
    427522       
    428523        wmi_reg_write(ar9271->htc_device, AR9271_RTC_PLL_CONTROL, pll);
    429524       
    430         return EOK;
    431 }
    432 
    433 static int hw_set_init_values(ar9271_t *ar9271)
     525        wmi_reg_write(ar9271->htc_device, AR9271_RTC_SLEEP_CLOCK,
     526                AR9271_RTC_SLEEP_CLOCK_FORCE_DERIVED);
     527        wmi_reg_set_bit(ar9271->htc_device, AR9271_RTC_FORCE_WAKE,
     528                AR9271_RTC_FORCE_WAKE_ENABLE);
     529       
     530        return EOK;
     531}
     532
     533static void hw_set_init_values(ar9271_t *ar9271)
    434534{
    435535        uint32_t reg_offset, reg_value;
     
    458558                wmi_reg_write(ar9271->htc_device, reg_offset, reg_value);
    459559        }
    460        
    461         return EOK;
    462560}
    463561
     
    533631        }
    534632       
    535         rc = hw_set_init_values(ar9271);
    536         if(rc != EOK) {
    537                 usb_log_error("Failed to set device init values.\n");
    538                 return rc;
    539         }
     633        hw_set_init_values(ar9271);
    540634       
    541635        /* Set physical layer mode. */
     
    586680        /* Byteswap TX and RX data buffer words. */
    587681        wmi_reg_write(ar9271->htc_device, AR9271_CONFIG, 0xA);
    588        
    589         usb_log_info("HW reset done.\n");
    590682       
    591683        return EOK;
Note: See TracChangeset for help on using the changeset viewer.