Skip to content

Commit

Permalink
iwlagn: support new P2P implementation
Browse files Browse the repository at this point in the history
The previous P2P implementation turned out to
not work well and new uCode capabilities were
added to support P2P. Modify the driver to
take advantage of those, and also discover P2P
support automatically based on a uCode flag
instead of having a Kconfig symbol for P2P.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Aug 8, 2011
1 parent 4d2a5d0 commit c6baf7f
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 215 deletions.
17 changes: 0 additions & 17 deletions drivers/net/wireless/iwlwifi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,3 @@ config IWLWIFI_DEVICE_SVTOOL
NL80211_TESTMODE. svtool is a software validation tool that runs in
the user space and interacts with the device in the kernel space
through the generic netlink message via NL80211_TESTMODE channel.

config IWL_P2P
bool "iwlwifi experimental P2P support"
depends on IWLAGN
help
This option enables experimental P2P support for some devices
based on microcode support. Since P2P support is still under
development, this option may even enable it for some devices
now that turn out to not support it in the future due to
microcode restrictions.

To determine if your microcode supports the experimental P2P
offered by this option, check if the driver advertises AP
support when it is loaded.

Say Y only if you want to experiment with P2P.

47 changes: 15 additions & 32 deletions drivers/net/wireless/iwlwifi/iwl-agn-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -753,18 +753,6 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
return added;
}

static int iwl_fill_offch_tx(struct iwl_priv *priv, void *data, size_t maxlen)
{
struct sk_buff *skb = priv->offchan_tx_skb;

if (skb->len < maxlen)
maxlen = skb->len;

memcpy(data, skb->data, maxlen);

return maxlen;
}

int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
struct iwl_host_cmd cmd = {
Expand Down Expand Up @@ -807,7 +795,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
scan->quiet_time = IWL_ACTIVE_QUIET_TIME;

if (priv->scan_type != IWL_SCAN_OFFCH_TX &&
if (priv->scan_type != IWL_SCAN_ROC &&
iwl_is_any_associated(priv)) {
u16 interval = 0;
u32 extra;
Expand All @@ -816,7 +804,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)

IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
switch (priv->scan_type) {
case IWL_SCAN_OFFCH_TX:
case IWL_SCAN_ROC:
WARN_ON(1);
break;
case IWL_SCAN_RADIO_RESET:
Expand All @@ -838,10 +826,11 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
scan->suspend_time = cpu_to_le32(scan_suspend_time);
IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
scan_suspend_time, interval);
} else if (priv->scan_type == IWL_SCAN_OFFCH_TX) {
} else if (priv->scan_type == IWL_SCAN_ROC) {
scan->suspend_time = 0;
scan->max_out_time =
cpu_to_le32(1024 * priv->offchan_tx_timeout);
scan->max_out_time = 0;
scan->quiet_time = 0;
scan->quiet_plcp_th = 0;
}

switch (priv->scan_type) {
Expand Down Expand Up @@ -869,8 +858,8 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
} else
IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
break;
case IWL_SCAN_OFFCH_TX:
IWL_DEBUG_SCAN(priv, "Start offchannel TX scan.\n");
case IWL_SCAN_ROC:
IWL_DEBUG_SCAN(priv, "Start ROC scan.\n");
break;
}

Expand Down Expand Up @@ -988,19 +977,13 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
IWL_MAX_SCAN_SIZE - sizeof(*scan));
break;
case IWL_SCAN_RADIO_RESET:
case IWL_SCAN_ROC:
/* use bcast addr, will not be transmitted but must be valid */
cmd_len = iwl_fill_probe_req(priv,
(struct ieee80211_mgmt *)scan->data,
iwl_bcast_addr, NULL, 0,
IWL_MAX_SCAN_SIZE - sizeof(*scan));
break;
case IWL_SCAN_OFFCH_TX:
cmd_len = iwl_fill_offch_tx(priv, scan->data,
IWL_MAX_SCAN_SIZE
- sizeof(*scan)
- sizeof(struct iwl_scan_channel));
scan->scan_flags |= IWL_SCAN_FLAGS_ACTION_FRAME_TX;
break;
default:
BUG();
}
Expand All @@ -1021,18 +1004,18 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
is_active, n_probes,
(void *)&scan->data[cmd_len]);
break;
case IWL_SCAN_OFFCH_TX: {
case IWL_SCAN_ROC: {
struct iwl_scan_channel *scan_ch;

scan->channel_count = 1;

scan_ch = (void *)&scan->data[cmd_len];
scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
scan_ch->channel =
cpu_to_le16(priv->offchan_tx_chan->hw_value);
cpu_to_le16(priv->hw_roc_channel->hw_value);
scan_ch->active_dwell =
cpu_to_le16(priv->offchan_tx_timeout);
scan_ch->passive_dwell = 0;
scan_ch->passive_dwell =
cpu_to_le16(priv->hw_roc_duration);

/* Set txpower levels to defaults */
scan_ch->dsp_atten = 110;
Expand All @@ -1041,7 +1024,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
* power level:
* scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
*/
if (priv->offchan_tx_chan->band == IEEE80211_BAND_5GHZ)
if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ)
scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
else
scan_ch->tx_gain = ((1 << 5) | (5 << 3));
Expand Down
23 changes: 3 additions & 20 deletions drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,10 +337,10 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
cmd.slots[0].type = 0; /* BSS */
cmd.slots[1].type = 1; /* PAN */

if (priv->hw_roc_channel) {
if (priv->hw_roc_setup) {
/* both contexts must be used for this to happen */
slot1 = priv->hw_roc_duration;
slot0 = IWL_MIN_SLOT_TIME;
slot1 = IWL_MIN_SLOT_TIME;
slot0 = 3000;
} else if (ctx_bss->vif && ctx_pan->vif) {
int bcnint = ctx_pan->beacon_int;
int dtim = ctx_pan->vif->bss_conf.dtim_period ?: 1;
Expand Down Expand Up @@ -437,23 +437,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
/* always get timestamp with Rx frame */
ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;

if (ctx->ctxid == IWL_RXON_CTX_PAN && priv->hw_roc_channel) {
struct ieee80211_channel *chan = priv->hw_roc_channel;

iwl_set_rxon_channel(priv, chan, ctx);
iwl_set_flags_for_band(priv, ctx, chan->band, NULL);
ctx->staging.filter_flags |=
RXON_FILTER_ASSOC_MSK |
RXON_FILTER_PROMISC_MSK |
RXON_FILTER_CTL2HOST_MSK;
ctx->staging.dev_type = RXON_DEV_TYPE_P2P;
new_assoc = true;

if (memcmp(&ctx->staging, &ctx->active,
sizeof(ctx->staging)) == 0)
return 0;
}

/*
* force CTS-to-self frames protection if RTS-CTS is not preferred
* one aggregation protection method
Expand Down
30 changes: 12 additions & 18 deletions drivers/net/wireless/iwlwifi/iwl-agn-tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,10 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv,
* handle build REPLY_TX command notification.
*/
static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
struct sk_buff *skb,
struct iwl_tx_cmd *tx_cmd,
struct ieee80211_tx_info *info,
struct ieee80211_hdr *hdr,
u8 std_id)
struct sk_buff *skb,
struct iwl_tx_cmd *tx_cmd,
struct ieee80211_tx_info *info,
struct ieee80211_hdr *hdr, u8 sta_id)
{
__le16 fc = hdr->frame_control;
__le32 tx_flags = tx_cmd->tx_flags;
Expand All @@ -157,7 +156,7 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
tx_flags |= TX_CMD_FLG_IGNORE_BT;


tx_cmd->sta_id = std_id;
tx_cmd->sta_id = sta_id;
if (ieee80211_has_morefrags(fc))
tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;

Expand Down Expand Up @@ -189,9 +188,9 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
#define RTS_DFAULT_RETRY_LIMIT 60

static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
struct iwl_tx_cmd *tx_cmd,
struct ieee80211_tx_info *info,
__le16 fc)
struct iwl_tx_cmd *tx_cmd,
struct ieee80211_tx_info *info,
__le16 fc)
{
u32 rate_flags;
int rate_idx;
Expand Down Expand Up @@ -334,14 +333,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
unsigned long flags;
bool is_agg = false;

/*
* If the frame needs to go out off-channel, then
* we'll have put the PAN context to that channel,
* so make the frame go out there.
*/
if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
ctx = &priv->contexts[IWL_RXON_CTX_PAN];
else if (info->control.vif)
if (info->control.vif)
ctx = iwl_rxon_ctx_from_vif(info->control.vif);

spin_lock_irqsave(&priv->lock, flags);
Expand Down Expand Up @@ -407,7 +399,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
*/
hdr->frame_control |=
cpu_to_le16(IEEE80211_FCTL_MOREDATA);
} else
} else if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
txq_id = IWL_AUX_QUEUE;
else
txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];

/* irqs already disabled/saved above when locking priv->lock */
Expand Down
Loading

0 comments on commit c6baf7f

Please sign in to comment.