aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00config.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00config.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c119
1 files changed, 72 insertions, 47 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index c247ee77b3a3..20231e0c53fa 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -29,64 +29,89 @@
29#include "rt2x00.h" 29#include "rt2x00.h"
30#include "rt2x00lib.h" 30#include "rt2x00lib.h"
31 31
32 32void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev,
33/* 33 struct rt2x00_intf *intf,
34 * The MAC and BSSID addressess are simple array of bytes, 34 enum ieee80211_if_types type,
35 * these arrays are little endian, so when sending the addressess 35 u8 *mac, u8 *bssid)
36 * to the drivers, copy the it into a endian-signed variable.
37 *
38 * Note that all devices (except rt2500usb) have 32 bits
39 * register word sizes. This means that whatever variable we
40 * pass _must_ be a multiple of 32 bits. Otherwise the device
41 * might not accept what we are sending to it.
42 * This will also make it easier for the driver to write
43 * the data to the device.
44 *
45 * Also note that when NULL is passed as address the
46 * we will send 00:00:00:00:00 to the device to clear the address.
47 * This will prevent the device being confused when it wants
48 * to ACK frames or consideres itself associated.
49 */
50void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac)
51{ 36{
52 __le32 reg[2]; 37 struct rt2x00intf_conf conf;
53 38 unsigned int flags = 0;
54 memset(&reg, 0, sizeof(reg));
55 if (mac)
56 memcpy(&reg, mac, ETH_ALEN);
57
58 rt2x00dev->ops->lib->config_mac_addr(rt2x00dev, &reg[0]);
59}
60 39
61void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid) 40 conf.type = type;
62{
63 __le32 reg[2];
64
65 memset(&reg, 0, sizeof(reg));
66 if (bssid)
67 memcpy(&reg, bssid, ETH_ALEN);
68
69 rt2x00dev->ops->lib->config_bssid(rt2x00dev, &reg[0]);
70}
71
72void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type)
73{
74 int tsf_sync;
75 41
76 switch (type) { 42 switch (type) {
77 case IEEE80211_IF_TYPE_IBSS: 43 case IEEE80211_IF_TYPE_IBSS:
78 case IEEE80211_IF_TYPE_AP: 44 case IEEE80211_IF_TYPE_AP:
79 tsf_sync = TSF_SYNC_BEACON; 45 conf.sync = TSF_SYNC_BEACON;
80 break; 46 break;
81 case IEEE80211_IF_TYPE_STA: 47 case IEEE80211_IF_TYPE_STA:
82 tsf_sync = TSF_SYNC_INFRA; 48 conf.sync = TSF_SYNC_INFRA;
83 break; 49 break;
84 default: 50 default:
85 tsf_sync = TSF_SYNC_NONE; 51 conf.sync = TSF_SYNC_NONE;
86 break; 52 break;
87 } 53 }
88 54
89 rt2x00dev->ops->lib->config_type(rt2x00dev, type, tsf_sync); 55 /*
56 * Note that when NULL is passed as address we will send
57 * 00:00:00:00:00 to the device to clear the address.
58 * This will prevent the device being confused when it wants
59 * to ACK frames or consideres itself associated.
60 */
61 memset(&conf.mac, 0, sizeof(conf.mac));
62 if (mac)
63 memcpy(&conf.mac, mac, ETH_ALEN);
64
65 memset(&conf.bssid, 0, sizeof(conf.bssid));
66 if (bssid)
67 memcpy(&conf.bssid, bssid, ETH_ALEN);
68
69 flags |= CONFIG_UPDATE_TYPE;
70 if (mac || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count))
71 flags |= CONFIG_UPDATE_MAC;
72 if (bssid || (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count))
73 flags |= CONFIG_UPDATE_BSSID;
74
75 rt2x00dev->ops->lib->config_intf(rt2x00dev, intf, &conf, flags);
76}
77
78void rt2x00lib_config_preamble(struct rt2x00_dev *rt2x00dev,
79 struct rt2x00_intf *intf,
80 const unsigned int short_preamble)
81{
82 int retval;
83 int ack_timeout;
84 int ack_consume_time;
85
86 ack_timeout = PLCP + get_duration(ACK_SIZE, 10);
87 ack_consume_time = SIFS + PLCP + get_duration(ACK_SIZE, 10);
88
89 if (rt2x00dev->hw->conf.flags & IEEE80211_CONF_SHORT_SLOT_TIME)
90 ack_timeout += SHORT_DIFS;
91 else
92 ack_timeout += DIFS;
93
94 if (short_preamble) {
95 ack_timeout += SHORT_PREAMBLE;
96 ack_consume_time += SHORT_PREAMBLE;
97 } else {
98 ack_timeout += PREAMBLE;
99 ack_consume_time += PREAMBLE;
100 }
101
102 retval = rt2x00dev->ops->lib->config_preamble(rt2x00dev,
103 short_preamble,
104 ack_timeout,
105 ack_consume_time);
106
107 spin_lock(&intf->lock);
108
109 if (retval) {
110 intf->delayed_flags |= DELAYED_CONFIG_PREAMBLE;
111 queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
112 }
113
114 spin_unlock(&intf->lock);
90} 115}
91 116
92void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, 117void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
@@ -113,7 +138,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
113 * The latter is required since we need to recalibrate the 138 * The latter is required since we need to recalibrate the
114 * noise-sensitivity ratio for the new setup. 139 * noise-sensitivity ratio for the new setup.
115 */ 140 */
116 rt2x00dev->ops->lib->config(rt2x00dev, CONFIG_UPDATE_ANTENNA, &libconf); 141 rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA);
117 rt2x00lib_reset_link_tuner(rt2x00dev); 142 rt2x00lib_reset_link_tuner(rt2x00dev);
118 143
119 rt2x00dev->link.ant.active.rx = libconf.ant.rx; 144 rt2x00dev->link.ant.active.rx = libconf.ant.rx;
@@ -266,7 +291,7 @@ config:
266 /* 291 /*
267 * Start configuration. 292 * Start configuration.
268 */ 293 */
269 rt2x00dev->ops->lib->config(rt2x00dev, flags, &libconf); 294 rt2x00dev->ops->lib->config(rt2x00dev, &libconf, flags);
270 295
271 /* 296 /*
272 * Some configuration changes affect the link quality 297 * Some configuration changes affect the link quality