2 * carl9170 firmware - used by the ar9170 wireless device
4 * Interface to the WLAN part of the chip
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-2012 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, see <http://www.gnu.org/licenses/>.
26 #include "shared/phy.h"
32 #include "linux/ieee80211.h"
35 #ifdef CONFIG_CARL9170FW_DEBUG
36 static void wlan_dump_queue(unsigned int qidx)
39 struct dma_desc *desc;
40 struct carl9170_tx_superframe *super;
43 __for_each_desc(desc, &fw.wlan.tx_queue[qidx]) {
44 super = get_super(desc);
45 DBG("%d: %p s:%x c:%x tl:%x ds:%x n:%p l:%p ", entries, desc,
46 desc->status, desc->ctrl, desc->totalLen,
47 desc->dataSize, desc->nextAddr, desc->lastAddr);
49 DBG("c:%x tr:%d ri:%d l:%x m:%x p:%x fc:%x",
50 super->s.cookie, super->s.cnt, super->s.rix,
51 super->f.hdr.length, super->f.hdr.mac.set,
52 (unsigned int) le32_to_cpu(super->f.hdr.phy.set),
53 super->f.data.i3e.frame_control);
58 desc = (struct dma_desc *)get_wlan_txq_addr(qidx);
60 DBG("Queue: %d: te:%d td:%d h:%p c:%p t:%p",
61 qidx, entries, queue_len(&fw.wlan.tx_queue[qidx]),
62 fw.wlan.tx_queue[qidx].head,
63 desc, fw.wlan.tx_queue[qidx].terminator);
65 DBG("HW: t:%x s:%x ac:%x c:%x",
66 (unsigned int) get(AR9170_MAC_REG_DMA_TRIGGER),
67 (unsigned int) get(AR9170_MAC_REG_DMA_STATUS),
68 (unsigned int) get(AR9170_MAC_REG_AMPDU_COUNT),
69 (unsigned int) get(AR9170_MAC_REG_DMA_TXQX_ADDR_CURR));
71 #endif /* CONFIG_CARL9170FW_DEBUG */
73 static void wlan_check_rx_overrun(void)
75 uint32_t overruns, total;
77 fw.tally.rx_total += total = get(AR9170_MAC_REG_RX_TOTAL);
78 fw.tally.rx_overrun += overruns = get(AR9170_MAC_REG_RX_OVERRUN);
79 if (unlikely(overruns)) {
80 if (overruns == total) {
85 wlan_trigger(AR9170_DMA_TRIGGER_RXQ);
89 static void handle_beacon_config(void)
93 bcn_count = get(AR9170_MAC_REG_BCN_COUNT);
94 send_cmd_to_host(4, CARL9170_RSP_BEACON_CONFIG, 0x00,
95 (uint8_t *) &bcn_count);
98 static void handle_pretbtt(void)
100 fw.wlan.cab_flush_time = get_clock_counter();
102 #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
105 send_cmd_to_host(4, CARL9170_RSP_PRETBTT, 0x00,
106 (uint8_t *) &fw.phy.psm.state);
107 #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
110 static void handle_atim(void)
112 send_cmd_to_host(0, CARL9170_RSP_ATIM, 0x00, NULL);
115 #ifdef CONFIG_CARL9170FW_DEBUG
116 static void handle_qos(void)
119 * What is the QoS Bit used for?
120 * Is it only an indicator for TXOP & Burst, or
121 * should we do something here?
125 static void handle_radar(void)
127 send_cmd_to_host(0, CARL9170_RSP_RADAR, 0x00, NULL);
129 #endif /* CONFIG_CARL9170FW_DEBUG */
131 static void wlan_janitor(void)
133 wlan_send_buffered_cab();
135 wlan_send_buffered_tx_status();
137 wlan_send_buffered_ba();
142 void handle_wlan(void)
146 intr = get(AR9170_MAC_REG_INT_CTRL);
148 set(AR9170_MAC_REG_INT_CTRL, intr);
150 #define HANDLER(intr, flag, func) \
152 if ((intr & flag) != 0) { \
157 intr |= fw.wlan.soft_int;
158 fw.wlan.soft_int = 0;
160 HANDLER(intr, AR9170_MAC_INT_PRETBTT, handle_pretbtt);
162 HANDLER(intr, AR9170_MAC_INT_ATIM, handle_atim);
164 HANDLER(intr, AR9170_MAC_INT_RXC, handle_wlan_rx);
166 HANDLER(intr, (AR9170_MAC_INT_TXC | AR9170_MAC_INT_RETRY_FAIL),
167 handle_wlan_tx_completion);
169 #ifdef CONFIG_CARL9170FW_DEBUG
170 HANDLER(intr, AR9170_MAC_INT_QOS, handle_qos);
172 HANDLER(intr, AR9170_MAC_INT_RADAR, handle_radar);
173 #endif /* CONFIG_CARL9170FW_DEBUG */
175 HANDLER(intr, AR9170_MAC_INT_CFG_BCN, handle_beacon_config);
178 DBG("Unhandled Interrupt %x\n", (unsigned int) intr);
186 CARL9170FW_TX_MAC_BUMP = 4,
187 CARL9170FW_TX_MAC_DEBUG = 6,
188 CARL9170FW_TX_MAC_RESET = 7,
191 static void wlan_check_hang(void)
193 struct dma_desc *desc;
196 for (i = AR9170_TXQ_SPECIAL; i >= AR9170_TXQ0; i--) {
197 if (queue_empty(&fw.wlan.tx_queue[i])) {
198 /* Nothing to do here... move along */
202 /* fetch the current DMA queue position */
203 desc = (struct dma_desc *)get_wlan_txq_addr(i);
205 /* Stuck frame detection */
206 if (unlikely(DESC_PAYLOAD(desc) == fw.wlan.last_super[i])) {
207 fw.wlan.last_super_num[i]++;
209 if (unlikely(fw.wlan.last_super_num[i] >= CARL9170FW_TX_MAC_RESET)) {
211 * schedule MAC reset (aka OFF/ON => dead)
213 * This will almost certainly kill
214 * the device for good, but it's the
215 * recommended thing to do...
221 #ifdef CONFIG_CARL9170FW_DEBUG
222 if (unlikely(fw.wlan.last_super_num[i] >= CARL9170FW_TX_MAC_DEBUG)) {
224 * Sigh, the queue is almost certainly
225 * dead. Dump the queue content to the
226 * user, maybe we find out why it got
232 #endif /* CONFIG_CARL9170FW_DEBUG */
234 #ifdef CONFIG_CARL9170FW_DMA_QUEUE_BUMP
235 if (unlikely(fw.wlan.last_super_num[i] >= CARL9170FW_TX_MAC_BUMP)) {
237 * Hrrm, bump the queue a bit.
238 * maybe this will get it going again.
242 wlan_trigger(BIT(i));
244 #endif /* CONFIG_CARL9170FW_DMA_QUEUE_BUMP */
247 fw.wlan.last_super[i] = DESC_PAYLOAD(desc);
248 fw.wlan.last_super_num[i] = 0;
253 #ifdef CONFIG_CARL9170FW_FW_MAC_RESET
255 * NB: Resetting the MAC is a two-edged sword.
256 * On most occasions, it does what it is supposed to do.
257 * But there is a chance that this will make it
258 * even worse and the radio dies silently.
260 static void wlan_mac_reset(void)
263 uint32_t agg_wait_counter;
264 uint32_t agg_density;
265 uint32_t bcn_start_addr;
269 uint32_t rts_cts_tpc;
270 uint32_t rts_cts_rate;
273 #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
275 #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
277 #ifdef CONFIG_CARL9170FW_NOISY_MAC_RESET
279 #endif /* CONFIG_CARL9170FW_NOISY_MAC_RESET */
281 /* Save aggregation parameters */
282 agg_wait_counter = get(AR9170_MAC_REG_AMPDU_FACTOR);
283 agg_density = get(AR9170_MAC_REG_AMPDU_DENSITY);
285 bcn_start_addr = get(AR9170_MAC_REG_BCN_ADDR);
287 cam_mode = get(AR9170_MAC_REG_CAM_MODE);
288 rctl = get(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L);
289 rcth = get(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H);
291 ack_power = get(AR9170_MAC_REG_ACK_TPC);
292 rts_cts_tpc = get(AR9170_MAC_REG_RTS_CTS_TPC);
293 rts_cts_rate = get(AR9170_MAC_REG_RTS_CTS_RATE);
295 #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
296 /* 0x1c8960 write only */
297 rx_BB = get(AR9170_PHY_REG_SWITCH_CHAIN_0);
298 #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
300 /* TX/RX must be stopped by now */
301 val = get(AR9170_MAC_REG_POWER_STATE_CTRL);
303 val |= AR9170_MAC_POWER_STATE_CTRL_RESET;
306 * Manipulate CCA threshold to stop transmission
308 * set(AR9170_PHY_REG_CCA_THRESHOLD, 0x300);
312 * check Rx state in 0(idle) 9(disable)
314 * chState = (get(AR9170_MAC_REG_MISC_684) >> 16) & 0xf;
315 * while( (chState != 0) && (chState != 9)) {
316 * chState = (get(AR9170_MAC_REG_MISC_684) >> 16) & 0xf;
320 set(AR9170_MAC_REG_POWER_STATE_CTRL, val);
324 /* Restore aggregation parameters */
325 set(AR9170_MAC_REG_AMPDU_FACTOR, agg_wait_counter);
326 set(AR9170_MAC_REG_AMPDU_DENSITY, agg_density);
328 set(AR9170_MAC_REG_BCN_ADDR, bcn_start_addr);
329 set(AR9170_MAC_REG_CAM_MODE, cam_mode);
330 set(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L, rctl);
331 set(AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H, rcth);
333 set(AR9170_MAC_REG_RTS_CTS_TPC, rts_cts_tpc);
334 set(AR9170_MAC_REG_ACK_TPC, ack_power);
335 set(AR9170_MAC_REG_RTS_CTS_RATE, rts_cts_rate);
337 #ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
338 set(AR9170_PHY_REG_SWITCH_CHAIN_2, rx_BB);
339 #endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
342 * Manipulate CCA threshold to resume transmission
344 * set(AR9170_PHY_REG_CCA_THRESHOLD, 0x0);
347 val = AR9170_DMA_TRIGGER_RXQ;
348 /* Reinitialize all WLAN TX DMA queues. */
349 for (i = AR9170_TXQ_SPECIAL; i >= AR9170_TXQ0; i--) {
350 struct dma_desc *iter;
352 __for_each_desc_bits(iter, &fw.wlan.tx_queue[i], AR9170_OWN_BITS_SW);
354 /* kill the stuck frame */
355 if (!is_terminator(&fw.wlan.tx_queue[i], iter) &&
356 fw.wlan.last_super_num[i] >= CARL9170FW_TX_MAC_RESET &&
357 fw.wlan.last_super[i] == DESC_PAYLOAD(iter)) {
358 struct carl9170_tx_superframe *super = get_super(iter);
360 iter->status = AR9170_OWN_BITS_SW;
362 * Mark the frame as failed.
363 * The BAFAIL flag allows the frame to sail through
364 * wlan_tx_status without much "unstuck" trouble.
366 iter->ctrl &= ~(AR9170_CTRL_FAIL);
367 iter->ctrl |= AR9170_CTRL_BAFAIL;
369 super->s.cnt = CARL9170_TX_MAX_RATE_TRIES;
370 super->s.rix = CARL9170_TX_MAX_RETRY_RATES;
372 fw.wlan.last_super_num[i] = 0;
373 fw.wlan.last_super[i] = NULL;
374 iter = iter->lastAddr->nextAddr;
377 set_wlan_txq_dma_addr(i, (uint32_t) iter);
378 if (!is_terminator(&fw.wlan.tx_queue[i], iter))
381 DBG("Q:%d l:%d h:%p t:%p cu:%p it:%p ct:%x st:%x\n", i, queue_len(&fw.wlan.tx_queue[i]),
382 fw.wlan.tx_queue[i].head, fw.wlan.tx_queue[i].terminator,
383 get_wlan_txq_addr(i), iter, iter->ctrl, iter->status);
386 fw.wlan.soft_int |= AR9170_MAC_INT_RXC | AR9170_MAC_INT_TXC |
387 AR9170_MAC_INT_RETRY_FAIL;
389 set(AR9170_MAC_REG_DMA_RXQ_ADDR, (uint32_t) fw.wlan.rx_queue.head);
393 static void wlan_mac_reset(void)
395 /* The driver takes care of reinitializing the device */
398 #endif /* CONFIG_CARL9170FW_FW_MAC_RESET */
400 void __cold wlan_timer(void)
402 unsigned int cached_mac_reset;
404 cached_mac_reset = fw.wlan.mac_reset;
406 /* TX Queue Hang check */
409 /* RX Overrun check */
410 wlan_check_rx_overrun();
412 if (unlikely(fw.wlan.mac_reset >= CARL9170_MAC_RESET_RESET)) {
414 fw.wlan.mac_reset = CARL9170_MAC_RESET_OFF;
416 if (fw.wlan.mac_reset && cached_mac_reset == fw.wlan.mac_reset)