wl12xx: update fw status struct
Update the fw status struct according to the new fw api (fw >= 6/7.0.0.35). All the roles use the same struct now. The memory accounting was changed a bit according to the struct changes. Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
Родитель
08c1d1c704
Коммит
4d56ad9cae
|
@ -349,10 +349,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
|
|||
DRIVER_STATE_PRINT_INT(tx_packets_count);
|
||||
DRIVER_STATE_PRINT_INT(tx_results_count);
|
||||
DRIVER_STATE_PRINT_LHEX(flags);
|
||||
DRIVER_STATE_PRINT_INT(tx_blocks_freed[0]);
|
||||
DRIVER_STATE_PRINT_INT(tx_blocks_freed[1]);
|
||||
DRIVER_STATE_PRINT_INT(tx_blocks_freed[2]);
|
||||
DRIVER_STATE_PRINT_INT(tx_blocks_freed[3]);
|
||||
DRIVER_STATE_PRINT_INT(tx_blocks_freed);
|
||||
DRIVER_STATE_PRINT_INT(tx_security_last_seq_lsb);
|
||||
DRIVER_STATE_PRINT_INT(rx_counter);
|
||||
DRIVER_STATE_PRINT_INT(session_counter);
|
||||
|
|
|
@ -826,22 +826,14 @@ static void wl1271_irq_update_links_status(struct wl1271 *wl,
|
|||
}
|
||||
#endif
|
||||
|
||||
static void wl1271_fw_status(struct wl1271 *wl,
|
||||
struct wl1271_fw_full_status *full_status)
|
||||
static void wl12xx_fw_status(struct wl1271 *wl,
|
||||
struct wl12xx_fw_status *status)
|
||||
{
|
||||
struct wl1271_fw_common_status *status = &full_status->common;
|
||||
struct timespec ts;
|
||||
u32 old_tx_blk_count = wl->tx_blocks_available;
|
||||
u32 freed_blocks = 0;
|
||||
int i;
|
||||
int avail, freed_blocks;
|
||||
|
||||
if (wl->bss_type == BSS_TYPE_AP_BSS) {
|
||||
wl1271_raw_read(wl, FW_STATUS_ADDR, status,
|
||||
sizeof(struct wl1271_fw_ap_status), false);
|
||||
} else {
|
||||
wl1271_raw_read(wl, FW_STATUS_ADDR, status,
|
||||
sizeof(struct wl1271_fw_sta_status), false);
|
||||
}
|
||||
wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false);
|
||||
|
||||
wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
|
||||
"drv_rx_counter = %d, tx_results_counter = %d)",
|
||||
|
@ -850,42 +842,36 @@ static void wl1271_fw_status(struct wl1271 *wl,
|
|||
status->drv_rx_counter,
|
||||
status->tx_results_counter);
|
||||
|
||||
/* update number of available TX blocks */
|
||||
for (i = 0; i < NUM_TX_QUEUES; i++) {
|
||||
freed_blocks += le32_to_cpu(status->tx_released_blks[i]) -
|
||||
wl->tx_blocks_freed[i];
|
||||
|
||||
wl->tx_blocks_freed[i] =
|
||||
le32_to_cpu(status->tx_released_blks[i]);
|
||||
}
|
||||
freed_blocks = le32_to_cpu(status->total_released_blks) -
|
||||
wl->tx_blocks_freed;
|
||||
wl->tx_blocks_freed = le32_to_cpu(status->total_released_blks);
|
||||
|
||||
wl->tx_allocated_blocks -= freed_blocks;
|
||||
|
||||
if (wl->bss_type == BSS_TYPE_AP_BSS) {
|
||||
/* Update num of allocated TX blocks per link and ps status */
|
||||
#if 0
|
||||
wl1271_irq_update_links_status(wl, &full_status->ap);
|
||||
#endif
|
||||
wl->tx_blocks_available += freed_blocks;
|
||||
} else {
|
||||
int avail = full_status->sta.tx_total - wl->tx_allocated_blocks;
|
||||
avail = le32_to_cpu(status->tx_total) - wl->tx_allocated_blocks;
|
||||
|
||||
/*
|
||||
* The FW might change the total number of TX memblocks before
|
||||
* we get a notification about blocks being released. Thus, the
|
||||
* available blocks calculation might yield a temporary result
|
||||
* which is lower than the actual available blocks. Keeping in
|
||||
* mind that only blocks that were allocated can be moved from
|
||||
* TX to RX, tx_blocks_available should never decrease here.
|
||||
*/
|
||||
wl->tx_blocks_available = max((int)wl->tx_blocks_available,
|
||||
avail);
|
||||
}
|
||||
/*
|
||||
* The FW might change the total number of TX memblocks before
|
||||
* we get a notification about blocks being released. Thus, the
|
||||
* available blocks calculation might yield a temporary result
|
||||
* which is lower than the actual available blocks. Keeping in
|
||||
* mind that only blocks that were allocated can be moved from
|
||||
* TX to RX, tx_blocks_available should never decrease here.
|
||||
*/
|
||||
wl->tx_blocks_available = max((int)wl->tx_blocks_available,
|
||||
avail);
|
||||
|
||||
/* if more blocks are available now, tx work can be scheduled */
|
||||
if (wl->tx_blocks_available > old_tx_blk_count)
|
||||
clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
|
||||
|
||||
/* for AP update num of allocated TX blocks per link and ps status */
|
||||
if (wl->bss_type == BSS_TYPE_AP_BSS) {
|
||||
#if 0
|
||||
wl1271_irq_update_links_status(wl, status);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* update the host-chipset time offset */
|
||||
getnstimeofday(&ts);
|
||||
wl->time_offset = (timespec_to_ns(&ts) >> 10) -
|
||||
|
@ -958,8 +944,8 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
|
|||
clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
|
||||
smp_mb__after_clear_bit();
|
||||
|
||||
wl1271_fw_status(wl, wl->fw_status);
|
||||
intr = le32_to_cpu(wl->fw_status->common.intr);
|
||||
wl12xx_fw_status(wl, wl->fw_status);
|
||||
intr = le32_to_cpu(wl->fw_status->intr);
|
||||
intr &= WL1271_INTR_MASK;
|
||||
if (!intr) {
|
||||
done = true;
|
||||
|
@ -978,7 +964,7 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
|
|||
if (likely(intr & WL1271_ACX_INTR_DATA)) {
|
||||
wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
|
||||
|
||||
wl1271_rx(wl, &wl->fw_status->common);
|
||||
wl12xx_rx(wl, wl->fw_status);
|
||||
|
||||
/* Check if any tx blocks were freed */
|
||||
spin_lock_irqsave(&wl->wl_lock, flags);
|
||||
|
@ -995,7 +981,7 @@ irqreturn_t wl1271_irq(int irq, void *cookie)
|
|||
}
|
||||
|
||||
/* check for tx results */
|
||||
if (wl->fw_status->common.tx_results_counter !=
|
||||
if (wl->fw_status->tx_results_counter !=
|
||||
(wl->tx_results_count & 0xff))
|
||||
wl1271_tx_complete(wl);
|
||||
|
||||
|
@ -1169,8 +1155,8 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
|
|||
wl12xx_cmd_stop_fwlog(wl);
|
||||
|
||||
/* Read the first memory block address */
|
||||
wl1271_fw_status(wl, wl->fw_status);
|
||||
first_addr = __le32_to_cpu(wl->fw_status->sta.log_start_addr);
|
||||
wl12xx_fw_status(wl, wl->fw_status);
|
||||
first_addr = le32_to_cpu(wl->fw_status->log_start_addr);
|
||||
if (!first_addr)
|
||||
goto out;
|
||||
|
||||
|
@ -1186,7 +1172,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
|
|||
* of each memory block hold the hardware address of the next
|
||||
* one. The last memory block points to the first one.
|
||||
*/
|
||||
addr = __le32_to_cpup((__le32 *)block);
|
||||
addr = le32_to_cpup((__le32 *)block);
|
||||
if (!wl12xx_copy_fwlog(wl, block + sizeof(addr),
|
||||
WL12XX_HW_BLOCK_SIZE - sizeof(addr)))
|
||||
break;
|
||||
|
@ -1923,7 +1909,6 @@ out:
|
|||
static void __wl1271_op_remove_interface(struct wl1271 *wl,
|
||||
bool reset_tx_queues)
|
||||
{
|
||||
int i;
|
||||
|
||||
wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
|
||||
|
||||
|
@ -2004,8 +1989,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
|
|||
*/
|
||||
wl->flags = 0;
|
||||
|
||||
for (i = 0; i < NUM_TX_QUEUES; i++)
|
||||
wl->tx_blocks_freed[i] = 0;
|
||||
wl->tx_blocks_freed = 0;
|
||||
|
||||
wl1271_debugfs_reset(wl);
|
||||
|
||||
|
|
|
@ -30,21 +30,21 @@
|
|||
#include "rx.h"
|
||||
#include "io.h"
|
||||
|
||||
static u8 wl1271_rx_get_mem_block(struct wl1271_fw_common_status *status,
|
||||
static u8 wl12xx_rx_get_mem_block(struct wl12xx_fw_status *status,
|
||||
u32 drv_rx_counter)
|
||||
{
|
||||
return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
|
||||
RX_MEM_BLOCK_MASK;
|
||||
}
|
||||
|
||||
static u32 wl1271_rx_get_buf_size(struct wl1271_fw_common_status *status,
|
||||
u32 drv_rx_counter)
|
||||
static u32 wl12xx_rx_get_buf_size(struct wl12xx_fw_status *status,
|
||||
u32 drv_rx_counter)
|
||||
{
|
||||
return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
|
||||
RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV;
|
||||
}
|
||||
|
||||
static bool wl1271_rx_get_unaligned(struct wl1271_fw_common_status *status,
|
||||
static bool wl12xx_rx_get_unaligned(struct wl12xx_fw_status *status,
|
||||
u32 drv_rx_counter)
|
||||
{
|
||||
/* Convert the value to bool */
|
||||
|
@ -181,7 +181,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
|
|||
return is_data;
|
||||
}
|
||||
|
||||
void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
|
||||
void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
|
||||
{
|
||||
struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
|
||||
u32 buf_size;
|
||||
|
@ -199,7 +199,7 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
|
|||
buf_size = 0;
|
||||
rx_counter = drv_rx_counter;
|
||||
while (rx_counter != fw_rx_counter) {
|
||||
pkt_length = wl1271_rx_get_buf_size(status, rx_counter);
|
||||
pkt_length = wl12xx_rx_get_buf_size(status, rx_counter);
|
||||
if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE)
|
||||
break;
|
||||
buf_size += pkt_length;
|
||||
|
@ -218,7 +218,7 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
|
|||
* For aggregated packets, only the first memory block
|
||||
* should be retrieved. The FW takes care of the rest.
|
||||
*/
|
||||
mem_block = wl1271_rx_get_mem_block(status,
|
||||
mem_block = wl12xx_rx_get_mem_block(status,
|
||||
drv_rx_counter);
|
||||
|
||||
wl->rx_mem_pool_addr.addr = (mem_block << 8) +
|
||||
|
@ -239,10 +239,10 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status)
|
|||
/* Split data into separate packets */
|
||||
pkt_offset = 0;
|
||||
while (pkt_offset < buf_size) {
|
||||
pkt_length = wl1271_rx_get_buf_size(status,
|
||||
pkt_length = wl12xx_rx_get_buf_size(status,
|
||||
drv_rx_counter);
|
||||
|
||||
unaligned = wl1271_rx_get_unaligned(status,
|
||||
unaligned = wl12xx_rx_get_unaligned(status,
|
||||
drv_rx_counter);
|
||||
|
||||
/*
|
||||
|
|
|
@ -129,7 +129,7 @@ struct wl1271_rx_descriptor {
|
|||
u8 reserved;
|
||||
} __packed;
|
||||
|
||||
void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status);
|
||||
void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status);
|
||||
u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -137,6 +137,7 @@ extern u32 wl12xx_debug_level;
|
|||
#define WL1271_DEFAULT_BEACON_INT 100
|
||||
#define WL1271_DEFAULT_DTIM_PERIOD 1
|
||||
|
||||
#define WL12XX_MAX_LINKS 8
|
||||
#define WL1271_AP_GLOBAL_HLID 0
|
||||
#define WL1271_AP_BROADCAST_HLID 1
|
||||
#define WL1271_AP_STA_HLID_START 2
|
||||
|
@ -230,23 +231,15 @@ struct wl1271_stats {
|
|||
/* Broadcast and Global links + links to stations */
|
||||
#define AP_MAX_LINKS (AP_MAX_STATIONS + 2)
|
||||
|
||||
/* FW status registers common for AP/STA */
|
||||
struct wl1271_fw_common_status {
|
||||
/* FW status registers */
|
||||
struct wl12xx_fw_status {
|
||||
__le32 intr;
|
||||
u8 fw_rx_counter;
|
||||
u8 drv_rx_counter;
|
||||
u8 reserved;
|
||||
u8 tx_results_counter;
|
||||
__le32 rx_pkt_descs[NUM_RX_PKT_DESC];
|
||||
__le32 tx_released_blks[NUM_TX_QUEUES];
|
||||
__le32 fw_localtime;
|
||||
} __packed;
|
||||
|
||||
/* FW status registers for AP */
|
||||
struct wl1271_fw_ap_status {
|
||||
struct wl1271_fw_common_status common;
|
||||
|
||||
/* Next fields valid only in AP FW */
|
||||
|
||||
/*
|
||||
* A bitmap (where each bit represents a single HLID)
|
||||
|
@ -254,30 +247,30 @@ struct wl1271_fw_ap_status {
|
|||
*/
|
||||
__le32 link_ps_bitmap;
|
||||
|
||||
/* Number of freed MBs per HLID */
|
||||
u8 tx_lnk_free_blks[AP_MAX_LINKS];
|
||||
u8 padding_1[1];
|
||||
} __packed;
|
||||
/*
|
||||
* A bitmap (where each bit represents a single HLID) to indicate
|
||||
* if the station is in Fast mode
|
||||
*/
|
||||
__le32 link_fast_bitmap;
|
||||
|
||||
/* FW status registers for STA */
|
||||
struct wl1271_fw_sta_status {
|
||||
struct wl1271_fw_common_status common;
|
||||
/* Cumulative counter of total released mem blocks since FW-reset */
|
||||
__le32 total_released_blks;
|
||||
|
||||
u8 tx_total;
|
||||
u8 reserved1;
|
||||
__le16 reserved2;
|
||||
/* Size (in Memory Blocks) of TX pool */
|
||||
__le32 tx_total;
|
||||
|
||||
/* Cumulative counter of released mem-blocks per AC */
|
||||
u8 tx_released_blks[NUM_TX_QUEUES];
|
||||
|
||||
/* Cumulative counter of freed MBs per HLID */
|
||||
u8 tx_lnk_free_blks[WL12XX_MAX_LINKS];
|
||||
|
||||
/* Cumulative counter of released Voice memory blocks */
|
||||
u8 tx_voice_released_blks;
|
||||
u8 padding_1[7];
|
||||
__le32 log_start_addr;
|
||||
} __packed;
|
||||
|
||||
struct wl1271_fw_full_status {
|
||||
union {
|
||||
struct wl1271_fw_common_status common;
|
||||
struct wl1271_fw_sta_status sta;
|
||||
struct wl1271_fw_ap_status ap;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
|
||||
struct wl1271_rx_mem_pool_addr {
|
||||
u32 addr;
|
||||
u32 addr_extra;
|
||||
|
@ -401,7 +394,7 @@ struct wl1271 {
|
|||
struct wl1271_acx_mem_map *target_mem_map;
|
||||
|
||||
/* Accounting for allocated / available TX blocks on HW */
|
||||
u32 tx_blocks_freed[NUM_TX_QUEUES];
|
||||
u32 tx_blocks_freed;
|
||||
u32 tx_blocks_available;
|
||||
u32 tx_allocated_blocks;
|
||||
u32 tx_results_count;
|
||||
|
@ -537,7 +530,7 @@ struct wl1271 {
|
|||
u32 buffer_cmd;
|
||||
u32 buffer_busyword[WL1271_BUSY_WORD_CNT];
|
||||
|
||||
struct wl1271_fw_full_status *fw_status;
|
||||
struct wl12xx_fw_status *fw_status;
|
||||
struct wl1271_tx_hw_res_if *tx_res_if;
|
||||
|
||||
struct ieee80211_vif *vif;
|
||||
|
|
Загрузка…
Ссылка в новой задаче