|
@@ -347,7 +347,7 @@ static void wl12xx_irq_ps_regulate_link(struct wl1271 *wl,
|
|
|
|
|
|
static void wl12xx_irq_update_links_status(struct wl1271 *wl,
|
|
|
struct wl12xx_vif *wlvif,
|
|
|
- struct wl_fw_status *status)
|
|
|
+ struct wl_fw_status_2 *status)
|
|
|
{
|
|
|
struct wl1271_link *lnk;
|
|
|
u32 cur_fw_ps_map;
|
|
@@ -379,7 +379,8 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl,
|
|
|
}
|
|
|
|
|
|
static void wl12xx_fw_status(struct wl1271 *wl,
|
|
|
- struct wl_fw_status *status)
|
|
|
+ struct wl_fw_status_1 *status_1,
|
|
|
+ struct wl_fw_status_2 *status_2)
|
|
|
{
|
|
|
struct wl12xx_vif *wlvif;
|
|
|
struct timespec ts;
|
|
@@ -388,37 +389,38 @@ static void wl12xx_fw_status(struct wl1271 *wl,
|
|
|
int i;
|
|
|
size_t status_len;
|
|
|
|
|
|
- status_len = sizeof(*status) + wl->fw_status_priv_len;
|
|
|
+ status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
|
|
|
+ sizeof(*status_2) + wl->fw_status_priv_len;
|
|
|
|
|
|
- wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status,
|
|
|
+ wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1,
|
|
|
status_len, false);
|
|
|
|
|
|
wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
|
|
|
"drv_rx_counter = %d, tx_results_counter = %d)",
|
|
|
- status->intr,
|
|
|
- status->fw_rx_counter,
|
|
|
- status->drv_rx_counter,
|
|
|
- status->tx_results_counter);
|
|
|
+ status_1->intr,
|
|
|
+ status_1->fw_rx_counter,
|
|
|
+ status_1->drv_rx_counter,
|
|
|
+ status_1->tx_results_counter);
|
|
|
|
|
|
for (i = 0; i < NUM_TX_QUEUES; i++) {
|
|
|
/* prevent wrap-around in freed-packets counter */
|
|
|
wl->tx_allocated_pkts[i] -=
|
|
|
- (status->counters.tx_released_pkts[i] -
|
|
|
+ (status_2->counters.tx_released_pkts[i] -
|
|
|
wl->tx_pkts_freed[i]) & 0xff;
|
|
|
|
|
|
- wl->tx_pkts_freed[i] = status->counters.tx_released_pkts[i];
|
|
|
+ wl->tx_pkts_freed[i] = status_2->counters.tx_released_pkts[i];
|
|
|
}
|
|
|
|
|
|
/* prevent wrap-around in total blocks counter */
|
|
|
if (likely(wl->tx_blocks_freed <=
|
|
|
- le32_to_cpu(status->total_released_blks)))
|
|
|
- freed_blocks = le32_to_cpu(status->total_released_blks) -
|
|
|
+ le32_to_cpu(status_2->total_released_blks)))
|
|
|
+ freed_blocks = le32_to_cpu(status_2->total_released_blks) -
|
|
|
wl->tx_blocks_freed;
|
|
|
else
|
|
|
freed_blocks = 0x100000000LL - wl->tx_blocks_freed +
|
|
|
- le32_to_cpu(status->total_released_blks);
|
|
|
+ le32_to_cpu(status_2->total_released_blks);
|
|
|
|
|
|
- wl->tx_blocks_freed = le32_to_cpu(status->total_released_blks);
|
|
|
+ wl->tx_blocks_freed = le32_to_cpu(status_2->total_released_blks);
|
|
|
|
|
|
wl->tx_allocated_blocks -= freed_blocks;
|
|
|
|
|
@@ -434,7 +436,7 @@ static void wl12xx_fw_status(struct wl1271 *wl,
|
|
|
cancel_delayed_work(&wl->tx_watchdog_work);
|
|
|
}
|
|
|
|
|
|
- avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks;
|
|
|
+ avail = le32_to_cpu(status_2->tx_total) - wl->tx_allocated_blocks;
|
|
|
|
|
|
/*
|
|
|
* The FW might change the total number of TX memblocks before
|
|
@@ -453,13 +455,13 @@ static void wl12xx_fw_status(struct wl1271 *wl,
|
|
|
|
|
|
/* for AP update num of allocated TX blocks per link and ps status */
|
|
|
wl12xx_for_each_wlvif_ap(wl, wlvif) {
|
|
|
- wl12xx_irq_update_links_status(wl, wlvif, status);
|
|
|
+ wl12xx_irq_update_links_status(wl, wlvif, status_2);
|
|
|
}
|
|
|
|
|
|
/* update the host-chipset time offset */
|
|
|
getnstimeofday(&ts);
|
|
|
wl->time_offset = (timespec_to_ns(&ts) >> 10) -
|
|
|
- (s64)le32_to_cpu(status->fw_localtime);
|
|
|
+ (s64)le32_to_cpu(status_2->fw_localtime);
|
|
|
}
|
|
|
|
|
|
static void wl1271_flush_deferred_work(struct wl1271 *wl)
|
|
@@ -528,11 +530,11 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
|
|
|
clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
|
|
|
smp_mb__after_clear_bit();
|
|
|
|
|
|
- wl12xx_fw_status(wl, wl->fw_status);
|
|
|
+ wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2);
|
|
|
|
|
|
wlcore_hw_tx_immediate_compl(wl);
|
|
|
|
|
|
- intr = le32_to_cpu(wl->fw_status->intr);
|
|
|
+ intr = le32_to_cpu(wl->fw_status_1->intr);
|
|
|
intr &= WL1271_INTR_MASK;
|
|
|
if (!intr) {
|
|
|
done = true;
|
|
@@ -551,7 +553,7 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
|
|
|
if (likely(intr & WL1271_ACX_INTR_DATA)) {
|
|
|
wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
|
|
|
|
|
|
- wl12xx_rx(wl, wl->fw_status);
|
|
|
+ wl12xx_rx(wl, wl->fw_status_1);
|
|
|
|
|
|
/* Check if any tx blocks were freed */
|
|
|
spin_lock_irqsave(&wl->wl_lock, flags);
|
|
@@ -786,8 +788,8 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
|
|
|
wl12xx_cmd_stop_fwlog(wl);
|
|
|
|
|
|
/* Read the first memory block address */
|
|
|
- wl12xx_fw_status(wl, wl->fw_status);
|
|
|
- first_addr = le32_to_cpu(wl->fw_status->log_start_addr);
|
|
|
+ wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2);
|
|
|
+ first_addr = le32_to_cpu(wl->fw_status_2->log_start_addr);
|
|
|
if (!first_addr)
|
|
|
goto out;
|
|
|
|
|
@@ -901,13 +903,18 @@ static void wl1271_fw_wakeup(struct wl1271 *wl)
|
|
|
|
|
|
static int wl1271_setup(struct wl1271 *wl)
|
|
|
{
|
|
|
- wl->fw_status = kmalloc(sizeof(*wl->fw_status), GFP_KERNEL);
|
|
|
- if (!wl->fw_status)
|
|
|
+ wl->fw_status_1 = kmalloc(WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) +
|
|
|
+ sizeof(*wl->fw_status_2), GFP_KERNEL);
|
|
|
+ if (!wl->fw_status_1)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
+ wl->fw_status_2 = (struct wl_fw_status_2 *)
|
|
|
+ (((u8 *) wl->fw_status_1) +
|
|
|
+ WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc));
|
|
|
+
|
|
|
wl->tx_res_if = kmalloc(sizeof(*wl->tx_res_if), GFP_KERNEL);
|
|
|
if (!wl->tx_res_if) {
|
|
|
- kfree(wl->fw_status);
|
|
|
+ kfree(wl->fw_status_1);
|
|
|
return -ENOMEM;
|
|
|
}
|
|
|
|
|
@@ -1746,8 +1753,9 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
|
|
|
|
|
|
wl1271_debugfs_reset(wl);
|
|
|
|
|
|
- kfree(wl->fw_status);
|
|
|
- wl->fw_status = NULL;
|
|
|
+ kfree(wl->fw_status_1);
|
|
|
+ wl->fw_status_1 = NULL;
|
|
|
+ wl->fw_status_2 = NULL;
|
|
|
kfree(wl->tx_res_if);
|
|
|
wl->tx_res_if = NULL;
|
|
|
kfree(wl->target_mem_map);
|
|
@@ -5181,7 +5189,7 @@ int wlcore_free_hw(struct wl1271 *wl)
|
|
|
kfree(wl->nvs);
|
|
|
wl->nvs = NULL;
|
|
|
|
|
|
- kfree(wl->fw_status);
|
|
|
+ kfree(wl->fw_status_1);
|
|
|
kfree(wl->tx_res_if);
|
|
|
destroy_workqueue(wl->freezable_wq);
|
|
|
|