mac80211: update to backports-4.14-rc2
This updates mac80211 to backprots-4.14-rc2. This was compile and runtime tested with ath9k, ath10k and b43 with multiple stations and ieee80211w and in different scenarios by many other people. To create the backports-4.14-rc2-1.tar.xz use this repository: https://git.kernel.org/pub/scm/linux/kernel/git/backports/backports.git from tag v4.14-rc2-1 Then run this: ./gentree.py --git-revision v4.14-rc2 --clean <path to linux repo> ../backports-4.14-rc2-1 This also adapts the ath10k-ct and mt76 driver to the changed cfg80211 APIs and syncs the nl80211.h file in iw with the new version from backports-4.14-rc2. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>v19.07.3_mercusys_ac12_duma
parent
1114f5dc10
commit
a8f63a0717
@ -0,0 +1,104 @@
|
||||
--- a/ath10k/htt_rx.c
|
||||
+++ b/ath10k/htt_rx.c
|
||||
@@ -642,11 +642,11 @@ static void ath10k_htt_rx_h_rates(struct
|
||||
sgi = (info3 >> 7) & 1;
|
||||
|
||||
status->rate_idx = mcs;
|
||||
- status->flag |= RX_FLAG_HT;
|
||||
+ status->encoding = RX_ENC_HT;
|
||||
if (sgi)
|
||||
- status->flag |= RX_FLAG_SHORT_GI;
|
||||
+ status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
if (bw)
|
||||
- status->flag |= RX_FLAG_40MHZ;
|
||||
+ status->bw = RATE_INFO_BW_40;
|
||||
break;
|
||||
case HTT_RX_VHT:
|
||||
case HTT_RX_VHT_WITH_TXBF:
|
||||
@@ -698,10 +698,10 @@ static void ath10k_htt_rx_h_rates(struct
|
||||
}
|
||||
|
||||
status->rate_idx = mcs;
|
||||
- status->vht_nss = nss;
|
||||
+ status->nss = nss;
|
||||
|
||||
if (sgi)
|
||||
- status->flag |= RX_FLAG_SHORT_GI;
|
||||
+ status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
|
||||
switch (bw) {
|
||||
/* 20MHZ */
|
||||
@@ -709,18 +709,18 @@ static void ath10k_htt_rx_h_rates(struct
|
||||
break;
|
||||
/* 40MHZ */
|
||||
case 1:
|
||||
- status->flag |= RX_FLAG_40MHZ;
|
||||
+ status->bw = RATE_INFO_BW_40;
|
||||
break;
|
||||
/* 80MHZ */
|
||||
case 2:
|
||||
- status->vht_flag |= RX_VHT_FLAG_80MHZ;
|
||||
+ status->bw = RATE_INFO_BW_80;
|
||||
break;
|
||||
case 3:
|
||||
- status->vht_flag |= RX_VHT_FLAG_160MHZ;
|
||||
+ status->bw = RATE_INFO_BW_160;
|
||||
break;
|
||||
}
|
||||
|
||||
- status->flag |= RX_FLAG_VHT;
|
||||
+ status->encoding = RX_ENC_VHT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -883,13 +883,10 @@ static void ath10k_htt_rx_h_ppdu(struct
|
||||
/* New PPDU starts so clear out the old per-PPDU status. */
|
||||
status->freq = 0;
|
||||
status->rate_idx = 0;
|
||||
- status->vht_nss = 0;
|
||||
- status->vht_flag &= ~RX_VHT_FLAG_80MHZ;
|
||||
- status->flag &= ~(RX_FLAG_HT |
|
||||
- RX_FLAG_VHT |
|
||||
- RX_FLAG_SHORT_GI |
|
||||
- RX_FLAG_40MHZ |
|
||||
- RX_FLAG_MACTIME_END);
|
||||
+ status->nss = 0;
|
||||
+ status->encoding = RX_ENC_LEGACY;
|
||||
+ status->bw = RATE_INFO_BW_20;
|
||||
+ status->flag &= ~RX_FLAG_MACTIME_END;
|
||||
status->flag |= RX_FLAG_NO_SIGNAL_VAL;
|
||||
|
||||
ath10k_htt_rx_h_signal(ar, status, rxd);
|
||||
@@ -942,7 +939,7 @@ static void ath10k_process_rx(struct ath
|
||||
*status = *rx_status;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_DATA,
|
||||
- "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
|
||||
+ "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
|
||||
skb,
|
||||
skb->len,
|
||||
ieee80211_get_SA(hdr),
|
||||
@@ -950,15 +947,15 @@ static void ath10k_process_rx(struct ath
|
||||
is_multicast_ether_addr(ieee80211_get_DA(hdr)) ?
|
||||
"mcast" : "ucast",
|
||||
(__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4,
|
||||
- status->flag == 0 ? "legacy" : "",
|
||||
- status->flag & RX_FLAG_HT ? "ht" : "",
|
||||
- status->flag & RX_FLAG_VHT ? "vht" : "",
|
||||
- status->flag & RX_FLAG_40MHZ ? "40" : "",
|
||||
- status->vht_flag & RX_VHT_FLAG_80MHZ ? "80" : "",
|
||||
- status->vht_flag & RX_VHT_FLAG_160MHZ ? "160" : "",
|
||||
- status->flag & RX_FLAG_SHORT_GI ? "sgi " : "",
|
||||
+ (status->encoding == RX_ENC_LEGACY) ? "legacy" : "",
|
||||
+ (status->encoding == RX_ENC_HT) ? "ht" : "",
|
||||
+ (status->encoding == RX_ENC_VHT) ? "vht" : "",
|
||||
+ (status->bw == RATE_INFO_BW_40) ? "40" : "",
|
||||
+ (status->bw == RATE_INFO_BW_80) ? "80" : "",
|
||||
+ (status->bw == RATE_INFO_BW_160) ? "160" : "",
|
||||
+ status->enc_flags & RX_ENC_FLAG_SHORT_GI ? "sgi " : "",
|
||||
status->rate_idx,
|
||||
- status->vht_nss,
|
||||
+ status->nss,
|
||||
status->freq,
|
||||
status->band, status->flag,
|
||||
!!(status->flag & RX_FLAG_FAILED_FCS_CRC),
|
@ -1,20 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
|
||||
@@ -177,7 +177,7 @@ static bool rt2800usb_tx_sta_fifo_read_c
|
||||
if (rt2800usb_txstatus_pending(rt2x00dev)) {
|
||||
/* Read register after 1 ms */
|
||||
hrtimer_start(&rt2x00dev->txstatus_timer,
|
||||
- TXSTATUS_READ_INTERVAL,
|
||||
+ ktime_set(0, TXSTATUS_READ_INTERVAL),
|
||||
HRTIMER_MODE_REL);
|
||||
return false;
|
||||
}
|
||||
@@ -204,7 +204,7 @@ static void rt2800usb_async_read_tx_stat
|
||||
|
||||
/* Read TX_STA_FIFO register after 2 ms */
|
||||
hrtimer_start(&rt2x00dev->txstatus_timer,
|
||||
- 2 * TXSTATUS_READ_INTERVAL,
|
||||
+ ktime_set(0, 2*TXSTATUS_READ_INTERVAL),
|
||||
HRTIMER_MODE_REL);
|
||||
}
|
||||
|
@ -1,266 +0,0 @@
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -32,8 +32,22 @@ static int nl80211_crypto_settings(struc
|
||||
struct cfg80211_crypto_settings *settings,
|
||||
int cipher_limit);
|
||||
|
||||
+static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
|
||||
+ struct genl_info *info);
|
||||
+static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
|
||||
+ struct genl_info *info);
|
||||
+
|
||||
/* the netlink family */
|
||||
-static struct genl_family nl80211_fam;
|
||||
+static struct genl_family nl80211_fam = {
|
||||
+ .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */
|
||||
+ .name = NL80211_GENL_NAME, /* have users key off the name instead */
|
||||
+ .hdrsize = 0, /* no private header */
|
||||
+ .version = 1, /* no particular meaning now */
|
||||
+ .maxattr = NL80211_ATTR_MAX,
|
||||
+ .netnsok = true,
|
||||
+ .pre_doit = nl80211_pre_doit,
|
||||
+ .post_doit = nl80211_post_doit,
|
||||
+};
|
||||
|
||||
/* multicast groups */
|
||||
enum nl80211_multicast_groups {
|
||||
@@ -549,14 +563,13 @@ static int nl80211_prepare_wdev_dump(str
|
||||
|
||||
if (!cb->args[0]) {
|
||||
err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
|
||||
- genl_family_attrbuf(&nl80211_fam),
|
||||
- nl80211_fam.maxattr, nl80211_policy);
|
||||
+ nl80211_fam.attrbuf, nl80211_fam.maxattr,
|
||||
+ nl80211_policy);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
|
||||
- *wdev = __cfg80211_wdev_from_attrs(
|
||||
- sock_net(skb->sk),
|
||||
- genl_family_attrbuf(&nl80211_fam));
|
||||
+ *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
|
||||
+ nl80211_fam.attrbuf);
|
||||
if (IS_ERR(*wdev)) {
|
||||
err = PTR_ERR(*wdev);
|
||||
goto out_unlock;
|
||||
@@ -1903,7 +1916,7 @@ static int nl80211_dump_wiphy_parse(stru
|
||||
struct netlink_callback *cb,
|
||||
struct nl80211_dump_wiphy_state *state)
|
||||
{
|
||||
- struct nlattr **tb = genl_family_attrbuf(&nl80211_fam);
|
||||
+ struct nlattr **tb = nl80211_fam.attrbuf;
|
||||
int ret = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
|
||||
tb, nl80211_fam.maxattr, nl80211_policy);
|
||||
/* ignore parse errors for backward compatibility */
|
||||
@@ -7733,7 +7746,6 @@ static int nl80211_send_survey(struct sk
|
||||
|
||||
static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
- struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
|
||||
struct survey_info survey;
|
||||
struct cfg80211_registered_device *rdev;
|
||||
struct wireless_dev *wdev;
|
||||
@@ -7746,7 +7758,7 @@ static int nl80211_dump_survey(struct sk
|
||||
return res;
|
||||
|
||||
/* prepare_wdev_dump parsed the attributes */
|
||||
- radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
|
||||
+ radio_stats = nl80211_fam.attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
|
||||
|
||||
if (!wdev->netdev) {
|
||||
res = -EINVAL;
|
||||
@@ -8594,14 +8606,14 @@ static int nl80211_testmode_dump(struct
|
||||
*/
|
||||
phy_idx = cb->args[0] - 1;
|
||||
} else {
|
||||
- struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
|
||||
-
|
||||
err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
|
||||
- attrbuf, nl80211_fam.maxattr, nl80211_policy);
|
||||
+ nl80211_fam.attrbuf, nl80211_fam.maxattr,
|
||||
+ nl80211_policy);
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
||||
- rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
|
||||
+ rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
|
||||
+ nl80211_fam.attrbuf);
|
||||
if (IS_ERR(rdev)) {
|
||||
err = PTR_ERR(rdev);
|
||||
goto out_err;
|
||||
@@ -8609,8 +8621,9 @@ static int nl80211_testmode_dump(struct
|
||||
phy_idx = rdev->wiphy_idx;
|
||||
rdev = NULL;
|
||||
|
||||
- if (attrbuf[NL80211_ATTR_TESTDATA])
|
||||
- cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA];
|
||||
+ if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
|
||||
+ cb->args[1] =
|
||||
+ (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
|
||||
}
|
||||
|
||||
if (cb->args[1]) {
|
||||
@@ -10814,7 +10827,8 @@ static int handle_nan_filter(struct nlat
|
||||
|
||||
i = 0;
|
||||
nla_for_each_nested(attr, attr_filter, rem) {
|
||||
- filter[i].filter = nla_memdup(attr, GFP_KERNEL);
|
||||
+ filter[i].filter = kmemdup(nla_data(attr), nla_len(attr),
|
||||
+ GFP_KERNEL);
|
||||
filter[i].len = nla_len(attr);
|
||||
i++;
|
||||
}
|
||||
@@ -11450,7 +11464,6 @@ static int nl80211_prepare_vendor_dump(s
|
||||
struct cfg80211_registered_device **rdev,
|
||||
struct wireless_dev **wdev)
|
||||
{
|
||||
- struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
|
||||
u32 vid, subcmd;
|
||||
unsigned int i;
|
||||
int vcmd_idx = -1;
|
||||
@@ -11486,28 +11499,31 @@ static int nl80211_prepare_vendor_dump(s
|
||||
}
|
||||
|
||||
err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
|
||||
- attrbuf, nl80211_fam.maxattr, nl80211_policy);
|
||||
+ nl80211_fam.attrbuf, nl80211_fam.maxattr,
|
||||
+ nl80211_policy);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
|
||||
- if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
|
||||
- !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
|
||||
+ if (!nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID] ||
|
||||
+ !nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
|
||||
err = -EINVAL;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
- *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), attrbuf);
|
||||
+ *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk),
|
||||
+ nl80211_fam.attrbuf);
|
||||
if (IS_ERR(*wdev))
|
||||
*wdev = NULL;
|
||||
|
||||
- *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
|
||||
+ *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
|
||||
+ nl80211_fam.attrbuf);
|
||||
if (IS_ERR(*rdev)) {
|
||||
err = PTR_ERR(*rdev);
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
- vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
|
||||
- subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
|
||||
+ vid = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_ID]);
|
||||
+ subcmd = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
|
||||
|
||||
for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
|
||||
const struct wiphy_vendor_command *vcmd;
|
||||
@@ -11531,9 +11547,9 @@ static int nl80211_prepare_vendor_dump(s
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
- if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
|
||||
- data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
|
||||
- data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
|
||||
+ if (nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]) {
|
||||
+ data = nla_data(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]);
|
||||
+ data_len = nla_len(nl80211_fam.attrbuf[NL80211_ATTR_VENDOR_DATA]);
|
||||
}
|
||||
|
||||
/* 0 is the first index - add 1 to parse only once */
|
||||
@@ -12795,21 +12811,6 @@ static __genl_const struct genl_ops nl80
|
||||
},
|
||||
};
|
||||
|
||||
-static struct genl_family nl80211_fam __ro_after_init = {
|
||||
- .name = NL80211_GENL_NAME, /* have users key off the name instead */
|
||||
- .hdrsize = 0, /* no private header */
|
||||
- .version = 1, /* no particular meaning now */
|
||||
- .maxattr = NL80211_ATTR_MAX,
|
||||
- .netnsok = true,
|
||||
- .pre_doit = nl80211_pre_doit,
|
||||
- .post_doit = nl80211_post_doit,
|
||||
- .module = THIS_MODULE,
|
||||
- .ops = nl80211_ops,
|
||||
- .n_ops = ARRAY_SIZE(nl80211_ops),
|
||||
- .mcgrps = nl80211_mcgrps,
|
||||
- .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
|
||||
-};
|
||||
-
|
||||
/* notification functions */
|
||||
|
||||
void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
|
||||
@@ -14759,11 +14760,12 @@ void nl80211_send_ap_stopped(struct wire
|
||||
|
||||
/* initialisation/exit functions */
|
||||
|
||||
-int __init nl80211_init(void)
|
||||
+int nl80211_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
- err = genl_register_family(&nl80211_fam);
|
||||
+ err = genl_register_family_with_ops_groups(&nl80211_fam, nl80211_ops,
|
||||
+ nl80211_mcgrps);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
--- a/drivers/net/wireless/mac80211_hwsim.c
|
||||
+++ b/drivers/net/wireless/mac80211_hwsim.c
|
||||
@@ -587,8 +587,15 @@ struct hwsim_radiotap_ack_hdr {
|
||||
__le16 rt_chbitmask;
|
||||
} __packed;
|
||||
|
||||
-/* MAC80211_HWSIM netlink family */
|
||||
-static struct genl_family hwsim_genl_family;
|
||||
+/* MAC80211_HWSIM netlinf family */
|
||||
+static struct genl_family hwsim_genl_family = {
|
||||
+ .id = GENL_ID_GENERATE,
|
||||
+ .hdrsize = 0,
|
||||
+ .name = "MAC80211_HWSIM",
|
||||
+ .version = 1,
|
||||
+ .maxattr = HWSIM_ATTR_MAX,
|
||||
+ .netnsok = true,
|
||||
+};
|
||||
|
||||
enum hwsim_multicast_groups {
|
||||
HWSIM_MCGRP_CONFIG,
|
||||
@@ -3250,18 +3257,6 @@ static __genl_const struct genl_ops hwsi
|
||||
},
|
||||
};
|
||||
|
||||
-static struct genl_family hwsim_genl_family __ro_after_init = {
|
||||
- .name = "MAC80211_HWSIM",
|
||||
- .version = 1,
|
||||
- .maxattr = HWSIM_ATTR_MAX,
|
||||
- .netnsok = true,
|
||||
- .module = THIS_MODULE,
|
||||
- .ops = hwsim_ops,
|
||||
- .n_ops = ARRAY_SIZE(hwsim_ops),
|
||||
- .mcgrps = hwsim_mcgrps,
|
||||
- .n_mcgrps = ARRAY_SIZE(hwsim_mcgrps),
|
||||
-};
|
||||
-
|
||||
static void destroy_radio(struct work_struct *work)
|
||||
{
|
||||
struct mac80211_hwsim_data *data =
|
||||
@@ -3309,13 +3304,15 @@ static struct notifier_block hwsim_netli
|
||||
.notifier_call = mac80211_hwsim_netlink_notify,
|
||||
};
|
||||
|
||||
-static int __init hwsim_init_netlink(void)
|
||||
+static int hwsim_init_netlink(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
printk(KERN_INFO "mac80211_hwsim: initializing netlink\n");
|
||||
|
||||
- rc = genl_register_family(&hwsim_genl_family);
|
||||
+ rc = genl_register_family_with_ops_groups(&hwsim_genl_family,
|
||||
+ hwsim_ops,
|
||||
+ hwsim_mcgrps);
|
||||
if (rc)
|
||||
goto failure;
|
||||
|
@ -1,20 +0,0 @@
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -1133,7 +1133,7 @@ static u16 ieee80211_netdev_select_queue
|
||||
return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb);
|
||||
}
|
||||
|
||||
-static void
|
||||
+static struct rtnl_link_stats64 *
|
||||
ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
|
||||
{
|
||||
int i;
|
||||
@@ -1158,6 +1158,8 @@ ieee80211_get_stats64(struct net_device
|
||||
stats->rx_bytes += rx_bytes;
|
||||
stats->tx_bytes += tx_bytes;
|
||||
}
|
||||
+
|
||||
+ return stats;
|
||||
}
|
||||
|
||||
static const struct net_device_ops ieee80211_dataif_ops = {
|
@ -1,338 +0,0 @@
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -151,6 +151,15 @@ void ieee80211_recalc_idle(struct ieee80
|
||||
ieee80211_hw_config(local, change);
|
||||
}
|
||||
|
||||
+static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
|
||||
+{
|
||||
+ if (new_mtu < 256 || new_mtu > IEEE80211_MAX_DATA_LEN)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ dev->mtu = new_mtu;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr,
|
||||
bool check_dup)
|
||||
{
|
||||
@@ -1168,6 +1177,7 @@ static const struct net_device_ops ieee8
|
||||
.ndo_uninit = ieee80211_uninit,
|
||||
.ndo_start_xmit = ieee80211_subif_start_xmit,
|
||||
.ndo_set_rx_mode = ieee80211_set_multicast_list,
|
||||
+ .ndo_change_mtu = ieee80211_change_mtu,
|
||||
.ndo_set_mac_address = ieee80211_change_mac,
|
||||
.ndo_select_queue = ieee80211_netdev_select_queue,
|
||||
.ndo_get_stats64 = ieee80211_get_stats64,
|
||||
@@ -1211,6 +1221,7 @@ static const struct net_device_ops ieee8
|
||||
.ndo_uninit = ieee80211_uninit,
|
||||
.ndo_start_xmit = ieee80211_monitor_start_xmit,
|
||||
.ndo_set_rx_mode = ieee80211_set_multicast_list,
|
||||
+ .ndo_change_mtu = ieee80211_change_mtu,
|
||||
.ndo_set_mac_address = ieee80211_change_mac,
|
||||
.ndo_select_queue = ieee80211_monitor_select_queue,
|
||||
.ndo_get_stats64 = ieee80211_get_stats64,
|
||||
@@ -1919,10 +1930,6 @@ int ieee80211_if_add(struct ieee80211_lo
|
||||
|
||||
netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops);
|
||||
|
||||
- /* MTU range: 256 - 2304 */
|
||||
- ndev->min_mtu = 256;
|
||||
- ndev->max_mtu = IEEE80211_MAX_DATA_LEN;
|
||||
-
|
||||
ret = register_netdevice(ndev);
|
||||
if (ret) {
|
||||
ieee80211_if_free(ndev);
|
||||
--- a/drivers/net/wireless/ath/wil6210/netdev.c
|
||||
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
|
||||
@@ -42,6 +42,21 @@ static int wil_stop(struct net_device *n
|
||||
return wil_down(wil);
|
||||
}
|
||||
|
||||
+static int wil_change_mtu(struct net_device *ndev, int new_mtu)
|
||||
+{
|
||||
+ struct wil6210_priv *wil = ndev_to_wil(ndev);
|
||||
+
|
||||
+ if (new_mtu < 68 || new_mtu > mtu_max) {
|
||||
+ wil_err(wil, "invalid MTU %d\n", new_mtu);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ wil_dbg_misc(wil, "change MTU %d -> %d\n", ndev->mtu, new_mtu);
|
||||
+ ndev->mtu = new_mtu;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int wil_do_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
struct wil6210_priv *wil = ndev_to_wil(ndev);
|
||||
@@ -55,6 +70,7 @@ static const struct net_device_ops wil_n
|
||||
.ndo_start_xmit = wil_start_xmit,
|
||||
.ndo_set_mac_address = eth_mac_addr,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
+ .ndo_change_mtu = wil_change_mtu,
|
||||
.ndo_do_ioctl = wil_do_ioctl,
|
||||
};
|
||||
|
||||
@@ -111,7 +127,6 @@ static int wil6210_netdev_poll_tx(struct
|
||||
static void wil_dev_setup(struct net_device *dev)
|
||||
{
|
||||
ether_setup(dev);
|
||||
- dev->max_mtu = mtu_max;
|
||||
dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/atmel/atmel.c
|
||||
+++ b/drivers/net/wireless/atmel/atmel.c
|
||||
@@ -1295,6 +1295,14 @@ static struct iw_statistics *atmel_get_w
|
||||
return &priv->wstats;
|
||||
}
|
||||
|
||||
+static int atmel_change_mtu(struct net_device *dev, int new_mtu)
|
||||
+{
|
||||
+ if ((new_mtu < 68) || (new_mtu > 2312))
|
||||
+ return -EINVAL;
|
||||
+ dev->mtu = new_mtu;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int atmel_set_mac_address(struct net_device *dev, void *p)
|
||||
{
|
||||
struct sockaddr *addr = p;
|
||||
@@ -1498,6 +1506,7 @@ static const struct file_operations atme
|
||||
static const struct net_device_ops atmel_netdev_ops = {
|
||||
.ndo_open = atmel_open,
|
||||
.ndo_stop = atmel_close,
|
||||
+ .ndo_change_mtu = atmel_change_mtu,
|
||||
.ndo_set_mac_address = atmel_set_mac_address,
|
||||
.ndo_start_xmit = start_tx,
|
||||
.ndo_do_ioctl = atmel_ioctl,
|
||||
@@ -1591,10 +1600,6 @@ struct net_device *init_atmel_card(unsig
|
||||
dev->irq = irq;
|
||||
dev->base_addr = port;
|
||||
|
||||
- /* MTU range: 68 - 2312 */
|
||||
- dev->min_mtu = 68;
|
||||
- dev->max_mtu = MAX_WIRELESS_BODY - ETH_FCS_LEN;
|
||||
-
|
||||
SET_NETDEV_DEV(dev, sys_dev);
|
||||
|
||||
if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
|
||||
--- a/drivers/net/wireless/cisco/airo.c
|
||||
+++ b/drivers/net/wireless/cisco/airo.c
|
||||
@@ -2329,6 +2329,14 @@ static int airo_set_mac_address(struct n
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int airo_change_mtu(struct net_device *dev, int new_mtu)
|
||||
+{
|
||||
+ if ((new_mtu < 68) || (new_mtu > 2400))
|
||||
+ return -EINVAL;
|
||||
+ dev->mtu = new_mtu;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static LIST_HEAD(airo_devices);
|
||||
|
||||
static void add_airo_dev(struct airo_info *ai)
|
||||
@@ -2648,6 +2656,7 @@ static const struct net_device_ops airo1
|
||||
.ndo_get_stats = airo_get_stats,
|
||||
.ndo_set_mac_address = airo_set_mac_address,
|
||||
.ndo_do_ioctl = airo_ioctl,
|
||||
+ .ndo_change_mtu = airo_change_mtu,
|
||||
};
|
||||
|
||||
static void wifi_setup(struct net_device *dev)
|
||||
@@ -2659,8 +2668,6 @@ static void wifi_setup(struct net_device
|
||||
dev->type = ARPHRD_IEEE80211;
|
||||
dev->hard_header_len = ETH_HLEN;
|
||||
dev->mtu = AIRO_DEF_MTU;
|
||||
- dev->min_mtu = 68;
|
||||
- dev->max_mtu = MIC_MSGLEN_MAX;
|
||||
dev->addr_len = ETH_ALEN;
|
||||
dev->tx_queue_len = 100;
|
||||
|
||||
@@ -2747,6 +2754,7 @@ static const struct net_device_ops airo_
|
||||
.ndo_set_rx_mode = airo_set_multicast_list,
|
||||
.ndo_set_mac_address = airo_set_mac_address,
|
||||
.ndo_do_ioctl = airo_ioctl,
|
||||
+ .ndo_change_mtu = airo_change_mtu,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
};
|
||||
|
||||
@@ -2758,6 +2766,7 @@ static const struct net_device_ops mpi_n
|
||||
.ndo_set_rx_mode = airo_set_multicast_list,
|
||||
.ndo_set_mac_address = airo_set_mac_address,
|
||||
.ndo_do_ioctl = airo_ioctl,
|
||||
+ .ndo_change_mtu = airo_change_mtu,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
};
|
||||
|
||||
@@ -2813,7 +2822,6 @@ static struct net_device *_init_airo_car
|
||||
dev->irq = irq;
|
||||
dev->base_addr = port;
|
||||
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
||||
- dev->max_mtu = MIC_MSGLEN_MAX;
|
||||
|
||||
SET_NETDEV_DEV(dev, dmdev);
|
||||
|
||||
--- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c
|
||||
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c
|
||||
@@ -6039,6 +6039,7 @@ static const struct net_device_ops ipw21
|
||||
.ndo_open = ipw2100_open,
|
||||
.ndo_stop = ipw2100_close,
|
||||
.ndo_start_xmit = libipw_xmit,
|
||||
+ .ndo_change_mtu = libipw_change_mtu,
|
||||
.ndo_tx_timeout = ipw2100_tx_timeout,
|
||||
.ndo_set_mac_address = ipw2100_set_address,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
@@ -6074,8 +6075,6 @@ static struct net_device *ipw2100_alloc_
|
||||
dev->wireless_data = &priv->wireless_data;
|
||||
dev->watchdog_timeo = 3 * HZ;
|
||||
dev->irq = 0;
|
||||
- dev->min_mtu = 68;
|
||||
- dev->max_mtu = LIBIPW_DATA_LEN;
|
||||
|
||||
/* NOTE: We don't use the wireless_handlers hook
|
||||
* in dev as the system will start throwing WX requests
|
||||
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
|
||||
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
|
||||
@@ -11561,6 +11561,7 @@ static const struct net_device_ops ipw_p
|
||||
.ndo_open = ipw_prom_open,
|
||||
.ndo_stop = ipw_prom_stop,
|
||||
.ndo_start_xmit = ipw_prom_hard_start_xmit,
|
||||
+ .ndo_change_mtu = libipw_change_mtu,
|
||||
.ndo_set_mac_address = eth_mac_addr,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
};
|
||||
@@ -11586,9 +11587,6 @@ static int ipw_prom_alloc(struct ipw_pri
|
||||
priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
|
||||
priv->prom_net_dev->netdev_ops = &ipw_prom_netdev_ops;
|
||||
|
||||
- priv->prom_net_dev->min_mtu = 68;
|
||||
- priv->prom_net_dev->max_mtu = LIBIPW_DATA_LEN;
|
||||
-
|
||||
priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
|
||||
SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev);
|
||||
|
||||
@@ -11621,6 +11619,7 @@ static const struct net_device_ops ipw_n
|
||||
.ndo_set_rx_mode = ipw_net_set_multicast_list,
|
||||
.ndo_set_mac_address = ipw_net_set_mac_address,
|
||||
.ndo_start_xmit = libipw_xmit,
|
||||
+ .ndo_change_mtu = libipw_change_mtu,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
};
|
||||
|
||||
@@ -11730,9 +11729,6 @@ static int ipw_pci_probe(struct pci_dev
|
||||
net_dev->wireless_handlers = &ipw_wx_handler_def;
|
||||
net_dev->ethtool_ops = &ipw_ethtool_ops;
|
||||
|
||||
- net_dev->min_mtu = 68;
|
||||
- net_dev->max_mtu = LIBIPW_DATA_LEN;
|
||||
-
|
||||
err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
|
||||
if (err) {
|
||||
IPW_ERROR("failed to create sysfs device attributes\n");
|
||||
--- a/drivers/net/wireless/intel/ipw2x00/libipw.h
|
||||
+++ b/drivers/net/wireless/intel/ipw2x00/libipw.h
|
||||
@@ -948,6 +948,7 @@ static inline int libipw_is_cck_rate(u8
|
||||
/* libipw.c */
|
||||
void free_libipw(struct net_device *dev, int monitor);
|
||||
struct net_device *alloc_libipw(int sizeof_priv, int monitor);
|
||||
+int libipw_change_mtu(struct net_device *dev, int new_mtu);
|
||||
|
||||
void libipw_networks_age(struct libipw_device *ieee, unsigned long age_secs);
|
||||
|
||||
--- a/drivers/net/wireless/intel/ipw2x00/libipw_module.c
|
||||
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_module.c
|
||||
@@ -118,6 +118,15 @@ static void libipw_networks_initialize(s
|
||||
&ieee->network_free_list);
|
||||
}
|
||||
|
||||
+int libipw_change_mtu(struct net_device *dev, int new_mtu)
|
||||
+{
|
||||
+ if ((new_mtu < 68) || (new_mtu > LIBIPW_DATA_LEN))
|
||||
+ return -EINVAL;
|
||||
+ dev->mtu = new_mtu;
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(libipw_change_mtu);
|
||||
+
|
||||
struct net_device *alloc_libipw(int sizeof_priv, int monitor)
|
||||
{
|
||||
struct libipw_device *ieee;
|
||||
--- a/drivers/net/wireless/intersil/hostap/hostap_main.c
|
||||
+++ b/drivers/net/wireless/intersil/hostap/hostap_main.c
|
||||
@@ -765,6 +765,16 @@ static void hostap_set_multicast_list(st
|
||||
}
|
||||
|
||||
|
||||
+static int prism2_change_mtu(struct net_device *dev, int new_mtu)
|
||||
+{
|
||||
+ if (new_mtu < PRISM2_MIN_MTU || new_mtu > PRISM2_MAX_MTU)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ dev->mtu = new_mtu;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static void prism2_tx_timeout(struct net_device *dev)
|
||||
{
|
||||
struct hostap_interface *iface;
|
||||
@@ -803,6 +813,7 @@ static const struct net_device_ops hosta
|
||||
.ndo_do_ioctl = hostap_ioctl,
|
||||
.ndo_set_mac_address = prism2_set_mac_address,
|
||||
.ndo_set_rx_mode = hostap_set_multicast_list,
|
||||
+ .ndo_change_mtu = prism2_change_mtu,
|
||||
.ndo_tx_timeout = prism2_tx_timeout,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
};
|
||||
@@ -815,6 +826,7 @@ static const struct net_device_ops hosta
|
||||
.ndo_do_ioctl = hostap_ioctl,
|
||||
.ndo_set_mac_address = prism2_set_mac_address,
|
||||
.ndo_set_rx_mode = hostap_set_multicast_list,
|
||||
+ .ndo_change_mtu = prism2_change_mtu,
|
||||
.ndo_tx_timeout = prism2_tx_timeout,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
};
|
||||
@@ -827,6 +839,7 @@ static const struct net_device_ops hosta
|
||||
.ndo_do_ioctl = hostap_ioctl,
|
||||
.ndo_set_mac_address = prism2_set_mac_address,
|
||||
.ndo_set_rx_mode = hostap_set_multicast_list,
|
||||
+ .ndo_change_mtu = prism2_change_mtu,
|
||||
.ndo_tx_timeout = prism2_tx_timeout,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
};
|
||||
@@ -838,8 +851,6 @@ void hostap_setup_dev(struct net_device
|
||||
|
||||
iface = netdev_priv(dev);
|
||||
ether_setup(dev);
|
||||
- dev->min_mtu = PRISM2_MIN_MTU;
|
||||
- dev->max_mtu = PRISM2_MAX_MTU;
|
||||
dev->priv_flags &= ~IFF_TX_SKB_SHARING;
|
||||
|
||||
/* kernel callbacks */
|
||||
--- a/drivers/net/wireless/intersil/orinoco/main.c
|
||||
+++ b/drivers/net/wireless/intersil/orinoco/main.c
|
||||
@@ -322,6 +322,9 @@ int orinoco_change_mtu(struct net_device
|
||||
{
|
||||
struct orinoco_private *priv = ndev_priv(dev);
|
||||
|
||||
+ if ((new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
/* MTU + encapsulation + header length */
|
||||
if ((new_mtu + ENCAPS_OVERHEAD + sizeof(struct ieee80211_hdr)) >
|
||||
(priv->nicbuf_size - ETH_HLEN))
|
||||
@@ -2285,9 +2288,6 @@ int orinoco_if_add(struct orinoco_privat
|
||||
dev->base_addr = base_addr;
|
||||
dev->irq = irq;
|
||||
|
||||
- dev->min_mtu = ORINOCO_MIN_MTU;
|
||||
- dev->max_mtu = ORINOCO_MAX_MTU;
|
||||
-
|
||||
SET_NETDEV_DEV(dev, priv->dev);
|
||||
ret = register_netdev(dev);
|
||||
if (ret)
|
@ -1,43 +0,0 @@
|
||||
--- a/backport-include/linux/string.h
|
||||
+++ b/backport-include/linux/string.h
|
||||
@@ -25,4 +25,8 @@ extern void *memdup_user_nul(const void
|
||||
void memzero_explicit(void *s, size_t count);
|
||||
#endif
|
||||
|
||||
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0))
|
||||
+ssize_t strscpy(char *dest, const char *src, size_t count);
|
||||
+#endif
|
||||
+
|
||||
#endif /* __BACKPORT_LINUX_STRING_H */
|
||||
--- a/compat/backport-4.3.c
|
||||
+++ b/compat/backport-4.3.c
|
||||
@@ -57,3 +57,29 @@ void seq_hex_dump(struct seq_file *m, co
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(seq_hex_dump);
|
||||
+
|
||||
+ssize_t strscpy(char *dest, const char *src, size_t count)
|
||||
+{
|
||||
+ long res = 0;
|
||||
+
|
||||
+ if (count == 0)
|
||||
+ return -E2BIG;
|
||||
+
|
||||
+ while (count) {
|
||||
+ char c;
|
||||
+
|
||||
+ c = src[res];
|
||||
+ dest[res] = c;
|
||||
+ if (!c)
|
||||
+ return res;
|
||||
+ res++;
|
||||
+ count--;
|
||||
+ }
|
||||
+
|
||||
+ /* Hit buffer length without finding a NUL; force NUL-termination. */
|
||||
+ if (res)
|
||||
+ dest[res-1] = '\0';
|
||||
+
|
||||
+ return -E2BIG;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(strscpy);
|
@ -1,156 +0,0 @@
|
||||
From ec8549e611465558bdf1bb5e9d308f39e5e248cd Mon Sep 17 00:00:00 2001
|
||||
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
Date: Sun, 17 Sep 2017 14:41:48 +0200
|
||||
Subject: backport dev_coredumpm() function
|
||||
|
||||
This is copied from a more recent backports version to add the
|
||||
dev_coredumpm() function when the internal core devdump is not used.
|
||||
---
|
||||
compat/Makefile | 1 +
|
||||
compat/backport-4.7.c | 82 ++++++++++++++++++++++++++++++++++++++++++
|
||||
include/linux/bp-devcoredump.h | 32 +++++++++++++++++
|
||||
include/linux/devcoredump.h | 1 +
|
||||
4 files changed, 116 insertions(+)
|
||||
create mode 100644 compat/backport-4.7.c
|
||||
create mode 100644 include/linux/bp-devcoredump.h
|
||||
|
||||
--- a/compat/Makefile
|
||||
+++ b/compat/Makefile
|
||||
@@ -32,6 +32,7 @@ compat-$(CPTCFG_KERNEL_4_3) += backport-
|
||||
compat-$(CPTCFG_KERNEL_4_4) += backport-4.4.o
|
||||
compat-$(CPTCFG_KERNEL_4_5) += backport-4.5.o
|
||||
compat-$(CPTCFG_KERNEL_4_6) += backport-4.6.o
|
||||
+compat-$(CPTCFG_KERNEL_4_6) += backport-4.7.o
|
||||
|
||||
compat-$(CPTCFG_BPAUTO_BUILD_CRYPTO_CCM) += crypto-ccm.o
|
||||
compat-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += crypto-skcipher.o
|
||||
--- /dev/null
|
||||
+++ b/compat/backport-4.7.c
|
||||
@@ -0,0 +1,82 @@
|
||||
+/*
|
||||
+ * Copyright(c) 2016 Hauke Mehrtens <hauke@hauke-m.de>
|
||||
+ *
|
||||
+ * Backport functionality introduced in Linux 4.7.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License version 2 as
|
||||
+ * published by the Free Software Foundation.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/export.h>
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/rcupdate.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/spinlock.h>
|
||||
+#include <linux/skbuff.h>
|
||||
+#include <net/netlink.h>
|
||||
+
|
||||
+/*
|
||||
+ * Below 3.18 or if the kernel has devcoredump disabled, we copied the
|
||||
+ * entire devcoredump, so no need to define these functions.
|
||||
+ */
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) && \
|
||||
+ !defined(CPTCFG_BPAUTO_BUILD_WANT_DEV_COREDUMP)
|
||||
+#include <linux/devcoredump.h>
|
||||
+#include <linux/scatterlist.h>
|
||||
+
|
||||
+static void devcd_free_sgtable(void *data)
|
||||
+{
|
||||
+ struct scatterlist *table = data;
|
||||
+ int i;
|
||||
+ struct page *page;
|
||||
+ struct scatterlist *iter;
|
||||
+ struct scatterlist *delete_iter;
|
||||
+
|
||||
+ /* free pages */
|
||||
+ iter = table;
|
||||
+ for_each_sg(table, iter, sg_nents(table), i) {
|
||||
+ page = sg_page(iter);
|
||||
+ if (page)
|
||||
+ __free_page(page);
|
||||
+ }
|
||||
+
|
||||
+ /* then free all chained tables */
|
||||
+ iter = table;
|
||||
+ delete_iter = table; /* always points on a head of a table */
|
||||
+ while (!sg_is_last(iter)) {
|
||||
+ iter++;
|
||||
+ if (sg_is_chain(iter)) {
|
||||
+ iter = sg_chain_ptr(iter);
|
||||
+ kfree(delete_iter);
|
||||
+ delete_iter = iter;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* free the last table */
|
||||
+ kfree(delete_iter);
|
||||
+}
|
||||
+
|
||||
+static ssize_t devcd_read_from_sgtable(char *buffer, loff_t offset,
|
||||
+ size_t buf_len, void *data,
|
||||
+ size_t data_len)
|
||||
+{
|
||||
+ struct scatterlist *table = data;
|
||||
+
|
||||
+ if (offset > data_len)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (offset + buf_len > data_len)
|
||||
+ buf_len = data_len - offset;
|
||||
+ return sg_pcopy_to_buffer(table, sg_nents(table), buffer, buf_len,
|
||||
+ offset);
|
||||
+}
|
||||
+
|
||||
+void dev_coredumpsg(struct device *dev, struct scatterlist *table,
|
||||
+ size_t datalen, gfp_t gfp)
|
||||
+{
|
||||
+ dev_coredumpm(dev, THIS_MODULE, table, datalen, gfp,
|
||||
+ devcd_read_from_sgtable, devcd_free_sgtable);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(dev_coredumpsg);
|
||||
+#endif /* >= 3.18.0 */
|
||||
--- /dev/null
|
||||
+++ b/include/linux/bp-devcoredump.h
|
||||
@@ -0,0 +1,32 @@
|
||||
+#ifndef __BACKPORT_LINUX_DEVCOREDUMP_H
|
||||
+#define __BACKPORT_LINUX_DEVCOREDUMP_H
|
||||
+#include <linux/version.h>
|
||||
+#include <linux/scatterlist.h>
|
||||
+
|
||||
+/* We only need to add our wrapper inside the range from 3.18 until
|
||||
+ * 4.6, outside that we can let our BPAUTO mechanism handle it.
|
||||
+ */
|
||||
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) && \
|
||||
+ LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0))
|
||||
+static inline
|
||||
+void backport_dev_coredumpm(struct device *dev, struct module *owner,
|
||||
+ void *data, size_t datalen, gfp_t gfp,
|
||||
+ ssize_t (*read_fn)(char *buffer, loff_t offset,
|
||||
+ size_t count, void *data,
|
||||
+ size_t datalen),
|
||||
+ void (*free_fn)(void *data))
|
||||
+{
|
||||
+ return dev_coredumpm(dev, owner, (const void *)data, datalen, gfp,
|
||||
+ (void *)read_fn, (void *)free_fn);
|
||||
+}
|
||||
+
|
||||
+#define dev_coredumpm LINUX_BACKPORT(dev_coredumpm)
|
||||
+
|
||||
+#define dev_coredumpsg LINUX_BACKPORT(dev_coredumpsg)
|
||||
+void dev_coredumpsg(struct device *dev, struct scatterlist *table,
|
||||
+ size_t datalen, gfp_t gfp);
|
||||
+
|
||||
+#endif /* (LINUX_VERSION_IS_GEQ(3,18,0) && \
|
||||
+ LINUX_VERSION_IS_LESS(4,7,0)) */
|
||||
+
|
||||
+#endif /* __BACKPORT_LINUX_DEVCOREDUMP_H */
|
||||
--- a/include/linux/devcoredump.h
|
||||
+++ b/include/linux/devcoredump.h
|
||||
@@ -1,6 +1,7 @@
|
||||
/* Automatically created during backport process */
|
||||
#ifndef CPTCFG_BPAUTO_BUILD_WANT_DEV_COREDUMP
|
||||
#include_next <linux/devcoredump.h>
|
||||
+#include <linux/bp-devcoredump.h>
|
||||
#else
|
||||
#undef dev_coredumpv
|
||||
#define dev_coredumpv LINUX_BACKPORT(dev_coredumpv)
|
@ -0,0 +1,34 @@
|
||||
--- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c
|
||||
+++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c
|
||||
@@ -11506,6 +11506,15 @@ static const struct attribute_group ipw_
|
||||
.attrs = ipw_sysfs_entries,
|
||||
};
|
||||
|
||||
+#if LINUX_VERSION_IS_LESS(4,10,0)
|
||||
+static int __change_mtu(struct net_device *ndev, int new_mtu){
|
||||
+ if (new_mtu < 68 || new_mtu > LIBIPW_DATA_LEN)
|
||||
+ return -EINVAL;
|
||||
+ ndev->mtu = new_mtu;
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#ifdef CPTCFG_IPW2200_PROMISCUOUS
|
||||
static int ipw_prom_open(struct net_device *dev)
|
||||
{
|
||||
@@ -11554,15 +11563,6 @@ static netdev_tx_t ipw_prom_hard_start_x
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
-#if LINUX_VERSION_IS_LESS(4,10,0)
|
||||
-static int __change_mtu(struct net_device *ndev, int new_mtu){
|
||||
- if (new_mtu < 68 || new_mtu > LIBIPW_DATA_LEN)
|
||||
- return -EINVAL;
|
||||
- ndev->mtu = new_mtu;
|
||||
- return 0;
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
static const struct net_device_ops ipw_prom_netdev_ops = {
|
||||
#if LINUX_VERSION_IS_LESS(4,10,0)
|
||||
.ndo_change_mtu = __change_mtu,
|
@ -1,78 +0,0 @@
|
||||
From 6232c17438ed01f43665197db5a98a4a4f77ef47 Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Thu, 2 Feb 2017 10:57:40 +0100
|
||||
Subject: [PATCH 01/19] rt2x00: avoid introducing a USB dependency in the
|
||||
rt2x00lib module
|
||||
|
||||
As reported by Felix:
|
||||
|
||||
Though protected by an ifdef, introducing an usb symbol dependency in
|
||||
the rt2x00lib module is a major inconvenience for distributions that
|
||||
package kernel modules split into individual packages.
|
||||
|
||||
Get rid of this unnecessary dependency by calling the usb related
|
||||
function from a more suitable place.
|
||||
|
||||
Cc: Vishal Thanki <vishalthanki@gmail.com>
|
||||
Reported-by: Felix Fietkau <nbd@nbd.name>
|
||||
Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB")
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 23 ++++++++---------------
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 5 +++++
|
||||
2 files changed, 13 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -1436,21 +1436,6 @@ void rt2x00lib_remove_dev(struct rt2x00_
|
||||
cancel_work_sync(&rt2x00dev->intf_work);
|
||||
cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
|
||||
cancel_work_sync(&rt2x00dev->sleep_work);
|
||||
-#if IS_ENABLED(CPTCFG_RT2X00_LIB_USB)
|
||||
- if (rt2x00_is_usb(rt2x00dev)) {
|
||||
- usb_kill_anchored_urbs(rt2x00dev->anchor);
|
||||
- hrtimer_cancel(&rt2x00dev->txstatus_timer);
|
||||
- cancel_work_sync(&rt2x00dev->rxdone_work);
|
||||
- cancel_work_sync(&rt2x00dev->txdone_work);
|
||||
- }
|
||||
-#endif
|
||||
- if (rt2x00dev->workqueue)
|
||||
- destroy_workqueue(rt2x00dev->workqueue);
|
||||
-
|
||||
- /*
|
||||
- * Free the tx status fifo.
|
||||
- */
|
||||
- kfifo_free(&rt2x00dev->txstatus_fifo);
|
||||
|
||||
/*
|
||||
* Kill the tx status tasklet.
|
||||
@@ -1466,6 +1451,14 @@ void rt2x00lib_remove_dev(struct rt2x00_
|
||||
*/
|
||||
rt2x00lib_uninitialize(rt2x00dev);
|
||||
|
||||
+ if (rt2x00dev->workqueue)
|
||||
+ destroy_workqueue(rt2x00dev->workqueue);
|
||||
+
|
||||
+ /*
|
||||
+ * Free the tx status fifo.
|
||||
+ */
|
||||
+ kfifo_free(&rt2x00dev->txstatus_fifo);
|
||||
+
|
||||
/*
|
||||
* Free extra components
|
||||
*/
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
|
||||
@@ -744,6 +744,11 @@ void rt2x00usb_uninitialize(struct rt2x0
|
||||
{
|
||||
struct data_queue *queue;
|
||||
|
||||
+ usb_kill_anchored_urbs(rt2x00dev->anchor);
|
||||
+ hrtimer_cancel(&rt2x00dev->txstatus_timer);
|
||||
+ cancel_work_sync(&rt2x00dev->rxdone_work);
|
||||
+ cancel_work_sync(&rt2x00dev->txdone_work);
|
||||
+
|
||||
queue_for_each(rt2x00dev, queue)
|
||||
rt2x00usb_free_entries(queue);
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
From 93c7018ec16bb83399dd4db61c361a6d6aba0d5a Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 8 Feb 2017 12:18:09 +0100
|
||||
Subject: [PATCH 02/19] rt2x00usb: do not anchor rx and tx urb's
|
||||
|
||||
We might kill TX or RX urb during rt2x00usb_flush_entry(), what can
|
||||
cause anchor list corruption like shown below:
|
||||
|
||||
[ 2074.035633] WARNING: CPU: 2 PID: 14480 at lib/list_debug.c:33 __list_add+0xac/0xc0
|
||||
[ 2074.035634] list_add corruption. prev->next should be next (ffff88020f362c28), but was dead000000000100. (prev=ffff8801d161bb70).
|
||||
<snip>
|
||||
[ 2074.035670] Call Trace:
|
||||
[ 2074.035672] [<ffffffff813bde47>] dump_stack+0x63/0x8c
|
||||
[ 2074.035674] [<ffffffff810a2231>] __warn+0xd1/0xf0
|
||||
[ 2074.035676] [<ffffffff810a22af>] warn_slowpath_fmt+0x5f/0x80
|
||||
[ 2074.035678] [<ffffffffa073855d>] ? rt2x00usb_register_write_lock+0x3d/0x60 [rt2800usb]
|
||||
[ 2074.035679] [<ffffffff813dbe4c>] __list_add+0xac/0xc0
|
||||
[ 2074.035681] [<ffffffff81591c6c>] usb_anchor_urb+0x4c/0xa0
|
||||
[ 2074.035683] [<ffffffffa07322af>] rt2x00usb_kick_rx_entry+0xaf/0x100 [rt2x00usb]
|
||||
[ 2074.035684] [<ffffffffa0732322>] rt2x00usb_clear_entry+0x22/0x30 [rt2x00usb]
|
||||
|
||||
To fix do not anchor TX and RX urb's, it is not needed as during
|
||||
shutdown we kill those urbs in rt2x00usb_free_entries().
|
||||
|
||||
Cc: Vishal Thanki <vishalthanki@gmail.com>
|
||||
Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB")
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 4 ----
|
||||
1 file changed, 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
|
||||
@@ -319,10 +319,8 @@ static bool rt2x00usb_kick_tx_entry(stru
|
||||
entry->skb->data, length,
|
||||
rt2x00usb_interrupt_txdone, entry);
|
||||
|
||||
- usb_anchor_urb(entry_priv->urb, rt2x00dev->anchor);
|
||||
status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
|
||||
if (status) {
|
||||
- usb_unanchor_urb(entry_priv->urb);
|
||||
if (status == -ENODEV)
|
||||
clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
|
||||
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
|
||||
@@ -410,10 +408,8 @@ static bool rt2x00usb_kick_rx_entry(stru
|
||||
entry->skb->data, entry->skb->len,
|
||||
rt2x00usb_interrupt_rxdone, entry);
|
||||
|
||||
- usb_anchor_urb(entry_priv->urb, rt2x00dev->anchor);
|
||||
status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
|
||||
if (status) {
|
||||
- usb_unanchor_urb(entry_priv->urb);
|
||||
if (status == -ENODEV)
|
||||
clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
|
||||
set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
|
@ -1,70 +0,0 @@
|
||||
From 0488a6121dfe6cbd44de15ea3627913b7549a1e9 Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 8 Feb 2017 12:18:10 +0100
|
||||
Subject: [PATCH 03/19] rt2x00usb: fix anchor initialization
|
||||
|
||||
If device fail to initialize we can OOPS in rt2x00lib_remove_dev(), due
|
||||
to using uninitialized usb_anchor structure:
|
||||
|
||||
[ 855.435820] ieee80211 phy3: rt2x00usb_vendor_request: Error - Vendor Request 0x07 failed for offset 0x1000 with error -19
|
||||
[ 855.435826] ieee80211 phy3: rt2800_probe_rt: Error - Invalid RT chipset 0x0000, rev 0000 detected
|
||||
[ 855.435829] ieee80211 phy3: rt2x00lib_probe_dev: Error - Failed to allocate device
|
||||
[ 855.435845] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
|
||||
[ 855.435900] IP: _raw_spin_lock_irq+0xd/0x30
|
||||
[ 855.435926] PGD 0
|
||||
[ 855.435953] Oops: 0002 [#1] SMP
|
||||
<snip>
|
||||
[ 855.437011] Call Trace:
|
||||
[ 855.437029] ? usb_kill_anchored_urbs+0x27/0xc0
|
||||
[ 855.437061] rt2x00lib_remove_dev+0x190/0x1c0 [rt2x00lib]
|
||||
[ 855.437097] rt2x00lib_probe_dev+0x246/0x7a0 [rt2x00lib]
|
||||
[ 855.437149] ? ieee80211_roc_setup+0x9e/0xd0 [mac80211]
|
||||
[ 855.437183] ? __kmalloc+0x1af/0x1f0
|
||||
[ 855.437207] ? rt2x00usb_probe+0x13d/0xc50 [rt2x00usb]
|
||||
[ 855.437240] rt2x00usb_probe+0x155/0xc50 [rt2x00usb]
|
||||
[ 855.437273] rt2800usb_probe+0x15/0x20 [rt2800usb]
|
||||
[ 855.437304] usb_probe_interface+0x159/0x2d0
|
||||
[ 855.437333] driver_probe_device+0x2bb/0x460
|
||||
|
||||
Patch changes initialization sequence to fix the problem.
|
||||
|
||||
Cc: Vishal Thanki <vishalthanki@gmail.com>
|
||||
Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB")
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 13 ++++++++-----
|
||||
1 file changed, 8 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
|
||||
@@ -825,10 +825,6 @@ int rt2x00usb_probe(struct usb_interface
|
||||
if (retval)
|
||||
goto exit_free_device;
|
||||
|
||||
- retval = rt2x00lib_probe_dev(rt2x00dev);
|
||||
- if (retval)
|
||||
- goto exit_free_reg;
|
||||
-
|
||||
rt2x00dev->anchor = devm_kmalloc(&usb_dev->dev,
|
||||
sizeof(struct usb_anchor),
|
||||
GFP_KERNEL);
|
||||
@@ -836,10 +832,17 @@ int rt2x00usb_probe(struct usb_interface
|
||||
retval = -ENOMEM;
|
||||
goto exit_free_reg;
|
||||
}
|
||||
-
|
||||
init_usb_anchor(rt2x00dev->anchor);
|
||||
+
|
||||
+ retval = rt2x00lib_probe_dev(rt2x00dev);
|
||||
+ if (retval)
|
||||
+ goto exit_free_anchor;
|
||||
+
|
||||
return 0;
|
||||
|
||||
+exit_free_anchor:
|
||||
+ usb_kill_anchored_urbs(rt2x00dev->anchor);
|
||||
+
|
||||
exit_free_reg:
|
||||
rt2x00usb_free_reg(rt2x00dev);
|
||||
|
@ -1,23 +0,0 @@
|
||||
From 80a97eae304631f57ff8560f87c0b18b95321443 Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 8 Feb 2017 13:51:29 +0100
|
||||
Subject: [PATCH 04/19] rt61pci: use entry directly
|
||||
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt61pci.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
|
||||
@@ -1903,8 +1903,7 @@ static void rt61pci_write_tx_desc(struct
|
||||
|
||||
rt2x00_desc_read(txd, 5, &word);
|
||||
rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid);
|
||||
- rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE,
|
||||
- skbdesc->entry->entry_idx);
|
||||
+ rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx);
|
||||
rt2x00_set_field32(&word, TXD_W5_TX_POWER,
|
||||
TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power));
|
||||
rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1);
|
@ -1,158 +0,0 @@
|
||||
From 2ceb813798e1fd33e71a574771828c0f298e077b Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 8 Feb 2017 13:51:30 +0100
|
||||
Subject: [PATCH 05/19] rt2x00: call entry directly in rt2x00_dump_frame
|
||||
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2400pci.c | 2 +-
|
||||
drivers/net/wireless/ralink/rt2x00/rt2500pci.c | 2 +-
|
||||
drivers/net/wireless/ralink/rt2x00/rt2500usb.c | 2 +-
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +-
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 4 ++--
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00debug.c | 7 ++++---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 4 ++--
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 2 +-
|
||||
drivers/net/wireless/ralink/rt2x00/rt61pci.c | 2 +-
|
||||
drivers/net/wireless/ralink/rt2x00/rt73usb.c | 2 +-
|
||||
10 files changed, 15 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c
|
||||
@@ -1200,7 +1200,7 @@ static void rt2400pci_write_beacon(struc
|
||||
/*
|
||||
* Dump beacon to userspace through debugfs.
|
||||
*/
|
||||
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
|
||||
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
|
||||
out:
|
||||
/*
|
||||
* Enable beaconing again.
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c
|
||||
@@ -1349,7 +1349,7 @@ static void rt2500pci_write_beacon(struc
|
||||
/*
|
||||
* Dump beacon to userspace through debugfs.
|
||||
*/
|
||||
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
|
||||
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
|
||||
out:
|
||||
/*
|
||||
* Enable beaconing again.
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
|
||||
@@ -1170,7 +1170,7 @@ static void rt2500usb_write_beacon(struc
|
||||
/*
|
||||
* Dump beacon to userspace through debugfs.
|
||||
*/
|
||||
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
|
||||
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
|
||||
|
||||
/*
|
||||
* USB devices cannot blindly pass the skb->len as the
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -1014,7 +1014,7 @@ void rt2800_write_beacon(struct queue_en
|
||||
/*
|
||||
* Dump beacon to userspace through debugfs.
|
||||
*/
|
||||
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
|
||||
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
|
||||
|
||||
/*
|
||||
* Write entire beacon with TXWI and padding to register.
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
@@ -1400,11 +1400,11 @@ void rt2x00queue_flush_queues(struct rt2
|
||||
*/
|
||||
#ifdef CPTCFG_RT2X00_LIB_DEBUGFS
|
||||
void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
|
||||
- enum rt2x00_dump_type type, struct sk_buff *skb);
|
||||
+ enum rt2x00_dump_type type, struct queue_entry *entry);
|
||||
#else
|
||||
static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
|
||||
enum rt2x00_dump_type type,
|
||||
- struct sk_buff *skb)
|
||||
+ struct queue_entry *entry)
|
||||
{
|
||||
}
|
||||
#endif /* CPTCFG_RT2X00_LIB_DEBUGFS */
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
|
||||
@@ -157,9 +157,10 @@ void rt2x00debug_update_crypto(struct rt
|
||||
}
|
||||
|
||||
void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
|
||||
- enum rt2x00_dump_type type, struct sk_buff *skb)
|
||||
+ enum rt2x00_dump_type type, struct queue_entry *entry)
|
||||
{
|
||||
struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf;
|
||||
+ struct sk_buff *skb = entry->skb;
|
||||
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
|
||||
struct sk_buff *skbcopy;
|
||||
struct rt2x00dump_hdr *dump_hdr;
|
||||
@@ -196,8 +197,8 @@ void rt2x00debug_dump_frame(struct rt2x0
|
||||
dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf);
|
||||
dump_hdr->chip_rev = cpu_to_le16(rt2x00dev->chip.rev);
|
||||
dump_hdr->type = cpu_to_le16(type);
|
||||
- dump_hdr->queue_index = skbdesc->entry->queue->qid;
|
||||
- dump_hdr->entry_index = skbdesc->entry->entry_idx;
|
||||
+ dump_hdr->queue_index = entry->queue->qid;
|
||||
+ dump_hdr->entry_index = entry->entry_idx;
|
||||
dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec);
|
||||
dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec);
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -363,7 +363,7 @@ void rt2x00lib_txdone(struct queue_entry
|
||||
* Send frame to debugfs immediately, after this call is completed
|
||||
* we are going to overwrite the skb->cb array.
|
||||
*/
|
||||
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry->skb);
|
||||
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry);
|
||||
|
||||
/*
|
||||
* Determine if the frame has been successfully transmitted and
|
||||
@@ -772,7 +772,7 @@ void rt2x00lib_rxdone(struct queue_entry
|
||||
*/
|
||||
rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc);
|
||||
rt2x00debug_update_crypto(rt2x00dev, &rxdesc);
|
||||
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb);
|
||||
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry);
|
||||
|
||||
/*
|
||||
* Initialize RX status information, and send frame
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
|
||||
@@ -544,7 +544,7 @@ static void rt2x00queue_write_tx_descrip
|
||||
* All processing on the frame has been completed, this means
|
||||
* it is now ready to be dumped to userspace through debugfs.
|
||||
*/
|
||||
- rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb);
|
||||
+ rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry);
|
||||
}
|
||||
|
||||
static void rt2x00queue_kick_tx_queue(struct data_queue *queue,
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
|
||||
@@ -1988,7 +1988,7 @@ static void rt61pci_write_beacon(struct
|
||||
/*
|
||||
* Dump beacon to userspace through debugfs.
|
||||
*/
|
||||
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
|
||||
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
|
||||
|
||||
/*
|
||||
* Write entire beacon with descriptor and padding to register.
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c
|
||||
@@ -1557,7 +1557,7 @@ static void rt73usb_write_beacon(struct
|
||||
/*
|
||||
* Dump beacon to userspace through debugfs.
|
||||
*/
|
||||
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb);
|
||||
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry);
|
||||
|
||||
/*
|
||||
* Write entire beacon with descriptor and padding to register.
|
@ -1,52 +0,0 @@
|
||||
From cf81db30a6edcca791b1bfa5348a162471121d11 Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 8 Feb 2017 13:51:31 +0100
|
||||
Subject: [PATCH 06/19] rt2x00: remove queue_entry from skbdesc
|
||||
|
||||
queue_entry field of skbdesc is not read any more, remove it to allow
|
||||
skbdesc contain other data.
|
||||
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 3 ---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00queue.h | 2 --
|
||||
2 files changed, 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
|
||||
@@ -83,7 +83,6 @@ struct sk_buff *rt2x00queue_alloc_rxskb(
|
||||
*/
|
||||
skbdesc = get_skb_frame_desc(skb);
|
||||
memset(skbdesc, 0, sizeof(*skbdesc));
|
||||
- skbdesc->entry = entry;
|
||||
|
||||
if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_DMA)) {
|
||||
dma_addr_t skb_dma;
|
||||
@@ -689,7 +688,6 @@ int rt2x00queue_write_tx_frame(struct da
|
||||
goto out;
|
||||
}
|
||||
|
||||
- skbdesc->entry = entry;
|
||||
entry->skb = skb;
|
||||
|
||||
/*
|
||||
@@ -774,7 +772,6 @@ int rt2x00queue_update_beacon(struct rt2
|
||||
*/
|
||||
skbdesc = get_skb_frame_desc(intf->beacon->skb);
|
||||
memset(skbdesc, 0, sizeof(*skbdesc));
|
||||
- skbdesc->entry = intf->beacon;
|
||||
|
||||
/*
|
||||
* Send beacon to hardware.
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
|
||||
@@ -116,8 +116,6 @@ struct skb_frame_desc {
|
||||
__le32 iv[2];
|
||||
|
||||
dma_addr_t skb_dma;
|
||||
-
|
||||
- struct queue_entry *entry;
|
||||
};
|
||||
|
||||
/**
|
@ -1,79 +0,0 @@
|
||||
From 7272416609126e8910b7f0d0e3dba008aa87830c Mon Sep 17 00:00:00 2001
|
||||
From: Arnd Bergmann <arnd@arndb.de>
|
||||
Date: Tue, 14 Feb 2017 22:28:33 +0100
|
||||
Subject: [PATCH 07/19] rt2500usb: don't mark register accesses as inline
|
||||
|
||||
When CONFIG_KASAN is set, we get a rather large stack here:
|
||||
|
||||
drivers/net/wireless/ralink/rt2x00/rt2500usb.c: In function 'rt2500usb_set_device_state':
|
||||
drivers/net/wireless/ralink/rt2x00/rt2500usb.c:1074:1: error: the frame size of 3032 bytes is larger than 100 bytes [-Werror=frame-larger-than=]
|
||||
|
||||
If we don't force those functions to be inline, the compiler can figure this
|
||||
out better itself and not inline the functions when doing so would be harmful,
|
||||
reducing the stack size to a merge 256 bytes.
|
||||
|
||||
Note that there is another problem that manifests in this driver, as a result
|
||||
of the typecheck() macro causing even larger stack frames.
|
||||
|
||||
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2500usb.c | 19 +++++--------------
|
||||
1 file changed, 5 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c
|
||||
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(nohwcrypt, "Disable har
|
||||
* If the csr_mutex is already held then the _lock variants must
|
||||
* be used instead.
|
||||
*/
|
||||
-static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
|
||||
+static void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned int offset,
|
||||
u16 *value)
|
||||
{
|
||||
@@ -66,7 +66,7 @@ static inline void rt2500usb_register_re
|
||||
*value = le16_to_cpu(reg);
|
||||
}
|
||||
|
||||
-static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
|
||||
+static void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned int offset,
|
||||
u16 *value)
|
||||
{
|
||||
@@ -77,16 +77,7 @@ static inline void rt2500usb_register_re
|
||||
*value = le16_to_cpu(reg);
|
||||
}
|
||||
|
||||
-static inline void rt2500usb_register_multiread(struct rt2x00_dev *rt2x00dev,
|
||||
- const unsigned int offset,
|
||||
- void *value, const u16 length)
|
||||
-{
|
||||
- rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ,
|
||||
- USB_VENDOR_REQUEST_IN, offset,
|
||||
- value, length);
|
||||
-}
|
||||
-
|
||||
-static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
|
||||
+static void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned int offset,
|
||||
u16 value)
|
||||
{
|
||||
@@ -96,7 +87,7 @@ static inline void rt2500usb_register_wr
|
||||
®, sizeof(reg));
|
||||
}
|
||||
|
||||
-static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
|
||||
+static void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned int offset,
|
||||
u16 value)
|
||||
{
|
||||
@@ -106,7 +97,7 @@ static inline void rt2500usb_register_wr
|
||||
®, sizeof(reg), REGISTER_TIMEOUT);
|
||||
}
|
||||
|
||||
-static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
|
||||
+static void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned int offset,
|
||||
void *value, const u16 length)
|
||||
{
|
@ -1,87 +0,0 @@
|
||||
From 96609f366c6f792421e1939c5c834abbe24eb88a Mon Sep 17 00:00:00 2001
|
||||
From: Gabor Juhos <juhosg@openwrt.org>
|
||||
Date: Wed, 15 Feb 2017 10:25:04 +0100
|
||||
Subject: [PATCH 08/19] rt2x00: rt2800lib: move rt2800_drv_data declaration
|
||||
into rt2800lib.h
|
||||
|
||||
The rt2800_drv_data structure contains driver specific
|
||||
information. Move the declaration into the rt2800lib.h
|
||||
header which is a more logical place for it. Also fix
|
||||
the comment style to avoid checkpatch warning.
|
||||
|
||||
The patch contains no functional changes, it is in
|
||||
preparation for the next patch.
|
||||
|
||||
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800.h | 25 -------------------------
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 23 +++++++++++++++++++++++
|
||||
2 files changed, 23 insertions(+), 25 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
@@ -2987,29 +2987,4 @@ enum rt2800_eeprom_word {
|
||||
*/
|
||||
#define BCN_TBTT_OFFSET 64
|
||||
|
||||
-/*
|
||||
- * Hardware has 255 WCID table entries. First 32 entries are reserved for
|
||||
- * shared keys. Since parts of the pairwise key table might be shared with
|
||||
- * the beacon frame buffers 6 & 7 we could only use the first 222 entries.
|
||||
- */
|
||||
-#define WCID_START 33
|
||||
-#define WCID_END 222
|
||||
-#define STA_IDS_SIZE (WCID_END - WCID_START + 2)
|
||||
-
|
||||
-/*
|
||||
- * RT2800 driver data structure
|
||||
- */
|
||||
-struct rt2800_drv_data {
|
||||
- u8 calibration_bw20;
|
||||
- u8 calibration_bw40;
|
||||
- u8 bbp25;
|
||||
- u8 bbp26;
|
||||
- u8 txmixer_gain_24g;
|
||||
- u8 txmixer_gain_5g;
|
||||
- u8 max_psdu;
|
||||
- unsigned int tbtt_tick;
|
||||
- unsigned int ampdu_factor_cnt[4];
|
||||
- DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
|
||||
-};
|
||||
-
|
||||
#endif /* RT2800_H */
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
@@ -20,6 +20,29 @@
|
||||
#ifndef RT2800LIB_H
|
||||
#define RT2800LIB_H
|
||||
|
||||
+/*
|
||||
+ * Hardware has 255 WCID table entries. First 32 entries are reserved for
|
||||
+ * shared keys. Since parts of the pairwise key table might be shared with
|
||||
+ * the beacon frame buffers 6 & 7 we could only use the first 222 entries.
|
||||
+ */
|
||||
+#define WCID_START 33
|
||||
+#define WCID_END 222
|
||||
+#define STA_IDS_SIZE (WCID_END - WCID_START + 2)
|
||||
+
|
||||
+/* RT2800 driver data structure */
|
||||
+struct rt2800_drv_data {
|
||||
+ u8 calibration_bw20;
|
||||
+ u8 calibration_bw40;
|
||||
+ u8 bbp25;
|
||||
+ u8 bbp26;
|
||||
+ u8 txmixer_gain_24g;
|
||||
+ u8 txmixer_gain_5g;
|
||||
+ u8 max_psdu;
|
||||
+ unsigned int tbtt_tick;
|
||||
+ unsigned int ampdu_factor_cnt[4];
|
||||
+ DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
|
||||
+};
|
||||
+
|
||||
struct rt2800_ops {
|
||||
void (*register_read)(struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned int offset, u32 *value);
|
@ -1,85 +0,0 @@
|
||||
From a13d985f26f6df07d5c5c0e190477628e236babc Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 15 Feb 2017 10:25:05 +0100
|
||||
Subject: [PATCH 09/19] rt2800: identify station based on status WCID
|
||||
|
||||
Add framework to identify sta based on tx status WCID. This is currently
|
||||
not used, will start be utilized in the future patch.
|
||||
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 +++++
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 1 +
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00queue.h | 3 ++-
|
||||
3 files changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -855,11 +855,13 @@ EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
|
||||
void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
+ struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
|
||||
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||
struct txdone_entry_desc txdesc;
|
||||
u32 word;
|
||||
u16 mcs, real_mcs;
|
||||
int aggr, ampdu;
|
||||
+ int wcid;
|
||||
|
||||
/*
|
||||
* Obtain the status about this packet.
|
||||
@@ -872,6 +874,7 @@ void rt2800_txdone_entry(struct queue_en
|
||||
|
||||
real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS);
|
||||
aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE);
|
||||
+ wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID);
|
||||
|
||||
/*
|
||||
* If a frame was meant to be sent as a single non-aggregated MPDU
|
||||
@@ -1468,6 +1471,7 @@ int rt2800_sta_add(struct rt2x00_dev *rt
|
||||
return 0;
|
||||
|
||||
__set_bit(wcid - WCID_START, drv_data->sta_ids);
|
||||
+ drv_data->wcid_to_sta[wcid - WCID_START] = sta;
|
||||
|
||||
/*
|
||||
* Clean up WCID attributes and write STA address to the device.
|
||||
@@ -1498,6 +1502,7 @@ int rt2800_sta_remove(struct rt2x00_dev
|
||||
* get renewed when the WCID is reused.
|
||||
*/
|
||||
rt2800_config_wcid(rt2x00dev, NULL, wcid);
|
||||
+ drv_data->wcid_to_sta[wcid - WCID_START] = NULL;
|
||||
__clear_bit(wcid - WCID_START, drv_data->sta_ids);
|
||||
|
||||
return 0;
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
@@ -41,6 +41,7 @@ struct rt2800_drv_data {
|
||||
unsigned int tbtt_tick;
|
||||
unsigned int ampdu_factor_cnt[4];
|
||||
DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
|
||||
+ struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE];
|
||||
};
|
||||
|
||||
struct rt2800_ops {
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
|
||||
@@ -102,7 +102,7 @@ enum skb_frame_desc_flags {
|
||||
* of the scope of the skb->data pointer.
|
||||
* @iv: IV/EIV data used during encryption/decryption.
|
||||
* @skb_dma: (PCI-only) the DMA address associated with the sk buffer.
|
||||
- * @entry: The entry to which this sk buffer belongs.
|
||||
+ * @sta: The station where sk buffer was sent.
|
||||
*/
|
||||
struct skb_frame_desc {
|
||||
u8 flags;
|
||||
@@ -116,6 +116,7 @@ struct skb_frame_desc {
|
||||
__le32 iv[2];
|
||||
|
||||
dma_addr_t skb_dma;
|
||||
+ struct ieee80211_sta *sta;
|
||||
};
|
||||
|
||||
/**
|
@ -1,173 +0,0 @@
|
||||
From 5edb05afebba8f488a30db29550e55c42eea6d6a Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 15 Feb 2017 10:25:06 +0100
|
||||
Subject: [PATCH 10/19] rt2x00: separte filling tx status from rt2x00lib_txdone
|
||||
|
||||
This makes rt2x00lib_txdone a bit simpler and will allow to reuse code
|
||||
in different variant of txdone which I'm preparing.
|
||||
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 141 +++++++++++++------------
|
||||
1 file changed, 76 insertions(+), 65 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -313,73 +313,14 @@ static inline int rt2x00lib_txdone_bar_s
|
||||
return ret;
|
||||
}
|
||||
|
||||
-void rt2x00lib_txdone(struct queue_entry *entry,
|
||||
- struct txdone_entry_desc *txdesc)
|
||||
+static void rt2x00lib_fill_tx_status(struct rt2x00_dev *rt2x00dev,
|
||||
+ struct ieee80211_tx_info *tx_info,
|
||||
+ struct skb_frame_desc *skbdesc,
|
||||
+ struct txdone_entry_desc *txdesc,
|
||||
+ bool success)
|
||||
{
|
||||
- struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
|
||||
- struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||
- unsigned int header_length, i;
|
||||
u8 rate_idx, rate_flags, retry_rates;
|
||||
- u8 skbdesc_flags = skbdesc->flags;
|
||||
- bool success;
|
||||
-
|
||||
- /*
|
||||
- * Unmap the skb.
|
||||
- */
|
||||
- rt2x00queue_unmap_skb(entry);
|
||||
-
|
||||
- /*
|
||||
- * Remove the extra tx headroom from the skb.
|
||||
- */
|
||||
- skb_pull(entry->skb, rt2x00dev->extra_tx_headroom);
|
||||
-
|
||||
- /*
|
||||
- * Signal that the TX descriptor is no longer in the skb.
|
||||
- */
|
||||
- skbdesc->flags &= ~SKBDESC_DESC_IN_SKB;
|
||||
-
|
||||
- /*
|
||||
- * Determine the length of 802.11 header.
|
||||
- */
|
||||
- header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
|
||||
-
|
||||
- /*
|
||||
- * Remove L2 padding which was added during
|
||||
- */
|
||||
- if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_L2PAD))
|
||||
- rt2x00queue_remove_l2pad(entry->skb, header_length);
|
||||
-
|
||||
- /*
|
||||
- * If the IV/EIV data was stripped from the frame before it was
|
||||
- * passed to the hardware, we should now reinsert it again because
|
||||
- * mac80211 will expect the same data to be present it the
|
||||
- * frame as it was passed to us.
|
||||
- */
|
||||
- if (rt2x00_has_cap_hw_crypto(rt2x00dev))
|
||||
- rt2x00crypto_tx_insert_iv(entry->skb, header_length);
|
||||
-
|
||||
- /*
|
||||
- * Send frame to debugfs immediately, after this call is completed
|
||||
- * we are going to overwrite the skb->cb array.
|
||||
- */
|
||||
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry);
|
||||
-
|
||||
- /*
|
||||
- * Determine if the frame has been successfully transmitted and
|
||||
- * remove BARs from our check list while checking for their
|
||||
- * TX status.
|
||||
- */
|
||||
- success =
|
||||
- rt2x00lib_txdone_bar_status(entry) ||
|
||||
- test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
|
||||
- test_bit(TXDONE_UNKNOWN, &txdesc->flags);
|
||||
-
|
||||
- /*
|
||||
- * Update TX statistics.
|
||||
- */
|
||||
- rt2x00dev->link.qual.tx_success += success;
|
||||
- rt2x00dev->link.qual.tx_failed += !success;
|
||||
+ int i;
|
||||
|
||||
rate_idx = skbdesc->tx_rate_idx;
|
||||
rate_flags = skbdesc->tx_rate_flags;
|
||||
@@ -448,6 +389,76 @@ void rt2x00lib_txdone(struct queue_entry
|
||||
else
|
||||
rt2x00dev->low_level_stats.dot11RTSFailureCount++;
|
||||
}
|
||||
+}
|
||||
+
|
||||
+void rt2x00lib_txdone(struct queue_entry *entry,
|
||||
+ struct txdone_entry_desc *txdesc)
|
||||
+{
|
||||
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
|
||||
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||
+ u8 skbdesc_flags = skbdesc->flags;
|
||||
+ unsigned int header_length;
|
||||
+ bool success;
|
||||
+
|
||||
+ /*
|
||||
+ * Unmap the skb.
|
||||
+ */
|
||||
+ rt2x00queue_unmap_skb(entry);
|
||||
+
|
||||
+ /*
|
||||
+ * Remove the extra tx headroom from the skb.
|
||||
+ */
|
||||
+ skb_pull(entry->skb, rt2x00dev->extra_tx_headroom);
|
||||
+
|
||||
+ /*
|
||||
+ * Signal that the TX descriptor is no longer in the skb.
|
||||
+ */
|
||||
+ skbdesc->flags &= ~SKBDESC_DESC_IN_SKB;
|
||||
+
|
||||
+ /*
|
||||
+ * Determine the length of 802.11 header.
|
||||
+ */
|
||||
+ header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
|
||||
+
|
||||
+ /*
|
||||
+ * Remove L2 padding which was added during
|
||||
+ */
|
||||
+ if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_L2PAD))
|
||||
+ rt2x00queue_remove_l2pad(entry->skb, header_length);
|
||||
+
|
||||
+ /*
|
||||
+ * If the IV/EIV data was stripped from the frame before it was
|
||||
+ * passed to the hardware, we should now reinsert it again because
|
||||
+ * mac80211 will expect the same data to be present it the
|
||||
+ * frame as it was passed to us.
|
||||
+ */
|
||||
+ if (rt2x00_has_cap_hw_crypto(rt2x00dev))
|
||||
+ rt2x00crypto_tx_insert_iv(entry->skb, header_length);
|
||||
+
|
||||
+ /*
|
||||
+ * Send frame to debugfs immediately, after this call is completed
|
||||
+ * we are going to overwrite the skb->cb array.
|
||||
+ */
|
||||
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry);
|
||||
+
|
||||
+ /*
|
||||
+ * Determine if the frame has been successfully transmitted and
|
||||
+ * remove BARs from our check list while checking for their
|
||||
+ * TX status.
|
||||
+ */
|
||||
+ success =
|
||||
+ rt2x00lib_txdone_bar_status(entry) ||
|
||||
+ test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
|
||||
+ test_bit(TXDONE_UNKNOWN, &txdesc->flags);
|
||||
+
|
||||
+ /*
|
||||
+ * Update TX statistics.
|
||||
+ */
|
||||
+ rt2x00dev->link.qual.tx_success += success;
|
||||
+ rt2x00dev->link.qual.tx_failed += !success;
|
||||
+
|
||||
+ rt2x00lib_fill_tx_status(rt2x00dev, tx_info, skbdesc, txdesc, success);
|
||||
|
||||
/*
|
||||
* Only send the status report to mac80211 when it's a frame
|
@ -1,83 +0,0 @@
|
||||
From 56646adf9cd60b488ddc5633a2d9aa1f30efa5db Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 15 Feb 2017 10:25:07 +0100
|
||||
Subject: [PATCH 11/19] rt2x00: separte clearing entry from rt2x00lib_txdone
|
||||
|
||||
This makes rt2x00lib_txdone a bit simpler and will allow to reuse
|
||||
code in different variant of txdone which I'm preparing.
|
||||
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 51 +++++++++++++++-----------
|
||||
1 file changed, 29 insertions(+), 22 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -391,6 +391,32 @@ static void rt2x00lib_fill_tx_status(str
|
||||
}
|
||||
}
|
||||
|
||||
+static void rt2x00lib_clear_entry(struct rt2x00_dev *rt2x00dev,
|
||||
+ struct queue_entry *entry)
|
||||
+{
|
||||
+ /*
|
||||
+ * Make this entry available for reuse.
|
||||
+ */
|
||||
+ entry->skb = NULL;
|
||||
+ entry->flags = 0;
|
||||
+
|
||||
+ rt2x00dev->ops->lib->clear_entry(entry);
|
||||
+
|
||||
+ rt2x00queue_index_inc(entry, Q_INDEX_DONE);
|
||||
+
|
||||
+ /*
|
||||
+ * If the data queue was below the threshold before the txdone
|
||||
+ * handler we must make sure the packet queue in the mac80211 stack
|
||||
+ * is reenabled when the txdone handler has finished. This has to be
|
||||
+ * serialized with rt2x00mac_tx(), otherwise we can wake up queue
|
||||
+ * before it was stopped.
|
||||
+ */
|
||||
+ spin_lock_bh(&entry->queue->tx_lock);
|
||||
+ if (!rt2x00queue_threshold(entry->queue))
|
||||
+ rt2x00queue_unpause_queue(entry->queue);
|
||||
+ spin_unlock_bh(&entry->queue->tx_lock);
|
||||
+}
|
||||
+
|
||||
void rt2x00lib_txdone(struct queue_entry *entry,
|
||||
struct txdone_entry_desc *txdesc)
|
||||
{
|
||||
@@ -471,30 +497,11 @@ void rt2x00lib_txdone(struct queue_entry
|
||||
ieee80211_tx_status(rt2x00dev->hw, entry->skb);
|
||||
else
|
||||
ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb);
|
||||
- } else
|
||||
+ } else {
|
||||
dev_kfree_skb_any(entry->skb);
|
||||
+ }
|
||||
|
||||
- /*
|
||||
- * Make this entry available for reuse.
|
||||
- */
|
||||
- entry->skb = NULL;
|
||||
- entry->flags = 0;
|
||||
-
|
||||
- rt2x00dev->ops->lib->clear_entry(entry);
|
||||
-
|
||||
- rt2x00queue_index_inc(entry, Q_INDEX_DONE);
|
||||
-
|
||||
- /*
|
||||
- * If the data queue was below the threshold before the txdone
|
||||
- * handler we must make sure the packet queue in the mac80211 stack
|
||||
- * is reenabled when the txdone handler has finished. This has to be
|
||||
- * serialized with rt2x00mac_tx(), otherwise we can wake up queue
|
||||
- * before it was stopped.
|
||||
- */
|
||||
- spin_lock_bh(&entry->queue->tx_lock);
|
||||
- if (!rt2x00queue_threshold(entry->queue))
|
||||
- rt2x00queue_unpause_queue(entry->queue);
|
||||
- spin_unlock_bh(&entry->queue->tx_lock);
|
||||
+ rt2x00lib_clear_entry(rt2x00dev, entry);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
|
||||
|
@ -1,85 +0,0 @@
|
||||
From a09305d052166cb489402a63a5d275e954e0b923 Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 15 Feb 2017 10:25:08 +0100
|
||||
Subject: [PATCH 12/19] rt2x00: add txdone nomatch function
|
||||
|
||||
This txdone nomatch function will be used when we get status from the HW,
|
||||
but we could not match it with any sent skb.
|
||||
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 2 ++
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 50 ++++++++++++++++++++++++++
|
||||
2 files changed, 52 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
@@ -1425,6 +1425,8 @@ void rt2x00lib_dmastart(struct queue_ent
|
||||
void rt2x00lib_dmadone(struct queue_entry *entry);
|
||||
void rt2x00lib_txdone(struct queue_entry *entry,
|
||||
struct txdone_entry_desc *txdesc);
|
||||
+void rt2x00lib_txdone_nomatch(struct queue_entry *entry,
|
||||
+ struct txdone_entry_desc *txdesc);
|
||||
void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status);
|
||||
void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp);
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -417,6 +417,56 @@ static void rt2x00lib_clear_entry(struct
|
||||
spin_unlock_bh(&entry->queue->tx_lock);
|
||||
}
|
||||
|
||||
+void rt2x00lib_txdone_nomatch(struct queue_entry *entry,
|
||||
+ struct txdone_entry_desc *txdesc)
|
||||
+{
|
||||
+ struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
+ struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||
+ struct ieee80211_tx_info txinfo = {};
|
||||
+ bool success;
|
||||
+
|
||||
+ /*
|
||||
+ * Unmap the skb.
|
||||
+ */
|
||||
+ rt2x00queue_unmap_skb(entry);
|
||||
+
|
||||
+ /*
|
||||
+ * Signal that the TX descriptor is no longer in the skb.
|
||||
+ */
|
||||
+ skbdesc->flags &= ~SKBDESC_DESC_IN_SKB;
|
||||
+
|
||||
+ /*
|
||||
+ * Send frame to debugfs immediately, after this call is completed
|
||||
+ * we are going to overwrite the skb->cb array.
|
||||
+ */
|
||||
+ rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TXDONE, entry);
|
||||
+
|
||||
+ /*
|
||||
+ * Determine if the frame has been successfully transmitted and
|
||||
+ * remove BARs from our check list while checking for their
|
||||
+ * TX status.
|
||||
+ */
|
||||
+ success =
|
||||
+ rt2x00lib_txdone_bar_status(entry) ||
|
||||
+ test_bit(TXDONE_SUCCESS, &txdesc->flags);
|
||||
+
|
||||
+ if (!test_bit(TXDONE_UNKNOWN, &txdesc->flags)) {
|
||||
+ /*
|
||||
+ * Update TX statistics.
|
||||
+ */
|
||||
+ rt2x00dev->link.qual.tx_success += success;
|
||||
+ rt2x00dev->link.qual.tx_failed += !success;
|
||||
+
|
||||
+ rt2x00lib_fill_tx_status(rt2x00dev, &txinfo, skbdesc, txdesc,
|
||||
+ success);
|
||||
+ ieee80211_tx_status_noskb(rt2x00dev->hw, skbdesc->sta, &txinfo);
|
||||
+ }
|
||||
+
|
||||
+ dev_kfree_skb_any(entry->skb);
|
||||
+ rt2x00lib_clear_entry(rt2x00dev, entry);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(rt2x00lib_txdone_nomatch);
|
||||
+
|
||||
void rt2x00lib_txdone(struct queue_entry *entry,
|
||||
struct txdone_entry_desc *txdesc)
|
||||
{
|
@ -1,47 +0,0 @@
|
||||
From ec80ad70d778af7665992672896633ebd3b02ac8 Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 15 Feb 2017 10:25:09 +0100
|
||||
Subject: [PATCH 13/19] rt2x00: fixup fill_tx_status for nomatch case
|
||||
|
||||
Add bits rt2x00lib_fill_tx_status() when filling status in nomatch
|
||||
case and hopefully do not break the function for existing cases.
|
||||
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 6 +++++-
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00queue.h | 1 +
|
||||
2 files changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -357,6 +357,9 @@ static void rt2x00lib_fill_tx_status(str
|
||||
if (i < (IEEE80211_TX_MAX_RATES - 1))
|
||||
tx_info->status.rates[i].idx = -1; /* terminate */
|
||||
|
||||
+ if (test_bit(TXDONE_NO_ACK_REQ, &txdesc->flags))
|
||||
+ tx_info->flags |= IEEE80211_TX_CTL_NO_ACK;
|
||||
+
|
||||
if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
|
||||
if (success)
|
||||
tx_info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
@@ -375,7 +378,8 @@ static void rt2x00lib_fill_tx_status(str
|
||||
*/
|
||||
if (test_bit(TXDONE_AMPDU, &txdesc->flags) ||
|
||||
tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
|
||||
- tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
|
||||
+ tx_info->flags |= IEEE80211_TX_STAT_AMPDU |
|
||||
+ IEEE80211_TX_CTL_AMPDU;
|
||||
tx_info->status.ampdu_len = 1;
|
||||
tx_info->status.ampdu_ack_len = success ? 1 : 0;
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h
|
||||
@@ -215,6 +215,7 @@ enum txdone_entry_desc_flags {
|
||||
TXDONE_FAILURE,
|
||||
TXDONE_EXCESSIVE_RETRY,
|
||||
TXDONE_AMPDU,
|
||||
+ TXDONE_NO_ACK_REQ,
|
||||
};
|
||||
|
||||
/**
|
@ -1,180 +0,0 @@
|
||||
From 293dff78ee058ec1e0b90e05a803c512b6a2097f Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 15 Feb 2017 10:25:10 +0100
|
||||
Subject: [PATCH 14/19] rt2x00: use txdone_nomatch on rt2800usb
|
||||
|
||||
If we do not match skb entry, provide tx status via nomatch procedure.
|
||||
|
||||
Currently in that case we do rt2x00lib_txdone_noinfo(TXDONE_NOINFO),
|
||||
which actually assume that entry->skb was posted without retries and
|
||||
provide rate saved in skb desc as successful. Patch changed that to
|
||||
rate read from TX_STAT_FIFO, however still do not provide correct
|
||||
number of retries.
|
||||
|
||||
On SoC/PCI devices we keep providing status via standard txdone
|
||||
procedure, no change in those devices, though we should thing about it.
|
||||
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 31 ++++++++++++++++++++-----
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 3 ++-
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 2 +-
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800usb.c | 18 ++++++--------
|
||||
4 files changed, 35 insertions(+), 19 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -852,7 +852,8 @@ void rt2800_process_rxwi(struct queue_en
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
|
||||
|
||||
-void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
|
||||
+void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
|
||||
+ bool match)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
|
||||
@@ -860,8 +861,7 @@ void rt2800_txdone_entry(struct queue_en
|
||||
struct txdone_entry_desc txdesc;
|
||||
u32 word;
|
||||
u16 mcs, real_mcs;
|
||||
- int aggr, ampdu;
|
||||
- int wcid;
|
||||
+ int aggr, ampdu, wcid, ack_req;
|
||||
|
||||
/*
|
||||
* Obtain the status about this packet.
|
||||
@@ -875,6 +875,7 @@ void rt2800_txdone_entry(struct queue_en
|
||||
real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS);
|
||||
aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE);
|
||||
wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID);
|
||||
+ ack_req = rt2x00_get_field32(status, TX_STA_FIFO_TX_ACK_REQUIRED);
|
||||
|
||||
/*
|
||||
* If a frame was meant to be sent as a single non-aggregated MPDU
|
||||
@@ -891,8 +892,12 @@ void rt2800_txdone_entry(struct queue_en
|
||||
* Hence, replace the requested rate with the real tx rate to not
|
||||
* confuse the rate control algortihm by providing clearly wrong
|
||||
* data.
|
||||
- */
|
||||
- if (unlikely(aggr == 1 && ampdu == 0 && real_mcs != mcs)) {
|
||||
+ *
|
||||
+ * FIXME: if we do not find matching entry, we tell that frame was
|
||||
+ * posted without any retries. We need to find a way to fix that
|
||||
+ * and provide retry count.
|
||||
+ */
|
||||
+ if (unlikely((aggr == 1 && ampdu == 0 && real_mcs != mcs)) || !match) {
|
||||
skbdesc->tx_rate_idx = real_mcs;
|
||||
mcs = real_mcs;
|
||||
}
|
||||
@@ -900,6 +905,9 @@ void rt2800_txdone_entry(struct queue_en
|
||||
if (aggr == 1 || ampdu == 1)
|
||||
__set_bit(TXDONE_AMPDU, &txdesc.flags);
|
||||
|
||||
+ if (!ack_req)
|
||||
+ __set_bit(TXDONE_NO_ACK_REQ, &txdesc.flags);
|
||||
+
|
||||
/*
|
||||
* Ralink has a retry mechanism using a global fallback
|
||||
* table. We setup this fallback table to try the immediate
|
||||
@@ -931,7 +939,18 @@ void rt2800_txdone_entry(struct queue_en
|
||||
if (txdesc.retry)
|
||||
__set_bit(TXDONE_FALLBACK, &txdesc.flags);
|
||||
|
||||
- rt2x00lib_txdone(entry, &txdesc);
|
||||
+ if (!match) {
|
||||
+ /* RCU assures non-null sta will not be freed by mac80211. */
|
||||
+ rcu_read_lock();
|
||||
+ if (likely(wcid >= WCID_START && wcid <= WCID_END))
|
||||
+ skbdesc->sta = drv_data->wcid_to_sta[wcid - WCID_START];
|
||||
+ else
|
||||
+ skbdesc->sta = NULL;
|
||||
+ rt2x00lib_txdone_nomatch(entry, &txdesc);
|
||||
+ rcu_read_unlock();
|
||||
+ } else {
|
||||
+ rt2x00lib_txdone(entry, &txdesc);
|
||||
+ }
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
@@ -191,7 +191,8 @@ void rt2800_write_tx_data(struct queue_e
|
||||
struct txentry_desc *txdesc);
|
||||
void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc);
|
||||
|
||||
-void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32* txwi);
|
||||
+void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
|
||||
+ bool match);
|
||||
|
||||
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
|
||||
void rt2800_clear_beacon(struct queue_entry *entry);
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
|
||||
@@ -239,7 +239,7 @@ static bool rt2800mmio_txdone_release_en
|
||||
{
|
||||
if (test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) {
|
||||
rt2800_txdone_entry(entry, entry->status,
|
||||
- rt2800mmio_get_txwi(entry));
|
||||
+ rt2800mmio_get_txwi(entry), true);
|
||||
return false;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
|
||||
@@ -501,8 +501,7 @@ static int rt2800usb_get_tx_data_len(str
|
||||
/*
|
||||
* TX control handlers
|
||||
*/
|
||||
-static enum txdone_entry_desc_flags
|
||||
-rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
|
||||
+static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg)
|
||||
{
|
||||
__le32 *txwi;
|
||||
u32 word;
|
||||
@@ -515,7 +514,7 @@ rt2800usb_txdone_entry_check(struct queu
|
||||
* frame.
|
||||
*/
|
||||
if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
|
||||
- return TXDONE_FAILURE;
|
||||
+ return false;
|
||||
|
||||
wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID);
|
||||
ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED);
|
||||
@@ -537,10 +536,10 @@ rt2800usb_txdone_entry_check(struct queu
|
||||
rt2x00_dbg(entry->queue->rt2x00dev,
|
||||
"TX status report missed for queue %d entry %d\n",
|
||||
entry->queue->qid, entry->entry_idx);
|
||||
- return TXDONE_UNKNOWN;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
- return TXDONE_SUCCESS;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
|
||||
@@ -549,7 +548,7 @@ static void rt2800usb_txdone(struct rt2x
|
||||
struct queue_entry *entry;
|
||||
u32 reg;
|
||||
u8 qid;
|
||||
- enum txdone_entry_desc_flags done_status;
|
||||
+ bool match;
|
||||
|
||||
while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) {
|
||||
/*
|
||||
@@ -574,11 +573,8 @@ static void rt2800usb_txdone(struct rt2x
|
||||
break;
|
||||
}
|
||||
|
||||
- done_status = rt2800usb_txdone_entry_check(entry, reg);
|
||||
- if (likely(done_status == TXDONE_SUCCESS))
|
||||
- rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry));
|
||||
- else
|
||||
- rt2x00lib_txdone_noinfo(entry, done_status);
|
||||
+ match = rt2800usb_txdone_entry_check(entry, reg);
|
||||
+ rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry), match);
|
||||
}
|
||||
}
|
||||
|
@ -1,81 +0,0 @@
|
||||
From 9d7a7a4d2b02bcd30fb5fe4270278212353cc332 Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 15 Feb 2017 10:25:11 +0100
|
||||
Subject: [PATCH 15/19] rt2800: status based rate flags for nomatch case
|
||||
|
||||
We use skb_desc->tx_rate_flags from entry as rate[].flags even if
|
||||
skb does not match status. Patch corrects flags and also fixes
|
||||
mcs for legacy rates.
|
||||
|
||||
rt2800_rate_from_status() is based on Felix's mt76
|
||||
mt76x2_mac_process_tx_rate() function.
|
||||
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800.h | 2 ++
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 35 +++++++++++++++++++++++++-
|
||||
2 files changed, 36 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
@@ -1760,6 +1760,8 @@
|
||||
#define TX_STA_FIFO_WCID FIELD32(0x0000ff00)
|
||||
#define TX_STA_FIFO_SUCCESS_RATE FIELD32(0xffff0000)
|
||||
#define TX_STA_FIFO_MCS FIELD32(0x007f0000)
|
||||
+#define TX_STA_FIFO_BW FIELD32(0x00800000)
|
||||
+#define TX_STA_FIFO_SGI FIELD32(0x01000000)
|
||||
#define TX_STA_FIFO_PHYMODE FIELD32(0xc0000000)
|
||||
|
||||
/*
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -852,6 +852,39 @@ void rt2800_process_rxwi(struct queue_en
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
|
||||
|
||||
+static void rt2800_rate_from_status(struct skb_frame_desc *skbdesc,
|
||||
+ u32 status, enum nl80211_band band)
|
||||
+{
|
||||
+ u8 flags = 0;
|
||||
+ u8 idx = rt2x00_get_field32(status, TX_STA_FIFO_MCS);
|
||||
+
|
||||
+ switch (rt2x00_get_field32(status, TX_STA_FIFO_PHYMODE)) {
|
||||
+ case RATE_MODE_HT_GREENFIELD:
|
||||
+ flags |= IEEE80211_TX_RC_GREEN_FIELD;
|
||||
+ /* fall through */
|
||||
+ case RATE_MODE_HT_MIX:
|
||||
+ flags |= IEEE80211_TX_RC_MCS;
|
||||
+ break;
|
||||
+ case RATE_MODE_OFDM:
|
||||
+ if (band == NL80211_BAND_2GHZ)
|
||||
+ idx += 4;
|
||||
+ break;
|
||||
+ case RATE_MODE_CCK:
|
||||
+ if (idx >= 8)
|
||||
+ idx -= 8;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (rt2x00_get_field32(status, TX_STA_FIFO_BW))
|
||||
+ flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
|
||||
+
|
||||
+ if (rt2x00_get_field32(status, TX_STA_FIFO_SGI))
|
||||
+ flags |= IEEE80211_TX_RC_SHORT_GI;
|
||||
+
|
||||
+ skbdesc->tx_rate_idx = idx;
|
||||
+ skbdesc->tx_rate_flags = flags;
|
||||
+}
|
||||
+
|
||||
void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
|
||||
bool match)
|
||||
{
|
||||
@@ -898,7 +931,7 @@ void rt2800_txdone_entry(struct queue_en
|
||||
* and provide retry count.
|
||||
*/
|
||||
if (unlikely((aggr == 1 && ampdu == 0 && real_mcs != mcs)) || !match) {
|
||||
- skbdesc->tx_rate_idx = real_mcs;
|
||||
+ rt2800_rate_from_status(skbdesc, status, rt2x00dev->curr_band);
|
||||
mcs = real_mcs;
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
From fb47ada8dc3c30c8e7b415da155742b49536c61e Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 15 Feb 2017 10:25:12 +0100
|
||||
Subject: [PATCH 16/19] rt2800: use TXOP_BACKOFF for probe frames
|
||||
|
||||
Even if we do not set AMPDU bit in TXWI, device still can aggregate
|
||||
frame and send it with rate not corresponding to requested. That mean
|
||||
we can do not sent probe frames with requested rate. To prevent that
|
||||
use TXOP_BACKOFF for probe frames.
|
||||
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c
|
||||
@@ -372,15 +372,16 @@ static void rt2x00queue_create_tx_descri
|
||||
|
||||
/*
|
||||
* Determine IFS values
|
||||
- * - Use TXOP_BACKOFF for management frames except beacons
|
||||
+ * - Use TXOP_BACKOFF for probe and management frames except beacons
|
||||
* - Use TXOP_SIFS for fragment bursts
|
||||
* - Use TXOP_HTTXOP for everything else
|
||||
*
|
||||
* Note: rt2800 devices won't use CTS protection (if used)
|
||||
* for frames not transmitted with TXOP_HTTXOP
|
||||
*/
|
||||
- if (ieee80211_is_mgmt(hdr->frame_control) &&
|
||||
- !ieee80211_is_beacon(hdr->frame_control))
|
||||
+ if ((ieee80211_is_mgmt(hdr->frame_control) &&
|
||||
+ !ieee80211_is_beacon(hdr->frame_control)) ||
|
||||
+ (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE))
|
||||
txdesc->u.ht.txop = TXOP_BACKOFF;
|
||||
else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT))
|
||||
txdesc->u.ht.txop = TXOP_SIFS;
|
@ -1,23 +0,0 @@
|
||||
From dd35cc0896faff5ed9d22eac9ea4a1920e2eec0c Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 15 Feb 2017 10:25:13 +0100
|
||||
Subject: [PATCH 17/19] rt2x00: fix rt2x00debug_dump_frame comment
|
||||
|
||||
Reported-by: Jeroen Roovers <jer@airfi.aero>
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
@@ -1396,7 +1396,7 @@ void rt2x00queue_flush_queues(struct rt2
|
||||
* rt2x00debug_dump_frame - Dump a frame to userspace through debugfs.
|
||||
* @rt2x00dev: Pointer to &struct rt2x00_dev.
|
||||
* @type: The type of frame that is being dumped.
|
||||
- * @skb: The skb containing the frame to be dumped.
|
||||
+ * @entry: The queue entry containing the frame to be dumped.
|
||||
*/
|
||||
#ifdef CPTCFG_RT2X00_LIB_DEBUGFS
|
||||
void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
|
@ -1,32 +0,0 @@
|
||||
From 5ce33b603063f36272fcfb1b4a5fde69f46eca88 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Thu, 9 Mar 2017 00:54:22 +0100
|
||||
Subject: [PATCH 18/19] rt2x00: fix TX_PWR_CFG_4 register definition
|
||||
|
||||
Some of the macros used to describe the TX_PWR_CFG_4 register accidentally
|
||||
refer to TX_PWR_CFG_3, probably a copy&paste error. Fix that.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800.h | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
@@ -1171,10 +1171,10 @@
|
||||
#define TX_PWR_CFG_4_UKNOWN7 FIELD32(0x00000f00)
|
||||
#define TX_PWR_CFG_4_UKNOWN8 FIELD32(0x0000f000)
|
||||
/* bits for 3T devices */
|
||||
-#define TX_PWR_CFG_3_STBC4_CH0 FIELD32(0x0000000f)
|
||||
-#define TX_PWR_CFG_3_STBC4_CH1 FIELD32(0x000000f0)
|
||||
-#define TX_PWR_CFG_3_STBC6_CH0 FIELD32(0x00000f00)
|
||||
-#define TX_PWR_CFG_3_STBC6_CH1 FIELD32(0x0000f000)
|
||||
+#define TX_PWR_CFG_4_STBC4_CH0 FIELD32(0x0000000f)
|
||||
+#define TX_PWR_CFG_4_STBC4_CH1 FIELD32(0x000000f0)
|
||||
+#define TX_PWR_CFG_4_STBC6_CH0 FIELD32(0x00000f00)
|
||||
+#define TX_PWR_CFG_4_STBC6_CH1 FIELD32(0x0000f000)
|
||||
|
||||
/*
|
||||
* TX_PIN_CFG:
|
File diff suppressed because it is too large
Load Diff
@ -1,121 +0,0 @@
|
||||
From 1f242a3de702d5a19c479685d35b050837122724 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 10 Apr 2017 15:29:45 +0200
|
||||
Subject: [PATCH] rt2x00: reverse external PA capability flag logic
|
||||
|
||||
Consequently refer to external PA instead of inverting the logic and
|
||||
use an internal PA capability flag which is a bit confusing.
|
||||
Currently this is used for Rt3352 only, but MT7620A also allows for an
|
||||
external PA which will be supported by a follow up patch.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 40 +++++++++++++-------------
|
||||
drivers/net/wireless/ralink/rt2x00/rt2x00.h | 4 +--
|
||||
2 files changed, 22 insertions(+), 22 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -7014,9 +7014,9 @@ static void rt2800_init_rfcsr_3290(struc
|
||||
|
||||
static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
- int tx0_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX0,
|
||||
+ int tx0_ext_pa = test_bit(CAPABILITY_EXTERNAL_PA_TX0,
|
||||
&rt2x00dev->cap_flags);
|
||||
- int tx1_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX1,
|
||||
+ int tx1_ext_pa = test_bit(CAPABILITY_EXTERNAL_PA_TX1,
|
||||
&rt2x00dev->cap_flags);
|
||||
u8 rfcsr;
|
||||
|
||||
@@ -7056,9 +7056,9 @@ static void rt2800_init_rfcsr_3352(struc
|
||||
rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
|
||||
rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
|
||||
rfcsr = 0x01;
|
||||
- if (!tx0_int_pa)
|
||||
+ if (tx0_ext_pa)
|
||||
rt2x00_set_field8(&rfcsr, RFCSR34_TX0_EXT_PA, 1);
|
||||
- if (!tx1_int_pa)
|
||||
+ if (tx1_ext_pa)
|
||||
rt2x00_set_field8(&rfcsr, RFCSR34_TX1_EXT_PA, 1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 34, rfcsr);
|
||||
rt2800_rfcsr_write(rt2x00dev, 35, 0x03);
|
||||
@@ -7068,13 +7068,13 @@ static void rt2800_init_rfcsr_3352(struc
|
||||
rt2800_rfcsr_write(rt2x00dev, 39, 0xc5);
|
||||
rt2800_rfcsr_write(rt2x00dev, 40, 0x33);
|
||||
rfcsr = 0x52;
|
||||
- if (tx0_int_pa) {
|
||||
+ if (!tx0_ext_pa) {
|
||||
rt2x00_set_field8(&rfcsr, RFCSR41_BIT1, 1);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR41_BIT4, 1);
|
||||
}
|
||||
rt2800_rfcsr_write(rt2x00dev, 41, rfcsr);
|
||||
rfcsr = 0x52;
|
||||
- if (tx1_int_pa) {
|
||||
+ if (!tx1_ext_pa) {
|
||||
rt2x00_set_field8(&rfcsr, RFCSR42_BIT1, 1);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR42_BIT4, 1);
|
||||
}
|
||||
@@ -7087,19 +7087,19 @@ static void rt2800_init_rfcsr_3352(struc
|
||||
rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
|
||||
rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
|
||||
rfcsr = 0x2d;
|
||||
- if (!tx0_int_pa)
|
||||
+ if (tx0_ext_pa)
|
||||
rt2x00_set_field8(&rfcsr, RFCSR50_TX0_EXT_PA, 1);
|
||||
- if (!tx1_int_pa)
|
||||
+ if (tx1_ext_pa)
|
||||
rt2x00_set_field8(&rfcsr, RFCSR50_TX1_EXT_PA, 1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 50, rfcsr);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 51, (tx0_int_pa ? 0x7f : 0x52));
|
||||
- rt2800_rfcsr_write(rt2x00dev, 52, (tx0_int_pa ? 0x00 : 0xc0));
|
||||
- rt2800_rfcsr_write(rt2x00dev, 53, (tx0_int_pa ? 0x52 : 0xd2));
|
||||
- rt2800_rfcsr_write(rt2x00dev, 54, (tx0_int_pa ? 0x1b : 0xc0));
|
||||
- rt2800_rfcsr_write(rt2x00dev, 55, (tx1_int_pa ? 0x7f : 0x52));
|
||||
- rt2800_rfcsr_write(rt2x00dev, 56, (tx1_int_pa ? 0x00 : 0xc0));
|
||||
- rt2800_rfcsr_write(rt2x00dev, 57, (tx0_int_pa ? 0x52 : 0x49));
|
||||
- rt2800_rfcsr_write(rt2x00dev, 58, (tx1_int_pa ? 0x1b : 0xc0));
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 51, (tx0_ext_pa ? 0x52 : 0x7f));
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 52, (tx0_ext_pa ? 0xc0 : 0x00));
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 53, (tx0_ext_pa ? 0xd2 : 0x52));
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 54, (tx0_ext_pa ? 0xc0 : 0x1b));
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 55, (tx1_ext_pa ? 0x52 : 0x7f));
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 56, (tx1_ext_pa ? 0xc0 : 0x00));
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 57, (tx0_ext_pa ? 0x49 : 0x52));
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 58, (tx1_ext_pa ? 0xc0 : 0x1b));
|
||||
rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
|
||||
@@ -8782,13 +8782,13 @@ static int rt2800_init_eeprom(struct rt2
|
||||
rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3352)) {
|
||||
- if (!rt2x00_get_field16(eeprom,
|
||||
+ if (rt2x00_get_field16(eeprom,
|
||||
EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
|
||||
- __set_bit(CAPABILITY_INTERNAL_PA_TX0,
|
||||
+ __set_bit(CAPABILITY_EXTERNAL_PA_TX0,
|
||||
&rt2x00dev->cap_flags);
|
||||
- if (!rt2x00_get_field16(eeprom,
|
||||
+ if (rt2x00_get_field16(eeprom,
|
||||
EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352))
|
||||
- __set_bit(CAPABILITY_INTERNAL_PA_TX1,
|
||||
+ __set_bit(CAPABILITY_EXTERNAL_PA_TX1,
|
||||
&rt2x00dev->cap_flags);
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
@@ -719,8 +719,8 @@ enum rt2x00_capability_flags {
|
||||
CAPABILITY_DOUBLE_ANTENNA,
|
||||
CAPABILITY_BT_COEXIST,
|
||||
CAPABILITY_VCO_RECALIBRATION,
|
||||
- CAPABILITY_INTERNAL_PA_TX0,
|
||||
- CAPABILITY_INTERNAL_PA_TX1,
|
||||
+ CAPABILITY_EXTERNAL_PA_TX0,
|
||||
+ CAPABILITY_EXTERNAL_PA_TX1,
|
||||
};
|
||||
|
||||
/*
|
@ -1,49 +0,0 @@
|
||||
From 0109238d62a99ea779a7e28e21868118e7b8d69d Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 10 Apr 2017 14:28:14 +0200
|
||||
Subject: [PATCH 1/2] rt2800: fix LNA gain assignment for MT7620
|
||||
To: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Cc: Helmut Schaa <helmut.schaa@googlemail.com>,
|
||||
linux-wireless@vger.kernel.org,
|
||||
Kalle Valo <kvalo@codeaurora.org>
|
||||
|
||||
The base value used for MT7620 differs from Rt5392 which resulted in
|
||||
quite bad RX signal quality. Fix this by using the correct base value as
|
||||
well as the LNA calibration values for HT20.
|
||||
|
||||
Reported-by: Tom Psyborg <pozega.tomislav@gmail.com>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 18 ++++++++++++++++--
|
||||
1 file changed, 16 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -3806,11 +3806,25 @@ static void rt2800_config_channel(struct
|
||||
}
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5592) || rt2x00_rt(rt2x00dev, RT6352)) {
|
||||
+ reg = 0x10;
|
||||
+ if (!conf_is_ht40(conf)) {
|
||||
+ if (rt2x00_rt(rt2x00dev, RT6352) &&
|
||||
+ rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
|
||||
+ reg |= 0x5;
|
||||
+ } else {
|
||||
+ reg |= 0xa;
|
||||
+ }
|
||||
+ }
|
||||
rt2800_bbp_write(rt2x00dev, 195, 141);
|
||||
- rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a);
|
||||
+ rt2800_bbp_write(rt2x00dev, 196, reg);
|
||||
|
||||
/* AGC init */
|
||||
- reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2 * rt2x00dev->lna_gain;
|
||||
+ if (rt2x00_rt(rt2x00dev, RT6352))
|
||||
+ reg = 0x04;
|
||||
+ else
|
||||
+ reg = rf->channel <= 14 ? 0x1c : 0x24;
|
||||
+
|
||||
+ reg += 2 * rt2x00dev->lna_gain;
|
||||
rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
|
||||
|
||||
rt2800_iq_calibrate(rt2x00dev, rf->channel);
|
@ -1,29 +0,0 @@
|
||||
From feb608c7986c14bab153f31f8e96f251072e6578 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 10 Apr 2017 15:33:20 +0200
|
||||
Subject: [PATCH 2/2] rt2800: do VCO calibration after programming ALC
|
||||
To: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Cc: Helmut Schaa <helmut.schaa@googlemail.com>,
|
||||
linux-wireless@vger.kernel.org,
|
||||
Kalle Valo <kvalo@codeaurora.org>
|
||||
|
||||
Scanning fails if we don't do VCO calibration every time.
|
||||
The vendor driver duplicates the VCO calibration function into the
|
||||
channel switching logic, we can do the same with less duplication.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -3407,6 +3407,8 @@ static void rt2800_config_alc(struct rt2
|
||||
rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
|
||||
}
|
||||
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl);
|
||||
+
|
||||
+ rt2800_vco_calibration(rt2x00dev);
|
||||
}
|
||||
|
||||
static void rt2800_bbp_write_with_rx_chain(struct rt2x00_dev *rt2x00dev,
|
@ -1,45 +0,0 @@
|
||||
From 02c452f317b4a4d06c433c294e66896a389731c1 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 18 Apr 2017 11:09:53 +0200
|
||||
Subject: [PATCH] rt2800: fix mt7620 vco calibration registers
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
To: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Cc: Helmut Schaa <helmut.schaa@googlemail.com>,
|
||||
linux-wireless@vger.kernel.org,
|
||||
Kalle Valo <kvalo@codeaurora.org>,
|
||||
Tom Psyborg <pozega.tomislav@gmail.com>
|
||||
|
||||
Use register values from init LNA function instead of the ones from
|
||||
restore LNA function. Apply register values based on rx path
|
||||
configuration.
|
||||
|
||||
Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -4932,7 +4932,7 @@ void rt2800_vco_calibration(struct rt2x0
|
||||
rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT6352)) {
|
||||
- if (rt2x00dev->default_ant.tx_chain_num == 1) {
|
||||
+ if (rt2x00dev->default_ant.rx_chain_num == 1) {
|
||||
rt2800_bbp_write(rt2x00dev, 91, 0x07);
|
||||
rt2800_bbp_write(rt2x00dev, 95, 0x1A);
|
||||
rt2800_bbp_write(rt2x00dev, 195, 128);
|
||||
@@ -4953,8 +4953,8 @@ void rt2800_vco_calibration(struct rt2x0
|
||||
}
|
||||
|
||||
if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
|
||||
- rt2800_bbp_write(rt2x00dev, 75, 0x60);
|
||||
- rt2800_bbp_write(rt2x00dev, 76, 0x44);
|
||||
+ rt2800_bbp_write(rt2x00dev, 75, 0x68);
|
||||
+ rt2800_bbp_write(rt2x00dev, 76, 0x4C);
|
||||
rt2800_bbp_write(rt2x00dev, 79, 0x1C);
|
||||
rt2800_bbp_write(rt2x00dev, 80, 0x0C);
|
||||
rt2800_bbp_write(rt2x00dev, 82, 0xB6);
|
@ -1,36 +0,0 @@
|
||||
From c426cb0ed15ee12dfdc8c53ddd1449ac617023cf Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Tue, 18 Apr 2017 11:45:37 +0200
|
||||
Subject: [PATCH] rt2800: fix mt7620 E2 channel registers
|
||||
To: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Cc: Helmut Schaa <helmut.schaa@googlemail.com>,
|
||||
linux-wireless@vger.kernel.org,
|
||||
Kalle Valo <kvalo@codeaurora.org>,
|
||||
Tom Psyborg <pozega.tomislav@gmail.com>
|
||||
|
||||
From: Tomislav Požega <pozega.tomislav@gmail.com>
|
||||
|
||||
update RF register 47 and 54 values according to vendor driver
|
||||
|
||||
Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -8145,9 +8145,11 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3);
|
||||
rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
|
||||
rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x69);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 47, 0x67);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 47, 0x69);
|
||||
rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFF);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x20);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 54, 0x27);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 54, 0x20);
|
||||
rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
|
||||
rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xFF);
|
||||
rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x1C);
|
@ -1,15 +0,0 @@
|
||||
This is only needed for kernel < 2.6.29 and conflicts with kernel 4.4.42
|
||||
|
||||
--- a/backport-include/linux/cred.h
|
||||
+++ /dev/null
|
||||
@@ -1,10 +0,0 @@
|
||||
-#ifndef __BACKPORT_LINUX_CRED_H
|
||||
-#define __BACKPORT_LINUX_CRED_H
|
||||
-#include_next <linux/cred.h>
|
||||
-#include <linux/version.h>
|
||||
-
|
||||
-#ifndef current_user_ns
|
||||
-#define current_user_ns() (current->nsproxy->user_ns)
|
||||
-#endif
|
||||
-
|
||||
-#endif /* __BACKPORT_LINUX_CRED_H */
|
@ -1,11 +0,0 @@
|
||||
--- a/drivers/net/wireless/mac80211_hwsim.c
|
||||
+++ b/drivers/net/wireless/mac80211_hwsim.c
|
||||
@@ -2678,7 +2678,7 @@ static int mac80211_hwsim_new_radio(stru
|
||||
|
||||
tasklet_hrtimer_init(&data->beacon_timer,
|
||||
mac80211_hwsim_beacon,
|
||||
- CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS);
|
||||
+ CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
|
||||
|
||||
spin_lock_bh(&hwsim_radio_lock);
|
||||
list_add_tail(&data->list, &hwsim_radios);
|
@ -1,175 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 25 Jan 2017 12:57:05 +0100
|
||||
Subject: [PATCH] ath9k: rename tx_complete_work to hw_check_work
|
||||
|
||||
Also include common MAC alive check. This should make the hang checks
|
||||
more reliable for modes where beacons are not sent and is used as a
|
||||
starting point for further hang check improvements
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -108,7 +108,7 @@ int ath_descdma_setup(struct ath_softc *
|
||||
#define ATH_AGGR_MIN_QDEPTH 2
|
||||
/* minimum h/w qdepth for non-aggregated traffic */
|
||||
#define ATH_NON_AGGR_MIN_QDEPTH 8
|
||||
-#define ATH_TX_COMPLETE_POLL_INT 1000
|
||||
+#define ATH_HW_CHECK_POLL_INT 1000
|
||||
#define ATH_TXFIFO_DEPTH 8
|
||||
#define ATH_TX_ERROR 0x01
|
||||
|
||||
@@ -745,7 +745,7 @@ void ath9k_csa_update(struct ath_softc *
|
||||
#define ATH_PAPRD_TIMEOUT 100 /* msecs */
|
||||
#define ATH_PLL_WORK_INTERVAL 100
|
||||
|
||||
-void ath_tx_complete_poll_work(struct work_struct *work);
|
||||
+void ath_hw_check_work(struct work_struct *work);
|
||||
void ath_reset_work(struct work_struct *work);
|
||||
bool ath_hw_check(struct ath_softc *sc);
|
||||
void ath_hw_pll_work(struct work_struct *work);
|
||||
@@ -1053,7 +1053,7 @@ struct ath_softc {
|
||||
#ifdef CPTCFG_ATH9K_DEBUGFS
|
||||
struct ath9k_debug debug;
|
||||
#endif
|
||||
- struct delayed_work tx_complete_work;
|
||||
+ struct delayed_work hw_check_work;
|
||||
struct delayed_work hw_pll_work;
|
||||
struct timer_list sleep_timer;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -681,6 +681,7 @@ static int ath9k_init_softc(u16 devid, s
|
||||
INIT_WORK(&sc->hw_reset_work, ath_reset_work);
|
||||
INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
|
||||
INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
|
||||
+ INIT_DELAYED_WORK(&sc->hw_check_work, ath_hw_check_work);
|
||||
|
||||
ath9k_init_channel_context(sc);
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/link.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/link.c
|
||||
@@ -20,20 +20,13 @@
|
||||
* TX polling - checks if the TX engine is stuck somewhere
|
||||
* and issues a chip reset if so.
|
||||
*/
|
||||
-void ath_tx_complete_poll_work(struct work_struct *work)
|
||||
+static bool ath_tx_complete_check(struct ath_softc *sc)
|
||||
{
|
||||
- struct ath_softc *sc = container_of(work, struct ath_softc,
|
||||
- tx_complete_work.work);
|
||||
struct ath_txq *txq;
|
||||
int i;
|
||||
- bool needreset = false;
|
||||
-
|
||||
|
||||
- if (sc->tx99_state) {
|
||||
- ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
|
||||
- "skip tx hung detection on tx99\n");
|
||||
- return;
|
||||
- }
|
||||
+ if (sc->tx99_state)
|
||||
+ return true;
|
||||
|
||||
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
|
||||
txq = sc->tx.txq_map[i];
|
||||
@@ -41,25 +34,36 @@ void ath_tx_complete_poll_work(struct wo
|
||||
ath_txq_lock(sc, txq);
|
||||
if (txq->axq_depth) {
|
||||
if (txq->axq_tx_inprogress) {
|
||||
- needreset = true;
|
||||
ath_txq_unlock(sc, txq);
|
||||
- break;
|
||||
- } else {
|
||||
- txq->axq_tx_inprogress = true;
|
||||
+ goto reset;
|
||||
}
|
||||
+
|
||||
+ txq->axq_tx_inprogress = true;
|
||||
}
|
||||
ath_txq_unlock(sc, txq);
|
||||
}
|
||||
|
||||
- if (needreset) {
|
||||
- ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
|
||||
- "tx hung, resetting the chip\n");
|
||||
- ath9k_queue_reset(sc, RESET_TYPE_TX_HANG);
|
||||
+ return true;
|
||||
+
|
||||
+reset:
|
||||
+ ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
|
||||
+ "tx hung, resetting the chip\n");
|
||||
+ ath9k_queue_reset(sc, RESET_TYPE_TX_HANG);
|
||||
+ return false;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+void ath_hw_check_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct ath_softc *sc = container_of(work, struct ath_softc,
|
||||
+ hw_check_work.work);
|
||||
+
|
||||
+ if (!ath_hw_check(sc) ||
|
||||
+ !ath_tx_complete_check(sc))
|
||||
return;
|
||||
- }
|
||||
|
||||
- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
|
||||
- msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT));
|
||||
+ ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
|
||||
+ msecs_to_jiffies(ATH_HW_CHECK_POLL_INT));
|
||||
}
|
||||
|
||||
/*
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -181,7 +181,7 @@ void ath9k_ps_restore(struct ath_softc *
|
||||
static void __ath_cancel_work(struct ath_softc *sc)
|
||||
{
|
||||
cancel_work_sync(&sc->paprd_work);
|
||||
- cancel_delayed_work_sync(&sc->tx_complete_work);
|
||||
+ cancel_delayed_work_sync(&sc->hw_check_work);
|
||||
cancel_delayed_work_sync(&sc->hw_pll_work);
|
||||
|
||||
#ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT
|
||||
@@ -198,7 +198,8 @@ void ath_cancel_work(struct ath_softc *s
|
||||
|
||||
void ath_restart_work(struct ath_softc *sc)
|
||||
{
|
||||
- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
|
||||
+ ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
|
||||
+ ATH_HW_CHECK_POLL_INT);
|
||||
|
||||
if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah))
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work,
|
||||
@@ -2091,7 +2092,7 @@ void __ath9k_flush(struct ieee80211_hw *
|
||||
int timeout;
|
||||
bool drain_txq;
|
||||
|
||||
- cancel_delayed_work_sync(&sc->tx_complete_work);
|
||||
+ cancel_delayed_work_sync(&sc->hw_check_work);
|
||||
|
||||
if (ah->ah_flags & AH_UNPLUGGED) {
|
||||
ath_dbg(common, ANY, "Device has been unplugged!\n");
|
||||
@@ -2129,7 +2130,8 @@ void __ath9k_flush(struct ieee80211_hw *
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
|
||||
- ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
|
||||
+ ieee80211_queue_delayed_work(hw, &sc->hw_check_work,
|
||||
+ ATH_HW_CHECK_POLL_INT);
|
||||
}
|
||||
|
||||
static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
|
||||
--- a/drivers/net/wireless/ath/ath9k/xmit.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
|
||||
@@ -2916,8 +2916,6 @@ int ath_tx_init(struct ath_softc *sc, in
|
||||
return error;
|
||||
}
|
||||
|
||||
- INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
|
||||
-
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
error = ath_tx_edma_init(sc);
|
||||
|
@ -1,30 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 25 Jan 2017 12:58:17 +0100
|
||||
Subject: [PATCH] ath9k_hw: check if the chip failed to wake up
|
||||
|
||||
In an RFC patch, Sven Eckelmann and Simon Wunderlich reported:
|
||||
|
||||
"QCA 802.11n chips (especially AR9330/AR9340) sometimes end up in a
|
||||
state in which a read of AR_CFG always returns 0xdeadbeef.
|
||||
This should not happen when when the power_mode of the device is
|
||||
ATH9K_PM_AWAKE."
|
||||
|
||||
Include the check for the default register state in the existing MAC
|
||||
hang check.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -1624,6 +1624,10 @@ bool ath9k_hw_check_alive(struct ath_hw
|
||||
int count = 50;
|
||||
u32 reg, last_val;
|
||||
|
||||
+ /* Check if chip failed to wake up */
|
||||
+ if (REG_READ(ah, AR_CFG) == 0xdeadbeef)
|
||||
+ return false;
|
||||
+
|
||||
if (AR_SREV_9300(ah))
|
||||
return !ath9k_hw_detect_mac_hang(ah);
|
||||
|
@ -1,197 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 25 Jan 2017 15:10:37 +0100
|
||||
Subject: [PATCH] ath9k: fix race condition in enabling/disabling IRQs
|
||||
|
||||
The code currently relies on refcounting to disable IRQs from within the
|
||||
IRQ handler and re-enabling them again after the tasklet has run.
|
||||
|
||||
However, due to race conditions sometimes the IRQ handler might be
|
||||
called twice, or the tasklet may not run at all (if interrupted in the
|
||||
middle of a reset).
|
||||
|
||||
This can cause nasty imbalances in the irq-disable refcount which will
|
||||
get the driver permanently stuck until the entire radio has been stopped
|
||||
and started again (ath_reset will not recover from this).
|
||||
|
||||
Instead of using this fragile logic, change the code to ensure that
|
||||
running the irq handler during tasklet processing is safe, and leave the
|
||||
refcount untouched.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -998,6 +998,7 @@ struct ath_softc {
|
||||
struct survey_info *cur_survey;
|
||||
struct survey_info survey[ATH9K_NUM_CHANNELS];
|
||||
|
||||
+ spinlock_t intr_lock;
|
||||
struct tasklet_struct intr_tq;
|
||||
struct tasklet_struct bcon_tasklet;
|
||||
struct ath_hw *sc_ah;
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -669,6 +669,7 @@ static int ath9k_init_softc(u16 devid, s
|
||||
common->bt_ant_diversity = 1;
|
||||
|
||||
spin_lock_init(&common->cc_lock);
|
||||
+ spin_lock_init(&sc->intr_lock);
|
||||
spin_lock_init(&sc->sc_serial_rw);
|
||||
spin_lock_init(&sc->sc_pm_lock);
|
||||
spin_lock_init(&sc->chan_lock);
|
||||
--- a/drivers/net/wireless/ath/ath9k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/mac.c
|
||||
@@ -810,21 +810,12 @@ void ath9k_hw_disable_interrupts(struct
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
|
||||
|
||||
-void ath9k_hw_enable_interrupts(struct ath_hw *ah)
|
||||
+static void __ath9k_hw_enable_interrupts(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 sync_default = AR_INTR_SYNC_DEFAULT;
|
||||
u32 async_mask;
|
||||
|
||||
- if (!(ah->imask & ATH9K_INT_GLOBAL))
|
||||
- return;
|
||||
-
|
||||
- if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
|
||||
- ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
|
||||
- atomic_read(&ah->intr_ref_cnt));
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
|
||||
AR_SREV_9561(ah))
|
||||
sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
|
||||
@@ -846,6 +837,39 @@ void ath9k_hw_enable_interrupts(struct a
|
||||
ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
|
||||
REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
|
||||
}
|
||||
+
|
||||
+void ath9k_hw_resume_interrupts(struct ath_hw *ah)
|
||||
+{
|
||||
+ struct ath_common *common = ath9k_hw_common(ah);
|
||||
+
|
||||
+ if (!(ah->imask & ATH9K_INT_GLOBAL))
|
||||
+ return;
|
||||
+
|
||||
+ if (atomic_read(&ah->intr_ref_cnt) != 0) {
|
||||
+ ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
|
||||
+ atomic_read(&ah->intr_ref_cnt));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ __ath9k_hw_enable_interrupts(ah);
|
||||
+}
|
||||
+EXPORT_SYMBOL(ath9k_hw_resume_interrupts);
|
||||
+
|
||||
+void ath9k_hw_enable_interrupts(struct ath_hw *ah)
|
||||
+{
|
||||
+ struct ath_common *common = ath9k_hw_common(ah);
|
||||
+
|
||||
+ if (!(ah->imask & ATH9K_INT_GLOBAL))
|
||||
+ return;
|
||||
+
|
||||
+ if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
|
||||
+ ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
|
||||
+ atomic_read(&ah->intr_ref_cnt));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ __ath9k_hw_enable_interrupts(ah);
|
||||
+}
|
||||
EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
|
||||
|
||||
void ath9k_hw_set_interrupts(struct ath_hw *ah)
|
||||
--- a/drivers/net/wireless/ath/ath9k/mac.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/mac.h
|
||||
@@ -744,6 +744,7 @@ void ath9k_hw_set_interrupts(struct ath_
|
||||
void ath9k_hw_enable_interrupts(struct ath_hw *ah);
|
||||
void ath9k_hw_disable_interrupts(struct ath_hw *ah);
|
||||
void ath9k_hw_kill_interrupts(struct ath_hw *ah);
|
||||
+void ath9k_hw_resume_interrupts(struct ath_hw *ah);
|
||||
|
||||
void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -374,21 +374,20 @@ void ath9k_tasklet(unsigned long data)
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
enum ath_reset_type type;
|
||||
unsigned long flags;
|
||||
- u32 status = sc->intrstatus;
|
||||
+ u32 status;
|
||||
u32 rxmask;
|
||||
|
||||
+ spin_lock_irqsave(&sc->intr_lock, flags);
|
||||
+ status = sc->intrstatus;
|
||||
+ sc->intrstatus = 0;
|
||||
+ spin_unlock_irqrestore(&sc->intr_lock, flags);
|
||||
+
|
||||
ath9k_ps_wakeup(sc);
|
||||
spin_lock(&sc->sc_pcu_lock);
|
||||
|
||||
if (status & ATH9K_INT_FATAL) {
|
||||
type = RESET_TYPE_FATAL_INT;
|
||||
ath9k_queue_reset(sc, type);
|
||||
-
|
||||
- /*
|
||||
- * Increment the ref. counter here so that
|
||||
- * interrupts are enabled in the reset routine.
|
||||
- */
|
||||
- atomic_inc(&ah->intr_ref_cnt);
|
||||
ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
|
||||
goto out;
|
||||
}
|
||||
@@ -404,11 +403,6 @@ void ath9k_tasklet(unsigned long data)
|
||||
type = RESET_TYPE_BB_WATCHDOG;
|
||||
ath9k_queue_reset(sc, type);
|
||||
|
||||
- /*
|
||||
- * Increment the ref. counter here so that
|
||||
- * interrupts are enabled in the reset routine.
|
||||
- */
|
||||
- atomic_inc(&ah->intr_ref_cnt);
|
||||
ath_dbg(common, RESET,
|
||||
"BB_WATCHDOG: Skipping interrupts\n");
|
||||
goto out;
|
||||
@@ -421,7 +415,6 @@ void ath9k_tasklet(unsigned long data)
|
||||
if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {
|
||||
type = RESET_TYPE_TX_GTT;
|
||||
ath9k_queue_reset(sc, type);
|
||||
- atomic_inc(&ah->intr_ref_cnt);
|
||||
ath_dbg(common, RESET,
|
||||
"GTT: Skipping interrupts\n");
|
||||
goto out;
|
||||
@@ -478,7 +471,7 @@ void ath9k_tasklet(unsigned long data)
|
||||
ath9k_btcoex_handle_interrupt(sc, status);
|
||||
|
||||
/* re-enable hardware interrupt */
|
||||
- ath9k_hw_enable_interrupts(ah);
|
||||
+ ath9k_hw_resume_interrupts(ah);
|
||||
out:
|
||||
spin_unlock(&sc->sc_pcu_lock);
|
||||
ath9k_ps_restore(sc);
|
||||
@@ -542,7 +535,9 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
return IRQ_NONE;
|
||||
|
||||
/* Cache the status */
|
||||
- sc->intrstatus = status;
|
||||
+ spin_lock(&sc->intr_lock);
|
||||
+ sc->intrstatus |= status;
|
||||
+ spin_unlock(&sc->intr_lock);
|
||||
|
||||
if (status & SCHED_INTR)
|
||||
sched = true;
|
||||
@@ -588,7 +583,7 @@ chip_reset:
|
||||
|
||||
if (sched) {
|
||||
/* turn off every interrupt */
|
||||
- ath9k_hw_disable_interrupts(ah);
|
||||
+ ath9k_hw_kill_interrupts(ah);
|
||||
tasklet_schedule(&sc->intr_tq);
|
||||
}
|
||||
|
@ -1,52 +0,0 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Mon, 30 Jan 2017 16:09:51 +0100
|
||||
Subject: [PATCH] brcmfmac: check brcmf_bus_get_memdump result for error
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This method may be unsupported (see: USB bus) or may just fail (see:
|
||||
SDIO bus).
|
||||
While at it rework logic in brcmf_sdio_bus_get_memdump function to avoid
|
||||
too many conditional code nesting levels.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
|
||||
@@ -32,16 +32,25 @@ static int brcmf_debug_create_memdump(st
|
||||
{
|
||||
void *dump;
|
||||
size_t ramsize;
|
||||
+ int err;
|
||||
|
||||
ramsize = brcmf_bus_get_ramsize(bus);
|
||||
- if (ramsize) {
|
||||
- dump = vzalloc(len + ramsize);
|
||||
- if (!dump)
|
||||
- return -ENOMEM;
|
||||
- memcpy(dump, data, len);
|
||||
- brcmf_bus_get_memdump(bus, dump + len, ramsize);
|
||||
- dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL);
|
||||
+ if (!ramsize)
|
||||
+ return -ENOTSUPP;
|
||||
+
|
||||
+ dump = vzalloc(len + ramsize);
|
||||
+ if (!dump)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ memcpy(dump, data, len);
|
||||
+ err = brcmf_bus_get_memdump(bus, dump + len, ramsize);
|
||||
+ if (err) {
|
||||
+ vfree(dump);
|
||||
+ return err;
|
||||
}
|
||||
+
|
||||
+ dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Mon, 30 Jan 2017 16:09:52 +0100
|
||||
Subject: [PATCH] brcmfmac: be more verbose when PSM's watchdog fires
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
It's important to inform user so he knows things went wrong. He may also
|
||||
want to get memory dump for further debugging purposes.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
|
||||
@@ -58,10 +58,18 @@ static int brcmf_debug_psm_watchdog_noti
|
||||
const struct brcmf_event_msg *evtmsg,
|
||||
void *data)
|
||||
{
|
||||
+ int err;
|
||||
+
|
||||
brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
|
||||
- return brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
|
||||
- evtmsg->datalen);
|
||||
+ brcmf_err("PSM's watchdog has fired!\n");
|
||||
+
|
||||
+ err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
|
||||
+ evtmsg->datalen);
|
||||
+ if (err)
|
||||
+ brcmf_err("Failed to get memory dump, %d\n", err);
|
||||
+
|
||||
+ return err;
|
||||
}
|
||||
|
||||
void brcmf_debugfs_init(void)
|
@ -1,44 +0,0 @@
|
||||
From 0f83ff69735651cc7a3d150466a5257ff829b62b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Tue, 17 Jan 2017 23:35:50 +0100
|
||||
Subject: [PATCH] brcmfmac: use wiphy_read_of_freq_limits to respect limits
|
||||
from DT
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This new helper reads extra frequency limits specified in DT and
|
||||
disables unavailable chanels. This is useful for devices (like home
|
||||
routers) with chipsets limited e.g. by board design.
|
||||
|
||||
In order to respect info read from DT we simply need to check for
|
||||
IEEE80211_CHAN_DISABLED bit when constructing channel info.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -5908,6 +5908,9 @@ static int brcmf_construct_chaninfo(stru
|
||||
continue;
|
||||
}
|
||||
|
||||
+ if (channel->orig_flags & IEEE80211_CHAN_DISABLED)
|
||||
+ continue;
|
||||
+
|
||||
/* assuming the chanspecs order is HT20,
|
||||
* HT40 upper, HT40 lower, and VHT80.
|
||||
*/
|
||||
@@ -6509,6 +6512,9 @@ static int brcmf_setup_wiphy(struct wiph
|
||||
wiphy->bands[NL80211_BAND_5GHZ] = band;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ wiphy_read_of_freq_limits(wiphy);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
From 9587a01a7ead9efc5032c16e0d9668de58be1186 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Thu, 2 Feb 2017 22:33:13 +0100
|
||||
Subject: [PATCH] brcmfmac: merge two brcmf_err macros into one
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This allows simplifying the code by adding a simple IS_ENABLED check for
|
||||
CONFIG_BRCMDB symbol.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 8 ++------
|
||||
1 file changed, 2 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
|
||||
@@ -45,20 +45,16 @@
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
+#ifndef CPTCFG_BRCM_TRACING
|
||||
/* Macro for error messages. net_ratelimit() is used when driver
|
||||
* debugging is not selected. When debugging the driver error
|
||||
* messages are as important as other tracing or even more so.
|
||||
*/
|
||||
-#ifndef CPTCFG_BRCM_TRACING
|
||||
-#ifdef CPTCFG_BRCMDBG
|
||||
-#define brcmf_err(fmt, ...) pr_err("%s: " fmt, __func__, ##__VA_ARGS__)
|
||||
-#else
|
||||
#define brcmf_err(fmt, ...) \
|
||||
do { \
|
||||
- if (net_ratelimit()) \
|
||||
+ if (IS_ENABLED(CPTCFG_BRCMDBG) || net_ratelimit()) \
|
||||
pr_err("%s: " fmt, __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
-#endif
|
||||
#else
|
||||
__printf(2, 3)
|
||||
void __brcmf_err(const char *func, const char *fmt, ...);
|
@ -1,69 +0,0 @@
|
||||
From 087fa712a00685dac4bcc64b7c3dc8ae6bee8026 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Thu, 2 Feb 2017 22:33:14 +0100
|
||||
Subject: [PATCH] brcmfmac: switch to C function (__brcmf_err) for printing
|
||||
errors
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This will allow extending code and using more detailed messages e.g.
|
||||
with the help of dev_err.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/common.c | 16 ++++++++++++++++
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 6 +++---
|
||||
2 files changed, 19 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -218,6 +218,22 @@ done:
|
||||
return err;
|
||||
}
|
||||
|
||||
+#ifndef CPTCFG_BRCM_TRACING
|
||||
+void __brcmf_err(const char *func, const char *fmt, ...)
|
||||
+{
|
||||
+ struct va_format vaf;
|
||||
+ va_list args;
|
||||
+
|
||||
+ va_start(args, fmt);
|
||||
+
|
||||
+ vaf.fmt = fmt;
|
||||
+ vaf.va = &args;
|
||||
+ pr_err("%s: %pV", func, &vaf);
|
||||
+
|
||||
+ va_end(args);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#if defined(CPTCFG_BRCM_TRACING) || defined(CPTCFG_BRCMDBG)
|
||||
void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
|
||||
{
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
|
||||
@@ -45,6 +45,8 @@
|
||||
#undef pr_fmt
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
+__printf(2, 3)
|
||||
+void __brcmf_err(const char *func, const char *fmt, ...);
|
||||
#ifndef CPTCFG_BRCM_TRACING
|
||||
/* Macro for error messages. net_ratelimit() is used when driver
|
||||
* debugging is not selected. When debugging the driver error
|
||||
@@ -53,11 +55,9 @@
|
||||
#define brcmf_err(fmt, ...) \
|
||||
do { \
|
||||
if (IS_ENABLED(CPTCFG_BRCMDBG) || net_ratelimit()) \
|
||||
- pr_err("%s: " fmt, __func__, ##__VA_ARGS__); \
|
||||
+ __brcmf_err(__func__, fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
-__printf(2, 3)
|
||||
-void __brcmf_err(const char *func, const char *fmt, ...);
|
||||
#define brcmf_err(fmt, ...) \
|
||||
__brcmf_err(__func__, fmt, ##__VA_ARGS__)
|
||||
#endif
|
@ -1,46 +0,0 @@
|
||||
From d0630555650a394cf5743268820511f527a561a5 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Thu, 2 Feb 2017 22:33:15 +0100
|
||||
Subject: [PATCH] brcmfmac: merge two remaining brcmf_err macros
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Now we always have __brcmf_err function we can do perfectly fine with
|
||||
just one macro.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 14 +++++---------
|
||||
1 file changed, 5 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
|
||||
@@ -47,20 +47,16 @@
|
||||
|
||||
__printf(2, 3)
|
||||
void __brcmf_err(const char *func, const char *fmt, ...);
|
||||
-#ifndef CPTCFG_BRCM_TRACING
|
||||
-/* Macro for error messages. net_ratelimit() is used when driver
|
||||
- * debugging is not selected. When debugging the driver error
|
||||
- * messages are as important as other tracing or even more so.
|
||||
+/* Macro for error messages. When debugging / tracing the driver all error
|
||||
+ * messages are important to us.
|
||||
*/
|
||||
#define brcmf_err(fmt, ...) \
|
||||
do { \
|
||||
- if (IS_ENABLED(CPTCFG_BRCMDBG) || net_ratelimit()) \
|
||||
+ if (IS_ENABLED(CPTCFG_BRCMDBG) || \
|
||||
+ IS_ENABLED(CPTCFG_BRCM_TRACING) || \
|
||||
+ net_ratelimit()) \
|
||||
__brcmf_err(__func__, fmt, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
-#else
|
||||
-#define brcmf_err(fmt, ...) \
|
||||
- __brcmf_err(__func__, fmt, ##__VA_ARGS__)
|
||||
-#endif
|
||||
|
||||
#if defined(DEBUG) || defined(CPTCFG_BRCM_TRACING)
|
||||
__printf(3, 4)
|
@ -1,107 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sun, 12 Feb 2017 13:13:05 +0100
|
||||
Subject: [PATCH] ath9k: clean up and fix ath_tx_count_airtime
|
||||
|
||||
ath_tx_count_airtime is doing a lot of unnecessary work:
|
||||
|
||||
- Redundant station lookup
|
||||
- Redundant rcu_read_lock/unlock
|
||||
- Useless memcpy of bf->rates
|
||||
- Useless NULL check of bf->bf_mpdu
|
||||
- Redundant lookup of the skb tid
|
||||
|
||||
Additionally, it tries to look up the mac80211 queue index from the txq,
|
||||
which fails if the frame was delivered via the power save queue.
|
||||
|
||||
This patch fixes all of these issues by passing down the right set of
|
||||
pointers instead of doing extra work
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 63fefa050477 ("ath9k: Introduce airtime fairness scheduling between stations")
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/xmit.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
|
||||
@@ -723,51 +723,31 @@ static bool bf_is_ampdu_not_probing(stru
|
||||
return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
|
||||
}
|
||||
|
||||
-static void ath_tx_count_airtime(struct ath_softc *sc, struct ath_txq *txq,
|
||||
- struct ath_buf *bf, struct ath_tx_status *ts)
|
||||
+static void ath_tx_count_airtime(struct ath_softc *sc, struct ath_node *an,
|
||||
+ struct ath_atx_tid *tid, struct ath_buf *bf,
|
||||
+ struct ath_tx_status *ts)
|
||||
{
|
||||
- struct ath_node *an;
|
||||
- struct ath_acq *acq = &sc->cur_chan->acq[txq->mac80211_qnum];
|
||||
- struct sk_buff *skb;
|
||||
- struct ieee80211_hdr *hdr;
|
||||
- struct ieee80211_hw *hw = sc->hw;
|
||||
- struct ieee80211_tx_rate rates[4];
|
||||
- struct ieee80211_sta *sta;
|
||||
- int i;
|
||||
+ struct ath_txq *txq = tid->txq;
|
||||
u32 airtime = 0;
|
||||
-
|
||||
- skb = bf->bf_mpdu;
|
||||
- if(!skb)
|
||||
- return;
|
||||
-
|
||||
- hdr = (struct ieee80211_hdr *)skb->data;
|
||||
- memcpy(rates, bf->rates, sizeof(rates));
|
||||
-
|
||||
- rcu_read_lock();
|
||||
-
|
||||
- sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
|
||||
- if(!sta)
|
||||
- goto exit;
|
||||
-
|
||||
-
|
||||
- an = (struct ath_node *) sta->drv_priv;
|
||||
+ int i;
|
||||
|
||||
airtime += ts->duration * (ts->ts_longretry + 1);
|
||||
+ for(i = 0; i < ts->ts_rateindex; i++) {
|
||||
+ int rate_dur = ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc, i);
|
||||
+ airtime += rate_dur * bf->rates[i].count;
|
||||
+ }
|
||||
|
||||
- for(i=0; i < ts->ts_rateindex; i++)
|
||||
- airtime += ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc, i) * rates[i].count;
|
||||
+ if (sc->airtime_flags & AIRTIME_USE_TX) {
|
||||
+ int q = txq->mac80211_qnum;
|
||||
+ struct ath_acq *acq = &sc->cur_chan->acq[q];
|
||||
|
||||
- if (!!(sc->airtime_flags & AIRTIME_USE_TX)) {
|
||||
spin_lock_bh(&acq->lock);
|
||||
- an->airtime_deficit[txq->mac80211_qnum] -= airtime;
|
||||
- if (an->airtime_deficit[txq->mac80211_qnum] <= 0)
|
||||
- __ath_tx_queue_tid(sc, ath_get_skb_tid(sc, an, skb));
|
||||
+ an->airtime_deficit[q] -= airtime;
|
||||
+ if (an->airtime_deficit[q] <= 0)
|
||||
+ __ath_tx_queue_tid(sc, tid);
|
||||
spin_unlock_bh(&acq->lock);
|
||||
}
|
||||
ath_debug_airtime(sc, an, 0, airtime);
|
||||
-
|
||||
-exit:
|
||||
- rcu_read_unlock();
|
||||
}
|
||||
|
||||
static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
|
||||
@@ -791,13 +771,13 @@ static void ath_tx_process_buffer(struct
|
||||
|
||||
ts->duration = ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc,
|
||||
ts->ts_rateindex);
|
||||
- ath_tx_count_airtime(sc, txq, bf, ts);
|
||||
|
||||
hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data;
|
||||
sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
|
||||
if (sta) {
|
||||
struct ath_node *an = (struct ath_node *)sta->drv_priv;
|
||||
tid = ath_get_skb_tid(sc, an, bf->bf_mpdu);
|
||||
+ ath_tx_count_airtime(sc, an, tid, bf, ts);
|
||||
if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
|
||||
tid->clear_ps_filter = true;
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
From: Koen Vandeputte <koen.vandeputte@ncentric.com>
|
||||
Date: Wed, 8 Feb 2017 15:29:45 +0100
|
||||
Subject: [PATCH] mac80211: fix CSA in IBSS mode
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add the missing IBSS capability flag during capability init as it needs
|
||||
to be inserted into the generated beacon in order for CSA to work.
|
||||
|
||||
Signed-off-by: Piotr Gawlowicz <gawlowicz@tkn.tu-berlin.de>
|
||||
Signed-off-by: Mikołaj Chwalisz <chwalisz@tkn.tu-berlin.de>
|
||||
Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/ibss.c
|
||||
+++ b/net/mac80211/ibss.c
|
||||
@@ -487,14 +487,14 @@ int ieee80211_ibss_csa_beacon(struct iee
|
||||
struct beacon_data *presp, *old_presp;
|
||||
struct cfg80211_bss *cbss;
|
||||
const struct cfg80211_bss_ies *ies;
|
||||
- u16 capability = 0;
|
||||
+ u16 capability = WLAN_CAPABILITY_IBSS;
|
||||
u64 tsf;
|
||||
int ret = 0;
|
||||
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (ifibss->privacy)
|
||||
- capability = WLAN_CAPABILITY_PRIVACY;
|
||||
+ capability |= WLAN_CAPABILITY_PRIVACY;
|
||||
|
||||
cbss = cfg80211_get_bss(sdata->local->hw.wiphy, ifibss->chandef.chan,
|
||||
ifibss->bssid, ifibss->ssid,
|
@ -1,28 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 22 Feb 2017 16:13:17 +0100
|
||||
Subject: [PATCH] mac80211: don't handle filtered frames within a BA session
|
||||
|
||||
When running a BA session, the driver (or the hardware) already takes
|
||||
care of retransmitting failed frames, since it has to keep the receiver
|
||||
reorder window in sync.
|
||||
|
||||
Adding another layer of retransmit around that does not improve
|
||||
anything. In fact, it can only lead to some strong reordering with huge
|
||||
latency.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/status.c
|
||||
+++ b/net/mac80211/status.c
|
||||
@@ -51,7 +51,8 @@ static void ieee80211_handle_filtered_fr
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
int ac;
|
||||
|
||||
- if (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER) {
|
||||
+ if (info->flags & (IEEE80211_TX_CTL_NO_PS_BUFFER |
|
||||
+ IEEE80211_TX_CTL_AMPDU)) {
|
||||
ieee80211_free_txskb(&local->hw, skb);
|
||||
return;
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
From 91b632803ee4e47c5a5c4dc3d8bf5abf9c16107a Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Klauser <tklauser@distanz.ch>
|
||||
Date: Mon, 13 Feb 2017 11:14:09 +0100
|
||||
Subject: [PATCH] brcmfmac: Use net_device_stats from struct net_device
|
||||
|
||||
Instead of using a private copy of struct net_device_stats in struct
|
||||
brcm_if, use stats from struct net_device. Also remove the now
|
||||
unnecessary .ndo_get_stats function.
|
||||
|
||||
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/core.c | 26 +++++++---------------
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/core.h | 2 --
|
||||
2 files changed, 8 insertions(+), 20 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -249,10 +249,10 @@ static netdev_tx_t brcmf_netdev_start_xm
|
||||
|
||||
done:
|
||||
if (ret) {
|
||||
- ifp->stats.tx_dropped++;
|
||||
+ ndev->stats.tx_dropped++;
|
||||
} else {
|
||||
- ifp->stats.tx_packets++;
|
||||
- ifp->stats.tx_bytes += skb->len;
|
||||
+ ndev->stats.tx_packets++;
|
||||
+ ndev->stats.tx_bytes += skb->len;
|
||||
}
|
||||
|
||||
/* Return ok: we always eat the packet */
|
||||
@@ -296,15 +296,15 @@ void brcmf_txflowblock(struct device *de
|
||||
void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
|
||||
{
|
||||
if (skb->pkt_type == PACKET_MULTICAST)
|
||||
- ifp->stats.multicast++;
|
||||
+ ifp->ndev->stats.multicast++;
|
||||
|
||||
if (!(ifp->ndev->flags & IFF_UP)) {
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
- ifp->stats.rx_bytes += skb->len;
|
||||
- ifp->stats.rx_packets++;
|
||||
+ ifp->ndev->stats.rx_bytes += skb->len;
|
||||
+ ifp->ndev->stats.rx_packets++;
|
||||
|
||||
brcmf_dbg(DATA, "rx proto=0x%X\n", ntohs(skb->protocol));
|
||||
if (in_interrupt())
|
||||
@@ -327,7 +327,7 @@ static int brcmf_rx_hdrpull(struct brcmf
|
||||
|
||||
if (ret || !(*ifp) || !(*ifp)->ndev) {
|
||||
if (ret != -ENODATA && *ifp)
|
||||
- (*ifp)->stats.rx_errors++;
|
||||
+ (*ifp)->ndev->stats.rx_errors++;
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
return -ENODATA;
|
||||
}
|
||||
@@ -388,7 +388,7 @@ void brcmf_txfinalize(struct brcmf_if *i
|
||||
}
|
||||
|
||||
if (!success)
|
||||
- ifp->stats.tx_errors++;
|
||||
+ ifp->ndev->stats.tx_errors++;
|
||||
|
||||
brcmu_pkt_buf_free_skb(txp);
|
||||
}
|
||||
@@ -411,15 +411,6 @@ void brcmf_txcomplete(struct device *dev
|
||||
}
|
||||
}
|
||||
|
||||
-static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
|
||||
-{
|
||||
- struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
-
|
||||
- brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
-
|
||||
- return &ifp->stats;
|
||||
-}
|
||||
-
|
||||
static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
|
||||
struct ethtool_drvinfo *info)
|
||||
{
|
||||
@@ -492,7 +483,6 @@ static int brcmf_netdev_open(struct net_
|
||||
static const struct net_device_ops brcmf_netdev_ops_pri = {
|
||||
.ndo_open = brcmf_netdev_open,
|
||||
.ndo_stop = brcmf_netdev_stop,
|
||||
- .ndo_get_stats = brcmf_netdev_get_stats,
|
||||
.ndo_start_xmit = brcmf_netdev_start_xmit,
|
||||
.ndo_set_mac_address = brcmf_netdev_set_mac_address,
|
||||
.ndo_set_rx_mode = brcmf_netdev_set_multicast_list
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||
@@ -171,7 +171,6 @@ enum brcmf_netif_stop_reason {
|
||||
* @drvr: points to device related information.
|
||||
* @vif: points to cfg80211 specific interface information.
|
||||
* @ndev: associated network device.
|
||||
- * @stats: interface specific network statistics.
|
||||
* @multicast_work: worker object for multicast provisioning.
|
||||
* @ndoffload_work: worker object for neighbor discovery offload configuration.
|
||||
* @fws_desc: interface specific firmware-signalling descriptor.
|
||||
@@ -187,7 +186,6 @@ struct brcmf_if {
|
||||
struct brcmf_pub *drvr;
|
||||
struct brcmf_cfg80211_vif *vif;
|
||||
struct net_device *ndev;
|
||||
- struct net_device_stats stats;
|
||||
struct work_struct multicast_work;
|
||||
struct work_struct ndoffload_work;
|
||||
struct brcmf_fws_mac_descriptor *fws_desc;
|
@ -1,148 +0,0 @@
|
||||
From f1ac3aa212af6dd0a36dc07a63f95f91be6f4935 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Date: Fri, 24 Feb 2017 17:32:46 +0100
|
||||
Subject: [PATCH] brcmfmac: always print error when PSM's watchdog fires
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
So far we were attaching BRCMF_E_PSM_WATCHDOG event listener in
|
||||
brcmf_debug_attach which gets compiled only with CONFIG_BRCMDBG. This
|
||||
event means something went wrong and firmware / hardware usually can't
|
||||
be expected to work (reliably).
|
||||
|
||||
Such a problem is significant for user experience so I believe we should
|
||||
print an error unconditionally (even with debugging disabled). What can
|
||||
be indeed optional is dumping bus memory as this is clearly part of
|
||||
debugging process.
|
||||
|
||||
In the future we may also try to extend this listener by trying to
|
||||
recover from the error or at least signal it to the cfg80211.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/core.c | 22 ++++++++++++++++++
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/debug.c | 26 +++-------------------
|
||||
.../wireless/broadcom/brcm80211/brcmfmac/debug.h | 9 ++++++++
|
||||
3 files changed, 34 insertions(+), 23 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -738,6 +738,24 @@ void brcmf_remove_interface(struct brcmf
|
||||
brcmf_del_if(ifp->drvr, ifp->bsscfgidx, rtnl_locked);
|
||||
}
|
||||
|
||||
+static int brcmf_psm_watchdog_notify(struct brcmf_if *ifp,
|
||||
+ const struct brcmf_event_msg *evtmsg,
|
||||
+ void *data)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
+
|
||||
+ brcmf_err("PSM's watchdog has fired!\n");
|
||||
+
|
||||
+ err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
|
||||
+ evtmsg->datalen);
|
||||
+ if (err)
|
||||
+ brcmf_err("Failed to get memory dump, %d\n", err);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
#ifdef CONFIG_INET
|
||||
#define ARPOL_MAX_ENTRIES 8
|
||||
static int brcmf_inetaddr_changed(struct notifier_block *nb,
|
||||
@@ -917,6 +935,10 @@ int brcmf_attach(struct device *dev, str
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ /* Attach to events important for core code */
|
||||
+ brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG,
|
||||
+ brcmf_psm_watchdog_notify);
|
||||
+
|
||||
/* attach firmware event handler */
|
||||
brcmf_fweh_attach(drvr);
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
|
||||
@@ -27,8 +27,8 @@
|
||||
|
||||
static struct dentry *root_folder;
|
||||
|
||||
-static int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
|
||||
- size_t len)
|
||||
+int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
|
||||
+ size_t len)
|
||||
{
|
||||
void *dump;
|
||||
size_t ramsize;
|
||||
@@ -54,24 +54,6 @@ static int brcmf_debug_create_memdump(st
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int brcmf_debug_psm_watchdog_notify(struct brcmf_if *ifp,
|
||||
- const struct brcmf_event_msg *evtmsg,
|
||||
- void *data)
|
||||
-{
|
||||
- int err;
|
||||
-
|
||||
- brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
-
|
||||
- brcmf_err("PSM's watchdog has fired!\n");
|
||||
-
|
||||
- err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
|
||||
- evtmsg->datalen);
|
||||
- if (err)
|
||||
- brcmf_err("Failed to get memory dump, %d\n", err);
|
||||
-
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
void brcmf_debugfs_init(void)
|
||||
{
|
||||
root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
|
||||
@@ -99,9 +81,7 @@ int brcmf_debug_attach(struct brcmf_pub
|
||||
if (IS_ERR(drvr->dbgfs_dir))
|
||||
return PTR_ERR(drvr->dbgfs_dir);
|
||||
|
||||
-
|
||||
- return brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG,
|
||||
- brcmf_debug_psm_watchdog_notify);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
void brcmf_debug_detach(struct brcmf_pub *drvr)
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
|
||||
@@ -99,6 +99,7 @@ do { \
|
||||
|
||||
extern int brcmf_msg_level;
|
||||
|
||||
+struct brcmf_bus;
|
||||
struct brcmf_pub;
|
||||
#ifdef DEBUG
|
||||
void brcmf_debugfs_init(void);
|
||||
@@ -108,6 +109,8 @@ void brcmf_debug_detach(struct brcmf_pub
|
||||
struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
|
||||
int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
|
||||
int (*read_fn)(struct seq_file *seq, void *data));
|
||||
+int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
|
||||
+ size_t len);
|
||||
#else
|
||||
static inline void brcmf_debugfs_init(void)
|
||||
{
|
||||
@@ -128,6 +131,12 @@ int brcmf_debugfs_add_entry(struct brcmf
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
+static inline
|
||||
+int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
|
||||
+ size_t len)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
#endif
|
||||
|
||||
#endif /* BRCMFMAC_DEBUG_H */
|
@ -1,56 +0,0 @@
|
||||
From d79fe4cb70d8deab7b8dc1de547ed4b915574414 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 8 Mar 2017 14:50:15 +0100
|
||||
Subject: [PATCH] brcmfmac: Do not print the firmware version as an error
|
||||
|
||||
Using pr_err for things which are not errors is a bad idea. E.g. it
|
||||
will cause the plymouth bootsplash screen to drop back to the text
|
||||
console so that the user can see the error, which is not what we
|
||||
normally want to happen.
|
||||
|
||||
Instead add a new brcmf_info macro and use that.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 2 +-
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 9 +++++++++
|
||||
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -161,7 +161,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
|
||||
strsep(&ptr, "\n");
|
||||
|
||||
/* Print fw version info */
|
||||
- brcmf_err("Firmware version = %s\n", buf);
|
||||
+ brcmf_info("Firmware version = %s\n", buf);
|
||||
|
||||
/* locate firmware version number for ethtool */
|
||||
ptr = strrchr(buf, ' ') + 1;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
|
||||
@@ -59,6 +59,10 @@ void __brcmf_err(const char *func, const
|
||||
} while (0)
|
||||
|
||||
#if defined(DEBUG) || defined(CPTCFG_BRCM_TRACING)
|
||||
+
|
||||
+/* For debug/tracing purposes treat info messages as errors */
|
||||
+#define brcmf_info brcmf_err
|
||||
+
|
||||
__printf(3, 4)
|
||||
void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...);
|
||||
#define brcmf_dbg(level, fmt, ...) \
|
||||
@@ -77,6 +81,11 @@ do { \
|
||||
|
||||
#else /* defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) */
|
||||
|
||||
+#define brcmf_info(fmt, ...) \
|
||||
+ do { \
|
||||
+ pr_info("%s: " fmt, __func__, ##__VA_ARGS__); \
|
||||
+ } while (0)
|
||||
+
|
||||
#define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
|
||||
|
||||
#define BRCMF_DATA_ON() 0
|
@ -1,28 +0,0 @@
|
||||
From 26e537884a8ef451f5c60f6949b1615069931ffa Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 8 Mar 2017 14:50:16 +0100
|
||||
Subject: [PATCH] brcmfmac: Do not complain about country code "00"
|
||||
|
||||
The country code gets set to "00" by default at boot, ignore this
|
||||
rather then logging an error about it.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -6736,6 +6736,10 @@ static void brcmf_cfg80211_reg_notifier(
|
||||
s32 err;
|
||||
int i;
|
||||
|
||||
+ /* The country code gets set to "00" by default at boot, ignore */
|
||||
+ if (req->alpha2[0] == '0' && req->alpha2[1] == '0')
|
||||
+ return;
|
||||
+
|
||||
/* ignore non-ISO3166 country codes */
|
||||
for (i = 0; i < sizeof(req->alpha2); i++)
|
||||
if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
|
@ -1,35 +0,0 @@
|
||||
From b9472a2e3e452c414634b3ccb1ef6c4098878686 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 8 Mar 2017 14:50:17 +0100
|
||||
Subject: [PATCH] brcmfmac: Handle status == BRCMF_E_STATUS_ABORT in
|
||||
cfg80211_escan_handler
|
||||
|
||||
If a scan gets aborted BRCMF_SCAN_STATUS_BUSY gets cleared in
|
||||
cfg->scan_status and when we receive an abort event from the firmware
|
||||
the BRCMF_SCAN_STATUS_BUSY check in the cfg80211_escan_handler will
|
||||
trigger resulting in multiple errors getting logged.
|
||||
|
||||
Check for a status of BRCMF_E_STATUS_ABORT and in this case simply
|
||||
cleanly exit the cfg80211_escan_handler. This also avoids a
|
||||
BRCMF_E_STATUS_ABORT event arriving after a new scan has been started
|
||||
causing the new scan to complete prematurely without any data.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -3097,6 +3097,9 @@ brcmf_cfg80211_escan_handler(struct brcm
|
||||
|
||||
status = e->status;
|
||||
|
||||
+ if (status == BRCMF_E_STATUS_ABORT)
|
||||
+ goto exit;
|
||||
+
|
||||
if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
|
||||
brcmf_err("scan not ready, bsscfgidx=%d\n", ifp->bsscfgidx);
|
||||
return -EPERM;
|
@ -1,137 +0,0 @@
|
||||
From 20ec4f57498f8770c7a1a3e2a316fa752a424178 Mon Sep 17 00:00:00 2001
|
||||
From: Franky Lin <franky.lin@broadcom.com>
|
||||
Date: Fri, 10 Mar 2017 21:17:02 +0000
|
||||
Subject: [PATCH] brcmfmac: move brcmf_txflowblock to bcdc layer
|
||||
|
||||
brcmf_txflowblock is invoked by sdio and usb bus module which are using
|
||||
bcdc protocol. This patch makes it a bcdc API instead of a core module
|
||||
function.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 10 ++++++++++
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h | 1 +
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 2 --
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 10 ----------
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 5 +++--
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 5 +++--
|
||||
6 files changed, 17 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
@@ -345,6 +345,16 @@ brcmf_proto_bcdc_txdata(struct brcmf_pub
|
||||
return brcmf_bus_txdata(drvr->bus_if, pktbuf);
|
||||
}
|
||||
|
||||
+void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state)
|
||||
+{
|
||||
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
+ struct brcmf_pub *drvr = bus_if->drvr;
|
||||
+
|
||||
+ brcmf_dbg(TRACE, "Enter\n");
|
||||
+
|
||||
+ brcmf_fws_bus_blocked(drvr, state);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
brcmf_proto_bcdc_configure_addr_mode(struct brcmf_pub *drvr, int ifidx,
|
||||
enum proto_addr_mode addr_mode)
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h
|
||||
@@ -19,6 +19,7 @@
|
||||
#ifdef CPTCFG_BRCMFMAC_PROTO_BCDC
|
||||
int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr);
|
||||
void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr);
|
||||
+void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state);
|
||||
#else
|
||||
static inline int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { return 0; }
|
||||
static inline void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) {}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
@@ -229,8 +229,6 @@ int brcmf_attach(struct device *dev, str
|
||||
void brcmf_detach(struct device *dev);
|
||||
/* Indication from bus module that dongle should be reset */
|
||||
void brcmf_dev_reset(struct device *dev);
|
||||
-/* Indication from bus module to change flow-control state */
|
||||
-void brcmf_txflowblock(struct device *dev, bool state);
|
||||
|
||||
/* Notify the bus has transferred the tx packet to firmware */
|
||||
void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -283,16 +283,6 @@ void brcmf_txflowblock_if(struct brcmf_i
|
||||
spin_unlock_irqrestore(&ifp->netif_stop_lock, flags);
|
||||
}
|
||||
|
||||
-void brcmf_txflowblock(struct device *dev, bool state)
|
||||
-{
|
||||
- struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
- struct brcmf_pub *drvr = bus_if->drvr;
|
||||
-
|
||||
- brcmf_dbg(TRACE, "Enter\n");
|
||||
-
|
||||
- brcmf_fws_bus_blocked(drvr, state);
|
||||
-}
|
||||
-
|
||||
void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
|
||||
{
|
||||
if (skb->pkt_type == PACKET_MULTICAST)
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "firmware.h"
|
||||
#include "core.h"
|
||||
#include "common.h"
|
||||
+#include "bcdc.h"
|
||||
|
||||
#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500)
|
||||
#define CTL_DONE_TIMEOUT msecs_to_jiffies(2500)
|
||||
@@ -2328,7 +2329,7 @@ static uint brcmf_sdio_sendfromq(struct
|
||||
if ((bus->sdiodev->state == BRCMF_SDIOD_DATA) &&
|
||||
bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
|
||||
bus->txoff = false;
|
||||
- brcmf_txflowblock(bus->sdiodev->dev, false);
|
||||
+ brcmf_proto_bcdc_txflowblock(bus->sdiodev->dev, false);
|
||||
}
|
||||
|
||||
return cnt;
|
||||
@@ -2753,7 +2754,7 @@ static int brcmf_sdio_bus_txdata(struct
|
||||
|
||||
if (pktq_len(&bus->txq) >= TXHI) {
|
||||
bus->txoff = true;
|
||||
- brcmf_txflowblock(dev, true);
|
||||
+ brcmf_proto_bcdc_txflowblock(dev, true);
|
||||
}
|
||||
spin_unlock_bh(&bus->txq_lock);
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "usb.h"
|
||||
#include "core.h"
|
||||
#include "common.h"
|
||||
+#include "bcdc.h"
|
||||
|
||||
|
||||
#define IOCTL_RESP_TIMEOUT msecs_to_jiffies(2000)
|
||||
@@ -488,7 +489,7 @@ static void brcmf_usb_tx_complete(struct
|
||||
spin_lock_irqsave(&devinfo->tx_flowblock_lock, flags);
|
||||
if (devinfo->tx_freecount > devinfo->tx_high_watermark &&
|
||||
devinfo->tx_flowblock) {
|
||||
- brcmf_txflowblock(devinfo->dev, false);
|
||||
+ brcmf_proto_bcdc_txflowblock(devinfo->dev, false);
|
||||
devinfo->tx_flowblock = false;
|
||||
}
|
||||
spin_unlock_irqrestore(&devinfo->tx_flowblock_lock, flags);
|
||||
@@ -635,7 +636,7 @@ static int brcmf_usb_tx(struct device *d
|
||||
spin_lock_irqsave(&devinfo->tx_flowblock_lock, flags);
|
||||
if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
|
||||
!devinfo->tx_flowblock) {
|
||||
- brcmf_txflowblock(dev, true);
|
||||
+ brcmf_proto_bcdc_txflowblock(dev, true);
|
||||
devinfo->tx_flowblock = true;
|
||||
}
|
||||
spin_unlock_irqrestore(&devinfo->tx_flowblock_lock, flags);
|
@ -1,122 +0,0 @@
|
||||
From 7b584396b7a760bc77bbde4625f83ef173159d3e Mon Sep 17 00:00:00 2001
|
||||
From: Franky Lin <franky.lin@broadcom.com>
|
||||
Date: Fri, 10 Mar 2017 21:17:03 +0000
|
||||
Subject: [PATCH] brcmfmac: move brcmf_txcomplete to bcdc layer
|
||||
|
||||
brcmf_txcomplete is invoked by sdio and usb bus module which are using
|
||||
bcdc protocol. So move it from core module into bcdc layer.
|
||||
|
||||
Signed-off-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 20 ++++++++++++++++++++
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h | 2 ++
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 3 ---
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/core.c | 18 ------------------
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 3 ++-
|
||||
.../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 2 +-
|
||||
6 files changed, 25 insertions(+), 23 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
@@ -355,6 +355,26 @@ void brcmf_proto_bcdc_txflowblock(struct
|
||||
brcmf_fws_bus_blocked(drvr, state);
|
||||
}
|
||||
|
||||
+void
|
||||
+brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp,
|
||||
+ bool success)
|
||||
+{
|
||||
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
+ struct brcmf_pub *drvr = bus_if->drvr;
|
||||
+ struct brcmf_if *ifp;
|
||||
+
|
||||
+ /* await txstatus signal for firmware if active */
|
||||
+ if (brcmf_fws_fc_active(drvr->fws)) {
|
||||
+ if (!success)
|
||||
+ brcmf_fws_bustxfail(drvr->fws, txp);
|
||||
+ } else {
|
||||
+ if (brcmf_proto_bcdc_hdrpull(drvr, false, txp, &ifp))
|
||||
+ brcmu_pkt_buf_free_skb(txp);
|
||||
+ else
|
||||
+ brcmf_txfinalize(ifp, txp, success);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
brcmf_proto_bcdc_configure_addr_mode(struct brcmf_pub *drvr, int ifidx,
|
||||
enum proto_addr_mode addr_mode)
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h
|
||||
@@ -20,6 +20,8 @@
|
||||
int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr);
|
||||
void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr);
|
||||
void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state);
|
||||
+void brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp,
|
||||
+ bool success);
|
||||
#else
|
||||
static inline int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { return 0; }
|
||||
static inline void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) {}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
|
||||
@@ -230,9 +230,6 @@ void brcmf_detach(struct device *dev);
|
||||
/* Indication from bus module that dongle should be reset */
|
||||
void brcmf_dev_reset(struct device *dev);
|
||||
|
||||
-/* Notify the bus has transferred the tx packet to firmware */
|
||||
-void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
|
||||
-
|
||||
/* Configure the "global" bus state used by upper layers */
|
||||
void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state);
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -383,24 +383,6 @@ void brcmf_txfinalize(struct brcmf_if *i
|
||||
brcmu_pkt_buf_free_skb(txp);
|
||||
}
|
||||
|
||||
-void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
|
||||
-{
|
||||
- struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
- struct brcmf_pub *drvr = bus_if->drvr;
|
||||
- struct brcmf_if *ifp;
|
||||
-
|
||||
- /* await txstatus signal for firmware if active */
|
||||
- if (brcmf_fws_fc_active(drvr->fws)) {
|
||||
- if (!success)
|
||||
- brcmf_fws_bustxfail(drvr->fws, txp);
|
||||
- } else {
|
||||
- if (brcmf_proto_hdrpull(drvr, false, txp, &ifp))
|
||||
- brcmu_pkt_buf_free_skb(txp);
|
||||
- else
|
||||
- brcmf_txfinalize(ifp, txp, success);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
|
||||
struct ethtool_drvinfo *info)
|
||||
{
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||
@@ -2266,7 +2266,8 @@ done:
|
||||
bus->tx_seq = (bus->tx_seq + pktq->qlen) % SDPCM_SEQ_WRAP;
|
||||
skb_queue_walk_safe(pktq, pkt_next, tmp) {
|
||||
__skb_unlink(pkt_next, pktq);
|
||||
- brcmf_txcomplete(bus->sdiodev->dev, pkt_next, ret == 0);
|
||||
+ brcmf_proto_bcdc_txcomplete(bus->sdiodev->dev, pkt_next,
|
||||
+ ret == 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||
@@ -483,7 +483,7 @@ static void brcmf_usb_tx_complete(struct
|
||||
req->skb);
|
||||
brcmf_usb_del_fromq(devinfo, req);
|
||||
|
||||
- brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
|
||||
+ brcmf_proto_bcdc_txcomplete(devinfo->dev, req->skb, urb->status == 0);
|
||||
req->skb = NULL;
|
||||
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
|
||||
spin_lock_irqsave(&devinfo->tx_flowblock_lock, flags);
|
@ -1,95 +0,0 @@
|
||||
From 9fdc64bbdbe7bd546e0fbcedd2f1c03448c6df42 Mon Sep 17 00:00:00 2001
|
||||
From: Franky Lin <franky.lin@broadcom.com>
|
||||
Date: Fri, 10 Mar 2017 21:17:04 +0000
|
||||
Subject: [PATCH] brcmfmac: wrap brcmf_fws_add_interface into bcdc layer
|
||||
|
||||
fwsignal is only used by bcdc. Create a new protocol interface function
|
||||
brcmf_proto_add_if for core module to notify protocol layer upon a new
|
||||
interface is created.
|
||||
|
||||
Signed-off-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 7 +++++++
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 +-
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 3 ++-
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | 9 +++++++++
|
||||
4 files changed, 19 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
@@ -399,6 +399,12 @@ static void brcmf_proto_bcdc_rxreorder(s
|
||||
brcmf_fws_rxreorder(ifp, skb);
|
||||
}
|
||||
|
||||
+static void
|
||||
+brcmf_proto_bcdc_add_if(struct brcmf_if *ifp)
|
||||
+{
|
||||
+ brcmf_fws_add_interface(ifp);
|
||||
+}
|
||||
+
|
||||
int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_bcdc *bcdc;
|
||||
@@ -422,6 +428,7 @@ int brcmf_proto_bcdc_attach(struct brcmf
|
||||
drvr->proto->delete_peer = brcmf_proto_bcdc_delete_peer;
|
||||
drvr->proto->add_tdls_peer = brcmf_proto_bcdc_add_tdls_peer;
|
||||
drvr->proto->rxreorder = brcmf_proto_bcdc_rxreorder;
|
||||
+ drvr->proto->add_if = brcmf_proto_bcdc_add_if;
|
||||
drvr->proto->pd = bcdc;
|
||||
|
||||
drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -990,7 +990,7 @@ int brcmf_bus_started(struct device *dev
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
- brcmf_fws_add_interface(ifp);
|
||||
+ brcmf_proto_add_if(drvr, ifp);
|
||||
|
||||
drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev,
|
||||
drvr->settings->p2p_enable);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "fwsignal.h"
|
||||
#include "fweh.h"
|
||||
#include "fwil.h"
|
||||
+#include "proto.h"
|
||||
|
||||
/**
|
||||
* struct brcmf_fweh_queue_item - event item on event queue.
|
||||
@@ -172,7 +173,7 @@ static void brcmf_fweh_handle_if_event(s
|
||||
if (IS_ERR(ifp))
|
||||
return;
|
||||
if (!is_p2pdev)
|
||||
- brcmf_fws_add_interface(ifp);
|
||||
+ brcmf_proto_add_if(drvr, ifp);
|
||||
if (!drvr->fweh.evt_handler[BRCMF_E_IF])
|
||||
if (brcmf_net_attach(ifp, false) < 0)
|
||||
return;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
|
||||
@@ -44,6 +44,7 @@ struct brcmf_proto {
|
||||
void (*add_tdls_peer)(struct brcmf_pub *drvr, int ifidx,
|
||||
u8 peer[ETH_ALEN]);
|
||||
void (*rxreorder)(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||
+ void (*add_if)(struct brcmf_if *ifp);
|
||||
void *pd;
|
||||
};
|
||||
|
||||
@@ -118,4 +119,12 @@ brcmf_proto_rxreorder(struct brcmf_if *i
|
||||
ifp->drvr->proto->rxreorder(ifp, skb);
|
||||
}
|
||||
|
||||
+static inline void
|
||||
+brcmf_proto_add_if(struct brcmf_pub *drvr, struct brcmf_if *ifp)
|
||||
+{
|
||||
+ if (!drvr->proto->add_if)
|
||||
+ return;
|
||||
+ drvr->proto->add_if(ifp);
|
||||
+}
|
||||
+
|
||||
#endif /* BRCMFMAC_PROTO_H */
|
@ -1,83 +0,0 @@
|
||||
From c02a5eb82056f75615cb48aa540bfd245f489b99 Mon Sep 17 00:00:00 2001
|
||||
From: Franky Lin <franky.lin@broadcom.com>
|
||||
Date: Fri, 10 Mar 2017 21:17:05 +0000
|
||||
Subject: [PATCH] brcmfmac: wrap brcmf_fws_del_interface into bcdc layer
|
||||
|
||||
Create a new protocol interface function brcmf_proto_del_if for core
|
||||
module to notify protocol layer upon interface deletion.
|
||||
|
||||
Signed-off-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 7 +++++++
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 4 ++--
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | 9 +++++++++
|
||||
3 files changed, 18 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
@@ -405,6 +405,12 @@ brcmf_proto_bcdc_add_if(struct brcmf_if
|
||||
brcmf_fws_add_interface(ifp);
|
||||
}
|
||||
|
||||
+static void
|
||||
+brcmf_proto_bcdc_del_if(struct brcmf_if *ifp)
|
||||
+{
|
||||
+ brcmf_fws_del_interface(ifp);
|
||||
+}
|
||||
+
|
||||
int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_bcdc *bcdc;
|
||||
@@ -429,6 +435,7 @@ int brcmf_proto_bcdc_attach(struct brcmf
|
||||
drvr->proto->add_tdls_peer = brcmf_proto_bcdc_add_tdls_peer;
|
||||
drvr->proto->rxreorder = brcmf_proto_bcdc_rxreorder;
|
||||
drvr->proto->add_if = brcmf_proto_bcdc_add_if;
|
||||
+ drvr->proto->del_if = brcmf_proto_bcdc_del_if;
|
||||
drvr->proto->pd = bcdc;
|
||||
|
||||
drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||
@@ -706,7 +706,7 @@ void brcmf_remove_interface(struct brcmf
|
||||
return;
|
||||
brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", ifp->bsscfgidx,
|
||||
ifp->ifidx);
|
||||
- brcmf_fws_del_interface(ifp);
|
||||
+ brcmf_proto_del_if(ifp->drvr, ifp);
|
||||
brcmf_del_if(ifp->drvr, ifp->bsscfgidx, rtnl_locked);
|
||||
}
|
||||
|
||||
@@ -1035,7 +1035,7 @@ fail:
|
||||
drvr->config = NULL;
|
||||
}
|
||||
if (drvr->fws) {
|
||||
- brcmf_fws_del_interface(ifp);
|
||||
+ brcmf_proto_del_if(ifp->drvr, ifp);
|
||||
brcmf_fws_deinit(drvr);
|
||||
}
|
||||
brcmf_net_detach(ifp->ndev, false);
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
|
||||
@@ -45,6 +45,7 @@ struct brcmf_proto {
|
||||
u8 peer[ETH_ALEN]);
|
||||
void (*rxreorder)(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||
void (*add_if)(struct brcmf_if *ifp);
|
||||
+ void (*del_if)(struct brcmf_if *ifp);
|
||||
void *pd;
|
||||
};
|
||||
|
||||
@@ -127,4 +128,12 @@ brcmf_proto_add_if(struct brcmf_pub *drv
|
||||
drvr->proto->add_if(ifp);
|
||||
}
|
||||
|
||||
+static inline void
|
||||
+brcmf_proto_del_if(struct brcmf_pub *drvr, struct brcmf_if *ifp)
|
||||
+{
|
||||
+ if (!drvr->proto->del_if)
|
||||
+ return;
|
||||
+ drvr->proto->del_if(ifp);
|
||||
+}
|
||||
+
|
||||
#endif /* BRCMFMAC_PROTO_H */
|
@ -1,82 +0,0 @@
|
||||
From 66ded1f8b33cdd9d6d3e20f5f8dd23615a110e70 Mon Sep 17 00:00:00 2001
|
||||
From: Franky Lin <franky.lin@broadcom.com>
|
||||
Date: Fri, 10 Mar 2017 21:17:06 +0000
|
||||
Subject: [PATCH] brcmfmac: wrap brcmf_fws_reset_interface into bcdc layer
|
||||
|
||||
Create a new protocol interface function brcmf_proto_reset_if for core
|
||||
module to notify protocol layer when interface role changes.
|
||||
|
||||
Signed-off-by: Franky Lin <franky.lin@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 7 +++++++
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 3 +--
|
||||
drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h | 9 +++++++++
|
||||
3 files changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
|
||||
@@ -411,6 +411,12 @@ brcmf_proto_bcdc_del_if(struct brcmf_if
|
||||
brcmf_fws_del_interface(ifp);
|
||||
}
|
||||
|
||||
+static void
|
||||
+brcmf_proto_bcdc_reset_if(struct brcmf_if *ifp)
|
||||
+{
|
||||
+ brcmf_fws_reset_interface(ifp);
|
||||
+}
|
||||
+
|
||||
int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_bcdc *bcdc;
|
||||
@@ -436,6 +442,7 @@ int brcmf_proto_bcdc_attach(struct brcmf
|
||||
drvr->proto->rxreorder = brcmf_proto_bcdc_rxreorder;
|
||||
drvr->proto->add_if = brcmf_proto_bcdc_add_if;
|
||||
drvr->proto->del_if = brcmf_proto_bcdc_del_if;
|
||||
+ drvr->proto->reset_if = brcmf_proto_bcdc_reset_if;
|
||||
drvr->proto->pd = bcdc;
|
||||
|
||||
drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "core.h"
|
||||
#include "debug.h"
|
||||
#include "tracepoint.h"
|
||||
-#include "fwsignal.h"
|
||||
#include "fweh.h"
|
||||
#include "fwil.h"
|
||||
#include "proto.h"
|
||||
@@ -180,7 +179,7 @@ static void brcmf_fweh_handle_if_event(s
|
||||
}
|
||||
|
||||
if (ifp && ifevent->action == BRCMF_E_IF_CHANGE)
|
||||
- brcmf_fws_reset_interface(ifp);
|
||||
+ brcmf_proto_reset_if(drvr, ifp);
|
||||
|
||||
err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
|
||||
@@ -46,6 +46,7 @@ struct brcmf_proto {
|
||||
void (*rxreorder)(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||
void (*add_if)(struct brcmf_if *ifp);
|
||||
void (*del_if)(struct brcmf_if *ifp);
|
||||
+ void (*reset_if)(struct brcmf_if *ifp);
|
||||
void *pd;
|
||||
};
|
||||
|
||||
@@ -136,4 +137,12 @@ brcmf_proto_del_if(struct brcmf_pub *drv
|
||||
drvr->proto->del_if(ifp);
|
||||
}
|
||||
|
||||
+static inline void
|
||||
+brcmf_proto_reset_if(struct brcmf_pub *drvr, struct brcmf_if *ifp)
|
||||
+{
|
||||
+ if (!drvr->proto->reset_if)
|
||||
+ return;
|
||||
+ drvr->proto->reset_if(ifp);
|
||||
+}
|
||||
+
|
||||
#endif /* BRCMFMAC_PROTO_H */
|
@ -1,29 +0,0 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Wed, 29 Mar 2017 14:15:24 +0200
|
||||
Subject: [PATCH] mac80211: unconditionally start new netdev queues with iTXQ
|
||||
support
|
||||
|
||||
When internal mac80211 TXQs aren't supported, netdev queues must
|
||||
always started out started even when driver queues are stopped
|
||||
while the interface is added. This is necessary because with the
|
||||
internal TXQ support netdev queues are never stopped and packet
|
||||
scheduling/dropping is done in mac80211.
|
||||
|
||||
Cc: stable@vger.kernel.org # 4.9+
|
||||
Fixes: 80a83cfc434b1 ("mac80211: skip netdev queue control with software queuing")
|
||||
Reported-and-tested-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -727,7 +727,8 @@ int ieee80211_do_open(struct wireless_de
|
||||
ieee80211_recalc_ps(local);
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
|
||||
- sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
|
||||
+ sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
|
||||
+ local->ops->wake_tx_queue) {
|
||||
/* XXX: for AP_VLAN, actually track AP queues */
|
||||
netif_tx_start_all_queues(dev);
|
||||
} else if (dev) {
|
@ -1,42 +0,0 @@
|
||||
From: Christian Lamparter <chunkeey@googlemail.com>
|
||||
Date: Tue, 14 Feb 2017 20:10:30 +0100
|
||||
Subject: ath9k: use correct OTP register offsets for the AR9340 and AR9550
|
||||
|
||||
This patch fixes the OTP register definitions for the AR934x and AR9550
|
||||
WMAC SoC.
|
||||
|
||||
Previously, the ath9k driver was unable to initialize the integrated
|
||||
WMAC on an Aerohive AP121:
|
||||
|
||||
| ath: phy0: timeout (1000 us) on reg 0x30018: 0xbadc0ffe & 0x00000007 != 0x00000004
|
||||
| ath: phy0: timeout (1000 us) on reg 0x30018: 0xbadc0ffe & 0x00000007 != 0x00000004
|
||||
| ath: phy0: Unable to initialize hardware; initialization status: -5
|
||||
| ath9k ar934x_wmac: failed to initialize device
|
||||
| ath9k: probe of ar934x_wmac failed with error -5
|
||||
|
||||
It turns out that the AR9300_OTP_STATUS and AR9300_OTP_DATA
|
||||
definitions contain a typo.
|
||||
|
||||
Fixes: add295a4afbdf5852d0 "ath9k: use correct OTP register offsets for AR9550"
|
||||
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
|
||||
Signed-off-by: Chris Blake <chrisrblake93@gmail.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
|
||||
@@ -75,13 +75,13 @@
|
||||
#define AR9300_OTP_BASE \
|
||||
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000)
|
||||
#define AR9300_OTP_STATUS \
|
||||
- ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30018 : 0x15f18)
|
||||
+ ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x31018 : 0x15f18)
|
||||
#define AR9300_OTP_STATUS_TYPE 0x7
|
||||
#define AR9300_OTP_STATUS_VALID 0x4
|
||||
#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
|
||||
#define AR9300_OTP_STATUS_SM_BUSY 0x1
|
||||
#define AR9300_OTP_READ_DATA \
|
||||
- ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3001c : 0x15f1c)
|
||||
+ ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3101c : 0x15f1c)
|
||||
|
||||
enum targetPowerHTRates {
|
||||
HT_TARGET_RATE_0_8_16,
|
@ -1,31 +0,0 @@
|
||||
From: Ben Greear <greearb@candelatech.com>
|
||||
Date: Wed, 31 May 2017 14:21:19 +0300
|
||||
Subject: [PATCH] ath10k: increase BMI timeout
|
||||
|
||||
When testing a 9888 chipset NIC, I notice it often takes
|
||||
almost 2 seconds, and then many times OTP fails, probably due
|
||||
to the two-second timeout.
|
||||
|
||||
[ 2269.841842] ath10k_pci 0000:05:00.0: bmi cmd took: 1984 jiffies (HZ: 1000), rv: 0
|
||||
[ 2273.608185] ath10k_pci 0000:05:00.0: bmi cmd took: 1986 jiffies (HZ: 1000), rv: 0
|
||||
[ 2277.294732] ath10k_pci 0000:05:00.0: bmi cmd took: 1989 jiffies (HZ: 1000), rv: 0
|
||||
|
||||
So, increase the BMI timeout to 3 seconds.
|
||||
|
||||
Signed-off-by: Ben Greear <greearb@candelatech.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/bmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/bmi.h
|
||||
@@ -187,8 +187,8 @@ struct bmi_target_info {
|
||||
u32 type;
|
||||
};
|
||||
|
||||
-/* in msec */
|
||||
-#define BMI_COMMUNICATION_TIMEOUT_HZ (2 * HZ)
|
||||
+/* in jiffies */
|
||||
+#define BMI_COMMUNICATION_TIMEOUT_HZ (3 * HZ)
|
||||
|
||||
#define BMI_CE_NUM_TO_TARG 0
|
||||
#define BMI_CE_NUM_TO_HOST 1
|
@ -1,74 +0,0 @@
|
||||
From: Ben Greear <greearb@candelatech.com>
|
||||
Date: Wed, 31 May 2017 14:21:21 +0300
|
||||
Subject: [PATCH] ath10k: log when longer bmi cmds happen
|
||||
|
||||
This lets one have a clue that maybe timeouts are happening
|
||||
when we just aren't waiting long enough.
|
||||
|
||||
Signed-off-by: Ben Greear <greearb@candelatech.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/pci.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/pci.c
|
||||
@@ -101,7 +101,8 @@ static int ath10k_pci_init_irq(struct at
|
||||
static int ath10k_pci_deinit_irq(struct ath10k *ar);
|
||||
static int ath10k_pci_request_irq(struct ath10k *ar);
|
||||
static void ath10k_pci_free_irq(struct ath10k *ar);
|
||||
-static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
|
||||
+static int ath10k_pci_bmi_wait(struct ath10k *ar,
|
||||
+ struct ath10k_ce_pipe *tx_pipe,
|
||||
struct ath10k_ce_pipe *rx_pipe,
|
||||
struct bmi_xfer *xfer);
|
||||
static int ath10k_pci_qca99x0_chip_reset(struct ath10k *ar);
|
||||
@@ -1843,7 +1844,7 @@ int ath10k_pci_hif_exchange_bmi_msg(stru
|
||||
if (ret)
|
||||
goto err_resp;
|
||||
|
||||
- ret = ath10k_pci_bmi_wait(ce_tx, ce_rx, &xfer);
|
||||
+ ret = ath10k_pci_bmi_wait(ar, ce_tx, ce_rx, &xfer);
|
||||
if (ret) {
|
||||
u32 unused_buffer;
|
||||
unsigned int unused_nbytes;
|
||||
@@ -1910,23 +1911,37 @@ static void ath10k_pci_bmi_recv_data(str
|
||||
xfer->rx_done = true;
|
||||
}
|
||||
|
||||
-static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
|
||||
+static int ath10k_pci_bmi_wait(struct ath10k *ar,
|
||||
+ struct ath10k_ce_pipe *tx_pipe,
|
||||
struct ath10k_ce_pipe *rx_pipe,
|
||||
struct bmi_xfer *xfer)
|
||||
{
|
||||
unsigned long timeout = jiffies + BMI_COMMUNICATION_TIMEOUT_HZ;
|
||||
+ unsigned long started = jiffies;
|
||||
+ unsigned long dur;
|
||||
+ int ret;
|
||||
|
||||
while (time_before_eq(jiffies, timeout)) {
|
||||
ath10k_pci_bmi_send_done(tx_pipe);
|
||||
ath10k_pci_bmi_recv_data(rx_pipe);
|
||||
|
||||
- if (xfer->tx_done && (xfer->rx_done == xfer->wait_for_resp))
|
||||
- return 0;
|
||||
+ if (xfer->tx_done && (xfer->rx_done == xfer->wait_for_resp)) {
|
||||
+ ret = 0;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
schedule();
|
||||
}
|
||||
|
||||
- return -ETIMEDOUT;
|
||||
+ ret = -ETIMEDOUT;
|
||||
+
|
||||
+out:
|
||||
+ dur = jiffies - started;
|
||||
+ if (dur > HZ)
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_BMI,
|
||||
+ "bmi cmd took %lu jiffies hz %d ret %d\n",
|
||||
+ dur, HZ, ret);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/*
|
@ -1,80 +0,0 @@
|
||||
From: Anilkumar Kolli <akolli@qti.qualcomm.com>
|
||||
Date: Wed, 31 May 2017 14:21:27 +0300
|
||||
Subject: [PATCH] ath10k: add BMI parameters to fix calibration from
|
||||
DT/pre-cal
|
||||
|
||||
QCA99X0, QCA9888, QCA9984 supports calibration data in
|
||||
either OTP or DT/pre-cal file. Current ath10k supports
|
||||
Calibration data from OTP only.
|
||||
|
||||
If caldata is loaded from DT/pre-cal file, fetching board id
|
||||
and applying calibration parameters like tx power gets failed.
|
||||
|
||||
error log:
|
||||
[ 15.733663] ath10k_pci 0000:01:00.0: failed to fetch board file: -2
|
||||
[ 15.741474] ath10k_pci 0000:01:00.0: could not probe fw (-2)
|
||||
|
||||
This patch adds calibration data support from DT/pre-cal
|
||||
file. Below parameters are used to get board id and
|
||||
applying calibration parameters from cal data.
|
||||
|
||||
EEPROM[OTP] FLASH[DT/pre-cal file]
|
||||
Cal param 0x700 0x10000
|
||||
Board id 0x10 0x8000
|
||||
|
||||
Tested on QCA9888 with pre-cal file.
|
||||
|
||||
Signed-off-by: Anilkumar Kolli <akolli@qti.qualcomm.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/bmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/bmi.h
|
||||
@@ -83,6 +83,8 @@ enum bmi_cmd_id {
|
||||
#define BMI_NVRAM_SEG_NAME_SZ 16
|
||||
|
||||
#define BMI_PARAM_GET_EEPROM_BOARD_ID 0x10
|
||||
+#define BMI_PARAM_GET_FLASH_BOARD_ID 0x8000
|
||||
+#define BMI_PARAM_FLASH_SECTION_ALL 0x10000
|
||||
|
||||
#define ATH10K_BMI_BOARD_ID_FROM_OTP_MASK 0x7c00
|
||||
#define ATH10K_BMI_BOARD_ID_FROM_OTP_LSB 10
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
|
||||
@@ -657,7 +657,7 @@ static int ath10k_core_get_board_id_from
|
||||
{
|
||||
u32 result, address;
|
||||
u8 board_id, chip_id;
|
||||
- int ret;
|
||||
+ int ret, bmi_board_id_param;
|
||||
|
||||
address = ar->hw_params.patch_load_addr;
|
||||
|
||||
@@ -681,8 +681,13 @@ static int ath10k_core_get_board_id_from
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = ath10k_bmi_execute(ar, address, BMI_PARAM_GET_EEPROM_BOARD_ID,
|
||||
- &result);
|
||||
+ if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
|
||||
+ ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
|
||||
+ bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID;
|
||||
+ else
|
||||
+ bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID;
|
||||
+
|
||||
+ ret = ath10k_bmi_execute(ar, address, bmi_board_id_param, &result);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "could not execute otp for board id check: %d\n",
|
||||
ret);
|
||||
@@ -810,6 +815,11 @@ static int ath10k_download_and_run_otp(s
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ /* As of now pre-cal is valid for 10_4 variants */
|
||||
+ if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
|
||||
+ ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
|
||||
+ bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL;
|
||||
+
|
||||
ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "could not execute otp (%d)\n", ret);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue