Changeset 8a64320e in mainline
- Timestamp:
- 2015-04-23T23:40:14Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- dcba819
- Parents:
- 09044cb
- Files:
-
- 35 edited
Legend:
- Unmodified
- Added
- Removed
-
boot/Makefile
r09044cb r8a64320e 115 115 cp "$(USPACE_PATH)/$(DRVS_PATH)/$$file_dir/$$file_name/$$file_name.dev" "$(DIST_PATH)/$(DRVS_PATH)/$$file_name/" ; \ 116 116 done 117 for file in $(RD_DRV _FW) ; do \117 for file in $(RD_DRVS_FW) ; do \ 118 118 file_dir="`dirname "$$file"`" ; \ 119 119 file_name="`basename "$$file"`" ; \ -
boot/Makefile.common
r09044cb r8a64320e 139 139 nic/rtl8139 \ 140 140 nic/rtl8169 \ 141 141 nic/ar9271 \ 142 142 block/ahci 143 143 144 144 RD_DRV_CFG = 145 145 146 RD_DRV _FW= \147 146 RD_DRVS_FW_NON_ESSENTIAL = \ 147 nic/ar9271 148 148 149 149 RD_LIBS = … … 228 228 $(USPACE_PATH)/app/df/df \ 229 229 $(USPACE_PATH)/app/fontviewer/fontviewer \ 230 230 $(USPACE_PATH)/app/wifi_supplicant/wifi_supplicant 231 231 232 232 RD_TESTS = \ … … 252 252 RD_APPS = $(RD_APPS_ESSENTIAL) 253 253 RD_DRVS = $(RD_DRVS_ESSENTIAL) 254 RD_DRVS_FW = $(RD_DRVS_FW_ESSENTIAL) 254 255 else 255 256 RD_SRVS = $(RD_SRVS_ESSENTIAL) $(RD_SRVS_NON_ESSENTIAL) 256 257 RD_APPS = $(RD_APPS_ESSENTIAL) $(RD_APPS_NON_ESSENTIAL) 257 258 RD_DRVS = $(RD_DRVS_ESSENTIAL) $(RD_DRVS_NON_ESSENTIAL) 259 RD_DRVS_FW = $(RD_DRVS_FW_ESSENTIAL) $(RD_DRVS_FW_NON_ESSENTIAL) 258 260 endif 259 261 -
boot/arch/amd64/Makefile.inc
r09044cb r8a64320e 61 61 RD_DRV_CFG += \ 62 62 bus/isa 63 63 64 64 RD_APPS_ESSENTIAL += \ 65 65 $(USPACE_PATH)/app/edit/edit \ -
uspace/Makefile
r09044cb r8a64320e 252 252 lib/mbr \ 253 253 lib/gpt \ 254 lib/ieee80211 \254 lib/ieee80211 255 255 256 256 LIBC_BUILD = $(addsuffix .build,$(LIBC)) -
uspace/app/wifi_supplicant/Makefile
r09044cb r8a64320e 35 35 wifi_supplicant.c 36 36 37 include $(USPACE_PREFIX)/Makefile.common 37 include $(USPACE_PREFIX)/Makefile.common -
uspace/app/wifi_supplicant/wifi_supplicant.c
r09044cb r8a64320e 42 42 #include <loc.h> 43 43 44 #define NAME "wifi_supplicant" 45 46 #define enum_name(name_arr, i) ((i < 0) ? "NA" : name_arr[i]) 44 #define NAME "wifi_supplicant" 45 46 #define enum_name(name_arr, i) \ 47 ((i < 0) ? "NA" : name_arr[i]) 47 48 48 49 static const char* ieee80211_security_type_strs[] = { … … 65 66 printf("\tlist - list wifi devices in <index>: <name> format\n"); 66 67 printf("\tscan <index> [-n] - output scan results (force scan " 67 68 "immediately)\n"); 68 69 printf("\tconnect <index> <ssid_prefix> [<password>] - connect to " 69 70 "network\n"); 70 71 printf("\tdisconnect <index> - disconnect from network\n"); 71 72 } 72 73 73 static char *nic_addr_format(nic_address_t *a) 74 { 75 int rc; 76 char *s; 77 78 rc = asprintf(&s, "%02x:%02x:%02x:%02x:%02x:%02x", 79 a->address[0], a->address[1], a->address[2], 80 a->address[3], a->address[4], a->address[5]); 81 74 static char *nic_addr_format(nic_address_t *addr) 75 { 76 char *str; 77 int rc = asprintf(&str, "%02x:%02x:%02x:%02x:%02x:%02x", 78 addr->address[0], addr->address[1], addr->address[2], 79 addr->address[3], addr->address[4], addr->address[5]); 80 82 81 if (rc < 0) 83 82 return NULL; 84 85 return s ;83 84 return str; 86 85 } 87 86 … … 89 88 { 90 89 category_id_t wifi_cat; 91 92 90 int rc = loc_category_get_id("ieee80211", &wifi_cat, 0); 93 91 if (rc != EOK) { … … 95 93 return rc; 96 94 } 97 95 98 96 rc = loc_category_get_svcs(wifi_cat, wifis, count); 99 97 if (rc != EOK) { … … 107 105 static async_sess_t *get_wifi_by_index(size_t i) 108 106 { 109 int rc;107 service_id_t *wifis = NULL; 110 108 size_t count; 111 service_id_t *wifis = NULL; 112 113 rc = get_wifi_list(&wifis, &count); 109 110 int rc = get_wifi_list(&wifis, &count); 114 111 if (rc != EOK) { 115 112 printf("Error fetching wifi list.\n"); … … 117 114 } 118 115 119 if (i >= count) {116 if (i >= count) { 120 117 printf("Invalid wifi index.\n"); 121 118 free(wifis); 122 119 return NULL; 123 120 } 124 125 async_sess_t *sess = 126 121 122 async_sess_t *sess = 123 loc_service_connect(EXCHANGE_SERIALIZE, wifis[i], 0); 127 124 if (sess == NULL) { 128 125 printf("Error connecting to service.\n"); … … 130 127 return NULL; 131 128 } 132 129 133 130 return sess; 134 131 } … … 138 135 service_id_t *wifis = NULL; 139 136 size_t count; 140 char *svc_name; 141 int rc; 142 143 rc = get_wifi_list(&wifis, &count); 137 138 int rc = get_wifi_list(&wifis, &count); 144 139 if (rc != EOK) { 145 140 printf("Error fetching wifi list.\n"); 146 141 return EINVAL; 147 142 } 148 143 149 144 printf("[Index]: [Service Name]\n"); 150 145 for (size_t i = 0; i < count; i++) { 146 char *svc_name; 151 147 rc = loc_service_get_name(wifis[i], &svc_name); 152 148 if (rc != EOK) { … … 157 153 158 154 printf("%zu: %s\n", i, svc_name); 159 155 160 156 free(svc_name); 161 157 } 162 158 163 159 return EOK; 164 160 } … … 171 167 if (sess == NULL) { 172 168 printf("Specified WIFI doesn't exist or cannot connect to " 173 169 "it.\n"); 174 170 return EINVAL; 175 171 } … … 177 173 int rc = ieee80211_disconnect(sess); 178 174 if(rc != EOK) { 179 if (rc == EREFUSED) {180 printf("Device is not ready yet.\n"); 181 } else {175 if (rc == EREFUSED) 176 printf("Device is not ready yet.\n"); 177 else 182 178 printf("Error when disconnecting device. " 183 "Error: %d\n", rc); 184 } 179 "Error: %d\n", rc); 185 180 186 181 return rc; … … 189 184 rc = ieee80211_connect(sess, ssid_start, password); 190 185 if(rc != EOK) { 191 if (rc == EREFUSED) {192 printf("Device is not ready yet.\n"); 193 } else if(rc == ETIMEOUT) {186 if (rc == EREFUSED) 187 printf("Device is not ready yet.\n"); 188 else if (rc == ETIMEOUT) 194 189 printf("Timeout when authenticating to network.\n"); 195 } else if(rc == ENOENT) {190 else if (rc == ENOENT) 196 191 printf("Given SSID not in scan results.\n"); 197 } else {192 else 198 193 printf("Error when connecting to network. " 199 "Error: %d\n", rc); 200 } 201 202 return rc; 203 } 204 205 // TODO: Wait for DHCP address ? 194 "Error: %d\n", rc); 195 196 return rc; 197 } 198 199 // TODO: Wait for DHCP address? 206 200 207 201 printf("Successfully connected to network!\n"); … … 215 209 if (sess == NULL) { 216 210 printf("Specified WIFI doesn't exist or cannot connect to " 217 211 "it.\n"); 218 212 return EINVAL; 219 213 } 220 214 221 215 int rc = ieee80211_disconnect(sess); 222 if (rc != EOK) {223 if (rc == EREFUSED) {216 if (rc != EOK) { 217 if (rc == EREFUSED) 224 218 printf("Device is not ready yet.\n"); 225 } else if(rc == EINVAL) {219 else if (rc == EINVAL) 226 220 printf("Not connected to any WiFi network.\n"); 227 } else {221 else 228 222 printf("Error when disconnecting from network. " 229 230 }223 "Error: %d\n", rc); 224 231 225 return rc; 232 226 } … … 239 233 static int wifi_scan(uint32_t index, bool now) 240 234 { 241 ieee80211_scan_results_t scan_results;242 243 235 async_sess_t *sess = get_wifi_by_index(index); 244 236 if (sess == NULL) { 245 237 printf("Specified WIFI doesn't exist or cannot connect to " 246 238 "it.\n"); 247 239 return EINVAL; 248 240 } 249 241 242 ieee80211_scan_results_t scan_results; 250 243 int rc = ieee80211_get_scan_results(sess, &scan_results, now); 251 if (rc != EOK) {252 if (rc == EREFUSED) {244 if (rc != EOK) { 245 if (rc == EREFUSED) 253 246 printf("Device is not ready yet.\n"); 254 } else {247 else 255 248 printf("Failed to fetch scan results. Error: %d\n", rc); 256 } 257 258 return rc; 259 } 260 261 if(scan_results.length == 0) 249 250 return rc; 251 } 252 253 if (scan_results.length == 0) 262 254 return EOK; 263 255 264 printf("%16.16s %17s %4s %5s %5s %7s %7s\n", 265 266 267 for (int i = 0; i < scan_results.length; i++) {256 printf("%16.16s %17s %4s %5s %5s %7s %7s\n", 257 "SSID", "MAC", "CHAN", "TYPE", "AUTH", "UNI-ALG", "GRP-ALG"); 258 259 for (uint8_t i = 0; i < scan_results.length; i++) { 268 260 ieee80211_scan_result_t result = scan_results.results[i]; 269 261 270 printf("%16.16s %17s %4d %5s %5s %7s %7s\n", 271 result.ssid, 272 nic_addr_format(&result.bssid), 273 result.channel, 274 enum_name(ieee80211_security_type_strs, 275 result.security.type), 276 enum_name(ieee80211_security_auth_strs, 277 result.security.auth), 278 enum_name(ieee80211_security_alg_strs, 279 result.security.pair_alg), 280 enum_name(ieee80211_security_alg_strs, 281 result.security.group_alg) 282 ); 262 printf("%16.16s %17s %4d %5s %5s %7s %7s\n", 263 result.ssid, nic_addr_format(&result.bssid), 264 result.channel, 265 enum_name(ieee80211_security_type_strs, result.security.type), 266 enum_name(ieee80211_security_auth_strs, result.security.auth), 267 enum_name(ieee80211_security_alg_strs, result.security.pair_alg), 268 enum_name(ieee80211_security_alg_strs, result.security.group_alg)); 283 269 } 284 270 … … 288 274 int main(int argc, char *argv[]) 289 275 { 290 int rc; 291 uint32_t index; 292 293 rc = inetcfg_init(); 294 if (rc != EOK) { 295 printf(NAME ": Failed connecting to inetcfg service (%d).\n", 296 rc); 276 int rc = inetcfg_init(); 277 if (rc != EOK) { 278 printf("%s: Failed connecting to inetcfg service (%d).\n", 279 NAME, rc); 297 280 return 1; 298 281 } … … 300 283 rc = dhcp_init(); 301 284 if (rc != EOK) { 302 printf(NAME ": Failed connecting to dhcp service (%d).\n", rc); 285 printf("%s: Failed connecting to dhcp service (%d).\n", 286 NAME, rc); 303 287 return 1; 304 288 } 305 289 306 if (argc == 2) {307 if (!str_cmp(argv[1], "list")) {290 if (argc == 2) { 291 if (!str_cmp(argv[1], "list")) 308 292 return wifi_list(); 309 }310 } else if(argc > 2) {293 } else if (argc > 2) { 294 uint32_t index; 311 295 rc = str_uint32_t(argv[2], NULL, 10, false, &index); 312 if (rc != EOK) {313 printf( NAME ": Invalid argument.\n");296 if (rc != EOK) { 297 printf("%s: Invalid argument.\n", NAME); 314 298 print_syntax(); 315 299 return EINVAL; 316 300 } 317 if(!str_cmp(argv[1], "scan")) { 301 302 if (!str_cmp(argv[1], "scan")) { 318 303 bool now = false; 319 if (argc > 3)320 if (!str_cmp(argv[3], "-n"))304 if (argc > 3) 305 if (!str_cmp(argv[3], "-n")) 321 306 now = true; 307 322 308 return wifi_scan(index, now); 323 } else if (!str_cmp(argv[1], "connect")) {309 } else if (!str_cmp(argv[1], "connect")) { 324 310 char *pass = NULL; 325 if (argc > 3) {326 if (argc > 4)311 if (argc > 3) { 312 if (argc > 4) 327 313 pass = argv[4]; 314 328 315 return wifi_connect(index, argv[3], pass); 329 } 330 } else if (!str_cmp(argv[1], "disconnect")) {316 } 317 } else if (!str_cmp(argv[1], "disconnect")) 331 318 return wifi_disconnect(index); 332 }333 319 } 334 320 -
uspace/drv/nic/ar9271/Makefile
r09044cb r8a64320e 36 36 $(LIBIEEE80211_PREFIX)/libieee80211.a \ 37 37 $(LIBCRYPTO_PREFIX)/libcrypto.a 38 38 39 39 EXTRA_CFLAGS += \ 40 40 -I. \ … … 45 45 -I$(LIBIEEE80211_PREFIX)/include \ 46 46 -I$(LIBCRYPTO_PREFIX) 47 47 48 48 BINARY = ar9271 49 49 -
uspace/drv/nic/ar9271/ar9271.c
r09044cb r8a64320e 42 42 #include <nic.h> 43 43 #include <macros.h> 44 45 44 #include "ath_usb.h" 46 45 #include "wmi.h" … … 48 47 #include "ar9271.h" 49 48 50 #define NAME "ar9271"51 #define FIRMWARE_FILENAME "/drv/ar9271/ar9271.fw"49 #define NAME "ar9271" 50 #define FIRMWARE_FILENAME "/drv/ar9271/ar9271.fw" 52 51 53 52 const usb_endpoint_description_t usb_ar9271_out_bulk_endpoint_description = { … … 91 90 &usb_ar9271_out_bulk_endpoint_description, 92 91 &usb_ar9271_in_bulk_endpoint_description, 93 94 92 &usb_ar9271_in_int_endpoint_description, 93 &usb_ar9271_out_int_endpoint_description, 95 94 NULL 96 95 }; … … 100 99 101 100 /* IEEE 802.11 callbacks */ 102 static int ar9271_ieee80211_start(ieee80211_dev_t *ieee80211_dev); 103 static int ar9271_ieee80211_tx_handler(ieee80211_dev_t *ieee80211_dev, 104 void *buffer, size_t buffer_size); 105 static int ar9271_ieee80211_set_freq(ieee80211_dev_t *ieee80211_dev, 106 uint16_t freq); 107 static int ar9271_ieee80211_bssid_change(ieee80211_dev_t *ieee80211_dev, 108 bool connected); 109 static int ar9271_ieee80211_key_config(ieee80211_dev_t *ieee80211_dev, 110 ieee80211_key_config_t *key_conf, bool insert); 101 static int ar9271_ieee80211_start(ieee80211_dev_t *); 102 static int ar9271_ieee80211_tx_handler(ieee80211_dev_t *, void *, size_t); 103 static int ar9271_ieee80211_set_freq(ieee80211_dev_t *, uint16_t); 104 static int ar9271_ieee80211_bssid_change(ieee80211_dev_t *, bool); 105 static int ar9271_ieee80211_key_config(ieee80211_dev_t *, ieee80211_key_config_t *, 106 bool); 111 107 112 108 static driver_ops_t ar9271_driver_ops = { … … 129 125 static ieee80211_iface_t ar9271_ieee80211_iface; 130 126 131 static int ar9271_get_device_info(ddf_fun_t * dev, nic_device_info_t *info);127 static int ar9271_get_device_info(ddf_fun_t *, nic_device_info_t *); 132 128 static int ar9271_get_cable_state(ddf_fun_t *, nic_cable_state_t *); 133 static int ar9271_get_operation_mode(ddf_fun_t *, int *, 134 nic_channel_mode_t *,nic_role_t *);129 static int ar9271_get_operation_mode(ddf_fun_t *, int *, nic_channel_mode_t *, 130 nic_role_t *); 135 131 136 132 static nic_iface_t ar9271_ieee80211_nic_iface = { … … 142 138 static ddf_dev_ops_t ar9271_ieee80211_dev_ops; 143 139 144 /** 145 * Get device information. 140 /** Get device information. 146 141 * 147 142 */ … … 153 148 memset(info, 0, sizeof(nic_device_info_t)); 154 149 155 info->vendor_id = 0x0 CF3;150 info->vendor_id = 0x0cf3; 156 151 info->device_id = 0x9271; 157 152 str_cpy(info->vendor_name, NIC_VENDOR_MAX_LENGTH, … … 163 158 } 164 159 165 /** 166 * Get cable state. 160 /** Get cable state. 167 161 * 168 162 */ … … 174 168 } 175 169 176 /** 177 * Get operation mode of the device. 170 /** Get operation mode of the device. 178 171 * 179 172 */ … … 188 181 } 189 182 190 /** 191 * Set multicast frames acceptance mode. 192 * 193 */ 194 static int ar9271_on_multicast_mode_change(nic_t *nic, 195 nic_multicast_mode_t mode, const nic_address_t *addr, size_t addr_cnt) 196 { 197 /* 198 ieee80211_dev_t *ieee80211_dev = (ieee80211_dev_t *) 199 nic_get_specific(nic); 200 ar9271_t *ar9271 = (ar9271_t *) ieee80211_get_specific(ieee80211_dev); 201 */ 202 183 /** Set multicast frames acceptance mode. 184 * 185 */ 186 static int ar9271_on_multicast_mode_change(nic_t *nic, 187 nic_multicast_mode_t mode, const nic_address_t *addr, size_t addr_cnt) 188 { 203 189 switch (mode) { 204 case NIC_MULTICAST_BLOCKED: 205 /* TODO */ 206 break; 207 case NIC_MULTICAST_LIST: 208 /* TODO */ 209 break; 210 case NIC_MULTICAST_PROMISC: 211 /* TODO */ 212 break; 213 default: 214 return ENOTSUP; 215 } 216 217 return EOK; 218 } 219 220 /** 221 * Set unicast frames acceptance mode. 190 case NIC_MULTICAST_BLOCKED: 191 /* TODO */ 192 break; 193 case NIC_MULTICAST_LIST: 194 /* TODO */ 195 break; 196 case NIC_MULTICAST_PROMISC: 197 /* TODO */ 198 break; 199 default: 200 return ENOTSUP; 201 } 202 203 return EOK; 204 } 205 206 /** Set unicast frames acceptance mode. 222 207 * 223 208 */ … … 225 210 const nic_address_t *addr, size_t addr_cnt) 226 211 { 227 /*228 ieee80211_dev_t *ieee80211_dev = (ieee80211_dev_t *)229 nic_get_specific(nic);230 ar9271_t *ar9271 = (ar9271_t *) ieee80211_get_specific(ieee80211_dev);231 */232 233 212 switch (mode) { 234 case NIC_UNICAST_BLOCKED: 235 /* TODO */ 236 break; 237 case NIC_UNICAST_DEFAULT: 238 /* TODO */ 239 break; 240 case NIC_UNICAST_LIST: 241 /* TODO */ 242 break; 243 case NIC_UNICAST_PROMISC: 244 /* TODO */ 245 break; 246 default: 247 return ENOTSUP; 248 } 249 250 return EOK; 251 } 252 253 /** 254 * Set broadcast frames acceptance mode. 255 * 256 */ 257 static int ar9271_on_broadcast_mode_change(nic_t *nic, 258 nic_broadcast_mode_t mode) 259 { 260 /* 261 ieee80211_dev_t *ieee80211_dev = (ieee80211_dev_t *) 262 nic_get_specific(nic); 263 ar9271_t *ar9271 = (ar9271_t *) ieee80211_get_specific(ieee80211_dev); 264 */ 265 213 case NIC_UNICAST_BLOCKED: 214 /* TODO */ 215 break; 216 case NIC_UNICAST_DEFAULT: 217 /* TODO */ 218 break; 219 case NIC_UNICAST_LIST: 220 /* TODO */ 221 break; 222 case NIC_UNICAST_PROMISC: 223 /* TODO */ 224 break; 225 default: 226 return ENOTSUP; 227 } 228 229 return EOK; 230 } 231 232 /** Set broadcast frames acceptance mode. 233 * 234 */ 235 static int ar9271_on_broadcast_mode_change(nic_t *nic, 236 nic_broadcast_mode_t mode) 237 { 266 238 switch (mode) { 267 268 269 270 271 272 273 274 239 case NIC_BROADCAST_BLOCKED: 240 /* TODO */ 241 break; 242 case NIC_BROADCAST_ACCEPTED: 243 /* TODO */ 244 break; 245 default: 246 return ENOTSUP; 275 247 } 276 248 … … 292 264 void *buffer = malloc(buffer_size); 293 265 294 while (true) {266 while (true) { 295 267 size_t transferred_size; 296 if (htc_read_data_message(ar9271->htc_device,297 298 size_t strip_length = 299 300 sizeof(htc_frame_header_t) +301 302 303 if (transferred_size < strip_length)268 if (htc_read_data_message(ar9271->htc_device, 269 buffer, buffer_size, &transferred_size) == EOK) { 270 size_t strip_length = 271 sizeof(ath_usb_data_header_t) + 272 sizeof(htc_frame_header_t) + 273 sizeof(htc_rx_status_t); 274 275 if (transferred_size < strip_length) 304 276 continue; 305 306 ath_usb_data_header_t *data_header = 307 308 277 278 ath_usb_data_header_t *data_header = 279 (ath_usb_data_header_t *) buffer; 280 309 281 /* Invalid packet. */ 310 if (data_header->tag != uint16_t_le2host(RX_TAG))282 if (data_header->tag != uint16_t_le2host(RX_TAG)) 311 283 continue; 312 284 313 285 htc_rx_status_t *rx_status = 314 315 316 286 (htc_rx_status_t *) ((void *) buffer + 287 sizeof(ath_usb_data_header_t) + 288 sizeof(htc_frame_header_t)); 317 289 318 290 uint16_t data_length = 319 320 321 int16_t payload_length = 322 323 324 if (payload_length - data_length < 0)291 uint16_t_be2host(rx_status->data_length); 292 293 int16_t payload_length = 294 transferred_size - strip_length; 295 296 if (payload_length - data_length < 0) 325 297 continue; 326 298 327 if (ar9271_rx_status_error(rx_status->status))299 if (ar9271_rx_status_error(rx_status->status)) 328 300 continue; 329 301 330 302 void *strip_buffer = buffer + strip_length; 331 303 332 304 ieee80211_rx_handler(ar9271->ieee80211_dev, 333 334 305 strip_buffer, 306 payload_length); 335 307 } 336 308 } … … 341 313 } 342 314 343 /** 344 * IEEE 802.11 handlers. 345 */ 346 315 /** IEEE 802.11 handlers. 316 * 317 */ 347 318 static int ar9271_ieee80211_set_freq(ieee80211_dev_t *ieee80211_dev, 348 319 uint16_t freq) 349 320 { 350 321 assert(ieee80211_dev); … … 357 328 358 329 int rc = hw_freq_switch(ar9271, freq); 359 if (rc != EOK) {330 if (rc != EOK) { 360 331 usb_log_error("Failed to HW switch frequency.\n"); 361 332 return rc; … … 365 336 366 337 rc = hw_rx_init(ar9271); 367 if (rc != EOK) {338 if (rc != EOK) { 368 339 usb_log_error("Failed to initialize RX.\n"); 369 340 return rc; … … 371 342 372 343 uint16_t htc_mode = host2uint16_t_be(1); 373 wmi_send_command(ar9271->htc_device, WMI_SET_MODE, 374 344 wmi_send_command(ar9271->htc_device, WMI_SET_MODE, 345 (uint8_t *) &htc_mode, sizeof(htc_mode), NULL); 375 346 wmi_send_command(ar9271->htc_device, WMI_ENABLE_INTR, NULL, 0, NULL); 376 347 … … 379 350 380 351 static int ar9271_ieee80211_bssid_change(ieee80211_dev_t *ieee80211_dev, 381 352 bool connected) 382 353 { 383 354 assert(ieee80211_dev); 384 355 385 356 ar9271_t *ar9271 = (ar9271_t *) ieee80211_get_specific(ieee80211_dev); 386 387 if (connected) {357 358 if (connected) { 388 359 nic_address_t bssid; 389 360 ieee80211_query_bssid(ieee80211_dev, &bssid); 390 361 391 362 htc_sta_msg_t sta_msg; 392 363 memset(&sta_msg, 0, sizeof(htc_sta_msg_t)); 393 364 sta_msg.is_vif_sta = 0; 394 sta_msg.max_ampdu = 395 365 sta_msg.max_ampdu = 366 host2uint16_t_be(1 << IEEE80211_MAX_AMPDU_FACTOR); 396 367 sta_msg.sta_index = 1; 397 368 sta_msg.vif_index = 0; 398 369 memcpy(&sta_msg.addr, bssid.address, ETH_ADDR); 399 400 wmi_send_command(ar9271->htc_device, WMI_NODE_CREATE, 401 402 370 371 wmi_send_command(ar9271->htc_device, WMI_NODE_CREATE, 372 (uint8_t *) &sta_msg, sizeof(sta_msg), NULL); 373 403 374 htc_rate_msg_t rate_msg; 404 375 memset(&rate_msg, 0, sizeof(htc_rate_msg_t)); 405 376 rate_msg.sta_index = 1; 406 377 rate_msg.is_new = 1; 407 rate_msg.legacy_rates_count = 408 ARRAY_SIZE(ieee80211bg_data_rates); 409 memcpy(&rate_msg.legacy_rates, 410 ieee80211bg_data_rates, 411 ARRAY_SIZE(ieee80211bg_data_rates)); 412 413 wmi_send_command(ar9271->htc_device, WMI_RC_RATE_UPDATE, 414 (uint8_t *) &rate_msg, sizeof(rate_msg), NULL); 415 378 rate_msg.legacy_rates_count = ARRAY_SIZE(ieee80211bg_data_rates); 379 memcpy(&rate_msg.legacy_rates, 380 ieee80211bg_data_rates, 381 ARRAY_SIZE(ieee80211bg_data_rates)); 382 383 wmi_send_command(ar9271->htc_device, WMI_RC_RATE_UPDATE, 384 (uint8_t *) &rate_msg, sizeof(rate_msg), NULL); 385 416 386 hw_set_rx_filter(ar9271, true); 417 387 } else { 418 388 uint8_t station_id = 1; 419 389 wmi_send_command(ar9271->htc_device, WMI_NODE_REMOVE, 420 390 &station_id, sizeof(station_id), NULL); 421 391 422 392 hw_set_rx_filter(ar9271, false); … … 429 399 430 400 static int ar9271_ieee80211_key_config(ieee80211_dev_t *ieee80211_dev, 431 401 ieee80211_key_config_t *key_conf, bool insert) 432 402 { 433 403 assert(ieee80211_dev); … … 446 416 ieee80211_query_bssid(ieee80211_dev, &bssid); 447 417 448 switch (key_conf->suite) {449 450 451 452 453 454 455 456 457 458 459 460 461 462 418 switch (key_conf->suite) { 419 case IEEE80211_SECURITY_SUITE_WEP40: 420 key_type = AR9271_KEY_TABLE_TYPE_WEP40; 421 break; 422 case IEEE80211_SECURITY_SUITE_WEP104: 423 key_type = AR9271_KEY_TABLE_TYPE_WEP104; 424 break; 425 case IEEE80211_SECURITY_SUITE_TKIP: 426 key_type = AR9271_KEY_TABLE_TYPE_TKIP; 427 break; 428 case IEEE80211_SECURITY_SUITE_CCMP: 429 key_type = AR9271_KEY_TABLE_TYPE_CCMP; 430 break; 431 default: 432 key_type = -1; 463 433 } 464 434 465 uint8_t key_id = 466 467 435 uint8_t key_id = 436 (key_conf->flags & IEEE80211_KEY_FLAG_TYPE_PAIRWISE) ? 437 AR9271_STA_KEY_INDEX : key_conf->id; 468 438 469 439 reg_ptr = AR9271_KEY_TABLE(key_id); … … 471 441 data_start = (void *) key_conf->data; 472 442 473 key[0] = uint32_t_le2host( 474 *((uint32_t *) data_start)); 475 key[1] = uint16_t_le2host( 476 *((uint16_t *) (data_start + 4))); 477 key[2] = uint32_t_le2host( 478 *((uint32_t *) (data_start + 6))); 479 key[3] = uint16_t_le2host( 480 *((uint16_t *) (data_start + 10))); 481 key[4] = uint32_t_le2host( 482 *((uint32_t *) (data_start + 12))); 483 484 if(key_conf->suite == IEEE80211_SECURITY_SUITE_WEP40 || 485 key_conf->suite == IEEE80211_SECURITY_SUITE_WEP104) { 443 key[0] = uint32_t_le2host(*((uint32_t *) data_start)); 444 key[1] = uint16_t_le2host(*((uint16_t *) (data_start + 4))); 445 key[2] = uint32_t_le2host(*((uint32_t *) (data_start + 6))); 446 key[3] = uint16_t_le2host(*((uint16_t *) (data_start + 10))); 447 key[4] = uint32_t_le2host(*((uint32_t *) (data_start + 12))); 448 449 if ((key_conf->suite == IEEE80211_SECURITY_SUITE_WEP40) || 450 (key_conf->suite == IEEE80211_SECURITY_SUITE_WEP104)) 486 451 key[4] &= 0xFF; 487 }488 452 489 453 wmi_reg_write(ar9271->htc_device, reg_ptr + 0, key[0]); … … 494 458 wmi_reg_write(ar9271->htc_device, reg_ptr + 20, key_type); 495 459 496 uint32_t macL, macH; 497 if(key_conf->flags & IEEE80211_KEY_FLAG_TYPE_PAIRWISE) { 460 uint32_t macl; 461 uint32_t mach; 462 if (key_conf->flags & IEEE80211_KEY_FLAG_TYPE_PAIRWISE) { 498 463 data_start = (void *) bssid.address; 499 macL = uint32_t_le2host(*((uint32_t *) data_start)); 500 macH = uint16_t_le2host(*((uint16_t *) 501 (data_start + 4))); 464 macl = uint32_t_le2host(*((uint32_t *) data_start)); 465 mach = uint16_t_le2host(*((uint16_t *) (data_start + 4))); 502 466 } else { 503 macL = macH = 0; 467 macl = 0; 468 mach = 0; 504 469 } 505 470 506 mac L>>= 1;507 mac L |= (macH& 1) << 31;508 mac H>>= 1;509 mac H|= 0x8000;510 511 wmi_reg_write(ar9271->htc_device, reg_ptr + 24, mac L);512 wmi_reg_write(ar9271->htc_device, reg_ptr + 28, mac H);471 macl >>= 1; 472 macl |= (mach & 1) << 31; 473 mach >>= 1; 474 mach |= 0x8000; 475 476 wmi_reg_write(ar9271->htc_device, reg_ptr + 24, macl); 477 wmi_reg_write(ar9271->htc_device, reg_ptr + 28, mach); 513 478 514 479 /* Setup MIC keys for TKIP. */ 515 if (key_conf->suite == IEEE80211_SECURITY_SUITE_TKIP) {480 if (key_conf->suite == IEEE80211_SECURITY_SUITE_TKIP) { 516 481 uint32_t mic[5]; 517 uint8_t *gen_mic = 518 data_start + IEEE80211_TKIP_RX_MIC_OFFSET; 482 uint8_t *gen_mic = data_start + IEEE80211_TKIP_RX_MIC_OFFSET; 519 483 uint8_t *tx_mic; 520 if(key_conf->flags & IEEE80211_KEY_FLAG_TYPE_GROUP) { 484 485 if (key_conf->flags & IEEE80211_KEY_FLAG_TYPE_GROUP) 521 486 tx_mic = gen_mic; 522 } else { 523 tx_mic = data_start + 524 IEEE80211_TKIP_TX_MIC_OFFSET; 525 } 526 527 mic[0] = uint32_t_le2host( 528 *((uint32_t *) gen_mic)); 529 mic[1] = uint16_t_le2host( 530 *((uint16_t *) (tx_mic + 2))) & 0xFFFF; 531 mic[2] = uint32_t_le2host( 532 *((uint32_t *) (gen_mic + 4))); 533 mic[3] = uint16_t_le2host( 534 *((uint16_t *) tx_mic)) & 0xFFFF; 535 mic[4] = uint32_t_le2host( 536 *((uint32_t *) (tx_mic + 4))); 537 538 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 0, 539 mic[0]); 540 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 4, 541 mic[1]); 542 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 8, 543 mic[2]); 544 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 12, 545 mic[3]); 546 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 16, 547 mic[4]); 548 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 20, 549 AR9271_KEY_TABLE_TYPE_CLR); 487 else 488 tx_mic = data_start + IEEE80211_TKIP_TX_MIC_OFFSET; 489 490 mic[0] = uint32_t_le2host(*((uint32_t *) gen_mic)); 491 mic[1] = uint16_t_le2host(*((uint16_t *) (tx_mic + 2))) & 0xFFFF; 492 mic[2] = uint32_t_le2host(*((uint32_t *) (gen_mic + 4))); 493 mic[3] = uint16_t_le2host(*((uint16_t *) tx_mic)) & 0xFFFF; 494 mic[4] = uint32_t_le2host(*((uint32_t *) (tx_mic + 4))); 495 496 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 0, mic[0]); 497 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 4, mic[1]); 498 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 8, mic[2]); 499 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 12, mic[3]); 500 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 16, mic[4]); 501 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 20, 502 AR9271_KEY_TABLE_TYPE_CLR); 550 503 551 504 wmi_reg_write(ar9271->htc_device, mic_reg_ptr + 24, 0); … … 553 506 } 554 507 555 if (key_conf->flags & IEEE80211_KEY_FLAG_TYPE_GROUP)508 if (key_conf->flags & IEEE80211_KEY_FLAG_TYPE_GROUP) 556 509 ieee80211_setup_key_confirm(ieee80211_dev, true); 557 510 } else { … … 564 517 565 518 static int ar9271_ieee80211_tx_handler(ieee80211_dev_t *ieee80211_dev, 566 519 void *buffer, size_t buffer_size) 567 520 { 568 521 assert(ieee80211_dev); 569 522 570 size_t complete_size, offset; 523 size_t complete_size; 524 size_t offset; 571 525 void *complete_buffer; 572 526 int endpoint; … … 575 529 576 530 uint16_t frame_ctrl = *((uint16_t *) buffer); 577 if (ieee80211_is_data_frame(frame_ctrl)) {531 if (ieee80211_is_data_frame(frame_ctrl)) { 578 532 offset = sizeof(htc_tx_data_header_t) + 579 533 sizeof(htc_frame_header_t); 580 534 complete_size = buffer_size + offset; 581 535 complete_buffer = malloc(complete_size); 582 536 memset(complete_buffer, 0, complete_size); 583 537 584 /* 538 /* 585 539 * Because we handle just station mode yet, node ID and VIF ID 586 540 * are fixed. 587 541 */ 588 542 htc_tx_data_header_t *data_header = 589 (htc_tx_data_header_t *)590 543 (htc_tx_data_header_t *) 544 (complete_buffer + sizeof(htc_frame_header_t)); 591 545 data_header->data_type = HTC_DATA_NORMAL; 592 546 data_header->node_idx = 1; … … 594 548 data_header->cookie = 0; 595 549 596 if (ieee80211_query_using_key(ieee80211_dev)) {550 if (ieee80211_query_using_key(ieee80211_dev)) { 597 551 data_header->keyix = AR9271_STA_KEY_INDEX; 598 int sec_suite = 599 ieee80211_get_pairwise_security(ieee80211_dev); 600 switch(sec_suite) { 601 case IEEE80211_SECURITY_SUITE_WEP40: 602 case IEEE80211_SECURITY_SUITE_WEP104: 603 data_header->key_type = 604 AR9271_KEY_TYPE_WEP; 605 break; 606 case IEEE80211_SECURITY_SUITE_TKIP: 607 data_header->key_type = 608 AR9271_KEY_TYPE_TKIP; 609 break; 610 case IEEE80211_SECURITY_SUITE_CCMP: 611 data_header->key_type = 612 AR9271_KEY_TYPE_AES; 613 break; 552 553 int sec_suite = 554 ieee80211_get_pairwise_security(ieee80211_dev); 555 556 switch (sec_suite) { 557 case IEEE80211_SECURITY_SUITE_WEP40: 558 case IEEE80211_SECURITY_SUITE_WEP104: 559 data_header->key_type = AR9271_KEY_TYPE_WEP; 560 break; 561 case IEEE80211_SECURITY_SUITE_TKIP: 562 data_header->key_type = AR9271_KEY_TYPE_TKIP; 563 break; 564 case IEEE80211_SECURITY_SUITE_CCMP: 565 data_header->key_type = AR9271_KEY_TYPE_AES; 566 break; 614 567 } 615 568 } else { … … 621 574 } else { 622 575 offset = sizeof(htc_tx_management_header_t) + 623 576 sizeof(htc_frame_header_t); 624 577 complete_size = buffer_size + offset; 625 578 complete_buffer = malloc(complete_size); 626 579 memset(complete_buffer, 0, complete_size); 627 580 628 /* 581 /* 629 582 * Because we handle just station mode yet, node ID and VIF ID 630 583 * are fixed. 631 584 */ 632 585 htc_tx_management_header_t *mgmt_header = 633 (htc_tx_management_header_t *)634 586 (htc_tx_management_header_t *) 587 (complete_buffer + sizeof(htc_frame_header_t)); 635 588 mgmt_header->node_idx = 0; 636 589 mgmt_header->vif_idx = 0; … … 645 598 646 599 htc_send_data_message(ar9271->htc_device, complete_buffer, 647 600 complete_size, endpoint); 648 601 649 602 free(complete_buffer); … … 661 614 662 615 int rc = hw_reset(ar9271); 663 if (rc != EOK) {616 if (rc != EOK) { 664 617 usb_log_error("Failed to do HW reset.\n"); 665 618 return rc; … … 667 620 668 621 uint16_t htc_mode = host2uint16_t_be(1); 669 wmi_send_command(ar9271->htc_device, WMI_SET_MODE, 670 622 wmi_send_command(ar9271->htc_device, WMI_SET_MODE, 623 (uint8_t *) &htc_mode, sizeof(htc_mode), NULL); 671 624 wmi_send_command(ar9271->htc_device, WMI_ATH_INIT, NULL, 0, NULL); 672 625 wmi_send_command(ar9271->htc_device, WMI_START_RECV, NULL, 0, NULL); … … 674 627 675 628 rc = hw_rx_init(ar9271); 676 if (rc != EOK) {629 if (rc != EOK) { 677 630 usb_log_error("Failed to initialize RX.\n"); 678 631 return rc; … … 681 634 /* Send capability message to target. */ 682 635 htc_cap_msg_t cap_msg; 683 cap_msg.ampdu_limit = host2uint32_t_be(0x FFFF);684 cap_msg.ampdu_subframes = 0x FF;636 cap_msg.ampdu_limit = host2uint32_t_be(0xffff); 637 cap_msg.ampdu_subframes = 0xff; 685 638 cap_msg.enable_coex = 0; 686 639 cap_msg.tx_chainmask = 0x1; 687 640 688 641 wmi_send_command(ar9271->htc_device, WMI_TARGET_IC_UPDATE, 689 642 (uint8_t *) &cap_msg, sizeof(cap_msg), NULL); 690 643 691 644 rc = htc_init_new_vif(ar9271->htc_device); 692 if (rc != EOK) {645 if (rc != EOK) { 693 646 usb_log_error("Failed to initialize new VIF.\n"); 694 647 return rc; … … 697 650 /* Add data polling fibril. */ 698 651 fid_t fibril = fibril_create(ar9271_data_polling, ar9271); 699 if (fibril == 0) {652 if (fibril == 0) 700 653 return ENOMEM; 701 }654 702 655 fibril_add_ready(fibril); 703 656 … … 725 678 726 679 int rc = ath_usb_init(ar9271->ath_device, usb_device); 727 if (rc != EOK) {680 if (rc != EOK) { 728 681 free(ar9271->ath_device); 729 682 usb_log_error("Failed to initialize ath device.\n"); … … 741 694 742 695 rc = ieee80211_device_init(ar9271->ieee80211_dev, ar9271->ddf_dev); 743 if (rc != EOK) {696 if (rc != EOK) { 744 697 free(ar9271->ieee80211_dev); 745 698 free(ar9271->ath_device); 746 699 usb_log_error("Failed to initialize IEEE80211 device structure." 747 700 "\n"); 748 701 return rc; 749 702 } 750 703 751 704 ieee80211_set_specific(ar9271->ieee80211_dev, ar9271); 752 705 753 706 /* HTC device structure initialization. */ 754 707 ar9271->htc_device = calloc(1, sizeof(htc_device_t)); 755 if (!ar9271->htc_device) {708 if (!ar9271->htc_device) { 756 709 free(ar9271->ieee80211_dev); 757 710 free(ar9271->ath_device); … … 761 714 } 762 715 763 rc = htc_device_init(ar9271->ath_device, ar9271->ieee80211_dev, 764 765 if (rc != EOK) {716 rc = htc_device_init(ar9271->ath_device, ar9271->ieee80211_dev, 717 ar9271->htc_device); 718 if (rc != EOK) { 766 719 free(ar9271->htc_device); 767 720 free(ar9271->ieee80211_dev); … … 774 727 } 775 728 776 /** 777 * Upload firmware to WiFi device. 778 * 729 /** Upload firmware to WiFi device. 730 * 779 731 * @param ar9271 AR9271 device structure 780 * 732 * 781 733 * @return EOK if succeed, negative error code otherwise 734 * 782 735 */ 783 736 static int ar9271_upload_fw(ar9271_t *ar9271) 784 737 { 785 int rc;786 787 738 usb_device_t *usb_device = ar9271->usb_device; 788 789 739 740 /* TODO: Set by maximum packet size in pipe. */ 790 741 static const size_t MAX_TRANSFER_SIZE = 512; 791 742 … … 802 753 803 754 void *fw_data = malloc(file_size); 804 if (fw_data == NULL) {755 if (fw_data == NULL) { 805 756 fclose(fw_file); 806 757 usb_log_error("Failed allocating memory for firmware.\n"); 807 758 return ENOMEM; 808 759 } 809 760 810 761 fread(fw_data, file_size, 1, fw_file); 811 762 fclose(fw_file); … … 816 767 uint8_t *current_data = fw_data; 817 768 uint8_t *buffer = malloc(MAX_TRANSFER_SIZE); 818 while(remain_size > 0) { 769 770 while (remain_size > 0) { 819 771 size_t chunk_size = min(remain_size, MAX_TRANSFER_SIZE); 820 772 memcpy(buffer, current_data, chunk_size); 821 rc = usb_control_request_set(&usb_device->ctrl_pipe,773 int rc = usb_control_request_set(&usb_device->ctrl_pipe, 822 774 USB_REQUEST_TYPE_VENDOR, 823 775 USB_REQUEST_RECIPIENT_DEVICE, … … 825 777 uint16_host2usb(current_addr >> 8), 826 778 0, buffer, chunk_size); 827 if (rc != EOK) {779 if (rc != EOK) { 828 780 free(fw_data); 829 781 free(buffer); … … 841 793 free(buffer); 842 794 843 /* Send command that firmware is successfully uploaded. 844 * This should initiate creating confirmation message in 845 * device side buffer which we will check in htc_check_ready function. 846 */ 847 rc = usb_control_request_set(&usb_device->ctrl_pipe, 795 /* 796 * Send command that firmware is successfully uploaded. 797 * This should initiate creating confirmation message in 798 * device side buffer which we will check in htc_check_ready function. 799 */ 800 int rc = usb_control_request_set(&usb_device->ctrl_pipe, 848 801 USB_REQUEST_TYPE_VENDOR, 849 802 USB_REQUEST_RECIPIENT_DEVICE, … … 852 805 0, NULL, 0); 853 806 854 if (rc != EOK) {807 if (rc != EOK) { 855 808 usb_log_error("IO error when sending fw upload confirmation " 856 809 "message.\n"); 857 810 return rc; 858 811 } … … 867 820 868 821 /** Create driver data structure. 869 * 822 * 870 823 * @param dev The device structure 871 * 824 * 872 825 * @return Intialized device data structure or NULL if error occured 873 826 */ … … 883 836 const char *err_msg = NULL; 884 837 int rc = usb_device_init(usb_device, dev, endpoints, &err_msg); 885 if (rc != EOK) {838 if (rc != EOK) { 886 839 free(usb_device); 887 840 usb_log_error("Failed to create USB device: %s, " … … 902 855 903 856 rc = ar9271_init(ar9271, usb_device); 904 if (rc != EOK) {857 if (rc != EOK) { 905 858 free(ar9271); 906 859 free(usb_device); 907 usb_log_error("Failed to initialize AR9271 structure: %d\n", 908 860 usb_log_error("Failed to initialize AR9271 structure: %d\n", 861 rc); 909 862 return NULL; 910 863 } … … 948 901 /* Initialize AR9271 HTC services. */ 949 902 int rc = htc_init(ar9271->htc_device); 950 if (rc != EOK) {903 if (rc != EOK) { 951 904 ar9271_delete_dev_data(ar9271); 952 905 usb_log_error("HTC initialization failed.\n"); … … 956 909 /* Initialize AR9271 HW. */ 957 910 rc = hw_init(ar9271); 958 if (rc != EOK) {911 if (rc != EOK) { 959 912 ar9271_delete_dev_data(ar9271); 960 913 usb_log_error("HW initialization failed.\n"); … … 964 917 /* Initialize AR9271 IEEE 802.11 framework. */ 965 918 rc = ieee80211_init(ar9271->ieee80211_dev, &ar9271_ieee80211_ops, 966 967 968 if (rc != EOK) {919 &ar9271_ieee80211_iface, &ar9271_ieee80211_nic_iface, 920 &ar9271_ieee80211_dev_ops); 921 if (rc != EOK) { 969 922 ar9271_delete_dev_data(ar9271); 970 923 usb_log_error("Failed to initialize IEEE80211 framework.\n"); … … 973 926 974 927 nic_set_filtering_change_handlers(nic_get_from_ddf_dev(dev), 975 976 928 ar9271_on_unicast_mode_change, ar9271_on_multicast_mode_change, 929 ar9271_on_broadcast_mode_change, NULL, NULL); 977 930 978 931 usb_log_info("HelenOS AR9271 added device.\n"); … … 989 942 990 943 usb_log_info("HelenOS AR9271 driver started.\n"); 991 944 992 945 return ddf_driver_main(&ar9271_driver); 993 946 } -
uspace/drv/nic/ar9271/ar9271.h
r09044cb r8a64320e 37 37 38 38 #include <usb/dev/driver.h> 39 40 39 #include "htc.h" 41 40 42 41 /** Number of transmission queues */ 43 #define AR9271_QUEUES_COUNT 1042 #define AR9271_QUEUES_COUNT 10 44 43 45 44 /** Number of GPIO pin used for handling led light */ 46 #define AR9271_LED_PIN 1545 #define AR9271_LED_PIN 15 47 46 48 47 /** Nominal value for AR9271 noise floor calibration. */ 49 #define AR9271_CALIB_NOMINAL_VALUE_2GHZ -11848 #define AR9271_CALIB_NOMINAL_VALUE_2GHZ -118 50 49 51 50 /** RX errors values. */ 52 #define AR9271_RX_ERROR_CRC 0x0153 #define AR9271_RX_ERROR_PHY 0x0251 #define AR9271_RX_ERROR_CRC 0x01 52 #define AR9271_RX_ERROR_PHY 0x02 54 53 55 54 /** Key index used for device in station mode. */ 56 #define AR9271_STA_KEY_INDEX 455 #define AR9271_STA_KEY_INDEX 4 57 56 58 57 /* HW encryption key indicator. */ … … 83 82 AR9271_RC = 0x4000, 84 83 AR9271_RC_AHB = 0x00000001, 85 84 86 85 /* GPIO registers */ 87 AR9271_GPIO_IN_OUT = 0x4048, 88 AR9271_GPIO_OE_OUT = 0x404C, 89 AR9271_GPIO_OE_OUT_ALWAYS = 0x3, 86 AR9271_GPIO_IN_OUT = 0x4048, /**< GPIO value read/set */ 87 AR9271_GPIO_OE_OUT = 0x404C, /**< GPIO set to output */ 88 AR9271_GPIO_OE_OUT_ALWAYS = 0x3, /**< GPIO always drive output */ 90 89 AR9271_GPIO_OUT_MUX1 = 0x4060, 91 90 AR9271_GPIO_OUT_MUX2 = 0x4064, 92 91 AR9271_GPIO_OUT_MUX3 = 0x4068, 93 AR9271_GPIO_OUT_MUX_AS_OUT = 0x0, 94 92 AR9271_GPIO_OUT_MUX_AS_OUT = 0x0, /**< GPIO set mux as output */ 93 95 94 /* RTC related registers */ 96 95 AR9271_RTC_RC = 0x7000, … … 109 108 AR9271_RTC_FORCE_WAKE_ENABLE = 0x00000001, 110 109 AR9271_RTC_FORCE_WAKE_ON_INT = 0x00000002, 111 110 112 111 /* MAC Registers */ 113 AR9271_STATION_ID0 = 0x8000, 114 AR9271_STATION_ID1 = 0x8004, 115 AR9271_BSSID0 = 0x8008, 116 AR9271_BSSID1 = 0x800C, 117 AR9271_BSSID_MASK0 = 0x80E0, 118 AR9271_BSSID_MASK1 = 0x80E4, 112 AR9271_STATION_ID0 = 0x8000, /**< STA Address Lower 32 Bits */ 113 AR9271_STATION_ID1 = 0x8004, /**< STA Address Upper 16 Bits */ 114 AR9271_BSSID0 = 0x8008, /**< BSSID Lower 32 Bits */ 115 AR9271_BSSID1 = 0x800C, /**< BSSID Upper 16 Bits */ 116 AR9271_BSSID_MASK0 = 0x80E0, /**< BSSID Mask Lower 32 Bits */ 117 AR9271_BSSID_MASK1 = 0x80E4, /**< BSSID Mask Upper 16 Bits */ 119 118 AR9271_STATION_ID1_MASK = 0x0000FFFF, 120 119 AR9271_STATION_ID1_POWER_SAVING = 0x00040000, 121 120 AR9271_MULTICAST_FILTER1 = 0x8040, 122 AR9271_MULTICAST_FILTER2 = 0x8044, 121 AR9271_MULTICAST_FILTER2 = 0x8044, 123 122 AR9271_DIAG = 0x8048, 124 123 125 124 /* RX filtering register */ 126 125 AR9271_RX_FILTER = 0x803C, … … 134 133 AR9271_RX_FILTER_MYBEACON = 0x00000200, 135 134 AR9271_RX_FILTER_MCAST_BCAST_ALL = 0x00008000, 136 135 137 136 /* Key related registers */ 138 137 AR9271_KEY_TABLE_BASE = 0x8800, … … 142 141 AR9271_KEY_TABLE_TYPE_CCMP = 0x6, 143 142 AR9271_KEY_TABLE_TYPE_CLR = 0x7, 144 143 145 144 /* Physical layer registers */ 146 145 AR9271_PHY_ACTIVE = 0x981C, … … 168 167 AR9271_PHY_TPCRG1_PD_CALIB = 0x00400000, 169 168 AR9271_CARRIER_LEAK_CALIB = 0x00000002, 170 169 171 170 AR9271_OPMODE_STATION_AP_MASK = 0x00010000, 172 171 AR9271_OPMODE_ADHOC_MASK = 0x00020000, 173 172 174 173 AR9271_CLOCK_CONTROL = 0x50040, 175 174 AR9271_MAX_CPU_CLOCK = 0x304, 176 175 177 176 AR9271_RESET_POWER_DOWN_CONTROL = 0x50044, 178 177 AR9271_RADIO_RF_RESET = 0x20, 179 178 AR9271_GATE_MAC_CONTROL = 0x4000, 180 179 181 180 /* FW Addresses */ 182 181 AR9271_FW_ADDRESS = 0x501000, … … 185 184 186 185 /** Compute key table base position for key by its id. */ 187 #define AR9271_KEY_TABLE(id) (AR9271_KEY_TABLE_BASE + (id)*32)186 #define AR9271_KEY_TABLE(id) (AR9271_KEY_TABLE_BASE + (id) * 32) 188 187 189 188 /** AR9271 Requests */ … … 217 216 } ar9271_t; 218 217 219 /** 220 * AR9271 init values for 2GHz mode operation. 221 * 218 /** AR9271 init values for 2GHz mode operation. 219 * 222 220 * Including settings of noise floor limits. 223 * 224 * Taken from Linux sources. 221 * 222 * Taken from the Linux driver (drivers/net/wireless/ath/ath9k/) 223 * Copyright (c) 2008-2011 Atheros Communications Inc. 224 * Licensed under the terms of ISC 225 * 225 226 */ 226 227 static const uint32_t ar9271_2g_mode_array[][2] = { … … 232 233 {0x0000801c, 0x12e0002b}, 233 234 {0x00008318, 0x00003440}, 234 {0x00009804, 0x000003c0}, /*< note: overridden */235 {0x00009804, 0x000003c0}, /*< Note: overridden */ 235 236 {0x00009820, 0x02020200}, 236 237 {0x00009824, 0x01000e0e}, 237 {0x00009828, 0x0a020001}, /*< note: overridden */238 {0x00009828, 0x0a020001}, /*< Note: overridden */ 238 239 {0x00009834, 0x00000e0e}, 239 240 {0x00009838, 0x00000007}, … … 530 531 }; 531 532 532 /** 533 * AR9271 TX init values for 2GHz mode operation. 534 * 535 * Taken from Linux sources. 533 /** AR9271 TX init values for 2GHz mode operation. 534 * 535 * Taken from the Linux driver (drivers/net/wireless/ath/ath9k/) 536 * Copyright (c) 2008-2011 Atheros Communications Inc. 537 * Licensed under the terms of ISC 538 * 536 539 */ 537 540 static const uint32_t ar9271_2g_tx_array[][2] = { … … 571 574 }; 572 575 573 /** 574 * AR9271 hardware init values. 575 * 576 * Taken from Linux sources, some values omitted. 576 /** AR9271 hardware init values. 577 * 578 * Taken from the Linux driver (drivers/net/wireless/ath/ath9k/) 579 * Copyright (c) 2008-2011 Atheros Communications Inc. 580 * Licensed under the terms of ISC 581 * 577 582 */ 578 583 static const uint32_t ar9271_init_array[][2] = { … … 766 771 {0x0000833c, 0x00000000}, 767 772 {0x00008340, 0x00010380}, 768 {0x00008344, 0x00481083}, /*< note: disabled ADHOC_MCAST_KEYID feature */773 {0x00008344, 0x00481083}, /**< Note: disabled ADHOC_MCAST_KEYID feature */ 769 774 {0x00007010, 0x00000030}, 770 775 {0x00007034, 0x00000002}, -
uspace/drv/nic/ar9271/ath.h
r09044cb r8a64320e 34 34 35 35 #ifndef ATHEROS_ATH_H 36 #define 36 #define ATHEROS_ATH_H 37 37 38 38 struct ath; … … 61 61 } ath_t; 62 62 63 #endif 63 #endif /* ATHEROS_ATH_H */ -
uspace/drv/nic/ar9271/ath_usb.c
r09044cb r8a64320e 36 36 #include <usb/debug.h> 37 37 #include <malloc.h> 38 39 38 #include "ath_usb.h" 40 39 41 static int ath_usb_send_ctrl_message(ath_t *ath, void *buffer, 42 size_t buffer_size); 43 44 static int ath_usb_read_ctrl_message(ath_t *ath, void *buffer, 45 size_t buffer_size, size_t *transferred_size); 46 47 static int ath_usb_send_data_message(ath_t *ath, void *buffer, 48 size_t buffer_size); 49 50 static int ath_usb_read_data_message(ath_t *ath, void *buffer, 51 size_t buffer_size, size_t *transferred_size); 40 static int ath_usb_send_ctrl_message(ath_t *, void *, size_t); 41 static int ath_usb_read_ctrl_message(ath_t *, void *, size_t, size_t *); 42 static int ath_usb_send_data_message(ath_t *, void *, size_t); 43 static int ath_usb_read_data_message(ath_t *, void *, size_t, size_t *); 52 44 53 45 static ath_ops_t ath_usb_ops = { … … 58 50 }; 59 51 60 /** 61 * Initialize Atheros WiFi USB device. 62 * 52 /** Initialize Atheros WiFi USB device. 53 * 63 54 * @param ath Generic Atheros WiFi device structure. 64 * @param usb_device Connected USB device.65 * 55 * @param usb_device Connected USB device. 56 * 66 57 * @return EOK if succeed, negative error code otherwise. 58 * 67 59 */ 68 60 int ath_usb_init(ath_t *ath, usb_device_t *usb_device) … … 92 84 } 93 85 94 /** 95 * Send control message. 96 * 97 * @param ath Generic Atheros WiFi device structure. 98 * @param buffer Buffer with data to send. 86 /** Send control message. 87 * 88 * @param ath Generic Atheros WiFi device structure. 89 * @param buffer Buffer with data to send. 99 90 * @param buffer_size Buffer size. 100 * 91 * 101 92 * @return EOK if succeed, negative error code otherwise. 93 * 102 94 */ 103 static int ath_usb_send_ctrl_message(ath_t *ath, void *buffer, 104 95 static int ath_usb_send_ctrl_message(ath_t *ath, void *buffer, 96 size_t buffer_size) 105 97 { 106 98 ath_usb_t *ath_usb = (ath_usb_t *) ath->specific_data; 107 usb_pipe_t *pipe = 108 &ath_usb->usb_device->pipes[ath_usb->output_ctrl_pipe_number]. 109 pipe; 99 usb_pipe_t *pipe = 100 &ath_usb->usb_device->pipes[ath_usb->output_ctrl_pipe_number].pipe; 110 101 111 102 return usb_pipe_write(pipe, buffer, buffer_size); 112 103 } 113 104 114 /** 115 * Read control message. 116 * 117 * @param ath Generic Atheros WiFi device structure. 118 * @param buffer Buffer with data to send. 119 * @param buffer_size Buffer size. 105 /** Read control message. 106 * 107 * @param ath Generic Atheros WiFi device structure. 108 * @param buffer Buffer with data to send. 109 * @param buffer_size Buffer size. 120 110 * @param transferred_size Real size of read data. 121 * 111 * 122 112 * @return EOK if succeed, negative error code otherwise. 113 * 123 114 */ 124 static int ath_usb_read_ctrl_message(ath_t *ath, void *buffer, 125 115 static int ath_usb_read_ctrl_message(ath_t *ath, void *buffer, 116 size_t buffer_size, size_t *transferred_size) 126 117 { 127 118 ath_usb_t *ath_usb = (ath_usb_t *) ath->specific_data; 128 usb_pipe_t *pipe = 129 &ath_usb->usb_device->pipes[ath_usb->input_ctrl_pipe_number]. 130 pipe; 119 usb_pipe_t *pipe = 120 &ath_usb->usb_device->pipes[ath_usb->input_ctrl_pipe_number].pipe; 131 121 132 122 return usb_pipe_read(pipe, buffer, buffer_size, transferred_size); 133 123 } 134 124 135 /** 136 * Send data message. 137 * 138 * @param ath Generic Atheros WiFi device structure. 139 * @param buffer Buffer with data to send. 125 /** Send data message. 126 * 127 * @param ath Generic Atheros WiFi device structure. 128 * @param buffer Buffer with data to send. 140 129 * @param buffer_size Buffer size. 141 * 130 * 142 131 * @return EOK if succeed, negative error code otherwise. 132 * 143 133 */ 144 static int ath_usb_send_data_message(ath_t *ath, void *buffer, 145 134 static int ath_usb_send_data_message(ath_t *ath, void *buffer, 135 size_t buffer_size) 146 136 { 147 size_t complete_buffer_size = buffer_size + 148 137 size_t complete_buffer_size = buffer_size + 138 sizeof(ath_usb_data_header_t); 149 139 void *complete_buffer = malloc(complete_buffer_size); 150 memcpy(complete_buffer + sizeof(ath_usb_data_header_t), 151 140 memcpy(complete_buffer + sizeof(ath_usb_data_header_t), 141 buffer, buffer_size); 152 142 153 ath_usb_data_header_t *data_header = 154 143 ath_usb_data_header_t *data_header = 144 (ath_usb_data_header_t *) complete_buffer; 155 145 data_header->length = host2uint16_t_le(buffer_size); 156 146 data_header->tag = host2uint16_t_le(TX_TAG); 157 147 158 148 ath_usb_t *ath_usb = (ath_usb_t *) ath->specific_data; 159 usb_pipe_t *pipe = 160 &ath_usb->usb_device->pipes[ath_usb->output_data_pipe_number]. 161 pipe; 149 usb_pipe_t *pipe = 150 &ath_usb->usb_device->pipes[ath_usb->output_data_pipe_number].pipe; 162 151 163 int ret_val = usb_pipe_write(pipe, complete_buffer, 164 152 int ret_val = usb_pipe_write(pipe, complete_buffer, 153 complete_buffer_size); 165 154 166 155 free(complete_buffer); … … 169 158 } 170 159 171 /** 172 * Read data message. 173 * 174 * @param ath Generic Atheros WiFi device structure. 175 * @param buffer Buffer with data to send. 176 * @param buffer_size Buffer size. 160 /** Read data message. 161 * 162 * @param ath Generic Atheros WiFi device structure. 163 * @param buffer Buffer with data to send. 164 * @param buffer_size Buffer size. 177 165 * @param transferred_size Real size of read data. 178 * 166 * 179 167 * @return EOK if succeed, negative error code otherwise. 168 * 180 169 */ 181 static int ath_usb_read_data_message(ath_t *ath, void *buffer, 182 170 static int ath_usb_read_data_message(ath_t *ath, void *buffer, 171 size_t buffer_size, size_t *transferred_size) 183 172 { 184 173 ath_usb_t *ath_usb = (ath_usb_t *) ath->specific_data; 185 usb_pipe_t *pipe = 186 &ath_usb->usb_device->pipes[ath_usb->input_data_pipe_number]. 187 pipe; 174 usb_pipe_t *pipe = 175 &ath_usb->usb_device->pipes[ath_usb->input_data_pipe_number].pipe; 188 176 189 return usb_pipe_read(pipe, buffer, buffer_size, 190 177 return usb_pipe_read(pipe, buffer, buffer_size, 178 transferred_size); 191 179 } -
uspace/drv/nic/ar9271/ath_usb.h
r09044cb r8a64320e 34 34 35 35 #ifndef ATHEROS_ATH_USB_H 36 #define 36 #define ATHEROS_ATH_USB_H 37 37 38 38 #include <usb/dev/driver.h> 39 40 39 #include "ath.h" 41 40 42 #define RX_TAG 0x4e0043 #define TX_TAG 0x697e41 #define RX_TAG 0x4e00 42 #define TX_TAG 0x697e 44 43 45 44 /** Atheros USB wifi device structure */ … … 56 55 57 56 typedef struct { 58 uint16_t length; 59 uint16_t tag; 57 uint16_t length; /**< Little Endian value! */ 58 uint16_t tag; /**< Little Endian value! */ 60 59 } ath_usb_data_header_t; 61 60 62 extern int ath_usb_init(ath_t * ath, usb_device_t *usb_device);61 extern int ath_usb_init(ath_t *, usb_device_t *); 63 62 64 #endif 63 #endif /* ATHEROS_ATH_USB_H */ -
uspace/drv/nic/ar9271/htc.c
r09044cb r8a64320e 36 36 #include <byteorder.h> 37 37 #include <errno.h> 38 39 38 #include "wmi.h" 40 39 #include "htc.h" … … 42 41 #include "ar9271.h" 43 42 44 /** 45 * HTC download pipes mapping. 46 * 43 /** HTC download pipes mapping. 44 * 47 45 * @param service_id Identification of WMI service. 48 * 46 * 49 47 * @return Number of pipe used for this service. 48 * 50 49 */ 51 50 static inline uint8_t wmi_service_to_download_pipe(wmi_services_t service_id) … … 54 53 } 55 54 56 /** 57 * HTC upload pipes mapping. 58 * 55 /** HTC upload pipes mapping. 56 * 59 57 * @param service_id Identification of WMI service. 60 * 58 * 61 59 * @return Number of pipe used for this service. 60 * 62 61 */ 63 62 static inline uint8_t wmi_service_to_upload_pipe(wmi_services_t service_id) … … 75 74 76 75 nic_address_t addr; 77 nic_t *nic = 78 nic_get_from_ddf_dev( 79 ieee80211_get_ddf_dev(htc_device->ieee80211_dev) 80 ); 76 nic_t *nic = 77 nic_get_from_ddf_dev(ieee80211_get_ddf_dev(htc_device->ieee80211_dev)); 81 78 nic_query_address(nic, &addr); 82 79 … … 84 81 memcpy(&sta_msg.addr, &addr.address, ETH_ADDR); 85 82 86 ieee80211_operating_mode_t op_mode = 87 88 89 switch (op_mode) {90 91 92 93 94 95 96 97 98 99 100 101 83 ieee80211_operating_mode_t op_mode = 84 ieee80211_query_current_op_mode(htc_device->ieee80211_dev); 85 86 switch (op_mode) { 87 case IEEE80211_OPMODE_ADHOC: 88 vif_msg.op_mode = HTC_OPMODE_ADHOC; 89 break; 90 case IEEE80211_OPMODE_AP: 91 vif_msg.op_mode = HTC_OPMODE_AP; 92 break; 93 case IEEE80211_OPMODE_MESH: 94 vif_msg.op_mode = HTC_OPMODE_MESH; 95 break; 96 case IEEE80211_OPMODE_STATION: 97 vif_msg.op_mode = HTC_OPMODE_STATION; 98 break; 102 99 } 103 100 … … 105 102 vif_msg.rts_thres = host2uint16_t_be(HTC_RTS_THRESHOLD); 106 103 107 wmi_send_command(htc_device, WMI_VAP_CREATE, (uint8_t *) &vif_msg, 108 104 wmi_send_command(htc_device, WMI_VAP_CREATE, (uint8_t *) &vif_msg, 105 sizeof(vif_msg), NULL); 109 106 110 107 sta_msg.is_vif_sta = 1; … … 113 110 sta_msg.vif_index = 0; 114 111 115 wmi_send_command(htc_device, WMI_NODE_CREATE, (uint8_t *) &sta_msg, 116 112 wmi_send_command(htc_device, WMI_NODE_CREATE, (uint8_t *) &sta_msg, 113 sizeof(sta_msg), NULL); 117 114 118 115 /* Write first 4 bytes of MAC address. */ … … 121 118 id0 = host2uint32_t_le(id0); 122 119 wmi_reg_write(htc_device, AR9271_STATION_ID0, id0); 123 120 124 121 /* Write last 2 bytes of MAC address (and preserve existing data). */ 125 122 uint32_t id1; 126 123 wmi_reg_read(htc_device, AR9271_STATION_ID1, &id1); 127 124 128 125 uint16_t id1_addr; 129 126 memcpy(&id1_addr, &addr.address[4], 2); … … 134 131 } 135 132 136 static void htc_config_frame_header(htc_frame_header_t *header, 137 133 static void htc_config_frame_header(htc_frame_header_t *header, 134 size_t buffer_size, uint8_t endpoint_id) 138 135 { 139 136 memset(header, 0, sizeof(htc_frame_header_t)); 140 137 141 138 header->endpoint_id = endpoint_id; 142 header->payload_length = 143 host2uint16_t_be(buffer_size - sizeof(htc_frame_header_t)); 144 } 145 146 /** 147 * Send control HTC message to USB device. 148 * 149 * @param htc_device HTC device structure. 150 * @param buffer Buffer with data to be sent to USB device (without HTC frame 151 * header). 139 header->payload_length = 140 host2uint16_t_be(buffer_size - sizeof(htc_frame_header_t)); 141 } 142 143 /** Send control HTC message to USB device. 144 * 145 * @param htc_device HTC device structure. 146 * @param buffer Buffer with data to be sent to USB device 147 * (without HTC frame header). 152 148 * @param buffer_size Size of buffer (including HTC frame header). 153 149 * @param endpoint_id Destination endpoint. 154 * 155 * @return EOK if succeed, negative error code otherwise. 156 */ 157 int htc_send_control_message(htc_device_t *htc_device, void *buffer, 158 size_t buffer_size, uint8_t endpoint_id) 150 * 151 * @return EOK if succeed, negative error code otherwise. 152 * 153 */ 154 int htc_send_control_message(htc_device_t *htc_device, void *buffer, 155 size_t buffer_size, uint8_t endpoint_id) 159 156 { 160 157 htc_config_frame_header((htc_frame_header_t *) buffer, buffer_size, 161 158 endpoint_id); 162 159 163 160 ath_t *ath_device = htc_device->ath_device; 164 161 165 return ath_device->ops->send_ctrl_message(ath_device, buffer, 166 buffer_size); 167 } 168 169 /** 170 * Send data HTC message to USB device. 171 * 172 * @param htc_device HTC device structure. 173 * @param buffer Buffer with data to be sent to USB device (without HTC frame 174 * header). 162 return ath_device->ops->send_ctrl_message(ath_device, buffer, 163 buffer_size); 164 } 165 166 /** Send data HTC message to USB device. 167 * 168 * @param htc_device HTC device structure. 169 * @param buffer Buffer with data to be sent to USB device 170 * (without HTC frame header). 175 171 * @param buffer_size Size of buffer (including HTC frame header). 176 172 * @param endpoint_id Destination endpoint. 177 * 178 * @return EOK if succeed, negative error code otherwise. 179 */ 180 int htc_send_data_message(htc_device_t *htc_device, void *buffer, 181 size_t buffer_size, uint8_t endpoint_id) 173 * 174 * @return EOK if succeed, negative error code otherwise. 175 * 176 */ 177 int htc_send_data_message(htc_device_t *htc_device, void *buffer, 178 size_t buffer_size, uint8_t endpoint_id) 182 179 { 183 180 htc_config_frame_header((htc_frame_header_t *) buffer, buffer_size, 184 181 endpoint_id); 185 182 186 183 ath_t *ath_device = htc_device->ath_device; 187 184 188 return ath_device->ops->send_data_message(ath_device, buffer, 189 190 } 191 192 /** 193 * Read HTC data message from USB device.194 * 195 * @param htc_device HTC device structure.196 * @param buffer Buffer where data from USB devicewill be stored.197 * @param buffer_size Size of buffer.185 return ath_device->ops->send_data_message(ath_device, buffer, 186 buffer_size); 187 } 188 189 /** Read HTC data message from USB device. 190 * 191 * @param htc_device HTC device structure. 192 * @param buffer Buffer where data from USB device 193 * will be stored. 194 * @param buffer_size Size of buffer. 198 195 * @param transferred_size Real size of read data. 199 * 200 * @return EOK if succeed, negative error code otherwise. 201 */ 202 int htc_read_data_message(htc_device_t *htc_device, void *buffer, 203 size_t buffer_size, size_t *transferred_size) 196 * 197 * @return EOK if succeed, negative error code otherwise. 198 * 199 */ 200 int htc_read_data_message(htc_device_t *htc_device, void *buffer, 201 size_t buffer_size, size_t *transferred_size) 204 202 { 205 203 ath_t *ath_device = htc_device->ath_device; 206 204 207 return ath_device->ops->read_data_message(ath_device, buffer, 208 209 } 210 211 /** 212 * Read HTC control message from USB device.213 * 214 * @param htc_device HTC device structure.215 * @param buffer Buffer where data from USB devicewill be stored.216 * @param buffer_size Size of buffer.205 return ath_device->ops->read_data_message(ath_device, buffer, 206 buffer_size, transferred_size); 207 } 208 209 /** Read HTC control message from USB device. 210 * 211 * @param htc_device HTC device structure. 212 * @param buffer Buffer where data from USB device 213 * will be stored. 214 * @param buffer_size Size of buffer. 217 215 * @param transferred_size Real size of read data. 218 * 219 * @return EOK if succeed, negative error code otherwise. 220 */ 221 int htc_read_control_message(htc_device_t *htc_device, void *buffer, 222 size_t buffer_size, size_t *transferred_size) 216 * 217 * @return EOK if succeed, negative error code otherwise. 218 * 219 */ 220 int htc_read_control_message(htc_device_t *htc_device, void *buffer, 221 size_t buffer_size, size_t *transferred_size) 223 222 { 224 223 ath_t *ath_device = htc_device->ath_device; 225 224 226 return ath_device->ops->read_ctrl_message(ath_device, buffer, 227 buffer_size, transferred_size); 228 } 229 230 /** 231 * Initialize HTC service. 232 * 233 * @param htc_device HTC device structure. 234 * @param service_id Identification of WMI service. 235 * @param response_endpoint_no HTC endpoint to be used for this service. 236 * 237 * @return EOK if succeed, EINVAL when failed to connect service, 238 * negative error code otherwise. 239 */ 240 static int htc_connect_service(htc_device_t *htc_device, 225 return ath_device->ops->read_ctrl_message(ath_device, buffer, 226 buffer_size, transferred_size); 227 } 228 229 /** Initialize HTC service. 230 * 231 * @param htc_device HTC device structure. 232 * @param service_id Identification of WMI service. 233 * @param response_endpoint_no HTC endpoint to be used for 234 * this service. 235 * 236 * @return EOK if succeed, EINVAL when failed to connect service, 237 * negative error code otherwise. 238 * 239 */ 240 static int htc_connect_service(htc_device_t *htc_device, 241 241 wmi_services_t service_id, int *response_endpoint_no) 242 242 { 243 size_t buffer_size = sizeof(htc_frame_header_t) + 244 243 size_t buffer_size = sizeof(htc_frame_header_t) + 244 sizeof(htc_service_msg_t); 245 245 void *buffer = malloc(buffer_size); 246 246 memset(buffer, 0, buffer_size); … … 248 248 /* Fill service message structure. */ 249 249 htc_service_msg_t *service_message = (htc_service_msg_t *) 250 251 service_message->service_id = 252 253 service_message->message_id = 254 255 service_message->download_pipe_id = 256 257 service_message->upload_pipe_id = 258 250 ((void *) buffer + sizeof(htc_frame_header_t)); 251 service_message->service_id = 252 host2uint16_t_be(service_id); 253 service_message->message_id = 254 host2uint16_t_be(HTC_MESSAGE_CONNECT_SERVICE); 255 service_message->download_pipe_id = 256 wmi_service_to_download_pipe(service_id); 257 service_message->upload_pipe_id = 258 wmi_service_to_upload_pipe(service_id); 259 259 service_message->connection_flags = 0; 260 260 261 261 /* Send HTC message. */ 262 262 int rc = htc_send_control_message(htc_device, buffer, buffer_size, 263 264 if (rc != EOK) {263 htc_device->endpoints.ctrl_endpoint); 264 if (rc != EOK) { 265 265 free(buffer); 266 266 usb_log_error("Failed to send HTC message. Error: %d\n", rc); … … 275 275 /* Read response from device. */ 276 276 rc = htc_read_control_message(htc_device, buffer, buffer_size, NULL); 277 if (rc != EOK) {277 if (rc != EOK) { 278 278 free(buffer); 279 279 usb_log_error("Failed to receive HTC service connect response. " 280 280 "Error: %d\n", rc); 281 281 return rc; 282 282 } 283 283 284 284 htc_service_resp_msg_t *response_message = (htc_service_resp_msg_t *) 285 ((void *) buffer + sizeof(htc_frame_header_t)); 286 287 /* If service was successfully connected, write down HTC endpoint number 288 * that will be used for communication. */ 289 if(response_message->status == HTC_SERVICE_SUCCESS) { 285 ((void *) buffer + sizeof(htc_frame_header_t)); 286 287 /* 288 * If service was successfully connected, 289 * write down HTC endpoint number that will 290 * be used for communication. 291 */ 292 if (response_message->status == HTC_SERVICE_SUCCESS) { 290 293 *response_endpoint_no = response_message->endpoint_id; 291 294 rc = EOK; 292 295 } else { 293 296 usb_log_error("Failed to connect HTC service. " 294 297 "Message status: %d\n", response_message->status); 295 298 rc = EINVAL; 296 299 } 297 300 298 301 free(buffer); … … 301 304 } 302 305 303 /** 304 * HTC credits initialization message. 305 * 306 /** HTC credits initialization message. 307 * 306 308 * @param htc_device HTC device structure. 307 * 308 * @return EOK if succeed, negative error code otherwise. 309 * 310 * @return EOK if succeed, negative error code otherwise. 311 * 309 312 */ 310 313 static int htc_config_credits(htc_device_t *htc_device) 311 314 { 312 size_t buffer_size = sizeof(htc_frame_header_t) + 313 315 size_t buffer_size = sizeof(htc_frame_header_t) + 316 sizeof(htc_config_msg_t); 314 317 void *buffer = malloc(buffer_size); 315 318 htc_config_msg_t *config_message = (htc_config_msg_t *) 316 319 ((void *) buffer + sizeof(htc_frame_header_t)); 317 320 318 321 config_message->message_id = 319 322 host2uint16_t_be(HTC_MESSAGE_CONFIG); 320 323 /* Magic number to initialize device. */ 321 324 config_message->credits = 33; 322 325 config_message->pipe_id = 1; 323 326 324 327 /* Send HTC message. */ 325 328 int rc = htc_send_control_message(htc_device, buffer, buffer_size, 326 327 if (rc != EOK) {329 htc_device->endpoints.ctrl_endpoint); 330 if (rc != EOK) { 328 331 free(buffer); 329 332 usb_log_error("Failed to send HTC config message. " 330 333 "Error: %d\n", rc); 331 334 return rc; 332 335 } … … 336 339 buffer_size = htc_device->ath_device->ctrl_response_length; 337 340 buffer = malloc(buffer_size); 338 341 339 342 /* Check response from device. */ 340 343 rc = htc_read_control_message(htc_device, buffer, buffer_size, NULL); 341 if (rc != EOK) {344 if (rc != EOK) { 342 345 usb_log_error("Failed to receive HTC config response message. " 343 346 "Error: %d\n", rc); 344 347 } 345 348 346 349 free(buffer); 347 350 348 351 return rc; 349 352 } 350 353 351 /** 352 * HTC setup complete confirmation message. 353 * 354 /** HTC setup complete confirmation message. 355 * 354 356 * @param htc_device HTC device structure. 355 * 356 * @return EOK if succeed, negative error code otherwise. 357 * 358 * @return EOK if succeed, negative error code otherwise. 359 * 357 360 */ 358 361 static int htc_complete_setup(htc_device_t *htc_device) 359 362 { 360 size_t buffer_size = sizeof(htc_frame_header_t) + 361 363 size_t buffer_size = sizeof(htc_frame_header_t) + 364 sizeof(htc_setup_complete_msg_t); 362 365 void *buffer = malloc(buffer_size); 363 htc_setup_complete_msg_t *complete_message = 364 365 366 367 complete_message->message_id = 368 369 366 htc_setup_complete_msg_t *complete_message = 367 (htc_setup_complete_msg_t *) 368 ((void *) buffer + sizeof(htc_frame_header_t)); 369 370 complete_message->message_id = 371 host2uint16_t_be(HTC_MESSAGE_SETUP_COMPLETE); 372 370 373 /* Send HTC message. */ 371 int rc = htc_send_control_message(htc_device, buffer, buffer_size, 372 373 if (rc != EOK) {374 int rc = htc_send_control_message(htc_device, buffer, buffer_size, 375 htc_device->endpoints.ctrl_endpoint); 376 if (rc != EOK) 374 377 usb_log_error("Failed to send HTC setup complete message. " 375 "Error: %d\n", rc); 376 } 378 "Error: %d\n", rc); 377 379 378 380 free(buffer); 379 381 380 382 return rc; 381 383 } 382 384 383 /** 384 * Try to fetch ready message from device.385 /** Try to fetch ready message from device. 386 * 385 387 * Checks that firmware was successfully loaded on device side. 386 * 388 * 387 389 * @param htc_device HTC device structure. 388 * 389 * @return EOK if succeed, EINVAL if response error, negative error code 390 * otherwise. 390 * 391 * @return EOK if succeed, EINVAL if response error, 392 * negative error code otherwise. 393 * 391 394 */ 392 395 static int htc_check_ready(htc_device_t *htc_device) … … 394 397 size_t buffer_size = htc_device->ath_device->ctrl_response_length; 395 398 void *buffer = malloc(buffer_size); 396 399 397 400 /* Read response from device. */ 398 int rc = htc_read_control_message(htc_device, buffer, buffer_size, 399 400 if (rc != EOK) {401 int rc = htc_read_control_message(htc_device, buffer, buffer_size, 402 NULL); 403 if (rc != EOK) { 401 404 free(buffer); 402 405 usb_log_error("Failed to receive HTC check ready message. " 403 404 return rc; 405 } 406 407 uint16_t *message_id = (uint16_t *) ((void *) buffer + 408 409 if (uint16_t_be2host(*message_id) == HTC_MESSAGE_READY) {406 "Error: %d\n", rc); 407 return rc; 408 } 409 410 uint16_t *message_id = (uint16_t *) ((void *) buffer + 411 sizeof(htc_frame_header_t)); 412 if (uint16_t_be2host(*message_id) == HTC_MESSAGE_READY) 410 413 rc = EOK; 411 } else {414 else 412 415 rc = EINVAL; 413 }414 416 415 417 free(buffer); … … 418 420 } 419 421 420 /** 421 * Initialize HTC device structure.422 * 423 * @param ath_device Atheros WiFi device connectedwith this HTC device.422 /** Initialize HTC device structure. 423 * 424 * @param ath_device Atheros WiFi device connected 425 * with this HTC device. 424 426 * @param htc_device HTC device structure to be initialized. 425 * 426 * @return EOK if succeed, negative error code otherwise. 427 */ 428 int htc_device_init(ath_t *ath_device, ieee80211_dev_t *ieee80211_dev, 429 htc_device_t *htc_device) 427 * 428 * @return EOK if succeed, negative error code otherwise. 429 * 430 */ 431 int htc_device_init(ath_t *ath_device, ieee80211_dev_t *ieee80211_dev, 432 htc_device_t *htc_device) 430 433 { 431 434 fibril_mutex_initialize(&htc_device->rx_lock); … … 440 443 } 441 444 442 /** 443 * HTC communication initalization. 444 * 445 /** HTC communication initalization. 446 * 445 447 * @param htc_device HTC device structure. 446 * 447 * @return EOK if succeed, negative error code otherwise. 448 * 449 * @return EOK if succeed, negative error code otherwise. 450 * 448 451 */ 449 452 int htc_init(htc_device_t *htc_device) … … 451 454 /* First check ready message in device. */ 452 455 int rc = htc_check_ready(htc_device); 453 if (rc != EOK) {456 if (rc != EOK) { 454 457 usb_log_error("Device is not in ready state after loading " 455 456 return rc; 457 } 458 459 /* 458 "firmware.\n"); 459 return rc; 460 } 461 462 /* 460 463 * HTC services initialization start. 461 *462 464 */ 463 464 465 rc = htc_connect_service(htc_device, WMI_CONTROL_SERVICE, 465 466 &htc_device->endpoints.wmi_endpoint); 466 if (rc != EOK) {467 if (rc != EOK) { 467 468 usb_log_error("Error while initalizing WMI service.\n"); 468 469 return rc; 469 470 } 470 471 471 472 rc = htc_connect_service(htc_device, WMI_BEACON_SERVICE, 472 473 &htc_device->endpoints.beacon_endpoint); 473 if (rc != EOK) {474 if (rc != EOK) { 474 475 usb_log_error("Error while initalizing beacon service.\n"); 475 476 return rc; 476 477 } 477 478 478 479 rc = htc_connect_service(htc_device, WMI_CAB_SERVICE, 479 480 &htc_device->endpoints.cab_endpoint); 480 if (rc != EOK) {481 if (rc != EOK) { 481 482 usb_log_error("Error while initalizing CAB service.\n"); 482 483 return rc; 483 484 } 484 485 485 486 rc = htc_connect_service(htc_device, WMI_UAPSD_SERVICE, 486 487 &htc_device->endpoints.uapsd_endpoint); 487 if (rc != EOK) {488 if (rc != EOK) { 488 489 usb_log_error("Error while initalizing UAPSD service.\n"); 489 490 return rc; 490 491 } 491 492 492 493 rc = htc_connect_service(htc_device, WMI_MGMT_SERVICE, 493 494 &htc_device->endpoints.mgmt_endpoint); 494 if (rc != EOK) {495 if (rc != EOK) { 495 496 usb_log_error("Error while initalizing MGMT service.\n"); 496 497 return rc; … … 499 500 rc = htc_connect_service(htc_device, WMI_DATA_BE_SERVICE, 500 501 &htc_device->endpoints.data_be_endpoint); 501 if (rc != EOK) {502 if (rc != EOK) { 502 503 usb_log_error("Error while initalizing data best effort " 503 504 "service.\n"); 504 505 return rc; 505 506 } 506 507 507 508 rc = htc_connect_service(htc_device, WMI_DATA_BK_SERVICE, 508 509 &htc_device->endpoints.data_bk_endpoint); 509 if (rc != EOK) {510 if (rc != EOK) { 510 511 usb_log_error("Error while initalizing data background " 511 512 "service.\n"); 512 513 return rc; 513 514 } 514 515 515 516 rc = htc_connect_service(htc_device, WMI_DATA_VIDEO_SERVICE, 516 517 &htc_device->endpoints.data_video_endpoint); 517 if (rc != EOK) {518 if (rc != EOK) { 518 519 usb_log_error("Error while initalizing data video service.\n"); 519 520 return rc; … … 522 523 rc = htc_connect_service(htc_device, WMI_DATA_VOICE_SERVICE, 523 524 &htc_device->endpoints.data_voice_endpoint); 524 if (rc != EOK) {525 if (rc != EOK) { 525 526 usb_log_error("Error while initalizing data voice service.\n"); 526 527 return rc; 527 528 } 528 529 /* 529 530 /* 530 531 * HTC services initialization end. 531 *532 532 */ 533 533 534 534 /* Credits initialization message. */ 535 535 rc = htc_config_credits(htc_device); 536 if (rc != EOK) {536 if (rc != EOK) { 537 537 usb_log_error("Failed to send HTC config message.\n"); 538 538 return rc; 539 539 } 540 540 541 541 /* HTC setup complete confirmation message. */ 542 542 rc = htc_complete_setup(htc_device); 543 if (rc != EOK) {543 if (rc != EOK) { 544 544 usb_log_error("Failed to send HTC complete setup message.\n"); 545 545 return rc; 546 546 } 547 547 548 548 usb_log_info("HTC services initialization finished successfully.\n"); 549 549 -
uspace/drv/nic/ar9271/htc.h
r09044cb r8a64320e 29 29 /** @file htc.h 30 30 * 31 * Definitions of the Atheros HTC (Host Target Communication) technology 31 * Definitions of the Atheros HTC (Host Target Communication) technology 32 32 * for communication between host (PC) and target (device firmware). 33 33 * … … 35 35 36 36 #ifndef ATHEROS_HTC_H 37 #define 37 #define ATHEROS_HTC_H 38 38 39 39 #include <ieee80211.h> … … 41 41 #include <sys/types.h> 42 42 #include <nic.h> 43 44 43 #include "ath.h" 45 44 46 #define HTC_RTS_THRESHOLD 230447 #define HTC_RATES_MAX_LENGTH 3048 49 /** 50 * HTC message IDs.45 #define HTC_RTS_THRESHOLD 2304 46 #define HTC_RATES_MAX_LENGTH 30 47 48 /** HTC message IDs. 49 * 51 50 */ 52 51 typedef enum { 53 52 HTC_MESSAGE_READY = 1, 54 53 HTC_MESSAGE_CONNECT_SERVICE, 55 56 57 54 HTC_MESSAGE_CONNECT_SERVICE_RESPONSE, 55 HTC_MESSAGE_SETUP_COMPLETE, 56 HTC_MESSAGE_CONFIG 58 57 } htc_message_id_t; 59 58 60 /** 61 * HTC response message status codes.59 /** HTC response message status codes. 60 * 62 61 */ 63 62 typedef enum { 64 65 66 67 68 63 HTC_SERVICE_SUCCESS = 0, 64 HTC_SERVICE_NOT_FOUND, 65 HTC_SERVICE_FAILED, 66 HTC_SERVICE_NO_RESOURCES, 67 HTC_SERVICE_NO_MORE_EP 69 68 } htc_response_status_code_t; 70 69 71 /** 72 * HTC operating mode definition.70 /** HTC operating mode definition. 71 * 73 72 */ 74 73 typedef enum { … … 79 78 } htc_operating_mode_t; 80 79 81 /** 82 * HTC data type indicator.80 /** HTC data type indicator. 81 * 83 82 */ 84 83 typedef enum { … … 89 88 } htc_data_type_t; 90 89 91 /** 92 * HTC endpoint numbers.93 */ 94 typedef struct { 95 90 /** HTC endpoint numbers. 91 * 92 */ 93 typedef struct { 94 int ctrl_endpoint; 96 95 int wmi_endpoint; 97 96 int beacon_endpoint; … … 105 104 } htc_pipes_t; 106 105 107 /** 108 * HTC device data.109 */ 110 typedef struct { 111 112 113 106 /** HTC device data. 107 * 108 */ 109 typedef struct { 110 /** WMI message sequence number */ 111 uint16_t sequence_number; 112 114 113 /** HTC endpoints numbers */ 115 114 htc_pipes_t endpoints; … … 128 127 } htc_device_t; 129 128 130 /** 131 * HTC frame header structure.132 */ 133 typedef struct { 134 uint8_t 135 uint8_t 136 uint16_t payload_length;/**< Big Endian value! */137 uint8_t 129 /** HTC frame header structure. 130 * 131 */ 132 typedef struct { 133 uint8_t endpoint_id; 134 uint8_t flags; 135 uint16_t payload_length; /**< Big Endian value! */ 136 uint8_t control_bytes[4]; 138 137 } __attribute__((packed)) htc_frame_header_t; 139 138 140 /** 141 * HTC management TX frame header structure.139 /** HTC management TX frame header structure. 140 * 142 141 */ 143 142 typedef struct { … … 152 151 } __attribute__((packed)) htc_tx_management_header_t; 153 152 154 /** 155 * HTC data TX frame header structure.153 /** HTC data TX frame header structure. 154 * 156 155 */ 157 156 typedef struct { … … 160 159 uint8_t vif_idx; 161 160 uint8_t tidno; 162 uint32_t flags; 161 uint32_t flags; /**< Big Endian value! */ 163 162 uint8_t key_type; 164 163 uint8_t keyix; … … 167 166 } __attribute__((packed)) htc_tx_data_header_t; 168 167 169 /** 170 * HTC ready message structure.171 */ 172 typedef struct { 173 uint16_t message_id;/**< Big Endian value! */174 uint16_t credits;/**< Big Endian value! */175 uint16_t credit_size;/**< Big Endian value! */176 177 168 /** HTC ready message structure. 169 * 170 */ 171 typedef struct { 172 uint16_t message_id; /**< Big Endian value! */ 173 uint16_t credits; /**< Big Endian value! */ 174 uint16_t credit_size; /**< Big Endian value! */ 175 176 uint8_t max_endpoints; 178 177 uint8_t pad; 179 178 } __attribute__((packed)) htc_ready_msg_t; 180 179 181 /** 182 * HTC service message structure.183 */ 184 typedef struct { 185 uint16_t message_id; 186 uint16_t service_id; 187 uint16_t connection_flags; 180 /** HTC service message structure. 181 * 182 */ 183 typedef struct { 184 uint16_t message_id; /**< Big Endian value! */ 185 uint16_t service_id; /**< Big Endian value! */ 186 uint16_t connection_flags; /**< Big Endian value! */ 188 187 189 188 uint8_t download_pipe_id; … … 193 192 } __attribute__((packed)) htc_service_msg_t; 194 193 195 /** 196 * HTC service response message structure.197 */ 198 typedef struct { 199 uint16_t message_id;/**< Big Endian value! */200 uint16_t service_id;/**< Big Endian value! */201 202 203 uint16_t max_message_length;/**< Big Endian value! */204 205 194 /** HTC service response message structure. 195 * 196 */ 197 typedef struct { 198 uint16_t message_id; /**< Big Endian value! */ 199 uint16_t service_id; /**< Big Endian value! */ 200 uint8_t status; 201 uint8_t endpoint_id; 202 uint16_t max_message_length; /**< Big Endian value! */ 203 uint8_t service_meta_length; 204 uint8_t pad; 206 205 } __attribute__((packed)) htc_service_resp_msg_t; 207 206 208 /** 209 * HTC credits config message structure.210 */ 211 typedef struct { 212 uint16_t message_id;/**< Big Endian value! */213 214 207 /** HTC credits config message structure. 208 * 209 */ 210 typedef struct { 211 uint16_t message_id; /**< Big Endian value! */ 212 uint8_t pipe_id; 213 uint8_t credits; 215 214 } __attribute__((packed)) htc_config_msg_t; 216 215 217 /** 218 * HTC new virtual interface message.219 */ 220 typedef struct { 221 216 /** HTC new virtual interface message. 217 * 218 */ 219 typedef struct { 220 uint8_t index; 222 221 uint8_t op_mode; 223 222 uint8_t addr[ETH_ADDR]; 224 223 uint8_t ath_cap; 225 uint16_t rts_thres; 224 uint16_t rts_thres; /**< Big Endian value! */ 226 225 uint8_t pad; 227 226 } __attribute__((packed)) htc_vif_msg_t; 228 227 229 /** 230 * HTC new station message.228 /** HTC new station message. 229 * 231 230 */ 232 231 typedef struct { 233 232 uint8_t addr[ETH_ADDR]; 234 233 uint8_t bssid[ETH_ADDR]; 235 234 uint8_t sta_index; 236 235 uint8_t vif_index; 237 236 uint8_t is_vif_sta; 238 239 uint16_t flags; 240 uint16_t ht_cap; 241 uint16_t max_ampdu; 237 238 uint16_t flags; /**< Big Endian value! */ 239 uint16_t ht_cap; /**< Big Endian value! */ 240 uint16_t max_ampdu; /**< Big Endian value! */ 242 241 243 242 uint8_t pad; 244 243 } __attribute__((packed)) htc_sta_msg_t; 245 244 246 /** 247 * HTC message to inform target about available capabilities.248 */ 249 typedef struct { 250 uint32_t ampdu_limit; 245 /** HTC message to inform target about available capabilities. 246 * 247 */ 248 typedef struct { 249 uint32_t ampdu_limit; /**< Big Endian value! */ 251 250 uint8_t ampdu_subframes; 252 251 uint8_t enable_coex; … … 258 257 uint8_t sta_index; 259 258 uint8_t is_new; 260 uint32_t cap_flags; 259 uint32_t cap_flags; /**< Big Endian value! */ 261 260 uint8_t legacy_rates_count; 262 261 uint8_t legacy_rates[HTC_RATES_MAX_LENGTH]; … … 264 263 } htc_rate_msg_t; 265 264 266 /** 267 * HTC RX status structure used in incoming HTC data messages.268 */ 269 typedef struct { 270 uint64_t timestamp; 271 uint16_t data_length; 265 /** HTC RX status structure used in incoming HTC data messages. 266 * 267 */ 268 typedef struct { 269 uint64_t timestamp; /**< Big Endian value! */ 270 uint16_t data_length; /**< Big Endian value! */ 272 271 uint8_t status; 273 272 uint8_t phy_err; … … 284 283 uint8_t flags; 285 284 uint8_t dummy; 286 uint32_t evm0; 287 uint32_t evm1; 288 uint32_t evm2; 285 uint32_t evm0; /**< Big Endian value! */ 286 uint32_t evm1; /**< Big Endian value! */ 287 uint32_t evm2; /**< Big Endian value! */ 289 288 } htc_rx_status_t; 290 289 291 /** 292 * HTC setup complete message structure293 */ 294 typedef struct { 295 uint16_t message_id;/**< Big Endian value! */290 /** HTC setup complete message structure 291 * 292 */ 293 typedef struct { 294 uint16_t message_id; /**< Big Endian value! */ 296 295 } __attribute__((packed)) htc_setup_complete_msg_t; 297 296 298 extern int htc_device_init(ath_t *ath_device, ieee80211_dev_t *ieee80211_dev, 299 htc_device_t *htc_device); 300 extern int htc_init(htc_device_t *htc_device); 301 extern int htc_init_new_vif(htc_device_t *htc_device); 302 extern int htc_read_control_message(htc_device_t *htc_device, void *buffer, 303 size_t buffer_size, size_t *transferred_size); 304 extern int htc_read_data_message(htc_device_t *htc_device, void *buffer, 305 size_t buffer_size, size_t *transferred_size); 306 extern int htc_send_control_message(htc_device_t *htc_device, void *buffer, 307 size_t buffer_size, uint8_t endpoint_id); 308 extern int htc_send_data_message(htc_device_t *htc_device, void *buffer, 309 size_t buffer_size, uint8_t endpoint_id); 310 311 #endif /* ATHEROS_HTC_H */ 312 297 extern int htc_device_init(ath_t *, ieee80211_dev_t *, htc_device_t *); 298 extern int htc_init(htc_device_t *); 299 extern int htc_init_new_vif(htc_device_t *); 300 extern int htc_read_control_message(htc_device_t *, void *, size_t, size_t *); 301 extern int htc_read_data_message(htc_device_t *, void *, size_t, size_t *); 302 extern int htc_send_control_message(htc_device_t *, void *, size_t, uint8_t); 303 extern int htc_send_data_message(htc_device_t *, void *, size_t, uint8_t); 304 305 #endif /* ATHEROS_HTC_H */ -
uspace/drv/nic/ar9271/hw.c
r09044cb r8a64320e 38 38 #include <nic.h> 39 39 #include <ieee80211.h> 40 41 40 #include "hw.h" 42 41 #include "wmi.h" 43 42 44 /** 45 * Try to wait for register value repeatedly until timeout is reached. 46 * 43 /** Try to wait for register value repeatedly until timeout is reached. 44 * 47 45 * @param ar9271 Device structure. 48 46 * @param offset Registry offset (address) to be read. 49 * @param mask Mask to apply on read result. 50 * @param value Required value we are waiting for. 51 * 52 * @return EOK if succeed, ETIMEOUT on timeout, negative error code otherwise. 47 * @param mask Mask to apply on read result. 48 * @param value Required value we are waiting for. 49 * 50 * @return EOK if succeed, ETIMEOUT on timeout, 51 * negative error code otherwise. 52 * 53 53 */ 54 54 static int hw_read_wait(ar9271_t *ar9271, uint32_t offset, uint32_t mask, 55 uint32_t value) 56 { 57 uint32_t result; 58 59 for(size_t i = 0; i < HW_WAIT_LOOPS; i++) { 55 uint32_t value) 56 { 57 for (size_t i = 0; i < HW_WAIT_LOOPS; i++) { 60 58 udelay(HW_WAIT_TIME_US); 61 59 60 uint32_t result; 62 61 wmi_reg_read(ar9271->htc_device, offset, &result); 63 if ((result & mask) == value) {62 if ((result & mask) == value) 64 63 return EOK; 65 }66 64 } 67 65 … … 74 72 { 75 73 .offset = AR9271_RTC_FORCE_WAKE, 76 .value = AR9271_RTC_FORCE_WAKE_ENABLE | 77 74 .value = AR9271_RTC_FORCE_WAKE_ENABLE | 75 AR9271_RTC_FORCE_WAKE_ON_INT 78 76 }, 79 77 { … … 88 86 89 87 wmi_reg_buffer_write(ar9271->htc_device, buffer, 90 88 sizeof(buffer) / sizeof(wmi_reg_t)); 91 89 92 90 udelay(2); … … 95 93 wmi_reg_write(ar9271->htc_device, AR9271_RTC_RESET, 1); 96 94 97 int rc = hw_read_wait(ar9271, 98 AR9271_RTC_STATUS,99 AR9271_RTC_STATUS_MASK,100 101 if (rc != EOK) {95 int rc = hw_read_wait(ar9271, 96 AR9271_RTC_STATUS, 97 AR9271_RTC_STATUS_MASK, 98 AR9271_RTC_STATUS_ON); 99 if (rc != EOK) { 102 100 usb_log_error("Failed to wait for RTC wake up register.\n"); 103 101 return rc; … … 111 109 uint32_t reset_value = AR9271_RTC_RC_MAC_WARM; 112 110 113 if (cold) {111 if (cold) 114 112 reset_value |= AR9271_RTC_RC_MAC_COLD; 115 }116 113 117 114 wmi_reg_t buffer[] = { 118 115 { 119 116 .offset = AR9271_RTC_FORCE_WAKE, 120 .value = AR9271_RTC_FORCE_WAKE_ENABLE | 121 117 .value = AR9271_RTC_FORCE_WAKE_ENABLE | 118 AR9271_RTC_FORCE_WAKE_ON_INT 122 119 }, 123 120 { … … 131 128 }; 132 129 133 wmi_reg_buffer_write(ar9271->htc_device, buffer, 134 130 wmi_reg_buffer_write(ar9271->htc_device, buffer, 131 sizeof(buffer) / sizeof(wmi_reg_t)); 135 132 136 133 udelay(100); … … 139 136 140 137 int rc = hw_read_wait(ar9271, AR9271_RTC_RC, AR9271_RTC_RC_MASK, 0); 141 if (rc != EOK) {138 if (rc != EOK) { 142 139 usb_log_error("Failed to wait for RTC RC register.\n"); 143 140 return rc; … … 145 142 146 143 wmi_reg_write(ar9271->htc_device, AR9271_RC, 0); 147 wmi_reg_clear_bit(ar9271->htc_device, AR9271_STATION_ID1, 148 144 wmi_reg_clear_bit(ar9271->htc_device, AR9271_STATION_ID1, 145 AR9271_STATION_ID1_POWER_SAVING); 149 146 150 147 return EOK; … … 156 153 nic_address_t ar9271_address; 157 154 158 for(int i = 0; i < 3; i++) { 159 wmi_reg_read(ar9271->htc_device, 160 AR9271_EEPROM_MAC_ADDR_START + i*4, 161 &value); 155 for (unsigned int i = 0; i < 3; i++) { 156 wmi_reg_read(ar9271->htc_device, 157 AR9271_EEPROM_MAC_ADDR_START + i * 4, &value); 162 158 163 159 uint16_t two_bytes = uint16_t_be2host(value); … … 169 165 170 166 int rc = nic_report_address(nic, &ar9271_address); 171 if (rc != EOK) {167 if (rc != EOK) { 172 168 usb_log_error("Failed to report NIC HW address.\n"); 173 169 return rc; … … 179 175 static int hw_gpio_set_output(ar9271_t *ar9271, uint32_t gpio, uint32_t type) 180 176 { 181 uint32_t address , gpio_shift, temp;182 183 if (gpio > 11) {177 uint32_t address; 178 179 if (gpio > 11) 184 180 address = AR9271_GPIO_OUT_MUX3; 185 } else if(gpio > 5) {181 else if (gpio > 5) 186 182 address = AR9271_GPIO_OUT_MUX2; 187 } else {183 else 188 184 address = AR9271_GPIO_OUT_MUX1; 189 }190 191 gpio_shift = (gpio % 6) * 5;192 185 186 uint32_t gpio_shift = (gpio % 6) * 5; 187 188 uint32_t temp; 193 189 wmi_reg_read(ar9271->htc_device, address, &temp); 194 195 temp = ((temp & 0x1 F0) << 1) | (temp & ~0x1F0);190 191 temp = ((temp & 0x1f0) << 1) | (temp & ~0x1f0); 196 192 temp &= ~(0x1f << gpio_shift); 197 193 temp |= (type << gpio_shift); 198 194 199 195 wmi_reg_write(ar9271->htc_device, address, temp); 200 196 … … 202 198 203 199 wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_GPIO_OE_OUT, 204 AR9271_GPIO_OE_OUT_ALWAYS << gpio_shift,205 200 AR9271_GPIO_OE_OUT_ALWAYS << gpio_shift, 201 AR9271_GPIO_OE_OUT_ALWAYS << gpio_shift); 206 202 207 203 return EOK; … … 211 207 { 212 208 wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_GPIO_IN_OUT, 213 (~value & 1) << gpio, 1 << gpio); 214 return EOK; 215 } 216 217 /** 218 * Hardware init procedure of AR9271 device. 219 * 209 (~value & 1) << gpio, 1 << gpio); 210 return EOK; 211 } 212 213 /**Hardware init procedure of AR9271 device. 214 * 220 215 * @param ar9271 Device structure. 221 * 216 * 222 217 * @return EOK if succeed, negative error code otherwise. 218 * 223 219 */ 224 220 static int hw_init_proc(ar9271_t *ar9271) 225 221 { 226 222 int rc = hw_reset_power_on(ar9271); 227 if (rc != EOK) {223 if (rc != EOK) { 228 224 usb_log_error("Failed to HW reset power on.\n"); 229 225 return rc; … … 231 227 232 228 rc = hw_set_reset(ar9271, false); 233 if (rc != EOK) {229 if (rc != EOK) { 234 230 usb_log_error("Failed to HW warm reset.\n"); 235 231 return rc; … … 237 233 238 234 rc = hw_addr_init(ar9271); 239 if (rc != EOK) {235 if (rc != EOK) { 240 236 usb_log_error("Failed to init HW addr.\n"); 241 237 return rc; … … 247 243 static int hw_init_led(ar9271_t *ar9271) 248 244 { 249 int rc = hw_gpio_set_output(ar9271, AR9271_LED_PIN, 250 251 if (rc != EOK) {245 int rc = hw_gpio_set_output(ar9271, AR9271_LED_PIN, 246 AR9271_GPIO_OUT_MUX_AS_OUT); 247 if (rc != EOK) { 252 248 usb_log_error("Failed to set led GPIO to output.\n"); 253 249 return rc; … … 255 251 256 252 rc = hw_gpio_set_value(ar9271, AR9271_LED_PIN, 0); 257 if (rc != EOK) {253 if (rc != EOK) { 258 254 usb_log_error("Failed to init bring up GPIO led.\n"); 259 255 return rc; … … 271 267 } 272 268 273 static int hw_set_operating_mode(ar9271_t *ar9271, 274 269 static int hw_set_operating_mode(ar9271_t *ar9271, 270 ieee80211_operating_mode_t op_mode) 275 271 { 276 272 uint32_t set_bit = 0x10000000; 277 273 278 274 switch(op_mode) { 279 280 281 282 283 284 285 286 287 288 289 275 case IEEE80211_OPMODE_ADHOC: 276 set_bit |= AR9271_OPMODE_ADHOC_MASK; 277 wmi_reg_set_bit(ar9271->htc_device, AR9271_CONFIG, 278 AR9271_CONFIG_ADHOC); 279 break; 280 case IEEE80211_OPMODE_MESH: 281 case IEEE80211_OPMODE_AP: 282 set_bit |= AR9271_OPMODE_STATION_AP_MASK; 283 case IEEE80211_OPMODE_STATION: 284 wmi_reg_clear_bit(ar9271->htc_device, AR9271_CONFIG, 285 AR9271_CONFIG_ADHOC); 290 286 } 291 287 292 288 wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_STATION_ID1, 293 set_bit, 294 AR9271_OPMODE_STATION_AP_MASK | AR9271_OPMODE_ADHOC_MASK); 289 set_bit, AR9271_OPMODE_STATION_AP_MASK | AR9271_OPMODE_ADHOC_MASK); 295 290 296 291 ieee80211_report_current_op_mode(ar9271->ieee80211_dev, op_mode); … … 302 297 { 303 298 int rc = hw_set_operating_mode(ar9271, IEEE80211_OPMODE_STATION); 304 if (rc != EOK) {299 if (rc != EOK) { 305 300 usb_log_error("Failed to set opmode to station.\n"); 306 301 return rc; … … 314 309 uint32_t value; 315 310 wmi_reg_read(ar9271->htc_device, AR9271_PHY_CAL, &value); 316 value &= 0xFFFFFE00; 317 value |= (((uint32_t) AR9271_CALIB_NOMINAL_VALUE_2GHZ << 1) & 0x1FF); 311 312 value &= 0xfffffe00; 313 value |= (((uint32_t) AR9271_CALIB_NOMINAL_VALUE_2GHZ << 1) & 0x1ff); 314 318 315 wmi_reg_write(ar9271->htc_device, AR9271_PHY_CAL, value); 319 316 320 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 321 322 323 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 324 325 326 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 327 328 329 int rc = hw_read_wait(ar9271, AR9271_AGC_CONTROL, 330 331 if (rc != EOK) {317 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 318 AR9271_AGC_CONTROL_NF_CALIB_EN); 319 320 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 321 AR9271_AGC_CONTROL_NF_NOT_UPDATE); 322 323 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 324 AR9271_AGC_CONTROL_NF_CALIB); 325 326 int rc = hw_read_wait(ar9271, AR9271_AGC_CONTROL, 327 AR9271_AGC_CONTROL_NF_CALIB, 0); 328 if (rc != EOK) { 332 329 usb_log_error("Failed to wait for NF calibration.\n"); 333 330 return rc; 334 331 } 335 332 336 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 337 338 339 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 340 341 342 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 343 333 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 334 AR9271_AGC_CONTROL_NF_CALIB_EN); 335 336 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 337 AR9271_AGC_CONTROL_NF_NOT_UPDATE); 338 339 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 340 AR9271_AGC_CONTROL_NF_CALIB); 344 341 345 342 return EOK; … … 349 346 { 350 347 /* Not supported channel frequency. */ 351 if (freq < IEEE80211_FIRST_FREQ || freq > IEEE80211_MAX_FREQ) {348 if ((freq < IEEE80211_FIRST_FREQ) || (freq > IEEE80211_MAX_FREQ)) 352 349 return EINVAL; 353 }354 350 355 351 /* Not supported channel frequency. */ 356 if ((freq - IEEE80211_FIRST_FREQ) % IEEE80211_CHANNEL_GAP != 0) {352 if ((freq - IEEE80211_FIRST_FREQ) % IEEE80211_CHANNEL_GAP != 0) 357 353 return EINVAL; 358 }359 354 360 355 uint32_t tx_control; 361 356 wmi_reg_read(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL, &tx_control); 362 357 wmi_reg_write(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL, 363 358 tx_control & ~AR9271_PHY_CCK_TX_CTRL_JAPAN); 364 359 365 360 /* Some magic here. */ 366 361 uint32_t synth_ctl; 367 362 wmi_reg_read(ar9271->htc_device, AR9271_PHY_SYNTH_CONTROL, &synth_ctl); 368 synth_ctl &= 0x C0000000;363 synth_ctl &= 0xc0000000; 369 364 uint32_t channel_select = (freq * 0x10000) / 15; 370 365 synth_ctl = synth_ctl | (1 << 29) | (1 << 28) | channel_select; … … 382 377 383 378 int rc = hw_read_wait(ar9271, AR9271_PHY_RFBUS_GRANT, 0x1, 0x1); 384 if (rc != EOK) {379 if (rc != EOK) { 385 380 usb_log_error("Failed to kill RF bus.\n"); 386 381 return rc; … … 388 383 389 384 rc = hw_set_freq(ar9271, freq); 390 if (rc != EOK) {385 if (rc != EOK) { 391 386 usb_log_error("Failed to HW set frequency.\n"); 392 387 return rc; … … 394 389 395 390 rc = hw_activate_phy(ar9271); 396 if (rc != EOK) {391 if (rc != EOK) { 397 392 usb_log_error("Failed to activate physical layer.\n"); 398 393 return rc; … … 403 398 404 399 rc = hw_noise_floor_calibration(ar9271); 405 if (rc != EOK) {400 if (rc != EOK) { 406 401 usb_log_error("Failed to do NF calibration.\n"); 407 402 return rc; … … 413 408 int hw_set_rx_filter(ar9271_t *ar9271, bool assoc) 414 409 { 415 uint32_t filter_bits;416 417 410 uint32_t additional_bits = 0; 418 411 419 if (assoc) {412 if (assoc) 420 413 additional_bits |= AR9271_RX_FILTER_MYBEACON; 421 } else {414 else 422 415 additional_bits |= AR9271_RX_FILTER_BEACON; 423 }424 425 filter_bits = AR9271_RX_FILTER_UNI | AR9271_RX_FILTER_MULTI |426 AR9271_RX_FILTER_BROAD |additional_bits;416 417 uint32_t filter_bits = AR9271_RX_FILTER_UNI | 418 AR9271_RX_FILTER_MULTI | AR9271_RX_FILTER_BROAD | 419 additional_bits; 427 420 428 421 wmi_reg_write(ar9271->htc_device, AR9271_RX_FILTER, filter_bits); … … 441 434 uint16_t *last_2bytes = (uint16_t *) &bssid.address[4]; 442 435 443 wmi_reg_write(ar9271->htc_device, AR9271_BSSID0, 444 445 446 wmi_reg_write(ar9271->htc_device, AR9271_BSSID1, 447 uint16_t_le2host(*last_2bytes) |448 ((ieee80211_get_aid(ieee80211_dev) & 0x3FFF) << 16));436 wmi_reg_write(ar9271->htc_device, AR9271_BSSID0, 437 uint32_t_le2host(*first_4bytes)); 438 439 wmi_reg_write(ar9271->htc_device, AR9271_BSSID1, 440 uint16_t_le2host(*last_2bytes) | 441 ((ieee80211_get_aid(ieee80211_dev) & 0x3fff) << 16)); 449 442 450 443 return EOK; … … 453 446 int hw_rx_init(ar9271_t *ar9271) 454 447 { 455 wmi_reg_write(ar9271->htc_device, AR9271_COMMAND, 456 448 wmi_reg_write(ar9271->htc_device, AR9271_COMMAND, 449 AR9271_COMMAND_RX_ENABLE); 457 450 458 451 int rc = hw_set_rx_filter(ar9271, false); 459 if (rc != EOK) {452 if (rc != EOK) { 460 453 usb_log_error("Failed to set RX filtering.\n"); 461 454 return rc; … … 473 466 static int hw_init_pll(ar9271_t *ar9271) 474 467 { 475 uint32_t pll;476 477 468 /* Some magic here (set for 2GHz channels). But VERY important :-) */ 478 pll = (0x5 << 10) | 0x2C;469 uint32_t pll = (0x5 << 10) | 0x2c; 479 470 480 471 wmi_reg_write(ar9271->htc_device, AR9271_RTC_PLL_CONTROL, pll); 481 472 482 473 wmi_reg_write(ar9271->htc_device, AR9271_RTC_SLEEP_CLOCK, 483 474 AR9271_RTC_SLEEP_CLOCK_FORCE_DERIVED); 484 475 wmi_reg_set_bit(ar9271->htc_device, AR9271_RTC_FORCE_WAKE, 485 476 AR9271_RTC_FORCE_WAKE_ENABLE); 486 477 487 478 return EOK; … … 490 481 static void hw_set_init_values(ar9271_t *ar9271) 491 482 { 492 uint32_t reg_offset, reg_value; 493 494 int size = ARRAY_SIZE(ar9271_2g_mode_array); 495 496 for(int i = 0; i < size; i++) { 483 uint32_t reg_offset; 484 uint32_t reg_value; 485 486 size_t size = ARRAY_SIZE(ar9271_2g_mode_array); 487 488 for (size_t i = 0; i < size; i++) { 497 489 reg_offset = ar9271_2g_mode_array[i][0]; 498 490 reg_value = ar9271_2g_mode_array[i][1]; … … 502 494 size = ARRAY_SIZE(ar9271_2g_tx_array); 503 495 504 for (int i = 0; i < size; i++) {496 for (size_t i = 0; i < size; i++) { 505 497 reg_offset = ar9271_2g_tx_array[i][0]; 506 498 reg_value = ar9271_2g_tx_array[i][1]; … … 510 502 size = ARRAY_SIZE(ar9271_init_array); 511 503 512 for (int i = 0; i < size; i++) {504 for (size_t i = 0; i < size; i++) { 513 505 reg_offset = ar9271_init_array[i][0]; 514 506 reg_value = ar9271_init_array[i][1]; … … 520 512 { 521 513 wmi_reg_set_bit(ar9271->htc_device, AR9271_CARRIER_LEAK_CONTROL, 522 514 AR9271_CARRIER_LEAK_CALIB); 523 515 wmi_reg_clear_bit(ar9271->htc_device, AR9271_ADC_CONTROL, 524 516 AR9271_ADC_CONTROL_OFF_PWDADC); 525 517 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 526 518 AR9271_AGC_CONTROL_TX_CALIB); 527 519 wmi_reg_set_bit(ar9271->htc_device, AR9271_PHY_TPCRG1, 528 520 AR9271_PHY_TPCRG1_PD_CALIB); 529 521 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 530 531 532 int rc = hw_read_wait(ar9271, AR9271_AGC_CONTROL, 533 534 if (rc != EOK) {522 AR9271_AGC_CONTROL_CALIB); 523 524 int rc = hw_read_wait(ar9271, AR9271_AGC_CONTROL, 525 AR9271_AGC_CONTROL_CALIB, 0); 526 if (rc != EOK) { 535 527 usb_log_error("Failed to wait on calibrate completion.\n"); 536 528 return rc; … … 538 530 539 531 wmi_reg_set_bit(ar9271->htc_device, AR9271_ADC_CONTROL, 540 532 AR9271_ADC_CONTROL_OFF_PWDADC); 541 533 wmi_reg_clear_bit(ar9271->htc_device, AR9271_CARRIER_LEAK_CONTROL, 542 534 AR9271_CARRIER_LEAK_CALIB); 543 535 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL, 544 545 546 return EOK; 547 } 548 549 int hw_reset(ar9271_t *ar9271) 536 AR9271_AGC_CONTROL_TX_CALIB); 537 538 return EOK; 539 } 540 541 int hw_reset(ar9271_t *ar9271) 550 542 { 551 543 /* Set physical layer as deactivated. */ … … 553 545 554 546 if(ar9271->starting_up) { 555 wmi_reg_write(ar9271->htc_device, 556 557 558 547 wmi_reg_write(ar9271->htc_device, 548 AR9271_RESET_POWER_DOWN_CONTROL, 549 AR9271_RADIO_RF_RESET); 550 559 551 udelay(50); 560 552 } … … 563 555 uint32_t config_reg; 564 556 wmi_reg_read(ar9271->htc_device, AR9271_COMMAND, &config_reg); 565 if (config_reg & AR9271_COMMAND_RX_ENABLE) {557 if (config_reg & AR9271_COMMAND_RX_ENABLE) 566 558 hw_set_reset(ar9271, true); 567 }568 559 569 560 int rc = hw_init_pll(ar9271); 570 if (rc != EOK) {561 if (rc != EOK) { 571 562 usb_log_error("Failed to init PLL.\n"); 572 563 return rc; … … 575 566 udelay(500); 576 567 577 wmi_reg_write(ar9271->htc_device, AR9271_CLOCK_CONTROL, 578 568 wmi_reg_write(ar9271->htc_device, AR9271_CLOCK_CONTROL, 569 AR9271_MAX_CPU_CLOCK); 579 570 580 571 udelay(100); 581 572 582 if (ar9271->starting_up) {583 wmi_reg_write(ar9271->htc_device, 584 585 586 573 if (ar9271->starting_up) { 574 wmi_reg_write(ar9271->htc_device, 575 AR9271_RESET_POWER_DOWN_CONTROL, 576 AR9271_GATE_MAC_CONTROL); 577 587 578 udelay(50); 588 579 } … … 591 582 592 583 /* Set physical layer mode. */ 593 wmi_reg_write(ar9271->htc_device, AR9271_PHY_MODE, 594 584 wmi_reg_write(ar9271->htc_device, AR9271_PHY_MODE, 585 AR9271_PHY_MODE_DYNAMIC); 595 586 596 587 /* Reset device operating mode. */ 597 588 rc = hw_reset_operating_mode(ar9271); 598 if (rc != EOK) {589 if (rc != EOK) { 599 590 usb_log_error("Failed to reset operating mode.\n"); 600 591 return rc; … … 603 594 /* Set initial channel frequency. */ 604 595 rc = hw_set_freq(ar9271, IEEE80211_FIRST_FREQ); 605 if (rc != EOK) {596 if (rc != EOK) { 606 597 usb_log_error("Failed to set channel.\n"); 607 598 return rc; … … 609 600 610 601 /* Initialize transmission queues. */ 611 for(int i = 0; i < AR9271_QUEUES_COUNT; i++) { 612 wmi_reg_write(ar9271->htc_device, 613 AR9271_QUEUE_BASE_MASK + (i << 2), 614 1 << i); 602 for (unsigned int i = 0; i < AR9271_QUEUES_COUNT; i++) { 603 wmi_reg_write(ar9271->htc_device, 604 AR9271_QUEUE_BASE_MASK + (i << 2), 1 << i); 615 605 } 616 606 617 607 /* Activate physical layer. */ 618 608 rc = hw_activate_phy(ar9271); 619 if (rc != EOK) {609 if (rc != EOK) { 620 610 usb_log_error("Failed to activate physical layer.\n"); 621 611 return rc; … … 624 614 /* Calibration. */ 625 615 rc = hw_calibration(ar9271); 626 if (rc != EOK) {616 if (rc != EOK) { 627 617 usb_log_error("Failed to calibrate device.\n"); 628 618 return rc; … … 630 620 631 621 rc = hw_noise_floor_calibration(ar9271); 632 if (rc != EOK) {622 if (rc != EOK) { 633 623 usb_log_error("Failed to calibrate noise floor.\n"); 634 624 return rc; … … 641 631 } 642 632 643 /** 644 * Initialize hardware of AR9271 device. 645 * 633 /** Initialize hardware of AR9271 device. 634 * 646 635 * @param ar9271 Device structure. 647 * 636 * 648 637 * @return EOK if succeed, negative error code otherwise. 649 638 */ … … 651 640 { 652 641 int rc = hw_init_proc(ar9271); 653 if (rc != EOK) {642 if (rc != EOK) { 654 643 usb_log_error("Failed to HW reset device.\n"); 655 644 return rc; … … 657 646 658 647 rc = hw_init_led(ar9271); 659 if (rc != EOK) {648 if (rc != EOK) { 660 649 usb_log_error("Failed to HW init led.\n"); 661 650 return rc; -
uspace/drv/nic/ar9271/hw.h
r09044cb r8a64320e 34 34 35 35 #ifndef ATHEROS_HW_H 36 #define 36 #define ATHEROS_HW_H 37 37 38 38 #include "ar9271.h" 39 39 40 #define HW_WAIT_LOOPS 100041 #define HW_WAIT_TIME_US 1040 #define HW_WAIT_LOOPS 1000 41 #define HW_WAIT_TIME_US 10 42 42 43 extern int hw_init(ar9271_t * ar9271);44 extern int hw_freq_switch(ar9271_t *, uint16_t freq);45 extern int hw_rx_init(ar9271_t * ar9271);46 extern int hw_reset(ar9271_t * ar9271);47 extern int hw_set_bssid(ar9271_t * ar9271);48 extern int hw_set_rx_filter(ar9271_t * ar9271, bool assoc);43 extern int hw_init(ar9271_t *); 44 extern int hw_freq_switch(ar9271_t *, uint16_t); 45 extern int hw_rx_init(ar9271_t *); 46 extern int hw_reset(ar9271_t *); 47 extern int hw_set_bssid(ar9271_t *); 48 extern int hw_set_rx_filter(ar9271_t *, bool); 49 49 50 #endif 50 #endif /* ATHEROS_HW_H */ -
uspace/drv/nic/ar9271/wmi.c
r09044cb r8a64320e 34 34 35 35 #include <usb/debug.h> 36 37 36 #include <malloc.h> 38 37 #include <mem.h> 39 38 #include <byteorder.h> 40 41 39 #include "wmi.h" 42 40 43 /** 44 * WMI registry read. 45 * 41 /** WMI registry read. 42 * 46 43 * @param htc_device HTC device structure. 47 44 * @param reg_offset Registry offset (address) to be read. 48 * @param res Stored result. 49 * 50 * @return EOK if succeed, negative error code otherwise. 45 * @param res Stored result. 46 * 47 * @return EOK if succeed, negative error code otherwise. 48 * 51 49 */ 52 50 int wmi_reg_read(htc_device_t *htc_device, uint32_t reg_offset, uint32_t *res) … … 54 52 uint32_t cmd_value = host2uint32_t_be(reg_offset); 55 53 56 void *resp_buffer = 57 58 59 int rc = wmi_send_command(htc_device, WMI_REG_READ, 60 61 62 if (rc != EOK) {54 void *resp_buffer = 55 malloc(htc_device->ath_device->ctrl_response_length); 56 57 int rc = wmi_send_command(htc_device, WMI_REG_READ, 58 (uint8_t *) &cmd_value, sizeof(cmd_value), resp_buffer); 59 60 if (rc != EOK) { 63 61 usb_log_error("Failed to read registry value.\n"); 64 62 return rc; 65 63 } 66 64 67 uint32_t *resp_value = (uint32_t *) ((void*) resp_buffer + 68 sizeof(htc_frame_header_t) + 69 sizeof(wmi_command_header_t)); 65 uint32_t *resp_value = (uint32_t *) ((void *) resp_buffer + 66 sizeof(htc_frame_header_t) + sizeof(wmi_command_header_t)); 70 67 71 68 *res = uint32_t_be2host(*resp_value); … … 74 71 } 75 72 76 /** 77 * WMI registry write.78 * 79 * @param htc_device HTC device structure.80 * @param reg_offset Registry offset (address) to be written.81 * @param val Value to be written82 * 83 * @return EOK if succeed, negative error code otherwise.73 /** WMI registry write. 74 * 75 * @param htc_device HTC device structure. 76 * @param reg_offset Registry offset (address) to be written. 77 * @param val Value to be written 78 * 79 * @return EOK if succeed, negative error code otherwise. 80 * 84 81 */ 85 82 int wmi_reg_write(htc_device_t *htc_device, uint32_t reg_offset, uint32_t val) 86 83 { 87 84 uint32_t cmd_buffer[] = { 88 89 85 host2uint32_t_be(reg_offset), 86 host2uint32_t_be(val) 90 87 }; 91 88 92 void *resp_buffer = 93 94 95 int rc = wmi_send_command(htc_device, WMI_REG_WRITE, 96 89 void *resp_buffer = 90 malloc(htc_device->ath_device->ctrl_response_length); 91 92 int rc = wmi_send_command(htc_device, WMI_REG_WRITE, 93 (uint8_t *) &cmd_buffer, sizeof(cmd_buffer), resp_buffer); 97 94 98 95 free(resp_buffer); 99 96 100 if (rc != EOK) {97 if (rc != EOK) { 101 98 usb_log_error("Failed to write registry value.\n"); 102 99 return rc; … … 106 103 } 107 104 108 /** 109 * WMI registry set or clear specified bits.110 * 111 * @param htc_device HTC device structure.112 * @param reg_offset Registry offset (address) to be written.113 * @param set_bit Bit to be set.114 * @param clear_bit Bit to be cleared.115 * 116 * @return EOK if succeed, negative error code otherwise.117 */ 118 int wmi_reg_set_clear_bit(htc_device_t *htc_device, uint32_t reg_offset, 119 105 /** WMI registry set or clear specified bits. 106 * 107 * @param htc_device HTC device structure. 108 * @param reg_offset Registry offset (address) to be written. 109 * @param set_bit Bit to be set. 110 * @param clear_bit Bit to be cleared. 111 * 112 * @return EOK if succeed, negative error code otherwise. 113 * 114 */ 115 int wmi_reg_set_clear_bit(htc_device_t *htc_device, uint32_t reg_offset, 116 uint32_t set_bit, uint32_t clear_bit) 120 117 { 121 118 uint32_t value; 122 119 123 120 int rc = wmi_reg_read(htc_device, reg_offset, &value); 124 if (rc != EOK) {121 if (rc != EOK) { 125 122 usb_log_error("Failed to read registry value in RMW " 126 123 "function.\n"); 127 124 return rc; 128 125 } … … 132 129 133 130 rc = wmi_reg_write(htc_device, reg_offset, value); 134 if (rc != EOK) {131 if (rc != EOK) { 135 132 usb_log_error("Failed to write registry value in RMW " 136 137 return rc; 138 } 139 140 return rc; 141 } 142 143 /** 144 * WMI registry set specified bit.145 * 146 * @param htc_device HTC device structure.147 * @param reg_offset Registry offset (address) to be written.148 * @param set_bit Bit to be set.149 * 150 * @return EOK if succeed, negative error code otherwise.151 */ 152 int wmi_reg_set_bit(htc_device_t *htc_device, uint32_t reg_offset, 153 133 "function.\n"); 134 return rc; 135 } 136 137 return rc; 138 } 139 140 /** WMI registry set specified bit. 141 * 142 * @param htc_device HTC device structure. 143 * @param reg_offset Registry offset (address) to be written. 144 * @param set_bit Bit to be set. 145 * 146 * @return EOK if succeed, negative error code otherwise. 147 * 148 */ 149 int wmi_reg_set_bit(htc_device_t *htc_device, uint32_t reg_offset, 150 uint32_t set_bit) 154 151 { 155 152 return wmi_reg_set_clear_bit(htc_device, reg_offset, set_bit, 0); 156 153 } 157 154 158 /** 159 * WMI registry clear specified bit.160 * 161 * @param htc_device HTC device structure.162 * @param reg_offset Registry offset (address) to be written.163 * @param clear_bit Bit to be cleared.164 * 165 * @return EOK if succeed, negative error code otherwise.166 */ 167 int wmi_reg_clear_bit(htc_device_t *htc_device, uint32_t reg_offset, 168 155 /** WMI registry clear specified bit. 156 * 157 * @param htc_device HTC device structure. 158 * @param reg_offset Registry offset (address) to be written. 159 * @param clear_bit Bit to be cleared. 160 * 161 * @return EOK if succeed, negative error code otherwise. 162 * 163 */ 164 int wmi_reg_clear_bit(htc_device_t *htc_device, uint32_t reg_offset, 165 uint32_t clear_bit) 169 166 { 170 167 return wmi_reg_set_clear_bit(htc_device, reg_offset, 0, clear_bit); 171 168 } 172 169 173 /** 174 * WMI multi registry write. 175 * 170 /** WMI multi registry write. 171 * 176 172 * @param htc_device HTC device structure. 177 173 * @param reg_buffer Array of registry values to be written. 178 * @param elements Number of elements in array. 179 * 180 * @return EOK if succeed, negative error code otherwise. 174 * @param elements Number of elements in array. 175 * 176 * @return EOK if succeed, negative error code otherwise. 177 * 181 178 */ 182 179 int wmi_reg_buffer_write(htc_device_t *htc_device, wmi_reg_t *reg_buffer, 183 180 size_t elements) 184 181 { 185 182 size_t buffer_size = sizeof(wmi_reg_t) * elements; 186 183 void *buffer = malloc(buffer_size); 187 void *resp_buffer = 188 184 void *resp_buffer = 185 malloc(htc_device->ath_device->ctrl_response_length); 189 186 190 187 /* Convert values to correct endianness. */ 191 for (size_t i = 0; i < elements; i++) {188 for (size_t i = 0; i < elements; i++) { 192 189 wmi_reg_t *buffer_element = ®_buffer[i]; 193 190 wmi_reg_t *buffer_it = (wmi_reg_t *) 194 ((void *) buffer + i*sizeof(wmi_reg_t));195 buffer_it->offset = 196 191 ((void *) buffer + i * sizeof(wmi_reg_t)); 192 buffer_it->offset = 193 host2uint32_t_be(buffer_element->offset); 197 194 buffer_it->value = 198 199 } 200 201 int rc = wmi_send_command(htc_device, WMI_REG_WRITE, 202 195 host2uint32_t_be(buffer_element->value); 196 } 197 198 int rc = wmi_send_command(htc_device, WMI_REG_WRITE, 199 (uint8_t *) buffer, buffer_size, resp_buffer); 203 200 204 201 free(buffer); 205 202 free(resp_buffer); 206 203 207 if (rc != EOK) {204 if (rc != EOK) { 208 205 usb_log_error("Failed to write multi registry value.\n"); 209 206 return rc; … … 213 210 } 214 211 215 /** 216 * Send WMI message to HTC device. 217 * 218 * @param htc_device HTC device structure. 219 * @param command_id Command identification. 220 * @param command_buffer Buffer with command data. 221 * @param command_length Length of command data. 212 /** Send WMI message to HTC device. 213 * 214 * @param htc_device HTC device structure. 215 * @param command_id Command identification. 216 * @param command_buffer Buffer with command data. 217 * @param command_length Length of command data. 222 218 * @param response_buffer Buffer with response data. 223 * 224 * @return EOK if succeed, negative error code otherwise. 225 */ 226 int wmi_send_command(htc_device_t *htc_device, wmi_command_t command_id, 227 uint8_t *command_buffer, uint32_t command_length, void *response_buffer) 228 { 229 size_t header_size = sizeof(wmi_command_header_t) + 230 sizeof(htc_frame_header_t); 219 * 220 * @return EOK if succeed, negative error code otherwise. 221 * 222 */ 223 int wmi_send_command(htc_device_t *htc_device, wmi_command_t command_id, 224 uint8_t *command_buffer, uint32_t command_length, void *response_buffer) 225 { 226 size_t header_size = sizeof(wmi_command_header_t) + 227 sizeof(htc_frame_header_t); 231 228 size_t buffer_size = header_size + command_length; 232 229 void *buffer = malloc(buffer_size); 233 230 234 if (command_buffer != NULL) {231 if (command_buffer != NULL) 235 232 memcpy(buffer+header_size, command_buffer, command_length); 236 }237 233 238 234 /* Set up WMI header */ 239 235 wmi_command_header_t *wmi_header = (wmi_command_header_t *) 240 ((void *) buffer + sizeof(htc_frame_header_t)); 241 wmi_header->command_id = 242 host2uint16_t_be(command_id); 243 wmi_header->sequence_number = 244 host2uint16_t_be(++htc_device->sequence_number); 236 ((void *) buffer + sizeof(htc_frame_header_t)); 237 wmi_header->command_id = host2uint16_t_be(command_id); 238 wmi_header->sequence_number = 239 host2uint16_t_be(++htc_device->sequence_number); 245 240 246 241 /* Send message. */ 247 242 int rc = htc_send_control_message(htc_device, buffer, buffer_size, 248 249 if (rc != EOK) {243 htc_device->endpoints.wmi_endpoint); 244 if (rc != EOK) { 250 245 free(buffer); 251 246 usb_log_error("Failed to send WMI message. Error: %d\n", rc); … … 256 251 257 252 bool clean_resp_buffer = false; 258 size_t response_buffer_size = 259 260 if (response_buffer == NULL) {253 size_t response_buffer_size = 254 htc_device->ath_device->ctrl_response_length; 255 if (response_buffer == NULL) { 261 256 response_buffer = malloc(response_buffer_size); 262 257 clean_resp_buffer = true; … … 267 262 uint16_t cmd_id; 268 263 do { 269 rc = htc_read_control_message(htc_device, response_buffer, 270 271 if (rc != EOK) {264 rc = htc_read_control_message(htc_device, response_buffer, 265 response_buffer_size, NULL); 266 if (rc != EOK) { 272 267 free(buffer); 273 268 usb_log_error("Failed to receive WMI message response. " … … 276 271 } 277 272 278 if (response_buffer_size < sizeof(htc_frame_header_t) +279 273 if (response_buffer_size < sizeof(htc_frame_header_t) + 274 sizeof(wmi_command_header_t)) { 280 275 free(buffer); 281 276 usb_log_error("Corrupted response received.\n"); … … 283 278 } 284 279 285 wmi_command_header_t *wmi_hdr = (wmi_command_header_t *) 286 ((void*) response_buffer + sizeof(htc_frame_header_t));280 wmi_command_header_t *wmi_hdr = (wmi_command_header_t *) 281 ((void *) response_buffer + sizeof(htc_frame_header_t)); 287 282 cmd_id = uint16_t_be2host(wmi_hdr->command_id); 288 283 } while(cmd_id & WMI_MGMT_CMD_MASK); 289 284 290 if (clean_resp_buffer) {285 if (clean_resp_buffer) 291 286 free(response_buffer); 292 } 293 294 return rc; 295 } 287 288 return rc; 289 } -
uspace/drv/nic/ar9271/wmi.h
r09044cb r8a64320e 35 35 36 36 #ifndef ATHEROS_WMI_H 37 #define 37 #define ATHEROS_WMI_H 38 38 39 39 #include "htc.h" 40 40 41 41 /* Macros for creating service identificators. */ 42 #define WMI_SERVICE_GROUP 1 43 #define CREATE_SERVICE_ID(group, i) (int) (((int) group << 8) | (int) (i)) 42 #define WMI_SERVICE_GROUP 1 44 43 45 #define WMI_MGMT_CMD_MASK 0x1000 44 #define CREATE_SERVICE_ID(group, i) \ 45 (unsigned int) (((unsigned int) group << 8) | (unsigned int) (i)) 46 46 47 /** 48 * WMI header structure. 47 #define WMI_MGMT_CMD_MASK 0x1000 48 49 /** WMI header structure. 50 * 49 51 */ 50 52 typedef struct { 51 uint16_t command_id;/**< Big Endian value! */52 uint16_t sequence_number;/**< Big Endian value! */53 uint16_t command_id; /**< Big Endian value! */ 54 uint16_t sequence_number; /**< Big Endian value! */ 53 55 } __attribute__((packed)) wmi_command_header_t; 54 56 55 /** 56 * WMI services IDs57 /** WMI services IDs 58 * 57 59 */ 58 60 typedef enum { … … 68 70 } wmi_services_t; 69 71 70 /** 71 * List of WMI commands72 /** List of WMI commands 73 * 72 74 */ 73 75 typedef enum { 74 76 WMI_ECHO = 0x0001, 75 77 WMI_ACCESS_MEMORY, 76 78 77 79 /* Commands used for HOST -> DEVICE communication */ 78 80 WMI_GET_FW_VERSION, … … 107 109 } wmi_command_t; 108 110 109 /** 110 * Structure used when sending registry buffer111 /**Structure used when sending registry buffer 112 * 111 113 */ 112 114 typedef struct { 113 uint32_t offset; 114 uint32_t value; 115 uint32_t offset; /**< Big Endian value! */ 116 uint32_t value; /**< Big Endian value! */ 115 117 } wmi_reg_t; 116 118 117 extern int wmi_reg_read(htc_device_t *htc_device, uint32_t reg_offset, 118 uint32_t *res); 119 extern int wmi_reg_write(htc_device_t *htc_device, uint32_t reg_offset, 120 uint32_t val); 121 extern int wmi_reg_set_clear_bit(htc_device_t *htc_device, 122 uint32_t reg_offset, uint32_t set_bit, uint32_t clear_bit); 123 extern int wmi_reg_set_bit(htc_device_t *htc_device, uint32_t reg_offset, 124 uint32_t set_bit); 125 extern int wmi_reg_clear_bit(htc_device_t *htc_device, uint32_t reg_offset, 126 uint32_t clear_bit); 127 extern int wmi_reg_buffer_write(htc_device_t *htc_device, 128 wmi_reg_t *reg_buffer, size_t elements); 129 extern int wmi_send_command(htc_device_t *htc_device, 130 wmi_command_t command_id, 131 uint8_t *command_buffer, uint32_t command_length, 132 void *response_buffer); 119 extern int wmi_reg_read(htc_device_t *, uint32_t, uint32_t *); 120 extern int wmi_reg_write(htc_device_t *, uint32_t, uint32_t); 121 extern int wmi_reg_set_clear_bit(htc_device_t *, uint32_t, uint32_t, uint32_t); 122 extern int wmi_reg_set_bit(htc_device_t *, uint32_t, uint32_t); 123 extern int wmi_reg_clear_bit(htc_device_t *, uint32_t, uint32_t); 124 extern int wmi_reg_buffer_write(htc_device_t *, wmi_reg_t *, size_t); 125 extern int wmi_send_command(htc_device_t *, wmi_command_t, uint8_t *, uint32_t, 126 void *); 133 127 134 #endif /* ATHEROS_WMI_H */ 135 128 #endif /* ATHEROS_WMI_H */ -
uspace/lib/c/include/ieee80211/ieee80211.h
r09044cb r8a64320e 44 44 45 45 /** Max length of scan results array. */ 46 #define IEEE80211_MAX_RESULTS_LENGTH 3246 #define IEEE80211_MAX_RESULTS_LENGTH 32 47 47 48 48 /** Max SSID length including null character. */ 49 #define IEEE80211_MAX_SSID_LENGTH 3549 #define IEEE80211_MAX_SSID_LENGTH 35 50 50 51 51 /** WiFi security authentication method indicator. */ … … 97 97 /** @} 98 98 */ 99 -
uspace/lib/crypto/aes.c
r09044cb r8a64320e 28 28 29 29 /** @file aes.c 30 * 30 * 31 31 * Implementation of AES-128 symmetric cipher cryptographic algorithm. 32 * 32 * 33 33 * Based on FIPS 197. 34 34 */ … … 37 37 #include <errno.h> 38 38 #include <mem.h> 39 40 39 #include "crypto.h" 41 40 42 41 /* Number of elements in rows/columns in AES arrays. */ 43 #define ELEMS 442 #define ELEMS 4 44 43 45 44 /* Number of elements (words) in cipher. */ 46 #define CIPHER_ELEMS 445 #define CIPHER_ELEMS 4 47 46 48 47 /* Length of AES block. */ 49 #define BLOCK_LEN 1648 #define BLOCK_LEN 16 50 49 51 50 /* Number of iterations in AES algorithm. */ 52 #define ROUNDS 10 53 54 /* 55 * Irreducible polynomial used in AES algorithm. 56 * 51 #define ROUNDS 10 52 53 /** Irreducible polynomial used in AES algorithm. 54 * 57 55 * NOTE: x^8 + x^4 + x^3 + x + 1. 58 */ 59 #define AES_IP 0x1B 60 61 /* Precomputed values for AES sub_byte transformation. */ 56 * 57 */ 58 #define AES_IP 0x1b 59 60 /** Precomputed values for AES sub_byte transformation. */ 62 61 static const uint8_t sbox[BLOCK_LEN][BLOCK_LEN] = { 63 62 { 64 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 63 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 65 64 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 66 65 }, 67 66 { 68 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 67 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 69 68 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 70 69 }, … … 74 73 }, 75 74 { 76 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 75 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 77 76 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 78 77 }, 79 78 { 80 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 79 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 81 80 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 82 81 }, 83 82 { 84 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 83 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 85 84 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf 86 85 }, 87 86 { 88 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 87 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 89 88 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 90 89 }, 91 90 { 92 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 91 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 93 92 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 94 93 }, 95 94 { 96 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 95 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 97 96 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 98 97 }, 99 98 { 100 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 99 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 101 100 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb 102 101 }, 103 102 { 104 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 103 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 105 104 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 106 105 }, 107 106 { 108 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 107 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 109 108 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 110 109 }, 111 110 { 112 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 111 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 113 112 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a 114 113 }, 115 114 { 116 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 115 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 117 116 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e 118 117 }, 119 118 { 120 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 119 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 121 120 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf 122 121 }, 123 122 { 124 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 123 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 125 124 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 126 125 } 127 126 }; 128 127 129 /* Precomputed values for AES inv_sub_byte transformation. */128 /** Precomputed values for AES inv_sub_byte transformation. */ 130 129 static uint8_t inv_sbox[BLOCK_LEN][BLOCK_LEN] = { 131 130 { 132 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 131 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 133 132 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb 134 133 }, 135 134 { 136 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 135 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 137 136 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb 138 137 }, 139 138 { 140 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 139 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 141 140 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e 142 141 }, 143 142 { 144 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 143 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 145 144 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 146 145 }, 147 146 { 148 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 147 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 149 148 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 150 149 }, 151 150 { 152 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 151 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 153 152 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 154 153 }, 155 154 { 156 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 155 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 157 156 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 158 157 }, 159 158 { 160 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 159 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 161 160 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b 162 161 }, 163 162 { 164 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 163 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 165 164 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 166 165 }, 167 166 { 168 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 167 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 169 168 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e 170 169 }, 171 170 { 172 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 171 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 173 172 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b 174 173 }, 175 174 { 176 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 175 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 177 176 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 178 177 }, 179 178 { 180 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 179 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 181 180 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f 182 181 }, 183 182 { 184 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 183 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 185 184 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef 186 185 }, 187 186 { 188 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 187 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 189 188 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 190 189 }, 191 190 { 192 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 191 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 193 192 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d 194 193 } 195 194 }; 196 195 197 /* Precomputed values of powers of 2 in GF(2^8) left shifted by 24b. */196 /** Precomputed values of powers of 2 in GF(2^8) left shifted by 24b. */ 198 197 static const uint32_t r_con_array[] = { 199 0x01000000, 0x02000000, 0x04000000, 0x08000000,198 0x01000000, 0x02000000, 0x04000000, 0x08000000, 200 199 0x10000000, 0x20000000, 0x40000000, 0x80000000, 201 0x1 B000000, 0x36000000200 0x1b000000, 0x36000000 202 201 }; 203 202 204 /** 205 * Perform substitution transformation on given byte. 206 * 203 /** Perform substitution transformation on given byte. 204 * 207 205 * @param byte Input byte. 208 * @param inv Flag indicating whether to use inverse table.209 * 206 * @param inv Flag indicating whether to use inverse table. 207 * 210 208 * @return Substituted value. 209 * 211 210 */ 212 211 static uint8_t sub_byte(uint8_t byte, bool inv) … … 215 214 uint8_t j = byte & 0xF; 216 215 217 if (!inv) {216 if (!inv) 218 217 return sbox[i][j]; 219 } else { 220 return inv_sbox[i][j]; 221 } 222 } 223 224 /** 225 * Perform substitution transformation on state table. 226 * 218 219 return inv_sbox[i][j]; 220 } 221 222 /** Perform substitution transformation on state table. 223 * 227 224 * @param state State table to be modified. 228 * @param inv Flag indicating whether to use inverse table. 225 * @param inv Flag indicating whether to use inverse table. 226 * 229 227 */ 230 228 static void sub_bytes(uint8_t state[ELEMS][ELEMS], bool inv) … … 232 230 uint8_t val; 233 231 234 for (size_t i = 0; i < ELEMS; i++) {235 for (size_t j = 0; j < ELEMS; j++) {232 for (size_t i = 0; i < ELEMS; i++) { 233 for (size_t j = 0; j < ELEMS; j++) { 236 234 val = state[i][j]; 237 235 state[i][j] = sub_byte(val, inv); … … 240 238 } 241 239 242 /** 243 * Perform shift rows transformation on state table. 244 * 240 /** Perform shift rows transformation on state table. 241 * 245 242 * @param state State table to be modified. 243 * 246 244 */ 247 245 static void shift_rows(uint8_t state[ELEMS][ELEMS]) … … 249 247 uint8_t temp[ELEMS]; 250 248 251 for (size_t i = 1; i < ELEMS; i++) {249 for (size_t i = 1; i < ELEMS; i++) { 252 250 memcpy(temp, state[i], i); 253 251 memcpy(state[i], state[i] + i, ELEMS - i); … … 256 254 } 257 255 258 /** 259 * Perform inverted shift rows transformation on state table. 260 * 256 /** Perform inverted shift rows transformation on state table. 257 * 261 258 * @param state State table to be modified. 259 * 262 260 */ 263 261 static void inv_shift_rows(uint8_t state[ELEMS][ELEMS]) … … 265 263 uint8_t temp[ELEMS]; 266 264 267 for (size_t i = 1; i < ELEMS; i++) {265 for (size_t i = 1; i < ELEMS; i++) { 268 266 memcpy(temp, state[i], ELEMS - i); 269 267 memcpy(state[i], state[i] + ELEMS - i, i); … … 272 270 } 273 271 274 /** 275 * Multiplication in GF(2^8). 276 * 272 /** Multiplication in GF(2^8). 273 * 277 274 * @param x First factor. 278 275 * @param y Second factor. 279 * 276 * 280 277 * @return Multiplication of given factors in GF(2^8). 281 */ 282 static uint8_t galois_mult(uint8_t x, uint8_t y) { 283 uint8_t result = 0; 284 uint8_t F_bitH; 285 286 for(size_t i = 0; i < 8; i++) { 287 if (y & 1) 278 * 279 */ 280 static uint8_t galois_mult(uint8_t x, uint8_t y) 281 { 282 uint8_t result = 0; 283 uint8_t f_bith; 284 285 for (size_t i = 0; i < 8; i++) { 286 if (y & 1) 288 287 result ^= x; 289 F_bitH = (x & 0x80); 290 x <<= 1; 291 if (F_bitH) 292 x ^= AES_IP; 293 y >>= 1; 294 } 295 296 return result; 297 } 298 299 /** 300 * Perform mix columns transformation on state table. 301 * 288 289 f_bith = (x & 0x80); 290 x <<= 1; 291 292 if (f_bith) 293 x ^= AES_IP; 294 295 y >>= 1; 296 } 297 298 return result; 299 } 300 301 /** Perform mix columns transformation on state table. 302 * 302 303 * @param state State table to be modified. 304 * 303 305 */ 304 306 static void mix_columns(uint8_t state[ELEMS][ELEMS]) … … 307 309 memcpy(orig_state, state, BLOCK_LEN); 308 310 309 for(size_t j = 0; j < ELEMS; j++) { 310 state[0][j] = 311 galois_mult(0x2, orig_state[0][j]) ^ 312 galois_mult(0x3, orig_state[1][j]) ^ 313 orig_state[2][j] ^ 314 orig_state[3][j]; 315 state[1][j] = 316 orig_state[0][j] ^ 317 galois_mult(0x2, orig_state[1][j]) ^ 318 galois_mult(0x3, orig_state[2][j]) ^ 319 orig_state[3][j]; 320 state[2][j] = 321 orig_state[0][j] ^ 322 orig_state[1][j] ^ 323 galois_mult(0x2, orig_state[2][j]) ^ 324 galois_mult(0x3, orig_state[3][j]); 325 state[3][j] = 326 galois_mult(0x3, orig_state[0][j]) ^ 327 orig_state[1][j] ^ 328 orig_state[2][j] ^ 329 galois_mult(0x2, orig_state[3][j]); 330 } 331 } 332 333 /** 334 * Perform inverted mix columns transformation on state table. 335 * 311 for (size_t j = 0; j < ELEMS; j++) { 312 state[0][j] = 313 galois_mult(0x2, orig_state[0][j]) ^ 314 galois_mult(0x3, orig_state[1][j]) ^ 315 orig_state[2][j] ^ 316 orig_state[3][j]; 317 state[1][j] = 318 orig_state[0][j] ^ 319 galois_mult(0x2, orig_state[1][j]) ^ 320 galois_mult(0x3, orig_state[2][j]) ^ 321 orig_state[3][j]; 322 state[2][j] = 323 orig_state[0][j] ^ 324 orig_state[1][j] ^ 325 galois_mult(0x2, orig_state[2][j]) ^ 326 galois_mult(0x3, orig_state[3][j]); 327 state[3][j] = 328 galois_mult(0x3, orig_state[0][j]) ^ 329 orig_state[1][j] ^ 330 orig_state[2][j] ^ 331 galois_mult(0x2, orig_state[3][j]); 332 } 333 } 334 335 /** Perform inverted mix columns transformation on state table. 336 * 336 337 * @param state State table to be modified. 338 * 337 339 */ 338 340 static void inv_mix_columns(uint8_t state[ELEMS][ELEMS]) … … 341 343 memcpy(orig_state, state, BLOCK_LEN); 342 344 343 for(size_t j = 0; j < ELEMS; j++) { 344 state[0][j] = 345 galois_mult(0x0E, orig_state[0][j]) ^ 346 galois_mult(0x0B, orig_state[1][j]) ^ 347 galois_mult(0x0D, orig_state[2][j]) ^ 348 galois_mult(0x09, orig_state[3][j]); 349 state[1][j] = 350 galois_mult(0x09, orig_state[0][j]) ^ 351 galois_mult(0x0E, orig_state[1][j]) ^ 352 galois_mult(0x0B, orig_state[2][j]) ^ 353 galois_mult(0x0D, orig_state[3][j]); 354 state[2][j] = 355 galois_mult(0x0D, orig_state[0][j]) ^ 356 galois_mult(0x09, orig_state[1][j]) ^ 357 galois_mult(0x0E, orig_state[2][j]) ^ 358 galois_mult(0x0B, orig_state[3][j]); 359 state[3][j] = 360 galois_mult(0x0B, orig_state[0][j]) ^ 361 galois_mult(0x0D, orig_state[1][j]) ^ 362 galois_mult(0x09, orig_state[2][j]) ^ 363 galois_mult(0x0E, orig_state[3][j]); 364 } 365 } 366 367 /** 368 * Perform round key transformation on state table. 369 * 370 * @param state State table to be modified. 345 for (size_t j = 0; j < ELEMS; j++) { 346 state[0][j] = 347 galois_mult(0x0e, orig_state[0][j]) ^ 348 galois_mult(0x0b, orig_state[1][j]) ^ 349 galois_mult(0x0d, orig_state[2][j]) ^ 350 galois_mult(0x09, orig_state[3][j]); 351 state[1][j] = 352 galois_mult(0x09, orig_state[0][j]) ^ 353 galois_mult(0x0e, orig_state[1][j]) ^ 354 galois_mult(0x0b, orig_state[2][j]) ^ 355 galois_mult(0x0d, orig_state[3][j]); 356 state[2][j] = 357 galois_mult(0x0d, orig_state[0][j]) ^ 358 galois_mult(0x09, orig_state[1][j]) ^ 359 galois_mult(0x0e, orig_state[2][j]) ^ 360 galois_mult(0x0b, orig_state[3][j]); 361 state[3][j] = 362 galois_mult(0x0b, orig_state[0][j]) ^ 363 galois_mult(0x0d, orig_state[1][j]) ^ 364 galois_mult(0x09, orig_state[2][j]) ^ 365 galois_mult(0x0e, orig_state[3][j]); 366 } 367 } 368 369 /** Perform round key transformation on state table. 370 * 371 * @param state State table to be modified. 371 372 * @param round_key Round key to be applied on state table. 373 * 372 374 */ 373 375 static void add_round_key(uint8_t state[ELEMS][ELEMS], uint32_t *round_key) … … 375 377 uint8_t byte_round; 376 378 uint8_t shift; 377 uint32_t mask = 0x FF;378 379 for (size_t j = 0; j < ELEMS; j++) {380 for (size_t i = 0; i < ELEMS; i++) {381 shift = 24 - 8 *i;379 uint32_t mask = 0xff; 380 381 for (size_t j = 0; j < ELEMS; j++) { 382 for (size_t i = 0; i < ELEMS; i++) { 383 shift = 24 - 8 * i; 382 384 byte_round = (round_key[j] & (mask << shift)) >> shift; 383 385 state[i][j] = state[i][j] ^ byte_round; … … 386 388 } 387 389 388 /** 389 * Perform substitution transformation on given word. 390 * 390 /** Perform substitution transformation on given word. 391 * 391 392 * @param byte Input word. 392 * 393 * 393 394 * @return Substituted word. 395 * 394 396 */ 395 397 static uint32_t sub_word(uint32_t word) … … 398 400 uint8_t *start = (uint8_t *) &temp; 399 401 400 for(size_t i = 0; i < 4; i++) { 401 *(start+i) = sub_byte(*(start+i), false); 402 } 402 for (size_t i = 0; i < 4; i++) 403 *(start + i) = sub_byte(*(start + i), false); 403 404 404 405 return temp; 405 406 } 406 407 407 /** 408 * Perform left rotation by one byte on given word. 409 * 408 /** Perform left rotation by one byte on given word. 409 * 410 410 * @param byte Input word. 411 * 411 * 412 412 * @return Rotated word. 413 * 413 414 */ 414 415 static uint32_t rot_word(uint32_t word) … … 417 418 } 418 419 419 /** 420 * Key expansion procedure for AES algorithm. 421 * 422 * @param key Input key. 420 /** Key expansion procedure for AES algorithm. 421 * 422 * @param key Input key. 423 423 * @param key_exp Result key expansion. 424 * 424 425 */ 425 426 static void key_expansion(uint8_t *key, uint32_t *key_exp) … … 427 428 uint32_t temp; 428 429 429 for (size_t i = 0; i < CIPHER_ELEMS; i++) {430 key_exp[i] = 431 (key[4*i] << 24) +432 (key[4*i+1] << 16) +433 (key[4*i+2] << 8) +434 (key[4*i+3]);435 } 436 437 for (size_t i = CIPHER_ELEMS; i < ELEMS * (ROUNDS + 1); i++) {438 temp = key_exp[i -1];439 440 if ((i % CIPHER_ELEMS) == 0) {441 temp = sub_word(rot_word(temp)) ^ 442 r_con_array[i/CIPHER_ELEMS - 1];430 for (size_t i = 0; i < CIPHER_ELEMS; i++) { 431 key_exp[i] = 432 (key[4 * i] << 24) + 433 (key[4 * i + 1] << 16) + 434 (key[4 * i + 2] << 8) + 435 (key[4 * i + 3]); 436 } 437 438 for (size_t i = CIPHER_ELEMS; i < ELEMS * (ROUNDS + 1); i++) { 439 temp = key_exp[i - 1]; 440 441 if ((i % CIPHER_ELEMS) == 0) { 442 temp = sub_word(rot_word(temp)) ^ 443 r_con_array[i / CIPHER_ELEMS - 1]; 443 444 } 444 445 … … 447 448 } 448 449 449 /** 450 * AES-128 encryption algorithm. 451 * 452 * @param key Input key. 453 * @param input Input data sequence to be encrypted. 450 /** AES-128 encryption algorithm. 451 * 452 * @param key Input key. 453 * @param input Input data sequence to be encrypted. 454 454 * @param output Encrypted data sequence. 455 * 456 * @return EINVAL when input or key not specified, ENOMEM when pointer for 457 * output is not allocated, otherwise EOK. 455 * 456 * @return EINVAL when input or key not specified, 457 * ENOMEM when pointer for output is not allocated, 458 * otherwise EOK. 459 * 458 460 */ 459 461 int aes_encrypt(uint8_t *key, uint8_t *input, uint8_t *output) 460 462 { 461 if (!key || !input)463 if ((!key) || (!input)) 462 464 return EINVAL; 463 465 464 if (!output)466 if (!output) 465 467 return ENOMEM; 466 468 467 469 /* Create key expansion. */ 468 uint32_t key_exp[ELEMS * (ROUNDS +1)];470 uint32_t key_exp[ELEMS * (ROUNDS + 1)]; 469 471 key_expansion(key, key_exp); 470 472 471 473 /* Copy input into state array. */ 472 474 uint8_t state[ELEMS][ELEMS]; 473 for(size_t i = 0; i < ELEMS; i++) { 474 for(size_t j = 0; j < ELEMS; j++) { 475 state[i][j] = input[i + ELEMS*j]; 476 } 475 for (size_t i = 0; i < ELEMS; i++) { 476 for (size_t j = 0; j < ELEMS; j++) 477 state[i][j] = input[i + ELEMS * j]; 477 478 } 478 479 … … 480 481 add_round_key(state, key_exp); 481 482 482 for (size_t k = 1; k <= ROUNDS; k++) {483 for (size_t k = 1; k <= ROUNDS; k++) { 483 484 sub_bytes(state, false); 484 485 shift_rows(state); 485 if(k < ROUNDS) 486 487 if (k < ROUNDS) 486 488 mix_columns(state); 487 add_round_key(state, key_exp + k*ELEMS); 489 490 add_round_key(state, key_exp + k * ELEMS); 488 491 } 489 492 490 493 /* Copy state array into output. */ 491 for(size_t i = 0; i < ELEMS; i++) { 492 for(size_t j = 0; j < ELEMS; j++) { 493 output[i + j*ELEMS] = state[i][j]; 494 } 494 for (size_t i = 0; i < ELEMS; i++) { 495 for (size_t j = 0; j < ELEMS; j++) 496 output[i + j * ELEMS] = state[i][j]; 495 497 } 496 498 … … 498 500 } 499 501 500 /** 501 * AES-128 decryption algorithm. 502 * 503 * @param key Input key. 504 * @param input Input data sequence to be decrypted. 502 /** AES-128 decryption algorithm. 503 * 504 * @param key Input key. 505 * @param input Input data sequence to be decrypted. 505 506 * @param output Decrypted data sequence. 506 * 507 * @return EINVAL when input or key not specified, ENOMEM when pointer for 508 * output is not allocated, otherwise EOK. 507 * 508 * @return EINVAL when input or key not specified, 509 * ENOMEM when pointer for output is not allocated, 510 * otherwise EOK. 511 * 509 512 */ 510 513 int aes_decrypt(uint8_t *key, uint8_t *input, uint8_t *output) 511 514 { 512 if (!key || !input)515 if ((!key) || (!input)) 513 516 return EINVAL; 514 517 515 if (!output)518 if (!output) 516 519 return ENOMEM; 517 520 518 521 /* Create key expansion. */ 519 uint32_t key_exp[ELEMS * (ROUNDS +1)];522 uint32_t key_exp[ELEMS * (ROUNDS + 1)]; 520 523 key_expansion(key, key_exp); 521 524 522 525 /* Copy input into state array. */ 523 526 uint8_t state[ELEMS][ELEMS]; 524 for(size_t i = 0; i < ELEMS; i++) { 525 for(size_t j = 0; j < ELEMS; j++) { 526 state[i][j] = input[i + ELEMS*j]; 527 } 527 for (size_t i = 0; i < ELEMS; i++) { 528 for (size_t j = 0; j < ELEMS; j++) 529 state[i][j] = input[i + ELEMS * j]; 528 530 } 529 531 530 532 /* Processing loop. */ 531 add_round_key(state, key_exp + ROUNDS *ELEMS);532 533 for (int k = ROUNDS - 1; k >= 0; k--) {533 add_round_key(state, key_exp + ROUNDS * ELEMS); 534 535 for (int k = ROUNDS - 1; k >= 0; k--) { 534 536 inv_shift_rows(state); 535 537 sub_bytes(state, true); 536 add_round_key(state, key_exp + k*ELEMS); 537 if(k > 0) 538 add_round_key(state, key_exp + k * ELEMS); 539 540 if (k > 0) 538 541 inv_mix_columns(state); 539 542 } 540 543 541 544 /* Copy state array into output. */ 542 for(size_t i = 0; i < ELEMS; i++) { 543 for(size_t j = 0; j < ELEMS; j++) { 544 output[i + j*ELEMS] = state[i][j]; 545 } 545 for (size_t i = 0; i < ELEMS; i++) { 546 for (size_t j = 0; j < ELEMS; j++) 547 output[i + j * ELEMS] = state[i][j]; 546 548 } 547 549 -
uspace/lib/crypto/crypto.c
r09044cb r8a64320e 28 28 29 29 /** @file crypto.c 30 * 30 * 31 31 * Cryptographic functions library. 32 32 */ … … 37 37 #include <errno.h> 38 38 #include <byteorder.h> 39 40 39 #include "crypto.h" 41 40 42 /* Hash function procedure definition. */ 43 typedef void (*HASH_FUNC)(uint32_t*, uint32_t*); 44 45 /* Length of HMAC block. */ 46 #define HMAC_BLOCK_LENGTH 64 47 48 /* Ceiling for UINT32. */ 49 #define ceil_uint32(val) (((val) - (uint32_t)(val)) > 0 ? \ 50 (uint32_t)((val) + 1) : (uint32_t)(val)) 51 52 /* Floor for UINT32. */ 53 #define floor_uint32(val) (((val) - (uint32_t)(val)) < 0 ? \ 54 (uint32_t)((val) - 1) : (uint32_t)(val)) 55 56 /* Pick value at specified index from array or zero if out of bounds. */ 57 #define get_at(input, size, i) (i < size ? input[i] : 0) 58 59 /* Init values used in SHA1 and MD5 functions. */ 41 /** Hash function procedure definition. */ 42 typedef void (*hash_fnc_t)(uint32_t *, uint32_t *); 43 44 /** Length of HMAC block. */ 45 #define HMAC_BLOCK_LENGTH 64 46 47 /** Ceiling for uint32_t. */ 48 #define ceil_uint32(val) \ 49 (((val) - (uint32_t) (val)) > 0 ? \ 50 (uint32_t) ((val) + 1) : (uint32_t) (val)) 51 52 /** Floor for uint32_t. */ 53 #define floor_uint32(val) \ 54 (((val) - (uint32_t) (val)) < 0 ? \ 55 (uint32_t) ((val) - 1) : (uint32_t) (val)) 56 57 /** Pick value at specified index from array or zero if out of bounds. */ 58 #define get_at(input, size, i) \ 59 ((i) < (size) ? (input[i]) : 0) 60 61 /** Init values used in SHA1 and MD5 functions. */ 60 62 static const uint32_t hash_init[] = { 61 0x67452301, 0x EFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F063 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 62 64 }; 63 65 64 /* Shift amount array for MD5 algorithm. */66 /** Shift amount array for MD5 algorithm. */ 65 67 static const uint32_t md5_shift[] = { 66 68 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, … … 70 72 }; 71 73 72 /* Substitution box for MD5 algorithm. */74 /** Substitution box for MD5 algorithm. */ 73 75 static const uint32_t md5_sbox[] = { 74 76 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, … … 90 92 }; 91 93 92 /** 93 * Working procedure of MD5 cryptographic hash function. 94 * 95 * @param h Working array with interim hash parts values. 94 /** Working procedure of MD5 cryptographic hash function. 95 * 96 * @param h Working array with interim hash parts values. 96 97 * @param sched_arr Input array with scheduled values from input string. 98 * 97 99 */ 98 100 static void md5_proc(uint32_t *h, uint32_t *sched_arr) 99 101 { 100 102 uint32_t f, g, temp; 101 uint32_t w[HASH_MD5 /4];102 103 memcpy(w, h, (HASH_MD5 /4) * sizeof(uint32_t));104 105 for (size_t k = 0; k < 64; k++) {106 if (k < 16) {103 uint32_t w[HASH_MD5 / 4]; 104 105 memcpy(w, h, (HASH_MD5 / 4) * sizeof(uint32_t)); 106 107 for (size_t k = 0; k < 64; k++) { 108 if (k < 16) { 107 109 f = (w[1] & w[2]) | (~w[1] & w[3]); 108 110 g = k; 109 } else if (k >= 16 && k < 32) {111 } else if ((k >= 16) && (k < 32)) { 110 112 f = (w[1] & w[3]) | (w[2] & ~w[3]); 111 g = (5 *k + 1) % 16;112 } else if (k >= 32 && k < 48) {113 g = (5 * k + 1) % 16; 114 } else if ((k >= 32) && (k < 48)) { 113 115 f = w[1] ^ w[2] ^ w[3]; 114 g = (3 *k + 5) % 16;116 g = (3 * k + 5) % 16; 115 117 } else { 116 118 f = w[2] ^ (w[1] | ~w[3]); 117 g = 7 *k % 16;119 g = 7 * k % 16; 118 120 } 121 119 122 temp = w[3]; 120 123 w[3] = w[2]; 121 124 w[2] = w[1]; 122 w[1] += rotl_uint32(w[0] + f + md5_sbox[k] + 123 uint32_t_byteorder_swap(sched_arr[g]),124 125 w[1] += rotl_uint32(w[0] + f + md5_sbox[k] + 126 uint32_t_byteorder_swap(sched_arr[g]), 127 md5_shift[k]); 125 128 w[0] = temp; 126 129 } 127 130 128 for (uint8_t k = 0; k < HASH_MD5/4; k++)131 for (uint8_t k = 0; k < HASH_MD5 / 4; k++) 129 132 h[k] += w[k]; 130 133 } 131 134 132 /** 133 * Working procedure of SHA-1 cryptographic hash function. 134 * 135 * @param h Working array with interim hash parts values. 135 /** Working procedure of SHA-1 cryptographic hash function. 136 * 137 * @param h Working array with interim hash parts values. 136 138 * @param sched_arr Input array with scheduled values from input string. 139 * 137 140 */ 138 141 static void sha1_proc(uint32_t *h, uint32_t *sched_arr) 139 142 { 140 143 uint32_t f, cf, temp; 141 uint32_t w[HASH_SHA1 /4];142 143 for (size_t k = 16; k < 80; k++) {144 uint32_t w[HASH_SHA1 / 4]; 145 146 for (size_t k = 16; k < 80; k++) { 144 147 sched_arr[k] = rotl_uint32( 145 146 147 148 sched_arr[k-16],149 150 } 151 152 memcpy(w, h, (HASH_SHA1 /4) * sizeof(uint32_t));153 154 for (size_t k = 0; k < 80; k++) {155 if (k < 20) {148 sched_arr[k-3] ^ 149 sched_arr[k-8] ^ 150 sched_arr[k-14] ^ 151 sched_arr[k-16], 152 1); 153 } 154 155 memcpy(w, h, (HASH_SHA1 / 4) * sizeof(uint32_t)); 156 157 for (size_t k = 0; k < 80; k++) { 158 if (k < 20) { 156 159 f = (w[1] & w[2]) | (~w[1] & w[3]); 157 160 cf = 0x5A827999; 158 } else if (k >= 20 && k < 40) {161 } else if ((k >= 20) && (k < 40)) { 159 162 f = w[1] ^ w[2] ^ w[3]; 160 cf = 0x6 ED9EBA1;161 } else if (k >= 40 && k < 60) {163 cf = 0x6ed9eba1; 164 } else if ((k >= 40) && (k < 60)) { 162 165 f = (w[1] & w[2]) | (w[1] & w[3]) | (w[2] & w[3]); 163 cf = 0x8 F1BBCDC;166 cf = 0x8f1bbcdc; 164 167 } else { 165 168 f = w[1] ^ w[2] ^ w[3]; 166 cf = 0x CA62C1D6;169 cf = 0xca62c1d6; 167 170 } 168 171 169 172 temp = rotl_uint32(w[0], 5) + f + w[4] + cf + sched_arr[k]; 170 173 171 174 w[4] = w[3]; 172 175 w[3] = w[2]; … … 175 178 w[0] = temp; 176 179 } 177 178 for (uint8_t k = 0; k < HASH_SHA1/4; k++)180 181 for (uint8_t k = 0; k < HASH_SHA1 / 4; k++) 179 182 h[k] += w[k]; 180 183 } 181 184 182 /** 183 * Create hash based on selected algorithm. 184 * 185 * @param input Input message byte sequence. 185 /** Create hash based on selected algorithm. 186 * 187 * @param input Input message byte sequence. 186 188 * @param input_size Size of message sequence. 187 * @param output Result hash byte sequence. 188 * @param hash_sel Hash function selector. 189 * 190 * @return EINVAL when input not specified, ENOMEM when pointer for 191 * output hash result is not allocated, otherwise EOK. 189 * @param output Result hash byte sequence. 190 * @param hash_sel Hash function selector. 191 * 192 * @return EINVAL when input not specified, 193 * ENOMEM when pointer for output hash result 194 * is not allocated, otherwise EOK. 195 * 192 196 */ 193 197 int create_hash(uint8_t *input, size_t input_size, uint8_t *output, 194 195 { 196 if (!input)198 hash_func_t hash_sel) 199 { 200 if (!input) 197 201 return EINVAL; 198 202 199 if (!output)203 if (!output) 200 204 return ENOMEM; 201 205 202 HASH_FUNChash_func = (hash_sel == HASH_MD5) ? md5_proc : sha1_proc;206 hash_fnc_t hash_func = (hash_sel == HASH_MD5) ? md5_proc : sha1_proc; 203 207 204 208 /* Prepare scheduled input. */ … … 207 211 work_input[input_size] = 0x80; 208 212 209 size_t blocks = ceil_uint32((((double)input_size + 1) / 4 + 2) / 16); 213 // FIXME: double? 214 size_t blocks = ceil_uint32((((double) input_size + 1) / 4 + 2) / 16); 210 215 uint32_t work_arr[blocks * 16]; 211 for (size_t i = 0; i < blocks; i++) {212 for (size_t j = 0; j < 16; j++) {213 work_arr[i*16 + j] = 214 (get_at(work_input, input_size+1, i*64+j*4) << 24) |215 (get_at(work_input, input_size+1, i*64+j*4+1) << 16) |216 (get_at(work_input, input_size+1, i*64+j*4+2) << 8) |217 get_at(work_input, input_size+1, i*64+j*4+3);216 for (size_t i = 0; i < blocks; i++) { 217 for (size_t j = 0; j < 16; j++) { 218 work_arr[i*16 + j] = 219 (get_at(work_input, input_size + 1, i * 64 + j * 4) << 24) | 220 (get_at(work_input, input_size + 1, i * 64 + j * 4 + 1) << 16) | 221 (get_at(work_input, input_size + 1, i * 64 + j * 4 + 2) << 8) | 222 get_at(work_input, input_size + 1, i * 64 + j * 4 + 3); 218 223 } 219 224 } 220 225 221 uint64_t bits_size = (uint64_t) (input_size * 8);222 if (hash_sel == HASH_MD5)226 uint64_t bits_size = (uint64_t) (input_size * 8); 227 if (hash_sel == HASH_MD5) 223 228 bits_size = uint64_t_byteorder_swap(bits_size); 224 229 225 230 work_arr[(blocks - 1) * 16 + 14] = bits_size >> 32; 226 work_arr[(blocks - 1) * 16 + 15] = bits_size & 0x FFFFFFFF;231 work_arr[(blocks - 1) * 16 + 15] = bits_size & 0xffffffff; 227 232 228 233 /* Hash computation. */ 229 uint32_t h[hash_sel /4];230 memcpy(h, hash_init, (hash_sel /4) * sizeof(uint32_t));234 uint32_t h[hash_sel / 4]; 235 memcpy(h, hash_init, (hash_sel / 4) * sizeof(uint32_t)); 231 236 uint32_t sched_arr[80]; 232 for(size_t i = 0; i < blocks; i++) { 233 for(size_t k = 0; k < 16; k++) { 234 sched_arr[k] = work_arr[i*16 + k]; 235 } 237 for (size_t i = 0; i < blocks; i++) { 238 for (size_t k = 0; k < 16; k++) 239 sched_arr[k] = work_arr[i * 16 + k]; 236 240 237 241 hash_func(h, sched_arr); … … 239 243 240 244 /* Copy hash parts into final result. */ 241 for (size_t i = 0; i < hash_sel/4; i++) {242 if (hash_sel == HASH_SHA1)245 for (size_t i = 0; i < hash_sel / 4; i++) { 246 if (hash_sel == HASH_SHA1) 243 247 h[i] = uint32_t_byteorder_swap(h[i]); 244 memcpy(output + i*sizeof(uint32_t), &h[i], sizeof(uint32_t)); 248 249 memcpy(output + i * sizeof(uint32_t), &h[i], sizeof(uint32_t)); 245 250 } 246 251 … … 248 253 } 249 254 250 /** 251 * Hash-based message authentication code. 252 * 253 * @param key Cryptographic key sequence. 255 /** Hash-based message authentication code. 256 * 257 * @param key Cryptographic key sequence. 254 258 * @param key_size Size of key sequence. 255 * @param msg Message sequence.259 * @param msg Message sequence. 256 260 * @param msg_size Size of message sequence. 257 * @param hash Output parameter for result hash.261 * @param hash Output parameter for result hash. 258 262 * @param hash_sel Hash function selector. 259 * 260 * @return EINVAL when key or message not specified, ENOMEM when pointer for 261 * output hash result is not allocated, otherwise EOK. 263 * 264 * @return EINVAL when key or message not specified, 265 * ENOMEM when pointer for output hash result 266 * is not allocated, otherwise EOK. 267 * 262 268 */ 263 269 int hmac(uint8_t *key, size_t key_size, uint8_t *msg, size_t msg_size, 264 265 { 266 if (!key || !msg)270 uint8_t *hash, hash_func_t hash_sel) 271 { 272 if ((!key) || (!msg)) 267 273 return EINVAL; 268 274 269 if (!hash)275 if (!hash) 270 276 return ENOMEM; 271 277 … … 276 282 memset(work_key, 0, HMAC_BLOCK_LENGTH); 277 283 278 if(key_size > HMAC_BLOCK_LENGTH) {284 if(key_size > HMAC_BLOCK_LENGTH) 279 285 create_hash(key, key_size, work_key, hash_sel); 280 } else {286 else 281 287 memcpy(work_key, key, key_size); 282 } 283 284 for(size_t i = 0; i < HMAC_BLOCK_LENGTH; i++) { 285 o_key_pad[i] = work_key[i] ^ 0x5C; 288 289 for (size_t i = 0; i < HMAC_BLOCK_LENGTH; i++) { 290 o_key_pad[i] = work_key[i] ^ 0x5c; 286 291 i_key_pad[i] = work_key[i] ^ 0x36; 287 292 } … … 291 296 memcpy(temp_work + HMAC_BLOCK_LENGTH, msg, msg_size); 292 297 293 create_hash(temp_work, HMAC_BLOCK_LENGTH + msg_size, temp_hash, 294 298 create_hash(temp_work, HMAC_BLOCK_LENGTH + msg_size, temp_hash, 299 hash_sel); 295 300 296 301 memcpy(temp_work, o_key_pad, HMAC_BLOCK_LENGTH); … … 302 307 } 303 308 304 /** 305 * Password-Based Key Derivation Function 2 as defined in RFC 2898,306 * using HMAC-SHA1 with 4096 iterations and 32 bytes key result used307 * for WPA/WPA2.308 * 309 * @param pass Password sequence.309 /** Password-Based Key Derivation Function 2. 310 * 311 * As defined in RFC 2898, using HMAC-SHA1 with 4096 iterations 312 * and 32 bytes key result used for WPA/WPA2. 313 * 314 * @param pass Password sequence. 310 315 * @param pass_size Password sequence length. 311 * @param salt Salt sequence to be used with password.316 * @param salt Salt sequence to be used with password. 312 317 * @param salt_size Salt sequence length. 313 * @param hash Output parameter for result hash (32 byte value). 314 * 315 * @return EINVAL when pass or salt not specified, ENOMEM when pointer for 316 * output hash result is not allocated, otherwise EOK. 317 */ 318 int pbkdf2(uint8_t *pass, size_t pass_size, uint8_t *salt, size_t salt_size, 319 uint8_t *hash) 320 { 321 if(!pass || !salt) 318 * @param hash Output parameter for result hash (32 byte value). 319 * 320 * @return EINVAL when pass or salt not specified, 321 * ENOMEM when pointer for output hash result 322 * is not allocated, otherwise EOK. 323 * 324 */ 325 int pbkdf2(uint8_t *pass, size_t pass_size, uint8_t *salt, size_t salt_size, 326 uint8_t *hash) 327 { 328 if ((!pass) || (!salt)) 322 329 return EINVAL; 323 330 324 if (!hash)331 if (!hash) 325 332 return ENOMEM; 326 333 … … 330 337 uint8_t temp_hmac[HASH_SHA1]; 331 338 uint8_t xor_hmac[HASH_SHA1]; 332 uint8_t temp_hash[HASH_SHA1*2]; 333 334 for(size_t i = 0; i < 2; i++) { 335 uint32_t be_i = host2uint32_t_be(i+1); 339 uint8_t temp_hash[HASH_SHA1 * 2]; 340 341 for (size_t i = 0; i < 2; i++) { 342 uint32_t be_i = host2uint32_t_be(i + 1); 343 336 344 memcpy(work_salt + salt_size, &be_i, 4); 337 345 hmac(pass, pass_size, work_salt, salt_size + 4, 338 346 work_hmac, HASH_SHA1); 339 347 memcpy(xor_hmac, work_hmac, HASH_SHA1); 340 348 341 for (size_t k = 1; k < 4096; k++) {349 for (size_t k = 1; k < 4096; k++) { 342 350 memcpy(temp_hmac, work_hmac, HASH_SHA1); 343 hmac(pass, pass_size, temp_hmac, HASH_SHA1, 344 work_hmac, HASH_SHA1); 345 for(size_t t = 0; t < HASH_SHA1; t++) { 351 hmac(pass, pass_size, temp_hmac, HASH_SHA1, 352 work_hmac, HASH_SHA1); 353 354 for (size_t t = 0; t < HASH_SHA1; t++) 346 355 xor_hmac[t] ^= work_hmac[t]; 347 }348 356 } 349 memcpy(temp_hash + i*HASH_SHA1, xor_hmac, HASH_SHA1); 357 358 memcpy(temp_hash + i * HASH_SHA1, xor_hmac, HASH_SHA1); 350 359 } 351 360 -
uspace/lib/crypto/crypto.h
r09044cb r8a64320e 32 32 #include <sys/types.h> 33 33 34 #define AES_CIPHER_LENGTH 1635 #define PBKDF2_KEY_LENGTH 3234 #define AES_CIPHER_LENGTH 16 35 #define PBKDF2_KEY_LENGTH 32 36 36 37 /* Left rotation for UINT32. */ 38 #define rotl_uint32(val, shift) (((val) << shift) | ((val) >> (32 - shift))) 37 /* Left rotation for uint32_t. */ 38 #define rotl_uint32(val, shift) \ 39 (((val) << shift) | ((val) >> (32 - shift))) 39 40 40 /* Right rotation for UINT32. */ 41 #define rotr_uint32(val, shift) (((val) >> shift) | ((val) << (32 - shift))) 41 /* Right rotation for uint32_t. */ 42 #define rotr_uint32(val, shift) \ 43 (((val) >> shift) | ((val) << (32 - shift))) 42 44 43 45 /** Hash function selector and also result hash length indicator. */ 44 46 typedef enum { 45 HASH_MD5 = 46 HASH_SHA1 = 47 HASH_MD5 = 16, 48 HASH_SHA1 = 20 47 49 } hash_func_t; 48 50 49 extern int rc4(uint8_t *key, size_t key_size, uint8_t *input, size_t input_size, 50 size_t skip, uint8_t *output); 51 extern int aes_encrypt(uint8_t *key, uint8_t *input, uint8_t *output); 52 extern int aes_decrypt(uint8_t *key, uint8_t *input, uint8_t *output); 53 extern int create_hash(uint8_t *input, size_t input_size, uint8_t *output, 54 hash_func_t hash_sel); 55 extern int hmac(uint8_t *key, size_t key_size, uint8_t *msg, size_t msg_size, 56 uint8_t *hash, hash_func_t hash_sel); 57 extern int pbkdf2(uint8_t *pass, size_t pass_size, uint8_t *salt, 58 size_t salt_size, uint8_t *hash); 51 extern int rc4(uint8_t *, size_t, uint8_t *, size_t, size_t, uint8_t *); 52 extern int aes_encrypt(uint8_t *, uint8_t *, uint8_t *); 53 extern int aes_decrypt(uint8_t *, uint8_t *, uint8_t *); 54 extern int create_hash(uint8_t *, size_t, uint8_t *, hash_func_t); 55 extern int hmac(uint8_t *, size_t, uint8_t *, size_t, uint8_t *, hash_func_t); 56 extern int pbkdf2(uint8_t *, size_t, uint8_t *, size_t, uint8_t *); 59 57 60 58 #endif -
uspace/lib/crypto/rc4.c
r09044cb r8a64320e 28 28 29 29 /** @file rc4.c 30 * 30 * 31 31 * Implementation of ARC4 symmetric cipher cryptographic algorithm.