* [PATCH] brcmfmac: rework bphy_err() to take struct brcmf_pub argument
From: Rafał Miłecki @ 2019-02-15 14:45 UTC (permalink / raw)
To: Kalle Valo
Cc: Arend van Spriel, linux-wireless, brcm80211-dev-list.pdl,
brcm80211-dev-list, Rafał Miłecki
From: Rafał Miłecki <rafal@milecki.pl>
This macro will be used in more places not just the cfg80211.c. It makes
sense to pass some common struct to it as "struct wiphy" is mostly
referenced in cfg80211 code only.
A very common one (used above the bus abstraction layer) is struct
brcmf_pub. Many functions already keep reference to it which will make
using bphy_err() simpler. It should also allow extending that macro's
logic if it's ever needed.
This improves code recently added in the commit 3ef005b82e2a ("brcmfmac:
add bphy_err() and use it in the cfg80211.c").
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
While working on the:
[PATCH] brcmfmac: use bphy_err() in all wiphy-related code
[PATCH V2] brcmfmac: use bphy_err() in all wiphy-related code
[PATCH V3] brcmfmac: use bphy_err() in all wiphy-related code
I realized it would be:
1) Simpler for the rest of the code
2) More consistent with driver's design
to make bphy_err() take brcmfmac's internal & generic struct as
argument.
So I put above work on hold & I decided to modify bphy_err() to sth more
generic before we start using it all around.
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 510 ++++++++++--------
.../broadcom/brcm80211/brcmfmac/debug.h | 4 +-
2 files changed, 281 insertions(+), 233 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index fa752ec04f22..60b5fb29e5f3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -457,7 +457,7 @@ static void convert_key_from_CPU(struct brcmf_wsec_key *key,
static int
send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
{
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
int err;
struct brcmf_wsec_key_le key_le;
@@ -469,7 +469,7 @@ send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
sizeof(key_le));
if (err)
- bphy_err(wiphy, "wsec_key error (%d)\n", err);
+ bphy_err(drvr, "wsec_key error (%d)\n", err);
return err;
}
@@ -509,7 +509,7 @@ static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
{
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_mbss_ssid_le mbss_ssid_le;
int bsscfgidx;
int err;
@@ -526,7 +526,7 @@ static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
sizeof(mbss_ssid_le));
if (err < 0)
- bphy_err(wiphy, "setting ssid failed %d\n", err);
+ bphy_err(drvr, "setting ssid failed %d\n", err);
return err;
}
@@ -544,6 +544,7 @@ struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_cfg80211_vif *vif;
int err;
@@ -569,7 +570,7 @@ struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
BRCMF_VIF_EVENT_TIMEOUT);
brcmf_cfg80211_arm_vif_event(cfg, NULL);
if (!err) {
- bphy_err(wiphy, "timeout occurred\n");
+ bphy_err(drvr, "timeout occurred\n");
err = -EIO;
goto fail;
}
@@ -577,7 +578,7 @@ struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
/* interface created in firmware */
ifp = vif->ifp;
if (!ifp) {
- bphy_err(wiphy, "no if pointer provided\n");
+ bphy_err(drvr, "no if pointer provided\n");
err = -ENOENT;
goto fail;
}
@@ -585,7 +586,7 @@ struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
err = brcmf_net_attach(ifp, true);
if (err) {
- bphy_err(wiphy, "Registering netdevice failed\n");
+ bphy_err(drvr, "Registering netdevice failed\n");
free_netdev(ifp->ndev);
goto fail;
}
@@ -616,13 +617,15 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
enum nl80211_iftype type,
struct vif_params *params)
{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_pub *drvr = cfg->pub;
struct wireless_dev *wdev;
int err;
brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
if (err) {
- bphy_err(wiphy, "iface validation failed: err=%d\n", err);
+ bphy_err(drvr, "iface validation failed: err=%d\n", err);
return ERR_PTR(err);
}
switch (type) {
@@ -647,7 +650,7 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
}
if (IS_ERR(wdev))
- bphy_err(wiphy, "add iface %s type %d failed: err=%d\n", name,
+ bphy_err(drvr, "add iface %s type %d failed: err=%d\n", name,
type, (int)PTR_ERR(wdev));
else
brcmf_cfg80211_update_proto_addr_mode(wdev);
@@ -663,13 +666,13 @@ static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
{
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
s32 err = 0;
if (check_vif_up(ifp->vif)) {
err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
if (err) {
- bphy_err(wiphy, "fail to set mpc\n");
+ bphy_err(drvr, "fail to set mpc\n");
return;
}
brcmf_dbg(INFO, "MPC : %d\n", mpc);
@@ -680,7 +683,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
struct brcmf_if *ifp, bool aborted,
bool fw_abort)
{
- struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_scan_params_le params_le;
struct cfg80211_scan_request *scan_request;
u64 reqid;
@@ -715,7 +718,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
¶ms_le, sizeof(params_le));
if (err)
- bphy_err(wiphy, "Scan abort failed\n");
+ bphy_err(drvr, "Scan abort failed\n");
}
brcmf_scan_config_mpc(ifp, 1);
@@ -760,6 +763,7 @@ static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct net_device *ndev = wdev->netdev;
struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = cfg->pub;
int ret;
int err;
@@ -767,7 +771,7 @@ static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
if (err) {
- bphy_err(wiphy, "interface_remove failed %d\n", err);
+ bphy_err(drvr, "interface_remove failed %d\n", err);
goto err_unarm;
}
@@ -775,7 +779,7 @@ static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
BRCMF_VIF_EVENT_TIMEOUT);
if (!ret) {
- bphy_err(wiphy, "timeout occurred\n");
+ bphy_err(drvr, "timeout occurred\n");
err = -EIO;
goto err_unarm;
}
@@ -838,6 +842,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_vif *vif = ifp->vif;
+ struct brcmf_pub *drvr = cfg->pub;
s32 infra = 0;
s32 ap = 0;
s32 err = 0;
@@ -877,13 +882,13 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
}
err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
if (err) {
- bphy_err(wiphy, "iface validation failed: err=%d\n", err);
+ bphy_err(drvr, "iface validation failed: err=%d\n", err);
return err;
}
switch (type) {
case NL80211_IFTYPE_MONITOR:
case NL80211_IFTYPE_WDS:
- bphy_err(wiphy, "type (%d) : currently we do not support this type\n",
+ bphy_err(drvr, "type (%d) : currently we do not support this type\n",
type);
return -EOPNOTSUPP;
case NL80211_IFTYPE_ADHOC:
@@ -912,7 +917,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
} else {
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
if (err) {
- bphy_err(wiphy, "WLC_SET_INFRA error (%d)\n", err);
+ bphy_err(drvr, "WLC_SET_INFRA error (%d)\n", err);
err = -EAGAIN;
goto done;
}
@@ -1003,7 +1008,7 @@ static s32
brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
struct cfg80211_scan_request *request)
{
- struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct brcmf_pub *drvr = cfg->pub;
s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
offsetof(struct brcmf_escan_params_le, params_le);
struct brcmf_escan_params_le *params;
@@ -1035,7 +1040,7 @@ brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
if (err == -EBUSY)
brcmf_dbg(INFO, "system busy : escan canceled\n");
else
- bphy_err(wiphy, "error (%d)\n", err);
+ bphy_err(drvr, "error (%d)\n", err);
}
kfree(params);
@@ -1072,6 +1077,7 @@ static s32
brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_cfg80211_vif *vif;
s32 err = 0;
@@ -1081,22 +1087,22 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
return -EIO;
if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
- bphy_err(wiphy, "Scanning already: status (%lu)\n",
+ bphy_err(drvr, "Scanning already: status (%lu)\n",
cfg->scan_status);
return -EAGAIN;
}
if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
- bphy_err(wiphy, "Scanning being aborted: status (%lu)\n",
+ bphy_err(drvr, "Scanning being aborted: status (%lu)\n",
cfg->scan_status);
return -EAGAIN;
}
if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
- bphy_err(wiphy, "Scanning suppressed: status (%lu)\n",
+ bphy_err(drvr, "Scanning suppressed: status (%lu)\n",
cfg->scan_status);
return -EAGAIN;
}
if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) {
- bphy_err(wiphy, "Connecting: status (%lu)\n", vif->sme_state);
+ bphy_err(drvr, "Connecting: status (%lu)\n", vif->sme_state);
return -EAGAIN;
}
@@ -1130,7 +1136,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
return 0;
scan_out:
- bphy_err(wiphy, "scan error (%d)\n", err);
+ bphy_err(drvr, "scan error (%d)\n", err);
clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
cfg->scan_request = NULL;
return err;
@@ -1139,12 +1145,12 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
{
struct brcmf_if *ifp = netdev_priv(ndev);
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
s32 err = 0;
err = brcmf_fil_iovar_int_set(ifp, "rtsthresh", rts_threshold);
if (err)
- bphy_err(wiphy, "Error (%d)\n", err);
+ bphy_err(drvr, "Error (%d)\n", err);
return err;
}
@@ -1152,13 +1158,13 @@ static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
{
struct brcmf_if *ifp = netdev_priv(ndev);
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
s32 err = 0;
err = brcmf_fil_iovar_int_set(ifp, "fragthresh",
frag_threshold);
if (err)
- bphy_err(wiphy, "Error (%d)\n", err);
+ bphy_err(drvr, "Error (%d)\n", err);
return err;
}
@@ -1166,13 +1172,13 @@ static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
{
struct brcmf_if *ifp = netdev_priv(ndev);
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
s32 err = 0;
u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
err = brcmf_fil_cmd_int_set(ifp, cmd, retry);
if (err) {
- bphy_err(wiphy, "cmd (%d) , error (%d)\n", cmd, err);
+ bphy_err(drvr, "cmd (%d) , error (%d)\n", cmd, err);
return err;
}
return err;
@@ -1248,7 +1254,7 @@ static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len)
{
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_wsec_pmk_le pmk;
int i, err;
@@ -1262,7 +1268,7 @@ static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len)
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK,
&pmk, sizeof(pmk));
if (err < 0)
- bphy_err(wiphy, "failed to change PSK in firmware (len=%u)\n",
+ bphy_err(drvr, "failed to change PSK in firmware (len=%u)\n",
pmk_len);
return err;
@@ -1271,7 +1277,7 @@ static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len)
static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
- struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct brcmf_pub *drvr = cfg->pub;
s32 err = 0;
brcmf_dbg(TRACE, "Enter\n");
@@ -1281,7 +1287,7 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
err = brcmf_fil_cmd_data_set(vif->ifp,
BRCMF_C_DISASSOC, NULL, 0);
if (err) {
- bphy_err(wiphy, "WLC_DISASSOC failed (%d)\n", err);
+ bphy_err(drvr, "WLC_DISASSOC failed (%d)\n", err);
}
if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) ||
(vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
@@ -1305,6 +1311,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_join_params join_params;
size_t join_params_size = 0;
s32 err = 0;
@@ -1369,7 +1376,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
if (err) {
- bphy_err(wiphy, "wsec failed (%d)\n", err);
+ bphy_err(drvr, "wsec failed (%d)\n", err);
goto done;
}
@@ -1381,7 +1388,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
if (err) {
- bphy_err(wiphy, "WLC_SET_BCNPRD failed (%d)\n", err);
+ bphy_err(drvr, "WLC_SET_BCNPRD failed (%d)\n", err);
goto done;
}
@@ -1426,7 +1433,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
target_channel);
if (err) {
- bphy_err(wiphy, "WLC_SET_CHANNEL failed (%d)\n", err);
+ bphy_err(drvr, "WLC_SET_CHANNEL failed (%d)\n", err);
goto done;
}
} else
@@ -1438,7 +1445,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
&join_params, join_params_size);
if (err) {
- bphy_err(wiphy, "WLC_SET_SSID failed (%d)\n", err);
+ bphy_err(drvr, "WLC_SET_SSID failed (%d)\n", err);
goto done;
}
@@ -1475,8 +1482,8 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
struct cfg80211_connect_params *sme)
{
struct brcmf_if *ifp = netdev_priv(ndev);
- struct wiphy *wiphy = ifp->drvr->wiphy;
struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
+ struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_cfg80211_security *sec;
s32 val = 0;
s32 err = 0;
@@ -1490,7 +1497,7 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", val);
if (err) {
- bphy_err(wiphy, "set wpa_auth failed (%d)\n", err);
+ bphy_err(drvr, "set wpa_auth failed (%d)\n", err);
return err;
}
sec = &profile->sec;
@@ -1502,8 +1509,8 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
struct cfg80211_connect_params *sme)
{
struct brcmf_if *ifp = netdev_priv(ndev);
- struct wiphy *wiphy = ifp->drvr->wiphy;
struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
+ struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_cfg80211_security *sec;
s32 val = 0;
s32 err = 0;
@@ -1525,7 +1532,7 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
err = brcmf_fil_bsscfg_int_set(ifp, "auth", val);
if (err) {
- bphy_err(wiphy, "set auth failed (%d)\n", err);
+ bphy_err(drvr, "set auth failed (%d)\n", err);
return err;
}
sec = &profile->sec;
@@ -1538,8 +1545,8 @@ brcmf_set_wsec_mode(struct net_device *ndev,
struct cfg80211_connect_params *sme)
{
struct brcmf_if *ifp = netdev_priv(ndev);
- struct wiphy *wiphy = ifp->drvr->wiphy;
struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
+ struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_cfg80211_security *sec;
s32 pval = 0;
s32 gval = 0;
@@ -1562,7 +1569,7 @@ brcmf_set_wsec_mode(struct net_device *ndev,
pval = AES_ENABLED;
break;
default:
- bphy_err(wiphy, "invalid cipher pairwise (%d)\n",
+ bphy_err(drvr, "invalid cipher pairwise (%d)\n",
sme->crypto.ciphers_pairwise[0]);
return -EINVAL;
}
@@ -1583,7 +1590,7 @@ brcmf_set_wsec_mode(struct net_device *ndev,
gval = AES_ENABLED;
break;
default:
- bphy_err(wiphy, "invalid cipher group (%d)\n",
+ bphy_err(drvr, "invalid cipher group (%d)\n",
sme->crypto.cipher_group);
return -EINVAL;
}
@@ -1599,7 +1606,7 @@ brcmf_set_wsec_mode(struct net_device *ndev,
wsec = pval | gval;
err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
if (err) {
- bphy_err(wiphy, "error (%d)\n", err);
+ bphy_err(drvr, "error (%d)\n", err);
return err;
}
@@ -1614,8 +1621,8 @@ static s32
brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
{
struct brcmf_if *ifp = netdev_priv(ndev);
- struct wiphy *wiphy = ifp->drvr->wiphy;
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
+ struct brcmf_pub *drvr = ifp->drvr;
s32 val;
s32 err;
const struct brcmf_tlv *rsn_ie;
@@ -1633,7 +1640,7 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val);
if (err) {
- bphy_err(wiphy, "could not get wpa_auth (%d)\n", err);
+ bphy_err(drvr, "could not get wpa_auth (%d)\n", err);
return err;
}
if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
@@ -1647,7 +1654,7 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
val = WPA_AUTH_PSK;
break;
default:
- bphy_err(wiphy, "invalid cipher group (%d)\n",
+ bphy_err(drvr, "invalid cipher group (%d)\n",
sme->crypto.cipher_group);
return -EINVAL;
}
@@ -1678,7 +1685,7 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
val = WPA2_AUTH_PSK | WPA2_AUTH_FT;
break;
default:
- bphy_err(wiphy, "invalid cipher group (%d)\n",
+ bphy_err(drvr, "invalid cipher group (%d)\n",
sme->crypto.cipher_group);
return -EINVAL;
}
@@ -1725,7 +1732,7 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
if (err) {
- bphy_err(wiphy, "could not set wpa_auth (%d)\n", err);
+ bphy_err(drvr, "could not set wpa_auth (%d)\n", err);
return err;
}
@@ -1737,7 +1744,7 @@ brcmf_set_sharedkey(struct net_device *ndev,
struct cfg80211_connect_params *sme)
{
struct brcmf_if *ifp = netdev_priv(ndev);
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
struct brcmf_cfg80211_security *sec;
struct brcmf_wsec_key key;
@@ -1764,7 +1771,7 @@ brcmf_set_sharedkey(struct net_device *ndev,
key.len = (u32) sme->key_len;
key.index = (u32) sme->key_idx;
if (key.len > sizeof(key.data)) {
- bphy_err(wiphy, "Too long key length (%u)\n", key.len);
+ bphy_err(drvr, "Too long key length (%u)\n", key.len);
return -EINVAL;
}
memcpy(key.data, sme->key, key.len);
@@ -1777,7 +1784,7 @@ brcmf_set_sharedkey(struct net_device *ndev,
key.algo = CRYPTO_ALGO_WEP128;
break;
default:
- bphy_err(wiphy, "Invalid algorithm (%d)\n",
+ bphy_err(drvr, "Invalid algorithm (%d)\n",
sme->crypto.ciphers_pairwise[0]);
return -EINVAL;
}
@@ -1794,7 +1801,7 @@ brcmf_set_sharedkey(struct net_device *ndev,
val = WL_AUTH_SHARED_KEY; /* shared key */
err = brcmf_fil_bsscfg_int_set(ifp, "auth", val);
if (err)
- bphy_err(wiphy, "set auth failed (%d)\n", err);
+ bphy_err(drvr, "set auth failed (%d)\n", err);
}
return err;
}
@@ -1814,7 +1821,7 @@ enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
static void brcmf_set_join_pref(struct brcmf_if *ifp,
struct cfg80211_bss_selection *bss_select)
{
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_join_pref_params join_pref_params[2];
enum nl80211_band band;
int err, i = 0;
@@ -1853,7 +1860,7 @@ static void brcmf_set_join_pref(struct brcmf_if *ifp,
err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
sizeof(join_pref_params));
if (err)
- bphy_err(wiphy, "Set join_pref error (%d)\n", err);
+ bphy_err(drvr, "Set join_pref error (%d)\n", err);
}
static s32
@@ -1864,6 +1871,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct ieee80211_channel *chan = sme->channel;
+ struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_join_params join_params;
size_t join_params_size;
const struct brcmf_tlv *rsn_ie;
@@ -1880,7 +1888,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
return -EIO;
if (!sme->ssid) {
- bphy_err(wiphy, "Invalid ssid\n");
+ bphy_err(drvr, "Invalid ssid\n");
return -EOPNOTSUPP;
}
@@ -1909,7 +1917,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
sme->ie, sme->ie_len);
if (err)
- bphy_err(wiphy, "Set Assoc REQ IE Failed\n");
+ bphy_err(drvr, "Set Assoc REQ IE Failed\n");
else
brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
@@ -1930,32 +1938,32 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_set_wpa_version(ndev, sme);
if (err) {
- bphy_err(wiphy, "wl_set_wpa_version failed (%d)\n", err);
+ bphy_err(drvr, "wl_set_wpa_version failed (%d)\n", err);
goto done;
}
sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
err = brcmf_set_auth_type(ndev, sme);
if (err) {
- bphy_err(wiphy, "wl_set_auth_type failed (%d)\n", err);
+ bphy_err(drvr, "wl_set_auth_type failed (%d)\n", err);
goto done;
}
err = brcmf_set_wsec_mode(ndev, sme);
if (err) {
- bphy_err(wiphy, "wl_set_set_cipher failed (%d)\n", err);
+ bphy_err(drvr, "wl_set_set_cipher failed (%d)\n", err);
goto done;
}
err = brcmf_set_key_mgmt(ndev, sme);
if (err) {
- bphy_err(wiphy, "wl_set_key_mgmt failed (%d)\n", err);
+ bphy_err(drvr, "wl_set_key_mgmt failed (%d)\n", err);
goto done;
}
err = brcmf_set_sharedkey(ndev, sme);
if (err) {
- bphy_err(wiphy, "brcmf_set_sharedkey failed (%d)\n", err);
+ bphy_err(drvr, "brcmf_set_sharedkey failed (%d)\n", err);
goto done;
}
@@ -1972,7 +1980,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
/* enable firmware supplicant for this interface */
err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1);
if (err < 0) {
- bphy_err(wiphy, "failed to enable fw supplicant\n");
+ bphy_err(drvr, "failed to enable fw supplicant\n");
goto done;
}
}
@@ -2067,7 +2075,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
&join_params, join_params_size);
if (err)
- bphy_err(wiphy, "BRCMF_C_SET_SSID failed (%d)\n", err);
+ bphy_err(drvr, "BRCMF_C_SET_SSID failed (%d)\n", err);
done:
if (err)
@@ -2080,8 +2088,10 @@ static s32
brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
u16 reason_code)
{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_scb_val_le scbval;
s32 err = 0;
@@ -2098,7 +2108,7 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
&scbval, sizeof(scbval));
if (err)
- bphy_err(wiphy, "error (%d)\n", err);
+ bphy_err(drvr, "error (%d)\n", err);
brcmf_dbg(TRACE, "Exit\n");
return err;
@@ -2111,6 +2121,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct net_device *ndev = cfg_to_ndev(cfg);
struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = cfg->pub;
s32 err;
s32 disable;
u32 qdbm = 127;
@@ -2125,7 +2136,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
case NL80211_TX_POWER_LIMITED:
case NL80211_TX_POWER_FIXED:
if (mbm < 0) {
- bphy_err(wiphy, "TX_POWER_FIXED - dbm is negative\n");
+ bphy_err(drvr, "TX_POWER_FIXED - dbm is negative\n");
err = -EINVAL;
goto done;
}
@@ -2135,7 +2146,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
qdbm |= WL_TXPWR_OVERRIDE;
break;
default:
- bphy_err(wiphy, "Unsupported type %d\n", type);
+ bphy_err(drvr, "Unsupported type %d\n", type);
err = -EINVAL;
goto done;
}
@@ -2143,11 +2154,11 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
disable = WL_RADIO_SW_DISABLE << 16;
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
if (err)
- bphy_err(wiphy, "WLC_SET_RADIO error (%d)\n", err);
+ bphy_err(drvr, "WLC_SET_RADIO error (%d)\n", err);
err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
if (err)
- bphy_err(wiphy, "qtxpower error (%d)\n", err);
+ bphy_err(drvr, "qtxpower error (%d)\n", err);
done:
brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
@@ -2158,7 +2169,9 @@ static s32
brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
s32 *dbm)
{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev);
+ struct brcmf_pub *drvr = cfg->pub;
s32 qdbm = 0;
s32 err;
@@ -2168,7 +2181,7 @@ brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm);
if (err) {
- bphy_err(wiphy, "error (%d)\n", err);
+ bphy_err(drvr, "error (%d)\n", err);
goto done;
}
*dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
@@ -2183,6 +2196,7 @@ brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_idx, bool unicast, bool multicast)
{
struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = ifp->drvr;
u32 index;
u32 wsec;
s32 err = 0;
@@ -2194,7 +2208,7 @@ brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
if (err) {
- bphy_err(wiphy, "WLC_GET_WSEC error (%d)\n", err);
+ bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err);
goto done;
}
@@ -2204,7 +2218,7 @@ brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_int_set(ifp,
BRCMF_C_SET_KEY_PRIMARY, index);
if (err)
- bphy_err(wiphy, "error (%d)\n", err);
+ bphy_err(drvr, "error (%d)\n", err);
}
done:
brcmf_dbg(TRACE, "Exit\n");
@@ -2253,7 +2267,9 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
u8 key_idx, bool pairwise, const u8 *mac_addr,
struct key_params *params)
{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_wsec_key *key;
s32 val;
s32 wsec;
@@ -2268,7 +2284,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
/* we ignore this key index in this case */
- bphy_err(wiphy, "invalid key index (%d)\n", key_idx);
+ bphy_err(drvr, "invalid key index (%d)\n", key_idx);
return -EINVAL;
}
@@ -2277,7 +2293,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
mac_addr);
if (params->key_len > sizeof(key->data)) {
- bphy_err(wiphy, "Too long key length (%u)\n", params->key_len);
+ bphy_err(drvr, "Too long key length (%u)\n", params->key_len);
return -EINVAL;
}
@@ -2331,7 +2347,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
break;
default:
- bphy_err(wiphy, "Invalid cipher (0x%x)\n", params->cipher);
+ bphy_err(drvr, "Invalid cipher (0x%x)\n", params->cipher);
err = -EINVAL;
goto done;
}
@@ -2342,13 +2358,13 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
if (err) {
- bphy_err(wiphy, "get wsec error (%d)\n", err);
+ bphy_err(drvr, "get wsec error (%d)\n", err);
goto done;
}
wsec |= val;
err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
if (err) {
- bphy_err(wiphy, "set wsec error (%d)\n", err);
+ bphy_err(drvr, "set wsec error (%d)\n", err);
goto done;
}
@@ -2363,9 +2379,11 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx,
void (*callback)(void *cookie,
struct key_params *params))
{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct key_params params;
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_cfg80211_security *sec;
s32 wsec;
s32 err = 0;
@@ -2379,7 +2397,7 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx,
err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
if (err) {
- bphy_err(wiphy, "WLC_GET_WSEC error (%d)\n", err);
+ bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err);
/* Ignore this error, may happen during DISASSOC */
err = -EAGAIN;
goto done;
@@ -2400,7 +2418,7 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx,
params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
} else {
- bphy_err(wiphy, "Invalid algo (0x%x)\n", wsec);
+ bphy_err(drvr, "Invalid algo (0x%x)\n", wsec);
err = -EINVAL;
goto done;
}
@@ -2430,7 +2448,7 @@ brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
static void
brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
{
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
s32 err;
u8 key_idx;
struct brcmf_wsec_key *key;
@@ -2447,18 +2465,18 @@ brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
err = send_key_to_dongle(ifp, key);
if (err) {
- bphy_err(wiphy, "Setting WEP key failed (%d)\n", err);
+ bphy_err(drvr, "Setting WEP key failed (%d)\n", err);
return;
}
err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
if (err) {
- bphy_err(wiphy, "get wsec error (%d)\n", err);
+ bphy_err(drvr, "get wsec error (%d)\n", err);
return;
}
wsec |= WEP_ENABLED;
err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
if (err)
- bphy_err(wiphy, "set wsec error (%d)\n", err);
+ bphy_err(drvr, "set wsec error (%d)\n", err);
}
static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
@@ -2484,7 +2502,7 @@ static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
{
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
struct {
__le32 len;
struct brcmf_bss_info_le bss_le;
@@ -2500,7 +2518,7 @@ static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
WL_BSS_INFO_MAX);
if (err) {
- bphy_err(wiphy, "Failed to get bss info (%d)\n", err);
+ bphy_err(drvr, "Failed to get bss info (%d)\n", err);
goto out_kfree;
}
si->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM);
@@ -2522,7 +2540,7 @@ static s32
brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
struct station_info *sinfo)
{
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
struct brcmf_scb_val_le scbval;
struct brcmf_pktcnt_le pktcnt;
s32 err;
@@ -2532,7 +2550,7 @@ brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
/* Get the current tx rate */
err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
if (err < 0) {
- bphy_err(wiphy, "BRCMF_C_GET_RATE error (%d)\n", err);
+ bphy_err(drvr, "BRCMF_C_GET_RATE error (%d)\n", err);
return err;
}
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
@@ -2542,7 +2560,7 @@ brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scbval,
sizeof(scbval));
if (err) {
- bphy_err(wiphy, "BRCMF_C_GET_RSSI error (%d)\n", err);
+ bphy_err(drvr, "BRCMF_C_GET_RSSI error (%d)\n", err);
return err;
}
rssi = le32_to_cpu(scbval.val);
@@ -2552,7 +2570,7 @@ brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_GET_PKTCNTS, &pktcnt,
sizeof(pktcnt));
if (err) {
- bphy_err(wiphy, "BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err);
+ bphy_err(drvr, "BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err);
return err;
}
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
@@ -2571,7 +2589,9 @@ static s32
brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
const u8 *mac, struct station_info *sinfo)
{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_scb_val_le scb_val;
s32 err = 0;
struct brcmf_sta_info_le sta_info_le;
@@ -2600,7 +2620,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
&sta_info_le,
sizeof(sta_info_le));
if (err < 0) {
- bphy_err(wiphy, "GET STA INFO failed, %d\n", err);
+ bphy_err(drvr, "GET STA INFO failed, %d\n", err);
goto done;
}
}
@@ -2669,7 +2689,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
&scb_val, sizeof(scb_val));
if (err) {
- bphy_err(wiphy, "Could not get rssi (%d)\n",
+ bphy_err(drvr, "Could not get rssi (%d)\n",
err);
goto done;
} else {
@@ -2691,6 +2711,7 @@ brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = cfg->pub;
s32 err;
brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
@@ -2701,7 +2722,7 @@ brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
&cfg->assoclist,
sizeof(cfg->assoclist));
if (err) {
- bphy_err(wiphy, "BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n",
+ bphy_err(drvr, "BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n",
err);
cfg->assoclist.count = 0;
return -EOPNOTSUPP;
@@ -2722,6 +2743,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
s32 err = 0;
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = cfg->pub;
brcmf_dbg(TRACE, "Enter\n");
@@ -2750,9 +2772,9 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
if (err) {
if (err == -ENODEV)
- bphy_err(wiphy, "net_device is not ready yet\n");
+ bphy_err(drvr, "net_device is not ready yet\n");
else
- bphy_err(wiphy, "error (%d)\n", err);
+ bphy_err(drvr, "error (%d)\n", err);
}
done:
brcmf_dbg(TRACE, "Exit\n");
@@ -2763,6 +2785,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
struct brcmf_bss_info_le *bi)
{
struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct brcmf_pub *drvr = cfg->pub;
struct cfg80211_bss *bss;
enum nl80211_band band;
struct brcmu_chan ch;
@@ -2775,7 +2798,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
struct cfg80211_inform_bss bss_data = {};
if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
- bphy_err(wiphy, "Bss info is larger than buffer. Discarding\n");
+ bphy_err(drvr, "Bss info is larger than buffer. Discarding\n");
return 0;
}
@@ -2834,7 +2857,7 @@ next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
{
- struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_scan_results *bss_list;
struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
s32 err = 0;
@@ -2843,7 +2866,7 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
if (bss_list->count != 0 &&
bss_list->version != BRCMF_BSS_INFO_VERSION) {
- bphy_err(wiphy, "Version %d != WL_BSS_INFO_VERSION\n",
+ bphy_err(drvr, "Version %d != WL_BSS_INFO_VERSION\n",
bss_list->version);
return -EOPNOTSUPP;
}
@@ -2861,6 +2884,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev, const u8 *bssid)
{
struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct brcmf_pub *drvr = cfg->pub;
struct ieee80211_channel *notify_channel;
struct brcmf_bss_info_le *bi = NULL;
struct ieee80211_supported_band *band;
@@ -2888,7 +2912,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
buf, WL_BSS_INFO_MAX);
if (err) {
- bphy_err(wiphy, "WLC_GET_BSS_INFO failed: %d\n", err);
+ bphy_err(drvr, "WLC_GET_BSS_INFO failed: %d\n", err);
goto CleanUp;
}
@@ -2942,7 +2966,7 @@ static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
struct brcmf_if *ifp)
{
- struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_bss_info_le *bi;
const struct brcmf_tlv *tim;
u16 beacon_interval;
@@ -2959,7 +2983,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
cfg->extra_buf, WL_EXTRA_BUF_MAX);
if (err) {
- bphy_err(wiphy, "Could not get bss info %d\n", err);
+ bphy_err(drvr, "Could not get bss info %d\n", err);
goto update_bss_info_out;
}
@@ -2984,7 +3008,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
u32 var;
err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
if (err) {
- bphy_err(wiphy, "wl dtim_assoc failed (%d)\n", err);
+ bphy_err(drvr, "wl dtim_assoc failed (%d)\n", err);
goto update_bss_info_out;
}
dtim_period = (u8)var;
@@ -3022,10 +3046,10 @@ static void brcmf_escan_timeout(struct timer_list *t)
{
struct brcmf_cfg80211_info *cfg =
from_timer(cfg, t, escan_timeout);
- struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct brcmf_pub *drvr = cfg->pub;
if (cfg->int_escan_map || cfg->scan_request) {
- bphy_err(wiphy, "timer expired\n");
+ bphy_err(drvr, "timer expired\n");
schedule_work(&cfg->escan_timeout_work);
}
}
@@ -3073,8 +3097,8 @@ static s32
brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
const struct brcmf_event_msg *e, void *data)
{
- struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
- struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct brcmf_pub *drvr = ifp->drvr;
+ struct brcmf_cfg80211_info *cfg = drvr->config;
s32 status;
struct brcmf_escan_result_le *escan_result_le;
u32 escan_buflen;
@@ -3091,7 +3115,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
goto exit;
if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
- bphy_err(wiphy, "scan not ready, bsscfgidx=%d\n",
+ bphy_err(drvr, "scan not ready, bsscfgidx=%d\n",
ifp->bsscfgidx);
return -EPERM;
}
@@ -3099,24 +3123,24 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
if (status == BRCMF_E_STATUS_PARTIAL) {
brcmf_dbg(SCAN, "ESCAN Partial result\n");
if (e->datalen < sizeof(*escan_result_le)) {
- bphy_err(wiphy, "invalid event data length\n");
+ bphy_err(drvr, "invalid event data length\n");
goto exit;
}
escan_result_le = (struct brcmf_escan_result_le *) data;
if (!escan_result_le) {
- bphy_err(wiphy, "Invalid escan result (NULL pointer)\n");
+ bphy_err(drvr, "Invalid escan result (NULL pointer)\n");
goto exit;
}
escan_buflen = le32_to_cpu(escan_result_le->buflen);
if (escan_buflen > BRCMF_ESCAN_BUF_SIZE ||
escan_buflen > e->datalen ||
escan_buflen < sizeof(*escan_result_le)) {
- bphy_err(wiphy, "Invalid escan buffer length: %d\n",
+ bphy_err(drvr, "Invalid escan buffer length: %d\n",
escan_buflen);
goto exit;
}
if (le16_to_cpu(escan_result_le->bss_count) != 1) {
- bphy_err(wiphy, "Invalid bss_count %d: ignoring\n",
+ bphy_err(drvr, "Invalid bss_count %d: ignoring\n",
escan_result_le->bss_count);
goto exit;
}
@@ -3132,7 +3156,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
bi_length = le32_to_cpu(bss_info_le->length);
if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) {
- bphy_err(wiphy, "Ignoring invalid bss_info length: %d\n",
+ bphy_err(drvr, "Ignoring invalid bss_info length: %d\n",
bi_length);
goto exit;
}
@@ -3141,7 +3165,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
BIT(NL80211_IFTYPE_ADHOC))) {
if (le16_to_cpu(bss_info_le->capability) &
WLAN_CAPABILITY_IBSS) {
- bphy_err(wiphy, "Ignoring IBSS result\n");
+ bphy_err(drvr, "Ignoring IBSS result\n");
goto exit;
}
}
@@ -3149,7 +3173,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
list = (struct brcmf_scan_results *)
cfg->escan_info.escan_buf;
if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) {
- bphy_err(wiphy, "Buffer is too small: ignoring\n");
+ bphy_err(drvr, "Buffer is too small: ignoring\n");
goto exit;
}
@@ -3308,7 +3332,8 @@ static s32
brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
const struct brcmf_event_msg *e, void *data)
{
- struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
+ struct brcmf_pub *drvr = ifp->drvr;
+ struct brcmf_cfg80211_info *cfg = drvr->config;
struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
struct cfg80211_scan_request *request = NULL;
struct wiphy *wiphy = cfg_to_wiphy(cfg);
@@ -3341,14 +3366,14 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
if (!result_count) {
- bphy_err(wiphy, "FALSE PNO Event. (pfn_count == 0)\n");
+ bphy_err(drvr, "FALSE PNO Event. (pfn_count == 0)\n");
goto out_err;
}
netinfo_start = brcmf_get_netinfo_array(pfn_result);
datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result);
if (datalen < result_count * sizeof(*netinfo)) {
- bphy_err(wiphy, "insufficient event data\n");
+ bphy_err(drvr, "insufficient event data\n");
goto out_err;
}
@@ -3395,14 +3420,15 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
struct net_device *ndev,
struct cfg80211_sched_scan_request *req)
{
- struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = cfg->pub;
brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n",
req->n_match_sets, req->n_ssids);
if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
- bphy_err(wiphy, "Scanning suppressed: status=%lu\n",
+ bphy_err(drvr, "Scanning suppressed: status=%lu\n",
cfg->scan_status);
return -EAGAIN;
}
@@ -3481,8 +3507,8 @@ static s32
brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
void *data)
{
- struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
- struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct brcmf_pub *drvr = ifp->drvr;
+ struct brcmf_cfg80211_info *cfg = drvr->config;
struct brcmf_pno_scanresults_le *pfn_result;
struct brcmf_pno_net_info_le *netinfo;
@@ -3501,7 +3527,7 @@ brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
}
if (le32_to_cpu(pfn_result->count) < 1) {
- bphy_err(wiphy, "Invalid result count, expected 1 (%d)\n",
+ bphy_err(drvr, "Invalid result count, expected 1 (%d)\n",
le32_to_cpu(pfn_result->count));
return -EINVAL;
}
@@ -3529,6 +3555,7 @@ brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_wowl_wakeind_le wake_ind_le;
struct cfg80211_wowlan_wakeup wakeup_data;
struct cfg80211_wowlan_wakeup *wakeup;
@@ -3539,7 +3566,7 @@ static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le,
sizeof(wake_ind_le));
if (err) {
- bphy_err(wiphy, "Get wowl_wakeind failed, err = %d\n", err);
+ bphy_err(drvr, "Get wowl_wakeind failed, err = %d\n", err);
return;
}
@@ -3580,7 +3607,7 @@ static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
cfg->wowl.nd_data_completed,
BRCMF_ND_INFO_TIMEOUT);
if (!timeout)
- bphy_err(wiphy, "No result for wowl net detect\n");
+ bphy_err(drvr, "No result for wowl net detect\n");
else
wakeup_data.net_detect = cfg->wowl.nd_info;
}
@@ -3769,6 +3796,7 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
+ struct brcmf_pub *drvr = cfg->pub;
s32 err;
u32 npmk, i;
@@ -3788,7 +3816,7 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
cfg->pmk_list.npmk = cpu_to_le32(npmk);
}
} else {
- bphy_err(wiphy, "Too many PMKSA entries cached %d\n", npmk);
+ bphy_err(drvr, "Too many PMKSA entries cached %d\n", npmk);
return -EINVAL;
}
@@ -3811,6 +3839,7 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
+ struct brcmf_pub *drvr = cfg->pub;
s32 err;
u32 npmk, i;
@@ -3834,7 +3863,7 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
memset(&pmk[i], 0, sizeof(*pmk));
cfg->pmk_list.npmk = cpu_to_le32(npmk - 1);
} else {
- bphy_err(wiphy, "Cache entry not found\n");
+ bphy_err(drvr, "Cache entry not found\n");
return -EINVAL;
}
@@ -3866,20 +3895,20 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
{
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
s32 err;
s32 wpa_val;
/* set auth */
err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
if (err < 0) {
- bphy_err(wiphy, "auth error %d\n", err);
+ bphy_err(drvr, "auth error %d\n", err);
return err;
}
/* set wsec */
err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
if (err < 0) {
- bphy_err(wiphy, "wsec error %d\n", err);
+ bphy_err(drvr, "wsec error %d\n", err);
return err;
}
/* set upper-layer auth */
@@ -3889,7 +3918,7 @@ static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
wpa_val = WPA_AUTH_DISABLED;
err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_val);
if (err < 0) {
- bphy_err(wiphy, "wpa_auth error %d\n", err);
+ bphy_err(drvr, "wpa_auth error %d\n", err);
return err;
}
@@ -3909,7 +3938,7 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
const struct brcmf_vs_tlv *wpa_ie,
bool is_rsn_ie)
{
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
u32 auth = 0; /* d11 open authentication */
u16 count;
s32 err = 0;
@@ -3940,13 +3969,13 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
/* check for multicast cipher suite */
if (offset + WPA_IE_MIN_OUI_LEN > len) {
err = -EINVAL;
- bphy_err(wiphy, "no multicast cipher suite\n");
+ bphy_err(drvr, "no multicast cipher suite\n");
goto exit;
}
if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
err = -EINVAL;
- bphy_err(wiphy, "ivalid OUI\n");
+ bphy_err(drvr, "ivalid OUI\n");
goto exit;
}
offset += TLV_OUI_LEN;
@@ -3968,7 +3997,7 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
break;
default:
err = -EINVAL;
- bphy_err(wiphy, "Invalid multi cast cipher info\n");
+ bphy_err(drvr, "Invalid multi cast cipher info\n");
goto exit;
}
@@ -3979,13 +4008,13 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
/* Check for unicast suite(s) */
if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
err = -EINVAL;
- bphy_err(wiphy, "no unicast cipher suite\n");
+ bphy_err(drvr, "no unicast cipher suite\n");
goto exit;
}
for (i = 0; i < count; i++) {
if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
err = -EINVAL;
- bphy_err(wiphy, "ivalid OUI\n");
+ bphy_err(drvr, "ivalid OUI\n");
goto exit;
}
offset += TLV_OUI_LEN;
@@ -4003,7 +4032,7 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
pval |= AES_ENABLED;
break;
default:
- bphy_err(wiphy, "Invalid unicast security info\n");
+ bphy_err(drvr, "Invalid unicast security info\n");
}
offset++;
}
@@ -4013,13 +4042,13 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
/* Check for auth key management suite(s) */
if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
err = -EINVAL;
- bphy_err(wiphy, "no auth key mgmt suite\n");
+ bphy_err(drvr, "no auth key mgmt suite\n");
goto exit;
}
for (i = 0; i < count; i++) {
if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
err = -EINVAL;
- bphy_err(wiphy, "ivalid OUI\n");
+ bphy_err(drvr, "ivalid OUI\n");
goto exit;
}
offset += TLV_OUI_LEN;
@@ -4047,7 +4076,7 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
wpa_auth |= WPA2_AUTH_1X_SHA256;
break;
default:
- bphy_err(wiphy, "Invalid key mgmt info\n");
+ bphy_err(drvr, "Invalid key mgmt info\n");
}
offset++;
}
@@ -4089,7 +4118,7 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
wme_bss_disable);
if (err < 0) {
- bphy_err(wiphy, "wme_bss_disable error %d\n", err);
+ bphy_err(drvr, "wme_bss_disable error %d\n", err);
goto exit;
}
@@ -4103,7 +4132,7 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
&data[offset],
WPA_IE_MIN_OUI_LEN);
if (err < 0) {
- bphy_err(wiphy, "bip error %d\n", err);
+ bphy_err(drvr, "bip error %d\n", err);
goto exit;
}
}
@@ -4114,13 +4143,13 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
/* set auth */
err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
if (err < 0) {
- bphy_err(wiphy, "auth error %d\n", err);
+ bphy_err(drvr, "auth error %d\n", err);
goto exit;
}
/* set wsec */
err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
if (err < 0) {
- bphy_err(wiphy, "wsec error %d\n", err);
+ bphy_err(drvr, "wsec error %d\n", err);
goto exit;
}
/* Configure MFP, this needs to go after wsec otherwise the wsec command
@@ -4129,14 +4158,14 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) {
err = brcmf_fil_bsscfg_int_set(ifp, "mfp", mfp);
if (err < 0) {
- bphy_err(wiphy, "mfp error %d\n", err);
+ bphy_err(drvr, "mfp error %d\n", err);
goto exit;
}
}
/* set upper-layer auth */
err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
if (err < 0) {
- bphy_err(wiphy, "wpa_auth error %d\n", err);
+ bphy_err(drvr, "wpa_auth error %d\n", err);
goto exit;
}
@@ -4222,8 +4251,8 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
const u8 *vndr_ie_buf, u32 vndr_ie_len)
{
+ struct brcmf_pub *drvr;
struct brcmf_if *ifp;
- struct wiphy *wiphy;
struct vif_saved_ie *saved_ie;
s32 err = 0;
u8 *iovar_ie_buf;
@@ -4244,7 +4273,7 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
if (!vif)
return -ENODEV;
ifp = vif->ifp;
- wiphy = ifp->drvr->wiphy;
+ drvr = ifp->drvr;
saved_ie = &vif->saved_ie;
brcmf_dbg(TRACE, "bsscfgidx %d, pktflag : 0x%02X\n", ifp->bsscfgidx,
@@ -4276,13 +4305,13 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
break;
default:
err = -EPERM;
- bphy_err(wiphy, "not suitable type\n");
+ bphy_err(drvr, "not suitable type\n");
goto exit;
}
if (vndr_ie_len > mgmt_ie_buf_len) {
err = -ENOMEM;
- bphy_err(wiphy, "extra IE size too big\n");
+ bphy_err(drvr, "extra IE size too big\n");
goto exit;
}
@@ -4343,7 +4372,7 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
/* verify remained buf size before copy data */
if (remained_buf_len < (vndrie_info->vndrie.len +
VNDR_IE_VSIE_OFFSET)) {
- bphy_err(wiphy, "no space in mgmt_ie_buf: len left %d",
+ bphy_err(drvr, "no space in mgmt_ie_buf: len left %d",
remained_buf_len);
break;
}
@@ -4375,7 +4404,7 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
total_ie_buf_len);
if (err)
- bphy_err(wiphy, "vndr ie set error : %d\n", err);
+ bphy_err(drvr, "vndr ie set error : %d\n", err);
}
exit:
@@ -4403,14 +4432,14 @@ static s32
brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
struct cfg80211_beacon_data *beacon)
{
- struct wiphy *wiphy = vif->ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = vif->ifp->drvr;
s32 err;
/* Set Beacon IEs to FW */
err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
beacon->tail, beacon->tail_len);
if (err) {
- bphy_err(wiphy, "Set Beacon IE Failed\n");
+ bphy_err(drvr, "Set Beacon IE Failed\n");
return err;
}
brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
@@ -4420,7 +4449,7 @@ brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
beacon->proberesp_ies,
beacon->proberesp_ies_len);
if (err)
- bphy_err(wiphy, "Set Probe Resp IE Failed\n");
+ bphy_err(drvr, "Set Probe Resp IE Failed\n");
else
brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
@@ -4434,6 +4463,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
s32 ie_offset;
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = cfg->pub;
const struct brcmf_tlv *ssid_ie;
const struct brcmf_tlv *country_ie;
struct brcmf_ssid_le ssid_le;
@@ -4529,7 +4559,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
is_11d);
if (err < 0) {
- bphy_err(wiphy, "Regulatory Set Error, %d\n",
+ bphy_err(drvr, "Regulatory Set Error, %d\n",
err);
goto exit;
}
@@ -4538,7 +4568,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
settings->beacon_interval);
if (err < 0) {
- bphy_err(wiphy, "Beacon Interval Set Error, %d\n",
+ bphy_err(drvr, "Beacon Interval Set Error, %d\n",
err);
goto exit;
}
@@ -4547,7 +4577,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
settings->dtim_period);
if (err < 0) {
- bphy_err(wiphy, "DTIM Interval Set Error, %d\n",
+ bphy_err(drvr, "DTIM Interval Set Error, %d\n",
err);
goto exit;
}
@@ -4558,7 +4588,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB))) {
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
if (err < 0) {
- bphy_err(wiphy, "BRCMF_C_DOWN error %d\n",
+ bphy_err(drvr, "BRCMF_C_DOWN error %d\n",
err);
goto exit;
}
@@ -4567,7 +4597,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
if (err < 0) {
- bphy_err(wiphy, "SET INFRA error %d\n", err);
+ bphy_err(drvr, "SET INFRA error %d\n", err);
goto exit;
}
} else if (WARN_ON(supports_11d && (is_11d != ifp->vif->is_11d))) {
@@ -4583,7 +4613,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
if (err < 0) {
- bphy_err(wiphy, "setting AP mode failed %d\n",
+ bphy_err(drvr, "setting AP mode failed %d\n",
err);
goto exit;
}
@@ -4593,14 +4623,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
*/
err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
if (err < 0) {
- bphy_err(wiphy, "Set Channel failed: chspec=%d, %d\n",
+ bphy_err(drvr, "Set Channel failed: chspec=%d, %d\n",
chanspec, err);
goto exit;
}
}
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
if (err < 0) {
- bphy_err(wiphy, "BRCMF_C_UP error (%d)\n", err);
+ bphy_err(drvr, "BRCMF_C_UP error (%d)\n", err);
goto exit;
}
/* On DOWN the firmware removes the WEP keys, reconfigure
@@ -4615,14 +4645,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
&join_params, sizeof(join_params));
if (err < 0) {
- bphy_err(wiphy, "SET SSID error (%d)\n", err);
+ bphy_err(drvr, "SET SSID error (%d)\n", err);
goto exit;
}
if (settings->hidden_ssid) {
err = brcmf_fil_iovar_int_set(ifp, "closednet", 1);
if (err) {
- bphy_err(wiphy, "closednet error (%d)\n", err);
+ bphy_err(drvr, "closednet error (%d)\n", err);
goto exit;
}
}
@@ -4631,14 +4661,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
} else if (dev_role == NL80211_IFTYPE_P2P_GO) {
err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
if (err < 0) {
- bphy_err(wiphy, "Set Channel failed: chspec=%d, %d\n",
+ bphy_err(drvr, "Set Channel failed: chspec=%d, %d\n",
chanspec, err);
goto exit;
}
err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
sizeof(ssid_le));
if (err < 0) {
- bphy_err(wiphy, "setting ssid failed %d\n", err);
+ bphy_err(drvr, "setting ssid failed %d\n", err);
goto exit;
}
bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
@@ -4646,7 +4676,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
sizeof(bss_enable));
if (err < 0) {
- bphy_err(wiphy, "bss_enable config failed %d\n", err);
+ bphy_err(drvr, "bss_enable config failed %d\n", err);
goto exit;
}
@@ -4669,7 +4699,9 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = cfg->pub;
s32 err;
struct brcmf_fil_bss_enable_le bss_enable;
struct brcmf_join_params join_params;
@@ -4694,13 +4726,13 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
&join_params, sizeof(join_params));
if (err < 0)
- bphy_err(wiphy, "SET SSID error (%d)\n", err);
+ bphy_err(drvr, "SET SSID error (%d)\n", err);
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
if (err < 0)
- bphy_err(wiphy, "BRCMF_C_DOWN error %d\n", err);
+ bphy_err(drvr, "BRCMF_C_DOWN error %d\n", err);
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
if (err < 0)
- bphy_err(wiphy, "setting AP mode failed %d\n", err);
+ bphy_err(drvr, "setting AP mode failed %d\n", err);
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
brcmf_fil_iovar_int_set(ifp, "mbss", 0);
brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
@@ -4708,7 +4740,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
/* Bring device back up so it can be used again */
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
if (err < 0)
- bphy_err(wiphy, "BRCMF_C_UP error %d\n", err);
+ bphy_err(drvr, "BRCMF_C_UP error %d\n", err);
brcmf_vif_clear_mgmt_ies(ifp->vif);
} else {
@@ -4717,7 +4749,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
sizeof(bss_enable));
if (err < 0)
- bphy_err(wiphy, "bss_enable config failed %d\n", err);
+ bphy_err(drvr, "bss_enable config failed %d\n", err);
}
brcmf_set_mpc(ifp, 1);
brcmf_configure_arp_nd_offload(ifp, true);
@@ -4746,6 +4778,7 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
struct station_del_parameters *params)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_scb_val_le scbval;
struct brcmf_if *ifp = netdev_priv(ndev);
s32 err;
@@ -4765,7 +4798,7 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
&scbval, sizeof(scbval));
if (err)
- bphy_err(wiphy, "SCB_DEAUTHENTICATE_FOR_REASON failed %d\n",
+ bphy_err(drvr, "SCB_DEAUTHENTICATE_FOR_REASON failed %d\n",
err);
brcmf_dbg(TRACE, "Exit\n");
@@ -4776,6 +4809,8 @@ static int
brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
const u8 *mac, struct station_parameters *params)
{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_if *ifp = netdev_priv(ndev);
s32 err;
@@ -4796,7 +4831,7 @@ brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
(void *)mac, ETH_ALEN);
if (err < 0)
- bphy_err(wiphy, "Setting SCB (de-)authorize failed, %d\n", err);
+ bphy_err(drvr, "Setting SCB (de-)authorize failed, %d\n", err);
return err;
}
@@ -4826,6 +4861,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct ieee80211_channel *chan = params->chan;
+ struct brcmf_pub *drvr = cfg->pub;
const u8 *buf = params->buf;
size_t len = params->len;
const struct ieee80211_mgmt *mgmt;
@@ -4846,7 +4882,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
mgmt = (const struct ieee80211_mgmt *)buf;
if (!ieee80211_is_mgmt(mgmt->frame_control)) {
- bphy_err(wiphy, "Driver only allows MGMT packet type\n");
+ bphy_err(drvr, "Driver only allows MGMT packet type\n");
return -EPERM;
}
@@ -4877,13 +4913,13 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
GFP_KERNEL);
} else if (ieee80211_is_action(mgmt->frame_control)) {
if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) {
- bphy_err(wiphy, "invalid action frame length\n");
+ bphy_err(drvr, "invalid action frame length\n");
err = -EINVAL;
goto exit;
}
af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
if (af_params == NULL) {
- bphy_err(wiphy, "unable to allocate frame\n");
+ bphy_err(drvr, "unable to allocate frame\n");
err = -ENOMEM;
goto exit;
}
@@ -4934,6 +4970,7 @@ brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
u64 cookie)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_cfg80211_vif *vif;
int err = 0;
@@ -4941,7 +4978,7 @@ brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
if (vif == NULL) {
- bphy_err(wiphy, "No p2p device available for probe response\n");
+ bphy_err(drvr, "No p2p device available for probe response\n");
err = -ENODEV;
goto exit;
}
@@ -4956,6 +4993,7 @@ static int brcmf_cfg80211_get_channel(struct wiphy *wiphy,
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct net_device *ndev = wdev->netdev;
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_if *ifp;
struct brcmu_chan ch;
enum nl80211_band band = 0;
@@ -4969,7 +5007,7 @@ static int brcmf_cfg80211_get_channel(struct wiphy *wiphy,
err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec);
if (err) {
- bphy_err(wiphy, "chanspec failed (%d)\n", err);
+ bphy_err(drvr, "chanspec failed (%d)\n", err);
return err;
}
@@ -5091,6 +5129,8 @@ static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
struct net_device *ndev, const u8 *peer,
enum nl80211_tdls_operation oper)
{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_if *ifp;
struct brcmf_tdls_iovar_le info;
int ret = 0;
@@ -5108,7 +5148,7 @@ static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
&info, sizeof(info));
if (ret < 0)
- bphy_err(wiphy, "tdls_endpoint iovar failed: ret=%d\n", ret);
+ bphy_err(drvr, "tdls_endpoint iovar failed: ret=%d\n", ret);
return ret;
}
@@ -5119,6 +5159,8 @@ brcmf_cfg80211_update_conn_params(struct wiphy *wiphy,
struct cfg80211_connect_params *sme,
u32 changed)
{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_if *ifp;
int err;
@@ -5129,7 +5171,7 @@ brcmf_cfg80211_update_conn_params(struct wiphy *wiphy,
err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
sme->ie, sme->ie_len);
if (err)
- bphy_err(wiphy, "Set Assoc REQ IE Failed\n");
+ bphy_err(drvr, "Set Assoc REQ IE Failed\n");
else
brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
@@ -5141,6 +5183,8 @@ static int
brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
struct cfg80211_gtk_rekey_data *gtk)
{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_gtk_keyinfo_le gtk_le;
int ret;
@@ -5155,7 +5199,7 @@ brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", >k_le,
sizeof(gtk_le));
if (ret < 0)
- bphy_err(wiphy, "gtk_key_info iovar failed: ret=%d\n", ret);
+ bphy_err(drvr, "gtk_key_info iovar failed: ret=%d\n", ret);
return ret;
}
@@ -5387,7 +5431,7 @@ static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
struct brcmf_if *ifp)
{
- struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
u32 req_len;
@@ -5399,7 +5443,7 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
cfg->extra_buf, WL_ASSOC_INFO_MAX);
if (err) {
- bphy_err(wiphy, "could not get assoc info (%d)\n", err);
+ bphy_err(drvr, "could not get assoc info (%d)\n", err);
return err;
}
assoc_info =
@@ -5411,7 +5455,7 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
cfg->extra_buf,
WL_ASSOC_INFO_MAX);
if (err) {
- bphy_err(wiphy, "could not get assoc req (%d)\n", err);
+ bphy_err(drvr, "could not get assoc req (%d)\n", err);
return err;
}
conn_info->req_ie_len = req_len;
@@ -5427,7 +5471,7 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
cfg->extra_buf,
WL_ASSOC_INFO_MAX);
if (err) {
- bphy_err(wiphy, "could not get assoc resp (%d)\n", err);
+ bphy_err(drvr, "could not get assoc resp (%d)\n", err);
return err;
}
conn_info->resp_ie_len = resp_len;
@@ -5554,7 +5598,7 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
struct net_device *ndev,
const struct brcmf_event_msg *e, void *data)
{
- struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct brcmf_pub *drvr = cfg->pub;
static int generation;
u32 event = e->event_code;
u32 reason = e->reason;
@@ -5572,7 +5616,7 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
(reason == BRCMF_E_STATUS_SUCCESS)) {
if (!data) {
- bphy_err(wiphy, "No IEs present in ASSOC/REASSOC_IND\n");
+ bphy_err(drvr, "No IEs present in ASSOC/REASSOC_IND\n");
return -EINVAL;
}
@@ -5864,7 +5908,7 @@ static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
{
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
s32 err;
u32 bcn_timeout;
__le32 roamtrigger[2];
@@ -5877,7 +5921,7 @@ static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON;
err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
if (err) {
- bphy_err(wiphy, "bcn_timeout error (%d)\n", err);
+ bphy_err(drvr, "bcn_timeout error (%d)\n", err);
goto roam_setup_done;
}
@@ -5889,7 +5933,7 @@ static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
err = brcmf_fil_iovar_int_set(ifp, "roam_off",
ifp->drvr->settings->roamoff);
if (err) {
- bphy_err(wiphy, "roam_off error (%d)\n", err);
+ bphy_err(drvr, "roam_off error (%d)\n", err);
goto roam_setup_done;
}
@@ -5898,7 +5942,7 @@ static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
(void *)roamtrigger, sizeof(roamtrigger));
if (err) {
- bphy_err(wiphy, "WLC_SET_ROAM_TRIGGER error (%d)\n", err);
+ bphy_err(drvr, "WLC_SET_ROAM_TRIGGER error (%d)\n", err);
goto roam_setup_done;
}
@@ -5907,7 +5951,7 @@ static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
(void *)roam_delta, sizeof(roam_delta));
if (err) {
- bphy_err(wiphy, "WLC_SET_ROAM_DELTA error (%d)\n", err);
+ bphy_err(drvr, "WLC_SET_ROAM_DELTA error (%d)\n", err);
goto roam_setup_done;
}
@@ -5918,26 +5962,26 @@ static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
static s32
brcmf_dongle_scantime(struct brcmf_if *ifp)
{
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
s32 err = 0;
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
BRCMF_SCAN_CHANNEL_TIME);
if (err) {
- bphy_err(wiphy, "Scan assoc time error (%d)\n", err);
+ bphy_err(drvr, "Scan assoc time error (%d)\n", err);
goto dongle_scantime_out;
}
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
BRCMF_SCAN_UNASSOC_TIME);
if (err) {
- bphy_err(wiphy, "Scan unassoc time error (%d)\n", err);
+ bphy_err(drvr, "Scan unassoc time error (%d)\n", err);
goto dongle_scantime_out;
}
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
BRCMF_SCAN_PASSIVE_TIME);
if (err) {
- bphy_err(wiphy, "Scan passive time error (%d)\n", err);
+ bphy_err(drvr, "Scan passive time error (%d)\n", err);
goto dongle_scantime_out;
}
@@ -5970,7 +6014,8 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
u32 bw_cap[])
{
struct wiphy *wiphy = cfg_to_wiphy(cfg);
- struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
+ struct brcmf_pub *drvr = cfg->pub;
+ struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
struct ieee80211_supported_band *band;
struct ieee80211_channel *channel;
struct brcmf_chanspec_list *list;
@@ -5991,7 +6036,7 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
BRCMF_DCMD_MEDLEN);
if (err) {
- bphy_err(wiphy, "get chanspecs error (%d)\n", err);
+ bphy_err(drvr, "get chanspecs error (%d)\n", err);
goto fail_pbuf;
}
@@ -6014,7 +6059,7 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
} else if (ch.band == BRCMU_CHAN_BAND_5G) {
band = wiphy->bands[NL80211_BAND_5GHZ];
} else {
- bphy_err(wiphy, "Invalid channel Spec. 0x%x.\n",
+ bphy_err(drvr, "Invalid channel Spec. 0x%x.\n",
ch.chspec);
continue;
}
@@ -6038,7 +6083,7 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
/* It seems firmware supports some channel we never
* considered. Something new in IEEE standard?
*/
- bphy_err(wiphy, "Ignoring unexpected firmware channel %d\n",
+ bphy_err(drvr, "Ignoring unexpected firmware channel %d\n",
ch.control_ch_num);
continue;
}
@@ -6092,8 +6137,8 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
{
- struct wiphy *wiphy = cfg_to_wiphy(cfg);
- struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
+ struct brcmf_pub *drvr = cfg->pub;
+ struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
struct ieee80211_supported_band *band;
struct brcmf_fil_bwcap_le band_bwcap;
struct brcmf_chanspec_list *list;
@@ -6139,7 +6184,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
BRCMF_DCMD_MEDLEN);
if (err) {
- bphy_err(wiphy, "get chanspecs error (%d)\n", err);
+ bphy_err(drvr, "get chanspecs error (%d)\n", err);
kfree(pbuf);
return err;
}
@@ -6170,7 +6215,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
{
- struct wiphy *wiphy = ifp->drvr->wiphy;
+ struct brcmf_pub *drvr = ifp->drvr;
u32 band, mimo_bwcap;
int err;
@@ -6206,7 +6251,7 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
break;
default:
- bphy_err(wiphy, "invalid mimo_bw_cap value\n");
+ bphy_err(drvr, "invalid mimo_bw_cap value\n");
}
}
@@ -6281,7 +6326,8 @@ static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
{
- struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
+ struct brcmf_pub *drvr = cfg->pub;
+ struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
struct wiphy *wiphy = cfg_to_wiphy(cfg);
u32 nmode = 0;
u32 vhtmode = 0;
@@ -6298,7 +6344,7 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
(void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
if (err) {
- bphy_err(wiphy, "nmode error (%d)\n", err);
+ bphy_err(drvr, "nmode error (%d)\n", err);
} else {
brcmf_get_bwcap(ifp, bw_cap);
}
@@ -6308,7 +6354,7 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
if (err) {
- bphy_err(wiphy, "rxchain error (%d)\n", err);
+ bphy_err(drvr, "rxchain error (%d)\n", err);
nchain = 1;
} else {
for (nchain = 0; rxchain; nchain++)
@@ -6318,7 +6364,7 @@ static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
err = brcmf_construct_chaninfo(cfg, bw_cap);
if (err) {
- bphy_err(wiphy, "brcmf_construct_chaninfo failed (%d)\n", err);
+ bphy_err(drvr, "brcmf_construct_chaninfo failed (%d)\n", err);
return err;
}
@@ -6525,12 +6571,13 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
{
#ifdef CONFIG_PM
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_pub *drvr = cfg->pub;
struct wiphy_wowlan_support *wowl;
wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support),
GFP_KERNEL);
if (!wowl) {
- bphy_err(wiphy, "only support basic wowlan features\n");
+ bphy_err(drvr, "only support basic wowlan features\n");
wiphy->wowlan = &brcmf_wowlan_support;
return;
}
@@ -6627,7 +6674,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
sizeof(bandlist));
if (err) {
- bphy_err(wiphy, "could not obtain band info: err=%d\n", err);
+ bphy_err(drvr, "could not obtain band info: err=%d\n", err);
return err;
}
/* first entry in bandlist is number of bands */
@@ -6676,7 +6723,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
{
- struct wiphy *wiphy = cfg_to_wiphy(cfg);
+ struct brcmf_pub *drvr = cfg->pub;
struct net_device *ndev;
struct wireless_dev *wdev;
struct brcmf_if *ifp;
@@ -6714,7 +6761,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_FAKEFRAG, 1);
if (err) {
- bphy_err(wiphy, "failed to set frameburst mode\n");
+ bphy_err(drvr, "failed to set frameburst mode\n");
goto default_conf_out;
}
@@ -6895,6 +6942,7 @@ static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
+ struct brcmf_pub *drvr = cfg->pub;
struct brcmf_fil_country_le ccreq;
s32 err;
int i;
@@ -6906,7 +6954,7 @@ static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
/* ignore non-ISO3166 country codes */
for (i = 0; i < 2; i++)
if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
- bphy_err(wiphy, "not an ISO3166 code (0x%02x 0x%02x)\n",
+ bphy_err(drvr, "not an ISO3166 code (0x%02x 0x%02x)\n",
req->alpha2[0], req->alpha2[1]);
return;
}
@@ -6916,7 +6964,7 @@ static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
if (err) {
- bphy_err(wiphy, "Country code iovar returned err = %d\n", err);
+ bphy_err(drvr, "Country code iovar returned err = %d\n", err);
return;
}
@@ -6926,7 +6974,7 @@ static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
if (err) {
- bphy_err(wiphy, "Firmware rejected country setting\n");
+ bphy_err(drvr, "Firmware rejected country setting\n");
return;
}
brcmf_setup_wiphybands(cfg);
@@ -6972,13 +7020,13 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
u16 *cap = NULL;
if (!ndev) {
- bphy_err(wiphy, "ndev is invalid\n");
+ bphy_err(drvr, "ndev is invalid\n");
return NULL;
}
cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
if (!cfg) {
- bphy_err(wiphy, "Could not allocate wiphy device\n");
+ bphy_err(drvr, "Could not allocate wiphy device\n");
return NULL;
}
@@ -6999,7 +7047,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
err = wl_init_priv(cfg);
if (err) {
- bphy_err(wiphy, "Failed to init iwm_priv (%d)\n", err);
+ bphy_err(drvr, "Failed to init iwm_priv (%d)\n", err);
brcmf_free_vif(vif);
goto wiphy_out;
}
@@ -7008,7 +7056,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
/* determine d11 io type before wiphy setup */
err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
if (err) {
- bphy_err(wiphy, "Failed to get D11 version (%d)\n", err);
+ bphy_err(drvr, "Failed to get D11 version (%d)\n", err);
goto priv_out;
}
cfg->d11inf.io_type = (u8)io_type;
@@ -7042,13 +7090,13 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
#endif
err = wiphy_register(wiphy);
if (err < 0) {
- bphy_err(wiphy, "Could not register wiphy device (%d)\n", err);
+ bphy_err(drvr, "Could not register wiphy device (%d)\n", err);
goto priv_out;
}
err = brcmf_setup_wiphybands(cfg);
if (err) {
- bphy_err(wiphy, "Setting wiphy bands failed (%d)\n", err);
+ bphy_err(drvr, "Setting wiphy bands failed (%d)\n", err);
goto wiphy_unreg_out;
}
@@ -7066,24 +7114,24 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
err = brcmf_fweh_activate_events(ifp);
if (err) {
- bphy_err(wiphy, "FWEH activation failed (%d)\n", err);
+ bphy_err(drvr, "FWEH activation failed (%d)\n", err);
goto wiphy_unreg_out;
}
err = brcmf_p2p_attach(cfg, p2pdev_forced);
if (err) {
- bphy_err(wiphy, "P2P initialisation failed (%d)\n", err);
+ bphy_err(drvr, "P2P initialisation failed (%d)\n", err);
goto wiphy_unreg_out;
}
err = brcmf_btcoex_attach(cfg);
if (err) {
- bphy_err(wiphy, "BT-coex initialisation failed (%d)\n", err);
+ bphy_err(drvr, "BT-coex initialisation failed (%d)\n", err);
brcmf_p2p_detach(&cfg->p2p);
goto wiphy_unreg_out;
}
err = brcmf_pno_attach(cfg);
if (err) {
- bphy_err(wiphy, "PNO initialisation failed (%d)\n", err);
+ bphy_err(drvr, "PNO initialisation failed (%d)\n", err);
brcmf_btcoex_detach(cfg);
brcmf_p2p_detach(&cfg->p2p);
goto wiphy_unreg_out;
@@ -7103,7 +7151,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
/* (re-) activate FWEH event handling */
err = brcmf_fweh_activate_events(ifp);
if (err) {
- bphy_err(wiphy, "FWEH activation failed (%d)\n", err);
+ bphy_err(drvr, "FWEH activation failed (%d)\n", err);
goto detach;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
index 3cf853c84a9e..2998726b62c3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
@@ -62,12 +62,12 @@ void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...);
} while (0)
#endif
-#define bphy_err(wiphy, fmt, ...) \
+#define bphy_err(drvr, fmt, ...) \
do { \
if (IS_ENABLED(CONFIG_BRCMDBG) || \
IS_ENABLED(CONFIG_BRCM_TRACING) || \
net_ratelimit()) \
- wiphy_err(wiphy, "%s: " fmt, __func__, \
+ wiphy_err((drvr)->wiphy, "%s: " fmt, __func__, \
##__VA_ARGS__); \
} while (0)
--
2.20.1
^ permalink raw reply related
* [PATCH] ath10k: Fix length of wmi tlv command for protected mgmt frames
From: Surabhi Vishnoi @ 2019-02-15 15:19 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless, Surabhi Vishnoi
The length of wmi tlv command for management tx send is calculated
incorrectly in case of protected management frames as there is addition
of IEEE80211_CCMP_MIC_LEN twice. This leads to improper behaviour of
firmware as the wmi tlv mgmt tx send command for protected mgmt frames
is formed wrongly.
Fix the length calculation of wmi tlv command for mgmt tx send in case
of protected management frames by adding the IEEE80211_CCMP_MIC_LEN only
once.
Tested HW: WCN3990
Tested FW: WLAN.HL.3.1-00784-QCAHLSWMTPLZ-1
Fixes: 1807da49733e "ath10k: wmi: add management tx by reference support over wmi"
Signed-off-by: Surabhi Vishnoi <svishnoi@codeaurora.org>
---
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 5d05bff..a1c28c1 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -2764,10 +2764,8 @@ static void *ath10k_wmi_tlv_put_wmm(void *ptr,
if ((ieee80211_is_action(hdr->frame_control) ||
ieee80211_is_deauth(hdr->frame_control) ||
ieee80211_is_disassoc(hdr->frame_control)) &&
- ieee80211_has_protected(hdr->frame_control)) {
- len += IEEE80211_CCMP_MIC_LEN;
+ ieee80211_has_protected(hdr->frame_control))
buf_len += IEEE80211_CCMP_MIC_LEN;
- }
buf_len = min_t(u32, buf_len, WMI_TLV_MGMT_TX_FRAME_MAX_LEN);
buf_len = round_up(buf_len, 4);
--
1.9.1
^ permalink raw reply related
* [BUG] ath10k firmware crash 100% recreated this way
From: Chaoxing Lin @ 2019-02-15 15:45 UTC (permalink / raw)
To: ath10k@lists.infradead.org, linux-wireless@vger.kernel.org
Hello ath10k firmware maintainers,
I saw ath10k firmware crash very often (~170 times in 20hours)
on our wireless AP/bridge environment below:
arm64 board
kernel 4.14.16
hostapd-2.6 run in 4-address mode
Qualcomm Atheros QCA986x/988x 802.11ac Wireless Network Adapter
ath10k_core.ko in software crypto mode
running RSTP (Rapid Spanning Tree Protocol)
I also consistently recreated this firmware crash on Linux PC acting as AP
as follows. Please take a look.
"must" conditions:
1. ath10k_core.ko MUST be in software crypto mode
("modprobe ath10k_core cryptmode=1")
2. MUST run our proprietary RSTP bridge module 3ebridge.ko
(I can provide binary complied for kernel 4.14.16 on X86_64 PC)
3. STP must be on.
("brctl stp brg0 on", by default 3ebridge.ko would turn STP on. Just a note
that if STP is turned off, you won't see firmware crash)
4. hostapd-2.6 MUST be configured in 4-address mode
(put "wds_sta=1" in hostapd.conf)
5. Linux PC wireless client must be in 4-address mode.
(run "iw wlan0 set 4addr on" before starting wpa_supplicant)
To 100% recreate this firmware crash RIGHT AWAY, use the following WiFi
client.
root@Dell-D620:~# lspci
0c:00.0 Network controller: Intel Corporation PRO/Wireless 3945ABG
[Golan] Network Connection (rev 02)
You can find such radio card in very old (~15 years old) laptop.
I can send you this radio card if you cannot find it.
ath10k firmware crashes right away when this 4-address client associates with
the PC acting as AP.
FYI: What's known special about this wireless client?
Our experiments show this client does not really work in 4 address mode.
It successfully associates with AP but no traffic is possible in
4-address mode.
Packets sniffed in the air show that this client (when in 4 address mode)
does NOT send ACK packets to AP on receiving from AP packet whose RA is
client MAC and DA is multicast MAC (e.g. BPDU)
NOTE: Don't be distracted by what I saw about this wireless client.
It may not be related to the firmware crash.
The following are DONT-CARE in re-creating the firmware crash.
1. WiFi encryption:
The firmare crash happens even in bypass/no-encryption mode, although
ath10k_core.ko MUST be put in software crypto mode to see the crash.
2. ath10k firmware version:
As long as it supports software crypto mode (i.e. support raw mode),
the above procedure can crash it. I tried various firmware versions from
the initial version that supports raw mode to the latest
firmware-5.bin_10.2.4.70.69 dated 18-Dec-2018. They all crashed.
3. Linux wireless client distribution/OS is a don't care.
As long as the WiFi adapter is "Intel Corporation PRO/Wireless 3945AB"
Tried distributions below. They both make firmare crash right away on
PC AP side
Slackware 14.2 (kernel 4.4.14-smp)
Ubuntu 18.04.01 live (kernel 4.15.0-29-generic)
4. Radio channel setting is a don't care.
Tried with/without 11n/11ac/ and different channel width.
They all crash firmware.
I can provide all configurations/binary as below.
hostapd.conf [see later in this message]
wpa_supplicant.conf [see later in this message]
3ebridge.ko (RSTP bridge binary compiled for
mainline kernel 4.14.16 X86_64.
Please "modprobe -r bridge" before "insmod 3ebridge.ko")
Below is the syslog/messages related to the ath10k firmware crash.
For easier reading, Timestamps are removed. line edited just to wrap around
at 80char
/var/log/messages
---------------------------------------------------------------------------
ath10k_pci 0000:03:00.0: pci irq msi oper_irq_mode 2 irq_mode 0 reset_mode 0
ath10k_pci 0000:03:00.0: qca988x hw2.0 target 0x4100016c chip_id 0x043202ff
sub 0000:0000
ath10k_pci 0000:03:00.0: kconfig debug 0 debugfs 1 tracing 0 dfs 0 testmode 0
ath10k_pci 0000:03:00.0: firmware ver 10.2.4.70.69 api 5 features no-p2p,
raw-mode,mfp,allows-mesh-bcast crc32 edfb196a
ath10k_pci 0000:03:00.0: board_file api 1 bmi_id N/A crc32 bebc7c08
ath10k_pci 0000:03:00.0: htt-ver 2.1 wmi-op 5 htt-op 2 cal otp max-sta 128
raw 1 hwcrypto 0
ath10k_pci 0000:03:00.0 wlan50: renamed from wlan0
ath10k_pci 0000:03:00.0 wlan4: renamed from wlan50
IPv6: ADDRCONF(NETDEV_UP): phy0ap: link is not ready
device phy0ap entered promiscuous mode
IPv6: ADDRCONF(NETDEV_CHANGE): phy0ap: link becomes ready
device phy0ap.sta1 entered promiscuous mode
ath10k_pci 0000:03:00.0: qca988x hw2.0 target 0x4100016c chip_id 0x043202ff
sub 0000:0000
ath10k_pci 0000:03:00.0: kconfig debug 0 debugfs 1 tracing 0 dfs 0 testmode 0
ath10k_pci 0000:03:00.0: firmware ver 10.2.4.70.69 api 5 features no-p2p,
raw-mode,mfp,allows-mesh-bcast crc32 edfb196a
ath10k_pci 0000:03:00.0: board_file api 1 bmi_id N/A crc32 bebc7c08
ath10k_pci 0000:03:00.0: htt-ver 2.1 wmi-op 5 htt-op 2 cal otp max-sta 128
raw 1 hwcrypto 0
ieee80211 phy0: Hardware restart was requested
ath10k_pci 0000:03:00.0: device successfully recovered
/var/log/syslog
----------------------------------------------------------------------------
ath10k_pci 0000:03:00.0: firmware crashed!
(guid 64627eb3-5b90-491a-8181-6972fc50d317)
ath10k_pci 0000:03:00.0: firmware register dump:
ath10k_pci 0000:03:00.0: [00]: 0x4100016C 0x000015B3 0x0099901F 0x00955B31
ath10k_pci 0000:03:00.0: [04]: 0x0099901F 0x00060130 0x00000020 0x000FFFFF
ath10k_pci 0000:03:00.0: [08]: 0x00427D80 0x00000003 0x00000000 0x00401C3C
ath10k_pci 0000:03:00.0: [12]: 0x00000009 0xFFFFFFFF 0x00958360 0x0095836B
ath10k_pci 0000:03:00.0: [16]: 0x00958080 0x0094085D 0x00000000 0x00000000
ath10k_pci 0000:03:00.0: [20]: 0x4099901F 0x0040AA94 0x00000001 0x00100000
ath10k_pci 0000:03:00.0: [24]: 0x80996254 0x0040AAF4 0x00409418 0xC099901F
ath10k_pci 0000:03:00.0: [28]: 0x8099A4BD 0x0040AB44 0x00427D80 0x00439BC0
ath10k_pci 0000:03:00.0: [32]: 0x8099A62C 0x0040ACE4 0x00000000 0x0042E648
ath10k_pci 0000:03:00.0: [36]: 0x8099A5BC 0x0040AD14 0x00000002 0x0042E648
ath10k_pci 0000:03:00.0: [40]: 0x8099A7AC 0x0040AD44 0x00439BC0 0x0042E648
ath10k_pci 0000:03:00.0: [44]: 0x8099885F 0x0040AD64 0x00439BC0 0x00000002
ath10k_pci 0000:03:00.0: [48]: 0x8099AF6D 0x0040AD84 0x0042066C 0x0042621C
ath10k_pci 0000:03:00.0: [52]: 0x809BF051 0x0040AEE4 0x00424D5C 0x00000002
ath10k_pci 0000:03:00.0: [56]: 0x80940F18 0x0040AF14 0x00000005 0x004039E4
ath10k_pci 0000:03:00.0: Copy Engine register dump:
ath10k_pci 0000:03:00.0: [00]: 0x00057400 1 1 3 3
ath10k_pci 0000:03:00.0: [01]: 0x00057800 14 14 241 242
ath10k_pci 0000:03:00.0: [02]: 0x00057c00 56 56 55 56
ath10k_pci 0000:03:00.0: [03]: 0x00058000 12 12 14 12
ath10k_pci 0000:03:00.0: [04]: 0x00058400 24 24 62 22
ath10k_pci 0000:03:00.0: [05]: 0x00058800 7 7 326 327
ath10k_pci 0000:03:00.0: [06]: 0x00058c00 19 19 19 19
ath10k_pci 0000:03:00.0: [07]: 0x00059000 0 0 0 0
phy0ap.sta1: Failed check-sdata-in-driver check, flags: 0x0
------------[ cut here ]------------
WARNING: CPU: 1 PID: 30409 at net/mac80211/driver-ops.h:18
ieee80211_assign_chanctx.part.16+0x15e/0x170 [mac80211]
Modules linked in: ath10k_pci ath10k_core ath mac80211 cfg80211 3ebridge(O)
nfnetlink_queue nfnetlink_log nfnetlink bluetooth ecdh_generic rfkill ipv6
fuse hid_generic usbhid hid i2c_dev dell_wmi dell_smbios sparse_keymap
gpio_ich wmi_bmof ppdev evdev dcdbas snd_hda_codec_analog snd_hda_codec_generic
coretemp snd_hda_intel snd_hda_codec snd_hda_core snd_hwdep snd_pcm kvm_intel
kvm snd_timer hwmon psmouse irqbypass serio_raw snd i915 i2c_i801 uhci_hcd
video drm_kms_helper drm lpc_ich i2c_algo_bit fb_sys_fops syscopyarea
sysfillrect sysimgblt i2c_core ehci_pci e100 mii tpm_tis tpm_tis_core tpm wmi
soundcore parport_pc parport ehci_hcd intel_agp intel_gtt button agpgart
shpchp e1000e acpi_cpufreq loop [last unloaded: cfg80211]
CPU: 1 PID: 30409 Comm: kworker/1:2 Tainted: G W O 4.14.16 #2
Hardware name: Dell Inc. OptiPlex 780 /0C27VV, BIOS A05 08/11/2010
Workqueue: events_freezable ieee80211_restart_work [mac80211]
task: ffff8ed6d13b0c80 task.stack: ffffaec64372c000
RIP: 0010:ieee80211_assign_chanctx.part.16+0x15e/0x170 [mac80211]
RSP: 0018:ffffaec64372fdb0 EFLAGS: 00010282
RAX: 000000000000003c RBX: ffff8ed682380780 RCX: 0000000000000000
RDX: ffff8ed6fd85d130 RSI: ffff8ed6fd855518 RDI: ffff8ed6fd855518
RBP: ffff8ed682380780 R08: 0000000000000001 R09: 0000000000000779
R10: ffff8ed682381560 R11: 0000000000000779 R12: ffff8ed6f5b0e8c0
R13: ffff8ed682381198 R14: ffff8ed6f5b92f58 R15: ffff8ed6f5b0e8c0
FS: 0000000000000000(0000) GS:ffff8ed6fd840000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fe13bcba00a CR3: 000000005d140000 CR4: 00000000000406e0
Call Trace:
ieee80211_reconfig+0xc7f/0x1300 [mac80211]
? try_to_del_timer_sync+0x3d/0x50
ieee80211_restart_work+0x99/0xc0 [mac80211]
process_one_work+0x139/0x400
worker_thread+0x47/0x430
kthread+0xfc/0x130
? process_one_work+0x400/0x400
? kthread_create_on_node+0x40/0x40
ret_from_fork+0x35/0x40
Code: 45 31 e4 e9 46 ff ff ff 49 8b 84 24 00 04 00 00 49 8d b4 24 20 04 00 00 48 c7 c7 70 71 77 c0 48 85 c0 48 0f 45 f0 e8 0d 19 9b df <0f> ff e9 26 ff ff ff 90 66 2e 0f 1f 84 00 00 00 00 00 66 66 66
---[ end trace d5e6e93890bc3ea5 ]---
hostapd.conf
---------------------------------------------------------------------------
interface=phy0ap
bridge=brg0
driver=nl80211
logger_syslog=-1
logger_syslog_level=4
logger_stdout=-1
logger_stdout_level=4
country_code=US
ieee80211d=1
hw_mode=a
wds_sta=1
channel=36
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
beacon_int=200
ap_table_max_size=63
ap_table_expiration_time=300
local_pwr_constraint=3
ieee80211h=1
bssid=04:f0:21:3b:2f:78
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
ssid=4-addr-ap
dtim_period=2
max_num_sta=64
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wmm_enabled=1
ap_max_inactivity=300
ieee80211w=0
ieee8021x=0
#---------end of hostapd.conf---------------------------------------------
wpa_supplicant.conf
#------------------------------------------------------------------------
ctrl_interface=/var/run/wpa_supplicant
network={
ssid="4-addr-ap"
scan_ssid=1
key_mgmt=NONE
}
#---------end of wpa_supplicant.conf------------------------------------
BTW: The Linux distribution should not matter. I use Slackware Linux on the PC
acting as AP because Slackware Linux use exact mainline kernel source
without any patching. Kernel source from kernel.org can be just compiled
and dropped in.
I can also send you the radio card "Intel
^ permalink raw reply
* [PATCH] ath9k: Make sure to zero status.tx_time before reporting TX status
From: Toke Høiland-Jørgensen @ 2019-02-15 16:48 UTC (permalink / raw)
To: make-wifi-fast, linux-wireless; +Cc: Toke Høiland-Jørgensen
Since ath9k reports airtime usage directly using the
ieee80211_report_airtime() callback, it shouldn't also report it using the
tx_time in status. Make sure the field is zeroed before TX status is
reported to avoid spurious airtime being accounted by bits being left over
from earlier uses of the cb.
Fixes: 89cea7493a34 ("ath9k: Switch to mac80211 TXQ scheduling and airtime APIs")
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
drivers/net/wireless/ath/ath9k/xmit.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 06e0c5a6fab6..773d428ff1b0 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2552,6 +2552,9 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
}
tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1;
+
+ /* we report airtime in ath_tx_count_airtime(), don't report twice */
+ tx_info->status.tx_time = 0;
}
static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
--
2.20.1
^ permalink raw reply related
* [RFC/RFT] mac80211: Switch to a virtual time-based airtime scheduler
From: Toke Høiland-Jørgensen @ 2019-02-15 17:05 UTC (permalink / raw)
To: make-wifi-fast, linux-wireless
Cc: Felix Fietkau, Rajkumar Manoharan, Kan Yan,
Toke Høiland-Jørgensen
This switches the airtime scheduler in mac80211 to use a virtual time-based
scheduler instead of the round-robin scheduler used before. This has a
couple of advantages:
- No need to sync up the round-robin scheduler in firmware/hardware with
the round-robin airtime scheduler.
- If several stations are eligible for transmission we can schedule both of
them; no need to hard-block the scheduling rotation until the head of the
queue has used up its quantum.
- The check of whether a station is eligible for transmission becomes
simpler (in ieee80211_txq_may_transmit()).
The drawback is that scheduling becomes slightly more expensive, as we need
to maintain an rbtree of TXQs sorted by virtual time. This means that
ieee80211_register_airtime() becomes O(logN) in the number of currently
scheduled TXQs. However, hopefully this number rarely grows too big (it's
only TXQs currently backlogged, not all associated stations), so it
shouldn't be too big of an issue.
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
---
This is basically the idea I mentioned earlier for a different way to
handle the airtime scheduling.
I've tested it on ath9k, where it achieves the same fairness and
weighing properties as the old scheduler. It would be good if you could
test it on your ath10k setup, Rajkumar; and all of you please comment on
whether you agree that this is better from an API point of view.
net/mac80211/debugfs.c | 49 ++++++++-
net/mac80211/debugfs_sta.c | 16 +--
net/mac80211/ieee80211_i.h | 15 ++-
net/mac80211/main.c | 2 +-
net/mac80211/sta_info.c | 19 +++-
net/mac80211/sta_info.h | 3 +-
net/mac80211/tx.c | 217 ++++++++++++++++++++++++-------------
7 files changed, 225 insertions(+), 96 deletions(-)
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 343ad0a915e4..93b9ed2f9451 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -150,6 +150,47 @@ static const struct file_operations aqm_ops = {
.llseek = default_llseek,
};
+static ssize_t airtime_read(struct file *file,
+ char __user *user_buf,
+ size_t count,
+ loff_t *ppos)
+{
+ struct ieee80211_local *local = file->private_data;
+ char buf[200];
+ u64 v_t[IEEE80211_NUM_ACS];
+ u64 wt[IEEE80211_NUM_ACS];
+ int len = 0, ac;
+
+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+ spin_lock_bh(&local->active_txq_lock[ac]);
+ v_t[ac] = local->airtime_v_t[ac];
+ wt[ac] = local->airtime_weight_sum[ac];
+ spin_unlock_bh(&local->active_txq_lock[ac]);
+ }
+ len = scnprintf(buf, sizeof(buf),
+ "\tVO VI BE BK\n"
+ "Virt-t\t%-10llu %-10llu %-10llu %-10llu\n"
+ "Weight\t%-10llu %-10llu %-10llu %-10llu\n",
+ v_t[0],
+ v_t[1],
+ v_t[2],
+ v_t[3],
+ wt[0],
+ wt[1],
+ wt[2],
+ wt[3]);
+
+ return simple_read_from_buffer(user_buf, count, ppos,
+ buf, len);
+}
+
+static const struct file_operations airtime_ops = {
+ .read = airtime_read,
+ .open = simple_open,
+ .llseek = default_llseek,
+};
+
+
#ifdef CONFIG_PM
static ssize_t reset_write(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
@@ -384,8 +425,12 @@ void debugfs_hw_add(struct ieee80211_local *local)
if (local->ops->wake_tx_queue)
DEBUGFS_ADD_MODE(aqm, 0600);
- debugfs_create_u16("airtime_flags", 0600,
- phyd, &local->airtime_flags);
+ if (wiphy_ext_feature_isset(local->hw.wiphy,
+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) {
+ DEBUGFS_ADD_MODE(airtime, 0600);
+ debugfs_create_u16("airtime_flags", 0600,
+ phyd, &local->airtime_flags);
+ }
statsd = debugfs_create_dir("statistics", phyd);
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 3aa618dcc58e..80028da27b98 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -203,7 +203,7 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
size_t bufsz = 200;
char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
u64 rx_airtime = 0, tx_airtime = 0;
- s64 deficit[IEEE80211_NUM_ACS];
+ u64 v_t[IEEE80211_NUM_ACS];
ssize_t rv;
int ac;
@@ -214,20 +214,20 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
spin_lock_bh(&local->active_txq_lock[ac]);
rx_airtime += sta->airtime[ac].rx_airtime;
tx_airtime += sta->airtime[ac].tx_airtime;
- deficit[ac] = sta->airtime[ac].deficit;
+ v_t[ac] = sta->airtime[ac].v_t;
spin_unlock_bh(&local->active_txq_lock[ac]);
}
p += scnprintf(p, bufsz + buf - p,
"RX: %llu us\nTX: %llu us\nWeight: %u\n"
- "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n",
+ "Virt-T: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n",
rx_airtime,
tx_airtime,
sta->airtime_weight,
- deficit[0],
- deficit[1],
- deficit[2],
- deficit[3]);
+ v_t[0],
+ v_t[1],
+ v_t[2],
+ v_t[3]);
rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
kfree(buf);
@@ -245,7 +245,7 @@ static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
spin_lock_bh(&local->active_txq_lock[ac]);
sta->airtime[ac].rx_airtime = 0;
sta->airtime[ac].tx_airtime = 0;
- sta->airtime[ac].deficit = sta->airtime_weight;
+ sta->airtime[ac].v_t = 0;
spin_unlock_bh(&local->active_txq_lock[ac]);
}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 056b16bce3b0..994a70ee0ec0 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -840,8 +840,7 @@ struct txq_info {
struct codel_vars def_cvars;
struct codel_stats cstats;
struct sk_buff_head frags;
- struct list_head schedule_order;
- u16 schedule_round;
+ struct rb_node schedule_order;
unsigned long flags;
/* keep last! */
@@ -1135,8 +1134,10 @@ struct ieee80211_local {
/* protects active_txqs and txqi->schedule_order */
spinlock_t active_txq_lock[IEEE80211_NUM_ACS];
- struct list_head active_txqs[IEEE80211_NUM_ACS];
- u16 schedule_round[IEEE80211_NUM_ACS];
+ struct rb_root_cached active_txqs[IEEE80211_NUM_ACS];
+ struct rb_node *schedule_pos[IEEE80211_NUM_ACS];
+ u64 airtime_v_t[IEEE80211_NUM_ACS];
+ u64 airtime_weight_sum[IEEE80211_NUM_ACS];
u16 airtime_flags;
@@ -1765,6 +1766,12 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
const u8 *buf, size_t len,
const u8 *dest, __be16 proto, bool unencrypted);
+void ieee80211_resort_txq(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq);
+void ieee80211_unschedule_txq(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq);
+
+
/* HT */
void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
struct ieee80211_sta_ht_cap *ht_cap);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 71005b6dfcd1..f207bc284921 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -666,7 +666,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
spin_lock_init(&local->queue_stop_reason_lock);
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
- INIT_LIST_HEAD(&local->active_txqs[i]);
+ local->active_txqs[i] = RB_ROOT_CACHED;
spin_lock_init(&local->active_txq_lock[i]);
}
local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 11f058987a54..9d01fdd86e2d 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -389,7 +389,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
skb_queue_head_init(&sta->ps_tx_buf[i]);
skb_queue_head_init(&sta->tx_filtered[i]);
- sta->airtime[i].deficit = sta->airtime_weight;
}
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
@@ -1831,18 +1830,32 @@ void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
{
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
struct ieee80211_local *local = sta->sdata->local;
+ struct ieee80211_txq *txq = sta->sta.txq[tid];
u8 ac = ieee80211_ac_from_tid(tid);
- u32 airtime = 0;
+ u64 airtime = 0, weight_sum;
+
+ if (!txq)
+ return;
if (sta->local->airtime_flags & AIRTIME_USE_TX)
airtime += tx_airtime;
if (sta->local->airtime_flags & AIRTIME_USE_RX)
airtime += rx_airtime;
+ /* Weights scale so the unit weight is 256 */
+ airtime <<= 8;
+
spin_lock_bh(&local->active_txq_lock[ac]);
+
sta->airtime[ac].tx_airtime += tx_airtime;
sta->airtime[ac].rx_airtime += rx_airtime;
- sta->airtime[ac].deficit -= airtime;
+
+ weight_sum = local->airtime_weight_sum[ac] ?: sta->airtime_weight;
+
+ local->airtime_v_t[ac] += airtime / weight_sum;
+ sta->airtime[ac].v_t += airtime / sta->airtime_weight;
+ ieee80211_resort_txq(&local->hw, txq);
+
spin_unlock_bh(&local->active_txq_lock[ac]);
}
EXPORT_SYMBOL(ieee80211_sta_register_airtime);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 05647d835894..4b901a2a998e 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -130,11 +130,12 @@ enum ieee80211_agg_stop_reason {
/* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */
#define AIRTIME_USE_TX BIT(0)
#define AIRTIME_USE_RX BIT(1)
+#define AIRTIME_GRACE 500 /* usec of grace period before reset */
struct airtime_info {
u64 rx_airtime;
u64 tx_airtime;
- s64 deficit;
+ u64 v_t;
};
struct sta_info;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 61c7ea9de2cc..8e125df8ade0 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1449,7 +1449,7 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
codel_vars_init(&txqi->def_cvars);
codel_stats_init(&txqi->cstats);
__skb_queue_head_init(&txqi->frags);
- INIT_LIST_HEAD(&txqi->schedule_order);
+ RB_CLEAR_NODE(&txqi->schedule_order);
txqi->txq.vif = &sdata->vif;
@@ -1493,9 +1493,7 @@ void ieee80211_txq_purge(struct ieee80211_local *local,
ieee80211_purge_tx_queue(&local->hw, &txqi->frags);
spin_unlock_bh(&fq->lock);
- spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]);
- list_del_init(&txqi->schedule_order);
- spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]);
+ ieee80211_unschedule_txq(&local->hw, &txqi->txq);
}
void ieee80211_txq_set_params(struct ieee80211_local *local)
@@ -3640,126 +3638,191 @@ EXPORT_SYMBOL(ieee80211_tx_dequeue);
struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
{
struct ieee80211_local *local = hw_to_local(hw);
+ struct rb_node *node = local->schedule_pos[ac];
struct txq_info *txqi = NULL;
+ bool first = false;
lockdep_assert_held(&local->active_txq_lock[ac]);
- begin:
- txqi = list_first_entry_or_null(&local->active_txqs[ac],
- struct txq_info,
- schedule_order);
- if (!txqi)
+ if (!node) {
+ node = rb_first_cached(&local->active_txqs[ac]);
+ first = true;
+ } else
+ node = rb_next(node);
+
+ if (!node)
return NULL;
+ txqi = container_of(node, struct txq_info, schedule_order);
+
if (txqi->txq.sta) {
struct sta_info *sta = container_of(txqi->txq.sta,
struct sta_info, sta);
- if (sta->airtime[txqi->txq.ac].deficit < 0) {
- sta->airtime[txqi->txq.ac].deficit +=
- sta->airtime_weight;
- list_move_tail(&txqi->schedule_order,
- &local->active_txqs[txqi->txq.ac]);
- goto begin;
+ if (sta->airtime[ac].v_t > local->airtime_v_t[ac]) {
+ if (first)
+ local->airtime_v_t[ac] = sta->airtime[ac].v_t;
+ else
+ return NULL;
}
}
- if (txqi->schedule_round == local->schedule_round[ac])
- return NULL;
-
- list_del_init(&txqi->schedule_order);
- txqi->schedule_round = local->schedule_round[ac];
+ local->schedule_pos[ac] = node;
return &txqi->txq;
}
EXPORT_SYMBOL(ieee80211_next_txq);
-void ieee80211_return_txq(struct ieee80211_hw *hw,
+static void __ieee80211_insert_txq(struct rb_root_cached *root,
+ struct txq_info *txqi, u8 ac)
+{
+ struct rb_node **new = &root->rb_root.rb_node;
+ struct rb_node *parent = NULL;
+ struct txq_info *__txqi;
+ bool leftmost = true;
+
+ while (*new) {
+ parent = *new;
+ __txqi = rb_entry(parent, struct txq_info, schedule_order);
+
+ if (!txqi->txq.sta) {
+ /* new txqi has no sta - insert to the left */
+ new = &parent->rb_left;
+ } else if (!__txqi->txq.sta) {
+ /* existing txqi has no sta - insert to the right */
+ new = &parent->rb_right;
+ leftmost = false;
+ } else {
+ struct sta_info *old_sta = container_of(__txqi->txq.sta,
+ struct sta_info,
+ sta);
+ struct sta_info *new_sta = container_of(txqi->txq.sta,
+ struct sta_info,
+ sta);
+
+ if (new_sta->airtime[ac].v_t <= old_sta->airtime[ac].v_t)
+ new = &parent->rb_left;
+ else {
+ new = &parent->rb_right;
+ leftmost = false;
+ }
+
+ }
+ }
+
+ rb_link_node(&txqi->schedule_order, parent, new);
+ rb_insert_color_cached(&txqi->schedule_order, root, leftmost);
+}
+
+void ieee80211_schedule_txq(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq)
+ __acquires(txq_lock) __releases(txq_lock)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+ struct txq_info *txqi = to_txq_info(txq);
+ u8 ac = txq->ac;
+
+ spin_lock_bh(&local->active_txq_lock[ac]);
+
+ if (!RB_EMPTY_NODE(&txqi->schedule_order))
+ goto out;
+
+ if (txq->sta) {
+ struct sta_info *sta = container_of(txq->sta,
+ struct sta_info, sta);
+
+ local->airtime_weight_sum[ac] += sta->airtime_weight;
+ if (local->airtime_v_t[ac] > AIRTIME_GRACE)
+ sta->airtime[ac].v_t = max(local->airtime_v_t[ac] - AIRTIME_GRACE,
+ sta->airtime[ac].v_t);
+ }
+
+ __ieee80211_insert_txq(&local->active_txqs[ac], txqi, ac);
+
+ out:
+ spin_unlock_bh(&local->active_txq_lock[ac]);
+}
+EXPORT_SYMBOL(ieee80211_schedule_txq);
+
+void ieee80211_resort_txq(struct ieee80211_hw *hw,
struct ieee80211_txq *txq)
{
struct ieee80211_local *local = hw_to_local(hw);
struct txq_info *txqi = to_txq_info(txq);
+ u8 ac = txq->ac;
+
+ if (!RB_EMPTY_NODE(&txqi->schedule_order)) {
+ rb_erase_cached(&txqi->schedule_order,
+ &local->active_txqs[ac]);
+ RB_CLEAR_NODE(&txqi->schedule_order);
+ __ieee80211_insert_txq(&local->active_txqs[ac], txqi, ac);
+ }
+}
+
+static void __ieee80211_unschedule_txq(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+ struct txq_info *txqi = to_txq_info(txq);
+ u8 ac = txq->ac;
lockdep_assert_held(&local->active_txq_lock[txq->ac]);
- if (list_empty(&txqi->schedule_order) &&
- (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) {
- /* If airtime accounting is active, always enqueue STAs at the
- * head of the list to ensure that they only get moved to the
- * back by the airtime DRR scheduler once they have a negative
- * deficit. A station that already has a negative deficit will
- * get immediately moved to the back of the list on the next
- * call to ieee80211_next_txq().
- */
- if (txqi->txq.sta &&
- wiphy_ext_feature_isset(local->hw.wiphy,
- NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
- list_add(&txqi->schedule_order,
- &local->active_txqs[txq->ac]);
- else
- list_add_tail(&txqi->schedule_order,
- &local->active_txqs[txq->ac]);
+ if (RB_EMPTY_NODE(&txqi->schedule_order))
+ return;
+
+ if (txq->sta) {
+ struct sta_info *sta = container_of(txq->sta,
+ struct sta_info, sta);
+
+ local->airtime_weight_sum[ac] -= sta->airtime_weight;
}
+
+ rb_erase_cached(&txqi->schedule_order,
+ &local->active_txqs[txq->ac]);
+ RB_CLEAR_NODE(&txqi->schedule_order);
}
-EXPORT_SYMBOL(ieee80211_return_txq);
-void ieee80211_schedule_txq(struct ieee80211_hw *hw,
- struct ieee80211_txq *txq)
+void ieee80211_unschedule_txq(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq)
__acquires(txq_lock) __releases(txq_lock)
{
struct ieee80211_local *local = hw_to_local(hw);
spin_lock_bh(&local->active_txq_lock[txq->ac]);
- ieee80211_return_txq(hw, txq);
+ __ieee80211_unschedule_txq(hw, txq);
spin_unlock_bh(&local->active_txq_lock[txq->ac]);
}
-EXPORT_SYMBOL(ieee80211_schedule_txq);
+
+void ieee80211_return_txq(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+ struct txq_info *txqi = to_txq_info(txq);
+
+ lockdep_assert_held(&local->active_txq_lock[txq->ac]);
+
+ if (!RB_EMPTY_NODE(&txqi->schedule_order) &&
+ (skb_queue_empty(&txqi->frags) && !txqi->tin.backlog_packets))
+ __ieee80211_unschedule_txq(hw, txq);
+}
+EXPORT_SYMBOL(ieee80211_return_txq);
bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
struct ieee80211_txq *txq)
{
struct ieee80211_local *local = hw_to_local(hw);
- struct txq_info *iter, *tmp, *txqi = to_txq_info(txq);
+ struct txq_info *txqi = to_txq_info(txq);
struct sta_info *sta;
u8 ac = txq->ac;
lockdep_assert_held(&local->active_txq_lock[ac]);
if (!txqi->txq.sta)
- goto out;
-
- if (list_empty(&txqi->schedule_order))
- goto out;
-
- list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
- schedule_order) {
- if (iter == txqi)
- break;
-
- if (!iter->txq.sta) {
- list_move_tail(&iter->schedule_order,
- &local->active_txqs[ac]);
- continue;
- }
- sta = container_of(iter->txq.sta, struct sta_info, sta);
- if (sta->airtime[ac].deficit < 0)
- sta->airtime[ac].deficit += sta->airtime_weight;
- list_move_tail(&iter->schedule_order, &local->active_txqs[ac]);
- }
+ return true;
sta = container_of(txqi->txq.sta, struct sta_info, sta);
- if (sta->airtime[ac].deficit >= 0)
- goto out;
-
- sta->airtime[ac].deficit += sta->airtime_weight;
- list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]);
-
- return false;
-out:
- if (!list_empty(&txqi->schedule_order))
- list_del_init(&txqi->schedule_order);
-
- return true;
+ return (sta->airtime[ac].v_t <= local->airtime_v_t[ac]);
}
EXPORT_SYMBOL(ieee80211_txq_may_transmit);
@@ -3769,7 +3832,6 @@ void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
struct ieee80211_local *local = hw_to_local(hw);
spin_lock_bh(&local->active_txq_lock[ac]);
- local->schedule_round[ac]++;
}
EXPORT_SYMBOL(ieee80211_txq_schedule_start);
@@ -3778,6 +3840,7 @@ void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
{
struct ieee80211_local *local = hw_to_local(hw);
+ local->schedule_pos[ac] = NULL;
spin_unlock_bh(&local->active_txq_lock[ac]);
}
EXPORT_SYMBOL(ieee80211_txq_schedule_end);
--
2.20.1
^ permalink raw reply related
* [PATCH] cfg80211/nl80211: Offload OWE processing to user space in AP mode
From: Srinivas Dasari @ 2019-02-15 19:14 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Sunil Dutt, Liangwei Dong, Srinivas Dasari
From: Sunil Dutt <usdutt@codeaurora.org>
This interface allows the host driver to offload OWE processing
to user space. This intends to support OWE (Opportunistic Wireless
Encryption) AKM by the drivers that implement SME but rely on the
user space for the cryptographic/OWE processing in AP mode. Such
drivers are not capable of processing/deriving the DH IE.
A new NL80211 command - NL80211_CMD_UPDATE_OWE_INFO is introduced
to send the request/event between the host driver and user space.
The driver shall use the event to notify the OWE info of the peer
to the user space for the cryptographic processing of the DH IE.
Accordingly, the user space shall update the OWE info/DH IE to
the driver.
Following is the sequence in AP mode for OWE authentication.
Driver passes the OWE info obtained from the peer in the
Association Request to the user space through the event
cfg80211_update_owe_info_event. User space shall process the
OWE info received and generate new OWE info. This OWE info is
passed to the driver through NL80211_CMD_UPDATE_OWE_INFO
request. Driver eventually uses this OWE info to send the
Association Response to the peer.
This OWE info in the command interface carries the IEs that include
PMKID of the peer if the PMKSA is still valid or an updated DH IE
for generating a new PMKSA with the peer.
Signed-off-by: Liangwei Dong <liangwei@codeaurora.org>
Signed-off-by: Sunil Dutt <usdutt@codeaurora.org>
Signed-off-by: Srinivas Dasari <dasaris@codeaurora.org>
---
include/net/cfg80211.h | 42 ++++++++++++++++++++++++++
include/uapi/linux/nl80211.h | 7 +++++
net/wireless/nl80211.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
net/wireless/rdev-ops.h | 13 ++++++++
net/wireless/trace.h | 38 +++++++++++++++++++++++
5 files changed, 172 insertions(+)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f81677f..9a314ee 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3100,6 +3100,32 @@ struct cfg80211_pmsr_request {
};
/**
+ * struct cfg80211_update_owe_info - OWE Information
+ *
+ * This structure provides information needed for the drivers to offload OWE
+ * (Opportunistic Wireless Encryption) processing to the user space.
+ *
+ * Commonly used across update_owe_info request and event interfaces.
+ *
+ * @peer: MAC address of the peer device for which the OWE processing
+ * has to be done.
+ * @status: status code, %WLAN_STATUS_SUCCESS for successful OWE info
+ * processing, use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space
+ * cannot give you the real status code for failures. Used only for
+ * OWE update request command interface (user space to driver).
+ * @ie: IEs obtained from the peer or constructed by the user space. These are
+ * the IEs of the remote peer in the event from the host driver and
+ * the constructed IEs by the user space in the request interface.
+ * @ie_len: Length of IEs in octets.
+ */
+struct cfg80211_update_owe_info {
+ u8 peer[ETH_ALEN] __aligned(2);
+ u16 status;
+ const u8 *ie;
+ size_t ie_len;
+};
+
+/**
* struct cfg80211_ops - backend description for wireless configuration
*
* This struct is registered by fullmac card drivers and/or wireless stacks
@@ -3436,6 +3462,10 @@ struct cfg80211_pmsr_request {
* Statistics should be cumulative, currently no way to reset is provided.
* @start_pmsr: start peer measurement (e.g. FTM)
* @abort_pmsr: abort peer measurement
+ *
+ * @update_owe_info: Provide updated OWE info to driver. Driver implementing SME
+ * but offloading OWE processing to the user space will get the updated
+ * DH IE through this interface.
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3750,6 +3780,8 @@ struct cfg80211_ops {
struct cfg80211_pmsr_request *request);
void (*abort_pmsr)(struct wiphy *wiphy, struct wireless_dev *wdev,
struct cfg80211_pmsr_request *request);
+ int (*update_owe_info)(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_update_owe_info *owe_info);
};
/*
@@ -7160,4 +7192,14 @@ void cfg80211_pmsr_complete(struct wireless_dev *wdev,
#define wiphy_WARN(wiphy, format, args...) \
WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args);
+/**
+ * cfg80211_update_owe_info_event - Notify the peer's OWE info to user space
+ * @netdev: network device
+ * @owe_info: peer's owe info
+ * @gfp: allocation flags
+ */
+void cfg80211_update_owe_info_event(struct net_device *netdev,
+ struct cfg80211_update_owe_info *owe_info,
+ gfp_t gfp);
+
#endif /* __NET_CFG80211_H */
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index dd4f86e..26aa319 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1065,6 +1065,11 @@
* indicated by %NL80211_ATTR_WIPHY_FREQ and other attributes
* determining the width and type.
*
+ * @NL80211_CMD_UPDATE_OWE_INFO: This interface allows the host driver to
+ * offload OWE processing to user space. This intends to support
+ * OWE AKM by the host drivers that implement SME but rely
+ * on the user space for the cryptographic/DH IE processing in AP mode.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -1285,6 +1290,8 @@ enum nl80211_commands {
NL80211_CMD_NOTIFY_RADAR,
+ NL80211_CMD_UPDATE_OWE_INFO,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 80878b4..2fe0421 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -13241,6 +13241,31 @@ static int nl80211_get_ftm_responder_stats(struct sk_buff *skb,
return -ENOBUFS;
}
+static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
+ struct cfg80211_update_owe_info owe_info;
+ struct net_device *dev = info->user_ptr[1];
+
+ if (!rdev->ops->update_owe_info)
+ return -EOPNOTSUPP;
+
+ if (!info->attrs[NL80211_ATTR_STATUS_CODE] ||
+ !info->attrs[NL80211_ATTR_MAC])
+ return -EINVAL;
+
+ memset(&owe_info, 0, sizeof(owe_info));
+ owe_info.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
+ nla_memcpy(owe_info.peer, info->attrs[NL80211_ATTR_MAC], ETH_ALEN);
+
+ if (info->attrs[NL80211_ATTR_IE]) {
+ owe_info.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+ owe_info.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+ }
+
+ return rdev_update_owe_info(rdev, dev, &owe_info);
+}
+
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
@@ -14175,6 +14200,14 @@ static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
NL80211_FLAG_NEED_RTNL,
},
+ {
+ .cmd = NL80211_CMD_UPDATE_OWE_INFO,
+ .doit = nl80211_update_owe_info,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
};
static struct genl_family nl80211_fam __ro_after_init = {
@@ -16340,6 +16373,45 @@ int cfg80211_external_auth_request(struct net_device *dev,
}
EXPORT_SYMBOL(cfg80211_external_auth_request);
+void cfg80211_update_owe_info_event(struct net_device *netdev,
+ struct cfg80211_update_owe_info *owe_info,
+ gfp_t gfp)
+{
+ struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+ struct sk_buff *msg;
+ void *hdr;
+
+ trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+ if (!msg)
+ return;
+
+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
+ if (!hdr)
+ goto nla_put_failure;
+
+ if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+ nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
+ nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->peer))
+ goto nla_put_failure;
+
+ if (nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
+ goto nla_put_failure;
+
+ genlmsg_end(msg, hdr);
+
+ genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+ NL80211_MCGRP_MLME, gfp);
+ return;
+
+nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_update_owe_info_event);
+
/* initialisation/exit functions */
int __init nl80211_init(void)
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 5cb48d1..c1e3210 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -1272,4 +1272,17 @@ static inline int rdev_del_pmk(struct cfg80211_registered_device *rdev,
trace_rdev_return_void(&rdev->wiphy);
}
+static inline int rdev_update_owe_info(struct cfg80211_registered_device *rdev,
+ struct net_device *dev,
+ struct cfg80211_update_owe_info *oweinfo)
+{
+ int ret = -EOPNOTSUPP;
+
+ trace_rdev_update_owe_info(&rdev->wiphy, dev, oweinfo);
+ if (rdev->ops->update_owe_info)
+ ret = rdev->ops->update_owe_info(&rdev->wiphy, dev, oweinfo);
+ trace_rdev_return_int(&rdev->wiphy, ret);
+ return ret;
+}
+
#endif /* __CFG80211_RDEV_OPS */
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 44b2ce1..2dda529 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -3362,6 +3362,44 @@
WIPHY_PR_ARG, WDEV_PR_ARG,
(unsigned long long)__entry->cookie)
);
+
+TRACE_EVENT(rdev_update_owe_info,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_update_owe_info *owe_info),
+ TP_ARGS(wiphy, netdev, owe_info),
+ TP_STRUCT__entry(WIPHY_ENTRY
+ NETDEV_ENTRY
+ MAC_ENTRY(peer)
+ __field(u16, status)
+ __dynamic_array(u8, ie, owe_info->ie_len)),
+ TP_fast_assign(WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(peer, owe_info->peer);
+ __entry->status = owe_info->status;
+ memcpy(__get_dynamic_array(ie),
+ owe_info->ie, owe_info->ie_len);),
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT
+ " status %d", WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
+ __entry->status)
+);
+
+TRACE_EVENT(cfg80211_update_owe_info_event,
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_update_owe_info *owe_info),
+ TP_ARGS(wiphy, netdev, owe_info),
+ TP_STRUCT__entry(WIPHY_ENTRY
+ NETDEV_ENTRY
+ MAC_ENTRY(peer)
+ __dynamic_array(u8, ie, owe_info->ie_len)),
+ TP_fast_assign(WIPHY_ASSIGN;
+ NETDEV_ASSIGN;
+ MAC_ASSIGN(peer, owe_info->peer);
+ memcpy(__get_dynamic_array(ie), owe_info->ie,
+ owe_info->ie_len);),
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT,
+ WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer))
+);
+
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
#undef TRACE_INCLUDE_PATH
--
1.9.1
^ permalink raw reply related
* Re: [Make-wifi-fast] [RFC/RFT] mac80211: Switch to a virtual time-based airtime scheduler
From: Dave Taht @ 2019-02-15 19:44 UTC (permalink / raw)
To: Toke Høiland-Jørgensen
Cc: Make-Wifi-fast, linux-wireless, Kan Yan, Rajkumar Manoharan,
Felix Fietkau
In-Reply-To: <20190215170512.31512-1-toke@redhat.com>
On Fri, Feb 15, 2019 at 9:05 AM Toke Høiland-Jørgensen <toke@redhat.com> wrote:
>
> This switches the airtime scheduler in mac80211 to use a virtual time-based
> scheduler instead of the round-robin scheduler used before. This has a
> couple of advantages:
>
> - No need to sync up the round-robin scheduler in firmware/hardware with
> the round-robin airtime scheduler.
>
> - If several stations are eligible for transmission we can schedule both of
> them; no need to hard-block the scheduling rotation until the head of the
> queue has used up its quantum.
This sounds like this will support some concepts in 802.11ax much better?
Do we have any feedback from ax folk (any platform - qca, intel,
mediatek, broadcom) as to whether this will help?
> - The check of whether a station is eligible for transmission becomes
> simpler (in ieee80211_txq_may_transmit()).
>
> The drawback is that scheduling becomes slightly more expensive, as we need
> to maintain an rbtree of TXQs sorted by virtual time. This means that
> ieee80211_register_airtime() becomes O(logN) in the number of currently
> scheduled TXQs. However, hopefully this number rarely grows too big (it's
> only TXQs currently backlogged, not all associated stations), so it
> shouldn't be too big of an issue.
SGTM.
> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
> ---
> This is basically the idea I mentioned earlier for a different way to
> handle the airtime scheduling.
>
> I've tested it on ath9k, where it achieves the same fairness and
> weighing properties as the old scheduler. It would be good if you could
> test it on your ath10k setup, Rajkumar; and all of you please comment on
> whether you agree that this is better from an API point of view.
>
> net/mac80211/debugfs.c | 49 ++++++++-
> net/mac80211/debugfs_sta.c | 16 +--
> net/mac80211/ieee80211_i.h | 15 ++-
> net/mac80211/main.c | 2 +-
> net/mac80211/sta_info.c | 19 +++-
> net/mac80211/sta_info.h | 3 +-
> net/mac80211/tx.c | 217 ++++++++++++++++++++++++-------------
> 7 files changed, 225 insertions(+), 96 deletions(-)
>
> diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
> index 343ad0a915e4..93b9ed2f9451 100644
> --- a/net/mac80211/debugfs.c
> +++ b/net/mac80211/debugfs.c
> @@ -150,6 +150,47 @@ static const struct file_operations aqm_ops = {
> .llseek = default_llseek,
> };
>
> +static ssize_t airtime_read(struct file *file,
> + char __user *user_buf,
> + size_t count,
> + loff_t *ppos)
> +{
> + struct ieee80211_local *local = file->private_data;
> + char buf[200];
> + u64 v_t[IEEE80211_NUM_ACS];
> + u64 wt[IEEE80211_NUM_ACS];
> + int len = 0, ac;
> +
> + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
> + spin_lock_bh(&local->active_txq_lock[ac]);
> + v_t[ac] = local->airtime_v_t[ac];
> + wt[ac] = local->airtime_weight_sum[ac];
> + spin_unlock_bh(&local->active_txq_lock[ac]);
> + }
> + len = scnprintf(buf, sizeof(buf),
> + "\tVO VI BE BK\n"
> + "Virt-t\t%-10llu %-10llu %-10llu %-10llu\n"
> + "Weight\t%-10llu %-10llu %-10llu %-10llu\n",
> + v_t[0],
> + v_t[1],
> + v_t[2],
> + v_t[3],
> + wt[0],
> + wt[1],
> + wt[2],
> + wt[3]);
> +
> + return simple_read_from_buffer(user_buf, count, ppos,
> + buf, len);
> +}
> +
> +static const struct file_operations airtime_ops = {
> + .read = airtime_read,
> + .open = simple_open,
> + .llseek = default_llseek,
> +};
> +
> +
> #ifdef CONFIG_PM
> static ssize_t reset_write(struct file *file, const char __user *user_buf,
> size_t count, loff_t *ppos)
> @@ -384,8 +425,12 @@ void debugfs_hw_add(struct ieee80211_local *local)
> if (local->ops->wake_tx_queue)
> DEBUGFS_ADD_MODE(aqm, 0600);
>
> - debugfs_create_u16("airtime_flags", 0600,
> - phyd, &local->airtime_flags);
> + if (wiphy_ext_feature_isset(local->hw.wiphy,
> + NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) {
> + DEBUGFS_ADD_MODE(airtime, 0600);
> + debugfs_create_u16("airtime_flags", 0600,
> + phyd, &local->airtime_flags);
> + }
>
> statsd = debugfs_create_dir("statistics", phyd);
>
> diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
> index 3aa618dcc58e..80028da27b98 100644
> --- a/net/mac80211/debugfs_sta.c
> +++ b/net/mac80211/debugfs_sta.c
> @@ -203,7 +203,7 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
> size_t bufsz = 200;
> char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf;
> u64 rx_airtime = 0, tx_airtime = 0;
> - s64 deficit[IEEE80211_NUM_ACS];
> + u64 v_t[IEEE80211_NUM_ACS];
> ssize_t rv;
> int ac;
>
> @@ -214,20 +214,20 @@ static ssize_t sta_airtime_read(struct file *file, char __user *userbuf,
> spin_lock_bh(&local->active_txq_lock[ac]);
> rx_airtime += sta->airtime[ac].rx_airtime;
> tx_airtime += sta->airtime[ac].tx_airtime;
> - deficit[ac] = sta->airtime[ac].deficit;
> + v_t[ac] = sta->airtime[ac].v_t;
> spin_unlock_bh(&local->active_txq_lock[ac]);
> }
>
> p += scnprintf(p, bufsz + buf - p,
> "RX: %llu us\nTX: %llu us\nWeight: %u\n"
> - "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n",
> + "Virt-T: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n",
> rx_airtime,
> tx_airtime,
> sta->airtime_weight,
> - deficit[0],
> - deficit[1],
> - deficit[2],
> - deficit[3]);
> + v_t[0],
> + v_t[1],
> + v_t[2],
> + v_t[3]);
>
> rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
> kfree(buf);
> @@ -245,7 +245,7 @@ static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf,
> spin_lock_bh(&local->active_txq_lock[ac]);
> sta->airtime[ac].rx_airtime = 0;
> sta->airtime[ac].tx_airtime = 0;
> - sta->airtime[ac].deficit = sta->airtime_weight;
> + sta->airtime[ac].v_t = 0;
> spin_unlock_bh(&local->active_txq_lock[ac]);
> }
>
> diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
> index 056b16bce3b0..994a70ee0ec0 100644
> --- a/net/mac80211/ieee80211_i.h
> +++ b/net/mac80211/ieee80211_i.h
> @@ -840,8 +840,7 @@ struct txq_info {
> struct codel_vars def_cvars;
> struct codel_stats cstats;
> struct sk_buff_head frags;
> - struct list_head schedule_order;
> - u16 schedule_round;
> + struct rb_node schedule_order;
> unsigned long flags;
>
> /* keep last! */
> @@ -1135,8 +1134,10 @@ struct ieee80211_local {
>
> /* protects active_txqs and txqi->schedule_order */
> spinlock_t active_txq_lock[IEEE80211_NUM_ACS];
> - struct list_head active_txqs[IEEE80211_NUM_ACS];
> - u16 schedule_round[IEEE80211_NUM_ACS];
> + struct rb_root_cached active_txqs[IEEE80211_NUM_ACS];
> + struct rb_node *schedule_pos[IEEE80211_NUM_ACS];
> + u64 airtime_v_t[IEEE80211_NUM_ACS];
> + u64 airtime_weight_sum[IEEE80211_NUM_ACS];
>
> u16 airtime_flags;
>
> @@ -1765,6 +1766,12 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
> const u8 *buf, size_t len,
> const u8 *dest, __be16 proto, bool unencrypted);
>
> +void ieee80211_resort_txq(struct ieee80211_hw *hw,
> + struct ieee80211_txq *txq);
> +void ieee80211_unschedule_txq(struct ieee80211_hw *hw,
> + struct ieee80211_txq *txq);
> +
> +
> /* HT */
> void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
> struct ieee80211_sta_ht_cap *ht_cap);
> diff --git a/net/mac80211/main.c b/net/mac80211/main.c
> index 71005b6dfcd1..f207bc284921 100644
> --- a/net/mac80211/main.c
> +++ b/net/mac80211/main.c
> @@ -666,7 +666,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
> spin_lock_init(&local->queue_stop_reason_lock);
>
> for (i = 0; i < IEEE80211_NUM_ACS; i++) {
> - INIT_LIST_HEAD(&local->active_txqs[i]);
> + local->active_txqs[i] = RB_ROOT_CACHED;
> spin_lock_init(&local->active_txq_lock[i]);
> }
> local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX;
> diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
> index 11f058987a54..9d01fdd86e2d 100644
> --- a/net/mac80211/sta_info.c
> +++ b/net/mac80211/sta_info.c
> @@ -389,7 +389,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
> for (i = 0; i < IEEE80211_NUM_ACS; i++) {
> skb_queue_head_init(&sta->ps_tx_buf[i]);
> skb_queue_head_init(&sta->tx_filtered[i]);
> - sta->airtime[i].deficit = sta->airtime_weight;
> }
>
> for (i = 0; i < IEEE80211_NUM_TIDS; i++)
> @@ -1831,18 +1830,32 @@ void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid,
> {
> struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
> struct ieee80211_local *local = sta->sdata->local;
> + struct ieee80211_txq *txq = sta->sta.txq[tid];
> u8 ac = ieee80211_ac_from_tid(tid);
> - u32 airtime = 0;
> + u64 airtime = 0, weight_sum;
> +
> + if (!txq)
> + return;
>
> if (sta->local->airtime_flags & AIRTIME_USE_TX)
> airtime += tx_airtime;
> if (sta->local->airtime_flags & AIRTIME_USE_RX)
> airtime += rx_airtime;
>
> + /* Weights scale so the unit weight is 256 */
> + airtime <<= 8;
> +
> spin_lock_bh(&local->active_txq_lock[ac]);
> +
> sta->airtime[ac].tx_airtime += tx_airtime;
> sta->airtime[ac].rx_airtime += rx_airtime;
> - sta->airtime[ac].deficit -= airtime;
> +
> + weight_sum = local->airtime_weight_sum[ac] ?: sta->airtime_weight;
> +
> + local->airtime_v_t[ac] += airtime / weight_sum;
> + sta->airtime[ac].v_t += airtime / sta->airtime_weight;
> + ieee80211_resort_txq(&local->hw, txq);
> +
> spin_unlock_bh(&local->active_txq_lock[ac]);
> }
> EXPORT_SYMBOL(ieee80211_sta_register_airtime);
> diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
> index 05647d835894..4b901a2a998e 100644
> --- a/net/mac80211/sta_info.h
> +++ b/net/mac80211/sta_info.h
> @@ -130,11 +130,12 @@ enum ieee80211_agg_stop_reason {
> /* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */
> #define AIRTIME_USE_TX BIT(0)
> #define AIRTIME_USE_RX BIT(1)
> +#define AIRTIME_GRACE 500 /* usec of grace period before reset */
>
> struct airtime_info {
> u64 rx_airtime;
> u64 tx_airtime;
> - s64 deficit;
> + u64 v_t;
> };
>
> struct sta_info;
> diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
> index 61c7ea9de2cc..8e125df8ade0 100644
> --- a/net/mac80211/tx.c
> +++ b/net/mac80211/tx.c
> @@ -1449,7 +1449,7 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
> codel_vars_init(&txqi->def_cvars);
> codel_stats_init(&txqi->cstats);
> __skb_queue_head_init(&txqi->frags);
> - INIT_LIST_HEAD(&txqi->schedule_order);
> + RB_CLEAR_NODE(&txqi->schedule_order);
>
> txqi->txq.vif = &sdata->vif;
>
> @@ -1493,9 +1493,7 @@ void ieee80211_txq_purge(struct ieee80211_local *local,
> ieee80211_purge_tx_queue(&local->hw, &txqi->frags);
> spin_unlock_bh(&fq->lock);
>
> - spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]);
> - list_del_init(&txqi->schedule_order);
> - spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]);
> + ieee80211_unschedule_txq(&local->hw, &txqi->txq);
> }
>
> void ieee80211_txq_set_params(struct ieee80211_local *local)
> @@ -3640,126 +3638,191 @@ EXPORT_SYMBOL(ieee80211_tx_dequeue);
> struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
> {
> struct ieee80211_local *local = hw_to_local(hw);
> + struct rb_node *node = local->schedule_pos[ac];
> struct txq_info *txqi = NULL;
> + bool first = false;
>
> lockdep_assert_held(&local->active_txq_lock[ac]);
>
> - begin:
> - txqi = list_first_entry_or_null(&local->active_txqs[ac],
> - struct txq_info,
> - schedule_order);
> - if (!txqi)
> + if (!node) {
> + node = rb_first_cached(&local->active_txqs[ac]);
> + first = true;
> + } else
> + node = rb_next(node);
> +
> + if (!node)
> return NULL;
>
> + txqi = container_of(node, struct txq_info, schedule_order);
> +
> if (txqi->txq.sta) {
> struct sta_info *sta = container_of(txqi->txq.sta,
> struct sta_info, sta);
>
> - if (sta->airtime[txqi->txq.ac].deficit < 0) {
> - sta->airtime[txqi->txq.ac].deficit +=
> - sta->airtime_weight;
> - list_move_tail(&txqi->schedule_order,
> - &local->active_txqs[txqi->txq.ac]);
> - goto begin;
> + if (sta->airtime[ac].v_t > local->airtime_v_t[ac]) {
> + if (first)
> + local->airtime_v_t[ac] = sta->airtime[ac].v_t;
> + else
> + return NULL;
> }
> }
>
>
> - if (txqi->schedule_round == local->schedule_round[ac])
> - return NULL;
> -
> - list_del_init(&txqi->schedule_order);
> - txqi->schedule_round = local->schedule_round[ac];
> + local->schedule_pos[ac] = node;
> return &txqi->txq;
> }
> EXPORT_SYMBOL(ieee80211_next_txq);
>
> -void ieee80211_return_txq(struct ieee80211_hw *hw,
> +static void __ieee80211_insert_txq(struct rb_root_cached *root,
> + struct txq_info *txqi, u8 ac)
> +{
> + struct rb_node **new = &root->rb_root.rb_node;
> + struct rb_node *parent = NULL;
> + struct txq_info *__txqi;
> + bool leftmost = true;
> +
> + while (*new) {
> + parent = *new;
> + __txqi = rb_entry(parent, struct txq_info, schedule_order);
> +
> + if (!txqi->txq.sta) {
> + /* new txqi has no sta - insert to the left */
> + new = &parent->rb_left;
> + } else if (!__txqi->txq.sta) {
> + /* existing txqi has no sta - insert to the right */
> + new = &parent->rb_right;
> + leftmost = false;
> + } else {
> + struct sta_info *old_sta = container_of(__txqi->txq.sta,
> + struct sta_info,
> + sta);
> + struct sta_info *new_sta = container_of(txqi->txq.sta,
> + struct sta_info,
> + sta);
> +
> + if (new_sta->airtime[ac].v_t <= old_sta->airtime[ac].v_t)
> + new = &parent->rb_left;
> + else {
> + new = &parent->rb_right;
> + leftmost = false;
> + }
> +
> + }
> + }
> +
> + rb_link_node(&txqi->schedule_order, parent, new);
> + rb_insert_color_cached(&txqi->schedule_order, root, leftmost);
> +}
> +
> +void ieee80211_schedule_txq(struct ieee80211_hw *hw,
> + struct ieee80211_txq *txq)
> + __acquires(txq_lock) __releases(txq_lock)
> +{
> + struct ieee80211_local *local = hw_to_local(hw);
> + struct txq_info *txqi = to_txq_info(txq);
> + u8 ac = txq->ac;
> +
> + spin_lock_bh(&local->active_txq_lock[ac]);
> +
> + if (!RB_EMPTY_NODE(&txqi->schedule_order))
> + goto out;
> +
> + if (txq->sta) {
> + struct sta_info *sta = container_of(txq->sta,
> + struct sta_info, sta);
> +
> + local->airtime_weight_sum[ac] += sta->airtime_weight;
> + if (local->airtime_v_t[ac] > AIRTIME_GRACE)
> + sta->airtime[ac].v_t = max(local->airtime_v_t[ac] - AIRTIME_GRACE,
> + sta->airtime[ac].v_t);
> + }
> +
> + __ieee80211_insert_txq(&local->active_txqs[ac], txqi, ac);
> +
> + out:
> + spin_unlock_bh(&local->active_txq_lock[ac]);
> +}
> +EXPORT_SYMBOL(ieee80211_schedule_txq);
> +
> +void ieee80211_resort_txq(struct ieee80211_hw *hw,
> struct ieee80211_txq *txq)
> {
> struct ieee80211_local *local = hw_to_local(hw);
> struct txq_info *txqi = to_txq_info(txq);
> + u8 ac = txq->ac;
> +
> + if (!RB_EMPTY_NODE(&txqi->schedule_order)) {
> + rb_erase_cached(&txqi->schedule_order,
> + &local->active_txqs[ac]);
> + RB_CLEAR_NODE(&txqi->schedule_order);
> + __ieee80211_insert_txq(&local->active_txqs[ac], txqi, ac);
> + }
> +}
> +
> +static void __ieee80211_unschedule_txq(struct ieee80211_hw *hw,
> + struct ieee80211_txq *txq)
> +{
> + struct ieee80211_local *local = hw_to_local(hw);
> + struct txq_info *txqi = to_txq_info(txq);
> + u8 ac = txq->ac;
>
> lockdep_assert_held(&local->active_txq_lock[txq->ac]);
>
> - if (list_empty(&txqi->schedule_order) &&
> - (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) {
> - /* If airtime accounting is active, always enqueue STAs at the
> - * head of the list to ensure that they only get moved to the
> - * back by the airtime DRR scheduler once they have a negative
> - * deficit. A station that already has a negative deficit will
> - * get immediately moved to the back of the list on the next
> - * call to ieee80211_next_txq().
> - */
> - if (txqi->txq.sta &&
> - wiphy_ext_feature_isset(local->hw.wiphy,
> - NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
> - list_add(&txqi->schedule_order,
> - &local->active_txqs[txq->ac]);
> - else
> - list_add_tail(&txqi->schedule_order,
> - &local->active_txqs[txq->ac]);
> + if (RB_EMPTY_NODE(&txqi->schedule_order))
> + return;
> +
> + if (txq->sta) {
> + struct sta_info *sta = container_of(txq->sta,
> + struct sta_info, sta);
> +
> + local->airtime_weight_sum[ac] -= sta->airtime_weight;
> }
> +
> + rb_erase_cached(&txqi->schedule_order,
> + &local->active_txqs[txq->ac]);
> + RB_CLEAR_NODE(&txqi->schedule_order);
> }
> -EXPORT_SYMBOL(ieee80211_return_txq);
>
> -void ieee80211_schedule_txq(struct ieee80211_hw *hw,
> - struct ieee80211_txq *txq)
> +void ieee80211_unschedule_txq(struct ieee80211_hw *hw,
> + struct ieee80211_txq *txq)
> __acquires(txq_lock) __releases(txq_lock)
> {
> struct ieee80211_local *local = hw_to_local(hw);
>
> spin_lock_bh(&local->active_txq_lock[txq->ac]);
> - ieee80211_return_txq(hw, txq);
> + __ieee80211_unschedule_txq(hw, txq);
> spin_unlock_bh(&local->active_txq_lock[txq->ac]);
> }
> -EXPORT_SYMBOL(ieee80211_schedule_txq);
> +
> +void ieee80211_return_txq(struct ieee80211_hw *hw,
> + struct ieee80211_txq *txq)
> +{
> + struct ieee80211_local *local = hw_to_local(hw);
> + struct txq_info *txqi = to_txq_info(txq);
> +
> + lockdep_assert_held(&local->active_txq_lock[txq->ac]);
> +
> + if (!RB_EMPTY_NODE(&txqi->schedule_order) &&
> + (skb_queue_empty(&txqi->frags) && !txqi->tin.backlog_packets))
> + __ieee80211_unschedule_txq(hw, txq);
> +}
> +EXPORT_SYMBOL(ieee80211_return_txq);
>
> bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
> struct ieee80211_txq *txq)
> {
> struct ieee80211_local *local = hw_to_local(hw);
> - struct txq_info *iter, *tmp, *txqi = to_txq_info(txq);
> + struct txq_info *txqi = to_txq_info(txq);
> struct sta_info *sta;
> u8 ac = txq->ac;
>
> lockdep_assert_held(&local->active_txq_lock[ac]);
>
> if (!txqi->txq.sta)
> - goto out;
> -
> - if (list_empty(&txqi->schedule_order))
> - goto out;
> -
> - list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
> - schedule_order) {
> - if (iter == txqi)
> - break;
> -
> - if (!iter->txq.sta) {
> - list_move_tail(&iter->schedule_order,
> - &local->active_txqs[ac]);
> - continue;
> - }
> - sta = container_of(iter->txq.sta, struct sta_info, sta);
> - if (sta->airtime[ac].deficit < 0)
> - sta->airtime[ac].deficit += sta->airtime_weight;
> - list_move_tail(&iter->schedule_order, &local->active_txqs[ac]);
> - }
> + return true;
>
> sta = container_of(txqi->txq.sta, struct sta_info, sta);
> - if (sta->airtime[ac].deficit >= 0)
> - goto out;
> -
> - sta->airtime[ac].deficit += sta->airtime_weight;
> - list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]);
> -
> - return false;
> -out:
> - if (!list_empty(&txqi->schedule_order))
> - list_del_init(&txqi->schedule_order);
> -
> - return true;
> + return (sta->airtime[ac].v_t <= local->airtime_v_t[ac]);
> }
> EXPORT_SYMBOL(ieee80211_txq_may_transmit);
>
> @@ -3769,7 +3832,6 @@ void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
> struct ieee80211_local *local = hw_to_local(hw);
>
> spin_lock_bh(&local->active_txq_lock[ac]);
> - local->schedule_round[ac]++;
> }
> EXPORT_SYMBOL(ieee80211_txq_schedule_start);
>
> @@ -3778,6 +3840,7 @@ void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
> {
> struct ieee80211_local *local = hw_to_local(hw);
>
> + local->schedule_pos[ac] = NULL;
> spin_unlock_bh(&local->active_txq_lock[ac]);
> }
> EXPORT_SYMBOL(ieee80211_txq_schedule_end);
> --
> 2.20.1
>
> _______________________________________________
> Make-wifi-fast mailing list
> Make-wifi-fast@lists.bufferbloat.net
> https://lists.bufferbloat.net/listinfo/make-wifi-fast
--
Dave Täht
CTO, TekLibre, LLC
http://www.teklibre.com
Tel: 1-831-205-9740
^ permalink raw reply
* Re: pull-request: mac80211 2019-02-15
From: David Miller @ 2019-02-16 3:42 UTC (permalink / raw)
To: johannes; +Cc: netdev, linux-wireless
In-Reply-To: <20190215125146.18856-1-johannes@sipsolutions.net>
From: Johannes Berg <johannes@sipsolutions.net>
Date: Fri, 15 Feb 2019 13:51:45 +0100
> It's clear things are winding down, this is basically just the stuff
> from Herbert that we've been discussing. I threw in a simple error
> path fix, mostly because it's simple :-)
>
> Please pull and let me know if there's any problem.
Ok, pulled, thanks Johannes.
^ permalink raw reply
* Re: [PATCH] cfg80211/nl80211: Offload OWE processing to user space in AP mode
From: Sergey Matyukevich @ 2019-02-16 4:11 UTC (permalink / raw)
To: Srinivas Dasari
Cc: johannes@sipsolutions.net, linux-wireless@vger.kernel.org,
Sunil Dutt, Liangwei Dong
In-Reply-To: <1550258078-13504-1-git-send-email-dasaris@codeaurora.org>
Hi Srinivas,
> include/net/cfg80211.h | 42 ++++++++++++++++++++++++++
> include/uapi/linux/nl80211.h | 7 +++++
> net/wireless/nl80211.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
> net/wireless/rdev-ops.h | 13 ++++++++
> net/wireless/trace.h | 38 +++++++++++++++++++++++
> 5 files changed, 172 insertions(+)
...
> +void cfg80211_update_owe_info_event(struct net_device *netdev,
> + struct cfg80211_update_owe_info *owe_info,
> + gfp_t gfp)
> +{
> + struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
> + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
> + struct sk_buff *msg;
> + void *hdr;
> +
> + trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);
> +
> + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
> + if (!msg)
> + return;
> +
> + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
> + if (!hdr)
> + goto nla_put_failure;
> +
> + if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
> + nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
> + nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->peer))
> + goto nla_put_failure;
> +
> + if (nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
> + goto nla_put_failure;
Maybe worth adding sanity check if IE length is non-zero ?
Reviewed-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
Regards,
Sergey
^ permalink raw reply
* [PATCH net-next] cfg80211: pmsr: use eth_broadcast_addr() to assign broadcast address
From: Mao Wenan @ 2019-02-16 9:47 UTC (permalink / raw)
To: johannes, linux-wireless, kernel-janitors, netdev
This patch is to use eth_broadcast_addr() to assign broadcast address
insetad of memset().
Signed-off-by: Mao Wenan <maowenan@huawei.com>
---
net/wireless/pmsr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c
index de9286703280..21139b82749f 100644
--- a/net/wireless/pmsr.c
+++ b/net/wireless/pmsr.c
@@ -258,7 +258,7 @@ int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info)
} else {
memcpy(req->mac_addr, nla_data(info->attrs[NL80211_ATTR_MAC]),
ETH_ALEN);
- memset(req->mac_addr_mask, 0xff, ETH_ALEN);
+ eth_broadcast_addr(req->mac_addr_mask);
}
idx = 0;
--
2.20.1
^ permalink raw reply related
* Re: [BUG] mt76x0u: Probing issues on Raspberry Pi 3 B+
From: Stefan Wahren @ 2019-02-16 11:05 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: Lorenzo Bianconi, Alan Stern, Felix Fietkau, Doug Anderson,
Minas Harutyunyan, USB list, linux-wireless
In-Reply-To: <20190215071226.GA2372@redhat.com>
Hi Stanislaw,
> Stanislaw Gruszka <sgruszka@redhat.com> hat am 15. Februar 2019 um 08:12 geschrieben:
>
>
> On Thu, Feb 14, 2019 at 10:48:15AM +0100, Stefan Wahren wrote:
> > Hi Stanislaw,
> >
> > Am 14.02.19 um 10:25 schrieb Stanislaw Gruszka:
> > > On Thu, Feb 14, 2019 at 07:49:57AM +0100, Stefan Wahren wrote:
> > >> Hi Stanislaw,
> > >>
> > >>> Stanislaw Gruszka <sgruszka@redhat.com> hat am 12. Februar 2019 um 10:30 geschrieben:
> > >>>
> > >>>
> > >>>
> > >>> In usb_sg_init() urb->num_sgs is set 0 for sg_tablesize = 0 controllers.
> > >>> In mt76 we set urb->num_sgs to 1. I thought it is fine, but now I think
> > >>> this is bug. We can fix that without changing allocation method and
> > >>> still use SG allocation. Attached patch do this, please check if it works
> > >>> on rpi. Patch is on top of your error path fixes.
> > >> your patch didn't apply cleanly to yesterdays next. After some minor manual fixup, i was able to build them and here are the results starting from boot (please ignore the invalid time in the kernel log):
> > >> https://gist.github.com/lategoodbye/33bd5bc75b9fc935faa231bc472defa8
> > > I think this is due to urb->transfer_length and sg[0]->length mismatch,
> > > which should be addressed by my other patch. I'm attaching the patch
> > > rebased on -next with this line integrated, please test.
> > >
> > > But there could be other bug's in mt76-usb SG code.
>
> I found another bug in mt76usb SG code. We set sg->offset bigger than
> PAGE_SIZE that actually make sg point to memory in different page than
> sg->page. Correcting this with another patch that avoid using sg
> mapping with sg->length > PAGE_SIZE, fixed mt76x0u with AMD IOMMU:
> https://bugzilla.kernel.org/show_bug.cgi?id=202241
>
> I'm attaching 3 patches, they should also fix issue on rpi.
> It's also possible that only 2 patches are sufficient:
>
> 0001-mt76usb-do-not-set-urb-num_sgs-to-1-for-non-SG-usb-h.patch
> 0003-mt76usb-do-not-use-compound-head-page-for-SG-I-O.patch
>
> to fix the issue, if doing dma_map_{page,sg} is fine with
> sg->offset == 0 and sg->length bigger than one page.
>
> Please test, thanks.
>
sorry for the delay, but i do this all in my spare time.
The results for your recent patch series are better (no firmware timeout), but still no working wifi and still a warning:
https://gist.github.com/lategoodbye/c4864e446821717419cbe65df07f8d8d
I've identified the reason for the warning in dwc2:
/*
* We assume that DMA is always aligned in non-split
* case or split out case. Warn if not.
*/
WARN_ON_ONCE(hsotg->params.host_dma && (chan->xfer_dma & 0x3));
Btw i can confirm a regression was introduced after 4.19, because in 4.19 there was no firmware timeout but even no working wifi:
Feb 15 19:10:51 raspberrypi kernel: [ 79.818414] usb 1-1.3: new high-speed USB device number 6 using dwc2
Feb 15 19:10:51 raspberrypi kernel: [ 80.178470] usb 1-1.3: reset high-speed USB device number 6 using dwc2
Feb 15 19:10:51 raspberrypi kernel: [ 80.314388] mt76x0 1-1.3:1.0: ASIC revision: 76100002 MAC revision: 76502000
Feb 15 19:10:52 raspberrypi kernel: [ 81.118751] BBP version f000f200
Feb 15 19:10:52 raspberrypi kernel: [ 81.152995] mt76x0 1-1.3:1.0: EEPROM ver:02 fae:01
Feb 15 19:10:52 raspberrypi kernel: [ 81.153232] mt76x0 1-1.3:1.0: EEPROM country region 01 (channels 1-13)
Feb 15 19:10:52 raspberrypi kernel: [ 81.176968] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
Feb 15 19:10:52 raspberrypi kernel: [ 81.178255] usbcore: registered new interface driver mt76x0
Feb 15 19:10:53 raspberrypi kernel: [ 81.578982] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
Stefan
> Stanislaw
^ permalink raw reply
* -Wimplicit-fallthrough not working with ccache
From: Kalle Valo @ 2019-02-16 11:21 UTC (permalink / raw)
To: Gustavo A. R. Silva
Cc: netdev, linux-wireless, linux-kernel, ath10k, David S. Miller,
linux-kbuild
In-Reply-To: <20180613114059.DAC95601D2@smtp.codeaurora.org>
(replying to an old thread but renaming it)
Kalle Valo <kvalo@codeaurora.org> writes:
> "Gustavo A. R. Silva" <gustavo@embeddedor.com> wrote:
>
>> In preparation to enabling -Wimplicit-fallthrough, mark switch cases
>> where we are expecting to fall through.
>>
>> Notice that in this particular case, I replaced "pass through" with
>> a proper "fall through" comment, which is what GCC is expecting
>> to find.
>>
>> Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
>> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
>
> Patch applied to ath-next branch of ath.git, thanks.
>
> f1d270ae10ff ath10k: htt_tx: mark expected switch fall-throughs
Gustavo, I enabled W=1 on my ath10k build checks and it took me a while
to figure out why GCC was warning about fall through annotations missing
even I knew you had fixed them. Finally I figured out that the reason
was ccache, which I need because I work with different branches and need
to recompile the kernel quite often.
If the plan is to enable -Wimplicit-fallthrough by default in the kernel
IMHO this might become an issue, as otherwise people using ccache start
seeing lots of invalid warnings. Apparently CCACHE_COMMENTS=1 will fix
that but my version of ccache doesn't support it, and how would everyone
learn that trick anyway? Or maybe CCACHE_COMMENTS can enabled through
kernel Makefile?
--
Kalle Valo
^ permalink raw reply
* Re: [BUG] mt76x0u: Probing issues on Raspberry Pi 3 B+
From: Stanislaw Gruszka @ 2019-02-16 14:07 UTC (permalink / raw)
To: Stefan Wahren
Cc: Lorenzo Bianconi, Alan Stern, Felix Fietkau, Doug Anderson,
Minas Harutyunyan, USB list, linux-wireless
In-Reply-To: <1411983628.668277.1550315118443@email.ionos.de>
[-- Attachment #1: Type: text/plain, Size: 1064 bytes --]
On Sat, Feb 16, 2019 at 12:05:18PM +0100, Stefan Wahren wrote:
> sorry for the delay, but i do this all in my spare time.
Stefan, thanks for sacrifing your spare time for testing this!
> The results for your recent patch series are better (no firmware timeout), but still no working wifi and still a warning:
> https://gist.github.com/lategoodbye/c4864e446821717419cbe65df07f8d8d
>
> I've identified the reason for the warning in dwc2:
>
> /*
> * We assume that DMA is always aligned in non-split
> * case or split out case. Warn if not.
> */
> WARN_ON_ONCE(hsotg->params.host_dma && (chan->xfer_dma & 0x3));
I think I understand why that happen, we first allocate 1024 mcu
buffer then standard 4096 rx buffers, that couse 4096 buffers are
not contained in single page and need split by dwc2 driver.
Attached patch should fix this, plese test, thanks in advance.
> Btw i can confirm a regression was introduced after 4.19, because in 4.19 there was no firmware timeout but even no working wifi:
You ment 'no working wifi' or 'working wifi'?
Stanislaw
[-- Attachment #2: 0004-mt76usb-allocate-page-contained-rx-buffers.patch --]
[-- Type: text/plain, Size: 5102 bytes --]
From 35dadd09bd3193b33b10f56e0210da680c6d915f Mon Sep 17 00:00:00 2001
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Sat, 16 Feb 2019 14:53:19 +0100
Subject: [PATCH] mt76usb: allocate page contained rx buffers
If we first allocate 1024 bytes buffer and then 4096 bytes
buffer via page_frag_alloc() the second buffer will be crossing
page boundaries what is most likely not appropriate for
dma_map_{sg/page} and make buffer split misalign issues on
dwc2 usb host driver.
Since patch changed arguments of mt76u_buf_alloc() function I also
changed name to indicate it is only used for RX allocation.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 5 ++---
drivers/net/wireless/mediatek/mt76/usb.c | 24 ++++++++++--------------
drivers/net/wireless/mediatek/mt76/usb_mcu.c | 4 +---
3 files changed, 13 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 364f3571c033..9e24f603664a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -364,7 +364,6 @@ enum mt76u_out_ep {
#define MT_SG_MAX_SIZE 8
#define MT_NUM_TX_ENTRIES 256
#define MT_NUM_RX_ENTRIES 128
-#define MCU_RESP_URB_SIZE 1024
struct mt76_usb {
struct mutex usb_ctrl_mtx;
u8 data[32];
@@ -753,8 +752,8 @@ void mt76u_single_wr(struct mt76_dev *dev, const u8 req,
const u16 offset, const u32 val);
int mt76u_init(struct mt76_dev *dev, struct usb_interface *intf);
void mt76u_deinit(struct mt76_dev *dev);
-int mt76u_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf,
- int nsgs, int len, int sglen, gfp_t gfp);
+int mt76u_rx_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf, int nsgs,
+ gfp_t gfp);
void mt76u_buf_free(struct mt76u_buf *buf);
int mt76u_submit_buf(struct mt76_dev *dev, int dir, int index,
struct mt76u_buf *buf, gfp_t gfp,
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index de906f07e85a..472642ef25a4 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -271,11 +271,11 @@ mt76u_set_endpoints(struct usb_interface *intf,
}
static int
-mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf,
- int nsgs, int len, int sglen)
+mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf, int nsgs)
{
struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
struct urb *urb = buf->urb;
+ int sglen = SKB_WITH_OVERHEAD(q->buf_size);
int i;
spin_lock_bh(&q->rx_page_lock);
@@ -284,7 +284,7 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf,
void *data;
int offset;
- data = page_frag_alloc(&q->rx_page, len, GFP_ATOMIC);
+ data = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
if (!data)
break;
@@ -309,8 +309,8 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76u_buf *buf,
return i ? : -ENOMEM;
}
-int mt76u_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf,
- int nsgs, int len, int sglen, gfp_t gfp)
+int mt76u_rx_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf,
+ int nsgs, gfp_t gfp)
{
buf->urb = usb_alloc_urb(0, gfp);
if (!buf->urb)
@@ -325,7 +325,7 @@ int mt76u_buf_alloc(struct mt76_dev *dev, struct mt76u_buf *buf,
buf->dev = dev;
buf->num_sgs = nsgs;
- return mt76u_fill_rx_sg(dev, buf, nsgs, len, sglen);
+ return mt76u_fill_rx_sg(dev, buf, nsgs);
}
void mt76u_buf_free(struct mt76u_buf *buf)
@@ -485,7 +485,7 @@ static void mt76u_rx_tasklet(unsigned long data)
{
struct mt76_dev *dev = (struct mt76_dev *)data;
struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN];
- int err, nsgs, buf_len = q->buf_size;
+ int err, nsgs;
struct mt76u_buf *buf;
rcu_read_lock();
@@ -497,9 +497,7 @@ static void mt76u_rx_tasklet(unsigned long data)
nsgs = mt76u_process_rx_entry(dev, buf->urb);
if (nsgs > 0) {
- err = mt76u_fill_rx_sg(dev, buf, nsgs,
- buf_len,
- SKB_WITH_OVERHEAD(buf_len));
+ err = mt76u_fill_rx_sg(dev, buf, nsgs);
if (err < 0)
break;
}
@@ -556,10 +554,8 @@ static int mt76u_alloc_rx(struct mt76_dev *dev)
}
for (i = 0; i < MT_NUM_RX_ENTRIES; i++) {
- err = mt76u_buf_alloc(dev, &q->entry[i].ubuf,
- nsgs, q->buf_size,
- SKB_WITH_OVERHEAD(q->buf_size),
- GFP_KERNEL);
+ err = mt76u_rx_buf_alloc(dev, &q->entry[i].ubuf, nsgs,
+ GFP_KERNEL);
if (err < 0)
return err;
}
diff --git a/drivers/net/wireless/mediatek/mt76/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/usb_mcu.c
index 036be4163e69..7c43738f5a6e 100644
--- a/drivers/net/wireless/mediatek/mt76/usb_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/usb_mcu.c
@@ -29,9 +29,7 @@ int mt76u_mcu_init_rx(struct mt76_dev *dev)
struct mt76_usb *usb = &dev->usb;
int err;
- err = mt76u_buf_alloc(dev, &usb->mcu.res, 1,
- MCU_RESP_URB_SIZE, MCU_RESP_URB_SIZE,
- GFP_KERNEL);
+ err = mt76u_rx_buf_alloc(dev, &usb->mcu.res, 1, GFP_KERNEL);
if (err < 0)
return err;
--
2.7.5
^ permalink raw reply related
* [PATCH 0/2] remove qid dependency from mt76-core code
From: lorenzo @ 2019-02-16 17:47 UTC (permalink / raw)
To: nbd; +Cc: linux-wireless, sgruszka, ryder.lee, roychl666, Lorenzo Bianconi
From: Lorenzo Bianconi <lorenzo@kernel.org>
Move queue id dependency in driver specific tx queue initialization code
since new chipsets rely on a different tx queue enumeration scheme.
Add the possibility to specify qid in mt76_tx routine
Lorenzo Bianconi (2):
mt76: add qid parameter to mt76_tx signature
mt76: move txq qid dependency in driver specific code
drivers/net/wireless/mediatek/mt76/mac80211.c | 27 +++++++++++-------
drivers/net/wireless/mediatek/mt76/mt76.h | 14 ++++++++--
.../net/wireless/mediatek/mt76/mt76x02_txrx.c | 8 +++++-
.../net/wireless/mediatek/mt76/mt76x02_util.c | 2 ++
drivers/net/wireless/mediatek/mt76/tx.c | 28 +++++--------------
5 files changed, 45 insertions(+), 34 deletions(-)
--
2.20.1
^ permalink raw reply
* [PATCH 1/2] mt76: add qid parameter to mt76_tx signature
From: lorenzo @ 2019-02-16 17:47 UTC (permalink / raw)
To: nbd; +Cc: linux-wireless, sgruszka, ryder.lee, roychl666, Lorenzo Bianconi
In-Reply-To: <cover.1550336347.git.lorenzo@kernel.org>
From: Lorenzo Bianconi <lorenzo@kernel.org>
Add queue id parameter to mt76_tx signature since new chipsets
rely on a different hw queue enumeration
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c | 8 +++++++-
drivers/net/wireless/mediatek/mt76/tx.c | 12 +++---------
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 13f6febc9b0f..53b85042b793 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -645,7 +645,7 @@ int mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb);
void mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
- struct mt76_wcid *wcid, struct sk_buff *skb);
+ struct mt76_wcid *wcid, struct sk_buff *skb, int qid);
void mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq);
void mt76_txq_remove(struct mt76_dev *dev, struct ieee80211_txq *txq);
void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index 94f47248c59f..fcabbd9c25f2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -26,6 +26,7 @@ void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
struct mt76x02_dev *dev = hw->priv;
struct ieee80211_vif *vif = info->control.vif;
struct mt76_wcid *wcid = &dev->mt76.global_wcid;
+ int qid = skb_get_queue_mapping(skb);
if (control->sta) {
struct mt76x02_sta *msta;
@@ -39,7 +40,12 @@ void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
wcid = &mvif->group_wcid;
}
- mt76_tx(&dev->mt76, control->sta, wcid, skb);
+ if (WARN_ON(qid >= MT_TXQ_PSD)) {
+ qid = MT_TXQ_BE;
+ skb_set_queue_mapping(skb, qid);
+ }
+
+ mt76_tx(&dev->mt76, control->sta, wcid, skb, qid);
}
EXPORT_SYMBOL_GPL(mt76x02_tx);
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index ef38e8626da9..3617de2c1325 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -255,19 +255,13 @@ void mt76_tx_complete_skb(struct mt76_dev *dev, struct sk_buff *skb)
}
EXPORT_SYMBOL_GPL(mt76_tx_complete_skb);
-void
-mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
- struct mt76_wcid *wcid, struct sk_buff *skb)
+void mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
+ struct mt76_wcid *wcid, struct sk_buff *skb,
+ int qid)
{
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct mt76_queue *q;
- int qid = skb_get_queue_mapping(skb);
-
- if (WARN_ON(qid >= MT_TXQ_PSD)) {
- qid = MT_TXQ_BE;
- skb_set_queue_mapping(skb, qid);
- }
if (!wcid->tx_rate_set)
ieee80211_get_tx_rates(info->control.vif, sta, skb,
--
2.20.1
^ permalink raw reply related
* [PATCH 2/2] mt76: move txq qid dependency in driver specific code
From: lorenzo @ 2019-02-16 17:47 UTC (permalink / raw)
To: nbd; +Cc: linux-wireless, sgruszka, ryder.lee, roychl666, Lorenzo Bianconi
In-Reply-To: <cover.1550336347.git.lorenzo@kernel.org>
From: Lorenzo Bianconi <lorenzo@kernel.org>
Move queue id dependency in driver specific tx queue initialization code
since new chipsets rely on a different tx queue enumeration scheme
Introduce mt76_sta_init_tx_queue utility routine
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mac80211.c | 27 ++++++++++++-------
drivers/net/wireless/mediatek/mt76/mt76.h | 12 ++++++++-
.../net/wireless/mediatek/mt76/mt76x02_util.c | 2 ++
drivers/net/wireless/mediatek/mt76/tx.c | 16 +++--------
4 files changed, 34 insertions(+), 23 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index c7abf4f54867..3d25b625b8cc 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -644,20 +644,12 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q,
}
EXPORT_SYMBOL_GPL(mt76_rx_poll_complete);
-static int
-mt76_sta_add(struct mt76_dev *dev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+void mt76_sta_init_tx_queue(struct mt76_dev *dev,
+ struct ieee80211_sta *sta)
{
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
- int ret;
int i;
- mutex_lock(&dev->mutex);
-
- ret = dev->drv->sta_add(dev, vif, sta);
- if (ret)
- goto out;
-
for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
struct mt76_txq *mtxq;
@@ -669,6 +661,21 @@ mt76_sta_add(struct mt76_dev *dev, struct ieee80211_vif *vif,
mt76_txq_init(dev, sta->txq[i]);
}
+}
+EXPORT_SYMBOL_GPL(mt76_sta_init_tx_queue);
+
+static int
+mt76_sta_add(struct mt76_dev *dev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
+ int ret;
+
+ mutex_lock(&dev->mutex);
+
+ ret = dev->drv->sta_add(dev, vif, sta);
+ if (ret)
+ goto out;
ewma_signal_init(&wcid->rssi);
rcu_assign_pointer(dev->wcid[wcid->idx], wcid);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 53b85042b793..f6aab5ee782b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -639,6 +639,17 @@ static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb)
return ((void *) IEEE80211_SKB_CB(skb)->status.status_driver_data);
}
+void mt76_sta_init_tx_queue(struct mt76_dev *dev,
+ struct ieee80211_sta *sta);
+void __mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq, int qid);
+static inline void
+mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq)
+{
+ int qid = txq->sta ? txq->ac : MT_TXQ_BE;
+
+ return __mt76_txq_init(dev, txq, qid);
+}
+
int mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta);
@@ -646,7 +657,6 @@ int mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb);
void mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
struct mt76_wcid *wcid, struct sk_buff *skb, int qid);
-void mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq);
void mt76_txq_remove(struct mt76_dev *dev, struct ieee80211_txq *txq);
void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
void mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 87ed00768bc7..c3a36519a942 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -251,6 +251,8 @@ int mt76x02_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
if (vif->type == NL80211_IFTYPE_AP)
set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags);
+ mt76_sta_init_tx_queue(mdev, sta);
+
return 0;
}
EXPORT_SYMBOL_GPL(mt76x02_sta_add);
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 3617de2c1325..142b12877a34 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -82,15 +82,6 @@ void mt76_tx_free(struct mt76_dev *dev)
DMA_TO_DEVICE);
}
-static int
-mt76_txq_get_qid(struct ieee80211_txq *txq)
-{
- if (!txq->sta)
- return MT_TXQ_BE;
-
- return txq->ac;
-}
-
static void
mt76_check_agg_ssn(struct mt76_txq *mtxq, struct sk_buff *skb)
{
@@ -604,16 +595,17 @@ void mt76_txq_remove(struct mt76_dev *dev, struct ieee80211_txq *txq)
}
EXPORT_SYMBOL_GPL(mt76_txq_remove);
-void mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq)
+void __mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq,
+ int qid)
{
struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv;
INIT_LIST_HEAD(&mtxq->list);
skb_queue_head_init(&mtxq->retry_q);
- mtxq->hwq = &dev->q_tx[mt76_txq_get_qid(txq)];
+ mtxq->hwq = &dev->q_tx[qid];
}
-EXPORT_SYMBOL_GPL(mt76_txq_init);
+EXPORT_SYMBOL_GPL(__mt76_txq_init);
u8 mt76_ac_to_hwq(u8 ac)
{
--
2.20.1
^ permalink raw reply related
* Re: [BUG] mt76x0u: Probing issues on Raspberry Pi 3 B+
From: Stefan Wahren @ 2019-02-16 19:17 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: Lorenzo Bianconi, Alan Stern, Felix Fietkau, Doug Anderson,
Minas Harutyunyan, USB list, linux-wireless
In-Reply-To: <20190216140739.GA2236@redhat.com>
Hi Stanislaw,
> Stanislaw Gruszka <sgruszka@redhat.com> hat am 16. Februar 2019 um 15:07 geschrieben:
>
>
> On Sat, Feb 16, 2019 at 12:05:18PM +0100, Stefan Wahren wrote:
> > sorry for the delay, but i do this all in my spare time.
>
> Stefan, thanks for sacrifing your spare time for testing this!
>
> > The results for your recent patch series are better (no firmware timeout), but still no working wifi and still a warning:
> > https://gist.github.com/lategoodbye/c4864e446821717419cbe65df07f8d8d
> >
> > I've identified the reason for the warning in dwc2:
> >
> > /*
> > * We assume that DMA is always aligned in non-split
> > * case or split out case. Warn if not.
> > */
> > WARN_ON_ONCE(hsotg->params.host_dma && (chan->xfer_dma & 0x3));
>
> I think I understand why that happen, we first allocate 1024 mcu
> buffer then standard 4096 rx buffers, that couse 4096 buffers are
> not contained in single page and need split by dwc2 driver.
this is a misunderstanding. The warning is about memory alignment to 32 bit addresses, not about page alignment. This is a typical ARM restriction. Maybe we need to make sure in mt76 that the DMA buffer needs to be aligned. But it's also possible that the warning isn't the root cause of our problem.
>
> Attached patch should fix this, plese test, thanks in advance.
Anyway i tested the following patch combinations against next with the same results as 1,2,3 (no wifi, alignment warning):
1,3
1,2,3,4
>
> > Btw i can confirm a regression was introduced after 4.19, because in 4.19 there was no firmware timeout but even no working wifi:
>
> You ment 'no working wifi' or 'working wifi'?
Wifi is broken in 4.19, 4.20, 5.0 and next. It only worked with Lorenzo's SG avoid patches so far. Btw the regression (firmware timeout) started in 4.20. I also tested it today.
Thanks
Stefan
>
> Stanislaw
^ permalink raw reply
* preparing for 802.11ah channels
From: thomas pedersen @ 2019-02-16 23:45 UTC (permalink / raw)
To: linux-wireless
Hello,
I'm working on defining new channels for S1G PHYs in mac80211. These
are in the 900MHz range and center frequency for the 1MHz channels are
on a half MHz, while the existing channel definitions are in units of
MHz.
In order to support the new channels we could change the internal
center frequency units to KHz and extend the nl80211 API so
NL80211_FREQUENCY_ATTR_FREQ and NL80211_ATTR_WIPHY_FREQ get _KHZ
variants while renaming the original attributes to _MHZ to reflect the
units.
From looking at the code it looks like this should be fairly
straightforward, if involving a lot of changes since the driver
declarations would have to change too. Am I missing something
obviously wrong, or does this sound reasonable?
Thanks,
Thomas
^ permalink raw reply
* Kernel hangs on regulatory.db X.509 key initialization
From: Dominik Schmidt @ 2019-02-17 9:38 UTC (permalink / raw)
To: linux-wireless; +Cc: mail, james.morris
[-- Attachment #1: Type: text/plain, Size: 1572 bytes --]
Hi there!
I'm running a Gentoo Linux on an APU2C2-Board (AMD Jaguar GX-412TC x86_64), with
an Atheros QCA9882 (ath10k) and an Atheros AR9280 (ath9k) card.
The kernels after 4.18 do not reach userspace any longer. They just somehow
"freeze" without emitting any oops or kernel panic. I've tracked the issue
down to the cfg80211 subsystem and a change in the X.509 parser:
* If I do not compile cfg80211 into the kernel, it starts perfectly (minus wireless)
* Bisecting the issue shows that it starts with
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b65c32ec5a942ab3ada93a048089a938918aba7f
* The last message I see in the logs is this one:
cfg80211: Loading compiled-in X.509 certificates for regulatory database
defined at
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/wireless/reg.c#n770
* If I add another pr_notice to the end of that function, it is never displayed.
* It seems to get stuck at the call to key_create_or_update, here:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/wireless/reg.c#n735
* If I throw more pr_notices at key_create_or_update, the last one I see
is before this memset:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/security/keys/key.c#n843
* As an additional hindrance, this problem occurs only on the APU2 board,
and not when running the same kernel in a Qemu-VM
Any idea what could be the cause of this, or hints as to how to
debug this further?
Cheers
Dominik
[-- Attachment #2: .config.bz2 --]
[-- Type: application/x-bzip, Size: 20579 bytes --]
^ permalink raw reply
* Re: [PATCH] wireless-regdb: update 60ghz band rules for us
From: Seth Forshee @ 2019-02-17 10:53 UTC (permalink / raw)
To: Krishna Chaitanya; +Cc: wireless-regdb, linux-wireless
In-Reply-To: <CABPxzY+jbfoVGF_fta3reHa5yngmp_+dVKCiu3DR-8WzzxAPow@mail.gmail.com>
On Wed, Jan 23, 2019 at 04:19:26PM +0530, Krishna Chaitanya wrote:
> On Wed, Jan 23, 2019 at 2:43 AM Seth Forshee <seth.forshee@canonical.com> wrote:
> >
> > On Tue, Dec 18, 2018 at 01:38:15PM +0530, chaitanya.mgit@gmail.com wrote:
> > > From: Chaitanya Tata <Chaitanya.Mgit@gmail.com>
> > >
> > > Include channels 4, 5 & 6 for US in 60GHz band. FCC extended the
> > > 57-64GHz band till 71GHz with almost same rules.
> >
> > This looks right to me based on my research. You're missing one thing
> > though. You need to provide a Signed-off-by tag, please see the
> > CONTRIBUTING file for more information. If you reply with your tag I
> > will add it when I apply the patch. Thanks!
>
> Sorry, didn't realize missed SO. You can use below. Thanks.
> Signed-off-by: Chaitanya Tata <Chaitanya.Tata@bluwireless.co.uk>
Sorry for the delay. Applied now, thanks!
^ permalink raw reply
* Re: [PATCH v2] wireless-regdb: Sync IN with G.S.R. 1048(E), October 2018
From: Seth Forshee @ 2019-02-17 10:55 UTC (permalink / raw)
To: Felix Fietkau; +Cc: linux-wireless, Felix Fietkau, wireless-regdb
In-Reply-To: <20190209101947.4876-1-nbd@nbd.name>
On Sat, Feb 09, 2019 at 11:19:47AM +0100, Felix Fietkau wrote:
> From: Felix Fietkau <felix@wiowireless.com>
>
> Add new frequency ranges, increase power, as documented in:
> http://wpc.dot.gov.in/WriteReadData/userfiles/License%20Exemption%20in%205%20GHz%20G_S_R_1048(E)%20dated%2022nd%20October,%202018.pdf
>
> Signed-off-by: Felix Fietkau <felix@wiowireless.com>
Please also include wireless-regdb@lists.infradead.org on wireless-regdb
patches.
Applied, thanks!
^ permalink raw reply
* Re: Kernel hangs on regulatory.db X.509 key initialization
From: Maciej S. Szmigiero @ 2019-02-17 12:29 UTC (permalink / raw)
To: Dominik Schmidt; +Cc: linux-wireless, james.morris
In-Reply-To: <1549746752.q02fowo7n3.astroid@I7-2600.none>
Hi,
On 17.02.2019 10:38, Dominik Schmidt wrote:
> Hi there!
>
> I'm running a Gentoo Linux on an APU2C2-Board (AMD Jaguar GX-412TC x86_64), with
> an Atheros QCA9882 (ath10k) and an Atheros AR9280 (ath9k) card.
>
> The kernels after 4.18 do not reach userspace any longer.
Did you test a more recent kernel like 4.20?
> They just somehow
> "freeze" without emitting any oops or kernel panic. I've tracked the issue
> down to the cfg80211 subsystem and a change in the X.509 parser:
>
> * If I do not compile cfg80211 into the kernel, it starts perfectly (minus wireless)
>
> * Bisecting the issue shows that it starts with
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b65c32ec5a942ab3ada93a048089a938918aba7f
>
> * The last message I see in the logs is this one:
> cfg80211: Loading compiled-in X.509 certificates for regulatory database
> defined at
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/wireless/reg.c#n770
>
> * If I add another pr_notice to the end of that function, it is never displayed.
>
> * It seems to get stuck at the call to key_create_or_update, here:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/wireless/reg.c#n735
>
> * If I throw more pr_notices at key_create_or_update, the last one I see
> is before this memset:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/security/keys/key.c#n843
>
> * As an additional hindrance, this problem occurs only on the APU2 board,
> and not when running the same kernel in a Qemu-VM
>
> Any idea what could be the cause of this, or hints as to how to
> debug this further?
I see that you are using an AMD CPU-based board, with AMD CCP enabled
in your kernel config.
Before my patch, that you bisected your problem to, such configuration
would fail (early) in-kernel X.509 certificate signature verification
as its length wasn't exactly correct.
Now, when this was fixed the CCP RSA implementation actually gets
exercised (however, it works for me without problems on Ryzen).
You can temporarily change CONFIG_CFG80211 in your kernel config to
'm' and compile the kernel with KASAN.
Don't load any wireless modules at startup, this should at least
defer the crash until you load them manually later when the system is
idle and you can monitor it.
If you are lucky KASAN will give you information then where the bug
might be.
> Cheers
> Dominik
>
Maciej
^ permalink raw reply
* [PATCH v2] ath10k: wait for vdev delete response from firmware
From: Rakesh Pillai @ 2019-02-17 13:51 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless, Rakesh Pillai
When we add an interface immediately after removing
the interface the vdev deletion in firmware might not
have been completed. We need to synchronize the vdev creation
with the firmware.
Wait for vdev delete response from firmware when we
remove an interface.
Tested HW: WCN3990
Tested FW: WLAN.HL.2.0-01188-QCAHLSWMTPLZ-1
Signed-off-by: Rakesh Pillai <pillair@codeaurora.org>
---
Changes from v1:
- Unlock conf_mutex in vdev delete failure case.
---
drivers/net/wireless/ath/ath10k/core.c | 4 +++-
drivers/net/wireless/ath/ath10k/core.h | 6 ++++--
drivers/net/wireless/ath/ath10k/mac.c | 15 +++++++++++++++
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 12 +++++++++++-
drivers/net/wireless/ath/ath10k/wmi-tlv.h | 6 +++++-
drivers/net/wireless/ath/ath10k/wmi.h | 4 +++-
6 files changed, 41 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 327a74c0..16d2d04 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -2137,6 +2137,7 @@ static void ath10k_core_restart(struct work_struct *work)
complete(&ar->offchan_tx_completed);
complete(&ar->install_key_done);
complete(&ar->vdev_setup_done);
+ complete(&ar->vdev_delete_done);
complete(&ar->thermal.wmi_sync);
complete(&ar->bss_survey_done);
wake_up(&ar->htt.empty_tx_wq);
@@ -3093,6 +3094,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
init_completion(&ar->install_key_done);
init_completion(&ar->vdev_setup_done);
+ init_completion(&ar->vdev_delete_done);
init_completion(&ar->thermal.wmi_sync);
init_completion(&ar->bss_survey_done);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 46e9c8c..ad1da95 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -511,7 +511,8 @@ struct ath10k_sta {
u32 peer_ps_state;
};
-#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5 * HZ)
+#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5 * HZ)
+#define ATH10K_VDEV_DELETE_TIMEOUT_HZ (5 * HZ)
enum ath10k_beacon_state {
ATH10K_BEACON_SCHEDULED = 0,
@@ -1058,6 +1059,7 @@ struct ath10k {
int last_wmi_vdev_start_status;
struct completion vdev_setup_done;
+ struct completion vdev_delete_done;
struct workqueue_struct *workqueue;
/* Auxiliary workqueue */
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 4dd64f3..02c17f4 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1022,6 +1022,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
reinit_completion(&ar->vdev_setup_done);
+ reinit_completion(&ar->vdev_delete_done);
ret = ath10k_wmi_vdev_start(ar, &arg);
if (ret) {
@@ -1071,6 +1072,7 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar)
ar->monitor_vdev_id, ret);
reinit_completion(&ar->vdev_setup_done);
+ reinit_completion(&ar->vdev_delete_done);
ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
if (ret)
@@ -1412,6 +1414,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
lockdep_assert_held(&ar->conf_mutex);
reinit_completion(&ar->vdev_setup_done);
+ reinit_completion(&ar->vdev_delete_done);
ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
if (ret) {
@@ -1448,6 +1451,7 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
lockdep_assert_held(&ar->conf_mutex);
reinit_completion(&ar->vdev_setup_done);
+ reinit_completion(&ar->vdev_delete_done);
arg.vdev_id = arvif->vdev_id;
arg.dtim_period = arvif->dtim_period;
@@ -5397,6 +5401,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
struct ath10k *ar = hw->priv;
struct ath10k_vif *arvif = (void *)vif->drv_priv;
struct ath10k_peer *peer;
+ unsigned long time_left;
int ret;
int i;
@@ -5438,6 +5443,15 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
arvif->vdev_id, ret);
+ if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) {
+ time_left = wait_for_completion_timeout(&ar->vdev_delete_done,
+ ATH10K_VDEV_DELETE_TIMEOUT_HZ);
+ if (time_left == 0) {
+ ath10k_warn(ar, "Timeout in receiving vdev delete response\n");
+ goto out:
+ }
+ }
+
/* Some firmware revisions don't notify host about self-peer removal
* until after associated vdev is deleted.
*/
@@ -5488,6 +5502,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
ath10k_mac_txq_unref(ar, vif->txq);
+out:
mutex_unlock(&ar->conf_mutex);
}
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 90617e1..642d770 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -222,6 +222,13 @@ static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar,
return 0;
}
+static void ath10k_wmi_tlv_event_vdev_delete_resp(struct ath10k *ar,
+ struct sk_buff *skb)
+{
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_DELETE_RESP_EVENTID\n");
+ complete(&ar->vdev_delete_done);
+}
+
static int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar,
struct sk_buff *skb)
{
@@ -524,6 +531,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
case WMI_TLV_VDEV_STOPPED_EVENTID:
ath10k_wmi_event_vdev_stopped(ar, skb);
break;
+ case WMI_TLV_VDEV_DELETE_RESP_EVENTID:
+ ath10k_wmi_tlv_event_vdev_delete_resp(ar, skb);
+ break;
case WMI_TLV_PEER_STA_KICKOUT_EVENTID:
ath10k_wmi_event_peer_sta_kickout(ar, skb);
break;
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
index 298d917..872da8e 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -310,6 +310,8 @@ enum wmi_tlv_event_id {
WMI_TLV_VDEV_STOPPED_EVENTID,
WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID,
WMI_TLV_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID,
+ WMI_TLV_VDEV_TSF_REPORT_EVENTID,
+ WMI_TLV_VDEV_DELETE_RESP_EVENTID,
WMI_TLV_PEER_STA_KICKOUT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_PEER),
WMI_TLV_PEER_INFO_EVENTID,
WMI_TLV_PEER_TX_FAIL_CNT_THR_EVENTID,
@@ -1557,6 +1559,8 @@ wmi_tlv_svc_map(const __le32 *in, unsigned long *out, size_t len)
WMI_SERVICE_SAP_AUTH_OFFLOAD, len);
SVCMAP(WMI_TLV_SERVICE_MGMT_TX_WMI,
WMI_SERVICE_MGMT_TX_WMI, len);
+ SVCMAP(WMI_TLV_SERVICE_SYNC_DELETE_CMDS,
+ WMI_SERVICE_SYNC_DELETE_CMDS, len);
}
static inline void
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 1f82f10..b941240 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -208,6 +208,7 @@ enum wmi_service {
WMI_SERVICE_VDEV_DISABLE_4_ADDR_SRC_LRN_SUPPORT,
WMI_SERVICE_BB_TIMING_CONFIG_SUPPORT,
WMI_SERVICE_THERM_THROT,
+ WMI_SERVICE_SYNC_DELETE_CMDS,
/* keep last */
WMI_SERVICE_MAX,
@@ -483,6 +484,7 @@ static inline char *wmi_service_name(int service_id)
SVCSTR(WMI_SERVICE_RESET_CHIP);
SVCSTR(WMI_SERVICE_TX_DATA_ACK_RSSI);
SVCSTR(WMI_SERVICE_VDEV_DIFFERENT_BEACON_INTERVAL_SUPPORT);
+ SVCSTR(WMI_SERVICE_SYNC_DELETE_CMDS);
default:
return NULL;
}
--
2.7.4
^ permalink raw reply related
* Re: Kernel hangs on regulatory.db X.509 key initialization
From: Dominik Schmidt @ 2019-02-17 15:47 UTC (permalink / raw)
To: Maciej S. Szmigiero; +Cc: james.morris, linux-wireless
In-Reply-To: <0ce6546d-0f1d-922c-0acd-796966c98aab@maciej.szmigiero.name>
Excerpts from Maciej S. Szmigiero's message of Februar 17, 2019 1:29 pm:
> Hi,
>
> On 17.02.2019 10:38, Dominik Schmidt wrote:
>> Hi there!
>>
>> I'm running a Gentoo Linux on an APU2C2-Board (AMD Jaguar GX-412TC x86_64), with
>> an Atheros QCA9882 (ath10k) and an Atheros AR9280 (ath9k) card.
>>
>> The kernels after 4.18 do not reach userspace any longer.
>
> Did you test a more recent kernel like 4.20?
Yes, up to 4.20.7, yielding the same fault
>> They just somehow
>> "freeze" without emitting any oops or kernel panic. I've tracked the issue
>> down to the cfg80211 subsystem and a change in the X.509 parser:
>>
>> * If I do not compile cfg80211 into the kernel, it starts perfectly (minus wireless)
>>
>> * Bisecting the issue shows that it starts with
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b65c32ec5a942ab3ada93a048089a938918aba7f
>>
>> * The last message I see in the logs is this one:
>> cfg80211: Loading compiled-in X.509 certificates for regulatory database
>> defined at
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/wireless/reg.c#n770
>>
>> * If I add another pr_notice to the end of that function, it is never displayed.
>>
>> * It seems to get stuck at the call to key_create_or_update, here:
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/wireless/reg.c#n735
>>
>> * If I throw more pr_notices at key_create_or_update, the last one I see
>> is before this memset:
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/security/keys/key.c#n843
>>
>> * As an additional hindrance, this problem occurs only on the APU2 board,
>> and not when running the same kernel in a Qemu-VM
>>
>> Any idea what could be the cause of this, or hints as to how to
>> debug this further?
>
> I see that you are using an AMD CPU-based board, with AMD CCP enabled
> in your kernel config.
>
> Before my patch, that you bisected your problem to, such configuration
> would fail (early) in-kernel X.509 certificate signature verification
> as its length wasn't exactly correct.
Yes, it did/does actually fail with:
[ 7.376473] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[ 7.388090] cfg80211: Problem loading in-kernel X.509 certificate (-22)
[ 7.406107] cfg80211: failed to load regulatory.db
> Now, when this was fixed the CCP RSA implementation actually gets
> exercised (however, it works for me without problems on Ryzen).
In deed it seems that CCP might be the culprit here, nice catch.
If I remove the option, the kernel starts up nicely with:
[ 7.097244] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[ 7.109893] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[ 7.117763] platform regulatory.0: Direct firmware load for regulatory.db failed with error -2
[ 7.129880] cfg80211: failed to load regulatory.db
> You can temporarily change CONFIG_CFG80211 in your kernel config to
> 'm' and compile the kernel with KASAN.
> Don't load any wireless modules at startup, this should at least
> defer the crash until you load them manually later when the system is
> idle and you can monitor it.
>
> If you are lucky KASAN will give you information then where the bug
> might be.
Oh, this works marvellously:
[ 23.301826] ==================================================================
[ 23.309463] BUG: KASAN: slab-out-of-bounds in ccp_rsa_crypt+0x84/0x250
[ 23.316092] Write of size 296 at addr ffff88805ba00c40 by task swapper/0/1
[ 23.323030]
[ 23.324633] CPU: 1 PID: 1 Comm: swapper/0 Tainted: G T 4.20.7 #38
[ 23.332121] Hardware name: PC Engines apu2/apu2, BIOS v4.9.0.1 01/09/2019
[ 23.339051] Call Trace:
[ 23.341610] dump_stack+0xd1/0x160
[ 23.345123] ? dump_stack_print_info.cold.0+0x1b/0x1b
[ 23.350321] ? kmsg_dump_rewind_nolock+0x60/0x60
[ 23.355093] print_address_description.cold.3+0x9/0x26a
[ 23.360465] kasan_report.cold.4+0x65/0xa3
[ 23.364662] ? ccp_rsa_crypt+0x84/0x250
[ 23.368605] memset+0x2d/0x50
[ 23.371681] ccp_rsa_crypt+0x84/0x250
[ 23.375506] ? ccp_rsa_exit_tfm+0x10/0x10
[ 23.379651] pkcs1pad_verify+0x254/0x2c0
[ 23.383706] public_key_verify_signature+0x385/0x5b0
[ 23.388800] ? software_key_query+0x2f0/0x2f0
[ 23.393285] ? ret_from_fork+0x27/0x50
[ 23.397157] ? sha256_base_init+0xa0/0xa0
[ 23.401319] ? match_held_lock+0xb8/0x380
[ 23.405485] ? __lock_acquire+0x2d30/0x2d30
[ 23.409807] ? x509_get_sig_params+0x223/0x280
[ 23.414385] ? kasan_unpoison_shadow+0x3b/0x60
[ 23.418931] ? kasan_kmalloc+0xee/0x100
[ 23.422929] ? asymmetric_key_generate_id+0x3e/0xa0
[ 23.427925] x509_check_for_self_signed+0x183/0x20c
[ 23.432919] ? asymmetric_key_generate_id+0x77/0xa0
[ 23.437930] x509_cert_parse+0x315/0x3c0
[ 23.441958] x509_key_preparse+0x47/0x3a0
[ 23.446084] asymmetric_key_preparse+0x60/0x90
[ 23.450648] key_create_or_update+0x3aa/0x8b0
[ 23.455107] ? key_type_lookup+0x90/0x90
[ 23.459195] ? key_instantiate_and_link+0x250/0x2c0
[ 23.464144] ? key_user_put+0x50/0x50
[ 23.467943] regulatory_init_db+0x20d/0x386
[ 23.472245] ? regulatory_init+0x201/0x201
[ 23.476471] do_one_initcall+0xd5/0x458
[ 23.480436] ? perf_trace_initcall_level+0x370/0x370
[ 23.485499] ? strlen+0x5/0x40
[ 23.488697] ? next_arg+0x19c/0x220
[ 23.492291] ? strlen+0x1e/0x40
[ 23.495508] ? rcu_is_watching+0xa5/0xf0
[ 23.499532] ? __lock_is_held+0x38/0xd0
[ 23.503472] ? rcu_gpnum_ovf+0x210/0x210
[ 23.507499] ? rcu_read_lock_sched_held+0x70/0x80
[ 23.512328] ? trace_initcall_level+0x15b/0x1bc
[ 23.516964] ? do_one_initcall+0x400/0x458
[ 23.521192] ? up_write+0xcf/0x180
[ 23.524674] ? down_read_non_owner+0xb0/0xb0
[ 23.529105] ? kasan_unpoison_shadow+0x3b/0x60
[ 23.533654] kernel_init_freeable+0x511/0x60e
[ 23.538103] ? rest_init+0x2df/0x2df
[ 23.541782] kernel_init+0x7/0x121
[ 23.545263] ? rest_init+0x2df/0x2df
[ 23.548912] ret_from_fork+0x27/0x50
[ 23.552583]
[ 23.554173] Allocated by task 1:
[ 23.557564] kasan_kmalloc+0xee/0x100
[ 23.561325] __kmalloc+0x123/0x280
[ 23.564859] public_key_verify_signature+0x157/0x5b0
[ 23.569893] x509_check_for_self_signed+0x183/0x20c
[ 23.574899] x509_cert_parse+0x315/0x3c0
[ 23.578913] x509_key_preparse+0x47/0x3a0
[ 23.582993] asymmetric_key_preparse+0x60/0x90
[ 23.587565] key_create_or_update+0x3aa/0x8b0
[ 23.592047] regulatory_init_db+0x20d/0x386
[ 23.596332] do_one_initcall+0xd5/0x458
[ 23.600273] kernel_init_freeable+0x511/0x60e
[ 23.604714] kernel_init+0x7/0x121
[ 23.608228] ret_from_fork+0x27/0x50
[ 23.611928]
[ 23.613522] Freed by task 0:
[ 23.616497] (stack is not available)
[ 23.620158]
[ 23.621740] The buggy address belongs to the object at ffff88805ba00b40
[ 23.621740] which belongs to the cache kmalloc-256 of size 256
[ 23.634410] The buggy address is located 0 bytes to the right of
[ 23.634410] 256-byte region [ffff88805ba00b40, ffff88805ba00c40)
[ 23.646599] The buggy address belongs to the page:
[ 23.651537] page:ffffea00016e8000 count:1 mapcount:0 mapping:ffff88805f803200 index:0x0 compound_mapcount: 0
[ 23.661500] flags: 0x4000000000010200(slab|head)
[ 23.666272] raw: 4000000000010200 dead000000000100 dead000000000200 ffff88805f803200
[ 23.674178] raw: 0000000000000000 0000000080190019 00000001ffffffff 0000000000000000
[ 23.682028] page dumped because: kasan: bad access detected
[ 23.687724]
[ 23.689329] Memory state around the buggy address:
[ 23.694255] ffff88805ba00b00: fc fc fc fc fc fc fc fc 00 00 00 00 00 00 00 00
[ 23.701593] ffff88805ba00b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 23.708926] >ffff88805ba00c00: 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc
[ 23.716304] ^
[ 23.721725] ffff88805ba00c80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 23.729058] ffff88805ba00d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 23.736370] ==================================================================
[ 23.743664] Disabling lock debugging due to kernel taint
I will investigate further and start a new thread in linux-crypto once I find out more
(sorry about abusing linux-wireless :/)
Anyways, many thanks Maciej for looking into it, your help is much appreciated!
>> Cheers
>> Dominik
>>
>
> Maciej
>
^ permalink raw reply
* Re: [PATCH 2/2] mac80211: probe unexercised mesh links
From: Rajkumar Manoharan @ 2019-02-17 15:56 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, kevinhayes, julanhsu
In-Reply-To: <0541dec472c83b173a486a924983a450ede7e923.camel@sipsolutions.net>
On 2019-02-15 02:44, Johannes Berg wrote:
>> void __ieee80211_subif_start_xmit(struct sk_buff *skb,
>> struct net_device *dev,
>> - u32 info_flags);
>> + u32 info_flags,
>> + u32 ctrl_flags);
>
> I'd feel better if we could avoid all this, but if you really can't
> then
> I guess we should split this out to a separate patch.
>
Hmm.. I don't see any options other than this. no free slot in
info_flags.
Will split this change.
>>
>> + /* Allow injected packets to bypass mesh routing */
>> + if (info->control.flags & IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP)
>
> unlikely?
>
>> +int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device
>> *dev,
>> + const u8 *dest, const u8 *buf, size_t len)
>> +{
>> + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
>> + struct ieee80211_local *local = sdata->local;
>> + struct sta_info *sta;
>> + struct sk_buff *skb;
>> + struct ethhdr *ehdr;
>> +
>> + if (len < sizeof(*ehdr))
>> + return -EINVAL;
>> +
>> + mutex_lock(&local->sta_mtx);
>> + sta = sta_info_get_bss(sdata, dest);
>> + mutex_unlock(&local->sta_mtx);
>> +
>> + if (!sta)
>> + return -ENOENT;
>
> better add a comment here that the locking is fine because you only
> check *existence* and don't use the sta pointer for anything else
>
>> + ehdr = (struct ethhdr *)buf;
>> + if (!ether_addr_equal(ehdr->h_dest, dest) ||
>
> that check could be in cfg80211, but then why even bother passing the
> "dest" separately?
>
>> + !ether_addr_equal(ehdr->h_source, sdata->vif.addr) ||
>
> probably this one too
>
>> + is_multicast_ether_addr(ehdr->h_dest))
>
> this one too
>
Will move all the condition checks to cfg80211.
> But also, ehdr isn't packed I think, you might have alignment issues
> here as you don't know how the netlink message looks like? I think?
>
>> + if (ehdr->h_proto != htons(ETH_P_802_3))
>> + return -EINVAL;
>
> same here
>
>> + skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
>
> you should make it a bit bigger so header conversion will fit, I guess?
>
Hmm. I thought ieee80211_skb_resize in build_hdr will take care of it.
-Rajkumar
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox