aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKalle Valo <kalle.valo@nokia.com>2010-02-18 06:25:41 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-02-19 15:52:43 -0500
commitc6999d831ab9ae5e368b20f3bc11b0ca9c17a7ec (patch)
treeb32ce8ce76cbe875f264a51bf79ae7e60e656c7f /drivers
parentf2054df5170734eacd1db82138c70746ec8387de (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.c31
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c10
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.h36
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
1715static 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
1739out:
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 */
1717static struct ieee80211_rate wl1271_rates[] = { 1747static 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
1882static int wl1271_register_hw(struct wl1271 *wl) 1913static 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
126static 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 */
146static 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
126void wl1271_tx_work(struct work_struct *work); 162void wl1271_tx_work(struct work_struct *work);
127void wl1271_tx_complete(struct wl1271 *wl, u32 count); 163void wl1271_tx_complete(struct wl1271 *wl, u32 count);
128void wl1271_tx_flush(struct wl1271 *wl); 164void wl1271_tx_flush(struct wl1271 *wl);