fix mac82011
This commit is contained in:
parent
d9ac00d2c4
commit
86b4c27773
package/kernel/mac80211/.svn
entriesformat
pristine
00
03
04
06
0655ec19ffdea20a141d9c194fc5d851e05e4123.svn-base0657a1805b3d7498274152b17458afdc8923e876.svn-base06c2530ecdb7eb9cbed4e4df81c5b6b2e6d50379.svn-base06cdc39ba41c4d5940707b208ee6d238c3defef9.svn-base
08
0a
0d
0e
11
12
13
14
15
16
19
1a
1b
1c
1d
1d2ae63c6cdf829fcf2f8bd1d52d4ac4214e8cd7.svn-base1d4cd2af6de7fce97b5f8d22ac1a5c0cdc27138e.svn-base1d6e293a49b945b3fcd9395e6767ebaa581d6bd8.svn-base
23
24
26
267cd919e4bbe44fe8e38a7b85c9f61b34afe16e.svn-base2680060479752e9c543fe8e8638adf2e203dce7c.svn-base2694fa6db0e1d6e5b260beb80605887cced21956.svn-base26da6ec3bc34c26f0181dab3eea823a2f5f17115.svn-base
29
2a
2b
30
33
34
35
38
3a
3e
42
43
46
48
4a
4e
50
54
5b
5bbc76c7d80625cc2be37f3c4c410bb6147104dc.svn-base5bcd83d024f0f8b2ccc0ed334818df9f07e4ea56.svn-base5bf3b15664a459152ee8080945dd4d9db995fca7.svn-base
5d
5e
5f
60
62
64
65
66
68
6b
6c
70
71
72
73
75
76
77
79
7a
7c
7d
80
82
84
85
89
8b
8c
8e
@ -1 +0,0 @@
|
||||
12
|
@ -1 +0,0 @@
|
||||
12
|
@ -1,485 +0,0 @@
|
||||
From: John Crispin <john@phrozen.org>
|
||||
Date: Fri, 2 Jul 2021 19:44:07 +0200
|
||||
Subject: [PATCH] nl80211: add support for BSS coloring
|
||||
|
||||
This patch adds support for BSS color collisions to the wireless subsystem.
|
||||
Add the required functionality to nl80211 that will notify about color
|
||||
collisions, triggering the color change and notifying when it is completed.
|
||||
|
||||
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: John Crispin <john@phrozen.org>
|
||||
Link: https://lore.kernel.org/r/500b3582aec8fe2c42ef46f3117b148cb7cbceb5.1625247619.git.lorenzo@kernel.org
|
||||
[remove unnecessary NULL initialisation]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -1252,6 +1252,27 @@ struct cfg80211_csa_settings {
|
||||
#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10
|
||||
|
||||
/**
|
||||
+ * struct cfg80211_color_change_settings - color change settings
|
||||
+ *
|
||||
+ * Used for bss color change
|
||||
+ *
|
||||
+ * @beacon_color_change: beacon data while performing the color countdown
|
||||
+ * @counter_offsets_beacon: offsets of the counters within the beacon (tail)
|
||||
+ * @counter_offsets_presp: offsets of the counters within the probe response
|
||||
+ * @beacon_next: beacon data to be used after the color change
|
||||
+ * @count: number of beacons until the color change
|
||||
+ * @color: the color used after the change
|
||||
+ */
|
||||
+struct cfg80211_color_change_settings {
|
||||
+ struct cfg80211_beacon_data beacon_color_change;
|
||||
+ u16 counter_offset_beacon;
|
||||
+ u16 counter_offset_presp;
|
||||
+ struct cfg80211_beacon_data beacon_next;
|
||||
+ u8 count;
|
||||
+ u8 color;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
* struct iface_combination_params - input parameters for interface combinations
|
||||
*
|
||||
* Used to pass interface combination parameters
|
||||
@@ -3979,6 +4000,8 @@ struct mgmt_frame_regs {
|
||||
* This callback may sleep.
|
||||
* @reset_tid_config: Reset TID specific configuration for the peer, for the
|
||||
* given TIDs. This callback may sleep.
|
||||
+ *
|
||||
+ * @color_change: Initiate a color change.
|
||||
*/
|
||||
struct cfg80211_ops {
|
||||
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
|
||||
@@ -4309,6 +4332,9 @@ struct cfg80211_ops {
|
||||
const u8 *peer, u8 tids);
|
||||
int (*set_sar_specs)(struct wiphy *wiphy,
|
||||
struct cfg80211_sar_specs *sar);
|
||||
+ int (*color_change)(struct wiphy *wiphy,
|
||||
+ struct net_device *dev,
|
||||
+ struct cfg80211_color_change_settings *params);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -8092,4 +8118,70 @@ void cfg80211_update_owe_info_event(stru
|
||||
*/
|
||||
void cfg80211_bss_flush(struct wiphy *wiphy);
|
||||
|
||||
+/**
|
||||
+ * cfg80211_bss_color_notify - notify about bss color event
|
||||
+ * @dev: network device
|
||||
+ * @gfp: allocation flags
|
||||
+ * @cmd: the actual event we want to notify
|
||||
+ * @count: the number of TBTTs until the color change happens
|
||||
+ * @color_bitmap: representations of the colors that the local BSS is aware of
|
||||
+ */
|
||||
+int cfg80211_bss_color_notify(struct net_device *dev, gfp_t gfp,
|
||||
+ enum nl80211_commands cmd, u8 count,
|
||||
+ u64 color_bitmap);
|
||||
+
|
||||
+/**
|
||||
+ * cfg80211_obss_color_collision_notify - notify about bss color collision
|
||||
+ * @dev: network device
|
||||
+ * @color_bitmap: representations of the colors that the local BSS is aware of
|
||||
+ */
|
||||
+static inline int cfg80211_obss_color_collision_notify(struct net_device *dev,
|
||||
+ u64 color_bitmap)
|
||||
+{
|
||||
+ return cfg80211_bss_color_notify(dev, GFP_KERNEL,
|
||||
+ NL80211_CMD_OBSS_COLOR_COLLISION,
|
||||
+ 0, color_bitmap);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * cfg80211_color_change_started_notify - notify color change start
|
||||
+ * @dev: the device on which the color is switched
|
||||
+ * @count: the number of TBTTs until the color change happens
|
||||
+ *
|
||||
+ * Inform the userspace about the color change that has started.
|
||||
+ */
|
||||
+static inline int cfg80211_color_change_started_notify(struct net_device *dev,
|
||||
+ u8 count)
|
||||
+{
|
||||
+ return cfg80211_bss_color_notify(dev, GFP_KERNEL,
|
||||
+ NL80211_CMD_COLOR_CHANGE_STARTED,
|
||||
+ count, 0);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * cfg80211_color_change_aborted_notify - notify color change abort
|
||||
+ * @dev: the device on which the color is switched
|
||||
+ *
|
||||
+ * Inform the userspace about the color change that has aborted.
|
||||
+ */
|
||||
+static inline int cfg80211_color_change_aborted_notify(struct net_device *dev)
|
||||
+{
|
||||
+ return cfg80211_bss_color_notify(dev, GFP_KERNEL,
|
||||
+ NL80211_CMD_COLOR_CHANGE_ABORTED,
|
||||
+ 0, 0);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * cfg80211_color_change_notify - notify color change completion
|
||||
+ * @dev: the device on which the color was switched
|
||||
+ *
|
||||
+ * Inform the userspace about the color change that has completed.
|
||||
+ */
|
||||
+static inline int cfg80211_color_change_notify(struct net_device *dev)
|
||||
+{
|
||||
+ return cfg80211_bss_color_notify(dev, GFP_KERNEL,
|
||||
+ NL80211_CMD_COLOR_CHANGE_COMPLETED,
|
||||
+ 0, 0);
|
||||
+}
|
||||
+
|
||||
#endif /* __NET_CFG80211_H */
|
||||
--- a/include/uapi/linux/nl80211.h
|
||||
+++ b/include/uapi/linux/nl80211.h
|
||||
@@ -1185,6 +1185,21 @@
|
||||
* passed using %NL80211_ATTR_SAR_SPEC. %NL80211_ATTR_WIPHY is used to
|
||||
* specify the wiphy index to be applied to.
|
||||
*
|
||||
+ * @NL80211_CMD_OBSS_COLOR_COLLISION: This notification is sent out whenever
|
||||
+ * mac80211/drv detects a bss color collision.
|
||||
+ *
|
||||
+ * @NL80211_CMD_COLOR_CHANGE_REQUEST: This command is used to indicate that
|
||||
+ * userspace wants to change the BSS color.
|
||||
+ *
|
||||
+ * @NL80211_CMD_COLOR_CHANGE_STARTED: Notify userland, that a color change has
|
||||
+ * started
|
||||
+ *
|
||||
+ * @NL80211_CMD_COLOR_CHANGE_ABORTED: Notify userland, that the color change has
|
||||
+ * been aborted
|
||||
+ *
|
||||
+ * @NL80211_CMD_COLOR_CHANGE_COMPLETED: Notify userland that the color change
|
||||
+ * has completed
|
||||
+ *
|
||||
* @NL80211_CMD_MAX: highest used command number
|
||||
* @__NL80211_CMD_AFTER_LAST: internal use
|
||||
*/
|
||||
@@ -1417,6 +1432,14 @@ enum nl80211_commands {
|
||||
|
||||
NL80211_CMD_SET_SAR_SPECS,
|
||||
|
||||
+ NL80211_CMD_OBSS_COLOR_COLLISION,
|
||||
+
|
||||
+ NL80211_CMD_COLOR_CHANGE_REQUEST,
|
||||
+
|
||||
+ NL80211_CMD_COLOR_CHANGE_STARTED,
|
||||
+ NL80211_CMD_COLOR_CHANGE_ABORTED,
|
||||
+ NL80211_CMD_COLOR_CHANGE_COMPLETED,
|
||||
+
|
||||
/* add new commands above here */
|
||||
|
||||
/* used to define NL80211_CMD_MAX below */
|
||||
@@ -2560,6 +2583,16 @@ enum nl80211_commands {
|
||||
* disassoc events to indicate that an immediate reconnect to the AP
|
||||
* is desired.
|
||||
*
|
||||
+ * @NL80211_ATTR_OBSS_COLOR_BITMAP: bitmap of the u64 BSS colors for the
|
||||
+ * %NL80211_CMD_OBSS_COLOR_COLLISION event.
|
||||
+ *
|
||||
+ * @NL80211_ATTR_COLOR_CHANGE_COUNT: u8 attribute specifying the number of TBTT's
|
||||
+ * until the color switch event.
|
||||
+ * @NL80211_ATTR_COLOR_CHANGE_COLOR: u8 attribute specifying the color that we are
|
||||
+ * switching to
|
||||
+ * @NL80211_ATTR_COLOR_CHANGE_ELEMS: Nested set of attributes containing the IE
|
||||
+ * information for the time while performing a color switch.
|
||||
+ *
|
||||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
@@ -3057,6 +3090,12 @@ enum nl80211_attrs {
|
||||
|
||||
NL80211_ATTR_DISABLE_HE,
|
||||
|
||||
+ NL80211_ATTR_OBSS_COLOR_BITMAP,
|
||||
+
|
||||
+ NL80211_ATTR_COLOR_CHANGE_COUNT,
|
||||
+ NL80211_ATTR_COLOR_CHANGE_COLOR,
|
||||
+ NL80211_ATTR_COLOR_CHANGE_ELEMS,
|
||||
+
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
@@ -5950,6 +5989,9 @@ enum nl80211_feature_flags {
|
||||
* frame protection for all management frames exchanged during the
|
||||
* negotiation and range measurement procedure.
|
||||
*
|
||||
+ * @NL80211_EXT_FEATURE_BSS_COLOR: The driver supports BSS color collision
|
||||
+ * detection and change announcemnts.
|
||||
+ *
|
||||
* @NUM_NL80211_EXT_FEATURES: number of extended features.
|
||||
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
|
||||
*/
|
||||
@@ -6014,6 +6056,7 @@ enum nl80211_ext_feature_index {
|
||||
NL80211_EXT_FEATURE_SECURE_LTF,
|
||||
NL80211_EXT_FEATURE_SECURE_RTT,
|
||||
NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
|
||||
+ NL80211_EXT_FEATURE_BSS_COLOR,
|
||||
|
||||
/* add new features before the definition below */
|
||||
NUM_NL80211_EXT_FEATURES,
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -753,6 +753,10 @@ static const struct nla_policy nl80211_p
|
||||
NL80211_SAE_PWE_BOTH),
|
||||
[NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
|
||||
[NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
|
||||
+ [NL80211_ATTR_OBSS_COLOR_BITMAP] = { .type = NLA_U64 },
|
||||
+ [NL80211_ATTR_COLOR_CHANGE_COUNT] = { .type = NLA_U8 },
|
||||
+ [NL80211_ATTR_COLOR_CHANGE_COLOR] = { .type = NLA_U8 },
|
||||
+ [NL80211_ATTR_COLOR_CHANGE_ELEMS] = NLA_POLICY_NESTED(nl80211_policy),
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@@ -14677,6 +14681,106 @@ bad_tid_conf:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int nl80211_color_change(struct sk_buff *skb, struct genl_info *info)
|
||||
+{
|
||||
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
+ struct cfg80211_color_change_settings params = {};
|
||||
+ struct net_device *dev = info->user_ptr[1];
|
||||
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
+ struct nlattr **tb;
|
||||
+ u16 offset;
|
||||
+ int err;
|
||||
+
|
||||
+ if (!rdev->ops->color_change)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
+ NL80211_EXT_FEATURE_BSS_COLOR))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ if (wdev->iftype != NL80211_IFTYPE_AP)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ if (!info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT] ||
|
||||
+ !info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR] ||
|
||||
+ !info->attrs[NL80211_ATTR_COLOR_CHANGE_ELEMS])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ params.count = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT]);
|
||||
+ params.color = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR]);
|
||||
+
|
||||
+ err = nl80211_parse_beacon(rdev, info->attrs, ¶ms.beacon_next);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ tb = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*tb), GFP_KERNEL);
|
||||
+ if (!tb)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ err = nla_parse_nested(tb, NL80211_ATTR_MAX,
|
||||
+ info->attrs[NL80211_ATTR_COLOR_CHANGE_ELEMS],
|
||||
+ nl80211_policy, info->extack);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+
|
||||
+ err = nl80211_parse_beacon(rdev, tb, ¶ms.beacon_color_change);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (!tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (nla_len(tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]) != sizeof(u16)) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ offset = nla_get_u16(tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]);
|
||||
+ if (offset >= params.beacon_color_change.tail_len) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (params.beacon_color_change.tail[offset] != params.count) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ params.counter_offset_beacon = offset;
|
||||
+
|
||||
+ if (tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]) {
|
||||
+ if (nla_len(tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]) !=
|
||||
+ sizeof(u16)) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ offset = nla_get_u16(tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]);
|
||||
+ if (offset >= params.beacon_color_change.probe_resp_len) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (params.beacon_color_change.probe_resp[offset] !=
|
||||
+ params.count) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ params.counter_offset_presp = offset;
|
||||
+ }
|
||||
+
|
||||
+ wdev_lock(wdev);
|
||||
+ err = rdev_color_change(rdev, dev, ¶ms);
|
||||
+ wdev_unlock(wdev);
|
||||
+
|
||||
+out:
|
||||
+ kfree(tb);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
#define NL80211_FLAG_NEED_WIPHY 0x01
|
||||
#define NL80211_FLAG_NEED_NETDEV 0x02
|
||||
#define NL80211_FLAG_NEED_RTNL 0x04
|
||||
@@ -15758,6 +15862,14 @@ static const struct genl_small_ops nl802
|
||||
.internal_flags = NL80211_FLAG_NEED_WIPHY |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
+ {
|
||||
+ .cmd = NL80211_CMD_COLOR_CHANGE_REQUEST,
|
||||
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
+ .doit = nl80211_color_change,
|
||||
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
||||
+ NL80211_FLAG_NEED_RTNL,
|
||||
+ },
|
||||
};
|
||||
|
||||
static struct genl_family nl80211_fam __genl_ro_after_init = {
|
||||
@@ -17384,6 +17496,51 @@ void cfg80211_ch_switch_started_notify(s
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
|
||||
|
||||
+int cfg80211_bss_color_notify(struct net_device *dev, gfp_t gfp,
|
||||
+ enum nl80211_commands cmd, u8 count,
|
||||
+ u64 color_bitmap)
|
||||
+{
|
||||
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
+ struct wiphy *wiphy = wdev->wiphy;
|
||||
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
+ struct sk_buff *msg;
|
||||
+ void *hdr;
|
||||
+
|
||||
+ ASSERT_WDEV_LOCK(wdev);
|
||||
+
|
||||
+ trace_cfg80211_bss_color_notify(dev, cmd, count, color_bitmap);
|
||||
+
|
||||
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
|
||||
+ if (!msg)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
|
||||
+ if (!hdr)
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
+ if (cmd == NL80211_CMD_COLOR_CHANGE_STARTED &&
|
||||
+ nla_put_u32(msg, NL80211_ATTR_COLOR_CHANGE_COUNT, count))
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
+ if (cmd == NL80211_CMD_OBSS_COLOR_COLLISION &&
|
||||
+ nla_put_u64_64bit(msg, NL80211_ATTR_OBSS_COLOR_BITMAP,
|
||||
+ color_bitmap, NL80211_ATTR_PAD))
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
+ genlmsg_end(msg, hdr);
|
||||
+
|
||||
+ return genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
|
||||
+ msg, 0, NL80211_MCGRP_MLME, gfp);
|
||||
+
|
||||
+nla_put_failure:
|
||||
+ nlmsg_free(msg);
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+EXPORT_SYMBOL(cfg80211_bss_color_notify);
|
||||
+
|
||||
void
|
||||
nl80211_radar_notify(struct cfg80211_registered_device *rdev,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
--- a/net/wireless/rdev-ops.h
|
||||
+++ b/net/wireless/rdev-ops.h
|
||||
@@ -1368,4 +1368,17 @@ static inline int rdev_set_sar_specs(str
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static inline int rdev_color_change(struct cfg80211_registered_device *rdev,
|
||||
+ struct net_device *dev,
|
||||
+ struct cfg80211_color_change_settings *params)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ trace_rdev_color_change(&rdev->wiphy, dev, params);
|
||||
+ ret = rdev->ops->color_change(&rdev->wiphy, dev, params);
|
||||
+ trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
#endif /* __CFG80211_RDEV_OPS */
|
||||
--- a/net/wireless/trace.h
|
||||
+++ b/net/wireless/trace.h
|
||||
@@ -3570,6 +3570,52 @@ TRACE_EVENT(rdev_set_sar_specs,
|
||||
WIPHY_PR_ARG, __entry->type, __entry->num)
|
||||
);
|
||||
|
||||
+TRACE_EVENT(rdev_color_change,
|
||||
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
+ struct cfg80211_color_change_settings *params),
|
||||
+ TP_ARGS(wiphy, netdev, params),
|
||||
+ TP_STRUCT__entry(
|
||||
+ WIPHY_ENTRY
|
||||
+ NETDEV_ENTRY
|
||||
+ __field(u8, count)
|
||||
+ __field(u16, bcn_ofs)
|
||||
+ __field(u16, pres_ofs)
|
||||
+ ),
|
||||
+ TP_fast_assign(
|
||||
+ WIPHY_ASSIGN;
|
||||
+ NETDEV_ASSIGN;
|
||||
+ __entry->count = params->count;
|
||||
+ __entry->bcn_ofs = params->counter_offset_beacon;
|
||||
+ __entry->pres_ofs = params->counter_offset_presp;
|
||||
+ ),
|
||||
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT
|
||||
+ ", count: %u",
|
||||
+ WIPHY_PR_ARG, NETDEV_PR_ARG,
|
||||
+ __entry->count)
|
||||
+);
|
||||
+
|
||||
+TRACE_EVENT(cfg80211_bss_color_notify,
|
||||
+ TP_PROTO(struct net_device *netdev,
|
||||
+ enum nl80211_commands cmd,
|
||||
+ u8 count, u64 color_bitmap),
|
||||
+ TP_ARGS(netdev, cmd, count, color_bitmap),
|
||||
+ TP_STRUCT__entry(
|
||||
+ NETDEV_ENTRY
|
||||
+ __field(enum nl80211_bss_scan_width, cmd)
|
||||
+ __field(u8, count)
|
||||
+ __field(u64, color_bitmap)
|
||||
+ ),
|
||||
+ TP_fast_assign(
|
||||
+ NETDEV_ASSIGN;
|
||||
+ __entry->cmd = cmd;
|
||||
+ __entry->count = count;
|
||||
+ __entry->color_bitmap = color_bitmap;
|
||||
+ ),
|
||||
+ TP_printk(NETDEV_PR_FMT ", cmd: %x, count: %u, bitmap: %llx",
|
||||
+ NETDEV_PR_ARG, __entry->cmd, __entry->count,
|
||||
+ __entry->color_bitmap)
|
||||
+);
|
||||
+
|
||||
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
@ -1,767 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 22 Jan 2021 23:57:50 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: significantly redesign the rate
|
||||
probing strategy
|
||||
|
||||
The biggest flaw in current minstrel_ht is the fact that it needs way too
|
||||
many probing packets to be able to quickly find the best rate.
|
||||
Depending on the wifi hardware and operating mode, this can significantly
|
||||
reduce throughput when not operating at the highest available data rate.
|
||||
|
||||
In order to be able to significantly reduce the amount of rate sampling,
|
||||
we need a much smarter selection of probing rates.
|
||||
|
||||
The new approach introduced by this patch maintains a limited set of
|
||||
available rates to be tested during a statistics window.
|
||||
|
||||
They are split into distinct categories:
|
||||
- MINSTREL_SAMPLE_TYPE_INC - incremental rate upgrade:
|
||||
Pick the next rate group and find the first rate that is faster than
|
||||
the current max. throughput rate
|
||||
- MINSTREL_SAMPLE_TYPE_JUMP - random testing of higher rates:
|
||||
Pick a random rate from the next group that is faster than the current
|
||||
max throughput rate. This allows faster adaptation when the link changes
|
||||
significantly
|
||||
- MINSTREL_SAMPLE_TYPE_SLOW - test a rate between max_prob, max_tp2 and
|
||||
max_tp in order to reduce the gap between them
|
||||
|
||||
In order to prioritize sampling, every 6 attempts are split into 3x INC,
|
||||
2x JUMP, 1x SLOW.
|
||||
|
||||
Available rates are checked and refilled on every stats window update.
|
||||
|
||||
With this approach, we finally get a very small delta in throughput when
|
||||
comparing setting the optimal data rate as a fixed rate vs normal rate
|
||||
control operation.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -266,6 +266,14 @@ const struct mcs_group minstrel_mcs_grou
|
||||
const s16 minstrel_cck_bitrates[4] = { 10, 20, 55, 110 };
|
||||
const s16 minstrel_ofdm_bitrates[8] = { 60, 90, 120, 180, 240, 360, 480, 540 };
|
||||
static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly;
|
||||
+static const u8 minstrel_sample_seq[] = {
|
||||
+ MINSTREL_SAMPLE_TYPE_INC,
|
||||
+ MINSTREL_SAMPLE_TYPE_JUMP,
|
||||
+ MINSTREL_SAMPLE_TYPE_INC,
|
||||
+ MINSTREL_SAMPLE_TYPE_JUMP,
|
||||
+ MINSTREL_SAMPLE_TYPE_INC,
|
||||
+ MINSTREL_SAMPLE_TYPE_SLOW,
|
||||
+};
|
||||
|
||||
static void
|
||||
minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi);
|
||||
@@ -620,77 +628,31 @@ minstrel_ht_prob_rate_reduce_streams(str
|
||||
}
|
||||
}
|
||||
|
||||
-static bool
|
||||
-minstrel_ht_probe_group(struct minstrel_ht_sta *mi, const struct mcs_group *tp_group,
|
||||
- int tp_idx, const struct mcs_group *group)
|
||||
-{
|
||||
- if (group->bw < tp_group->bw)
|
||||
- return false;
|
||||
-
|
||||
- if (group->streams == tp_group->streams)
|
||||
- return true;
|
||||
-
|
||||
- if (tp_idx < 4 && group->streams == tp_group->streams - 1)
|
||||
- return true;
|
||||
-
|
||||
- return group->streams == tp_group->streams + 1;
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-minstrel_ht_find_probe_rates(struct minstrel_ht_sta *mi, u16 *rates, int *n_rates,
|
||||
- bool faster_rate)
|
||||
+static u16
|
||||
+__minstrel_ht_get_sample_rate(struct minstrel_ht_sta *mi,
|
||||
+ enum minstrel_sample_type type)
|
||||
{
|
||||
- const struct mcs_group *group, *tp_group;
|
||||
- int i, g, max_dur;
|
||||
- int tp_idx;
|
||||
-
|
||||
- tp_group = &minstrel_mcs_groups[MI_RATE_GROUP(mi->max_tp_rate[0])];
|
||||
- tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]);
|
||||
-
|
||||
- max_dur = minstrel_get_duration(mi->max_tp_rate[0]);
|
||||
- if (faster_rate)
|
||||
- max_dur -= max_dur / 16;
|
||||
-
|
||||
- for (g = 0; g < MINSTREL_GROUPS_NB; g++) {
|
||||
- u16 supported = mi->supported[g];
|
||||
-
|
||||
- if (!supported)
|
||||
- continue;
|
||||
+ u16 *rates = mi->sample[type].sample_rates;
|
||||
+ u16 cur;
|
||||
+ int i;
|
||||
|
||||
- group = &minstrel_mcs_groups[g];
|
||||
- if (!minstrel_ht_probe_group(mi, tp_group, tp_idx, group))
|
||||
+ for (i = 0; i < MINSTREL_SAMPLE_RATES; i++) {
|
||||
+ if (!rates[i])
|
||||
continue;
|
||||
|
||||
- for (i = 0; supported; supported >>= 1, i++) {
|
||||
- int idx;
|
||||
-
|
||||
- if (!(supported & 1))
|
||||
- continue;
|
||||
-
|
||||
- if ((group->duration[i] << group->shift) > max_dur)
|
||||
- continue;
|
||||
-
|
||||
- idx = MI_RATE(g, i);
|
||||
- if (idx == mi->max_tp_rate[0])
|
||||
- continue;
|
||||
-
|
||||
- rates[(*n_rates)++] = idx;
|
||||
- break;
|
||||
- }
|
||||
+ cur = rates[i];
|
||||
+ rates[i] = 0;
|
||||
+ return cur;
|
||||
}
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
minstrel_ht_rate_sample_switch(struct minstrel_priv *mp,
|
||||
struct minstrel_ht_sta *mi)
|
||||
{
|
||||
- struct minstrel_rate_stats *mrs;
|
||||
- u16 rates[MINSTREL_GROUPS_NB];
|
||||
- int n_rates = 0;
|
||||
- int probe_rate = 0;
|
||||
- bool faster_rate;
|
||||
- int i;
|
||||
- u8 random;
|
||||
+ u16 rate;
|
||||
|
||||
/*
|
||||
* Use rate switching instead of probing packets for devices with
|
||||
@@ -699,43 +661,11 @@ minstrel_ht_rate_sample_switch(struct mi
|
||||
if (mp->hw->max_rates > 1)
|
||||
return;
|
||||
|
||||
- /*
|
||||
- * If the current EWMA prob is >75%, look for a rate that's 6.25%
|
||||
- * faster than the max tp rate.
|
||||
- * If that fails, look again for a rate that is at least as fast
|
||||
- */
|
||||
- mrs = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
|
||||
- faster_rate = mrs->prob_avg > MINSTREL_FRAC(75, 100);
|
||||
- minstrel_ht_find_probe_rates(mi, rates, &n_rates, faster_rate);
|
||||
- if (!n_rates && faster_rate)
|
||||
- minstrel_ht_find_probe_rates(mi, rates, &n_rates, false);
|
||||
-
|
||||
- /* If no suitable rate was found, try to pick the next one in the group */
|
||||
- if (!n_rates) {
|
||||
- int g_idx = MI_RATE_GROUP(mi->max_tp_rate[0]);
|
||||
- u16 supported = mi->supported[g_idx];
|
||||
-
|
||||
- supported >>= MI_RATE_IDX(mi->max_tp_rate[0]);
|
||||
- for (i = 0; supported; supported >>= 1, i++) {
|
||||
- if (!(supported & 1))
|
||||
- continue;
|
||||
-
|
||||
- probe_rate = mi->max_tp_rate[0] + i;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
+ rate = __minstrel_ht_get_sample_rate(mi, MINSTREL_SAMPLE_TYPE_INC);
|
||||
+ if (!rate)
|
||||
return;
|
||||
- }
|
||||
-
|
||||
- i = 0;
|
||||
- if (n_rates > 1) {
|
||||
- random = prandom_u32();
|
||||
- i = random % n_rates;
|
||||
- }
|
||||
- probe_rate = rates[i];
|
||||
|
||||
-out:
|
||||
- mi->sample_rate = probe_rate;
|
||||
+ mi->sample_rate = rate;
|
||||
mi->sample_mode = MINSTREL_SAMPLE_ACTIVE;
|
||||
}
|
||||
|
||||
@@ -804,6 +734,274 @@ minstrel_ht_calc_rate_stats(struct minst
|
||||
mrs->attempts = 0;
|
||||
}
|
||||
|
||||
+static bool
|
||||
+minstrel_ht_find_sample_rate(struct minstrel_ht_sta *mi, int type, int idx)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < MINSTREL_SAMPLE_RATES; i++) {
|
||||
+ u16 cur = mi->sample[type].sample_rates[i];
|
||||
+
|
||||
+ if (cur == idx)
|
||||
+ return true;
|
||||
+
|
||||
+ if (!cur)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+minstrel_ht_move_sample_rates(struct minstrel_ht_sta *mi, int type,
|
||||
+ u32 fast_rate_dur, u32 slow_rate_dur)
|
||||
+{
|
||||
+ u16 *rates = mi->sample[type].sample_rates;
|
||||
+ int i, j;
|
||||
+
|
||||
+ for (i = 0, j = 0; i < MINSTREL_SAMPLE_RATES; i++) {
|
||||
+ u32 duration;
|
||||
+ bool valid = false;
|
||||
+ u16 cur;
|
||||
+
|
||||
+ cur = rates[i];
|
||||
+ if (!cur)
|
||||
+ continue;
|
||||
+
|
||||
+ duration = minstrel_get_duration(cur);
|
||||
+ switch (type) {
|
||||
+ case MINSTREL_SAMPLE_TYPE_SLOW:
|
||||
+ valid = duration > fast_rate_dur &&
|
||||
+ duration < slow_rate_dur;
|
||||
+ break;
|
||||
+ case MINSTREL_SAMPLE_TYPE_INC:
|
||||
+ case MINSTREL_SAMPLE_TYPE_JUMP:
|
||||
+ valid = duration < fast_rate_dur;
|
||||
+ break;
|
||||
+ default:
|
||||
+ valid = false;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!valid) {
|
||||
+ rates[i] = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (i == j)
|
||||
+ continue;
|
||||
+
|
||||
+ rates[j++] = cur;
|
||||
+ rates[i] = 0;
|
||||
+ }
|
||||
+
|
||||
+ return j;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+minstrel_ht_group_min_rate_offset(struct minstrel_ht_sta *mi, int group,
|
||||
+ u32 max_duration)
|
||||
+{
|
||||
+ u16 supported = mi->supported[group];
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < MCS_GROUP_RATES && supported; i++, supported >>= 1) {
|
||||
+ if (!(supported & BIT(0)))
|
||||
+ continue;
|
||||
+
|
||||
+ if (minstrel_get_duration(MI_RATE(group, i)) >= max_duration)
|
||||
+ continue;
|
||||
+
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Incremental update rates:
|
||||
+ * Flip through groups and pick the first group rate that is faster than the
|
||||
+ * highest currently selected rate
|
||||
+ */
|
||||
+static u16
|
||||
+minstrel_ht_next_inc_rate(struct minstrel_ht_sta *mi, u32 fast_rate_dur)
|
||||
+{
|
||||
+ struct minstrel_mcs_group_data *mg;
|
||||
+ u8 type = MINSTREL_SAMPLE_TYPE_INC;
|
||||
+ int i, index = 0;
|
||||
+ u8 group;
|
||||
+
|
||||
+ group = mi->sample[type].sample_group;
|
||||
+ for (i = 0; i < ARRAY_SIZE(minstrel_mcs_groups); i++) {
|
||||
+ group = (group + 1) % ARRAY_SIZE(minstrel_mcs_groups);
|
||||
+ mg = &mi->groups[group];
|
||||
+
|
||||
+ index = minstrel_ht_group_min_rate_offset(mi, group,
|
||||
+ fast_rate_dur);
|
||||
+ if (index < 0)
|
||||
+ continue;
|
||||
+
|
||||
+ index = MI_RATE(group, index & 0xf);
|
||||
+ if (!minstrel_ht_find_sample_rate(mi, type, index))
|
||||
+ goto out;
|
||||
+ }
|
||||
+ index = 0;
|
||||
+
|
||||
+out:
|
||||
+ mi->sample[type].sample_group = group;
|
||||
+
|
||||
+ return index;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+minstrel_ht_next_group_sample_rate(struct minstrel_ht_sta *mi, int group,
|
||||
+ u16 supported, int offset)
|
||||
+{
|
||||
+ struct minstrel_mcs_group_data *mg = &mi->groups[group];
|
||||
+ u16 idx;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < MCS_GROUP_RATES; i++) {
|
||||
+ idx = sample_table[mg->column][mg->index];
|
||||
+ if (++mg->index >= MCS_GROUP_RATES) {
|
||||
+ mg->index = 0;
|
||||
+ if (++mg->column >= ARRAY_SIZE(sample_table))
|
||||
+ mg->column = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (idx < offset)
|
||||
+ continue;
|
||||
+
|
||||
+ if (!(supported & BIT(idx)))
|
||||
+ continue;
|
||||
+
|
||||
+ return MI_RATE(group, idx);
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Jump rates:
|
||||
+ * Sample random rates, use those that are faster than the highest
|
||||
+ * currently selected rate. Rates between the fastest and the slowest
|
||||
+ * get sorted into the slow sample bucket, but only if it has room
|
||||
+ */
|
||||
+static u16
|
||||
+minstrel_ht_next_jump_rate(struct minstrel_ht_sta *mi, u32 fast_rate_dur,
|
||||
+ u32 slow_rate_dur, int *slow_rate_ofs)
|
||||
+{
|
||||
+ struct minstrel_mcs_group_data *mg;
|
||||
+ struct minstrel_rate_stats *mrs;
|
||||
+ u32 max_duration = slow_rate_dur;
|
||||
+ int i, index, offset;
|
||||
+ u16 *slow_rates;
|
||||
+ u16 supported;
|
||||
+ u32 duration;
|
||||
+ u8 group;
|
||||
+
|
||||
+ if (*slow_rate_ofs >= MINSTREL_SAMPLE_RATES)
|
||||
+ max_duration = fast_rate_dur;
|
||||
+
|
||||
+ slow_rates = mi->sample[MINSTREL_SAMPLE_TYPE_SLOW].sample_rates;
|
||||
+ group = mi->sample[MINSTREL_SAMPLE_TYPE_JUMP].sample_group;
|
||||
+ for (i = 0; i < ARRAY_SIZE(minstrel_mcs_groups); i++) {
|
||||
+ u8 type;
|
||||
+
|
||||
+ group = (group + 1) % ARRAY_SIZE(minstrel_mcs_groups);
|
||||
+ mg = &mi->groups[group];
|
||||
+
|
||||
+ supported = mi->supported[group];
|
||||
+ if (!supported)
|
||||
+ continue;
|
||||
+
|
||||
+ offset = minstrel_ht_group_min_rate_offset(mi, group,
|
||||
+ max_duration);
|
||||
+ if (offset < 0)
|
||||
+ continue;
|
||||
+
|
||||
+ index = minstrel_ht_next_group_sample_rate(mi, group, supported,
|
||||
+ offset);
|
||||
+ if (index < 0)
|
||||
+ continue;
|
||||
+
|
||||
+ duration = minstrel_get_duration(index);
|
||||
+ if (duration < fast_rate_dur)
|
||||
+ type = MINSTREL_SAMPLE_TYPE_JUMP;
|
||||
+ else
|
||||
+ type = MINSTREL_SAMPLE_TYPE_SLOW;
|
||||
+
|
||||
+ if (minstrel_ht_find_sample_rate(mi, type, index))
|
||||
+ continue;
|
||||
+
|
||||
+ if (type == MINSTREL_SAMPLE_TYPE_JUMP)
|
||||
+ goto found;
|
||||
+
|
||||
+ if (*slow_rate_ofs >= MINSTREL_SAMPLE_RATES)
|
||||
+ continue;
|
||||
+
|
||||
+ if (duration >= slow_rate_dur)
|
||||
+ continue;
|
||||
+
|
||||
+ /* skip slow rates with high success probability */
|
||||
+ mrs = minstrel_get_ratestats(mi, index);
|
||||
+ if (mrs->prob_avg > MINSTREL_FRAC(95, 100))
|
||||
+ continue;
|
||||
+
|
||||
+ slow_rates[(*slow_rate_ofs)++] = index;
|
||||
+ if (*slow_rate_ofs >= MINSTREL_SAMPLE_RATES)
|
||||
+ max_duration = fast_rate_dur;
|
||||
+ }
|
||||
+ index = 0;
|
||||
+
|
||||
+found:
|
||||
+ mi->sample[MINSTREL_SAMPLE_TYPE_JUMP].sample_group = group;
|
||||
+
|
||||
+ return index;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+minstrel_ht_refill_sample_rates(struct minstrel_ht_sta *mi)
|
||||
+{
|
||||
+ u32 prob_dur = minstrel_get_duration(mi->max_prob_rate);
|
||||
+ u32 tp_dur = minstrel_get_duration(mi->max_tp_rate[0]);
|
||||
+ u32 tp2_dur = minstrel_get_duration(mi->max_tp_rate[1]);
|
||||
+ u32 fast_rate_dur = min(min(tp_dur, tp2_dur), prob_dur);
|
||||
+ u32 slow_rate_dur = max(max(tp_dur, tp2_dur), prob_dur);
|
||||
+ u16 *rates;
|
||||
+ int i, j;
|
||||
+
|
||||
+ rates = mi->sample[MINSTREL_SAMPLE_TYPE_INC].sample_rates;
|
||||
+ i = minstrel_ht_move_sample_rates(mi, MINSTREL_SAMPLE_TYPE_INC,
|
||||
+ fast_rate_dur, slow_rate_dur);
|
||||
+ while (i < MINSTREL_SAMPLE_RATES) {
|
||||
+ rates[i] = minstrel_ht_next_inc_rate(mi, tp_dur);
|
||||
+ if (!rates[i])
|
||||
+ break;
|
||||
+
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ rates = mi->sample[MINSTREL_SAMPLE_TYPE_JUMP].sample_rates;
|
||||
+ i = minstrel_ht_move_sample_rates(mi, MINSTREL_SAMPLE_TYPE_JUMP,
|
||||
+ fast_rate_dur, slow_rate_dur);
|
||||
+ j = minstrel_ht_move_sample_rates(mi, MINSTREL_SAMPLE_TYPE_SLOW,
|
||||
+ fast_rate_dur, slow_rate_dur);
|
||||
+ while (i < MINSTREL_SAMPLE_RATES) {
|
||||
+ rates[i] = minstrel_ht_next_jump_rate(mi, fast_rate_dur,
|
||||
+ slow_rate_dur, &j);
|
||||
+ if (!rates[i])
|
||||
+ break;
|
||||
+
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(mi->sample); i++)
|
||||
+ memcpy(mi->sample[i].cur_sample_rates, mi->sample[i].sample_rates,
|
||||
+ sizeof(mi->sample[i].cur_sample_rates));
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Update rate statistics and select new primary rates
|
||||
*
|
||||
@@ -848,8 +1046,6 @@ minstrel_ht_update_stats(struct minstrel
|
||||
mi->ampdu_packets = 0;
|
||||
}
|
||||
|
||||
- mi->sample_count = 0;
|
||||
-
|
||||
if (mi->supported[MINSTREL_CCK_GROUP])
|
||||
group = MINSTREL_CCK_GROUP;
|
||||
else if (mi->supported[MINSTREL_OFDM_GROUP])
|
||||
@@ -884,8 +1080,6 @@ minstrel_ht_update_stats(struct minstrel
|
||||
if (!mi->supported[group])
|
||||
continue;
|
||||
|
||||
- mi->sample_count++;
|
||||
-
|
||||
/* (re)Initialize group rate indexes */
|
||||
for(j = 0; j < MAX_THR_RATES; j++)
|
||||
tmp_group_tp_rate[j] = MI_RATE(group, 0);
|
||||
@@ -952,9 +1146,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
|
||||
/* Try to increase robustness of max_prob_rate*/
|
||||
minstrel_ht_prob_rate_reduce_streams(mi);
|
||||
-
|
||||
- /* try to sample half of all available rates during each interval */
|
||||
- mi->sample_count *= 4;
|
||||
+ minstrel_ht_refill_sample_rates(mi);
|
||||
|
||||
if (sample)
|
||||
minstrel_ht_rate_sample_switch(mp, mi);
|
||||
@@ -971,6 +1163,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
|
||||
/* Reset update timer */
|
||||
mi->last_stats_update = jiffies;
|
||||
+ mi->sample_time = jiffies;
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -1001,28 +1194,6 @@ minstrel_ht_txstat_valid(struct minstrel
|
||||
}
|
||||
|
||||
static void
|
||||
-minstrel_set_next_sample_idx(struct minstrel_ht_sta *mi)
|
||||
-{
|
||||
- struct minstrel_mcs_group_data *mg;
|
||||
-
|
||||
- for (;;) {
|
||||
- mi->sample_group++;
|
||||
- mi->sample_group %= ARRAY_SIZE(minstrel_mcs_groups);
|
||||
- mg = &mi->groups[mi->sample_group];
|
||||
-
|
||||
- if (!mi->supported[mi->sample_group])
|
||||
- continue;
|
||||
-
|
||||
- if (++mg->index >= MCS_GROUP_RATES) {
|
||||
- mg->index = 0;
|
||||
- if (++mg->column >= ARRAY_SIZE(sample_table))
|
||||
- mg->column = 0;
|
||||
- }
|
||||
- break;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary)
|
||||
{
|
||||
int group, orig_group;
|
||||
@@ -1107,14 +1278,6 @@ minstrel_ht_tx_status(void *priv, struct
|
||||
mi->ampdu_packets++;
|
||||
mi->ampdu_len += info->status.ampdu_len;
|
||||
|
||||
- if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) {
|
||||
- int avg_ampdu_len = minstrel_ht_avg_ampdu_len(mi);
|
||||
-
|
||||
- mi->sample_wait = 16 + 2 * avg_ampdu_len;
|
||||
- mi->sample_tries = 1;
|
||||
- mi->sample_count--;
|
||||
- }
|
||||
-
|
||||
if (mi->sample_mode != MINSTREL_SAMPLE_IDLE)
|
||||
rate_sample = minstrel_get_ratestats(mi, mi->sample_rate);
|
||||
|
||||
@@ -1386,97 +1549,20 @@ minstrel_ht_update_rates(struct minstrel
|
||||
rate_control_set_rates(mp->hw, mi->sta, rates);
|
||||
}
|
||||
|
||||
-static int
|
||||
-minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
|
||||
+static u16
|
||||
+minstrel_ht_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
|
||||
{
|
||||
- struct minstrel_rate_stats *mrs;
|
||||
- struct minstrel_mcs_group_data *mg;
|
||||
- unsigned int sample_dur, sample_group, cur_max_tp_streams;
|
||||
- int tp_rate1, tp_rate2;
|
||||
- int sample_idx = 0;
|
||||
-
|
||||
- if (mp->hw->max_rates == 1 && mp->sample_switch &&
|
||||
- (mi->total_packets_cur >= SAMPLE_SWITCH_THR ||
|
||||
- mp->sample_switch == 1))
|
||||
- return -1;
|
||||
-
|
||||
- if (mi->sample_wait > 0) {
|
||||
- mi->sample_wait--;
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- if (!mi->sample_tries)
|
||||
- return -1;
|
||||
-
|
||||
- sample_group = mi->sample_group;
|
||||
- mg = &mi->groups[sample_group];
|
||||
- sample_idx = sample_table[mg->column][mg->index];
|
||||
- minstrel_set_next_sample_idx(mi);
|
||||
-
|
||||
- if (!(mi->supported[sample_group] & BIT(sample_idx)))
|
||||
- return -1;
|
||||
+ u8 seq;
|
||||
|
||||
- mrs = &mg->rates[sample_idx];
|
||||
- sample_idx += MI_RATE(sample_group, 0);
|
||||
-
|
||||
- tp_rate1 = mi->max_tp_rate[0];
|
||||
-
|
||||
- /* Set tp_rate2 to the second highest max_tp_rate */
|
||||
- if (minstrel_get_duration(mi->max_tp_rate[0]) >
|
||||
- minstrel_get_duration(mi->max_tp_rate[1])) {
|
||||
- tp_rate2 = mi->max_tp_rate[0];
|
||||
+ if (mp->hw->max_rates > 1) {
|
||||
+ seq = mi->sample_seq;
|
||||
+ mi->sample_seq = (seq + 1) % ARRAY_SIZE(minstrel_sample_seq);
|
||||
+ seq = minstrel_sample_seq[seq];
|
||||
} else {
|
||||
- tp_rate2 = mi->max_tp_rate[1];
|
||||
+ seq = MINSTREL_SAMPLE_TYPE_INC;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Sampling might add some overhead (RTS, no aggregation)
|
||||
- * to the frame. Hence, don't use sampling for the highest currently
|
||||
- * used highest throughput or probability rate.
|
||||
- */
|
||||
- if (sample_idx == mi->max_tp_rate[0] || sample_idx == mi->max_prob_rate)
|
||||
- return -1;
|
||||
-
|
||||
- /*
|
||||
- * Do not sample if the probability is already higher than 95%,
|
||||
- * or if the rate is 3 times slower than the current max probability
|
||||
- * rate, to avoid wasting airtime.
|
||||
- */
|
||||
- sample_dur = minstrel_get_duration(sample_idx);
|
||||
- if (mrs->prob_avg > MINSTREL_FRAC(95, 100) ||
|
||||
- minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur)
|
||||
- return -1;
|
||||
-
|
||||
-
|
||||
- /*
|
||||
- * For devices with no configurable multi-rate retry, skip sampling
|
||||
- * below the per-group max throughput rate, and only use one sampling
|
||||
- * attempt per rate
|
||||
- */
|
||||
- if (mp->hw->max_rates == 1 &&
|
||||
- (minstrel_get_duration(mg->max_group_tp_rate[0]) < sample_dur ||
|
||||
- mrs->attempts))
|
||||
- return -1;
|
||||
-
|
||||
- /* Skip already sampled slow rates */
|
||||
- if (sample_dur >= minstrel_get_duration(tp_rate1) && mrs->attempts)
|
||||
- return -1;
|
||||
-
|
||||
- /*
|
||||
- * Make sure that lower rates get sampled only occasionally,
|
||||
- * if the link is working perfectly.
|
||||
- */
|
||||
-
|
||||
- cur_max_tp_streams = minstrel_mcs_groups[MI_RATE_GROUP(tp_rate1)].streams;
|
||||
- if (sample_dur >= minstrel_get_duration(tp_rate2) &&
|
||||
- (cur_max_tp_streams - 1 <
|
||||
- minstrel_mcs_groups[sample_group].streams ||
|
||||
- sample_dur >= minstrel_get_duration(mi->max_prob_rate)))
|
||||
- return -1;
|
||||
-
|
||||
- mi->sample_tries--;
|
||||
-
|
||||
- return sample_idx;
|
||||
+ return __minstrel_ht_get_sample_rate(mi, seq);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1488,7 +1574,7 @@ minstrel_ht_get_rate(void *priv, struct
|
||||
struct ieee80211_tx_rate *rate = &info->status.rates[0];
|
||||
struct minstrel_ht_sta *mi = priv_sta;
|
||||
struct minstrel_priv *mp = priv;
|
||||
- int sample_idx;
|
||||
+ u16 sample_idx;
|
||||
|
||||
if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
|
||||
!minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_prob_rate)))
|
||||
@@ -1504,11 +1590,19 @@ minstrel_ht_get_rate(void *priv, struct
|
||||
/* Don't use EAPOL frames for sampling on non-mrr hw */
|
||||
if (mp->hw->max_rates == 1 &&
|
||||
(info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO))
|
||||
- sample_idx = -1;
|
||||
- else
|
||||
- sample_idx = minstrel_get_sample_rate(mp, mi);
|
||||
+ return;
|
||||
+
|
||||
+ if (mp->hw->max_rates == 1 && mp->sample_switch &&
|
||||
+ (mi->total_packets_cur >= SAMPLE_SWITCH_THR ||
|
||||
+ mp->sample_switch == 1))
|
||||
+ return;
|
||||
+
|
||||
+ if (time_is_before_jiffies(mi->sample_time))
|
||||
+ return;
|
||||
|
||||
- if (sample_idx < 0)
|
||||
+ mi->sample_time = jiffies + MINSTREL_SAMPLE_INTERVAL;
|
||||
+ sample_idx = minstrel_ht_get_sample_rate(mp, mi);
|
||||
+ if (!sample_idx)
|
||||
return;
|
||||
|
||||
sample_group = &minstrel_mcs_groups[MI_RATE_GROUP(sample_idx)];
|
||||
@@ -1629,16 +1723,6 @@ minstrel_ht_update_caps(void *priv, stru
|
||||
|
||||
mi->avg_ampdu_len = MINSTREL_FRAC(1, 1);
|
||||
|
||||
- /* When using MRR, sample more on the first attempt, without delay */
|
||||
- if (mp->has_mrr) {
|
||||
- mi->sample_count = 16;
|
||||
- mi->sample_wait = 0;
|
||||
- } else {
|
||||
- mi->sample_count = 8;
|
||||
- mi->sample_wait = 8;
|
||||
- }
|
||||
- mi->sample_tries = 4;
|
||||
-
|
||||
if (!use_vht) {
|
||||
stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >>
|
||||
IEEE80211_HT_CAP_RX_STBC_SHIFT;
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.h
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.h
|
||||
@@ -69,6 +69,8 @@
|
||||
#define MI_RATE_IDX(_rate) FIELD_GET(MI_RATE_IDX_MASK, _rate)
|
||||
#define MI_RATE_GROUP(_rate) FIELD_GET(MI_RATE_GROUP_MASK, _rate)
|
||||
|
||||
+#define MINSTREL_SAMPLE_RATES 5 /* rates per sample type */
|
||||
+#define MINSTREL_SAMPLE_INTERVAL (HZ / 50)
|
||||
|
||||
struct minstrel_priv {
|
||||
struct ieee80211_hw *hw;
|
||||
@@ -126,6 +128,13 @@ struct minstrel_rate_stats {
|
||||
bool retry_updated;
|
||||
};
|
||||
|
||||
+enum minstrel_sample_type {
|
||||
+ MINSTREL_SAMPLE_TYPE_INC,
|
||||
+ MINSTREL_SAMPLE_TYPE_JUMP,
|
||||
+ MINSTREL_SAMPLE_TYPE_SLOW,
|
||||
+ __MINSTREL_SAMPLE_TYPE_MAX
|
||||
+};
|
||||
+
|
||||
struct minstrel_mcs_group_data {
|
||||
u8 index;
|
||||
u8 column;
|
||||
@@ -144,6 +153,12 @@ enum minstrel_sample_mode {
|
||||
MINSTREL_SAMPLE_PENDING,
|
||||
};
|
||||
|
||||
+struct minstrel_sample_category {
|
||||
+ u8 sample_group;
|
||||
+ u16 sample_rates[MINSTREL_SAMPLE_RATES];
|
||||
+ u16 cur_sample_rates[MINSTREL_SAMPLE_RATES];
|
||||
+};
|
||||
+
|
||||
struct minstrel_ht_sta {
|
||||
struct ieee80211_sta *sta;
|
||||
|
||||
@@ -175,16 +190,14 @@ struct minstrel_ht_sta {
|
||||
/* tx flags to add for frames for this sta */
|
||||
u32 tx_flags;
|
||||
|
||||
- u8 sample_wait;
|
||||
- u8 sample_tries;
|
||||
- u8 sample_count;
|
||||
+ unsigned long sample_time;
|
||||
+ struct minstrel_sample_category sample[__MINSTREL_SAMPLE_TYPE_MAX];
|
||||
+
|
||||
+ u8 sample_seq;
|
||||
|
||||
enum minstrel_sample_mode sample_mode;
|
||||
u16 sample_rate;
|
||||
|
||||
- /* current MCS group to be sampled */
|
||||
- u8 sample_group;
|
||||
-
|
||||
u8 band;
|
||||
|
||||
/* Bitfield of supported MCS rates of all groups */
|
@ -1,26 +0,0 @@
|
||||
From: Ryder Lee <ryder.lee@mediatek.com>
|
||||
Date: Fri, 18 Jun 2021 04:38:59 +0800
|
||||
Subject: [PATCH] mac80211: check per vif offload_flags in Tx path
|
||||
|
||||
offload_flags has been introduced to indicate encap status of each interface.
|
||||
An interface can encap offload at runtime, or if it has some extra limitations
|
||||
it can simply override the flags, so it's more flexible to check offload_flags
|
||||
in Tx path.
|
||||
|
||||
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
||||
Link: https://lore.kernel.org/r/177785418cf407808bf3a44760302d0647076990.1623961575.git.ryder.lee@mediatek.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3335,6 +3335,9 @@ static bool ieee80211_amsdu_aggregate(st
|
||||
if (!ieee80211_hw_check(&local->hw, TX_AMSDU))
|
||||
return false;
|
||||
|
||||
+ if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
|
||||
+ return false;
|
||||
+
|
||||
if (skb_is_gso(skb))
|
||||
return false;
|
||||
|
@ -1,53 +0,0 @@
|
||||
From: Christian Lamparter <chunkeey@gmail.com>
|
||||
Date: Sat, 16 Nov 2019 19:25:24 +0100
|
||||
Subject: [PATCH] owl_loader: compatibility patch
|
||||
|
||||
This patch includes OpenWrt specific changes that are
|
||||
not included in the upstream owl-loader.
|
||||
|
||||
This includes a platform data handling changes for ar71xx.
|
||||
|
||||
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c
|
||||
@@ -103,6 +103,7 @@ static void owl_fw_cb(const struct firmw
|
||||
{
|
||||
struct pci_dev *pdev = (struct pci_dev *)context;
|
||||
struct owl_ctx *ctx = (struct owl_ctx *)pci_get_drvdata(pdev);
|
||||
+ struct ath9k_platform_data *pdata = dev_get_platdata(&pdev->dev);
|
||||
struct pci_bus *bus;
|
||||
|
||||
complete(&ctx->eeprom_load);
|
||||
@@ -118,6 +119,16 @@ static void owl_fw_cb(const struct firmw
|
||||
goto release;
|
||||
}
|
||||
|
||||
+ if (pdata) {
|
||||
+ memcpy(pdata->eeprom_data, fw->data, fw->size);
|
||||
+
|
||||
+ /*
|
||||
+ * eeprom has been successfully loaded - pass the data to ath9k
|
||||
+ * but remove the eeprom_name, so it doesn't try to load it too.
|
||||
+ */
|
||||
+ pdata->eeprom_name = NULL;
|
||||
+ }
|
||||
+
|
||||
if (ath9k_pci_fixup(pdev, (const u16 *)fw->data, fw->size))
|
||||
goto release;
|
||||
|
||||
@@ -137,8 +148,14 @@ release:
|
||||
static const char *owl_get_eeprom_name(struct pci_dev *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
+ struct ath9k_platform_data *pdata;
|
||||
char *eeprom_name;
|
||||
|
||||
+ /* try the existing platform data first */
|
||||
+ pdata = dev_get_platdata(dev);
|
||||
+ if (pdata && pdata->eeprom_name)
|
||||
+ return pdata->eeprom_name;
|
||||
+
|
||||
dev_dbg(dev, "using auto-generated eeprom filename\n");
|
||||
|
||||
eeprom_name = devm_kzalloc(dev, EEPROM_FILENAME_LEN, GFP_KERNEL);
|
@ -1,67 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -8419,6 +8419,56 @@ static void rt2800_init_rfcsr_5592(struc
|
||||
rt2800_led_open_drain_enable(rt2x00dev);
|
||||
}
|
||||
|
||||
+static void rt2800_rf_self_txdc_cal(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ u8 rfb5r1_org, rfb7r1_org, rfvalue;
|
||||
+ u32 mac0518, mac051c, mac0528, mac052c;
|
||||
+ u8 i;
|
||||
+
|
||||
+ rt2x00_info(rt2x00dev, "RF Tx self calibration start\n");
|
||||
+ mac0518 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
|
||||
+ mac051c = rt2800_register_read(rt2x00dev, RF_BYPASS0);
|
||||
+ mac0528 = rt2800_register_read(rt2x00dev, RF_CONTROL2);
|
||||
+ mac052c = rt2800_register_read(rt2x00dev, RF_BYPASS2);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x0);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS2, 0x0);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0xC);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x3306);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL2, 0x3330);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS2, 0xfffff);
|
||||
+ rfb5r1_org = rt2800_rfcsr_read_bank(rt2x00dev, 5, 1);
|
||||
+ rfb7r1_org = rt2800_rfcsr_read_bank(rt2x00dev, 7, 1);
|
||||
+
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, 0x4);
|
||||
+ for (i = 0; i < 100; i = i + 1) {
|
||||
+ udelay(50);
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 1);
|
||||
+ if((rfvalue & 0x04) != 0x4)
|
||||
+ break;
|
||||
+ }
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 1, rfb5r1_org);
|
||||
+
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 1, 0x4);
|
||||
+ for (i = 0; i < 100; i = i + 1) {
|
||||
+ udelay(50);
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 1);
|
||||
+ if((rfvalue & 0x04) != 0x4)
|
||||
+ break;
|
||||
+ }
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 1, rfb7r1_org);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x0);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS2, 0x0);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, mac0518);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, mac051c);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL2, mac0528);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS2, mac052c);
|
||||
+
|
||||
+ rt2x00_info(rt2x00dev, "RF Tx self calibration end\n");
|
||||
+}
|
||||
+
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
bool set_bw, bool is_ht40)
|
||||
{
|
||||
@@ -9026,6 +9076,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
|
||||
|
||||
+ rt2800_rf_self_txdc_cal(rt2x00dev);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, true);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, false);
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
Date: Mon, 19 Apr 2021 14:59:56 +0800
|
||||
From: Ping-Ke Shih <pkshih@realtek.com>
|
||||
To: <kvalo@codeaurora.org>
|
||||
CC: <linux-wireless@vger.kernel.org>, <mail@maciej.szmigiero.name>,
|
||||
<Larry.Finger@lwfinger.net>
|
||||
Subject: [PATCH] rtlwifi: implement set_tim by update beacon content
|
||||
|
||||
Once beacon content is changed, we update the content to wifi card by
|
||||
send_beacon_frame(). Then, STA with PS can wake up properly to receive its
|
||||
packets.
|
||||
|
||||
Since we update beacon content to PCI wifi devices every beacon interval,
|
||||
the only one usb device, 8192CU, needs to update beacon content when
|
||||
mac80211 calling set_tim.
|
||||
|
||||
Reported-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
|
||||
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
|
||||
Tested-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
|
||||
---
|
||||
drivers/net/wireless/realtek/rtlwifi/core.c | 32 +++++++++++++++++++++
|
||||
drivers/net/wireless/realtek/rtlwifi/core.h | 1 +
|
||||
drivers/net/wireless/realtek/rtlwifi/usb.c | 3 ++
|
||||
drivers/net/wireless/realtek/rtlwifi/wifi.h | 1 +
|
||||
4 files changed, 37 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
|
||||
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
|
||||
@@ -1018,6 +1018,25 @@ static void send_beacon_frame(struct iee
|
||||
}
|
||||
}
|
||||
|
||||
+void rtl_update_beacon_work_callback(struct work_struct *work)
|
||||
+{
|
||||
+ struct rtl_works *rtlworks =
|
||||
+ container_of(work, struct rtl_works, update_beacon_work);
|
||||
+ struct ieee80211_hw *hw = rtlworks->hw;
|
||||
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
+ struct ieee80211_vif *vif = rtlpriv->mac80211.vif;
|
||||
+
|
||||
+ if (!vif) {
|
||||
+ WARN_ONCE(true, "no vif to update beacon\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ mutex_lock(&rtlpriv->locks.conf_mutex);
|
||||
+ send_beacon_frame(hw, vif);
|
||||
+ mutex_unlock(&rtlpriv->locks.conf_mutex);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(rtl_update_beacon_work_callback);
|
||||
+
|
||||
static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *bss_conf,
|
||||
@@ -1747,6 +1766,18 @@ static void rtl_op_flush(struct ieee8021
|
||||
rtlpriv->intf_ops->flush(hw, queues, drop);
|
||||
}
|
||||
|
||||
+static int rtl_op_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
|
||||
+ bool set)
|
||||
+{
|
||||
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
+
|
||||
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU)
|
||||
+ schedule_work(&rtlpriv->works.update_beacon_work);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Description:
|
||||
* This routine deals with the Power Configuration CMD
|
||||
* parsing for RTL8723/RTL8188E Series IC.
|
||||
@@ -1903,6 +1934,7 @@ const struct ieee80211_ops rtl_ops = {
|
||||
.sta_add = rtl_op_sta_add,
|
||||
.sta_remove = rtl_op_sta_remove,
|
||||
.flush = rtl_op_flush,
|
||||
+ .set_tim = rtl_op_set_tim,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(rtl_ops);
|
||||
|
||||
--- a/drivers/net/wireless/realtek/rtlwifi/core.h
|
||||
+++ b/drivers/net/wireless/realtek/rtlwifi/core.h
|
||||
@@ -60,5 +60,6 @@ void rtl_bb_delay(struct ieee80211_hw *h
|
||||
bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
bool rtl_btc_status_false(void);
|
||||
void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igval);
|
||||
+void rtl_update_beacon_work_callback(struct work_struct *work);
|
||||
|
||||
#endif
|
||||
--- a/drivers/net/wireless/realtek/rtlwifi/usb.c
|
||||
+++ b/drivers/net/wireless/realtek/rtlwifi/usb.c
|
||||
@@ -807,6 +807,7 @@ static void rtl_usb_stop(struct ieee8021
|
||||
|
||||
tasklet_kill(&rtlusb->rx_work_tasklet);
|
||||
cancel_work_sync(&rtlpriv->works.lps_change_work);
|
||||
+ cancel_work_sync(&rtlpriv->works.update_beacon_work);
|
||||
|
||||
flush_workqueue(rtlpriv->works.rtl_wq);
|
||||
|
||||
@@ -1033,6 +1034,8 @@ int rtl_usb_probe(struct usb_interface *
|
||||
rtl_fill_h2c_cmd_work_callback);
|
||||
INIT_WORK(&rtlpriv->works.lps_change_work,
|
||||
rtl_lps_change_work_callback);
|
||||
+ INIT_WORK(&rtlpriv->works.update_beacon_work,
|
||||
+ rtl_update_beacon_work_callback);
|
||||
|
||||
rtlpriv->usb_data_index = 0;
|
||||
init_completion(&rtlpriv->firmware_loading_complete);
|
||||
--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
|
||||
+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
|
||||
@@ -2487,6 +2487,7 @@ struct rtl_works {
|
||||
|
||||
struct work_struct lps_change_work;
|
||||
struct work_struct fill_h2c_cmd;
|
||||
+ struct work_struct update_beacon_work;
|
||||
};
|
||||
|
||||
struct rtl_debug {
|
@ -1,23 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Tue, 26 Jan 2021 16:40:52 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: fix regression in the max_prob_rate
|
||||
fix
|
||||
|
||||
Since mi->max_prob_rate is overwritten after the loop that calls
|
||||
minstrel_ht_set_best_prob_rate, the new best rate needs to be written to *dest
|
||||
|
||||
Fixes: a7fca4e4037f ("mac80211: minstrel_ht: fix max probability rate selection")
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -545,7 +545,7 @@ minstrel_ht_set_best_prob_rate(struct mi
|
||||
cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx,
|
||||
mrs->prob_avg);
|
||||
if (cur_tp_avg > tmp_tp_avg)
|
||||
- mi->max_prob_rate = index;
|
||||
+ *dest = index;
|
||||
|
||||
max_gpr_tp_avg = minstrel_ht_get_tp_avg(mi, max_gpr_group,
|
||||
max_gpr_idx,
|
@ -1,172 +0,0 @@
|
||||
PKG_DRIVERS += \
|
||||
rt2x00-lib rt2x00-pci rt2x00-usb rt2x00-mmio \
|
||||
rt2400-pci rt2500-pci rt2500-usb \
|
||||
rt2800-lib rt2800-mmio rt2800-pci rt2800-soc rt2800-usb \
|
||||
rt61-pci rt73-usb
|
||||
|
||||
PKG_CONFIG_DEPENDS += \
|
||||
CONFIG_PACKAGE_RT2X00_LIB_DEBUGFS \
|
||||
CONFIG_PACKAGE_RT2X00_DEBUG
|
||||
|
||||
config-$(call config_package,rt2x00-lib) += RT2X00 RT2X00_LIB
|
||||
config-$(call config_package,rt2x00-pci) += RT2X00_LIB_PCI
|
||||
config-$(call config_package,rt2x00-mmio) += RT2X00_LIB_MMIO
|
||||
config-$(call config_package,rt2x00-usb) += RT2X00_LIB_USB
|
||||
config-$(CONFIG_PACKAGE_RT2X00_LIB_DEBUGFS) += RT2X00_LIB_DEBUGFS
|
||||
config-$(CONFIG_PACKAGE_RT2X00_DEBUG) += RT2X00_DEBUG
|
||||
|
||||
config-$(call config_package,rt2400-pci) += RT2400PCI
|
||||
config-$(call config_package,rt2500-pci) += RT2500PCI
|
||||
config-$(call config_package,rt2500-usb) += RT2500USB
|
||||
config-$(call config_package,rt61-pci) += RT61PCI
|
||||
config-$(call config_package,rt73-usb) += RT73USB
|
||||
|
||||
config-$(call config_package,rt2800-lib) += RT2800_LIB
|
||||
|
||||
config-$(call config_package,rt2800-soc) += RT2800SOC
|
||||
config-$(call config_package,rt2800-pci) += RT2800PCI
|
||||
config-y += RT2800PCI_RT33XX RT2800PCI_RT35XX RT2800PCI_RT53XX RT2800PCI_RT3290
|
||||
|
||||
config-$(call config_package,rt2800-usb) += RT2800USB
|
||||
config-y += RT2800USB_RT33XX RT2800USB_RT35XX RT2800USB_RT3573 RT2800USB_RT53XX RT2800USB_RT55XX RT2800USB_UNKNOWN
|
||||
|
||||
define KernelPackage/rt2x00/Default
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Ralink Drivers for RT2x00 cards
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2x00-lib
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-mac80211
|
||||
TITLE+= (LIB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00lib.ko
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2x00-lib/config
|
||||
if PACKAGE_kmod-rt2x00-lib
|
||||
|
||||
config PACKAGE_RT2X00_LIB_DEBUGFS
|
||||
bool "Enable rt2x00 debugfs support"
|
||||
depends on PACKAGE_MAC80211_DEBUGFS
|
||||
help
|
||||
Enable creation of debugfs files for the rt2x00 drivers.
|
||||
These debugfs files support both reading and writing of the
|
||||
most important register types of the rt2x00 hardware.
|
||||
|
||||
config PACKAGE_RT2X00_DEBUG
|
||||
bool "Enable rt2x00 debug output"
|
||||
help
|
||||
Enable debugging output for all rt2x00 modules
|
||||
|
||||
endif
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2x00-mmio
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @(PCI_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib
|
||||
HIDDEN:=1
|
||||
TITLE+= (MMIO)
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2x00-pci
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-mmio +kmod-rt2x00-lib
|
||||
HIDDEN:=1
|
||||
TITLE+= (PCI)
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2x00pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2x00-usb
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-rt2x00-lib +kmod-usb-core
|
||||
HIDDEN:=1
|
||||
TITLE+= (USB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00usb.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2x00usb)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2800-lib
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT||TARGET_ramips) +kmod-rt2x00-lib +kmod-lib-crc-ccitt +@DRIVER_11N_SUPPORT
|
||||
HIDDEN:=1
|
||||
TITLE+= (rt2800 LIB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800lib.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2400-pci
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci +kmod-eeprom-93cx6
|
||||
TITLE+= (RT2400 PCI)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2400pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2400pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2500-pci
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci +kmod-eeprom-93cx6
|
||||
TITLE+= (RT2500 PCI)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2500pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2500pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2500-usb
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb
|
||||
TITLE+= (RT2500 USB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2500usb.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2500usb)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2800-mmio
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
TITLE += (RT28xx/RT3xxx MMIO)
|
||||
DEPENDS += +kmod-rt2800-lib +kmod-rt2x00-mmio
|
||||
HIDDEN:=1
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800mmio.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2800-soc
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS += @(TARGET_ramips_rt288x||TARGET_ramips_rt305x||TARGET_ramips_rt3883||TARGET_ramips_mt7620) +kmod-rt2800-mmio +kmod-rt2800-lib
|
||||
TITLE += (RT28xx/RT3xxx SoC)
|
||||
FILES := \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2x00soc.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800soc.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2800soc)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2800-pci
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci +kmod-rt2800-lib +kmod-rt2800-mmio +kmod-eeprom-93cx6 +rt2800-pci-firmware
|
||||
TITLE+= (RT2860 PCI)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2800pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt2800-usb
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb +kmod-rt2800-lib +kmod-lib-crc-ccitt +rt2800-usb-firmware
|
||||
TITLE+= (RT2870 USB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt2800usb.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt2800usb)
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/rt61-pci
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-rt2x00-pci +kmod-eeprom-93cx6 +kmod-lib-crc-itu-t +rt61-pci-firmware
|
||||
TITLE+= (RT2x61 PCI)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt61pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt61pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/rt73-usb
|
||||
$(call KernelPackage/rt2x00/Default)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-rt2x00-usb +kmod-lib-crc-itu-t +rt73-usb-firmware
|
||||
TITLE+= (RT73 USB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ralink/rt2x00/rt73usb.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rt73usb)
|
||||
endef
|
@ -1,28 +0,0 @@
|
||||
--- a/backport-include/linux/kconfig.h
|
||||
+++ b/backport-include/linux/kconfig.h
|
||||
@@ -5,6 +5,8 @@
|
||||
#include_next <linux/kconfig.h>
|
||||
#endif
|
||||
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
|
||||
+
|
||||
#ifndef __ARG_PLACEHOLDER_1
|
||||
#define __ARG_PLACEHOLDER_1 0,
|
||||
#define config_enabled(cfg) _config_enabled(cfg)
|
||||
@@ -16,6 +18,7 @@
|
||||
* 3.1 - 3.3 had a broken version of this, so undef
|
||||
* (they didn't have __ARG_PLACEHOLDER_1)
|
||||
*/
|
||||
+
|
||||
#undef IS_ENABLED
|
||||
#define IS_ENABLED(option) \
|
||||
(config_enabled(option) || config_enabled(option##_MODULE))
|
||||
@@ -31,6 +34,8 @@
|
||||
#undef IS_BUILTIN
|
||||
#define IS_BUILTIN(option) config_enabled(option)
|
||||
|
||||
+#endif
|
||||
+
|
||||
#ifndef IS_REACHABLE
|
||||
/*
|
||||
* IS_REACHABLE(CONFIG_FOO) evaluates to 1 if the currently compiled
|
@ -1,125 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||
@@ -1411,6 +1411,52 @@ static const struct file_operations fops
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
||||
+
|
||||
+static ssize_t read_file_chan_bw(struct file *file, char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ath_softc *sc = file->private_data;
|
||||
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
+ char buf[32];
|
||||
+ unsigned int len;
|
||||
+
|
||||
+ len = sprintf(buf, "0x%08x\n", common->chan_bw);
|
||||
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
+}
|
||||
+
|
||||
+static ssize_t write_file_chan_bw(struct file *file, const char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ath_softc *sc = file->private_data;
|
||||
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
+ unsigned long chan_bw;
|
||||
+ char buf[32];
|
||||
+ ssize_t len;
|
||||
+
|
||||
+ len = min(count, sizeof(buf) - 1);
|
||||
+ if (copy_from_user(buf, user_buf, len))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ buf[len] = '\0';
|
||||
+ if (kstrtoul(buf, 0, &chan_bw))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ common->chan_bw = chan_bw;
|
||||
+ if (!test_bit(ATH_OP_INVALID, &common->op_flags))
|
||||
+ ath9k_ops.config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL);
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations fops_chanbw = {
|
||||
+ .read = read_file_chan_bw,
|
||||
+ .write = write_file_chan_bw,
|
||||
+ .open = simple_open,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .llseek = default_llseek,
|
||||
+};
|
||||
+
|
||||
+
|
||||
int ath9k_init_debug(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
@@ -1432,6 +1478,8 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||
|
||||
debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
|
||||
&fops_eeprom);
|
||||
+ debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
|
||||
+ sc, &fops_chanbw);
|
||||
debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
|
||||
read_file_dma);
|
||||
debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
|
||||
--- a/drivers/net/wireless/ath/ath.h
|
||||
+++ b/drivers/net/wireless/ath/ath.h
|
||||
@@ -149,6 +149,7 @@ struct ath_common {
|
||||
int debug_mask;
|
||||
enum ath_device_state state;
|
||||
unsigned long op_flags;
|
||||
+ u32 chan_bw;
|
||||
|
||||
struct ath_ani ani;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/common.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/common.c
|
||||
@@ -297,11 +297,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke
|
||||
/*
|
||||
* Update internal channel flags.
|
||||
*/
|
||||
-static void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
|
||||
+static void ath9k_cmn_update_ichannel(struct ath_common *common,
|
||||
+ struct ath9k_channel *ichan,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ieee80211_channel *chan = chandef->chan;
|
||||
u16 flags = 0;
|
||||
+ int width;
|
||||
|
||||
ichan->channel = chan->center_freq;
|
||||
ichan->chan = chan;
|
||||
@@ -309,7 +311,19 @@ static void ath9k_cmn_update_ichannel(st
|
||||
if (chan->band == NL80211_BAND_5GHZ)
|
||||
flags |= CHANNEL_5GHZ;
|
||||
|
||||
- switch (chandef->width) {
|
||||
+ switch (common->chan_bw) {
|
||||
+ case 5:
|
||||
+ width = NL80211_CHAN_WIDTH_5;
|
||||
+ break;
|
||||
+ case 10:
|
||||
+ width = NL80211_CHAN_WIDTH_10;
|
||||
+ break;
|
||||
+ default:
|
||||
+ width = chandef->width;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ switch (width) {
|
||||
case NL80211_CHAN_WIDTH_5:
|
||||
flags |= CHANNEL_QUARTER;
|
||||
break;
|
||||
@@ -342,10 +356,11 @@ struct ath9k_channel *ath9k_cmn_get_chan
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ieee80211_channel *curchan = chandef->chan;
|
||||
+ struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_channel *channel;
|
||||
|
||||
channel = &ah->channels[curchan->hw_value];
|
||||
- ath9k_cmn_update_ichannel(channel, chandef);
|
||||
+ ath9k_cmn_update_ichannel(common, channel, chandef);
|
||||
|
||||
return channel;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -830,6 +830,7 @@ static const struct ieee80211_iface_limi
|
||||
BIT(NL80211_IFTYPE_AP) },
|
||||
{ .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO) },
|
||||
+ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
|
||||
};
|
||||
|
||||
#ifdef CPTCFG_WIRELESS_WDS
|
@ -1,58 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 23 Jan 2021 00:10:34 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: show sampling rates in debugfs
|
||||
|
||||
This makes it easier to see what rates are going to be tested next
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
|
||||
@@ -32,6 +32,18 @@ minstrel_stats_release(struct inode *ino
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static bool
|
||||
+minstrel_ht_is_sample_rate(struct minstrel_ht_sta *mi, int idx)
|
||||
+{
|
||||
+ int type, i;
|
||||
+
|
||||
+ for (type = 0; type < ARRAY_SIZE(mi->sample); type++)
|
||||
+ for (i = 0; i < MINSTREL_SAMPLE_RATES; i++)
|
||||
+ if (mi->sample[type].cur_sample_rates[i] == idx)
|
||||
+ return true;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static char *
|
||||
minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
|
||||
{
|
||||
@@ -84,6 +96,7 @@ minstrel_ht_stats_dump(struct minstrel_h
|
||||
*(p++) = (idx == mi->max_tp_rate[2]) ? 'C' : ' ';
|
||||
*(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' ';
|
||||
*(p++) = (idx == mi->max_prob_rate) ? 'P' : ' ';
|
||||
+ *(p++) = minstrel_ht_is_sample_rate(mi, idx) ? 'S' : ' ';
|
||||
|
||||
if (gflags & IEEE80211_TX_RC_MCS) {
|
||||
p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j);
|
||||
@@ -145,9 +158,9 @@ minstrel_ht_stats_open(struct inode *ino
|
||||
|
||||
p += sprintf(p, "\n");
|
||||
p += sprintf(p,
|
||||
- " best ____________rate__________ ____statistics___ _____last____ ______sum-of________\n");
|
||||
+ " best ____________rate__________ ____statistics___ _____last____ ______sum-of________\n");
|
||||
p += sprintf(p,
|
||||
- "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts]\n");
|
||||
+ "mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob)] [retry|suc|att] [#success | #attempts]\n");
|
||||
|
||||
p = minstrel_ht_stats_dump(mi, MINSTREL_CCK_GROUP, p);
|
||||
for (i = 0; i < MINSTREL_CCK_GROUP; i++)
|
||||
@@ -228,6 +241,7 @@ minstrel_ht_stats_csv_dump(struct minstr
|
||||
p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[2]) ? "C" : ""));
|
||||
p += sprintf(p, "%s" ,((idx == mi->max_tp_rate[3]) ? "D" : ""));
|
||||
p += sprintf(p, "%s" ,((idx == mi->max_prob_rate) ? "P" : ""));
|
||||
+ p += sprintf(p, "%s", (minstrel_ht_is_sample_rate(mi, idx) ? "S" : ""));
|
||||
|
||||
if (gflags & IEEE80211_TX_RC_MCS) {
|
||||
p += sprintf(p, ",MCS%-2u,", (mg->streams - 1) * 8 + j);
|
@ -1,169 +0,0 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -5,7 +5,7 @@
|
||||
ifeq ($(KERNELRELEASE),)
|
||||
|
||||
MAKEFLAGS += --no-print-directory
|
||||
-SHELL := /bin/bash
|
||||
+SHELL := /usr/bin/env bash
|
||||
BACKPORT_DIR := $(shell pwd)
|
||||
|
||||
KMODDIR ?= updates
|
||||
@@ -19,6 +19,7 @@ KLIB_BUILD ?= $(KLIB)/build/
|
||||
KERNEL_CONFIG := $(KLIB_BUILD)/.config
|
||||
KERNEL_MAKEFILE := $(KLIB_BUILD)/Makefile
|
||||
CONFIG_MD5 := $(shell md5sum $(KERNEL_CONFIG) 2>/dev/null | sed 's/\s.*//')
|
||||
+STAMP_KERNEL_CONFIG := .kernel_config_md5_$(CONFIG_MD5)
|
||||
|
||||
export KLIB KLIB_BUILD BACKPORT_DIR KMODDIR KMODPATH_ARG
|
||||
|
||||
@@ -36,7 +37,8 @@ mrproper:
|
||||
@rm -f .kernel_config_md5 Kconfig.versions Kconfig.kernel
|
||||
@rm -f backport-include/backport/autoconf.h
|
||||
|
||||
-.DEFAULT:
|
||||
+.SILENT: $(STAMP_KERNEL_CONFIG)
|
||||
+$(STAMP_KERNEL_CONFIG):
|
||||
@set -e ; test -f local-symbols || ( \
|
||||
echo "/--------------" ;\
|
||||
echo "| You shouldn't run make in the backports tree, but only in" ;\
|
||||
@@ -60,58 +62,62 @@ mrproper:
|
||||
echo "| (that isn't currently running.)" ;\
|
||||
echo "\\--" ;\
|
||||
false)
|
||||
- @set -e ; if [ "$$(cat .kernel_config_md5 2>/dev/null)" != "$(CONFIG_MD5)" ] ;\
|
||||
- then \
|
||||
- echo -n "Generating local configuration database from kernel ..." ;\
|
||||
- grep -v -f local-symbols $(KERNEL_CONFIG) | grep = | ( \
|
||||
- while read l ; do \
|
||||
- if [ "$${l:0:7}" != "CONFIG_" ] ; then \
|
||||
- continue ;\
|
||||
- fi ;\
|
||||
- l=$${l:7} ;\
|
||||
- n=$${l%%=*} ;\
|
||||
- v=$${l#*=} ;\
|
||||
- if [ "$$v" = "m" ] ; then \
|
||||
- echo config $$n ;\
|
||||
- echo ' tristate' ;\
|
||||
- elif [ "$$v" = "y" ] ; then \
|
||||
- echo config $$n ;\
|
||||
- echo ' bool' ;\
|
||||
- else \
|
||||
- continue ;\
|
||||
- fi ;\
|
||||
- echo " default $$v" ;\
|
||||
- echo "" ;\
|
||||
- done \
|
||||
- ) > Kconfig.kernel ;\
|
||||
- kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \
|
||||
- kernelversion | sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\
|
||||
- test "$$kver" != "" || echo "Kernel version parse failed!" ;\
|
||||
- test "$$kver" != "" ;\
|
||||
- kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\
|
||||
- kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\
|
||||
- kvers="$$kvers $$(seq 0 20 | sed 's/^/4./')" ;\
|
||||
- kvers="$$kvers $$(seq 0 99 | sed 's/^/5./')" ;\
|
||||
- print=0 ;\
|
||||
- for v in $$kvers ; do \
|
||||
- if [ "$$print" = "1" ] ; then \
|
||||
- echo config KERNEL_$$(echo $$v | tr . _) ;\
|
||||
- echo " def_bool y" ;\
|
||||
- fi ;\
|
||||
- if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\
|
||||
- done > Kconfig.versions ;\
|
||||
- # RHEL as well, sadly we need to grep for it ;\
|
||||
- RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \
|
||||
- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
|
||||
- RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \
|
||||
- sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
|
||||
- for v in $$(seq 0 $$RHEL_MINOR) ; do \
|
||||
- echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\
|
||||
- echo " def_bool y" ;\
|
||||
- done >> Kconfig.versions ;\
|
||||
- echo " done." ;\
|
||||
- fi ;\
|
||||
- echo "$(CONFIG_MD5)" > .kernel_config_md5
|
||||
+ @rm -f .kernel_config_md5_*
|
||||
+ @touch $@
|
||||
+
|
||||
+Kconfig.kernel: $(STAMP_KERNEL_CONFIG) local-symbols
|
||||
+ @printf "Generating local configuration database from kernel ..."
|
||||
+ @grep -v -f local-symbols $(KERNEL_CONFIG) | grep = | ( \
|
||||
+ while read l ; do \
|
||||
+ if [ "$${l:0:7}" != "CONFIG_" ] ; then \
|
||||
+ continue ;\
|
||||
+ fi ;\
|
||||
+ l=$${l:7} ;\
|
||||
+ n=$${l%%=*} ;\
|
||||
+ v=$${l#*=} ;\
|
||||
+ if [ "$$v" = "m" ] ; then \
|
||||
+ echo config $$n ;\
|
||||
+ echo ' tristate' ;\
|
||||
+ elif [ "$$v" = "y" ] ; then \
|
||||
+ echo config $$n ;\
|
||||
+ echo ' bool' ;\
|
||||
+ else \
|
||||
+ continue ;\
|
||||
+ fi ;\
|
||||
+ echo " default $$v" ;\
|
||||
+ echo "" ;\
|
||||
+ done \
|
||||
+ ) > $@
|
||||
+ @echo " done."
|
||||
+
|
||||
+Kconfig.versions: Kconfig.kernel
|
||||
+ @kver=$$($(MAKE) --no-print-directory -C $(KLIB_BUILD) M=$(BACKPORT_DIR) \
|
||||
+ kernelversion | sed 's/^\(\([3-5]\|2\.6\)\.[0-9]\+\).*/\1/;t;d');\
|
||||
+ test "$$kver" != "" || echo "Kernel version parse failed!" ;\
|
||||
+ test "$$kver" != "" ;\
|
||||
+ kvers="$$(seq 14 39 | sed 's/^/2.6./')" ;\
|
||||
+ kvers="$$kvers $$(seq 0 19 | sed 's/^/3./')" ;\
|
||||
+ kvers="$$kvers $$(seq 0 20 | sed 's/^/4./')" ;\
|
||||
+ kvers="$$kvers $$(seq 0 99 | sed 's/^/5./')" ;\
|
||||
+ print=0 ;\
|
||||
+ for v in $$kvers ; do \
|
||||
+ if [ "$$print" = "1" ] ; then \
|
||||
+ echo config KERNEL_$$(echo $$v | tr . _) ;\
|
||||
+ echo " def_bool y" ;\
|
||||
+ fi ;\
|
||||
+ if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\
|
||||
+ done > $@
|
||||
+ @RHEL_MAJOR=$$(grep '^RHEL_MAJOR' $(KERNEL_MAKEFILE) | \
|
||||
+ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
|
||||
+ RHEL_MINOR=$$(grep '^RHEL_MINOR' $(KERNEL_MAKEFILE) | \
|
||||
+ sed 's/.*=\s*\([0-9]*\)/\1/;t;d') ;\
|
||||
+ for v in $$(seq 0 $$RHEL_MINOR) ; do \
|
||||
+ echo config BACKPORT_RHEL_KERNEL_$${RHEL_MAJOR}_$$v ;\
|
||||
+ echo " def_bool y" ;\
|
||||
+ done >> $@
|
||||
+
|
||||
+.DEFAULT:
|
||||
+ @$(MAKE) Kconfig.versions
|
||||
@$(MAKE) -f Makefile.real "$@"
|
||||
|
||||
.PHONY: defconfig-help
|
||||
--- a/Makefile.real
|
||||
+++ b/Makefile.real
|
||||
@@ -59,7 +59,7 @@ defconfig-%::
|
||||
|
||||
backport-include/backport/autoconf.h: .config Kconfig.versions Kconfig.kernel
|
||||
@$(MAKE) oldconfig
|
||||
- @echo -n "Building backport-include/backport/autoconf.h ..."
|
||||
+ @printf "Building backport-include/backport/autoconf.h ..."
|
||||
@grep -f local-symbols .config | ( \
|
||||
echo "#ifndef COMPAT_AUTOCONF_INCLUDED" ;\
|
||||
echo "#define COMPAT_AUTOCONF_INCLUDED" ;\
|
||||
@@ -80,7 +80,12 @@ backport-include/backport/autoconf.h: .c
|
||||
esac ;\
|
||||
done ;\
|
||||
echo "#endif /* COMPAT_AUTOCONF_INCLUDED */" ;\
|
||||
- ) > backport-include/backport/autoconf.h
|
||||
+ ) > $@.new
|
||||
+ @if cmp -s $@ $@.new; then \
|
||||
+ rm -f $@.new; \
|
||||
+ else \
|
||||
+ mv $@.new $@; \
|
||||
+ fi
|
||||
@echo " done."
|
||||
|
||||
.PHONY: modules
|
@ -1,570 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 16 Dec 2020 21:34:03 +0100
|
||||
Subject: [PATCH] mac80211: add rx decapsulation offload support
|
||||
|
||||
This allows drivers to pass 802.3 frames to mac80211, with some restrictions:
|
||||
|
||||
- the skb must be passed with a valid sta
|
||||
- fast-rx needs to be active for the sta
|
||||
- monitor mode needs to be disabled
|
||||
|
||||
mac80211 will tell the driver when it is safe to enable rx decap offload for
|
||||
a particular station.
|
||||
|
||||
In order to implement support, a driver must:
|
||||
|
||||
- call ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD)
|
||||
- implement ops->sta_set_decap_offload
|
||||
- mark 802.3 frames with RX_FLAG_8023
|
||||
|
||||
If it doesn't want to enable offload for some vif types, it can mask out
|
||||
IEEE80211_OFFLOAD_DECAP_ENABLED in vif->offload_flags from within the
|
||||
.add_interface or .update_vif_offload driver ops
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -1297,6 +1297,8 @@ ieee80211_tx_info_clear_status(struct ie
|
||||
* the "0-length PSDU" field included there. The value for it is
|
||||
* in &struct ieee80211_rx_status. Note that if this value isn't
|
||||
* known the frame shouldn't be reported.
|
||||
+ * @RX_FLAG_8023: the frame has an 802.3 header (decap offload performed by
|
||||
+ * hardware or driver)
|
||||
*/
|
||||
enum mac80211_rx_flags {
|
||||
RX_FLAG_MMIC_ERROR = BIT(0),
|
||||
@@ -1329,6 +1331,7 @@ enum mac80211_rx_flags {
|
||||
RX_FLAG_RADIOTAP_HE_MU = BIT(27),
|
||||
RX_FLAG_RADIOTAP_LSIG = BIT(28),
|
||||
RX_FLAG_NO_PSDU = BIT(29),
|
||||
+ RX_FLAG_8023 = BIT(30),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1650,11 +1653,15 @@ enum ieee80211_vif_flags {
|
||||
* The driver supports sending frames passed as 802.3 frames by mac80211.
|
||||
* It must also support sending 802.11 packets for the same interface.
|
||||
* @IEEE80211_OFFLOAD_ENCAP_4ADDR: support 4-address mode encapsulation offload
|
||||
+ * @IEEE80211_OFFLOAD_DECAP_ENABLED: rx encapsulation offload is enabled
|
||||
+ * The driver supports passing received 802.11 frames as 802.3 frames to
|
||||
+ * mac80211.
|
||||
*/
|
||||
|
||||
enum ieee80211_offload_flags {
|
||||
IEEE80211_OFFLOAD_ENCAP_ENABLED = BIT(0),
|
||||
IEEE80211_OFFLOAD_ENCAP_4ADDR = BIT(1),
|
||||
+ IEEE80211_OFFLOAD_DECAP_ENABLED = BIT(2),
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2390,6 +2397,9 @@ struct ieee80211_txq {
|
||||
* @IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD: Hardware supports tx encapsulation
|
||||
* offload
|
||||
*
|
||||
+ * @IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD: Hardware supports rx decapsulation
|
||||
+ * offload
|
||||
+ *
|
||||
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
|
||||
*/
|
||||
enum ieee80211_hw_flags {
|
||||
@@ -2443,6 +2453,7 @@ enum ieee80211_hw_flags {
|
||||
IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
|
||||
IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT,
|
||||
IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD,
|
||||
+ IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD,
|
||||
|
||||
/* keep last, obviously */
|
||||
NUM_IEEE80211_HW_FLAGS
|
||||
@@ -4196,6 +4207,9 @@ struct ieee80211_ops {
|
||||
struct ieee80211_vif *vif);
|
||||
void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enabled);
|
||||
+ void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_vif *vif,
|
||||
+ struct ieee80211_sta *sta, bool enabled);
|
||||
};
|
||||
|
||||
/**
|
||||
--- a/net/mac80211/debugfs.c
|
||||
+++ b/net/mac80211/debugfs.c
|
||||
@@ -405,6 +405,7 @@ static const char *hw_flag_names[] = {
|
||||
FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
|
||||
FLAG(AMPDU_KEYBORDER_SUPPORT),
|
||||
FLAG(SUPPORTS_TX_ENCAP_OFFLOAD),
|
||||
+ FLAG(SUPPORTS_RX_DECAP_OFFLOAD),
|
||||
#undef FLAG
|
||||
};
|
||||
|
||||
--- a/net/mac80211/debugfs_sta.c
|
||||
+++ b/net/mac80211/debugfs_sta.c
|
||||
@@ -79,6 +79,7 @@ static const char * const sta_flag_names
|
||||
FLAG(MPSP_RECIPIENT),
|
||||
FLAG(PS_DELIVER),
|
||||
FLAG(USES_ENCRYPTION),
|
||||
+ FLAG(DECAP_OFFLOAD),
|
||||
#undef FLAG
|
||||
};
|
||||
|
||||
--- a/net/mac80211/driver-ops.h
|
||||
+++ b/net/mac80211/driver-ops.h
|
||||
@@ -1413,4 +1413,20 @@ static inline void drv_sta_set_4addr(str
|
||||
trace_drv_return_void(local);
|
||||
}
|
||||
|
||||
+static inline void drv_sta_set_decap_offload(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sub_if_data *sdata,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ bool enabled)
|
||||
+{
|
||||
+ sdata = get_bss_sdata(sdata);
|
||||
+ if (!check_sdata_in_driver(sdata))
|
||||
+ return;
|
||||
+
|
||||
+ trace_drv_sta_set_decap_offload(local, sdata, sta, enabled);
|
||||
+ if (local->ops->sta_set_decap_offload)
|
||||
+ local->ops->sta_set_decap_offload(&local->hw, &sdata->vif, sta,
|
||||
+ enabled);
|
||||
+ trace_drv_return_void(local);
|
||||
+}
|
||||
+
|
||||
#endif /* __MAC80211_DRIVER_OPS */
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -856,7 +856,7 @@ static const struct net_device_ops ieee8
|
||||
|
||||
};
|
||||
|
||||
-static bool ieee80211_iftype_supports_encap_offload(enum nl80211_iftype iftype)
|
||||
+static bool ieee80211_iftype_supports_hdr_offload(enum nl80211_iftype iftype)
|
||||
{
|
||||
switch (iftype) {
|
||||
/* P2P GO and client are mapped to AP/STATION types */
|
||||
@@ -876,7 +876,7 @@ static bool ieee80211_set_sdata_offload_
|
||||
flags = sdata->vif.offload_flags;
|
||||
|
||||
if (ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) &&
|
||||
- ieee80211_iftype_supports_encap_offload(sdata->vif.type)) {
|
||||
+ ieee80211_iftype_supports_hdr_offload(sdata->vif.type)) {
|
||||
flags |= IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
||||
|
||||
if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_FRAG) &&
|
||||
@@ -889,10 +889,21 @@ static bool ieee80211_set_sdata_offload_
|
||||
flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
||||
}
|
||||
|
||||
+ if (ieee80211_hw_check(&local->hw, SUPPORTS_RX_DECAP_OFFLOAD) &&
|
||||
+ ieee80211_iftype_supports_hdr_offload(sdata->vif.type)) {
|
||||
+ flags |= IEEE80211_OFFLOAD_DECAP_ENABLED;
|
||||
+
|
||||
+ if (local->monitors)
|
||||
+ flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
|
||||
+ } else {
|
||||
+ flags &= ~IEEE80211_OFFLOAD_DECAP_ENABLED;
|
||||
+ }
|
||||
+
|
||||
if (sdata->vif.offload_flags == flags)
|
||||
return false;
|
||||
|
||||
sdata->vif.offload_flags = flags;
|
||||
+ ieee80211_check_fast_rx_iface(sdata);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -910,7 +921,7 @@ static void ieee80211_set_vif_encap_ops(
|
||||
}
|
||||
|
||||
if (!ieee80211_hw_check(&local->hw, SUPPORTS_TX_ENCAP_OFFLOAD) ||
|
||||
- !ieee80211_iftype_supports_encap_offload(bss->vif.type))
|
||||
+ !ieee80211_iftype_supports_hdr_offload(bss->vif.type))
|
||||
return;
|
||||
|
||||
enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -4198,7 +4198,9 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
.vif_type = sdata->vif.type,
|
||||
.control_port_protocol = sdata->control_port_protocol,
|
||||
}, *old, *new = NULL;
|
||||
+ bool set_offload = false;
|
||||
bool assign = false;
|
||||
+ bool offload;
|
||||
|
||||
/* use sparse to check that we don't return without updating */
|
||||
__acquire(check_fast_rx);
|
||||
@@ -4311,6 +4313,17 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
if (assign)
|
||||
new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL);
|
||||
|
||||
+ offload = assign &&
|
||||
+ (sdata->vif.offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED);
|
||||
+
|
||||
+ if (offload)
|
||||
+ set_offload = !test_and_set_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD);
|
||||
+ else
|
||||
+ set_offload = test_and_clear_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD);
|
||||
+
|
||||
+ if (set_offload)
|
||||
+ drv_sta_set_decap_offload(local, sdata, &sta->sta, assign);
|
||||
+
|
||||
spin_lock_bh(&sta->lock);
|
||||
old = rcu_dereference_protected(sta->fast_rx, true);
|
||||
rcu_assign_pointer(sta->fast_rx, new);
|
||||
@@ -4357,6 +4370,108 @@ void ieee80211_check_fast_rx_iface(struc
|
||||
mutex_unlock(&local->sta_mtx);
|
||||
}
|
||||
|
||||
+static void ieee80211_rx_8023(struct ieee80211_rx_data *rx,
|
||||
+ struct ieee80211_fast_rx *fast_rx,
|
||||
+ int orig_len)
|
||||
+{
|
||||
+ struct ieee80211_sta_rx_stats *stats;
|
||||
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
||||
+ struct sta_info *sta = rx->sta;
|
||||
+ struct sk_buff *skb = rx->skb;
|
||||
+ void *sa = skb->data + ETH_ALEN;
|
||||
+ void *da = skb->data;
|
||||
+
|
||||
+ stats = &sta->rx_stats;
|
||||
+ if (fast_rx->uses_rss)
|
||||
+ stats = this_cpu_ptr(sta->pcpu_rx_stats);
|
||||
+
|
||||
+ /* statistics part of ieee80211_rx_h_sta_process() */
|
||||
+ if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
|
||||
+ stats->last_signal = status->signal;
|
||||
+ if (!fast_rx->uses_rss)
|
||||
+ ewma_signal_add(&sta->rx_stats_avg.signal,
|
||||
+ -status->signal);
|
||||
+ }
|
||||
+
|
||||
+ if (status->chains) {
|
||||
+ int i;
|
||||
+
|
||||
+ stats->chains = status->chains;
|
||||
+ for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) {
|
||||
+ int signal = status->chain_signal[i];
|
||||
+
|
||||
+ if (!(status->chains & BIT(i)))
|
||||
+ continue;
|
||||
+
|
||||
+ stats->chain_signal_last[i] = signal;
|
||||
+ if (!fast_rx->uses_rss)
|
||||
+ ewma_signal_add(&sta->rx_stats_avg.chain_signal[i],
|
||||
+ -signal);
|
||||
+ }
|
||||
+ }
|
||||
+ /* end of statistics */
|
||||
+
|
||||
+ stats->last_rx = jiffies;
|
||||
+ stats->last_rate = sta_stats_encode_rate(status);
|
||||
+
|
||||
+ stats->fragments++;
|
||||
+ stats->packets++;
|
||||
+
|
||||
+ skb->dev = fast_rx->dev;
|
||||
+
|
||||
+ ieee80211_rx_stats(fast_rx->dev, skb->len);
|
||||
+
|
||||
+ /* The seqno index has the same property as needed
|
||||
+ * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
|
||||
+ * for non-QoS-data frames. Here we know it's a data
|
||||
+ * frame, so count MSDUs.
|
||||
+ */
|
||||
+ u64_stats_update_begin(&stats->syncp);
|
||||
+ stats->msdu[rx->seqno_idx]++;
|
||||
+ stats->bytes += orig_len;
|
||||
+ u64_stats_update_end(&stats->syncp);
|
||||
+
|
||||
+ if (fast_rx->internal_forward) {
|
||||
+ struct sk_buff *xmit_skb = NULL;
|
||||
+ if (is_multicast_ether_addr(da)) {
|
||||
+ xmit_skb = skb_copy(skb, GFP_ATOMIC);
|
||||
+ } else if (!ether_addr_equal(da, sa) &&
|
||||
+ sta_info_get(rx->sdata, da)) {
|
||||
+ xmit_skb = skb;
|
||||
+ skb = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (xmit_skb) {
|
||||
+ /*
|
||||
+ * Send to wireless media and increase priority by 256
|
||||
+ * to keep the received priority instead of
|
||||
+ * reclassifying the frame (see cfg80211_classify8021d).
|
||||
+ */
|
||||
+ xmit_skb->priority += 256;
|
||||
+ xmit_skb->protocol = htons(ETH_P_802_3);
|
||||
+ skb_reset_network_header(xmit_skb);
|
||||
+ skb_reset_mac_header(xmit_skb);
|
||||
+ dev_queue_xmit(xmit_skb);
|
||||
+ }
|
||||
+
|
||||
+ if (!skb)
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* deliver to local stack */
|
||||
+ skb->protocol = eth_type_trans(skb, fast_rx->dev);
|
||||
+ memset(skb->cb, 0, sizeof(skb->cb));
|
||||
+ if (rx->list)
|
||||
+#if LINUX_VERSION_IS_GEQ(4,19,0)
|
||||
+ list_add_tail(&skb->list, rx->list);
|
||||
+#else
|
||||
+ __skb_queue_tail(rx->list, skb);
|
||||
+#endif
|
||||
+ else
|
||||
+ netif_receive_skb(skb);
|
||||
+
|
||||
+}
|
||||
+
|
||||
static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
|
||||
struct ieee80211_fast_rx *fast_rx)
|
||||
{
|
||||
@@ -4377,9 +4492,6 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
} addrs __aligned(2);
|
||||
struct ieee80211_sta_rx_stats *stats = &sta->rx_stats;
|
||||
|
||||
- if (fast_rx->uses_rss)
|
||||
- stats = this_cpu_ptr(sta->pcpu_rx_stats);
|
||||
-
|
||||
/* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write
|
||||
* to a common data structure; drivers can implement that per queue
|
||||
* but we don't have that information in mac80211
|
||||
@@ -4453,32 +4565,6 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
pskb_trim(skb, skb->len - fast_rx->icv_len))
|
||||
goto drop;
|
||||
|
||||
- /* statistics part of ieee80211_rx_h_sta_process() */
|
||||
- if (!(status->flag & RX_FLAG_NO_SIGNAL_VAL)) {
|
||||
- stats->last_signal = status->signal;
|
||||
- if (!fast_rx->uses_rss)
|
||||
- ewma_signal_add(&sta->rx_stats_avg.signal,
|
||||
- -status->signal);
|
||||
- }
|
||||
-
|
||||
- if (status->chains) {
|
||||
- int i;
|
||||
-
|
||||
- stats->chains = status->chains;
|
||||
- for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) {
|
||||
- int signal = status->chain_signal[i];
|
||||
-
|
||||
- if (!(status->chains & BIT(i)))
|
||||
- continue;
|
||||
-
|
||||
- stats->chain_signal_last[i] = signal;
|
||||
- if (!fast_rx->uses_rss)
|
||||
- ewma_signal_add(&sta->rx_stats_avg.chain_signal[i],
|
||||
- -signal);
|
||||
- }
|
||||
- }
|
||||
- /* end of statistics */
|
||||
-
|
||||
if (rx->key && !ieee80211_has_protected(hdr->frame_control))
|
||||
goto drop;
|
||||
|
||||
@@ -4490,12 +4576,6 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
return true;
|
||||
}
|
||||
|
||||
- stats->last_rx = jiffies;
|
||||
- stats->last_rate = sta_stats_encode_rate(status);
|
||||
-
|
||||
- stats->fragments++;
|
||||
- stats->packets++;
|
||||
-
|
||||
/* do the header conversion - first grab the addresses */
|
||||
ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs);
|
||||
ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs);
|
||||
@@ -4504,62 +4584,14 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
/* push the addresses in front */
|
||||
memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs));
|
||||
|
||||
- skb->dev = fast_rx->dev;
|
||||
-
|
||||
- ieee80211_rx_stats(fast_rx->dev, skb->len);
|
||||
-
|
||||
- /* The seqno index has the same property as needed
|
||||
- * for the rx_msdu field, i.e. it is IEEE80211_NUM_TIDS
|
||||
- * for non-QoS-data frames. Here we know it's a data
|
||||
- * frame, so count MSDUs.
|
||||
- */
|
||||
- u64_stats_update_begin(&stats->syncp);
|
||||
- stats->msdu[rx->seqno_idx]++;
|
||||
- stats->bytes += orig_len;
|
||||
- u64_stats_update_end(&stats->syncp);
|
||||
-
|
||||
- if (fast_rx->internal_forward) {
|
||||
- struct sk_buff *xmit_skb = NULL;
|
||||
- if (is_multicast_ether_addr(addrs.da)) {
|
||||
- xmit_skb = skb_copy(skb, GFP_ATOMIC);
|
||||
- } else if (!ether_addr_equal(addrs.da, addrs.sa) &&
|
||||
- sta_info_get(rx->sdata, addrs.da)) {
|
||||
- xmit_skb = skb;
|
||||
- skb = NULL;
|
||||
- }
|
||||
-
|
||||
- if (xmit_skb) {
|
||||
- /*
|
||||
- * Send to wireless media and increase priority by 256
|
||||
- * to keep the received priority instead of
|
||||
- * reclassifying the frame (see cfg80211_classify8021d).
|
||||
- */
|
||||
- xmit_skb->priority += 256;
|
||||
- xmit_skb->protocol = htons(ETH_P_802_3);
|
||||
- skb_reset_network_header(xmit_skb);
|
||||
- skb_reset_mac_header(xmit_skb);
|
||||
- dev_queue_xmit(xmit_skb);
|
||||
- }
|
||||
-
|
||||
- if (!skb)
|
||||
- return true;
|
||||
- }
|
||||
-
|
||||
- /* deliver to local stack */
|
||||
- skb->protocol = eth_type_trans(skb, fast_rx->dev);
|
||||
- memset(skb->cb, 0, sizeof(skb->cb));
|
||||
- if (rx->list)
|
||||
-#if LINUX_VERSION_IS_GEQ(4,19,0)
|
||||
- list_add_tail(&skb->list, rx->list);
|
||||
-#else
|
||||
- __skb_queue_tail(rx->list, skb);
|
||||
-#endif
|
||||
- else
|
||||
- netif_receive_skb(skb);
|
||||
+ ieee80211_rx_8023(rx, fast_rx, orig_len);
|
||||
|
||||
return true;
|
||||
drop:
|
||||
dev_kfree_skb(skb);
|
||||
+ if (fast_rx->uses_rss)
|
||||
+ stats = this_cpu_ptr(sta->pcpu_rx_stats);
|
||||
+
|
||||
stats->dropped++;
|
||||
return true;
|
||||
}
|
||||
@@ -4613,6 +4645,47 @@ static bool ieee80211_prepare_and_rx_han
|
||||
return true;
|
||||
}
|
||||
|
||||
+static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_sta *pubsta,
|
||||
+ struct sk_buff *skb,
|
||||
+#if LINUX_VERSION_IS_GEQ(4,19,0)
|
||||
+ struct list_head *list)
|
||||
+#else
|
||||
+ struct sk_buff_head *list)
|
||||
+#endif
|
||||
+{
|
||||
+ struct ieee80211_local *local = hw_to_local(hw);
|
||||
+ struct ieee80211_fast_rx *fast_rx;
|
||||
+ struct ieee80211_rx_data rx;
|
||||
+
|
||||
+ memset(&rx, 0, sizeof(rx));
|
||||
+ rx.skb = skb;
|
||||
+ rx.local = local;
|
||||
+ rx.list = list;
|
||||
+
|
||||
+ I802_DEBUG_INC(local->dot11ReceivedFragmentCount);
|
||||
+
|
||||
+ /* drop frame if too short for header */
|
||||
+ if (skb->len < sizeof(struct ethhdr))
|
||||
+ goto drop;
|
||||
+
|
||||
+ if (!pubsta)
|
||||
+ goto drop;
|
||||
+
|
||||
+ rx.sta = container_of(pubsta, struct sta_info, sta);
|
||||
+ rx.sdata = rx.sta->sdata;
|
||||
+
|
||||
+ fast_rx = rcu_dereference(rx.sta->fast_rx);
|
||||
+ if (!fast_rx)
|
||||
+ goto drop;
|
||||
+
|
||||
+ ieee80211_rx_8023(&rx, fast_rx, skb->len);
|
||||
+ return;
|
||||
+
|
||||
+drop:
|
||||
+ dev_kfree_skb(skb);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* This is the actual Rx frames handler. as it belongs to Rx path it must
|
||||
* be called with rcu_read_lock protection.
|
||||
@@ -4850,15 +4923,20 @@ void ieee80211_rx_list(struct ieee80211_
|
||||
* if it was previously present.
|
||||
* Also, frames with less than 16 bytes are dropped.
|
||||
*/
|
||||
- skb = ieee80211_rx_monitor(local, skb, rate);
|
||||
- if (!skb)
|
||||
- return;
|
||||
+ if (!(status->flag & RX_FLAG_8023)) {
|
||||
+ skb = ieee80211_rx_monitor(local, skb, rate);
|
||||
+ if (!skb)
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
ieee80211_tpt_led_trig_rx(local,
|
||||
((struct ieee80211_hdr *)skb->data)->frame_control,
|
||||
skb->len);
|
||||
|
||||
- __ieee80211_rx_handle_packet(hw, pubsta, skb, list);
|
||||
+ if (status->flag & RX_FLAG_8023)
|
||||
+ __ieee80211_rx_handle_8023(hw, pubsta, skb, list);
|
||||
+ else
|
||||
+ __ieee80211_rx_handle_packet(hw, pubsta, skb, list);
|
||||
|
||||
return;
|
||||
drop:
|
||||
--- a/net/mac80211/sta_info.h
|
||||
+++ b/net/mac80211/sta_info.h
|
||||
@@ -71,6 +71,7 @@
|
||||
* until pending frames are delivered
|
||||
* @WLAN_STA_USES_ENCRYPTION: This station was configured for encryption,
|
||||
* so drop all packets without a key later.
|
||||
+ * @WLAN_STA_DECAP_OFFLOAD: This station uses rx decap offload
|
||||
*
|
||||
* @NUM_WLAN_STA_FLAGS: number of defined flags
|
||||
*/
|
||||
@@ -102,6 +103,7 @@ enum ieee80211_sta_info_flags {
|
||||
WLAN_STA_MPSP_RECIPIENT,
|
||||
WLAN_STA_PS_DELIVER,
|
||||
WLAN_STA_USES_ENCRYPTION,
|
||||
+ WLAN_STA_DECAP_OFFLOAD,
|
||||
|
||||
NUM_WLAN_STA_FLAGS,
|
||||
};
|
||||
--- a/net/mac80211/trace.h
|
||||
+++ b/net/mac80211/trace.h
|
||||
@@ -2761,7 +2761,7 @@ DEFINE_EVENT(local_sdata_addr_evt, drv_u
|
||||
TP_ARGS(local, sdata)
|
||||
);
|
||||
|
||||
-TRACE_EVENT(drv_sta_set_4addr,
|
||||
+DECLARE_EVENT_CLASS(sta_flag_evt,
|
||||
TP_PROTO(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_sta *sta, bool enabled),
|
||||
@@ -2788,6 +2788,22 @@ TRACE_EVENT(drv_sta_set_4addr,
|
||||
)
|
||||
);
|
||||
|
||||
+DEFINE_EVENT(sta_flag_evt, drv_sta_set_4addr,
|
||||
+ TP_PROTO(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sub_if_data *sdata,
|
||||
+ struct ieee80211_sta *sta, bool enabled),
|
||||
+
|
||||
+ TP_ARGS(local, sdata, sta, enabled)
|
||||
+);
|
||||
+
|
||||
+DEFINE_EVENT(sta_flag_evt, drv_sta_set_decap_offload,
|
||||
+ TP_PROTO(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sub_if_data *sdata,
|
||||
+ struct ieee80211_sta *sta, bool enabled),
|
||||
+
|
||||
+ TP_ARGS(local, sdata, sta, enabled)
|
||||
+);
|
||||
+
|
||||
#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
@ -1,576 +0,0 @@
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Mon, 23 Aug 2021 20:02:39 +0200
|
||||
Subject: [PATCH] mac80211: introduce individual TWT support in AP mode
|
||||
|
||||
Introduce TWT action frames parsing support to mac80211.
|
||||
Currently just individual TWT agreement are support in AP mode.
|
||||
Whenever the AP receives a TWT action frame from an associated client,
|
||||
after performing sanity checks, it will notify the underlay driver with
|
||||
requested parameters in order to check if they are supported and if there
|
||||
is enough room for a new agreement. The driver is expected to set the
|
||||
agreement result and report it to mac80211.
|
||||
|
||||
Drivers supporting this have two new callbacks:
|
||||
- add_twt_setup (mandatory)
|
||||
- twt_teardown_request (optional)
|
||||
|
||||
mac80211 will send an action frame reply according to the result
|
||||
reported by the driver.
|
||||
|
||||
Tested-by: Peter Chiu <chui-hao.chiu@mediatek.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://lore.kernel.org/r/257512f2e22ba42b9f2624942a128dd8f141de4b.1629741512.git.lorenzo@kernel.org
|
||||
[use le16p_replace_bits(), minor cleanups, use (void *) casts,
|
||||
fix to use ieee80211_get_he_iftype_cap() correctly]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -4219,6 +4219,11 @@ struct ieee80211_ops {
|
||||
void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enabled);
|
||||
+ void (*add_twt_setup)(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ struct ieee80211_twt_setup *twt);
|
||||
+ void (*twt_teardown_request)(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_sta *sta, u8 flowid);
|
||||
};
|
||||
|
||||
/**
|
||||
--- a/net/mac80211/driver-ops.h
|
||||
+++ b/net/mac80211/driver-ops.h
|
||||
@@ -1429,4 +1429,40 @@ static inline void drv_sta_set_decap_off
|
||||
trace_drv_return_void(local);
|
||||
}
|
||||
|
||||
+static inline void drv_add_twt_setup(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sub_if_data *sdata,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ struct ieee80211_twt_setup *twt)
|
||||
+{
|
||||
+ struct ieee80211_twt_params *twt_agrt;
|
||||
+
|
||||
+ might_sleep();
|
||||
+
|
||||
+ if (!check_sdata_in_driver(sdata))
|
||||
+ return;
|
||||
+
|
||||
+ twt_agrt = (void *)twt->params;
|
||||
+
|
||||
+ trace_drv_add_twt_setup(local, sta, twt, twt_agrt);
|
||||
+ local->ops->add_twt_setup(&local->hw, sta, twt);
|
||||
+ trace_drv_return_void(local);
|
||||
+}
|
||||
+
|
||||
+static inline void drv_twt_teardown_request(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sub_if_data *sdata,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ u8 flowid)
|
||||
+{
|
||||
+ might_sleep();
|
||||
+ if (!check_sdata_in_driver(sdata))
|
||||
+ return;
|
||||
+
|
||||
+ if (!local->ops->twt_teardown_request)
|
||||
+ return;
|
||||
+
|
||||
+ trace_drv_twt_teardown_request(local, sta, flowid);
|
||||
+ local->ops->twt_teardown_request(&local->hw, sta, flowid);
|
||||
+ trace_drv_return_void(local);
|
||||
+}
|
||||
+
|
||||
#endif /* __MAC80211_DRIVER_OPS */
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -954,6 +954,7 @@ struct ieee80211_sub_if_data {
|
||||
|
||||
struct work_struct work;
|
||||
struct sk_buff_head skb_queue;
|
||||
+ struct sk_buff_head status_queue;
|
||||
|
||||
u8 needed_rx_chains;
|
||||
enum ieee80211_smps_mode smps_mode;
|
||||
@@ -2093,6 +2094,11 @@ ieee80211_he_op_ie_to_bss_conf(struct ie
|
||||
|
||||
/* S1G */
|
||||
void ieee80211_s1g_sta_rate_init(struct sta_info *sta);
|
||||
+bool ieee80211_s1g_is_twt_setup(struct sk_buff *skb);
|
||||
+void ieee80211_s1g_rx_twt_action(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb);
|
||||
+void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb);
|
||||
|
||||
/* Spectrum management */
|
||||
void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -563,6 +563,7 @@ static void ieee80211_do_stop(struct iee
|
||||
*/
|
||||
ieee80211_free_keys(sdata, true);
|
||||
skb_queue_purge(&sdata->skb_queue);
|
||||
+ skb_queue_purge(&sdata->status_queue);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
||||
@@ -1070,6 +1071,7 @@ int ieee80211_add_virtual_monitor(struct
|
||||
}
|
||||
|
||||
skb_queue_head_init(&sdata->skb_queue);
|
||||
+ skb_queue_head_init(&sdata->status_queue);
|
||||
INIT_WORK(&sdata->work, ieee80211_iface_work);
|
||||
|
||||
return 0;
|
||||
@@ -1442,6 +1444,24 @@ static void ieee80211_if_setup_no_queue(
|
||||
#endif
|
||||
}
|
||||
|
||||
+static void ieee80211_iface_process_status(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
|
||||
+
|
||||
+ if (ieee80211_is_action(mgmt->frame_control) &&
|
||||
+ mgmt->u.action.category == WLAN_CATEGORY_S1G) {
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ ieee80211_s1g_status_twt_action(sdata, skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void ieee80211_iface_work(struct work_struct *work)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata =
|
||||
@@ -1519,6 +1539,16 @@ static void ieee80211_iface_work(struct
|
||||
WARN_ON(1);
|
||||
break;
|
||||
}
|
||||
+ } else if (ieee80211_is_action(mgmt->frame_control) &&
|
||||
+ mgmt->u.action.category == WLAN_CATEGORY_S1G) {
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ ieee80211_s1g_rx_twt_action(sdata, skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
} else if (ieee80211_is_ext(mgmt->frame_control)) {
|
||||
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||
ieee80211_sta_rx_queued_ext(sdata, skb);
|
||||
@@ -1574,6 +1604,12 @@ static void ieee80211_iface_work(struct
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
+ /* process status queue */
|
||||
+ while ((skb = skb_dequeue(&sdata->status_queue))) {
|
||||
+ ieee80211_iface_process_status(sdata, skb);
|
||||
+ kfree_skb(skb);
|
||||
+ }
|
||||
+
|
||||
/* then other type-dependent work */
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
@@ -1637,6 +1673,7 @@ static void ieee80211_setup_sdata(struct
|
||||
}
|
||||
|
||||
skb_queue_head_init(&sdata->skb_queue);
|
||||
+ skb_queue_head_init(&sdata->status_queue);
|
||||
INIT_WORK(&sdata->work, ieee80211_iface_work);
|
||||
INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work);
|
||||
INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -3210,6 +3210,68 @@ ieee80211_rx_h_mgmt_check(struct ieee802
|
||||
return RX_CONTINUE;
|
||||
}
|
||||
|
||||
+static bool
|
||||
+ieee80211_process_rx_twt_action(struct ieee80211_rx_data *rx)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)rx->skb->data;
|
||||
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
||||
+ struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||
+ const struct ieee80211_sta_he_cap *hecap;
|
||||
+ struct ieee80211_supported_band *sband;
|
||||
+
|
||||
+ /* TWT actions are only supported in AP for the moment */
|
||||
+ if (sdata->vif.type != NL80211_IFTYPE_AP)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!rx->local->ops->add_twt_setup)
|
||||
+ return false;
|
||||
+
|
||||
+ sband = rx->local->hw.wiphy->bands[status->band];
|
||||
+ hecap = ieee80211_get_he_iftype_cap(sband,
|
||||
+ ieee80211_vif_type_p2p(&sdata->vif));
|
||||
+ if (!hecap)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!(hecap->he_cap_elem.mac_cap_info[0] &
|
||||
+ IEEE80211_HE_MAC_CAP0_TWT_RES))
|
||||
+ return false;
|
||||
+
|
||||
+ if (!rx->sta)
|
||||
+ return false;
|
||||
+
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_SETUP: {
|
||||
+ struct ieee80211_twt_setup *twt;
|
||||
+
|
||||
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE +
|
||||
+ 1 + /* action code */
|
||||
+ sizeof(struct ieee80211_twt_setup) +
|
||||
+ 2 /* TWT req_type agrt */)
|
||||
+ break;
|
||||
+
|
||||
+ twt = (void *)mgmt->u.action.u.s1g.variable;
|
||||
+ if (twt->element_id != WLAN_EID_S1G_TWT)
|
||||
+ break;
|
||||
+
|
||||
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE +
|
||||
+ 4 + /* action code + token + tlv */
|
||||
+ twt->length)
|
||||
+ break;
|
||||
+
|
||||
+ return true; /* queue the frame */
|
||||
+ }
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE + 2)
|
||||
+ break;
|
||||
+
|
||||
+ return true; /* queue the frame */
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static ieee80211_rx_result debug_noinline
|
||||
ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
||||
{
|
||||
@@ -3489,6 +3551,17 @@ ieee80211_rx_h_action(struct ieee80211_r
|
||||
!mesh_path_sel_is_hwmp(sdata))
|
||||
break;
|
||||
goto queue;
|
||||
+ case WLAN_CATEGORY_S1G:
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ if (ieee80211_process_rx_twt_action(rx))
|
||||
+ goto queue;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
}
|
||||
|
||||
return RX_CONTINUE;
|
||||
--- a/net/mac80211/s1g.c
|
||||
+++ b/net/mac80211/s1g.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <linux/ieee80211.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "ieee80211_i.h"
|
||||
+#include "driver-ops.h"
|
||||
|
||||
void ieee80211_s1g_sta_rate_init(struct sta_info *sta)
|
||||
{
|
||||
@@ -14,3 +15,182 @@ void ieee80211_s1g_sta_rate_init(struct
|
||||
sta->rx_stats.last_rate =
|
||||
STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_S1G);
|
||||
}
|
||||
+
|
||||
+bool ieee80211_s1g_is_twt_setup(struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+
|
||||
+ if (likely(!ieee80211_is_action(mgmt->frame_control)))
|
||||
+ return false;
|
||||
+
|
||||
+ if (likely(mgmt->u.action.category != WLAN_CATEGORY_S1G))
|
||||
+ return false;
|
||||
+
|
||||
+ return mgmt->u.action.u.s1g.action_code == WLAN_S1G_TWT_SETUP;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_send_twt_setup(struct ieee80211_sub_if_data *sdata, const u8 *da,
|
||||
+ const u8 *bssid, struct ieee80211_twt_setup *twt)
|
||||
+{
|
||||
+ int len = IEEE80211_MIN_ACTION_SIZE + 4 + twt->length;
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct ieee80211_mgmt *mgmt;
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
|
||||
+ if (!skb)
|
||||
+ return;
|
||||
+
|
||||
+ skb_reserve(skb, local->hw.extra_tx_headroom);
|
||||
+ mgmt = skb_put_zero(skb, len);
|
||||
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||
+ IEEE80211_STYPE_ACTION);
|
||||
+ memcpy(mgmt->da, da, ETH_ALEN);
|
||||
+ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
|
||||
+ memcpy(mgmt->bssid, bssid, ETH_ALEN);
|
||||
+
|
||||
+ mgmt->u.action.category = WLAN_CATEGORY_S1G;
|
||||
+ mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_SETUP;
|
||||
+ memcpy(mgmt->u.action.u.s1g.variable, twt, 3 + twt->length);
|
||||
+
|
||||
+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
|
||||
+ IEEE80211_TX_INTFL_MLME_CONN_TX |
|
||||
+ IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
+ ieee80211_tx_skb(sdata, skb);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_send_twt_teardown(struct ieee80211_sub_if_data *sdata,
|
||||
+ const u8 *da, const u8 *bssid, u8 flowid)
|
||||
+{
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct ieee80211_mgmt *mgmt;
|
||||
+ struct sk_buff *skb;
|
||||
+ u8 *id;
|
||||
+
|
||||
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom +
|
||||
+ IEEE80211_MIN_ACTION_SIZE + 2);
|
||||
+ if (!skb)
|
||||
+ return;
|
||||
+
|
||||
+ skb_reserve(skb, local->hw.extra_tx_headroom);
|
||||
+ mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE + 2);
|
||||
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||
+ IEEE80211_STYPE_ACTION);
|
||||
+ memcpy(mgmt->da, da, ETH_ALEN);
|
||||
+ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
|
||||
+ memcpy(mgmt->bssid, bssid, ETH_ALEN);
|
||||
+
|
||||
+ mgmt->u.action.category = WLAN_CATEGORY_S1G;
|
||||
+ mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_TEARDOWN;
|
||||
+ id = (u8 *)mgmt->u.action.u.s1g.variable;
|
||||
+ *id = flowid;
|
||||
+
|
||||
+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
|
||||
+ IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
+ ieee80211_tx_skb(sdata, skb);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_rx_twt_setup(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sta_info *sta, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
|
||||
+ struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable;
|
||||
+ struct ieee80211_twt_params *twt_agrt = (void *)twt->params;
|
||||
+
|
||||
+ twt_agrt->req_type &= cpu_to_le16(~IEEE80211_TWT_REQTYPE_REQUEST);
|
||||
+
|
||||
+ /* broadcast TWT not supported yet */
|
||||
+ if (twt->control & IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST) {
|
||||
+ le16p_replace_bits(&twt_agrt->req_type,
|
||||
+ TWT_SETUP_CMD_REJECT,
|
||||
+ IEEE80211_TWT_REQTYPE_SETUP_CMD);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ drv_add_twt_setup(sdata->local, sdata, &sta->sta, twt);
|
||||
+out:
|
||||
+ ieee80211_s1g_send_twt_setup(sdata, mgmt->sa, sdata->vif.addr, twt);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_rx_twt_teardown(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sta_info *sta, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+
|
||||
+ drv_twt_teardown_request(sdata->local, sdata, &sta->sta,
|
||||
+ mgmt->u.action.u.s1g.variable[0]);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_tx_twt_setup_fail(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sta_info *sta, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+ struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable;
|
||||
+ struct ieee80211_twt_params *twt_agrt = (void *)twt->params;
|
||||
+ u8 flowid = le16_get_bits(twt_agrt->req_type,
|
||||
+ IEEE80211_TWT_REQTYPE_FLOWID);
|
||||
+
|
||||
+ drv_twt_teardown_request(sdata->local, sdata, &sta->sta, flowid);
|
||||
+
|
||||
+ ieee80211_s1g_send_twt_teardown(sdata, mgmt->sa, sdata->vif.addr,
|
||||
+ flowid);
|
||||
+}
|
||||
+
|
||||
+void ieee80211_s1g_rx_twt_action(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct sta_info *sta;
|
||||
+
|
||||
+ mutex_lock(&local->sta_mtx);
|
||||
+
|
||||
+ sta = sta_info_get_bss(sdata, mgmt->sa);
|
||||
+ if (!sta)
|
||||
+ goto out;
|
||||
+
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ ieee80211_s1g_rx_twt_setup(sdata, sta, skb);
|
||||
+ break;
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ ieee80211_s1g_rx_twt_teardown(sdata, sta, skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ mutex_unlock(&local->sta_mtx);
|
||||
+}
|
||||
+
|
||||
+void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct sta_info *sta;
|
||||
+
|
||||
+ mutex_lock(&local->sta_mtx);
|
||||
+
|
||||
+ sta = sta_info_get_bss(sdata, mgmt->da);
|
||||
+ if (!sta)
|
||||
+ goto out;
|
||||
+
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ /* process failed twt setup frames */
|
||||
+ ieee80211_s1g_tx_twt_setup_fail(sdata, sta, skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ mutex_unlock(&local->sta_mtx);
|
||||
+}
|
||||
--- a/net/mac80211/status.c
|
||||
+++ b/net/mac80211/status.c
|
||||
@@ -705,13 +705,26 @@ static void ieee80211_report_used_skb(st
|
||||
/* Check to see if packet is a TDLS teardown packet */
|
||||
if (ieee80211_is_data(hdr->frame_control) &&
|
||||
(ieee80211_get_tdls_action(skb, hdr_size) ==
|
||||
- WLAN_TDLS_TEARDOWN))
|
||||
+ WLAN_TDLS_TEARDOWN)) {
|
||||
ieee80211_tdls_td_tx_handle(local, sdata, skb,
|
||||
info->flags);
|
||||
- else
|
||||
+ } else if (ieee80211_s1g_is_twt_setup(skb)) {
|
||||
+ if (!acked) {
|
||||
+ struct sk_buff *qskb;
|
||||
+
|
||||
+ qskb = skb_clone(skb, GFP_ATOMIC);
|
||||
+ if (qskb) {
|
||||
+ skb_queue_tail(&sdata->status_queue,
|
||||
+ qskb);
|
||||
+ ieee80211_queue_work(&local->hw,
|
||||
+ &sdata->work);
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
ieee80211_mgd_conn_tx_status(sdata,
|
||||
hdr->frame_control,
|
||||
acked);
|
||||
+ }
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
--- a/net/mac80211/trace.h
|
||||
+++ b/net/mac80211/trace.h
|
||||
@@ -2804,6 +2804,73 @@ DEFINE_EVENT(sta_flag_evt, drv_sta_set_d
|
||||
TP_ARGS(local, sdata, sta, enabled)
|
||||
);
|
||||
|
||||
+TRACE_EVENT(drv_add_twt_setup,
|
||||
+ TP_PROTO(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ struct ieee80211_twt_setup *twt,
|
||||
+ struct ieee80211_twt_params *twt_agrt),
|
||||
+
|
||||
+ TP_ARGS(local, sta, twt, twt_agrt),
|
||||
+
|
||||
+ TP_STRUCT__entry(
|
||||
+ LOCAL_ENTRY
|
||||
+ STA_ENTRY
|
||||
+ __field(u8, dialog_token)
|
||||
+ __field(u8, control)
|
||||
+ __field(__le16, req_type)
|
||||
+ __field(__le64, twt)
|
||||
+ __field(u8, duration)
|
||||
+ __field(__le16, mantissa)
|
||||
+ __field(u8, channel)
|
||||
+ ),
|
||||
+
|
||||
+ TP_fast_assign(
|
||||
+ LOCAL_ASSIGN;
|
||||
+ STA_ASSIGN;
|
||||
+ __entry->dialog_token = twt->dialog_token;
|
||||
+ __entry->control = twt->control;
|
||||
+ __entry->req_type = twt_agrt->req_type;
|
||||
+ __entry->twt = twt_agrt->twt;
|
||||
+ __entry->duration = twt_agrt->min_twt_dur;
|
||||
+ __entry->mantissa = twt_agrt->mantissa;
|
||||
+ __entry->channel = twt_agrt->channel;
|
||||
+ ),
|
||||
+
|
||||
+ TP_printk(
|
||||
+ LOCAL_PR_FMT STA_PR_FMT
|
||||
+ " token:%d control:0x%02x req_type:0x%04x"
|
||||
+ " twt:%llu duration:%d mantissa:%d channel:%d",
|
||||
+ LOCAL_PR_ARG, STA_PR_ARG, __entry->dialog_token,
|
||||
+ __entry->control, le16_to_cpu(__entry->req_type),
|
||||
+ le64_to_cpu(__entry->twt), __entry->duration,
|
||||
+ le16_to_cpu(__entry->mantissa), __entry->channel
|
||||
+ )
|
||||
+);
|
||||
+
|
||||
+TRACE_EVENT(drv_twt_teardown_request,
|
||||
+ TP_PROTO(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sta *sta, u8 flowid),
|
||||
+
|
||||
+ TP_ARGS(local, sta, flowid),
|
||||
+
|
||||
+ TP_STRUCT__entry(
|
||||
+ LOCAL_ENTRY
|
||||
+ STA_ENTRY
|
||||
+ __field(u8, flowid)
|
||||
+ ),
|
||||
+
|
||||
+ TP_fast_assign(
|
||||
+ LOCAL_ASSIGN;
|
||||
+ STA_ASSIGN;
|
||||
+ __entry->flowid = flowid;
|
||||
+ ),
|
||||
+
|
||||
+ TP_printk(
|
||||
+ LOCAL_PR_FMT STA_PR_FMT " flowid:%d",
|
||||
+ LOCAL_PR_ARG, STA_PR_ARG, __entry->flowid
|
||||
+ )
|
||||
+);
|
||||
+
|
||||
#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
@ -1,11 +0,0 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -2,7 +2,7 @@
|
||||
# Makefile for the output source package
|
||||
#
|
||||
|
||||
-ifeq ($(KERNELRELEASE),)
|
||||
+ifeq ($(KERNELVERSION),)
|
||||
|
||||
MAKEFLAGS += --no-print-directory
|
||||
SHELL := /usr/bin/env bash
|
@ -1,206 +0,0 @@
|
||||
PKG_DRIVERS += \
|
||||
rtl8180 rtl8187 \
|
||||
rtlwifi rtlwifi-pci rtlwifi-btcoexist rtlwifi-usb rtl8192c-common \
|
||||
rtl8192ce rtl8192se rtl8192de rtl8192cu rtl8723bs rtl8821ae \
|
||||
rtl8xxxu rtw88
|
||||
|
||||
config-$(call config_package,rtl8180) += RTL8180
|
||||
config-$(call config_package,rtl8187) += RTL8187
|
||||
|
||||
config-$(call config_package,rtlwifi) += RTL_CARDS RTLWIFI
|
||||
config-$(call config_package,rtlwifi-pci) += RTLWIFI_PCI
|
||||
config-$(call config_package,rtlwifi-btcoexist) += RTLBTCOEXIST
|
||||
config-$(call config_package,rtlwifi-usb) += RTLWIFI_USB
|
||||
config-$(call config_package,rtl8192c-common) += RTL8192C_COMMON
|
||||
config-$(call config_package,rtl8192ce) += RTL8192CE
|
||||
config-$(call config_package,rtl8192se) += RTL8192SE
|
||||
config-$(call config_package,rtl8192de) += RTL8192DE
|
||||
config-$(call config_package,rtl8192cu) += RTL8192CU
|
||||
config-$(call config_package,rtl8821ae) += RTL8821AE
|
||||
config-$(CONFIG_PACKAGE_RTLWIFI_DEBUG) += RTLWIFI_DEBUG
|
||||
|
||||
config-$(call config_package,rtl8xxxu) += RTL8XXXU
|
||||
config-y += RTL8XXXU_UNTESTED
|
||||
|
||||
config-$(call config_package,rtl8723bs) += RTL8723BS
|
||||
config-y += STAGING
|
||||
|
||||
config-$(call config_package,rtw88) += RTW88 RTW88_CORE RTW88_PCI
|
||||
config-y += RTW88_8822BE RTW88_8822CE RTW88_8723DE
|
||||
|
||||
define KernelPackage/rtl818x/Default
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek Drivers for RTL818x devices
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/rtl8187
|
||||
DEPENDS+= +kmod-eeprom-93cx6 +kmod-mac80211
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8180
|
||||
$(call KernelPackage/rtl818x/Default)
|
||||
DEPENDS+= @PCI_SUPPORT
|
||||
TITLE+= (RTL8180 PCI)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl818x_pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl818x_pci)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8187
|
||||
$(call KernelPackage/rtl818x/Default)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-usb-core
|
||||
TITLE+= (RTL8187 USB)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8187.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8187)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtlwifi/config
|
||||
config PACKAGE_RTLWIFI_DEBUG
|
||||
bool "Realtek wireless debugging"
|
||||
depends on PACKAGE_kmod-rtlwifi
|
||||
help
|
||||
Say Y, if you want to debug realtek wireless drivers.
|
||||
|
||||
endef
|
||||
|
||||
define KernelPackage/rtlwifi
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek common driver part
|
||||
DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT) +kmod-mac80211 +@DRIVER_11N_SUPPORT
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtlwifi.ko
|
||||
HIDDEN:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/rtlwifi-pci
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek common driver part (PCI support)
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-rtlwifi
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl_pci)
|
||||
HIDDEN:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/rtlwifi-btcoexist
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek BT coexist support
|
||||
DEPENDS+= +kmod-rtlwifi
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/btcoexist/btcoexist.ko
|
||||
AUTOLOAD:=$(call AutoProbe,btcoexist)
|
||||
HIDDEN:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/rtlwifi-usb
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek common driver part (USB support)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-rtlwifi
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_usb.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl_usb)
|
||||
HIDDEN:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8192c-common
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8192CE/RTL8192CU common support module
|
||||
DEPENDS+= +kmod-rtlwifi
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192c/rtl8192c-common.ko
|
||||
HIDDEN:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8192ce
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8192CE/RTL8188CE support
|
||||
DEPENDS+= +kmod-rtlwifi-pci +kmod-rtl8192c-common +rtl8192ce-firmware
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rtl8192ce.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8192ce)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8192se
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8192SE/RTL8191SE support
|
||||
DEPENDS+= +kmod-rtlwifi-pci +rtl8192se-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rtl8192se.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8192se)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8192de
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8192DE/RTL8188DE support
|
||||
DEPENDS+= +kmod-rtlwifi-pci +rtl8192de-firmware
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rtl8192de.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8192de)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8192cu
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8192CU/RTL8188CU support
|
||||
DEPENDS+= +kmod-rtlwifi-usb +kmod-rtl8192c-common +rtl8192cu-firmware
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rtl8192cu.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8192cu)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8821ae
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8821AE support
|
||||
DEPENDS+= +kmod-rtlwifi-btcoexist +kmod-rtlwifi-pci +rtl8821ae-firmware
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/rtl8821ae.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8821ae)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8xxxu
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=alternative Realtek RTL8XXXU support
|
||||
DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-mac80211
|
||||
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtl8xxxu)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8xxxu/description
|
||||
This is an alternative driver for various Realtek RTL8XXX
|
||||
parts written to utilize the Linux mac80211 stack.
|
||||
The driver is known to work with a number of RTL8723AU,
|
||||
RL8188CU, RTL8188RU, RTL8191CU, and RTL8192CU devices
|
||||
|
||||
This driver is under development and has a limited feature
|
||||
set. In particular it does not yet support 40MHz channels
|
||||
and power management. However it should have a smaller
|
||||
memory footprint than the vendor drivers and benetifs
|
||||
from the in kernel mac80211 stack.
|
||||
|
||||
It can coexist with drivers from drivers/staging/rtl8723au,
|
||||
drivers/staging/rtl8192u, and drivers/net/wireless/rtlwifi,
|
||||
but you will need to control which module you wish to load.
|
||||
|
||||
RTL8XXXU_UNTESTED is enabled
|
||||
This option enables detection of Realtek 8723/8188/8191/8192 WiFi
|
||||
USB devices which have not been tested directly by the driver
|
||||
author or reported to be working by third parties.
|
||||
|
||||
Please report your results!
|
||||
endef
|
||||
|
||||
define KernelPackage/rtw88
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8822BE/RTL8822CE/RTL8723DE
|
||||
DEPENDS+= @(PCI_SUPPORT) +kmod-mac80211 +@DRIVER_11AC_SUPPORT +@DRIVER_11N_SUPPORT
|
||||
FILES:=\
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822be.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822b.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822ce.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8822c.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8723de.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8723d.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_core.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_pci.ko
|
||||
AUTOLOAD:=$(call AutoProbe,rtw88_8822be rtw88_8822ce rtw88_8723de)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8723bs
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Realtek RTL8723BS SDIO Wireless LAN NIC driver (staging)
|
||||
DEPENDS+=+kmod-mmc +kmod-mac80211
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/staging/rtl8723bs/r8723bs.ko
|
||||
AUTOLOAD:=$(call AutoProbe,r8723bs)
|
||||
endef
|
||||
|
||||
define KernelPackage/rtl8723bs/description
|
||||
This option enables support for RTL8723BS SDIO drivers, such as the wifi found
|
||||
on the 1st gen Intel Compute Stick, the CHIP and many other Intel Atom and ARM
|
||||
based devices.
|
||||
endef
|
@ -1,15 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -627,6 +627,12 @@ static int ath9k_of_init(struct ath_soft
|
||||
|
||||
ath_dbg(common, CONFIG, "parsing configuration from OF node\n");
|
||||
|
||||
+ if (of_property_read_bool(np, "qca,disable-2ghz"))
|
||||
+ ah->disable_2ghz = true;
|
||||
+
|
||||
+ if (of_property_read_bool(np, "qca,disable-5ghz"))
|
||||
+ ah->disable_5ghz = true;
|
||||
+
|
||||
if (of_property_read_bool(np, "qca,no-eeprom")) {
|
||||
/* ath9k-eeprom-<bus>-<id>.bin */
|
||||
scnprintf(eeprom_name, sizeof(eeprom_name),
|
@ -1,107 +0,0 @@
|
||||
From 9782a7f7488443568fa4d6088b73c9aff7eb8510 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Wed, 19 Apr 2017 16:14:53 +0200
|
||||
Subject: [PATCH] rt2x00: add support for external PA on MT7620
|
||||
To: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Cc: Helmut Schaa <helmut.schaa@googlemail.com>,
|
||||
linux-wireless@vger.kernel.org,
|
||||
Kalle Valo <kvalo@codeaurora.org>
|
||||
Content-Type: text/plain; charset="UTF-8"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: Tomislav Po=C5=BEega <pozega.tomislav@gmail.com>
|
||||
[pozega.tomislav@gmail.com: use chanreg and dccal helpers.]
|
||||
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800.h | 1 +
|
||||
drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 70 +++++++++++++++++++++++++-
|
||||
2 files changed, 70 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
@@ -2739,6 +2739,7 @@ enum rt2800_eeprom_word {
|
||||
#define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f)
|
||||
#define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0)
|
||||
#define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600)
|
||||
+#define EEPROM_NIC_CONF2_EXTERNAL_PA FIELD16(0xc000)
|
||||
|
||||
/*
|
||||
* EEPROM LNA
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -4356,6 +4356,45 @@ static void rt2800_config_channel(struct
|
||||
rt2800_iq_calibrate(rt2x00dev, rf->channel);
|
||||
}
|
||||
|
||||
+ if (rt2x00_rt(rt2x00dev, RT6352)) {
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0,
|
||||
+ &rt2x00dev->cap_flags)) {
|
||||
+ rt2x00_warn(rt2x00dev, "Using incomplete support for " \
|
||||
+ "external PA\n");
|
||||
+ reg = rt2800_register_read(rt2x00dev, RF_CONTROL3);
|
||||
+ reg |= 0x00000101;
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, reg);
|
||||
+
|
||||
+ reg = rt2800_register_read(rt2x00dev, RF_BYPASS3);
|
||||
+ reg |= 0x00000101;
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, reg);
|
||||
+
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0x73);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0x73);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0x73);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0xC8);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xA4);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x05);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0xC8);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xA4);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 57, 0x05);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x27);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0xC8);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xA4);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x05);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 05, 0x00);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
|
||||
+ 0x36303636);
|
||||
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN,
|
||||
+ 0x6C6C6B6C);
|
||||
+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN,
|
||||
+ 0x6C6C6B6C);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
bbp = rt2800_bbp_read(rt2x00dev, 4);
|
||||
rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
|
||||
rt2800_bbp_write(rt2x00dev, 4, bbp);
|
||||
@@ -9559,7 +9598,8 @@ static int rt2800_init_eeprom(struct rt2
|
||||
*/
|
||||
eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1);
|
||||
|
||||
- if (rt2x00_rt(rt2x00dev, RT3352)) {
|
||||
+ if (rt2x00_rt(rt2x00dev, RT3352) ||
|
||||
+ rt2x00_rt(rt2x00dev, RT6352)) {
|
||||
if (rt2x00_get_field16(eeprom,
|
||||
EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352))
|
||||
__set_bit(CAPABILITY_EXTERNAL_PA_TX0,
|
||||
@@ -9570,6 +9610,18 @@ static int rt2800_init_eeprom(struct rt2
|
||||
&rt2x00dev->cap_flags);
|
||||
}
|
||||
|
||||
+ eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF2);
|
||||
+
|
||||
+ if (rt2x00_rt(rt2x00dev, RT6352) && eeprom != 0 && eeprom != 0xffff) {
|
||||
+ if (rt2x00_get_field16(eeprom,
|
||||
+ EEPROM_NIC_CONF2_EXTERNAL_PA)) {
|
||||
+ __set_bit(CAPABILITY_EXTERNAL_PA_TX0,
|
||||
+ &rt2x00dev->cap_flags);
|
||||
+ __set_bit(CAPABILITY_EXTERNAL_PA_TX1,
|
||||
+ &rt2x00dev->cap_flags);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,109 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
BASE=$1; shift
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 NNN <file>..."
|
||||
exit 1
|
||||
}
|
||||
|
||||
check_number() {
|
||||
case "$1" in
|
||||
[0-9][0-9][0-9]) return 0;;
|
||||
esac
|
||||
return 1;
|
||||
}
|
||||
|
||||
patch_header()
|
||||
{
|
||||
awk '
|
||||
/^(---|\*\*\*|Index:)[ \t][^ \t]|^diff -/ \
|
||||
{ exit }
|
||||
{ print }
|
||||
'
|
||||
}
|
||||
|
||||
strip_diffstat()
|
||||
{
|
||||
awk '
|
||||
/#? .* \| / \
|
||||
{ eat = eat $0 "\n"
|
||||
next }
|
||||
/^#? .* files? changed(, .* insertions?\(\+\))?(, .* deletions?\(-\))?/ \
|
||||
{ eat = ""
|
||||
next }
|
||||
{ print eat $0
|
||||
eat = "" }
|
||||
'
|
||||
}
|
||||
|
||||
strip_trailing_whitespace() {
|
||||
sed -e 's:[ '$'\t'']*$::'
|
||||
}
|
||||
|
||||
fixup_header() {
|
||||
awk '
|
||||
/^From / { next }
|
||||
/^Subject: / {
|
||||
sub("Subject: \\[[^\]]*\\]", "Subject: [PATCH]")
|
||||
}
|
||||
{ print }
|
||||
'
|
||||
}
|
||||
|
||||
check_number "$BASE" || usage
|
||||
|
||||
quilt series > /dev/null || {
|
||||
echo "Not in quilt directory"
|
||||
exit 2
|
||||
}
|
||||
|
||||
get_next() {
|
||||
NEW=$BASE
|
||||
quilt series | while read CUR; do
|
||||
[ -n "$CUR" ] || break
|
||||
CUR=${CUR%%-*}
|
||||
check_number "$CUR" || continue
|
||||
[ "$CUR" -lt "$NEW" ] && continue
|
||||
[ "$CUR" -ge "$(($BASE + 100))" ] && continue
|
||||
NEW="$(($CUR + 1))"
|
||||
echo $NEW
|
||||
done | tail -n1
|
||||
}
|
||||
|
||||
CUR=$(get_next)
|
||||
CUR="${CUR:-$BASE}"
|
||||
|
||||
while [ -n "$1" ]; do
|
||||
FILE="$1"; shift
|
||||
NAME="$(basename $FILE)"
|
||||
NAME="${NAME#[0-9]*-}"
|
||||
echo -n "Processing patch $NAME: "
|
||||
|
||||
[ -e "$FILE" ] || {
|
||||
echo "file $FILE not found"
|
||||
exit 1
|
||||
}
|
||||
|
||||
grep -qE "$NAME$" patches/series && {
|
||||
echo "already applied"
|
||||
continue
|
||||
}
|
||||
|
||||
quilt new "$CUR-$NAME" || exit 1
|
||||
patch_header < "$FILE" |
|
||||
strip_diffstat |
|
||||
strip_trailing_whitespace |
|
||||
fixup_header > "patches/$CUR-$NAME"
|
||||
|
||||
quilt fold < "$FILE" || {
|
||||
cp "$FILE" ./cur_patch
|
||||
echo "patch $FILE failed to apply, copied to ./cur_patch"
|
||||
exit 1
|
||||
}
|
||||
|
||||
quilt refresh -p ab --no-index --no-timestamps
|
||||
|
||||
CUR="$(($CUR + 1))"
|
||||
done
|
||||
|
||||
exit 0
|
@ -1,74 +0,0 @@
|
||||
From: Rohan Dutta <drohan@codeaurora.org>
|
||||
Date: Tue, 27 Oct 2020 12:09:10 +0200
|
||||
Subject: [PATCH] cfg80211: Add support to configure SAE PWE value to drivers
|
||||
|
||||
Add support to configure SAE PWE preference from userspace to drivers in
|
||||
both AP and STA modes. This is needed for cases where the driver takes
|
||||
care of Authentication frame processing (SME in the driver) so that
|
||||
correct enforcement of the acceptable PWE derivation mechanism can be
|
||||
performed.
|
||||
|
||||
The userspace applications can pass the sae_pwe value using the
|
||||
NL80211_ATTR_SAE_PWE attribute in the NL80211_CMD_CONNECT and
|
||||
NL80211_CMD_START_AP commands to the driver. This allows selection
|
||||
between the hunting-and-pecking loop and hash-to-element options for PWE
|
||||
derivation. For backwards compatibility, this new attribute is optional
|
||||
and if not included, the driver is notified of the value being
|
||||
unspecified.
|
||||
|
||||
Signed-off-by: Rohan Dutta <drohan@codeaurora.org>
|
||||
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||||
Link: https://lore.kernel.org/r/20201027100910.22283-1-jouni@codeaurora.org
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -1009,6 +1009,14 @@ struct survey_info {
|
||||
* @sae_pwd: password for SAE authentication (for devices supporting SAE
|
||||
* offload)
|
||||
* @sae_pwd_len: length of SAE password (for devices supporting SAE offload)
|
||||
+ * @sae_pwe: The mechanisms allowed for SAE PWE derivation
|
||||
+ * NL80211_SAE_PWE_UNSPECIFIED: Not-specified, used to indicate userspace
|
||||
+ * did not specify any preference. The driver should follow its
|
||||
+ * internal policy in such a scenario.
|
||||
+ * NL80211_SAE_PWE_HUNT_AND_PECK: Allow hunting-and-pecking loop only
|
||||
+ * NL80211_SAE_PWE_HASH_TO_ELEMENT: Allow hash-to-element only
|
||||
+ * NL80211_SAE_PWE_BOTH: Allow either hunting-and-pecking loop
|
||||
+ * or hash-to-element
|
||||
*/
|
||||
struct cfg80211_crypto_settings {
|
||||
u32 wpa_versions;
|
||||
@@ -1027,6 +1035,7 @@ struct cfg80211_crypto_settings {
|
||||
const u8 *psk;
|
||||
const u8 *sae_pwd;
|
||||
u8 sae_pwd_len;
|
||||
+ enum nl80211_sae_pwe_mechanism sae_pwe;
|
||||
};
|
||||
|
||||
/**
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -736,6 +736,9 @@ static const struct nla_policy nl80211_p
|
||||
NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
|
||||
[NL80211_ATTR_S1G_CAPABILITY_MASK] =
|
||||
NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
|
||||
+ [NL80211_ATTR_SAE_PWE] =
|
||||
+ NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
|
||||
+ NL80211_SAE_PWE_BOTH),
|
||||
[NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
|
||||
};
|
||||
|
||||
@@ -9763,6 +9766,12 @@ static int nl80211_crypto_settings(struc
|
||||
nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
|
||||
}
|
||||
|
||||
+ if (info->attrs[NL80211_ATTR_SAE_PWE])
|
||||
+ settings->sae_pwe =
|
||||
+ nla_get_u8(info->attrs[NL80211_ATTR_SAE_PWE]);
|
||||
+ else
|
||||
+ settings->sae_pwe = NL80211_SAE_PWE_UNSPECIFIED;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Mon, 8 Mar 2021 23:01:49 +0100
|
||||
Subject: [PATCH] mac80211: set sk_pacing_shift for 802.3 txpath
|
||||
|
||||
Similar to 802.11 txpath, set socket sk_pacing_shift for 802.3 tx path.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -4205,6 +4205,9 @@ static bool ieee80211_tx_8023(struct iee
|
||||
unsigned long flags;
|
||||
int q = info->hw_queue;
|
||||
|
||||
+ if (sta)
|
||||
+ sk_pacing_shift_update(skb->sk, local->hw.tx_sk_pacing_shift);
|
||||
+
|
||||
if (ieee80211_queue_skb(local, sdata, sta, skb))
|
||||
return true;
|
||||
|
@ -1,5 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ "${ACTION}" = "add" ] && {
|
||||
/sbin/wifi config
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
--- a/include/linux/rt2x00_platform.h
|
||||
+++ b/include/linux/rt2x00_platform.h
|
||||
@@ -14,6 +14,9 @@
|
||||
|
||||
struct rt2x00_platform_data {
|
||||
char *eeprom_file_name;
|
||||
+
|
||||
+ int disable_2ghz;
|
||||
+ int disable_5ghz;
|
||||
};
|
||||
|
||||
#endif /* _RT2X00_PLATFORM_H */
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -1012,6 +1012,22 @@ static int rt2x00lib_probe_hw_modes(stru
|
||||
unsigned int num_rates;
|
||||
unsigned int i;
|
||||
|
||||
+ if (rt2x00dev->dev->platform_data) {
|
||||
+ struct rt2x00_platform_data *pdata;
|
||||
+
|
||||
+ pdata = rt2x00dev->dev->platform_data;
|
||||
+ if (pdata->disable_2ghz)
|
||||
+ spec->supported_bands &= ~SUPPORT_BAND_2GHZ;
|
||||
+ if (pdata->disable_5ghz)
|
||||
+ spec->supported_bands &= ~SUPPORT_BAND_5GHZ;
|
||||
+ }
|
||||
+
|
||||
+ if ((spec->supported_bands & SUPPORT_BAND_BOTH) == 0) {
|
||||
+ rt2x00_err(rt2x00dev, "No supported bands\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
num_rates = 0;
|
||||
if (spec->supported_rates & SUPPORT_RATE_CCK)
|
||||
num_rates += 4;
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
@@ -399,6 +399,7 @@ struct hw_mode_spec {
|
||||
unsigned int supported_bands;
|
||||
#define SUPPORT_BAND_2GHZ 0x00000001
|
||||
#define SUPPORT_BAND_5GHZ 0x00000002
|
||||
+#define SUPPORT_BAND_BOTH (SUPPORT_BAND_2GHZ | SUPPORT_BAND_5GHZ)
|
||||
|
||||
unsigned int supported_rates;
|
||||
#define SUPPORT_RATE_CCK 0x00000001
|
@ -1,53 +0,0 @@
|
||||
From 79c9d7aabae1d1da9eea97d83b61e1517a8a2221 Mon Sep 17 00:00:00 2001
|
||||
From: Mathias Kresin <dev@kresin.me>
|
||||
Date: Fri, 22 Jun 2018 18:59:44 +0200
|
||||
Subject: [PATCH] ath10k: use tpt LED trigger by default
|
||||
|
||||
Use the tpt LED trigger for each created phy led. Ths way LEDs attached
|
||||
to the ath10k GPIO pins are indicating the phy status and blink on
|
||||
traffic.
|
||||
|
||||
Signed-off-by: Mathias Kresin <dev@kresin.me>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/core.h | 4 ++++
|
||||
drivers/net/wireless/ath/ath10k/leds.c | 4 +---
|
||||
drivers/net/wireless/ath/ath10k/mac.c | 2 +-
|
||||
3 files changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.h
|
||||
@@ -1290,6 +1290,10 @@ struct ath10k {
|
||||
bool coex_support;
|
||||
int coex_gpio_pin;
|
||||
|
||||
+#ifdef CPTCFG_MAC80211_LEDS
|
||||
+ const char *led_default_trigger;
|
||||
+#endif
|
||||
+
|
||||
/* must be last */
|
||||
u8 drv_priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
--- a/drivers/net/wireless/ath/ath10k/leds.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/leds.c
|
||||
@@ -81,9 +81,7 @@ int ath10k_leds_register(struct ath10k *
|
||||
|
||||
ar->leds.cdev.name = ar->leds.label;
|
||||
ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking;
|
||||
-
|
||||
- /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */
|
||||
- ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger;
|
||||
+ ar->leds.cdev.default_trigger = ar->led_default_trigger;
|
||||
|
||||
ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev);
|
||||
if (ret)
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -10098,7 +10098,7 @@ int ath10k_mac_register(struct ath10k *a
|
||||
ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
|
||||
|
||||
#ifdef CPTCFG_MAC80211_LEDS
|
||||
- ieee80211_create_tpt_led_trigger(ar->hw,
|
||||
+ ar->led_default_trigger = ieee80211_create_tpt_led_trigger(ar->hw,
|
||||
IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink,
|
||||
ARRAY_SIZE(ath10k_tpt_blink));
|
||||
#endif
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/net/wireless/marvell/mwl8k.c
|
||||
+++ b/drivers/net/wireless/marvell/mwl8k.c
|
||||
@@ -5695,6 +5695,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
|
||||
MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
|
||||
|
||||
static const struct pci_device_id mwl8k_pci_id_table[] = {
|
||||
+ { PCI_VDEVICE(MARVELL, 0x2a02), .driver_data = MWL8363, },
|
||||
{ PCI_VDEVICE(MARVELL, 0x2a0a), .driver_data = MWL8363, },
|
||||
{ PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
|
||||
{ PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
|
@ -1,196 +0,0 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Fri, 9 Apr 2021 12:40:17 +0300
|
||||
Subject: [PATCH] wireless: align some HE capabilities with the spec
|
||||
|
||||
Some names were changed, align that with the spec as of
|
||||
802.11ax-D6.1.
|
||||
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
Link: https://lore.kernel.org/r/iwlwifi.20210409123755.b1e5fbab0d8c.I3eb6076cb0714ec6aec6b8f9dee613ce4a05d825@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -3627,7 +3627,7 @@ ath11k_mac_filter_he_cap_mesh(struct iee
|
||||
IEEE80211_HE_MAC_CAP4_BQR;
|
||||
he_cap_elem->mac_cap_info[4] &= ~m;
|
||||
|
||||
- m = IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECVITE_TRANSMISSION |
|
||||
+ m = IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECTIVE_TRANSMISSION |
|
||||
IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU |
|
||||
IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING |
|
||||
IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX;
|
||||
@@ -3637,7 +3637,7 @@ ath11k_mac_filter_he_cap_mesh(struct iee
|
||||
IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;
|
||||
he_cap_elem->phy_cap_info[2] &= ~m;
|
||||
|
||||
- m = IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA |
|
||||
+ m = IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK;
|
||||
he_cap_elem->phy_cap_info[3] &= ~m;
|
||||
@@ -3649,13 +3649,13 @@ ath11k_mac_filter_he_cap_mesh(struct iee
|
||||
he_cap_elem->phy_cap_info[5] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
|
||||
- IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
|
||||
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
|
||||
IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO;
|
||||
he_cap_elem->phy_cap_info[6] &= ~m;
|
||||
|
||||
- m = IEEE80211_HE_PHY_CAP7_SRP_BASED_SR |
|
||||
- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
|
||||
+ m = IEEE80211_HE_PHY_CAP7_PSR_BASED_SR |
|
||||
+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP |
|
||||
IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ |
|
||||
IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ;
|
||||
he_cap_elem->phy_cap_info[7] &= ~m;
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
@@ -307,8 +307,8 @@ mt7915_set_stream_he_txbf_caps(struct ie
|
||||
IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK;
|
||||
elem->phy_cap_info[5] &= ~c;
|
||||
|
||||
- c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
|
||||
- IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB;
|
||||
+ c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
|
||||
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;
|
||||
elem->phy_cap_info[6] &= ~c;
|
||||
|
||||
elem->phy_cap_info[7] &= ~IEEE80211_HE_PHY_CAP7_MAX_NC_MASK;
|
||||
@@ -348,8 +348,8 @@ mt7915_set_stream_he_txbf_caps(struct ie
|
||||
c = (nss - 1) | (max_t(int, mcs->tx_mcs_160, 1) << 3);
|
||||
elem->phy_cap_info[5] |= c;
|
||||
|
||||
- c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
|
||||
- IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB;
|
||||
+ c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
|
||||
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;
|
||||
elem->phy_cap_info[6] |= c;
|
||||
}
|
||||
|
||||
@@ -484,7 +484,7 @@ mt7915_init_he_caps(struct mt7915_phy *p
|
||||
IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE |
|
||||
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
|
||||
he_cap_elem->phy_cap_info[7] |=
|
||||
- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
|
||||
+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP |
|
||||
IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI;
|
||||
he_cap_elem->phy_cap_info[8] |=
|
||||
IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
|
||||
--- a/include/linux/ieee80211.h
|
||||
+++ b/include/linux/ieee80211.h
|
||||
@@ -2065,7 +2065,7 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
#define IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG 0x01
|
||||
#define IEEE80211_HE_MAC_CAP4_QTP 0x02
|
||||
#define IEEE80211_HE_MAC_CAP4_BQR 0x04
|
||||
-#define IEEE80211_HE_MAC_CAP4_SRP_RESP 0x08
|
||||
+#define IEEE80211_HE_MAC_CAP4_PSR_RESP 0x08
|
||||
#define IEEE80211_HE_MAC_CAP4_NDP_FB_REP 0x10
|
||||
#define IEEE80211_HE_MAC_CAP4_OPS 0x20
|
||||
#define IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU 0x40
|
||||
@@ -2076,7 +2076,7 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
|
||||
#define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40 0x01
|
||||
#define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B41 0x02
|
||||
-#define IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECVITE_TRANSMISSION 0x04
|
||||
+#define IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECTIVE_TRANSMISSION 0x04
|
||||
#define IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU 0x08
|
||||
#define IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX 0x10
|
||||
#define IEEE80211_HE_MAC_CAP5_HE_DYNAMIC_SM_PS 0x20
|
||||
@@ -2134,7 +2134,7 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK 0x18
|
||||
#define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 0x00
|
||||
#define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_2 0x20
|
||||
-#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40
|
||||
+#define IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU 0x40
|
||||
#define IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER 0x80
|
||||
|
||||
#define IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE 0x01
|
||||
@@ -2181,15 +2181,15 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
|
||||
#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU 0x01
|
||||
#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU 0x02
|
||||
-#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB 0x04
|
||||
-#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB 0x08
|
||||
+#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB 0x04
|
||||
+#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB 0x08
|
||||
#define IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB 0x10
|
||||
#define IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE 0x20
|
||||
#define IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO 0x40
|
||||
#define IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT 0x80
|
||||
|
||||
-#define IEEE80211_HE_PHY_CAP7_SRP_BASED_SR 0x01
|
||||
-#define IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR 0x02
|
||||
+#define IEEE80211_HE_PHY_CAP7_PSR_BASED_SR 0x01
|
||||
+#define IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP 0x02
|
||||
#define IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI 0x04
|
||||
#define IEEE80211_HE_PHY_CAP7_MAX_NC_1 0x08
|
||||
#define IEEE80211_HE_PHY_CAP7_MAX_NC_2 0x10
|
||||
--- a/net/mac80211/debugfs_sta.c
|
||||
+++ b/net/mac80211/debugfs_sta.c
|
||||
@@ -732,15 +732,15 @@ static ssize_t sta_he_capa_read(struct f
|
||||
PFLAG(MAC, 4, BSRP_BQRP_A_MPDU_AGG, "BSRP-BQRP-A-MPDU-AGG");
|
||||
PFLAG(MAC, 4, QTP, "QTP");
|
||||
PFLAG(MAC, 4, BQR, "BQR");
|
||||
- PFLAG(MAC, 4, SRP_RESP, "SRP-RESP");
|
||||
+ PFLAG(MAC, 4, PSR_RESP, "PSR-RESP");
|
||||
PFLAG(MAC, 4, NDP_FB_REP, "NDP-FB-REP");
|
||||
PFLAG(MAC, 4, OPS, "OPS");
|
||||
PFLAG(MAC, 4, AMDSU_IN_AMPDU, "AMSDU-IN-AMPDU");
|
||||
|
||||
PRINT("MULTI-TID-AGG-TX-QOS-%d", ((cap[5] << 1) | (cap[4] >> 7)) & 0x7);
|
||||
|
||||
- PFLAG(MAC, 5, SUBCHAN_SELECVITE_TRANSMISSION,
|
||||
- "SUBCHAN-SELECVITE-TRANSMISSION");
|
||||
+ PFLAG(MAC, 5, SUBCHAN_SELECTIVE_TRANSMISSION,
|
||||
+ "SUBCHAN-SELECTIVE-TRANSMISSION");
|
||||
PFLAG(MAC, 5, UL_2x996_TONE_RU, "UL-2x996-TONE-RU");
|
||||
PFLAG(MAC, 5, OM_CTRL_UL_MU_DATA_DIS_RX, "OM-CTRL-UL-MU-DATA-DIS-RX");
|
||||
PFLAG(MAC, 5, HE_DYNAMIC_SM_PS, "HE-DYNAMIC-SM-PS");
|
||||
@@ -832,8 +832,8 @@ static ssize_t sta_he_capa_read(struct f
|
||||
|
||||
PFLAG(PHY, 3, DCM_MAX_RX_NSS_1, "DCM-MAX-RX-NSS-1");
|
||||
PFLAG(PHY, 3, DCM_MAX_RX_NSS_2, "DCM-MAX-RX-NSS-2");
|
||||
- PFLAG(PHY, 3, RX_HE_MU_PPDU_FROM_NON_AP_STA,
|
||||
- "RX-HE-MU-PPDU-FROM-NON-AP-STA");
|
||||
+ PFLAG(PHY, 3, RX_PARTIAL_BW_SU_IN_20MHZ_MU,
|
||||
+ "RX-PARTIAL-BW-SU-IN-20MHZ-MU");
|
||||
PFLAG(PHY, 3, SU_BEAMFORMER, "SU-BEAMFORMER");
|
||||
|
||||
PFLAG(PHY, 4, SU_BEAMFORMEE, "SU-BEAMFORMEE");
|
||||
@@ -853,16 +853,17 @@ static ssize_t sta_he_capa_read(struct f
|
||||
|
||||
PFLAG(PHY, 6, CODEBOOK_SIZE_42_SU, "CODEBOOK-SIZE-42-SU");
|
||||
PFLAG(PHY, 6, CODEBOOK_SIZE_75_MU, "CODEBOOK-SIZE-75-MU");
|
||||
- PFLAG(PHY, 6, TRIG_SU_BEAMFORMER_FB, "TRIG-SU-BEAMFORMER-FB");
|
||||
- PFLAG(PHY, 6, TRIG_MU_BEAMFORMER_FB, "TRIG-MU-BEAMFORMER-FB");
|
||||
+ PFLAG(PHY, 6, TRIG_SU_BEAMFORMING_FB, "TRIG-SU-BEAMFORMING-FB");
|
||||
+ PFLAG(PHY, 6, TRIG_MU_BEAMFORMING_PARTIAL_BW_FB,
|
||||
+ "MU-BEAMFORMING-PARTIAL-BW-FB");
|
||||
PFLAG(PHY, 6, TRIG_CQI_FB, "TRIG-CQI-FB");
|
||||
PFLAG(PHY, 6, PARTIAL_BW_EXT_RANGE, "PARTIAL-BW-EXT-RANGE");
|
||||
PFLAG(PHY, 6, PARTIAL_BANDWIDTH_DL_MUMIMO,
|
||||
"PARTIAL-BANDWIDTH-DL-MUMIMO");
|
||||
PFLAG(PHY, 6, PPE_THRESHOLD_PRESENT, "PPE-THRESHOLD-PRESENT");
|
||||
|
||||
- PFLAG(PHY, 7, SRP_BASED_SR, "SRP-BASED-SR");
|
||||
- PFLAG(PHY, 7, POWER_BOOST_FACTOR_AR, "POWER-BOOST-FACTOR-AR");
|
||||
+ PFLAG(PHY, 7, PSR_BASED_SR, "PSR-BASED-SR");
|
||||
+ PFLAG(PHY, 7, POWER_BOOST_FACTOR_SUPP, "POWER-BOOST-FACTOR-SUPP");
|
||||
PFLAG(PHY, 7, HE_SU_MU_PPDU_4XLTF_AND_08_US_GI,
|
||||
"HE-SU-MU-PPDU-4XLTF-AND-08-US-GI");
|
||||
PFLAG_RANGE(PHY, 7, MAX_NC, 0, 1, 1, "MAX-NC-%d");
|
||||
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
@@ -631,7 +631,7 @@ static struct ieee80211_sband_iftype_dat
|
||||
.phy_cap_info[6] =
|
||||
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
|
||||
.phy_cap_info[7] =
|
||||
- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
|
||||
+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP |
|
||||
IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI |
|
||||
IEEE80211_HE_PHY_CAP7_MAX_NC_1,
|
||||
.phy_cap_info[8] =
|
@ -1,139 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
@@ -78,6 +78,9 @@ struct rt2800_ops {
|
||||
int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
|
||||
__le32 *(*drv_get_txwi)(struct queue_entry *entry);
|
||||
unsigned int (*drv_get_dma_done)(struct data_queue *queue);
|
||||
+ int (*hw_get_chippkg)(void);
|
||||
+ int (*hw_get_chipver)(void);
|
||||
+ int (*hw_get_chipeco)(void);
|
||||
};
|
||||
|
||||
static inline u32 rt2800_register_read(struct rt2x00_dev *rt2x00dev,
|
||||
@@ -195,6 +198,27 @@ static inline unsigned int rt2800_drv_ge
|
||||
return rt2800ops->drv_get_dma_done(queue);
|
||||
}
|
||||
|
||||
+static inline int rt2800_hw_get_chippkg(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
|
||||
+
|
||||
+ return rt2800ops->hw_get_chippkg();
|
||||
+}
|
||||
+
|
||||
+static inline int rt2800_hw_get_chipver(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
|
||||
+
|
||||
+ return rt2800ops->hw_get_chipver();
|
||||
+}
|
||||
+
|
||||
+static inline int rt2800_hw_get_chipeco(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
|
||||
+
|
||||
+ return rt2800ops->hw_get_chipeco();
|
||||
+}
|
||||
+
|
||||
void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
|
||||
const u8 command, const u8 token,
|
||||
const u8 arg0, const u8 arg1);
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
|
||||
@@ -286,6 +286,10 @@ static int rt2800pci_read_eeprom(struct
|
||||
return retval;
|
||||
}
|
||||
|
||||
+static int rt2800pci_get_chippkg(void) { return 0; }
|
||||
+static int rt2800pci_get_chipver(void) { return 0; }
|
||||
+static int rt2800pci_get_chipeco(void) { return 0; }
|
||||
+
|
||||
static const struct ieee80211_ops rt2800pci_mac80211_ops = {
|
||||
.tx = rt2x00mac_tx,
|
||||
.start = rt2x00mac_start,
|
||||
@@ -328,6 +332,9 @@ static const struct rt2800_ops rt2800pci
|
||||
.drv_init_registers = rt2800mmio_init_registers,
|
||||
.drv_get_txwi = rt2800mmio_get_txwi,
|
||||
.drv_get_dma_done = rt2800mmio_get_dma_done,
|
||||
+ .hw_get_chippkg = rt2800pci_get_chippkg,
|
||||
+ .hw_get_chipver = rt2800pci_get_chipver,
|
||||
+ .hw_get_chipeco = rt2800pci_get_chipeco,
|
||||
};
|
||||
|
||||
static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
@@ -27,6 +27,12 @@
|
||||
#include "rt2800lib.h"
|
||||
#include "rt2800mmio.h"
|
||||
|
||||
+/* Needed to probe CHIP_VER register on MT7620 */
|
||||
+#ifdef CONFIG_SOC_MT7620
|
||||
+#include <asm/mach-ralink/ralink_regs.h>
|
||||
+#include <asm/mach-ralink/mt7620.h>
|
||||
+#endif
|
||||
+
|
||||
/* Allow hardware encryption to be disabled. */
|
||||
static bool modparam_nohwcrypt;
|
||||
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444);
|
||||
@@ -118,6 +124,27 @@ static int rt2800soc_write_firmware(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_SOC_MT7620
|
||||
+static int rt2800soc_get_chippkg(void)
|
||||
+{
|
||||
+ return mt7620_get_pkg();
|
||||
+}
|
||||
+
|
||||
+static int rt2800soc_get_chipver(void)
|
||||
+{
|
||||
+ return mt7620_get_chipver();
|
||||
+}
|
||||
+
|
||||
+static int rt2800soc_get_chipeco(void)
|
||||
+{
|
||||
+ return mt7620_get_eco();
|
||||
+}
|
||||
+#else
|
||||
+static int rt2800soc_get_chippkg(void) { return 0; }
|
||||
+static int rt2800soc_get_chipver(void) { return 0; }
|
||||
+static int rt2800soc_get_chipeco(void) { return 0; }
|
||||
+#endif
|
||||
+
|
||||
static const struct ieee80211_ops rt2800soc_mac80211_ops = {
|
||||
.tx = rt2x00mac_tx,
|
||||
.start = rt2x00mac_start,
|
||||
@@ -159,6 +186,9 @@ static const struct rt2800_ops rt2800soc
|
||||
.drv_init_registers = rt2800mmio_init_registers,
|
||||
.drv_get_txwi = rt2800mmio_get_txwi,
|
||||
.drv_get_dma_done = rt2800mmio_get_dma_done,
|
||||
+ .hw_get_chippkg = rt2800soc_get_chippkg,
|
||||
+ .hw_get_chipver = rt2800soc_get_chipver,
|
||||
+ .hw_get_chipeco = rt2800soc_get_chipeco,
|
||||
};
|
||||
|
||||
static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
|
||||
@@ -628,6 +628,10 @@ static int rt2800usb_probe_hw(struct rt2
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int rt2800usb_get_chippkg(void) { return 0; }
|
||||
+static int rt2800usb_get_chipver(void) { return 0; }
|
||||
+static int rt2800usb_get_chipeco(void) { return 0; }
|
||||
+
|
||||
static const struct ieee80211_ops rt2800usb_mac80211_ops = {
|
||||
.tx = rt2x00mac_tx,
|
||||
.start = rt2x00mac_start,
|
||||
@@ -671,6 +675,9 @@ static const struct rt2800_ops rt2800usb
|
||||
.drv_init_registers = rt2800usb_init_registers,
|
||||
.drv_get_txwi = rt2800usb_get_txwi,
|
||||
.drv_get_dma_done = rt2800usb_get_dma_done,
|
||||
+ .hw_get_chippkg = rt2800usb_get_chippkg,
|
||||
+ .hw_get_chipver = rt2800usb_get_chipver,
|
||||
+ .hw_get_chipeco = rt2800usb_get_chipeco,
|
||||
};
|
||||
|
||||
static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
|
@ -1,20 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 26 Dec 2020 19:14:58 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: increase stats update interval
|
||||
|
||||
The shorter interval was leading to too many frames being used for probing
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -1865,7 +1865,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h
|
||||
mp->has_mrr = true;
|
||||
|
||||
mp->hw = hw;
|
||||
- mp->update_interval = HZ / 20;
|
||||
+ mp->update_interval = HZ / 10;
|
||||
|
||||
minstrel_ht_init_cck_rates(mp);
|
||||
for (i = 0; i < ARRAY_SIZE(mp->hw->wiphy->bands); i++)
|
@ -1,37 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -9732,6 +9732,21 @@ static int ath10k_mac_init_rd(struct ath
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef CPTCFG_MAC80211_LEDS
|
||||
+static const struct ieee80211_tpt_blink ath10k_tpt_blink[] = {
|
||||
+ { .throughput = 0 * 1024, .blink_time = 334 },
|
||||
+ { .throughput = 1 * 1024, .blink_time = 260 },
|
||||
+ { .throughput = 2 * 1024, .blink_time = 220 },
|
||||
+ { .throughput = 5 * 1024, .blink_time = 190 },
|
||||
+ { .throughput = 10 * 1024, .blink_time = 170 },
|
||||
+ { .throughput = 25 * 1024, .blink_time = 150 },
|
||||
+ { .throughput = 54 * 1024, .blink_time = 130 },
|
||||
+ { .throughput = 120 * 1024, .blink_time = 110 },
|
||||
+ { .throughput = 265 * 1024, .blink_time = 80 },
|
||||
+ { .throughput = 586 * 1024, .blink_time = 50 },
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
int ath10k_mac_register(struct ath10k *ar)
|
||||
{
|
||||
static const u32 cipher_suites[] = {
|
||||
@@ -10081,6 +10096,12 @@ int ath10k_mac_register(struct ath10k *a
|
||||
|
||||
ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
|
||||
|
||||
+#ifdef CPTCFG_MAC80211_LEDS
|
||||
+ ieee80211_create_tpt_led_trigger(ar->hw,
|
||||
+ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink,
|
||||
+ ARRAY_SIZE(ath10k_tpt_blink));
|
||||
+#endif
|
||||
+
|
||||
ret = ieee80211_register_hw(ar->hw);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
|
@ -1,36 +0,0 @@
|
||||
mac80211_phy_to_path() {
|
||||
local phy="$1"
|
||||
|
||||
[ -x /usr/bin/readlink -a -h /sys/class/ieee80211/${phy} ] || return
|
||||
|
||||
local path="$(readlink -f /sys/class/ieee80211/${phy}/device)"
|
||||
[ -n "$path" ] || return
|
||||
|
||||
path="${path##/sys/devices/}"
|
||||
case "$path" in
|
||||
platform*/pci*) path="${path##platform/}";;
|
||||
esac
|
||||
|
||||
local p
|
||||
local seq=""
|
||||
for p in $(ls /sys/class/ieee80211/$phy/device/ieee80211); do
|
||||
[ "$p" = "$phy" ] && {
|
||||
echo "$path${seq:++$seq}"
|
||||
break
|
||||
}
|
||||
|
||||
seq=$((${seq:-0} + 1))
|
||||
done
|
||||
}
|
||||
|
||||
mac80211_path_to_phy() {
|
||||
local path="$1"
|
||||
|
||||
local p
|
||||
for p in $(ls /sys/class/ieee80211); do
|
||||
local cur="$(mac80211_phy_to_path "$p")"
|
||||
case "$cur" in
|
||||
*$path) echo "$p"; return;;
|
||||
esac
|
||||
done
|
||||
}
|
@ -1,408 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
|
||||
@@ -1042,6 +1042,11 @@
|
||||
#define MIMO_PS_CFG_RX_STBY_POL FIELD32(0x00000010)
|
||||
#define MIMO_PS_CFG_RX_RX_STBY0 FIELD32(0x00000020)
|
||||
|
||||
+#define BB_PA_MODE_CFG0 0x1214
|
||||
+#define BB_PA_MODE_CFG1 0x1218
|
||||
+#define RF_PA_MODE_CFG0 0x121C
|
||||
+#define RF_PA_MODE_CFG1 0x1220
|
||||
+
|
||||
/*
|
||||
* EDCA_AC0_CFG:
|
||||
*/
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -3685,14 +3685,16 @@ static void rt2800_config_channel_rf7620
|
||||
rt2x00_set_field8(&rfcsr, RFCSR19_K, rf->rf4);
|
||||
rt2800_rfcsr_write(rt2x00dev, 19, rfcsr);
|
||||
|
||||
- /* Default: XO=20MHz , SDM mode */
|
||||
- rfcsr = rt2800_rfcsr_read(rt2x00dev, 16);
|
||||
- rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
|
||||
-
|
||||
- rfcsr = rt2800_rfcsr_read(rt2x00dev, 21);
|
||||
- rt2x00_set_field8(&rfcsr, RFCSR21_BIT8, 1);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
|
||||
+ /* Default: XO=20MHz , SDM mode */
|
||||
+ rfcsr = rt2800_rfcsr_read(rt2x00dev, 16);
|
||||
+ rt2x00_set_field8(&rfcsr, RFCSR16_SDM_MODE_MT7620, 0x80);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 16, rfcsr);
|
||||
+
|
||||
+ rfcsr = rt2800_rfcsr_read(rt2x00dev, 21);
|
||||
+ rt2x00_set_field8(&rfcsr, RFCSR21_BIT8, 1);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 21, rfcsr);
|
||||
+ }
|
||||
|
||||
rfcsr = rt2800_rfcsr_read(rt2x00dev, 1);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_TX2_EN_MT7620,
|
||||
@@ -3726,18 +3728,23 @@ static void rt2800_config_channel_rf7620
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x20);
|
||||
}
|
||||
|
||||
- if (conf_is_ht40(conf)) {
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08);
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08);
|
||||
- } else {
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28);
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
|
||||
+ if (conf_is_ht40(conf)) {
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x08);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x08);
|
||||
+ } else {
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 58, 0x28);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 59, 0x28);
|
||||
+ }
|
||||
}
|
||||
|
||||
- rfcsr = rt2800_rfcsr_read(rt2x00dev, 28);
|
||||
- rt2x00_set_field8(&rfcsr, RFCSR28_CH11_HT40,
|
||||
- conf_is_ht40(conf) && (rf->channel == 11));
|
||||
- rt2800_rfcsr_write(rt2x00dev, 28, rfcsr);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
|
||||
+ rt2800_hw_get_chipeco(rt2x00dev) == 2) {
|
||||
+ rfcsr = rt2800_rfcsr_read(rt2x00dev, 28);
|
||||
+ rt2x00_set_field8(&rfcsr, RFCSR28_CH11_HT40,
|
||||
+ conf_is_ht40(conf) && (rf->channel == 11));
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 28, rfcsr);
|
||||
+ }
|
||||
|
||||
if (!test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) {
|
||||
if (conf_is_ht40(conf)) {
|
||||
@@ -3837,25 +3844,29 @@ static void rt2800_config_alc(struct rt2
|
||||
if (i == 10000)
|
||||
rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n");
|
||||
|
||||
- if (chan->center_freq > 2457) {
|
||||
- bbp = rt2800_bbp_read(rt2x00dev, 30);
|
||||
- bbp = 0x40;
|
||||
- rt2800_bbp_write(rt2x00dev, 30, bbp);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 39, 0);
|
||||
- if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
|
||||
- rt2800_rfcsr_write(rt2x00dev, 42, 0xfb);
|
||||
- else
|
||||
- rt2800_rfcsr_write(rt2x00dev, 42, 0x7b);
|
||||
- } else {
|
||||
- bbp = rt2800_bbp_read(rt2x00dev, 30);
|
||||
- bbp = 0x1f;
|
||||
- rt2800_bbp_write(rt2x00dev, 30, bbp);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
|
||||
- if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
|
||||
- rt2800_rfcsr_write(rt2x00dev, 42, 0xdb);
|
||||
- else
|
||||
- rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
|
||||
+ rt2800_hw_get_chipeco(rt2x00dev) >= 2) {
|
||||
+ if (chan->center_freq > 2457) {
|
||||
+ bbp = rt2800_bbp_read(rt2x00dev, 30);
|
||||
+ bbp = 0x40;
|
||||
+ rt2800_bbp_write(rt2x00dev, 30, bbp);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 39, 0);
|
||||
+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 42, 0xfb);
|
||||
+ else
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 42, 0x7b);
|
||||
+ } else {
|
||||
+ bbp = rt2800_bbp_read(rt2x00dev, 30);
|
||||
+ bbp = 0x1f;
|
||||
+ rt2800_bbp_write(rt2x00dev, 30, bbp);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
|
||||
+ if (rt2x00_has_cap_external_lna_bg(rt2x00dev))
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 42, 0xdb);
|
||||
+ else
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
|
||||
+ }
|
||||
}
|
||||
+
|
||||
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, mac_sys_ctrl);
|
||||
|
||||
rt2800_vco_calibration(rt2x00dev);
|
||||
@@ -5887,18 +5898,33 @@ static int rt2800_init_registers(struct
|
||||
} else if (rt2x00_rt(rt2x00dev, RT5350)) {
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT6352)) {
|
||||
- rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401);
|
||||
- rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000);
|
||||
- rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
|
||||
- rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000);
|
||||
- rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
|
||||
- rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0);
|
||||
- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C);
|
||||
- rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN, 0x6C6C666C);
|
||||
- rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
|
||||
- 0x3630363A);
|
||||
- rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT,
|
||||
- 0x3630363A);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) <= 1) {
|
||||
+ rt2800_register_write(rt2x00dev, TX_ALC_VGA3,
|
||||
+ 0x00000000);
|
||||
+ rt2800_register_write(rt2x00dev, BB_PA_MODE_CFG0,
|
||||
+ 0x000055FF);
|
||||
+ rt2800_register_write(rt2x00dev, BB_PA_MODE_CFG1,
|
||||
+ 0x00550055);
|
||||
+ rt2800_register_write(rt2x00dev, RF_PA_MODE_CFG0,
|
||||
+ 0x000055FF);
|
||||
+ rt2800_register_write(rt2x00dev, RF_PA_MODE_CFG1,
|
||||
+ 0x00550055);
|
||||
+ } else {
|
||||
+ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000401);
|
||||
+ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x000C0000);
|
||||
+ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
|
||||
+ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000);
|
||||
+ rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0);
|
||||
+ rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0);
|
||||
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN,
|
||||
+ 0x6C6C666C);
|
||||
+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_ATTEN,
|
||||
+ 0x6C6C666C);
|
||||
+ rt2800_register_write(rt2x00dev, TX0_RF_GAIN_CORRECT,
|
||||
+ 0x3630363A);
|
||||
+ rt2800_register_write(rt2x00dev, TX1_RF_GAIN_CORRECT,
|
||||
+ 0x3630363A);
|
||||
+ }
|
||||
reg = rt2800_register_read(rt2x00dev, TX_ALC_CFG_1);
|
||||
rt2x00_set_field32(®, TX_ALC_CFG_1_ROS_BUSY_EN, 0);
|
||||
rt2800_register_write(rt2x00dev, TX_ALC_CFG_1, reg);
|
||||
@@ -7042,14 +7068,16 @@ static void rt2800_init_bbp_6352(struct
|
||||
rt2800_bbp_write(rt2x00dev, 188, 0x00);
|
||||
rt2800_bbp_write(rt2x00dev, 189, 0x00);
|
||||
|
||||
- rt2800_bbp_write(rt2x00dev, 91, 0x06);
|
||||
- rt2800_bbp_write(rt2x00dev, 92, 0x04);
|
||||
- rt2800_bbp_write(rt2x00dev, 93, 0x54);
|
||||
- rt2800_bbp_write(rt2x00dev, 99, 0x50);
|
||||
- rt2800_bbp_write(rt2x00dev, 148, 0x84);
|
||||
- rt2800_bbp_write(rt2x00dev, 167, 0x80);
|
||||
- rt2800_bbp_write(rt2x00dev, 178, 0xFF);
|
||||
- rt2800_bbp_write(rt2x00dev, 106, 0x13);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 91, 0x06);
|
||||
+ rt2800_bbp_write(rt2x00dev, 92, 0x04);
|
||||
+ rt2800_bbp_write(rt2x00dev, 93, 0x54);
|
||||
+ rt2800_bbp_write(rt2x00dev, 99, 0x50);
|
||||
+ rt2800_bbp_write(rt2x00dev, 148, 0x84);
|
||||
+ rt2800_bbp_write(rt2x00dev, 167, 0x80);
|
||||
+ rt2800_bbp_write(rt2x00dev, 178, 0xFF);
|
||||
+ rt2800_bbp_write(rt2x00dev, 106, 0x13);
|
||||
+ }
|
||||
|
||||
/* BBP for G band GLRT function (BBP_128 ~ BBP_221) */
|
||||
rt2800_bbp_glrt_write(rt2x00dev, 0, 0x00);
|
||||
@@ -10388,31 +10416,36 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rfcsr_write(rt2x00dev, 42, 0x5B);
|
||||
rt2800_rfcsr_write(rt2x00dev, 43, 0x00);
|
||||
|
||||
- rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
|
||||
- if (rt2800_clk_is_20mhz(rt2x00dev))
|
||||
- rt2800_rfcsr_write(rt2x00dev, 13, 0x03);
|
||||
- else
|
||||
- rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 14, 0x7C);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 16, 0x80);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 17, 0x99);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 18, 0x99);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 19, 0x09);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 20, 0x50);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 21, 0xB0);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 23, 0x06);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 25, 0x00);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 26, 0x5D);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 28, 0x61);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 29, 0xB5);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 43, 0x02);
|
||||
-
|
||||
- rt2800_rfcsr_write(rt2x00dev, 28, 0x62);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 29, 0xAD);
|
||||
- rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 11, 0x21);
|
||||
+ if (rt2800_clk_is_20mhz(rt2x00dev))
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 13, 0x03);
|
||||
+ else
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 14, 0x7C);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 16, 0x80);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 17, 0x99);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 18, 0x99);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 19, 0x09);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 20, 0x50);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 21, 0xB0);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 23, 0x06);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 25, 0x00);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 26, 0x5D);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 27, 0x00);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 28, 0x61);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 29, 0xB5);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 43, 0x02);
|
||||
+ }
|
||||
+
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
|
||||
+ rt2800_hw_get_chipeco(rt2x00dev) >= 2) {
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 28, 0x62);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 29, 0xAD);
|
||||
+ rt2800_rfcsr_write(rt2x00dev, 39, 0x80);
|
||||
+ }
|
||||
|
||||
/* Initialize RF channel register to default value */
|
||||
rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x03);
|
||||
@@ -10478,63 +10511,71 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
|
||||
rt2800_rfcsr_write_bank(rt2x00dev, 6, 45, 0xC5);
|
||||
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
|
||||
- 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_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);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09);
|
||||
-
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16);
|
||||
-
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
|
||||
-
|
||||
- /* Initialize RF channel register for DRQFN */
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02);
|
||||
- rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x47);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x71);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x33);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x0E);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 17, 0x23);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA4);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 20, 0x02);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 21, 0x12);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x1C);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 29, 0xEB);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 32, 0x7D);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 34, 0xD6);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 36, 0x08);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 38, 0xB4);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xB3);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xD5);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 46, 0x27);
|
||||
+ 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_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);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x20);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xF7);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 61, 0x09);
|
||||
+ }
|
||||
+
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
|
||||
+ rt2800_hw_get_chipeco(rt2x00dev) >= 2) {
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 10, 0x51);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x06);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0xA7);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 28, 0x2C);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x64);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 8, 0x51);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 9, 0x36);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 11, 0x53);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 14, 0x16);
|
||||
+
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x6C);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 48, 0xFC);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 49, 0x1F);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 54, 0x27);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x66);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 59, 0x6B);
|
||||
+ }
|
||||
+
|
||||
+ if (rt2800_hw_get_chippkg(rt2x00dev) == 0 &&
|
||||
+ rt2800_hw_get_chipver(rt2x00dev) == 1) {
|
||||
+ /* Initialize RF channel register for DRQFN */
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 43, 0xD3);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 44, 0xE3);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 45, 0xE5);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 47, 0x28);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 55, 0x68);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 56, 0xF7);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 58, 0x02);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 60, 0xC7);
|
||||
+ }
|
||||
|
||||
/* Initialize RF DC calibration register to default value */
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 0, 0x47);
|
||||
@@ -10597,12 +10638,17 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 62, 0x00);
|
||||
rt2800_rfcsr_write_dccal(rt2x00dev, 63, 0x00);
|
||||
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08);
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04);
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1) {
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x08);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x04);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x20);
|
||||
+ }
|
||||
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
|
||||
- rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
|
||||
+ if (rt2800_hw_get_chipver(rt2x00dev) > 1 &&
|
||||
+ rt2800_hw_get_chipeco(rt2x00dev) >= 2) {
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C);
|
||||
+ }
|
||||
|
||||
rt2800_r_calibration(rt2x00dev);
|
||||
rt2800_rf_self_txdc_cal(rt2x00dev);
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/Kconfig
|
||||
+++ b/drivers/net/wireless/ath/Kconfig
|
||||
@@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: ISC
|
||||
config ATH_COMMON
|
||||
- tristate
|
||||
+ tristate "ath.ko"
|
||||
depends on m
|
||||
|
||||
config WLAN_VENDOR_ATH
|
@ -1,699 +0,0 @@
|
||||
--- a/net/mac80211/Makefile
|
||||
+++ b/net/mac80211/Makefile
|
||||
@@ -7,7 +7,6 @@ mac80211-y := \
|
||||
driver-ops.o \
|
||||
sta_info.o \
|
||||
wep.o \
|
||||
- aead_api.o \
|
||||
wpa.o \
|
||||
scan.o offchannel.o \
|
||||
ht.o agg-tx.o agg-rx.o \
|
||||
@@ -19,8 +18,8 @@ mac80211-y := \
|
||||
rate.o \
|
||||
michael.o \
|
||||
tkip.o \
|
||||
+ aes_ccm.o \
|
||||
aes_cmac.o \
|
||||
- aes_gmac.o \
|
||||
fils_aead.o \
|
||||
cfg.o \
|
||||
ethtool.o \
|
||||
--- a/net/mac80211/aead_api.c
|
||||
+++ /dev/null
|
||||
@@ -1,113 +0,0 @@
|
||||
-// SPDX-License-Identifier: GPL-2.0-only
|
||||
-/*
|
||||
- * Copyright 2003-2004, Instant802 Networks, Inc.
|
||||
- * Copyright 2005-2006, Devicescape Software, Inc.
|
||||
- * Copyright 2014-2015, Qualcomm Atheros, Inc.
|
||||
- *
|
||||
- * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
|
||||
- */
|
||||
-
|
||||
-#include <linux/kernel.h>
|
||||
-#include <linux/types.h>
|
||||
-#include <linux/err.h>
|
||||
-#include <linux/scatterlist.h>
|
||||
-#include <crypto/aead.h>
|
||||
-
|
||||
-#include "aead_api.h"
|
||||
-
|
||||
-int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
|
||||
- u8 *data, size_t data_len, u8 *mic)
|
||||
-{
|
||||
- size_t mic_len = crypto_aead_authsize(tfm);
|
||||
- struct scatterlist sg[3];
|
||||
- struct aead_request *aead_req;
|
||||
- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
|
||||
- u8 *__aad;
|
||||
- int ret;
|
||||
-
|
||||
- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
|
||||
- if (!aead_req)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- __aad = (u8 *)aead_req + reqsize;
|
||||
- memcpy(__aad, aad, aad_len);
|
||||
-
|
||||
- sg_init_table(sg, 3);
|
||||
- sg_set_buf(&sg[0], __aad, aad_len);
|
||||
- sg_set_buf(&sg[1], data, data_len);
|
||||
- sg_set_buf(&sg[2], mic, mic_len);
|
||||
-
|
||||
- aead_request_set_tfm(aead_req, tfm);
|
||||
- aead_request_set_crypt(aead_req, sg, sg, data_len, b_0);
|
||||
- aead_request_set_ad(aead_req, sg[0].length);
|
||||
-
|
||||
- ret = crypto_aead_encrypt(aead_req);
|
||||
- kfree_sensitive(aead_req);
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
|
||||
- u8 *data, size_t data_len, u8 *mic)
|
||||
-{
|
||||
- size_t mic_len = crypto_aead_authsize(tfm);
|
||||
- struct scatterlist sg[3];
|
||||
- struct aead_request *aead_req;
|
||||
- int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
|
||||
- u8 *__aad;
|
||||
- int err;
|
||||
-
|
||||
- if (data_len == 0)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
|
||||
- if (!aead_req)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- __aad = (u8 *)aead_req + reqsize;
|
||||
- memcpy(__aad, aad, aad_len);
|
||||
-
|
||||
- sg_init_table(sg, 3);
|
||||
- sg_set_buf(&sg[0], __aad, aad_len);
|
||||
- sg_set_buf(&sg[1], data, data_len);
|
||||
- sg_set_buf(&sg[2], mic, mic_len);
|
||||
-
|
||||
- aead_request_set_tfm(aead_req, tfm);
|
||||
- aead_request_set_crypt(aead_req, sg, sg, data_len + mic_len, b_0);
|
||||
- aead_request_set_ad(aead_req, sg[0].length);
|
||||
-
|
||||
- err = crypto_aead_decrypt(aead_req);
|
||||
- kfree_sensitive(aead_req);
|
||||
-
|
||||
- return err;
|
||||
-}
|
||||
-
|
||||
-struct crypto_aead *
|
||||
-aead_key_setup_encrypt(const char *alg, const u8 key[],
|
||||
- size_t key_len, size_t mic_len)
|
||||
-{
|
||||
- struct crypto_aead *tfm;
|
||||
- int err;
|
||||
-
|
||||
- tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC);
|
||||
- if (IS_ERR(tfm))
|
||||
- return tfm;
|
||||
-
|
||||
- err = crypto_aead_setkey(tfm, key, key_len);
|
||||
- if (err)
|
||||
- goto free_aead;
|
||||
- err = crypto_aead_setauthsize(tfm, mic_len);
|
||||
- if (err)
|
||||
- goto free_aead;
|
||||
-
|
||||
- return tfm;
|
||||
-
|
||||
-free_aead:
|
||||
- crypto_free_aead(tfm);
|
||||
- return ERR_PTR(err);
|
||||
-}
|
||||
-
|
||||
-void aead_key_free(struct crypto_aead *tfm)
|
||||
-{
|
||||
- crypto_free_aead(tfm);
|
||||
-}
|
||||
--- a/net/mac80211/aead_api.h
|
||||
+++ /dev/null
|
||||
@@ -1,23 +0,0 @@
|
||||
-/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
-
|
||||
-#ifndef _AEAD_API_H
|
||||
-#define _AEAD_API_H
|
||||
-
|
||||
-#include <crypto/aead.h>
|
||||
-#include <linux/crypto.h>
|
||||
-
|
||||
-struct crypto_aead *
|
||||
-aead_key_setup_encrypt(const char *alg, const u8 key[],
|
||||
- size_t key_len, size_t mic_len);
|
||||
-
|
||||
-int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
|
||||
- size_t aad_len, u8 *data,
|
||||
- size_t data_len, u8 *mic);
|
||||
-
|
||||
-int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
|
||||
- size_t aad_len, u8 *data,
|
||||
- size_t data_len, u8 *mic);
|
||||
-
|
||||
-void aead_key_free(struct crypto_aead *tfm);
|
||||
-
|
||||
-#endif /* _AEAD_API_H */
|
||||
--- a/net/mac80211/aes_ccm.h
|
||||
+++ b/net/mac80211/aes_ccm.h
|
||||
@@ -7,39 +7,17 @@
|
||||
#ifndef AES_CCM_H
|
||||
#define AES_CCM_H
|
||||
|
||||
-#include "aead_api.h"
|
||||
+#include <linux/crypto.h>
|
||||
|
||||
-#define CCM_AAD_LEN 32
|
||||
-
|
||||
-static inline struct crypto_aead *
|
||||
-ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_len)
|
||||
-{
|
||||
- return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len);
|
||||
-}
|
||||
-
|
||||
-static inline int
|
||||
-ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm,
|
||||
- u8 *b_0, u8 *aad, u8 *data,
|
||||
- size_t data_len, u8 *mic)
|
||||
-{
|
||||
- return aead_encrypt(tfm, b_0, aad + 2,
|
||||
- be16_to_cpup((__be16 *)aad),
|
||||
- data, data_len, mic);
|
||||
-}
|
||||
-
|
||||
-static inline int
|
||||
-ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm,
|
||||
- u8 *b_0, u8 *aad, u8 *data,
|
||||
- size_t data_len, u8 *mic)
|
||||
-{
|
||||
- return aead_decrypt(tfm, b_0, aad + 2,
|
||||
- be16_to_cpup((__be16 *)aad),
|
||||
- data, data_len, mic);
|
||||
-}
|
||||
-
|
||||
-static inline void ieee80211_aes_key_free(struct crypto_aead *tfm)
|
||||
-{
|
||||
- return aead_key_free(tfm);
|
||||
-}
|
||||
+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
|
||||
+ size_t key_len,
|
||||
+ size_t mic_len);
|
||||
+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic,
|
||||
+ size_t mic_len);
|
||||
+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic,
|
||||
+ size_t mic_len);
|
||||
+void ieee80211_aes_key_free(struct crypto_cipher *tfm);
|
||||
|
||||
#endif /* AES_CCM_H */
|
||||
--- /dev/null
|
||||
+++ b/net/mac80211/aes_gcm.c
|
||||
@@ -0,0 +1,109 @@
|
||||
+/*
|
||||
+ * Copyright 2014-2015, Qualcomm Atheros, Inc.
|
||||
+ *
|
||||
+ * 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/kernel.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <crypto/aead.h>
|
||||
+
|
||||
+#include <net/mac80211.h>
|
||||
+#include "key.h"
|
||||
+#include "aes_gcm.h"
|
||||
+
|
||||
+int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic)
|
||||
+{
|
||||
+ struct scatterlist sg[3];
|
||||
+ struct aead_request *aead_req;
|
||||
+ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
|
||||
+ u8 *__aad;
|
||||
+
|
||||
+ aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
|
||||
+ if (!aead_req)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ __aad = (u8 *)aead_req + reqsize;
|
||||
+ memcpy(__aad, aad, GCM_AAD_LEN);
|
||||
+
|
||||
+ sg_init_table(sg, 3);
|
||||
+ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
|
||||
+ sg_set_buf(&sg[1], data, data_len);
|
||||
+ sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
|
||||
+
|
||||
+ aead_request_set_tfm(aead_req, tfm);
|
||||
+ aead_request_set_crypt(aead_req, sg, sg, data_len, j_0);
|
||||
+ aead_request_set_ad(aead_req, sg[0].length);
|
||||
+
|
||||
+ crypto_aead_encrypt(aead_req);
|
||||
+ kzfree(aead_req);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic)
|
||||
+{
|
||||
+ struct scatterlist sg[3];
|
||||
+ struct aead_request *aead_req;
|
||||
+ int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
|
||||
+ u8 *__aad;
|
||||
+ int err;
|
||||
+
|
||||
+ if (data_len == 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
|
||||
+ if (!aead_req)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ __aad = (u8 *)aead_req + reqsize;
|
||||
+ memcpy(__aad, aad, GCM_AAD_LEN);
|
||||
+
|
||||
+ sg_init_table(sg, 3);
|
||||
+ sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
|
||||
+ sg_set_buf(&sg[1], data, data_len);
|
||||
+ sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
|
||||
+
|
||||
+ aead_request_set_tfm(aead_req, tfm);
|
||||
+ aead_request_set_crypt(aead_req, sg, sg,
|
||||
+ data_len + IEEE80211_GCMP_MIC_LEN, j_0);
|
||||
+ aead_request_set_ad(aead_req, sg[0].length);
|
||||
+
|
||||
+ err = crypto_aead_decrypt(aead_req);
|
||||
+ kzfree(aead_req);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
|
||||
+ size_t key_len)
|
||||
+{
|
||||
+ struct crypto_aead *tfm;
|
||||
+ int err;
|
||||
+
|
||||
+ tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
|
||||
+ if (IS_ERR(tfm))
|
||||
+ return tfm;
|
||||
+
|
||||
+ err = crypto_aead_setkey(tfm, key, key_len);
|
||||
+ if (err)
|
||||
+ goto free_aead;
|
||||
+ err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN);
|
||||
+ if (err)
|
||||
+ goto free_aead;
|
||||
+
|
||||
+ return tfm;
|
||||
+
|
||||
+free_aead:
|
||||
+ crypto_free_aead(tfm);
|
||||
+ return ERR_PTR(err);
|
||||
+}
|
||||
+
|
||||
+void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
|
||||
+{
|
||||
+ crypto_free_aead(tfm);
|
||||
+}
|
||||
--- a/net/mac80211/aes_gcm.h
|
||||
+++ b/net/mac80211/aes_gcm.h
|
||||
@@ -6,38 +6,30 @@
|
||||
#ifndef AES_GCM_H
|
||||
#define AES_GCM_H
|
||||
|
||||
-#include "aead_api.h"
|
||||
+#include <linux/crypto.h>
|
||||
|
||||
-#define GCM_AAD_LEN 32
|
||||
-
|
||||
-static inline int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm,
|
||||
- u8 *j_0, u8 *aad, u8 *data,
|
||||
- size_t data_len, u8 *mic)
|
||||
+static inline void
|
||||
+ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic)
|
||||
{
|
||||
- return aead_encrypt(tfm, j_0, aad + 2,
|
||||
- be16_to_cpup((__be16 *)aad),
|
||||
- data, data_len, mic);
|
||||
}
|
||||
|
||||
-static inline int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm,
|
||||
- u8 *j_0, u8 *aad, u8 *data,
|
||||
- size_t data_len, u8 *mic)
|
||||
+static inline int
|
||||
+ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic)
|
||||
{
|
||||
- return aead_decrypt(tfm, j_0, aad + 2,
|
||||
- be16_to_cpup((__be16 *)aad),
|
||||
- data, data_len, mic);
|
||||
+ return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline struct crypto_aead *
|
||||
ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len)
|
||||
{
|
||||
- return aead_key_setup_encrypt("gcm(aes)", key,
|
||||
- key_len, IEEE80211_GCMP_MIC_LEN);
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
-static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
|
||||
+static inline void
|
||||
+ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
|
||||
{
|
||||
- return aead_key_free(tfm);
|
||||
}
|
||||
|
||||
#endif /* AES_GCM_H */
|
||||
--- a/net/mac80211/wpa.c
|
||||
+++ b/net/mac80211/wpa.c
|
||||
@@ -312,7 +312,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
|
||||
}
|
||||
|
||||
|
||||
-static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
|
||||
+static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad,
|
||||
+ u16 data_len)
|
||||
{
|
||||
__le16 mask_fc;
|
||||
int a4_included, mgmt;
|
||||
@@ -342,14 +343,8 @@ static void ccmp_special_blocks(struct s
|
||||
else
|
||||
qos_tid = 0;
|
||||
|
||||
- /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
|
||||
- * mode authentication are not allowed to collide, yet both are derived
|
||||
- * from this vector b_0. We only set L := 1 here to indicate that the
|
||||
- * data size can be represented in (L+1) bytes. The CCM layer will take
|
||||
- * care of storing the data length in the top (L+1) bytes and setting
|
||||
- * and clearing the other bits as is required to derive the two IVs.
|
||||
- */
|
||||
- b_0[0] = 0x1;
|
||||
+ /* First block, b_0 */
|
||||
+ b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
|
||||
|
||||
/* Nonce: Nonce Flags | A2 | PN
|
||||
* Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
|
||||
@@ -357,6 +352,8 @@ static void ccmp_special_blocks(struct s
|
||||
b_0[1] = qos_tid | (mgmt << 4);
|
||||
memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
|
||||
memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
|
||||
+ /* l(m) */
|
||||
+ put_unaligned_be16(data_len, &b_0[14]);
|
||||
|
||||
/* AAD (extra authenticate-only data) / masked 802.11 header
|
||||
* FC | A1 | A2 | A3 | SC | [A4] | [QC] */
|
||||
@@ -413,7 +410,7 @@ static int ccmp_encrypt_skb(struct ieee8
|
||||
u8 *pos;
|
||||
u8 pn[6];
|
||||
u64 pn64;
|
||||
- u8 aad[CCM_AAD_LEN];
|
||||
+ u8 aad[2 * AES_BLOCK_SIZE];
|
||||
u8 b_0[AES_BLOCK_SIZE];
|
||||
|
||||
if (info->control.hw_key &&
|
||||
@@ -468,9 +465,11 @@ static int ccmp_encrypt_skb(struct ieee8
|
||||
return 0;
|
||||
|
||||
pos += IEEE80211_CCMP_HDR_LEN;
|
||||
- ccmp_special_blocks(skb, pn, b_0, aad);
|
||||
- return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
|
||||
- skb_put(skb, mic_len));
|
||||
+ ccmp_special_blocks(skb, pn, b_0, aad, len);
|
||||
+ ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
|
||||
+ skb_put(skb, mic_len), mic_len);
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -546,13 +545,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee
|
||||
u8 aad[2 * AES_BLOCK_SIZE];
|
||||
u8 b_0[AES_BLOCK_SIZE];
|
||||
/* hardware didn't decrypt/verify MIC */
|
||||
- ccmp_special_blocks(skb, pn, b_0, aad);
|
||||
+ ccmp_special_blocks(skb, pn, b_0, aad, data_len);
|
||||
|
||||
if (ieee80211_aes_ccm_decrypt(
|
||||
key->u.ccmp.tfm, b_0, aad,
|
||||
skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
|
||||
data_len,
|
||||
- skb->data + skb->len - mic_len))
|
||||
+ skb->data + skb->len - mic_len, mic_len))
|
||||
return RX_DROP_UNUSABLE;
|
||||
}
|
||||
|
||||
@@ -649,7 +648,7 @@ static int gcmp_encrypt_skb(struct ieee8
|
||||
u8 *pos;
|
||||
u8 pn[6];
|
||||
u64 pn64;
|
||||
- u8 aad[GCM_AAD_LEN];
|
||||
+ u8 aad[2 * AES_BLOCK_SIZE];
|
||||
u8 j_0[AES_BLOCK_SIZE];
|
||||
|
||||
if (info->control.hw_key &&
|
||||
@@ -706,8 +705,10 @@ static int gcmp_encrypt_skb(struct ieee8
|
||||
|
||||
pos += IEEE80211_GCMP_HDR_LEN;
|
||||
gcmp_special_blocks(skb, pn, j_0, aad);
|
||||
- return ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len,
|
||||
- skb_put(skb, IEEE80211_GCMP_MIC_LEN));
|
||||
+ ieee80211_aes_gcm_encrypt(key->u.gcmp.tfm, j_0, aad, pos, len,
|
||||
+ skb_put(skb, IEEE80211_GCMP_MIC_LEN));
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
ieee80211_tx_result
|
||||
@@ -1139,9 +1140,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct
|
||||
struct ieee80211_key *key = tx->key;
|
||||
struct ieee80211_mmie_16 *mmie;
|
||||
struct ieee80211_hdr *hdr;
|
||||
- u8 aad[GMAC_AAD_LEN];
|
||||
+ u8 aad[20];
|
||||
u64 pn64;
|
||||
- u8 nonce[GMAC_NONCE_LEN];
|
||||
+ u8 nonce[12];
|
||||
|
||||
if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
|
||||
return TX_DROP;
|
||||
@@ -1187,7 +1188,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct
|
||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||
struct ieee80211_key *key = rx->key;
|
||||
struct ieee80211_mmie_16 *mmie;
|
||||
- u8 aad[GMAC_AAD_LEN], *mic, ipn[6], nonce[GMAC_NONCE_LEN];
|
||||
+ u8 aad[20], *mic, ipn[6], nonce[12];
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
|
||||
if (!ieee80211_is_mgmt(hdr->frame_control))
|
||||
--- /dev/null
|
||||
+++ b/net/mac80211/aes_ccm.c
|
||||
@@ -0,0 +1,144 @@
|
||||
+/*
|
||||
+ * Copyright 2003-2004, Instant802 Networks, Inc.
|
||||
+ * Copyright 2005-2006, Devicescape Software, Inc.
|
||||
+ *
|
||||
+ * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
|
||||
+ *
|
||||
+ * 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/kernel.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/err.h>
|
||||
+#include <crypto/aead.h>
|
||||
+#include <crypto/aes.h>
|
||||
+
|
||||
+#include <net/mac80211.h>
|
||||
+#include "key.h"
|
||||
+#include "aes_ccm.h"
|
||||
+
|
||||
+static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *b_0, u8 *aad, u8 *s_0,
|
||||
+ u8 *a, u8 *b)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ crypto_cipher_encrypt_one(tfm, b, b_0);
|
||||
+
|
||||
+ /* Extra Authenticate-only data (always two AES blocks) */
|
||||
+ for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||
+ aad[i] ^= b[i];
|
||||
+ crypto_cipher_encrypt_one(tfm, b, aad);
|
||||
+
|
||||
+ aad += AES_BLOCK_SIZE;
|
||||
+
|
||||
+ for (i = 0; i < AES_BLOCK_SIZE; i++)
|
||||
+ aad[i] ^= b[i];
|
||||
+ crypto_cipher_encrypt_one(tfm, a, aad);
|
||||
+
|
||||
+ /* Mask out bits from auth-only-b_0 */
|
||||
+ b_0[0] &= 0x07;
|
||||
+
|
||||
+ /* S_0 is used to encrypt T (= MIC) */
|
||||
+ b_0[14] = 0;
|
||||
+ b_0[15] = 0;
|
||||
+ crypto_cipher_encrypt_one(tfm, s_0, b_0);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic,
|
||||
+ size_t mic_len)
|
||||
+{
|
||||
+ int i, j, last_len, num_blocks;
|
||||
+ u8 b[AES_BLOCK_SIZE];
|
||||
+ u8 s_0[AES_BLOCK_SIZE];
|
||||
+ u8 e[AES_BLOCK_SIZE];
|
||||
+ u8 *pos, *cpos;
|
||||
+
|
||||
+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
|
||||
+ last_len = data_len % AES_BLOCK_SIZE;
|
||||
+ aes_ccm_prepare(tfm, b_0, aad, s_0, b, b);
|
||||
+
|
||||
+ /* Process payload blocks */
|
||||
+ pos = data;
|
||||
+ cpos = data;
|
||||
+ for (j = 1; j <= num_blocks; j++) {
|
||||
+ int blen = (j == num_blocks && last_len) ?
|
||||
+ last_len : AES_BLOCK_SIZE;
|
||||
+
|
||||
+ /* Authentication followed by encryption */
|
||||
+ for (i = 0; i < blen; i++)
|
||||
+ b[i] ^= pos[i];
|
||||
+ crypto_cipher_encrypt_one(tfm, b, b);
|
||||
+
|
||||
+ b_0[14] = (j >> 8) & 0xff;
|
||||
+ b_0[15] = j & 0xff;
|
||||
+ crypto_cipher_encrypt_one(tfm, e, b_0);
|
||||
+ for (i = 0; i < blen; i++)
|
||||
+ *cpos++ = *pos++ ^ e[i];
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < mic_len; i++)
|
||||
+ mic[i] = b[i] ^ s_0[i];
|
||||
+}
|
||||
+
|
||||
+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *b_0, u8 *aad,
|
||||
+ u8 *data, size_t data_len, u8 *mic,
|
||||
+ size_t mic_len)
|
||||
+{
|
||||
+ int i, j, last_len, num_blocks;
|
||||
+ u8 *pos, *cpos;
|
||||
+ u8 a[AES_BLOCK_SIZE];
|
||||
+ u8 b[AES_BLOCK_SIZE];
|
||||
+ u8 s_0[AES_BLOCK_SIZE];
|
||||
+
|
||||
+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
|
||||
+ last_len = data_len % AES_BLOCK_SIZE;
|
||||
+ aes_ccm_prepare(tfm, b_0, aad, s_0, a, b);
|
||||
+
|
||||
+ /* Process payload blocks */
|
||||
+ cpos = data;
|
||||
+ pos = data;
|
||||
+ for (j = 1; j <= num_blocks; j++) {
|
||||
+ int blen = (j == num_blocks && last_len) ?
|
||||
+ last_len : AES_BLOCK_SIZE;
|
||||
+
|
||||
+ /* Decryption followed by authentication */
|
||||
+ b_0[14] = (j >> 8) & 0xff;
|
||||
+ b_0[15] = j & 0xff;
|
||||
+ crypto_cipher_encrypt_one(tfm, b, b_0);
|
||||
+ for (i = 0; i < blen; i++) {
|
||||
+ *pos = *cpos++ ^ b[i];
|
||||
+ a[i] ^= *pos++;
|
||||
+ }
|
||||
+ crypto_cipher_encrypt_one(tfm, a, a);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < mic_len; i++) {
|
||||
+ if ((mic[i] ^ s_0[i]) != a[i])
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[],
|
||||
+ size_t key_len,
|
||||
+ size_t mic_len)
|
||||
+{
|
||||
+ struct crypto_cipher *tfm;
|
||||
+
|
||||
+ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
|
||||
+ if (!IS_ERR(tfm))
|
||||
+ crypto_cipher_setkey(tfm, key, key_len);
|
||||
+
|
||||
+ return tfm;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void ieee80211_aes_key_free(struct crypto_cipher *tfm)
|
||||
+{
|
||||
+ crypto_free_cipher(tfm);
|
||||
+}
|
||||
--- a/net/mac80211/Kconfig
|
||||
+++ b/net/mac80211/Kconfig
|
||||
@@ -6,8 +6,6 @@ config MAC80211
|
||||
depends on CRYPTO
|
||||
select BPAUTO_CRYPTO_LIB_ARC4
|
||||
depends on CRYPTO_AES
|
||||
- depends on CRYPTO_CCM
|
||||
- depends on CRYPTO_GCM
|
||||
depends on CRYPTO_CMAC
|
||||
depends on CRC32
|
||||
help
|
||||
--- a/net/mac80211/aes_gmac.h
|
||||
+++ b/net/mac80211/aes_gmac.h
|
||||
@@ -12,10 +12,22 @@
|
||||
#define GMAC_MIC_LEN 16
|
||||
#define GMAC_NONCE_LEN 12
|
||||
|
||||
-struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
|
||||
- size_t key_len);
|
||||
-int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
|
||||
- const u8 *data, size_t data_len, u8 *mic);
|
||||
-void ieee80211_aes_gmac_key_free(struct crypto_aead *tfm);
|
||||
+static inline struct crypto_aead *
|
||||
+ieee80211_aes_gmac_key_setup(const u8 key[], size_t key_len)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static inline int
|
||||
+ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
|
||||
+ const u8 *data, size_t data_len, u8 *mic)
|
||||
+{
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+ieee80211_aes_gmac_key_free(struct crypto_aead *tfm)
|
||||
+{
|
||||
+}
|
||||
|
||||
#endif /* AES_GMAC_H */
|
||||
--- a/net/mac80211/key.h
|
||||
+++ b/net/mac80211/key.h
|
||||
@@ -89,7 +89,7 @@ struct ieee80211_key {
|
||||
* Management frames.
|
||||
*/
|
||||
u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
|
||||
- struct crypto_aead *tfm;
|
||||
+ struct crypto_cipher *tfm;
|
||||
u32 replays; /* dot11RSNAStatsCCMPReplays */
|
||||
} ccmp;
|
||||
struct {
|
@ -1,511 +0,0 @@
|
||||
PKG_DRIVERS += \
|
||||
b43 b43legacy brcmsmac brcmfmac brcmutil
|
||||
|
||||
PKG_CONFIG_DEPENDS += \
|
||||
CONFIG_PACKAGE_B43_DEBUG \
|
||||
CONFIG_PACKAGE_B43_PIO \
|
||||
CONFIG_PACKAGE_B43_PHY_G \
|
||||
CONFIG_PACKAGE_B43_PHY_N \
|
||||
CONFIG_PACKAGE_B43_PHY_LP \
|
||||
CONFIG_PACKAGE_B43_PHY_HT \
|
||||
CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB \
|
||||
CONFIG_PACKAGE_B43_BUSES_BCMA \
|
||||
CONFIG_PACKAGE_B43_BUSES_SSB \
|
||||
CONFIG_PACKAGE_BRCM80211_DEBUG
|
||||
|
||||
config-$(call config_package,b43) += B43
|
||||
config-$(CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB) += B43_BUSES_BCMA_AND_SSB
|
||||
config-$(CONFIG_PACKAGE_B43_BUSES_BCMA) += B43_BUSES_BCMA
|
||||
config-$(CONFIG_PACKAGE_B43_BUSES_SSB) += B43_BUSES_SSB
|
||||
config-$(CONFIG_PACKAGE_B43_PHY_G) += B43_PHY_G
|
||||
config-$(CONFIG_PACKAGE_B43_PHY_N) += B43_PHY_N
|
||||
config-$(CONFIG_PACKAGE_B43_PHY_LP) += B43_PHY_LP
|
||||
config-$(CONFIG_PACKAGE_B43_PHY_HT) += B43_PHY_HT
|
||||
config-$(CONFIG_PACKAGE_B43_PIO) += B43_PIO
|
||||
config-$(CONFIG_PACKAGE_B43_DEBUG) += B43_DEBUG
|
||||
|
||||
config-$(call config_package,b43legacy) += B43LEGACY
|
||||
config-y += B43LEGACY_DMA_MODE
|
||||
|
||||
config-$(call config_package,brcmutil) += BRCMUTIL
|
||||
config-$(call config_package,brcmsmac) += BRCMSMAC
|
||||
config-$(call config_package,brcmfmac) += BRCMFMAC
|
||||
config-$(CONFIG_BRCMFMAC_SDIO) += BRCMFMAC_SDIO
|
||||
config-$(CONFIG_BRCMFMAC_USB) += BRCMFMAC_USB
|
||||
config-$(CONFIG_BRCMFMAC_PCIE) += BRCMFMAC_PCIE
|
||||
config-$(CONFIG_PACKAGE_BRCM80211_DEBUG) += BRCMDBG
|
||||
|
||||
config-$(CONFIG_LEDS_TRIGGERS) += B43_LEDS B43LEGACY_LEDS
|
||||
|
||||
#Broadcom firmware
|
||||
ifneq ($(CONFIG_B43_FW_6_30),)
|
||||
PKG_B43_FWV4_NAME:=broadcom-wl
|
||||
PKG_B43_FWV4_VERSION:=6.30.163.46
|
||||
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).wl_apsta.o
|
||||
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
|
||||
PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/
|
||||
PKG_B43_FWV4_HASH:=a07c3b6b277833c7dbe61daa511f908cd66c5e2763eb7a0859abc36cd9335c2d
|
||||
else
|
||||
ifneq ($(CONFIG_B43_FW_5_10),)
|
||||
PKG_B43_FWV4_NAME:=broadcom-wl
|
||||
PKG_B43_FWV4_VERSION:=5.10.56.27.3
|
||||
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta/wl_prebuilt.o
|
||||
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)_mipsel.tar.bz2
|
||||
PKG_B43_FWV4_SOURCE_URL:=@OPENWRT
|
||||
PKG_B43_FWV4_HASH:=26a8c370f48fc129d0731cfd751c36cae1419b0bc8ca35781126744e60eae009
|
||||
else
|
||||
ifneq ($(CONFIG_B43_FW_4_178),)
|
||||
PKG_B43_FWV4_NAME:=broadcom-wl
|
||||
PKG_B43_FWV4_VERSION:=4.178.10.4
|
||||
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o
|
||||
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
|
||||
PKG_B43_FWV4_SOURCE_URL:=@OPENWRT
|
||||
PKG_B43_FWV4_HASH:=32f6ad98facbb9045646fdc8b54bb03086d204153253f9c65d0234a5d90ae53f
|
||||
else
|
||||
ifneq ($(CONFIG_B43_FW_5_100_138),)
|
||||
PKG_B43_FWV4_NAME:=broadcom-wl
|
||||
PKG_B43_FWV4_VERSION:=5.100.138
|
||||
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o
|
||||
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
|
||||
PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/
|
||||
PKG_B43_FWV4_HASH:=f1e7067aac5b62b67b8b6e4c517990277804339ac16065eb13c731ff909ae46f
|
||||
else
|
||||
PKG_B43_FWV4_NAME:=broadcom-wl
|
||||
PKG_B43_FWV4_VERSION:=4.150.10.5
|
||||
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta_mimo.o
|
||||
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
|
||||
PKG_B43_FWV4_SOURCE_URL:=@OPENWRT
|
||||
PKG_B43_FWV4_HASH:=a9f4e276a4d8d3a1cd0f2eb87080ae89b77f0a7140f06d4e9e2135fc44fdd533
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifneq ($(CONFIG_B43_OPENFIRMWARE),)
|
||||
PKG_B43_FWV4_NAME:=broadcom-wl
|
||||
PKG_B43_FWV4_VERSION:=5.2
|
||||
PKG_B43_FWV4_OBJECT:=openfwwf-$(PKG_B43_FWV4_VERSION)
|
||||
PKG_B43_FWV4_SOURCE:=openfwwf-$(PKG_B43_FWV4_VERSION).tar.gz
|
||||
PKG_B43_FWV4_SOURCE_URL:=http://netweb.ing.unibs.it/~openfwwf/firmware
|
||||
PKG_B43_FWV4_HASH:=9de03320083201080b2e94b81637ac07a159cf4e6f3481383e1a217e627bc0dc
|
||||
endif
|
||||
|
||||
|
||||
define Download/b43
|
||||
FILE:=$(PKG_B43_FWV4_SOURCE)
|
||||
URL:=$(PKG_B43_FWV4_SOURCE_URL)
|
||||
HASH:=$(PKG_B43_FWV4_HASH)
|
||||
endef
|
||||
$(eval $(call Download,b43))
|
||||
|
||||
define KernelPackage/b43
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Broadcom 43xx wireless support
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/b43
|
||||
KCONFIG:= \
|
||||
CONFIG_HW_RANDOM=y
|
||||
# Depend on PCI_SUPPORT to make sure we can select kmod-bcma or kmod-ssb
|
||||
DEPENDS += \
|
||||
@PCI_SUPPORT +kmod-mac80211 +kmod-lib-cordic \
|
||||
$(if $(CONFIG_PACKAGE_B43_USE_SSB),+kmod-ssb) \
|
||||
$(if $(CONFIG_PACKAGE_B43_USE_BCMA),+kmod-bcma)
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/b43/b43.ko
|
||||
AUTOLOAD:=$(call AutoProbe,b43)
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/b43/config
|
||||
|
||||
config PACKAGE_B43_USE_SSB
|
||||
select PACKAGE_kmod-ssb
|
||||
tristate
|
||||
depends on !TARGET_bcm47xx && !TARGET_bcm63xx
|
||||
default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB
|
||||
default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_SSB
|
||||
|
||||
config PACKAGE_B43_USE_BCMA
|
||||
select PACKAGE_kmod-bcma
|
||||
tristate
|
||||
depends on !TARGET_bcm47xx && !TARGET_bcm53xx
|
||||
default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB
|
||||
default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA
|
||||
|
||||
if PACKAGE_kmod-b43
|
||||
|
||||
choice
|
||||
prompt "b43 firmware version"
|
||||
default B43_FW_5_100_138
|
||||
help
|
||||
This option allows you to select the version of the b43 firmware.
|
||||
|
||||
config B43_FW_4_150
|
||||
bool "Firmware 410.2160 from driver 4.150.10.5 (old stable)"
|
||||
help
|
||||
Old stable firmware for BCM43xx devices.
|
||||
|
||||
If unsure, select this.
|
||||
|
||||
config B43_FW_4_178
|
||||
bool "Firmware 478.104 from driver 4.178.10.4"
|
||||
help
|
||||
Older firmware for BCM43xx devices.
|
||||
|
||||
If unsure, select the "stable" firmware.
|
||||
|
||||
config B43_FW_5_10
|
||||
bool "Firmware 508.1084 from driver 5.10.56.27"
|
||||
help
|
||||
Older firmware for BCM43xx devices.
|
||||
|
||||
If unsure, select the "stable" firmware.
|
||||
|
||||
config B43_FW_5_100_138
|
||||
bool "Firmware 666.2 from driver 5.100.138 (stable)"
|
||||
help
|
||||
The currently default firmware for BCM43xx devices.
|
||||
|
||||
This firmware currently gets most of the testing and is needed for some N-PHY devices.
|
||||
|
||||
If unsure, select the this firmware.
|
||||
|
||||
config B43_FW_6_30
|
||||
bool "Firmware 784.2 from driver 6.30.163.46 (experimental)"
|
||||
help
|
||||
Newer experimental firmware for BCM43xx devices.
|
||||
|
||||
This firmware is mostly untested.
|
||||
|
||||
If unsure, select the "stable" firmware.
|
||||
|
||||
config B43_OPENFIRMWARE
|
||||
bool "Open FirmWare for WiFi networks"
|
||||
help
|
||||
Opensource firmware for BCM43xx devices.
|
||||
|
||||
Do _not_ select this, unless you know what you are doing.
|
||||
The Opensource firmware is not suitable for embedded devices, yet.
|
||||
It does not support QoS, which is bad for AccessPoints.
|
||||
It does not support hardware crypto acceleration, which is a showstopper
|
||||
for embedded devices with low CPU resources.
|
||||
|
||||
If unsure, select the "stable" firmware.
|
||||
|
||||
endchoice
|
||||
|
||||
config B43_FW_SQUASH
|
||||
bool "Remove unnecessary firmware files"
|
||||
depends on !B43_OPENFIRMWARE
|
||||
default y
|
||||
help
|
||||
This options allows you to remove unnecessary b43 firmware files
|
||||
from the final rootfs image. This can reduce the rootfs size by
|
||||
up to 200k.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config B43_FW_SQUASH_COREREVS
|
||||
string "Core revisions to include"
|
||||
depends on B43_FW_SQUASH
|
||||
default "5,6,7,8,9,10,11,13,15" if TARGET_bcm47xx_legacy
|
||||
default "16,28,29,30" if TARGET_bcm47xx_mips74k
|
||||
default "5,6,7,8,9,10,11,13,15,16,28,29,30"
|
||||
help
|
||||
This is a comma seperated list of core revision numbers.
|
||||
|
||||
Example (keep files for rev5 only):
|
||||
5
|
||||
|
||||
Example (keep files for rev5 and rev11):
|
||||
5,11
|
||||
|
||||
config B43_FW_SQUASH_PHYTYPES
|
||||
string "PHY types to include"
|
||||
depends on B43_FW_SQUASH
|
||||
default "G,N,LP" if TARGET_bcm47xx_legacy
|
||||
default "N,HT" if TARGET_bcm47xx_mips74k
|
||||
default "G,N,LP,HT"
|
||||
help
|
||||
This is a comma seperated list of PHY types:
|
||||
A => A-PHY
|
||||
AG => Dual A-PHY G-PHY
|
||||
G => G-PHY
|
||||
LP => LP-PHY
|
||||
N => N-PHY
|
||||
HT => HT-PHY
|
||||
LCN => LCN-PHY
|
||||
LCN40 => LCN40-PHY
|
||||
AC => AC-PHY
|
||||
|
||||
Example (keep files for G-PHY only):
|
||||
G
|
||||
|
||||
Example (keep files for G-PHY and N-PHY):
|
||||
G,N
|
||||
|
||||
choice
|
||||
prompt "Supported buses"
|
||||
default PACKAGE_B43_BUSES_BCMA_AND_SSB
|
||||
help
|
||||
This allows choosing buses that b43 should support.
|
||||
|
||||
config PACKAGE_B43_BUSES_BCMA_AND_SSB
|
||||
depends on !TARGET_bcm47xx_legacy && !TARGET_bcm47xx_mips74k && !TARGET_bcm53xx
|
||||
bool "BCMA and SSB"
|
||||
|
||||
config PACKAGE_B43_BUSES_BCMA
|
||||
depends on !TARGET_bcm47xx_legacy
|
||||
bool "BCMA only"
|
||||
|
||||
config PACKAGE_B43_BUSES_SSB
|
||||
depends on !TARGET_bcm47xx_mips74k && !TARGET_bcm53xx
|
||||
bool "SSB only"
|
||||
|
||||
endchoice
|
||||
|
||||
config PACKAGE_B43_DEBUG
|
||||
bool "Enable debug output and debugfs for b43"
|
||||
default n
|
||||
help
|
||||
Enable additional debug output and runtime sanity checks for b43
|
||||
and enables the debugfs interface.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PACKAGE_B43_PIO
|
||||
bool "Enable support for PIO transfer mode"
|
||||
default n
|
||||
help
|
||||
Enable support for using PIO instead of DMA. Unless you have DMA
|
||||
transfer problems you don't need this.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PACKAGE_B43_PHY_G
|
||||
bool "Enable support for G-PHYs"
|
||||
default n if TARGET_bcm47xx_mips74k
|
||||
default y
|
||||
help
|
||||
Enable support for G-PHY. This includes support for the following devices:
|
||||
PCI: BCM4306, BCM4311, BCM4318
|
||||
SoC: BCM5352E, BCM4712
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config PACKAGE_B43_PHY_N
|
||||
bool "Enable support for N-PHYs"
|
||||
default y
|
||||
help
|
||||
Enable support for N-PHY. This includes support for the following devices:
|
||||
PCI: BCM4321, BCM4322, BCM43222, BCM43224, BCM43225
|
||||
SoC: BCM4716, BCM4717, BCM4718
|
||||
|
||||
Currently only 11g speed is available.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config PACKAGE_B43_PHY_LP
|
||||
bool "Enable support for LP-PHYs"
|
||||
default n if TARGET_bcm47xx_mips74k
|
||||
default y
|
||||
help
|
||||
Enable support for LP-PHY. This includes support for the following devices:
|
||||
PCI: BCM4312
|
||||
SoC: BCM5354
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config PACKAGE_B43_PHY_HT
|
||||
bool "Enable support for HT-PHYs"
|
||||
default n if TARGET_bcm47xx_legacy
|
||||
default y
|
||||
help
|
||||
Enable support for HT-PHY. This includes support for the following devices:
|
||||
PCI: BCM4331
|
||||
|
||||
Currently only 11g speed is available.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config PACKAGE_B43_PHY_LCN
|
||||
bool "Enable support for LCN-PHYs"
|
||||
depends on BROKEN
|
||||
default n
|
||||
help
|
||||
Currently broken.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
endif
|
||||
endef
|
||||
|
||||
define KernelPackage/b43/description
|
||||
Kernel module for Broadcom 43xx wireless support (mac80211 stack) new
|
||||
endef
|
||||
|
||||
define KernelPackage/b43legacy
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Broadcom 43xx-legacy wireless support
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/b43
|
||||
KCONFIG:= \
|
||||
CONFIG_HW_RANDOM=y
|
||||
DEPENDS+= +kmod-mac80211 +!(TARGET_bcm47xx||TARGET_bcm63xx):kmod-ssb @!TARGET_bcm47xx_mips74k +b43legacy-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/b43legacy/b43legacy.ko
|
||||
AUTOLOAD:=$(call AutoProbe,b43legacy)
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/b43legacy/description
|
||||
Kernel module for Broadcom 43xx-legacy wireless support (mac80211 stack) new
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/brcmutil
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Broadcom IEEE802.11n common driver parts
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211
|
||||
DEPENDS+=@PCI_SUPPORT||USB_SUPPORT
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmutil/brcmutil.ko
|
||||
AUTOLOAD:=$(call AutoProbe,brcmutil)
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmutil/description
|
||||
This module contains some common parts needed by Broadcom Wireless drivers brcmsmac and brcmfmac.
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmutil/config
|
||||
if PACKAGE_kmod-brcmutil
|
||||
|
||||
config PACKAGE_BRCM80211_DEBUG
|
||||
bool "Broadcom wireless driver debugging"
|
||||
help
|
||||
Say Y, if you want to debug brcmsmac and brcmfmac wireless driver.
|
||||
|
||||
endif
|
||||
endef
|
||||
|
||||
PKG_BRCMSMAC_FW_NAME:=broadcom-wl
|
||||
PKG_BRCMSMAC_FW_VERSION:=5.100.138
|
||||
PKG_BRCMSMAC_FW_OBJECT:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION)/linux/wl_apsta.o
|
||||
PKG_BRCMSMAC_FW_SOURCE:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION).tar.bz2
|
||||
PKG_BRCMSMAC_FW_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/
|
||||
PKG_BRCMSMAC_FW_HASH:=f1e7067aac5b62b67b8b6e4c517990277804339ac16065eb13c731ff909ae46f
|
||||
|
||||
define Download/brcmsmac
|
||||
FILE:=$(PKG_BRCMSMAC_FW_SOURCE)
|
||||
URL:=$(PKG_BRCMSMAC_FW_SOURCE_URL)
|
||||
HASH:=$(PKG_BRCMSMAC_FW_HASH)
|
||||
endef
|
||||
$(eval $(call Download,brcmsmac))
|
||||
|
||||
define KernelPackage/brcmsmac
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Broadcom IEEE802.11n PCIe SoftMAC WLAN driver
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211
|
||||
DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT +!TARGET_bcm47xx:kmod-bcma +kmod-lib-cordic +kmod-lib-crc8 +kmod-brcmutil +!BRCMSMAC_USE_FW_FROM_WL:brcmsmac-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcmsmac.ko
|
||||
AUTOLOAD:=$(call AutoProbe,brcmsmac)
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmsmac/description
|
||||
Kernel module for Broadcom IEEE802.11n PCIe Wireless cards
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmsmac/config
|
||||
if PACKAGE_kmod-brcmsmac
|
||||
|
||||
config BRCMSMAC_USE_FW_FROM_WL
|
||||
bool "Use firmware extracted from broadcom proprietary driver"
|
||||
default y
|
||||
help
|
||||
Instead of using the official brcmsmac firmware a firmware
|
||||
version 666.2 extracted from the proprietary Broadcom driver
|
||||
is used. This is needed to get core rev 17 used in bcm4716
|
||||
to work.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
endif
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/brcmfmac
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Broadcom IEEE802.11n USB FullMAC WLAN driver
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211
|
||||
DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT \
|
||||
+kmod-brcmutil +BRCMFMAC_SDIO:kmod-mmc @!TARGET_uml \
|
||||
+BRCMFMAC_USB:kmod-usb-core +BRCMFMAC_USB:brcmfmac-firmware-usb
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko
|
||||
AUTOLOAD:=$(call AutoProbe,brcmfmac)
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmfmac/description
|
||||
Kernel module for Broadcom IEEE802.11n USB Wireless cards
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmfmac/config
|
||||
if PACKAGE_kmod-brcmfmac
|
||||
|
||||
config BRCMFMAC_SDIO
|
||||
bool "Enable SDIO bus interface support"
|
||||
default y if TARGET_bcm27xx
|
||||
default y if TARGET_rockchip
|
||||
default y if TARGET_sunxi
|
||||
default n
|
||||
help
|
||||
Enable support for cards attached to an SDIO bus.
|
||||
Select this option only if you are sure that your
|
||||
board has a Broadcom wireless chip atacched to
|
||||
that bus.
|
||||
|
||||
config BRCMFMAC_USB
|
||||
bool "Enable USB bus interface support"
|
||||
depends on USB_SUPPORT
|
||||
default y
|
||||
help
|
||||
Supported USB connected chipsets:
|
||||
BCM43235, BCM43236, BCM43238 (all in revision 3 only)
|
||||
BCM43143, BCM43242, BCM43566, BCM43569
|
||||
|
||||
config BRCMFMAC_PCIE
|
||||
bool "Enable PCIE bus interface support"
|
||||
depends on PCI_SUPPORT
|
||||
default y
|
||||
help
|
||||
Supported PCIe connected chipsets:
|
||||
BCM4354, BCM4356, BCM43567, BCM43570, BCM43602
|
||||
|
||||
endif
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/b43/install
|
||||
rm -rf $(1)/lib/firmware/
|
||||
ifeq ($(CONFIG_B43_OPENFIRMWARE),y)
|
||||
tar xzf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)"
|
||||
else
|
||||
tar xjf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)"
|
||||
endif
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/
|
||||
ifeq ($(CONFIG_B43_OPENFIRMWARE),y)
|
||||
$(MAKE) -C "$(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/"
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/b43-open/
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/ucode5.fw $(1)/lib/firmware/b43-open/ucode5.fw
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0bsinitvals5.fw $(1)/lib/firmware/b43-open/b0g0bsinitvals5.fw
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0initvals5.fw $(1)/lib/firmware/b43-open/b0g0initvals5.fw
|
||||
else
|
||||
b43-fwcutter -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)
|
||||
endif
|
||||
ifneq ($(CONFIG_B43_FW_SQUASH),)
|
||||
b43-fwsquash.py "$(CONFIG_B43_FW_SQUASH_PHYTYPES)" "$(CONFIG_B43_FW_SQUASH_COREREVS)" "$(1)/lib/firmware/b43"
|
||||
endif
|
||||
endef
|
||||
|
||||
define KernelPackage/brcmsmac/install
|
||||
$(INSTALL_DIR) $(1)/lib/firmware/brcm
|
||||
ifeq ($(CONFIG_BRCMSMAC_USE_FW_FROM_WL),y)
|
||||
tar xjf "$(DL_DIR)/$(PKG_BRCMSMAC_FW_SOURCE)" -C "$(PKG_BUILD_DIR)"
|
||||
b43-fwcutter --brcmsmac -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_BRCMSMAC_FW_OBJECT)
|
||||
endif
|
||||
endef
|
@ -1,62 +0,0 @@
|
||||
From: Xing Song <xing.song@mediatek.com>
|
||||
Date: Tue, 23 Nov 2021 11:31:23 +0800
|
||||
Subject: [PATCH] mac80211: set up the fwd_skb->dev for mesh forwarding
|
||||
|
||||
Mesh forwarding requires that the fwd_skb->dev is set up for TX handling,
|
||||
otherwise the following warning will be generated, so set it up for the
|
||||
pending frames.
|
||||
|
||||
[ 72.835674 ] WARNING: CPU: 0 PID: 1193 at __skb_flow_dissect+0x284/0x1298
|
||||
[ 72.842379 ] Modules linked in: ksmbd pppoe ppp_async l2tp_ppp ...
|
||||
[ 72.962020 ] CPU: 0 PID: 1193 Comm: kworker/u5:1 Tainted: P S 5.4.137 #0
|
||||
[ 72.969938 ] Hardware name: MT7622_MT7531 RFB (DT)
|
||||
[ 72.974659 ] Workqueue: napi_workq napi_workfn
|
||||
[ 72.979025 ] pstate: 60000005 (nZCv daif -PAN -UAO)
|
||||
[ 72.983822 ] pc : __skb_flow_dissect+0x284/0x1298
|
||||
[ 72.988444 ] lr : __skb_flow_dissect+0x54/0x1298
|
||||
[ 72.992977 ] sp : ffffffc010c738c0
|
||||
[ 72.996293 ] x29: ffffffc010c738c0 x28: 0000000000000000
|
||||
[ 73.001615 ] x27: 000000000000ffc2 x26: ffffff800c2eb818
|
||||
[ 73.006937 ] x25: ffffffc010a987c8 x24: 00000000000000ce
|
||||
[ 73.012259 ] x23: ffffffc010c73a28 x22: ffffffc010a99c60
|
||||
[ 73.017581 ] x21: 000000000000ffc2 x20: ffffff80094da800
|
||||
[ 73.022903 ] x19: 0000000000000000 x18: 0000000000000014
|
||||
[ 73.028226 ] x17: 00000000084d16af x16: 00000000d1fc0bab
|
||||
[ 73.033548 ] x15: 00000000715f6034 x14: 000000009dbdd301
|
||||
[ 73.038870 ] x13: 00000000ea4dcbc3 x12: 0000000000000040
|
||||
[ 73.044192 ] x11: 000000000eb00ff0 x10: 0000000000000000
|
||||
[ 73.049513 ] x9 : 000000000eb00073 x8 : 0000000000000088
|
||||
[ 73.054834 ] x7 : 0000000000000000 x6 : 0000000000000001
|
||||
[ 73.060155 ] x5 : 0000000000000000 x4 : 0000000000000000
|
||||
[ 73.065476 ] x3 : ffffffc010a98000 x2 : 0000000000000000
|
||||
[ 73.070797 ] x1 : 0000000000000000 x0 : 0000000000000000
|
||||
[ 73.076120 ] Call trace:
|
||||
[ 73.078572 ] __skb_flow_dissect+0x284/0x1298
|
||||
[ 73.082846 ] __skb_get_hash+0x7c/0x228
|
||||
[ 73.086629 ] ieee80211_txq_may_transmit+0x7fc/0x17b8 [mac80211]
|
||||
[ 73.092564 ] ieee80211_tx_prepare_skb+0x20c/0x268 [mac80211]
|
||||
[ 73.098238 ] ieee80211_tx_pending+0x144/0x330 [mac80211]
|
||||
[ 73.103560 ] tasklet_action_common.isra.16+0xb4/0x158
|
||||
[ 73.108618 ] tasklet_action+0x2c/0x38
|
||||
[ 73.112286 ] __do_softirq+0x168/0x3b0
|
||||
[ 73.115954 ] do_softirq.part.15+0x88/0x98
|
||||
[ 73.119969 ] __local_bh_enable_ip+0xb0/0xb8
|
||||
[ 73.124156 ] napi_workfn+0x58/0x90
|
||||
[ 73.127565 ] process_one_work+0x20c/0x478
|
||||
[ 73.131579 ] worker_thread+0x50/0x4f0
|
||||
[ 73.135249 ] kthread+0x124/0x128
|
||||
[ 73.138484 ] ret_from_fork+0x10/0x1c
|
||||
|
||||
Signed-off-by: Xing Song <xing.song@mediatek.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2941,6 +2941,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
|
||||
if (!fwd_skb)
|
||||
goto out;
|
||||
|
||||
+ fwd_skb->dev = sdata->dev;
|
||||
fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data;
|
||||
fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY);
|
||||
info = IEEE80211_SKB_CB(fwd_skb);
|
@ -1,279 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 23 Jan 2021 07:18:26 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: remove sample rate switching code for
|
||||
constrained devices
|
||||
|
||||
This was added to mitigate the effects of too much sampling on devices that
|
||||
use a static global fallback table instead of configurable multi-rate retry.
|
||||
Now that the sampling algorithm is improved, this code path no longer performs
|
||||
any better than the standard probing on affected devices.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -648,27 +648,6 @@ __minstrel_ht_get_sample_rate(struct min
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void
|
||||
-minstrel_ht_rate_sample_switch(struct minstrel_priv *mp,
|
||||
- struct minstrel_ht_sta *mi)
|
||||
-{
|
||||
- u16 rate;
|
||||
-
|
||||
- /*
|
||||
- * Use rate switching instead of probing packets for devices with
|
||||
- * little control over retry fallback behavior
|
||||
- */
|
||||
- if (mp->hw->max_rates > 1)
|
||||
- return;
|
||||
-
|
||||
- rate = __minstrel_ht_get_sample_rate(mi, MINSTREL_SAMPLE_TYPE_INC);
|
||||
- if (!rate)
|
||||
- return;
|
||||
-
|
||||
- mi->sample_rate = rate;
|
||||
- mi->sample_mode = MINSTREL_SAMPLE_ACTIVE;
|
||||
-}
|
||||
-
|
||||
static inline int
|
||||
minstrel_ewma(int old, int new, int weight)
|
||||
{
|
||||
@@ -1012,8 +991,7 @@ minstrel_ht_refill_sample_rates(struct m
|
||||
* higher throughput rates, even if the probablity is a bit lower
|
||||
*/
|
||||
static void
|
||||
-minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
|
||||
- bool sample)
|
||||
+minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
|
||||
{
|
||||
struct minstrel_mcs_group_data *mg;
|
||||
struct minstrel_rate_stats *mrs;
|
||||
@@ -1023,18 +1001,6 @@ minstrel_ht_update_stats(struct minstrel
|
||||
u16 index;
|
||||
bool ht_supported = mi->sta->ht_cap.ht_supported;
|
||||
|
||||
- mi->sample_mode = MINSTREL_SAMPLE_IDLE;
|
||||
-
|
||||
- if (sample) {
|
||||
- mi->total_packets_cur = mi->total_packets -
|
||||
- mi->total_packets_last;
|
||||
- mi->total_packets_last = mi->total_packets;
|
||||
- }
|
||||
- if (!mp->sample_switch)
|
||||
- sample = false;
|
||||
- if (mi->total_packets_cur < SAMPLE_SWITCH_THR && mp->sample_switch != 1)
|
||||
- sample = false;
|
||||
-
|
||||
if (mi->ampdu_packets > 0) {
|
||||
if (!ieee80211_hw_check(mp->hw, TX_STATUS_NO_AMPDU_LEN))
|
||||
mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len,
|
||||
@@ -1148,16 +1114,12 @@ minstrel_ht_update_stats(struct minstrel
|
||||
minstrel_ht_prob_rate_reduce_streams(mi);
|
||||
minstrel_ht_refill_sample_rates(mi);
|
||||
|
||||
- if (sample)
|
||||
- minstrel_ht_rate_sample_switch(mp, mi);
|
||||
-
|
||||
#ifdef CPTCFG_MAC80211_DEBUGFS
|
||||
/* use fixed index if set */
|
||||
if (mp->fixed_rate_idx != -1) {
|
||||
for (i = 0; i < 4; i++)
|
||||
mi->max_tp_rate[i] = mp->fixed_rate_idx;
|
||||
mi->max_prob_rate = mp->fixed_rate_idx;
|
||||
- mi->sample_mode = MINSTREL_SAMPLE_IDLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1247,11 +1209,10 @@ minstrel_ht_tx_status(void *priv, struct
|
||||
struct ieee80211_tx_info *info = st->info;
|
||||
struct minstrel_ht_sta *mi = priv_sta;
|
||||
struct ieee80211_tx_rate *ar = info->status.rates;
|
||||
- struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL;
|
||||
+ struct minstrel_rate_stats *rate, *rate2;
|
||||
struct minstrel_priv *mp = priv;
|
||||
u32 update_interval = mp->update_interval;
|
||||
bool last, update = false;
|
||||
- bool sample_status = false;
|
||||
int i;
|
||||
|
||||
/* This packet was aggregated but doesn't carry status info */
|
||||
@@ -1278,49 +1239,18 @@ minstrel_ht_tx_status(void *priv, struct
|
||||
mi->ampdu_packets++;
|
||||
mi->ampdu_len += info->status.ampdu_len;
|
||||
|
||||
- if (mi->sample_mode != MINSTREL_SAMPLE_IDLE)
|
||||
- rate_sample = minstrel_get_ratestats(mi, mi->sample_rate);
|
||||
-
|
||||
last = !minstrel_ht_txstat_valid(mp, mi, &ar[0]);
|
||||
for (i = 0; !last; i++) {
|
||||
last = (i == IEEE80211_TX_MAX_RATES - 1) ||
|
||||
!minstrel_ht_txstat_valid(mp, mi, &ar[i + 1]);
|
||||
|
||||
rate = minstrel_ht_get_stats(mp, mi, &ar[i]);
|
||||
- if (rate == rate_sample)
|
||||
- sample_status = true;
|
||||
-
|
||||
if (last)
|
||||
rate->success += info->status.ampdu_ack_len;
|
||||
|
||||
rate->attempts += ar[i].count * info->status.ampdu_len;
|
||||
}
|
||||
|
||||
- switch (mi->sample_mode) {
|
||||
- case MINSTREL_SAMPLE_IDLE:
|
||||
- if (mp->hw->max_rates > 1 ||
|
||||
- mi->total_packets_cur < SAMPLE_SWITCH_THR)
|
||||
- update_interval /= 2;
|
||||
- break;
|
||||
-
|
||||
- case MINSTREL_SAMPLE_ACTIVE:
|
||||
- if (!sample_status)
|
||||
- break;
|
||||
-
|
||||
- mi->sample_mode = MINSTREL_SAMPLE_PENDING;
|
||||
- update = true;
|
||||
- break;
|
||||
-
|
||||
- case MINSTREL_SAMPLE_PENDING:
|
||||
- if (sample_status)
|
||||
- break;
|
||||
-
|
||||
- update = true;
|
||||
- minstrel_ht_update_stats(mp, mi, false);
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
-
|
||||
if (mp->hw->max_rates > 1) {
|
||||
/*
|
||||
* check for sudden death of spatial multiplexing,
|
||||
@@ -1343,7 +1273,7 @@ minstrel_ht_tx_status(void *priv, struct
|
||||
|
||||
if (time_after(jiffies, mi->last_stats_update + update_interval)) {
|
||||
update = true;
|
||||
- minstrel_ht_update_stats(mp, mi, true);
|
||||
+ minstrel_ht_update_stats(mp, mi);
|
||||
}
|
||||
|
||||
if (update)
|
||||
@@ -1522,18 +1452,14 @@ static void
|
||||
minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
|
||||
{
|
||||
struct ieee80211_sta_rates *rates;
|
||||
- u16 first_rate = mi->max_tp_rate[0];
|
||||
int i = 0;
|
||||
|
||||
- if (mi->sample_mode == MINSTREL_SAMPLE_ACTIVE)
|
||||
- first_rate = mi->sample_rate;
|
||||
-
|
||||
rates = kzalloc(sizeof(*rates), GFP_ATOMIC);
|
||||
if (!rates)
|
||||
return;
|
||||
|
||||
/* Start with max_tp_rate[0] */
|
||||
- minstrel_ht_set_rate(mp, mi, rates, i++, first_rate);
|
||||
+ minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[0]);
|
||||
|
||||
if (mp->hw->max_rates >= 3) {
|
||||
/* At least 3 tx rates supported, use max_tp_rate[1] next */
|
||||
@@ -1592,11 +1518,6 @@ minstrel_ht_get_rate(void *priv, struct
|
||||
(info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO))
|
||||
return;
|
||||
|
||||
- if (mp->hw->max_rates == 1 && mp->sample_switch &&
|
||||
- (mi->total_packets_cur >= SAMPLE_SWITCH_THR ||
|
||||
- mp->sample_switch == 1))
|
||||
- return;
|
||||
-
|
||||
if (time_is_before_jiffies(mi->sample_time))
|
||||
return;
|
||||
|
||||
@@ -1810,7 +1731,7 @@ minstrel_ht_update_caps(void *priv, stru
|
||||
minstrel_ht_update_ofdm(mp, mi, sband, sta);
|
||||
|
||||
/* create an initial rate table with the lowest supported rates */
|
||||
- minstrel_ht_update_stats(mp, mi, true);
|
||||
+ minstrel_ht_update_stats(mp, mi);
|
||||
minstrel_ht_update_rates(mp, mi);
|
||||
}
|
||||
|
||||
@@ -1926,8 +1847,6 @@ minstrel_ht_alloc(struct ieee80211_hw *h
|
||||
if (!mp)
|
||||
return NULL;
|
||||
|
||||
- mp->sample_switch = -1;
|
||||
-
|
||||
/* contention window settings
|
||||
* Just an approximation. Using the per-queue values would complicate
|
||||
* the calculations and is probably unnecessary */
|
||||
@@ -1947,7 +1866,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h
|
||||
mp->has_mrr = true;
|
||||
|
||||
mp->hw = hw;
|
||||
- mp->update_interval = HZ / 10;
|
||||
+ mp->update_interval = HZ / 20;
|
||||
|
||||
minstrel_ht_init_cck_rates(mp);
|
||||
for (i = 0; i < ARRAY_SIZE(mp->hw->wiphy->bands); i++)
|
||||
@@ -1965,8 +1884,6 @@ static void minstrel_ht_add_debugfs(stru
|
||||
mp->fixed_rate_idx = (u32) -1;
|
||||
debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir,
|
||||
&mp->fixed_rate_idx);
|
||||
- debugfs_create_u32("sample_switch", S_IRUGO | S_IWUSR, debugfsdir,
|
||||
- &mp->sample_switch);
|
||||
}
|
||||
#endif
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.h
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.h
|
||||
@@ -75,7 +75,6 @@
|
||||
struct minstrel_priv {
|
||||
struct ieee80211_hw *hw;
|
||||
bool has_mrr;
|
||||
- u32 sample_switch;
|
||||
unsigned int cw_min;
|
||||
unsigned int cw_max;
|
||||
unsigned int max_retry;
|
||||
@@ -147,12 +146,6 @@ struct minstrel_mcs_group_data {
|
||||
struct minstrel_rate_stats rates[MCS_GROUP_RATES];
|
||||
};
|
||||
|
||||
-enum minstrel_sample_mode {
|
||||
- MINSTREL_SAMPLE_IDLE,
|
||||
- MINSTREL_SAMPLE_ACTIVE,
|
||||
- MINSTREL_SAMPLE_PENDING,
|
||||
-};
|
||||
-
|
||||
struct minstrel_sample_category {
|
||||
u8 sample_group;
|
||||
u16 sample_rates[MINSTREL_SAMPLE_RATES];
|
||||
@@ -182,23 +175,19 @@ struct minstrel_ht_sta {
|
||||
unsigned int overhead_legacy;
|
||||
unsigned int overhead_legacy_rtscts;
|
||||
|
||||
- unsigned int total_packets_last;
|
||||
- unsigned int total_packets_cur;
|
||||
unsigned int total_packets;
|
||||
unsigned int sample_packets;
|
||||
|
||||
/* tx flags to add for frames for this sta */
|
||||
u32 tx_flags;
|
||||
|
||||
- unsigned long sample_time;
|
||||
- struct minstrel_sample_category sample[__MINSTREL_SAMPLE_TYPE_MAX];
|
||||
+ u8 band;
|
||||
|
||||
u8 sample_seq;
|
||||
-
|
||||
- enum minstrel_sample_mode sample_mode;
|
||||
u16 sample_rate;
|
||||
|
||||
- u8 band;
|
||||
+ unsigned long sample_time;
|
||||
+ struct minstrel_sample_category sample[__MINSTREL_SAMPLE_TYPE_MAX];
|
||||
|
||||
/* Bitfield of supported MCS rates of all groups */
|
||||
u16 supported[MINSTREL_GROUPS_NB];
|
@ -1,19 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -1016,6 +1016,16 @@ static int rt2x00lib_probe_hw_modes(stru
|
||||
struct ieee80211_rate *rates;
|
||||
unsigned int num_rates;
|
||||
unsigned int i;
|
||||
+#ifdef CONFIG_OF
|
||||
+ struct device_node *np = rt2x00dev->dev->of_node;
|
||||
+ unsigned int enabled;
|
||||
+ if (!of_property_read_u32(np, "ralink,2ghz",
|
||||
+ &enabled) && !enabled)
|
||||
+ spec->supported_bands &= ~SUPPORT_BAND_2GHZ;
|
||||
+ if (!of_property_read_u32(np, "ralink,5ghz",
|
||||
+ &enabled) && !enabled)
|
||||
+ spec->supported_bands &= ~SUPPORT_BAND_5GHZ;
|
||||
+#endif /* CONFIG_OF */
|
||||
|
||||
if (rt2x00dev->dev->platform_data) {
|
||||
struct rt2x00_platform_data *pdata;
|
@ -1,60 +0,0 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||
Subject: [PATCH] brcmfmac: add in-driver tables with country codes
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This adds early support for changing region. Ideally this data should
|
||||
be stored in DT as all these mappings are devices specific.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
|
||||
@@ -12,6 +12,36 @@
|
||||
#include "common.h"
|
||||
#include "of.h"
|
||||
|
||||
+/* TODO: FIXME: Use DT */
|
||||
+static void brcmf_of_probe_cc(struct device *dev,
|
||||
+ struct brcmf_mp_device *settings)
|
||||
+{
|
||||
+ static struct brcmfmac_pd_cc_entry netgear_r8000_cc_ent[] = {
|
||||
+ { "JP", "JP", 78 },
|
||||
+ { "US", "Q2", 86 },
|
||||
+ };
|
||||
+ struct brcmfmac_pd_cc_entry *cc_ent = NULL;
|
||||
+ int table_size = 0;
|
||||
+
|
||||
+ if (of_machine_is_compatible("netgear,r8000")) {
|
||||
+ cc_ent = netgear_r8000_cc_ent;
|
||||
+ table_size = ARRAY_SIZE(netgear_r8000_cc_ent);
|
||||
+ }
|
||||
+
|
||||
+ if (cc_ent && table_size) {
|
||||
+ struct brcmfmac_pd_cc *cc;
|
||||
+ size_t memsize;
|
||||
+
|
||||
+ memsize = table_size * sizeof(struct brcmfmac_pd_cc_entry);
|
||||
+ cc = devm_kzalloc(dev, sizeof(*cc) + memsize, GFP_KERNEL);
|
||||
+ if (!cc)
|
||||
+ return;
|
||||
+ cc->table_size = table_size;
|
||||
+ memcpy(cc->table, cc_ent, memsize);
|
||||
+ settings->country_codes = cc;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
|
||||
struct brcmf_mp_device *settings)
|
||||
{
|
||||
@@ -43,6 +73,8 @@ void brcmf_of_probe(struct device *dev,
|
||||
of_node_put(root);
|
||||
}
|
||||
|
||||
+ brcmf_of_probe_cc(dev, settings);
|
||||
+
|
||||
if (!np || bus_type != BRCMF_BUSTYPE_SDIO ||
|
||||
!of_device_is_compatible(np, "brcm,bcm4329-fmac"))
|
||||
return;
|
@ -1,271 +0,0 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Sun, 6 Dec 2020 14:54:43 +0200
|
||||
Subject: [PATCH] mac80211: support driver-based disconnect with reconnect hint
|
||||
|
||||
Support the driver indicating that a disconnection needs
|
||||
to be performed, and pass through the reconnect hint in
|
||||
this case.
|
||||
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
Link: https://lore.kernel.org/r/iwlwifi.20201206145305.5c8dab7a22a0.I58459fdf6968b16c90cab9c574f0f04ca22b0c79@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -5885,6 +5885,17 @@ void ieee80211_beacon_loss(struct ieee80
|
||||
void ieee80211_connection_loss(struct ieee80211_vif *vif);
|
||||
|
||||
/**
|
||||
+ * ieee80211_disconnect - request disconnection
|
||||
+ *
|
||||
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
|
||||
+ * @reconnect: immediate reconnect is desired
|
||||
+ *
|
||||
+ * Request disconnection from the current network and, if enabled, send a
|
||||
+ * hint to the higher layers that immediate reconnect is desired.
|
||||
+ */
|
||||
+void ieee80211_disconnect(struct ieee80211_vif *vif, bool reconnect);
|
||||
+
|
||||
+/**
|
||||
* ieee80211_resume_disconnect - disconnect from AP after resume
|
||||
*
|
||||
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -450,7 +450,9 @@ struct ieee80211_if_managed {
|
||||
unsigned long probe_timeout;
|
||||
int probe_send_count;
|
||||
bool nullfunc_failed;
|
||||
- bool connection_loss;
|
||||
+ u8 connection_loss:1,
|
||||
+ driver_disconnect:1,
|
||||
+ reconnect:1;
|
||||
|
||||
struct cfg80211_bss *associated;
|
||||
struct ieee80211_mgd_auth_data *auth_data;
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -2716,7 +2716,7 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get)
|
||||
|
||||
static void ieee80211_report_disconnect(struct ieee80211_sub_if_data *sdata,
|
||||
const u8 *buf, size_t len, bool tx,
|
||||
- u16 reason)
|
||||
+ u16 reason, bool reconnect)
|
||||
{
|
||||
struct ieee80211_event event = {
|
||||
.type = MLME_EVENT,
|
||||
@@ -2725,7 +2725,7 @@ static void ieee80211_report_disconnect(
|
||||
};
|
||||
|
||||
if (tx)
|
||||
- cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, false);
|
||||
+ cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, reconnect);
|
||||
else
|
||||
cfg80211_rx_mlme_mgmt(sdata->dev, buf, len);
|
||||
|
||||
@@ -2747,13 +2747,18 @@ static void __ieee80211_disconnect(struc
|
||||
|
||||
tx = !sdata->csa_block_tx;
|
||||
|
||||
- /* AP is probably out of range (or not reachable for another reason) so
|
||||
- * remove the bss struct for that AP.
|
||||
- */
|
||||
- cfg80211_unlink_bss(local->hw.wiphy, ifmgd->associated);
|
||||
+ if (!ifmgd->driver_disconnect) {
|
||||
+ /*
|
||||
+ * AP is probably out of range (or not reachable for another
|
||||
+ * reason) so remove the bss struct for that AP.
|
||||
+ */
|
||||
+ cfg80211_unlink_bss(local->hw.wiphy, ifmgd->associated);
|
||||
+ }
|
||||
|
||||
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
|
||||
- WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
|
||||
+ ifmgd->driver_disconnect ?
|
||||
+ WLAN_REASON_DEAUTH_LEAVING :
|
||||
+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
|
||||
tx, frame_buf);
|
||||
mutex_lock(&local->mtx);
|
||||
sdata->vif.csa_active = false;
|
||||
@@ -2766,7 +2771,9 @@ static void __ieee80211_disconnect(struc
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx,
|
||||
- WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
|
||||
+ WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
|
||||
+ ifmgd->reconnect);
|
||||
+ ifmgd->reconnect = false;
|
||||
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
@@ -2785,6 +2792,13 @@ static void ieee80211_beacon_connection_
|
||||
sdata_info(sdata, "Connection to AP %pM lost\n",
|
||||
ifmgd->bssid);
|
||||
__ieee80211_disconnect(sdata);
|
||||
+ ifmgd->connection_loss = false;
|
||||
+ } else if (ifmgd->driver_disconnect) {
|
||||
+ sdata_info(sdata,
|
||||
+ "Driver requested disconnection from AP %pM\n",
|
||||
+ ifmgd->bssid);
|
||||
+ __ieee80211_disconnect(sdata);
|
||||
+ ifmgd->driver_disconnect = false;
|
||||
} else {
|
||||
ieee80211_mgd_probe_ap(sdata, true);
|
||||
}
|
||||
@@ -2823,6 +2837,21 @@ void ieee80211_connection_loss(struct ie
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_connection_loss);
|
||||
|
||||
+void ieee80211_disconnect(struct ieee80211_vif *vif, bool reconnect)
|
||||
+{
|
||||
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||
+ struct ieee80211_hw *hw = &sdata->local->hw;
|
||||
+
|
||||
+ trace_api_disconnect(sdata, reconnect);
|
||||
+
|
||||
+ if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
|
||||
+ return;
|
||||
+
|
||||
+ sdata->u.mgd.driver_disconnect = true;
|
||||
+ sdata->u.mgd.reconnect = reconnect;
|
||||
+ ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
|
||||
+}
|
||||
+EXPORT_SYMBOL(ieee80211_disconnect);
|
||||
|
||||
static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
|
||||
bool assoc)
|
||||
@@ -3126,7 +3155,7 @@ static void ieee80211_rx_mgmt_deauth(str
|
||||
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
||||
|
||||
ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false,
|
||||
- reason_code);
|
||||
+ reason_code, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3175,7 +3204,8 @@ static void ieee80211_rx_mgmt_disassoc(s
|
||||
|
||||
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
||||
|
||||
- ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code);
|
||||
+ ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code,
|
||||
+ false);
|
||||
}
|
||||
|
||||
static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
|
||||
@@ -4199,7 +4229,8 @@ static void ieee80211_rx_mgmt_beacon(str
|
||||
true, deauth_buf);
|
||||
ieee80211_report_disconnect(sdata, deauth_buf,
|
||||
sizeof(deauth_buf), true,
|
||||
- WLAN_REASON_DEAUTH_LEAVING);
|
||||
+ WLAN_REASON_DEAUTH_LEAVING,
|
||||
+ false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4344,7 +4375,7 @@ static void ieee80211_sta_connection_los
|
||||
tx, frame_buf);
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
|
||||
- reason);
|
||||
+ reason, false);
|
||||
}
|
||||
|
||||
static int ieee80211_auth(struct ieee80211_sub_if_data *sdata)
|
||||
@@ -5434,7 +5465,8 @@ int ieee80211_mgd_auth(struct ieee80211_
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
- WLAN_REASON_UNSPECIFIED);
|
||||
+ WLAN_REASON_UNSPECIFIED,
|
||||
+ false);
|
||||
}
|
||||
|
||||
sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
|
||||
@@ -5506,7 +5538,8 @@ int ieee80211_mgd_assoc(struct ieee80211
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
- WLAN_REASON_UNSPECIFIED);
|
||||
+ WLAN_REASON_UNSPECIFIED,
|
||||
+ false);
|
||||
}
|
||||
|
||||
if (ifmgd->auth_data && !ifmgd->auth_data->done) {
|
||||
@@ -5809,7 +5842,7 @@ int ieee80211_mgd_deauth(struct ieee8021
|
||||
ieee80211_destroy_auth_data(sdata, false);
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
- req->reason_code);
|
||||
+ req->reason_code, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -5829,7 +5862,7 @@ int ieee80211_mgd_deauth(struct ieee8021
|
||||
ieee80211_destroy_assoc_data(sdata, false, true);
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
- req->reason_code);
|
||||
+ req->reason_code, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5844,7 +5877,7 @@ int ieee80211_mgd_deauth(struct ieee8021
|
||||
req->reason_code, tx, frame_buf);
|
||||
ieee80211_report_disconnect(sdata, frame_buf,
|
||||
sizeof(frame_buf), true,
|
||||
- req->reason_code);
|
||||
+ req->reason_code, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -5877,7 +5910,7 @@ int ieee80211_mgd_disassoc(struct ieee80
|
||||
frame_buf);
|
||||
|
||||
ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
|
||||
- req->reason_code);
|
||||
+ req->reason_code, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/net/mac80211/trace.h
|
||||
+++ b/net/mac80211/trace.h
|
||||
@@ -2,7 +2,7 @@
|
||||
/*
|
||||
* Portions of this file
|
||||
* Copyright(c) 2016-2017 Intel Deutschland GmbH
|
||||
-* Copyright (C) 2018 - 2019 Intel Corporation
|
||||
+* Copyright (C) 2018 - 2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
|
||||
@@ -2086,6 +2086,27 @@ TRACE_EVENT(api_connection_loss,
|
||||
)
|
||||
);
|
||||
|
||||
+TRACE_EVENT(api_disconnect,
|
||||
+ TP_PROTO(struct ieee80211_sub_if_data *sdata, bool reconnect),
|
||||
+
|
||||
+ TP_ARGS(sdata, reconnect),
|
||||
+
|
||||
+ TP_STRUCT__entry(
|
||||
+ VIF_ENTRY
|
||||
+ __field(int, reconnect)
|
||||
+ ),
|
||||
+
|
||||
+ TP_fast_assign(
|
||||
+ VIF_ASSIGN;
|
||||
+ __entry->reconnect = reconnect;
|
||||
+ ),
|
||||
+
|
||||
+ TP_printk(
|
||||
+ VIF_PR_FMT " reconnect:%d",
|
||||
+ VIF_PR_ARG, __entry->reconnect
|
||||
+ )
|
||||
+);
|
||||
+
|
||||
TRACE_EVENT(api_cqm_rssi_notify,
|
||||
TP_PROTO(struct ieee80211_sub_if_data *sdata,
|
||||
enum nl80211_cqm_rssi_threshold_event rssi_event,
|
@ -1,36 +0,0 @@
|
||||
--- a/net/mac80211/vht.c
|
||||
+++ b/net/mac80211/vht.c
|
||||
@@ -135,7 +135,8 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(stru
|
||||
have_80mhz = false;
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
|
||||
- IEEE80211_CHAN_NO_80MHZ))
|
||||
+ IEEE80211_CHAN_NO_80MHZ) &&
|
||||
+ (sband->band != NL80211_BAND_2GHZ))
|
||||
continue;
|
||||
|
||||
have_80mhz = true;
|
||||
--- a/net/mac80211/util.c
|
||||
+++ b/net/mac80211/util.c
|
||||
@@ -1769,7 +1769,8 @@ static int ieee80211_build_preq_ies_band
|
||||
/* Check if any channel in this sband supports at least 80 MHz */
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
|
||||
- IEEE80211_CHAN_NO_80MHZ))
|
||||
+ IEEE80211_CHAN_NO_80MHZ) &&
|
||||
+ (sband->band != NL80211_BAND_2GHZ))
|
||||
continue;
|
||||
|
||||
have_80mhz = true;
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -4824,7 +4824,8 @@ static int ieee80211_prep_channel(struct
|
||||
have_80mhz = false;
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
|
||||
- IEEE80211_CHAN_NO_80MHZ))
|
||||
+ IEEE80211_CHAN_NO_80MHZ) &&
|
||||
+ (sband->band != NL80211_BAND_2GHZ))
|
||||
continue;
|
||||
|
||||
have_80mhz = true;
|
@ -1,112 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Tue, 29 Jun 2021 13:25:09 +0200
|
||||
Subject: [PATCH] mac80211: fix starting aggregation sessions on mesh
|
||||
interfaces
|
||||
|
||||
The logic for starting aggregation sessions was recently moved from minstrel_ht
|
||||
to mac80211, into the subif tx handler just after the sta lookup.
|
||||
Unfortunately this didn't work for mesh interfaces, since the sta lookup is
|
||||
deferred until a much later point in time on those.
|
||||
Fix this by also calling the aggregation check right after the deferred sta
|
||||
lookup.
|
||||
|
||||
Fixes: 08a46c642001 ("mac80211: move A-MPDU session check from minstrel_ht to mac80211")
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -1159,6 +1159,29 @@ static bool ieee80211_tx_prep_agg(struct
|
||||
return queued;
|
||||
}
|
||||
|
||||
+static void
|
||||
+ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sta_info *sta,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ struct rate_control_ref *ref = sdata->local->rate_ctrl;
|
||||
+ u16 tid;
|
||||
+
|
||||
+ if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER))
|
||||
+ return;
|
||||
+
|
||||
+ if (!sta || !sta->sta.ht_cap.ht_supported ||
|
||||
+ !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO ||
|
||||
+ skb->protocol == sdata->control_port_protocol)
|
||||
+ return;
|
||||
+
|
||||
+ tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
|
||||
+ if (likely(sta->ampdu_mlme.tid_tx[tid]))
|
||||
+ return;
|
||||
+
|
||||
+ ieee80211_start_tx_ba_session(&sta->sta, tid, 0);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* initialises @tx
|
||||
* pass %NULL for the station if unknown, a valid pointer if known
|
||||
@@ -1172,6 +1195,7 @@ ieee80211_tx_prepare(struct ieee80211_su
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
+ bool aggr_check = false;
|
||||
int tid;
|
||||
|
||||
memset(tx, 0, sizeof(*tx));
|
||||
@@ -1200,8 +1224,10 @@ ieee80211_tx_prepare(struct ieee80211_su
|
||||
} else if (tx->sdata->control_port_protocol == tx->skb->protocol) {
|
||||
tx->sta = sta_info_get_bss(sdata, hdr->addr1);
|
||||
}
|
||||
- if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
|
||||
+ if (!tx->sta && !is_multicast_ether_addr(hdr->addr1)) {
|
||||
tx->sta = sta_info_get(sdata, hdr->addr1);
|
||||
+ aggr_check = true;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) &&
|
||||
@@ -1211,8 +1237,12 @@ ieee80211_tx_prepare(struct ieee80211_su
|
||||
struct tid_ampdu_tx *tid_tx;
|
||||
|
||||
tid = ieee80211_get_tid(hdr);
|
||||
-
|
||||
tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]);
|
||||
+ if (!tid_tx && aggr_check) {
|
||||
+ ieee80211_aggr_check(sdata, tx->sta, skb);
|
||||
+ tid_tx = rcu_dereference(tx->sta->ampdu_mlme.tid_tx[tid]);
|
||||
+ }
|
||||
+
|
||||
if (tid_tx) {
|
||||
bool queued;
|
||||
|
||||
@@ -3981,29 +4011,6 @@ void ieee80211_txq_schedule_start(struct
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_txq_schedule_start);
|
||||
|
||||
-static void
|
||||
-ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata,
|
||||
- struct sta_info *sta,
|
||||
- struct sk_buff *skb)
|
||||
-{
|
||||
- struct rate_control_ref *ref = sdata->local->rate_ctrl;
|
||||
- u16 tid;
|
||||
-
|
||||
- if (!ref || !(ref->ops->capa & RATE_CTRL_CAPA_AMPDU_TRIGGER))
|
||||
- return;
|
||||
-
|
||||
- if (!sta || !sta->sta.ht_cap.ht_supported ||
|
||||
- !sta->sta.wme || skb_get_queue_mapping(skb) == IEEE80211_AC_VO ||
|
||||
- skb->protocol == sdata->control_port_protocol)
|
||||
- return;
|
||||
-
|
||||
- tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
|
||||
- if (likely(sta->ampdu_mlme.tid_tx[tid]))
|
||||
- return;
|
||||
-
|
||||
- ieee80211_start_tx_ba_session(&sta->sta, tid, 0);
|
||||
-}
|
||||
-
|
||||
void __ieee80211_subif_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
u32 info_flags,
|
@ -1,335 +0,0 @@
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -437,43 +437,6 @@ USB_SIERRA_NET=
|
||||
USB_VL600=
|
||||
USB_NET_CH9200=
|
||||
USB_NET_AQC111=
|
||||
-SSB_POSSIBLE=
|
||||
-SSB=
|
||||
-SSB_SPROM=
|
||||
-SSB_BLOCKIO=
|
||||
-SSB_PCIHOST_POSSIBLE=
|
||||
-SSB_PCIHOST=
|
||||
-SSB_B43_PCI_BRIDGE=
|
||||
-SSB_PCMCIAHOST_POSSIBLE=
|
||||
-SSB_PCMCIAHOST=
|
||||
-SSB_SDIOHOST_POSSIBLE=
|
||||
-SSB_SDIOHOST=
|
||||
-SSB_HOST_SOC=
|
||||
-SSB_SERIAL=
|
||||
-SSB_DRIVER_PCICORE_POSSIBLE=
|
||||
-SSB_DRIVER_PCICORE=
|
||||
-SSB_PCICORE_HOSTMODE=
|
||||
-SSB_DRIVER_MIPS=
|
||||
-SSB_SFLASH=
|
||||
-SSB_EMBEDDED=
|
||||
-SSB_DRIVER_EXTIF=
|
||||
-SSB_DRIVER_GIGE=
|
||||
-SSB_DRIVER_GPIO=
|
||||
-BCMA_POSSIBLE=
|
||||
-BCMA=
|
||||
-BCMA_BLOCKIO=
|
||||
-BCMA_HOST_PCI_POSSIBLE=
|
||||
-BCMA_HOST_PCI=
|
||||
-BCMA_HOST_SOC=
|
||||
-BCMA_DRIVER_PCI=
|
||||
-BCMA_DRIVER_PCI_HOSTMODE=
|
||||
-BCMA_DRIVER_MIPS=
|
||||
-BCMA_PFLASH=
|
||||
-BCMA_SFLASH=
|
||||
-BCMA_NFLASH=
|
||||
-BCMA_DRIVER_GMAC_CMN=
|
||||
-BCMA_DRIVER_GPIO=
|
||||
-BCMA_DEBUG=
|
||||
USB_ACM=
|
||||
USB_PRINTER=
|
||||
USB_WDM=
|
||||
--- a/drivers/net/wireless/broadcom/b43/Kconfig
|
||||
+++ b/drivers/net/wireless/broadcom/b43/Kconfig
|
||||
@@ -63,21 +63,21 @@ endchoice
|
||||
config B43_PCI_AUTOSELECT
|
||||
bool
|
||||
depends on B43 && SSB_PCIHOST_POSSIBLE
|
||||
- select SSB_PCIHOST
|
||||
- select SSB_B43_PCI_BRIDGE
|
||||
+ depends on SSB_PCIHOST
|
||||
+ depends on SSB_B43_PCI_BRIDGE
|
||||
default y
|
||||
|
||||
# Auto-select SSB PCICORE driver, if possible
|
||||
config B43_PCICORE_AUTOSELECT
|
||||
bool
|
||||
depends on B43 && SSB_DRIVER_PCICORE_POSSIBLE
|
||||
- select SSB_DRIVER_PCICORE
|
||||
+ depends on SSB_DRIVER_PCICORE
|
||||
default y
|
||||
|
||||
config B43_SDIO
|
||||
bool "Broadcom 43xx SDIO device support"
|
||||
depends on B43 && B43_SSB && SSB_SDIOHOST_POSSIBLE
|
||||
- select SSB_SDIOHOST
|
||||
+ depends on SSB_SDIOHOST
|
||||
help
|
||||
Broadcom 43xx device support for Soft-MAC SDIO devices.
|
||||
|
||||
@@ -96,13 +96,13 @@ config B43_SDIO
|
||||
config B43_BCMA_PIO
|
||||
bool
|
||||
depends on B43 && B43_BCMA
|
||||
- select BCMA_BLOCKIO
|
||||
+ depends on BCMA_BLOCKIO
|
||||
default y
|
||||
|
||||
config B43_PIO
|
||||
bool
|
||||
depends on B43 && B43_SSB
|
||||
- select SSB_BLOCKIO
|
||||
+ depends on SSB_BLOCKIO
|
||||
default y
|
||||
|
||||
config B43_PHY_G
|
||||
--- a/drivers/net/wireless/broadcom/b43/main.c
|
||||
+++ b/drivers/net/wireless/broadcom/b43/main.c
|
||||
@@ -2853,7 +2853,7 @@ static struct ssb_device *b43_ssb_gpio_d
|
||||
{
|
||||
struct ssb_bus *bus = dev->dev->sdev->bus;
|
||||
|
||||
-#ifdef CPTCFG_SSB_DRIVER_PCICORE
|
||||
+#ifdef CONFIG_SSB_DRIVER_PCICORE
|
||||
return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
|
||||
#else
|
||||
return bus->chipco.dev;
|
||||
@@ -4870,7 +4870,7 @@ static int b43_wireless_core_init(struct
|
||||
}
|
||||
if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
|
||||
hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
|
||||
-#if defined(CPTCFG_B43_SSB) && defined(CPTCFG_SSB_DRIVER_PCICORE)
|
||||
+#if defined(CPTCFG_B43_SSB) && defined(CONFIG_SSB_DRIVER_PCICORE)
|
||||
if (dev->dev->bus_type == B43_BUS_SSB &&
|
||||
dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
|
||||
dev->dev->sdev->bus->pcicore.dev->id.revision <= 10)
|
||||
--- a/drivers/net/wireless/broadcom/b43legacy/Kconfig
|
||||
+++ b/drivers/net/wireless/broadcom/b43legacy/Kconfig
|
||||
@@ -3,7 +3,7 @@ config B43LEGACY
|
||||
tristate "Broadcom 43xx-legacy wireless support (mac80211 stack)"
|
||||
depends on m
|
||||
depends on SSB_POSSIBLE && MAC80211 && HAS_DMA
|
||||
- select SSB
|
||||
+ depends on SSB
|
||||
depends on FW_LOADER
|
||||
help
|
||||
b43legacy is a driver for 802.11b devices from Broadcom (BCM4301 and
|
||||
@@ -25,15 +25,15 @@ config B43LEGACY
|
||||
config B43LEGACY_PCI_AUTOSELECT
|
||||
bool
|
||||
depends on B43LEGACY && SSB_PCIHOST_POSSIBLE
|
||||
- select SSB_PCIHOST
|
||||
- select SSB_B43_PCI_BRIDGE
|
||||
+ depends on SSB_PCIHOST
|
||||
+ depends on SSB_B43_PCI_BRIDGE
|
||||
default y
|
||||
|
||||
# Auto-select SSB PCICORE driver, if possible
|
||||
config B43LEGACY_PCICORE_AUTOSELECT
|
||||
bool
|
||||
depends on B43LEGACY && SSB_DRIVER_PCICORE_POSSIBLE
|
||||
- select SSB_DRIVER_PCICORE
|
||||
+ depends on SSB_DRIVER_PCICORE
|
||||
default y
|
||||
|
||||
# LED support
|
||||
--- a/drivers/net/wireless/broadcom/b43legacy/main.c
|
||||
+++ b/drivers/net/wireless/broadcom/b43legacy/main.c
|
||||
@@ -1907,7 +1907,7 @@ static int b43legacy_gpio_init(struct b4
|
||||
if (dev->dev->id.revision >= 2)
|
||||
mask |= 0x0010; /* FIXME: This is redundant. */
|
||||
|
||||
-#ifdef CPTCFG_SSB_DRIVER_PCICORE
|
||||
+#ifdef CONFIG_SSB_DRIVER_PCICORE
|
||||
pcidev = bus->pcicore.dev;
|
||||
#endif
|
||||
gpiodev = bus->chipco.dev ? : pcidev;
|
||||
@@ -1926,7 +1926,7 @@ static void b43legacy_gpio_cleanup(struc
|
||||
struct ssb_bus *bus = dev->dev->bus;
|
||||
struct ssb_device *gpiodev, *pcidev = NULL;
|
||||
|
||||
-#ifdef CPTCFG_SSB_DRIVER_PCICORE
|
||||
+#ifdef CONFIG_SSB_DRIVER_PCICORE
|
||||
pcidev = bus->pcicore.dev;
|
||||
#endif
|
||||
gpiodev = bus->chipco.dev ? : pcidev;
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/led.h
|
||||
@@ -24,7 +24,7 @@ struct brcms_led {
|
||||
struct gpio_desc *gpiod;
|
||||
};
|
||||
|
||||
-#ifdef CPTCFG_BCMA_DRIVER_GPIO
|
||||
+#ifdef CONFIG_BCMA_DRIVER_GPIO
|
||||
void brcms_led_unregister(struct brcms_info *wl);
|
||||
int brcms_led_register(struct brcms_info *wl);
|
||||
#else
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/Makefile
|
||||
@@ -42,6 +42,6 @@ brcmsmac-y := \
|
||||
brcms_trace_events.o \
|
||||
debug.o
|
||||
|
||||
-brcmsmac-$(CPTCFG_BCMA_DRIVER_GPIO) += led.o
|
||||
+brcmsmac-$(CONFIG_BCMA_DRIVER_GPIO) += led.o
|
||||
|
||||
obj-$(CPTCFG_BRCMSMAC) += brcmsmac.o
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig
|
||||
@@ -8,7 +8,7 @@ config BRCMSMAC
|
||||
depends on m
|
||||
depends on MAC80211
|
||||
depends on BCMA_POSSIBLE
|
||||
- select BCMA
|
||||
+ depends on BCMA
|
||||
select NEW_LEDS if BCMA_DRIVER_GPIO
|
||||
select LEDS_CLASS if BCMA_DRIVER_GPIO
|
||||
select BRCMUTIL
|
||||
--- a/Kconfig.local
|
||||
+++ b/Kconfig.local
|
||||
@@ -1315,117 +1315,6 @@ config BACKPORTED_USB_NET_CH9200
|
||||
config BACKPORTED_USB_NET_AQC111
|
||||
tristate
|
||||
default USB_NET_AQC111
|
||||
-config BACKPORTED_SSB_POSSIBLE
|
||||
- tristate
|
||||
- default SSB_POSSIBLE
|
||||
-config BACKPORTED_SSB
|
||||
- tristate
|
||||
- default SSB
|
||||
-config BACKPORTED_SSB_SPROM
|
||||
- tristate
|
||||
- default SSB_SPROM
|
||||
-config BACKPORTED_SSB_BLOCKIO
|
||||
- tristate
|
||||
- default SSB_BLOCKIO
|
||||
-config BACKPORTED_SSB_PCIHOST_POSSIBLE
|
||||
- tristate
|
||||
- default SSB_PCIHOST_POSSIBLE
|
||||
-config BACKPORTED_SSB_PCIHOST
|
||||
- tristate
|
||||
- default SSB_PCIHOST
|
||||
-config BACKPORTED_SSB_B43_PCI_BRIDGE
|
||||
- tristate
|
||||
- default SSB_B43_PCI_BRIDGE
|
||||
-config BACKPORTED_SSB_PCMCIAHOST_POSSIBLE
|
||||
- tristate
|
||||
- default SSB_PCMCIAHOST_POSSIBLE
|
||||
-config BACKPORTED_SSB_PCMCIAHOST
|
||||
- tristate
|
||||
- default SSB_PCMCIAHOST
|
||||
-config BACKPORTED_SSB_SDIOHOST_POSSIBLE
|
||||
- tristate
|
||||
- default SSB_SDIOHOST_POSSIBLE
|
||||
-config BACKPORTED_SSB_SDIOHOST
|
||||
- tristate
|
||||
- default SSB_SDIOHOST
|
||||
-config BACKPORTED_SSB_HOST_SOC
|
||||
- tristate
|
||||
- default SSB_HOST_SOC
|
||||
-config BACKPORTED_SSB_SERIAL
|
||||
- tristate
|
||||
- default SSB_SERIAL
|
||||
-config BACKPORTED_SSB_DRIVER_PCICORE_POSSIBLE
|
||||
- tristate
|
||||
- default SSB_DRIVER_PCICORE_POSSIBLE
|
||||
-config BACKPORTED_SSB_DRIVER_PCICORE
|
||||
- tristate
|
||||
- default SSB_DRIVER_PCICORE
|
||||
-config BACKPORTED_SSB_PCICORE_HOSTMODE
|
||||
- tristate
|
||||
- default SSB_PCICORE_HOSTMODE
|
||||
-config BACKPORTED_SSB_DRIVER_MIPS
|
||||
- tristate
|
||||
- default SSB_DRIVER_MIPS
|
||||
-config BACKPORTED_SSB_SFLASH
|
||||
- tristate
|
||||
- default SSB_SFLASH
|
||||
-config BACKPORTED_SSB_EMBEDDED
|
||||
- tristate
|
||||
- default SSB_EMBEDDED
|
||||
-config BACKPORTED_SSB_DRIVER_EXTIF
|
||||
- tristate
|
||||
- default SSB_DRIVER_EXTIF
|
||||
-config BACKPORTED_SSB_DRIVER_GIGE
|
||||
- tristate
|
||||
- default SSB_DRIVER_GIGE
|
||||
-config BACKPORTED_SSB_DRIVER_GPIO
|
||||
- tristate
|
||||
- default SSB_DRIVER_GPIO
|
||||
-config BACKPORTED_BCMA_POSSIBLE
|
||||
- tristate
|
||||
- default BCMA_POSSIBLE
|
||||
-config BACKPORTED_BCMA
|
||||
- tristate
|
||||
- default BCMA
|
||||
-config BACKPORTED_BCMA_BLOCKIO
|
||||
- tristate
|
||||
- default BCMA_BLOCKIO
|
||||
-config BACKPORTED_BCMA_HOST_PCI_POSSIBLE
|
||||
- tristate
|
||||
- default BCMA_HOST_PCI_POSSIBLE
|
||||
-config BACKPORTED_BCMA_HOST_PCI
|
||||
- tristate
|
||||
- default BCMA_HOST_PCI
|
||||
-config BACKPORTED_BCMA_HOST_SOC
|
||||
- tristate
|
||||
- default BCMA_HOST_SOC
|
||||
-config BACKPORTED_BCMA_DRIVER_PCI
|
||||
- tristate
|
||||
- default BCMA_DRIVER_PCI
|
||||
-config BACKPORTED_BCMA_DRIVER_PCI_HOSTMODE
|
||||
- tristate
|
||||
- default BCMA_DRIVER_PCI_HOSTMODE
|
||||
-config BACKPORTED_BCMA_DRIVER_MIPS
|
||||
- tristate
|
||||
- default BCMA_DRIVER_MIPS
|
||||
-config BACKPORTED_BCMA_PFLASH
|
||||
- tristate
|
||||
- default BCMA_PFLASH
|
||||
-config BACKPORTED_BCMA_SFLASH
|
||||
- tristate
|
||||
- default BCMA_SFLASH
|
||||
-config BACKPORTED_BCMA_NFLASH
|
||||
- tristate
|
||||
- default BCMA_NFLASH
|
||||
-config BACKPORTED_BCMA_DRIVER_GMAC_CMN
|
||||
- tristate
|
||||
- default BCMA_DRIVER_GMAC_CMN
|
||||
-config BACKPORTED_BCMA_DRIVER_GPIO
|
||||
- tristate
|
||||
- default BCMA_DRIVER_GPIO
|
||||
-config BACKPORTED_BCMA_DEBUG
|
||||
- tristate
|
||||
- default BCMA_DEBUG
|
||||
config BACKPORTED_USB_ACM
|
||||
tristate
|
||||
default USB_ACM
|
||||
--- a/Kconfig.sources
|
||||
+++ b/Kconfig.sources
|
||||
@@ -7,9 +7,6 @@ source "$BACKPORT_DIR/net/mac80211/Kconf
|
||||
source "$BACKPORT_DIR/drivers/net/wireless/Kconfig"
|
||||
source "$BACKPORT_DIR/drivers/net/usb/Kconfig"
|
||||
|
||||
-source "$BACKPORT_DIR/drivers/ssb/Kconfig"
|
||||
-source "$BACKPORT_DIR/drivers/bcma/Kconfig"
|
||||
-
|
||||
source "$BACKPORT_DIR/drivers/usb/class/Kconfig"
|
||||
|
||||
source "$BACKPORT_DIR/drivers/staging/Kconfig"
|
||||
--- a/Makefile.kernel
|
||||
+++ b/Makefile.kernel
|
||||
@@ -40,8 +40,6 @@ obj-y += compat/
|
||||
obj-$(CPTCFG_CFG80211) += net/wireless/
|
||||
obj-$(CPTCFG_MAC80211) += net/mac80211/
|
||||
obj-$(CPTCFG_WLAN) += drivers/net/wireless/
|
||||
-obj-$(CPTCFG_SSB) += drivers/ssb/
|
||||
-obj-$(CPTCFG_BCMA) += drivers/bcma/
|
||||
obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/
|
||||
|
||||
obj-$(CPTCFG_USB_WDM) += drivers/usb/class/
|
@ -1,81 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -8618,6 +8618,70 @@ static void rt2800_r_calibration(struct
|
||||
rt2800_register_write(rt2x00dev, PWR_PIN_CFG, MAC_PWR_PIN_CFG);
|
||||
}
|
||||
|
||||
+static void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ u8 bbpreg = 0;
|
||||
+ u32 macvalue = 0, macvalue1 = 0;
|
||||
+ u8 saverfb0r2, saverfb5r4, saverfb7r4, rfvalue;
|
||||
+ int i;
|
||||
+
|
||||
+ saverfb0r2 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
|
||||
+ rfvalue = saverfb0r2;
|
||||
+ rfvalue |= 0x03;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfvalue);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 141);
|
||||
+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbpreg |= 0x10;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x8);
|
||||
+
|
||||
+ for (i = 0; i < 10000; i++) {
|
||||
+ macvalue1 = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
|
||||
+ if (macvalue1 & 0x1)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ saverfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 0);
|
||||
+ saverfb7r4 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
|
||||
+ saverfb5r4 = saverfb5r4 & (~0x40);
|
||||
+ saverfb7r4 = saverfb7r4 & (~0x40);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x64);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, saverfb5r4);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, saverfb7r4);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 141);
|
||||
+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbpreg = bbpreg & (~0x40);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
|
||||
+ bbpreg |= 0x48;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
|
||||
+
|
||||
+ for (i = 0; i < 10000; i++) {
|
||||
+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ if ((bbpreg & 0x40)==0)
|
||||
+ break;
|
||||
+ udelay(50);
|
||||
+ }
|
||||
+
|
||||
+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbpreg = bbpreg & (~0x40);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 141);
|
||||
+ bbpreg = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbpreg &= (~0x10);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbpreg);
|
||||
+
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, saverfb0r2);
|
||||
+}
|
||||
+
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
bool set_bw, bool is_ht40)
|
||||
{
|
||||
@@ -9227,6 +9291,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
|
||||
rt2800_r_calibration(rt2x00dev);
|
||||
rt2800_rf_self_txdc_cal(rt2x00dev);
|
||||
+ rt2800_rxdcoc_calibration(rt2x00dev);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, true);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, false);
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 22 Jan 2021 19:24:59 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: reduce the need to sample slower
|
||||
rates
|
||||
|
||||
In order to more gracefully be able to fall back to lower rates without too
|
||||
much throughput fluctuations, initialize all untested rates below tested ones
|
||||
to the maximum probabilty of higher rates.
|
||||
Usually this leads to untested lower rates getting initialized with a
|
||||
probability value of 100%, making them better candidates for fallback without
|
||||
having to rely on random probing
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -791,14 +791,11 @@ minstrel_ht_calc_rate_stats(struct minst
|
||||
unsigned int cur_prob;
|
||||
|
||||
if (unlikely(mrs->attempts > 0)) {
|
||||
- mrs->sample_skipped = 0;
|
||||
cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
|
||||
minstrel_filter_avg_add(&mrs->prob_avg,
|
||||
&mrs->prob_avg_1, cur_prob);
|
||||
mrs->att_hist += mrs->attempts;
|
||||
mrs->succ_hist += mrs->success;
|
||||
- } else {
|
||||
- mrs->sample_skipped++;
|
||||
}
|
||||
|
||||
mrs->last_success = mrs->success;
|
||||
@@ -851,7 +848,6 @@ minstrel_ht_update_stats(struct minstrel
|
||||
mi->ampdu_packets = 0;
|
||||
}
|
||||
|
||||
- mi->sample_slow = 0;
|
||||
mi->sample_count = 0;
|
||||
|
||||
if (mi->supported[MINSTREL_CCK_GROUP])
|
||||
@@ -882,6 +878,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
/* Find best rate sets within all MCS groups*/
|
||||
for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
|
||||
u16 *tp_rate = tmp_mcs_tp_rate;
|
||||
+ u16 last_prob = 0;
|
||||
|
||||
mg = &mi->groups[group];
|
||||
if (!mi->supported[group])
|
||||
@@ -896,7 +893,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
if (group == MINSTREL_CCK_GROUP && ht_supported)
|
||||
tp_rate = tmp_legacy_tp_rate;
|
||||
|
||||
- for (i = 0; i < MCS_GROUP_RATES; i++) {
|
||||
+ for (i = MCS_GROUP_RATES - 1; i >= 0; i--) {
|
||||
if (!(mi->supported[group] & BIT(i)))
|
||||
continue;
|
||||
|
||||
@@ -905,6 +902,11 @@ minstrel_ht_update_stats(struct minstrel
|
||||
mrs = &mg->rates[i];
|
||||
mrs->retry_updated = false;
|
||||
minstrel_ht_calc_rate_stats(mp, mrs);
|
||||
+
|
||||
+ if (mrs->att_hist)
|
||||
+ last_prob = max(last_prob, mrs->prob_avg);
|
||||
+ else
|
||||
+ mrs->prob_avg = max(last_prob, mrs->prob_avg);
|
||||
cur_prob = mrs->prob_avg;
|
||||
|
||||
if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0)
|
||||
@@ -1469,13 +1471,9 @@ minstrel_get_sample_rate(struct minstrel
|
||||
if (sample_dur >= minstrel_get_duration(tp_rate2) &&
|
||||
(cur_max_tp_streams - 1 <
|
||||
minstrel_mcs_groups[sample_group].streams ||
|
||||
- sample_dur >= minstrel_get_duration(mi->max_prob_rate))) {
|
||||
- if (mrs->sample_skipped < 20)
|
||||
+ sample_dur >= minstrel_get_duration(mi->max_prob_rate)))
|
||||
return -1;
|
||||
|
||||
- if (mi->sample_slow++ > 2)
|
||||
- return -1;
|
||||
- }
|
||||
mi->sample_tries--;
|
||||
|
||||
return sample_idx;
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.h
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.h
|
||||
@@ -123,7 +123,6 @@ struct minstrel_rate_stats {
|
||||
u8 retry_count;
|
||||
u8 retry_count_rtscts;
|
||||
|
||||
- u8 sample_skipped;
|
||||
bool retry_updated;
|
||||
};
|
||||
|
||||
@@ -179,7 +178,6 @@ struct minstrel_ht_sta {
|
||||
u8 sample_wait;
|
||||
u8 sample_tries;
|
||||
u8 sample_count;
|
||||
- u8 sample_slow;
|
||||
|
||||
enum minstrel_sample_mode sample_mode;
|
||||
u16 sample_rate;
|
@ -1,186 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.h
|
||||
@@ -723,6 +723,7 @@ struct ath_spec_scan {
|
||||
* @config_pci_powersave:
|
||||
* @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
|
||||
*
|
||||
+ * @get_adc_entropy: get entropy from the raw ADC I/Q output
|
||||
* @spectral_scan_config: set parameters for spectral scan and enable/disable it
|
||||
* @spectral_scan_trigger: trigger a spectral scan run
|
||||
* @spectral_scan_wait: wait for a spectral scan run to finish
|
||||
@@ -745,6 +746,7 @@ struct ath_hw_ops {
|
||||
struct ath_hw_antcomb_conf *antconf);
|
||||
void (*antdiv_comb_conf_set)(struct ath_hw *ah,
|
||||
struct ath_hw_antcomb_conf *antconf);
|
||||
+ void (*get_adc_entropy)(struct ath_hw *ah, u8 *buf, size_t len);
|
||||
void (*spectral_scan_config)(struct ath_hw *ah,
|
||||
struct ath_spec_scan *param);
|
||||
void (*spectral_scan_trigger)(struct ath_hw *ah);
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
@@ -1927,6 +1927,26 @@ void ar9003_hw_init_rate_txpower(struct
|
||||
}
|
||||
}
|
||||
|
||||
+static void ar9003_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len)
|
||||
+{
|
||||
+ int i, j;
|
||||
+
|
||||
+ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1);
|
||||
+ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5);
|
||||
+ REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_RX_OBS_SEL, 0);
|
||||
+
|
||||
+ memset(buf, 0, len);
|
||||
+ for (i = 0; i < len; i++) {
|
||||
+ for (j = 0; j < 4; j++) {
|
||||
+ u32 regval = REG_READ(ah, AR_PHY_TST_ADC);
|
||||
+
|
||||
+ buf[i] <<= 2;
|
||||
+ buf[i] |= (regval & 1) | ((regval & BIT(10)) >> 9);
|
||||
+ udelay(1);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
@@ -1963,6 +1983,7 @@ void ar9003_hw_attach_phy_ops(struct ath
|
||||
priv_ops->set_radar_params = ar9003_hw_set_radar_params;
|
||||
priv_ops->fast_chan_change = ar9003_hw_fast_chan_change;
|
||||
|
||||
+ ops->get_adc_entropy = ar9003_hw_get_adc_entropy;
|
||||
ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
|
||||
ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
|
||||
ops->spectral_scan_config = ar9003_hw_spectral_scan_config;
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -818,7 +818,8 @@ static void ath9k_init_txpower_limits(st
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
|
||||
ath9k_init_band_txpower(sc, NL80211_BAND_5GHZ);
|
||||
|
||||
- ah->curchan = curchan;
|
||||
+ if (curchan)
|
||||
+ ah->curchan = curchan;
|
||||
}
|
||||
|
||||
static const struct ieee80211_iface_limit if_limits[] = {
|
||||
@@ -1015,6 +1016,18 @@ static void ath9k_set_hw_capab(struct at
|
||||
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
|
||||
}
|
||||
|
||||
+static void ath_get_initial_entropy(struct ath_softc *sc)
|
||||
+{
|
||||
+ struct ath_hw *ah = sc->sc_ah;
|
||||
+ char buf[256];
|
||||
+
|
||||
+ /* reuse last channel initialized by the tx power test */
|
||||
+ ath9k_hw_reset(ah, ah->curchan, NULL, false);
|
||||
+
|
||||
+ ath9k_hw_get_adc_entropy(ah, buf, sizeof(buf));
|
||||
+ add_device_randomness(buf, sizeof(buf));
|
||||
+}
|
||||
+
|
||||
int ath9k_init_device(u16 devid, struct ath_softc *sc,
|
||||
const struct ath_bus_ops *bus_ops)
|
||||
{
|
||||
@@ -1060,6 +1073,8 @@ int ath9k_init_device(u16 devid, struct
|
||||
ARRAY_SIZE(ath9k_tpt_blink));
|
||||
#endif
|
||||
|
||||
+ ath_get_initial_entropy(sc);
|
||||
+
|
||||
/* Register with mac80211 */
|
||||
error = ieee80211_register_hw(hw);
|
||||
if (error)
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
|
||||
@@ -100,6 +100,12 @@ static inline void ath9k_hw_tx99_set_txp
|
||||
ath9k_hw_ops(ah)->tx99_set_txpower(ah, power);
|
||||
}
|
||||
|
||||
+static inline void ath9k_hw_get_adc_entropy(struct ath_hw *ah,
|
||||
+ u8 *buf, size_t len)
|
||||
+{
|
||||
+ ath9k_hw_ops(ah)->get_adc_entropy(ah, buf, len);
|
||||
+}
|
||||
+
|
||||
#ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT
|
||||
|
||||
static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
|
||||
@@ -1349,9 +1349,30 @@ void ar5008_hw_init_rate_txpower(struct
|
||||
}
|
||||
}
|
||||
|
||||
+static void ar5008_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len)
|
||||
+{
|
||||
+ int i, j;
|
||||
+
|
||||
+ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1);
|
||||
+ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5);
|
||||
+ REG_RMW_FIELD(ah, AR_PHY_TEST2, AR_PHY_TEST2_RX_OBS_SEL, 0);
|
||||
+
|
||||
+ memset(buf, 0, len);
|
||||
+ for (i = 0; i < len; i++) {
|
||||
+ for (j = 0; j < 4; j++) {
|
||||
+ u32 regval = REG_READ(ah, AR_PHY_TST_ADC);
|
||||
+
|
||||
+ buf[i] <<= 2;
|
||||
+ buf[i] |= (regval & 1) | ((regval & BIT(9)) >> 8);
|
||||
+ udelay(1);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
int ar5008_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
+ struct ath_hw_ops *ops = ath9k_hw_ops(ah);
|
||||
static const u32 ar5416_cca_regs[6] = {
|
||||
AR_PHY_CCA,
|
||||
AR_PHY_CH1_CCA,
|
||||
@@ -1366,6 +1387,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
+ ops->get_adc_entropy = ar5008_hw_get_adc_entropy;
|
||||
+
|
||||
priv_ops->rf_set_freq = ar5008_hw_set_channel;
|
||||
priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
|
||||
@@ -20,6 +20,12 @@
|
||||
#define PHY_AGC_CLR 0x10000000
|
||||
#define RFSILENT_BB 0x00002000
|
||||
|
||||
+#define AR_PHY_TEST_BBB_OBS_SEL 0x780000
|
||||
+#define AR_PHY_TEST_BBB_OBS_SEL_S 19
|
||||
+
|
||||
+#define AR_PHY_TEST_RX_OBS_SEL_BIT5_S 23
|
||||
+#define AR_PHY_TEST_RX_OBS_SEL_BIT5 (1 << AR_PHY_TEST_RX_OBS_SEL_BIT5_S)
|
||||
+
|
||||
#define AR_PHY_TURBO 0x9804
|
||||
#define AR_PHY_FC_TURBO_MODE 0x00000001
|
||||
#define AR_PHY_FC_TURBO_SHORT 0x00000002
|
||||
@@ -36,6 +42,9 @@
|
||||
|
||||
#define AR_PHY_TEST2 0x9808
|
||||
|
||||
+#define AR_PHY_TEST2_RX_OBS_SEL 0x3C00
|
||||
+#define AR_PHY_TEST2_RX_OBS_SEL_S 10
|
||||
+
|
||||
#define AR_PHY_TIMING2 0x9810
|
||||
#define AR_PHY_TIMING3 0x9814
|
||||
#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000
|
||||
@@ -393,6 +402,8 @@
|
||||
#define AR_PHY_RFBUS_GRANT 0x9C20
|
||||
#define AR_PHY_RFBUS_GRANT_EN 0x00000001
|
||||
|
||||
+#define AR_PHY_TST_ADC 0x9C24
|
||||
+
|
||||
#define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4
|
||||
#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
|
||||
|
@ -1,17 +0,0 @@
|
||||
--- a/drivers/net/wireless/broadcom/b43/main.c
|
||||
+++ b/drivers/net/wireless/broadcom/b43/main.c
|
||||
@@ -2886,6 +2886,14 @@ static int b43_gpio_init(struct b43_wlde
|
||||
} else if (dev->dev->chip_id == 0x5354) {
|
||||
/* Don't allow overtaking buttons GPIOs */
|
||||
set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */
|
||||
+ } else if (dev->dev->chip_id == BCMA_CHIP_ID_BCM4716 ||
|
||||
+ dev->dev->chip_id == BCMA_CHIP_ID_BCM47162 ||
|
||||
+ dev->dev->chip_id == BCMA_CHIP_ID_BCM5356 ||
|
||||
+ dev->dev->chip_id == BCMA_CHIP_ID_BCM5357 ||
|
||||
+ dev->dev->chip_id == BCMA_CHIP_ID_BCM53572) {
|
||||
+ /* just use gpio 0 and 1 for 2.4 GHz wifi led */
|
||||
+ set &= 0x3;
|
||||
+ mask &= 0x3;
|
||||
}
|
||||
|
||||
if (0 /* FIXME: conditional unknown */ ) {
|
@ -1,60 +0,0 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Fri, 19 Mar 2021 23:28:01 +0100
|
||||
Subject: [PATCH] mac80211: don't apply flow control on management frames
|
||||
|
||||
In some cases (depending on the driver, but it's true e.g. for
|
||||
iwlwifi) we're using an internal TXQ for management packets,
|
||||
mostly to simplify the code and to have a place to queue them.
|
||||
However, it appears that in certain cases we can confuse the
|
||||
code and management frames are dropped, which is certainly not
|
||||
what we want.
|
||||
|
||||
Short-circuit the processing of management frames. To keep the
|
||||
impact minimal, only put them on the frags queue and check the
|
||||
tid == management only for doing that and to skip the airtime
|
||||
fairness checks, if applicable.
|
||||
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -5,7 +5,7 @@
|
||||
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
- * Copyright (C) 2018-2020 Intel Corporation
|
||||
+ * Copyright (C) 2018-2021 Intel Corporation
|
||||
*
|
||||
* Transmit and frame generation functions.
|
||||
*/
|
||||
@@ -1401,8 +1401,17 @@ static void ieee80211_txq_enqueue(struct
|
||||
ieee80211_set_skb_enqueue_time(skb);
|
||||
|
||||
spin_lock_bh(&fq->lock);
|
||||
- fq_tin_enqueue(fq, tin, flow_idx, skb,
|
||||
- fq_skb_free_func);
|
||||
+ /*
|
||||
+ * For management frames, don't really apply codel etc.,
|
||||
+ * we don't want to apply any shaping or anything we just
|
||||
+ * want to simplify the driver API by having them on the
|
||||
+ * txqi.
|
||||
+ */
|
||||
+ if (unlikely(txqi->txq.tid == IEEE80211_NUM_TIDS))
|
||||
+ __skb_queue_tail(&txqi->frags, skb);
|
||||
+ else
|
||||
+ fq_tin_enqueue(fq, tin, flow_idx, skb,
|
||||
+ fq_skb_free_func);
|
||||
spin_unlock_bh(&fq->lock);
|
||||
}
|
||||
|
||||
@@ -3878,6 +3887,9 @@ bool ieee80211_txq_airtime_check(struct
|
||||
if (!txq->sta)
|
||||
return true;
|
||||
|
||||
+ if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
|
||||
+ return true;
|
||||
+
|
||||
sta = container_of(txq->sta, struct sta_info, sta);
|
||||
if (atomic_read(&sta->airtime[txq->ac].aql_tx_pending) <
|
||||
sta->airtime[txq->ac].aql_limit_low)
|
@ -1,34 +0,0 @@
|
||||
--- a/compat/main.c
|
||||
+++ b/compat/main.c
|
||||
@@ -20,31 +20,6 @@ MODULE_LICENSE("GPL");
|
||||
#error "You need a CPTCFG_VERSION"
|
||||
#endif
|
||||
|
||||
-static char *backported_kernel_name = CPTCFG_KERNEL_NAME;
|
||||
-
|
||||
-module_param(backported_kernel_name, charp, 0400);
|
||||
-MODULE_PARM_DESC(backported_kernel_name,
|
||||
- "The kernel tree name that was used for this backport (" CPTCFG_KERNEL_NAME ")");
|
||||
-
|
||||
-#ifdef BACKPORTS_GIT_TRACKED
|
||||
-static char *backports_tracker_id = BACKPORTS_GIT_TRACKED;
|
||||
-module_param(backports_tracker_id, charp, 0400);
|
||||
-MODULE_PARM_DESC(backports_tracker_id,
|
||||
- "The version of the tree containing this backport (" BACKPORTS_GIT_TRACKED ")");
|
||||
-#else
|
||||
-static char *backported_kernel_version = CPTCFG_KERNEL_VERSION;
|
||||
-static char *backports_version = CPTCFG_VERSION;
|
||||
-
|
||||
-module_param(backported_kernel_version, charp, 0400);
|
||||
-MODULE_PARM_DESC(backported_kernel_version,
|
||||
- "The kernel version that was used for this backport (" CPTCFG_KERNEL_VERSION ")");
|
||||
-
|
||||
-module_param(backports_version, charp, 0400);
|
||||
-MODULE_PARM_DESC(backports_version,
|
||||
- "The git version of the backports tree used to generate this backport (" CPTCFG_VERSION ")");
|
||||
-
|
||||
-#endif
|
||||
-
|
||||
void backport_dependency_symbol(void)
|
||||
{
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
--- a/drivers/net/wireless/broadcom/b43/main.c
|
||||
+++ b/drivers/net/wireless/broadcom/b43/main.c
|
||||
@@ -114,7 +114,7 @@ static int b43_modparam_pio = 0;
|
||||
module_param_named(pio, b43_modparam_pio, int, 0644);
|
||||
MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
|
||||
|
||||
-static int modparam_allhwsupport = !IS_ENABLED(CPTCFG_BRCMSMAC);
|
||||
+static int modparam_allhwsupport = 1;
|
||||
module_param_named(allhwsupport, modparam_allhwsupport, int, 0444);
|
||||
MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)");
|
||||
|
@ -1,12 +0,0 @@
|
||||
Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
|
||||
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -1307,7 +1307,6 @@ static int ieee80211_stop_ap(struct wiph
|
||||
sdata->vif.bss_conf.ftmr_params = NULL;
|
||||
|
||||
__sta_info_flush(sdata, true);
|
||||
- ieee80211_free_keys(sdata, true);
|
||||
|
||||
sdata->vif.bss_conf.enable_beacon = false;
|
||||
sdata->beacon_rate_set = false;
|
@ -1,11 +0,0 @@
|
||||
--- a/drivers/net/wireless/broadcom/b43/dma.h
|
||||
+++ b/drivers/net/wireless/broadcom/b43/dma.h
|
||||
@@ -170,7 +170,7 @@ struct b43_dmadesc_generic {
|
||||
|
||||
/* DMA engine tuning knobs */
|
||||
#define B43_TXRING_SLOTS 256
|
||||
-#define B43_RXRING_SLOTS 256
|
||||
+#define B43_RXRING_SLOTS 32
|
||||
#define B43_DMA0_RX_FW598_BUFSIZE (B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN)
|
||||
#define B43_DMA0_RX_FW351_BUFSIZE (B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN)
|
||||
|
@ -1,34 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -1143,25 +1143,25 @@ static int __init ath9k_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
- error = ath_pci_init();
|
||||
+ error = ath_ahb_init();
|
||||
if (error < 0) {
|
||||
- pr_err("No PCI devices found, driver not installed\n");
|
||||
error = -ENODEV;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
- error = ath_ahb_init();
|
||||
+ error = ath_pci_init();
|
||||
if (error < 0) {
|
||||
+ pr_err("No PCI devices found, driver not installed\n");
|
||||
error = -ENODEV;
|
||||
- goto err_pci_exit;
|
||||
+ goto err_ahb_exit;
|
||||
}
|
||||
|
||||
dmi_check_system(ath9k_quirks);
|
||||
|
||||
return 0;
|
||||
|
||||
- err_pci_exit:
|
||||
- ath_pci_exit();
|
||||
+ err_ahb_exit:
|
||||
+ ath_ahb_exit();
|
||||
err_out:
|
||||
return error;
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 26 Dec 2020 19:08:19 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: improve ampdu length estimation
|
||||
|
||||
If the driver does not report A-MPDU length, estimate it based on the rate.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -382,13 +382,37 @@ minstrel_get_ratestats(struct minstrel_h
|
||||
return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES];
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+minstrel_get_duration(int index)
|
||||
+{
|
||||
+ const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
|
||||
+ unsigned int duration = group->duration[index % MCS_GROUP_RATES];
|
||||
+ return duration << group->shift;
|
||||
+}
|
||||
+
|
||||
static unsigned int
|
||||
minstrel_ht_avg_ampdu_len(struct minstrel_ht_sta *mi)
|
||||
{
|
||||
- if (!mi->avg_ampdu_len)
|
||||
- return AVG_AMPDU_SIZE;
|
||||
+ int duration;
|
||||
+
|
||||
+ if (mi->avg_ampdu_len)
|
||||
+ return MINSTREL_TRUNC(mi->avg_ampdu_len);
|
||||
+
|
||||
+ if (minstrel_ht_is_legacy_group(mi->max_tp_rate[0] / MCS_GROUP_RATES))
|
||||
+ return 1;
|
||||
+
|
||||
+ duration = minstrel_get_duration(mi->max_tp_rate[0]);
|
||||
|
||||
- return MINSTREL_TRUNC(mi->avg_ampdu_len);
|
||||
+ if (duration > 400 * 1000)
|
||||
+ return 2;
|
||||
+
|
||||
+ if (duration > 250 * 1000)
|
||||
+ return 4;
|
||||
+
|
||||
+ if (duration > 150 * 1000)
|
||||
+ return 8;
|
||||
+
|
||||
+ return 16;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -588,14 +612,6 @@ minstrel_ht_prob_rate_reduce_streams(str
|
||||
}
|
||||
}
|
||||
|
||||
-static inline int
|
||||
-minstrel_get_duration(int index)
|
||||
-{
|
||||
- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
|
||||
- unsigned int duration = group->duration[index % MCS_GROUP_RATES];
|
||||
- return duration << group->shift;
|
||||
-}
|
||||
-
|
||||
static bool
|
||||
minstrel_ht_probe_group(struct minstrel_ht_sta *mi, const struct mcs_group *tp_group,
|
||||
int tp_idx, const struct mcs_group *group)
|
@ -1,524 +0,0 @@
|
||||
From: John Crispin <john@phrozen.org>
|
||||
Date: Fri, 2 Jul 2021 19:44:08 +0200
|
||||
Subject: [PATCH] mac80211: add support for BSS color change
|
||||
|
||||
The color change announcement is very similar to how CSA works where
|
||||
we have an IE that includes a counter. When the counter hits 0, the new
|
||||
color is applied via an updated beacon.
|
||||
|
||||
This patch makes the CSA counter functionality reusable, rather than
|
||||
implementing it again. This also allows for future reuse incase support
|
||||
for other counter IEs gets added.
|
||||
|
||||
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: John Crispin <john@phrozen.org>
|
||||
Link: https://lore.kernel.org/r/057c1e67b82bee561ea44ce6a45a8462d3da6995.1625247619.git.lorenzo@kernel.org
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -1710,6 +1710,10 @@ enum ieee80211_offload_flags {
|
||||
* protected by fq->lock.
|
||||
* @offload_flags: 802.3 -> 802.11 enapsulation offload flags, see
|
||||
* &enum ieee80211_offload_flags.
|
||||
+ * @color_change_active: marks whether a color change is ongoing. Internally it is
|
||||
+ * write-protected by sdata_lock and local->mtx so holding either is fine
|
||||
+ * for read access.
|
||||
+ * @color_change_color: the bss color that will be used after the change.
|
||||
*/
|
||||
struct ieee80211_vif {
|
||||
enum nl80211_iftype type;
|
||||
@@ -1738,6 +1742,9 @@ struct ieee80211_vif {
|
||||
|
||||
bool txqs_stopped[IEEE80211_NUM_ACS];
|
||||
|
||||
+ bool color_change_active;
|
||||
+ u8 color_change_color;
|
||||
+
|
||||
/* must be last */
|
||||
u8 drv_priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
@@ -4982,6 +4989,16 @@ void ieee80211_csa_finish(struct ieee802
|
||||
bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif);
|
||||
|
||||
/**
|
||||
+ * ieee80211_color_change_finish - notify mac80211 about color change
|
||||
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
|
||||
+ *
|
||||
+ * After a color change announcement was scheduled and the counter in this
|
||||
+ * announcement hits 1, this function must be called by the driver to
|
||||
+ * notify mac80211 that the color can be changed
|
||||
+ */
|
||||
+void ieee80211_color_change_finish(struct ieee80211_vif *vif);
|
||||
+
|
||||
+/**
|
||||
* ieee80211_proberesp_get - retrieve a Probe Response template
|
||||
* @hw: pointer obtained from ieee80211_alloc_hw().
|
||||
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
|
||||
@@ -6726,6 +6743,18 @@ ieee80211_get_unsol_bcast_probe_resp_tmp
|
||||
struct ieee80211_vif *vif);
|
||||
|
||||
/**
|
||||
+ * ieeee80211_obss_color_collision_notify - notify userland about a BSS color
|
||||
+ * collision.
|
||||
+ *
|
||||
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
|
||||
+ * @color_bitmap: a 64 bit bitmap representing the colors that the local BSS is
|
||||
+ * aware of.
|
||||
+ */
|
||||
+void
|
||||
+ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
|
||||
+ u64 color_bitmap);
|
||||
+
|
||||
+/**
|
||||
* ieee80211_is_tx_data - check if frame is a data frame
|
||||
*
|
||||
* The function is used to check if a frame is a data frame. Frames with
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -827,9 +827,11 @@ static int ieee80211_set_monitor_channel
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
|
||||
- const u8 *resp, size_t resp_len,
|
||||
- const struct ieee80211_csa_settings *csa)
|
||||
+static int
|
||||
+ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
|
||||
+ const u8 *resp, size_t resp_len,
|
||||
+ const struct ieee80211_csa_settings *csa,
|
||||
+ const struct ieee80211_color_change_settings *cca)
|
||||
{
|
||||
struct probe_resp *new, *old;
|
||||
|
||||
@@ -849,6 +851,8 @@ static int ieee80211_set_probe_resp(stru
|
||||
memcpy(new->cntdwn_counter_offsets, csa->counter_offsets_presp,
|
||||
csa->n_counter_offsets_presp *
|
||||
sizeof(new->cntdwn_counter_offsets[0]));
|
||||
+ else if (cca)
|
||||
+ new->cntdwn_counter_offsets[0] = cca->counter_offset_presp;
|
||||
|
||||
rcu_assign_pointer(sdata->u.ap.probe_resp, new);
|
||||
if (old)
|
||||
@@ -954,7 +958,8 @@ static int ieee80211_set_ftm_responder_p
|
||||
|
||||
static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
struct cfg80211_beacon_data *params,
|
||||
- const struct ieee80211_csa_settings *csa)
|
||||
+ const struct ieee80211_csa_settings *csa,
|
||||
+ const struct ieee80211_color_change_settings *cca)
|
||||
{
|
||||
struct beacon_data *new, *old;
|
||||
int new_head_len, new_tail_len;
|
||||
@@ -1003,6 +1008,9 @@ static int ieee80211_assign_beacon(struc
|
||||
memcpy(new->cntdwn_counter_offsets, csa->counter_offsets_beacon,
|
||||
csa->n_counter_offsets_beacon *
|
||||
sizeof(new->cntdwn_counter_offsets[0]));
|
||||
+ } else if (cca) {
|
||||
+ new->cntdwn_current_counter = cca->count;
|
||||
+ new->cntdwn_counter_offsets[0] = cca->counter_offset_beacon;
|
||||
}
|
||||
|
||||
/* copy in head */
|
||||
@@ -1019,7 +1027,7 @@ static int ieee80211_assign_beacon(struc
|
||||
memcpy(new->tail, old->tail, new_tail_len);
|
||||
|
||||
err = ieee80211_set_probe_resp(sdata, params->probe_resp,
|
||||
- params->probe_resp_len, csa);
|
||||
+ params->probe_resp_len, csa, cca);
|
||||
if (err < 0) {
|
||||
kfree(new);
|
||||
return err;
|
||||
@@ -1176,7 +1184,7 @@ static int ieee80211_start_ap(struct wip
|
||||
if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL))
|
||||
sdata->vif.bss_conf.beacon_tx_rate = params->beacon_rate;
|
||||
|
||||
- err = ieee80211_assign_beacon(sdata, ¶ms->beacon, NULL);
|
||||
+ err = ieee80211_assign_beacon(sdata, ¶ms->beacon, NULL, NULL);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
changed |= err;
|
||||
@@ -1231,17 +1239,17 @@ static int ieee80211_change_beacon(struc
|
||||
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
- /* don't allow changing the beacon while CSA is in place - offset
|
||||
+ /* don't allow changing the beacon while a countdown is in place - offset
|
||||
* of channel switch counter may change
|
||||
*/
|
||||
- if (sdata->vif.csa_active)
|
||||
+ if (sdata->vif.csa_active || sdata->vif.color_change_active)
|
||||
return -EBUSY;
|
||||
|
||||
old = sdata_dereference(sdata->u.ap.beacon, sdata);
|
||||
if (!old)
|
||||
return -ENOENT;
|
||||
|
||||
- err = ieee80211_assign_beacon(sdata, params, NULL);
|
||||
+ err = ieee80211_assign_beacon(sdata, params, NULL, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
ieee80211_bss_info_change_notify(sdata, err);
|
||||
@@ -3174,7 +3182,7 @@ static int ieee80211_set_after_csa_beaco
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon,
|
||||
- NULL);
|
||||
+ NULL, NULL);
|
||||
kfree(sdata->u.ap.next_beacon);
|
||||
sdata->u.ap.next_beacon = NULL;
|
||||
|
||||
@@ -3340,7 +3348,7 @@ static int ieee80211_set_csa_beacon(stru
|
||||
csa.n_counter_offsets_presp = params->n_counter_offsets_presp;
|
||||
csa.count = params->count;
|
||||
|
||||
- err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa, &csa);
|
||||
+ err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa, &csa, NULL);
|
||||
if (err < 0) {
|
||||
kfree(sdata->u.ap.next_beacon);
|
||||
return err;
|
||||
@@ -3428,6 +3436,15 @@ static int ieee80211_set_csa_beacon(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void ieee80211_color_change_abort(struct ieee80211_sub_if_data *sdata)
|
||||
+{
|
||||
+ sdata->vif.color_change_active = false;
|
||||
+ kfree(sdata->u.ap.next_beacon);
|
||||
+ sdata->u.ap.next_beacon = NULL;
|
||||
+
|
||||
+ cfg80211_color_change_aborted_notify(sdata->dev);
|
||||
+}
|
||||
+
|
||||
static int
|
||||
__ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_csa_settings *params)
|
||||
@@ -3496,6 +3513,10 @@ __ieee80211_channel_switch(struct wiphy
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ /* if there is a color change in progress, abort it */
|
||||
+ if (sdata->vif.color_change_active)
|
||||
+ ieee80211_color_change_abort(sdata);
|
||||
+
|
||||
err = ieee80211_set_csa_beacon(sdata, params, &changed);
|
||||
if (err) {
|
||||
ieee80211_vif_unreserve_chanctx(sdata);
|
||||
@@ -4147,6 +4168,196 @@ static int ieee80211_set_sar_specs(struc
|
||||
return local->ops->set_sar_specs(&local->hw, sar);
|
||||
}
|
||||
|
||||
+static int
|
||||
+ieee80211_set_after_color_change_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
+ u32 *changed)
|
||||
+{
|
||||
+ switch (sdata->vif.type) {
|
||||
+ case NL80211_IFTYPE_AP: {
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon,
|
||||
+ NULL, NULL);
|
||||
+ kfree(sdata->u.ap.next_beacon);
|
||||
+ sdata->u.ap.next_beacon = NULL;
|
||||
+
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ *changed |= ret;
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ WARN_ON_ONCE(1);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ieee80211_set_color_change_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct cfg80211_color_change_settings *params,
|
||||
+ u32 *changed)
|
||||
+{
|
||||
+ struct ieee80211_color_change_settings color_change = {};
|
||||
+ int err;
|
||||
+
|
||||
+ switch (sdata->vif.type) {
|
||||
+ case NL80211_IFTYPE_AP:
|
||||
+ sdata->u.ap.next_beacon =
|
||||
+ cfg80211_beacon_dup(¶ms->beacon_next);
|
||||
+ if (!sdata->u.ap.next_beacon)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (params->count <= 1)
|
||||
+ break;
|
||||
+
|
||||
+ color_change.counter_offset_beacon =
|
||||
+ params->counter_offset_beacon;
|
||||
+ color_change.counter_offset_presp =
|
||||
+ params->counter_offset_presp;
|
||||
+ color_change.count = params->count;
|
||||
+
|
||||
+ err = ieee80211_assign_beacon(sdata, ¶ms->beacon_color_change,
|
||||
+ NULL, &color_change);
|
||||
+ if (err < 0) {
|
||||
+ kfree(sdata->u.ap.next_beacon);
|
||||
+ return err;
|
||||
+ }
|
||||
+ *changed |= err;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_color_change_bss_config_notify(struct ieee80211_sub_if_data *sdata,
|
||||
+ u8 color, int enable, u32 changed)
|
||||
+{
|
||||
+ sdata->vif.bss_conf.he_bss_color.color = color;
|
||||
+ sdata->vif.bss_conf.he_bss_color.enabled = enable;
|
||||
+ changed |= BSS_CHANGED_HE_BSS_COLOR;
|
||||
+
|
||||
+ ieee80211_bss_info_change_notify(sdata, changed);
|
||||
+}
|
||||
+
|
||||
+static int ieee80211_color_change_finalize(struct ieee80211_sub_if_data *sdata)
|
||||
+{
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ u32 changed = 0;
|
||||
+ int err;
|
||||
+
|
||||
+ sdata_assert_lock(sdata);
|
||||
+ lockdep_assert_held(&local->mtx);
|
||||
+
|
||||
+ sdata->vif.color_change_active = false;
|
||||
+
|
||||
+ err = ieee80211_set_after_color_change_beacon(sdata, &changed);
|
||||
+ if (err) {
|
||||
+ cfg80211_color_change_aborted_notify(sdata->dev);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ ieee80211_color_change_bss_config_notify(sdata,
|
||||
+ sdata->vif.color_change_color,
|
||||
+ 1, changed);
|
||||
+ cfg80211_color_change_notify(sdata->dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void ieee80211_color_change_finalize_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct ieee80211_sub_if_data *sdata =
|
||||
+ container_of(work, struct ieee80211_sub_if_data,
|
||||
+ color_change_finalize_work);
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+
|
||||
+ sdata_lock(sdata);
|
||||
+ mutex_lock(&local->mtx);
|
||||
+
|
||||
+ /* AP might have been stopped while waiting for the lock. */
|
||||
+ if (!sdata->vif.color_change_active)
|
||||
+ goto unlock;
|
||||
+
|
||||
+ if (!ieee80211_sdata_running(sdata))
|
||||
+ goto unlock;
|
||||
+
|
||||
+ ieee80211_color_change_finalize(sdata);
|
||||
+
|
||||
+unlock:
|
||||
+ mutex_unlock(&local->mtx);
|
||||
+ sdata_unlock(sdata);
|
||||
+}
|
||||
+
|
||||
+void ieee80211_color_change_finish(struct ieee80211_vif *vif)
|
||||
+{
|
||||
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||
+
|
||||
+ ieee80211_queue_work(&sdata->local->hw,
|
||||
+ &sdata->color_change_finalize_work);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ieee80211_color_change_finish);
|
||||
+
|
||||
+void
|
||||
+ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
|
||||
+ u64 color_bitmap)
|
||||
+{
|
||||
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||
+
|
||||
+ if (sdata->vif.color_change_active || sdata->vif.csa_active)
|
||||
+ return;
|
||||
+
|
||||
+ cfg80211_obss_color_collision_notify(sdata->dev, color_bitmap);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ieeee80211_obss_color_collision_notify);
|
||||
+
|
||||
+static int
|
||||
+ieee80211_color_change(struct wiphy *wiphy, struct net_device *dev,
|
||||
+ struct cfg80211_color_change_settings *params)
|
||||
+{
|
||||
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ u32 changed = 0;
|
||||
+ int err;
|
||||
+
|
||||
+ sdata_assert_lock(sdata);
|
||||
+
|
||||
+ mutex_lock(&local->mtx);
|
||||
+
|
||||
+ /* don't allow another color change if one is already active or if csa
|
||||
+ * is active
|
||||
+ */
|
||||
+ if (sdata->vif.color_change_active || sdata->vif.csa_active) {
|
||||
+ err = -EBUSY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ err = ieee80211_set_color_change_beacon(sdata, params, &changed);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+
|
||||
+ sdata->vif.color_change_active = true;
|
||||
+ sdata->vif.color_change_color = params->color;
|
||||
+
|
||||
+ cfg80211_color_change_started_notify(sdata->dev, params->count);
|
||||
+
|
||||
+ if (changed)
|
||||
+ ieee80211_color_change_bss_config_notify(sdata, 0, 0, changed);
|
||||
+ else
|
||||
+ /* if the beacon didn't change, we can finalize immediately */
|
||||
+ ieee80211_color_change_finalize(sdata);
|
||||
+
|
||||
+out:
|
||||
+ mutex_unlock(&local->mtx);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
const struct cfg80211_ops mac80211_config_ops = {
|
||||
.add_virtual_intf = ieee80211_add_iface,
|
||||
.del_virtual_intf = ieee80211_del_iface,
|
||||
@@ -4251,4 +4462,5 @@ const struct cfg80211_ops mac80211_confi
|
||||
.set_tid_config = ieee80211_set_tid_config,
|
||||
.reset_tid_config = ieee80211_reset_tid_config,
|
||||
.set_sar_specs = ieee80211_set_sar_specs,
|
||||
+ .color_change = ieee80211_color_change,
|
||||
};
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -248,6 +248,12 @@ struct ieee80211_csa_settings {
|
||||
u8 count;
|
||||
};
|
||||
|
||||
+struct ieee80211_color_change_settings {
|
||||
+ u16 counter_offset_beacon;
|
||||
+ u16 counter_offset_presp;
|
||||
+ u8 count;
|
||||
+};
|
||||
+
|
||||
struct beacon_data {
|
||||
u8 *head, *tail;
|
||||
int head_len, tail_len;
|
||||
@@ -932,6 +938,8 @@ struct ieee80211_sub_if_data {
|
||||
bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */
|
||||
struct cfg80211_chan_def csa_chandef;
|
||||
|
||||
+ struct work_struct color_change_finalize_work;
|
||||
+
|
||||
struct list_head assigned_chanctx_list; /* protected by chanctx_mtx */
|
||||
struct list_head reserved_chanctx_list; /* protected by chanctx_mtx */
|
||||
|
||||
@@ -1900,6 +1908,9 @@ void ieee80211_csa_finalize_work(struct
|
||||
int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_csa_settings *params);
|
||||
|
||||
+/* color change handling */
|
||||
+void ieee80211_color_change_finalize_work(struct work_struct *work);
|
||||
+
|
||||
/* interface handling */
|
||||
#define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
|
||||
NETIF_F_HW_CSUM | NETIF_F_SG | \
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -465,6 +465,7 @@ static void ieee80211_do_stop(struct iee
|
||||
sdata_unlock(sdata);
|
||||
|
||||
cancel_work_sync(&sdata->csa_finalize_work);
|
||||
+ cancel_work_sync(&sdata->color_change_finalize_work);
|
||||
|
||||
cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
|
||||
|
||||
@@ -1639,6 +1640,7 @@ static void ieee80211_setup_sdata(struct
|
||||
INIT_WORK(&sdata->work, ieee80211_iface_work);
|
||||
INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work);
|
||||
INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);
|
||||
+ INIT_WORK(&sdata->color_change_finalize_work, ieee80211_color_change_finalize_work);
|
||||
INIT_LIST_HEAD(&sdata->assigned_chanctx_list);
|
||||
INIT_LIST_HEAD(&sdata->reserved_chanctx_list);
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -4802,11 +4802,11 @@ static int ieee80211_beacon_add_tim(stru
|
||||
static void ieee80211_set_beacon_cntdwn(struct ieee80211_sub_if_data *sdata,
|
||||
struct beacon_data *beacon)
|
||||
{
|
||||
+ u8 *beacon_data, count, max_count = 1;
|
||||
struct probe_resp *resp;
|
||||
- u8 *beacon_data;
|
||||
size_t beacon_data_len;
|
||||
+ u16 *bcn_offsets;
|
||||
int i;
|
||||
- u8 count = beacon->cntdwn_current_counter;
|
||||
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
@@ -4826,21 +4826,27 @@ static void ieee80211_set_beacon_cntdwn(
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
- for (i = 0; i < IEEE80211_MAX_CNTDWN_COUNTERS_NUM; ++i) {
|
||||
- resp = rcu_dereference(sdata->u.ap.probe_resp);
|
||||
+ resp = rcu_dereference(sdata->u.ap.probe_resp);
|
||||
|
||||
- if (beacon->cntdwn_counter_offsets[i]) {
|
||||
- if (WARN_ON_ONCE(beacon->cntdwn_counter_offsets[i] >=
|
||||
- beacon_data_len)) {
|
||||
+ bcn_offsets = beacon->cntdwn_counter_offsets;
|
||||
+ count = beacon->cntdwn_current_counter;
|
||||
+ if (sdata->vif.csa_active)
|
||||
+ max_count = IEEE80211_MAX_CNTDWN_COUNTERS_NUM;
|
||||
+
|
||||
+ for (i = 0; i < max_count; ++i) {
|
||||
+ if (bcn_offsets[i]) {
|
||||
+ if (WARN_ON_ONCE(bcn_offsets[i] >= beacon_data_len)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
-
|
||||
- beacon_data[beacon->cntdwn_counter_offsets[i]] = count;
|
||||
+ beacon_data[bcn_offsets[i]] = count;
|
||||
}
|
||||
|
||||
- if (sdata->vif.type == NL80211_IFTYPE_AP && resp)
|
||||
- resp->data[resp->cntdwn_counter_offsets[i]] = count;
|
||||
+ if (sdata->vif.type == NL80211_IFTYPE_AP && resp) {
|
||||
+ u16 *resp_offsets = resp->cntdwn_counter_offsets;
|
||||
+
|
||||
+ resp->data[resp_offsets[i]] = count;
|
||||
+ }
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
@@ -5050,6 +5056,7 @@ __ieee80211_beacon_get(struct ieee80211_
|
||||
if (offs) {
|
||||
offs->tim_offset = beacon->head_len;
|
||||
offs->tim_length = skb->len - beacon->head_len;
|
||||
+ offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0];
|
||||
|
||||
/* for AP the csa offsets are from tail */
|
||||
csa_off_base = skb->len;
|
@ -1,33 +0,0 @@
|
||||
--- /dev/null
|
||||
+++ b/include/linux/ath5k_platform.h
|
||||
@@ -0,0 +1,30 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2008 Atheros Communications Inc.
|
||||
+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
|
||||
+ * Copyright (c) 2010 Daniel Golle <daniel.golle@gmail.com>
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and/or distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _LINUX_ATH5K_PLATFORM_H
|
||||
+#define _LINUX_ATH5K_PLATFORM_H
|
||||
+
|
||||
+#define ATH5K_PLAT_EEP_MAX_WORDS 2048
|
||||
+
|
||||
+struct ath5k_platform_data {
|
||||
+ u16 *eeprom_data;
|
||||
+ u8 *macaddr;
|
||||
+};
|
||||
+
|
||||
+#endif /* _LINUX_ATH5K_PLATFORM_H */
|
@ -1,47 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath10k/Kconfig
|
||||
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
|
||||
@@ -86,6 +86,12 @@ config ATH10K_TRACING
|
||||
help
|
||||
Select this to ath10k use tracing infrastructure.
|
||||
|
||||
+config ATH10K_THERMAL
|
||||
+ bool "Atheros ath10k thermal monitoring support"
|
||||
+ depends on THERMAL
|
||||
+ ---help---
|
||||
+ Select this to ath10k use hwmon for thermal measurement.
|
||||
+
|
||||
config ATH10K_DFS_CERTIFIED
|
||||
bool "Atheros DFS support for certified platforms"
|
||||
depends on ATH10K && CFG80211_CERTIFICATION_ONUS
|
||||
--- a/drivers/net/wireless/ath/ath10k/Makefile
|
||||
+++ b/drivers/net/wireless/ath/ath10k/Makefile
|
||||
@@ -18,7 +18,7 @@ ath10k_core-y += mac.o \
|
||||
ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += spectral.o
|
||||
ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o
|
||||
ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o
|
||||
-ath10k_core-$(CONFIG_THERMAL) += thermal.o
|
||||
+ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o
|
||||
ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o
|
||||
ath10k_core-$(CONFIG_PM) += wow.o
|
||||
ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o
|
||||
--- a/drivers/net/wireless/ath/ath10k/thermal.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/thermal.h
|
||||
@@ -25,7 +25,7 @@ struct ath10k_thermal {
|
||||
int temperature;
|
||||
};
|
||||
|
||||
-#if IS_REACHABLE(CONFIG_THERMAL)
|
||||
+#if IS_REACHABLE(CPTCFG_ATH10K_THERMAL)
|
||||
int ath10k_thermal_register(struct ath10k *ar);
|
||||
void ath10k_thermal_unregister(struct ath10k *ar);
|
||||
void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature);
|
||||
--- a/local-symbols
|
||||
+++ b/local-symbols
|
||||
@@ -142,6 +142,7 @@ ATH10K_SNOC=
|
||||
ATH10K_DEBUG=
|
||||
ATH10K_DEBUGFS=
|
||||
ATH10K_SPECTRAL=
|
||||
+ATH10K_THERMAL=
|
||||
ATH10K_TRACING=
|
||||
ATH10K_DFS_CERTIFIED=
|
||||
WCN36XX=
|
@ -1,86 +0,0 @@
|
||||
--- a/drivers/net/wireless/broadcom/b43/Makefile
|
||||
+++ b/drivers/net/wireless/broadcom/b43/Makefile
|
||||
@@ -18,7 +18,7 @@ b43-$(CPTCFG_B43_PHY_AC) += phy_ac.o
|
||||
b43-y += sysfs.o
|
||||
b43-y += xmit.o
|
||||
b43-y += dma.o
|
||||
-b43-y += pio.o
|
||||
+b43-$(CPTCFG_B43_PIO) += pio.o
|
||||
b43-y += rfkill.o
|
||||
b43-y += ppr.o
|
||||
b43-$(CPTCFG_B43_LEDS) += leds.o
|
||||
--- a/drivers/net/wireless/broadcom/b43/main.c
|
||||
+++ b/drivers/net/wireless/broadcom/b43/main.c
|
||||
@@ -2001,10 +2001,12 @@ static void b43_do_interrupt_thread(stru
|
||||
dma_reason[0], dma_reason[1],
|
||||
dma_reason[2], dma_reason[3],
|
||||
dma_reason[4], dma_reason[5]);
|
||||
+#ifdef CPTCFG_B43_PIO
|
||||
b43err(dev->wl, "This device does not support DMA "
|
||||
"on your system. It will now be switched to PIO.\n");
|
||||
/* Fall back to PIO transfers if we get fatal DMA errors! */
|
||||
dev->use_pio = true;
|
||||
+#endif
|
||||
b43_controller_restart(dev, "DMA error");
|
||||
return;
|
||||
}
|
||||
--- a/drivers/net/wireless/broadcom/b43/pio.h
|
||||
+++ b/drivers/net/wireless/broadcom/b43/pio.h
|
||||
@@ -151,7 +151,7 @@ static inline void b43_piorx_write32(str
|
||||
b43_write32(q->dev, q->mmio_base + offset, value);
|
||||
}
|
||||
|
||||
-
|
||||
+#ifdef CPTCFG_B43_PIO
|
||||
int b43_pio_init(struct b43_wldev *dev);
|
||||
void b43_pio_free(struct b43_wldev *dev);
|
||||
|
||||
@@ -162,5 +162,37 @@ void b43_pio_rx(struct b43_pio_rxqueue *
|
||||
|
||||
void b43_pio_tx_suspend(struct b43_wldev *dev);
|
||||
void b43_pio_tx_resume(struct b43_wldev *dev);
|
||||
+#else
|
||||
+static inline int b43_pio_init(struct b43_wldev *dev)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline void b43_pio_free(struct b43_wldev *dev)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline void b43_pio_handle_txstatus(struct b43_wldev *dev,
|
||||
+ const struct b43_txstatus *status)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void b43_pio_rx(struct b43_pio_rxqueue *q)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void b43_pio_tx_suspend(struct b43_wldev *dev)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void b43_pio_tx_resume(struct b43_wldev *dev)
|
||||
+{
|
||||
+}
|
||||
+#endif /* CPTCFG_B43_PIO */
|
||||
|
||||
#endif /* B43_PIO_H_ */
|
||||
--- a/drivers/net/wireless/broadcom/b43/Kconfig
|
||||
+++ b/drivers/net/wireless/broadcom/b43/Kconfig
|
||||
@@ -100,7 +100,7 @@ config B43_BCMA_PIO
|
||||
default y
|
||||
|
||||
config B43_PIO
|
||||
- bool
|
||||
+ bool "Broadcom 43xx PIO support"
|
||||
depends on B43 && B43_SSB
|
||||
depends on SSB_BLOCKIO
|
||||
default y
|
@ -1,116 +0,0 @@
|
||||
From: Markus Theil <markus.theil@tu-ilmenau.de>
|
||||
Date: Sat, 6 Feb 2021 12:51:12 +0100
|
||||
Subject: [PATCH] mac80211: enable QoS support for nl80211 ctrl port
|
||||
|
||||
This patch unifies sending control port frames
|
||||
over nl80211 and AF_PACKET sockets a little more.
|
||||
|
||||
Before this patch, EAPOL frames got QoS prioritization
|
||||
only when using AF_PACKET sockets.
|
||||
|
||||
__ieee80211_select_queue only selects a QoS-enabled queue
|
||||
for control port frames, when the control port protocol
|
||||
is set correctly on the skb. For the AF_PACKET path this
|
||||
works, but the nl80211 path used ETH_P_802_3.
|
||||
|
||||
Another check for injected frames in wme.c then prevented
|
||||
the QoS TID to be copied in the frame.
|
||||
|
||||
In order to fix this, get rid of the frame injection marking
|
||||
for nl80211 ctrl port and set the correct ethernet protocol.
|
||||
|
||||
Please note:
|
||||
An erlier version of this path tried to prevent
|
||||
frame aggregation for control port frames in order to speed up
|
||||
the initial connection setup a little. This seemed to cause
|
||||
issues on my older Intel dvm-based hardware, and was therefore
|
||||
removed again. Future commits which try to reintroduce this
|
||||
have to check carefully how hw behaves with aggregated and
|
||||
non-aggregated traffic for the same TID.
|
||||
My NIC: Intel(R) Centrino(R) Ultimate-N 6300 AGN, REV=0x74
|
||||
|
||||
Reported-by: kernel test robot <lkp@intel.com>
|
||||
Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
|
||||
Link: https://lore.kernel.org/r/20210206115112.567881-1-markus.theil@tu-ilmenau.de
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/status.c
|
||||
+++ b/net/mac80211/status.c
|
||||
@@ -628,16 +628,12 @@ static void ieee80211_report_ack_skb(str
|
||||
u64 cookie = IEEE80211_SKB_CB(skb)->ack.cookie;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
- __be16 ethertype = 0;
|
||||
-
|
||||
- if (skb->len >= ETH_HLEN && skb->protocol == cpu_to_be16(ETH_P_802_3))
|
||||
- skb_copy_bits(skb, 2 * ETH_ALEN, ðertype, ETH_TLEN);
|
||||
|
||||
rcu_read_lock();
|
||||
sdata = ieee80211_sdata_from_skb(local, skb);
|
||||
if (sdata) {
|
||||
- if (ethertype == sdata->control_port_protocol ||
|
||||
- ethertype == cpu_to_be16(ETH_P_PREAUTH))
|
||||
+ if (skb->protocol == sdata->control_port_protocol ||
|
||||
+ skb->protocol == cpu_to_be16(ETH_P_PREAUTH))
|
||||
cfg80211_control_port_tx_status(&sdata->wdev,
|
||||
cookie,
|
||||
skb->data,
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -1195,9 +1195,7 @@ ieee80211_tx_prepare(struct ieee80211_su
|
||||
tx->sta = rcu_dereference(sdata->u.vlan.sta);
|
||||
if (!tx->sta && sdata->wdev.use_4addr)
|
||||
return TX_DROP;
|
||||
- } else if (info->flags & (IEEE80211_TX_INTFL_NL80211_FRAME_TX |
|
||||
- IEEE80211_TX_CTL_INJECTED) ||
|
||||
- tx->sdata->control_port_protocol == tx->skb->protocol) {
|
||||
+ } else if (tx->sdata->control_port_protocol == tx->skb->protocol) {
|
||||
tx->sta = sta_info_get_bss(sdata, hdr->addr1);
|
||||
}
|
||||
if (!tx->sta && !is_multicast_ether_addr(hdr->addr1))
|
||||
@@ -5455,6 +5453,7 @@ int ieee80211_tx_control_port(struct wip
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
+ struct sta_info *sta;
|
||||
struct sk_buff *skb;
|
||||
struct ethhdr *ehdr;
|
||||
u32 ctrl_flags = 0;
|
||||
@@ -5477,8 +5476,7 @@ int ieee80211_tx_control_port(struct wip
|
||||
if (cookie)
|
||||
ctrl_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
|
||||
- flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX |
|
||||
- IEEE80211_TX_CTL_INJECTED;
|
||||
+ flags |= IEEE80211_TX_INTFL_NL80211_FRAME_TX;
|
||||
|
||||
skb = dev_alloc_skb(local->hw.extra_tx_headroom +
|
||||
sizeof(struct ethhdr) + len);
|
||||
@@ -5495,10 +5493,25 @@ int ieee80211_tx_control_port(struct wip
|
||||
ehdr->h_proto = proto;
|
||||
|
||||
skb->dev = dev;
|
||||
- skb->protocol = htons(ETH_P_802_3);
|
||||
+ skb->protocol = proto;
|
||||
skb_reset_network_header(skb);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
+ /* update QoS header to prioritize control port frames if possible,
|
||||
+ * priorization also happens for control port frames send over
|
||||
+ * AF_PACKET
|
||||
+ */
|
||||
+ rcu_read_lock();
|
||||
+
|
||||
+ if (ieee80211_lookup_ra_sta(sdata, skb, &sta) == 0 && !IS_ERR(sta)) {
|
||||
+ u16 queue = __ieee80211_select_queue(sdata, sta, skb);
|
||||
+
|
||||
+ skb_set_queue_mapping(skb, queue);
|
||||
+ skb_get_hash(skb);
|
||||
+ }
|
||||
+
|
||||
+ rcu_read_unlock();
|
||||
+
|
||||
/* mutex lock is only needed for incrementing the cookie counter */
|
||||
mutex_lock(&local->mtx);
|
||||
|
@ -1,35 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Mon, 22 Nov 2021 21:39:38 +0100
|
||||
Subject: [PATCH] mac80211: fix rate control for retransmitted frames
|
||||
|
||||
Since retransmission clears info->control, rate control needs to be called
|
||||
again, otherwise the driver might crash due to invalid rates.
|
||||
|
||||
Cc: stable@vger.kernel.org # 5.14+
|
||||
Reported-by: Aaro Koskinen <aaro.koskinen@iki.fi>
|
||||
Reported-by: Robert W <rwbugreport@lost-in-the-void.net>
|
||||
Fixes: 03c3911d2d67 ("mac80211: call ieee80211_tx_h_rate_ctrl() when dequeue")
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -1835,15 +1835,15 @@ static int invoke_tx_handlers_late(struc
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
||||
ieee80211_tx_result res = TX_CONTINUE;
|
||||
|
||||
+ if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
|
||||
+ CALL_TXH(ieee80211_tx_h_rate_ctrl);
|
||||
+
|
||||
if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION)) {
|
||||
__skb_queue_tail(&tx->skbs, tx->skb);
|
||||
tx->skb = NULL;
|
||||
goto txh_done;
|
||||
}
|
||||
|
||||
- if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
|
||||
- CALL_TXH(ieee80211_tx_h_rate_ctrl);
|
||||
-
|
||||
CALL_TXH(ieee80211_tx_h_michael_mic_add);
|
||||
CALL_TXH(ieee80211_tx_h_sequence);
|
||||
CALL_TXH(ieee80211_tx_h_fragment);
|
@ -1,148 +0,0 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Fri, 9 Apr 2021 12:40:20 +0300
|
||||
Subject: [PATCH] wireless: align HE capabilities A-MPDU Length Exponent
|
||||
Extension
|
||||
|
||||
The A-MPDU length exponent extension is defined differently in
|
||||
802.11ax D6.1, align with that.
|
||||
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
Link: https://lore.kernel.org/r/iwlwifi.20210409123755.c2a257d3e2df.I3455245d388c52c61dace7e7958dbed7e807cfb6@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -1290,9 +1290,8 @@ static void ath11k_peer_assoc_h_he(struc
|
||||
* request, then use MAX_AMPDU_LEN_FACTOR as 16 to calculate max_ampdu
|
||||
* length.
|
||||
*/
|
||||
- ampdu_factor = (he_cap->he_cap_elem.mac_cap_info[3] &
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) >>
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_SHIFT;
|
||||
+ ampdu_factor = u8_get_bits(he_cap->he_cap_elem.mac_cap_info[3],
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK);
|
||||
|
||||
if (ampdu_factor) {
|
||||
if (sta->vht_cap.vht_supported)
|
||||
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
@@ -596,7 +596,7 @@ static struct ieee80211_sband_iftype_dat
|
||||
IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2,
|
||||
.mac_cap_info[4] =
|
||||
IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU |
|
||||
IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39,
|
||||
@@ -680,7 +680,7 @@ static struct ieee80211_sband_iftype_dat
|
||||
IEEE80211_HE_MAC_CAP2_BSR,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2,
|
||||
.mac_cap_info[4] =
|
||||
IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.mac_cap_info[5] =
|
||||
--- a/drivers/net/wireless/mac80211_hwsim.c
|
||||
+++ b/drivers/net/wireless/mac80211_hwsim.c
|
||||
@@ -2747,7 +2747,7 @@ static const struct ieee80211_sband_ifty
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
|
||||
.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
|
||||
@@ -2791,7 +2791,7 @@ static const struct ieee80211_sband_ifty
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
|
||||
.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
|
||||
@@ -2837,7 +2837,7 @@ static const struct ieee80211_sband_ifty
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
|
||||
.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
@@ -2885,7 +2885,7 @@ static const struct ieee80211_sband_ifty
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
|
||||
.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
@@ -425,7 +425,7 @@ mt7915_init_he_caps(struct mt7915_phy *p
|
||||
IEEE80211_HE_MAC_CAP0_HTC_HE;
|
||||
he_cap_elem->mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED;
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3;
|
||||
he_cap_elem->mac_cap_info[4] =
|
||||
IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU;
|
||||
|
||||
--- a/include/linux/ieee80211.h
|
||||
+++ b/include/linux/ieee80211.h
|
||||
@@ -2051,17 +2051,15 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
* A-MDPU Length Exponent field in the HT capabilities, VHT capabilities and the
|
||||
* same field in the HE capabilities.
|
||||
*/
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_USE_VHT 0x00
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_1 0x08
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2 0x10
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED 0x18
|
||||
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_0 0x00
|
||||
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1 0x08
|
||||
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2 0x10
|
||||
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3 0x18
|
||||
#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK 0x18
|
||||
#define IEEE80211_HE_MAC_CAP3_AMSDU_FRAG 0x20
|
||||
#define IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED 0x40
|
||||
#define IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS 0x80
|
||||
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_SHIFT 3
|
||||
-
|
||||
#define IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG 0x01
|
||||
#define IEEE80211_HE_MAC_CAP4_QTP 0x02
|
||||
#define IEEE80211_HE_MAC_CAP4_BQR 0x04
|
||||
--- a/net/mac80211/debugfs_sta.c
|
||||
+++ b/net/mac80211/debugfs_sta.c
|
||||
@@ -711,17 +711,17 @@ static ssize_t sta_he_capa_read(struct f
|
||||
PFLAG(MAC, 3, OFDMA_RA, "OFDMA-RA");
|
||||
|
||||
switch (cap[3] & IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) {
|
||||
- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_USE_VHT:
|
||||
- PRINT("MAX-AMPDU-LEN-EXP-USE-VHT");
|
||||
+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_0:
|
||||
+ PRINT("MAX-AMPDU-LEN-EXP-USE-EXT-0");
|
||||
break;
|
||||
- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_1:
|
||||
- PRINT("MAX-AMPDU-LEN-EXP-VHT-1");
|
||||
+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1:
|
||||
+ PRINT("MAX-AMPDU-LEN-EXP-VHT-EXT-1");
|
||||
break;
|
||||
- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2:
|
||||
- PRINT("MAX-AMPDU-LEN-EXP-VHT-2");
|
||||
+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2:
|
||||
+ PRINT("MAX-AMPDU-LEN-EXP-VHT-EXT-2");
|
||||
break;
|
||||
- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED:
|
||||
- PRINT("MAX-AMPDU-LEN-EXP-RESERVED");
|
||||
+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3:
|
||||
+ PRINT("MAX-AMPDU-LEN-EXP-VHT-EXT-3");
|
||||
break;
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -1344,7 +1344,7 @@ static inline void rt2x00lib_set_if_comb
|
||||
*/
|
||||
if_limit = &rt2x00dev->if_limits_ap;
|
||||
if_limit->max = rt2x00dev->ops->max_ap_intf;
|
||||
- if_limit->types = BIT(NL80211_IFTYPE_AP);
|
||||
+ if_limit->types = BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_STATION);
|
||||
#ifdef CPTCFG_MAC80211_MESH
|
||||
if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT);
|
||||
#endif
|
@ -1,90 +0,0 @@
|
||||
PKG_DRIVERS += \
|
||||
libertas-sdio libertas-usb libertas-spi \
|
||||
mwl8k mwifiex-pcie mwifiex-sdio
|
||||
|
||||
config-$(call config_package,libertas-sdio) += LIBERTAS LIBERTAS_SDIO
|
||||
config-$(call config_package,libertas-usb) += LIBERTAS LIBERTAS_USB
|
||||
config-$(call config_package,libertas-spi) += LIBERTAS LIBERTAS_SPI
|
||||
config-$(call config_package,mwl8k) += MWL8K
|
||||
config-$(call config_package,mwifiex-pcie) += MWIFIEX MWIFIEX_PCIE
|
||||
config-$(call config_package,mwifiex-sdio) += MWIFIEX MWIFIEX_SDIO
|
||||
|
||||
define KernelPackage/libertas-usb
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +kmod-usb-core +kmod-lib80211 +@DRIVER_WEXT_SUPPORT +libertas-usb-firmware
|
||||
TITLE:=Marvell 88W8015 Wireless Driver
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/usb8xxx.ko
|
||||
AUTOLOAD:=$(call AutoProbe,libertas usb8xxx)
|
||||
endef
|
||||
|
||||
define KernelPackage/libertas-sdio
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +kmod-mmc +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-sdio-firmware
|
||||
TITLE:=Marvell 88W8686 Wireless Driver
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas_sdio.ko
|
||||
AUTOLOAD:=$(call AutoProbe,libertas libertas_sdio)
|
||||
endef
|
||||
|
||||
define KernelPackage/libertas-spi
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
SUBMENU:=Wireless Drivers
|
||||
DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-spi-firmware
|
||||
KCONFIG := \
|
||||
CONFIG_SPI=y \
|
||||
CONFIG_SPI_MASTER=y
|
||||
TITLE:=Marvell 88W8686 SPI Wireless Driver
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas_spi.ko
|
||||
AUTOLOAD:=$(call AutoProbe,libertas libertas_spi)
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/mwl8k
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Driver for Marvell TOPDOG 802.11 Wireless cards
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwl8k
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +@DRIVER_11N_SUPPORT +mwl8k-firmware
|
||||
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwl8k.ko
|
||||
AUTOLOAD:=$(call AutoProbe,mwl8k)
|
||||
endef
|
||||
|
||||
define KernelPackage/mwl8k/description
|
||||
Kernel modules for Marvell TOPDOG 802.11 Wireless cards
|
||||
endef
|
||||
|
||||
|
||||
define KernelPackage/mwifiex-pcie
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Driver for Marvell 802.11n/802.11ac PCIe Wireless cards
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwifiex
|
||||
DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +mwifiex-pcie-firmware
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex_pcie.ko
|
||||
AUTOLOAD:=$(call AutoProbe,mwifiex_pcie)
|
||||
endef
|
||||
|
||||
define KernelPackage/mwifiex-pcie/description
|
||||
Kernel modules for Marvell 802.11n/802.11ac PCIe Wireless cards
|
||||
endef
|
||||
|
||||
define KernelPackage/mwifiex-sdio
|
||||
$(call KernelPackage/mac80211/Default)
|
||||
TITLE:=Driver for Marvell 802.11n/802.11ac SDIO Wireless cards
|
||||
URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwifiex
|
||||
DEPENDS+= +kmod-mmc +kmod-mac80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +mwifiex-sdio-firmware
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex.ko \
|
||||
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex_sdio.ko
|
||||
AUTOLOAD:=$(call AutoProbe,mwifiex_sdio)
|
||||
endef
|
||||
|
||||
define KernelPackage/mwifiex-sdio/description
|
||||
Kernel modules for Marvell 802.11n/802.11ac SDIO Wireless cards
|
||||
endef
|
||||
|
@ -1,183 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -1238,6 +1238,8 @@ void rt2800_watchdog(struct rt2x00_dev *
|
||||
if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags))
|
||||
return;
|
||||
|
||||
+ rt2800_update_survey(rt2x00dev);
|
||||
+
|
||||
queue_for_each(rt2x00dev, queue) {
|
||||
switch (queue->qid) {
|
||||
case QID_AC_VO:
|
||||
@@ -1274,6 +1276,18 @@ void rt2800_watchdog(struct rt2x00_dev *
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_watchdog);
|
||||
|
||||
+void rt2800_update_survey(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ struct ieee80211_channel *chan = rt2x00dev->hw->conf.chandef.chan;
|
||||
+ struct rt2x00_chan_survey *chan_survey =
|
||||
+ &rt2x00dev->chan_survey[chan->hw_value];
|
||||
+
|
||||
+ chan_survey->time_idle += rt2800_register_read(rt2x00dev, CH_IDLE_STA);
|
||||
+ chan_survey->time_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA);
|
||||
+ chan_survey->time_ext_busy += rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(rt2800_update_survey);
|
||||
+
|
||||
static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
|
||||
unsigned int index)
|
||||
{
|
||||
@@ -12199,26 +12213,30 @@ int rt2800_get_survey(struct ieee80211_h
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
- u32 idle, busy, busy_ext;
|
||||
+ struct rt2x00_chan_survey *chan_survey =
|
||||
+ &rt2x00dev->chan_survey[idx];
|
||||
+ enum nl80211_band band = NL80211_BAND_2GHZ;
|
||||
|
||||
- if (idx != 0)
|
||||
+ if (idx >= rt2x00dev->bands[band].n_channels) {
|
||||
+ idx -= rt2x00dev->bands[band].n_channels;
|
||||
+ band = NL80211_BAND_5GHZ;
|
||||
+ }
|
||||
+
|
||||
+ if (idx >= rt2x00dev->bands[band].n_channels)
|
||||
return -ENOENT;
|
||||
|
||||
- survey->channel = conf->chandef.chan;
|
||||
+ if (idx == 0)
|
||||
+ rt2800_update_survey(rt2x00dev);
|
||||
|
||||
- idle = rt2800_register_read(rt2x00dev, CH_IDLE_STA);
|
||||
- busy = rt2800_register_read(rt2x00dev, CH_BUSY_STA);
|
||||
- busy_ext = rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC);
|
||||
-
|
||||
- if (idle || busy) {
|
||||
- survey->filled = SURVEY_INFO_TIME |
|
||||
- SURVEY_INFO_TIME_BUSY |
|
||||
- SURVEY_INFO_TIME_EXT_BUSY;
|
||||
-
|
||||
- survey->time = (idle + busy) / 1000;
|
||||
- survey->time_busy = busy / 1000;
|
||||
- survey->time_ext_busy = busy_ext / 1000;
|
||||
- }
|
||||
+ survey->channel = &rt2x00dev->bands[band].channels[idx];
|
||||
+
|
||||
+ survey->filled = SURVEY_INFO_TIME |
|
||||
+ SURVEY_INFO_TIME_BUSY |
|
||||
+ SURVEY_INFO_TIME_EXT_BUSY;
|
||||
+
|
||||
+ survey->time = div_u64(chan_survey->time_idle + chan_survey->time_busy, 1000);
|
||||
+ survey->time_busy = div_u64(chan_survey->time_busy, 1000);
|
||||
+ survey->time_ext_busy = div_u64(chan_survey->time_ext_busy, 1000);
|
||||
|
||||
if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
|
||||
survey->filled |= SURVEY_INFO_IN_USE;
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
@@ -243,6 +243,7 @@ bool rt2800_txstatus_timeout(struct rt2x
|
||||
bool rt2800_txstatus_pending(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
void rt2800_watchdog(struct rt2x00_dev *rt2x00dev);
|
||||
+void rt2800_update_survey(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
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/rt2800pci.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
|
||||
@@ -360,6 +360,7 @@ static const struct rt2x00lib_ops rt2800
|
||||
.gain_calibration = rt2800_gain_calibration,
|
||||
.vco_calibration = rt2800_vco_calibration,
|
||||
.watchdog = rt2800_watchdog,
|
||||
+ .update_survey = rt2800_update_survey,
|
||||
.start_queue = rt2800mmio_start_queue,
|
||||
.kick_queue = rt2800mmio_kick_queue,
|
||||
.stop_queue = rt2800mmio_stop_queue,
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
|
||||
@@ -214,6 +214,7 @@ static const struct rt2x00lib_ops rt2800
|
||||
.gain_calibration = rt2800_gain_calibration,
|
||||
.vco_calibration = rt2800_vco_calibration,
|
||||
.watchdog = rt2800_watchdog,
|
||||
+ .update_survey = rt2800_update_survey,
|
||||
.start_queue = rt2800mmio_start_queue,
|
||||
.kick_queue = rt2800mmio_kick_queue,
|
||||
.stop_queue = rt2800mmio_stop_queue,
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
@@ -183,6 +183,15 @@ struct rf_channel {
|
||||
};
|
||||
|
||||
/*
|
||||
+ * Information structure for channel survey.
|
||||
+ */
|
||||
+struct rt2x00_chan_survey {
|
||||
+ u64 time_idle;
|
||||
+ u64 time_busy;
|
||||
+ u64 time_ext_busy;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
* Channel information structure
|
||||
*/
|
||||
struct channel_info {
|
||||
@@ -567,6 +576,7 @@ struct rt2x00lib_ops {
|
||||
* Data queue handlers.
|
||||
*/
|
||||
void (*watchdog) (struct rt2x00_dev *rt2x00dev);
|
||||
+ void (*update_survey) (struct rt2x00_dev *rt2x00dev);
|
||||
void (*start_queue) (struct data_queue *queue);
|
||||
void (*kick_queue) (struct data_queue *queue);
|
||||
void (*stop_queue) (struct data_queue *queue);
|
||||
@@ -755,6 +765,7 @@ struct rt2x00_dev {
|
||||
*/
|
||||
struct ieee80211_hw *hw;
|
||||
struct ieee80211_supported_band bands[NUM_NL80211_BANDS];
|
||||
+ struct rt2x00_chan_survey *chan_survey;
|
||||
enum nl80211_band curr_band;
|
||||
int curr_freq;
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -1057,6 +1057,12 @@ static int rt2x00lib_probe_hw_modes(stru
|
||||
if (!rates)
|
||||
goto exit_free_channels;
|
||||
|
||||
+ rt2x00dev->chan_survey =
|
||||
+ kcalloc(spec->num_channels, sizeof(struct rt2x00_chan_survey),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!rt2x00dev->chan_survey)
|
||||
+ goto exit_free_rates;
|
||||
+
|
||||
/*
|
||||
* Initialize Rate list.
|
||||
*/
|
||||
@@ -1108,6 +1114,8 @@ static int rt2x00lib_probe_hw_modes(stru
|
||||
|
||||
return 0;
|
||||
|
||||
+ exit_free_rates:
|
||||
+ kfree(rates);
|
||||
exit_free_channels:
|
||||
kfree(channels);
|
||||
rt2x00_err(rt2x00dev, "Allocation ieee80211 modes failed\n");
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c
|
||||
@@ -317,6 +317,15 @@ int rt2x00mac_config(struct ieee80211_hw
|
||||
return 0;
|
||||
|
||||
/*
|
||||
+ * To provide correct survey data for survey-based ACS algorithm
|
||||
+ * we have to save survey data for current channel before switching.
|
||||
+ */
|
||||
+ if (rt2x00dev->ops->lib->update_survey &&
|
||||
+ (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
|
||||
+ rt2x00dev->ops->lib->update_survey(rt2x00dev);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
* Some configuration parameters (e.g. channel and antenna values) can
|
||||
* only be set when the radio is enabled, but do require the RX to
|
||||
* be off. During this period we should keep link tuning enabled,
|
@ -1,398 +0,0 @@
|
||||
From: Carl Huang <cjhuang@codeaurora.org>
|
||||
Date: Thu, 3 Dec 2020 05:37:26 -0500
|
||||
Subject: [PATCH] nl80211: add common API to configure SAR power limitations
|
||||
|
||||
NL80211_CMD_SET_SAR_SPECS is added to configure SAR from
|
||||
user space. NL80211_ATTR_SAR_SPEC is used to pass the SAR
|
||||
power specification when used with NL80211_CMD_SET_SAR_SPECS.
|
||||
|
||||
Wireless driver needs to register SAR type, supported frequency
|
||||
ranges to wiphy, so user space can query it. The index in
|
||||
frequency range is used to specify which sub band the power
|
||||
limitation applies to. The SAR type is for compatibility, so later
|
||||
other SAR mechanism can be implemented without breaking the user
|
||||
space SAR applications.
|
||||
|
||||
Normal process is user space queries the SAR capability, and
|
||||
gets the index of supported frequency ranges and associates the
|
||||
power limitation with this index and sends to kernel.
|
||||
|
||||
Here is an example of message send to kernel:
|
||||
8c 00 00 00 08 00 01 00 00 00 00 00 38 00 2b 81
|
||||
08 00 01 00 00 00 00 00 2c 00 02 80 14 00 00 80
|
||||
08 00 02 00 00 00 00 00 08 00 01 00 38 00 00 00
|
||||
14 00 01 80 08 00 02 00 01 00 00 00 08 00 01 00
|
||||
48 00 00 00
|
||||
|
||||
NL80211_CMD_SET_SAR_SPECS: 0x8c
|
||||
NL80211_ATTR_WIPHY: 0x01(phy idx is 0)
|
||||
NL80211_ATTR_SAR_SPEC: 0x812b (NLA_NESTED)
|
||||
NL80211_SAR_ATTR_TYPE: 0x00 (NL80211_SAR_TYPE_POWER)
|
||||
NL80211_SAR_ATTR_SPECS: 0x8002 (NLA_NESTED)
|
||||
freq range 0 power: 0x38 in 0.25dbm unit (14dbm)
|
||||
freq range 1 power: 0x48 in 0.25dbm unit (18dbm)
|
||||
|
||||
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
|
||||
Reviewed-by: Brian Norris <briannorris@chromium.org>
|
||||
Reviewed-by: Abhishek Kumar <kuabhs@chromium.org>
|
||||
Link: https://lore.kernel.org/r/20201203103728.3034-2-cjhuang@codeaurora.org
|
||||
[minor edits, NLA parse cleanups]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -1737,6 +1737,54 @@ struct station_info {
|
||||
u8 connected_to_as;
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * struct cfg80211_sar_sub_specs - sub specs limit
|
||||
+ * @power: power limitation in 0.25dbm
|
||||
+ * @freq_range_index: index the power limitation applies to
|
||||
+ */
|
||||
+struct cfg80211_sar_sub_specs {
|
||||
+ s32 power;
|
||||
+ u32 freq_range_index;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct cfg80211_sar_specs - sar limit specs
|
||||
+ * @type: it's set with power in 0.25dbm or other types
|
||||
+ * @num_sub_specs: number of sar sub specs
|
||||
+ * @sub_specs: memory to hold the sar sub specs
|
||||
+ */
|
||||
+struct cfg80211_sar_specs {
|
||||
+ enum nl80211_sar_type type;
|
||||
+ u32 num_sub_specs;
|
||||
+ struct cfg80211_sar_sub_specs sub_specs[];
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * @struct cfg80211_sar_chan_ranges - sar frequency ranges
|
||||
+ * @start_freq: start range edge frequency
|
||||
+ * @end_freq: end range edge frequency
|
||||
+ */
|
||||
+struct cfg80211_sar_freq_ranges {
|
||||
+ u32 start_freq;
|
||||
+ u32 end_freq;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct cfg80211_sar_capa - sar limit capability
|
||||
+ * @type: it's set via power in 0.25dbm or other types
|
||||
+ * @num_freq_ranges: number of frequency ranges
|
||||
+ * @freq_ranges: memory to hold the freq ranges.
|
||||
+ *
|
||||
+ * Note: WLAN driver may append new ranges or split an existing
|
||||
+ * range to small ones and then append them.
|
||||
+ */
|
||||
+struct cfg80211_sar_capa {
|
||||
+ enum nl80211_sar_type type;
|
||||
+ u32 num_freq_ranges;
|
||||
+ const struct cfg80211_sar_freq_ranges *freq_ranges;
|
||||
+};
|
||||
+
|
||||
#if IS_ENABLED(CPTCFG_CFG80211)
|
||||
/**
|
||||
* cfg80211_get_station - retrieve information about a given station
|
||||
@@ -4259,6 +4307,8 @@ struct cfg80211_ops {
|
||||
struct cfg80211_tid_config *tid_conf);
|
||||
int (*reset_tid_config)(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *peer, u8 tids);
|
||||
+ int (*set_sar_specs)(struct wiphy *wiphy,
|
||||
+ struct cfg80211_sar_specs *sar);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -5030,6 +5080,8 @@ struct wiphy {
|
||||
|
||||
u8 max_data_retry_count;
|
||||
|
||||
+ const struct cfg80211_sar_capa *sar_capa;
|
||||
+
|
||||
char priv[] __aligned(NETDEV_ALIGN);
|
||||
};
|
||||
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -405,6 +405,18 @@ nl80211_unsol_bcast_probe_resp_policy[NL
|
||||
.len = IEEE80211_MAX_DATA_LEN }
|
||||
};
|
||||
|
||||
+static const struct nla_policy
|
||||
+sar_specs_policy[NL80211_SAR_ATTR_SPECS_MAX + 1] = {
|
||||
+ [NL80211_SAR_ATTR_SPECS_POWER] = { .type = NLA_S32 },
|
||||
+ [NL80211_SAR_ATTR_SPECS_RANGE_INDEX] = {.type = NLA_U32 },
|
||||
+};
|
||||
+
|
||||
+static const struct nla_policy
|
||||
+sar_policy[NL80211_SAR_ATTR_MAX + 1] = {
|
||||
+ [NL80211_SAR_ATTR_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_SAR_TYPE),
|
||||
+ [NL80211_SAR_ATTR_SPECS] = NLA_POLICY_NESTED_ARRAY(sar_specs_policy),
|
||||
+};
|
||||
+
|
||||
static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
||||
[0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
|
||||
[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
|
||||
@@ -739,6 +751,7 @@ static const struct nla_policy nl80211_p
|
||||
[NL80211_ATTR_SAE_PWE] =
|
||||
NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
|
||||
NL80211_SAE_PWE_BOTH),
|
||||
+ [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
|
||||
[NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
|
||||
};
|
||||
|
||||
@@ -2117,6 +2130,56 @@ fail:
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
+static int
|
||||
+nl80211_put_sar_specs(struct cfg80211_registered_device *rdev,
|
||||
+ struct sk_buff *msg)
|
||||
+{
|
||||
+ struct nlattr *sar_capa, *specs, *sub_freq_range;
|
||||
+ u8 num_freq_ranges;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!rdev->wiphy.sar_capa)
|
||||
+ return 0;
|
||||
+
|
||||
+ num_freq_ranges = rdev->wiphy.sar_capa->num_freq_ranges;
|
||||
+
|
||||
+ sar_capa = nla_nest_start(msg, NL80211_ATTR_SAR_SPEC);
|
||||
+ if (!sar_capa)
|
||||
+ return -ENOSPC;
|
||||
+
|
||||
+ if (nla_put_u32(msg, NL80211_SAR_ATTR_TYPE, rdev->wiphy.sar_capa->type))
|
||||
+ goto fail;
|
||||
+
|
||||
+ specs = nla_nest_start(msg, NL80211_SAR_ATTR_SPECS);
|
||||
+ if (!specs)
|
||||
+ goto fail;
|
||||
+
|
||||
+ /* report supported freq_ranges */
|
||||
+ for (i = 0; i < num_freq_ranges; i++) {
|
||||
+ sub_freq_range = nla_nest_start(msg, i + 1);
|
||||
+ if (!sub_freq_range)
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_START_FREQ,
|
||||
+ rdev->wiphy.sar_capa->freq_ranges[i].start_freq))
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_END_FREQ,
|
||||
+ rdev->wiphy.sar_capa->freq_ranges[i].end_freq))
|
||||
+ goto fail;
|
||||
+
|
||||
+ nla_nest_end(msg, sub_freq_range);
|
||||
+ }
|
||||
+
|
||||
+ nla_nest_end(msg, specs);
|
||||
+ nla_nest_end(msg, sar_capa);
|
||||
+
|
||||
+ return 0;
|
||||
+fail:
|
||||
+ nla_nest_cancel(msg, sar_capa);
|
||||
+ return -ENOBUFS;
|
||||
+}
|
||||
+
|
||||
struct nl80211_dump_wiphy_state {
|
||||
s64 filter_wiphy;
|
||||
long start;
|
||||
@@ -2366,6 +2429,8 @@ static int nl80211_send_wiphy(struct cfg
|
||||
CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
|
||||
CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
|
||||
CMD(update_ft_ies, UPDATE_FT_IES);
|
||||
+ if (rdev->wiphy.sar_capa)
|
||||
+ CMD(set_sar_specs, SET_SAR_SPECS);
|
||||
}
|
||||
#undef CMD
|
||||
|
||||
@@ -2691,6 +2756,11 @@ static int nl80211_send_wiphy(struct cfg
|
||||
|
||||
if (nl80211_put_tid_config_support(rdev, msg))
|
||||
goto nla_put_failure;
|
||||
+ state->split_start++;
|
||||
+ break;
|
||||
+ case 16:
|
||||
+ if (nl80211_put_sar_specs(rdev, msg))
|
||||
+ goto nla_put_failure;
|
||||
|
||||
/* done */
|
||||
state->split_start = 0;
|
||||
@@ -14712,6 +14782,111 @@ static void nl80211_post_doit(__genl_con
|
||||
}
|
||||
}
|
||||
|
||||
+static int nl80211_set_sar_sub_specs(struct cfg80211_registered_device *rdev,
|
||||
+ struct cfg80211_sar_specs *sar_specs,
|
||||
+ struct nlattr *spec[], int index)
|
||||
+{
|
||||
+ u32 range_index, i;
|
||||
+
|
||||
+ if (!sar_specs || !spec)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!spec[NL80211_SAR_ATTR_SPECS_POWER] ||
|
||||
+ !spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ range_index = nla_get_u32(spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]);
|
||||
+
|
||||
+ /* check if range_index exceeds num_freq_ranges */
|
||||
+ if (range_index >= rdev->wiphy.sar_capa->num_freq_ranges)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* check if range_index duplicates */
|
||||
+ for (i = 0; i < index; i++) {
|
||||
+ if (sar_specs->sub_specs[i].freq_range_index == range_index)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ sar_specs->sub_specs[index].power =
|
||||
+ nla_get_s32(spec[NL80211_SAR_ATTR_SPECS_POWER]);
|
||||
+
|
||||
+ sar_specs->sub_specs[index].freq_range_index = range_index;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int nl80211_set_sar_specs(struct sk_buff *skb, struct genl_info *info)
|
||||
+{
|
||||
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
+ struct nlattr *spec[NL80211_SAR_ATTR_SPECS_MAX + 1];
|
||||
+ struct nlattr *tb[NL80211_SAR_ATTR_MAX + 1];
|
||||
+ struct cfg80211_sar_specs *sar_spec;
|
||||
+ enum nl80211_sar_type type;
|
||||
+ struct nlattr *spec_list;
|
||||
+ u32 specs;
|
||||
+ int rem, err;
|
||||
+
|
||||
+ if (!rdev->wiphy.sar_capa || !rdev->ops->set_sar_specs)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ if (!info->attrs[NL80211_ATTR_SAR_SPEC])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ nla_parse_nested(tb, NL80211_SAR_ATTR_MAX,
|
||||
+ info->attrs[NL80211_ATTR_SAR_SPEC],
|
||||
+ NULL, NULL);
|
||||
+
|
||||
+ if (!tb[NL80211_SAR_ATTR_TYPE] || !tb[NL80211_SAR_ATTR_SPECS])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ type = nla_get_u32(tb[NL80211_SAR_ATTR_TYPE]);
|
||||
+ if (type != rdev->wiphy.sar_capa->type)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ specs = 0;
|
||||
+ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem)
|
||||
+ specs++;
|
||||
+
|
||||
+ if (specs > rdev->wiphy.sar_capa->num_freq_ranges)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ sar_spec = kzalloc(sizeof(*sar_spec) +
|
||||
+ specs * sizeof(struct cfg80211_sar_sub_specs),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!sar_spec)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ sar_spec->type = type;
|
||||
+ specs = 0;
|
||||
+ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) {
|
||||
+ nla_parse_nested(spec, NL80211_SAR_ATTR_SPECS_MAX,
|
||||
+ spec_list, NULL, NULL);
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case NL80211_SAR_TYPE_POWER:
|
||||
+ if (nl80211_set_sar_sub_specs(rdev, sar_spec,
|
||||
+ spec, specs)) {
|
||||
+ err = -EINVAL;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ err = -EINVAL;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ specs++;
|
||||
+ }
|
||||
+
|
||||
+ sar_spec->num_sub_specs = specs;
|
||||
+
|
||||
+ rdev->cur_cmd_info = info;
|
||||
+ err = rdev_set_sar_specs(rdev, sar_spec);
|
||||
+ rdev->cur_cmd_info = NULL;
|
||||
+error:
|
||||
+ kfree(sar_spec);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static __genl_const struct genl_ops nl80211_ops[] = {
|
||||
{
|
||||
.cmd = NL80211_CMD_GET_WIPHY,
|
||||
@@ -15575,6 +15750,14 @@ static const struct genl_small_ops nl802
|
||||
.internal_flags = NL80211_FLAG_NEED_NETDEV |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
+ {
|
||||
+ .cmd = NL80211_CMD_SET_SAR_SPECS,
|
||||
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
+ .doit = nl80211_set_sar_specs,
|
||||
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||
+ .internal_flags = NL80211_FLAG_NEED_WIPHY |
|
||||
+ NL80211_FLAG_NEED_RTNL,
|
||||
+ },
|
||||
};
|
||||
|
||||
static struct genl_family nl80211_fam __genl_ro_after_init = {
|
||||
--- a/net/wireless/rdev-ops.h
|
||||
+++ b/net/wireless/rdev-ops.h
|
||||
@@ -1356,4 +1356,16 @@ static inline int rdev_reset_tid_config(
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static inline int rdev_set_sar_specs(struct cfg80211_registered_device *rdev,
|
||||
+ struct cfg80211_sar_specs *sar)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ trace_rdev_set_sar_specs(&rdev->wiphy, sar);
|
||||
+ ret = rdev->ops->set_sar_specs(&rdev->wiphy, sar);
|
||||
+ trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
#endif /* __CFG80211_RDEV_OPS */
|
||||
--- a/net/wireless/trace.h
|
||||
+++ b/net/wireless/trace.h
|
||||
@@ -3551,6 +3551,25 @@ TRACE_EVENT(rdev_reset_tid_config,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT ", tids: 0x%x",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->tids)
|
||||
);
|
||||
+
|
||||
+TRACE_EVENT(rdev_set_sar_specs,
|
||||
+ TP_PROTO(struct wiphy *wiphy, struct cfg80211_sar_specs *sar),
|
||||
+ TP_ARGS(wiphy, sar),
|
||||
+ TP_STRUCT__entry(
|
||||
+ WIPHY_ENTRY
|
||||
+ __field(u16, type)
|
||||
+ __field(u16, num)
|
||||
+ ),
|
||||
+ TP_fast_assign(
|
||||
+ WIPHY_ASSIGN;
|
||||
+ __entry->type = sar->type;
|
||||
+ __entry->num = sar->num_sub_specs;
|
||||
+
|
||||
+ ),
|
||||
+ TP_printk(WIPHY_PR_FMT ", Set type:%d, num_specs:%d",
|
||||
+ WIPHY_PR_ARG, __entry->type, __entry->num)
|
||||
+);
|
||||
+
|
||||
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
@ -1,395 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -8682,6 +8682,384 @@ static void rt2800_rxdcoc_calibration(st
|
||||
rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, saverfb0r2);
|
||||
}
|
||||
|
||||
+static u32 rt2800_do_sqrt_accumulation(u32 si) {
|
||||
+ u32 root, root_pre, bit;
|
||||
+ char i;
|
||||
+ bit = 1 << 15;
|
||||
+ root = 0;
|
||||
+ for (i = 15; i >= 0; i = i - 1) {
|
||||
+ root_pre = root + bit;
|
||||
+ if ((root_pre*root_pre) <= si)
|
||||
+ root = root_pre;
|
||||
+ bit = bit >> 1;
|
||||
+ }
|
||||
+
|
||||
+ return root;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev) {
|
||||
+ u8 rfb0r1, rfb0r2, rfb0r42;
|
||||
+ u8 rfb4r0, rfb4r19;
|
||||
+ u8 rfb5r3, rfb5r4, rfb5r17, rfb5r18, rfb5r19, rfb5r20;
|
||||
+ u8 rfb6r0, rfb6r19;
|
||||
+ u8 rfb7r3, rfb7r4, rfb7r17, rfb7r18, rfb7r19, rfb7r20;
|
||||
+
|
||||
+ u8 bbp1, bbp4;
|
||||
+ u8 bbpr241, bbpr242;
|
||||
+ u32 i;
|
||||
+ u8 ch_idx;
|
||||
+ u8 bbpval;
|
||||
+ u8 rfval, vga_idx = 0;
|
||||
+ int mi = 0, mq = 0, si = 0, sq = 0, riq = 0;
|
||||
+ int sigma_i, sigma_q, r_iq, g_rx;
|
||||
+ int g_imb;
|
||||
+ int ph_rx;
|
||||
+ u32 savemacsysctrl = 0;
|
||||
+ u32 orig_RF_CONTROL0 = 0;
|
||||
+ u32 orig_RF_BYPASS0 = 0;
|
||||
+ u32 orig_RF_CONTROL1 = 0;
|
||||
+ u32 orig_RF_BYPASS1 = 0;
|
||||
+ u32 orig_RF_CONTROL3 = 0;
|
||||
+ u32 orig_RF_BYPASS3 = 0;
|
||||
+ u32 macstatus, bbpval1 = 0;
|
||||
+ u8 rf_vga_table[] = {0x20, 0x21, 0x22, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f};
|
||||
+
|
||||
+ savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ orig_RF_CONTROL0 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
|
||||
+ orig_RF_BYPASS0 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
|
||||
+ orig_RF_CONTROL1 = rt2800_register_read(rt2x00dev, RF_CONTROL1);
|
||||
+ orig_RF_BYPASS1 = rt2800_register_read(rt2x00dev, RF_BYPASS1);
|
||||
+ orig_RF_CONTROL3 = rt2800_register_read(rt2x00dev, RF_CONTROL3);
|
||||
+ orig_RF_BYPASS3 = rt2800_register_read(rt2x00dev, RF_BYPASS3);
|
||||
+
|
||||
+ bbp1 = rt2800_bbp_read(rt2x00dev, 1);
|
||||
+ bbp4 = rt2800_bbp_read(rt2x00dev, 4);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x0);
|
||||
+
|
||||
+ for (i = 0; i < 10000; i++) {
|
||||
+ macstatus = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
|
||||
+ if (macstatus & 0x3)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (i == 10000)
|
||||
+ rt2x00_warn(rt2x00dev, "Wait MAC Status to MAX !!!\n");
|
||||
+
|
||||
+ bbpval = bbp4 & (~0x18);
|
||||
+ bbpval = bbp4 | 0x00;
|
||||
+ rt2800_bbp_write(rt2x00dev, 4, bbpval);
|
||||
+
|
||||
+ bbpval = rt2800_bbp_read(rt2x00dev, 21);
|
||||
+ bbpval = bbpval | 1;
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, bbpval);
|
||||
+ bbpval = bbpval & 0xfe;
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, bbpval);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL1, 0x00000202);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS1, 0x00000303);
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags))
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x0101);
|
||||
+ else
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x0000);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, 0xf1f1);
|
||||
+
|
||||
+ rfb0r1 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
|
||||
+ rfb0r2 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
|
||||
+ rfb0r42 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
|
||||
+ rfb4r0 = rt2800_rfcsr_read_bank(rt2x00dev, 4, 0);
|
||||
+ rfb4r19 = rt2800_rfcsr_read_bank(rt2x00dev, 4, 19);
|
||||
+ rfb5r3 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 3);
|
||||
+ rfb5r4 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);
|
||||
+ rfb5r17 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 17);
|
||||
+ rfb5r18 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 18);
|
||||
+ rfb5r19 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 19);
|
||||
+ rfb5r20 = rt2800_rfcsr_read_bank(rt2x00dev, 5, 20);
|
||||
+
|
||||
+ rfb6r0 = rt2800_rfcsr_read_bank(rt2x00dev, 6, 0);
|
||||
+ rfb6r19 = rt2800_rfcsr_read_bank(rt2x00dev, 6, 19);
|
||||
+ rfb7r3 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 3);
|
||||
+ rfb7r4 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
|
||||
+ rfb7r17 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 17);
|
||||
+ rfb7r18 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 18);
|
||||
+ rfb7r19 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 19);
|
||||
+ rfb7r20 = rt2800_rfcsr_read_bank(rt2x00dev, 7, 20);
|
||||
+
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 0, 0x87);
|
||||
+ rt2800_rfcsr_write_chanreg(rt2x00dev, 19, 0x27);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x38);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x38);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x80);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 18, 0xC1);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 19, 0x60);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 20, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x0);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x0);
|
||||
+
|
||||
+ rt2800_bbp_dcoc_write(rt2x00dev, 5, 0x0);
|
||||
+
|
||||
+ bbpr241 = rt2800_bbp_read(rt2x00dev, 241);
|
||||
+ bbpr242 = rt2800_bbp_read(rt2x00dev, 242);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 241, 0x10);
|
||||
+ rt2800_bbp_write(rt2x00dev, 242, 0x84);
|
||||
+ rt2800_bbp_write(rt2x00dev, 244, 0x31);
|
||||
+
|
||||
+ bbpval = rt2800_bbp_dcoc_read(rt2x00dev, 3);
|
||||
+ bbpval = bbpval & (~0x7);
|
||||
+ rt2800_bbp_dcoc_write(rt2x00dev, 3, bbpval);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
|
||||
+ udelay(1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000006);
|
||||
+ usleep_range(1, 200);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00003376);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001006);
|
||||
+ udelay(1);
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x06);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x06);
|
||||
+ } else {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x02);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x02);
|
||||
+ }
|
||||
+
|
||||
+ for (ch_idx = 0; ch_idx < 2; ch_idx = ch_idx + 1) {
|
||||
+ if (ch_idx == 0) {
|
||||
+ rfval = rfb0r1 & (~0x3);
|
||||
+ rfval = rfb0r1 | 0x1;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfval);
|
||||
+ rfval = rfb0r2 & (~0x33);
|
||||
+ rfval = rfb0r2 | 0x11;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfval);
|
||||
+ rfval = rfb0r42 & (~0x50);
|
||||
+ rfval = rfb0r42 | 0x10;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfval);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001006);
|
||||
+ udelay(1);
|
||||
+
|
||||
+ bbpval = bbp1 & (~ 0x18);
|
||||
+ bbpval = bbpval | 0x00;
|
||||
+ rt2800_bbp_write(rt2x00dev, 1, bbpval);
|
||||
+
|
||||
+ rt2800_bbp_dcoc_write(rt2x00dev, 1, 0x00);
|
||||
+ } else {
|
||||
+ rfval = rfb0r1 & (~0x3);
|
||||
+ rfval = rfb0r1 | 0x2;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfval);
|
||||
+ rfval = rfb0r2 & (~0x33);
|
||||
+ rfval = rfb0r2 | 0x22;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfval);
|
||||
+ rfval = rfb0r42 & (~0x50);
|
||||
+ rfval = rfb0r42 | 0x40;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfval);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002006);
|
||||
+ udelay(1);
|
||||
+
|
||||
+ bbpval = bbp1 & (~ 0x18);
|
||||
+ bbpval = bbpval | 0x08;
|
||||
+ rt2800_bbp_write(rt2x00dev, 1, bbpval);
|
||||
+
|
||||
+ rt2800_bbp_dcoc_write(rt2x00dev, 1, 0x01);
|
||||
+ }
|
||||
+ udelay(500);
|
||||
+
|
||||
+ vga_idx = 0;
|
||||
+ while (vga_idx < 11) {
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, rf_vga_table[vga_idx]);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, rf_vga_table[vga_idx]);
|
||||
+
|
||||
+ rt2800_bbp_dcoc_write(rt2x00dev, 0, 0x93);
|
||||
+
|
||||
+ for (i = 0; i < 10000; i++) {
|
||||
+ bbpval = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ if ((bbpval & 0xff) == 0x93)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if ((bbpval & 0xff) == 0x93) {
|
||||
+ rt2x00_warn(rt2x00dev, "Fatal Error: Calibration doesn't finish");
|
||||
+ goto restore_value;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 5; i++) {
|
||||
+ u32 bbptemp = 0;
|
||||
+ u8 value = 0;
|
||||
+ int result = 0;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x1e);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, i);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x22);
|
||||
+ value = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbptemp = bbptemp + (value << 24);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x21);
|
||||
+ value = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbptemp = bbptemp + (value << 16);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x20);
|
||||
+ value = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbptemp = bbptemp + (value << 8);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x1f);
|
||||
+ value = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbptemp = bbptemp + value;
|
||||
+
|
||||
+ if ((i < 2) && (bbptemp & 0x800000))
|
||||
+ result = (bbptemp & 0xffffff) - 0x1000000;
|
||||
+ else if (i == 4)
|
||||
+ result = bbptemp;
|
||||
+ else
|
||||
+ result = bbptemp;
|
||||
+
|
||||
+ if (i == 0)
|
||||
+ mi = result/4096;
|
||||
+ else if (i == 1)
|
||||
+ mq = result/4096;
|
||||
+ else if (i == 2)
|
||||
+ si = bbptemp/4096;
|
||||
+ else if (i == 3)
|
||||
+ sq = bbptemp/4096;
|
||||
+ else
|
||||
+ riq = result/4096;
|
||||
+ }
|
||||
+
|
||||
+ bbpval1 = si - mi*mi;
|
||||
+ rt2x00_dbg(rt2x00dev, "RXIQ si=%d, sq=%d, riq=%d, bbpval %d, vga_idx %d", si, sq, riq, bbpval1, vga_idx);
|
||||
+
|
||||
+ if (bbpval1 >= (100*100))
|
||||
+ break;
|
||||
+
|
||||
+ if (bbpval1 <= 100)
|
||||
+ vga_idx = vga_idx + 9;
|
||||
+ else if (bbpval1 <= 158)
|
||||
+ vga_idx = vga_idx + 8;
|
||||
+ else if (bbpval1 <= 251)
|
||||
+ vga_idx = vga_idx + 7;
|
||||
+ else if (bbpval1 <= 398)
|
||||
+ vga_idx = vga_idx + 6;
|
||||
+ else if (bbpval1 <= 630)
|
||||
+ vga_idx = vga_idx + 5;
|
||||
+ else if (bbpval1 <= 1000)
|
||||
+ vga_idx = vga_idx + 4;
|
||||
+ else if (bbpval1 <= 1584)
|
||||
+ vga_idx = vga_idx + 3;
|
||||
+ else if (bbpval1 <= 2511)
|
||||
+ vga_idx = vga_idx + 2;
|
||||
+ else
|
||||
+ vga_idx = vga_idx + 1;
|
||||
+ }
|
||||
+
|
||||
+ sigma_i = rt2800_do_sqrt_accumulation(100*(si - mi*mi));
|
||||
+ sigma_q = rt2800_do_sqrt_accumulation(100*(sq - mq*mq));
|
||||
+ r_iq = 10*(riq-(mi*mq));
|
||||
+
|
||||
+ rt2x00_dbg(rt2x00dev, "Sigma_i=%d, Sigma_q=%d, R_iq=%d", sigma_i, sigma_q, r_iq);
|
||||
+
|
||||
+ if (((sigma_i <= 1400 ) && (sigma_i >= 1000))
|
||||
+ && ((sigma_i - sigma_q) <= 112)
|
||||
+ && ((sigma_i - sigma_q) >= -112)
|
||||
+ && ((mi <= 32) && (mi >= -32))
|
||||
+ && ((mq <= 32) && (mq >= -32))) {
|
||||
+ r_iq = 10*(riq-(mi*mq));
|
||||
+ rt2x00_dbg(rt2x00dev, "RXIQ Sigma_i=%d, Sigma_q=%d, R_iq=%d\n", sigma_i, sigma_q, r_iq);
|
||||
+
|
||||
+ g_rx = (1000 * sigma_q) / sigma_i;
|
||||
+ g_imb = ((-2) * 128 * (1000 - g_rx)) / (1000 + g_rx);
|
||||
+ ph_rx = (r_iq * 2292) / (sigma_i * sigma_q);
|
||||
+ rt2x00_info(rt2x00dev, "RXIQ G_imb=%d, Ph_rx=%d\n", g_imb, ph_rx);
|
||||
+
|
||||
+ if ((ph_rx > 20) || (ph_rx < -20)) {
|
||||
+ ph_rx = 0;
|
||||
+ rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
|
||||
+ }
|
||||
+
|
||||
+ if ((g_imb > 12) || (g_imb < -12)) {
|
||||
+ g_imb = 0;
|
||||
+ rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
|
||||
+ }
|
||||
+ }
|
||||
+ else {
|
||||
+ g_imb = 0;
|
||||
+ ph_rx = 0;
|
||||
+ rt2x00_dbg(rt2x00dev, "RXIQ Sigma_i=%d, Sigma_q=%d, R_iq=%d\n", sigma_i, sigma_q, r_iq);
|
||||
+ rt2x00_warn(rt2x00dev, "RXIQ calibration FAIL");
|
||||
+ }
|
||||
+
|
||||
+ if (ch_idx == 0) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x37);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, g_imb & 0x3f);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x35);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, ph_rx & 0x3f);
|
||||
+ } else {
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x55);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, g_imb & 0x3f);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x53);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, ph_rx & 0x3f);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+restore_value:
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x3);
|
||||
+ bbpval = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, (bbpval | 0x07));
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 1, bbp1);
|
||||
+ rt2800_bbp_write(rt2x00dev, 4, bbp4);
|
||||
+ rt2800_bbp_write(rt2x00dev, 241, bbpr241);
|
||||
+ rt2800_bbp_write(rt2x00dev, 242, bbpr242);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 244, 0x00);
|
||||
+ bbpval = rt2800_bbp_read(rt2x00dev, 21);
|
||||
+ bbpval |= 0x1;
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, bbpval);
|
||||
+ usleep_range(10, 200);
|
||||
+ bbpval &= 0xfe;
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, bbpval);
|
||||
+
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, rfb0r1);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, rfb0r2);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfb0r42);
|
||||
+
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 0, rfb4r0);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 19, rfb4r19);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, rfb5r3);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, rfb5r4);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, rfb5r17);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, rfb5r18);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, rfb5r19);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, rfb5r20);
|
||||
+
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 0, rfb6r0);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 19, rfb6r19);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 3, rfb7r3);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, rfb7r4);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 17, rfb7r17);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 18, rfb7r18);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 19, rfb7r19);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 20, rfb7r20);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000006);
|
||||
+ udelay(1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
|
||||
+ udelay(1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, orig_RF_CONTROL0);
|
||||
+ udelay(1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, orig_RF_BYPASS0);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL1, orig_RF_CONTROL1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS1, orig_RF_BYPASS1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, orig_RF_CONTROL3);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, orig_RF_BYPASS3);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
|
||||
+}
|
||||
+
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
bool set_bw, bool is_ht40)
|
||||
{
|
||||
@@ -9294,6 +9672,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rxdcoc_calibration(rt2x00dev);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, true);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, false);
|
||||
+ rt2800_rxiq_calibration(rt2x00dev);
|
||||
}
|
||||
|
||||
static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
@ -1,28 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Thu, 2 Dec 2021 13:30:05 +0100
|
||||
Subject: [PATCH] mac80211: send ADDBA requests using the tid/queue of the
|
||||
aggregation session
|
||||
|
||||
Sending them out on a different queue can cause a race condition where a
|
||||
number of packets in the queue may be discarded by the receiver, because
|
||||
the ADDBA request is sent too early.
|
||||
This affects any driver with software A-MPDU setup which does not allocate
|
||||
packet seqno in hardware on tx, regardless of whether iTXQ is used or not.
|
||||
The only driver I've seen that explicitly deals with this issue internally
|
||||
is mwl8k.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/agg-tx.c
|
||||
+++ b/net/mac80211/agg-tx.c
|
||||
@@ -106,7 +106,7 @@ static void ieee80211_send_addba_request
|
||||
mgmt->u.action.u.addba_req.start_seq_num =
|
||||
cpu_to_le16(start_seq_num << 4);
|
||||
|
||||
- ieee80211_tx_skb(sdata, skb);
|
||||
+ ieee80211_tx_skb_tid(sdata, skb, tid);
|
||||
}
|
||||
|
||||
void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn)
|
@ -1,67 +0,0 @@
|
||||
--- a/net/mac80211/main.c
|
||||
+++ b/net/mac80211/main.c
|
||||
@@ -321,7 +321,7 @@ void ieee80211_restart_hw(struct ieee802
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_restart_hw);
|
||||
|
||||
-#ifdef CONFIG_INET
|
||||
+#ifdef __disabled__CONFIG_INET
|
||||
static int ieee80211_ifa_changed(struct notifier_block *nb,
|
||||
unsigned long data, void *arg)
|
||||
{
|
||||
@@ -380,7 +380,7 @@ static int ieee80211_ifa_changed(struct
|
||||
}
|
||||
#endif
|
||||
|
||||
-#if IS_ENABLED(CONFIG_IPV6)
|
||||
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
|
||||
static int ieee80211_ifa6_changed(struct notifier_block *nb,
|
||||
unsigned long data, void *arg)
|
||||
{
|
||||
@@ -1315,14 +1315,14 @@ int ieee80211_register_hw(struct ieee802
|
||||
|
||||
rtnl_unlock();
|
||||
|
||||
-#ifdef CONFIG_INET
|
||||
+#ifdef __disabled__CONFIG_INET
|
||||
local->ifa_notifier.notifier_call = ieee80211_ifa_changed;
|
||||
result = register_inetaddr_notifier(&local->ifa_notifier);
|
||||
if (result)
|
||||
goto fail_ifa;
|
||||
#endif
|
||||
|
||||
-#if IS_ENABLED(CONFIG_IPV6)
|
||||
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
|
||||
local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
|
||||
result = register_inet6addr_notifier(&local->ifa6_notifier);
|
||||
if (result)
|
||||
@@ -1331,13 +1331,13 @@ int ieee80211_register_hw(struct ieee802
|
||||
|
||||
return 0;
|
||||
|
||||
-#if IS_ENABLED(CONFIG_IPV6)
|
||||
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
|
||||
fail_ifa6:
|
||||
-#ifdef CONFIG_INET
|
||||
+#ifdef __disabled__CONFIG_INET
|
||||
unregister_inetaddr_notifier(&local->ifa_notifier);
|
||||
#endif
|
||||
#endif
|
||||
-#if defined(CONFIG_INET) || defined(CONFIG_IPV6)
|
||||
+#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6)
|
||||
fail_ifa:
|
||||
#endif
|
||||
wiphy_unregister(local->hw.wiphy);
|
||||
@@ -1365,10 +1365,10 @@ void ieee80211_unregister_hw(struct ieee
|
||||
tasklet_kill(&local->tx_pending_tasklet);
|
||||
tasklet_kill(&local->tasklet);
|
||||
|
||||
-#ifdef CONFIG_INET
|
||||
+#ifdef __disabled__CONFIG_INET
|
||||
unregister_inetaddr_notifier(&local->ifa_notifier);
|
||||
#endif
|
||||
-#if IS_ENABLED(CONFIG_IPV6)
|
||||
+#if IS_ENABLED(__disabled__CONFIG_IPV6)
|
||||
unregister_inet6addr_notifier(&local->ifa6_notifier);
|
||||
#endif
|
||||
|
@ -1,18 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -403,13 +403,8 @@ static void ath9k_hw_init_config(struct
|
||||
|
||||
ah->config.rx_intr_mitigation = true;
|
||||
|
||||
- if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
- ah->config.rimt_last = 500;
|
||||
- ah->config.rimt_first = 2000;
|
||||
- } else {
|
||||
- ah->config.rimt_last = 250;
|
||||
- ah->config.rimt_first = 700;
|
||||
- }
|
||||
+ ah->config.rimt_last = 250;
|
||||
+ ah->config.rimt_first = 500;
|
||||
|
||||
if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
|
||||
ah->config.pll_pwrsave = 7;
|
@ -1,973 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
|
||||
@@ -9060,6 +9060,943 @@ restore_value:
|
||||
rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
|
||||
}
|
||||
|
||||
+static void rt2800_rf_configstore(struct rt2x00_dev *rt2x00dev, rf_reg_pair rf_reg_record[][13], u8 chain)
|
||||
+{
|
||||
+ u8 rfvalue = 0;
|
||||
+
|
||||
+ if (chain == CHAIN_0) {
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
|
||||
+ rf_reg_record[CHAIN_0][0].bank = 0;
|
||||
+ rf_reg_record[CHAIN_0][0].reg = 1;
|
||||
+ rf_reg_record[CHAIN_0][0].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
|
||||
+ rf_reg_record[CHAIN_0][1].bank = 0;
|
||||
+ rf_reg_record[CHAIN_0][1].reg = 2;
|
||||
+ rf_reg_record[CHAIN_0][1].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 35);
|
||||
+ rf_reg_record[CHAIN_0][2].bank = 0;
|
||||
+ rf_reg_record[CHAIN_0][2].reg = 35;
|
||||
+ rf_reg_record[CHAIN_0][2].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
|
||||
+ rf_reg_record[CHAIN_0][3].bank = 0;
|
||||
+ rf_reg_record[CHAIN_0][3].reg = 42;
|
||||
+ rf_reg_record[CHAIN_0][3].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 4, 0);
|
||||
+ rf_reg_record[CHAIN_0][4].bank = 4;
|
||||
+ rf_reg_record[CHAIN_0][4].reg = 0;
|
||||
+ rf_reg_record[CHAIN_0][4].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 4, 2);
|
||||
+ rf_reg_record[CHAIN_0][5].bank = 4;
|
||||
+ rf_reg_record[CHAIN_0][5].reg = 2;
|
||||
+ rf_reg_record[CHAIN_0][5].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 4, 34);
|
||||
+ rf_reg_record[CHAIN_0][6].bank = 4;
|
||||
+ rf_reg_record[CHAIN_0][6].reg = 34;
|
||||
+ rf_reg_record[CHAIN_0][6].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 3);
|
||||
+ rf_reg_record[CHAIN_0][7].bank = 5;
|
||||
+ rf_reg_record[CHAIN_0][7].reg = 3;
|
||||
+ rf_reg_record[CHAIN_0][7].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 4);
|
||||
+ rf_reg_record[CHAIN_0][8].bank = 5;
|
||||
+ rf_reg_record[CHAIN_0][8].reg = 4;
|
||||
+ rf_reg_record[CHAIN_0][8].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 17);
|
||||
+ rf_reg_record[CHAIN_0][9].bank = 5;
|
||||
+ rf_reg_record[CHAIN_0][9].reg = 17;
|
||||
+ rf_reg_record[CHAIN_0][9].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 18);
|
||||
+ rf_reg_record[CHAIN_0][10].bank = 5;
|
||||
+ rf_reg_record[CHAIN_0][10].reg = 18;
|
||||
+ rf_reg_record[CHAIN_0][10].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 19);
|
||||
+ rf_reg_record[CHAIN_0][11].bank = 5;
|
||||
+ rf_reg_record[CHAIN_0][11].reg = 19;
|
||||
+ rf_reg_record[CHAIN_0][11].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 5, 20);
|
||||
+ rf_reg_record[CHAIN_0][12].bank = 5;
|
||||
+ rf_reg_record[CHAIN_0][12].reg = 20;
|
||||
+ rf_reg_record[CHAIN_0][12].value = rfvalue;
|
||||
+ } else if (chain == CHAIN_1) {
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 1);
|
||||
+ rf_reg_record[CHAIN_1][0].bank = 0;
|
||||
+ rf_reg_record[CHAIN_1][0].reg = 1;
|
||||
+ rf_reg_record[CHAIN_1][0].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 2);
|
||||
+ rf_reg_record[CHAIN_1][1].bank = 0;
|
||||
+ rf_reg_record[CHAIN_1][1].reg = 2;
|
||||
+ rf_reg_record[CHAIN_1][1].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 35);
|
||||
+ rf_reg_record[CHAIN_1][2].bank = 0;
|
||||
+ rf_reg_record[CHAIN_1][2].reg = 35;
|
||||
+ rf_reg_record[CHAIN_1][2].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
|
||||
+ rf_reg_record[CHAIN_1][3].bank = 0;
|
||||
+ rf_reg_record[CHAIN_1][3].reg = 42;
|
||||
+ rf_reg_record[CHAIN_1][3].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 6, 0);
|
||||
+ rf_reg_record[CHAIN_1][4].bank = 6;
|
||||
+ rf_reg_record[CHAIN_1][4].reg = 0;
|
||||
+ rf_reg_record[CHAIN_1][4].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 6, 2);
|
||||
+ rf_reg_record[CHAIN_1][5].bank = 6;
|
||||
+ rf_reg_record[CHAIN_1][5].reg = 2;
|
||||
+ rf_reg_record[CHAIN_1][5].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 6, 34);
|
||||
+ rf_reg_record[CHAIN_1][6].bank = 6;
|
||||
+ rf_reg_record[CHAIN_1][6].reg = 34;
|
||||
+ rf_reg_record[CHAIN_1][6].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 3);
|
||||
+ rf_reg_record[CHAIN_1][7].bank = 7;
|
||||
+ rf_reg_record[CHAIN_1][7].reg = 3;
|
||||
+ rf_reg_record[CHAIN_1][7].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 4);
|
||||
+ rf_reg_record[CHAIN_1][8].bank = 7;
|
||||
+ rf_reg_record[CHAIN_1][8].reg = 4;
|
||||
+ rf_reg_record[CHAIN_1][8].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 17);
|
||||
+ rf_reg_record[CHAIN_1][9].bank = 7;
|
||||
+ rf_reg_record[CHAIN_1][9].reg = 17;
|
||||
+ rf_reg_record[CHAIN_1][9].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 18);
|
||||
+ rf_reg_record[CHAIN_1][10].bank = 7;
|
||||
+ rf_reg_record[CHAIN_1][10].reg = 18;
|
||||
+ rf_reg_record[CHAIN_1][10].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 19);
|
||||
+ rf_reg_record[CHAIN_1][11].bank = 7;
|
||||
+ rf_reg_record[CHAIN_1][11].reg = 19;
|
||||
+ rf_reg_record[CHAIN_1][11].value = rfvalue;
|
||||
+ rfvalue = rt2800_rfcsr_read_bank(rt2x00dev, 7, 20);
|
||||
+ rf_reg_record[CHAIN_1][12].bank = 7;
|
||||
+ rf_reg_record[CHAIN_1][12].reg = 20;
|
||||
+ rf_reg_record[CHAIN_1][12].value = rfvalue;
|
||||
+ } else {
|
||||
+ rt2x00_warn(rt2x00dev, "Unknown chain = %u\n", chain);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_rf_configrecover(struct rt2x00_dev *rt2x00dev, rf_reg_pair rf_record[][13])
|
||||
+{
|
||||
+ u8 chain_index = 0, record_index = 0;
|
||||
+ u8 bank = 0, rf_register = 0, value = 0;
|
||||
+
|
||||
+ for (chain_index = 0; chain_index < 2; chain_index++) {
|
||||
+ for (record_index = 0; record_index < 13; record_index++) {
|
||||
+ bank = rf_record[chain_index][record_index].bank;
|
||||
+ rf_register = rf_record[chain_index][record_index].reg;
|
||||
+ value = rf_record[chain_index][record_index].value;
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, bank, rf_register, value);
|
||||
+ rt2x00_dbg(rt2x00dev, "bank: %d, rf_register: %d, value: %x\n", bank, rf_register, value);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_setbbptonegenerator(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xAA);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xAB);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x0A);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xAC);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x3F);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xAD);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x3F);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 244, 0x40);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static u32 rt2800_do_fft_accumulation(struct rt2x00_dev *rt2x00dev, u8 tidx, u8 read_neg)
|
||||
+{
|
||||
+ u32 macvalue = 0;
|
||||
+ int fftout_i = 0, fftout_q = 0;
|
||||
+ u32 ptmp=0, pint = 0;
|
||||
+ u8 bbp = 0;
|
||||
+ u8 tidxi;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x9b);
|
||||
+
|
||||
+ bbp = 0x9b;
|
||||
+
|
||||
+ while (bbp == 0x9b) {
|
||||
+ udelay(10);
|
||||
+ bbp = rt2800_bbp_read(rt2x00dev, 159);
|
||||
+ bbp = bbp & 0xff;
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xba);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidx);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidx);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidx);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, 0x057C);
|
||||
+
|
||||
+ fftout_i = (macvalue >> 16);
|
||||
+ fftout_i = (fftout_i & 0x8000) ? (fftout_i - 0x10000) : fftout_i;
|
||||
+ fftout_q = (macvalue & 0xffff);
|
||||
+ fftout_q = (fftout_q & 0x8000) ? (fftout_q - 0x10000) : fftout_q;
|
||||
+ ptmp = (fftout_i * fftout_i);
|
||||
+ ptmp = ptmp + (fftout_q * fftout_q);
|
||||
+ pint = ptmp;
|
||||
+ rt2x00_dbg(rt2x00dev, "I = %d, Q = %d, power = %x\n", fftout_i, fftout_q, pint);
|
||||
+ if (read_neg) {
|
||||
+ pint = pint >> 1;
|
||||
+ tidxi = 0x40 - tidx;
|
||||
+ tidxi = tidxi & 0x3f;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xba);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidxi);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidxi);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidxi);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, 0x057C);
|
||||
+
|
||||
+ fftout_i = (macvalue >> 16);
|
||||
+ fftout_i = (fftout_i & 0x8000) ? (fftout_i - 0x10000) : fftout_i;
|
||||
+ fftout_q = (macvalue & 0xffff);
|
||||
+ fftout_q = (fftout_q & 0x8000) ? (fftout_q - 0x10000) : fftout_q;
|
||||
+ ptmp = (fftout_i * fftout_i);
|
||||
+ ptmp = ptmp + (fftout_q * fftout_q);
|
||||
+ ptmp = ptmp >> 1;
|
||||
+ pint = pint + ptmp;
|
||||
+ }
|
||||
+
|
||||
+ return pint;
|
||||
+}
|
||||
+
|
||||
+static u32 rt2800_read_fft_accumulation(struct rt2x00_dev *rt2x00dev, u8 tidx) {
|
||||
+ u32 macvalue = 0;
|
||||
+ int fftout_i = 0, fftout_q = 0;
|
||||
+ u32 ptmp=0, pint = 0;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xBA);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidx);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidx);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, tidx);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, 0x057C);
|
||||
+
|
||||
+ fftout_i = (macvalue >> 16);
|
||||
+ fftout_i = (fftout_i & 0x8000) ? (fftout_i - 0x10000) : fftout_i;
|
||||
+ fftout_q = (macvalue & 0xffff);
|
||||
+ fftout_q = (fftout_q & 0x8000) ? (fftout_q - 0x10000) : fftout_q;
|
||||
+ ptmp = (fftout_i * fftout_i);
|
||||
+ ptmp = ptmp + (fftout_q * fftout_q);
|
||||
+ pint = ptmp;
|
||||
+ rt2x00_info(rt2x00dev, "I = %d, Q = %d, power = %x\n", fftout_i, fftout_q, pint);
|
||||
+
|
||||
+ return pint;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_write_dc(struct rt2x00_dev *rt2x00dev, u8 ch_idx, u8 alc, u8 iorq, u8 dc)
|
||||
+{
|
||||
+ u8 bbp = 0;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xb0);
|
||||
+ bbp = alc | 0x80;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+
|
||||
+ if (ch_idx == 0)
|
||||
+ bbp = (iorq == 0) ? 0xb1: 0xb2;
|
||||
+ else
|
||||
+ bbp = (iorq == 0) ? 0xb8: 0xb9;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ bbp = dc;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_loft_search(struct rt2x00_dev *rt2x00dev, u8 ch_idx, u8 alc_idx, u8 dc_result[][RF_ALC_NUM][2])
|
||||
+{
|
||||
+ u32 p0 = 0, p1 = 0, pf = 0;
|
||||
+ char idx0 = 0, idx1 = 0;
|
||||
+ u8 idxf[] = {0x00, 0x00};
|
||||
+ u8 ibit = 0x20;
|
||||
+ u8 iorq;
|
||||
+ char bidx;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xb0);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x80);
|
||||
+
|
||||
+ for (bidx = 5; bidx >= 0; bidx--) {
|
||||
+ for (iorq = 0; iorq <= 1; iorq++) {
|
||||
+ rt2x00_dbg(rt2x00dev, "\n========================================================\n");
|
||||
+
|
||||
+ if (idxf[iorq] == 0x20) {
|
||||
+ idx0 = 0x20;
|
||||
+ p0 = pf;
|
||||
+ } else {
|
||||
+ idx0 = idxf[iorq] - ibit;
|
||||
+ idx0 = idx0 & 0x3F;
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idx0);
|
||||
+ p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
|
||||
+ }
|
||||
+
|
||||
+ idx1 = idxf[iorq] + ((bidx == 5) ? 0 : ibit);
|
||||
+ idx1 = idx1 & 0x3F;
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idx1);
|
||||
+ p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
|
||||
+
|
||||
+ rt2x00_dbg(rt2x00dev, "alc=%u, IorQ=%u, idx_final=%2x\n", alc_idx, iorq, idxf[iorq]);
|
||||
+ rt2x00_dbg(rt2x00dev, "p0=%x, p1=%x, pf=%x, idx_0=%x, idx_1=%x, ibit=%x !\n", p0, p1, pf, idx0, idx1, ibit);
|
||||
+
|
||||
+ if ((bidx != 5) && (pf <= p0) && (pf < p1)) {
|
||||
+ pf = pf;
|
||||
+ idxf[iorq] = idxf[iorq];
|
||||
+ } else if (p0 < p1) {
|
||||
+ pf = p0;
|
||||
+ idxf[iorq] = idx0 & 0x3F;
|
||||
+ } else {
|
||||
+ pf = p1;
|
||||
+ idxf[iorq] = idx1 & 0x3F;
|
||||
+ }
|
||||
+ rt2x00_dbg(rt2x00dev, "IorQ=%u, idx_final[%u]:%x, pf:%8x\n", iorq, iorq, idxf[iorq], pf);
|
||||
+
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, iorq, idxf[iorq]);
|
||||
+
|
||||
+ }
|
||||
+ ibit = ibit >> 1;
|
||||
+ }
|
||||
+ dc_result[ch_idx][alc_idx][0] = idxf[0];
|
||||
+ dc_result[ch_idx][alc_idx][1] = idxf[1];
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_iq_search(struct rt2x00_dev *rt2x00dev, u8 ch_idx, u8 *ges, u8 *pes)
|
||||
+{
|
||||
+ u32 p0 = 0, p1 = 0, pf = 0;
|
||||
+ char perr = 0, gerr = 0, iq_err = 0;
|
||||
+ char pef = 0, gef = 0;
|
||||
+ char psta, pend;
|
||||
+ char gsta, gend;
|
||||
+
|
||||
+ u8 ibit = 0x20;
|
||||
+ u8 first_search = 0x00, touch_neg_max = 0x00;
|
||||
+ char idx0 = 0, idx1 = 0;
|
||||
+ u8 gop;
|
||||
+ u8 bbp = 0;
|
||||
+ char bidx;
|
||||
+
|
||||
+ rt2x00_info(rt2x00dev, "IQCalibration Start!\n");
|
||||
+ for (bidx = 5; bidx >= 1; bidx--) {
|
||||
+ for (gop = 0; gop < 2; gop++) {
|
||||
+ rt2x00_dbg(rt2x00dev, "\n========================================================\n");
|
||||
+
|
||||
+ if ((gop == 1) || (bidx < 4)) {
|
||||
+ if (gop == 0)
|
||||
+ iq_err = gerr;
|
||||
+ else
|
||||
+ iq_err = perr;
|
||||
+
|
||||
+ first_search = (gop == 0) ? (bidx == 3) : (bidx == 5);
|
||||
+ touch_neg_max = (gop) ? ((iq_err & 0x0F) == 0x08) : ((iq_err & 0x3F) == 0x20);
|
||||
+
|
||||
+ if (touch_neg_max) {
|
||||
+ p0 = pf;
|
||||
+ idx0 = iq_err;
|
||||
+ } else {
|
||||
+ idx0 = iq_err - ibit;
|
||||
+ bbp = (ch_idx == 0) ? ((gop == 0) ? 0x28 : 0x29): ((gop == 0) ? 0x46 : 0x47);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, idx0);
|
||||
+
|
||||
+ p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1);
|
||||
+ }
|
||||
+
|
||||
+ idx1 = iq_err + (first_search ? 0 : ibit);
|
||||
+ idx1 = (gop == 0) ? (idx1 & 0x0F) : (idx1 & 0x3F);
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? (gop == 0) ? 0x28 : 0x29 : (gop == 0) ? 0x46 : 0x47;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, idx1);
|
||||
+
|
||||
+ p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1);
|
||||
+
|
||||
+ rt2x00_dbg(rt2x00dev, "p0=%x, p1=%x, pwer_final=%x, idx0=%x, idx1=%x, iq_err=%x, gop=%d, ibit=%x !\n", p0, p1, pf, idx0, idx1, iq_err, gop, ibit);
|
||||
+
|
||||
+ if ((!first_search) && (pf <= p0) && (pf < p1)) {
|
||||
+ pf = pf;
|
||||
+ } else if (p0 < p1) {
|
||||
+ pf = p0;
|
||||
+ iq_err = idx0;
|
||||
+ } else {
|
||||
+ pf = p1;
|
||||
+ iq_err = idx1;
|
||||
+ }
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? (gop == 0) ? 0x28 : 0x29 : (gop == 0) ? 0x46 : 0x47;
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, iq_err);
|
||||
+
|
||||
+ if (gop == 0)
|
||||
+ gerr = iq_err;
|
||||
+ else
|
||||
+ perr = iq_err;
|
||||
+
|
||||
+ rt2x00_dbg(rt2x00dev, "IQCalibration pf=%8x (%2x, %2x) !\n", pf, gerr & 0x0F, perr & 0x3F);
|
||||
+
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (bidx > 0)
|
||||
+ ibit = (ibit >> 1);
|
||||
+ }
|
||||
+ gerr = (gerr & 0x08) ? (gerr & 0x0F) - 0x10 : (gerr & 0x0F);
|
||||
+ perr = (perr & 0x20) ? (perr & 0x3F) - 0x40 : (perr & 0x3F);
|
||||
+
|
||||
+ gerr = (gerr < -0x07) ? -0x07 : (gerr > 0x05) ? 0x05 : gerr;
|
||||
+ gsta = gerr - 1;
|
||||
+ gend = gerr + 2;
|
||||
+
|
||||
+ perr = (perr < -0x1f) ? -0x1f : (perr > 0x1d) ? 0x1d : perr;
|
||||
+ psta = perr - 1;
|
||||
+ pend = perr + 2;
|
||||
+
|
||||
+ for (gef = gsta; gef <= gend; gef = gef + 1)
|
||||
+ for (pef = psta; pef <= pend; pef = pef + 1) {
|
||||
+ bbp = (ch_idx == 0) ? 0x28 : 0x46;
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, gef & 0x0F);
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? 0x29 : 0x47;
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, pef & 0x3F);
|
||||
+
|
||||
+ p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 1);
|
||||
+ if ((gef == gsta) && (pef == psta)) {
|
||||
+ pf = p1;
|
||||
+ gerr = gef;
|
||||
+ perr = pef;
|
||||
+ }
|
||||
+ else if (pf > p1){
|
||||
+ pf = p1;
|
||||
+ gerr = gef;
|
||||
+ perr = pef;
|
||||
+ }
|
||||
+ rt2x00_dbg(rt2x00dev, "Fine IQCalibration p1=%8x pf=%8x (%2x, %2x) !\n", p1, pf, gef & 0x0F, pef & 0x3F);
|
||||
+ }
|
||||
+
|
||||
+ ges[ch_idx] = gerr & 0x0F;
|
||||
+ pes[ch_idx] = perr & 0x3F;
|
||||
+
|
||||
+ rt2x00_info(rt2x00dev, "IQCalibration Done! CH = %u, (gain=%2x, phase=%2x)\n", ch_idx, gerr & 0x0F, perr & 0x3F);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void rt2800_rf_aux_tx0_loopback(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, 0x21);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, 0x10);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x00);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, 0x1b);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 0, 0x81);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 2, 0x81);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 4, 34, 0xee);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 3, 0x2d);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, 0x2d);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 17, 0x80);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 18, 0xd7);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 19, 0xa2);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 5, 20, 0x20);
|
||||
+}
|
||||
+
|
||||
+static void rt2800_rf_aux_tx1_loopback(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 1, 0x22);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 2, 0x20);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 35, 0x00);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, 0x4b);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 0, 0x81);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 2, 0x81);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 6, 34, 0xee);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 3, 0x2d);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, 0x2d);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 17, 0x80);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 18, 0xd7);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 19, 0xa2);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 7, 20, 0x20);
|
||||
+}
|
||||
+
|
||||
+void rt2800_loft_iq_calibration(struct rt2x00_dev *rt2x00dev)
|
||||
+{
|
||||
+ rf_reg_pair rf_store[CHAIN_NUM][13];
|
||||
+ u32 macorg1 = 0;
|
||||
+ u32 macorg2 = 0;
|
||||
+ u32 macorg3 = 0;
|
||||
+ u32 macorg4 = 0;
|
||||
+ u32 macorg5 = 0;
|
||||
+ u32 orig528 = 0;
|
||||
+ u32 orig52c = 0;
|
||||
+
|
||||
+ u32 savemacsysctrl = 0, mtxcycle = 0;
|
||||
+ u32 macvalue = 0;
|
||||
+ u32 mac13b8 = 0;
|
||||
+ u32 p0 = 0, p1 = 0;
|
||||
+ u32 p0_idx10 = 0, p1_idx10 = 0;
|
||||
+
|
||||
+ u8 rfvalue;
|
||||
+ u8 loft_dc_search_result[CHAIN_NUM][RF_ALC_NUM][2];
|
||||
+ u8 ger[CHAIN_NUM], per[CHAIN_NUM];
|
||||
+ u8 rf_gain[] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x0c};
|
||||
+ u8 rfvga_gain_table[] = {0x24, 0x25, 0x26, 0x27, 0x28, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3F};
|
||||
+
|
||||
+ u8 vga_gain[] = {14, 14};
|
||||
+ u8 bbp_2324gain[] = {0x16, 0x14, 0x12, 0x10, 0x0c, 0x08};
|
||||
+ u8 bbp = 0, ch_idx = 0, rf_alc_idx = 0, idx = 0;
|
||||
+ u8 bbpr30, rfb0r39, rfb0r42;
|
||||
+ u8 bbpr1;
|
||||
+ u8 bbpr4;
|
||||
+ u8 bbpr241, bbpr242;
|
||||
+ u8 count_step;
|
||||
+
|
||||
+ savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ macorg1 = rt2800_register_read(rt2x00dev, TX_PIN_CFG);
|
||||
+ macorg2 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
|
||||
+ macorg3 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
|
||||
+ macorg4 = rt2800_register_read(rt2x00dev, RF_CONTROL3);
|
||||
+ macorg5 = rt2800_register_read(rt2x00dev, RF_BYPASS3);
|
||||
+ mac13b8 = rt2800_register_read(rt2x00dev, 0x13b8);
|
||||
+ orig528 = rt2800_register_read(rt2x00dev, RF_CONTROL2);
|
||||
+ orig52c = rt2800_register_read(rt2x00dev, RF_BYPASS2);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ macvalue &= (~0x04);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
|
||||
+
|
||||
+ for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
|
||||
+ if (macvalue & 0x01)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ macvalue &= (~0x08);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
|
||||
+
|
||||
+ for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
|
||||
+ if (macvalue & 0x02)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ for (ch_idx = 0; ch_idx < 2; ch_idx++) {
|
||||
+ rt2800_rf_configstore(rt2x00dev, rf_store, ch_idx);
|
||||
+ }
|
||||
+
|
||||
+ bbpr30 = rt2800_bbp_read(rt2x00dev, 30);
|
||||
+ rfb0r39 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 39);
|
||||
+ rfb0r42 = rt2800_rfcsr_read_bank(rt2x00dev, 0, 42);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 30, 0x1F);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 39, 0x80);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, 0x5B);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x00);
|
||||
+
|
||||
+ rt2800_setbbptonegenerator(rt2x00dev);
|
||||
+
|
||||
+ for (ch_idx = 0; ch_idx < 2; ch_idx ++) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x0000000F);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00003306);
|
||||
+ rt2800_register_write(rt2x00dev, 0x13b8, 0x10);
|
||||
+ udelay(1);
|
||||
+
|
||||
+ if (ch_idx == 0) {
|
||||
+ rt2800_rf_aux_tx0_loopback(rt2x00dev);
|
||||
+ } else {
|
||||
+ rt2800_rf_aux_tx1_loopback(rt2x00dev);
|
||||
+ }
|
||||
+ udelay(1);
|
||||
+
|
||||
+ if (ch_idx == 0) {
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001004);
|
||||
+ } else {
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002004);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x05);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x01);
|
||||
+ if (ch_idx == 0)
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+ else
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x01);
|
||||
+
|
||||
+ vga_gain[ch_idx] = 18;
|
||||
+ for (rf_alc_idx = 0; rf_alc_idx < 3; rf_alc_idx++) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, bbp_2324gain[rf_alc_idx]);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, bbp_2324gain[rf_alc_idx]);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, RF_CONTROL3);
|
||||
+ macvalue &= (~0x0000F1F1);
|
||||
+ macvalue |= (rf_gain[rf_alc_idx] << 4);
|
||||
+ macvalue |= (rf_gain[rf_alc_idx] << 12);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, macvalue);
|
||||
+ macvalue = (0x0000F1F1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, macvalue);
|
||||
+
|
||||
+ if (rf_alc_idx == 0) {
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x21);
|
||||
+ for (;vga_gain[ch_idx] > 0;vga_gain[ch_idx] = vga_gain[ch_idx] - 2) {
|
||||
+ rfvalue = rfvga_gain_table[vga_gain[ch_idx]];
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue);
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x00);
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x00);
|
||||
+ p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x21);
|
||||
+ p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x0A, 0);
|
||||
+ rt2x00_dbg(rt2x00dev, "LOFT AGC %d %d\n", p0, p1);
|
||||
+ if ((p0 < 7000*7000) && (p1 < (7000*7000))) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, 0, 0x00);
|
||||
+ rt2800_write_dc(rt2x00dev, ch_idx, 0, 1, 0x00);
|
||||
+
|
||||
+ rt2x00_dbg(rt2x00dev, "Used VGA %d %x\n",vga_gain[ch_idx], rfvga_gain_table[vga_gain[ch_idx]]);
|
||||
+
|
||||
+ if (vga_gain[ch_idx] < 0)
|
||||
+ vga_gain[ch_idx] = 0;
|
||||
+ }
|
||||
+
|
||||
+ rfvalue = rfvga_gain_table[vga_gain[ch_idx]];
|
||||
+
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue);
|
||||
+
|
||||
+ rt2800_loft_search(rt2x00dev, ch_idx, rf_alc_idx, loft_dc_search_result);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (rf_alc_idx = 0; rf_alc_idx < 3; rf_alc_idx++) {
|
||||
+ for (idx = 0; idx < 4; idx++) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xB0);
|
||||
+ bbp = (idx<<2) + rf_alc_idx;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+ rt2x00_dbg(rt2x00dev, " ALC %2x,", bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xb1);
|
||||
+ bbp = loft_dc_search_result[CHAIN_0][rf_alc_idx][0x00];
|
||||
+ bbp = bbp & 0x3F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+ rt2x00_dbg(rt2x00dev, " I0 %2x,", bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xb2);
|
||||
+ bbp = loft_dc_search_result[CHAIN_0][rf_alc_idx][0x01];
|
||||
+ bbp = bbp & 0x3F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+ rt2x00_dbg(rt2x00dev, " Q0 %2x,", bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xb8);
|
||||
+ bbp = loft_dc_search_result[CHAIN_1][rf_alc_idx][0x00];
|
||||
+ bbp = bbp & 0x3F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+ rt2x00_dbg(rt2x00dev, " I1 %2x,", bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xb9);
|
||||
+ bbp = loft_dc_search_result[CHAIN_1][rf_alc_idx][0x01];
|
||||
+ bbp = bbp & 0x3F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+ rt2x00_dbg(rt2x00dev, " Q1 %2x\n", bbp);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x00);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+
|
||||
+ bbp = 0x00;
|
||||
+ rt2800_bbp_write(rt2x00dev, 244, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, 0x01);
|
||||
+ udelay(1);
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, 0x00);
|
||||
+
|
||||
+ rt2800_rf_configrecover(rt2x00dev, rf_store);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, macorg1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, macorg2);
|
||||
+ udelay(1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, macorg3);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, macorg4);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, macorg5);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL2, orig528);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS2, orig52c);
|
||||
+ rt2800_register_write(rt2x00dev, 0x13b8, mac13b8);
|
||||
+
|
||||
+ rt2x00_info(rt2x00dev, "LOFT Calibration Done!\n");
|
||||
+
|
||||
+ savemacsysctrl = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ macorg1 = rt2800_register_read(rt2x00dev, TX_PIN_CFG);
|
||||
+ macorg2 = rt2800_register_read(rt2x00dev, RF_CONTROL0);
|
||||
+ macorg3 = rt2800_register_read(rt2x00dev, RF_BYPASS0);
|
||||
+ macorg4 = rt2800_register_read(rt2x00dev, RF_CONTROL3);
|
||||
+ macorg5 = rt2800_register_read(rt2x00dev, RF_BYPASS3);
|
||||
+
|
||||
+ bbpr1 = rt2800_bbp_read(rt2x00dev, 1);
|
||||
+ bbpr4 = rt2800_bbp_read(rt2x00dev, 4);
|
||||
+ bbpr241 = rt2800_bbp_read(rt2x00dev, 241);
|
||||
+ bbpr242 = rt2800_bbp_read(rt2x00dev, 242);
|
||||
+ mac13b8 = rt2800_register_read(rt2x00dev, 0x13b8);
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ macvalue &= (~0x04);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
|
||||
+ for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
|
||||
+ if (macvalue & 0x01)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_SYS_CTRL);
|
||||
+ macvalue &= (~0x08);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, macvalue);
|
||||
+ for (mtxcycle = 0; mtxcycle < 10000; mtxcycle++) {
|
||||
+ macvalue = rt2800_register_read(rt2x00dev, MAC_STATUS_CFG);
|
||||
+ if (macvalue & 0x02)
|
||||
+ udelay(50);
|
||||
+ else
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x00000101);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0000F1F1);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x00);
|
||||
+
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 4, bbpr4 & (~0x18));
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, 0x01);
|
||||
+ udelay(1);
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 241, 0x14);
|
||||
+ rt2800_bbp_write(rt2x00dev, 242, 0x80);
|
||||
+ rt2800_bbp_write(rt2x00dev, 244, 0x31);
|
||||
+ } else {
|
||||
+ rt2800_setbbptonegenerator(rt2x00dev);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00000004);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00003306);
|
||||
+ udelay(1);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x0000000F);
|
||||
+
|
||||
+ if (!test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, 0x00000000);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, 0x0000F1F1);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, 0x13b8, 0x00000010);
|
||||
+
|
||||
+ for (ch_idx = 0; ch_idx < 2; ch_idx++) {
|
||||
+ rt2800_rf_configstore(rt2x00dev, rf_store, ch_idx);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, 0x3B);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, 0x3B);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x03);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x60);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xB0);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x80);
|
||||
+
|
||||
+ for (ch_idx = 0; ch_idx < 2; ch_idx ++) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x00);
|
||||
+
|
||||
+ if (ch_idx == 0) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x01);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ bbp = bbpr1 & (~0x18);
|
||||
+ bbp = bbp | 0x00;
|
||||
+ rt2800_bbp_write(rt2x00dev, 1, bbp);
|
||||
+ }
|
||||
+ rt2800_rf_aux_tx0_loopback(rt2x00dev);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00001004);
|
||||
+ } else {
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x01);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x01);
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX1, &rt2x00dev->cap_flags)) {
|
||||
+ bbp = bbpr1 & (~0x18);
|
||||
+ bbp = bbp | 0x08;
|
||||
+ rt2800_bbp_write(rt2x00dev, 1, bbp);
|
||||
+ }
|
||||
+ rt2800_rf_aux_tx1_loopback(rt2x00dev);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00002004);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x05);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x04);
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? 0x28 : 0x46;
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x06);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x06);
|
||||
+ count_step = 1;
|
||||
+ } else {
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x1F);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x1F);
|
||||
+ count_step = 2;
|
||||
+ }
|
||||
+
|
||||
+ for (;vga_gain[ch_idx] < 19; vga_gain[ch_idx]=(vga_gain[ch_idx] + count_step)) {
|
||||
+ rfvalue = rfvga_gain_table[vga_gain[ch_idx]];
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 3, rfvalue);
|
||||
+ rt2800_rfcsr_write_dccal(rt2x00dev, 4, rfvalue);
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? 0x29 : 0x47;
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+ p0 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 0);
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ p0_idx10 = rt2800_read_fft_accumulation(rt2x00dev, 0x0A);
|
||||
+ }
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? 0x29 : 0x47;
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x21);
|
||||
+ p1 = rt2800_do_fft_accumulation(rt2x00dev, 0x14, 0);
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX1, &rt2x00dev->cap_flags)) {
|
||||
+ p1_idx10 = rt2800_read_fft_accumulation(rt2x00dev, 0x0A);
|
||||
+ }
|
||||
+
|
||||
+ rt2x00_dbg(rt2x00dev, "IQ AGC %d %d\n", p0, p1);
|
||||
+
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2x00_dbg(rt2x00dev, "IQ AGC IDX 10 %d %d\n", p0_idx10, p1_idx10);
|
||||
+ if ((p0_idx10 > 7000*7000) || (p1_idx10 > 7000*7000)) {
|
||||
+ if (vga_gain[ch_idx]!=0)
|
||||
+ vga_gain[ch_idx] = vga_gain[ch_idx]-1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((p0 > 2500*2500) || (p1 > 2500*2500)) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (vga_gain[ch_idx] > 18)
|
||||
+ vga_gain[ch_idx] = 18;
|
||||
+ rt2x00_dbg(rt2x00dev, "Used VGA %d %x\n",vga_gain[ch_idx], rfvga_gain_table[vga_gain[ch_idx]]);
|
||||
+
|
||||
+ bbp = (ch_idx == 0) ? 0x29 : 0x47;
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, bbp);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+
|
||||
+ rt2800_iq_search(rt2x00dev, ch_idx, ger, per);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 23, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 24, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x04);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x28);
|
||||
+ bbp = ger[CHAIN_0] & 0x0F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x29);
|
||||
+ bbp = per[CHAIN_0] & 0x3F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x46);
|
||||
+ bbp = ger[CHAIN_1] & 0x0F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x47);
|
||||
+ bbp = per[CHAIN_1] & 0x3F;
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, bbp);
|
||||
+
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 1, bbpr1);
|
||||
+ rt2800_bbp_write(rt2x00dev, 241, bbpr241);
|
||||
+ rt2800_bbp_write(rt2x00dev, 242, bbpr242);
|
||||
+ }
|
||||
+ rt2800_bbp_write(rt2x00dev, 244, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+ rt2800_bbp_write(rt2x00dev, 158, 0xB0);
|
||||
+ rt2800_bbp_write(rt2x00dev, 159, 0x00);
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 30, bbpr30);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 39, rfb0r39);
|
||||
+ rt2800_rfcsr_write_bank(rt2x00dev, 0, 42, rfb0r42);
|
||||
+
|
||||
+ if (test_bit(CAPABILITY_EXTERNAL_PA_TX0, &rt2x00dev->cap_flags)) {
|
||||
+ rt2800_bbp_write(rt2x00dev, 4, bbpr4);
|
||||
+ }
|
||||
+
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, 0x01);
|
||||
+ udelay(1);
|
||||
+ rt2800_bbp_write(rt2x00dev, 21, 0x00);
|
||||
+
|
||||
+ rt2800_rf_configrecover(rt2x00dev, rf_store);
|
||||
+
|
||||
+ rt2800_register_write(rt2x00dev, TX_PIN_CFG, macorg1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, 0x00);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL0, macorg2);
|
||||
+ udelay(1);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS0, macorg3);
|
||||
+ rt2800_register_write(rt2x00dev, RF_CONTROL3, macorg4);
|
||||
+ rt2800_register_write(rt2x00dev, RF_BYPASS3, macorg5);
|
||||
+ rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, savemacsysctrl);
|
||||
+ rt2800_register_write(rt2x00dev, 0x13b8, mac13b8);
|
||||
+
|
||||
+ rt2x00_info(rt2x00dev, "TX IQ Calibration Done!\n");
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev,
|
||||
bool set_bw, bool is_ht40)
|
||||
{
|
||||
@@ -9672,6 +10609,7 @@ static void rt2800_init_rfcsr_6352(struc
|
||||
rt2800_rxdcoc_calibration(rt2x00dev);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, true);
|
||||
rt2800_bw_filter_calibration(rt2x00dev, false);
|
||||
+ rt2800_loft_iq_calibration(rt2x00dev);
|
||||
rt2800_rxiq_calibration(rt2x00dev);
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
|
||||
@@ -17,6 +17,16 @@
|
||||
#define WCID_START 33
|
||||
#define WCID_END 222
|
||||
#define STA_IDS_SIZE (WCID_END - WCID_START + 2)
|
||||
+#define CHAIN_0 0x0
|
||||
+#define CHAIN_1 0x1
|
||||
+#define RF_ALC_NUM 6
|
||||
+#define CHAIN_NUM 2
|
||||
+
|
||||
+typedef struct rf_reg_pair {
|
||||
+ u8 bank;
|
||||
+ u8 reg;
|
||||
+ u8 value;
|
||||
+} rf_reg_pair;
|
||||
|
||||
/* RT2800 driver data structure */
|
||||
struct rt2800_drv_data {
|
@ -1,27 +0,0 @@
|
||||
From 66ae1b1750720a33e29792a177b1e696f4f005fb Mon Sep 17 00:00:00 2001
|
||||
From: Phil Elwell <phil@raspberrypi.org>
|
||||
Date: Wed, 9 Mar 2016 17:25:59 +0000
|
||||
Subject: [PATCH] brcmfmac: Disable power management
|
||||
|
||||
Disable wireless power saving in the brcmfmac WLAN driver. This is a
|
||||
temporary measure until the connectivity loss resulting from power
|
||||
saving is resolved.
|
||||
|
||||
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
||||
---
|
||||
drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -2961,6 +2961,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
|
||||
* preference in cfg struct to apply this to
|
||||
* FW later while initializing the dongle
|
||||
*/
|
||||
+#if defined(CONFIG_ARCH_BCM2835)
|
||||
+ brcmf_dbg(INFO, "power management disabled\n");
|
||||
+ enabled = false;
|
||||
+#endif
|
||||
cfg->pwr_save = enabled;
|
||||
if (!check_vif_up(ifp->vif)) {
|
||||
|
@ -1,14 +0,0 @@
|
||||
--- a/kconf/Makefile
|
||||
+++ b/kconf/Makefile
|
||||
@@ -1,9 +1,9 @@
|
||||
-CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer
|
||||
+CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -DKBUILD_NO_NLS
|
||||
|
||||
LXDIALOG := lxdialog/checklist.o lxdialog/inputbox.o lxdialog/menubox.o lxdialog/textbox.o lxdialog/util.o lxdialog/yesno.o
|
||||
|
||||
conf: conf.o zconf.tab.o
|
||||
-mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags) -DLOCALE
|
||||
+mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags)
|
||||
mconf_LDFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
|
||||
mconf: CFLAGS += $(mconf_CFLAGS)
|
||||
|
@ -1,60 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Tue, 14 Dec 2021 17:53:12 +0100
|
||||
Subject: [PATCH] mac80211: use coarse boottime for airtime fairness code
|
||||
|
||||
The time values used by the airtime fairness code only need to be accurate
|
||||
enough to cover station activity detection.
|
||||
Using ktime_get_coarse_boottime_ns instead of ktime_get_boottime_ns will
|
||||
drop the accuracy down to jiffies intervals, but at the same time saves
|
||||
a lot of CPU cycles in a hot path
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3834,7 +3834,7 @@ struct ieee80211_txq *ieee80211_next_txq
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct airtime_sched_info *air_sched;
|
||||
- u64 now = ktime_get_boottime_ns();
|
||||
+ u64 now = ktime_get_coarse_boottime_ns();
|
||||
struct ieee80211_txq *ret = NULL;
|
||||
struct airtime_info *air_info;
|
||||
struct txq_info *txqi = NULL;
|
||||
@@ -3961,7 +3961,7 @@ void ieee80211_update_airtime_weight(str
|
||||
u64 weight_sum = 0;
|
||||
|
||||
if (unlikely(!now))
|
||||
- now = ktime_get_boottime_ns();
|
||||
+ now = ktime_get_coarse_boottime_ns();
|
||||
|
||||
lockdep_assert_held(&air_sched->lock);
|
||||
|
||||
@@ -3987,7 +3987,7 @@ void ieee80211_schedule_txq(struct ieee8
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct txq_info *txqi = to_txq_info(txq);
|
||||
struct airtime_sched_info *air_sched;
|
||||
- u64 now = ktime_get_boottime_ns();
|
||||
+ u64 now = ktime_get_coarse_boottime_ns();
|
||||
struct airtime_info *air_info;
|
||||
u8 ac = txq->ac;
|
||||
bool was_active;
|
||||
@@ -4045,7 +4045,7 @@ static void __ieee80211_unschedule_txq(s
|
||||
|
||||
if (!purge)
|
||||
airtime_set_active(air_sched, air_info,
|
||||
- ktime_get_boottime_ns());
|
||||
+ ktime_get_coarse_boottime_ns());
|
||||
|
||||
rb_erase_cached(&txqi->schedule_order,
|
||||
&air_sched->active_txqs);
|
||||
@@ -4133,7 +4133,7 @@ bool ieee80211_txq_may_transmit(struct i
|
||||
if (RB_EMPTY_NODE(&txqi->schedule_order))
|
||||
goto out;
|
||||
|
||||
- now = ktime_get_boottime_ns();
|
||||
+ now = ktime_get_coarse_boottime_ns();
|
||||
|
||||
/* Like in ieee80211_next_txq(), make sure the first station in the
|
||||
* scheduling order is eligible for transmission to avoid starvation.
|
@ -1,32 +0,0 @@
|
||||
--- /dev/null
|
||||
+++ b/include/linux/rt2x00_platform.h
|
||||
@@ -0,0 +1,19 @@
|
||||
+/*
|
||||
+ * Platform data definition for the rt2x00 driver
|
||||
+ *
|
||||
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#ifndef _RT2X00_PLATFORM_H
|
||||
+#define _RT2X00_PLATFORM_H
|
||||
+
|
||||
+struct rt2x00_platform_data {
|
||||
+ char *eeprom_file_name;
|
||||
+};
|
||||
+
|
||||
+#endif /* _RT2X00_PLATFORM_H */
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/average.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/clk.h>
|
||||
+#include <linux/rt2x00_platform.h>
|
||||
|
||||
#include <net/mac80211.h>
|
||||
|
@ -1,64 +0,0 @@
|
||||
--- a/kconf/conf.c
|
||||
+++ b/kconf/conf.c
|
||||
@@ -598,40 +598,12 @@ int main(int ac, char **av)
|
||||
case oldconfig:
|
||||
case listnewconfig:
|
||||
case olddefconfig:
|
||||
- conf_read(NULL);
|
||||
- break;
|
||||
case allnoconfig:
|
||||
case allyesconfig:
|
||||
case allmodconfig:
|
||||
case alldefconfig:
|
||||
case randconfig:
|
||||
- name = getenv("KCONFIG_ALLCONFIG");
|
||||
- if (!name)
|
||||
- break;
|
||||
- if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) {
|
||||
- if (conf_read_simple(name, S_DEF_USER)) {
|
||||
- fprintf(stderr,
|
||||
- _("*** Can't read seed configuration \"%s\"!\n"),
|
||||
- name);
|
||||
- exit(1);
|
||||
- }
|
||||
- break;
|
||||
- }
|
||||
- switch (input_mode) {
|
||||
- case allnoconfig: name = "allno.config"; break;
|
||||
- case allyesconfig: name = "allyes.config"; break;
|
||||
- case allmodconfig: name = "allmod.config"; break;
|
||||
- case alldefconfig: name = "alldef.config"; break;
|
||||
- case randconfig: name = "allrandom.config"; break;
|
||||
- default: break;
|
||||
- }
|
||||
- if (conf_read_simple(name, S_DEF_USER) &&
|
||||
- conf_read_simple("all.config", S_DEF_USER)) {
|
||||
- fprintf(stderr,
|
||||
- _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"),
|
||||
- name);
|
||||
- exit(1);
|
||||
- }
|
||||
+ conf_read(NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
--- a/kconf/confdata.c
|
||||
+++ b/kconf/confdata.c
|
||||
@@ -1170,6 +1170,8 @@ bool conf_set_all_new_symbols(enum conf_
|
||||
}
|
||||
bool has_changed = false;
|
||||
|
||||
+ sym_clear_all_valid();
|
||||
+
|
||||
for_all_symbols(i, sym) {
|
||||
if (sym_has_value(sym) || (sym->flags & SYMBOL_VALID))
|
||||
continue;
|
||||
@@ -1213,8 +1215,6 @@ bool conf_set_all_new_symbols(enum conf_
|
||||
|
||||
}
|
||||
|
||||
- sym_clear_all_valid();
|
||||
-
|
||||
/*
|
||||
* We have different type of choice blocks.
|
||||
* If curr.tri equals to mod then we can select several
|
@ -1,26 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
|
||||
@@ -990,8 +990,13 @@ static void rt2x00lib_rate(struct ieee80
|
||||
|
||||
void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr)
|
||||
{
|
||||
+ struct rt2x00_platform_data *pdata;
|
||||
const char *mac_addr;
|
||||
|
||||
+ pdata = rt2x00dev->dev->platform_data;
|
||||
+ if (pdata && pdata->mac_address)
|
||||
+ ether_addr_copy(eeprom_mac_addr, pdata->mac_address);
|
||||
+
|
||||
mac_addr = of_get_mac_address(rt2x00dev->dev->of_node);
|
||||
if (!IS_ERR(mac_addr))
|
||||
ether_addr_copy(eeprom_mac_addr, mac_addr);
|
||||
--- a/include/linux/rt2x00_platform.h
|
||||
+++ b/include/linux/rt2x00_platform.h
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
struct rt2x00_platform_data {
|
||||
char *eeprom_file_name;
|
||||
+ const u8 *mac_address;
|
||||
|
||||
int disable_2ghz;
|
||||
int disable_5ghz;
|
@ -1,51 +0,0 @@
|
||||
From: Carl Huang <cjhuang@codeaurora.org>
|
||||
Date: Thu, 3 Dec 2020 05:37:27 -0500
|
||||
Subject: [PATCH] mac80211: add ieee80211_set_sar_specs
|
||||
|
||||
This change registers ieee80211_set_sar_specs to
|
||||
mac80211_config_ops, so cfg80211 can call it.
|
||||
|
||||
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
|
||||
Reviewed-by: Brian Norris <briannorris@chromium.org>
|
||||
Reviewed-by: Abhishek Kumar <kuabhs@chromium.org>
|
||||
Link: https://lore.kernel.org/r/20201203103728.3034-3-cjhuang@codeaurora.org
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -4207,6 +4207,8 @@ struct ieee80211_ops {
|
||||
struct ieee80211_vif *vif);
|
||||
void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enabled);
|
||||
+ int (*set_sar_specs)(struct ieee80211_hw *hw,
|
||||
+ const struct cfg80211_sar_specs *sar);
|
||||
void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enabled);
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -4136,6 +4136,17 @@ static int ieee80211_reset_tid_config(st
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int ieee80211_set_sar_specs(struct wiphy *wiphy,
|
||||
+ struct cfg80211_sar_specs *sar)
|
||||
+{
|
||||
+ struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
+
|
||||
+ if (!local->ops->set_sar_specs)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return local->ops->set_sar_specs(&local->hw, sar);
|
||||
+}
|
||||
+
|
||||
const struct cfg80211_ops mac80211_config_ops = {
|
||||
.add_virtual_intf = ieee80211_add_iface,
|
||||
.del_virtual_intf = ieee80211_del_iface,
|
||||
@@ -4239,4 +4250,5 @@ const struct cfg80211_ops mac80211_confi
|
||||
.probe_mesh_link = ieee80211_probe_mesh_link,
|
||||
.set_tid_config = ieee80211_set_tid_config,
|
||||
.reset_tid_config = ieee80211_reset_tid_config,
|
||||
+ .set_sar_specs = ieee80211_set_sar_specs,
|
||||
};
|
@ -1,11 +0,0 @@
|
||||
--- a/drivers/net/wireless/marvell/libertas/cfg.c
|
||||
+++ b/drivers/net/wireless/marvell/libertas/cfg.c
|
||||
@@ -2129,6 +2129,8 @@ int lbs_cfg_register(struct lbs_private
|
||||
wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
|
||||
wdev->wiphy->reg_notifier = lbs_reg_notifier;
|
||||
|
||||
+ memcpy(wdev->wiphy->perm_addr, priv->current_addr, ETH_ALEN);
|
||||
+
|
||||
ret = wiphy_register(wdev->wiphy);
|
||||
if (ret < 0)
|
||||
pr_err("cannot register wiphy device\n");
|
@ -1,139 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/debug.c
|
||||
@@ -1512,6 +1512,50 @@ static const struct file_operations fops
|
||||
#endif
|
||||
|
||||
|
||||
+static ssize_t read_file_diag(struct file *file, char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ath_softc *sc = file->private_data;
|
||||
+ struct ath_hw *ah = sc->sc_ah;
|
||||
+ char buf[32];
|
||||
+ unsigned int len;
|
||||
+
|
||||
+ len = sprintf(buf, "0x%08lx\n", ah->diag);
|
||||
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
+}
|
||||
+
|
||||
+static ssize_t write_file_diag(struct file *file, const char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ath_softc *sc = file->private_data;
|
||||
+ struct ath_hw *ah = sc->sc_ah;
|
||||
+ unsigned long diag;
|
||||
+ char buf[32];
|
||||
+ ssize_t len;
|
||||
+
|
||||
+ len = min(count, sizeof(buf) - 1);
|
||||
+ if (copy_from_user(buf, user_buf, len))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ buf[len] = '\0';
|
||||
+ if (kstrtoul(buf, 0, &diag))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ah->diag = diag;
|
||||
+ ath9k_hw_update_diag(ah);
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations fops_diag = {
|
||||
+ .read = read_file_diag,
|
||||
+ .write = write_file_diag,
|
||||
+ .open = simple_open,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .llseek = default_llseek,
|
||||
+};
|
||||
+
|
||||
+
|
||||
int ath9k_init_debug(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
@@ -1539,6 +1583,8 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||
debugfs_create_file("gpio_led", S_IWUSR,
|
||||
sc->debug.debugfs_phy, sc, &fops_gpio_led);
|
||||
#endif
|
||||
+ debugfs_create_file("diag", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
|
||||
+ sc, &fops_diag);
|
||||
debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
|
||||
read_file_dma);
|
||||
debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.h
|
||||
@@ -522,6 +522,12 @@ enum {
|
||||
ATH9K_RESET_COLD,
|
||||
};
|
||||
|
||||
+enum {
|
||||
+ ATH_DIAG_DISABLE_RX,
|
||||
+ ATH_DIAG_DISABLE_TX,
|
||||
+ ATH_DIAG_TRIGGER_ERROR,
|
||||
+};
|
||||
+
|
||||
struct ath9k_hw_version {
|
||||
u32 magic;
|
||||
u16 devid;
|
||||
@@ -810,6 +816,8 @@ struct ath_hw {
|
||||
u32 ah_flags;
|
||||
s16 nf_override;
|
||||
|
||||
+ unsigned long diag;
|
||||
+
|
||||
bool reset_power_on;
|
||||
bool htc_reset_init;
|
||||
|
||||
@@ -1077,6 +1085,7 @@ void ath9k_hw_check_nav(struct ath_hw *a
|
||||
bool ath9k_hw_check_alive(struct ath_hw *ah);
|
||||
|
||||
bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
|
||||
+void ath9k_hw_update_diag(struct ath_hw *ah);
|
||||
|
||||
/* Generic hw timer primitives */
|
||||
struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -1882,6 +1882,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_get_tsf_offset);
|
||||
|
||||
+void ath9k_hw_update_diag(struct ath_hw *ah)
|
||||
+{
|
||||
+ if (test_bit(ATH_DIAG_DISABLE_RX, &ah->diag))
|
||||
+ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
|
||||
+ else
|
||||
+ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
|
||||
+
|
||||
+ if (test_bit(ATH_DIAG_DISABLE_TX, &ah->diag))
|
||||
+ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK);
|
||||
+ else
|
||||
+ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK);
|
||||
+}
|
||||
+EXPORT_SYMBOL(ath9k_hw_update_diag);
|
||||
+
|
||||
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
struct ath9k_hw_cal_data *caldata, bool fastcc)
|
||||
{
|
||||
@@ -2090,6 +2104,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
||||
ar9003_hw_disable_phy_restart(ah);
|
||||
|
||||
ath9k_hw_apply_gpio_override(ah);
|
||||
+ ath9k_hw_update_diag(ah);
|
||||
|
||||
if (AR_SREV_9565(ah) && common->bt_ant_diversity)
|
||||
REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -538,6 +538,11 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
+ if (test_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag)) {
|
||||
+ status |= ATH9K_INT_FATAL;
|
||||
+ clear_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag);
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* If there are no status bits set, then this interrupt was not
|
||||
* for me (should have been caught above).
|
@ -1,15 +0,0 @@
|
||||
--- a/backport-include/linux/rfkill.h
|
||||
+++ b/backport-include/linux/rfkill.h
|
||||
@@ -2,6 +2,12 @@
|
||||
#define __COMPAT_RFKILL_H
|
||||
#include <linux/version.h>
|
||||
|
||||
+#undef CONFIG_RFKILL
|
||||
+#undef CONFIG_RFKILL_FULL
|
||||
+#undef CONFIG_RFKILL_LEDS
|
||||
+#undef CONFIG_RFKILL_MODULE
|
||||
+#undef CONFIG_RFKILL_FULL_MODULE
|
||||
+
|
||||
#if LINUX_VERSION_IS_GEQ(3,10,0)
|
||||
#include_next <linux/rfkill.h>
|
||||
#else
|
@ -1,21 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 28 Apr 2021 21:03:13 +0200
|
||||
Subject: [PATCH] mac80211: minstrel_ht: fix MINSTREL_FRAC macro
|
||||
|
||||
Add missing braces to avoid issues with e.g. using additions in the
|
||||
div expression
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.h
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.h
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
/* scaled fraction values */
|
||||
#define MINSTREL_SCALE 12
|
||||
-#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div)
|
||||
+#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / (div))
|
||||
#define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE)
|
||||
|
||||
#define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */
|
@ -1,11 +0,0 @@
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -2463,7 +2463,7 @@ static int ieee80211_scan(struct wiphy *
|
||||
* the frames sent while scanning on other channel will be
|
||||
* lost)
|
||||
*/
|
||||
- if (sdata->u.ap.beacon &&
|
||||
+ if (0 && sdata->u.ap.beacon &&
|
||||
(!(wiphy->features & NL80211_FEATURE_AP_SCAN) ||
|
||||
!(req->flags & NL80211_SCAN_FLAG_AP)))
|
||||
return -EOPNOTSUPP;
|
@ -1,251 +0,0 @@
|
||||
From: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
|
||||
Date: Sun, 31 Jan 2016 21:01:31 +0100
|
||||
Subject: [PATCH v4 4/8] mac80211: ath9k: enable access to GPIO
|
||||
|
||||
Enable access to GPIO chip and its pins for Atheros AR92xx
|
||||
wireless devices. For now AR9285 and AR9287 are supported.
|
||||
|
||||
Signed-off-by: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <linux/completion.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/hw_random.h>
|
||||
+#include <linux/gpio/driver.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "debug.h"
|
||||
@@ -990,6 +991,14 @@ struct ath_led {
|
||||
struct led_classdev cdev;
|
||||
};
|
||||
|
||||
+#ifdef CONFIG_GPIOLIB
|
||||
+struct ath9k_gpio_chip {
|
||||
+ struct ath_softc *sc;
|
||||
+ char label[32];
|
||||
+ struct gpio_chip gchip;
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
struct ath_softc {
|
||||
struct ieee80211_hw *hw;
|
||||
struct device *dev;
|
||||
@@ -1045,6 +1054,9 @@ struct ath_softc {
|
||||
#ifdef CPTCFG_MAC80211_LEDS
|
||||
const char *led_default_trigger;
|
||||
struct list_head leds;
|
||||
+#ifdef CONFIG_GPIOLIB
|
||||
+ struct ath9k_gpio_chip *gpiochip;
|
||||
+#endif
|
||||
#endif
|
||||
|
||||
#ifdef CPTCFG_ATH9K_DEBUGFS
|
||||
--- a/drivers/net/wireless/ath/ath9k/gpio.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
|
||||
@@ -16,13 +16,139 @@
|
||||
|
||||
#include "ath9k.h"
|
||||
#include <linux/ath9k_platform.h>
|
||||
+#include <linux/gpio.h>
|
||||
+
|
||||
+#ifdef CPTCFG_MAC80211_LEDS
|
||||
+
|
||||
+#ifdef CONFIG_GPIOLIB
|
||||
+
|
||||
+/***************/
|
||||
+/* GPIO Chip */
|
||||
+/***************/
|
||||
+
|
||||
+/* gpio_chip handler : set GPIO to input */
|
||||
+static int ath9k_gpio_pin_cfg_input(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
|
||||
+ gchip);
|
||||
+
|
||||
+ ath9k_hw_gpio_request_in(gc->sc->sc_ah, offset, "ath9k-gpio");
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* gpio_chip handler : set GPIO to output */
|
||||
+static int ath9k_gpio_pin_cfg_output(struct gpio_chip *chip, unsigned offset,
|
||||
+ int value)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
|
||||
+ gchip);
|
||||
+
|
||||
+ ath9k_hw_gpio_request_out(gc->sc->sc_ah, offset, "ath9k-gpio",
|
||||
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
|
||||
+ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* gpio_chip handler : query GPIO direction (0=out, 1=in) */
|
||||
+static int ath9k_gpio_pin_get_dir(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
|
||||
+ gchip);
|
||||
+ struct ath_hw *ah = gc->sc->sc_ah;
|
||||
+
|
||||
+ return !((REG_READ(ah, AR_GPIO_OE_OUT) >> (offset * 2)) & 3);
|
||||
+}
|
||||
+
|
||||
+/* gpio_chip handler : get GPIO pin value */
|
||||
+static int ath9k_gpio_pin_get(struct gpio_chip *chip, unsigned offset)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
|
||||
+ gchip);
|
||||
+
|
||||
+ return ath9k_hw_gpio_get(gc->sc->sc_ah, offset);
|
||||
+}
|
||||
+
|
||||
+/* gpio_chip handler : set GPIO pin to value */
|
||||
+static void ath9k_gpio_pin_set(struct gpio_chip *chip, unsigned offset,
|
||||
+ int value)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
|
||||
+ gchip);
|
||||
+
|
||||
+ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value);
|
||||
+}
|
||||
+
|
||||
+/* register GPIO chip */
|
||||
+static void ath9k_register_gpio_chip(struct ath_softc *sc)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc;
|
||||
+ struct ath_hw *ah = sc->sc_ah;
|
||||
+
|
||||
+ gc = kzalloc(sizeof(struct ath9k_gpio_chip), GFP_KERNEL);
|
||||
+ if (!gc)
|
||||
+ return;
|
||||
+
|
||||
+ gc->sc = sc;
|
||||
+ snprintf(gc->label, sizeof(gc->label), "ath9k-%s",
|
||||
+ wiphy_name(sc->hw->wiphy));
|
||||
+#ifdef CONFIG_OF
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)
|
||||
+ gc->gchip.parent = sc->dev;
|
||||
+#else
|
||||
+ gc->gchip.dev = sc->dev;
|
||||
+#endif
|
||||
+#endif
|
||||
+ gc->gchip.label = gc->label;
|
||||
+ gc->gchip.base = -1; /* determine base automatically */
|
||||
+ gc->gchip.ngpio = ah->caps.num_gpio_pins;
|
||||
+ gc->gchip.direction_input = ath9k_gpio_pin_cfg_input;
|
||||
+ gc->gchip.direction_output = ath9k_gpio_pin_cfg_output;
|
||||
+ gc->gchip.get_direction = ath9k_gpio_pin_get_dir;
|
||||
+ gc->gchip.get = ath9k_gpio_pin_get;
|
||||
+ gc->gchip.set = ath9k_gpio_pin_set;
|
||||
+
|
||||
+ if (gpiochip_add(&gc->gchip)) {
|
||||
+ kfree(gc);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+#ifdef CONFIG_OF
|
||||
+ gc->gchip.owner = NULL;
|
||||
+#endif
|
||||
+ sc->gpiochip = gc;
|
||||
+}
|
||||
+
|
||||
+/* remove GPIO chip */
|
||||
+static void ath9k_unregister_gpio_chip(struct ath_softc *sc)
|
||||
+{
|
||||
+ struct ath9k_gpio_chip *gc = sc->gpiochip;
|
||||
+
|
||||
+ if (!gc)
|
||||
+ return;
|
||||
+
|
||||
+ gpiochip_remove(&gc->gchip);
|
||||
+ kfree(gc);
|
||||
+ sc->gpiochip = NULL;
|
||||
+}
|
||||
+
|
||||
+#else /* CONFIG_GPIOLIB */
|
||||
+
|
||||
+static inline void ath9k_register_gpio_chip(struct ath_softc *sc)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static inline void ath9k_unregister_gpio_chip(struct ath_softc *sc)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+#endif /* CONFIG_GPIOLIB */
|
||||
|
||||
/********************************/
|
||||
/* LED functions */
|
||||
/********************************/
|
||||
|
||||
-#ifdef CPTCFG_MAC80211_LEDS
|
||||
-
|
||||
static void ath_fill_led_pin(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
@@ -80,6 +206,12 @@ static int ath_add_led(struct ath_softc
|
||||
else
|
||||
ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low);
|
||||
|
||||
+#ifdef CONFIG_GPIOLIB
|
||||
+ /* If there is GPIO chip configured, reserve LED pin */
|
||||
+ if (sc->gpiochip)
|
||||
+ gpio_request(sc->gpiochip->gchip.base + gpio->gpio, gpio->name);
|
||||
+#endif
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -136,17 +268,24 @@ void ath_deinit_leds(struct ath_softc *s
|
||||
|
||||
while (!list_empty(&sc->leds)) {
|
||||
led = list_first_entry(&sc->leds, struct ath_led, list);
|
||||
+#ifdef CONFIG_GPIOLIB
|
||||
+ /* If there is GPIO chip configured, free LED pin */
|
||||
+ if (sc->gpiochip)
|
||||
+ gpio_free(sc->gpiochip->gchip.base + led->gpio->gpio);
|
||||
+#endif
|
||||
list_del(&led->list);
|
||||
ath_led_brightness(&led->cdev, LED_OFF);
|
||||
led_classdev_unregister(&led->cdev);
|
||||
ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio);
|
||||
kfree(led);
|
||||
}
|
||||
+ ath9k_unregister_gpio_chip(sc);
|
||||
}
|
||||
|
||||
void ath_init_leds(struct ath_softc *sc)
|
||||
{
|
||||
struct ath9k_platform_data *pdata = sc->dev->platform_data;
|
||||
+ struct device_node *np = sc->dev->of_node;
|
||||
char led_name[32];
|
||||
const char *trigger;
|
||||
int i;
|
||||
@@ -156,6 +295,15 @@ void ath_init_leds(struct ath_softc *sc)
|
||||
if (AR_SREV_9100(sc->sc_ah))
|
||||
return;
|
||||
|
||||
+ if (!np)
|
||||
+ ath9k_register_gpio_chip(sc);
|
||||
+
|
||||
+ /* setup gpio controller only if requested and skip the led_pin setup */
|
||||
+ if (of_property_read_bool(np, "gpio-controller")) {
|
||||
+ ath9k_register_gpio_chip(sc);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
ath_fill_led_pin(sc);
|
||||
|
||||
if (pdata && pdata->leds && pdata->num_leds)
|
||||
@@ -180,6 +328,7 @@ void ath_init_leds(struct ath_softc *sc)
|
||||
ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger,
|
||||
!sc->sc_ah->config.led_active_high);
|
||||
}
|
||||
+
|
||||
#endif
|
||||
|
||||
/*******************/
|
@ -1,279 +0,0 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Sun, 6 Dec 2020 14:54:42 +0200
|
||||
Subject: [PATCH] cfg80211: support immediate reconnect request hint
|
||||
|
||||
There are cases where it's necessary to disconnect, but an
|
||||
immediate reconnection is desired. Support a hint to userspace
|
||||
that this is the case, by including a new attribute in the
|
||||
deauth or disassoc event.
|
||||
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
Link: https://lore.kernel.org/r/iwlwifi.20201206145305.58d33941fb9d.I0e7168c205c7949529c8e3b86f3c9b12c01a7017@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -6408,13 +6408,15 @@ void cfg80211_abandon_assoc(struct net_d
|
||||
* @dev: network device
|
||||
* @buf: 802.11 frame (header + body)
|
||||
* @len: length of the frame data
|
||||
+ * @reconnect: immediate reconnect is desired (include the nl80211 attribute)
|
||||
*
|
||||
* This function is called whenever deauthentication has been processed in
|
||||
* station mode. This includes both received deauthentication frames and
|
||||
* locally generated ones. This function may sleep. The caller must hold the
|
||||
* corresponding wdev's mutex.
|
||||
*/
|
||||
-void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len);
|
||||
+void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len,
|
||||
+ bool reconnect);
|
||||
|
||||
/**
|
||||
* cfg80211_rx_unprot_mlme_mgmt - notification of unprotected mlme mgmt frame
|
||||
--- a/net/mac80211/mlme.c
|
||||
+++ b/net/mac80211/mlme.c
|
||||
@@ -2725,7 +2725,7 @@ static void ieee80211_report_disconnect(
|
||||
};
|
||||
|
||||
if (tx)
|
||||
- cfg80211_tx_mlme_mgmt(sdata->dev, buf, len);
|
||||
+ cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, false);
|
||||
else
|
||||
cfg80211_rx_mlme_mgmt(sdata->dev, buf, len);
|
||||
|
||||
@@ -4719,7 +4719,8 @@ void ieee80211_mgd_quiesce(struct ieee80
|
||||
if (ifmgd->auth_data)
|
||||
ieee80211_destroy_auth_data(sdata, false);
|
||||
cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
|
||||
- IEEE80211_DEAUTH_FRAME_LEN);
|
||||
+ IEEE80211_DEAUTH_FRAME_LEN,
|
||||
+ false);
|
||||
}
|
||||
|
||||
/* This is a bit of a hack - we should find a better and more generic
|
||||
--- a/net/wireless/mlme.c
|
||||
+++ b/net/wireless/mlme.c
|
||||
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2015 Intel Deutschland GmbH
|
||||
- * Copyright (C) 2019 Intel Corporation
|
||||
+ * Copyright (C) 2019-2020 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -81,7 +81,8 @@ static void cfg80211_process_auth(struct
|
||||
}
|
||||
|
||||
static void cfg80211_process_deauth(struct wireless_dev *wdev,
|
||||
- const u8 *buf, size_t len)
|
||||
+ const u8 *buf, size_t len,
|
||||
+ bool reconnect)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
|
||||
@@ -89,7 +90,7 @@ static void cfg80211_process_deauth(stru
|
||||
u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
|
||||
bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
|
||||
|
||||
- nl80211_send_deauth(rdev, wdev->netdev, buf, len, GFP_KERNEL);
|
||||
+ nl80211_send_deauth(rdev, wdev->netdev, buf, len, reconnect, GFP_KERNEL);
|
||||
|
||||
if (!wdev->current_bss ||
|
||||
!ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
|
||||
@@ -100,7 +101,8 @@ static void cfg80211_process_deauth(stru
|
||||
}
|
||||
|
||||
static void cfg80211_process_disassoc(struct wireless_dev *wdev,
|
||||
- const u8 *buf, size_t len)
|
||||
+ const u8 *buf, size_t len,
|
||||
+ bool reconnect)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
|
||||
@@ -108,7 +110,8 @@ static void cfg80211_process_disassoc(st
|
||||
u16 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
|
||||
bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
|
||||
|
||||
- nl80211_send_disassoc(rdev, wdev->netdev, buf, len, GFP_KERNEL);
|
||||
+ nl80211_send_disassoc(rdev, wdev->netdev, buf, len, reconnect,
|
||||
+ GFP_KERNEL);
|
||||
|
||||
if (WARN_ON(!wdev->current_bss ||
|
||||
!ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
|
||||
@@ -133,9 +136,9 @@ void cfg80211_rx_mlme_mgmt(struct net_de
|
||||
if (ieee80211_is_auth(mgmt->frame_control))
|
||||
cfg80211_process_auth(wdev, buf, len);
|
||||
else if (ieee80211_is_deauth(mgmt->frame_control))
|
||||
- cfg80211_process_deauth(wdev, buf, len);
|
||||
+ cfg80211_process_deauth(wdev, buf, len, false);
|
||||
else if (ieee80211_is_disassoc(mgmt->frame_control))
|
||||
- cfg80211_process_disassoc(wdev, buf, len);
|
||||
+ cfg80211_process_disassoc(wdev, buf, len, false);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt);
|
||||
|
||||
@@ -180,22 +183,23 @@ void cfg80211_abandon_assoc(struct net_d
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_abandon_assoc);
|
||||
|
||||
-void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
|
||||
+void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len,
|
||||
+ bool reconnect)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct ieee80211_mgmt *mgmt = (void *)buf;
|
||||
|
||||
ASSERT_WDEV_LOCK(wdev);
|
||||
|
||||
- trace_cfg80211_tx_mlme_mgmt(dev, buf, len);
|
||||
+ trace_cfg80211_tx_mlme_mgmt(dev, buf, len, reconnect);
|
||||
|
||||
if (WARN_ON(len < 2))
|
||||
return;
|
||||
|
||||
if (ieee80211_is_deauth(mgmt->frame_control))
|
||||
- cfg80211_process_deauth(wdev, buf, len);
|
||||
+ cfg80211_process_deauth(wdev, buf, len, reconnect);
|
||||
else
|
||||
- cfg80211_process_disassoc(wdev, buf, len);
|
||||
+ cfg80211_process_disassoc(wdev, buf, len, reconnect);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt);
|
||||
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -736,6 +736,7 @@ static const struct nla_policy nl80211_p
|
||||
NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
|
||||
[NL80211_ATTR_S1G_CAPABILITY_MASK] =
|
||||
NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
|
||||
+ [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@@ -15902,7 +15903,7 @@ static void nl80211_send_mlme_event(stru
|
||||
const u8 *buf, size_t len,
|
||||
enum nl80211_commands cmd, gfp_t gfp,
|
||||
int uapsd_queues, const u8 *req_ies,
|
||||
- size_t req_ies_len)
|
||||
+ size_t req_ies_len, bool reconnect)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
@@ -15924,6 +15925,9 @@ static void nl80211_send_mlme_event(stru
|
||||
nla_put(msg, NL80211_ATTR_REQ_IE, req_ies_len, req_ies)))
|
||||
goto nla_put_failure;
|
||||
|
||||
+ if (reconnect && nla_put_flag(msg, NL80211_ATTR_RECONNECT_REQUESTED))
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
if (uapsd_queues >= 0) {
|
||||
struct nlattr *nla_wmm =
|
||||
nla_nest_start_noflag(msg, NL80211_ATTR_STA_WME);
|
||||
@@ -15952,7 +15956,8 @@ void nl80211_send_rx_auth(struct cfg8021
|
||||
size_t len, gfp_t gfp)
|
||||
{
|
||||
nl80211_send_mlme_event(rdev, netdev, buf, len,
|
||||
- NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0);
|
||||
+ NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0,
|
||||
+ false);
|
||||
}
|
||||
|
||||
void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
|
||||
@@ -15962,23 +15967,25 @@ void nl80211_send_rx_assoc(struct cfg802
|
||||
{
|
||||
nl80211_send_mlme_event(rdev, netdev, buf, len,
|
||||
NL80211_CMD_ASSOCIATE, gfp, uapsd_queues,
|
||||
- req_ies, req_ies_len);
|
||||
+ req_ies, req_ies_len, false);
|
||||
}
|
||||
|
||||
void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, const u8 *buf,
|
||||
- size_t len, gfp_t gfp)
|
||||
+ size_t len, bool reconnect, gfp_t gfp)
|
||||
{
|
||||
nl80211_send_mlme_event(rdev, netdev, buf, len,
|
||||
- NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0);
|
||||
+ NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0,
|
||||
+ reconnect);
|
||||
}
|
||||
|
||||
void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, const u8 *buf,
|
||||
- size_t len, gfp_t gfp)
|
||||
+ size_t len, bool reconnect, gfp_t gfp)
|
||||
{
|
||||
nl80211_send_mlme_event(rdev, netdev, buf, len,
|
||||
- NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0);
|
||||
+ NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0,
|
||||
+ reconnect);
|
||||
}
|
||||
|
||||
void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
|
||||
@@ -16009,7 +16016,7 @@ void cfg80211_rx_unprot_mlme_mgmt(struct
|
||||
|
||||
trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
|
||||
nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1,
|
||||
- NULL, 0);
|
||||
+ NULL, 0, false);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
|
||||
|
||||
--- a/net/wireless/nl80211.h
|
||||
+++ b/net/wireless/nl80211.h
|
||||
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Portions of this file
|
||||
- * Copyright (C) 2018 Intel Corporation
|
||||
+ * Copyright (C) 2018, 2020 Intel Corporation
|
||||
*/
|
||||
#ifndef __NET_WIRELESS_NL80211_H
|
||||
#define __NET_WIRELESS_NL80211_H
|
||||
@@ -69,10 +69,12 @@ void nl80211_send_rx_assoc(struct cfg802
|
||||
const u8 *req_ies, size_t req_ies_len);
|
||||
void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev,
|
||||
- const u8 *buf, size_t len, gfp_t gfp);
|
||||
+ const u8 *buf, size_t len,
|
||||
+ bool reconnect, gfp_t gfp);
|
||||
void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev,
|
||||
- const u8 *buf, size_t len, gfp_t gfp);
|
||||
+ const u8 *buf, size_t len,
|
||||
+ bool reconnect, gfp_t gfp);
|
||||
void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev,
|
||||
const u8 *addr, gfp_t gfp);
|
||||
--- a/net/wireless/trace.h
|
||||
+++ b/net/wireless/trace.h
|
||||
@@ -2684,19 +2684,23 @@ DEFINE_EVENT(netdev_frame_event, cfg8021
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_tx_mlme_mgmt,
|
||||
- TP_PROTO(struct net_device *netdev, const u8 *buf, int len),
|
||||
- TP_ARGS(netdev, buf, len),
|
||||
+ TP_PROTO(struct net_device *netdev, const u8 *buf, int len,
|
||||
+ bool reconnect),
|
||||
+ TP_ARGS(netdev, buf, len, reconnect),
|
||||
TP_STRUCT__entry(
|
||||
NETDEV_ENTRY
|
||||
__dynamic_array(u8, frame, len)
|
||||
+ __field(int, reconnect)
|
||||
),
|
||||
TP_fast_assign(
|
||||
NETDEV_ASSIGN;
|
||||
memcpy(__get_dynamic_array(frame), buf, len);
|
||||
+ __entry->reconnect = reconnect;
|
||||
),
|
||||
- TP_printk(NETDEV_PR_FMT ", ftype:0x%.2x",
|
||||
+ TP_printk(NETDEV_PR_FMT ", ftype:0x%.2x reconnect:%d",
|
||||
NETDEV_PR_ARG,
|
||||
- le16_to_cpup((__le16 *)__get_dynamic_array(frame)))
|
||||
+ le16_to_cpup((__le16 *)__get_dynamic_array(frame)),
|
||||
+ __entry->reconnect)
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(netdev_mac_evt,
|
@ -1,155 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
|
||||
@@ -978,55 +978,6 @@ static bool ar5008_hw_ani_control_new(st
|
||||
* on == 0 means more noise imm
|
||||
*/
|
||||
u32 on = param ? 1 : 0;
|
||||
- /*
|
||||
- * make register setting for default
|
||||
- * (weak sig detect ON) come from INI file
|
||||
- */
|
||||
- int m1ThreshLow = on ?
|
||||
- aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
|
||||
- int m2ThreshLow = on ?
|
||||
- aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
|
||||
- int m1Thresh = on ?
|
||||
- aniState->iniDef.m1Thresh : m1Thresh_off;
|
||||
- int m2Thresh = on ?
|
||||
- aniState->iniDef.m2Thresh : m2Thresh_off;
|
||||
- int m2CountThr = on ?
|
||||
- aniState->iniDef.m2CountThr : m2CountThr_off;
|
||||
- int m2CountThrLow = on ?
|
||||
- aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
|
||||
- int m1ThreshLowExt = on ?
|
||||
- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
|
||||
- int m2ThreshLowExt = on ?
|
||||
- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
|
||||
- int m1ThreshExt = on ?
|
||||
- aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
|
||||
- int m2ThreshExt = on ?
|
||||
- aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
|
||||
-
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
- AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
|
||||
- m1ThreshLow);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
- AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
|
||||
- m2ThreshLow);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
- AR_PHY_SFCORR_M1_THRESH, m1Thresh);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
- AR_PHY_SFCORR_M2_THRESH, m2Thresh);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
- AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
|
||||
- m2CountThrLow);
|
||||
-
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
|
||||
|
||||
if (on)
|
||||
REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
@@ -42,20 +42,6 @@ static const int cycpwrThr1_table[] =
|
||||
/* level: 0 1 2 3 4 5 6 7 8 */
|
||||
{ -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */
|
||||
|
||||
-/*
|
||||
- * register values to turn OFDM weak signal detection OFF
|
||||
- */
|
||||
-static const int m1ThreshLow_off = 127;
|
||||
-static const int m2ThreshLow_off = 127;
|
||||
-static const int m1Thresh_off = 127;
|
||||
-static const int m2Thresh_off = 127;
|
||||
-static const int m2CountThr_off = 31;
|
||||
-static const int m2CountThrLow_off = 63;
|
||||
-static const int m1ThreshLowExt_off = 127;
|
||||
-static const int m2ThreshLowExt_off = 127;
|
||||
-static const int m1ThreshExt_off = 127;
|
||||
-static const int m2ThreshExt_off = 127;
|
||||
-
|
||||
static const u8 ofdm2pwr[] = {
|
||||
ALL_TARGET_LEGACY_6_24,
|
||||
ALL_TARGET_LEGACY_6_24,
|
||||
@@ -1077,11 +1063,6 @@ static bool ar9003_hw_ani_control(struct
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ar5416AniState *aniState = &ah->ani;
|
||||
- int m1ThreshLow, m2ThreshLow;
|
||||
- int m1Thresh, m2Thresh;
|
||||
- int m2CountThr, m2CountThrLow;
|
||||
- int m1ThreshLowExt, m2ThreshLowExt;
|
||||
- int m1ThreshExt, m2ThreshExt;
|
||||
s32 value, value2;
|
||||
|
||||
switch (cmd & ah->ani_function) {
|
||||
@@ -1095,61 +1076,6 @@ static bool ar9003_hw_ani_control(struct
|
||||
*/
|
||||
u32 on = param ? 1 : 0;
|
||||
|
||||
- if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
|
||||
- goto skip_ws_det;
|
||||
-
|
||||
- m1ThreshLow = on ?
|
||||
- aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
|
||||
- m2ThreshLow = on ?
|
||||
- aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
|
||||
- m1Thresh = on ?
|
||||
- aniState->iniDef.m1Thresh : m1Thresh_off;
|
||||
- m2Thresh = on ?
|
||||
- aniState->iniDef.m2Thresh : m2Thresh_off;
|
||||
- m2CountThr = on ?
|
||||
- aniState->iniDef.m2CountThr : m2CountThr_off;
|
||||
- m2CountThrLow = on ?
|
||||
- aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
|
||||
- m1ThreshLowExt = on ?
|
||||
- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
|
||||
- m2ThreshLowExt = on ?
|
||||
- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
|
||||
- m1ThreshExt = on ?
|
||||
- aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
|
||||
- m2ThreshExt = on ?
|
||||
- aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
|
||||
-
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
- AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
|
||||
- m1ThreshLow);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
- AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
|
||||
- m2ThreshLow);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
- AR_PHY_SFCORR_M1_THRESH,
|
||||
- m1Thresh);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
- AR_PHY_SFCORR_M2_THRESH,
|
||||
- m2Thresh);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
|
||||
- AR_PHY_SFCORR_M2COUNT_THR,
|
||||
- m2CountThr);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
|
||||
- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
|
||||
- m2CountThrLow);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
|
||||
- m1ThreshLowExt);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
|
||||
- m2ThreshLowExt);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M1_THRESH,
|
||||
- m1ThreshExt);
|
||||
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
|
||||
- AR_PHY_SFCORR_EXT_M2_THRESH,
|
||||
- m2ThreshExt);
|
||||
-skip_ws_det:
|
||||
if (on)
|
||||
REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
|
||||
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
|
@ -1,317 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 25 Nov 2020 18:10:34 +0100
|
||||
Subject: [PATCH] net/fq_impl: do not maintain a backlog-sorted list of
|
||||
flows
|
||||
|
||||
A sorted flow list is only needed to drop packets in the biggest flow when
|
||||
hitting the overmemory condition.
|
||||
By scanning flows only when needed, we can avoid paying the cost of
|
||||
maintaining the list under normal conditions
|
||||
In order to avoid scanning lots of empty flows and touching too many cold
|
||||
cache lines, a bitmap of flows with backlog is maintained
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/include/net/fq.h
|
||||
+++ b/include/net/fq.h
|
||||
@@ -19,8 +19,6 @@ struct fq_tin;
|
||||
* @flowchain: can be linked to fq_tin's new_flows or old_flows. Used for DRR++
|
||||
* (deficit round robin) based round robin queuing similar to the one
|
||||
* found in net/sched/sch_fq_codel.c
|
||||
- * @backlogchain: can be linked to other fq_flow and fq. Used to keep track of
|
||||
- * fat flows and efficient head-dropping if packet limit is reached
|
||||
* @queue: sk_buff queue to hold packets
|
||||
* @backlog: number of bytes pending in the queue. The number of packets can be
|
||||
* found in @queue.qlen
|
||||
@@ -29,7 +27,6 @@ struct fq_tin;
|
||||
struct fq_flow {
|
||||
struct fq_tin *tin;
|
||||
struct list_head flowchain;
|
||||
- struct list_head backlogchain;
|
||||
struct sk_buff_head queue;
|
||||
u32 backlog;
|
||||
int deficit;
|
||||
@@ -47,6 +44,7 @@ struct fq_flow {
|
||||
struct fq_tin {
|
||||
struct list_head new_flows;
|
||||
struct list_head old_flows;
|
||||
+ struct list_head tin_list;
|
||||
struct fq_flow default_flow;
|
||||
u32 backlog_bytes;
|
||||
u32 backlog_packets;
|
||||
@@ -60,14 +58,14 @@ struct fq_tin {
|
||||
/**
|
||||
* struct fq - main container for fair queuing purposes
|
||||
*
|
||||
- * @backlogs: linked to fq_flows. Used to maintain fat flows for efficient
|
||||
- * head-dropping when @backlog reaches @limit
|
||||
* @limit: max number of packets that can be queued across all flows
|
||||
* @backlog: number of packets queued across all flows
|
||||
*/
|
||||
struct fq {
|
||||
struct fq_flow *flows;
|
||||
- struct list_head backlogs;
|
||||
+ unsigned long *flows_bitmap;
|
||||
+
|
||||
+ struct list_head tin_backlog;
|
||||
spinlock_t lock;
|
||||
u32 flows_cnt;
|
||||
u32 limit;
|
||||
--- a/include/net/fq_impl.h
|
||||
+++ b/include/net/fq_impl.h
|
||||
@@ -17,12 +17,24 @@ __fq_adjust_removal(struct fq *fq, struc
|
||||
unsigned int bytes, unsigned int truesize)
|
||||
{
|
||||
struct fq_tin *tin = flow->tin;
|
||||
+ int idx;
|
||||
|
||||
tin->backlog_bytes -= bytes;
|
||||
tin->backlog_packets -= packets;
|
||||
flow->backlog -= bytes;
|
||||
fq->backlog -= packets;
|
||||
fq->memory_usage -= truesize;
|
||||
+
|
||||
+ if (flow->backlog)
|
||||
+ return;
|
||||
+
|
||||
+ if (flow == &tin->default_flow) {
|
||||
+ list_del_init(&tin->tin_list);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ idx = flow - fq->flows;
|
||||
+ __clear_bit(idx, fq->flows_bitmap);
|
||||
}
|
||||
|
||||
static void fq_adjust_removal(struct fq *fq,
|
||||
@@ -32,24 +44,6 @@ static void fq_adjust_removal(struct fq
|
||||
__fq_adjust_removal(fq, flow, 1, skb->len, skb->truesize);
|
||||
}
|
||||
|
||||
-static void fq_rejigger_backlog(struct fq *fq, struct fq_flow *flow)
|
||||
-{
|
||||
- struct fq_flow *i;
|
||||
-
|
||||
- if (flow->backlog == 0) {
|
||||
- list_del_init(&flow->backlogchain);
|
||||
- } else {
|
||||
- i = flow;
|
||||
-
|
||||
- list_for_each_entry_continue(i, &fq->backlogs, backlogchain)
|
||||
- if (i->backlog < flow->backlog)
|
||||
- break;
|
||||
-
|
||||
- list_move_tail(&flow->backlogchain,
|
||||
- &i->backlogchain);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
static struct sk_buff *fq_flow_dequeue(struct fq *fq,
|
||||
struct fq_flow *flow)
|
||||
{
|
||||
@@ -62,7 +56,6 @@ static struct sk_buff *fq_flow_dequeue(s
|
||||
return NULL;
|
||||
|
||||
fq_adjust_removal(fq, flow, skb);
|
||||
- fq_rejigger_backlog(fq, flow);
|
||||
|
||||
return skb;
|
||||
}
|
||||
@@ -90,7 +83,6 @@ static int fq_flow_drop(struct fq *fq, s
|
||||
} while (packets < pending);
|
||||
|
||||
__fq_adjust_removal(fq, flow, packets, bytes, truesize);
|
||||
- fq_rejigger_backlog(fq, flow);
|
||||
|
||||
return packets;
|
||||
}
|
||||
@@ -170,22 +162,36 @@ static struct fq_flow *fq_flow_classify(
|
||||
return flow;
|
||||
}
|
||||
|
||||
-static void fq_recalc_backlog(struct fq *fq,
|
||||
- struct fq_tin *tin,
|
||||
- struct fq_flow *flow)
|
||||
-{
|
||||
- struct fq_flow *i;
|
||||
-
|
||||
- if (list_empty(&flow->backlogchain))
|
||||
- list_add_tail(&flow->backlogchain, &fq->backlogs);
|
||||
-
|
||||
- i = flow;
|
||||
- list_for_each_entry_continue_reverse(i, &fq->backlogs,
|
||||
- backlogchain)
|
||||
- if (i->backlog > flow->backlog)
|
||||
- break;
|
||||
+static struct fq_flow *fq_find_fattest_flow(struct fq *fq)
|
||||
+{
|
||||
+ struct fq_tin *tin;
|
||||
+ struct fq_flow *flow = NULL;
|
||||
+ u32 len = 0;
|
||||
+ int i;
|
||||
+
|
||||
+ for_each_set_bit(i, fq->flows_bitmap, fq->flows_cnt) {
|
||||
+ struct fq_flow *cur = &fq->flows[i];
|
||||
+ unsigned int cur_len;
|
||||
+
|
||||
+ cur_len = cur->backlog;
|
||||
+ if (cur_len <= len)
|
||||
+ continue;
|
||||
+
|
||||
+ flow = cur;
|
||||
+ len = cur_len;
|
||||
+ }
|
||||
|
||||
- list_move(&flow->backlogchain, &i->backlogchain);
|
||||
+ list_for_each_entry(tin, &fq->tin_backlog, tin_list) {
|
||||
+ unsigned int cur_len = tin->default_flow.backlog;
|
||||
+
|
||||
+ if (cur_len <= len)
|
||||
+ continue;
|
||||
+
|
||||
+ flow = &tin->default_flow;
|
||||
+ len = cur_len;
|
||||
+ }
|
||||
+
|
||||
+ return flow;
|
||||
}
|
||||
|
||||
static void fq_tin_enqueue(struct fq *fq,
|
||||
@@ -200,6 +206,13 @@ static void fq_tin_enqueue(struct fq *fq
|
||||
|
||||
flow = fq_flow_classify(fq, tin, idx, skb);
|
||||
|
||||
+ if (!flow->backlog) {
|
||||
+ if (flow != &tin->default_flow)
|
||||
+ __set_bit(idx, fq->flows_bitmap);
|
||||
+ else if (list_empty(&tin->tin_list))
|
||||
+ list_add(&tin->tin_list, &fq->tin_backlog);
|
||||
+ }
|
||||
+
|
||||
flow->tin = tin;
|
||||
flow->backlog += skb->len;
|
||||
tin->backlog_bytes += skb->len;
|
||||
@@ -207,8 +220,6 @@ static void fq_tin_enqueue(struct fq *fq
|
||||
fq->memory_usage += skb->truesize;
|
||||
fq->backlog++;
|
||||
|
||||
- fq_recalc_backlog(fq, tin, flow);
|
||||
-
|
||||
if (list_empty(&flow->flowchain)) {
|
||||
flow->deficit = fq->quantum;
|
||||
list_add_tail(&flow->flowchain,
|
||||
@@ -218,9 +229,7 @@ static void fq_tin_enqueue(struct fq *fq
|
||||
__skb_queue_tail(&flow->queue, skb);
|
||||
oom = (fq->memory_usage > fq->memory_limit);
|
||||
while (fq->backlog > fq->limit || oom) {
|
||||
- flow = list_first_entry_or_null(&fq->backlogs,
|
||||
- struct fq_flow,
|
||||
- backlogchain);
|
||||
+ flow = fq_find_fattest_flow(fq);
|
||||
if (!flow)
|
||||
return;
|
||||
|
||||
@@ -255,8 +264,6 @@ static void fq_flow_filter(struct fq *fq
|
||||
fq_adjust_removal(fq, flow, skb);
|
||||
free_func(fq, tin, flow, skb);
|
||||
}
|
||||
-
|
||||
- fq_rejigger_backlog(fq, flow);
|
||||
}
|
||||
|
||||
static void fq_tin_filter(struct fq *fq,
|
||||
@@ -279,16 +286,18 @@ static void fq_flow_reset(struct fq *fq,
|
||||
struct fq_flow *flow,
|
||||
fq_skb_free_t free_func)
|
||||
{
|
||||
+ struct fq_tin *tin = flow->tin;
|
||||
struct sk_buff *skb;
|
||||
|
||||
while ((skb = fq_flow_dequeue(fq, flow)))
|
||||
- free_func(fq, flow->tin, flow, skb);
|
||||
+ free_func(fq, tin, flow, skb);
|
||||
|
||||
- if (!list_empty(&flow->flowchain))
|
||||
+ if (!list_empty(&flow->flowchain)) {
|
||||
list_del_init(&flow->flowchain);
|
||||
-
|
||||
- if (!list_empty(&flow->backlogchain))
|
||||
- list_del_init(&flow->backlogchain);
|
||||
+ if (list_empty(&tin->new_flows) &&
|
||||
+ list_empty(&tin->old_flows))
|
||||
+ list_del_init(&tin->tin_list);
|
||||
+ }
|
||||
|
||||
flow->tin = NULL;
|
||||
|
||||
@@ -314,6 +323,7 @@ static void fq_tin_reset(struct fq *fq,
|
||||
fq_flow_reset(fq, flow, free_func);
|
||||
}
|
||||
|
||||
+ WARN_ON_ONCE(!list_empty(&tin->tin_list));
|
||||
WARN_ON_ONCE(tin->backlog_bytes);
|
||||
WARN_ON_ONCE(tin->backlog_packets);
|
||||
}
|
||||
@@ -321,7 +331,6 @@ static void fq_tin_reset(struct fq *fq,
|
||||
static void fq_flow_init(struct fq_flow *flow)
|
||||
{
|
||||
INIT_LIST_HEAD(&flow->flowchain);
|
||||
- INIT_LIST_HEAD(&flow->backlogchain);
|
||||
__skb_queue_head_init(&flow->queue);
|
||||
}
|
||||
|
||||
@@ -329,6 +338,7 @@ static void fq_tin_init(struct fq_tin *t
|
||||
{
|
||||
INIT_LIST_HEAD(&tin->new_flows);
|
||||
INIT_LIST_HEAD(&tin->old_flows);
|
||||
+ INIT_LIST_HEAD(&tin->tin_list);
|
||||
fq_flow_init(&tin->default_flow);
|
||||
}
|
||||
|
||||
@@ -337,8 +347,8 @@ static int fq_init(struct fq *fq, int fl
|
||||
int i;
|
||||
|
||||
memset(fq, 0, sizeof(fq[0]));
|
||||
- INIT_LIST_HEAD(&fq->backlogs);
|
||||
spin_lock_init(&fq->lock);
|
||||
+ INIT_LIST_HEAD(&fq->tin_backlog);
|
||||
fq->flows_cnt = max_t(u32, flows_cnt, 1);
|
||||
fq->quantum = 300;
|
||||
fq->limit = 8192;
|
||||
@@ -348,6 +358,14 @@ static int fq_init(struct fq *fq, int fl
|
||||
if (!fq->flows)
|
||||
return -ENOMEM;
|
||||
|
||||
+ fq->flows_bitmap = kcalloc(BITS_TO_LONGS(fq->flows_cnt), sizeof(long),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!fq->flows_bitmap) {
|
||||
+ kvfree(fq->flows);
|
||||
+ fq->flows = NULL;
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < fq->flows_cnt; i++)
|
||||
fq_flow_init(&fq->flows[i]);
|
||||
|
||||
@@ -364,6 +382,9 @@ static void fq_reset(struct fq *fq,
|
||||
|
||||
kvfree(fq->flows);
|
||||
fq->flows = NULL;
|
||||
+
|
||||
+ kfree(fq->flows_bitmap);
|
||||
+ fq->flows_bitmap = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3398,8 +3398,6 @@ out_recalc:
|
||||
if (head->len != orig_len) {
|
||||
flow->backlog += head->len - orig_len;
|
||||
tin->backlog_bytes += head->len - orig_len;
|
||||
-
|
||||
- fq_recalc_backlog(fq, tin, flow);
|
||||
}
|
||||
out:
|
||||
spin_unlock_bh(&fq->lock);
|
@ -1,47 +0,0 @@
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/Kconfig
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
|
||||
@@ -226,36 +226,37 @@ config RT2800SOC
|
||||
|
||||
|
||||
config RT2800_LIB
|
||||
- tristate
|
||||
+ tristate "RT2800 USB/PCI support"
|
||||
depends on m
|
||||
|
||||
config RT2800_LIB_MMIO
|
||||
- tristate
|
||||
+ tristate "RT2800 MMIO support"
|
||||
depends on m
|
||||
select RT2X00_LIB_MMIO
|
||||
select RT2800_LIB
|
||||
|
||||
config RT2X00_LIB_MMIO
|
||||
- tristate
|
||||
+ tristate "RT2x00 MMIO support"
|
||||
depends on m
|
||||
|
||||
config RT2X00_LIB_PCI
|
||||
- tristate
|
||||
+ tristate "RT2x00 PCI support"
|
||||
depends on m
|
||||
select RT2X00_LIB
|
||||
|
||||
config RT2X00_LIB_SOC
|
||||
- tristate
|
||||
+ tristate "RT2x00 SoC support"
|
||||
+ depends on SOC_RT288X || SOC_RT305X || SOC_MT7620
|
||||
depends on m
|
||||
select RT2X00_LIB
|
||||
|
||||
config RT2X00_LIB_USB
|
||||
- tristate
|
||||
+ tristate "RT2x00 USB support"
|
||||
depends on m
|
||||
select RT2X00_LIB
|
||||
|
||||
config RT2X00_LIB
|
||||
- tristate
|
||||
+ tristate "RT2x00 support"
|
||||
depends on m
|
||||
|
||||
config RT2X00_LIB_FIRMWARE
|
@ -1,142 +0,0 @@
|
||||
This adds a bwmode debugfs file which can be used to set alternate
|
||||
channel operating bandwidths. Only tested with AR5413 and only at
|
||||
5 and 20 mhz channels.
|
||||
|
||||
Signed-off-by: Pat Erley <pat-lkml at erley.org>
|
||||
---
|
||||
Other devices will need to be added to the switch in write_file_bwmode
|
||||
|
||||
drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++
|
||||
1 files changed, 86 insertions(+), 0 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath5k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath5k/debug.c
|
||||
@@ -803,6 +803,97 @@ static const struct file_operations fops
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
+/* debugfs: bwmode */
|
||||
+
|
||||
+static ssize_t read_file_bwmode(struct file *file, char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ath5k_hw *ah = file->private_data;
|
||||
+ char buf[15];
|
||||
+ unsigned int len = 0;
|
||||
+
|
||||
+ int cur_ah_bwmode = ah->ah_bwmode_debug;
|
||||
+
|
||||
+#define print_selected(MODE, LABEL) \
|
||||
+ if (cur_ah_bwmode == MODE) \
|
||||
+ len += snprintf(buf+len, sizeof(buf)-len, "[%s]", LABEL); \
|
||||
+ else \
|
||||
+ len += snprintf(buf+len, sizeof(buf)-len, "%s", LABEL); \
|
||||
+ len += snprintf(buf+len, sizeof(buf)-len, " ");
|
||||
+
|
||||
+ print_selected(AR5K_BWMODE_5MHZ, "5");
|
||||
+ print_selected(AR5K_BWMODE_10MHZ, "10");
|
||||
+ print_selected(AR5K_BWMODE_DEFAULT, "20");
|
||||
+ print_selected(AR5K_BWMODE_40MHZ, "40");
|
||||
+#undef print_selected
|
||||
+
|
||||
+ len += snprintf(buf+len, sizeof(buf)-len, "\n");
|
||||
+
|
||||
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
+}
|
||||
+
|
||||
+static ssize_t write_file_bwmode(struct file *file,
|
||||
+ const char __user *userbuf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct ath5k_hw *ah = file->private_data;
|
||||
+ char buf[3];
|
||||
+ int bw = 20;
|
||||
+ int tobwmode = AR5K_BWMODE_DEFAULT;
|
||||
+
|
||||
+ if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ /* TODO: Add check for active interface */
|
||||
+
|
||||
+ if(strncmp(buf, "5", 1) == 0 ) {
|
||||
+ tobwmode = AR5K_BWMODE_5MHZ;
|
||||
+ bw = 5;
|
||||
+ } else if ( strncmp(buf, "10", 2) == 0 ) {
|
||||
+ tobwmode = AR5K_BWMODE_10MHZ;
|
||||
+ bw = 10;
|
||||
+ } else if ( strncmp(buf, "20", 2) == 0 ) {
|
||||
+ tobwmode = AR5K_BWMODE_DEFAULT;
|
||||
+ bw = 20;
|
||||
+ } else if ( strncmp(buf, "40", 2) == 0 ) {
|
||||
+ tobwmode = AR5K_BWMODE_40MHZ;
|
||||
+ bw = 40;
|
||||
+ } else
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ATH5K_INFO(ah, "Changing to %imhz channel width[%i]\n",
|
||||
+ bw, tobwmode);
|
||||
+
|
||||
+ switch (ah->ah_radio) {
|
||||
+ /* TODO: only define radios that actually support 5/10mhz channels */
|
||||
+ case AR5K_RF5413:
|
||||
+ case AR5K_RF5110:
|
||||
+ case AR5K_RF5111:
|
||||
+ case AR5K_RF5112:
|
||||
+ case AR5K_RF2413:
|
||||
+ case AR5K_RF2316:
|
||||
+ case AR5K_RF2317:
|
||||
+ case AR5K_RF2425:
|
||||
+ if(ah->ah_bwmode_debug != tobwmode) {
|
||||
+ mutex_lock(&ah->lock);
|
||||
+ ah->ah_bwmode = tobwmode;
|
||||
+ ah->ah_bwmode_debug = tobwmode;
|
||||
+ mutex_unlock(&ah->lock);
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations fops_bwmode = {
|
||||
+ .read = read_file_bwmode,
|
||||
+ .write = write_file_bwmode,
|
||||
+ .open = simple_open,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .llseek = default_llseek,
|
||||
+};
|
||||
|
||||
/* debugfs: queues etc */
|
||||
|
||||
@@ -997,6 +1088,8 @@ ath5k_debug_init_device(struct ath5k_hw
|
||||
debugfs_create_file("queue", 0600, phydir, ah, &fops_queue);
|
||||
debugfs_create_bool("32khz_clock", 0600, phydir,
|
||||
&ah->ah_use_32khz_clock);
|
||||
+ debugfs_create_file("bwmode", S_IWUSR | S_IRUSR, phydir, ah,
|
||||
+ &fops_bwmode);
|
||||
}
|
||||
|
||||
/* functions used in other places */
|
||||
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
|
||||
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
|
||||
@@ -1372,6 +1372,7 @@ struct ath5k_hw {
|
||||
u8 ah_coverage_class;
|
||||
bool ah_ack_bitrate_high;
|
||||
u8 ah_bwmode;
|
||||
+ u8 ah_bwmode_debug;
|
||||
bool ah_short_slot;
|
||||
|
||||
/* Antenna Control */
|
||||
--- a/drivers/net/wireless/ath/ath5k/base.c
|
||||
+++ b/drivers/net/wireless/ath/ath5k/base.c
|
||||
@@ -466,6 +466,9 @@ ath5k_chan_set(struct ath5k_hw *ah, stru
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ if (ah->ah_bwmode_debug != AR5K_BWMODE_DEFAULT)
|
||||
+ ah->ah_bwmode = ah->ah_bwmode_debug;
|
||||
+
|
||||
/*
|
||||
* To switch channels clear any pending DMA operations;
|
||||
* wait long enough for the RX fifo to drain, reset the
|
@ -1,46 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
|
||||
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
|
||||
@@ -86,13 +86,8 @@ ath5k_add_interface(struct ieee80211_hw
|
||||
goto end;
|
||||
}
|
||||
|
||||
- /* Don't allow other interfaces if one ad-hoc is configured.
|
||||
- * TODO: Fix the problems with ad-hoc and multiple other interfaces.
|
||||
- * We would need to operate the HW in ad-hoc mode to allow TSF updates
|
||||
- * for the IBSS, but this breaks with additional AP or STA interfaces
|
||||
- * at the moment. */
|
||||
- if (ah->num_adhoc_vifs ||
|
||||
- (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
|
||||
+ /* Don't allow more than one ad-hoc interface */
|
||||
+ if (ah->num_adhoc_vifs && vif->type == NL80211_IFTYPE_ADHOC) {
|
||||
ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n");
|
||||
ret = -ELNRNG;
|
||||
goto end;
|
||||
--- a/drivers/net/wireless/ath/ath5k/base.c
|
||||
+++ b/drivers/net/wireless/ath/ath5k/base.c
|
||||
@@ -1964,7 +1964,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
|
||||
}
|
||||
|
||||
if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +
|
||||
- ah->num_mesh_vifs > 1) ||
|
||||
+ ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) ||
|
||||
ah->opmode == NL80211_IFTYPE_MESH_POINT) {
|
||||
u64 tsf = ath5k_hw_get_tsf64(ah);
|
||||
u32 tsftu = TSF_TO_TU(tsf);
|
||||
@@ -2050,7 +2050,7 @@ ath5k_beacon_update_timers(struct ath5k_
|
||||
|
||||
intval = ah->bintval & AR5K_BEACON_PERIOD;
|
||||
if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs
|
||||
- + ah->num_mesh_vifs > 1) {
|
||||
+ + ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) {
|
||||
intval /= ATH_BCBUF; /* staggered multi-bss beacons */
|
||||
if (intval < 15)
|
||||
ATH5K_WARN(ah, "intval %u is too low, min 15\n",
|
||||
@@ -2516,6 +2516,7 @@ static const struct ieee80211_iface_limi
|
||||
BIT(NL80211_IFTYPE_MESH_POINT) |
|
||||
#endif
|
||||
BIT(NL80211_IFTYPE_AP) },
|
||||
+ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_combination if_comb = {
|
@ -1,11 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/ath9k/ani.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ani.h
|
||||
@@ -42,7 +42,7 @@
|
||||
#define ATH9K_ANI_PERIOD 300
|
||||
|
||||
/* in ms */
|
||||
-#define ATH9K_ANI_POLLINTERVAL 1000
|
||||
+#define ATH9K_ANI_POLLINTERVAL 300
|
||||
|
||||
#define ATH9K_SIG_FIRSTEP_SETTING_MIN 0
|
||||
#define ATH9K_SIG_FIRSTEP_SETTING_MAX 20
|
@ -1,129 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Sat, 9 Jul 2016 15:26:44 +0200
|
||||
Subject: [PATCH] ath9k_hw: issue external reset for QCA955x
|
||||
|
||||
The RTC interface on the SoC needs to be reset along with the rest of
|
||||
the WMAC.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -1312,39 +1312,56 @@ void ath9k_hw_get_delta_slope_vals(struc
|
||||
*coef_exponent = coef_exp - 16;
|
||||
}
|
||||
|
||||
-/* AR9330 WAR:
|
||||
- * call external reset function to reset WMAC if:
|
||||
- * - doing a cold reset
|
||||
- * - we have pending frames in the TX queues.
|
||||
- */
|
||||
-static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type)
|
||||
+static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type)
|
||||
{
|
||||
- int i, npend = 0;
|
||||
+ int i;
|
||||
|
||||
- for (i = 0; i < AR_NUM_QCU; i++) {
|
||||
- npend = ath9k_hw_numtxpending(ah, i);
|
||||
- if (npend)
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- if (ah->external_reset &&
|
||||
- (npend || type == ATH9K_RESET_COLD)) {
|
||||
- int reset_err = 0;
|
||||
-
|
||||
- ath_dbg(ath9k_hw_common(ah), RESET,
|
||||
- "reset MAC via external reset\n");
|
||||
-
|
||||
- reset_err = ah->external_reset();
|
||||
- if (reset_err) {
|
||||
- ath_err(ath9k_hw_common(ah),
|
||||
- "External reset failed, err=%d\n",
|
||||
- reset_err);
|
||||
- return false;
|
||||
+ if (type == ATH9K_RESET_COLD)
|
||||
+ return true;
|
||||
+
|
||||
+ if (AR_SREV_9550(ah))
|
||||
+ return true;
|
||||
+
|
||||
+ /* AR9330 WAR:
|
||||
+ * call external reset function to reset WMAC if:
|
||||
+ * - doing a cold reset
|
||||
+ * - we have pending frames in the TX queues.
|
||||
+ */
|
||||
+ if (AR_SREV_9330(ah)) {
|
||||
+ for (i = 0; i < AR_NUM_QCU; i++) {
|
||||
+ if (ath9k_hw_numtxpending(ah, i))
|
||||
+ return true;
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static bool ath9k_hw_external_reset(struct ath_hw *ah, int type)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type))
|
||||
+ return true;
|
||||
+
|
||||
+ ath_dbg(ath9k_hw_common(ah), RESET,
|
||||
+ "reset MAC via external reset\n");
|
||||
|
||||
- REG_WRITE(ah, AR_RTC_RESET, 1);
|
||||
+ err = ah->external_reset();
|
||||
+ if (err) {
|
||||
+ ath_err(ath9k_hw_common(ah),
|
||||
+ "External reset failed, err=%d\n", err);
|
||||
+ return false;
|
||||
}
|
||||
|
||||
+ if (AR_SREV_9550(ah)) {
|
||||
+ REG_WRITE(ah, AR_RTC_RESET, 0);
|
||||
+ udelay(10);
|
||||
+ }
|
||||
+
|
||||
+ REG_WRITE(ah, AR_RTC_RESET, 1);
|
||||
+ udelay(10);
|
||||
+
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1397,24 +1414,24 @@ static bool ath9k_hw_set_reset(struct at
|
||||
rst_flags |= AR_RTC_RC_MAC_COLD;
|
||||
}
|
||||
|
||||
- if (AR_SREV_9330(ah)) {
|
||||
- if (!ath9k_hw_ar9330_reset_war(ah, type))
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
if (ath9k_hw_mci_is_enabled(ah))
|
||||
ar9003_mci_check_gpm_offset(ah);
|
||||
|
||||
/* DMA HALT added to resolve ar9300 and ar9580 bus error during
|
||||
- * RTC_RC reg read
|
||||
+ * RTC_RC reg read. Also needed for AR9550 external reset
|
||||
*/
|
||||
- if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) {
|
||||
+ if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) {
|
||||
REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
|
||||
ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK,
|
||||
20 * AH_WAIT_TIMEOUT);
|
||||
- REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
|
||||
}
|
||||
|
||||
+ if (!AR_SREV_9100(ah))
|
||||
+ ath9k_hw_external_reset(ah, type);
|
||||
+
|
||||
+ if (AR_SREV_9300(ah) || AR_SREV_9580(ah))
|
||||
+ REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
|
||||
+
|
||||
REG_WRITE(ah, AR_RTC_RC, rst_flags);
|
||||
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
@ -1,51 +0,0 @@
|
||||
--- a/drivers/net/wireless/ath/regd.c
|
||||
+++ b/drivers/net/wireless/ath/regd.c
|
||||
@@ -115,6 +115,16 @@ static const struct ieee80211_regdomain
|
||||
)
|
||||
};
|
||||
|
||||
+static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
|
||||
+{
|
||||
+ return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
|
||||
+}
|
||||
+
|
||||
+static bool is_default_regd(struct ath_regulatory *reg)
|
||||
+{
|
||||
+ return ath_regd_get_eepromRD(reg) == CTRY_DEFAULT;
|
||||
+}
|
||||
+
|
||||
static bool dynamic_country_user_possible(struct ath_regulatory *reg)
|
||||
{
|
||||
if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
|
||||
@@ -123,6 +133,9 @@ static bool dynamic_country_user_possibl
|
||||
if (IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
|
||||
return true;
|
||||
|
||||
+ if (is_default_regd(reg))
|
||||
+ return true;
|
||||
+
|
||||
switch (reg->country_code) {
|
||||
case CTRY_UNITED_STATES:
|
||||
case CTRY_JAPAN1:
|
||||
@@ -208,11 +221,6 @@ static inline bool is_wwr_sku(u16 regd)
|
||||
(regd == WORLD));
|
||||
}
|
||||
|
||||
-static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
|
||||
-{
|
||||
- return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
|
||||
-}
|
||||
-
|
||||
bool ath_is_world_regd(struct ath_regulatory *reg)
|
||||
{
|
||||
return is_wwr_sku(ath_regd_get_eepromRD(reg));
|
||||
@@ -658,6 +666,9 @@ ath_regd_init_wiphy(struct ath_regulator
|
||||
if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
|
||||
return 0;
|
||||
|
||||
+ if (is_default_regd(reg))
|
||||
+ return 0;
|
||||
+
|
||||
wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
|
||||
REGULATORY_CUSTOM_REG;
|
||||
|
@ -1,43 +0,0 @@
|
||||
--- a/net/wireless/sysfs.c
|
||||
+++ b/net/wireless/sysfs.c
|
||||
@@ -23,18 +23,35 @@ static inline struct cfg80211_registered
|
||||
return container_of(dev, struct cfg80211_registered_device, wiphy.dev);
|
||||
}
|
||||
|
||||
-#define SHOW_FMT(name, fmt, member) \
|
||||
+#define SHOW_FMT(name, fmt, member, mode) \
|
||||
static ssize_t name ## _show(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *buf) \
|
||||
{ \
|
||||
return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \
|
||||
} \
|
||||
-static DEVICE_ATTR_RO(name)
|
||||
+static DEVICE_ATTR_##mode(name)
|
||||
|
||||
-SHOW_FMT(index, "%d", wiphy_idx);
|
||||
-SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
|
||||
-SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
|
||||
+static ssize_t macaddress_store(struct device *dev,
|
||||
+ struct device_attribute *attr,
|
||||
+ const char *buf, size_t len)
|
||||
+{
|
||||
+ u8 mac[ETH_ALEN];
|
||||
+
|
||||
+ if (!mac_pton(buf, mac))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n')
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ memcpy(dev_to_rdev(dev)->wiphy.perm_addr, mac, ETH_ALEN);
|
||||
+
|
||||
+ return strnlen(buf, len);
|
||||
+}
|
||||
+
|
||||
+SHOW_FMT(index, "%d", wiphy_idx, RO);
|
||||
+SHOW_FMT(macaddress, "%pM", wiphy.perm_addr, RW);
|
||||
+SHOW_FMT(address_mask, "%pM", wiphy.addr_mask, RO);
|
||||
|
||||
static ssize_t name_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
@ -1,23 +0,0 @@
|
||||
brcmfmac: do not use internal roaming engine by default
|
||||
|
||||
Some evidence of curing disconnects with this disabled, so make it a default.
|
||||
Can be overridden with module parameter roamoff=0
|
||||
See: http://projectable.me/optimize-my-pi-wi-fi/
|
||||
|
||||
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
|
||||
@@ -59,7 +59,11 @@ static int brcmf_fcmode;
|
||||
module_param_named(fcmode, brcmf_fcmode, int, 0);
|
||||
MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control");
|
||||
|
||||
+#if defined(CONFIG_ARCH_BCM2835)
|
||||
+static int brcmf_roamoff = 1;
|
||||
+#else
|
||||
static int brcmf_roamoff;
|
||||
+#endif
|
||||
module_param_named(roamoff, brcmf_roamoff, int, 0400);
|
||||
MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
|
||||
|
@ -1,49 +0,0 @@
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Thu, 9 Jul 2015 00:07:59 +0200
|
||||
Subject: [PATCH] brcmfmac: workaround bug with some inconsistent BSSes state
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -715,8 +715,36 @@ static struct wireless_dev *brcmf_cfg802
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct brcmf_pub *drvr = cfg->pub;
|
||||
struct wireless_dev *wdev;
|
||||
+ struct net_device *dev;
|
||||
int err;
|
||||
|
||||
+ /*
|
||||
+ * There is a bug with in-firmware BSS management. When adding virtual
|
||||
+ * interface brcmfmac first tells firmware to create new BSS and then
|
||||
+ * it creates new struct net_device.
|
||||
+ *
|
||||
+ * If creating/registering netdev(ice) fails, BSS remains in some bugged
|
||||
+ * state. It conflicts with existing BSSes by overtaking their auth
|
||||
+ * requests.
|
||||
+ *
|
||||
+ * It results in one BSS (addresss X) sending beacons and another BSS
|
||||
+ * (address Y) replying to authentication requests. This makes interface
|
||||
+ * unusable as AP.
|
||||
+ *
|
||||
+ * To workaround this bug we may try to guess if register_netdev(ice)
|
||||
+ * will fail. The most obvious case is using interface name that already
|
||||
+ * exists. This is actually quite likely with brcmfmac & some user space
|
||||
+ * scripts as brcmfmac doesn't allow deleting virtual interfaces.
|
||||
+ * So this bug can be triggered even by something trivial like:
|
||||
+ * iw dev wlan0 delete
|
||||
+ * iw phy phy0 interface add wlan0 type __ap
|
||||
+ */
|
||||
+ dev = dev_get_by_name(&init_net, name);
|
||||
+ if (dev) {
|
||||
+ dev_put(dev);
|
||||
+ return ERR_PTR(-ENFILE);
|
||||
+ }
|
||||
+
|
||||
brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
|
||||
err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
|
||||
if (err) {
|
@ -1,30 +0,0 @@
|
||||
From 91094ed065f7794886b4a5490fd6de942f036bb4 Mon Sep 17 00:00:00 2001
|
||||
From: Gabor Juhos <juhosg@openwrt.org>
|
||||
Date: Sun, 24 Mar 2013 19:26:26 +0100
|
||||
Subject: [PATCH] rt2x00: allow to build rt2800soc module for RT3883
|
||||
|
||||
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
|
||||
---
|
||||
drivers/net/wireless/ralink/rt2x00/Kconfig | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ralink/rt2x00/Kconfig
|
||||
+++ b/drivers/net/wireless/ralink/rt2x00/Kconfig
|
||||
@@ -211,7 +211,7 @@ endif
|
||||
config RT2800SOC
|
||||
tristate "Ralink WiSoC support"
|
||||
depends on m
|
||||
- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620
|
||||
+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620
|
||||
select RT2X00_LIB_SOC
|
||||
select RT2X00_LIB_MMIO
|
||||
select RT2X00_LIB_CRYPTO
|
||||
@@ -246,7 +246,7 @@ config RT2X00_LIB_PCI
|
||||
|
||||
config RT2X00_LIB_SOC
|
||||
tristate "RT2x00 SoC support"
|
||||
- depends on SOC_RT288X || SOC_RT305X || SOC_MT7620
|
||||
+ depends on SOC_RT288X || SOC_RT305X || SOC_RT3883 || SOC_MT7620
|
||||
depends on m
|
||||
select RT2X00_LIB
|
||||
|
@ -1,34 +0,0 @@
|
||||
From d946085ff5a331de64e91a2e3c96b9ca79d740f5 Mon Sep 17 00:00:00 2001
|
||||
From: David Bauer <mail@david-bauer.net>
|
||||
Date: Mon, 15 Jun 2020 00:10:34 +0200
|
||||
Subject: [PATCH] ath9k: enabled MFP capability unconditionally
|
||||
|
||||
ath9k will already fallback on software-crypto for chipsets not
|
||||
supporting IEEE802.11w (MFP). So advertising MFP is not dependent
|
||||
on disabling HW crypto for all traffic entirely.
|
||||
|
||||
Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
---
|
||||
drivers/net/wireless/ath/ath9k/init.c | 4 +---
|
||||
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/init.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/init.c
|
||||
@@ -927,6 +927,7 @@ static void ath9k_set_hw_capab(struct at
|
||||
ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
|
||||
ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
|
||||
ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
|
||||
+ ieee80211_hw_set(hw, MFP_CAPABLE);
|
||||
|
||||
if (ath9k_ps_enable)
|
||||
ieee80211_hw_set(hw, SUPPORTS_PS);
|
||||
@@ -939,9 +940,6 @@ static void ath9k_set_hw_capab(struct at
|
||||
IEEE80211_RADIOTAP_MCS_HAVE_STBC;
|
||||
}
|
||||
|
||||
- if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
|
||||
- ieee80211_hw_set(hw, MFP_CAPABLE);
|
||||
-
|
||||
hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR |
|
||||
NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
|
||||
NL80211_FEATURE_P2P_GO_CTWIN;
|
@ -1,412 +0,0 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Thu, 21 Jan 2021 18:29:30 +0100
|
||||
Subject: [PATCH] mac80211: minstrel_ht: use bitfields to encode rate
|
||||
indexes
|
||||
|
||||
Get rid of a lot of divisions and modulo operations
|
||||
Reduces code size and improves performance
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.c
|
||||
@@ -379,14 +379,14 @@ out:
|
||||
static inline struct minstrel_rate_stats *
|
||||
minstrel_get_ratestats(struct minstrel_ht_sta *mi, int index)
|
||||
{
|
||||
- return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES];
|
||||
+ return &mi->groups[MI_RATE_GROUP(index)].rates[MI_RATE_IDX(index)];
|
||||
}
|
||||
|
||||
-static inline int
|
||||
-minstrel_get_duration(int index)
|
||||
+static inline int minstrel_get_duration(int index)
|
||||
{
|
||||
- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES];
|
||||
- unsigned int duration = group->duration[index % MCS_GROUP_RATES];
|
||||
+ const struct mcs_group *group = &minstrel_mcs_groups[MI_RATE_GROUP(index)];
|
||||
+ unsigned int duration = group->duration[MI_RATE_IDX(index)];
|
||||
+
|
||||
return duration << group->shift;
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ minstrel_ht_avg_ampdu_len(struct minstre
|
||||
if (mi->avg_ampdu_len)
|
||||
return MINSTREL_TRUNC(mi->avg_ampdu_len);
|
||||
|
||||
- if (minstrel_ht_is_legacy_group(mi->max_tp_rate[0] / MCS_GROUP_RATES))
|
||||
+ if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_tp_rate[0])))
|
||||
return 1;
|
||||
|
||||
duration = minstrel_get_duration(mi->max_tp_rate[0]);
|
||||
@@ -465,14 +465,14 @@ minstrel_ht_sort_best_tp_rates(struct mi
|
||||
int tmp_group, tmp_idx, tmp_tp_avg, tmp_prob;
|
||||
int j = MAX_THR_RATES;
|
||||
|
||||
- cur_group = index / MCS_GROUP_RATES;
|
||||
- cur_idx = index % MCS_GROUP_RATES;
|
||||
+ cur_group = MI_RATE_GROUP(index);
|
||||
+ cur_idx = MI_RATE_IDX(index);
|
||||
cur_prob = mi->groups[cur_group].rates[cur_idx].prob_avg;
|
||||
cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, cur_prob);
|
||||
|
||||
do {
|
||||
- tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
|
||||
- tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
|
||||
+ tmp_group = MI_RATE_GROUP(tp_list[j - 1]);
|
||||
+ tmp_idx = MI_RATE_IDX(tp_list[j - 1]);
|
||||
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
|
||||
tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx,
|
||||
tmp_prob);
|
||||
@@ -504,23 +504,23 @@ minstrel_ht_set_best_prob_rate(struct mi
|
||||
int max_gpr_group, max_gpr_idx;
|
||||
int max_gpr_tp_avg, max_gpr_prob;
|
||||
|
||||
- cur_group = index / MCS_GROUP_RATES;
|
||||
- cur_idx = index % MCS_GROUP_RATES;
|
||||
- mg = &mi->groups[index / MCS_GROUP_RATES];
|
||||
- mrs = &mg->rates[index % MCS_GROUP_RATES];
|
||||
+ cur_group = MI_RATE_GROUP(index);
|
||||
+ cur_idx = MI_RATE_IDX(index);
|
||||
+ mg = &mi->groups[cur_group];
|
||||
+ mrs = &mg->rates[cur_idx];
|
||||
|
||||
- tmp_group = *dest / MCS_GROUP_RATES;
|
||||
- tmp_idx = *dest % MCS_GROUP_RATES;
|
||||
+ tmp_group = MI_RATE_GROUP(*dest);
|
||||
+ tmp_idx = MI_RATE_IDX(*dest);
|
||||
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
|
||||
tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
|
||||
|
||||
/* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from
|
||||
* MCS_GROUP as well as CCK_GROUP rates do not allow aggregation */
|
||||
- max_tp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES;
|
||||
- max_tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES;
|
||||
+ max_tp_group = MI_RATE_GROUP(mi->max_tp_rate[0]);
|
||||
+ max_tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]);
|
||||
max_tp_prob = mi->groups[max_tp_group].rates[max_tp_idx].prob_avg;
|
||||
|
||||
- if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES) &&
|
||||
+ if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(index)) &&
|
||||
!minstrel_ht_is_legacy_group(max_tp_group))
|
||||
return;
|
||||
|
||||
@@ -529,8 +529,8 @@ minstrel_ht_set_best_prob_rate(struct mi
|
||||
mrs->prob_avg < max_tp_prob)
|
||||
return;
|
||||
|
||||
- max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES;
|
||||
- max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
|
||||
+ max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate);
|
||||
+ max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate);
|
||||
max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg;
|
||||
|
||||
if (mrs->prob_avg > MINSTREL_FRAC(75, 100)) {
|
||||
@@ -567,13 +567,13 @@ minstrel_ht_assign_best_tp_rates(struct
|
||||
unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp, tmp_prob;
|
||||
int i;
|
||||
|
||||
- tmp_group = tmp_legacy_tp_rate[0] / MCS_GROUP_RATES;
|
||||
- tmp_idx = tmp_legacy_tp_rate[0] % MCS_GROUP_RATES;
|
||||
+ tmp_group = MI_RATE_GROUP(tmp_legacy_tp_rate[0]);
|
||||
+ tmp_idx = MI_RATE_IDX(tmp_legacy_tp_rate[0]);
|
||||
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
|
||||
tmp_cck_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
|
||||
|
||||
- tmp_group = tmp_mcs_tp_rate[0] / MCS_GROUP_RATES;
|
||||
- tmp_idx = tmp_mcs_tp_rate[0] % MCS_GROUP_RATES;
|
||||
+ tmp_group = MI_RATE_GROUP(tmp_mcs_tp_rate[0]);
|
||||
+ tmp_idx = MI_RATE_IDX(tmp_mcs_tp_rate[0]);
|
||||
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg;
|
||||
tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob);
|
||||
|
||||
@@ -600,14 +600,14 @@ minstrel_ht_prob_rate_reduce_streams(str
|
||||
if (!mi->sta->ht_cap.ht_supported)
|
||||
return;
|
||||
|
||||
- tmp_max_streams = minstrel_mcs_groups[mi->max_tp_rate[0] /
|
||||
- MCS_GROUP_RATES].streams;
|
||||
+ group = MI_RATE_GROUP(mi->max_tp_rate[0]);
|
||||
+ tmp_max_streams = minstrel_mcs_groups[group].streams;
|
||||
for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
|
||||
mg = &mi->groups[group];
|
||||
if (!mi->supported[group] || group == MINSTREL_CCK_GROUP)
|
||||
continue;
|
||||
|
||||
- tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES;
|
||||
+ tmp_idx = MI_RATE_IDX(mg->max_group_prob_rate);
|
||||
tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg;
|
||||
|
||||
if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) &&
|
||||
@@ -644,8 +644,8 @@ minstrel_ht_find_probe_rates(struct mins
|
||||
int i, g, max_dur;
|
||||
int tp_idx;
|
||||
|
||||
- tp_group = &minstrel_mcs_groups[mi->max_tp_rate[0] / MCS_GROUP_RATES];
|
||||
- tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES;
|
||||
+ tp_group = &minstrel_mcs_groups[MI_RATE_GROUP(mi->max_tp_rate[0])];
|
||||
+ tp_idx = MI_RATE_IDX(mi->max_tp_rate[0]);
|
||||
|
||||
max_dur = minstrel_get_duration(mi->max_tp_rate[0]);
|
||||
if (faster_rate)
|
||||
@@ -670,7 +670,7 @@ minstrel_ht_find_probe_rates(struct mins
|
||||
if ((group->duration[i] << group->shift) > max_dur)
|
||||
continue;
|
||||
|
||||
- idx = g * MCS_GROUP_RATES + i;
|
||||
+ idx = MI_RATE(g, i);
|
||||
if (idx == mi->max_tp_rate[0])
|
||||
continue;
|
||||
|
||||
@@ -712,10 +712,10 @@ minstrel_ht_rate_sample_switch(struct mi
|
||||
|
||||
/* If no suitable rate was found, try to pick the next one in the group */
|
||||
if (!n_rates) {
|
||||
- int g_idx = mi->max_tp_rate[0] / MCS_GROUP_RATES;
|
||||
+ int g_idx = MI_RATE_GROUP(mi->max_tp_rate[0]);
|
||||
u16 supported = mi->supported[g_idx];
|
||||
|
||||
- supported >>= mi->max_tp_rate[0] % MCS_GROUP_RATES;
|
||||
+ supported >>= MI_RATE_IDX(mi->max_tp_rate[0]);
|
||||
for (i = 0; supported; supported >>= 1, i++) {
|
||||
if (!(supported & 1))
|
||||
continue;
|
||||
@@ -854,24 +854,27 @@ minstrel_ht_update_stats(struct minstrel
|
||||
mi->sample_slow = 0;
|
||||
mi->sample_count = 0;
|
||||
|
||||
- memset(tmp_mcs_tp_rate, 0, sizeof(tmp_mcs_tp_rate));
|
||||
- memset(tmp_legacy_tp_rate, 0, sizeof(tmp_legacy_tp_rate));
|
||||
if (mi->supported[MINSTREL_CCK_GROUP])
|
||||
- for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++)
|
||||
- tmp_legacy_tp_rate[j] = MINSTREL_CCK_GROUP * MCS_GROUP_RATES;
|
||||
+ group = MINSTREL_CCK_GROUP;
|
||||
else if (mi->supported[MINSTREL_OFDM_GROUP])
|
||||
- for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++)
|
||||
- tmp_legacy_tp_rate[j] = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES;
|
||||
+ group = MINSTREL_OFDM_GROUP;
|
||||
+ else
|
||||
+ group = 0;
|
||||
+
|
||||
+ index = MI_RATE(group, 0);
|
||||
+ for (j = 0; j < ARRAY_SIZE(tmp_legacy_tp_rate); j++)
|
||||
+ tmp_legacy_tp_rate[j] = index;
|
||||
|
||||
if (mi->supported[MINSTREL_VHT_GROUP_0])
|
||||
- index = MINSTREL_VHT_GROUP_0 * MCS_GROUP_RATES;
|
||||
+ group = MINSTREL_VHT_GROUP_0;
|
||||
else if (ht_supported)
|
||||
- index = MINSTREL_HT_GROUP_0 * MCS_GROUP_RATES;
|
||||
+ group = MINSTREL_HT_GROUP_0;
|
||||
else if (mi->supported[MINSTREL_CCK_GROUP])
|
||||
- index = MINSTREL_CCK_GROUP * MCS_GROUP_RATES;
|
||||
+ group = MINSTREL_CCK_GROUP;
|
||||
else
|
||||
- index = MINSTREL_OFDM_GROUP * MCS_GROUP_RATES;
|
||||
+ group = MINSTREL_OFDM_GROUP;
|
||||
|
||||
+ index = MI_RATE(group, 0);
|
||||
tmp_max_prob_rate = index;
|
||||
for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++)
|
||||
tmp_mcs_tp_rate[j] = index;
|
||||
@@ -888,7 +891,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
|
||||
/* (re)Initialize group rate indexes */
|
||||
for(j = 0; j < MAX_THR_RATES; j++)
|
||||
- tmp_group_tp_rate[j] = MCS_GROUP_RATES * group;
|
||||
+ tmp_group_tp_rate[j] = MI_RATE(group, 0);
|
||||
|
||||
if (group == MINSTREL_CCK_GROUP && ht_supported)
|
||||
tp_rate = tmp_legacy_tp_rate;
|
||||
@@ -897,7 +900,7 @@ minstrel_ht_update_stats(struct minstrel
|
||||
if (!(mi->supported[group] & BIT(i)))
|
||||
continue;
|
||||
|
||||
- index = MCS_GROUP_RATES * group + i;
|
||||
+ index = MI_RATE(group, i);
|
||||
|
||||
mrs = &mg->rates[i];
|
||||
mrs->retry_updated = false;
|
||||
@@ -929,13 +932,13 @@ minstrel_ht_update_stats(struct minstrel
|
||||
continue;
|
||||
|
||||
mg = &mi->groups[group];
|
||||
- mg->max_group_prob_rate = MCS_GROUP_RATES * group;
|
||||
+ mg->max_group_prob_rate = MI_RATE(group, 0);
|
||||
|
||||
for (i = 0; i < MCS_GROUP_RATES; i++) {
|
||||
if (!(mi->supported[group] & BIT(i)))
|
||||
continue;
|
||||
|
||||
- index = MCS_GROUP_RATES * group + i;
|
||||
+ index = MI_RATE(group, i);
|
||||
|
||||
/* Find max probability rate per group and global */
|
||||
minstrel_ht_set_best_prob_rate(mi, &tmp_max_prob_rate,
|
||||
@@ -1022,7 +1025,7 @@ minstrel_downgrade_rate(struct minstrel_
|
||||
{
|
||||
int group, orig_group;
|
||||
|
||||
- orig_group = group = *idx / MCS_GROUP_RATES;
|
||||
+ orig_group = group = MI_RATE_GROUP(*idx);
|
||||
while (group > 0) {
|
||||
group--;
|
||||
|
||||
@@ -1206,7 +1209,7 @@ minstrel_calc_retransmit(struct minstrel
|
||||
ctime += (t_slot * cw) >> 1;
|
||||
cw = min((cw << 1) | 1, mp->cw_max);
|
||||
|
||||
- if (minstrel_ht_is_legacy_group(index / MCS_GROUP_RATES)) {
|
||||
+ if (minstrel_ht_is_legacy_group(MI_RATE_GROUP(index))) {
|
||||
overhead = mi->overhead_legacy;
|
||||
overhead_rtscts = mi->overhead_legacy_rtscts;
|
||||
} else {
|
||||
@@ -1239,7 +1242,7 @@ static void
|
||||
minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
|
||||
struct ieee80211_sta_rates *ratetbl, int offset, int index)
|
||||
{
|
||||
- int group_idx = index / MCS_GROUP_RATES;
|
||||
+ int group_idx = MI_RATE_GROUP(index);
|
||||
const struct mcs_group *group = &minstrel_mcs_groups[group_idx];
|
||||
struct minstrel_rate_stats *mrs;
|
||||
u8 idx;
|
||||
@@ -1259,7 +1262,7 @@ minstrel_ht_set_rate(struct minstrel_pri
|
||||
ratetbl->rate[offset].count_rts = mrs->retry_count_rtscts;
|
||||
}
|
||||
|
||||
- index %= MCS_GROUP_RATES;
|
||||
+ index = MI_RATE_IDX(index);
|
||||
if (group_idx == MINSTREL_CCK_GROUP)
|
||||
idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)];
|
||||
else if (group_idx == MINSTREL_OFDM_GROUP)
|
||||
@@ -1289,17 +1292,17 @@ minstrel_ht_set_rate(struct minstrel_pri
|
||||
static inline int
|
||||
minstrel_ht_get_prob_avg(struct minstrel_ht_sta *mi, int rate)
|
||||
{
|
||||
- int group = rate / MCS_GROUP_RATES;
|
||||
- rate %= MCS_GROUP_RATES;
|
||||
+ int group = MI_RATE_GROUP(rate);
|
||||
+ rate = MI_RATE_IDX(rate);
|
||||
return mi->groups[group].rates[rate].prob_avg;
|
||||
}
|
||||
|
||||
static int
|
||||
minstrel_ht_get_max_amsdu_len(struct minstrel_ht_sta *mi)
|
||||
{
|
||||
- int group = mi->max_prob_rate / MCS_GROUP_RATES;
|
||||
+ int group = MI_RATE_GROUP(mi->max_prob_rate);
|
||||
const struct mcs_group *g = &minstrel_mcs_groups[group];
|
||||
- int rate = mi->max_prob_rate % MCS_GROUP_RATES;
|
||||
+ int rate = MI_RATE_IDX(mi->max_prob_rate);
|
||||
unsigned int duration;
|
||||
|
||||
/* Disable A-MSDU if max_prob_rate is bad */
|
||||
@@ -1405,7 +1408,7 @@ minstrel_get_sample_rate(struct minstrel
|
||||
return -1;
|
||||
|
||||
mrs = &mg->rates[sample_idx];
|
||||
- sample_idx += sample_group * MCS_GROUP_RATES;
|
||||
+ sample_idx += MI_RATE(sample_group, 0);
|
||||
|
||||
tp_rate1 = mi->max_tp_rate[0];
|
||||
|
||||
@@ -1455,8 +1458,7 @@ minstrel_get_sample_rate(struct minstrel
|
||||
* if the link is working perfectly.
|
||||
*/
|
||||
|
||||
- cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 /
|
||||
- MCS_GROUP_RATES].streams;
|
||||
+ cur_max_tp_streams = minstrel_mcs_groups[MI_RATE_GROUP(tp_rate1)].streams;
|
||||
if (sample_dur >= minstrel_get_duration(tp_rate2) &&
|
||||
(cur_max_tp_streams - 1 <
|
||||
minstrel_mcs_groups[sample_group].streams ||
|
||||
@@ -1484,7 +1486,7 @@ minstrel_ht_get_rate(void *priv, struct
|
||||
int sample_idx;
|
||||
|
||||
if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
|
||||
- !minstrel_ht_is_legacy_group(mi->max_prob_rate / MCS_GROUP_RATES))
|
||||
+ !minstrel_ht_is_legacy_group(MI_RATE_GROUP(mi->max_prob_rate)))
|
||||
minstrel_aggr_check(sta, txrc->skb);
|
||||
|
||||
info->flags |= mi->tx_flags;
|
||||
@@ -1512,8 +1514,8 @@ minstrel_ht_get_rate(void *priv, struct
|
||||
if (sample_idx < 0)
|
||||
return;
|
||||
|
||||
- sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES];
|
||||
- sample_idx %= MCS_GROUP_RATES;
|
||||
+ sample_group = &minstrel_mcs_groups[MI_RATE_GROUP(sample_idx)];
|
||||
+ sample_idx = MI_RATE_IDX(sample_idx);
|
||||
|
||||
if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP] &&
|
||||
(sample_idx >= 4) != txrc->short_preamble)
|
||||
@@ -1529,7 +1531,7 @@ minstrel_ht_get_rate(void *priv, struct
|
||||
int idx = sample_idx % ARRAY_SIZE(mp->ofdm_rates[0]);
|
||||
rate->idx = mp->ofdm_rates[mi->band][idx];
|
||||
} else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) {
|
||||
- ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES,
|
||||
+ ieee80211_rate_set_vht(rate, MI_RATE_IDX(sample_idx),
|
||||
sample_group->streams);
|
||||
} else {
|
||||
rate->idx = sample_idx + (sample_group->streams - 1) * 8;
|
||||
@@ -1898,8 +1900,8 @@ static u32 minstrel_ht_get_expected_thro
|
||||
struct minstrel_ht_sta *mi = priv_sta;
|
||||
int i, j, prob, tp_avg;
|
||||
|
||||
- i = mi->max_tp_rate[0] / MCS_GROUP_RATES;
|
||||
- j = mi->max_tp_rate[0] % MCS_GROUP_RATES;
|
||||
+ i = MI_RATE_GROUP(mi->max_tp_rate[0]);
|
||||
+ j = MI_RATE_IDX(mi->max_tp_rate[0]);
|
||||
prob = mi->groups[i].rates[j].prob_avg;
|
||||
|
||||
/* convert tp_avg from pkt per second in kbps */
|
||||
--- a/net/mac80211/rc80211_minstrel_ht.h
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht.h
|
||||
@@ -6,6 +6,8 @@
|
||||
#ifndef __RC_MINSTREL_HT_H
|
||||
#define __RC_MINSTREL_HT_H
|
||||
|
||||
+#include <linux/bitfield.h>
|
||||
+
|
||||
/* number of highest throughput rates to consider*/
|
||||
#define MAX_THR_RATES 4
|
||||
#define SAMPLE_COLUMNS 10 /* number of columns in sample table */
|
||||
@@ -57,6 +59,17 @@
|
||||
|
||||
#define MCS_GROUP_RATES 10
|
||||
|
||||
+#define MI_RATE_IDX_MASK GENMASK(3, 0)
|
||||
+#define MI_RATE_GROUP_MASK GENMASK(15, 4)
|
||||
+
|
||||
+#define MI_RATE(_group, _idx) \
|
||||
+ (FIELD_PREP(MI_RATE_GROUP_MASK, _group) | \
|
||||
+ FIELD_PREP(MI_RATE_IDX_MASK, _idx))
|
||||
+
|
||||
+#define MI_RATE_IDX(_rate) FIELD_GET(MI_RATE_IDX_MASK, _rate)
|
||||
+#define MI_RATE_GROUP(_rate) FIELD_GET(MI_RATE_GROUP_MASK, _rate)
|
||||
+
|
||||
+
|
||||
struct minstrel_priv {
|
||||
struct ieee80211_hw *hw;
|
||||
bool has_mrr;
|
||||
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
|
||||
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
|
||||
@@ -56,7 +56,7 @@ minstrel_ht_stats_dump(struct minstrel_h
|
||||
|
||||
for (j = 0; j < MCS_GROUP_RATES; j++) {
|
||||
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
|
||||
- int idx = i * MCS_GROUP_RATES + j;
|
||||
+ int idx = MI_RATE(i, j);
|
||||
unsigned int duration;
|
||||
|
||||
if (!(mi->supported[i] & BIT(j)))
|
||||
@@ -201,7 +201,7 @@ minstrel_ht_stats_csv_dump(struct minstr
|
||||
|
||||
for (j = 0; j < MCS_GROUP_RATES; j++) {
|
||||
struct minstrel_rate_stats *mrs = &mi->groups[i].rates[j];
|
||||
- int idx = i * MCS_GROUP_RATES + j;
|
||||
+ int idx = MI_RATE(i, j);
|
||||
unsigned int duration;
|
||||
|
||||
if (!(mi->supported[i] & BIT(j)))
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user