137de943dSBryan O'Donoghue // SPDX-License-Identifier: GPL-2.0-only
237de943dSBryan O'Donoghue 
337de943dSBryan O'Donoghue #include "wcn36xx.h"
437de943dSBryan O'Donoghue #include "firmware.h"
537de943dSBryan O'Donoghue 
6*75072b29SBryan O'Donoghue #define DEFINE(s)[s] = #s
7*75072b29SBryan O'Donoghue 
8*75072b29SBryan O'Donoghue static const char * const wcn36xx_firmware_caps_names[] = {
9*75072b29SBryan O'Donoghue 	DEFINE(MCC),
10*75072b29SBryan O'Donoghue 	DEFINE(P2P),
11*75072b29SBryan O'Donoghue 	DEFINE(DOT11AC),
12*75072b29SBryan O'Donoghue 	DEFINE(SLM_SESSIONIZATION),
13*75072b29SBryan O'Donoghue 	DEFINE(DOT11AC_OPMODE),
14*75072b29SBryan O'Donoghue 	DEFINE(SAP32STA),
15*75072b29SBryan O'Donoghue 	DEFINE(TDLS),
16*75072b29SBryan O'Donoghue 	DEFINE(P2P_GO_NOA_DECOUPLE_INIT_SCAN),
17*75072b29SBryan O'Donoghue 	DEFINE(WLANACTIVE_OFFLOAD),
18*75072b29SBryan O'Donoghue 	DEFINE(BEACON_OFFLOAD),
19*75072b29SBryan O'Donoghue 	DEFINE(SCAN_OFFLOAD),
20*75072b29SBryan O'Donoghue 	DEFINE(ROAM_OFFLOAD),
21*75072b29SBryan O'Donoghue 	DEFINE(BCN_MISS_OFFLOAD),
22*75072b29SBryan O'Donoghue 	DEFINE(STA_POWERSAVE),
23*75072b29SBryan O'Donoghue 	DEFINE(STA_ADVANCED_PWRSAVE),
24*75072b29SBryan O'Donoghue 	DEFINE(AP_UAPSD),
25*75072b29SBryan O'Donoghue 	DEFINE(AP_DFS),
26*75072b29SBryan O'Donoghue 	DEFINE(BLOCKACK),
27*75072b29SBryan O'Donoghue 	DEFINE(PHY_ERR),
28*75072b29SBryan O'Donoghue 	DEFINE(BCN_FILTER),
29*75072b29SBryan O'Donoghue 	DEFINE(RTT),
30*75072b29SBryan O'Donoghue 	DEFINE(RATECTRL),
31*75072b29SBryan O'Donoghue 	DEFINE(WOW),
32*75072b29SBryan O'Donoghue 	DEFINE(WLAN_ROAM_SCAN_OFFLOAD),
33*75072b29SBryan O'Donoghue 	DEFINE(SPECULATIVE_PS_POLL),
34*75072b29SBryan O'Donoghue 	DEFINE(SCAN_SCH),
35*75072b29SBryan O'Donoghue 	DEFINE(IBSS_HEARTBEAT_OFFLOAD),
36*75072b29SBryan O'Donoghue 	DEFINE(WLAN_SCAN_OFFLOAD),
37*75072b29SBryan O'Donoghue 	DEFINE(WLAN_PERIODIC_TX_PTRN),
38*75072b29SBryan O'Donoghue 	DEFINE(ADVANCE_TDLS),
39*75072b29SBryan O'Donoghue 	DEFINE(BATCH_SCAN),
40*75072b29SBryan O'Donoghue 	DEFINE(FW_IN_TX_PATH),
41*75072b29SBryan O'Donoghue 	DEFINE(EXTENDED_NSOFFLOAD_SLOT),
42*75072b29SBryan O'Donoghue 	DEFINE(CH_SWITCH_V1),
43*75072b29SBryan O'Donoghue 	DEFINE(HT40_OBSS_SCAN),
44*75072b29SBryan O'Donoghue 	DEFINE(UPDATE_CHANNEL_LIST),
45*75072b29SBryan O'Donoghue 	DEFINE(WLAN_MCADDR_FLT),
46*75072b29SBryan O'Donoghue 	DEFINE(WLAN_CH144),
47*75072b29SBryan O'Donoghue 	DEFINE(NAN),
48*75072b29SBryan O'Donoghue 	DEFINE(TDLS_SCAN_COEXISTENCE),
49*75072b29SBryan O'Donoghue 	DEFINE(LINK_LAYER_STATS_MEAS),
50*75072b29SBryan O'Donoghue 	DEFINE(MU_MIMO),
51*75072b29SBryan O'Donoghue 	DEFINE(EXTENDED_SCAN),
52*75072b29SBryan O'Donoghue 	DEFINE(DYNAMIC_WMM_PS),
53*75072b29SBryan O'Donoghue 	DEFINE(MAC_SPOOFED_SCAN),
54*75072b29SBryan O'Donoghue 	DEFINE(BMU_ERROR_GENERIC_RECOVERY),
55*75072b29SBryan O'Donoghue 	DEFINE(DISA),
56*75072b29SBryan O'Donoghue 	DEFINE(FW_STATS),
57*75072b29SBryan O'Donoghue 	DEFINE(WPS_PRBRSP_TMPL),
58*75072b29SBryan O'Donoghue 	DEFINE(BCN_IE_FLT_DELTA),
59*75072b29SBryan O'Donoghue 	DEFINE(TDLS_OFF_CHANNEL),
60*75072b29SBryan O'Donoghue 	DEFINE(RTT3),
61*75072b29SBryan O'Donoghue 	DEFINE(MGMT_FRAME_LOGGING),
62*75072b29SBryan O'Donoghue 	DEFINE(ENHANCED_TXBD_COMPLETION),
63*75072b29SBryan O'Donoghue 	DEFINE(LOGGING_ENHANCEMENT),
64*75072b29SBryan O'Donoghue 	DEFINE(EXT_SCAN_ENHANCED),
65*75072b29SBryan O'Donoghue 	DEFINE(MEMORY_DUMP_SUPPORTED),
66*75072b29SBryan O'Donoghue 	DEFINE(PER_PKT_STATS_SUPPORTED),
67*75072b29SBryan O'Donoghue 	DEFINE(EXT_LL_STAT),
68*75072b29SBryan O'Donoghue 	DEFINE(WIFI_CONFIG),
69*75072b29SBryan O'Donoghue 	DEFINE(ANTENNA_DIVERSITY_SELECTION),
70*75072b29SBryan O'Donoghue };
71*75072b29SBryan O'Donoghue 
72*75072b29SBryan O'Donoghue #undef DEFINE
73*75072b29SBryan O'Donoghue 
wcn36xx_firmware_get_cap_name(enum wcn36xx_firmware_feat_caps x)74*75072b29SBryan O'Donoghue const char *wcn36xx_firmware_get_cap_name(enum wcn36xx_firmware_feat_caps x)
75*75072b29SBryan O'Donoghue {
76*75072b29SBryan O'Donoghue 	if (x >= ARRAY_SIZE(wcn36xx_firmware_caps_names))
77*75072b29SBryan O'Donoghue 		return "UNKNOWN";
78*75072b29SBryan O'Donoghue 	return wcn36xx_firmware_caps_names[x];
79*75072b29SBryan O'Donoghue }
80*75072b29SBryan O'Donoghue 
wcn36xx_firmware_set_feat_caps(u32 * bitmap,enum wcn36xx_firmware_feat_caps cap)8137de943dSBryan O'Donoghue void wcn36xx_firmware_set_feat_caps(u32 *bitmap,
8237de943dSBryan O'Donoghue 				    enum wcn36xx_firmware_feat_caps cap)
8337de943dSBryan O'Donoghue {
8437de943dSBryan O'Donoghue 	int arr_idx, bit_idx;
8537de943dSBryan O'Donoghue 
8637de943dSBryan O'Donoghue 	if (cap < 0 || cap > 127) {
8737de943dSBryan O'Donoghue 		wcn36xx_warn("error cap idx %d\n", cap);
8837de943dSBryan O'Donoghue 		return;
8937de943dSBryan O'Donoghue 	}
9037de943dSBryan O'Donoghue 
9137de943dSBryan O'Donoghue 	arr_idx = cap / 32;
9237de943dSBryan O'Donoghue 	bit_idx = cap % 32;
9337de943dSBryan O'Donoghue 	bitmap[arr_idx] |= (1 << bit_idx);
9437de943dSBryan O'Donoghue }
9537de943dSBryan O'Donoghue 
wcn36xx_firmware_get_feat_caps(u32 * bitmap,enum wcn36xx_firmware_feat_caps cap)9637de943dSBryan O'Donoghue int wcn36xx_firmware_get_feat_caps(u32 *bitmap,
9737de943dSBryan O'Donoghue 				   enum wcn36xx_firmware_feat_caps cap)
9837de943dSBryan O'Donoghue {
9937de943dSBryan O'Donoghue 	int arr_idx, bit_idx;
10037de943dSBryan O'Donoghue 
10137de943dSBryan O'Donoghue 	if (cap < 0 || cap > 127) {
10237de943dSBryan O'Donoghue 		wcn36xx_warn("error cap idx %d\n", cap);
10337de943dSBryan O'Donoghue 		return -EINVAL;
10437de943dSBryan O'Donoghue 	}
10537de943dSBryan O'Donoghue 
10637de943dSBryan O'Donoghue 	arr_idx = cap / 32;
10737de943dSBryan O'Donoghue 	bit_idx = cap % 32;
10837de943dSBryan O'Donoghue 
10937de943dSBryan O'Donoghue 	return (bitmap[arr_idx] & (1 << bit_idx)) ? 1 : 0;
11037de943dSBryan O'Donoghue }
11137de943dSBryan O'Donoghue 
wcn36xx_firmware_clear_feat_caps(u32 * bitmap,enum wcn36xx_firmware_feat_caps cap)11237de943dSBryan O'Donoghue void wcn36xx_firmware_clear_feat_caps(u32 *bitmap,
11337de943dSBryan O'Donoghue 				      enum wcn36xx_firmware_feat_caps cap)
11437de943dSBryan O'Donoghue {
11537de943dSBryan O'Donoghue 	int arr_idx, bit_idx;
11637de943dSBryan O'Donoghue 
11737de943dSBryan O'Donoghue 	if (cap < 0 || cap > 127) {
11837de943dSBryan O'Donoghue 		wcn36xx_warn("error cap idx %d\n", cap);
11937de943dSBryan O'Donoghue 		return;
12037de943dSBryan O'Donoghue 	}
12137de943dSBryan O'Donoghue 
12237de943dSBryan O'Donoghue 	arr_idx = cap / 32;
12337de943dSBryan O'Donoghue 	bit_idx = cap % 32;
12437de943dSBryan O'Donoghue 	bitmap[arr_idx] &= ~(1 << bit_idx);
12537de943dSBryan O'Donoghue }
126