On Mon, 2012-11-26 at 14:57 -0200, Herton Ronaldo Krzesinski wrote:
> 3.5.7u1 -stable review patch.  If anyone has any objections, please let me 
> know.
> 
> ------------------
> 
> From: Johannes Berg <johannes.b...@intel.com>
> 
> commit 8f7b8db6e0557c8437adf9371e020cd89a7e85dc upstream.
> 
> The channel switch command for 6000 series devices
> is larger than the maximum inline command size of
> 320 bytes. The command is therefore refused with a
> warning. Fix this by allocating the command and
> using the NOCOPY mechanism.
> 
> Reviewed-by: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
> Signed-off-by: Johannes Berg <johannes.b...@intel.com>
> [ herton: file name is different on 3.5, code differs a little bit at
>   the end, adjusted context ]
> Signed-off-by: Herton Ronaldo Krzesinski <herton.krzesin...@canonical.com>

Also missing from 3.4; the filename is different again
(drivers/net/wireless/iwlwifi/iwl-6000.c) but this should otherwise be
applicable with one line of fuzz at the end.

Ben.

> ---
>  drivers/net/wireless/iwlwifi/iwl-agn-devices.c |   39 
> +++++++++++++++---------
>  1 file changed, 24 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-devices.c 
> b/drivers/net/wireless/iwlwifi/iwl-agn-devices.c
> index 48533b3..8ab0a7c 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-agn-devices.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-agn-devices.c
> @@ -653,7 +653,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv 
> *priv,
>        * See iwlagn_mac_channel_switch.
>        */
>       struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
> -     struct iwl6000_channel_switch_cmd cmd;
> +     struct iwl6000_channel_switch_cmd *cmd;
>       const struct iwl_channel_info *ch_info;
>       u32 switch_time_in_usec, ucode_switch_time;
>       u16 ch;
> @@ -663,18 +663,25 @@ static int iwl6000_hw_channel_switch(struct iwl_priv 
> *priv,
>       struct ieee80211_vif *vif = ctx->vif;
>       struct iwl_host_cmd hcmd = {
>               .id = REPLY_CHANNEL_SWITCH,
> -             .len = { sizeof(cmd), },
> +             .len = { sizeof(*cmd), },
>               .flags = CMD_SYNC,
> -             .data = { &cmd, },
> +             .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
>       };
> +     int err;
>  
> -     cmd.band = priv->band == IEEE80211_BAND_2GHZ;
> +     cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
> +     if (!cmd)
> +             return -ENOMEM;
> +
> +     hcmd.data[0] = cmd;
> +
> +     cmd->band = priv->band == IEEE80211_BAND_2GHZ;
>       ch = ch_switch->channel->hw_value;
>       IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
>                     ctx->active.channel, ch);
> -     cmd.channel = cpu_to_le16(ch);
> -     cmd.rxon_flags = ctx->staging.flags;
> -     cmd.rxon_filter_flags = ctx->staging.filter_flags;
> +     cmd->channel = cpu_to_le16(ch);
> +     cmd->rxon_flags = ctx->staging.flags;
> +     cmd->rxon_filter_flags = ctx->staging.filter_flags;
>       switch_count = ch_switch->count;
>       tsf_low = ch_switch->timestamp & 0x0ffffffff;
>       /*
> @@ -690,30 +697,32 @@ static int iwl6000_hw_channel_switch(struct iwl_priv 
> *priv,
>                       switch_count = 0;
>       }
>       if (switch_count <= 1)
> -             cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
> +             cmd->switch_time = cpu_to_le32(priv->ucode_beacon_time);
>       else {
>               switch_time_in_usec =
>                       vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
>               ucode_switch_time = iwl_usecs_to_beacons(priv,
>                                                        switch_time_in_usec,
>                                                        beacon_interval);
> -             cmd.switch_time = iwl_add_beacon_time(priv,
> -                                                   priv->ucode_beacon_time,
> -                                                   ucode_switch_time,
> -                                                   beacon_interval);
> +             cmd->switch_time = iwl_add_beacon_time(priv,
> +                                                    priv->ucode_beacon_time,
> +                                                    ucode_switch_time,
> +                                                    beacon_interval);
>       }
>       IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
> -                   cmd.switch_time);
> +                   cmd->switch_time);
>       ch_info = iwl_get_channel_info(priv, priv->band, ch);
>       if (ch_info)
> -             cmd.expect_beacon = is_channel_radar(ch_info);
> +             cmd->expect_beacon = is_channel_radar(ch_info);
>       else {
>               IWL_ERR(priv, "invalid channel switch from %u to %u\n",
>                       ctx->active.channel, ch);
>               return -EFAULT;
>       }
>  
> -     return iwl_dvm_send_cmd(priv, &hcmd);
> +     err = iwl_dvm_send_cmd(priv, &hcmd);
> +     kfree(cmd);
> +     return err;
>  }
>  
>  struct iwl_lib_ops iwl6000_lib = {

-- 
Ben Hutchings
Never attribute to conspiracy what can adequately be explained by stupidity.

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to