cd3e924263
It's very useful for debugging problems with brcmfmac setting requested channel. Signed-off-by: Rafał Miłecki <zajec5@gmail.com> SVN-Revision: 49382
245 lines
8.6 KiB
Diff
245 lines
8.6 KiB
Diff
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
|
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 <zajec5@gmail.com>
|
|
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
|
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
|
---
|
|
|
|
--- 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;
|
|
|