Skip to content

Commit

Permalink
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/linville/wireless-next

John W. Linville says:

====================
One last batch of stragglers intended for 3.9...

For the iwlwifi pull, Johannes says:

"I hadn't expected to ask you to pull iwlwifi-next again, but I have a
number of fixes most of which I'd also send in after rc1, so here it is.

The first commit is a merge error between mac80211-next and
iwlwifi-next; in addition I have fixes for P2P scanning and MVM driver
MAC (virtual interface) management from Ilan, a CT-kill (critical
temperature) fix from Eytan, and myself fixed three different little but
annoying bugs in the MVM driver.

The only ones I might not send for -rc1 are Emmanuel's debug patch, but
OTOH it should help greatly if there are any issues, and my own time
event debugging patch that I used to find the race condition but we
decided to keep it for the future."

For the mac80211 pull, Johannes says:

"Like iwlwifi-next, this would almost be suitable for rc1.

I have a fix for station management on non-TDLS drivers, a CAB queue
crash fix for mesh, a fix for an annoying (but harmless) warning, a
tracing fix and a documentation fix. Other than that, only a few mesh
cleanups."

Along with that is a fix for memory corruption in rtlwifi, an
orinoco_usb fix to avoid allocating a DMA buffer on the stack, an a
hostap fix to return -ENOMEM instead of -1 after a memory allocation
failure.  The remaining bits implement 802.11ac support for the mwifiex
driver -- I think that is still worth getting into 3.9.

Please let me know if there are problems!
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Feb 20, 2013
2 parents 4aa896c + 0b71644 commit c6b5380
Show file tree
Hide file tree
Showing 45 changed files with 1,297 additions and 444 deletions.
4 changes: 2 additions & 2 deletions Documentation/DocBook/80211.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@
!Finclude/net/cfg80211.h key_params
!Finclude/net/cfg80211.h survey_info_flags
!Finclude/net/cfg80211.h survey_info
!Finclude/net/cfg80211.h beacon_parameters
!Finclude/net/cfg80211.h plink_actions
!Finclude/net/cfg80211.h cfg80211_beacon_data
!Finclude/net/cfg80211.h cfg80211_ap_settings
!Finclude/net/cfg80211.h station_parameters
!Finclude/net/cfg80211.h station_info_flags
!Finclude/net/cfg80211.h rate_info_flags
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/hostap/hostap_ap.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac)

entry = kmalloc(sizeof(struct mac_entry), GFP_KERNEL);
if (entry == NULL)
return -1;
return -ENOMEM;

memcpy(entry->addr, mac, ETH_ALEN);

Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/dvm/commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -1403,6 +1403,7 @@ enum {

#define AGG_TX_STATUS_MSK 0x00000fff /* bits 0:11 */
#define AGG_TX_TRY_MSK 0x0000f000 /* bits 12:15 */
#define AGG_TX_TRY_POS 12

#define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL_MSK | \
AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/dvm/tt.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,8 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
set_bit(STATUS_CT_KILL, &priv->status);
iwl_perform_ct_kill_task(priv, true);
} else {
iwl_prepare_ct_kill_task(priv);
tt->state = old_state;
iwl_prepare_ct_kill_task(priv);
}
} else if (old_state == IWL_TI_CT_KILL &&
tt->state != IWL_TI_CT_KILL) {
Expand Down
51 changes: 36 additions & 15 deletions drivers/net/wireless/iwlwifi/dvm/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,12 @@ static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status)
}
}

static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp)
{
return le32_to_cpup((__le32 *)&tx_resp->status +
tx_resp->frame_count) & MAX_SN;
}

static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
struct iwlagn_tx_resp *tx_resp)
{
Expand Down Expand Up @@ -942,16 +948,30 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
if (tx_resp->frame_count == 1)
return;

IWL_DEBUG_TX_REPLY(priv, "TXQ %d initial_rate 0x%x ssn %d frm_cnt %d\n",
agg->txq_id,
le32_to_cpu(tx_resp->rate_n_flags),
iwlagn_get_scd_ssn(tx_resp), tx_resp->frame_count);

/* Construct bit-map of pending frames within Tx window */
for (i = 0; i < tx_resp->frame_count; i++) {
u16 fstatus = le16_to_cpu(frame_status[i].status);
u8 retry_cnt = (fstatus & AGG_TX_TRY_MSK) >> AGG_TX_TRY_POS;

if (status & AGG_TX_STATUS_MSK)
iwlagn_count_agg_tx_err_status(priv, fstatus);

if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
AGG_TX_STATE_ABORT_MSK))
continue;

if (status & AGG_TX_STATUS_MSK || retry_cnt > 1)
IWL_DEBUG_TX_REPLY(priv,
"%d: status %s (0x%04x), try-count (0x%01x)\n",
i,
iwl_get_agg_tx_fail_reason(fstatus),
fstatus & AGG_TX_STATUS_MSK,
retry_cnt);
}
}

Expand Down Expand Up @@ -982,12 +1002,6 @@ const char *iwl_get_agg_tx_fail_reason(u16 status)
}
#endif /* CONFIG_IWLWIFI_DEBUG */

static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp)
{
return le32_to_cpup((__le32 *)&tx_resp->status +
tx_resp->frame_count) & MAX_SN;
}

static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status)
{
status &= TX_STATUS_MSK;
Expand Down Expand Up @@ -1119,8 +1133,14 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,

spin_lock_bh(&priv->sta_lock);

if (is_agg)
if (is_agg) {
WARN_ON_ONCE(sta_id >= IWLAGN_STATION_COUNT ||
tid >= IWL_MAX_TID_COUNT);
if (txq_id != priv->tid_data[sta_id][tid].agg.txq_id)
IWL_ERR(priv, "txq_id mismatch: %d %d\n", txq_id,
priv->tid_data[sta_id][tid].agg.txq_id);
iwl_rx_reply_tx_agg(priv, tx_resp);
}

__skb_queue_head_init(&skbs);

Expand Down Expand Up @@ -1224,16 +1244,17 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
*/
if (is_offchannel_skb && freed != 1)
IWL_ERR(priv, "OFFCHANNEL SKB freed %d\n", freed);
}

IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x)\n", txq_id,
iwl_get_tx_fail_reason(status), status);
IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x)\n", txq_id,
iwl_get_tx_fail_reason(status), status);

IWL_DEBUG_TX_REPLY(priv,
"\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d seq_ctl=0x%x\n",
le32_to_cpu(tx_resp->rate_n_flags),
tx_resp->failure_frame, SEQ_TO_INDEX(sequence), ssn,
le16_to_cpu(tx_resp->seq_ctl));
IWL_DEBUG_TX_REPLY(priv,
"\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d seq_ctl=0x%x\n",
le32_to_cpu(tx_resp->rate_n_flags),
tx_resp->failure_frame,
SEQ_TO_INDEX(sequence), ssn,
le16_to_cpu(tx_resp->seq_ctl));
}

iwl_check_abort_status(priv, tx_resp->frame_count, status);
spin_unlock_bh(&priv->sta_lock);
Expand Down
47 changes: 42 additions & 5 deletions drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
* that we should share it with another interface.
*/

/* Currently, MAC ID 0 should be used only for the managed vif */
if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
__clear_bit(0, data.available_mac_ids);

ieee80211_iterate_active_interfaces_atomic(
mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
iwl_mvm_mac_iface_iterator, &data);
Expand Down Expand Up @@ -286,6 +290,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,

mvmvif->color = 0;

INIT_LIST_HEAD(&mvmvif->time_event_data.list);
mvmvif->time_event_data.id = TE_MAX;

/* No need to allocate data queues to P2P Device MAC.*/
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
Expand Down Expand Up @@ -328,9 +335,6 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
mvmvif->bcast_sta.sta_id = IWL_MVM_STATION_COUNT;
mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;

INIT_LIST_HEAD(&mvmvif->time_event_data.list);
mvmvif->time_event_data.id = TE_MAX;

return 0;

exit_fail:
Expand Down Expand Up @@ -585,10 +589,43 @@ static void iwl_mvm_mac_ctxt_cmd_fill_sta(struct iwl_mvm *mvm,
struct iwl_mac_data_sta *ctxt_sta)
{
/* We need the dtim_period to set the MAC as associated */
if (vif->bss_conf.assoc && vif->bss_conf.dtim_period)
if (vif->bss_conf.assoc && vif->bss_conf.dtim_period) {
u32 dtim_offs;

/*
* The DTIM count counts down, so when it is N that means N
* more beacon intervals happen until the DTIM TBTT. Therefore
* add this to the current time. If that ends up being in the
* future, the firmware will handle it.
*
* Also note that the system_timestamp (which we get here as
* "sync_device_ts") and TSF timestamp aren't at exactly the
* same offset in the frame -- the TSF is at the first symbol
* of the TSF, the system timestamp is at signal acquisition
* time. This means there's an offset between them of at most
* a few hundred microseconds (24 * 8 bits + PLCP time gives
* 384us in the longest case), this is currently not relevant
* as the firmware wakes up around 2ms before the TBTT.
*/
dtim_offs = vif->bss_conf.sync_dtim_count *
vif->bss_conf.beacon_int;
/* convert TU to usecs */
dtim_offs *= 1024;

ctxt_sta->dtim_tsf =
cpu_to_le64(vif->bss_conf.sync_tsf + dtim_offs);
ctxt_sta->dtim_time =
cpu_to_le32(vif->bss_conf.sync_device_ts + dtim_offs);

IWL_DEBUG_INFO(mvm, "DTIM TBTT is 0x%llx/0x%x, offset %d\n",
le64_to_cpu(ctxt_sta->dtim_tsf),
le32_to_cpu(ctxt_sta->dtim_time),
dtim_offs);

ctxt_sta->is_assoc = cpu_to_le32(1);
else
} else {
ctxt_sta->is_assoc = cpu_to_le32(0);
}

ctxt_sta->bi = cpu_to_le32(vif->bss_conf.beacon_int);
ctxt_sta->bi_reciprocal =
Expand Down
10 changes: 4 additions & 6 deletions drivers/net/wireless/iwlwifi/mvm/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
IEEE80211_HW_QUEUE_CONTROL |
IEEE80211_HW_WANT_MONITOR_VIF |
IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
IEEE80211_HW_AMPDU_AGGREGATION;
IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_TIMING_BEACON_ONLY;

hw->queues = IWL_FIRST_AMPDU_QUEUE;
hw->offchannel_tx_hw_queue = IWL_OFFCHANNEL_QUEUE;
Expand Down Expand Up @@ -857,16 +857,14 @@ iwl_mvm_mac_allow_buffered_frames(struct ieee80211_hw *hw,
bool more_data)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;

/* TODO: how do we tell the fw to send frames for a specific TID */

/*
* The fw will send EOSP notification when the last frame will be
* transmitted.
*/
iwl_mvm_sta_modify_sleep_tx_count(mvm, mvmsta->sta_id, reason,
num_frames);
iwl_mvm_sta_modify_sleep_tx_count(mvm, sta, reason, num_frames);
}

static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
Expand All @@ -890,7 +888,7 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
case STA_NOTIFY_AWAKE:
if (WARN_ON(mvmsta->sta_id == IWL_INVALID_STATION))
break;
iwl_mvm_sta_modify_ps_wake(mvm, mvmsta->sta_id);
iwl_mvm_sta_modify_ps_wake(mvm, sta);
break;
default:
break;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/mvm/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,

/* rx_status carries information about the packet to mac80211 */
rx_status.mactime = le64_to_cpu(phy_info->timestamp);
rx_status.device_timestamp = le32_to_cpu(phy_info->system_timestamp);
rx_status.band =
(phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ?
IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
Expand Down
7 changes: 6 additions & 1 deletion drivers/net/wireless/iwlwifi/mvm/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,12 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req);
cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
MAC_FILTER_IN_BEACON);
cmd->type = SCAN_TYPE_FORCED;

if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
cmd->type = cpu_to_le32(SCAN_TYPE_DISCOVERY_FORCED);
else
cmd->type = cpu_to_le32(SCAN_TYPE_FORCED);

cmd->repeats = cpu_to_le32(1);

/*
Expand Down
14 changes: 10 additions & 4 deletions drivers/net/wireless/iwlwifi/mvm/sta.c
Original file line number Diff line number Diff line change
Expand Up @@ -1188,13 +1188,16 @@ void iwl_mvm_update_tkip_key(struct iwl_mvm *mvm,
rcu_read_unlock();
}

void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id)
void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
struct ieee80211_sta *sta)
{
struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
struct iwl_mvm_add_sta_cmd cmd = {
.add_modify = STA_MODE_MODIFY,
.sta_id = sta_id,
.sta_id = mvmsta->sta_id,
.modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
.sleep_state_flags = cpu_to_le16(STA_SLEEP_STATE_AWAKE),
.mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color),
};
int ret;

Expand All @@ -1208,18 +1211,21 @@ void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id)
IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
}

void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm, int sta_id,
void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
struct ieee80211_sta *sta,
enum ieee80211_frame_release_type reason,
u16 cnt)
{
u16 sleep_state_flags =
(reason == IEEE80211_FRAME_RELEASE_UAPSD) ?
STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL;
struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv;
struct iwl_mvm_add_sta_cmd cmd = {
.add_modify = STA_MODE_MODIFY,
.sta_id = sta_id,
.sta_id = mvmsta->sta_id,
.modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT,
.sleep_tx_count = cpu_to_le16(cnt),
.mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color),
/*
* Same modify mask for sleep_tx_count and sleep_state_flags so
* we must set the sleep_state_flags too.
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/wireless/iwlwifi/mvm/sta.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,10 @@ int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
struct iwl_mvm_int_sta *bsta);
int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta);
void iwl_mvm_sta_drained_wk(struct work_struct *wk);
void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, int sta_id);
void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm, int sta_id,
void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
struct ieee80211_sta *sta);
void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
struct ieee80211_sta *sta,
enum ieee80211_frame_release_type reason,
u16 cnt);
int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
Expand Down
10 changes: 9 additions & 1 deletion drivers/net/wireless/iwlwifi/mvm/time-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,11 @@ static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait,
}

resp = (void *)pkt->data;

/* we should never get a response to another TIME_EVENT_CMD here */
if (WARN_ON_ONCE(le32_to_cpu(resp->id) != te_data->id))
return false;

te_data->uid = le32_to_cpu(resp->unique_id);
IWL_DEBUG_TE(mvm, "TIME_EVENT_CMD response - UID = 0x%x\n",
te_data->uid);
Expand All @@ -265,6 +270,9 @@ static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm,

lockdep_assert_held(&mvm->mutex);

IWL_DEBUG_TE(mvm, "Add new TE, duration %d TU\n",
le32_to_cpu(te_cmd->duration));

spin_lock_bh(&mvm->time_event_lock);
if (WARN_ON(te_data->id != TE_MAX)) {
spin_unlock_bh(&mvm->time_event_lock);
Expand Down Expand Up @@ -413,7 +421,7 @@ void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));

IWL_DEBUG_TE(mvm, "Removing TE 0x%x\n", le32_to_cpu(time_cmd.id));
ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_ASYNC,
ret = iwl_mvm_send_cmd_pdu(mvm, TIME_EVENT_CMD, CMD_SYNC,
sizeof(time_cmd), &time_cmd);
if (WARN_ON(ret))
return;
Expand Down
Loading

0 comments on commit c6b5380

Please sign in to comment.