Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 194258
b: refs/heads/master
c: b1f9086
h: refs/heads/master
v: v3
  • Loading branch information
John W. Linville committed Apr 12, 2010
1 parent 3f4aa68 commit 5ea74a6
Show file tree
Hide file tree
Showing 15 changed files with 285 additions and 119 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 470058e0ad82fcfaaffd57307d8bf8c094e8e9d7
refs/heads/master: b1f90866fb3a329b1c4ebfff93ae9c110943e50a
13 changes: 9 additions & 4 deletions trunk/drivers/net/wireless/iwlwifi/iwl-4965.c
Original file line number Diff line number Diff line change
Expand Up @@ -2014,7 +2014,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
"%d index %d\n", scd_ssn , index);
freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
if (qc)
iwl_free_tfds_in_queue(priv, sta_id,
tid, freed);

if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark) &&
Expand All @@ -2040,14 +2042,17 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
tx_resp->failure_frame);

freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
if (qc && likely(sta_id != IWL_INVALID_STATION))
iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
else if (sta_id == IWL_INVALID_STATION)
IWL_DEBUG_TX_REPLY(priv, "Station not known\n");

if (priv->mac80211_registered &&
(iwl_queue_space(&txq->q) > txq->q.low_mark))
iwl_wake_queue(priv, txq_id);
}

iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
if (qc && likely(sta_id != IWL_INVALID_STATION))
iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);

iwl_check_abort_status(priv, tx_resp->frame_count, status);
}
Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/net/wireless/wl12xx/wl1271.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ struct wl1271 {
#define WL1271_FLAG_PSM_REQUESTED (8)
#define WL1271_FLAG_IRQ_PENDING (9)
#define WL1271_FLAG_IRQ_RUNNING (10)
#define WL1271_FLAG_IDLE (11)
unsigned long flags;

struct wl1271_partition_set part;
Expand Down Expand Up @@ -472,6 +473,9 @@ struct wl1271 {
/* in dBm */
int power_level;

int rssi_thold;
int last_rssi_event;

struct wl1271_stats stats;
struct wl1271_debugfs debugfs;

Expand Down
71 changes: 71 additions & 0 deletions trunk/drivers/net/wireless/wl12xx/wl1271_acx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,7 @@ int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable)
kfree(acx);
return ret;
}

int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid)
{
struct wl1271_acx_keep_alive_config *acx = NULL;
Expand Down Expand Up @@ -1194,3 +1195,73 @@ int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid)
kfree(acx);
return ret;
}

int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
s16 thold, u8 hyst)
{
struct wl1271_acx_rssi_snr_trigger *acx = NULL;
int ret = 0;

wl1271_debug(DEBUG_ACX, "acx rssi snr trigger");

acx = kzalloc(sizeof(*acx), GFP_KERNEL);
if (!acx) {
ret = -ENOMEM;
goto out;
}

wl->last_rssi_event = -1;

acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing);
acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON;
acx->type = WL1271_ACX_TRIG_TYPE_EDGE;
if (enable)
acx->enable = WL1271_ACX_TRIG_ENABLE;
else
acx->enable = WL1271_ACX_TRIG_DISABLE;

acx->index = WL1271_ACX_TRIG_IDX_RSSI;
acx->dir = WL1271_ACX_TRIG_DIR_BIDIR;
acx->threshold = cpu_to_le16(thold);
acx->hysteresis = hyst;

ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx));
if (ret < 0) {
wl1271_warning("acx rssi snr trigger setting failed: %d", ret);
goto out;
}

out:
kfree(acx);
return ret;
}

int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl)
{
struct wl1271_acx_rssi_snr_avg_weights *acx = NULL;
struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger;
int ret = 0;

wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights");

acx = kzalloc(sizeof(*acx), GFP_KERNEL);
if (!acx) {
ret = -ENOMEM;
goto out;
}

acx->rssi_beacon = c->avg_weight_rssi_beacon;
acx->rssi_data = c->avg_weight_rssi_data;
acx->snr_beacon = c->avg_weight_snr_beacon;
acx->snr_data = c->avg_weight_snr_data;

ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx));
if (ret < 0) {
wl1271_warning("acx rssi snr trigger weights failed: %d", ret);
goto out;
}

out:
kfree(acx);
return ret;
}
56 changes: 55 additions & 1 deletion trunk/drivers/net/wireless/wl12xx/wl1271_acx.h
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,57 @@ struct wl1271_acx_keep_alive_config {
u8 padding;
} __attribute__ ((packed));

enum {
WL1271_ACX_TRIG_TYPE_LEVEL = 0,
WL1271_ACX_TRIG_TYPE_EDGE,
};

enum {
WL1271_ACX_TRIG_DIR_LOW = 0,
WL1271_ACX_TRIG_DIR_HIGH,
WL1271_ACX_TRIG_DIR_BIDIR,
};

enum {
WL1271_ACX_TRIG_ENABLE = 1,
WL1271_ACX_TRIG_DISABLE,
};

enum {
WL1271_ACX_TRIG_METRIC_RSSI_BEACON = 0,
WL1271_ACX_TRIG_METRIC_RSSI_DATA,
WL1271_ACX_TRIG_METRIC_SNR_BEACON,
WL1271_ACX_TRIG_METRIC_SNR_DATA,
};

enum {
WL1271_ACX_TRIG_IDX_RSSI = 0,
WL1271_ACX_TRIG_COUNT = 8,
};

struct wl1271_acx_rssi_snr_trigger {
struct acx_header header;

__le16 threshold;
__le16 pacing; /* 0 - 60000 ms */
u8 metric;
u8 type;
u8 dir;
u8 hysteresis;
u8 index;
u8 enable;
u8 padding[2];
};

struct wl1271_acx_rssi_snr_avg_weights {
struct acx_header header;

u8 rssi_beacon;
u8 rssi_data;
u8 snr_beacon;
u8 snr_data;
};

enum {
ACX_WAKE_UP_CONDITIONS = 0x0002,
ACX_MEM_CFG = 0x0003,
Expand Down Expand Up @@ -990,7 +1041,7 @@ enum {
ACX_FRAG_CFG = 0x004F,
ACX_BET_ENABLE = 0x0050,
ACX_RSSI_SNR_TRIGGER = 0x0051,
ACX_RSSI_SNR_WEIGHTS = 0x0051,
ACX_RSSI_SNR_WEIGHTS = 0x0052,
ACX_KEEP_ALIVE_MODE = 0x0053,
ACX_SET_KEEP_ALIVE_CONFIG = 0x0054,
ACX_BA_SESSION_RESPONDER_POLICY = 0x0055,
Expand Down Expand Up @@ -1060,5 +1111,8 @@ int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address,
int wl1271_acx_pm_config(struct wl1271 *wl);
int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable);
int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid);
int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable,
s16 thold, u8 hyst);
int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl);

#endif /* __WL1271_ACX_H__ */
3 changes: 2 additions & 1 deletion trunk/drivers/net/wireless/wl12xx/wl1271_boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
SCAN_COMPLETE_EVENT_ID |
PS_REPORT_EVENT_ID |
JOIN_EVENT_COMPLETE_ID |
DISCONNECT_EVENT_COMPLETE_ID;
DISCONNECT_EVENT_COMPLETE_ID |
RSSI_SNR_TRIGGER_0_EVENT_ID;

ret = wl1271_event_unmask(wl);
if (ret < 0) {
Expand Down
103 changes: 38 additions & 65 deletions trunk/drivers/net/wireless/wl12xx/wl1271_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -756,65 +756,6 @@ enum {
CONF_TRIG_EVENT_DIR_BIDIR
};


struct conf_sig_trigger {
/*
* The RSSI / SNR threshold value.
*
* FIXME: what is the range?
*/
s16 threshold;

/*
* Minimum delay between two trigger events for this trigger in ms.
*
* Range: 0 - 60000
*/
u16 pacing;

/*
* The measurement data source for this trigger.
*
* Range: CONF_TRIG_METRIC_*
*/
u8 metric;

/*
* The trigger type of this trigger.
*
* Range: CONF_TRIG_EVENT_TYPE_*
*/
u8 type;

/*
* The direction of the trigger.
*
* Range: CONF_TRIG_EVENT_DIR_*
*/
u8 direction;

/*
* Hysteresis range of the trigger around the threshold (in dB)
*
* Range: u8
*/
u8 hysteresis;

/*
* Index of the trigger rule.
*
* Range: 0 - CONF_MAX_RSSI_SNR_TRIGGERS-1
*/
u8 index;

/*
* Enable / disable this rule (to use for clearing rules.)
*
* Range: 1 - Enabled, 2 - Not enabled
*/
u8 enable;
};

struct conf_sig_weights {

/*
Expand Down Expand Up @@ -932,12 +873,6 @@ struct conf_conn_settings {
*/
u8 ps_poll_threshold;

/*
* Configuration of signal (rssi/snr) triggers.
*/
u8 sig_trigger_count;
struct conf_sig_trigger sig_trigger[CONF_MAX_RSSI_SNR_TRIGGERS];

/*
* Configuration of signal average weights.
*/
Expand Down Expand Up @@ -1045,6 +980,43 @@ struct conf_pm_config_settings {
bool host_fast_wakeup_support;
};

struct conf_roam_trigger_settings {
/*
* The minimum interval between two trigger events.
*
* Range: 0 - 60000 ms
*/
u16 trigger_pacing;

/*
* The weight for rssi/beacon average calculation
*
* Range: 0 - 255
*/
u8 avg_weight_rssi_beacon;

/*
* The weight for rssi/data frame average calculation
*
* Range: 0 - 255
*/
u8 avg_weight_rssi_data;

/*
* The weight for snr/beacon average calculation
*
* Range: 0 - 255
*/
u8 avg_weight_snr_beacon;

/*
* The weight for snr/data frame average calculation
*
* Range: 0 - 255
*/
u8 avg_weight_snr_data;
};

struct conf_drv_settings {
struct conf_sg_settings sg;
struct conf_rx_settings rx;
Expand All @@ -1053,6 +1025,7 @@ struct conf_drv_settings {
struct conf_init_settings init;
struct conf_itrim_settings itrim;
struct conf_pm_config_settings pm_config;
struct conf_roam_trigger_settings roam_trigger;
};

#endif
24 changes: 24 additions & 0 deletions trunk/drivers/net/wireless/wl12xx/wl1271_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,24 @@ static int wl1271_event_ps_report(struct wl1271 *wl,
return ret;
}

static void wl1271_event_rssi_trigger(struct wl1271 *wl,
struct event_mailbox *mbox)
{
enum nl80211_cqm_rssi_threshold_event event;
s8 metric = mbox->rssi_snr_trigger_metric[0];

wl1271_debug(DEBUG_EVENT, "RSSI trigger metric: %d", metric);

if (metric <= wl->rssi_thold)
event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
else
event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;

if (event != wl->last_rssi_event)
ieee80211_cqm_rssi_notify(wl->vif, event, GFP_KERNEL);
wl->last_rssi_event = event;
}

static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
{
wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
Expand Down Expand Up @@ -173,6 +191,12 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
return ret;
}

if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) {
wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT");
if (wl->vif)
wl1271_event_rssi_trigger(wl, mbox);
}

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

Expand Down
Loading

0 comments on commit 5ea74a6

Please sign in to comment.