提交 fac7f9bf 编写于 作者: I Igor Mitsyanko 提交者: Kalle Valo

qtnfmac: make "Channel change" event report full channel info

Specifically, it has to report center frequency, secondary center
frequency (for 80+80) and BW.
Introduce channel definition structure to qlink and modify channel
change event processing function accordingly.
Signed-off-by: NIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
Signed-off-by: NKalle Valo <kvalo@codeaurora.org>
上级 77d68147
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "trans.h" #include "trans.h"
#include "util.h" #include "util.h"
#include "event.h" #include "event.h"
#include "qlink_util.h"
static int static int
qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif, qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
...@@ -359,39 +360,35 @@ qtnf_event_handle_freq_change(struct qtnf_wmac *mac, ...@@ -359,39 +360,35 @@ qtnf_event_handle_freq_change(struct qtnf_wmac *mac,
{ {
struct wiphy *wiphy = priv_to_wiphy(mac); struct wiphy *wiphy = priv_to_wiphy(mac);
struct cfg80211_chan_def chandef; struct cfg80211_chan_def chandef;
struct ieee80211_channel *chan;
struct qtnf_vif *vif; struct qtnf_vif *vif;
int freq;
int i; int i;
if (len < sizeof(*data)) { if (len < sizeof(*data)) {
pr_err("payload is too short\n"); pr_err("MAC%u: payload is too short\n", mac->macid);
return -EINVAL; return -EINVAL;
} }
freq = le32_to_cpu(data->freq); qlink_chandef_q2cfg(wiphy, &data->chan, &chandef);
chan = ieee80211_get_channel(wiphy, freq);
if (!chan) { if (!cfg80211_chandef_valid(&chandef)) {
pr_err("channel at %d MHz not found\n", freq); pr_err("MAC%u: bad channel f1=%u f2=%u bw=%u\n", mac->macid,
chandef.center_freq1, chandef.center_freq2,
chandef.width);
return -EINVAL; return -EINVAL;
} }
pr_debug("MAC%d switch to new channel %u MHz\n", mac->macid, freq); pr_debug("MAC%d: new channel ieee=%u freq1=%u freq2=%u bw=%u\n",
mac->macid, chandef.chan->hw_value, chandef.center_freq1,
chandef.center_freq2, chandef.width);
if (mac->status & QTNF_MAC_CSA_ACTIVE) { if (mac->status & QTNF_MAC_CSA_ACTIVE) {
mac->status &= ~QTNF_MAC_CSA_ACTIVE; mac->status &= ~QTNF_MAC_CSA_ACTIVE;
if (chan->hw_value != mac->csa_chandef.chan->hw_value) if (chandef.chan->hw_value != mac->csa_chandef.chan->hw_value)
pr_warn("unexpected switch to %u during CSA to %u\n", pr_warn("unexpected switch to %u during CSA to %u\n",
chan->hw_value, chandef.chan->hw_value,
mac->csa_chandef.chan->hw_value); mac->csa_chandef.chan->hw_value);
} }
/* FIXME: need to figure out proper nl80211_channel_type value */
cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
/* fall-back to minimal safe chandef description */
if (!cfg80211_chandef_valid(&chandef))
cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
memcpy(&mac->chandef, &chandef, sizeof(mac->chandef)); memcpy(&mac->chandef, &chandef, sizeof(mac->chandef));
for (i = 0; i < QTNF_MAX_INTF; i++) { for (i = 0; i < QTNF_MAX_INTF; i++) {
......
...@@ -118,6 +118,20 @@ enum qlink_channel_width { ...@@ -118,6 +118,20 @@ enum qlink_channel_width {
QLINK_CHAN_WIDTH_160, QLINK_CHAN_WIDTH_160,
}; };
/**
* struct qlink_chandef - qlink channel definition
*
* @center_freq1: center frequency of first segment
* @center_freq2: center frequency of second segment (80+80 only)
* @width: channel width, one of @enum qlink_channel_width
*/
struct qlink_chandef {
__le16 center_freq1;
__le16 center_freq2;
u8 width;
u8 rsvd[3];
} __packed;
/* QLINK Command messages related definitions /* QLINK Command messages related definitions
*/ */
...@@ -764,11 +778,11 @@ struct qlink_event_bss_leave { ...@@ -764,11 +778,11 @@ struct qlink_event_bss_leave {
/** /**
* struct qlink_event_freq_change - data for QLINK_EVENT_FREQ_CHANGE event * struct qlink_event_freq_change - data for QLINK_EVENT_FREQ_CHANGE event
* *
* @freq: new operating frequency in MHz * @chan: new operating channel definition
*/ */
struct qlink_event_freq_change { struct qlink_event_freq_change {
struct qlink_event ehdr; struct qlink_event ehdr;
__le32 freq; struct qlink_chandef chan;
} __packed; } __packed;
enum qlink_rxmgmt_flags { enum qlink_rxmgmt_flags {
......
...@@ -75,3 +75,55 @@ u8 qlink_chan_width_mask_to_nl(u16 qlink_mask) ...@@ -75,3 +75,55 @@ u8 qlink_chan_width_mask_to_nl(u16 qlink_mask)
return result; return result;
} }
static enum nl80211_chan_width qlink_chanwidth_to_nl(u8 qlw)
{
switch (qlw) {
case QLINK_CHAN_WIDTH_20_NOHT:
return NL80211_CHAN_WIDTH_20_NOHT;
case QLINK_CHAN_WIDTH_20:
return NL80211_CHAN_WIDTH_20;
case QLINK_CHAN_WIDTH_40:
return NL80211_CHAN_WIDTH_40;
case QLINK_CHAN_WIDTH_80:
return NL80211_CHAN_WIDTH_80;
case QLINK_CHAN_WIDTH_80P80:
return NL80211_CHAN_WIDTH_80P80;
case QLINK_CHAN_WIDTH_160:
return NL80211_CHAN_WIDTH_160;
case QLINK_CHAN_WIDTH_5:
return NL80211_CHAN_WIDTH_5;
case QLINK_CHAN_WIDTH_10:
return NL80211_CHAN_WIDTH_10;
default:
return -1;
}
}
void qlink_chandef_q2cfg(struct wiphy *wiphy,
const struct qlink_chandef *qch,
struct cfg80211_chan_def *chdef)
{
chdef->center_freq1 = le16_to_cpu(qch->center_freq1);
chdef->center_freq2 = le16_to_cpu(qch->center_freq2);
chdef->width = qlink_chanwidth_to_nl(qch->width);
switch (chdef->width) {
case NL80211_CHAN_WIDTH_20_NOHT:
case NL80211_CHAN_WIDTH_20:
case NL80211_CHAN_WIDTH_5:
case NL80211_CHAN_WIDTH_10:
chdef->chan = ieee80211_get_channel(wiphy, chdef->center_freq1);
break;
case NL80211_CHAN_WIDTH_40:
case NL80211_CHAN_WIDTH_80:
case NL80211_CHAN_WIDTH_80P80:
case NL80211_CHAN_WIDTH_160:
chdef->chan = ieee80211_get_channel(wiphy,
chdef->center_freq1 - 10);
break;
default:
chdef->chan = NULL;
break;
}
}
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <net/cfg80211.h>
#include "qlink.h" #include "qlink.h"
...@@ -62,5 +63,8 @@ static inline void qtnf_cmd_skb_put_tlv_u16(struct sk_buff *skb, ...@@ -62,5 +63,8 @@ static inline void qtnf_cmd_skb_put_tlv_u16(struct sk_buff *skb,
u16 qlink_iface_type_to_nl_mask(u16 qlink_type); u16 qlink_iface_type_to_nl_mask(u16 qlink_type);
u8 qlink_chan_width_mask_to_nl(u16 qlink_mask); u8 qlink_chan_width_mask_to_nl(u16 qlink_mask);
void qlink_chandef_q2cfg(struct wiphy *wiphy,
const struct qlink_chandef *qch,
struct cfg80211_chan_def *chdef);
#endif /* _QTN_FMAC_QLINK_UTIL_H_ */ #endif /* _QTN_FMAC_QLINK_UTIL_H_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册