@@ -482,31 +482,79 @@ static int ath10k_fetch_cal_file(struct ath10k *ar)
482
482
return 0 ;
483
483
}
484
484
485
- static int ath10k_core_fetch_firmware_api_1 (struct ath10k * ar )
485
+ static int ath10k_core_fetch_spec_board_file (struct ath10k * ar )
486
486
{
487
- int ret = 0 ;
487
+ char filename [ 100 ] ;
488
488
489
- if (ar -> hw_params .fw .fw == NULL ) {
490
- ath10k_err (ar , "firmware file not defined\n" );
491
- return - EINVAL ;
492
- }
489
+ scnprintf (filename , sizeof (filename ), "board-%s-%s.bin" ,
490
+ ath10k_bus_str (ar -> hif .bus ), ar -> spec_board_id );
491
+
492
+ ar -> board = ath10k_fetch_fw_file (ar , ar -> hw_params .fw .dir , filename );
493
+ if (IS_ERR (ar -> board ))
494
+ return PTR_ERR (ar -> board );
495
+
496
+ ar -> board_data = ar -> board -> data ;
497
+ ar -> board_len = ar -> board -> size ;
498
+ ar -> spec_board_loaded = true;
493
499
494
- if (ar -> hw_params .fw .board == NULL ) {
495
- ath10k_err (ar , "board data file not defined" );
500
+ return 0 ;
501
+ }
502
+
503
+ static int ath10k_core_fetch_generic_board_file (struct ath10k * ar )
504
+ {
505
+ if (!ar -> hw_params .fw .board ) {
506
+ ath10k_err (ar , "failed to find board file fw entry\n" );
496
507
return - EINVAL ;
497
508
}
498
509
499
510
ar -> board = ath10k_fetch_fw_file (ar ,
500
511
ar -> hw_params .fw .dir ,
501
512
ar -> hw_params .fw .board );
502
- if (IS_ERR (ar -> board )) {
503
- ret = PTR_ERR (ar -> board );
504
- ath10k_err (ar , "could not fetch board data (%d)\n" , ret );
505
- goto err ;
506
- }
513
+ if (IS_ERR (ar -> board ))
514
+ return PTR_ERR (ar -> board );
507
515
508
516
ar -> board_data = ar -> board -> data ;
509
517
ar -> board_len = ar -> board -> size ;
518
+ ar -> spec_board_loaded = false;
519
+
520
+ return 0 ;
521
+ }
522
+
523
+ static int ath10k_core_fetch_board_file (struct ath10k * ar )
524
+ {
525
+ int ret ;
526
+
527
+ if (strlen (ar -> spec_board_id ) > 0 ) {
528
+ ret = ath10k_core_fetch_spec_board_file (ar );
529
+ if (ret ) {
530
+ ath10k_info (ar , "failed to load spec board file, falling back to generic: %d\n" ,
531
+ ret );
532
+ goto generic ;
533
+ }
534
+
535
+ ath10k_dbg (ar , ATH10K_DBG_BOOT , "found specific board file for %s\n" ,
536
+ ar -> spec_board_id );
537
+ return 0 ;
538
+ }
539
+
540
+ generic :
541
+ ret = ath10k_core_fetch_generic_board_file (ar );
542
+ if (ret ) {
543
+ ath10k_err (ar , "failed to fetch generic board data: %d\n" , ret );
544
+ return ret ;
545
+ }
546
+
547
+ return 0 ;
548
+ }
549
+
550
+ static int ath10k_core_fetch_firmware_api_1 (struct ath10k * ar )
551
+ {
552
+ int ret = 0 ;
553
+
554
+ if (ar -> hw_params .fw .fw == NULL ) {
555
+ ath10k_err (ar , "firmware file not defined\n" );
556
+ return - EINVAL ;
557
+ }
510
558
511
559
ar -> firmware = ath10k_fetch_fw_file (ar ,
512
560
ar -> hw_params .fw .dir ,
@@ -675,6 +723,17 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
675
723
ath10k_dbg (ar , ATH10K_DBG_BOOT , "found fw ie wmi op version %d\n" ,
676
724
ar -> wmi .op_version );
677
725
break ;
726
+ case ATH10K_FW_IE_HTT_OP_VERSION :
727
+ if (ie_len != sizeof (u32 ))
728
+ break ;
729
+
730
+ version = (__le32 * )data ;
731
+
732
+ ar -> htt .op_version = le32_to_cpup (version );
733
+
734
+ ath10k_dbg (ar , ATH10K_DBG_BOOT , "found fw ie htt op version %d\n" ,
735
+ ar -> htt .op_version );
736
+ break ;
678
737
default :
679
738
ath10k_warn (ar , "Unknown FW IE: %u\n" ,
680
739
le32_to_cpu (hdr -> id ));
@@ -695,27 +754,6 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
695
754
goto err ;
696
755
}
697
756
698
- /* now fetch the board file */
699
- if (ar -> hw_params .fw .board == NULL ) {
700
- ath10k_err (ar , "board data file not defined" );
701
- ret = - EINVAL ;
702
- goto err ;
703
- }
704
-
705
- ar -> board = ath10k_fetch_fw_file (ar ,
706
- ar -> hw_params .fw .dir ,
707
- ar -> hw_params .fw .board );
708
- if (IS_ERR (ar -> board )) {
709
- ret = PTR_ERR (ar -> board );
710
- ath10k_err (ar , "could not fetch board data '%s/%s' (%d)\n" ,
711
- ar -> hw_params .fw .dir , ar -> hw_params .fw .board ,
712
- ret );
713
- goto err ;
714
- }
715
-
716
- ar -> board_data = ar -> board -> data ;
717
- ar -> board_len = ar -> board -> size ;
718
-
719
757
return 0 ;
720
758
721
759
err :
@@ -730,6 +768,19 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
730
768
/* calibration file is optional, don't check for any errors */
731
769
ath10k_fetch_cal_file (ar );
732
770
771
+ ret = ath10k_core_fetch_board_file (ar );
772
+ if (ret ) {
773
+ ath10k_err (ar , "failed to fetch board file: %d\n" , ret );
774
+ return ret ;
775
+ }
776
+
777
+ ar -> fw_api = 5 ;
778
+ ath10k_dbg (ar , ATH10K_DBG_BOOT , "trying fw api %d\n" , ar -> fw_api );
779
+
780
+ ret = ath10k_core_fetch_firmware_api_n (ar , ATH10K_FW_API5_FILE );
781
+ if (ret == 0 )
782
+ goto success ;
783
+
733
784
ar -> fw_api = 4 ;
734
785
ath10k_dbg (ar , ATH10K_DBG_BOOT , "trying fw api %d\n" , ar -> fw_api );
735
786
@@ -958,6 +1009,8 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
958
1009
ar -> max_num_stations = TARGET_NUM_STATIONS ;
959
1010
ar -> max_num_vdevs = TARGET_NUM_VDEVS ;
960
1011
ar -> htt .max_num_pending_tx = TARGET_NUM_MSDU_DESC ;
1012
+ ar -> fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
1013
+ WMI_STAT_PEER ;
961
1014
break ;
962
1015
case ATH10K_FW_WMI_OP_VERSION_10_1 :
963
1016
case ATH10K_FW_WMI_OP_VERSION_10_2 :
@@ -966,19 +1019,47 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
966
1019
ar -> max_num_stations = TARGET_10X_NUM_STATIONS ;
967
1020
ar -> max_num_vdevs = TARGET_10X_NUM_VDEVS ;
968
1021
ar -> htt .max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC ;
1022
+ ar -> fw_stats_req_mask = WMI_STAT_PEER ;
969
1023
break ;
970
1024
case ATH10K_FW_WMI_OP_VERSION_TLV :
971
1025
ar -> max_num_peers = TARGET_TLV_NUM_PEERS ;
972
1026
ar -> max_num_stations = TARGET_TLV_NUM_STATIONS ;
973
1027
ar -> max_num_vdevs = TARGET_TLV_NUM_VDEVS ;
1028
+ ar -> max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS ;
974
1029
ar -> htt .max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC ;
1030
+ ar -> wow .max_num_patterns = TARGET_TLV_NUM_WOW_PATTERNS ;
1031
+ ar -> fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
1032
+ WMI_STAT_PEER ;
975
1033
break ;
976
1034
case ATH10K_FW_WMI_OP_VERSION_UNSET :
977
1035
case ATH10K_FW_WMI_OP_VERSION_MAX :
978
1036
WARN_ON (1 );
979
1037
return - EINVAL ;
980
1038
}
981
1039
1040
+ /* Backwards compatibility for firmwares without
1041
+ * ATH10K_FW_IE_HTT_OP_VERSION.
1042
+ */
1043
+ if (ar -> htt .op_version == ATH10K_FW_HTT_OP_VERSION_UNSET ) {
1044
+ switch (ar -> wmi .op_version ) {
1045
+ case ATH10K_FW_WMI_OP_VERSION_MAIN :
1046
+ ar -> htt .op_version = ATH10K_FW_HTT_OP_VERSION_MAIN ;
1047
+ break ;
1048
+ case ATH10K_FW_WMI_OP_VERSION_10_1 :
1049
+ case ATH10K_FW_WMI_OP_VERSION_10_2 :
1050
+ case ATH10K_FW_WMI_OP_VERSION_10_2_4 :
1051
+ ar -> htt .op_version = ATH10K_FW_HTT_OP_VERSION_10_1 ;
1052
+ break ;
1053
+ case ATH10K_FW_WMI_OP_VERSION_TLV :
1054
+ ar -> htt .op_version = ATH10K_FW_HTT_OP_VERSION_TLV ;
1055
+ break ;
1056
+ case ATH10K_FW_WMI_OP_VERSION_UNSET :
1057
+ case ATH10K_FW_WMI_OP_VERSION_MAX :
1058
+ WARN_ON (1 );
1059
+ return - EINVAL ;
1060
+ }
1061
+ }
1062
+
982
1063
return 0 ;
983
1064
}
984
1065
@@ -1080,9 +1161,8 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
1080
1161
1081
1162
if (mode == ATH10K_FIRMWARE_MODE_NORMAL ) {
1082
1163
status = ath10k_wmi_wait_for_service_ready (ar );
1083
- if (status <= 0 ) {
1164
+ if (status ) {
1084
1165
ath10k_warn (ar , "wmi service ready event not received" );
1085
- status = - ETIMEDOUT ;
1086
1166
goto err_hif_stop ;
1087
1167
}
1088
1168
}
@@ -1098,9 +1178,8 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
1098
1178
}
1099
1179
1100
1180
status = ath10k_wmi_wait_for_unified_ready (ar );
1101
- if (status <= 0 ) {
1181
+ if (status ) {
1102
1182
ath10k_err (ar , "wmi unified ready event not received\n" );
1103
- status = - ETIMEDOUT ;
1104
1183
goto err_hif_stop ;
1105
1184
}
1106
1185
@@ -1151,6 +1230,7 @@ EXPORT_SYMBOL(ath10k_core_start);
1151
1230
int ath10k_wait_for_suspend (struct ath10k * ar , u32 suspend_opt )
1152
1231
{
1153
1232
int ret ;
1233
+ unsigned long time_left ;
1154
1234
1155
1235
reinit_completion (& ar -> target_suspend );
1156
1236
@@ -1160,9 +1240,9 @@ int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt)
1160
1240
return ret ;
1161
1241
}
1162
1242
1163
- ret = wait_for_completion_timeout (& ar -> target_suspend , 1 * HZ );
1243
+ time_left = wait_for_completion_timeout (& ar -> target_suspend , 1 * HZ );
1164
1244
1165
- if (ret == 0 ) {
1245
+ if (! time_left ) {
1166
1246
ath10k_warn (ar , "suspend timed out - target pause event never came\n" );
1167
1247
return - ETIMEDOUT ;
1168
1248
}
@@ -1386,6 +1466,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
1386
1466
init_completion (& ar -> scan .completed );
1387
1467
init_completion (& ar -> scan .on_channel );
1388
1468
init_completion (& ar -> target_suspend );
1469
+ init_completion (& ar -> wow .wakeup_completed );
1389
1470
1390
1471
init_completion (& ar -> install_key_done );
1391
1472
init_completion (& ar -> vdev_setup_done );
0 commit comments