1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
4*4882a593Smuzhiyun <http://rt2x00.serialmonkey.com>
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun /*
9*4882a593Smuzhiyun Module: rt2x00mac
10*4882a593Smuzhiyun Abstract: rt2x00 generic mac80211 routines.
11*4882a593Smuzhiyun */
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include <linux/kernel.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include "rt2x00.h"
17*4882a593Smuzhiyun #include "rt2x00lib.h"
18*4882a593Smuzhiyun
rt2x00mac_tx_rts_cts(struct rt2x00_dev * rt2x00dev,struct data_queue * queue,struct sk_buff * frag_skb)19*4882a593Smuzhiyun static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
20*4882a593Smuzhiyun struct data_queue *queue,
21*4882a593Smuzhiyun struct sk_buff *frag_skb)
22*4882a593Smuzhiyun {
23*4882a593Smuzhiyun struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb);
24*4882a593Smuzhiyun struct ieee80211_tx_info *rts_info;
25*4882a593Smuzhiyun struct sk_buff *skb;
26*4882a593Smuzhiyun unsigned int data_length;
27*4882a593Smuzhiyun int retval = 0;
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
30*4882a593Smuzhiyun data_length = sizeof(struct ieee80211_cts);
31*4882a593Smuzhiyun else
32*4882a593Smuzhiyun data_length = sizeof(struct ieee80211_rts);
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun skb = dev_alloc_skb(data_length + rt2x00dev->hw->extra_tx_headroom);
35*4882a593Smuzhiyun if (unlikely(!skb)) {
36*4882a593Smuzhiyun rt2x00_warn(rt2x00dev, "Failed to create RTS/CTS frame\n");
37*4882a593Smuzhiyun return -ENOMEM;
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun skb_reserve(skb, rt2x00dev->hw->extra_tx_headroom);
41*4882a593Smuzhiyun skb_put(skb, data_length);
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun /*
44*4882a593Smuzhiyun * Copy TX information over from original frame to
45*4882a593Smuzhiyun * RTS/CTS frame. Note that we set the no encryption flag
46*4882a593Smuzhiyun * since we don't want this frame to be encrypted.
47*4882a593Smuzhiyun * RTS frames should be acked, while CTS-to-self frames
48*4882a593Smuzhiyun * should not. The ready for TX flag is cleared to prevent
49*4882a593Smuzhiyun * it being automatically send when the descriptor is
50*4882a593Smuzhiyun * written to the hardware.
51*4882a593Smuzhiyun */
52*4882a593Smuzhiyun memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb));
53*4882a593Smuzhiyun rts_info = IEEE80211_SKB_CB(skb);
54*4882a593Smuzhiyun rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_RTS_CTS;
55*4882a593Smuzhiyun rts_info->control.rates[0].flags &= ~IEEE80211_TX_RC_USE_CTS_PROTECT;
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
58*4882a593Smuzhiyun rts_info->flags |= IEEE80211_TX_CTL_NO_ACK;
59*4882a593Smuzhiyun else
60*4882a593Smuzhiyun rts_info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun /* Disable hardware encryption */
63*4882a593Smuzhiyun rts_info->control.hw_key = NULL;
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /*
66*4882a593Smuzhiyun * RTS/CTS frame should use the length of the frame plus any
67*4882a593Smuzhiyun * encryption overhead that will be added by the hardware.
68*4882a593Smuzhiyun */
69*4882a593Smuzhiyun data_length += rt2x00crypto_tx_overhead(rt2x00dev, skb);
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun if (tx_info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
72*4882a593Smuzhiyun ieee80211_ctstoself_get(rt2x00dev->hw, tx_info->control.vif,
73*4882a593Smuzhiyun frag_skb->data, data_length, tx_info,
74*4882a593Smuzhiyun (struct ieee80211_cts *)(skb->data));
75*4882a593Smuzhiyun else
76*4882a593Smuzhiyun ieee80211_rts_get(rt2x00dev->hw, tx_info->control.vif,
77*4882a593Smuzhiyun frag_skb->data, data_length, tx_info,
78*4882a593Smuzhiyun (struct ieee80211_rts *)(skb->data));
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun retval = rt2x00queue_write_tx_frame(queue, skb, NULL, true);
81*4882a593Smuzhiyun if (retval) {
82*4882a593Smuzhiyun dev_kfree_skb_any(skb);
83*4882a593Smuzhiyun rt2x00_warn(rt2x00dev, "Failed to send RTS/CTS frame\n");
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun return retval;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun
rt2x00mac_tx(struct ieee80211_hw * hw,struct ieee80211_tx_control * control,struct sk_buff * skb)89*4882a593Smuzhiyun void rt2x00mac_tx(struct ieee80211_hw *hw,
90*4882a593Smuzhiyun struct ieee80211_tx_control *control,
91*4882a593Smuzhiyun struct sk_buff *skb)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
94*4882a593Smuzhiyun struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
95*4882a593Smuzhiyun enum data_queue_qid qid = skb_get_queue_mapping(skb);
96*4882a593Smuzhiyun struct data_queue *queue = NULL;
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /*
99*4882a593Smuzhiyun * Mac80211 might be calling this function while we are trying
100*4882a593Smuzhiyun * to remove the device or perhaps suspending it.
101*4882a593Smuzhiyun * Note that we can only stop the TX queues inside the TX path
102*4882a593Smuzhiyun * due to possible race conditions in mac80211.
103*4882a593Smuzhiyun */
104*4882a593Smuzhiyun if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
105*4882a593Smuzhiyun goto exit_free_skb;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun /*
108*4882a593Smuzhiyun * Use the ATIM queue if appropriate and present.
109*4882a593Smuzhiyun */
110*4882a593Smuzhiyun if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
111*4882a593Smuzhiyun rt2x00_has_cap_flag(rt2x00dev, REQUIRE_ATIM_QUEUE))
112*4882a593Smuzhiyun qid = QID_ATIM;
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
115*4882a593Smuzhiyun if (unlikely(!queue)) {
116*4882a593Smuzhiyun rt2x00_err(rt2x00dev,
117*4882a593Smuzhiyun "Attempt to send packet over invalid queue %d\n"
118*4882a593Smuzhiyun "Please file bug report to %s\n", qid, DRV_PROJECT);
119*4882a593Smuzhiyun goto exit_free_skb;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun /*
123*4882a593Smuzhiyun * If CTS/RTS is required. create and queue that frame first.
124*4882a593Smuzhiyun * Make sure we have at least enough entries available to send
125*4882a593Smuzhiyun * this CTS/RTS frame as well as the data frame.
126*4882a593Smuzhiyun * Note that when the driver has set the set_rts_threshold()
127*4882a593Smuzhiyun * callback function it doesn't need software generation of
128*4882a593Smuzhiyun * either RTS or CTS-to-self frame and handles everything
129*4882a593Smuzhiyun * inside the hardware.
130*4882a593Smuzhiyun */
131*4882a593Smuzhiyun if (!rt2x00dev->ops->hw->set_rts_threshold &&
132*4882a593Smuzhiyun (tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS |
133*4882a593Smuzhiyun IEEE80211_TX_RC_USE_CTS_PROTECT))) {
134*4882a593Smuzhiyun if (rt2x00queue_available(queue) <= 1) {
135*4882a593Smuzhiyun /*
136*4882a593Smuzhiyun * Recheck for full queue under lock to avoid race
137*4882a593Smuzhiyun * conditions with rt2x00lib_txdone().
138*4882a593Smuzhiyun */
139*4882a593Smuzhiyun spin_lock(&queue->tx_lock);
140*4882a593Smuzhiyun if (rt2x00queue_threshold(queue))
141*4882a593Smuzhiyun rt2x00queue_pause_queue(queue);
142*4882a593Smuzhiyun spin_unlock(&queue->tx_lock);
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun goto exit_free_skb;
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun if (rt2x00mac_tx_rts_cts(rt2x00dev, queue, skb))
148*4882a593Smuzhiyun goto exit_free_skb;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun if (unlikely(rt2x00queue_write_tx_frame(queue, skb, control->sta, false)))
152*4882a593Smuzhiyun goto exit_free_skb;
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun return;
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun exit_free_skb:
157*4882a593Smuzhiyun ieee80211_free_txskb(hw, skb);
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_tx);
160*4882a593Smuzhiyun
rt2x00mac_start(struct ieee80211_hw * hw)161*4882a593Smuzhiyun int rt2x00mac_start(struct ieee80211_hw *hw)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
166*4882a593Smuzhiyun return 0;
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun if (test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) {
169*4882a593Smuzhiyun /*
170*4882a593Smuzhiyun * This is special case for ieee80211_restart_hw(), otherwise
171*4882a593Smuzhiyun * mac80211 never call start() two times in row without stop();
172*4882a593Smuzhiyun */
173*4882a593Smuzhiyun set_bit(DEVICE_STATE_RESET, &rt2x00dev->flags);
174*4882a593Smuzhiyun rt2x00dev->ops->lib->pre_reset_hw(rt2x00dev);
175*4882a593Smuzhiyun rt2x00lib_stop(rt2x00dev);
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun return rt2x00lib_start(rt2x00dev);
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_start);
180*4882a593Smuzhiyun
rt2x00mac_stop(struct ieee80211_hw * hw)181*4882a593Smuzhiyun void rt2x00mac_stop(struct ieee80211_hw *hw)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
186*4882a593Smuzhiyun return;
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun rt2x00lib_stop(rt2x00dev);
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_stop);
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun void
rt2x00mac_reconfig_complete(struct ieee80211_hw * hw,enum ieee80211_reconfig_type reconfig_type)193*4882a593Smuzhiyun rt2x00mac_reconfig_complete(struct ieee80211_hw *hw,
194*4882a593Smuzhiyun enum ieee80211_reconfig_type reconfig_type)
195*4882a593Smuzhiyun {
196*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun if (reconfig_type == IEEE80211_RECONFIG_TYPE_RESTART)
199*4882a593Smuzhiyun clear_bit(DEVICE_STATE_RESET, &rt2x00dev->flags);
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_reconfig_complete);
202*4882a593Smuzhiyun
rt2x00mac_add_interface(struct ieee80211_hw * hw,struct ieee80211_vif * vif)203*4882a593Smuzhiyun int rt2x00mac_add_interface(struct ieee80211_hw *hw,
204*4882a593Smuzhiyun struct ieee80211_vif *vif)
205*4882a593Smuzhiyun {
206*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
207*4882a593Smuzhiyun struct rt2x00_intf *intf = vif_to_intf(vif);
208*4882a593Smuzhiyun struct data_queue *queue = rt2x00dev->bcn;
209*4882a593Smuzhiyun struct queue_entry *entry = NULL;
210*4882a593Smuzhiyun unsigned int i;
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun /*
213*4882a593Smuzhiyun * Don't allow interfaces to be added
214*4882a593Smuzhiyun * the device has disappeared.
215*4882a593Smuzhiyun */
216*4882a593Smuzhiyun if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
217*4882a593Smuzhiyun !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
218*4882a593Smuzhiyun return -ENODEV;
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun /*
221*4882a593Smuzhiyun * Loop through all beacon queues to find a free
222*4882a593Smuzhiyun * entry. Since there are as much beacon entries
223*4882a593Smuzhiyun * as the maximum interfaces, this search shouldn't
224*4882a593Smuzhiyun * fail.
225*4882a593Smuzhiyun */
226*4882a593Smuzhiyun for (i = 0; i < queue->limit; i++) {
227*4882a593Smuzhiyun entry = &queue->entries[i];
228*4882a593Smuzhiyun if (!test_and_set_bit(ENTRY_BCN_ASSIGNED, &entry->flags))
229*4882a593Smuzhiyun break;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun if (unlikely(i == queue->limit))
233*4882a593Smuzhiyun return -ENOBUFS;
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun /*
236*4882a593Smuzhiyun * We are now absolutely sure the interface can be created,
237*4882a593Smuzhiyun * increase interface count and start initialization.
238*4882a593Smuzhiyun */
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun if (vif->type == NL80211_IFTYPE_AP)
241*4882a593Smuzhiyun rt2x00dev->intf_ap_count++;
242*4882a593Smuzhiyun else
243*4882a593Smuzhiyun rt2x00dev->intf_sta_count++;
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun mutex_init(&intf->beacon_skb_mutex);
246*4882a593Smuzhiyun intf->beacon = entry;
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun /*
249*4882a593Smuzhiyun * The MAC address must be configured after the device
250*4882a593Smuzhiyun * has been initialized. Otherwise the device can reset
251*4882a593Smuzhiyun * the MAC registers.
252*4882a593Smuzhiyun * The BSSID address must only be configured in AP mode,
253*4882a593Smuzhiyun * however we should not send an empty BSSID address for
254*4882a593Smuzhiyun * STA interfaces at this time, since this can cause
255*4882a593Smuzhiyun * invalid behavior in the device.
256*4882a593Smuzhiyun */
257*4882a593Smuzhiyun rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
258*4882a593Smuzhiyun vif->addr, NULL);
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun /*
261*4882a593Smuzhiyun * Some filters depend on the current working mode. We can force
262*4882a593Smuzhiyun * an update during the next configure_filter() run by mac80211 by
263*4882a593Smuzhiyun * resetting the current packet_filter state.
264*4882a593Smuzhiyun */
265*4882a593Smuzhiyun rt2x00dev->packet_filter = 0;
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun return 0;
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_add_interface);
270*4882a593Smuzhiyun
rt2x00mac_remove_interface(struct ieee80211_hw * hw,struct ieee80211_vif * vif)271*4882a593Smuzhiyun void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
272*4882a593Smuzhiyun struct ieee80211_vif *vif)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
275*4882a593Smuzhiyun struct rt2x00_intf *intf = vif_to_intf(vif);
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun /*
278*4882a593Smuzhiyun * Don't allow interfaces to be remove while
279*4882a593Smuzhiyun * either the device has disappeared or when
280*4882a593Smuzhiyun * no interface is present.
281*4882a593Smuzhiyun */
282*4882a593Smuzhiyun if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
283*4882a593Smuzhiyun (vif->type == NL80211_IFTYPE_AP && !rt2x00dev->intf_ap_count) ||
284*4882a593Smuzhiyun (vif->type != NL80211_IFTYPE_AP && !rt2x00dev->intf_sta_count))
285*4882a593Smuzhiyun return;
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun if (vif->type == NL80211_IFTYPE_AP)
288*4882a593Smuzhiyun rt2x00dev->intf_ap_count--;
289*4882a593Smuzhiyun else
290*4882a593Smuzhiyun rt2x00dev->intf_sta_count--;
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun /*
293*4882a593Smuzhiyun * Release beacon entry so it is available for
294*4882a593Smuzhiyun * new interfaces again.
295*4882a593Smuzhiyun */
296*4882a593Smuzhiyun clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags);
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun /*
299*4882a593Smuzhiyun * Make sure the bssid and mac address registers
300*4882a593Smuzhiyun * are cleared to prevent false ACKing of frames.
301*4882a593Smuzhiyun */
302*4882a593Smuzhiyun rt2x00lib_config_intf(rt2x00dev, intf,
303*4882a593Smuzhiyun NL80211_IFTYPE_UNSPECIFIED, NULL, NULL);
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface);
306*4882a593Smuzhiyun
rt2x00mac_config(struct ieee80211_hw * hw,u32 changed)307*4882a593Smuzhiyun int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
308*4882a593Smuzhiyun {
309*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
310*4882a593Smuzhiyun struct ieee80211_conf *conf = &hw->conf;
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun /*
313*4882a593Smuzhiyun * mac80211 might be calling this function while we are trying
314*4882a593Smuzhiyun * to remove the device or perhaps suspending it.
315*4882a593Smuzhiyun */
316*4882a593Smuzhiyun if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
317*4882a593Smuzhiyun return 0;
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun /*
320*4882a593Smuzhiyun * Some configuration parameters (e.g. channel and antenna values) can
321*4882a593Smuzhiyun * only be set when the radio is enabled, but do require the RX to
322*4882a593Smuzhiyun * be off. During this period we should keep link tuning enabled,
323*4882a593Smuzhiyun * if for any reason the link tuner must be reset, this will be
324*4882a593Smuzhiyun * handled by rt2x00lib_config().
325*4882a593Smuzhiyun */
326*4882a593Smuzhiyun rt2x00queue_stop_queue(rt2x00dev->rx);
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun /* Do not race with with link tuner. */
329*4882a593Smuzhiyun mutex_lock(&rt2x00dev->conf_mutex);
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun /*
332*4882a593Smuzhiyun * When we've just turned on the radio, we want to reprogram
333*4882a593Smuzhiyun * everything to ensure a consistent state
334*4882a593Smuzhiyun */
335*4882a593Smuzhiyun rt2x00lib_config(rt2x00dev, conf, changed);
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun /*
338*4882a593Smuzhiyun * After the radio has been enabled we need to configure
339*4882a593Smuzhiyun * the antenna to the default settings. rt2x00lib_config_antenna()
340*4882a593Smuzhiyun * should determine if any action should be taken based on
341*4882a593Smuzhiyun * checking if diversity has been enabled or no antenna changes
342*4882a593Smuzhiyun * have been made since the last configuration change.
343*4882a593Smuzhiyun */
344*4882a593Smuzhiyun rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant);
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun mutex_unlock(&rt2x00dev->conf_mutex);
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun /* Turn RX back on */
349*4882a593Smuzhiyun rt2x00queue_start_queue(rt2x00dev->rx);
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun return 0;
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_config);
354*4882a593Smuzhiyun
rt2x00mac_configure_filter(struct ieee80211_hw * hw,unsigned int changed_flags,unsigned int * total_flags,u64 multicast)355*4882a593Smuzhiyun void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
356*4882a593Smuzhiyun unsigned int changed_flags,
357*4882a593Smuzhiyun unsigned int *total_flags,
358*4882a593Smuzhiyun u64 multicast)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun /*
363*4882a593Smuzhiyun * Mask off any flags we are going to ignore
364*4882a593Smuzhiyun * from the total_flags field.
365*4882a593Smuzhiyun */
366*4882a593Smuzhiyun *total_flags &=
367*4882a593Smuzhiyun FIF_ALLMULTI |
368*4882a593Smuzhiyun FIF_FCSFAIL |
369*4882a593Smuzhiyun FIF_PLCPFAIL |
370*4882a593Smuzhiyun FIF_CONTROL |
371*4882a593Smuzhiyun FIF_PSPOLL |
372*4882a593Smuzhiyun FIF_OTHER_BSS;
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun /*
375*4882a593Smuzhiyun * Apply some rules to the filters:
376*4882a593Smuzhiyun * - Some filters imply different filters to be set.
377*4882a593Smuzhiyun * - Some things we can't filter out at all.
378*4882a593Smuzhiyun * - Multicast filter seems to kill broadcast traffic so never use it.
379*4882a593Smuzhiyun */
380*4882a593Smuzhiyun *total_flags |= FIF_ALLMULTI;
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun /*
383*4882a593Smuzhiyun * If the device has a single filter for all control frames,
384*4882a593Smuzhiyun * FIF_CONTROL and FIF_PSPOLL flags imply each other.
385*4882a593Smuzhiyun * And if the device has more than one filter for control frames
386*4882a593Smuzhiyun * of different types, but has no a separate filter for PS Poll frames,
387*4882a593Smuzhiyun * FIF_CONTROL flag implies FIF_PSPOLL.
388*4882a593Smuzhiyun */
389*4882a593Smuzhiyun if (!rt2x00_has_cap_control_filters(rt2x00dev)) {
390*4882a593Smuzhiyun if (*total_flags & FIF_CONTROL || *total_flags & FIF_PSPOLL)
391*4882a593Smuzhiyun *total_flags |= FIF_CONTROL | FIF_PSPOLL;
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun if (!rt2x00_has_cap_control_filter_pspoll(rt2x00dev)) {
394*4882a593Smuzhiyun if (*total_flags & FIF_CONTROL)
395*4882a593Smuzhiyun *total_flags |= FIF_PSPOLL;
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun rt2x00dev->packet_filter = *total_flags;
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
403*4882a593Smuzhiyun
rt2x00mac_set_tim_iter(void * data,u8 * mac,struct ieee80211_vif * vif)404*4882a593Smuzhiyun static void rt2x00mac_set_tim_iter(void *data, u8 *mac,
405*4882a593Smuzhiyun struct ieee80211_vif *vif)
406*4882a593Smuzhiyun {
407*4882a593Smuzhiyun struct rt2x00_intf *intf = vif_to_intf(vif);
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun if (vif->type != NL80211_IFTYPE_AP &&
410*4882a593Smuzhiyun vif->type != NL80211_IFTYPE_ADHOC &&
411*4882a593Smuzhiyun vif->type != NL80211_IFTYPE_MESH_POINT &&
412*4882a593Smuzhiyun vif->type != NL80211_IFTYPE_WDS)
413*4882a593Smuzhiyun return;
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun set_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags);
416*4882a593Smuzhiyun }
417*4882a593Smuzhiyun
rt2x00mac_set_tim(struct ieee80211_hw * hw,struct ieee80211_sta * sta,bool set)418*4882a593Smuzhiyun int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
419*4882a593Smuzhiyun bool set)
420*4882a593Smuzhiyun {
421*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
424*4882a593Smuzhiyun return 0;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun ieee80211_iterate_active_interfaces_atomic(
427*4882a593Smuzhiyun rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
428*4882a593Smuzhiyun rt2x00mac_set_tim_iter, rt2x00dev);
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun /* queue work to upodate the beacon template */
431*4882a593Smuzhiyun ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work);
432*4882a593Smuzhiyun return 0;
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_set_tim);
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun #ifdef CONFIG_RT2X00_LIB_CRYPTO
memcpy_tkip(struct rt2x00lib_crypto * crypto,u8 * key,u8 key_len)437*4882a593Smuzhiyun static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len)
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun if (key_len > NL80211_TKIP_DATA_OFFSET_ENCR_KEY)
440*4882a593Smuzhiyun memcpy(crypto->key,
441*4882a593Smuzhiyun &key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY],
442*4882a593Smuzhiyun sizeof(crypto->key));
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun if (key_len > NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY)
445*4882a593Smuzhiyun memcpy(crypto->tx_mic,
446*4882a593Smuzhiyun &key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY],
447*4882a593Smuzhiyun sizeof(crypto->tx_mic));
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun if (key_len > NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY)
450*4882a593Smuzhiyun memcpy(crypto->rx_mic,
451*4882a593Smuzhiyun &key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY],
452*4882a593Smuzhiyun sizeof(crypto->rx_mic));
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun
rt2x00mac_set_key(struct ieee80211_hw * hw,enum set_key_cmd cmd,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_key_conf * key)455*4882a593Smuzhiyun int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
456*4882a593Smuzhiyun struct ieee80211_vif *vif, struct ieee80211_sta *sta,
457*4882a593Smuzhiyun struct ieee80211_key_conf *key)
458*4882a593Smuzhiyun {
459*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
460*4882a593Smuzhiyun int (*set_key) (struct rt2x00_dev *rt2x00dev,
461*4882a593Smuzhiyun struct rt2x00lib_crypto *crypto,
462*4882a593Smuzhiyun struct ieee80211_key_conf *key);
463*4882a593Smuzhiyun struct rt2x00lib_crypto crypto;
464*4882a593Smuzhiyun static const u8 bcast_addr[ETH_ALEN] =
465*4882a593Smuzhiyun { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, };
466*4882a593Smuzhiyun struct rt2x00_sta *sta_priv = NULL;
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
469*4882a593Smuzhiyun return 0;
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun /* The hardware can't do MFP */
472*4882a593Smuzhiyun if (!rt2x00_has_cap_hw_crypto(rt2x00dev) || (sta && sta->mfp))
473*4882a593Smuzhiyun return -EOPNOTSUPP;
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun /*
476*4882a593Smuzhiyun * To support IBSS RSN, don't program group keys in IBSS, the
477*4882a593Smuzhiyun * hardware will then not attempt to decrypt the frames.
478*4882a593Smuzhiyun */
479*4882a593Smuzhiyun if (vif->type == NL80211_IFTYPE_ADHOC &&
480*4882a593Smuzhiyun !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
481*4882a593Smuzhiyun return -EOPNOTSUPP;
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun if (key->keylen > 32)
484*4882a593Smuzhiyun return -ENOSPC;
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun memset(&crypto, 0, sizeof(crypto));
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun crypto.bssidx = rt2x00lib_get_bssidx(rt2x00dev, vif);
489*4882a593Smuzhiyun crypto.cipher = rt2x00crypto_key_to_cipher(key);
490*4882a593Smuzhiyun if (crypto.cipher == CIPHER_NONE)
491*4882a593Smuzhiyun return -EOPNOTSUPP;
492*4882a593Smuzhiyun if (crypto.cipher == CIPHER_TKIP && rt2x00_is_usb(rt2x00dev))
493*4882a593Smuzhiyun return -EOPNOTSUPP;
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun crypto.cmd = cmd;
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun if (sta) {
498*4882a593Smuzhiyun crypto.address = sta->addr;
499*4882a593Smuzhiyun sta_priv = sta_to_rt2x00_sta(sta);
500*4882a593Smuzhiyun crypto.wcid = sta_priv->wcid;
501*4882a593Smuzhiyun } else
502*4882a593Smuzhiyun crypto.address = bcast_addr;
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun if (crypto.cipher == CIPHER_TKIP)
505*4882a593Smuzhiyun memcpy_tkip(&crypto, &key->key[0], key->keylen);
506*4882a593Smuzhiyun else
507*4882a593Smuzhiyun memcpy(crypto.key, &key->key[0], key->keylen);
508*4882a593Smuzhiyun /*
509*4882a593Smuzhiyun * Each BSS has a maximum of 4 shared keys.
510*4882a593Smuzhiyun * Shared key index values:
511*4882a593Smuzhiyun * 0) BSS0 key0
512*4882a593Smuzhiyun * 1) BSS0 key1
513*4882a593Smuzhiyun * ...
514*4882a593Smuzhiyun * 4) BSS1 key0
515*4882a593Smuzhiyun * ...
516*4882a593Smuzhiyun * 8) BSS2 key0
517*4882a593Smuzhiyun * ...
518*4882a593Smuzhiyun * Both pairwise as shared key indeces are determined by
519*4882a593Smuzhiyun * driver. This is required because the hardware requires
520*4882a593Smuzhiyun * keys to be assigned in correct order (When key 1 is
521*4882a593Smuzhiyun * provided but key 0 is not, then the key is not found
522*4882a593Smuzhiyun * by the hardware during RX).
523*4882a593Smuzhiyun */
524*4882a593Smuzhiyun if (cmd == SET_KEY)
525*4882a593Smuzhiyun key->hw_key_idx = 0;
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
528*4882a593Smuzhiyun set_key = rt2x00dev->ops->lib->config_pairwise_key;
529*4882a593Smuzhiyun else
530*4882a593Smuzhiyun set_key = rt2x00dev->ops->lib->config_shared_key;
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun if (!set_key)
533*4882a593Smuzhiyun return -EOPNOTSUPP;
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun return set_key(rt2x00dev, &crypto, key);
536*4882a593Smuzhiyun }
537*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_set_key);
538*4882a593Smuzhiyun #endif /* CONFIG_RT2X00_LIB_CRYPTO */
539*4882a593Smuzhiyun
rt2x00mac_sw_scan_start(struct ieee80211_hw * hw,struct ieee80211_vif * vif,const u8 * mac_addr)540*4882a593Smuzhiyun void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw,
541*4882a593Smuzhiyun struct ieee80211_vif *vif,
542*4882a593Smuzhiyun const u8 *mac_addr)
543*4882a593Smuzhiyun {
544*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
545*4882a593Smuzhiyun set_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
546*4882a593Smuzhiyun rt2x00link_stop_tuner(rt2x00dev);
547*4882a593Smuzhiyun }
548*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_start);
549*4882a593Smuzhiyun
rt2x00mac_sw_scan_complete(struct ieee80211_hw * hw,struct ieee80211_vif * vif)550*4882a593Smuzhiyun void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw,
551*4882a593Smuzhiyun struct ieee80211_vif *vif)
552*4882a593Smuzhiyun {
553*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
554*4882a593Smuzhiyun clear_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
555*4882a593Smuzhiyun rt2x00link_start_tuner(rt2x00dev);
556*4882a593Smuzhiyun }
557*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_complete);
558*4882a593Smuzhiyun
rt2x00mac_get_stats(struct ieee80211_hw * hw,struct ieee80211_low_level_stats * stats)559*4882a593Smuzhiyun int rt2x00mac_get_stats(struct ieee80211_hw *hw,
560*4882a593Smuzhiyun struct ieee80211_low_level_stats *stats)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun /*
565*4882a593Smuzhiyun * The dot11ACKFailureCount, dot11RTSFailureCount and
566*4882a593Smuzhiyun * dot11RTSSuccessCount are updated in interrupt time.
567*4882a593Smuzhiyun * dot11FCSErrorCount is updated in the link tuner.
568*4882a593Smuzhiyun */
569*4882a593Smuzhiyun memcpy(stats, &rt2x00dev->low_level_stats, sizeof(*stats));
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun return 0;
572*4882a593Smuzhiyun }
573*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_get_stats);
574*4882a593Smuzhiyun
rt2x00mac_bss_info_changed(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_bss_conf * bss_conf,u32 changes)575*4882a593Smuzhiyun void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
576*4882a593Smuzhiyun struct ieee80211_vif *vif,
577*4882a593Smuzhiyun struct ieee80211_bss_conf *bss_conf,
578*4882a593Smuzhiyun u32 changes)
579*4882a593Smuzhiyun {
580*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
581*4882a593Smuzhiyun struct rt2x00_intf *intf = vif_to_intf(vif);
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun /*
584*4882a593Smuzhiyun * mac80211 might be calling this function while we are trying
585*4882a593Smuzhiyun * to remove the device or perhaps suspending it.
586*4882a593Smuzhiyun */
587*4882a593Smuzhiyun if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
588*4882a593Smuzhiyun return;
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun /*
591*4882a593Smuzhiyun * Update the BSSID.
592*4882a593Smuzhiyun */
593*4882a593Smuzhiyun if (changes & BSS_CHANGED_BSSID)
594*4882a593Smuzhiyun rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
595*4882a593Smuzhiyun bss_conf->bssid);
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun /*
598*4882a593Smuzhiyun * Start/stop beaconing.
599*4882a593Smuzhiyun */
600*4882a593Smuzhiyun if (changes & BSS_CHANGED_BEACON_ENABLED) {
601*4882a593Smuzhiyun mutex_lock(&intf->beacon_skb_mutex);
602*4882a593Smuzhiyun if (!bss_conf->enable_beacon && intf->enable_beacon) {
603*4882a593Smuzhiyun rt2x00dev->intf_beaconing--;
604*4882a593Smuzhiyun intf->enable_beacon = false;
605*4882a593Smuzhiyun
606*4882a593Smuzhiyun if (rt2x00dev->intf_beaconing == 0) {
607*4882a593Smuzhiyun /*
608*4882a593Smuzhiyun * Last beaconing interface disabled
609*4882a593Smuzhiyun * -> stop beacon queue.
610*4882a593Smuzhiyun */
611*4882a593Smuzhiyun rt2x00queue_stop_queue(rt2x00dev->bcn);
612*4882a593Smuzhiyun }
613*4882a593Smuzhiyun /*
614*4882a593Smuzhiyun * Clear beacon in the H/W for this vif. This is needed
615*4882a593Smuzhiyun * to disable beaconing on this particular interface
616*4882a593Smuzhiyun * and keep it running on other interfaces.
617*4882a593Smuzhiyun */
618*4882a593Smuzhiyun rt2x00queue_clear_beacon(rt2x00dev, vif);
619*4882a593Smuzhiyun } else if (bss_conf->enable_beacon && !intf->enable_beacon) {
620*4882a593Smuzhiyun rt2x00dev->intf_beaconing++;
621*4882a593Smuzhiyun intf->enable_beacon = true;
622*4882a593Smuzhiyun /*
623*4882a593Smuzhiyun * Upload beacon to the H/W. This is only required on
624*4882a593Smuzhiyun * USB devices. PCI devices fetch beacons periodically.
625*4882a593Smuzhiyun */
626*4882a593Smuzhiyun if (rt2x00_is_usb(rt2x00dev))
627*4882a593Smuzhiyun rt2x00queue_update_beacon(rt2x00dev, vif);
628*4882a593Smuzhiyun
629*4882a593Smuzhiyun if (rt2x00dev->intf_beaconing == 1) {
630*4882a593Smuzhiyun /*
631*4882a593Smuzhiyun * First beaconing interface enabled
632*4882a593Smuzhiyun * -> start beacon queue.
633*4882a593Smuzhiyun */
634*4882a593Smuzhiyun rt2x00queue_start_queue(rt2x00dev->bcn);
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun mutex_unlock(&intf->beacon_skb_mutex);
638*4882a593Smuzhiyun }
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun /*
641*4882a593Smuzhiyun * When the association status has changed we must reset the link
642*4882a593Smuzhiyun * tuner counter. This is because some drivers determine if they
643*4882a593Smuzhiyun * should perform link tuning based on the number of seconds
644*4882a593Smuzhiyun * while associated or not associated.
645*4882a593Smuzhiyun */
646*4882a593Smuzhiyun if (changes & BSS_CHANGED_ASSOC) {
647*4882a593Smuzhiyun rt2x00dev->link.count = 0;
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun if (bss_conf->assoc)
650*4882a593Smuzhiyun rt2x00dev->intf_associated++;
651*4882a593Smuzhiyun else
652*4882a593Smuzhiyun rt2x00dev->intf_associated--;
653*4882a593Smuzhiyun
654*4882a593Smuzhiyun rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);
655*4882a593Smuzhiyun }
656*4882a593Smuzhiyun
657*4882a593Smuzhiyun /*
658*4882a593Smuzhiyun * When the erp information has changed, we should perform
659*4882a593Smuzhiyun * additional configuration steps. For all other changes we are done.
660*4882a593Smuzhiyun */
661*4882a593Smuzhiyun if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE |
662*4882a593Smuzhiyun BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES |
663*4882a593Smuzhiyun BSS_CHANGED_BEACON_INT | BSS_CHANGED_HT))
664*4882a593Smuzhiyun rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes);
665*4882a593Smuzhiyun }
666*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
667*4882a593Smuzhiyun
rt2x00mac_conf_tx(struct ieee80211_hw * hw,struct ieee80211_vif * vif,u16 queue_idx,const struct ieee80211_tx_queue_params * params)668*4882a593Smuzhiyun int rt2x00mac_conf_tx(struct ieee80211_hw *hw,
669*4882a593Smuzhiyun struct ieee80211_vif *vif, u16 queue_idx,
670*4882a593Smuzhiyun const struct ieee80211_tx_queue_params *params)
671*4882a593Smuzhiyun {
672*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
673*4882a593Smuzhiyun struct data_queue *queue;
674*4882a593Smuzhiyun
675*4882a593Smuzhiyun queue = rt2x00queue_get_tx_queue(rt2x00dev, queue_idx);
676*4882a593Smuzhiyun if (unlikely(!queue))
677*4882a593Smuzhiyun return -EINVAL;
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun /*
680*4882a593Smuzhiyun * The passed variables are stored as real value ((2^n)-1).
681*4882a593Smuzhiyun * Ralink registers require to know the bit number 'n'.
682*4882a593Smuzhiyun */
683*4882a593Smuzhiyun if (params->cw_min > 0)
684*4882a593Smuzhiyun queue->cw_min = fls(params->cw_min);
685*4882a593Smuzhiyun else
686*4882a593Smuzhiyun queue->cw_min = 5; /* cw_min: 2^5 = 32. */
687*4882a593Smuzhiyun
688*4882a593Smuzhiyun if (params->cw_max > 0)
689*4882a593Smuzhiyun queue->cw_max = fls(params->cw_max);
690*4882a593Smuzhiyun else
691*4882a593Smuzhiyun queue->cw_max = 10; /* cw_min: 2^10 = 1024. */
692*4882a593Smuzhiyun
693*4882a593Smuzhiyun queue->aifs = params->aifs;
694*4882a593Smuzhiyun queue->txop = params->txop;
695*4882a593Smuzhiyun
696*4882a593Smuzhiyun rt2x00_dbg(rt2x00dev,
697*4882a593Smuzhiyun "Configured TX queue %d - CWmin: %d, CWmax: %d, Aifs: %d, TXop: %d\n",
698*4882a593Smuzhiyun queue_idx, queue->cw_min, queue->cw_max, queue->aifs,
699*4882a593Smuzhiyun queue->txop);
700*4882a593Smuzhiyun
701*4882a593Smuzhiyun return 0;
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_conf_tx);
704*4882a593Smuzhiyun
rt2x00mac_rfkill_poll(struct ieee80211_hw * hw)705*4882a593Smuzhiyun void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw)
706*4882a593Smuzhiyun {
707*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
708*4882a593Smuzhiyun bool active = !!rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
709*4882a593Smuzhiyun
710*4882a593Smuzhiyun wiphy_rfkill_set_hw_state(hw->wiphy, !active);
711*4882a593Smuzhiyun }
712*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
713*4882a593Smuzhiyun
rt2x00mac_flush(struct ieee80211_hw * hw,struct ieee80211_vif * vif,u32 queues,bool drop)714*4882a593Smuzhiyun void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
715*4882a593Smuzhiyun u32 queues, bool drop)
716*4882a593Smuzhiyun {
717*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
718*4882a593Smuzhiyun struct data_queue *queue;
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
721*4882a593Smuzhiyun return;
722*4882a593Smuzhiyun
723*4882a593Smuzhiyun set_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags);
724*4882a593Smuzhiyun
725*4882a593Smuzhiyun tx_queue_for_each(rt2x00dev, queue)
726*4882a593Smuzhiyun rt2x00queue_flush_queue(queue, drop);
727*4882a593Smuzhiyun
728*4882a593Smuzhiyun clear_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags);
729*4882a593Smuzhiyun }
730*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_flush);
731*4882a593Smuzhiyun
rt2x00mac_set_antenna(struct ieee80211_hw * hw,u32 tx_ant,u32 rx_ant)732*4882a593Smuzhiyun int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
733*4882a593Smuzhiyun {
734*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
735*4882a593Smuzhiyun struct link_ant *ant = &rt2x00dev->link.ant;
736*4882a593Smuzhiyun struct antenna_setup *def = &rt2x00dev->default_ant;
737*4882a593Smuzhiyun struct antenna_setup setup;
738*4882a593Smuzhiyun
739*4882a593Smuzhiyun // The antenna value is not supposed to be 0,
740*4882a593Smuzhiyun // or exceed the maximum number of antenna's.
741*4882a593Smuzhiyun if (!tx_ant || (tx_ant & ~3) || !rx_ant || (rx_ant & ~3))
742*4882a593Smuzhiyun return -EINVAL;
743*4882a593Smuzhiyun
744*4882a593Smuzhiyun // When the client tried to configure the antenna to or from
745*4882a593Smuzhiyun // diversity mode, we must reset the default antenna as well
746*4882a593Smuzhiyun // as that controls the diversity switch.
747*4882a593Smuzhiyun if (ant->flags & ANTENNA_TX_DIVERSITY && tx_ant != 3)
748*4882a593Smuzhiyun ant->flags &= ~ANTENNA_TX_DIVERSITY;
749*4882a593Smuzhiyun if (ant->flags & ANTENNA_RX_DIVERSITY && rx_ant != 3)
750*4882a593Smuzhiyun ant->flags &= ~ANTENNA_RX_DIVERSITY;
751*4882a593Smuzhiyun
752*4882a593Smuzhiyun // If diversity is being enabled, check if we need hardware
753*4882a593Smuzhiyun // or software diversity. In the latter case, reset the value,
754*4882a593Smuzhiyun // and make sure we update the antenna flags to have the
755*4882a593Smuzhiyun // link tuner pick up the diversity tuning.
756*4882a593Smuzhiyun if (tx_ant == 3 && def->tx == ANTENNA_SW_DIVERSITY) {
757*4882a593Smuzhiyun tx_ant = ANTENNA_SW_DIVERSITY;
758*4882a593Smuzhiyun ant->flags |= ANTENNA_TX_DIVERSITY;
759*4882a593Smuzhiyun }
760*4882a593Smuzhiyun
761*4882a593Smuzhiyun if (rx_ant == 3 && def->rx == ANTENNA_SW_DIVERSITY) {
762*4882a593Smuzhiyun rx_ant = ANTENNA_SW_DIVERSITY;
763*4882a593Smuzhiyun ant->flags |= ANTENNA_RX_DIVERSITY;
764*4882a593Smuzhiyun }
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun setup.tx = tx_ant;
767*4882a593Smuzhiyun setup.rx = rx_ant;
768*4882a593Smuzhiyun setup.rx_chain_num = 0;
769*4882a593Smuzhiyun setup.tx_chain_num = 0;
770*4882a593Smuzhiyun
771*4882a593Smuzhiyun rt2x00lib_config_antenna(rt2x00dev, setup);
772*4882a593Smuzhiyun
773*4882a593Smuzhiyun return 0;
774*4882a593Smuzhiyun }
775*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_set_antenna);
776*4882a593Smuzhiyun
rt2x00mac_get_antenna(struct ieee80211_hw * hw,u32 * tx_ant,u32 * rx_ant)777*4882a593Smuzhiyun int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
778*4882a593Smuzhiyun {
779*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
780*4882a593Smuzhiyun struct link_ant *ant = &rt2x00dev->link.ant;
781*4882a593Smuzhiyun struct antenna_setup *active = &rt2x00dev->link.ant.active;
782*4882a593Smuzhiyun
783*4882a593Smuzhiyun // When software diversity is active, we must report this to the
784*4882a593Smuzhiyun // client and not the current active antenna state.
785*4882a593Smuzhiyun if (ant->flags & ANTENNA_TX_DIVERSITY)
786*4882a593Smuzhiyun *tx_ant = ANTENNA_HW_DIVERSITY;
787*4882a593Smuzhiyun else
788*4882a593Smuzhiyun *tx_ant = active->tx;
789*4882a593Smuzhiyun
790*4882a593Smuzhiyun if (ant->flags & ANTENNA_RX_DIVERSITY)
791*4882a593Smuzhiyun *rx_ant = ANTENNA_HW_DIVERSITY;
792*4882a593Smuzhiyun else
793*4882a593Smuzhiyun *rx_ant = active->rx;
794*4882a593Smuzhiyun
795*4882a593Smuzhiyun return 0;
796*4882a593Smuzhiyun }
797*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_get_antenna);
798*4882a593Smuzhiyun
rt2x00mac_get_ringparam(struct ieee80211_hw * hw,u32 * tx,u32 * tx_max,u32 * rx,u32 * rx_max)799*4882a593Smuzhiyun void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
800*4882a593Smuzhiyun u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
801*4882a593Smuzhiyun {
802*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
803*4882a593Smuzhiyun struct data_queue *queue;
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun tx_queue_for_each(rt2x00dev, queue) {
806*4882a593Smuzhiyun *tx += queue->length;
807*4882a593Smuzhiyun *tx_max += queue->limit;
808*4882a593Smuzhiyun }
809*4882a593Smuzhiyun
810*4882a593Smuzhiyun *rx = rt2x00dev->rx->length;
811*4882a593Smuzhiyun *rx_max = rt2x00dev->rx->limit;
812*4882a593Smuzhiyun }
813*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_get_ringparam);
814*4882a593Smuzhiyun
rt2x00mac_tx_frames_pending(struct ieee80211_hw * hw)815*4882a593Smuzhiyun bool rt2x00mac_tx_frames_pending(struct ieee80211_hw *hw)
816*4882a593Smuzhiyun {
817*4882a593Smuzhiyun struct rt2x00_dev *rt2x00dev = hw->priv;
818*4882a593Smuzhiyun struct data_queue *queue;
819*4882a593Smuzhiyun
820*4882a593Smuzhiyun tx_queue_for_each(rt2x00dev, queue) {
821*4882a593Smuzhiyun if (!rt2x00queue_empty(queue))
822*4882a593Smuzhiyun return true;
823*4882a593Smuzhiyun }
824*4882a593Smuzhiyun
825*4882a593Smuzhiyun return false;
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rt2x00mac_tx_frames_pending);
828