2 Copyright (C) 2004 - 2007 rt2x00 SourceForge Project
3 <http://rt2x00.serialmonkey.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 Abstract: rt2x00 generic mac80211 routines.
24 Supported chipsets: RT2460, RT2560, RT2570,
25 rt2561, rt2561s, rt2661, rt2571W & rt2671.
29 * Set enviroment defines for rt2x00.h
31 #define DRV_NAME "rt2x00lib"
33 #include <linux/netdevice.h>
36 #include "rt2x00lib.h"
37 #include "rt2x00dev.h"
39 static int rt2x00_tx_rts_cts(struct rt2x00_dev *rt2x00dev,
40 struct data_ring *ring, struct sk_buff *frag_skb,
41 struct ieee80211_tx_control *control)
46 if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
47 size = sizeof(struct ieee80211_cts);
49 size = sizeof(struct ieee80211_rts);
51 skb = dev_alloc_skb(size + rt2x00dev->hw->extra_tx_headroom);
53 WARNING(rt2x00dev, "Failed to create RTS/CTS frame.\n");
54 return NETDEV_TX_BUSY;
57 skb_reserve(skb, rt2x00dev->hw->extra_tx_headroom);
60 if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
61 ieee80211_ctstoself_get(rt2x00dev->hw,
62 frag_skb->data, frag_skb->len, control,
63 (struct ieee80211_cts*)(skb->data));
65 ieee80211_rts_get(rt2x00dev->hw,
66 frag_skb->data, frag_skb->len, control,
67 (struct ieee80211_rts*)(skb->data));
69 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control)) {
70 WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");
71 return NETDEV_TX_BUSY;
77 int rt2x00lib_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
78 struct ieee80211_tx_control *control)
80 struct rt2x00_dev *rt2x00dev = hw->priv;
81 struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr*)skb->data;
82 struct data_ring *ring;
86 * Determine which ring to put packet on.
88 ring = rt2x00_get_ring(rt2x00dev, control->queue);
89 if (unlikely(!ring)) {
91 "Attempt to send packet over invalid queue %d.\n"
92 "Please file bug report to %s.\n",
93 control->queue, DRV_PROJECT);
94 dev_kfree_skb_any(skb);
99 * If CTS/RTS is required. and this frame is not CTS or RTS,
100 * create and queue that frame first. But make sure we have
101 * at least enough entries available to send this CTS/RTS
102 * frame as well as the data frame.
104 frame_control = le16_to_cpu(ieee80211hdr->frame_control);
105 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS &&
106 !is_cts_frame(frame_control) && !is_rts_frame(frame_control)) {
107 if (rt2x00_ring_free(ring) <= 1)
108 return NETDEV_TX_BUSY;
110 if (rt2x00_tx_rts_cts(rt2x00dev, ring, skb, control))
111 return NETDEV_TX_BUSY;
114 if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, ring, skb, control))
115 return NETDEV_TX_BUSY;
117 if (rt2x00dev->ops->lib->kick_tx_queue)
118 rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue);
122 EXPORT_SYMBOL_GPL(rt2x00lib_tx);
124 int rt2x00lib_reset(struct ieee80211_hw *hw)
126 struct rt2x00_dev *rt2x00dev = hw->priv;
128 rt2x00lib_disable_radio(rt2x00dev);
129 return rt2x00lib_enable_radio(rt2x00dev);
131 EXPORT_SYMBOL_GPL(rt2x00lib_reset);
133 int rt2x00lib_add_interface(struct ieee80211_hw *hw,
134 struct ieee80211_if_init_conf *conf)
136 struct rt2x00_dev *rt2x00dev = hw->priv;
137 struct interface *intf = &rt2x00dev->interface;
141 * We only support 1 non-monitor interface.
143 if (conf->type != IEEE80211_IF_TYPE_MNTR &&
144 is_interface_present(intf))
148 * We support muliple monitor mode interfaces.
149 * All we need to do is increase the monitor_count.
151 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
152 intf->monitor_count++;
154 intf->id = conf->if_id;
155 intf->type = conf->type;
156 if (conf->type == IEEE80211_IF_TYPE_AP)
157 memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN);
162 * Initialize interface, and enable the radio when this
163 * is the first interface that is brought up.
165 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) {
167 * We must wait on the firmware before
168 * we can safely continue.
170 status = rt2x00lib_load_firmware_wait(rt2x00dev);
175 * Before initialization, the mac address should
178 rt2x00dev->ops->lib->config_mac_addr(rt2x00dev,
182 * Initialize the device.
184 status = rt2x00lib_initialize(rt2x00dev);
191 status = rt2x00lib_enable_radio(rt2x00dev);
198 EXPORT_SYMBOL_GPL(rt2x00lib_add_interface);
200 void rt2x00lib_remove_interface(struct ieee80211_hw *hw,
201 struct ieee80211_if_init_conf *conf)
203 struct rt2x00_dev *rt2x00dev = hw->priv;
204 struct interface *intf = &rt2x00dev->interface;
207 * We only support 1 non-monitor interface.
209 if (conf->type != IEEE80211_IF_TYPE_MNTR &&
210 !is_interface_present(intf))
214 * When removing an monitor interface, decrease monitor_count.
215 * For non-monitor interfaces, all interface data needs to be reset.
217 if (conf->type == IEEE80211_IF_TYPE_MNTR) {
218 intf->monitor_count--;
219 } else if (intf->type == conf->type) {
221 intf->type = -EINVAL;
222 memset(&intf->bssid, 0x00, ETH_ALEN);
227 * If this was the last interface,
228 * this is the time to disable the radio.
229 * If this is not the last interface, then we should
230 * check if we should switch completely to monitor
231 * mode or completely switch to the non-monitor mode.
233 if (!is_monitor_present(intf) && !is_interface_present(intf))
234 rt2x00lib_disable_radio(rt2x00dev);
235 else if (is_monitor_present(intf) ^ is_interface_present(intf))
236 rt2x00lib_config_type(rt2x00dev,
237 is_interface_present(intf) ?
238 intf->type : IEEE80211_IF_TYPE_MNTR);
240 EXPORT_SYMBOL_GPL(rt2x00lib_remove_interface);
242 int rt2x00lib_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
244 struct rt2x00_dev *rt2x00dev = hw->priv;
247 * Check if we need to disable the radio,
248 * if this is not the case, at least the RX must be disabled.
250 if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) {
251 if (!conf->radio_enabled)
252 rt2x00lib_disable_radio(rt2x00dev);
254 rt2x00lib_toggle_rx(rt2x00dev, 0);
257 rt2x00lib_config_phymode(rt2x00dev, conf->phymode);
258 rt2x00lib_config_channel(rt2x00dev, conf->channel_val,
259 conf->channel, conf->freq, conf->power_level);
260 rt2x00lib_config_txpower(rt2x00dev, conf->power_level);
261 rt2x00lib_config_antenna(rt2x00dev,
262 conf->antenna_sel_tx, conf->antenna_sel_rx);
263 rt2x00dev->ops->lib->config_duration(rt2x00dev,
264 (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME),
268 * Reenable RX only if the radio should be on.
270 if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
271 rt2x00lib_toggle_rx(rt2x00dev, 1);
272 else if (conf->radio_enabled)
273 return rt2x00lib_enable_radio(rt2x00dev);
277 EXPORT_SYMBOL_GPL(rt2x00lib_config);
279 int rt2x00lib_config_interface(struct ieee80211_hw *hw, int if_id,
280 struct ieee80211_if_conf *conf)
282 struct rt2x00_dev *rt2x00dev = hw->priv;
283 struct interface *intf = &rt2x00dev->interface;
287 * Monitor mode does not need configuring.
288 * If the given type does not match the configured type,
289 * there has been a problem.
291 if (conf->type == IEEE80211_IF_TYPE_MNTR)
293 else if (conf->type != intf->type)
297 * If the interface does not work in master mode,
298 * then the bssid value in the interface structure
301 if (conf->type != IEEE80211_IF_TYPE_AP)
302 memcpy(&intf->bssid, conf->bssid, ETH_ALEN);
305 * Enable configuration.
306 * For Monitor mode, promisc mode will be forced on.
308 rt2x00lib_config_type(rt2x00dev, conf->type);
309 rt2x00lib_config_promisc(rt2x00dev, rt2x00dev->interface.promisc);
310 rt2x00dev->ops->lib->config_bssid(rt2x00dev, intf->bssid);
313 * We only need to initialize the beacon when master mode is enabled.
315 if (conf->type != IEEE80211_IF_TYPE_AP || !conf->beacon)
318 status = rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw,
319 conf->beacon, conf->beacon_control);
321 dev_kfree_skb(conf->beacon);
325 EXPORT_SYMBOL_GPL(rt2x00lib_config_interface);
327 void rt2x00lib_set_multicast_list(struct ieee80211_hw *hw,
328 unsigned short flags, int mc_count)
330 struct rt2x00_dev *rt2x00dev = hw->priv;
333 * Promisc mode is forced on for Monitor interfaces.
335 if (is_monitor_present(&rt2x00dev->interface))
339 * Check if the new state is different then the old state.
341 if (test_bit(INTERFACE_ENABLED_PROMISC, &rt2x00dev->flags) ==
342 !!(flags & IFF_PROMISC))
345 rt2x00dev->interface.promisc = !!(flags & IFF_PROMISC);
348 * Schedule the link tuner if this does not run
349 * automatically. The link tuner will be automatically
350 * switched off when it is not required.
352 if (!work_pending(&rt2x00dev->link.work.work))
353 queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work.work);
355 EXPORT_SYMBOL_GPL(rt2x00lib_set_multicast_list);
357 int rt2x00lib_get_tx_stats(struct ieee80211_hw *hw,
358 struct ieee80211_tx_queue_stats *stats)
360 struct rt2x00_dev *rt2x00dev = hw->priv;
363 for (i = 0; i < hw->queues; i++)
364 memcpy(&stats->data[i], &rt2x00dev->tx[i].stats,
365 sizeof(rt2x00dev->tx[i].stats));
369 EXPORT_SYMBOL_GPL(rt2x00lib_get_tx_stats);
371 int rt2x00lib_conf_tx(struct ieee80211_hw *hw, int queue,
372 const struct ieee80211_tx_queue_params *params)
374 struct rt2x00_dev *rt2x00dev = hw->priv;
375 struct data_ring *ring;
377 ring = rt2x00_get_ring(rt2x00dev, queue);
382 * The passed variables are stored as real value ((2^n)-1).
383 * Ralink registers require to know the bit number 'n'.
386 ring->tx_params.cw_min = fls(params->cw_min);
388 ring->tx_params.cw_min = 5; /* cw_min: 2^5 = 32. */
391 ring->tx_params.cw_max = fls(params->cw_max);
393 ring->tx_params.cw_max = 10; /* cw_min: 2^10 = 1024. */
396 ring->tx_params.aifs = params->aifs;
398 ring->tx_params.aifs = 2;
401 "Configured TX ring %d - CWmin: %d, CWmax: %d, Aifs: %d.\n",
402 queue, ring->tx_params.cw_min, ring->tx_params.cw_max,
403 ring->tx_params.aifs);
407 EXPORT_SYMBOL_GPL(rt2x00lib_conf_tx);