diff options
author | Kalle Valo <kalle.valo@nokia.com> | 2010-02-18 06:25:41 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-02-19 15:52:43 -0500 |
commit | c6999d831ab9ae5e368b20f3bc11b0ca9c17a7ec (patch) | |
tree | b32ce8ce76cbe875f264a51bf79ae7e60e656c7f /drivers | |
parent | f2054df5170734eacd1db82138c70746ec8387de (diff) |
wl1271: implement WMM
Now that necessary commands for WMM are implemented, implement queue handling
for WMM. But WMM is not enabled yet, only one queue is used.
Based on a similar patch from wl1251.
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
Reviewed-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 31 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_tx.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_tx.h | 36 |
3 files changed, 73 insertions, 4 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index a3742c8052d4..6f7a7d946359 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c | |||
@@ -1712,6 +1712,36 @@ out: | |||
1712 | mutex_unlock(&wl->mutex); | 1712 | mutex_unlock(&wl->mutex); |
1713 | } | 1713 | } |
1714 | 1714 | ||
1715 | static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue, | ||
1716 | const struct ieee80211_tx_queue_params *params) | ||
1717 | { | ||
1718 | struct wl1271 *wl = hw->priv; | ||
1719 | int ret; | ||
1720 | |||
1721 | mutex_lock(&wl->mutex); | ||
1722 | |||
1723 | wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue); | ||
1724 | |||
1725 | ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue), | ||
1726 | params->cw_min, params->cw_max, | ||
1727 | params->aifs, params->txop); | ||
1728 | if (ret < 0) | ||
1729 | goto out; | ||
1730 | |||
1731 | ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue), | ||
1732 | CONF_CHANNEL_TYPE_EDCF, | ||
1733 | wl1271_tx_get_queue(queue), | ||
1734 | CONF_PS_SCHEME_LEGACY_PSPOLL, | ||
1735 | CONF_ACK_POLICY_LEGACY, 0, 0); | ||
1736 | if (ret < 0) | ||
1737 | goto out; | ||
1738 | |||
1739 | out: | ||
1740 | mutex_unlock(&wl->mutex); | ||
1741 | |||
1742 | return ret; | ||
1743 | } | ||
1744 | |||
1715 | 1745 | ||
1716 | /* can't be const, mac80211 writes to this */ | 1746 | /* can't be const, mac80211 writes to this */ |
1717 | static struct ieee80211_rate wl1271_rates[] = { | 1747 | static struct ieee80211_rate wl1271_rates[] = { |
@@ -1877,6 +1907,7 @@ static const struct ieee80211_ops wl1271_ops = { | |||
1877 | .hw_scan = wl1271_op_hw_scan, | 1907 | .hw_scan = wl1271_op_hw_scan, |
1878 | .bss_info_changed = wl1271_op_bss_info_changed, | 1908 | .bss_info_changed = wl1271_op_bss_info_changed, |
1879 | .set_rts_threshold = wl1271_op_set_rts_threshold, | 1909 | .set_rts_threshold = wl1271_op_set_rts_threshold, |
1910 | .conf_tx = wl1271_op_conf_tx, | ||
1880 | }; | 1911 | }; |
1881 | 1912 | ||
1882 | static int wl1271_register_hw(struct wl1271 *wl) | 1913 | static int wl1271_register_hw(struct wl1271 *wl) |
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index a288cc317d7b..f6815a9239e5 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c | |||
@@ -87,7 +87,7 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, | |||
87 | u32 extra, struct ieee80211_tx_info *control) | 87 | u32 extra, struct ieee80211_tx_info *control) |
88 | { | 88 | { |
89 | struct wl1271_tx_hw_descr *desc; | 89 | struct wl1271_tx_hw_descr *desc; |
90 | int pad; | 90 | int pad, ac; |
91 | u16 tx_attr; | 91 | u16 tx_attr; |
92 | 92 | ||
93 | desc = (struct wl1271_tx_hw_descr *) skb->data; | 93 | desc = (struct wl1271_tx_hw_descr *) skb->data; |
@@ -107,9 +107,11 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, | |||
107 | 107 | ||
108 | /* configure the tx attributes */ | 108 | /* configure the tx attributes */ |
109 | tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER; | 109 | tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER; |
110 | /* FIXME: do we know the packet priority? can we identify mgmt | 110 | |
111 | packets, and use max prio for them at least? */ | 111 | /* queue */ |
112 | desc->tid = 0; | 112 | ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); |
113 | desc->tid = wl1271_tx_ac_to_tid(ac); | ||
114 | |||
113 | desc->aid = TX_HW_DEFAULT_AID; | 115 | desc->aid = TX_HW_DEFAULT_AID; |
114 | desc->reserved = 0; | 116 | desc->reserved = 0; |
115 | 117 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h index 416396caf0a0..17e405a09caa 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.h +++ b/drivers/net/wireless/wl12xx/wl1271_tx.h | |||
@@ -123,6 +123,42 @@ struct wl1271_tx_hw_res_if { | |||
123 | struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN]; | 123 | struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN]; |
124 | } __attribute__ ((packed)); | 124 | } __attribute__ ((packed)); |
125 | 125 | ||
126 | static inline int wl1271_tx_get_queue(int queue) | ||
127 | { | ||
128 | /* FIXME: use best effort until WMM is enabled */ | ||
129 | return CONF_TX_AC_BE; | ||
130 | |||
131 | switch (queue) { | ||
132 | case 0: | ||
133 | return CONF_TX_AC_VO; | ||
134 | case 1: | ||
135 | return CONF_TX_AC_VI; | ||
136 | case 2: | ||
137 | return CONF_TX_AC_BE; | ||
138 | case 3: | ||
139 | return CONF_TX_AC_BK; | ||
140 | default: | ||
141 | return CONF_TX_AC_BE; | ||
142 | } | ||
143 | } | ||
144 | |||
145 | /* wl1271 tx descriptor needs the tid and we need to convert it from ac */ | ||
146 | static inline int wl1271_tx_ac_to_tid(int ac) | ||
147 | { | ||
148 | switch (ac) { | ||
149 | case 0: | ||
150 | return 0; | ||
151 | case 1: | ||
152 | return 2; | ||
153 | case 2: | ||
154 | return 4; | ||
155 | case 3: | ||
156 | return 6; | ||
157 | default: | ||
158 | return 0; | ||
159 | } | ||
160 | } | ||
161 | |||
126 | void wl1271_tx_work(struct work_struct *work); | 162 | void wl1271_tx_work(struct work_struct *work); |
127 | void wl1271_tx_complete(struct wl1271 *wl, u32 count); | 163 | void wl1271_tx_complete(struct wl1271 *wl, u32 count); |
128 | void wl1271_tx_flush(struct wl1271 *wl); | 164 | void wl1271_tx_flush(struct wl1271 *wl); |