* [PATCH v2] mac80211: exit cooked monitor RX early if there are none
From: Johannes Berg @ 2011-10-21 8:22 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
In-Reply-To: <1319185071.3964.5.camel@jlt3.sipsolutions.net>
From: Johannes Berg <johannes.berg@intel.com>
If there are no cooked monitor interfaces, there's
no point in building the radiotap RX header for the
frame and iterating the interface list.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
v2: wow, embarrassing ... try quilt refresh ...
net/mac80211/rx.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/net/mac80211/rx.c 2011-10-21 10:19:33.000000000 +0200
+++ b/net/mac80211/rx.c 2011-10-21 10:20:59.000000000 +0200
@@ -2489,6 +2489,10 @@ static void ieee80211_rx_cooked_monitor(
goto out_free_skb;
rx->flags |= IEEE80211_RX_CMNTR;
+ /* If there are no cooked monitor interfaces, just free the SKB */
+ if (!local->cooked_mntrs)
+ goto out_free_skb;
+
if (skb_headroom(skb) < sizeof(*rthdr) &&
pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC))
goto out_free_skb;
^ permalink raw reply
* [RFC 0/7] mesh power saving implementation: indication
From: Ivan Bezyazychnyy @ 2011-10-21 8:36 UTC (permalink / raw)
To: linux-wireless
Hello!
We have started implementation of power saving modes in mesh according
to chapter 11C.13 of the IEEE802.11s standard. We divided the work in
several phases and the first is indication of mesh STA's power save
modes in frames according to 11C.13.2 and 11C.13.3. We are very keen
to receive comments.
Thanks,
Ivan
^ permalink raw reply
* [RFC 1/7] mac80211: mesh power mode indication in QoS frames
From: Ivan Bezyazychnyy @ 2011-10-21 8:36 UTC (permalink / raw)
To: linux-wireless
indicate non-peer mesh power mode in multicast and local
link-specific power mode in unicast QoS frames
Signed-off-by: Ivan Bezyazychnyy <ivan.bezyazychnyy@gmail.com>
---
include/linux/ieee80211.h | 3 ++
include/linux/nl80211.h | 29 ++++++++++++++++++++++++++
include/net/cfg80211.h | 2 +
net/mac80211/sta_info.h | 2 +
net/mac80211/tx.c | 50 ++++++++++++++++++++++++++++++++++++++++++++-
net/wireless/mesh.c | 1 +
6 files changed, 86 insertions(+), 1 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 48363c3..b206b94 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -133,6 +133,9 @@
/* Mesh Control 802.11s */
#define IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT 0x0100
+/* mesh power save level subfield mask */
+#define IEEE80211_QOS_CTL_PS_LEVEL 0x0200
+
/* U-APSD queue for WMM IEs sent by AP */
#define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD (1<<7)
#define IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK 0x0f
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 8049bf7..001e9e3 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1915,6 +1915,35 @@ enum nl80211_mntr_flags {
};
/**
+ * enum nl80211_mesh_power_mode - mesh power save modes
+ *
+ * @__NL80211_MESH_POWER_INVALID - internal use
+ *
+ * @NL80211_MESH_POWER_ACTIVE - active mesh power mode, mesh STA
+ * in Awake state all the time
+ * @NL80211_MESH_POWER_LIGHT_SLEEP - light sleep mode, mesh STA
+ * alternate between Active and Doze states,
+ * mesh STA should listen to all the beacons
+ * @NL80211_MESH_POWER_DEEP_SLEEP - deep sleep mode, mesh STA
+ * alternates between Active and Doze states,
+ * may choose not listen to the beacons
+ *
+ * @__NL80211_MESH_POWER_AFTER_LAST - internal use
+ * @NL80211_MESH_POWER_MAX - highest possible power save level
+ */
+
+enum nl80211_mesh_power_mode {
+ __NL80211_MESH_POWER_INVALID,
+
+ NL80211_MESH_POWER_ACTIVE,
+ NL80211_MESH_POWER_LIGHT_SLEEP,
+ NL80211_MESH_POWER_DEEP_SLEEP,
+
+ __NL80211_MESH_POWER_AFTER_LAST,
+ NL80211_MESH_POWER_MAX = __NL80211_MESH_POWER_AFTER_LAST - 1
+};
+
+/**
* enum nl80211_meshconf_params - mesh configuration parameters
*
* Mesh configuration parameters. These can be changed while the mesh is
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 92cf1c2..e00e04e 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -765,6 +765,8 @@ struct mesh_config {
u16 dot11MeshMaxPeerLinks;
u8 dot11MeshMaxRetries;
u8 dot11MeshTTL;
+ /* non-peer mesh power save mode */
+ u8 power_mode;
/* ttl used in path selection information elements */
u8 element_ttl;
bool auto_open_plinks;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 8c8ce05..8742668 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -250,6 +250,7 @@ struct sta_ampdu_mlme {
* @plink_retries: Retries in establishment
* @ignore_plink_timer: ignore the peer-link timer (used internally)
* @plink_state: peer link state
+ * @local_ps_mode: local link-specific power save mode
* @plink_timeout: timeout of peer link
* @plink_timer: peer link watch timer
* @plink_timer_was_running: used by suspend/resume to restore timers
@@ -338,6 +339,7 @@ struct sta_info {
bool ignore_plink_timer;
bool plink_timer_was_running;
enum nl80211_plink_state plink_state;
+ enum nl80211_mesh_power_mode local_ps_mode;
u32 plink_timeout;
struct timer_list plink_timer;
#endif
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 48bbb96..8f2bc51 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1033,6 +1033,48 @@ ieee80211_tx_h_calculate_duration(struct
ieee80211_tx_data *tx)
return TX_CONTINUE;
}
+#ifdef CONFIG_MAC80211_MESH
+static enum nl80211_mesh_power_mode
+ieee80211s_get_ps_mode(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_hdr *hdr)
+{
+ enum nl80211_mesh_power_mode pm = NL80211_MESH_POWER_ACTIVE;
+ struct mesh_path *mpath;
+
+ if (is_multicast_ether_addr(hdr->addr1)) {
+ pm = (enum nl80211_mesh_power_mode)
+ sdata->u.mesh.mshcfg.power_mode;
+ } else {
+ rcu_read_lock();
+ mpath = mesh_path_lookup(hdr->addr3, sdata);
+ if (mpath) {
+ pm = mpath->next_hop->local_ps_mode;
+ }
+ rcu_read_unlock();
+ }
+
+ return pm;
+}
+
+static void ieee80211_set_mesh_ps_fields(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_hdr *hdr)
+{
+ if (ieee80211_vif_is_mesh(&sdata->vif) &&
+ (ieee80211_is_data_qos(hdr->frame_control)
+ || ieee80211_is_qos_nullfunc(hdr->frame_control))) {
+ enum nl80211_mesh_power_mode
+ pm = ieee80211s_get_ps_mode(sdata, hdr);
+ if (pm != NL80211_MESH_POWER_ACTIVE) {
+ __le16 *qc = (__le16 *) ieee80211_get_qos_ctl(hdr);
+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+ if (pm == NL80211_MESH_POWER_DEEP_SLEEP) {
+ *qc |= cpu_to_le16(IEEE80211_QOS_CTL_PS_LEVEL);
+ }
+ }
+ }
+}
+#endif /* CONFIG_MAC80211_MESH*/
+
/* actual transmit path */
static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
@@ -1437,6 +1479,9 @@ void ieee80211_xmit(struct ieee80211_sub_if_data
*sdata, struct sk_buff *skb)
}
ieee80211_set_qos_hdr(sdata, skb);
+#ifdef CONFIG_MAC80211_MESH
+ ieee80211_set_mesh_ps_fields(sdata, hdr);
+#endif /* CONFIG_MAC80211_MESH */
ieee80211_tx(sdata, skb, false);
rcu_read_unlock();
}
@@ -1887,7 +1932,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct
sk_buff *skb,
wme_sta = true;
/* receiver and we are QoS enabled, use a QoS type frame */
- if (wme_sta && local->hw.queues >= 4) {
+ if ((wme_sta && local->hw.queues >= 4) ||
+ (ieee80211_vif_is_mesh(&sdata->vif) &&
+ (ieee80211s_get_ps_mode(sdata, &hdr) !=
+ NL80211_MESH_POWER_ACTIVE))) {
fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
hdrlen += 2;
}
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 4423e64..5febd0b 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -52,6 +52,7 @@ const struct mesh_config default_mesh_config = {
.min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT,
.dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL,
.dot11MeshGateAnnouncementProtocol = false,
+ .power_mode = NL80211_MESH_POWER_ACTIVE,
};
const struct mesh_setup default_mesh_setup = {
--
1.7.3.4
^ permalink raw reply related
* [RFC 2/7] mac80211: tracking mesh peer link-specific power mode
From: Ivan Bezyazychnyy @ 2011-10-21 8:37 UTC (permalink / raw)
To: linux-wireless
Tracking link-specific power mode from QoS data and QoS null frames
Signed-off-by: Ivan Bezyazychnyy <ivan.bezyazychnyy@gmail.com>
---
include/linux/ieee80211.h | 10 +++++++
net/mac80211/mesh.h | 2 +
net/mac80211/rx.c | 65 +++++++++++++++++++++++++++++++++++++++++++++
net/mac80211/sta_info.h | 2 +
4 files changed, 79 insertions(+), 0 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index b206b94..aa6e61d 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -546,6 +546,16 @@ static inline int ieee80211_is_qos_nullfunc(__le16 fc)
cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC);
}
+/**
+ * ieee80211s_has_qos_pm - check Power Save Level in QoS control
+ * @qc - QoS control bytes in little-endian byteorder
+ */
+
+static inline int ieee80211s_has_qos_pm(__le16 qc)
+{
+ return (qc & cpu_to_le16(IEEE80211_QOS_CTL_PS_LEVEL)) != 0;
+}
+
struct ieee80211s_hdr {
u8 flags;
u8 ttl;
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 8c00e2d..6842453 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -222,6 +222,8 @@ void ieee80211_mesh_init_sdata(struct
ieee80211_sub_if_data *sdata);
void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata);
void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh);
+void ieee80211s_set_sta_ps_mode(struct sta_info *sta,
+ enum nl80211_mesh_power_mode mode);
/* Mesh paths */
int mesh_nexthop_lookup(struct sk_buff *skb,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b867bd5..4decfab 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1162,6 +1162,36 @@ int ieee80211_sta_ps_transition(struct
ieee80211_sta *sta, bool start)
}
EXPORT_SYMBOL(ieee80211_sta_ps_transition);
+#ifdef CONFIG_MAC80211_MESH
+void ieee80211s_set_sta_ps_mode(struct sta_info *sta,
+ enum nl80211_mesh_power_mode mode)
+{
+ if (sta->peer_ps_mode != mode) {
+ sta->peer_ps_mode = mode;
+#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
+ switch (mode) {
+ case NL80211_MESH_POWER_ACTIVE:
+ printk(KERN_DEBUG "%s: STA %pM enters active mode\n",
+ sta->sdata->name, sta->sta.addr);
+ break;
+ case NL80211_MESH_POWER_LIGHT_SLEEP:
+ printk(KERN_DEBUG "%s: STA %pM enters light sleep mode\n",
+ sta->sdata->name, sta->sta.addr);
+ break;
+ case NL80211_MESH_POWER_DEEP_SLEEP:
+ printk(KERN_DEBUG "%s: STA %pM enters deep sleep mode\n",
+ sta->sdata->name, sta->sta.addr);
+ break;
+ default:
+ printk(KERN_DEBUG "%s: STA %pM used invalid power save mode\n",
+ sta->sdata->name, sta->sta.addr);
+ break;
+ }
+#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
+ }
+}
+#endif /* CONFIG_MAC80211_MESH */
+
static ieee80211_rx_result debug_noinline
ieee80211_rx_h_uapsd_and_pspoll(struct ieee80211_rx_data *rx)
{
@@ -1313,6 +1343,41 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
}
}
+#ifdef CONFIG_MAC80211_MESH
+ /*
+ * Test mesh power save level subfield of QoS control field (PSL)
+ * and Power Managment field of frame control (PW)
+ * +----+----+-----------------+
+ * | PM | PSL| Mesh Power Mode |
+ * +----+----+-----------------+
+ * | 0 |Rsrv| Active |
+ * +----+----+-----------------+
+ * | 1 | 0 | Light |
+ * +----+----+-----------------+
+ * | 1 | 1 | Deep |
+ * +----+----+-----------------+
+ */
+ if (!ieee80211_has_morefrags(hdr->frame_control) &&
+ !(status->rx_flags & IEEE80211_RX_DEFERRED_RELEASE) &&
+ ieee80211_vif_is_mesh(&rx->sdata->vif) &&
+ (ieee80211_is_data(hdr->frame_control) ||
+ ieee80211_is_nullfunc(hdr->frame_control))) {
+ if (ieee80211_has_pm(hdr->frame_control)) {
+ __le16 *qc = (__le16 *) ieee80211_get_qos_ctl(hdr);
+ if (ieee80211s_has_qos_pm(*qc)) {
+ ieee80211s_set_sta_ps_mode(sta,
+ NL80211_MESH_POWER_DEEP_SLEEP);
+ } else {
+ ieee80211s_set_sta_ps_mode(sta,
+ NL80211_MESH_POWER_LIGHT_SLEEP);
+ }
+ } else {
+ ieee80211s_set_sta_ps_mode(sta,
+ NL80211_MESH_POWER_ACTIVE);
+ }
+ }
+#endif /* CONFIG_MAC80211_MESH */
+
/*
* Drop (qos-)data::nullfunc frames silently, since they
* are used only to control station power saving mode.
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 8742668..86fe10a 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -251,6 +251,7 @@ struct sta_ampdu_mlme {
* @ignore_plink_timer: ignore the peer-link timer (used internally)
* @plink_state: peer link state
* @local_ps_mode: local link-specific power save mode
+ * @peer_ps_mode: peer link-specific power save mode
* @plink_timeout: timeout of peer link
* @plink_timer: peer link watch timer
* @plink_timer_was_running: used by suspend/resume to restore timers
@@ -340,6 +341,7 @@ struct sta_info {
bool plink_timer_was_running;
enum nl80211_plink_state plink_state;
enum nl80211_mesh_power_mode local_ps_mode;
+ enum nl80211_mesh_power_mode peer_ps_mode;
u32 plink_timeout;
struct timer_list plink_timer;
#endif
--
1.7.3.4
^ permalink raw reply related
* [RFC 3/7] mac80211: mesh non-peer power mode indication in beacons
From: Ivan Bezyazychnyy @ 2011-10-21 8:37 UTC (permalink / raw)
To: linux-wireless
inidicate local mesh sta non-peer power mode in beacons
Signed-off-by: Ivan Bezyazychnyy <ivan.bezyazychnyy@gmail.com>
---
net/mac80211/mesh.c | 3 +++
net/mac80211/mesh.h | 3 +++
net/mac80211/tx.c | 3 +++
3 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index a7078fd..c16a203 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -242,6 +242,9 @@ mesh_add_meshconf_ie(struct sk_buff *skb, struct
ieee80211_sub_if_data *sdata)
/* Mesh capability */
ifmsh->accepting_plinks = mesh_plink_availables(sdata);
*pos = MESHCONF_CAPAB_FORWARDING;
+ if (sdata->u.mesh.mshcfg.power_mode == NL80211_MESH_POWER_DEEP_SLEEP) {
+ *pos |= MESHCONF_CAPAB_PS_LEVEL;
+ }
*pos++ |= ifmsh->accepting_plinks ?
MESHCONF_CAPAB_ACCEPT_PLINKS : 0x00;
*pos++ = 0x00;
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 6842453..188cc86 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -188,6 +188,9 @@ struct mesh_rmc {
/* Maximum number of paths per interface */
#define MESH_MAX_MPATHS 1024
+/* capability power save flag mask */
+#define MESHCONF_CAPAB_PS_LEVEL 0x80
+
/* Public interfaces */
/* Various */
int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 8f2bc51..b1b1234 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2344,6 +2344,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct
ieee80211_hw *hw,
memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
mgmt->frame_control =
cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
+ if (sdata->u.mesh.mshcfg.power_mode != NL80211_MESH_POWER_ACTIVE) {
+ mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+ }
memset(mgmt->da, 0xff, ETH_ALEN);
memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
--
1.7.3.4
^ permalink raw reply related
* [RFC 4/7] mac80211: setting link-specific mesh power modes when plink open
From: Ivan Bezyazychnyy @ 2011-10-21 8:37 UTC (permalink / raw)
To: linux-wireless
Setting peer link-specific power mode equal to peer non-peer power mode
value and local link-specific power mode equal to local non-peer value
Signed-off-by: Ivan Bezyazychnyy <ivan.bezyazychnyy@gmail.com>
---
net/mac80211/mesh.c | 33 +++++++++++++++++++++++++++++++++
net/mac80211/mesh.h | 6 ++++++
net/mac80211/mesh_plink.c | 22 +++++++++++++++++++++-
3 files changed, 60 insertions(+), 1 deletions(-)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index c16a203..275f2cf 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -387,6 +387,39 @@ void ieee80211_mesh_root_setup(struct
ieee80211_if_mesh *ifmsh)
}
}
+void ieee80211s_set_local_ps_mode(struct sta_info *sta, u8 pm)
+{
+ switch (pm) {
+ case NL80211_MESH_POWER_ACTIVE:
+ sta->local_ps_mode = NL80211_MESH_POWER_ACTIVE;
+#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
+ printk(KERN_DEBUG "%s: local STA operates in active mode with STA %pM\n",
+ sta->sdata->name, sta->sta.addr);
+#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
+ break;
+ case NL80211_MESH_POWER_LIGHT_SLEEP:
+ sta->local_ps_mode = NL80211_MESH_POWER_LIGHT_SLEEP;
+#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
+ printk(KERN_DEBUG "%s: local STA operates in light sleep mode with
STA %pM\n",
+ sta->sdata->name, sta->sta.addr);
+#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
+ break;
+ case NL80211_MESH_POWER_DEEP_SLEEP:
+ sta->local_ps_mode = NL80211_MESH_POWER_DEEP_SLEEP;
+#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
+ printk(KERN_DEBUG "%s: local STA operates in deep sleep mode with STA %pM\n",
+ sta->sdata->name, sta->sta.addr);
+#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
+ break;
+ default:
+#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
+ printk(KERN_DEBUG "%s: local STA used invalid power mode to operate
with STA %pM\n",
+ sta->sdata->name, sta->sta.addr);
+#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
+ break;
+ }
+}
+
/**
* ieee80211_fill_mesh_addresses - fill addresses of a locally
originated mesh frame
* @hdr: 802.11 frame header
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 188cc86..c67a9f1 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -227,6 +227,7 @@ void ieee80211_stop_mesh(struct
ieee80211_sub_if_data *sdata);
void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh);
void ieee80211s_set_sta_ps_mode(struct sta_info *sta,
enum nl80211_mesh_power_mode mode);
+void ieee80211s_set_local_ps_mode(struct sta_info *sta, u8 pm);
/* Mesh paths */
int mesh_nexthop_lookup(struct sk_buff *skb,
@@ -312,6 +313,11 @@ static inline bool mesh_path_sel_is_hwmp(struct
ieee80211_sub_if_data *sdata)
return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
}
+static inline bool ieee80211s_has_capab_pm(__le16 capab_info)
+{
+ return (capab_info & MESHCONF_CAPAB_PS_LEVEL) != 0;
+}
+
void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 7e57f5d..a8f92f3 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -248,6 +248,8 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
{
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
+ struct ieee80211_mgmt *mgmt = container_of(hw_addr,
+ struct ieee80211_mgmt, sa[0]);
rcu_read_lock();
@@ -275,8 +277,26 @@ void mesh_neighbour_update(u8 *hw_addr, u32 rates,
if (mesh_peer_accepts_plinks(elems) &&
sta->plink_state == NL80211_PLINK_LISTEN &&
sdata->u.mesh.accepting_plinks &&
- sdata->u.mesh.mshcfg.auto_open_plinks)
+ sdata->u.mesh.mshcfg.auto_open_plinks) {
+ if (ieee80211_has_pm(mgmt->frame_control)) {
+ __le16 capab_info = mgmt->u.probe_resp.capab_info;
+ if (ieee80211s_has_capab_pm(capab_info)) {
+ ieee80211s_set_sta_ps_mode(sta,
+ NL80211_MESH_POWER_DEEP_SLEEP);
+ } else {
+ ieee80211s_set_sta_ps_mode(sta,
+ NL80211_MESH_POWER_LIGHT_SLEEP);
+ }
+ } else {
+ ieee80211s_set_sta_ps_mode(sta,
+ NL80211_MESH_POWER_ACTIVE);
+ }
+
+ ieee80211s_set_local_ps_mode(sta,
+ sdata->u.mesh.mshcfg.power_mode);
+
mesh_plink_open(sta);
+ }
rcu_read_unlock();
}
--
1.7.3.4
^ permalink raw reply related
* [RFC 5/7] cfg80211 and nl80211: Setting local link-specific power mode
From: Ivan Bezyazychnyy @ 2011-10-21 8:37 UTC (permalink / raw)
To: linux-wireless
Signed-off-by: Ivan Bezyazychnyy <ivan.bezyazychnyy@gmail.com>
---
include/linux/nl80211.h | 3 +++
include/net/cfg80211.h | 2 ++
net/mac80211/cfg.c | 5 +++++
net/wireless/nl80211.c | 8 ++++++++
4 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 001e9e3..ce789ce 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1054,6 +1054,7 @@ enum nl80211_commands {
* %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that
* are managed in software: interfaces of these types aren't subject to
* any restrictions in their number or combinations.
+ * @NL80211_ATTR_LOCAL_MESH_POWER_MODE: local mesh STA link-specific power mode
*
* @%NL80211_ATTR_REKEY_DATA: nested attribute containing the information
* necessary for GTK rekeying in the device, see &enum nl80211_rekey_data.
@@ -1337,6 +1338,8 @@ enum nl80211_attrs {
NL80211_ATTR_TDLS_SUPPORT,
NL80211_ATTR_TDLS_EXTERNAL_SETUP,
+ NL80211_ATTR_LOCAL_MESH_POWER_MODE,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index e00e04e..2204222 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -456,6 +456,7 @@ enum station_parameters_apply_mask {
* as the AC bitmap in the QoS info field
* @max_sp: max Service Period. same format as the MAX_SP in the
* QoS info field (but already shifted down)
+ * @local_ps_mode: local link-specific mesh power save mode
*/
struct station_parameters {
u8 *supported_rates;
@@ -470,6 +471,7 @@ struct station_parameters {
struct ieee80211_ht_cap *ht_capa;
u8 uapsd_queues;
u8 max_sp;
+ u8 local_ps_mode;
};
/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e253afa..78c61ee 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -804,6 +804,11 @@ static void sta_apply_parameters(struct
ieee80211_local *local,
mesh_plink_block(sta);
break;
}
+
+ if (params->local_ps_mode) {
+ ieee80211s_set_local_ps_mode(sta,
+ params->local_ps_mode);
+ }
#endif
}
}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 48260c2..80bc2a7 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2517,6 +2517,10 @@ static int nl80211_set_station(struct sk_buff
*skb, struct genl_info *info)
params.plink_state =
nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
+ if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE])
+ params.local_ps_mode =
+ nla_get_u8(info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
+
err = get_vlan(info, rdev, ¶ms.vlan);
if (err)
goto out;
@@ -2531,6 +2535,8 @@ static int nl80211_set_station(struct sk_buff
*skb, struct genl_info *info)
/* disallow mesh-specific things */
if (params.plink_action)
err = -EINVAL;
+ if (params.local_ps_mode)
+ err = -EINVAL;
break;
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_STATION:
@@ -2554,6 +2560,8 @@ static int nl80211_set_station(struct sk_buff
*skb, struct genl_info *info)
if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
(params.sta_flags_mask & BIT(NL80211_STA_FLAG_TDLS_PEER)))
err = -EINVAL;
+ if (params.local_ps_mode)
+ err = -EINVAL;
break;
case NL80211_IFTYPE_MESH_POINT:
/* disallow things mesh doesn't support */
--
1.7.3.4
^ permalink raw reply related
* [RFC 6/7] cfg80211 and nl80211: getting local and peer mesh power modes
From: Ivan Bezyazychnyy @ 2011-10-21 8:37 UTC (permalink / raw)
To: linux-wireless
Signed-off-by: Ivan Bezyazychnyy <ivan.bezyazychnyy@gmail.com>
---
include/linux/nl80211.h | 6 ++++++
include/net/cfg80211.h | 10 +++++++++-
net/mac80211/cfg.c | 6 +++++-
net/wireless/nl80211.c | 6 ++++++
4 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index ce789ce..4f4bfb8 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1552,6 +1552,10 @@ enum nl80211_sta_bss_param {
* containing info as possible, see &enum nl80211_sta_bss_param
* @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected
* @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update.
+ * @NL80211_STA_INFO_LOCAL_MESH_PS_MODE: local mesh STA link-specific power
+ * save mode
+ * @NL80211_STA_INFO_PEER_MESH_PS_MODE: peer mesh STA link-specific power
+ * save mode
* @__NL80211_STA_INFO_AFTER_LAST: internal
* @NL80211_STA_INFO_MAX: highest possible station info attribute
*/
@@ -1574,6 +1578,8 @@ enum nl80211_sta_info {
NL80211_STA_INFO_BSS_PARAM,
NL80211_STA_INFO_CONNECTED_TIME,
NL80211_STA_INFO_STA_FLAGS,
+ NL80211_STA_INFO_LOCAL_MESH_PS_MODE,
+ NL80211_STA_INFO_PEER_MESH_PS_MODE,
/* keep last */
__NL80211_STA_INFO_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 2204222..845937c 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -500,6 +500,8 @@ struct station_parameters {
* @STATION_INFO_CONNECTED_TIME: @connected_time filled
* @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled
* @STATION_INFO_STA_FLAGS: @sta_flags filled
+ * @STATION_INFO_LOCAL_MESH_PS_MODE: @local_ps_mode filled
+ * @STATION_INFO_PEER_MESH_PS_MODE: @peer_ps_mode filled
*/
enum station_info_flags {
STATION_INFO_INACTIVE_TIME = 1<<0,
@@ -520,7 +522,9 @@ enum station_info_flags {
STATION_INFO_BSS_PARAM = 1<<15,
STATION_INFO_CONNECTED_TIME = 1<<16,
STATION_INFO_ASSOC_REQ_IES = 1<<17,
- STATION_INFO_STA_FLAGS = 1<<18
+ STATION_INFO_STA_FLAGS = 1<<18,
+ STATION_INFO_LOCAL_MESH_PS_MODE = 1<<17,
+ STATION_INFO_PEER_MESH_PS_MODE = 1<<18
};
/**
@@ -608,6 +612,8 @@ struct sta_bss_parameters {
* @tx_failed: number of failed transmissions (retries exceeded, no ACK)
* @rx_dropped_misc: Dropped for un-specified reason.
* @bss_param: current BSS parameters
+ * @local_ps_mode: local mesh STA power save mode
+ * @peer_ps_mode: peer mesh STA power save mode
* @generation: generation number for nl80211 dumps.
* This number should increase every time the list of stations
* changes, i.e. when a station is added or removed, so that
@@ -638,6 +644,8 @@ struct station_info {
u32 rx_dropped_misc;
struct sta_bss_parameters bss_param;
struct nl80211_sta_flag_update sta_flags;
+ u8 local_ps_mode;
+ u8 peer_ps_mode;
int generation;
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 78c61ee..2b0cc2c 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -388,11 +388,15 @@ static void sta_set_sinfo(struct sta_info *sta,
struct station_info *sinfo)
#ifdef CONFIG_MAC80211_MESH
sinfo->filled |= STATION_INFO_LLID |
STATION_INFO_PLID |
- STATION_INFO_PLINK_STATE;
+ STATION_INFO_PLINK_STATE |
+ STATION_INFO_LOCAL_MESH_PS_MODE |
+ STATION_INFO_PEER_MESH_PS_MODE;
sinfo->llid = le16_to_cpu(sta->llid);
sinfo->plid = le16_to_cpu(sta->plid);
sinfo->plink_state = sta->plink_state;
+ sinfo->local_ps_mode = sta->local_ps_mode;
+ sinfo->peer_ps_mode = sta->peer_ps_mode;
#endif
}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 80bc2a7..c53c8bb 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2325,6 +2325,12 @@ static int nl80211_send_station(struct sk_buff
*msg, u32 pid, u32 seq,
if (sinfo->filled & STATION_INFO_TX_FAILED)
NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED,
sinfo->tx_failed);
+ if (sinfo->filled & STATION_INFO_LOCAL_MESH_PS_MODE)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_LOCAL_MESH_PS_MODE,
+ sinfo->local_ps_mode);
+ if (sinfo->filled & STATION_INFO_PEER_MESH_PS_MODE)
+ NLA_PUT_U8(msg, NL80211_STA_INFO_PEER_MESH_PS_MODE,
+ sinfo->peer_ps_mode);
if (sinfo->filled & STATION_INFO_BSS_PARAM) {
bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
if (!bss_param)
--
1.7.3.4
^ permalink raw reply related
* [RFC 7/7] cfg80211 and nl80211: setting and getting mesh non-peer power mode
From: Ivan Bezyazychnyy @ 2011-10-21 8:37 UTC (permalink / raw)
To: linux-wireless
Signed-off-by: Ivan Bezyazychnyy <ivan.bezyazychnyy@gmail.com>
---
include/linux/nl80211.h | 3 +++
net/mac80211/cfg.c | 5 +++++
net/wireless/nl80211.c | 8 ++++++++
3 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 4f4bfb8..78807f4 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -2015,6 +2015,8 @@ enum nl80211_mesh_power_mode {
* access to a broader network beyond the MBSS. This is done via Root
* Announcement frames.
*
+ * @NL80211_MESHCONF_POWER_MODE: mesh non-peer power mode
+ *
* @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute
*
* @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use
@@ -2038,6 +2040,7 @@ enum nl80211_meshconf_params {
NL80211_MESHCONF_ELEMENT_TTL,
NL80211_MESHCONF_HWMP_RANN_INTERVAL,
NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
+ NL80211_MESHCONF_POWER_MODE,
/* keep last */
__NL80211_MESHCONF_ATTR_AFTER_LAST,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 2b0cc2c..e841740 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1227,6 +1227,11 @@ static int ieee80211_update_mesh_config(struct
wiphy *wiphy,
conf->dot11MeshHWMPRannInterval =
nconf->dot11MeshHWMPRannInterval;
}
+ if (_chg_mesh_attr(NL80211_MESHCONF_POWER_MODE, mask)) {
+ conf->power_mode = nconf->power_mode;
+ ieee80211_bss_info_change_notify(sdata,
+ BSS_CHANGED_BEACON);
+ }
return 0;
}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c53c8bb..cfa8b0e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3144,6 +3144,8 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
cur_params.dot11MeshHWMPRannInterval);
NLA_PUT_U8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
cur_params.dot11MeshGateAnnouncementProtocol);
+ NLA_PUT_U8(msg, NL80211_MESHCONF_POWER_MODE,
+ cur_params.power_mode);
nla_nest_end(msg, pinfoattr);
genlmsg_end(msg, hdr);
return genlmsg_reply(msg, info);
@@ -3174,6 +3176,8 @@ static const struct nla_policy
nl80211_meshconf_params_policy[NL80211_MESHCONF_A
[NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
[NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
[NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
+
+ [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U8 },
};
static const struct nla_policy
@@ -3260,6 +3264,10 @@ do {\
dot11MeshGateAnnouncementProtocol, mask,
NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
nla_get_u8);
+ FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
+ power_mode, mask,
+ NL80211_MESHCONF_POWER_MODE,
+ nla_get_u8);
if (mask_out)
*mask_out = mask;
--
1.7.3.4
^ permalink raw reply related
* Re: [RFC 1/7] mac80211: mesh power mode indication in QoS frames
From: Johannes Berg @ 2011-10-21 9:52 UTC (permalink / raw)
To: Ivan Bezyazychnyy; +Cc: linux-wireless
In-Reply-To: <CAG5dHkRULKh90W1MeR3zq+-gpeNUshrHZ0qbKXsW19PMG5enoQ@mail.gmail.com>
On Fri, 2011-10-21 at 12:36 +0400, Ivan Bezyazychnyy wrote:
> +/* mesh power save level subfield mask */
> +#define IEEE80211_QOS_CTL_PS_LEVEL 0x0200
That looks like it could use a better name?
> --- a/include/linux/nl80211.h
Why is this in a mac80211 patch?
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -765,6 +765,8 @@ struct mesh_config {
> u16 dot11MeshMaxPeerLinks;
> u8 dot11MeshMaxRetries;
> u8 dot11MeshTTL;
> + /* non-peer mesh power save mode */
> + u8 power_mode;
Ditto.
> +#ifdef CONFIG_MAC80211_MESH
No ifdefs please. There's no need for these.
> ieee80211_set_qos_hdr(sdata, skb);
> +#ifdef CONFIG_MAC80211_MESH
> + ieee80211_set_mesh_ps_fields(sdata, hdr);
> +#endif /* CONFIG_MAC80211_MESH */
ditto.
> /* receiver and we are QoS enabled, use a QoS type frame */
> - if (wme_sta && local->hw.queues >= 4) {
> + if ((wme_sta && local->hw.queues >= 4) ||
> + (ieee80211_vif_is_mesh(&sdata->vif) &&
> + (ieee80211s_get_ps_mode(sdata, &hdr) !=
> + NL80211_MESH_POWER_ACTIVE))) {
> fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
This should not be necessary.
johannes
^ permalink raw reply
* Re: [RFC 0/7] mesh power saving implementation: indication
From: Johannes Berg @ 2011-10-21 9:53 UTC (permalink / raw)
To: Ivan Bezyazychnyy; +Cc: linux-wireless
In-Reply-To: <CAG5dHkTg0JQK7d3jc1hO_A8xsPyogaufOnvvvas8Hx5GgFbskA@mail.gmail.com>
Please send patches are replies to the cover letter.
johannes
^ permalink raw reply
* Re: [RFC 3/7] mac80211: mesh non-peer power mode indication in beacons
From: Johannes Berg @ 2011-10-21 10:03 UTC (permalink / raw)
To: Ivan Bezyazychnyy; +Cc: linux-wireless
In-Reply-To: <CAG5dHkQTpfXvhC8w_1z5MvuKxWV32u2+PM8VKq4Lc5pZm2hAug@mail.gmail.com>
On Fri, 2011-10-21 at 12:37 +0400, Ivan Bezyazychnyy wrote:
> + if (sdata->u.mesh.mshcfg.power_mode == NL80211_MESH_POWER_DEEP_SLEEP) {
> + *pos |= MESHCONF_CAPAB_PS_LEVEL;
> + }
braces?
johannes
^ permalink raw reply
* Re: [RFC 4/7] mac80211: setting link-specific mesh power modes when plink open
From: Johannes Berg @ 2011-10-21 10:05 UTC (permalink / raw)
To: Ivan Bezyazychnyy; +Cc: linux-wireless
In-Reply-To: <CAG5dHkT8fPodB_ejoqSmH4Dgr-ynuMzwo5r5czXfCWgJWLiS=w@mail.gmail.com>
On Fri, 2011-10-21 at 12:37 +0400, Ivan Bezyazychnyy wrote:
> Setting peer link-specific power mode equal to peer non-peer power mode
> value and local link-specific power mode equal to local non-peer value
You really need more verbose changelogs, I can't even parse that
properly. How about mentioning why, what it means, etc?
You should also extend your cover letter to explain how the power save
stuff works.
johannes
^ permalink raw reply
* Re: ath9k: irq storm after suspend/resume
From: Clemens Buchacher @ 2011-10-21 10:22 UTC (permalink / raw)
To: Adrian Chadd; +Cc: Mohammed Shafi, linux-wireless
In-Reply-To: <CAJ-Vmo=Qt3rGDbM0yOvFuz6Pksdx9bdm8HEBnhfjP6=zjGOgTA@mail.gmail.com>
On Tue, Oct 18, 2011 at 03:05:38PM +0800, Adrian Chadd wrote:
>
> Hm, which version of the AR9285 is it, exactly?
> Would you just do a quick check (or code hack) and see if it matches
> the AR_SREV_9285SE_20 (or similar) macro?
It matches AR_SREV_9285, but it does not match AR_SREV_9285E_20.
Clemens
^ permalink raw reply
* Re: rtl8192cu - fails to maintain connection to some Access Points
From: Alan Pater @ 2011-10-21 13:23 UTC (permalink / raw)
To: sedat.dilek; +Cc: Larry Finger, linux-wireless, George0505, georgia
In-Reply-To: <CA+icZUVGi9t6Prawqz4jDqChFR+w8X9xmc_wRgPmHG3BwUVEpw@mail.gmail.com>
On Fri, Oct 21, 2011 at 1:28 AM, Sedat Dilek <sedat.dilek@googlemail.com> wrote:
> Asking as a non-native speaker/writer: What do you mean by "Meraki"?
>
> - Sedat -
>
> [1] http://meraki.com/products/wireless/wifi-stumbler
Two of their hardware access points linked together in what they call
a multi-radio mesh.
Like these: http://meraki.com/products/wireless/mr62
Perhaps it is the multi-radio setup that the rtl8192cu does not like?
Alan
^ permalink raw reply
* [PATCH 08/17] brcm80211: smac: fixed inconsistency in transmit mute
From: Arend van Spriel @ 2011-10-21 13:55 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Roland Vossen, Arend van Spriel
In-Reply-To: <1319205319-16891-1-git-send-email-arend@broadcom.com>
From: Roland Vossen <rvossen@broadcom.com>
Transmit was muted in two ways: full mute and a partial mute called
'pre ism cac time' mute. But, this 'pre ism cac time' mute was done at
one place in the code (when tx_mute == false), and overridden later
on in another place in code.
To fix this, the 'pre ism cac time' mute has been replaced by a non
mute.
Signed-off-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Alwin Beukers <alwin@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmsmac/main.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 8eb665e..cc74205 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -2453,11 +2453,11 @@ static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw,
}
/* precondition: requires the mac core to be enabled */
-static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, u32 flags)
+static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx)
{
static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
- if (on) {
+ if (mute_tx) {
/* suspend tx fifos */
brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO);
brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO);
@@ -2479,9 +2479,9 @@ static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, u32 flags)
wlc_hw->etheraddr);
}
- wlc_phy_mute_upd(wlc_hw->band->pi, on, flags);
+ wlc_phy_mute_upd(wlc_hw->band->pi, mute_tx, 0);
- if (on)
+ if (mute_tx)
brcms_c_ucode_mute_override_set(wlc_hw);
else
brcms_c_ucode_mute_override_clear(wlc_hw);
@@ -3892,7 +3892,7 @@ static void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec)
void
brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,
- bool mute, struct txpwr_limits *txpwr)
+ bool mute_tx, struct txpwr_limits *txpwr)
{
uint bandunit;
@@ -3918,7 +3918,7 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,
}
}
- wlc_phy_initcal_enable(wlc_hw->band->pi, !mute);
+ wlc_phy_initcal_enable(wlc_hw->band->pi, !mute_tx);
if (!wlc_hw->up) {
if (wlc_hw->clk)
@@ -3930,7 +3930,7 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec,
wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec);
/* Update muting of the channel */
- brcms_b_mute(wlc_hw, mute, 0);
+ brcms_b_mute(wlc_hw, mute_tx);
}
}
@@ -8341,7 +8341,7 @@ void brcms_c_init(struct brcms_c_info *wlc)
/* suspend the tx fifos and mute the phy for preism cac time */
if (mute_tx)
- brcms_b_mute(wlc->hw, ON, PHY_MUTE_FOR_PREISM);
+ brcms_b_mute(wlc->hw, true);
/* clear tx flow control */
brcms_c_txflowcontrol_reset(wlc);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 09/17] brcm80211: smac: modified Mac80211 callback interface
From: Arend van Spriel @ 2011-10-21 13:55 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Roland Vossen, Arend van Spriel
In-Reply-To: <1319205319-16891-1-git-send-email-arend@broadcom.com>
From: Roland Vossen <rvossen@broadcom.com>
Upon ops_start(), a Mac80211 driver should enable receive functionality to
support monitor mode. Also, upon ops_stop(), it should disable rx.
Driver did not follow this rule so code has been changed.
Signed-off-by: Roland Vossen <rvossen@broadcom.com>
Reported-by: Johannes Berg <johannes@sipsolutions.net>
Reviewed-by: Alwin Beukers <alwin@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
.../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 84 +++++++++-----------
1 files changed, 37 insertions(+), 47 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 915b741..f38ba17 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -284,6 +284,7 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
{
struct brcms_info *wl = hw->priv;
bool blocked;
+ int err;
ieee80211_wake_queues(hw);
spin_lock_bh(&wl->lock);
@@ -292,20 +293,48 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
if (!blocked)
wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
- return 0;
+ spin_lock_bh(&wl->lock);
+ if (!wl->pub->up)
+ err = brcms_up(wl);
+ else
+ err = -ENODEV;
+ spin_unlock_bh(&wl->lock);
+
+ if (err != 0)
+ wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__,
+ err);
+ return err;
}
static void brcms_ops_stop(struct ieee80211_hw *hw)
{
+ struct brcms_info *wl = hw->priv;
+ int status;
+
ieee80211_stop_queues(hw);
+
+ if (wl->wlc == NULL)
+ return;
+
+ spin_lock_bh(&wl->lock);
+ status = brcms_c_chipmatch(wl->wlc->hw->vendorid,
+ wl->wlc->hw->deviceid);
+ spin_unlock_bh(&wl->lock);
+ if (!status) {
+ wiphy_err(wl->wiphy,
+ "wl: brcms_ops_stop: chipmatch failed\n");
+ return;
+ }
+
+ /* put driver in down state */
+ spin_lock_bh(&wl->lock);
+ brcms_down(wl);
+ spin_unlock_bh(&wl->lock);
}
static int
brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
- struct brcms_info *wl;
- int err;
-
/* Just STA for now */
if (vif->type != NL80211_IFTYPE_AP &&
vif->type != NL80211_IFTYPE_MESH_POINT &&
@@ -317,32 +346,12 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
return -EOPNOTSUPP;
}
- wl = hw->priv;
- spin_lock_bh(&wl->lock);
- if (!wl->pub->up)
- err = brcms_up(wl);
- else
- err = -ENODEV;
- spin_unlock_bh(&wl->lock);
-
- if (err != 0)
- wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__,
- err);
-
- return err;
+ return 0;
}
static void
brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
- struct brcms_info *wl;
-
- wl = hw->priv;
-
- /* put driver in down state */
- spin_lock_bh(&wl->lock);
- brcms_down(wl);
- spin_unlock_bh(&wl->lock);
}
static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
@@ -874,37 +883,18 @@ static void brcms_free(struct brcms_info *wl)
}
/*
-* called from both kernel as from this kernel module.
+* called from both kernel as from this kernel module (error flow on attach)
* precondition: perimeter lock is not acquired.
*/
static void brcms_remove(struct pci_dev *pdev)
{
- struct brcms_info *wl;
- struct ieee80211_hw *hw;
- int status;
-
- hw = pci_get_drvdata(pdev);
- wl = hw->priv;
- if (!wl) {
- pr_err("wl: brcms_remove: pci_get_drvdata failed\n");
- return;
- }
+ struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ struct brcms_info *wl = hw->priv;
- spin_lock_bh(&wl->lock);
- status = brcms_c_chipmatch(pdev->vendor, pdev->device);
- spin_unlock_bh(&wl->lock);
- if (!status) {
- wiphy_err(wl->wiphy, "wl: brcms_remove: chipmatch "
- "failed\n");
- return;
- }
if (wl->wlc) {
wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
ieee80211_unregister_hw(hw);
- spin_lock_bh(&wl->lock);
- brcms_down(wl);
- spin_unlock_bh(&wl->lock);
}
pci_disable_device(pdev);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 04/17] brcm80211: smac: removed MPC related variables
From: Arend van Spriel @ 2011-10-21 13:55 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Roland Vossen, Arend van Spriel
In-Reply-To: <1319205319-16891-1-git-send-email-arend@broadcom.com>
From: Roland Vossen <rvossen@broadcom.com>
Several member variables were never read.
Signed-off-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Alwin Beukers <alwin@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmsmac/main.c | 8 ++------
drivers/net/wireless/brcm80211/brcmsmac/main.h | 6 ------
2 files changed, 2 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 4687983..e7d14e4 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -4303,10 +4303,6 @@ static void brcms_c_radio_timer(void *arg)
return;
}
- /* cap mpc off count */
- if (wlc->mpc_offcnt < BRCMS_MPC_MAX_DELAYCNT)
- wlc->mpc_offcnt++;
-
brcms_c_radio_hwdisable_upd(wlc);
brcms_c_radio_upd(wlc);
}
@@ -4488,7 +4484,7 @@ static void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
wlc->pub->bcmerror = 0;
/* initialize mpc delay */
- wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
+ wlc->mpc_delay_off = BRCMS_MPC_MIN_DELAYCNT;
}
static uint brcms_c_attach_module(struct brcms_c_info *wlc)
@@ -8447,7 +8443,7 @@ void brcms_c_init(struct brcms_c_info *wlc)
W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT);
/* initialize mpc delay */
- wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT;
+ wlc->mpc_delay_off = BRCMS_MPC_MIN_DELAYCNT;
/*
* Initialize WME parameters; if they haven't been set by some other
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
index 37c55fd..fc5852f 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
@@ -427,10 +427,7 @@ struct brcms_txq_info {
* bandinit_pending: track band init in auto band.
* radio_monitor: radio timer is running.
* going_down: down path intermediate variable.
- * mpc_dlycnt: # of watchdog cnt before turn disable radio.
- * mpc_offcnt: # of watchdog cnt that radio is disabled.
* mpc_delay_off: delay radio disable by # of watchdog cnt.
- * prev_non_delay_mpc: prev state brcms_c_is_non_delay_mpc.
* wdtimer: timer for watchdog routine.
* radio_timer: timer for hw radio button monitor routine.
* monitor: monitor (MPDU sniffing) mode.
@@ -521,10 +518,7 @@ struct brcms_c_info {
bool radio_monitor;
bool going_down;
- u8 mpc_dlycnt;
- u8 mpc_offcnt;
u8 mpc_delay_off;
- u8 prev_non_delay_mpc;
struct brcms_timer *wdtimer;
struct brcms_timer *radio_timer;
--
1.7.4.1
^ permalink raw reply related
* [PATCH 12/17] brcm80211: smac: rename buffer endianess conversion functions
From: Arend van Spriel @ 2011-10-21 13:55 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1319205319-16891-1-git-send-email-arend@broadcom.com>
The functions ltoh16_buf() and htol16_buf() have been renamed
to le16_to_cpu_buf() and cpu_to_le16_buf() for more clarity
what it does.
Reported-by: Joe Perches <joe@perches.com>
Reported-by: Larry Finger <Larry.Finger@lwfinger.net>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Alwin Beukers <alwin@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmsmac/srom.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.c b/drivers/net/wireless/brcm80211/brcmsmac/srom.c
index 66aa0e7..8f1cf2f 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/srom.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/srom.c
@@ -617,14 +617,14 @@ static uint mask_width(u16 mask)
return 0;
}
-static inline void ltoh16_buf(u16 *buf, unsigned int size)
+static inline void le16_to_cpu_buf(u16 *buf, unsigned int size)
{
size /= 2;
while (size--)
*(buf + size) = le16_to_cpu(*(__le16 *)(buf + size));
}
-static inline void htol16_buf(u16 *buf, unsigned int size)
+static inline void cpu_to_le16_buf(u16 *buf, unsigned int size)
{
size /= 2;
while (size--)
@@ -807,7 +807,7 @@ sprom_read_pci(struct si_pub *sih, u8 __iomem *sprom, uint wordoff,
err = -EIO;
else
/* now correct the endianness of the byte array */
- ltoh16_buf(buf, nbytes);
+ le16_to_cpu_buf(buf, nbytes);
return err;
}
@@ -837,13 +837,13 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz)
return -ENODATA;
/* fixup the endianness so crc8 will pass */
- htol16_buf(buf, bufsz);
+ cpu_to_le16_buf(buf, bufsz);
if (crc8(brcms_srom_crc8_table, (u8 *) buf, SROM4_WORDS * 2,
CRC8_INIT_VALUE) != CRC8_GOOD_VALUE(brcms_srom_crc8_table))
err = -EIO;
/* now correct the endianness of the byte array */
- ltoh16_buf(buf, bufsz);
+ le16_to_cpu_buf(buf, bufsz);
return err;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH 01/17] brcm80211: fmac: allow wd timer to be disabled when bus down
From: Arend van Spriel @ 2011-10-21 13:55 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Franky Lin, Arend van Spriel
In-Reply-To: <1319205319-16891-1-git-send-email-arend@broadcom.com>
From: Franky Lin <frankyl@broadcom.com>
Watchdog timer should be able to be stopped even firmware is not
loaded.
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index c6825f2..785ab08 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -4579,10 +4579,6 @@ struct device *brcmf_bus_get_device(struct brcmf_bus *bus)
void
brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick)
{
- /* don't start the wd until fw is loaded */
- if (bus->drvr->busstate == BRCMF_BUS_DOWN)
- return;
-
/* Totally stop the timer */
if (!wdtick && bus->wd_timer_valid == true) {
del_timer_sync(&bus->timer);
@@ -4591,6 +4587,10 @@ brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick)
return;
}
+ /* don't start the wd until fw is loaded */
+ if (bus->drvr->busstate == BRCMF_BUS_DOWN)
+ return;
+
if (wdtick) {
if (bus->save_ms != BRCMF_WD_POLL_MS) {
if (bus->wd_timer_valid == true)
--
1.7.4.1
^ permalink raw reply related
* [PATCH 02/17] brcm80211: fmac: use brcmf_del_if for all net devices
From: Arend van Spriel @ 2011-10-21 13:55 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Franky Lin, Arend van Spriel
In-Reply-To: <1319205319-16891-1-git-send-email-arend@broadcom.com>
From: Franky Lin <frankyl@broadcom.com>
Use brcmf_del_if for primary and virtual net device interfaces. This
is part of the net device interface clean up for fullmac.
Reviewed-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 55 +++++++++----------
1 files changed, 26 insertions(+), 29 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 4acbac5..6739ece 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -893,6 +893,16 @@ static int brcmf_netdev_open(struct net_device *ndev)
return ret;
}
+static const struct net_device_ops brcmf_netdev_ops_pri = {
+ .ndo_open = brcmf_netdev_open,
+ .ndo_stop = brcmf_netdev_stop,
+ .ndo_get_stats = brcmf_netdev_get_stats,
+ .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
+ .ndo_start_xmit = brcmf_netdev_start_xmit,
+ .ndo_set_mac_address = brcmf_netdev_set_mac_address,
+ .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
+};
+
int
brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, struct net_device *ndev,
char *name, u8 *mac_addr, u32 flags, u8 bssidx)
@@ -977,14 +987,23 @@ void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx)
brcmf_dbg(ERROR, "Null interface\n");
return;
}
-
ifp->state = BRCMF_E_IF_DEL;
- ifp->idx = ifidx;
- if (ifp->ndev != NULL) {
- netif_stop_queue(ifp->ndev);
+ if (ifp->ndev) {
+ if (ifidx == 0) {
+ if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
+ rtnl_lock();
+ brcmf_netdev_stop(ifp->ndev);
+ rtnl_unlock();
+ }
+ } else {
+ netif_stop_queue(ifp->ndev);
+ }
+
unregister_netdev(ifp->ndev);
- free_netdev(ifp->ndev);
drvr_priv->iflist[ifidx] = NULL;
+ if (ifidx == 0)
+ brcmf_cfg80211_detach(drvr_priv->pub.config);
+ free_netdev(ifp->ndev);
kfree(ifp);
}
}
@@ -1123,16 +1142,6 @@ int brcmf_bus_start(struct brcmf_pub *drvr)
return 0;
}
-static struct net_device_ops brcmf_netdev_ops_pri = {
- .ndo_open = brcmf_netdev_open,
- .ndo_stop = brcmf_netdev_stop,
- .ndo_get_stats = brcmf_netdev_get_stats,
- .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
- .ndo_start_xmit = brcmf_netdev_start_xmit,
- .ndo_set_mac_address = brcmf_netdev_set_mac_address,
- .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
-};
-
int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx)
{
struct brcmf_info *drvr_priv = drvr->info;
@@ -1210,21 +1219,13 @@ void brcmf_detach(struct brcmf_pub *drvr)
if (drvr) {
drvr_priv = drvr->info;
if (drvr_priv) {
- struct brcmf_if *ifp;
int i;
- for (i = 1; i < BRCMF_MAX_IFS; i++)
+ /* make sure primary interface removed last */
+ for (i = BRCMF_MAX_IFS-1; i > -1; i--)
if (drvr_priv->iflist[i])
brcmf_del_if(drvr_priv, i);
- ifp = drvr_priv->iflist[0];
- if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
- rtnl_lock();
- brcmf_netdev_stop(ifp->ndev);
- rtnl_unlock();
- unregister_netdev(ifp->ndev);
- }
-
cancel_work_sync(&drvr_priv->setmacaddr_work);
cancel_work_sync(&drvr_priv->multicast_work);
@@ -1233,10 +1234,6 @@ void brcmf_detach(struct brcmf_pub *drvr)
if (drvr->prot)
brcmf_proto_detach(drvr);
- brcmf_cfg80211_detach(drvr->config);
-
- free_netdev(ifp->ndev);
- kfree(ifp);
kfree(drvr_priv);
}
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH 00/17] fix mac80211 callback in brcmsmac and brcmfmac refactor
From: Arend van Spriel @ 2011-10-21 13:55 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Arend van Spriel
Johannes Berg commented on our use of the start/stop callbacks in brcmsmac
and we changed those callbacks. In rfkill testing it revealed a problem which
has been fixed in this series as well.
The brcmfmac driver had some restructuring in preparation of USB support
for new devices.
This patch series applies to the wireless-testing repository and depends on the
series posted on Oct 18, 2011 with message id:
Message-ID: <1318939391-19495-1-git-send-email-arend@broadcom.com>
Arend van Spriel (3):
brcm80211: smac: rename buffer endianess conversion functions
brcm80211: smac: use sk_buff list for handling frames in receive path
brcm80211: smac: change buffer endianess convert function interface
Franky Lin (5):
brcm80211: fmac: allow wd timer to be disabled when bus down
brcm80211: fmac: use brcmf_del_if for all net devices
brcm80211: fmac: use brcmf_add_if for all net devices
brcm80211: fmac: store brcmf_if in net device private data
brcm80211: fmac: remove state from brcmf_if in fullmac
Roland Vossen (9):
brcm80211: smac: removed MPC related code
brcm80211: smac: removed MPC related variables
brcm80211: smac: removed down-on-watchdog MPC functionality
brcm80211: smac: removed down-on-rf-kill functionality
brcm80211: smac: bugfix for tx mute in brcms_b_init()
brcm80211: smac: fixed inconsistency in transmit mute
brcm80211: smac: modified Mac80211 callback interface
brcm80211: smac: mute transmit on ops_start
brcm80211: smac: changed check to confirm STA only support
drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 5 +-
.../net/wireless/brcm80211/brcmfmac/dhd_common.c | 5 +-
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 301 +++++++-------------
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 15 +-
drivers/net/wireless/brcm80211/brcmsmac/dma.c | 38 ++-
drivers/net/wireless/brcm80211/brcmsmac/dma.h | 3 +-
.../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 100 +++----
.../net/wireless/brcm80211/brcmsmac/mac80211_if.h | 1 +
drivers/net/wireless/brcm80211/brcmsmac/main.c | 219 ++------------
drivers/net/wireless/brcm80211/brcmsmac/main.h | 11 -
drivers/net/wireless/brcm80211/brcmsmac/pub.h | 4 +-
drivers/net/wireless/brcm80211/brcmsmac/srom.c | 33 +--
drivers/net/wireless/brcm80211/include/defs.h | 1 -
13 files changed, 232 insertions(+), 504 deletions(-)
--
1.7.4.1
^ permalink raw reply
* [PATCH 06/17] brcm80211: smac: removed down-on-rf-kill functionality
From: Arend van Spriel @ 2011-10-21 13:55 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Roland Vossen, Arend van Spriel
In-Reply-To: <1319205319-16891-1-git-send-email-arend@broadcom.com>
From: Roland Vossen <rvossen@broadcom.com>
Softmac would bring its interface down on an RF kill switch condition,
without Mac80211 intervention. Because Mac80211 should be the only party
initiating interfaces going up and down, this functionality has been
removed.
Signed-off-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Alwin Beukers <alwin@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
.../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 2 -
drivers/net/wireless/brcm80211/brcmsmac/main.c | 67 --------------------
drivers/net/wireless/brcm80211/brcmsmac/pub.h | 1 -
3 files changed, 0 insertions(+), 70 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index fe8f1ec..915b741 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -1078,8 +1078,6 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device,
wl->pub->ieee_hw = hw;
- brcms_c_set_radio_mon(wl->wlc);
-
/* register our interrupt handler */
if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index d185eed..2fecf06 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -4194,17 +4194,6 @@ static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend)
}
}
-/* maintain LED behavior in down state */
-static void brcms_c_down_led_upd(struct brcms_c_info *wlc)
-{
- /*
- * maintain LEDs while in down state, turn on sbclk if
- * not available yet. Turn on sbclk if necessary
- */
- brcms_b_pllreq(wlc->hw, true, BRCMS_PLLREQ_FLIP);
- brcms_b_pllreq(wlc->hw, false, BRCMS_PLLREQ_FLIP);
-}
-
static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc)
{
/* Don't start the timer if HWRADIO feature is disabled */
@@ -4216,28 +4205,6 @@ static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc)
brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true);
}
-static void brcms_c_radio_disable(struct brcms_c_info *wlc)
-{
- if (!wlc->pub->up) {
- brcms_c_down_led_upd(wlc);
- return;
- }
-
- brcms_c_radio_monitor_start(wlc);
- brcms_down(wlc->wl);
-}
-
-static void brcms_c_radio_enable(struct brcms_c_info *wlc)
-{
- if (wlc->pub->up)
- return;
-
- if (brcms_deviceremoved(wlc))
- return;
-
- brcms_up(wlc->wl);
-}
-
static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc)
{
if (!wlc->radio_monitor)
@@ -4260,18 +4227,6 @@ static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc)
mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE);
}
-/*
- * centralized radio disable/enable function,
- * invoke radio enable/disable after updating hwradio status
- */
-static void brcms_c_radio_upd(struct brcms_c_info *wlc)
-{
- if (wlc->pub->radio_disabled)
- brcms_c_radio_disable(wlc);
- else
- brcms_c_radio_enable(wlc);
-}
-
/* update hwradio status and return it */
bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc)
{
@@ -4294,7 +4249,6 @@ static void brcms_c_radio_timer(void *arg)
}
brcms_c_radio_hwdisable_upd(wlc);
- brcms_c_radio_upd(wlc);
}
/* common low-level watchdog code */
@@ -4320,18 +4274,6 @@ static void brcms_b_watchdog(void *arg)
wlc_phy_watchdog(wlc_hw->band->pi);
}
-static void brcms_c_radio_mon_upd(struct brcms_c_info *wlc)
-{
- /*
- * Stop the radio monitor when the radio is going down.
- */
- if (!wlc->pub->radio_disabled)
- return;
- brcms_c_radio_upd(wlc);
- if (!wlc->pub->radio_disabled)
- brcms_c_radio_monitor_stop(wlc);
-}
-
/* common watchdog code */
static void brcms_c_watchdog(void *arg)
{
@@ -4352,10 +4294,7 @@ static void brcms_c_watchdog(void *arg)
/* increment second count */
wlc->pub->now++;
- brcms_c_radio_mon_upd(wlc);
- /* radio sync: sw/hw --> radio_disable/radio_enable */
brcms_c_radio_hwdisable_upd(wlc);
- brcms_c_radio_upd(wlc);
/* if radio is disable, driver may be down, quit here */
if (wlc->pub->radio_disabled)
return;
@@ -8104,11 +8043,6 @@ int brcms_c_get_tx_power(struct brcms_c_info *wlc)
return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR);
}
-void brcms_c_set_radio_mon(struct brcms_c_info *wlc)
-{
- brcms_c_radio_mon_upd(wlc);
-}
-
/* Process received frames */
/*
* Return true if more frames need to be processed. false otherwise.
@@ -8600,7 +8534,6 @@ brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit,
brcms_c_ht_update_sgi_rx(wlc, 0);
}
- brcms_c_radio_mon_upd(wlc);
brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail);
if (perr)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index 4f8e859..97b9cce 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -596,7 +596,6 @@ extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc,
u8 interval);
extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
-extern void brcms_c_set_radio_mon(struct brcms_c_info *wlc);
extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
#endif /* _BRCM_PUB_H_ */
--
1.7.4.1
^ permalink raw reply related
* [PATCH 07/17] brcm80211: smac: bugfix for tx mute in brcms_b_init()
From: Arend van Spriel @ 2011-10-21 13:55 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Roland Vossen, Arend van Spriel
In-Reply-To: <1319205319-16891-1-git-send-email-arend@broadcom.com>
From: Roland Vossen <rvossen@broadcom.com>
Transmit can only be muted if the mac core is enabled. When brcms_b_init()
is called, the mac core is suspended. Brcms_b_init() calls a transmit mute
function that requires an enabled mac core. This code path is never taken,
but would have been taken in subsequent patches.
Signed-off-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Alwin Beukers <alwin@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmsmac/main.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 2fecf06..8eb665e 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -2452,6 +2452,7 @@ static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw,
}
}
+/* precondition: requires the mac core to be enabled */
static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, u32 flags)
{
static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
@@ -3354,8 +3355,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc)
}
void
-static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec,
- bool mute) {
+static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) {
u32 macintmask;
bool fastclk;
struct brcms_c_info *wlc = wlc_hw->wlc;
@@ -3380,10 +3380,6 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec,
/* core-specific initialization */
brcms_b_coreinit(wlc);
- /* suspend the tx fifos and mute the phy for preism cac time */
- if (mute)
- brcms_b_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM);
-
/* band-specific inits */
brcms_b_bsinit(wlc, chanspec);
@@ -8261,7 +8257,7 @@ void brcms_c_init(struct brcms_c_info *wlc)
{
struct d11regs __iomem *regs;
u16 chanspec;
- bool mute = false;
+ bool mute_tx = false;
BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
@@ -8277,7 +8273,7 @@ void brcms_c_init(struct brcms_c_info *wlc)
else
chanspec = brcms_c_init_chanspec(wlc);
- brcms_b_init(wlc->hw, chanspec, mute);
+ brcms_b_init(wlc->hw, chanspec);
/* update beacon listen interval */
brcms_c_bcn_li_upd(wlc);
@@ -8343,6 +8339,10 @@ void brcms_c_init(struct brcms_c_info *wlc)
/* ..now really unleash hell (allow the MAC out of suspend) */
brcms_c_enable_mac(wlc);
+ /* suspend the tx fifos and mute the phy for preism cac time */
+ if (mute_tx)
+ brcms_b_mute(wlc->hw, ON, PHY_MUTE_FOR_PREISM);
+
/* clear tx flow control */
brcms_c_txflowcontrol_reset(wlc);
--
1.7.4.1
^ permalink raw reply related
* [PATCH 05/17] brcm80211: smac: removed down-on-watchdog MPC functionality
From: Arend van Spriel @ 2011-10-21 13:55 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Roland Vossen, Arend van Spriel
In-Reply-To: <1319205319-16891-1-git-send-email-arend@broadcom.com>
From: Roland Vossen <rvossen@broadcom.com>
Softmac would bring its interface down on a certain Minimum Power Save
related condition, without Mac80211 intervention. Because Mac80211 should
be the only party initiating interfaces going up and down, this functionality
has been removed. All notions of 'MPC' have been removed in the code as
well.
Signed-off-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Alwin Beukers <alwin@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
.../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 3 +-
drivers/net/wireless/brcm80211/brcmsmac/main.c | 45 +++----------------
drivers/net/wireless/brcm80211/brcmsmac/main.h | 3 -
drivers/net/wireless/brcm80211/brcmsmac/pub.h | 2 +-
drivers/net/wireless/brcm80211/include/defs.h | 1 -
5 files changed, 9 insertions(+), 45 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 1781157..fe8f1ec 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -1078,8 +1078,7 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device,
wl->pub->ieee_hw = hw;
- /* disable mpc */
- brcms_c_set_radio_mpc(wl->wlc);
+ brcms_c_set_radio_mon(wl->wlc);
/* register our interrupt handler */
if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index e7d14e4..d185eed 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -43,16 +43,6 @@
/* radio monitor timer, in unit of ms */
#define TIMER_INTERVAL_RADIOCHK 800
-/* Max MPC timeout, in unit of watchdog */
-#ifndef BRCMS_MPC_MAX_DELAYCNT
-#define BRCMS_MPC_MAX_DELAYCNT 10
-#endif
-
-/* Min MPC timeout, in unit of watchdog */
-#define BRCMS_MPC_MIN_DELAYCNT 1
-/* MPC count threshold level */
-#define BRCMS_MPC_THRESHOLD 3
-
/* beacon interval, in unit of 1024TU */
#define BEACON_INTERVAL_DEFAULT 100
@@ -4330,17 +4320,13 @@ static void brcms_b_watchdog(void *arg)
wlc_phy_watchdog(wlc_hw->band->pi);
}
-static void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc)
+static void brcms_c_radio_mon_upd(struct brcms_c_info *wlc)
{
/*
- * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled
- * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio
- * monitor also when WL_RADIO_MPC_DISABLE is the only reason that
- * the radio is going down.
+ * Stop the radio monitor when the radio is going down.
*/
if (!wlc->pub->radio_disabled)
return;
- mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE);
brcms_c_radio_upd(wlc);
if (!wlc->pub->radio_disabled)
brcms_c_radio_monitor_stop(wlc);
@@ -4366,17 +4352,8 @@ static void brcms_c_watchdog(void *arg)
/* increment second count */
wlc->pub->now++;
- /* delay radio disable */
- if (wlc->mpc_delay_off) {
- if (--wlc->mpc_delay_off == 0) {
- mboolset(wlc->pub->radio_disabled,
- WL_RADIO_MPC_DISABLE);
- }
- }
-
- /* mpc sync */
- brcms_c_radio_mpc_upd(wlc);
- /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */
+ brcms_c_radio_mon_upd(wlc);
+ /* radio sync: sw/hw --> radio_disable/radio_enable */
brcms_c_radio_hwdisable_upd(wlc);
brcms_c_radio_upd(wlc);
/* if radio is disable, driver may be down, quit here */
@@ -4482,9 +4459,6 @@ static void brcms_c_info_init(struct brcms_c_info *wlc, int unit)
/* WME QoS mode is Auto by default */
wlc->pub->_ampdu = AMPDU_AGG_HOST;
wlc->pub->bcmerror = 0;
-
- /* initialize mpc delay */
- wlc->mpc_delay_off = BRCMS_MPC_MIN_DELAYCNT;
}
static uint brcms_c_attach_module(struct brcms_c_info *wlc)
@@ -5455,7 +5429,6 @@ uint brcms_c_down(struct brcms_c_info *wlc)
if (!wlc->pub->up)
return callbacks;
- /* in between, mpc could try to bring down again.. */
wlc->going_down = true;
callbacks += brcms_b_bmac_down_prep(wlc->hw);
@@ -8131,9 +8104,9 @@ int brcms_c_get_tx_power(struct brcms_c_info *wlc)
return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR);
}
-void brcms_c_set_radio_mpc(struct brcms_c_info *wlc)
+void brcms_c_set_radio_mon(struct brcms_c_info *wlc)
{
- brcms_c_radio_mpc_upd(wlc);
+ brcms_c_radio_mon_upd(wlc);
}
/* Process received frames */
@@ -8442,9 +8415,6 @@ void brcms_c_init(struct brcms_c_info *wlc)
/* enable the RF Disable Delay timer */
W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT);
- /* initialize mpc delay */
- wlc->mpc_delay_off = BRCMS_MPC_MIN_DELAYCNT;
-
/*
* Initialize WME parameters; if they haven't been set by some other
* mechanism (IOVar, etc) then read them from the hardware.
@@ -8630,8 +8600,7 @@ brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit,
brcms_c_ht_update_sgi_rx(wlc, 0);
}
- /* initialize radio_mpc_disable according to wlc->mpc */
- brcms_c_radio_mpc_upd(wlc);
+ brcms_c_radio_mon_upd(wlc);
brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail);
if (perr)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
index fc5852f..9a7535d 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
@@ -427,7 +427,6 @@ struct brcms_txq_info {
* bandinit_pending: track band init in auto band.
* radio_monitor: radio timer is running.
* going_down: down path intermediate variable.
- * mpc_delay_off: delay radio disable by # of watchdog cnt.
* wdtimer: timer for watchdog routine.
* radio_timer: timer for hw radio button monitor routine.
* monitor: monitor (MPDU sniffing) mode.
@@ -518,8 +517,6 @@ struct brcms_c_info {
bool radio_monitor;
bool going_down;
- u8 mpc_delay_off;
-
struct brcms_timer *wdtimer;
struct brcms_timer *radio_timer;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index 2e09216..4f8e859 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -596,7 +596,7 @@ extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc,
u8 interval);
extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr);
extern int brcms_c_get_tx_power(struct brcms_c_info *wlc);
-extern void brcms_c_set_radio_mpc(struct brcms_c_info *wlc);
+extern void brcms_c_set_radio_mon(struct brcms_c_info *wlc);
extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc);
#endif /* _BRCM_PUB_H_ */
diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h
index 1e5f310..f0d8c04 100644
--- a/drivers/net/wireless/brcm80211/include/defs.h
+++ b/drivers/net/wireless/brcm80211/include/defs.h
@@ -62,7 +62,6 @@
#define WL_RADIO_SW_DISABLE (1<<0)
#define WL_RADIO_HW_DISABLE (1<<1)
-#define WL_RADIO_MPC_DISABLE (1<<2)
/* some countries don't support any channel */
#define WL_RADIO_COUNTRY_DISABLE (1<<3)
--
1.7.4.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox