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

Changeset 01784d2 in mainline


Ignore:
Timestamp:
2015-01-28T18:19:30Z (5 years ago)
Author:
Jan Kolarik <kolarik@…>
Branches:
master
Children:
462054a
Parents:
ef521d4
Message:

Fixed errors in registry read and write, finished reseting device.

Location:
uspace/drv/bus/usb/ar9271
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ar9271/ar9271.h

    ref521d4 r01784d2  
    4747   
    4848        /* Wakeup related registers */
     49        AR9271_RTC_RC = 0x7000,
     50        AR9271_RTC_RC_MASK = 0x00000003,
    4951        AR9271_RTC_RESET = 0x7040,
    5052        AR9271_RTC_STATUS = 0x7044,
  • uspace/drv/bus/usb/ar9271/htc.c

    ref521d4 r01784d2  
    3939#include "htc.h"
    4040
    41 #define MAX_RESP_LEN 64
    42 
    4341/**
    4442 * HTC download pipes mapping.
     
    8280        htc_header->endpoint_id = endpoint_id;
    8381        htc_header->flags = 0;
    84         htc_header->payload_length = host2uint16_t_be(buffer_size);
     82        htc_header->payload_length =
     83                host2uint16_t_be(buffer_size - sizeof(htc_frame_header_t));
     84       
     85        htc_header->control_bytes[0] = 0x02;
     86        htc_header->control_bytes[1] = 0x88;
     87        htc_header->control_bytes[2] = 0xFF;
     88        htc_header->control_bytes[3] = 0xFF;
    8589       
    8690        ath_t *ath_device = htc_device->ath_device;
     
    150154        free(buffer);
    151155       
    152         buffer_size = MAX_RESP_LEN;
     156        buffer_size = MAX_RESPONSE_LENGTH;
    153157        buffer = malloc(buffer_size);
    154158       
     
    214218        free(buffer);
    215219       
    216         buffer_size = MAX_RESP_LEN;
     220        buffer_size = MAX_RESPONSE_LENGTH;
    217221        buffer = malloc(buffer_size);
    218222
     
    272276static int htc_check_ready(htc_device_t *htc_device)
    273277{
    274         size_t buffer_size = MAX_RESP_LEN;
     278        size_t buffer_size = MAX_RESPONSE_LENGTH;
    275279        void *buffer = malloc(buffer_size);
    276280
  • uspace/drv/bus/usb/ar9271/htc.h

    ref521d4 r01784d2  
    4242
    4343#include "ath.h"
     44
     45#define MAX_RESPONSE_LENGTH 64
    4446
    4547/**
  • uspace/drv/bus/usb/ar9271/hw.c

    ref521d4 r01784d2  
    6464                        continue;
    6565                }
    66 
     66               
    6767                if((result & mask) == value) {
    6868                        return EOK;
     
    7373}
    7474
    75 /**
    76  * Hardware reset of AR9271 device.
    77  *
    78  * @param ar9271 Device structure.
    79  *
    80  * @return EOK if succeed, negative error code otherwise.
    81  */
    82 int hw_reset(ar9271_t *ar9271)
    83 {
    84         reg_buffer_t buffer[] = {
     75static int hw_reset_power_on(ar9271_t *ar9271)
     76{
     77        int rc = wmi_reg_write(ar9271->htc_device, AR9271_RTC_FORCE_WAKE,
     78                AR9271_RTC_FORCE_WAKE_ENABLE |  AR9271_RTC_FORCE_WAKE_ON_INT);
     79        if(rc != EOK) {
     80                usb_log_error("Failed to bring up RTC register.\n");
     81                return rc;
     82        }
     83       
     84        wmi_reg_t buffer[] = {
    8585                {
    8686                        .offset = AR9271_RTC_FORCE_WAKE,
     
    9898        };
    9999       
    100         int rc = wmi_reg_buffer_write(ar9271->htc_device, buffer,
    101                 sizeof(buffer) / sizeof(reg_buffer_t));
     100        rc = wmi_reg_buffer_write(ar9271->htc_device, buffer,
     101                sizeof(buffer) / sizeof(wmi_reg_t));
    102102        if(rc != EOK) {
    103103                usb_log_error("Failed to set RT FORCE WAKE register.\n");
     
    128128        }
    129129       
    130         /* TODO: Finish HW init. */
     130        return EOK;
     131}
     132
     133static int hw_warm_reset(ar9271_t *ar9271)
     134{
     135        wmi_reg_t buffer[] = {
     136                {
     137                        .offset = AR9271_RTC_FORCE_WAKE,
     138                        .value = AR9271_RTC_FORCE_WAKE_ENABLE |
     139                                AR9271_RTC_FORCE_WAKE_ON_INT
     140                },
     141                {
     142                        .offset = AR9271_RC,
     143                        .value = AR9271_RC_AHB
     144                },
     145                {
     146                        .offset = AR9271_RTC_RC,
     147                        .value = 1
     148                }
     149        };
     150       
     151        int rc = wmi_reg_buffer_write(ar9271->htc_device, buffer,
     152                sizeof(buffer) / sizeof(wmi_reg_t));
     153        if(rc != EOK) {
     154                usb_log_error("Failed to set warm reset register.\n");
     155                return rc;
     156        }
     157       
     158        udelay(100);
     159       
     160        rc = wmi_reg_write(ar9271->htc_device, AR9271_RTC_RC, 0);
     161        if(rc != EOK) {
     162                usb_log_error("Failed to reset RTC RC register.\n");
     163                return rc;
     164        }
     165       
     166        rc = hw_read_wait(ar9271, AR9271_RTC_RC, AR9271_RTC_RC_MASK, 0);
     167        if(rc != EOK) {
     168                usb_log_error("Failed to read RTC RC register.\n");
     169                return rc;
     170        }
     171       
     172        rc = wmi_reg_write(ar9271->htc_device, AR9271_RC, 0);
     173        if(rc != EOK) {
     174                usb_log_error("Failed to reset MAC AHB register.\n");
     175                return rc;
     176        }
     177       
     178        return EOK;
     179}
     180
     181/**
     182 * Hardware reset of AR9271 device.
     183 *
     184 * @param ar9271 Device structure.
     185 *
     186 * @return EOK if succeed, negative error code otherwise.
     187 */
     188int hw_reset(ar9271_t *ar9271)
     189{
     190        int rc = hw_reset_power_on(ar9271);
     191        if(rc != EOK) {
     192                usb_log_error("Failed to HW reset power on.\n");
     193                return rc;
     194        }
     195       
     196        rc = hw_warm_reset(ar9271);
     197        if(rc != EOK) {
     198                usb_log_error("Failed to HW warm reset.\n");
     199                return rc;
     200        }
     201       
     202        /* TODO: Finish HW init (EEPROM init, MAC ADDR init). */
    131203       
    132204        return EOK;
  • uspace/drv/bus/usb/ar9271/hw.h

    ref521d4 r01784d2  
    3838#include "ar9271.h"
    3939
    40 #define HW_WAIT_LOOPS 10000
     40#define HW_WAIT_LOOPS 100
    4141#define HW_WAIT_TIME_US 10
    4242
  • uspace/drv/bus/usb/ar9271/wmi.c

    ref521d4 r01784d2  
    5252int wmi_reg_read(htc_device_t *htc_device, uint32_t reg_offset, uint32_t *res)
    5353{
    54         uint32_t resp_value;
    5554        uint32_t cmd_value = host2uint32_t_be(reg_offset);
    5655       
     56        size_t buffer_size = MAX_RESPONSE_LENGTH;
     57        void *resp_buffer = malloc(buffer_size);
     58       
    5759        int rc = wmi_send_command(htc_device, WMI_REG_READ,
    58                 (uint8_t *) &cmd_value, sizeof(cmd_value),
    59                 (uint8_t *) &resp_value, sizeof(resp_value));
     60                (uint8_t *) &cmd_value, sizeof(cmd_value), resp_buffer);
    6061       
    6162        if(rc != EOK) {
     
    6465        }
    6566       
    66         *res = uint32_t_be2host(resp_value);
     67        uint32_t *resp_value = (uint32_t *) ((void*) resp_buffer +
     68                sizeof(htc_frame_header_t) +
     69                sizeof(wmi_command_header_t));
     70       
     71        *res = uint32_t_be2host(*resp_value);
    6772       
    6873        return rc;
     
    8085int wmi_reg_write(htc_device_t *htc_device, uint32_t reg_offset, uint32_t val)
    8186{
    82         uint32_t resp_value = host2uint32_t_be(val);   
    8387        uint32_t cmd_buffer[] = {
    8488            host2uint32_t_be(reg_offset),
    85             resp_value
     89            host2uint32_t_be(val)
    8690        };
    8791       
     92        void *resp_buffer = malloc(MAX_RESPONSE_LENGTH);
     93       
    8894        int rc = wmi_send_command(htc_device, WMI_REG_WRITE,
    89                 (uint8_t *) &cmd_buffer, sizeof(cmd_buffer),
    90                 (uint8_t *) &resp_value, sizeof(resp_value));
     95                (uint8_t *) &cmd_buffer, sizeof(cmd_buffer), resp_buffer);
     96       
     97        free(resp_buffer);
    9198       
    9299        if(rc != EOK) {
     
    96103       
    97104        return rc;
     105}
     106
     107/**
     108 * WMI registry set or clear specified bits.
     109 *
     110 * @param htc_device HTC device structure.
     111 * @param reg_offset Registry offset (address) to be written.
     112 * @param set_bit Bit to be set.
     113 * @param clear_bit Bit to be cleared.
     114 *
     115 * @return EOK if succeed, negative error code otherwise.
     116 */
     117int wmi_reg_rmw(htc_device_t *htc_device, uint32_t reg_offset,
     118        uint32_t set_bit, uint32_t clear_bit)
     119{
     120        uint32_t value;
     121       
     122        int rc = wmi_reg_read(htc_device, reg_offset, &value);
     123        if(rc != EOK) {
     124                usb_log_error("Failed to read registry value in RMW "
     125                        "function.\n");
     126                return rc;
     127        }
     128       
     129        value |= set_bit;
     130        value &= ~clear_bit;
     131       
     132        rc = wmi_reg_write(htc_device, reg_offset, value);
     133        if(rc != EOK) {
     134                usb_log_error("Failed to write registry value in RMW "
     135                        "function.\n");
     136                return rc;
     137        }
     138       
     139        return rc;
     140}
     141
     142/**
     143 * WMI registry set specified bit.
     144 *
     145 * @param htc_device HTC device structure.
     146 * @param reg_offset Registry offset (address) to be written.
     147 * @param set_bit Bit to be set.
     148 *
     149 * @return EOK if succeed, negative error code otherwise.
     150 */
     151int wmi_reg_set_bit(htc_device_t *htc_device, uint32_t reg_offset,
     152        uint32_t set_bit)
     153{
     154        return wmi_reg_rmw(htc_device, reg_offset, set_bit, 0);
     155}
     156
     157/**
     158 * WMI registry clear specified bit.
     159 *
     160 * @param htc_device HTC device structure.
     161 * @param reg_offset Registry offset (address) to be written.
     162 * @param clear_bit Bit to be cleared.
     163 *
     164 * @return EOK if succeed, negative error code otherwise.
     165 */
     166int wmi_reg_clear_bit(htc_device_t *htc_device, uint32_t reg_offset,
     167        uint32_t clear_bit)
     168{
     169        return wmi_reg_rmw(htc_device, reg_offset, 0, clear_bit);
    98170}
    99171
     
    107179 * @return EOK if succeed, negative error code otherwise.
    108180 */
    109 int wmi_reg_buffer_write(htc_device_t *htc_device, reg_buffer_t *reg_buffer,
     181int wmi_reg_buffer_write(htc_device_t *htc_device, wmi_reg_t *reg_buffer,
    110182        size_t elements)
    111183{
    112         uint32_t resp_value;
     184        size_t buffer_size = sizeof(wmi_reg_t) * elements;
     185        void *buffer = malloc(buffer_size);
     186        void *resp_buffer = malloc(MAX_RESPONSE_LENGTH);
    113187       
    114188        /* Convert values to correct endianness. */
    115189        for(size_t i = 0; i < elements; i++) {
    116                 reg_buffer_t *buffer_element = &reg_buffer[i];
    117                 buffer_element->offset =
     190                wmi_reg_t *buffer_element = &reg_buffer[i];
     191                wmi_reg_t *buffer_it = (wmi_reg_t *)
     192                        ((void *) buffer + i*sizeof(wmi_reg_t));
     193                buffer_it->offset =
    118194                        host2uint32_t_be(buffer_element->offset);
    119                 buffer_element->value =
     195                buffer_it->value =
    120196                        host2uint32_t_be(buffer_element->value);
    121197        }
    122198       
    123199        int rc = wmi_send_command(htc_device, WMI_REG_WRITE,
    124                 (uint8_t *) &reg_buffer, sizeof(reg_buffer_t)*elements,
    125                 (uint8_t *) &resp_value, sizeof(resp_value));
     200                (uint8_t *) buffer, buffer_size, resp_buffer);
     201       
     202        free(buffer);
     203        free(resp_buffer);
    126204       
    127205        if(rc != EOK) {
     
    141219 * @param command_length Length of command data.
    142220 * @param response_buffer Buffer with response data.
    143  * @param response_length Length of response data.
    144221 *
    145222 * @return EOK if succeed, negative error code otherwise.
    146223 */
    147224int wmi_send_command(htc_device_t *htc_device, wmi_command_t command_id,
    148     uint8_t *command_buffer, uint32_t command_length,
    149     uint8_t *response_buffer, uint32_t response_length)
     225    uint8_t *command_buffer, uint32_t command_length, void *response_buffer)
    150226{
    151227        size_t header_size = sizeof(wmi_command_header_t) +
     
    174250        free(buffer);
    175251       
    176         buffer_size = header_size + response_length;
    177         buffer = malloc(buffer_size);
    178        
    179252        /* Read response. */
    180         rc = htc_read_message(htc_device, buffer, buffer_size, NULL);
     253        rc = htc_read_message(htc_device, response_buffer, MAX_RESPONSE_LENGTH,
     254                NULL);
    181255        if(rc != EOK) {
    182256                free(buffer);
     
    186260        }
    187261       
    188         memcpy(response_buffer,
    189                 buffer + sizeof(wmi_command_header_t),
    190                 response_length);
    191        
    192         free(buffer);
    193        
    194         return rc;
    195 }
     262        return rc;
     263}
  • uspace/drv/bus/usb/ar9271/wmi.h

    ref521d4 r01784d2  
    106106} wmi_command_t;
    107107
     108/**
     109 * Structure used when sending registry buffer
     110 */
    108111typedef struct {
    109112        uint32_t offset;                /**< Big Endian value! */
    110113        uint32_t value;                 /**< Big Endian value! */
    111 } reg_buffer_t;
     114} wmi_reg_t;
    112115
    113116extern int wmi_reg_read(htc_device_t *htc_device, uint32_t reg_offset,
     
    115118extern int wmi_reg_write(htc_device_t *htc_device, uint32_t reg_offset,
    116119        uint32_t val);
     120extern int wmi_reg_rmw(htc_device_t *htc_device, uint32_t reg_offset,
     121        uint32_t set_bit, uint32_t clear_bit);
     122extern int wmi_reg_set_bit(htc_device_t *htc_device, uint32_t reg_offset,
     123        uint32_t set_bit);
     124extern int wmi_reg_clear_bit(htc_device_t *htc_device, uint32_t reg_offset,
     125        uint32_t clear_bit);
    117126extern int wmi_reg_buffer_write(htc_device_t *htc_device,
    118         reg_buffer_t *reg_buffer, size_t elements);
     127        wmi_reg_t *reg_buffer, size_t elements);
    119128extern int wmi_send_command(htc_device_t *htc_device,
    120129        wmi_command_t command_id,
    121130        uint8_t *command_buffer, uint32_t command_length,
    122         uint8_t *response_buffer, uint32_t response_length);
     131        void *response_buffer);
    123132
    124133#endif  /* ATHEROS_WMI_H */
Note: See TracChangeset for help on using the changeset viewer.