[PATCH 2/2] Simplify scanning and use correct receive channel

Eugene Krasnikov k.eugene.e at gmail.com
Wed May 22 06:32:33 EDT 2013


Please send pull request.

2013/5/22 Olof Johansson <dev at skyshaper.net>:
> updated patch
> ----
>
> This simplifies the scanning a bit by removing the end_scan which is
> not necessary. It also makes use of the channel switch command instead
> of using start scan on every channel.
>
> Reorders the 2.4Ghz channels to that the hw_values are correct
> and possible to use.
>
> Signed-off-by: Olof Johansson <dev at skyshaper.net>
> ---
>  main.c    | 53 ++++++++++++++++++++++-------------------------------
>  smd.c     | 27 +++++++++++++++++++++++++++
>  smd.h     |  1 +
>  txrx.c    |  4 ++--
>  wcn36xx.h |  2 +-
>  5 files changed, 53 insertions(+), 34 deletions(-)
>
> diff --git a/main.c b/main.c
> index 6eacee6..e96309d 100644
> --- a/main.c
> +++ b/main.c
> @@ -109,16 +109,10 @@ static int wcn36xx_config(struct ieee80211_hw
> *hw, u32 changed)
>         wcn36xx_dbg(WCN36XX_DBG_MAC, "mac config changed 0x%08x", changed);
>
>         if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
> -               wcn->ch = ieee80211_frequency_to_channel(hw->conf.chandef.chan->center_freq);
> -               wcn36xx_dbg(WCN36XX_DBG_MAC, "mac change channel %d", wcn->ch);
> -
> -               if (wcn->is_scanning) {
> -                       if (wcn->prev_channel) {
> -                               wcn36xx_smd_end_scan(wcn, wcn->prev_channel);
> -                       }
> -                       wcn36xx_smd_start_scan(wcn, wcn->ch);
> -                       wcn->prev_channel = wcn->ch;
> -               }
> +               wcn->ch = hw->conf.chandef.chan->hw_value;
> +               wcn->current_channel = hw->conf.chandef.chan;
> +               wcn36xx_info("wcn36xx_config channel switch=%d", wcn->ch);
> +               wcn36xx_smd_switch_channel_req(wcn, wcn->ch);
>         }
>
>         return 0;
> @@ -171,19 +165,14 @@ static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw)
>         struct wcn36xx *wcn = hw->priv;
>
>         wcn36xx_smd_init_scan(wcn);
> -       wcn->is_scanning = 1;
>         wcn36xx_smd_start_scan(wcn, wcn->ch);
> -       wcn->prev_channel = wcn->ch;
> +       wcn->is_scanning = 1;
>  }
>
>  static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw)
>  {
>         struct wcn36xx *wcn = hw->priv;
> -
> -       if (wcn->prev_channel) {
> -               wcn36xx_smd_end_scan(wcn, wcn->prev_channel);
> -               wcn->prev_channel = 0;
> -       }
> +       wcn36xx_smd_end_scan(wcn, wcn->ch);
>         wcn36xx_smd_finish_scan(wcn);
>         wcn->is_scanning = 0;
>  }
> @@ -348,21 +337,23 @@ static struct ieee80211_hw *wcn36xx_alloc_hw(void)
>         .max_power = 25, \
>  }
>
> +/* The wcn firmware expects channel values to matching
> + * their mnemonic values. So use these for .hw_value. */
>  static struct ieee80211_channel wcn_2ghz_channels[] = {
> -       CHAN2G(2412, 0), /* Channel 1 */
> -       CHAN2G(2417, 1), /* Channel 2 */
> -       CHAN2G(2422, 2), /* Channel 3 */
> -       CHAN2G(2427, 3), /* Channel 4 */
> -       CHAN2G(2432, 4), /* Channel 5 */
> -       CHAN2G(2437, 5), /* Channel 6 */
> -       CHAN2G(2442, 6), /* Channel 7 */
> -       CHAN2G(2447, 7), /* Channel 8 */
> -       CHAN2G(2452, 8), /* Channel 9 */
> -       CHAN2G(2457, 9), /* Channel 10 */
> -       CHAN2G(2462, 10), /* Channel 11 */
> -       CHAN2G(2467, 11), /* Channel 12 */
> -       CHAN2G(2472, 12), /* Channel 13 */
> -       CHAN2G(2484, 13)  /* Channel 14 */
> +       CHAN2G(2412, 1), /* Channel 1 */
> +       CHAN2G(2417, 2), /* Channel 2 */
> +       CHAN2G(2422, 3), /* Channel 3 */
> +       CHAN2G(2427, 4), /* Channel 4 */
> +       CHAN2G(2432, 5), /* Channel 5 */
> +       CHAN2G(2437, 6), /* Channel 6 */
> +       CHAN2G(2442, 7), /* Channel 7 */
> +       CHAN2G(2447, 8), /* Channel 8 */
> +       CHAN2G(2452, 9), /* Channel 9 */
> +       CHAN2G(2457, 10), /* Channel 10 */
> +       CHAN2G(2462, 11), /* Channel 11 */
> +       CHAN2G(2467, 12), /* Channel 12 */
> +       CHAN2G(2472, 13), /* Channel 13 */
> +       CHAN2G(2484, 14)  /* Channel 14 */
>
>  };
>
> diff --git a/smd.c b/smd.c
> index 19ff583..28d8ec8 100644
> --- a/smd.c
> +++ b/smd.c
> @@ -233,6 +233,30 @@ int wcn36xx_smd_finish_scan(struct wcn36xx *wcn)
>
>         return wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
>  }
> +
> +int wcn36xx_smd_switch_channel_req(struct wcn36xx *wcn, int ch)
> +{
> +       struct wcn36xx_hal_switch_channel_req_msg msg_body;
> +
> +       INIT_HAL_MSG(msg_body, WCN36XX_HAL_CH_SWITCH_REQ);
> +
> +       msg_body.channel_number = (u8)ch;
> +       msg_body.tx_mgmt_power = 0xbf;
> +       msg_body.max_tx_power = 0xbf;
> +       memcpy(msg_body.self_sta_mac_addr, wcn->addresses[0].addr, ETH_ALEN);
> +
> +       PREPARE_HAL_BUF(wcn->smd_buf, msg_body);
> +
> +       return wcn36xx_smd_send_and_wait(wcn, msg_body.header.len);
> +}
> +
> +void wcn36xx_smd_switch_channel_rsp(void *buf, size_t len)
> +{
> +       struct wcn36xx_hal_switch_channel_rsp_msg *rsp;
> +       rsp = (struct wcn36xx_hal_switch_channel_rsp_msg*)buf;
> +       wcn36xx_info("channel switched to: %d, status: %d",
> rsp->channel_number, rsp->status);
> +}
> +
>  int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn){
>         struct wcn36xx_hal_update_scan_params_req msg_body;
>
> @@ -564,6 +588,9 @@ static void wcn36xx_smd_rsp_process(struct wcn36xx
> *wcn, void *buf, size_t len)
>         case WCN36XX_HAL_UPDATE_SCAN_PARAM_RSP:
>                 wcn36xx_smd_update_scan_params_rsp(buf, len);
>                 break;
> +       case WCN36XX_HAL_CH_SWITCH_RSP:
> +               wcn36xx_smd_switch_channel_rsp(buf,len);
> +               break;
>         default:
>                 wcn36xx_error("SMD_EVENT (%d) not supported", msg_header->msg_type);
>         }
> diff --git a/smd.h b/smd.h
> index ad5af54..3b7d6db 100644
> --- a/smd.h
> +++ b/smd.h
> @@ -62,6 +62,7 @@ int wcn36xx_smd_config_bss(struct wcn36xx *wcn, bool
> sta_mode, u8 *bssid, u8 upd
>  int wcn36xx_smd_delete_bss(struct wcn36xx *wcn);
>  int wcn36xx_smd_config_sta(struct wcn36xx *wcn, u8 *bssid, u16
> ass_id, u8 *sta_mac);
>  int wcn36xx_smd_send_beacon(struct wcn36xx *wcn, struct sk_buff
> *skb_beacon, u16 tim_off, u16 p2p_off);
> +int wcn36xx_smd_switch_channel_req(struct wcn36xx *wcn, int ch);
>
>  // WCN36XX configuration parameters
>  struct wcn36xx_fw_cfg {
> diff --git a/txrx.c b/txrx.c
> index f199f4b..873cc6a 100644
> --- a/txrx.c
> +++ b/txrx.c
> @@ -31,8 +31,8 @@ int  wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
>
>         skb_trim(skb2, bd->pdu.mpdu_len);
>         status.mactime = 10;
> -       status.band = IEEE80211_BAND_2GHZ;
> -       status.freq = ieee80211_channel_to_frequency(bd->rx_ch, status.band);
> +       status.freq = wcn->current_channel->center_freq;
> +       status.band = wcn->current_channel->band;
>         status.signal = 1;
>         status.antenna = 1;
>         status.rate_idx = 1;
> diff --git a/wcn36xx.h b/wcn36xx.h
> index 2860c10..bebe47b 100644
> --- a/wcn36xx.h
> +++ b/wcn36xx.h
> @@ -97,6 +97,7 @@ struct wcn36xx {
>         const struct firmware   *nv;
>         struct mac_address addresses[2];
>         int ch;
> +       struct ieee80211_channel *current_channel;
>
>         u8 fw_revision;
>         u8 fw_version;
> @@ -126,7 +127,6 @@ struct wcn36xx {
>
>         //Scanning
>         int                     is_scanning;
> -       int                     prev_channel;
>
>         // DXE chanels
>         struct wcn36xx_dxe_ch   dxe_tx_l_ch;    // TX low channel
> --
> 1.8.2.2
>
> _______________________________________________
> wcn36xx mailing list
> wcn36xx at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/wcn36xx



-- 
Best regards,
Eugene



More information about the wcn36xx mailing list