aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-04-20 12:27:04 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-04-22 16:57:17 -0400
commit9e52b0623c6eb49c3f23a326c1fb97bdecc49ba1 (patch)
tree465bc1673865d114dc011ddd410f3c242f23b076 /drivers/net
parent314bd7503b1e96841931311f28a8925dab66ed83 (diff)
ar9170: support HT receive and channel config
This patch adds support for configuring HT40 channels and receiving HT40 to ar9170. Receiving aggregation doesn't seem to work right now, so it's not enabled. Same goes for TX aggregation, but that probably needs even more work. With this, I can receive roughly 33 Mbits/sec. The HT capabilities are a little odd, I tried following otus here -- in particular having SGI_40 but not SGI_20 is a little weird but afaict that's what otus does. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h15
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c54
2 files changed, 61 insertions, 8 deletions
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index 2522a190fdfb..b6a1bff67cab 100644
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -60,6 +60,21 @@ enum ar9170_bw {
60 __AR9170_NUM_BW, 60 __AR9170_NUM_BW,
61}; 61};
62 62
63static inline enum ar9170_bw nl80211_to_ar9170(enum nl80211_channel_type type)
64{
65 switch (type) {
66 case NL80211_CHAN_NO_HT:
67 case NL80211_CHAN_HT20:
68 return AR9170_BW_20;
69 case NL80211_CHAN_HT40MINUS:
70 return AR9170_BW_40_BELOW;
71 case NL80211_CHAN_HT40PLUS:
72 return AR9170_BW_40_ABOVE;
73 default:
74 BUG();
75 }
76}
77
63enum ar9170_rf_init_mode { 78enum ar9170_rf_init_mode {
64 AR9170_RFI_NONE, 79 AR9170_RFI_NONE,
65 AR9170_RFI_WARM, 80 AR9170_RFI_WARM,
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 857416c80199..4682fe2f3f3c 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -142,11 +142,36 @@ static struct ieee80211_channel ar9170_5ghz_chantable[] = {
142}; 142};
143#undef CHAN 143#undef CHAN
144 144
145#define AR9170_HT_CAP \
146{ \
147 .ht_supported = true, \
148 .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
149 IEEE80211_HT_CAP_SM_PS | \
150 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
151 IEEE80211_HT_CAP_SGI_40 | \
152 IEEE80211_HT_CAP_DSSSCCK40 | \
153 IEEE80211_HT_CAP_SM_PS, \
154 .ampdu_factor = 3, /* ?? */ \
155 .ampdu_density = 7, /* ?? */ \
156 .mcs = { \
157 .rx_mask = { 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, }, \
158 }, \
159}
160
145static struct ieee80211_supported_band ar9170_band_2GHz = { 161static struct ieee80211_supported_band ar9170_band_2GHz = {
146 .channels = ar9170_2ghz_chantable, 162 .channels = ar9170_2ghz_chantable,
147 .n_channels = ARRAY_SIZE(ar9170_2ghz_chantable), 163 .n_channels = ARRAY_SIZE(ar9170_2ghz_chantable),
148 .bitrates = ar9170_g_ratetable, 164 .bitrates = ar9170_g_ratetable,
149 .n_bitrates = ar9170_g_ratetable_size, 165 .n_bitrates = ar9170_g_ratetable_size,
166 .ht_cap = AR9170_HT_CAP,
167};
168
169static struct ieee80211_supported_band ar9170_band_5GHz = {
170 .channels = ar9170_5ghz_chantable,
171 .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
172 .bitrates = ar9170_a_ratetable,
173 .n_bitrates = ar9170_a_ratetable_size,
174 .ht_cap = AR9170_HT_CAP,
150}; 175};
151 176
152#ifdef AR9170_QUEUE_DEBUG 177#ifdef AR9170_QUEUE_DEBUG
@@ -190,13 +215,6 @@ static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar,
190} 215}
191#endif /* AR9170_QUEUE_DEBUG */ 216#endif /* AR9170_QUEUE_DEBUG */
192 217
193static struct ieee80211_supported_band ar9170_band_5GHz = {
194 .channels = ar9170_5ghz_chantable,
195 .n_channels = ARRAY_SIZE(ar9170_5ghz_chantable),
196 .bitrates = ar9170_a_ratetable,
197 .n_bitrates = ar9170_a_ratetable_size,
198};
199
200void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, 218void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
201 bool valid_status, u16 tx_status) 219 bool valid_status, u16 tx_status)
202{ 220{
@@ -1077,7 +1095,8 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
1077 1095
1078 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1096 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1079 err = ar9170_set_channel(ar, hw->conf.channel, 1097 err = ar9170_set_channel(ar, hw->conf.channel,
1080 AR9170_RFI_NONE, AR9170_BW_20); 1098 AR9170_RFI_NONE,
1099 nl80211_to_ar9170(hw->conf.channel_type));
1081 if (err) 1100 if (err)
1082 goto out; 1101 goto out;
1083 /* adjust slot time for 5 GHz */ 1102 /* adjust slot time for 5 GHz */
@@ -1499,6 +1518,24 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
1499 return ret; 1518 return ret;
1500} 1519}
1501 1520
1521static int ar9170_ampdu_action(struct ieee80211_hw *hw,
1522 enum ieee80211_ampdu_mlme_action action,
1523 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
1524{
1525 switch (action) {
1526 case IEEE80211_AMPDU_RX_START:
1527 case IEEE80211_AMPDU_RX_STOP:
1528 /*
1529 * Something goes wrong -- RX locks up
1530 * after a while of receiving aggregated
1531 * frames -- not enabling for now.
1532 */
1533 return -EOPNOTSUPP;
1534 default:
1535 return -EOPNOTSUPP;
1536 }
1537}
1538
1502static const struct ieee80211_ops ar9170_ops = { 1539static const struct ieee80211_ops ar9170_ops = {
1503 .start = ar9170_op_start, 1540 .start = ar9170_op_start,
1504 .stop = ar9170_op_stop, 1541 .stop = ar9170_op_stop,
@@ -1515,6 +1552,7 @@ static const struct ieee80211_ops ar9170_ops = {
1515 .sta_notify = ar9170_sta_notify, 1552 .sta_notify = ar9170_sta_notify,
1516 .get_stats = ar9170_get_stats, 1553 .get_stats = ar9170_get_stats,
1517 .get_tx_stats = ar9170_get_tx_stats, 1554 .get_tx_stats = ar9170_get_tx_stats,
1555 .ampdu_action = ar9170_ampdu_action,
1518}; 1556};
1519 1557
1520void *ar9170_alloc(size_t priv_size) 1558void *ar9170_alloc(size_t priv_size)