xref: /linux/drivers/net/wireless/ath/wcn36xx/firmware.c (revision 3d0fe49454652117522f60bfbefb978ba0e5300b)
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 #include "wcn36xx.h"
4 #include "firmware.h"
5 
6 #define DEFINE(s)[s] = #s
7 
8 static const char * const wcn36xx_firmware_caps_names[] = {
9 	DEFINE(MCC),
10 	DEFINE(P2P),
11 	DEFINE(DOT11AC),
12 	DEFINE(SLM_SESSIONIZATION),
13 	DEFINE(DOT11AC_OPMODE),
14 	DEFINE(SAP32STA),
15 	DEFINE(TDLS),
16 	DEFINE(P2P_GO_NOA_DECOUPLE_INIT_SCAN),
17 	DEFINE(WLANACTIVE_OFFLOAD),
18 	DEFINE(BEACON_OFFLOAD),
19 	DEFINE(SCAN_OFFLOAD),
20 	DEFINE(ROAM_OFFLOAD),
21 	DEFINE(BCN_MISS_OFFLOAD),
22 	DEFINE(STA_POWERSAVE),
23 	DEFINE(STA_ADVANCED_PWRSAVE),
24 	DEFINE(AP_UAPSD),
25 	DEFINE(AP_DFS),
26 	DEFINE(BLOCKACK),
27 	DEFINE(PHY_ERR),
28 	DEFINE(BCN_FILTER),
29 	DEFINE(RTT),
30 	DEFINE(RATECTRL),
31 	DEFINE(WOW),
32 	DEFINE(WLAN_ROAM_SCAN_OFFLOAD),
33 	DEFINE(SPECULATIVE_PS_POLL),
34 	DEFINE(SCAN_SCH),
35 	DEFINE(IBSS_HEARTBEAT_OFFLOAD),
36 	DEFINE(WLAN_SCAN_OFFLOAD),
37 	DEFINE(WLAN_PERIODIC_TX_PTRN),
38 	DEFINE(ADVANCE_TDLS),
39 	DEFINE(BATCH_SCAN),
40 	DEFINE(FW_IN_TX_PATH),
41 	DEFINE(EXTENDED_NSOFFLOAD_SLOT),
42 	DEFINE(CH_SWITCH_V1),
43 	DEFINE(HT40_OBSS_SCAN),
44 	DEFINE(UPDATE_CHANNEL_LIST),
45 	DEFINE(WLAN_MCADDR_FLT),
46 	DEFINE(WLAN_CH144),
47 	DEFINE(NAN),
48 	DEFINE(TDLS_SCAN_COEXISTENCE),
49 	DEFINE(LINK_LAYER_STATS_MEAS),
50 	DEFINE(MU_MIMO),
51 	DEFINE(EXTENDED_SCAN),
52 	DEFINE(DYNAMIC_WMM_PS),
53 	DEFINE(MAC_SPOOFED_SCAN),
54 	DEFINE(BMU_ERROR_GENERIC_RECOVERY),
55 	DEFINE(DISA),
56 	DEFINE(FW_STATS),
57 	DEFINE(WPS_PRBRSP_TMPL),
58 	DEFINE(BCN_IE_FLT_DELTA),
59 	DEFINE(TDLS_OFF_CHANNEL),
60 	DEFINE(RTT3),
61 	DEFINE(MGMT_FRAME_LOGGING),
62 	DEFINE(ENHANCED_TXBD_COMPLETION),
63 	DEFINE(LOGGING_ENHANCEMENT),
64 	DEFINE(EXT_SCAN_ENHANCED),
65 	DEFINE(MEMORY_DUMP_SUPPORTED),
66 	DEFINE(PER_PKT_STATS_SUPPORTED),
67 	DEFINE(EXT_LL_STAT),
68 	DEFINE(WIFI_CONFIG),
69 	DEFINE(ANTENNA_DIVERSITY_SELECTION),
70 };
71 
72 #undef DEFINE
73 
74 const char *wcn36xx_firmware_get_cap_name(enum wcn36xx_firmware_feat_caps x)
75 {
76 	if (x >= ARRAY_SIZE(wcn36xx_firmware_caps_names))
77 		return "UNKNOWN";
78 	return wcn36xx_firmware_caps_names[x];
79 }
80 
81 void wcn36xx_firmware_set_feat_caps(u32 *bitmap,
82 				    enum wcn36xx_firmware_feat_caps cap)
83 {
84 	int arr_idx, bit_idx;
85 
86 	if (cap < 0 || cap > 127) {
87 		wcn36xx_warn("error cap idx %d\n", cap);
88 		return;
89 	}
90 
91 	arr_idx = cap / 32;
92 	bit_idx = cap % 32;
93 	bitmap[arr_idx] |= (1 << bit_idx);
94 }
95 
96 int wcn36xx_firmware_get_feat_caps(u32 *bitmap,
97 				   enum wcn36xx_firmware_feat_caps cap)
98 {
99 	int arr_idx, bit_idx;
100 
101 	if (cap < 0 || cap > 127) {
102 		wcn36xx_warn("error cap idx %d\n", cap);
103 		return -EINVAL;
104 	}
105 
106 	arr_idx = cap / 32;
107 	bit_idx = cap % 32;
108 
109 	return (bitmap[arr_idx] & (1 << bit_idx)) ? 1 : 0;
110 }
111 
112 void wcn36xx_firmware_clear_feat_caps(u32 *bitmap,
113 				      enum wcn36xx_firmware_feat_caps cap)
114 {
115 	int arr_idx, bit_idx;
116 
117 	if (cap < 0 || cap > 127) {
118 		wcn36xx_warn("error cap idx %d\n", cap);
119 		return;
120 	}
121 
122 	arr_idx = cap / 32;
123 	bit_idx = cap % 32;
124 	bitmap[arr_idx] &= ~(1 << bit_idx);
125 }
126