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

Changeset 56c0930 in mainline for uspace/drv/bus/usb/ar9271/hw.c


Ignore:
Timestamp:
2015-02-20T14:33:29Z (7 years ago)
Author:
Jan Kolarik <kolarik@…>
Branches:
lfn, master
Children:
4cb0148
Parents:
ab365c4
Message:

Started writing TX and RX handlers, VIF init, setting RX filter, PLL init and calibration, some corrections. Added HW values array initialization, registered diagnostic polling fibril. But still not receiving any packets…

File:
1 edited

Legend:

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

    rab365c4 r56c0930  
    245245        gpio_shift = 2 * gpio;
    246246       
    247         rc = wmi_reg_clear_set_bit(ar9271->htc_device, AR9271_GPIO_OE_OUT,
     247        rc = wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_GPIO_OE_OUT,
    248248                AR9271_GPIO_OE_OUT_ALWAYS << gpio_shift,
    249249                AR9271_GPIO_OE_OUT_ALWAYS << gpio_shift);
     
    258258static int hw_gpio_set_value(ar9271_t *ar9271, uint32_t gpio, uint32_t value)
    259259{
    260         int rc = wmi_reg_clear_set_bit(ar9271->htc_device, AR9271_GPIO_IN_OUT,
     260        int rc = wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_GPIO_IN_OUT,
    261261                (~value & 1) << gpio, 1 << gpio);
    262262        if(rc != EOK) {
     
    317317
    318318static int hw_set_operating_mode(ar9271_t *ar9271,
    319         ieee80211_operating_mode_t opmode)
     319        ieee80211_operating_mode_t op_mode)
    320320{
    321321        uint32_t set_bit = 0x10000000;
    322322       
    323323        /* NOTICE: Fall-through switch statement! */
    324         switch(opmode) {
     324        switch(op_mode) {
    325325                case IEEE80211_OPMODE_ADHOC:
    326326                        set_bit |= AR9271_OPMODE_ADHOC_MASK;
     
    333333        }
    334334       
    335         wmi_reg_clear_set_bit(ar9271->htc_device, AR9271_STATION_ID1,
     335        wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_STATION_ID1,
    336336                set_bit,
    337337                AR9271_OPMODE_STATION_AP_MASK | AR9271_OPMODE_ADHOC_MASK);
     338       
     339        ar9271->ieee80211_dev->current_op_mode = op_mode;
    338340       
    339341        return EOK;
     
    352354}
    353355
    354 static int hw_set_channel(ar9271_t *ar9271, uint16_t freq)
     356static int hw_set_freq(ar9271_t *ar9271, uint16_t freq)
    355357{
    356358        /* Not supported channel frequency. */
    357         if(freq < IEEE80211_FIRST_CHANNEL || freq > IEEE80211_MAX_CHANNEL) {
     359        if(freq < IEEE80211_FIRST_FREQ || freq > IEEE80211_MAX_FREQ) {
    358360                return EINVAL;
    359361        }
    360362       
    361363        /* Not supported channel frequency. */
    362         if((freq - IEEE80211_FIRST_CHANNEL) % IEEE80211_CHANNEL_GAP != 0) {
     364        if((freq - IEEE80211_FIRST_FREQ) % IEEE80211_CHANNEL_GAP != 0) {
    363365                return EINVAL;
    364366        }
    365367       
    366         uint32_t result;
    367         wmi_reg_read(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL, &result);
     368        uint32_t tx_control;
     369        wmi_reg_read(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL, &tx_control);
    368370        wmi_reg_write(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL,
    369                 result & ~AR9271_PHY_CCK_TX_CTRL_JAPAN);
     371                tx_control & ~AR9271_PHY_CCK_TX_CTRL_JAPAN);
    370372       
    371373        /* Some magic here. */
     
    377379                to_write);
    378380       
     381        ar9271->ieee80211_dev->current_freq = freq;
     382       
     383        return EOK;
     384}
     385
     386static int hw_set_rx_filter(ar9271_t *ar9271)
     387{
     388        uint32_t filter_bits;
     389        int rc = wmi_reg_read(ar9271->htc_device, AR9271_RX_FILTER,
     390                &filter_bits);
     391        if(rc != EOK) {
     392                usb_log_error("Failed to read RX filter.\n");
     393                return EINVAL;
     394        }
     395       
     396        /* TODO: Do proper filtering here. */
     397       
     398        filter_bits |= AR9271_RX_FILTER_UNI | AR9271_RX_FILTER_MULTI |
     399                AR9271_RX_FILTER_BROAD | AR9271_RX_FILTER_BEACON |
     400                AR9271_RX_FILTER_MYBEACON | AR9271_RX_FILTER_PROMISCUOUS;
     401       
     402        rc = wmi_reg_write(ar9271->htc_device, AR9271_RX_FILTER, filter_bits);
     403        if(rc != EOK) {
     404                usb_log_error("Failed to write RX filter.\n");
     405                return EINVAL;
     406        }
     407       
     408        return EOK;
     409}
     410
     411int hw_rx_init(ar9271_t *ar9271)
     412{
     413        int rc = wmi_reg_write(ar9271->htc_device, AR9271_COMMAND,
     414                AR9271_COMMAND_RX_ENABLE);
     415        if(rc != EOK) {
     416                usb_log_error("Failed to send RX enable command.\n");
     417                return EINVAL;
     418        }
     419       
     420        rc = hw_set_rx_filter(ar9271);
     421        if(rc != EOK) {
     422                usb_log_error("Failed to set RX filtering.\n");
     423                return EINVAL;
     424        }
     425       
     426        return EOK;
     427}
     428
     429static int hw_activate_phy(ar9271_t *ar9271)
     430{
     431        int rc = wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 1);
     432        if(rc != EOK) {
     433                usb_log_error("Failed to activate set PHY active.\n");
     434                return rc;
     435        }
     436       
     437        udelay(1000);
     438       
     439        return EOK;
     440}
     441
     442static int hw_init_pll(ar9271_t *ar9271)
     443{
     444        uint32_t pll;
     445       
     446        /* Some magic here. */
     447        pll = (0x5 << 10) & 0x00003C00;
     448        pll |= (0x2 << 14) & 0x0000C000; /**< 0x2 ~ quarter rate (0x1 half) */
     449        pll |= 0x58 & 0x000003FF;
     450       
     451        return wmi_reg_write(ar9271->htc_device, AR9271_RTC_PLL_CONTROL, pll);
     452}
     453
     454static int hw_calibrate(ar9271_t *ar9271)
     455{
     456        wmi_reg_set_bit(ar9271->htc_device, AR9271_CARRIER_LEAK_CONTROL,
     457                AR9271_CARRIER_LEAK_CALIB);
     458        wmi_reg_clear_bit(ar9271->htc_device, AR9271_ADC_CONTROL,
     459                AR9271_ADC_CONTROL_OFF_PWDADC);
     460        wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
     461                AR9271_AGC_CONTROL_TX_CALIB);
     462        wmi_reg_set_bit(ar9271->htc_device, AR9271_PHY_TPCRG1,
     463                AR9271_PHY_TPCRG1_PD_CALIB);
     464        wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
     465                AR9271_AGC_CONTROL_CALIB);
     466       
     467        int rc = hw_read_wait(ar9271, AR9271_AGC_CONTROL,
     468                AR9271_AGC_CONTROL_CALIB, 0);
     469        if(rc != EOK) {
     470                usb_log_error("Failed to wait on calibrate completion.\n");
     471                return rc;
     472        }
     473       
     474        wmi_reg_set_bit(ar9271->htc_device, AR9271_ADC_CONTROL,
     475                AR9271_ADC_CONTROL_OFF_PWDADC);
     476        wmi_reg_clear_bit(ar9271->htc_device, AR9271_CARRIER_LEAK_CONTROL,
     477                AR9271_CARRIER_LEAK_CALIB);
     478        wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
     479                AR9271_AGC_CONTROL_TX_CALIB);
     480       
     481        return EOK;
     482}
     483
     484static int hw_set_init_values(ar9271_t *ar9271)
     485{
     486        int size = sizeof(ar9271_init_array) / sizeof(ar9271_init_array[0]);
     487       
     488        for(int i = 0; i < size; i++) {
     489                uint32_t reg_offset = ar9271_init_array[i][0];
     490                uint32_t reg_value = ar9271_init_array[i][1];
     491                wmi_reg_write(ar9271->htc_device, reg_offset, reg_value);
     492        }
     493       
    379494        return EOK;
    380495}
     
    382497int hw_reset(ar9271_t *ar9271)
    383498{
    384         int rc = wmi_reg_write(ar9271->htc_device,
     499        /* Set physical layer as deactivated. */
     500        int rc = wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 0);
     501        if(rc != EOK) {
     502                usb_log_error("Failed to set PHY deactivated.\n");
     503                return rc;
     504        }
     505       
     506        rc = wmi_reg_write(ar9271->htc_device,
    385507                AR9271_RESET_POWER_DOWN_CONTROL,
    386508                AR9271_RADIO_RF_RESET);
     
    391513       
    392514        udelay(50);
     515       
     516        /* TODO: There should be cold reset only if RX or TX is enabled. */
     517       
     518        rc = hw_init_pll(ar9271);
     519        if(rc != EOK) {
     520                usb_log_error("Failed to init PLL.\n");
     521                return rc;
     522        }
     523       
     524        udelay(500);
     525       
     526        rc = wmi_reg_write(ar9271->htc_device,
     527                AR9271_CLOCK_CONTROL,
     528                AR9271_MAX_CPU_CLOCK);
     529        if(rc != EOK) {
     530                usb_log_error("Failed to set CPU clock.\n");
     531                return rc;
     532        }
     533       
     534        udelay(100);
    393535       
    394536        rc = wmi_reg_write(ar9271->htc_device,
     
    403545        udelay(50);
    404546       
    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         }
     547        rc = hw_set_init_values(ar9271);
     548        if(rc != EOK) {
     549                usb_log_error("Failed to set device init values.\n");
     550                return rc;
     551        }
     552       
     553        /* TODO: There should probably be TX power settings. */
    411554       
    412555        /* Set physical layer mode. */
     
    418561        }
    419562       
     563        /* TODO: Init EEPROM here. */
     564       
    420565        /* Set device operating mode. */
    421566        rc = hw_set_operating_mode(ar9271, IEEE80211_OPMODE_STATION);
     
    425570        }
    426571       
    427         /* Set channel. */
    428         rc = hw_set_channel(ar9271, IEEE80211_FIRST_CHANNEL);
     572        /* Set channel frequency. */
     573        rc = hw_set_freq(ar9271, IEEE80211_FIRST_FREQ);
    429574        if(rc != EOK) {
    430575                usb_log_error("Failed to set channel.\n");
     
    444589        }
    445590       
     591        /* TODO: Maybe resetting TX queues will be necessary afterwards here. */
     592       
     593        /* TODO: Setting RX, TX timeouts and others may be necessary here. */
     594       
    446595        /* Activate physical layer. */
    447         rc = wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 1);
     596        rc = hw_activate_phy(ar9271);
    448597        if(rc != EOK) {
    449598                usb_log_error("Failed to activate physical layer.\n");
    450599                return rc;
    451600        }
     601       
     602        /* Calibration. */
     603        rc = hw_calibrate(ar9271);
     604        if(rc != EOK) {
     605                usb_log_error("Failed to calibrate device.\n");
     606                return rc;
     607        }
     608       
     609        usb_log_info("HW reset done.\n");
    452610       
    453611        return EOK;
Note: See TracChangeset for help on using the changeset viewer.