Skip to content

Commit

Permalink
Merge branch 'for-linville' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/luca/wl12xx
  • Loading branch information
John W. Linville committed Jul 8, 2011
2 parents 5f0dd29 + f1a4638 commit e441a5e
Show file tree
Hide file tree
Showing 17 changed files with 414 additions and 144 deletions.
12 changes: 6 additions & 6 deletions drivers/net/wireless/wl12xx/acx.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ int wl1271_acx_tx_power(struct wl1271 *wl, int power)
struct acx_current_tx_power *acx;
int ret;

wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
wl1271_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr %d", power);

if (power < 0 || power > 25)
return -EINVAL;
Expand Down Expand Up @@ -1624,22 +1624,22 @@ int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, bool enable)
return ret;
}

int wl1271_acx_max_tx_retry(struct wl1271 *wl)
int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl)
{
struct wl1271_acx_max_tx_retry *acx = NULL;
struct wl1271_acx_ap_max_tx_retry *acx = NULL;
int ret;

wl1271_debug(DEBUG_ACX, "acx max tx retry");
wl1271_debug(DEBUG_ACX, "acx ap max tx retry");

acx = kzalloc(sizeof(*acx), GFP_KERNEL);
if (!acx)
return -ENOMEM;

acx->max_tx_retry = cpu_to_le16(wl->conf.tx.ap_max_tx_retries);
acx->max_tx_retry = cpu_to_le16(wl->conf.tx.max_tx_retries);

ret = wl1271_cmd_configure(wl, ACX_MAX_TX_FAILURE, acx, sizeof(*acx));
if (ret < 0) {
wl1271_warning("acx max tx retry failed: %d", ret);
wl1271_warning("acx ap max tx retry failed: %d", ret);
goto out;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/wl12xx/acx.h
Original file line number Diff line number Diff line change
Expand Up @@ -1168,7 +1168,7 @@ struct wl1271_acx_ps_rx_streaming {
u8 timeout;
} __packed;

struct wl1271_acx_max_tx_retry {
struct wl1271_acx_ap_max_tx_retry {
struct acx_header header;

/*
Expand Down Expand Up @@ -1400,7 +1400,7 @@ int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
bool enable);
int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, bool enable);
int wl1271_acx_max_tx_retry(struct wl1271 *wl);
int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl);
int wl1271_acx_config_ps(struct wl1271 *wl);
int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
int wl1271_acx_set_ap_beacon_filter(struct wl1271 *wl, bool enable);
Expand Down
4 changes: 3 additions & 1 deletion drivers/net/wireless/wl12xx/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,9 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
PERIODIC_SCAN_COMPLETE_EVENT_ID;

if (wl->bss_type == BSS_TYPE_AP_BSS)
wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID;
wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID |
INACTIVE_STA_EVENT_ID |
MAX_TX_RETRY_EVENT_ID;
else
wl->event_mask |= DUMMY_PACKET_EVENT_ID |
BA_SESSION_RX_CONSTRAINT_EVENT_ID;
Expand Down
6 changes: 1 addition & 5 deletions drivers/net/wireless/wl12xx/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,10 +400,6 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)

join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET;

/* reset TX security counters */
wl->tx_security_last_seq = 0;
wl->tx_security_seq = 0;

wl1271_debug(DEBUG_CMD, "cmd join: basic_rate_set=0x%x, rate_set=0x%x",
join->basic_rate_set, join->supported_rate_set);

Expand Down Expand Up @@ -1084,7 +1080,7 @@ int wl1271_cmd_start_bss(struct wl1271 *wl)

memcpy(cmd->bssid, bss_conf->bssid, ETH_ALEN);

cmd->aging_period = cpu_to_le16(WL1271_AP_DEF_INACTIV_SEC);
cmd->aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period);
cmd->bss_index = WL1271_AP_BSS_INDEX;
cmd->global_hlid = WL1271_AP_GLOBAL_HLID;
cmd->broadcast_hlid = WL1271_AP_BROADCAST_HLID;
Expand Down
10 changes: 9 additions & 1 deletion drivers/net/wireless/wl12xx/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -713,8 +713,16 @@ struct conf_tx_settings {
/*
* AP-mode - allow this number of TX retries to a station before an
* event is triggered from FW.
* In AP-mode the hlids of unreachable stations are given in the
* "sta_tx_retry_exceeded" member in the event mailbox.
*/
u16 ap_max_tx_retries;
u8 max_tx_retries;

/*
* AP-mode - after this number of seconds a connected station is
* considered inactive.
*/
u16 ap_aging_period;

/*
* Configuration for TID parameters.
Expand Down
15 changes: 11 additions & 4 deletions drivers/net/wireless/wl12xx/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "acx.h"
#include "ps.h"
#include "io.h"
#include "tx.h"

/* ms */
#define WL1271_DEBUGFS_STATS_LIFETIME 1000
Expand Down Expand Up @@ -233,7 +234,7 @@ static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
char buf[20];
int res;

queue_len = wl->tx_queue_count;
queue_len = wl1271_tx_total_queue_count(wl);

res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
Expand Down Expand Up @@ -338,18 +339,24 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf,
#define DRIVER_STATE_PRINT_HEX(x) DRIVER_STATE_PRINT(x, "0x%x")

DRIVER_STATE_PRINT_INT(tx_blocks_available);
DRIVER_STATE_PRINT_INT(tx_allocated_blocks);
DRIVER_STATE_PRINT_INT(tx_allocated_blocks[0]);
DRIVER_STATE_PRINT_INT(tx_allocated_blocks[1]);
DRIVER_STATE_PRINT_INT(tx_allocated_blocks[2]);
DRIVER_STATE_PRINT_INT(tx_allocated_blocks[3]);
DRIVER_STATE_PRINT_INT(tx_frames_cnt);
DRIVER_STATE_PRINT_LHEX(tx_frames_map[0]);
DRIVER_STATE_PRINT_INT(tx_queue_count);
DRIVER_STATE_PRINT_INT(tx_queue_count[0]);
DRIVER_STATE_PRINT_INT(tx_queue_count[1]);
DRIVER_STATE_PRINT_INT(tx_queue_count[2]);
DRIVER_STATE_PRINT_INT(tx_queue_count[3]);
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_security_last_seq);
DRIVER_STATE_PRINT_INT(tx_security_last_seq_lsb);
DRIVER_STATE_PRINT_INT(rx_counter);
DRIVER_STATE_PRINT_INT(session_counter);
DRIVER_STATE_PRINT_INT(state);
Expand Down
42 changes: 42 additions & 0 deletions drivers/net/wireless/wl12xx/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
u32 vector;
bool beacon_loss = false;
bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
bool disconnect_sta = false;
unsigned long sta_bitmap = 0;

wl1271_event_mbox_dump(mbox);

Expand Down Expand Up @@ -295,6 +297,46 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
wl1271_tx_dummy_packet(wl);
}

/*
* "TX retries exceeded" has a different meaning according to mode.
* In AP mode the offending station is disconnected.
*/
if ((vector & MAX_TX_RETRY_EVENT_ID) && is_ap) {
wl1271_debug(DEBUG_EVENT, "MAX_TX_RETRY_EVENT_ID");
sta_bitmap |= le16_to_cpu(mbox->sta_tx_retry_exceeded);
disconnect_sta = true;
}

if ((vector & INACTIVE_STA_EVENT_ID) && is_ap) {
wl1271_debug(DEBUG_EVENT, "INACTIVE_STA_EVENT_ID");
sta_bitmap |= le16_to_cpu(mbox->sta_aging_status);
disconnect_sta = true;
}

if (is_ap && disconnect_sta) {
u32 num_packets = wl->conf.tx.max_tx_retries;
struct ieee80211_sta *sta;
const u8 *addr;
int h;

for (h = find_first_bit(&sta_bitmap, AP_MAX_LINKS);
h < AP_MAX_LINKS;
h = find_next_bit(&sta_bitmap, AP_MAX_LINKS, h+1)) {
if (!wl1271_is_active_sta(wl, h))
continue;

addr = wl->links[h].addr;

rcu_read_lock();
sta = ieee80211_find_sta(wl->vif, addr);
if (sta) {
wl1271_debug(DEBUG_EVENT, "remove sta %d", h);
ieee80211_report_low_ack(sta, num_packets);
}
rcu_read_unlock();
}
}

if (wl->vif && beacon_loss)
ieee80211_connection_loss(wl->vif);

Expand Down
12 changes: 11 additions & 1 deletion drivers/net/wireless/wl12xx/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,16 @@ enum {
CHANNEL_SWITCH_COMPLETE_EVENT_ID = BIT(17),
BSS_LOSE_EVENT_ID = BIT(18),
REGAINED_BSS_EVENT_ID = BIT(19),
ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID = BIT(20),
MAX_TX_RETRY_EVENT_ID = BIT(20),
/* STA: dummy paket for dynamic mem blocks */
DUMMY_PACKET_EVENT_ID = BIT(21),
/* AP: STA remove complete */
STA_REMOVE_COMPLETE_EVENT_ID = BIT(21),
SOFT_GEMINI_SENSE_EVENT_ID = BIT(22),
/* STA: SG prediction */
SOFT_GEMINI_PREDICTION_EVENT_ID = BIT(23),
/* AP: Inactive STA */
INACTIVE_STA_EVENT_ID = BIT(23),
SOFT_GEMINI_AVALANCHE_EVENT_ID = BIT(24),
PLT_RX_CALIBRATION_COMPLETE_EVENT_ID = BIT(25),
DBG_EVENT_ID = BIT(26),
Expand Down Expand Up @@ -119,7 +122,11 @@ struct event_mailbox {

/* AP FW only */
u8 hlid_removed;

/* a bitmap of hlids for stations that have been inactive too long */
__le16 sta_aging_status;

/* a bitmap of hlids for stations which didn't respond to TX */
__le16 sta_tx_retry_exceeded;

/*
Expand All @@ -143,4 +150,7 @@ void wl1271_event_mbox_config(struct wl1271 *wl);
int wl1271_event_handle(struct wl1271 *wl, u8 mbox);
void wl1271_pspoll_work(struct work_struct *work);

/* Functions from main.c */
bool wl1271_is_active_sta(struct wl1271 *wl, u8 hlid);

#endif
7 changes: 6 additions & 1 deletion drivers/net/wireless/wl12xx/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,14 +447,19 @@ static int wl1271_ap_hw_init(struct wl1271 *wl)
if (ret < 0)
return ret;

ret = wl1271_acx_max_tx_retry(wl);
ret = wl1271_acx_ap_max_tx_retry(wl);
if (ret < 0)
return ret;

ret = wl1271_acx_ap_mem_cfg(wl);
if (ret < 0)
return ret;

/* initialize Tx power */
ret = wl1271_acx_tx_power(wl, wl->power_level);
if (ret < 0)
return ret;

return 0;
}

Expand Down
Loading

0 comments on commit e441a5e

Please sign in to comment.