Skip to content

Commit

Permalink
wlcore: update event mailbox to new fw api
Browse files Browse the repository at this point in the history
The event mailbox now has different structure
for 12xx and 18xx.

For now, handle only 18xx.

TODO: handle 12xx as well

Signed-off-by: Eliad Peller <eliad@wizery.com>
  • Loading branch information
elp committed Oct 10, 2012
1 parent 5d2b40b commit 5d6c13e
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 41 deletions.
55 changes: 31 additions & 24 deletions drivers/net/wireless/ti/wlcore/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
{
wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
wl1271_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
wl1271_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
}

static int wl1271_event_process(struct wl1271 *wl)
Expand All @@ -94,19 +93,19 @@ static int wl1271_event_process(struct wl1271 *wl)
wl1271_event_mbox_dump(mbox);

vector = le32_to_cpu(mbox->events_vector);
vector &= ~(le32_to_cpu(mbox->events_mask));
wl1271_debug(DEBUG_EVENT, "vector: 0x%x", vector);

if (vector & SCAN_COMPLETE_EVENT_ID) {
wl1271_debug(DEBUG_EVENT, "status: 0x%x",
mbox->scheduled_scan_status);
wl1271_debug(DEBUG_EVENT, "scan results: %d",
mbox->number_of_scan_results);

wl12xx_scan_completed(wl);
}

if (vector & PERIODIC_SCAN_COMPLETE_EVENT_ID) {
wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT "
"(status 0x%0x)", mbox->scheduled_scan_status);
wl1271_debug(DEBUG_EVENT,
"PERIODIC_SCAN_COMPLETE_EVENT (results 0x%0x)",
mbox->number_of_sched_scan_results);
if (wl->sched_vif) {
ieee80211_sched_scan_stopped(wl->hw);
wl->sched_vif = NULL;
Expand Down Expand Up @@ -150,43 +149,51 @@ static int wl1271_event_process(struct wl1271 *wl)
}

if (vector & BA_SESSION_RX_CONSTRAINT_EVENT_ID) {
u8 role_id = mbox->role_id;
unsigned long roles_bitmap =
le16_to_cpu(mbox->rx_ba_role_id_bitmap);
unsigned long allowed_bitmap =
le16_to_cpu(mbox->rx_ba_allowed_bitmap);

wl1271_debug(DEBUG_EVENT, "BA_SESSION_RX_CONSTRAINT_EVENT_ID. "
"ba_allowed = 0x%x, role_id=%d",
mbox->rx_ba_allowed, role_id);
"ba_allowed = 0x%lx, role_id=0x%lx",
allowed_bitmap, roles_bitmap);

wl12xx_for_each_wlvif(wl, wlvif) {
if (role_id != 0xff && role_id != wlvif->role_id)
if (wlvif->role_id == WL12XX_INVALID_ROLE_ID ||
!test_bit(wlvif->role_id , &roles_bitmap))
continue;

wlvif->ba_allowed = !!mbox->rx_ba_allowed;
wlvif->ba_allowed = !!test_bit(wlvif->role_id,
&allowed_bitmap);
if (!wlvif->ba_allowed)
wl1271_stop_ba_event(wl, wlvif);
}
}

if (vector & CHANNEL_SWITCH_COMPLETE_EVENT_ID) {
wl1271_debug(DEBUG_EVENT, "CHANNEL_SWITCH_COMPLETE_EVENT_ID. "
"status = 0x%x",
mbox->channel_switch_status);
unsigned long roles_bitmap =
le16_to_cpu(mbox->channel_switch_role_id_bitmap);

wl1271_debug(DEBUG_EVENT, "CHANNEL_SWITCH_COMPLETE_EVENT_ID. roles=0x%lx",
roles_bitmap);

/*
* That event uses for two cases:
* 1) channel switch complete with status=0
* 2) channel switch failed status=1
* we get this event only when channel switch was completed
* successfully. there is no indication for failure...
*/

/* TODO: configure only the relevant vif */
wl12xx_for_each_wlvif_sta(wl, wlvif) {
bool success;
if (wlvif->role_id == WL12XX_INVALID_ROLE_ID ||
!test_bit(wlvif->role_id , &roles_bitmap))
continue;

if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS,
&wlvif->flags))
continue;

success = mbox->channel_switch_status ? false : true;
vif = wl12xx_wlvif_to_vif(wlvif);

ieee80211_chswitch_done(vif, success);
ieee80211_chswitch_done(vif, true);
cancel_delayed_work(&wlvif->channel_switch_work);
}
}

Expand All @@ -203,13 +210,13 @@ static int wl1271_event_process(struct wl1271 *wl)
*/
if (vector & MAX_TX_FAILURE_EVENT_ID) {
wl1271_debug(DEBUG_EVENT, "MAX_TX_FAILURE_EVENT_ID");
sta_bitmap |= le16_to_cpu(mbox->sta_tx_retry_exceeded);
sta_bitmap |= le32_to_cpu(mbox->tx_retry_exceeded_bitmap);
disconnect_sta = true;
}

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

Expand Down
43 changes: 28 additions & 15 deletions drivers/net/wireless/ti/wlcore/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,54 +71,67 @@ enum {

struct event_mailbox {
__le32 events_vector;

u8 number_of_scan_results;
u8 number_of_sched_scan_results;

__le16 channel_switch_role_id_bitmap;

s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS];

/* bitmap of removed links */
__le32 hlid_removed_bitmap;

/* rx ba constraint */
__le16 rx_ba_role_id_bitmap; /* 0xfff means any role. */
__le16 rx_ba_allowed_bitmap;

/* bitmap of roc completed (by role id) */
__le16 roc_completed_bitmap;

/* bitmap of stations (by role id) with bss loss */
__le16 bss_loss_bitmap;

/* bitmap of stations (by HLID) which exceeded max tx retries */
__le32 tx_retry_exceeded_bitmap;

/* bitmap of inactive stations (by HLID) */
__le32 inactive_sta_bitmap;
#if 0
__le32 events_mask;
__le32 reserved_1;
__le32 reserved_2;

u8 number_of_scan_results;
u8 scan_tag;
u8 completed_scan_status;
u8 reserved_3;

u8 soft_gemini_sense_info;
u8 soft_gemini_protective_info;
s8 rssi_snr_trigger_metric[NUM_OF_RSSI_SNR_TRIGGERS];
u8 change_auto_mode_timeout;
u8 scheduled_scan_status;
u8 reserved4;
/* tuned channel (roc) */
u8 roc_channel;

__le16 hlid_removed_bitmap;

/* bitmap of aged stations (by HLID) */
__le16 sta_aging_status;

/* bitmap of stations (by HLID) which exceeded max tx retries */
__le16 sta_tx_retry_exceeded;

/* discovery completed results */
u8 discovery_tag;
u8 number_of_preq_results;
u8 number_of_prsp_results;
u8 reserved_5;

/* rx ba constraint */
u8 role_id; /* 0xFF means any role. */
u8 rx_ba_allowed;
u8 reserved_6[2];

/* Channel switch results */

u8 channel_switch_role_id;
u8 channel_switch_status;
u8 reserved_7[2];

u8 ps_poll_delivery_failure_role_ids;
u8 stopped_role_ids;
u8 started_role_ids;

u8 reserved_8[9];
#endif
} __packed;

struct wl1271;
Expand Down
55 changes: 53 additions & 2 deletions drivers/net/wireless/ti/wlcore/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1985,6 +1985,43 @@ static void wlcore_op_stop(struct ieee80211_hw *hw)
mutex_unlock(&wl->mutex);
}

static void wlcore_channel_switch_work(struct work_struct *work)
{
struct delayed_work *dwork;
struct wl1271 *wl;
struct ieee80211_vif *vif;
struct wl12xx_vif *wlvif;
int ret;

dwork = container_of(work, struct delayed_work, work);
wlvif = container_of(dwork, struct wl12xx_vif, channel_switch_work);
wl = wlvif->wl;

wl1271_info("channel switch failed (role_id: %d).", wlvif->role_id);

mutex_lock(&wl->mutex);

if (unlikely(wl->state != WLCORE_STATE_ON))
goto out;

/* check the channel switch is still ongoing */
if (!test_and_clear_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags))
goto out;

vif = wl12xx_wlvif_to_vif(wlvif);
ieee80211_chswitch_done(vif, false);

ret = wl1271_ps_elp_wakeup(wl);
if (ret < 0)
goto out;

wl12xx_cmd_stop_channel_switch(wl, wlvif);

wl1271_ps_elp_sleep(wl);
out:
mutex_unlock(&wl->mutex);
}

static int wl12xx_allocate_rate_policy(struct wl1271 *wl, u8 *idx)
{
u8 policy = find_first_zero_bit(wl->rate_policies_map,
Expand Down Expand Up @@ -2132,6 +2169,8 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
wl1271_rx_streaming_enable_work);
INIT_WORK(&wlvif->rx_streaming_disable_work,
wl1271_rx_streaming_disable_work);
INIT_DELAYED_WORK(&wlvif->channel_switch_work,
wlcore_channel_switch_work);
INIT_LIST_HEAD(&wlvif->list);

setup_timer(&wlvif->rx_streaming_timer, wl1271_rx_streaming_timer,
Expand Down Expand Up @@ -2659,6 +2698,7 @@ static void wl1271_unjoin(struct wl1271 *wl, struct wl12xx_vif *wlvif)

wl12xx_cmd_stop_channel_switch(wl, wlvif);
ieee80211_chswitch_done(vif, false);
cancel_delayed_work(&wlvif->channel_switch_work);
}

/* invalidate keep-alive template */
Expand Down Expand Up @@ -4905,15 +4945,26 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,

/* TODO: change mac80211 to pass vif as param */
wl12xx_for_each_wlvif_sta(wl, wlvif) {
unsigned long delay_usec;

if (wl12xx_wlvif_to_vif(wlvif)->dummy_p2p)
continue;

ret = wl12xx_cmd_channel_switch(wl, wlvif, ch_switch);
if (ret)
goto out_sleep;

if (!ret)
set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);
set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);

/* indicate failure 5 seconds after channel switch time */
delay_usec = ieee80211_tu_to_usec(wlvif->beacon_int) *
ch_switch->count;
ieee80211_queue_delayed_work(hw, &wlvif->channel_switch_work,
usecs_to_jiffies(delay_usec) +
msecs_to_jiffies(5000));
}

out_sleep:
wl1271_ps_elp_sleep(wl);

out:
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/ti/wlcore/wlcore_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,8 @@ struct wl12xx_vif {
struct work_struct rx_streaming_disable_work;
struct timer_list rx_streaming_timer;

struct delayed_work channel_switch_work;

bool pending_roc;

/*
Expand Down

0 comments on commit 5d6c13e

Please sign in to comment.