1 // SPDX-License-Identifier: GPL-2.0-only
3 * Implementation of the host-to-chip MIBs of the hardware API.
5 * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
6 * Copyright (c) 2010, ST-Ericsson
7 * Copyright (C) 2010, ST-Ericsson SA
10 #include <linux/etherdevice.h>
14 #include "hif_tx_mib.h"
15 #include "hif_api_mib.h"
17 int wfx_hif_set_output_power(struct wfx_vif
*wvif
, int val
)
19 struct wfx_hif_mib_current_tx_power_level arg
= {
20 .power_level
= cpu_to_le32(val
* 10),
23 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_CURRENT_TX_POWER_LEVEL
,
27 int wfx_hif_set_beacon_wakeup_period(struct wfx_vif
*wvif
,
28 unsigned int dtim_interval
, unsigned int listen_interval
)
30 struct wfx_hif_mib_beacon_wake_up_period arg
= {
31 .wakeup_period_min
= dtim_interval
,
33 .wakeup_period_max
= listen_interval
,
36 if (dtim_interval
> 0xFF || listen_interval
> 0xFFFF)
38 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_BEACON_WAKEUP_PERIOD
,
42 int wfx_hif_set_rcpi_rssi_threshold(struct wfx_vif
*wvif
, int rssi_thold
, int rssi_hyst
)
44 struct wfx_hif_mib_rcpi_rssi_threshold arg
= {
45 .rolling_average_count
= 8,
49 if (!rssi_thold
&& !rssi_hyst
) {
53 arg
.upper_threshold
= rssi_thold
+ rssi_hyst
;
54 arg
.upper_threshold
= (arg
.upper_threshold
+ 110) * 2;
55 arg
.lower_threshold
= rssi_thold
;
56 arg
.lower_threshold
= (arg
.lower_threshold
+ 110) * 2;
59 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_RCPI_RSSI_THRESHOLD
,
63 int wfx_hif_get_counters_table(struct wfx_dev
*wdev
, int vif_id
,
64 struct wfx_hif_mib_extended_count_table
*arg
)
66 if (wfx_api_older_than(wdev
, 1, 3)) {
67 /* extended_count_table is wider than count_table */
68 memset(arg
, 0xFF, sizeof(*arg
));
69 return wfx_hif_read_mib(wdev
, vif_id
, HIF_MIB_ID_COUNTERS_TABLE
,
70 arg
, sizeof(struct wfx_hif_mib_count_table
));
72 return wfx_hif_read_mib(wdev
, vif_id
, HIF_MIB_ID_EXTENDED_COUNTERS_TABLE
,
73 arg
, sizeof(struct wfx_hif_mib_extended_count_table
));
77 int wfx_hif_set_macaddr(struct wfx_vif
*wvif
, u8
*mac
)
79 struct wfx_hif_mib_mac_address arg
= { };
82 ether_addr_copy(arg
.mac_addr
, mac
);
83 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_DOT11_MAC_ADDRESS
,
87 int wfx_hif_set_rx_filter(struct wfx_vif
*wvif
, bool filter_bssid
, bool filter_prbreq
)
89 struct wfx_hif_mib_rx_filter arg
= { };
94 arg
.fwd_probe_req
= 1;
95 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_RX_FILTER
, &arg
, sizeof(arg
));
98 int wfx_hif_set_beacon_filter_table(struct wfx_vif
*wvif
, int tbl_len
,
99 const struct wfx_hif_ie_table_entry
*tbl
)
102 struct wfx_hif_mib_bcn_filter_table
*arg
;
103 int buf_len
= struct_size(arg
, ie_table
, tbl_len
);
105 arg
= kzalloc(buf_len
, GFP_KERNEL
);
108 arg
->num_of_info_elmts
= cpu_to_le32(tbl_len
);
109 memcpy(arg
->ie_table
, tbl
, flex_array_size(arg
, ie_table
, tbl_len
));
110 ret
= wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_BEACON_FILTER_TABLE
,
116 int wfx_hif_beacon_filter_control(struct wfx_vif
*wvif
, int enable
, int beacon_count
)
118 struct wfx_hif_mib_bcn_filter_enable arg
= {
119 .enable
= cpu_to_le32(enable
),
120 .bcn_count
= cpu_to_le32(beacon_count
),
122 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_BEACON_FILTER_ENABLE
,
126 int wfx_hif_set_operational_mode(struct wfx_dev
*wdev
, enum wfx_hif_op_power_mode mode
)
128 struct wfx_hif_mib_gl_operational_power_mode arg
= {
130 .wup_ind_activation
= 1,
133 return wfx_hif_write_mib(wdev
, -1, HIF_MIB_ID_GL_OPERATIONAL_POWER_MODE
,
137 int wfx_hif_set_template_frame(struct wfx_vif
*wvif
, struct sk_buff
*skb
,
138 u8 frame_type
, int init_rate
)
140 struct wfx_hif_mib_template_frame
*arg
;
142 WARN(skb
->len
> HIF_API_MAX_TEMPLATE_FRAME_SIZE
, "frame is too big");
144 arg
= (struct wfx_hif_mib_template_frame
*)skb
->data
;
146 arg
->init_rate
= init_rate
;
147 arg
->frame_type
= frame_type
;
148 arg
->frame_length
= cpu_to_le16(skb
->len
);
149 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_TEMPLATE_FRAME
,
150 arg
, sizeof(*arg
) + skb
->len
);
153 int wfx_hif_set_mfp(struct wfx_vif
*wvif
, bool capable
, bool required
)
155 struct wfx_hif_mib_protected_mgmt_policy arg
= { };
157 WARN(required
&& !capable
, "incoherent arguments");
160 arg
.host_enc_auth_frames
= 1;
163 arg
.unpmf_allowed
= 1;
164 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_PROTECTED_MGMT_POLICY
,
168 int wfx_hif_set_block_ack_policy(struct wfx_vif
*wvif
, u8 tx_tid_policy
, u8 rx_tid_policy
)
170 struct wfx_hif_mib_block_ack_policy arg
= {
171 .block_ack_tx_tid_policy
= tx_tid_policy
,
172 .block_ack_rx_tid_policy
= rx_tid_policy
,
175 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_BLOCK_ACK_POLICY
,
179 int wfx_hif_set_association_mode(struct wfx_vif
*wvif
, int ampdu_density
,
180 bool greenfield
, bool short_preamble
)
182 struct wfx_hif_mib_set_association_mode arg
= {
186 .short_preamble
= short_preamble
,
187 .greenfield
= greenfield
,
188 .mpdu_start_spacing
= ampdu_density
,
191 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_SET_ASSOCIATION_MODE
,
195 int wfx_hif_set_tx_rate_retry_policy(struct wfx_vif
*wvif
, int policy_index
, u8
*rates
)
197 struct wfx_hif_mib_set_tx_rate_retry_policy
*arg
;
198 size_t size
= struct_size(arg
, tx_rate_retry_policy
, 1);
201 arg
= kzalloc(size
, GFP_KERNEL
);
204 arg
->num_tx_rate_policies
= 1;
205 arg
->tx_rate_retry_policy
[0].policy_index
= policy_index
;
206 arg
->tx_rate_retry_policy
[0].short_retry_count
= 255;
207 arg
->tx_rate_retry_policy
[0].long_retry_count
= 255;
208 arg
->tx_rate_retry_policy
[0].first_rate_sel
= 1;
209 arg
->tx_rate_retry_policy
[0].terminate
= 1;
210 arg
->tx_rate_retry_policy
[0].count_init
= 1;
211 memcpy(&arg
->tx_rate_retry_policy
[0].rates
, rates
,
212 sizeof(arg
->tx_rate_retry_policy
[0].rates
));
213 ret
= wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_SET_TX_RATE_RETRY_POLICY
,
219 int wfx_hif_keep_alive_period(struct wfx_vif
*wvif
, int period
)
221 struct wfx_hif_mib_keep_alive_period arg
= {
222 .keep_alive_period
= cpu_to_le16(period
),
225 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_KEEP_ALIVE_PERIOD
,
229 int wfx_hif_set_arp_ipv4_filter(struct wfx_vif
*wvif
, int idx
, __be32
*addr
)
231 struct wfx_hif_mib_arp_ip_addr_table arg
= {
232 .condition_idx
= idx
,
233 .arp_enable
= HIF_ARP_NS_FILTERING_DISABLE
,
237 /* Caution: type of addr is __be32 */
238 memcpy(arg
.ipv4_address
, addr
, sizeof(arg
.ipv4_address
));
239 arg
.arp_enable
= HIF_ARP_NS_FILTERING_ENABLE
;
241 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_ARP_IP_ADDRESSES_TABLE
,
245 int wfx_hif_use_multi_tx_conf(struct wfx_dev
*wdev
, bool enable
)
247 struct wfx_hif_mib_gl_set_multi_msg arg
= {
248 .enable_multi_tx_conf
= enable
,
251 return wfx_hif_write_mib(wdev
, -1, HIF_MIB_ID_GL_SET_MULTI_MSG
, &arg
, sizeof(arg
));
254 int wfx_hif_set_uapsd_info(struct wfx_vif
*wvif
, unsigned long val
)
256 struct wfx_hif_mib_set_uapsd_information arg
= { };
258 if (val
& BIT(IEEE80211_AC_VO
))
260 if (val
& BIT(IEEE80211_AC_VI
))
262 if (val
& BIT(IEEE80211_AC_BE
))
264 if (val
& BIT(IEEE80211_AC_BK
))
265 arg
.trig_bckgrnd
= 1;
266 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_SET_UAPSD_INFORMATION
,
270 int wfx_hif_erp_use_protection(struct wfx_vif
*wvif
, bool enable
)
272 struct wfx_hif_mib_non_erp_protection arg
= {
273 .use_cts_to_self
= enable
,
276 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_NON_ERP_PROTECTION
,
280 int wfx_hif_slot_time(struct wfx_vif
*wvif
, int val
)
282 struct wfx_hif_mib_slot_time arg
= {
283 .slot_time
= cpu_to_le32(val
),
286 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_SLOT_TIME
, &arg
, sizeof(arg
));
289 int wfx_hif_wep_default_key_id(struct wfx_vif
*wvif
, int val
)
291 struct wfx_hif_mib_wep_default_key_id arg
= {
292 .wep_default_key_id
= val
,
295 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_DOT11_WEP_DEFAULT_KEY_ID
,
299 int wfx_hif_rts_threshold(struct wfx_vif
*wvif
, int val
)
301 struct wfx_hif_mib_dot11_rts_threshold arg
= {
302 .threshold
= cpu_to_le32(val
>= 0 ? val
: 0xFFFF),
305 return wfx_hif_write_mib(wvif
->wdev
, wvif
->id
, HIF_MIB_ID_DOT11_RTS_THRESHOLD
,