source: mainline/uspace/drv/nic/ar9271/hw.c

Last change on this file was 3bacee1, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Make ccheck-fix again and commit more good files.

  • Property mode set to 100644
File size: 16.2 KB
Line 
1/*
2 * Copyright (c) 2015 Jan Kolarik
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @file hw.c
30 *
31 * AR9271 hardware related functions implementation.
32 *
33 */
34
35#include <macros.h>
36#include <usb/debug.h>
37#include <errno.h>
38#include <nic.h>
39#include <ieee80211.h>
40#include "hw.h"
41#include "wmi.h"
42
43/** Try to wait for register value repeatedly until timeout is reached.
44 *
45 * @param ar9271 Device structure.
46 * @param offset Registry offset (address) to be read.
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 * error code otherwise.
52 *
53 */
54static errno_t hw_read_wait(ar9271_t *ar9271, uint32_t offset, uint32_t mask,
55 uint32_t value)
56{
57 for (size_t i = 0; i < HW_WAIT_LOOPS; i++) {
58 udelay(HW_WAIT_TIME_US);
59
60 uint32_t result;
61 wmi_reg_read(ar9271->htc_device, offset, &result);
62 if ((result & mask) == value)
63 return EOK;
64 }
65
66 return ETIMEOUT;
67}
68
69static errno_t hw_reset_power_on(ar9271_t *ar9271)
70{
71 wmi_reg_t buffer[] = {
72 {
73 .offset = AR9271_RTC_FORCE_WAKE,
74 .value = AR9271_RTC_FORCE_WAKE_ENABLE |
75 AR9271_RTC_FORCE_WAKE_ON_INT
76 },
77 {
78 .offset = AR9271_RC,
79 .value = AR9271_RC_AHB
80 },
81 {
82 .offset = AR9271_RTC_RESET,
83 .value = 0
84 }
85 };
86
87 wmi_reg_buffer_write(ar9271->htc_device, buffer,
88 sizeof(buffer) / sizeof(wmi_reg_t));
89
90 udelay(2);
91
92 wmi_reg_write(ar9271->htc_device, AR9271_RC, 0);
93 wmi_reg_write(ar9271->htc_device, AR9271_RTC_RESET, 1);
94
95 errno_t rc = hw_read_wait(ar9271,
96 AR9271_RTC_STATUS,
97 AR9271_RTC_STATUS_MASK,
98 AR9271_RTC_STATUS_ON);
99 if (rc != EOK) {
100 usb_log_error("Failed to wait for RTC wake up register.\n");
101 return rc;
102 }
103
104 return EOK;
105}
106
107static errno_t hw_set_reset(ar9271_t *ar9271, bool cold)
108{
109 uint32_t reset_value = AR9271_RTC_RC_MAC_WARM;
110
111 if (cold)
112 reset_value |= AR9271_RTC_RC_MAC_COLD;
113
114 wmi_reg_t buffer[] = {
115 {
116 .offset = AR9271_RTC_FORCE_WAKE,
117 .value = AR9271_RTC_FORCE_WAKE_ENABLE |
118 AR9271_RTC_FORCE_WAKE_ON_INT
119 },
120 {
121 .offset = AR9271_RC,
122 .value = AR9271_RC_AHB
123 },
124 {
125 .offset = AR9271_RTC_RC,
126 .value = reset_value
127 }
128 };
129
130 wmi_reg_buffer_write(ar9271->htc_device, buffer,
131 sizeof(buffer) / sizeof(wmi_reg_t));
132
133 udelay(100);
134
135 wmi_reg_write(ar9271->htc_device, AR9271_RTC_RC, 0);
136
137 errno_t rc = hw_read_wait(ar9271, AR9271_RTC_RC, AR9271_RTC_RC_MASK, 0);
138 if (rc != EOK) {
139 usb_log_error("Failed to wait for RTC RC register.\n");
140 return rc;
141 }
142
143 wmi_reg_write(ar9271->htc_device, AR9271_RC, 0);
144 wmi_reg_clear_bit(ar9271->htc_device, AR9271_STATION_ID1,
145 AR9271_STATION_ID1_POWER_SAVING);
146
147 return EOK;
148}
149
150static errno_t hw_addr_init(ar9271_t *ar9271)
151{
152 uint32_t value;
153 nic_address_t ar9271_address;
154
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);
158
159 uint16_t two_bytes = uint16_t_be2host(value);
160 ar9271_address.address[2 * i] = two_bytes >> 8;
161 ar9271_address.address[2 * i + 1] = two_bytes & 0xff;
162 }
163
164 nic_t *nic = nic_get_from_ddf_dev(ar9271->ddf_dev);
165
166 errno_t rc = nic_report_address(nic, &ar9271_address);
167 if (rc != EOK) {
168 usb_log_error("Failed to report NIC HW address.\n");
169 return rc;
170 }
171
172 return EOK;
173}
174
175static errno_t hw_gpio_set_output(ar9271_t *ar9271, uint32_t gpio, uint32_t type)
176{
177 uint32_t address;
178
179 if (gpio > 11)
180 address = AR9271_GPIO_OUT_MUX3;
181 else if (gpio > 5)
182 address = AR9271_GPIO_OUT_MUX2;
183 else
184 address = AR9271_GPIO_OUT_MUX1;
185
186 uint32_t gpio_shift = (gpio % 6) * 5;
187
188 uint32_t temp;
189 wmi_reg_read(ar9271->htc_device, address, &temp);
190
191 temp = ((temp & 0x1f0) << 1) | (temp & ~0x1f0);
192 temp &= ~(0x1f << gpio_shift);
193 temp |= (type << gpio_shift);
194
195 wmi_reg_write(ar9271->htc_device, address, temp);
196
197 gpio_shift = 2 * gpio;
198
199 wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_GPIO_OE_OUT,
200 AR9271_GPIO_OE_OUT_ALWAYS << gpio_shift,
201 AR9271_GPIO_OE_OUT_ALWAYS << gpio_shift);
202
203 return EOK;
204}
205
206static errno_t hw_gpio_set_value(ar9271_t *ar9271, uint32_t gpio, uint32_t value)
207{
208 wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_GPIO_IN_OUT,
209 (~value & 1) << gpio, 1 << gpio);
210 return EOK;
211}
212
213/**Hardware init procedure of AR9271 device.
214 *
215 * @param ar9271 Device structure.
216 *
217 * @return EOK if succeed, error code otherwise.
218 *
219 */
220static errno_t hw_init_proc(ar9271_t *ar9271)
221{
222 errno_t rc = hw_reset_power_on(ar9271);
223 if (rc != EOK) {
224 usb_log_error("Failed to HW reset power on.\n");
225 return rc;
226 }
227
228 rc = hw_set_reset(ar9271, false);
229 if (rc != EOK) {
230 usb_log_error("Failed to HW warm reset.\n");
231 return rc;
232 }
233
234 rc = hw_addr_init(ar9271);
235 if (rc != EOK) {
236 usb_log_error("Failed to init HW addr.\n");
237 return rc;
238 }
239
240 return EOK;
241}
242
243static errno_t hw_init_led(ar9271_t *ar9271)
244{
245 errno_t rc = hw_gpio_set_output(ar9271, AR9271_LED_PIN,
246 AR9271_GPIO_OUT_MUX_AS_OUT);
247 if (rc != EOK) {
248 usb_log_error("Failed to set led GPIO to output.\n");
249 return rc;
250 }
251
252 rc = hw_gpio_set_value(ar9271, AR9271_LED_PIN, 0);
253 if (rc != EOK) {
254 usb_log_error("Failed to init bring up GPIO led.\n");
255 return rc;
256 }
257
258 return EOK;
259}
260
261static errno_t hw_activate_phy(ar9271_t *ar9271)
262{
263 wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 1);
264 udelay(1000);
265
266 return EOK;
267}
268
269static errno_t hw_set_operating_mode(ar9271_t *ar9271,
270 ieee80211_operating_mode_t op_mode)
271{
272 uint32_t set_bit = 0x10000000;
273
274 switch (op_mode) {
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 /* Fallthrough */
284 case IEEE80211_OPMODE_STATION:
285 wmi_reg_clear_bit(ar9271->htc_device, AR9271_CONFIG,
286 AR9271_CONFIG_ADHOC);
287 }
288
289 wmi_reg_set_clear_bit(ar9271->htc_device, AR9271_STATION_ID1,
290 set_bit, AR9271_OPMODE_STATION_AP_MASK | AR9271_OPMODE_ADHOC_MASK);
291
292 ieee80211_report_current_op_mode(ar9271->ieee80211_dev, op_mode);
293
294 return EOK;
295}
296
297static errno_t hw_reset_operating_mode(ar9271_t *ar9271)
298{
299 errno_t rc = hw_set_operating_mode(ar9271, IEEE80211_OPMODE_STATION);
300 if (rc != EOK) {
301 usb_log_error("Failed to set opmode to station.\n");
302 return rc;
303 }
304
305 return EOK;
306}
307
308static errno_t hw_noise_floor_calibration(ar9271_t *ar9271)
309{
310 uint32_t value;
311 wmi_reg_read(ar9271->htc_device, AR9271_PHY_CAL, &value);
312
313 value &= 0xfffffe00;
314 value |= (((uint32_t) AR9271_CALIB_NOMINAL_VALUE_2GHZ << 1) & 0x1ff);
315
316 wmi_reg_write(ar9271->htc_device, AR9271_PHY_CAL, value);
317
318 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
319 AR9271_AGC_CONTROL_NF_CALIB_EN);
320
321 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
322 AR9271_AGC_CONTROL_NF_NOT_UPDATE);
323
324 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
325 AR9271_AGC_CONTROL_NF_CALIB);
326
327 errno_t rc = hw_read_wait(ar9271, AR9271_AGC_CONTROL,
328 AR9271_AGC_CONTROL_NF_CALIB, 0);
329 if (rc != EOK) {
330 usb_log_error("Failed to wait for NF calibration.\n");
331 return rc;
332 }
333
334 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
335 AR9271_AGC_CONTROL_NF_CALIB_EN);
336
337 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
338 AR9271_AGC_CONTROL_NF_NOT_UPDATE);
339
340 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
341 AR9271_AGC_CONTROL_NF_CALIB);
342
343 return EOK;
344}
345
346static errno_t hw_set_freq(ar9271_t *ar9271, uint16_t freq)
347{
348 /* Not supported channel frequency. */
349 if ((freq < IEEE80211_FIRST_FREQ) || (freq > IEEE80211_MAX_FREQ))
350 return EINVAL;
351
352 /* Not supported channel frequency. */
353 if ((freq - IEEE80211_FIRST_FREQ) % IEEE80211_CHANNEL_GAP != 0)
354 return EINVAL;
355
356 uint32_t tx_control;
357 wmi_reg_read(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL, &tx_control);
358 wmi_reg_write(ar9271->htc_device, AR9271_PHY_CCK_TX_CTRL,
359 tx_control & ~AR9271_PHY_CCK_TX_CTRL_JAPAN);
360
361 /* Some magic here. */
362 uint32_t synth_ctl;
363 wmi_reg_read(ar9271->htc_device, AR9271_PHY_SYNTH_CONTROL, &synth_ctl);
364 synth_ctl &= 0xc0000000;
365 uint32_t channel_select = (freq * 0x10000) / 15;
366 synth_ctl = synth_ctl | (1 << 29) | (1 << 28) | channel_select;
367
368 wmi_reg_write(ar9271->htc_device, AR9271_PHY_SYNTH_CONTROL, synth_ctl);
369
370 ieee80211_report_current_freq(ar9271->ieee80211_dev, freq);
371
372 return EOK;
373}
374
375errno_t hw_freq_switch(ar9271_t *ar9271, uint16_t freq)
376{
377 wmi_reg_write(ar9271->htc_device, AR9271_PHY_RFBUS_KILL, 0x1);
378
379 errno_t rc = hw_read_wait(ar9271, AR9271_PHY_RFBUS_GRANT, 0x1, 0x1);
380 if (rc != EOK) {
381 usb_log_error("Failed to kill RF bus.\n");
382 return rc;
383 }
384
385 rc = hw_set_freq(ar9271, freq);
386 if (rc != EOK) {
387 usb_log_error("Failed to HW set frequency.\n");
388 return rc;
389 }
390
391 rc = hw_activate_phy(ar9271);
392 if (rc != EOK) {
393 usb_log_error("Failed to activate physical layer.\n");
394 return rc;
395 }
396
397 udelay(1000);
398 wmi_reg_write(ar9271->htc_device, AR9271_PHY_RFBUS_KILL, 0x0);
399
400 rc = hw_noise_floor_calibration(ar9271);
401 if (rc != EOK) {
402 usb_log_error("Failed to do NF calibration.\n");
403 return rc;
404 }
405
406 return EOK;
407}
408
409errno_t hw_set_rx_filter(ar9271_t *ar9271, bool assoc)
410{
411 uint32_t additional_bits = 0;
412
413 if (assoc)
414 additional_bits |= AR9271_RX_FILTER_MYBEACON;
415 else
416 additional_bits |= AR9271_RX_FILTER_BEACON;
417
418 uint32_t filter_bits = AR9271_RX_FILTER_UNI |
419 AR9271_RX_FILTER_MULTI | AR9271_RX_FILTER_BROAD |
420 additional_bits;
421
422 wmi_reg_write(ar9271->htc_device, AR9271_RX_FILTER, filter_bits);
423
424 return EOK;
425}
426
427errno_t hw_set_bssid(ar9271_t *ar9271)
428{
429 ieee80211_dev_t *ieee80211_dev = ar9271->ieee80211_dev;
430
431 nic_address_t bssid;
432 ieee80211_query_bssid(ieee80211_dev, &bssid);
433
434 uint32_t *first_4bytes = (uint32_t *) &bssid.address;
435 uint16_t *last_2bytes = (uint16_t *) &bssid.address[4];
436
437 wmi_reg_write(ar9271->htc_device, AR9271_BSSID0,
438 uint32_t_le2host(*first_4bytes));
439
440 wmi_reg_write(ar9271->htc_device, AR9271_BSSID1,
441 uint16_t_le2host(*last_2bytes) |
442 ((ieee80211_get_aid(ieee80211_dev) & 0x3fff) << 16));
443
444 return EOK;
445}
446
447errno_t hw_rx_init(ar9271_t *ar9271)
448{
449 wmi_reg_write(ar9271->htc_device, AR9271_COMMAND,
450 AR9271_COMMAND_RX_ENABLE);
451
452 errno_t rc = hw_set_rx_filter(ar9271, false);
453 if (rc != EOK) {
454 usb_log_error("Failed to set RX filtering.\n");
455 return rc;
456 }
457
458 wmi_reg_write(ar9271->htc_device, AR9271_MULTICAST_FILTER1, ~0);
459 wmi_reg_write(ar9271->htc_device, AR9271_MULTICAST_FILTER2, ~0);
460
461 /* Disable RX blocking. */
462 wmi_reg_clear_bit(ar9271->htc_device, AR9271_DIAG, (0x20 | 0x02000000));
463
464 return EOK;
465}
466
467static errno_t hw_init_pll(ar9271_t *ar9271)
468{
469 /* Some magic here (set for 2GHz channels). But VERY important :-) */
470 uint32_t pll = (0x5 << 10) | 0x2c;
471
472 wmi_reg_write(ar9271->htc_device, AR9271_RTC_PLL_CONTROL, pll);
473
474 wmi_reg_write(ar9271->htc_device, AR9271_RTC_SLEEP_CLOCK,
475 AR9271_RTC_SLEEP_CLOCK_FORCE_DERIVED);
476 wmi_reg_set_bit(ar9271->htc_device, AR9271_RTC_FORCE_WAKE,
477 AR9271_RTC_FORCE_WAKE_ENABLE);
478
479 return EOK;
480}
481
482static void hw_set_init_values(ar9271_t *ar9271)
483{
484 uint32_t reg_offset;
485 uint32_t reg_value;
486
487 size_t size = ARRAY_SIZE(ar9271_2g_mode_array);
488
489 for (size_t i = 0; i < size; i++) {
490 reg_offset = ar9271_2g_mode_array[i][0];
491 reg_value = ar9271_2g_mode_array[i][1];
492 wmi_reg_write(ar9271->htc_device, reg_offset, reg_value);
493 }
494
495 size = ARRAY_SIZE(ar9271_2g_tx_array);
496
497 for (size_t i = 0; i < size; i++) {
498 reg_offset = ar9271_2g_tx_array[i][0];
499 reg_value = ar9271_2g_tx_array[i][1];
500 wmi_reg_write(ar9271->htc_device, reg_offset, reg_value);
501 }
502
503 size = ARRAY_SIZE(ar9271_init_array);
504
505 for (size_t i = 0; i < size; i++) {
506 reg_offset = ar9271_init_array[i][0];
507 reg_value = ar9271_init_array[i][1];
508 wmi_reg_write(ar9271->htc_device, reg_offset, reg_value);
509 }
510}
511
512static errno_t hw_calibration(ar9271_t *ar9271)
513{
514 wmi_reg_set_bit(ar9271->htc_device, AR9271_CARRIER_LEAK_CONTROL,
515 AR9271_CARRIER_LEAK_CALIB);
516 wmi_reg_clear_bit(ar9271->htc_device, AR9271_ADC_CONTROL,
517 AR9271_ADC_CONTROL_OFF_PWDADC);
518 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
519 AR9271_AGC_CONTROL_TX_CALIB);
520 wmi_reg_set_bit(ar9271->htc_device, AR9271_PHY_TPCRG1,
521 AR9271_PHY_TPCRG1_PD_CALIB);
522 wmi_reg_set_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
523 AR9271_AGC_CONTROL_CALIB);
524
525 errno_t rc = hw_read_wait(ar9271, AR9271_AGC_CONTROL,
526 AR9271_AGC_CONTROL_CALIB, 0);
527 if (rc != EOK) {
528 usb_log_error("Failed to wait on calibrate completion.\n");
529 return rc;
530 }
531
532 wmi_reg_set_bit(ar9271->htc_device, AR9271_ADC_CONTROL,
533 AR9271_ADC_CONTROL_OFF_PWDADC);
534 wmi_reg_clear_bit(ar9271->htc_device, AR9271_CARRIER_LEAK_CONTROL,
535 AR9271_CARRIER_LEAK_CALIB);
536 wmi_reg_clear_bit(ar9271->htc_device, AR9271_AGC_CONTROL,
537 AR9271_AGC_CONTROL_TX_CALIB);
538
539 return EOK;
540}
541
542errno_t hw_reset(ar9271_t *ar9271)
543{
544 /* Set physical layer as deactivated. */
545 wmi_reg_write(ar9271->htc_device, AR9271_PHY_ACTIVE, 0);
546
547 if (ar9271->starting_up) {
548 wmi_reg_write(ar9271->htc_device,
549 AR9271_RESET_POWER_DOWN_CONTROL,
550 AR9271_RADIO_RF_RESET);
551
552 udelay(50);
553 }
554
555 /* Cold reset when RX is enabled. */
556 uint32_t config_reg;
557 wmi_reg_read(ar9271->htc_device, AR9271_COMMAND, &config_reg);
558 if (config_reg & AR9271_COMMAND_RX_ENABLE)
559 hw_set_reset(ar9271, true);
560
561 errno_t rc = hw_init_pll(ar9271);
562 if (rc != EOK) {
563 usb_log_error("Failed to init PLL.\n");
564 return rc;
565 }
566
567 udelay(500);
568
569 wmi_reg_write(ar9271->htc_device, AR9271_CLOCK_CONTROL,
570 AR9271_MAX_CPU_CLOCK);
571
572 udelay(100);
573
574 if (ar9271->starting_up) {
575 wmi_reg_write(ar9271->htc_device,
576 AR9271_RESET_POWER_DOWN_CONTROL,
577 AR9271_GATE_MAC_CONTROL);
578
579 udelay(50);
580 }
581
582 hw_set_init_values(ar9271);
583
584 /* Set physical layer mode. */
585 wmi_reg_write(ar9271->htc_device, AR9271_PHY_MODE,
586 AR9271_PHY_MODE_DYNAMIC);
587
588 /* Reset device operating mode. */
589 rc = hw_reset_operating_mode(ar9271);
590 if (rc != EOK) {
591 usb_log_error("Failed to reset operating mode.\n");
592 return rc;
593 }
594
595 /* Set initial channel frequency. */
596 rc = hw_set_freq(ar9271, IEEE80211_FIRST_FREQ);
597 if (rc != EOK) {
598 usb_log_error("Failed to set channel.\n");
599 return rc;
600 }
601
602 /* Initialize transmission queues. */
603 for (unsigned int i = 0; i < AR9271_QUEUES_COUNT; i++) {
604 wmi_reg_write(ar9271->htc_device,
605 AR9271_QUEUE_BASE_MASK + (i << 2), 1 << i);
606 }
607
608 /* Activate physical layer. */
609 rc = hw_activate_phy(ar9271);
610 if (rc != EOK) {
611 usb_log_error("Failed to activate physical layer.\n");
612 return rc;
613 }
614
615 /* Calibration. */
616 rc = hw_calibration(ar9271);
617 if (rc != EOK) {
618 usb_log_error("Failed to calibrate device.\n");
619 return rc;
620 }
621
622 rc = hw_noise_floor_calibration(ar9271);
623 if (rc != EOK) {
624 usb_log_error("Failed to calibrate noise floor.\n");
625 return rc;
626 }
627
628 /* Byteswap TX and RX data buffer words. */
629 wmi_reg_write(ar9271->htc_device, AR9271_CONFIG, 0xA);
630
631 return EOK;
632}
633
634/** Initialize hardware of AR9271 device.
635 *
636 * @param ar9271 Device structure.
637 *
638 * @return EOK if succeed, error code otherwise.
639 */
640errno_t hw_init(ar9271_t *ar9271)
641{
642 errno_t rc = hw_init_proc(ar9271);
643 if (rc != EOK) {
644 usb_log_error("Failed to HW reset device.\n");
645 return rc;
646 }
647
648 rc = hw_init_led(ar9271);
649 if (rc != EOK) {
650 usb_log_error("Failed to HW init led.\n");
651 return rc;
652 }
653
654 usb_log_info("HW initialization finished successfully.\n");
655
656 return EOK;
657}
Note: See TracBrowser for help on using the repository browser.