Commit 4712d88a authored by Rafał Miłecki's avatar Rafał Miłecki Committed by Kalle Valo

brcmutil: add field storing control channel to the struct brcmu_chan

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: default avatarRafał Miłecki <zajec5@gmail.com>
Reviewed-by: default avatarArend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent d464fd8b
...@@ -2749,7 +2749,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg, ...@@ -2749,7 +2749,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
if (!bi->ctl_ch) { if (!bi->ctl_ch) {
ch.chspec = le16_to_cpu(bi->chanspec); ch.chspec = le16_to_cpu(bi->chanspec);
cfg->d11inf.decchspec(&ch); cfg->d11inf.decchspec(&ch);
bi->ctl_ch = ch.chnum; bi->ctl_ch = ch.control_ch_num;
} }
channel = bi->ctl_ch; channel = bi->ctl_ch;
...@@ -2867,7 +2867,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg, ...@@ -2867,7 +2867,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
else else
band = wiphy->bands[NL80211_BAND_5GHZ]; band = wiphy->bands[NL80211_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; cfg->channel = freq;
notify_channel = ieee80211_get_channel(wiphy, freq); notify_channel = ieee80211_get_channel(wiphy, freq);
...@@ -2877,7 +2877,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg, ...@@ -2877,7 +2877,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
notify_ielen = le32_to_cpu(bi->ie_length); notify_ielen = le32_to_cpu(bi->ie_length);
notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100; 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, "capability: %X\n", notify_capability);
brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval); brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
brcmf_dbg(CONN, "signal: %d\n", notify_signal); brcmf_dbg(CONN, "signal: %d\n", notify_signal);
...@@ -5295,7 +5295,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg, ...@@ -5295,7 +5295,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
else else
band = wiphy->bands[NL80211_BAND_5GHZ]; band = wiphy->bands[NL80211_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); notify_channel = ieee80211_get_channel(wiphy, freq);
done: done:
...@@ -5817,14 +5817,15 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, ...@@ -5817,14 +5817,15 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
channel = band->channels; channel = band->channels;
index = band->n_channels; index = band->n_channels;
for (j = 0; j < band->n_channels; j++) { 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; index = j;
break; break;
} }
} }
channel[index].center_freq = channel[index].center_freq =
ieee80211_channel_to_frequency(ch.chnum, band->band); ieee80211_channel_to_frequency(ch.control_ch_num,
channel[index].hw_value = ch.chnum; band->band);
channel[index].hw_value = ch.control_ch_num;
/* assuming the chanspecs order is HT20, /* assuming the chanspecs order is HT20,
* HT40 upper, HT40 lower, and VHT80. * HT40 upper, HT40 lower, and VHT80.
...@@ -5926,7 +5927,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg) ...@@ -5926,7 +5927,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40)) if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
continue; continue;
for (j = 0; j < band->n_channels; j++) { 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; break;
} }
if (WARN_ON(j == band->n_channels)) if (WARN_ON(j == band->n_channels))
......
...@@ -1246,7 +1246,7 @@ bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg, ...@@ -1246,7 +1246,7 @@ bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg,
if (!bi->ctl_ch) { if (!bi->ctl_ch) {
ch.chspec = le16_to_cpu(bi->chanspec); ch.chspec = le16_to_cpu(bi->chanspec);
cfg->d11inf.decchspec(&ch); cfg->d11inf.decchspec(&ch);
bi->ctl_ch = ch.chnum; bi->ctl_ch = ch.control_ch_num;
} }
afx_hdl->peer_chan = bi->ctl_ch; afx_hdl->peer_chan = bi->ctl_ch;
brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n", brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n",
...@@ -1385,7 +1385,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, ...@@ -1385,7 +1385,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL,
&p2p->status) && &p2p->status) &&
(ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) { (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", brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n",
afx_hdl->peer_chan); afx_hdl->peer_chan);
complete(&afx_hdl->act_frm_scan); complete(&afx_hdl->act_frm_scan);
...@@ -1428,7 +1428,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, ...@@ -1428,7 +1428,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
memcpy(&mgmt_frame->u, frame, mgmt_frame_len); memcpy(&mgmt_frame->u, frame, mgmt_frame_len);
mgmt_frame_len += offsetof(struct ieee80211_mgmt, u); 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 ? ch.band == BRCMU_CHAN_BAND_2G ?
NL80211_BAND_2GHZ : NL80211_BAND_2GHZ :
NL80211_BAND_5GHZ); NL80211_BAND_5GHZ);
...@@ -1873,7 +1873,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, ...@@ -1873,7 +1873,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) && if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) &&
(ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) { (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", brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n",
afx_hdl->peer_chan); afx_hdl->peer_chan);
complete(&afx_hdl->act_frm_scan); complete(&afx_hdl->act_frm_scan);
...@@ -1898,7 +1898,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, ...@@ -1898,7 +1898,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
mgmt_frame = (u8 *)(rxframe + 1); mgmt_frame = (u8 *)(rxframe + 1);
mgmt_frame_len = e->datalen - sizeof(*rxframe); 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 ? ch.band == BRCMU_CHAN_BAND_2G ?
NL80211_BAND_2GHZ : NL80211_BAND_2GHZ :
NL80211_BAND_5GHZ); NL80211_BAND_5GHZ);
......
...@@ -107,6 +107,7 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch) ...@@ -107,6 +107,7 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch)
u16 val; u16 val;
ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK); ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);
ch->control_ch_num = ch->chnum;
switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) { switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) {
case BRCMU_CHSPEC_D11N_BW_20: case BRCMU_CHSPEC_D11N_BW_20:
...@@ -118,10 +119,10 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch) ...@@ -118,10 +119,10 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch)
val = ch->chspec & BRCMU_CHSPEC_D11N_SB_MASK; val = ch->chspec & BRCMU_CHSPEC_D11N_SB_MASK;
if (val == BRCMU_CHSPEC_D11N_SB_L) { if (val == BRCMU_CHSPEC_D11N_SB_L) {
ch->sb = BRCMU_CHAN_SB_L; ch->sb = BRCMU_CHAN_SB_L;
ch->chnum -= CH_10MHZ_APART; ch->control_ch_num -= CH_10MHZ_APART;
} else { } else {
ch->sb = BRCMU_CHAN_SB_U; ch->sb = BRCMU_CHAN_SB_U;
ch->chnum += CH_10MHZ_APART; ch->control_ch_num += CH_10MHZ_APART;
} }
break; break;
default: default:
...@@ -147,6 +148,7 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch) ...@@ -147,6 +148,7 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
u16 val; u16 val;
ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK); ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK);
ch->control_ch_num = ch->chnum;
switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) { switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) {
case BRCMU_CHSPEC_D11AC_BW_20: case BRCMU_CHSPEC_D11AC_BW_20:
...@@ -158,10 +160,10 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch) ...@@ -158,10 +160,10 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
val = ch->chspec & BRCMU_CHSPEC_D11AC_SB_MASK; val = ch->chspec & BRCMU_CHSPEC_D11AC_SB_MASK;
if (val == BRCMU_CHSPEC_D11AC_SB_L) { if (val == BRCMU_CHSPEC_D11AC_SB_L) {
ch->sb = BRCMU_CHAN_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) { } else if (val == BRCMU_CHSPEC_D11AC_SB_U) {
ch->sb = BRCMU_CHAN_SB_U; ch->sb = BRCMU_CHAN_SB_U;
ch->chnum += CH_10MHZ_APART; ch->control_ch_num += CH_10MHZ_APART;
} else { } else {
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
} }
...@@ -172,16 +174,16 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch) ...@@ -172,16 +174,16 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
BRCMU_CHSPEC_D11AC_SB_SHIFT); BRCMU_CHSPEC_D11AC_SB_SHIFT);
switch (ch->sb) { switch (ch->sb) {
case BRCMU_CHAN_SB_LL: case BRCMU_CHAN_SB_LL:
ch->chnum -= CH_30MHZ_APART; ch->control_ch_num -= CH_30MHZ_APART;
break; break;
case BRCMU_CHAN_SB_LU: case BRCMU_CHAN_SB_LU:
ch->chnum -= CH_10MHZ_APART; ch->control_ch_num -= CH_10MHZ_APART;
break; break;
case BRCMU_CHAN_SB_UL: case BRCMU_CHAN_SB_UL:
ch->chnum += CH_10MHZ_APART; ch->control_ch_num += CH_10MHZ_APART;
break; break;
case BRCMU_CHAN_SB_UU: case BRCMU_CHAN_SB_UU:
ch->chnum += CH_30MHZ_APART; ch->control_ch_num += CH_30MHZ_APART;
break; break;
default: default:
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
......
...@@ -125,14 +125,36 @@ enum brcmu_chan_sb { ...@@ -125,14 +125,36 @@ enum brcmu_chan_sb {
BRCMU_CHAN_SB_UU = BRCMU_CHAN_SB_LUU, 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 { struct brcmu_chan {
u16 chspec; u16 chspec;
u8 chnum; u8 chnum;
u8 control_ch_num;
u8 band; u8 band;
enum brcmu_chan_bw bw; enum brcmu_chan_bw bw;
enum brcmu_chan_sb sb; 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 { struct brcmu_d11inf {
u8 io_type; u8 io_type;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment