Changeset 9e5a51c in mainline for uspace/drv/bus/usb/ar9271/hw.c


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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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");
Note: See TracChangeset for help on using the changeset viewer.