2019-05-13 16:15:17

by Alexei Avshalom Lazar

[permalink] [raw]
Subject: [PATCH v2 0/2] Add support for new channels on 60GHz band

The following set of patches add support for new channels on
60GHz band and EDMG channels:
-Nl80211 support for EDMG channels
-Wil6210 support for EDMG channels

Alexei Avshalom Lazar (2):
nl80211: Add support for EDMG channels
wil6210: Add EDMG channel support

drivers/net/wireless/ath/wil6210/cfg80211.c | 205 +++++++++++++++++++++++++--
drivers/net/wireless/ath/wil6210/txrx_edma.c | 2 +
drivers/net/wireless/ath/wil6210/txrx_edma.h | 6 +
drivers/net/wireless/ath/wil6210/wil6210.h | 8 +-
drivers/net/wireless/ath/wil6210/wmi.c | 5 +-
drivers/net/wireless/ath/wil6210/wmi.h | 30 +++-
include/net/cfg80211.h | 39 ++++-
include/uapi/linux/nl80211.h | 19 +++
net/wireless/chan.c | 152 +++++++++++++++++++-
net/wireless/nl80211.c | 33 +++++
net/wireless/util.c | 42 +++++-
11 files changed, 521 insertions(+), 20 deletions(-)

--
1.9.1


2019-05-13 16:15:18

by Alexei Avshalom Lazar

[permalink] [raw]
Subject: [PATCH v2 2/2] wil6210: Add EDMG channel support

Add support for Enhanced Directional Multi-Gigabit (EDMG) channels 9-11.
wil6210 reports it's EDMG capabilities (that are also based on FW
capability) to cfg80211 by filling
wiphy->bands[NL80211_BAND_60GHZ]->edmg_cap.
wil6210 handles edmg_channels and edmg_bw_config requested in connect
and start_ap operations.

Change-Id: I96a2776fe27ed2d8e922e23063e879361cfcb552
---
drivers/net/wireless/ath/wil6210/cfg80211.c | 205 +++++++++++++++++++++++++--
drivers/net/wireless/ath/wil6210/txrx_edma.c | 2 +
drivers/net/wireless/ath/wil6210/txrx_edma.h | 6 +
drivers/net/wireless/ath/wil6210/wil6210.h | 8 +-
drivers/net/wireless/ath/wil6210/wmi.c | 5 +-
drivers/net/wireless/ath/wil6210/wmi.h | 30 +++-
6 files changed, 242 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index ce68fbc..161d271 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -25,6 +25,22 @@

#define WIL_MAX_ROC_DURATION_MS 5000

+#define WIL_EDMG_CHANNEL_9_SUBCHANNELS (BIT(0) | BIT(1))
+#define WIL_EDMG_CHANNEL_10_SUBCHANNELS (BIT(1) | BIT(2))
+#define WIL_EDMG_CHANNEL_11_SUBCHANNELS (BIT(2) | BIT(3))
+
+/* WIL_EDMG_BW_CONFIGURATION define the allowed channel bandwidth
+ * configurations as defined by IEEE 802.11 section 9.4.2.251, Table 13.
+ * The value 5 allowing CB1 and CB2 of adjacent channels.
+ */
+#define WIL_EDMG_BW_CONFIGURATION 5
+
+/* WIL_EDMG_CHANNELS is a bitmap that indicates the 2.16 GHz channel(s) that
+ * are allowed to be used for EDMG transmissions in the BSS as defined by
+ * IEEE 802.11 section 9.4.2.251.
+ */
+#define WIL_EDMG_CHANNELS (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+
bool disable_ap_sme;
module_param(disable_ap_sme, bool, 0444);
MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME");
@@ -51,6 +67,39 @@
CHAN60G(4, 0),
};

+/* Rx channel bonding mode */
+enum wil_rx_cb_mode {
+ WIL_RX_CB_MODE_DMG,
+ WIL_RX_CB_MODE_EDMG,
+ WIL_RX_CB_MODE_WIDE,
+};
+
+static int wil_rx_cb_mode_to_n_bonded(u8 cb_mode)
+{
+ switch (cb_mode) {
+ case WIL_RX_CB_MODE_DMG:
+ case WIL_RX_CB_MODE_EDMG:
+ return 1;
+ case WIL_RX_CB_MODE_WIDE:
+ return 2;
+ default:
+ return 1;
+ }
+}
+
+static int wil_tx_cb_mode_to_n_bonded(u8 cb_mode)
+{
+ switch (cb_mode) {
+ case WMI_TX_MODE_DMG:
+ case WMI_TX_MODE_EDMG_CB1:
+ return 1;
+ case WMI_TX_MODE_EDMG_CB2:
+ return 2;
+ default:
+ return 1;
+ }
+}
+
static void
wil_memdup_ie(u8 **pdst, size_t *pdst_len, const u8 *src, size_t src_len)
{
@@ -82,6 +131,12 @@ void update_supported_bands(struct wil6210_priv *wil)

wiphy->bands[NL80211_BAND_60GHZ]->n_channels =
wil_num_supported_channels(wil);
+
+ if (test_bit(WMI_FW_CAPABILITY_CHANNEL_BONDING, wil->fw_capabilities))
+ wiphy->bands[NL80211_BAND_60GHZ]->edmg_cap.channels =
+ WIL_EDMG_CHANNELS;
+ wiphy->bands[NL80211_BAND_60GHZ]->edmg_cap.bw_config =
+ WIL_EDMG_BW_CONFIGURATION;
}

/* Vendor id to be used in vendor specific command and events
@@ -296,6 +351,86 @@ int wil_iftype_nl2wmi(enum nl80211_iftype type)
return -EOPNOTSUPP;
}

+int wil_spec2wmi_ch(u8 spec_ch, u8 *wmi_ch)
+{
+ switch (spec_ch) {
+ case 1:
+ *wmi_ch = WMI_CHANNEL_1;
+ break;
+ case 2:
+ *wmi_ch = WMI_CHANNEL_2;
+ break;
+ case 3:
+ *wmi_ch = WMI_CHANNEL_3;
+ break;
+ case 4:
+ *wmi_ch = WMI_CHANNEL_4;
+ break;
+ case 5:
+ *wmi_ch = WMI_CHANNEL_5;
+ break;
+ case 6:
+ *wmi_ch = WMI_CHANNEL_6;
+ break;
+ case 9:
+ *wmi_ch = WMI_CHANNEL_9;
+ break;
+ case 10:
+ *wmi_ch = WMI_CHANNEL_10;
+ break;
+ case 11:
+ *wmi_ch = WMI_CHANNEL_11;
+ break;
+ case 12:
+ *wmi_ch = WMI_CHANNEL_12;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int wil_wmi2spec_ch(u8 wmi_ch, u8 *spec_ch)
+{
+ switch (wmi_ch) {
+ case WMI_CHANNEL_1:
+ *spec_ch = 1;
+ break;
+ case WMI_CHANNEL_2:
+ *spec_ch = 2;
+ break;
+ case WMI_CHANNEL_3:
+ *spec_ch = 3;
+ break;
+ case WMI_CHANNEL_4:
+ *spec_ch = 4;
+ break;
+ case WMI_CHANNEL_5:
+ *spec_ch = 5;
+ break;
+ case WMI_CHANNEL_6:
+ *spec_ch = 6;
+ break;
+ case WMI_CHANNEL_9:
+ *spec_ch = 9;
+ break;
+ case WMI_CHANNEL_10:
+ *spec_ch = 10;
+ break;
+ case WMI_CHANNEL_11:
+ *spec_ch = 11;
+ break;
+ case WMI_CHANNEL_12:
+ *spec_ch = 12;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
struct station_info *sinfo)
{
@@ -310,6 +445,7 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
} __packed reply;
struct wil_net_stats *stats = &wil->sta[cid].stats;
int rc;
+ u8 txflag = RATE_INFO_FLAGS_DMG;

memset(&reply, 0, sizeof(reply));

@@ -322,7 +458,8 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
" MCS %d TSF 0x%016llx\n"
" BF status 0x%08x RSSI %d SQI %d%%\n"
" Tx Tpt %d goodput %d Rx goodput %d\n"
- " Sectors(rx:tx) my %d:%d peer %d:%d\n""}\n",
+ " Sectors(rx:tx) my %d:%d peer %d:%d\n"
+ " Tx mode %d}\n",
cid, vif->mid, le16_to_cpu(reply.evt.bf_mcs),
le64_to_cpu(reply.evt.tsf), reply.evt.status,
reply.evt.rssi,
@@ -333,7 +470,8 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
le16_to_cpu(reply.evt.my_rx_sector),
le16_to_cpu(reply.evt.my_tx_sector),
le16_to_cpu(reply.evt.other_rx_sector),
- le16_to_cpu(reply.evt.other_tx_sector));
+ le16_to_cpu(reply.evt.other_tx_sector),
+ reply.evt.tx_mode);

sinfo->generation = wil->sinfo_gen;

@@ -346,9 +484,16 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC) |
BIT_ULL(NL80211_STA_INFO_TX_FAILED);

- sinfo->txrate.flags = RATE_INFO_FLAGS_DMG;
+ if (wil->use_enhanced_dma_hw && reply.evt.tx_mode != WMI_TX_MODE_DMG)
+ txflag = RATE_INFO_FLAGS_EDMG;
+
+ sinfo->txrate.flags = txflag;
sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
sinfo->rxrate.mcs = stats->last_mcs_rx;
+ sinfo->txrate.n_bonded_ch =
+ wil_tx_cb_mode_to_n_bonded(reply.evt.tx_mode);
+ sinfo->rxrate.n_bonded_ch =
+ wil_rx_cb_mode_to_n_bonded(stats->last_cb_mode_rx);
sinfo->rx_bytes = stats->rx_bytes;
sinfo->rx_packets = stats->rx_packets;
sinfo->rx_dropped_misc = stats->rx_dropped;
@@ -1006,6 +1151,33 @@ static int wil_ft_connect(struct wiphy *wiphy,
return rc;
}

+static int wil_get_wmi_edmg_channel(struct wil6210_priv *wil, u8 edmg_bw_config,
+ u8 edmg_channels, u8 *wmi_ch)
+{
+ if (!edmg_bw_config) {
+ *wmi_ch = 0;
+ return 0;
+ } else if (edmg_bw_config == WIL_EDMG_BW_CONFIGURATION) {
+ /* convert from edmg channel bitmap into edmg channel number */
+ switch (edmg_channels) {
+ case WIL_EDMG_CHANNEL_9_SUBCHANNELS:
+ return wil_spec2wmi_ch(9, wmi_ch);
+ case WIL_EDMG_CHANNEL_10_SUBCHANNELS:
+ return wil_spec2wmi_ch(10, wmi_ch);
+ case WIL_EDMG_CHANNEL_11_SUBCHANNELS:
+ return wil_spec2wmi_ch(11, wmi_ch);
+ default:
+ wil_err(wil, "Unsupported edmg channel bitmap 0x%x\n",
+ edmg_channels);
+ return -EINVAL;
+ }
+ } else {
+ wil_err(wil, "Unsupported EDMG BW configuration %d\n",
+ edmg_bw_config);
+ return -EINVAL;
+ }
+}
+
static int wil_cfg80211_connect(struct wiphy *wiphy,
struct net_device *ndev,
struct cfg80211_connect_params *sme)
@@ -1151,6 +1323,11 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
memcpy(conn.ssid, ssid_eid+2, conn.ssid_len);
conn.channel = ch - 1;

+ rc = wil_get_wmi_edmg_channel(wil, sme->edmg_bw_config,
+ sme->edmg_channels, &conn.edmg_channel);
+ if (rc < 0)
+ return rc;
+
ether_addr_copy(conn.bssid, bss->bssid);
ether_addr_copy(conn.dst_mac, bss->bssid);

@@ -1707,7 +1884,7 @@ static int _wil_cfg80211_set_ies(struct wil6210_vif *vif,
static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
struct net_device *ndev,
const u8 *ssid, size_t ssid_len, u32 privacy,
- int bi, u8 chan,
+ int bi, u8 chan, u8 wmi_edmg_channel,
struct cfg80211_beacon_data *bcon,
u8 hidden_ssid, u32 pbss)
{
@@ -1770,6 +1947,7 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,

vif->privacy = privacy;
vif->channel = chan;
+ vif->wmi_edmg_channel = wmi_edmg_channel;
vif->hidden_ssid = hidden_ssid;
vif->pbss = pbss;
vif->bi = bi;
@@ -1780,7 +1958,8 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
if (!wil_has_other_active_ifaces(wil, ndev, false, true))
wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);

- rc = wmi_pcp_start(vif, bi, wmi_nettype, chan, hidden_ssid, is_go);
+ rc = wmi_pcp_start(vif, bi, wmi_nettype, chan, wmi_edmg_channel,
+ hidden_ssid, is_go);
if (rc)
goto err_pcp_start;

@@ -1832,7 +2011,8 @@ void wil_cfg80211_ap_recovery(struct wil6210_priv *wil)
rc = _wil_cfg80211_start_ap(wiphy, ndev,
vif->ssid, vif->ssid_len,
vif->privacy, vif->bi,
- vif->channel, &bcon,
+ vif->channel,
+ vif->wmi_edmg_channel, &bcon,
vif->hidden_ssid, vif->pbss);
if (rc) {
wil_err(wil, "vif %d recovery failed (%d)\n", i, rc);
@@ -1882,7 +2062,8 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
rc = _wil_cfg80211_start_ap(wiphy, ndev, vif->ssid,
vif->ssid_len, privacy,
wdev->beacon_interval,
- vif->channel, bcon,
+ vif->channel,
+ vif->wmi_edmg_channel, bcon,
vif->hidden_ssid,
vif->pbss);
} else {
@@ -1901,10 +2082,17 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
struct ieee80211_channel *channel = info->chandef.chan;
struct cfg80211_beacon_data *bcon = &info->beacon;
struct cfg80211_crypto_settings *crypto = &info->crypto;
+ u8 wmi_edmg_channel;
u8 hidden_ssid;

wil_dbg_misc(wil, "start_ap\n");

+ rc = wil_get_wmi_edmg_channel(wil, info->chandef.edmg_bw_config,
+ info->chandef.edmg_channels,
+ &wmi_edmg_channel);
+ if (rc < 0)
+ return rc;
+
if (!channel) {
wil_err(wil, "AP: No channel???\n");
return -EINVAL;
@@ -1944,7 +2132,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
rc = _wil_cfg80211_start_ap(wiphy, ndev,
info->ssid, info->ssid_len, info->privacy,
info->beacon_interval, channel->hw_value,
- bcon, hidden_ssid, info->pbss);
+ wmi_edmg_channel, bcon, hidden_ssid,
+ info->pbss);

return rc;
}
diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c
index c387738..0c9bb2c 100644
--- a/drivers/net/wireless/ath/wil6210/txrx_edma.c
+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c
@@ -1006,6 +1006,8 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil,
stats->rx_per_mcs[stats->last_mcs_rx]++;
}

+ stats->last_cb_mode_rx = wil_rx_status_get_cb_mode(msg);
+
if (!wil->use_rx_hw_reordering && !wil->use_compressed_rx_status &&
wil_check_bar(wil, msg, cid, skb, stats) == -EAGAIN) {
kfree_skb(skb);
diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.h b/drivers/net/wireless/ath/wil6210/txrx_edma.h
index 343516a..2680ffc 100644
--- a/drivers/net/wireless/ath/wil6210/txrx_edma.h
+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.h
@@ -366,6 +366,12 @@ static inline u8 wil_rx_status_get_mcs(void *msg)
16, 21);
}

+static inline u8 wil_rx_status_get_cb_mode(void *msg)
+{
+ return WIL_GET_BITS(((struct wil_rx_status_compressed *)msg)->d1,
+ 22, 23);
+}
+
static inline u16 wil_rx_status_get_flow_id(void *msg)
{
return WIL_GET_BITS(((struct wil_rx_status_compressed *)msg)->d0,
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index e1b1039b..d32c0bf 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -590,6 +590,7 @@ struct wil_net_stats {
unsigned long rx_amsdu_error; /* eDMA specific */
unsigned long rx_csum_err;
u16 last_mcs_rx;
+ u8 last_cb_mode_rx;
u64 rx_per_mcs[WIL_MCS_MAX + 1];
u32 ft_roams; /* relevant in STA mode */
};
@@ -851,6 +852,7 @@ struct wil6210_vif {
DECLARE_BITMAP(status, wil_vif_status_last);
u32 privacy; /* secure connection? */
u16 channel; /* relevant in AP mode */
+ u8 wmi_edmg_channel; /* relevant in AP mode */
u8 hidden_ssid; /* relevant in AP mode */
u32 ap_isolate; /* no intra-BSS communication */
bool pbss;
@@ -1313,7 +1315,7 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,

int wmi_set_mac_address(struct wil6210_priv *wil, void *addr);
int wmi_pcp_start(struct wil6210_vif *vif, int bi, u8 wmi_nettype, u8 chan,
- u8 hidden_ssid, u8 is_go);
+ u8 edmg_chan, u8 hidden_ssid, u8 is_go);
int wmi_pcp_stop(struct wil6210_vif *vif);
int wmi_led_cfg(struct wil6210_priv *wil, bool enable);
int wmi_abort_scan(struct wil6210_vif *vif);
@@ -1389,6 +1391,10 @@ int wmi_start_sched_scan(struct wil6210_priv *wil,
int wmi_mgmt_tx_ext(struct wil6210_vif *vif, const u8 *buf, size_t len,
u8 channel, u16 duration_ms);

+int wil_wmi2spec_ch(u8 wmi_ch, u8 *spec_ch);
+int wil_spec2wmi_ch(u8 spec_ch, u8 *wmi_ch);
+void wil_update_supported_bands(struct wil6210_priv *wil);
+
int reverse_memcmp(const void *cs, const void *ct, size_t count);

/* WMI for enhanced DMA */
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index bda4a97..fe8530d 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -2123,8 +2123,8 @@ int wmi_led_cfg(struct wil6210_priv *wil, bool enable)
return rc;
}

-int wmi_pcp_start(struct wil6210_vif *vif,
- int bi, u8 wmi_nettype, u8 chan, u8 hidden_ssid, u8 is_go)
+int wmi_pcp_start(struct wil6210_vif *vif, int bi, u8 wmi_nettype,
+ u8 chan, u8 wmi_edmg_chan, u8 hidden_ssid, u8 is_go)
{
struct wil6210_priv *wil = vif_to_wil(vif);
int rc;
@@ -2134,6 +2134,7 @@ int wmi_pcp_start(struct wil6210_vif *vif,
.network_type = wmi_nettype,
.disable_sec_offload = 1,
.channel = chan - 1,
+ .edmg_channel = wmi_edmg_chan,
.pcp_max_assoc_sta = max_assoc_sta,
.hidden_ssid = hidden_ssid,
.is_go = is_go,
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h
index b668758..1b39aeb 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -95,6 +95,7 @@ enum wmi_fw_capability {
WMI_FW_CAPABILITY_SET_SILENT_RSSI_TABLE = 13,
WMI_FW_CAPABILITY_LO_POWER_CALIB_FROM_OTP = 14,
WMI_FW_CAPABILITY_PNO = 15,
+ WMI_FW_CAPABILITY_CHANNEL_BONDING = 17,
WMI_FW_CAPABILITY_REF_CLOCK_CONTROL = 18,
WMI_FW_CAPABILITY_AP_SME_OFFLOAD_NONE = 19,
WMI_FW_CAPABILITY_MULTI_VIFS = 20,
@@ -355,6 +356,19 @@ enum wmi_connect_ctrl_flag_bits {

#define WMI_MAX_SSID_LEN (32)

+enum wmi_channel {
+ WMI_CHANNEL_1 = 0x00,
+ WMI_CHANNEL_2 = 0x01,
+ WMI_CHANNEL_3 = 0x02,
+ WMI_CHANNEL_4 = 0x03,
+ WMI_CHANNEL_5 = 0x04,
+ WMI_CHANNEL_6 = 0x05,
+ WMI_CHANNEL_9 = 0x06,
+ WMI_CHANNEL_10 = 0x07,
+ WMI_CHANNEL_11 = 0x08,
+ WMI_CHANNEL_12 = 0x09,
+};
+
/* WMI_CONNECT_CMDID */
struct wmi_connect_cmd {
u8 network_type;
@@ -366,8 +380,12 @@ struct wmi_connect_cmd {
u8 group_crypto_len;
u8 ssid_len;
u8 ssid[WMI_MAX_SSID_LEN];
+ /* enum wmi_channel WMI_CHANNEL_1..WMI_CHANNEL_6; for EDMG this is
+ * the primary channel number
+ */
u8 channel;
- u8 reserved0;
+ /* enum wmi_channel WMI_CHANNEL_9..WMI_CHANNEL_12 */
+ u8 edmg_channel;
u8 bssid[WMI_MAC_LEN];
__le32 ctrl_flags;
u8 dst_mac[WMI_MAC_LEN];
@@ -2267,7 +2285,9 @@ struct wmi_notify_req_done_event {
__le32 status;
__le64 tsf;
s8 rssi;
- u8 reserved0[3];
+ /* enum wmi_edmg_tx_mode */
+ u8 tx_mode;
+ u8 reserved0[2];
__le32 tx_tpt;
__le32 tx_goodput;
__le32 rx_goodput;
@@ -2283,8 +2303,12 @@ struct wmi_notify_req_done_event {

/* WMI_CONNECT_EVENTID */
struct wmi_connect_event {
+ /* enum wmi_channel WMI_CHANNEL_1..WMI_CHANNEL_6; for EDMG this is
+ * the primary channel number
+ */
u8 channel;
- u8 reserved0;
+ /* enum wmi_channel WMI_CHANNEL_9..WMI_CHANNEL_12 */
+ u8 edmg_channel;
u8 bssid[WMI_MAC_LEN];
__le16 listen_interval;
__le16 beacon_interval;
--
1.9.1

2019-05-13 16:15:19

by Alexei Avshalom Lazar

[permalink] [raw]
Subject: [PATCH v2 1/2] nl80211: Add support for EDMG channels

802.11ay specification defines Enhanced Directional Multi-Gigabit
(EDMG) STA and AP which allow channel bonding of 2 channels and more.
Introduce NL80211_ATTR_WIPHY_EDMG_CHANNELS,
NL80211_ATTR_WIPHY_EDMG_BW_CONFIG, NL80211_BAND_ATTR_EDMG_CHANNELS,
NL80211_BAND_ATTR_EDMG_BW_CONFIG and RATE_INFO_FLAGS_EDMG
that needed for enabling and configuring EDMG support.
Driver is expected to report its EDMG capabilities: whether EDMG
is supported and the supported EDMG channels.
Bitrate calculation is enhanced to take into account EDMG support
according to the 802.11ay specification.
The kernel uses NL80211_BAND_ATTR_EDMG_CHANNELS and
NL80211_BAND_ATTR_EDMG_BW_CONFIG attributes in order to publish
the EDMG capabilities to the userspace.
NL80211_BAND_ATTR_EDMG_CHANNELS is a bitmap field that indicates
the 2.16 GHz channel(s) that are allowed to be used for transmissions
in the BSS.
If NL80211_BAND_ATTR_EDMG_CHANNELS is not set then EDMG not
supported. NL80211_BAND_ATTR_EDMG_BW_CONFIG represent the allowed
channel bandwidth configurations.
NL80211_ATTR_WIPHY_EDMG_CHANNELS and NL80211_ATTR_WIPHY_EDMG_BW_CONFIG
will be used by the userspace for AP configuration and connect command.

Change-Id: I534f4a750354a4b0baad28c47dc29afb9cbc36ac
---
drivers/net/wireless/ath/wil6210/cfg80211.c | 2 +-
include/net/cfg80211.h | 39 ++++++-
include/uapi/linux/nl80211.h | 19 ++++
net/wireless/chan.c | 152 +++++++++++++++++++++++++++-
net/wireless/nl80211.c | 33 ++++++
net/wireless/util.c | 42 +++++++-
6 files changed, 280 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index a1e226652..ce68fbc 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -346,7 +346,7 @@ int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC) |
BIT_ULL(NL80211_STA_INFO_TX_FAILED);

- sinfo->txrate.flags = RATE_INFO_FLAGS_60G;
+ sinfo->txrate.flags = RATE_INFO_FLAGS_DMG;
sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
sinfo->rxrate.mcs = stats->last_mcs_rx;
sinfo->rx_bytes = stats->rx_bytes;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 117691f..f2d2239 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -321,6 +321,23 @@ struct ieee80211_sband_iftype_data {
};

/**
+ * struct ieee80211_sta_edmg_cap - EDMG capabilities
+ *
+ * This structure describes most essential parameters needed
+ * to describe 802.11ay EDMG capabilities
+ *
+ * @channels: bitmap that indicates the 2.16 GHz channel(s)
+ * that are allowed to be used for transmissions in the BSS.
+ * Set to 0 indicate EDMG not supported.
+ * @bw_config: Channel BW Configuration subfield encodes
+ * the allowed channel bandwidth configurations
+ */
+struct ieee80211_sta_edmg_cap {
+ u8 channels;
+ u8 bw_config;
+};
+
+/**
* struct ieee80211_supported_band - frequency band definition
*
* This structure describes a frequency band a wiphy
@@ -336,6 +353,7 @@ struct ieee80211_sband_iftype_data {
* @n_bitrates: Number of bitrates in @bitrates
* @ht_cap: HT capabilities in this band
* @vht_cap: VHT capabilities in this band
+ * @edmg_cap: EDMG capabilities in this band
* @n_iftype_data: number of iftype data entries
* @iftype_data: interface type data entries. Note that the bits in
* @types_mask inside this structure cannot overlap (i.e. only
@@ -350,6 +368,7 @@ struct ieee80211_supported_band {
int n_bitrates;
struct ieee80211_sta_ht_cap ht_cap;
struct ieee80211_sta_vht_cap vht_cap;
+ struct ieee80211_sta_edmg_cap edmg_cap;
u16 n_iftype_data;
const struct ieee80211_sband_iftype_data *iftype_data;
};
@@ -503,12 +522,18 @@ struct key_params {
* @center_freq1: center frequency of first segment
* @center_freq2: center frequency of second segment
* (only with 80+80 MHz)
+ * @edmg_channels: bitmap that indicates the 2.16 GHz channel(s)
+ * that are allowed to be used for transmissions in the BSS.
+ * @edmg_bw_config: Channel BW Configuration subfield encodes
+ * the allowed channel bandwidth configurations
*/
struct cfg80211_chan_def {
struct ieee80211_channel *chan;
enum nl80211_chan_width width;
u32 center_freq1;
u32 center_freq2;
+ u8 edmg_channels;
+ u8 edmg_bw_config;
};

/**
@@ -1144,15 +1169,17 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
* @RATE_INFO_FLAGS_MCS: mcs field filled with HT MCS
* @RATE_INFO_FLAGS_VHT_MCS: mcs field filled with VHT MCS
* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval
- * @RATE_INFO_FLAGS_60G: 60GHz MCS
+ * @RATE_INFO_FLAGS_DMG: 60GHz MCS
* @RATE_INFO_FLAGS_HE_MCS: HE MCS information
+ * @RATE_INFO_FLAGS_EDMG: 60GHz MCS in EDMG mode
*/
enum rate_info_flags {
RATE_INFO_FLAGS_MCS = BIT(0),
RATE_INFO_FLAGS_VHT_MCS = BIT(1),
RATE_INFO_FLAGS_SHORT_GI = BIT(2),
- RATE_INFO_FLAGS_60G = BIT(3),
+ RATE_INFO_FLAGS_DMG = BIT(3),
RATE_INFO_FLAGS_HE_MCS = BIT(4),
+ RATE_INFO_FLAGS_EDMG = BIT(5),
};

/**
@@ -1192,6 +1219,7 @@ enum rate_info_bw {
* @he_dcm: HE DCM value
* @he_ru_alloc: HE RU allocation (from &enum nl80211_he_ru_alloc,
* only valid if bw is %RATE_INFO_BW_HE_RU)
+ * @n_bonded_ch: In case of EDMG the number of bonded channels (1-4)
*/
struct rate_info {
u8 flags;
@@ -1202,6 +1230,7 @@ struct rate_info {
u8 he_gi;
u8 he_dcm;
u8 he_ru_alloc;
+ u8 n_bonded_ch;
};

/**
@@ -2403,6 +2432,10 @@ struct cfg80211_bss_selection {
* @fils_erp_rrk_len: Length of @fils_erp_rrk in octets.
* @want_1x: indicates user-space supports and wants to use 802.1X driver
* offload of 4-way handshake.
+ * @edmg_channels: bitmap that indicates the 2.16 GHz channel(s)
+ * that are allowed to be used for transmissions in the BSS.
+ * @edmg_bw_config: Channel BW Configuration subfield encodes
+ * the allowed channel bandwidth configurations
*/
struct cfg80211_connect_params {
struct ieee80211_channel *channel;
@@ -2436,6 +2469,8 @@ struct cfg80211_connect_params {
const u8 *fils_erp_rrk;
size_t fils_erp_rrk_len;
bool want_1x;
+ u8 edmg_channels;
+ u8 edmg_bw_config;
};

/**
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 25f70dd..f74cce1 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2324,6 +2324,13 @@ enum nl80211_commands {
* should be picking up the lowest tx power, either tx power per-interface
* or per-station.
*
+ * @NL80211_ATTR_WIPHY_EDMG_CHANNELS: bitmap that indicates the 2.16 GHz
+ * channel(s) that are allowed to be used for EDMG transmissions in the
+ * BSS as defined by IEEE 802.11 section 9.4.2.251.
+ * @NL80211_ATTR_WIPHY_EDMG_BW_CONFIG: Channel BW Configuration subfield encodes
+ * the allowed channel bandwidth configurations as defined by IEEE 802.11
+ * section 9.4.2.251, Table 13.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2777,6 +2784,9 @@ enum nl80211_attrs {
NL80211_ATTR_STA_TX_POWER_SETTING,
NL80211_ATTR_STA_TX_POWER,

+ NL80211_ATTR_WIPHY_EDMG_CHANNELS,
+ NL80211_ATTR_WIPHY_EDMG_BW_CONFIG,
+
/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
@@ -3385,6 +3395,12 @@ enum nl80211_band_iftype_attr {
* @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE
* @NL80211_BAND_ATTR_IFTYPE_DATA: nested array attribute, with each entry using
* attributes from &enum nl80211_band_iftype_attr
+ * @NL80211_BAND_ATTR_EDMG_CHANNELS: bitmap that indicates the 2.16 GHz
+ * channel(s) that are allowed to be used for EDMG transmissions in the
+ * BSS as defined by IEEE 802.11 section 9.4.2.251.
+ * @NL80211_BAND_ATTR_EDMG_BW_CONFIG: Channel BW Configuration subfield
+ * encodes the allowed channel bandwidth configurations as defined by
+ * IEEE 802.11 section 9.4.2.251, Table 13.
* @NL80211_BAND_ATTR_MAX: highest band attribute currently defined
* @__NL80211_BAND_ATTR_AFTER_LAST: internal use
*/
@@ -3402,6 +3418,9 @@ enum nl80211_band_attr {
NL80211_BAND_ATTR_VHT_CAPA,
NL80211_BAND_ATTR_IFTYPE_DATA,

+ NL80211_BAND_ATTR_EDMG_CHANNELS,
+ NL80211_BAND_ATTR_EDMG_BW_CONFIG,
+
/* keep last */
__NL80211_BAND_ATTR_AFTER_LAST,
NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 7dc1bbd..d23135c 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -23,6 +23,8 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,

chandef->chan = chan;
chandef->center_freq2 = 0;
+ chandef->edmg_bw_config = 0;
+ chandef->edmg_channels = 0;

switch (chan_type) {
case NL80211_CHAN_NO_HT:
@@ -47,6 +49,92 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
}
EXPORT_SYMBOL(cfg80211_chandef_create);

+static bool cfg80211_edmg_chandef_valid(const struct cfg80211_chan_def *chandef)
+{
+ int max_continuous = 0;
+ int num_of_enabled = 0;
+ int continuous = 0;
+ int i;
+
+ if (!chandef->edmg_channels && !chandef->edmg_bw_config)
+ return true;
+
+ if ((!chandef->edmg_channels && chandef->edmg_bw_config) ||
+ (chandef->edmg_channels && !chandef->edmg_bw_config))
+ return false;
+
+ for (i = 0; i < 6; i++) {
+ if (chandef->edmg_channels & BIT(i)) {
+ continuous++;
+ num_of_enabled++;
+ } else {
+ continuous = 0;
+ }
+
+ max_continuous = max(continuous, max_continuous);
+ }
+ /* basic verification of edmg configuration according to
+ * IEEE802.11 section 9.4.2.251
+ */
+ /* check bw_config against continuous edmg channels */
+ switch (chandef->edmg_bw_config) {
+ case 4:
+ case 8:
+ case 12:
+ if (max_continuous < 1)
+ return false;
+ break;
+ case 5:
+ case 9:
+ case 13:
+ if (max_continuous < 2)
+ return false;
+ break;
+ case 6:
+ case 10:
+ case 14:
+ if (max_continuous < 3)
+ return false;
+ break;
+ case 7:
+ case 11:
+ case 15:
+ if (max_continuous < 4)
+ return false;
+ break;
+
+ default:
+ return false;
+ }
+
+ /* check bw_config against aggregated (non continuous) edmg channels */
+ switch (chandef->edmg_bw_config) {
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ break;
+ case 8:
+ case 9:
+ case 10:
+ case 11:
+ if (num_of_enabled < 2)
+ return false;
+ break;
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ if (num_of_enabled < 4 || max_continuous < 2)
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
{
u32 control_freq;
@@ -112,7 +200,7 @@ bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
return false;
}

- return true;
+ return cfg80211_edmg_chandef_valid(chandef);
}
EXPORT_SYMBOL(cfg80211_chandef_valid);

@@ -721,12 +809,65 @@ static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
return true;
}

+/* check if the operating channels are valid and supported */
+static bool cfg80211_edmg_usable(struct wiphy *wiphy, u8 edmg_channels,
+ u8 edmg_bw_config, int primary_channel,
+ struct ieee80211_sta_edmg_cap *edmg_cap)
+{
+ struct ieee80211_channel *chan;
+ int i, freq;
+ int channels_counter = 0;
+
+ if (!edmg_channels && !edmg_bw_config)
+ return true;
+
+ if ((!edmg_channels && edmg_bw_config) ||
+ (edmg_channels && !edmg_bw_config))
+ return false;
+
+ if (!(edmg_channels & BIT(primary_channel - 1)))
+ return false;
+
+ /* 60GHz channels 1..6 */
+ for (i = 0; i < 6; i++) {
+ if (!(edmg_channels & BIT(i)))
+ continue;
+
+ if (!(edmg_cap->channels & BIT(i)))
+ return false;
+
+ channels_counter++;
+
+ freq = ieee80211_channel_to_frequency(i + 1,
+ NL80211_BAND_60GHZ);
+ chan = ieee80211_get_channel(wiphy, freq);
+ if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
+ return false;
+ }
+
+ /* IEEE802.11 allows max 4 channels */
+ if (channels_counter > 4)
+ return false;
+
+ /* check bw_config is a subset of what driver supports
+ * (see IEEE 802.11 section 9.4.2.251, Table 13)
+ */
+ if ((edmg_bw_config % 4) > (edmg_cap->bw_config % 4))
+ return false;
+
+ if (edmg_bw_config > edmg_cap->bw_config)
+ return false;
+
+ return true;
+}
+
bool cfg80211_chandef_usable(struct wiphy *wiphy,
const struct cfg80211_chan_def *chandef,
u32 prohibited_flags)
{
struct ieee80211_sta_ht_cap *ht_cap;
struct ieee80211_sta_vht_cap *vht_cap;
+ struct ieee80211_sta_edmg_cap *edmg_cap;
u32 width, control_freq, cap;

if (WARN_ON(!cfg80211_chandef_valid(chandef)))
@@ -734,6 +875,15 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,

ht_cap = &wiphy->bands[chandef->chan->band]->ht_cap;
vht_cap = &wiphy->bands[chandef->chan->band]->vht_cap;
+ edmg_cap = &wiphy->bands[chandef->chan->band]->edmg_cap;
+
+ if (edmg_cap->channels &&
+ !cfg80211_edmg_usable(wiphy,
+ chandef->edmg_channels,
+ chandef->edmg_bw_config,
+ chandef->chan->hw_value,
+ edmg_cap))
+ return false;

control_freq = chandef->chan->center_freq;

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index da3843a..c6d4b44 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -288,6 +288,9 @@ static int validate_ie_attr(const struct nlattr *attr,

[NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
[NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
+ [NL80211_ATTR_WIPHY_EDMG_CHANNELS] = { .type = NLA_U8 },
+ [NL80211_ATTR_WIPHY_EDMG_BW_CONFIG] = { .type = NLA_U8 },
+
[NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
[NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
[NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
@@ -1501,6 +1504,15 @@ static int nl80211_send_band_rateinfo(struct sk_buff *msg,
nla_nest_end(msg, nl_iftype_data);
}

+ /* add EDMG info */
+ if (sband->edmg_cap.channels &&
+ (nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_CHANNELS,
+ sband->edmg_cap.channels) ||
+ nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_BW_CONFIG,
+ sband->edmg_cap.bw_config)))
+
+ return -ENOBUFS;
+
/* add bitrates */
nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
if (!nl_rates)
@@ -2560,6 +2572,18 @@ int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2]);
}

+ if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
+ chandef->edmg_channels =
+ nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
+
+ if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
+ chandef->edmg_bw_config =
+ nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
+ } else {
+ chandef->edmg_bw_config = 0;
+ chandef->edmg_channels = 0;
+ }
+
if (!cfg80211_chandef_valid(chandef)) {
NL_SET_ERR_MSG(extack, "invalid channel definition");
return -EINVAL;
@@ -9699,6 +9723,15 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
}

+ if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
+ connect.edmg_channels =
+ nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
+
+ if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
+ connect.edmg_bw_config =
+ nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
+ }
+
if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
connkeys = nl80211_parse_connkeys(rdev, info, NULL);
if (IS_ERR(connkeys))
diff --git a/net/wireless/util.c b/net/wireless/util.c
index cf63b63..7d06dd6 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1034,7 +1034,7 @@ static u32 cfg80211_calculate_bitrate_ht(struct rate_info *rate)
return (bitrate + 50000) / 100000;
}

-static u32 cfg80211_calculate_bitrate_60g(struct rate_info *rate)
+static u32 cfg80211_calculate_bitrate_dmg(struct rate_info *rate)
{
static const u32 __mcs2bitrate[] = {
/* control PHY */
@@ -1081,6 +1081,40 @@ static u32 cfg80211_calculate_bitrate_60g(struct rate_info *rate)
return __mcs2bitrate[rate->mcs];
}

+static u32 cfg80211_calculate_bitrate_edmg(struct rate_info *rate)
+{
+ static const u32 __mcs2bitrate[] = {
+ /* control PHY */
+ [0] = 275,
+ /* SC PHY */
+ [1] = 3850,
+ [2] = 7700,
+ [3] = 9625,
+ [4] = 11550,
+ [5] = 12512, /* 1251.25 mbps */
+ [6] = 13475,
+ [7] = 15400,
+ [8] = 19250,
+ [9] = 23100,
+ [10] = 25025,
+ [11] = 26950,
+ [12] = 30800,
+ [13] = 38500,
+ [14] = 46200,
+ [15] = 50050,
+ [16] = 53900,
+ [17] = 57750,
+ [18] = 69300,
+ [19] = 75075,
+ [20] = 80850,
+ };
+
+ if (WARN_ON_ONCE(rate->mcs >= ARRAY_SIZE(__mcs2bitrate)))
+ return 0;
+
+ return __mcs2bitrate[rate->mcs] * rate->n_bonded_ch;
+}
+
static u32 cfg80211_calculate_bitrate_vht(struct rate_info *rate)
{
static const u32 base[4][10] = {
@@ -1253,8 +1287,10 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
{
if (rate->flags & RATE_INFO_FLAGS_MCS)
return cfg80211_calculate_bitrate_ht(rate);
- if (rate->flags & RATE_INFO_FLAGS_60G)
- return cfg80211_calculate_bitrate_60g(rate);
+ if (rate->flags & RATE_INFO_FLAGS_DMG)
+ return cfg80211_calculate_bitrate_dmg(rate);
+ if (rate->flags & RATE_INFO_FLAGS_EDMG)
+ return cfg80211_calculate_bitrate_edmg(rate);
if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
return cfg80211_calculate_bitrate_vht(rate);
if (rate->flags & RATE_INFO_FLAGS_HE_MCS)
--
1.9.1

2019-05-20 17:58:32

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] nl80211: Add support for EDMG channels

Alexei Avshalom Lazar <[email protected]> writes:

> 802.11ay specification defines Enhanced Directional Multi-Gigabit
> (EDMG) STA and AP which allow channel bonding of 2 channels and more.
> Introduce NL80211_ATTR_WIPHY_EDMG_CHANNELS,
> NL80211_ATTR_WIPHY_EDMG_BW_CONFIG, NL80211_BAND_ATTR_EDMG_CHANNELS,
> NL80211_BAND_ATTR_EDMG_BW_CONFIG and RATE_INFO_FLAGS_EDMG
> that needed for enabling and configuring EDMG support.
> Driver is expected to report its EDMG capabilities: whether EDMG
> is supported and the supported EDMG channels.
> Bitrate calculation is enhanced to take into account EDMG support
> according to the 802.11ay specification.
> The kernel uses NL80211_BAND_ATTR_EDMG_CHANNELS and
> NL80211_BAND_ATTR_EDMG_BW_CONFIG attributes in order to publish
> the EDMG capabilities to the userspace.
> NL80211_BAND_ATTR_EDMG_CHANNELS is a bitmap field that indicates
> the 2.16 GHz channel(s) that are allowed to be used for transmissions
> in the BSS.
> If NL80211_BAND_ATTR_EDMG_CHANNELS is not set then EDMG not
> supported. NL80211_BAND_ATTR_EDMG_BW_CONFIG represent the allowed
> channel bandwidth configurations.
> NL80211_ATTR_WIPHY_EDMG_CHANNELS and NL80211_ATTR_WIPHY_EDMG_BW_CONFIG
> will be used by the userspace for AP configuration and connect command.
>
> Change-Id: I534f4a750354a4b0baad28c47dc29afb9cbc36ac

No Change-Id in upstream patches. And please read:

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#signed-off-by_missing

--
Kalle Valo

2019-05-20 18:13:36

by Alexei Avshalom Lazar

[permalink] [raw]
Subject: Re: [PATCH v2 1/2] nl80211: Add support for EDMG channels



On 5/20/2019 4:03 PM, Kalle Valo wrote:
> Alexei Avshalom Lazar <[email protected]> writes:
>
>> 802.11ay specification defines Enhanced Directional Multi-Gigabit
>> (EDMG) STA and AP which allow channel bonding of 2 channels and more.
>> Introduce NL80211_ATTR_WIPHY_EDMG_CHANNELS,
>> NL80211_ATTR_WIPHY_EDMG_BW_CONFIG, NL80211_BAND_ATTR_EDMG_CHANNELS,
>> NL80211_BAND_ATTR_EDMG_BW_CONFIG and RATE_INFO_FLAGS_EDMG
>> that needed for enabling and configuring EDMG support.
>> Driver is expected to report its EDMG capabilities: whether EDMG
>> is supported and the supported EDMG channels.
>> Bitrate calculation is enhanced to take into account EDMG support
>> according to the 802.11ay specification.
>> The kernel uses NL80211_BAND_ATTR_EDMG_CHANNELS and
>> NL80211_BAND_ATTR_EDMG_BW_CONFIG attributes in order to publish
>> the EDMG capabilities to the userspace.
>> NL80211_BAND_ATTR_EDMG_CHANNELS is a bitmap field that indicates
>> the 2.16 GHz channel(s) that are allowed to be used for transmissions
>> in the BSS.
>> If NL80211_BAND_ATTR_EDMG_CHANNELS is not set then EDMG not
>> supported. NL80211_BAND_ATTR_EDMG_BW_CONFIG represent the allowed
>> channel bandwidth configurations.
>> NL80211_ATTR_WIPHY_EDMG_CHANNELS and NL80211_ATTR_WIPHY_EDMG_BW_CONFIG
>> will be used by the userspace for AP configuration and connect command.
>>
>> Change-Id: I534f4a750354a4b0baad28c47dc29afb9cbc36ac
>
> No Change-Id in upstream patches. And please read:
>
> https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches#signed-off-by_missing
>

Hi Kalle,
Thanks for sharing the Wiki page, I will raise updated patches.

--
Alexei Lazar
Qualcomm Israel, on behalf of Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum a
Linux Foundation Collaborative Project