X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fsvn-archive%2Farchive.git;a=blobdiff_plain;f=package%2Fkernel%2Fmac80211%2Fpatches%2F351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch;fp=package%2Fkernel%2Fmac80211%2Fpatches%2F351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch;h=8b284f0b2f4dd55673fb1f1e9caaebe89bea6dd0;hp=0000000000000000000000000000000000000000;hb=d31cb5c5bf875619701d91918e947367e6444380;hpb=ffaea53fbfcd9f88d720e8071d326d8aa0c726a7 diff --git a/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch b/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch new file mode 100644 index 0000000000..8b284f0b2f --- /dev/null +++ b/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch @@ -0,0 +1,244 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 20 May 2016 13:38:57 +0200 +Subject: [PATCH] brcmutil: add field storing control channel to the struct + brcmu_chan +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Our d11 code supports encoding/decoding channel info into/from chanspec +format used by firmware. Current implementation is quite misleading +because of the way "chnum" field is used. +When encoding channel info, "chnum" has to be filled by a caller with +*center* channel number. However when decoding chanspec the same field +is filled with a *control* channel number. + +1) This can be confusing. It's expected for information to be the same + after encoding and decoding. +2) It doesn't allow accessing all info when decoding. Some functions may + need to know both channel numbers, e.g. cfg80211 callback getting + current channel. +Solve this by adding a separated field for control channel. + +Signed-off-by: Rafał Miłecki +Reviewed-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2705,7 +2705,7 @@ static s32 brcmf_inform_single_bss(struc + if (!bi->ctl_ch) { + ch.chspec = le16_to_cpu(bi->chanspec); + cfg->d11inf.decchspec(&ch); +- bi->ctl_ch = ch.chnum; ++ bi->ctl_ch = ch.control_ch_num; + } + channel = bi->ctl_ch; + +@@ -2823,7 +2823,7 @@ static s32 brcmf_inform_ibss(struct brcm + else + band = wiphy->bands[IEEE80211_BAND_5GHZ]; + +- freq = ieee80211_channel_to_frequency(ch.chnum, band->band); ++ freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band); + cfg->channel = freq; + notify_channel = ieee80211_get_channel(wiphy, freq); + +@@ -2833,7 +2833,7 @@ static s32 brcmf_inform_ibss(struct brcm + notify_ielen = le32_to_cpu(bi->ie_length); + notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100; + +- brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq); ++ brcmf_dbg(CONN, "channel: %d(%d)\n", ch.control_ch_num, freq); + brcmf_dbg(CONN, "capability: %X\n", notify_capability); + brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval); + brcmf_dbg(CONN, "signal: %d\n", notify_signal); +@@ -5251,7 +5251,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg8 + else + band = wiphy->bands[IEEE80211_BAND_5GHZ]; + +- freq = ieee80211_channel_to_frequency(ch.chnum, band->band); ++ freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band); + notify_channel = ieee80211_get_channel(wiphy, freq); + + done: +@@ -5773,14 +5773,15 @@ static int brcmf_construct_chaninfo(stru + channel = band->channels; + index = band->n_channels; + for (j = 0; j < band->n_channels; j++) { +- if (channel[j].hw_value == ch.chnum) { ++ if (channel[j].hw_value == ch.control_ch_num) { + index = j; + break; + } + } + channel[index].center_freq = +- ieee80211_channel_to_frequency(ch.chnum, band->band); +- channel[index].hw_value = ch.chnum; ++ ieee80211_channel_to_frequency(ch.control_ch_num, ++ band->band); ++ channel[index].hw_value = ch.control_ch_num; + + /* assuming the chanspecs order is HT20, + * HT40 upper, HT40 lower, and VHT80. +@@ -5882,7 +5883,7 @@ static int brcmf_enable_bw40_2g(struct b + if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40)) + continue; + for (j = 0; j < band->n_channels; j++) { +- if (band->channels[j].hw_value == ch.chnum) ++ if (band->channels[j].hw_value == ch.control_ch_num) + break; + } + if (WARN_ON(j == band->n_channels)) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -1246,7 +1246,7 @@ bool brcmf_p2p_scan_finding_common_chann + if (!bi->ctl_ch) { + ch.chspec = le16_to_cpu(bi->chanspec); + cfg->d11inf.decchspec(&ch); +- bi->ctl_ch = ch.chnum; ++ bi->ctl_ch = ch.control_ch_num; + } + afx_hdl->peer_chan = bi->ctl_ch; + brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n", +@@ -1385,7 +1385,7 @@ int brcmf_p2p_notify_action_frame_rx(str + if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, + &p2p->status) && + (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) { +- afx_hdl->peer_chan = ch.chnum; ++ afx_hdl->peer_chan = ch.control_ch_num; + brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n", + afx_hdl->peer_chan); + complete(&afx_hdl->act_frm_scan); +@@ -1428,7 +1428,7 @@ int brcmf_p2p_notify_action_frame_rx(str + memcpy(&mgmt_frame->u, frame, mgmt_frame_len); + mgmt_frame_len += offsetof(struct ieee80211_mgmt, u); + +- freq = ieee80211_channel_to_frequency(ch.chnum, ++ freq = ieee80211_channel_to_frequency(ch.control_ch_num, + ch.band == BRCMU_CHAN_BAND_2G ? + IEEE80211_BAND_2GHZ : + IEEE80211_BAND_5GHZ); +@@ -1873,7 +1873,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere + + if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) && + (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) { +- afx_hdl->peer_chan = ch.chnum; ++ afx_hdl->peer_chan = ch.control_ch_num; + brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n", + afx_hdl->peer_chan); + complete(&afx_hdl->act_frm_scan); +@@ -1898,7 +1898,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere + + mgmt_frame = (u8 *)(rxframe + 1); + mgmt_frame_len = e->datalen - sizeof(*rxframe); +- freq = ieee80211_channel_to_frequency(ch.chnum, ++ freq = ieee80211_channel_to_frequency(ch.control_ch_num, + ch.band == BRCMU_CHAN_BAND_2G ? + IEEE80211_BAND_2GHZ : + IEEE80211_BAND_5GHZ); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c +@@ -107,6 +107,7 @@ static void brcmu_d11n_decchspec(struct + u16 val; + + ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK); ++ ch->control_ch_num = ch->chnum; + + switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) { + case BRCMU_CHSPEC_D11N_BW_20: +@@ -118,10 +119,10 @@ static void brcmu_d11n_decchspec(struct + val = ch->chspec & BRCMU_CHSPEC_D11N_SB_MASK; + if (val == BRCMU_CHSPEC_D11N_SB_L) { + ch->sb = BRCMU_CHAN_SB_L; +- ch->chnum -= CH_10MHZ_APART; ++ ch->control_ch_num -= CH_10MHZ_APART; + } else { + ch->sb = BRCMU_CHAN_SB_U; +- ch->chnum += CH_10MHZ_APART; ++ ch->control_ch_num += CH_10MHZ_APART; + } + break; + default: +@@ -147,6 +148,7 @@ static void brcmu_d11ac_decchspec(struct + u16 val; + + ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK); ++ ch->control_ch_num = ch->chnum; + + switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) { + case BRCMU_CHSPEC_D11AC_BW_20: +@@ -158,10 +160,10 @@ static void brcmu_d11ac_decchspec(struct + val = ch->chspec & BRCMU_CHSPEC_D11AC_SB_MASK; + if (val == BRCMU_CHSPEC_D11AC_SB_L) { + ch->sb = BRCMU_CHAN_SB_L; +- ch->chnum -= CH_10MHZ_APART; ++ ch->control_ch_num -= CH_10MHZ_APART; + } else if (val == BRCMU_CHSPEC_D11AC_SB_U) { + ch->sb = BRCMU_CHAN_SB_U; +- ch->chnum += CH_10MHZ_APART; ++ ch->control_ch_num += CH_10MHZ_APART; + } else { + WARN_ON_ONCE(1); + } +@@ -172,16 +174,16 @@ static void brcmu_d11ac_decchspec(struct + BRCMU_CHSPEC_D11AC_SB_SHIFT); + switch (ch->sb) { + case BRCMU_CHAN_SB_LL: +- ch->chnum -= CH_30MHZ_APART; ++ ch->control_ch_num -= CH_30MHZ_APART; + break; + case BRCMU_CHAN_SB_LU: +- ch->chnum -= CH_10MHZ_APART; ++ ch->control_ch_num -= CH_10MHZ_APART; + break; + case BRCMU_CHAN_SB_UL: +- ch->chnum += CH_10MHZ_APART; ++ ch->control_ch_num += CH_10MHZ_APART; + break; + case BRCMU_CHAN_SB_UU: +- ch->chnum += CH_30MHZ_APART; ++ ch->control_ch_num += CH_30MHZ_APART; + break; + default: + WARN_ON_ONCE(1); +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h +@@ -125,14 +125,36 @@ enum brcmu_chan_sb { + BRCMU_CHAN_SB_UU = BRCMU_CHAN_SB_LUU, + }; + ++/** ++ * struct brcmu_chan - stores channel formats ++ * ++ * This structure can be used with functions translating chanspec into generic ++ * channel info and the other way. ++ * ++ * @chspec: firmware specific format ++ * @chnum: center channel number ++ * @control_ch_num: control channel number ++ * @band: frequency band ++ * @bw: channel width ++ * @sb: control sideband (location of control channel against the center one) ++ */ + struct brcmu_chan { + u16 chspec; + u8 chnum; ++ u8 control_ch_num; + u8 band; + enum brcmu_chan_bw bw; + enum brcmu_chan_sb sb; + }; + ++/** ++ * struct brcmu_d11inf - provides functions translating channel format ++ * ++ * @io_type: determines version of channel format used by firmware ++ * @encchspec: encodes channel info into a chanspec, requires center channel ++ * number, ignores control one ++ * @decchspec: decodes chanspec into generic info ++ */ + struct brcmu_d11inf { + u8 io_type; +