2 * carl9170 firmware - used by the ar9170 wireless device
6 * Copyright (c) 2000-2005 ZyDAS Technology Corporation
7 * Copyright (c) 2007-2009 Atheros Communications, Inc.
8 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
9 * Copyright 2009, 2010 Christian Lamparter <chunkeey@googlemail.com>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #ifndef __CARL9170FW_WLAN_H
27 #define __CARL9170FW_WLAN_H
35 static inline __inline void set_wlan_txq_dma_addr(const unsigned int q, const uint32_t v)
37 set(AR9170_MAC_REG_DMA_TXQ_ADDR + (q << 3), v);
40 static inline __inline void set_wlan_txq_dma_curr_addr(const unsigned int q, const uint32_t v)
42 set(AR9170_MAC_REG_DMA_TXQ_CURR_ADDR + (q << 3), v);
45 static inline __inline struct dma_desc *get_wlan_txq_dma_addr(const unsigned int q)
47 return getp(AR9170_MAC_REG_DMA_TXQ_ADDR + (q << 3));
50 static inline __inline struct dma_desc *get_wlan_txq_addr(const unsigned int q)
52 return getp(AR9170_MAC_REG_DMA_TXQ_CURR_ADDR + (q << 3));
55 static inline __inline void _wlan_trigger(const uint32_t queue_bit)
57 set(AR9170_MAC_REG_DMA_TRIGGER, queue_bit);
60 #ifdef CONFIG_CARL9170FW_DELAYED_TX
61 static inline __inline void wlan_trigger(const uint32_t queue_bit)
63 fw.wlan.tx_trigger |= queue_bit;
66 static inline __inline void wlan_trigger(const uint32_t queue_bit)
68 _wlan_trigger(queue_bit);
70 #endif /* CONFIG_CARL9170FW_DELAYED_TX */
72 static inline __inline uint8_t ar9170_get_rx_macstatus_status(struct dma_desc *desc)
74 return *((uint8_t *) DESC_PAYLOAD_OFF(desc->lastAddr,
75 (unsigned int) desc->lastAddr->dataSize - 1));
78 static inline __inline uint8_t ar9170_get_rx_macstatus_error(struct dma_desc *desc)
82 if (desc->lastAddr->dataSize == 1) {
83 while (desc->lastAddr != desc->nextAddr)
84 desc = desc->nextAddr;
86 offset = (unsigned int) (desc->dataSize - 1);
88 desc = desc->lastAddr;
89 offset = desc->dataSize -
90 (sizeof(struct ar9170_rx_macstatus) -
91 offsetof(struct ar9170_rx_macstatus, error));
94 return *((uint8_t *) DESC_PAYLOAD_OFF(desc, offset));
97 static inline __inline struct ieee80211_hdr *ar9170_get_rx_i3e(struct dma_desc *desc)
99 if (!((ar9170_get_rx_macstatus_status(desc) &
100 AR9170_RX_STATUS_MPDU) & AR9170_RX_STATUS_MPDU_LAST)) {
101 return (void *)(DESC_PAYLOAD_OFF(desc,
102 offsetof(struct ar9170_rx_frame_head, i3e)));
104 return (void *)(DESC_PAYLOAD_OFF(desc,
105 offsetof(struct ar9170_rx_frame_tail, i3e)));
109 static inline __inline struct ar9170_rx_head *ar9170_get_rx_head(struct dma_desc *desc)
111 if (!((ar9170_get_rx_macstatus_status(desc) &
112 AR9170_RX_STATUS_MPDU) & AR9170_RX_STATUS_MPDU_LAST)) {
113 return (void *)((uint8_t *)DESC_PAYLOAD(desc) +
114 offsetof(struct ar9170_rx_frame_head, phy_head));
116 return (void *) NULL;
120 static inline __inline uint32_t ar9170_rx_to_phy(struct dma_desc *rx)
122 struct ar9170_tx_hw_phy_control phy;
123 struct ar9170_rx_head *head;
128 head = ar9170_get_rx_head(rx);
130 return le32_to_cpu(phy.set);
132 mac_status = ar9170_get_rx_macstatus_status(rx);
134 phy.modulation = mac_status & AR9170_RX_STATUS_MODULATION;
135 phy.chains = AR9170_TX_PHY_TXCHAIN_1;
137 switch (phy.modulation) {
138 case AR9170_RX_STATUS_MODULATION_CCK:
139 if (mac_status & AR9170_RX_STATUS_SHORT_PREAMBLE)
142 switch (head->plcp[0]) {
143 case AR9170_RX_PHY_RATE_CCK_2M:
144 phy.mcs = AR9170_TX_PHY_RATE_CCK_2M;
147 case AR9170_RX_PHY_RATE_CCK_5M:
148 phy.mcs = AR9170_TX_PHY_RATE_CCK_5M;
151 case AR9170_RX_PHY_RATE_CCK_11M:
152 phy.mcs = AR9170_TX_PHY_RATE_CCK_11M;
155 case AR9170_RX_PHY_RATE_CCK_1M:
157 phy.mcs = AR9170_TX_PHY_RATE_CCK_1M;
163 case AR9170_RX_STATUS_MODULATION_DUPOFDM:
164 case AR9170_RX_STATUS_MODULATION_OFDM:
165 phy.mcs = head->plcp[0] & 0xf;
168 case AR9170_RX_STATUS_MODULATION_HT:
169 if (head->plcp[3] & 0x80)
172 if (head->plcp[6] & 0x80)
175 /* TODO: Enable both chains for MCS > 7 */
176 phy.mcs = head->plcp[6] & 0x7;
180 return le32_to_cpu(phy.set);
183 static inline __inline unsigned int ar9170_get_rx_mpdu_len(struct dma_desc *desc)
186 * WARNING: you have to check the error bits in macstatus first!
189 unsigned int mpdu_len = desc->totalLen;
191 mpdu_len -= sizeof(struct ar9170_rx_macstatus);
193 switch (ar9170_get_rx_macstatus_status(desc) & AR9170_RX_STATUS_MPDU) {
194 case AR9170_RX_STATUS_MPDU_LAST:
195 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
198 case AR9170_RX_STATUS_MPDU_SINGLE:
199 mpdu_len -= sizeof(struct ar9170_rx_phystatus);
201 case AR9170_RX_STATUS_MPDU_FIRST:
202 mpdu_len -= sizeof(struct ar9170_rx_head);
205 case AR9170_RX_STATUS_MPDU_MIDDLE:
213 static inline __inline bool ar9170_tx_length_check(const uint16_t len)
215 return len > (sizeof(struct carl9170_tx_superframe) + 24 +
219 static inline __inline struct carl9170_tx_superframe *get_super(struct dma_desc *desc)
221 return container_of(DESC_PAYLOAD(desc), struct carl9170_tx_superframe,
225 static inline __inline void hide_super(struct dma_desc *desc)
227 desc->dataAddr = (uint8_t *)
228 (((unsigned long)(DESC_PAYLOAD(desc)) +
229 offsetof(struct carl9170_tx_superframe, f)));
231 desc->dataSize -= sizeof(struct carl9170_tx_superdesc);
232 desc->totalLen -= sizeof(struct carl9170_tx_superdesc);
235 static inline __inline void unhide_super(struct dma_desc *desc)
237 desc->dataAddr = (uint8_t *) get_super(desc);
238 desc->dataSize += sizeof(struct carl9170_tx_superdesc);
239 desc->totalLen += sizeof(struct carl9170_tx_superdesc);
242 static inline __inline __hot void read_tsf(uint32_t *tsf)
245 * "According to the [hardware] documentation:
246 * > when TSF_LOW is read, TSF_HI is automatically concurrently
247 * > copied into a temporary register so that an immediate read
248 * > of TSF_HI will get the value that was present when TSF_LOW
251 * (David H. Lynch Jr. - mail from 2010-05-22)
252 * http://permalink.gmane.org/gmane.linux.kernel.wireless.general/51249
255 tsf[0] = get(AR9170_MAC_REG_TSF_L);
256 tsf[1] = get(AR9170_MAC_REG_TSF_H);
259 void wlan_tx(struct dma_desc *desc);
260 void wlan_timer(void);
261 void handle_wlan(void);
263 void wlan_cab_flush_queue(const unsigned int vif);
264 void wlan_cab_modify_dtim_beacon(const unsigned int vif,
265 const unsigned int bcn_addr,
266 const unsigned int bcn_len);
268 static inline void wlan_prepare_wol(void)
270 /* set filter policy to: discard everything */
271 fw.wlan.rx_filter = CARL9170_RX_FILTER_EVERYTHING;
273 /* reenable rx dma */
274 wlan_trigger(AR9170_DMA_TRIGGER_RXQ);
277 static inline void __check_wlantx(void)
279 BUILD_BUG_ON(CARL9170_TX_SUPERDESC_LEN & 3);
280 BUILD_BUG_ON(sizeof(struct carl9170_tx_superdesc) != CARL9170_TX_SUPERDESC_LEN);
281 BUILD_BUG_ON(sizeof(struct _carl9170_tx_superdesc) != CARL9170_TX_SUPERDESC_LEN);
282 BUILD_BUG_ON(sizeof(struct _carl9170_tx_superframe) != CARL9170_TX_SUPERFRAME_LEN);
283 BUILD_BUG_ON((offsetof(struct carl9170_tx_superframe, f) & 3) != 0);
284 BUILD_BUG_ON(offsetof(struct _carl9170_tx_superframe, f) !=
285 (offsetof(struct _carl9170_tx_superframe, f)));
286 BUILD_BUG_ON(sizeof(struct ar9170_tx_hwdesc) != AR9170_TX_HWDESC_LEN);
287 BUILD_BUG_ON(sizeof(struct _ar9170_tx_hwdesc) != AR9170_TX_HWDESC_LEN);
288 BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != AR9170_RX_HEAD_LEN);
289 BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != AR9170_RX_PHYSTATUS_LEN);
290 BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != AR9170_RX_MACSTATUS_LEN);
293 #endif /* __CARL9170FW_WLAN_H */