}
if (!cfg80211_chandef_valid(chandef)) {
- pr_err("%s: bad chan freq1=%u freq2=%u bw=%u\n", ndev->name,
+ pr_err("%s: bad channel freq=%u cf1=%u cf2=%u bw=%u\n",
+ ndev->name, chandef->chan->center_freq,
chandef->center_freq1, chandef->center_freq2,
chandef->width);
ret = -ENODATA;
chtlv->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANDEF);
chtlv->hdr.len = cpu_to_le16(sizeof(*chtlv) -
sizeof(chtlv->hdr));
- qlink_chandef_cfg2q(&s->chandef, &chtlv->chan);
+ qlink_chandef_cfg2q(&s->chandef, &chtlv->chdef);
}
qtnf_cmd_tlv_ie_set_add(cmd_skb, QLINK_IE_SET_BEACON_HEAD,
size_t tlv_len;
size_t tlv_dlen;
const struct qlink_tlv_hdr *tlv;
- const struct qlink_tlv_channel *qchan;
+ const struct qlink_channel *qchan;
struct ieee80211_channel *chan;
unsigned int chidx = 0;
u32 qflags;
switch (tlv_type) {
case QTN_TLV_ID_CHANNEL:
- if (unlikely(tlv_len != sizeof(*qchan))) {
+ if (unlikely(tlv_dlen != sizeof(*qchan))) {
pr_err("invalid channel TLV len %zu\n",
tlv_len);
goto error_ret;
goto error_ret;
}
- qchan = (const struct qlink_tlv_channel *)tlv;
+ qchan = (const struct qlink_channel *)tlv->val;
chan = &band->channels[chidx++];
qflags = le32_to_cpu(qchan->flags);
qchan = skb_put_zero(cmd_skb, sizeof(*qchan));
qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL);
qchan->hdr.len = cpu_to_le16(sizeof(*qchan) - sizeof(qchan->hdr));
- qchan->center_freq = cpu_to_le16(sc->center_freq);
- qchan->hw_value = cpu_to_le16(sc->hw_value);
+ qchan->chan.center_freq = cpu_to_le16(sc->center_freq);
+ qchan->chan.hw_value = cpu_to_le16(sc->hw_value);
if (sc->flags & IEEE80211_CHAN_NO_IR)
flags |= QLINK_CHAN_NO_IR;
if (sc->flags & IEEE80211_CHAN_RADAR)
flags |= QLINK_CHAN_RADAR;
- qchan->flags = cpu_to_le32(flags);
+ qchan->chan.flags = cpu_to_le32(flags);
}
int qtnf_cmd_send_scan(struct qtnf_wmac *mac)
qlink_chandef_q2cfg(wiphy, &data->chan, &chandef);
if (!cfg80211_chandef_valid(&chandef)) {
- pr_err("MAC%u: bad channel f1=%u f2=%u bw=%u\n", mac->macid,
+ pr_err("MAC%u: bad channel freq=%u cf1=%u cf2=%u bw=%u\n",
+ mac->macid, chandef.chan->center_freq,
chandef.center_freq1, chandef.center_freq2,
chandef.width);
return -EINVAL;
#include <linux/ieee80211.h>
-#define QLINK_PROTO_VER 6
+#define QLINK_PROTO_VER 7
#define QLINK_MACID_RSVD 0xFF
#define QLINK_VIFID_RSVD 0xFF
QLINK_CHAN_WIDTH_160,
};
+/**
+ * struct qlink_channel - qlink control channel definition
+ *
+ * @hw_value: hardware-specific value for the channel
+ * @center_freq: center frequency in MHz
+ * @flags: channel flags from &enum qlink_channel_flags
+ * @band: band this channel belongs to
+ * @max_antenna_gain: maximum antenna gain in dBi
+ * @max_power: maximum transmission power (in dBm)
+ * @max_reg_power: maximum regulatory transmission power (in dBm)
+ * @dfs_state: current state of this channel.
+ * Only relevant if radar is required on this channel.
+ * @beacon_found: helper to regulatory code to indicate when a beacon
+ * has been found on this channel. Use regulatory_hint_found_beacon()
+ * to enable this, this is useful only on 5 GHz band.
+ */
+struct qlink_channel {
+ __le16 hw_value;
+ __le16 center_freq;
+ __le32 flags;
+ u8 band;
+ u8 max_antenna_gain;
+ u8 max_power;
+ u8 max_reg_power;
+ __le32 dfs_cac_ms;
+ u8 dfs_state;
+ u8 beacon_found;
+ u8 rsvd[2];
+} __packed;
+
/**
* struct qlink_chandef - qlink channel definition
*
+ * @chan: primary 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 {
+ struct qlink_channel chan;
__le16 center_freq1;
__le16 center_freq2;
u8 width;
- u8 rsvd[3];
+ u8 rsvd;
} __packed;
#define QLINK_MAX_NR_CIPHER_SUITES 5
QLINK_DFS_AVAILABLE,
};
+/**
+ * struct qlink_tlv_channel - data for QTN_TLV_ID_CHANNEL TLV
+ *
+ * Channel settings.
+ *
+ * @channel: ieee80211 channel settings.
+ */
struct qlink_tlv_channel {
struct qlink_tlv_hdr hdr;
- __le16 hw_value;
- __le16 center_freq;
- __le32 flags;
- u8 band;
- u8 max_antenna_gain;
- u8 max_power;
- u8 max_reg_power;
- __le32 dfs_cac_ms;
- u8 dfs_state;
- u8 beacon_found;
- u8 rsvd[2];
+ struct qlink_channel chan;
} __packed;
/**
*/
struct qlink_tlv_chandef {
struct qlink_tlv_hdr hdr;
- struct qlink_chandef chan;
+ struct qlink_chandef chdef;
} __packed;
enum qlink_ie_set_type {
}
}
-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;
- }
-}
-
static u8 qlink_chanwidth_nl_to_qlink(enum nl80211_chan_width nlwidth)
{
switch (nlwidth) {
}
}
+void qlink_chandef_q2cfg(struct wiphy *wiphy,
+ const struct qlink_chandef *qch,
+ struct cfg80211_chan_def *chdef)
+{
+ struct ieee80211_channel *chan;
+
+ chan = ieee80211_get_channel(wiphy, le16_to_cpu(qch->chan.center_freq));
+
+ chdef->chan = chan;
+ 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);
+}
+
void qlink_chandef_cfg2q(const struct cfg80211_chan_def *chdef,
struct qlink_chandef *qch)
{
+ struct ieee80211_channel *chan = chdef->chan;
+
+ qch->chan.hw_value = cpu_to_le16(chan->hw_value);
+ qch->chan.center_freq = cpu_to_le16(chan->center_freq);
+ qch->chan.flags = cpu_to_le32(chan->flags);
+
qch->center_freq1 = cpu_to_le16(chdef->center_freq1);
qch->center_freq2 = cpu_to_le16(chdef->center_freq2);
qch->width = qlink_chanwidth_nl_to_qlink(chdef->width);