* Re: [PATCH] RFC: Universal scan proposal
From: Arend Van Spriel @ 2016-12-07 20:51 UTC (permalink / raw)
To: Dmitry Shmidt, Johannes Berg; +Cc: linux-wireless
In-Reply-To: <CAH7ZN-wP+9AGrXFUS4RY65-RyfP-J46svBvLdytP2c=QPtiaug@mail.gmail.com>
On 7-12-2016 19:39, Dmitry Shmidt wrote:
> On Tue, Dec 6, 2016 at 10:44 PM, Johannes Berg
> <johannes@sipsolutions.net> wrote:
>>
>>> Indeed, results are results. I just want to take care of two things:
>>> 1) Memory consumption - we can clear stale scan results for
>>> connection, but not for location if we are using history scan.
>>
>> Well eventually we also have to clear for location if we run out of
>> memory, that usually means dumping them out to the host, no?
>
> Being out of memory and consuming more memory are different
> things, but I agree - maybe we don't need to worry about it.
>
>>> 2) Use of insufficient results for connection - in case we had
>>> history or hotlist scan only for very limited amount of channels,
>>> then we may not have enough APs in our result for "sterling"
>>> connection decision.
>>
>> I'm not entirely sure about this case - surely noticing "we can do
>> better now" is still better than waiting for being able to make the
>> perfect decision?
>
> Maybe we can just keep flag saying that currently available results
> were not received by usual full scan.
>
>>>>> Report: none / batch / immediate
>>>>
>>>> Not sure I see much point in "none"??
>>>>
>>>> Can you define these more clearly? Do you think "batch" reporting
>>>> should be like the gscan buckets? Or actually have full
>>>> information?
>>>
>>> None - means that there is not need to report. It can be useful
>>> in case of roaming scan, scheduling or hotlist scan - you didn't find
>>> anything suitable - don't report that there is no scan results.
>>
>> But that seems more of a filtering thing, combined with "immediate" for
>> anything passing the filter?
>
> We can use this approach as well.
>
>>>>> Request may have priority and can be inserted into
>>>>> the head of the queue.
>>>>> Types of scans:
>>>>> - Normal scan
>>>>> - Scheduled scan
>>>>> - Hotlist (BSSID scan)
>>>>> - Roaming
>>>>> - AutoJoin
>>>>
>>>> I think somebody else said this but I didn't find it now - I think
>>>> this would make more sense to define in terms of expected behaviour
>>>> than use cases for each type of scan.
>>>
>>> I think Luca made this statement.
>>
>> Yeah - I just couldn't find it again on re-reading the thread :)
>>
>>> It is totally ok from SW point of
>>> view - especially due to the fact that scan is scan. However,
>>> I suspect it will be harder to handle from user experience. I mean
>>> at the end wireless framework / driver / FW will convert special
>>> scan type to usual scan with special params and response, but why
>>> to put this burden on user?
I don't think this will put burden on the user although it depends
who/what you mean by this. If you mean the mere mortal end-user I would
say no as indeed there must be some software entity (in user-space) that
will have to initiate a nl80211 command with appropriate attributes
according to whatever user-space is trying to accomplish.
>> I just think it's more flexible and open-ended. The actual definition
>> of the resulting parameters needs to be somewhere anyway - putting it
>> into driver/firmware (vs. wifi framework or so) seems to duplicate it
>> and certainly makes it harder to modify/extend in the future, no?
>
> So, let's summarize:
> Instead of creating new type of generic scan with special types,
> we want to go with additional expansion of scheduled scan options and
> parameters (in order not to "multiply entities"), including ability to send
> new scheduled scan request without stopping previous one.
>
> Is it Ok?
Sounds ok. To me a generic scan command with type attribute is
equivalent to having seperate commands for each type so there seems to
be no gain. Now whether this all can be accomplished by extending the
scheduled scan depends on the problem that you are trying to solve.
Main purpose seems to be offloading different scanning tasks which could
make scheduled scan a good candidate. Now I want to add gscan to this
mix as it seems some concepts for that are in play in this discussion as
well, eg. hotlist. gscan is like scheduled scan, but it supports
multiple schedules. However, it is still a single request from a single
user-space process. I think Luca mentioned supporting requests from
different user-space processes. Is that also what you mean by "ability
to send new scheduled scan request without stopping previous one" or is
that still from a single user-space process. Do we need a limit to the
amount of scheduled scan requests that can be handled simultaneously.
A maybe more important aspect of gscan is user-space control of result
reporting and thus the frequency of waking up host and/or user-space. I
suspect this would be needed in the scheduled scan extension as well, right?
Regards,
Arend
^ permalink raw reply
* [PATCH] ath10k: fix incorrect txpower set by P2P_DEVICE interface
From: ryanhsu @ 2016-12-07 21:45 UTC (permalink / raw)
To: ath10k, linux-wireless; +Cc: ryanhsu
From: Ryan Hsu <ryanhsu@qca.qualcomm.com>
Ath10k reports the phy capability that upports P2P_DEVICE interface.
When we use the P2P supported wpa_supplicant to start connection, it'll
create the two interfaces, one is wlan0 (vdev_id=0) and one is P2P_DEVICE
p2p-dev-wlan0 which is for p2p control channel (vdev_id=1).
ath10k_pci mac vdev create 0 (add interface) type 2 subtype 0
ath10k_add_interface: vdev_id: 0, txpower: 0, bss_power: 0
...
ath10k_pci mac vdev create 1 (add interface) type 2 subtype 1
ath10k_add_interface: vdev_id: 1, txpower: 0, bss_power: 0
And the txpower in per vif bss_conf will only be set to valid tx power when
the interface is assigned with channel_ctx.
But this P2P_DEVICE interface will never be used for any connection, so
that the uninitialized bss_conf.txpower=0 is assinged to the
arvif->txpower when interface created.
Since the txpower configuration is per phy interface.
So the smallest txpower of all vifs will be the one limit the tx power
of the phyical device, that causing the low txpower issue on other
active interfaces.
wlan0: Limiting TX power to 21 (24 - 3) dBm
ath10k_pci mac vdev_id 0 txpower 21
ath10k_mac_txpower_recalc: vdev_id: 1, txpower: 0
ath10k_mac_txpower_recalc: vdev_id: 0, txpower: 21
ath10k_pci mac txpower 0
This issue only happens when we use the wpa_supplicant that supports
P2P or if we use the iw tool to create the control P2P_DEVICE interface.
Signed-off-by: Ryan Hsu <ryanhsu@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath10k/mac.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index fe42bf5..6e1550b 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4671,7 +4671,8 @@ static int ath10k_mac_txpower_recalc(struct ath10k *ar)
lockdep_assert_held(&ar->conf_mutex);
list_for_each_entry(arvif, &ar->arvifs, list) {
- WARN_ON(arvif->txpower < 0);
+ if (arvif->txpower <= 0)
+ continue;
if (txpower == -1)
txpower = arvif->txpower;
@@ -4679,8 +4680,8 @@ static int ath10k_mac_txpower_recalc(struct ath10k *ar)
txpower = min(txpower, arvif->txpower);
}
- if (WARN_ON(txpower == -1))
- return -EINVAL;
+ if (txpower == -1)
+ return 0;
ret = ath10k_mac_txpower_setup(ar, txpower);
if (ret) {
--
1.9.1
^ permalink raw reply related
* [PATCH 1/1] orinoco: fix improper return value
From: Pan Bian @ 2016-12-08 0:40 UTC (permalink / raw)
To: Kalle Valo, linux-wireless, netdev; +Cc: linux-kernel, Pan Bian
Function orinoco_ioctl_commit() returns 0 (indicates success) when the
call to orinoco_lock() fails. Thus, the return value is inconsistent with
the execution status. It may be better to return "-EBUSY" when the call
to orinoco_lock() fails.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=188671
Signed-off-by: Pan Bian <bianpan2016@163.com>
---
drivers/net/wireless/intersil/orinoco/wext.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intersil/orinoco/wext.c b/drivers/net/wireless/intersil/orinoco/wext.c
index 1d4dae4..fee57ea 100644
--- a/drivers/net/wireless/intersil/orinoco/wext.c
+++ b/drivers/net/wireless/intersil/orinoco/wext.c
@@ -1314,7 +1314,7 @@ static int orinoco_ioctl_commit(struct net_device *dev,
return 0;
if (orinoco_lock(priv, &flags) != 0)
- return err;
+ return -EBUSY;
err = orinoco_commit(priv);
--
1.9.1
^ permalink raw reply related
* Ralink Rt3290
From: Abhiroop Dabral @ 2016-12-08 1:10 UTC (permalink / raw)
To: linux-wireless
Hi,
I am working on porting of Ralinks rt3290 wireless adapter.
Is there any resource like specification manual or programming guide
which explains the register space of the chip?
I will really appreciate if anyone can direct me to a resource like this.
Kins regards,
Abhiroop
^ permalink raw reply
* [PATCH v2 2/2] mac80211: Use appropriate name for functions and messages
From: Masashi Honma @ 2016-12-08 1:15 UTC (permalink / raw)
To: johannes, me; +Cc: linux-wireless, Masashi Honma
In-Reply-To: <1481159751-4097-1-git-send-email-masashi.honma@gmail.com>
These functions drifts TSF timers, not TBTT.
Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
---
net/mac80211/ieee80211_i.h | 4 ++--
net/mac80211/mesh.c | 2 +-
net/mac80211/mesh.h | 2 +-
net/mac80211/mesh_sync.c | 16 ++++++++--------
net/mac80211/tx.c | 2 +-
5 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d37a577..94b2c9e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -624,8 +624,8 @@ struct ieee80211_mesh_sync_ops {
struct ieee80211_rx_status *rx_status);
/* should be called with beacon_data under RCU read lock */
- void (*adjust_tbtt)(struct ieee80211_sub_if_data *sdata,
- struct beacon_data *beacon);
+ void (*adjust_tsf)(struct ieee80211_sub_if_data *sdata,
+ struct beacon_data *beacon);
/* add other framework functions here */
};
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 42120d9..a6b43e4 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1349,7 +1349,7 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
ieee80211_mesh_rootpath(sdata);
if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags))
- mesh_sync_adjust_tbtt(sdata);
+ mesh_sync_adjust_tsf(sdata);
if (test_and_clear_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags))
mesh_bss_info_changed(sdata);
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 26b9ccb..7e5f271 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -341,7 +341,7 @@ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
}
void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
-void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata);
+void mesh_sync_adjust_tsf(struct ieee80211_sub_if_data *sdata);
void ieee80211s_stop(void);
#else
static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c
index 75608c0..a435f09 100644
--- a/net/mac80211/mesh_sync.c
+++ b/net/mac80211/mesh_sync.c
@@ -12,7 +12,7 @@
#include "mesh.h"
#include "driver-ops.h"
-/* This is not in the standard. It represents a tolerable tbtt drift below
+/* This is not in the standard. It represents a tolerable tsf drift below
* which we do no TSF adjustment.
*/
#define TOFFSET_MINIMUM_ADJUSTMENT 10
@@ -46,7 +46,7 @@ static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie)
IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING) != 0;
}
-void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
+void mesh_sync_adjust_tsf(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
@@ -57,12 +57,12 @@ void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
spin_lock_bh(&ifmsh->sync_offset_lock);
if (ifmsh->sync_offset_clockdrift_max < beacon_int_fraction) {
- msync_dbg(sdata, "TBTT : max clockdrift=%lld; adjusting\n",
+ msync_dbg(sdata, "TSF : max clockdrift=%lld; adjusting\n",
(long long) ifmsh->sync_offset_clockdrift_max);
tsfdelta = -ifmsh->sync_offset_clockdrift_max;
ifmsh->sync_offset_clockdrift_max = 0;
} else {
- msync_dbg(sdata, "TBTT : max clockdrift=%lld; adjusting by %llu\n",
+ msync_dbg(sdata, "TSF : max clockdrift=%lld; adjusting by %llu\n",
(long long) ifmsh->sync_offset_clockdrift_max,
(unsigned long long) beacon_int_fraction);
tsfdelta = -beacon_int_fraction;
@@ -167,7 +167,7 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
rcu_read_unlock();
}
-static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata,
+static void mesh_sync_offset_adjust_tsf(struct ieee80211_sub_if_data *sdata,
struct beacon_data *beacon)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
@@ -184,12 +184,12 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata,
* the tsf adjustment to the mesh tasklet
*/
msync_dbg(sdata,
- "TBTT : kicking off TBTT adjustment with clockdrift_max=%lld\n",
+ "TSF : kicking off TSF adjustment with clockdrift_max=%lld\n",
ifmsh->sync_offset_clockdrift_max);
set_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags);
} else {
msync_dbg(sdata,
- "TBTT : max clockdrift=%lld; too small to adjust\n",
+ "TSF : max clockdrift=%lld; too small to adjust\n",
(long long)ifmsh->sync_offset_clockdrift_max);
ifmsh->sync_offset_clockdrift_max = 0;
}
@@ -201,7 +201,7 @@ static const struct sync_method sync_methods[] = {
.method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET,
.ops = {
.rx_bcn_presp = &mesh_sync_offset_rx_bcn_presp,
- .adjust_tbtt = &mesh_sync_offset_adjust_tbtt,
+ .adjust_tsf = &mesh_sync_offset_adjust_tsf,
}
},
};
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 2c21b70..874332d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -4076,7 +4076,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
}
if (ifmsh->sync_ops)
- ifmsh->sync_ops->adjust_tbtt(sdata, beacon);
+ ifmsh->sync_ops->adjust_tsf(sdata, beacon);
skb = dev_alloc_skb(local->tx_headroom +
beacon->head_len +
--
2.7.4
^ permalink raw reply related
* [PATCH v2 1/2] mac80211: Remove invalid flag operations in mesh TSF synchronization
From: Masashi Honma @ 2016-12-08 1:15 UTC (permalink / raw)
To: johannes, me; +Cc: linux-wireless, Masashi Honma
In-Reply-To: <1480545889-3690-1-git-send-email-masashi.honma@gmail.com>
mesh_sync_offset_adjust_tbtt() implements Extensible synchronization
framework ([1] 13.13.2 Extensible synchronization framework). It shall
not operate the flag "TBTT Adjusting subfield" ([1] 8.4.2.100.8 Mesh
Capability), since it is used only for MBCA ([1] 13.13.4 Mesh beacon
collision avoidance, see 13.13.4.4.3 TBTT scanning and adjustment
procedures for detail). So this patch remove the flag operations.
[1] IEEE Std 802.11 2012
Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
---
net/mac80211/mesh_sync.c | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c
index faca22c..75608c0 100644
--- a/net/mac80211/mesh_sync.c
+++ b/net/mac80211/mesh_sync.c
@@ -123,7 +123,6 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
*/
if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) {
- clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN);
msync_dbg(sdata, "STA %pM : is adjusting TBTT\n",
sta->sta.addr);
goto no_sync;
@@ -172,11 +171,9 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata,
struct beacon_data *beacon)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
- u8 cap;
WARN_ON(ifmsh->mesh_sp_id != IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET);
WARN_ON(!rcu_read_lock_held());
- cap = beacon->meshconf->meshconf_cap;
spin_lock_bh(&ifmsh->sync_offset_lock);
@@ -190,21 +187,13 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata,
"TBTT : kicking off TBTT adjustment with clockdrift_max=%lld\n",
ifmsh->sync_offset_clockdrift_max);
set_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags);
-
- ifmsh->adjusting_tbtt = true;
} else {
msync_dbg(sdata,
"TBTT : max clockdrift=%lld; too small to adjust\n",
(long long)ifmsh->sync_offset_clockdrift_max);
ifmsh->sync_offset_clockdrift_max = 0;
-
- ifmsh->adjusting_tbtt = false;
}
spin_unlock_bh(&ifmsh->sync_offset_lock);
-
- beacon->meshconf->meshconf_cap = ifmsh->adjusting_tbtt ?
- IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING | cap :
- ~IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING & cap;
}
static const struct sync_method sync_methods[] = {
--
2.7.4
^ permalink raw reply related
* Re: [PATCH] mac80211: Remove invalid flag operations in mesh TSF synchronization
From: Masashi Honma @ 2016-12-08 1:16 UTC (permalink / raw)
To: Bob Copeland; +Cc: Johannes Berg, Thomas Pedersen, linux-wireless
In-Reply-To: <20161207133315.GD7524@localhost>
On 2016年12月07日 22:33, Bob Copeland wrote:
> This mesh_sync_offset_adjust_tbtt is definitely doing offset
> synchronization, so probably "tbtt" should be renamed "tsf" here.
Right. I will send a patch for this.
> Actually, looking at the code now it doesn't make a lot of sense to set
> this flag for offset sync because TOFFSET_KNOWN flag is completely cleared
> whenever that is set, so we have to be forgetting the current t_offset all
> the time?
Right, TOFFSET_KNOWN flag looks not need to be cleared when
TBTT_ADJUSTING flag is on. Because the t_offset is received when
TBTT_ADJUSTING flag is off. The t_offset is expected to have valid
value. I will remove the code by next patch.
Masashi Honma.
^ permalink raw reply
* [PATCH 1/3] rsi: Renamed the file rsi_91x_pkt.c to rsi_91x_hal.c
From: Prameela Rani Garnepudi @ 2016-12-08 5:07 UTC (permalink / raw)
To: linux-wireless
Cc: kvalo, johannes.berg, hofrat, xypron.glpk, prameela.garnepudi,
Prameela Rani Garnepudi
The file 'rsi_91x_hal.c' is going to contain device specific
code like firmware loading etc. As the file 'rsi_91x_pkt.c'
contains code for preparing device (frimware understandable)
specific descriptors for the transmit frames, it is moved to
'rsi_91x_hal.c'
Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
---
drivers/net/wireless/rsi/Makefile | 2 +-
drivers/net/wireless/rsi/rsi_91x_hal.c | 215 +++++++++++++++++++++++++++++++++
drivers/net/wireless/rsi/rsi_91x_pkt.c | 215 ---------------------------------
3 files changed, 216 insertions(+), 216 deletions(-)
create mode 100644 drivers/net/wireless/rsi/rsi_91x_hal.c
delete mode 100644 drivers/net/wireless/rsi/rsi_91x_pkt.c
diff --git a/drivers/net/wireless/rsi/Makefile b/drivers/net/wireless/rsi/Makefile
index 25828b6..a475c81 100644
--- a/drivers/net/wireless/rsi/Makefile
+++ b/drivers/net/wireless/rsi/Makefile
@@ -2,7 +2,7 @@ rsi_91x-y += rsi_91x_main.o
rsi_91x-y += rsi_91x_core.o
rsi_91x-y += rsi_91x_mac80211.o
rsi_91x-y += rsi_91x_mgmt.o
-rsi_91x-y += rsi_91x_pkt.o
+rsi_91x-y += rsi_91x_hal.o
rsi_91x-$(CONFIG_RSI_DEBUGFS) += rsi_91x_debugfs.o
rsi_usb-y += rsi_91x_usb.o rsi_91x_usb_ops.o
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
new file mode 100644
index 0000000..02920c9
--- /dev/null
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -0,0 +1,215 @@
+/**
+ * Copyright (c) 2014 Redpine Signals Inc.
+ *
+ * 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.
+ */
+
+#include "rsi_mgmt.h"
+
+/**
+ * rsi_send_data_pkt() - This function sends the recieved data packet from
+ * driver to device.
+ * @common: Pointer to the driver private structure.
+ * @skb: Pointer to the socket buffer structure.
+ *
+ * Return: status: 0 on success, -1 on failure.
+ */
+int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
+{
+ struct rsi_hw *adapter = common->priv;
+ struct ieee80211_hdr *tmp_hdr;
+ struct ieee80211_tx_info *info;
+ struct skb_info *tx_params;
+ struct ieee80211_bss_conf *bss;
+ int status;
+ u8 ieee80211_size = MIN_802_11_HDR_LEN;
+ u8 extnd_size;
+ __le16 *frame_desc;
+ u16 seq_num;
+
+ info = IEEE80211_SKB_CB(skb);
+ bss = &info->control.vif->bss_conf;
+ tx_params = (struct skb_info *)info->driver_data;
+
+ if (!bss->assoc) {
+ status = -EINVAL;
+ goto err;
+ }
+
+ tmp_hdr = (struct ieee80211_hdr *)&skb->data[0];
+ seq_num = (le16_to_cpu(tmp_hdr->seq_ctrl) >> 4);
+
+ extnd_size = ((uintptr_t)skb->data & 0x3);
+
+ if ((FRAME_DESC_SZ + extnd_size) > skb_headroom(skb)) {
+ rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
+ status = -ENOSPC;
+ goto err;
+ }
+
+ skb_push(skb, (FRAME_DESC_SZ + extnd_size));
+ frame_desc = (__le16 *)&skb->data[0];
+ memset((u8 *)frame_desc, 0, FRAME_DESC_SZ);
+
+ if (ieee80211_is_data_qos(tmp_hdr->frame_control)) {
+ ieee80211_size += 2;
+ frame_desc[6] |= cpu_to_le16(BIT(12));
+ }
+
+ if ((!(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) &&
+ (common->secinfo.security_enable)) {
+ if (rsi_is_cipher_wep(common))
+ ieee80211_size += 4;
+ else
+ ieee80211_size += 8;
+ frame_desc[6] |= cpu_to_le16(BIT(15));
+ }
+
+ frame_desc[0] = cpu_to_le16((skb->len - FRAME_DESC_SZ) |
+ (RSI_WIFI_DATA_Q << 12));
+ frame_desc[2] = cpu_to_le16((extnd_size) | (ieee80211_size) << 8);
+
+ if (common->min_rate != 0xffff) {
+ /* Send fixed rate */
+ frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE);
+ frame_desc[4] = cpu_to_le16(common->min_rate);
+
+ if (conf_is_ht40(&common->priv->hw->conf))
+ frame_desc[5] = cpu_to_le16(FULL40M_ENABLE);
+
+ if (common->vif_info[0].sgi) {
+ if (common->min_rate & 0x100) /* Only MCS rates */
+ frame_desc[4] |=
+ cpu_to_le16(ENABLE_SHORTGI_RATE);
+ }
+
+ }
+
+ frame_desc[6] |= cpu_to_le16(seq_num & 0xfff);
+ frame_desc[7] = cpu_to_le16(((tx_params->tid & 0xf) << 4) |
+ (skb->priority & 0xf) |
+ (tx_params->sta_id << 8));
+
+ status = adapter->host_intf_write_pkt(common->priv,
+ skb->data,
+ skb->len);
+ if (status)
+ rsi_dbg(ERR_ZONE, "%s: Failed to write pkt\n",
+ __func__);
+
+err:
+ ++common->tx_stats.total_tx_pkt_freed[skb->priority];
+ rsi_indicate_tx_status(common->priv, skb, status);
+ return status;
+}
+
+/**
+ * rsi_send_mgmt_pkt() - This functions sends the received management packet
+ * from driver to device.
+ * @common: Pointer to the driver private structure.
+ * @skb: Pointer to the socket buffer structure.
+ *
+ * Return: status: 0 on success, -1 on failure.
+ */
+int rsi_send_mgmt_pkt(struct rsi_common *common,
+ struct sk_buff *skb)
+{
+ struct rsi_hw *adapter = common->priv;
+ struct ieee80211_hdr *wh;
+ struct ieee80211_tx_info *info;
+ struct ieee80211_bss_conf *bss;
+ struct ieee80211_hw *hw = adapter->hw;
+ struct ieee80211_conf *conf = &hw->conf;
+ struct skb_info *tx_params;
+ int status = -E2BIG;
+ __le16 *msg;
+ u8 extnd_size;
+ u8 vap_id = 0;
+
+ info = IEEE80211_SKB_CB(skb);
+ tx_params = (struct skb_info *)info->driver_data;
+ extnd_size = ((uintptr_t)skb->data & 0x3);
+
+ if (tx_params->flags & INTERNAL_MGMT_PKT) {
+ if ((extnd_size) > skb_headroom(skb)) {
+ rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
+ dev_kfree_skb(skb);
+ return -ENOSPC;
+ }
+ skb_push(skb, extnd_size);
+ skb->data[extnd_size + 4] = extnd_size;
+ status = adapter->host_intf_write_pkt(common->priv,
+ (u8 *)skb->data,
+ skb->len);
+ if (status) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Failed to write the packet\n", __func__);
+ }
+ dev_kfree_skb(skb);
+ return status;
+ }
+
+ bss = &info->control.vif->bss_conf;
+ wh = (struct ieee80211_hdr *)&skb->data[0];
+
+ if (FRAME_DESC_SZ > skb_headroom(skb))
+ goto err;
+
+ skb_push(skb, FRAME_DESC_SZ);
+ memset(skb->data, 0, FRAME_DESC_SZ);
+ msg = (__le16 *)skb->data;
+
+ if (skb->len > MAX_MGMT_PKT_SIZE) {
+ rsi_dbg(INFO_ZONE, "%s: Dropping mgmt pkt > 512\n", __func__);
+ goto err;
+ }
+
+ msg[0] = cpu_to_le16((skb->len - FRAME_DESC_SZ) |
+ (RSI_WIFI_MGMT_Q << 12));
+ msg[1] = cpu_to_le16(TX_DOT11_MGMT);
+ msg[2] = cpu_to_le16(MIN_802_11_HDR_LEN << 8);
+ msg[3] = cpu_to_le16(RATE_INFO_ENABLE);
+ msg[6] = cpu_to_le16(le16_to_cpu(wh->seq_ctrl) >> 4);
+
+ if (wh->addr1[0] & BIT(0))
+ msg[3] |= cpu_to_le16(RSI_BROADCAST_PKT);
+
+ if (common->band == NL80211_BAND_2GHZ)
+ msg[4] = cpu_to_le16(RSI_11B_MODE);
+ else
+ msg[4] = cpu_to_le16((RSI_RATE_6 & 0x0f) | RSI_11G_MODE);
+
+ if (conf_is_ht40(conf)) {
+ msg[4] = cpu_to_le16(0xB | RSI_11G_MODE);
+ msg[5] = cpu_to_le16(0x6);
+ }
+
+ /* Indicate to firmware to give cfm */
+ if ((skb->data[16] == IEEE80211_STYPE_PROBE_REQ) && (!bss->assoc)) {
+ msg[1] |= cpu_to_le16(BIT(10));
+ msg[7] = cpu_to_le16(PROBEREQ_CONFIRM);
+ common->mgmt_q_block = true;
+ }
+
+ msg[7] |= cpu_to_le16(vap_id << 8);
+
+ status = adapter->host_intf_write_pkt(common->priv,
+ (u8 *)msg,
+ skb->len);
+ if (status)
+ rsi_dbg(ERR_ZONE, "%s: Failed to write the packet\n", __func__);
+
+err:
+ rsi_indicate_tx_status(common->priv, skb, status);
+ return status;
+}
diff --git a/drivers/net/wireless/rsi/rsi_91x_pkt.c b/drivers/net/wireless/rsi/rsi_91x_pkt.c
deleted file mode 100644
index 02920c9..0000000
--- a/drivers/net/wireless/rsi/rsi_91x_pkt.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/**
- * Copyright (c) 2014 Redpine Signals Inc.
- *
- * 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.
- */
-
-#include "rsi_mgmt.h"
-
-/**
- * rsi_send_data_pkt() - This function sends the recieved data packet from
- * driver to device.
- * @common: Pointer to the driver private structure.
- * @skb: Pointer to the socket buffer structure.
- *
- * Return: status: 0 on success, -1 on failure.
- */
-int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
-{
- struct rsi_hw *adapter = common->priv;
- struct ieee80211_hdr *tmp_hdr;
- struct ieee80211_tx_info *info;
- struct skb_info *tx_params;
- struct ieee80211_bss_conf *bss;
- int status;
- u8 ieee80211_size = MIN_802_11_HDR_LEN;
- u8 extnd_size;
- __le16 *frame_desc;
- u16 seq_num;
-
- info = IEEE80211_SKB_CB(skb);
- bss = &info->control.vif->bss_conf;
- tx_params = (struct skb_info *)info->driver_data;
-
- if (!bss->assoc) {
- status = -EINVAL;
- goto err;
- }
-
- tmp_hdr = (struct ieee80211_hdr *)&skb->data[0];
- seq_num = (le16_to_cpu(tmp_hdr->seq_ctrl) >> 4);
-
- extnd_size = ((uintptr_t)skb->data & 0x3);
-
- if ((FRAME_DESC_SZ + extnd_size) > skb_headroom(skb)) {
- rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
- status = -ENOSPC;
- goto err;
- }
-
- skb_push(skb, (FRAME_DESC_SZ + extnd_size));
- frame_desc = (__le16 *)&skb->data[0];
- memset((u8 *)frame_desc, 0, FRAME_DESC_SZ);
-
- if (ieee80211_is_data_qos(tmp_hdr->frame_control)) {
- ieee80211_size += 2;
- frame_desc[6] |= cpu_to_le16(BIT(12));
- }
-
- if ((!(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) &&
- (common->secinfo.security_enable)) {
- if (rsi_is_cipher_wep(common))
- ieee80211_size += 4;
- else
- ieee80211_size += 8;
- frame_desc[6] |= cpu_to_le16(BIT(15));
- }
-
- frame_desc[0] = cpu_to_le16((skb->len - FRAME_DESC_SZ) |
- (RSI_WIFI_DATA_Q << 12));
- frame_desc[2] = cpu_to_le16((extnd_size) | (ieee80211_size) << 8);
-
- if (common->min_rate != 0xffff) {
- /* Send fixed rate */
- frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE);
- frame_desc[4] = cpu_to_le16(common->min_rate);
-
- if (conf_is_ht40(&common->priv->hw->conf))
- frame_desc[5] = cpu_to_le16(FULL40M_ENABLE);
-
- if (common->vif_info[0].sgi) {
- if (common->min_rate & 0x100) /* Only MCS rates */
- frame_desc[4] |=
- cpu_to_le16(ENABLE_SHORTGI_RATE);
- }
-
- }
-
- frame_desc[6] |= cpu_to_le16(seq_num & 0xfff);
- frame_desc[7] = cpu_to_le16(((tx_params->tid & 0xf) << 4) |
- (skb->priority & 0xf) |
- (tx_params->sta_id << 8));
-
- status = adapter->host_intf_write_pkt(common->priv,
- skb->data,
- skb->len);
- if (status)
- rsi_dbg(ERR_ZONE, "%s: Failed to write pkt\n",
- __func__);
-
-err:
- ++common->tx_stats.total_tx_pkt_freed[skb->priority];
- rsi_indicate_tx_status(common->priv, skb, status);
- return status;
-}
-
-/**
- * rsi_send_mgmt_pkt() - This functions sends the received management packet
- * from driver to device.
- * @common: Pointer to the driver private structure.
- * @skb: Pointer to the socket buffer structure.
- *
- * Return: status: 0 on success, -1 on failure.
- */
-int rsi_send_mgmt_pkt(struct rsi_common *common,
- struct sk_buff *skb)
-{
- struct rsi_hw *adapter = common->priv;
- struct ieee80211_hdr *wh;
- struct ieee80211_tx_info *info;
- struct ieee80211_bss_conf *bss;
- struct ieee80211_hw *hw = adapter->hw;
- struct ieee80211_conf *conf = &hw->conf;
- struct skb_info *tx_params;
- int status = -E2BIG;
- __le16 *msg;
- u8 extnd_size;
- u8 vap_id = 0;
-
- info = IEEE80211_SKB_CB(skb);
- tx_params = (struct skb_info *)info->driver_data;
- extnd_size = ((uintptr_t)skb->data & 0x3);
-
- if (tx_params->flags & INTERNAL_MGMT_PKT) {
- if ((extnd_size) > skb_headroom(skb)) {
- rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__);
- dev_kfree_skb(skb);
- return -ENOSPC;
- }
- skb_push(skb, extnd_size);
- skb->data[extnd_size + 4] = extnd_size;
- status = adapter->host_intf_write_pkt(common->priv,
- (u8 *)skb->data,
- skb->len);
- if (status) {
- rsi_dbg(ERR_ZONE,
- "%s: Failed to write the packet\n", __func__);
- }
- dev_kfree_skb(skb);
- return status;
- }
-
- bss = &info->control.vif->bss_conf;
- wh = (struct ieee80211_hdr *)&skb->data[0];
-
- if (FRAME_DESC_SZ > skb_headroom(skb))
- goto err;
-
- skb_push(skb, FRAME_DESC_SZ);
- memset(skb->data, 0, FRAME_DESC_SZ);
- msg = (__le16 *)skb->data;
-
- if (skb->len > MAX_MGMT_PKT_SIZE) {
- rsi_dbg(INFO_ZONE, "%s: Dropping mgmt pkt > 512\n", __func__);
- goto err;
- }
-
- msg[0] = cpu_to_le16((skb->len - FRAME_DESC_SZ) |
- (RSI_WIFI_MGMT_Q << 12));
- msg[1] = cpu_to_le16(TX_DOT11_MGMT);
- msg[2] = cpu_to_le16(MIN_802_11_HDR_LEN << 8);
- msg[3] = cpu_to_le16(RATE_INFO_ENABLE);
- msg[6] = cpu_to_le16(le16_to_cpu(wh->seq_ctrl) >> 4);
-
- if (wh->addr1[0] & BIT(0))
- msg[3] |= cpu_to_le16(RSI_BROADCAST_PKT);
-
- if (common->band == NL80211_BAND_2GHZ)
- msg[4] = cpu_to_le16(RSI_11B_MODE);
- else
- msg[4] = cpu_to_le16((RSI_RATE_6 & 0x0f) | RSI_11G_MODE);
-
- if (conf_is_ht40(conf)) {
- msg[4] = cpu_to_le16(0xB | RSI_11G_MODE);
- msg[5] = cpu_to_le16(0x6);
- }
-
- /* Indicate to firmware to give cfm */
- if ((skb->data[16] == IEEE80211_STYPE_PROBE_REQ) && (!bss->assoc)) {
- msg[1] |= cpu_to_le16(BIT(10));
- msg[7] = cpu_to_le16(PROBEREQ_CONFIRM);
- common->mgmt_q_block = true;
- }
-
- msg[7] |= cpu_to_le16(vap_id << 8);
-
- status = adapter->host_intf_write_pkt(common->priv,
- (u8 *)msg,
- skb->len);
- if (status)
- rsi_dbg(ERR_ZONE, "%s: Failed to write the packet\n", __func__);
-
-err:
- rsi_indicate_tx_status(common->priv, skb, status);
- return status;
-}
--
2.4.11
^ permalink raw reply related
* [PATCH 2/3] rsi: Add new firmware loading method for RS9113 chip set
From: Prameela Rani Garnepudi @ 2016-12-08 5:10 UTC (permalink / raw)
To: linux-wireless
Cc: kvalo, johannes.berg, hofrat, xypron.glpk, prameela.garnepudi,
Prameela Rani Garnepudi
The older firmware loading method has been deprecated and not
in use with the current RS9113 modules. The newer method uses
soft boot loader (resides in device) to load the functional
firmware.
In this method complete RAM image and FLASH image are present
in the flash. Before loading the functional firmware, host
issues boot loader commands to verify whether the firmware
to load is different from the firmware in the device. If it is
different, firmware upgrade will progress and then boot loader
switches to the functional firmware.
Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
---
drivers/net/wireless/rsi/rsi_91x_hal.c | 667 +++++++++++++++++++++++++++++++++
drivers/net/wireless/rsi/rsi_hal.h | 152 ++++++++
drivers/net/wireless/rsi/rsi_main.h | 40 ++
3 files changed, 859 insertions(+)
create mode 100644 drivers/net/wireless/rsi/rsi_hal.h
diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c
index 02920c9..55bc8f4 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -1,6 +1,9 @@
/**
* Copyright (c) 2014 Redpine Signals Inc.
*
+ * Developers
+ * Prameela Rani Garnepudi 2016 <prameela.garnepudi@redpinesignals.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.
@@ -14,7 +17,21 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/firmware.h>
#include "rsi_mgmt.h"
+#include "rsi_hal.h"
+#include "rsi_sdio.h"
+
+/* FLASH Firmware */
+struct ta_metadata metadata_flash_content[] = {
+ {"flash_content", 0x00010000},
+ {"rs9113_wlan_qspi.rps", 0x00010000},
+ {"rs9113_wlan_bt_dual_mode.rps", 0x00010000},
+ {"rs9113_wlan_zigbee.rps", 0x00010000},
+ {"rs9113_ap_bt_dual_mode.rps", 0x00010000},
+ {"rs9113_wlan_qspi.rps", 0x00010000}
+};
+
/**
* rsi_send_data_pkt() - This function sends the recieved data packet from
@@ -213,3 +230,653 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
rsi_indicate_tx_status(common->priv, skb, status);
return status;
}
+
+/**
+ * bl_cmd_timeout() - This function is called when BL(Boot Loader) command is
+ * timed out
+ *
+ * @priv: Pointer to the hardware structure.
+ *
+ * Return: NONE.
+ */
+static void bl_cmd_timeout(unsigned long priv)
+{
+ struct rsi_hw *adapter = (struct rsi_hw *)priv;
+
+ adapter->blcmd_timer_expired = 1;
+ del_timer(&adapter->bl_cmd_timer);
+}
+
+/**
+ * bl_start_cmd_timer() - This function starts the BL command timer
+ *
+ * @adapter: Pointer to the hardware structure.
+ * @timeout: Timeout of the command in milliseconds
+ *
+ * Return: 0 on success.
+ */
+static int bl_start_cmd_timer(struct rsi_hw *adapter, u32 timeout)
+{
+ init_timer(&adapter->bl_cmd_timer);
+ adapter->bl_cmd_timer.data = (unsigned long)adapter;
+ adapter->bl_cmd_timer.function = (void *)&bl_cmd_timeout;
+ adapter->bl_cmd_timer.expires = (msecs_to_jiffies(timeout) + jiffies);
+
+ adapter->blcmd_timer_expired = 0;
+ add_timer(&adapter->bl_cmd_timer);
+
+ return 0;
+}
+
+/**
+ * bl_stop_cmd_timer() - This function stops the BL command timer
+ *
+ * @adapter: Pointer to the hardware structure.
+ *
+ * Return: 0 on success.
+ */
+static int bl_stop_cmd_timer(struct rsi_hw *adapter)
+{
+ adapter->blcmd_timer_expired = 0;
+ if (timer_pending(&adapter->bl_cmd_timer))
+ del_timer(&adapter->bl_cmd_timer);
+
+ return 0;
+}
+
+/**
+ * bl_write_cmd() - This function writes the BL command to device
+ *
+ * @adapter: Pointer to the hardware structure.
+ * @cmd: Command to write
+ * @exp_resp: Expected Response
+ * @cmd_resp: Received Response
+ *
+ * Return: 0 on success.
+ */
+static int bl_write_cmd(struct rsi_hw *adapter, u8 cmd,
+ u8 exp_resp, u16 *cmd_resp)
+{
+ struct rsi_host_intf_ops *hif_ops = adapter->host_intf_ops;
+ u32 regin_val = 0, regout_val = 0;
+ u8 output = 0;
+ u32 regin_input = 0;
+
+ regin_input = (REGIN_INPUT | adapter->priv->coex_mode);
+
+ while (!adapter->blcmd_timer_expired) {
+ regin_val = 0;
+ if (hif_ops->master_reg_read(adapter,
+ SWBL_REGIN,
+ ®in_val,
+ 2) < 0) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Command %0x REGIN reading failed\n",
+ __func__, cmd);
+ goto fail;
+ }
+ mdelay(1);
+ if ((regin_val >> 12) != REGIN_VALID)
+ break;
+ }
+ if (adapter->blcmd_timer_expired) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Command %0x REGIN reading timed out\n",
+ __func__, cmd);
+ goto fail;
+ }
+
+ rsi_dbg(INFO_ZONE,
+ "Issuing write to Regin regin_val:%0x sending cmd:%0x\n",
+ regin_val, (cmd | regin_input << 8));
+ if ((hif_ops->master_reg_write(adapter,
+ SWBL_REGIN,
+ (cmd | regin_input << 8),
+ 2)) < 0) {
+ goto fail;
+ }
+ mdelay(1);
+
+ if (cmd == LOAD_HOSTED_FW || cmd == JUMP_TO_ZERO_PC) {
+ /* JUMP_TO_ZERO_PC doesn't expect
+ * any response. So return from here
+ */
+ return 0;
+ }
+
+ while (!adapter->blcmd_timer_expired) {
+ regout_val = 0;
+ if (hif_ops->master_reg_read(adapter,
+ SWBL_REGOUT,
+ ®out_val,
+ 2) < 0) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Command %0x REGOUT reading failed\n",
+ __func__, cmd);
+ goto fail;
+ }
+ mdelay(1);
+ if ((regout_val >> 8) == REGOUT_VALID)
+ break;
+ }
+ if (adapter->blcmd_timer_expired) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Command %0x REGOUT reading timed out\n",
+ __func__, cmd);
+ goto fail;
+ }
+
+ *cmd_resp = ((u16 *)®out_val)[0] & 0xffff;
+
+ output = ((u8 *)®out_val)[0] & 0xff;
+
+ rsi_dbg(INFO_ZONE, "Invalidating regout\n");
+ if ((hif_ops->master_reg_write(adapter,
+ SWBL_REGOUT,
+ (cmd | REGOUT_INVALID << 8),
+ 2)) < 0) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Command %0x REGOUT writing failed..\n",
+ __func__, cmd);
+ goto fail;
+ }
+ mdelay(1);
+
+ if (output == exp_resp) {
+ rsi_dbg(INFO_ZONE,
+ "%s: Recvd Expected resp %x for cmd %0x\n",
+ __func__, output, cmd);
+ } else {
+ rsi_dbg(ERR_ZONE,
+ "%s: Recvd resp %x for cmd %0x\n",
+ __func__, output, cmd);
+ goto fail;
+ }
+ return 0;
+
+fail:
+ return -EINVAL;
+}
+
+/**
+ * bl_cmd() - This function initiates the BL command
+ *
+ * @adapter: Pointer to the hardware structure.
+ * @cmd: Command to write
+ * @exp_resp: Expected Response
+ * @str: Command string
+ *
+ * Return: 0 on success, -1 on failure.
+ */
+static int bl_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, char *str)
+{
+ u16 regout_val = 0;
+ u32 timeout = 0;
+
+ rsi_dbg(INFO_ZONE, "Issuing cmd: \"%s\"\n", str);
+
+ if ((cmd == EOF_REACHED) || (cmd == PING_VALID) || (cmd == PONG_VALID))
+ timeout = BL_BURN_TIMEOUT;
+ else
+ timeout = BL_CMD_TIMEOUT;
+
+ bl_start_cmd_timer(adapter, timeout);
+ if (bl_write_cmd(adapter, cmd, exp_resp, ®out_val) < 0) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Command %s (%0x) writing failed..\n",
+ __func__, str, cmd);
+ goto fail;
+ }
+ bl_stop_cmd_timer(adapter);
+ return 0;
+
+fail:
+ return -EINVAL;
+}
+
+/**
+ * bl_write_header() - This function writes the Bootloader header
+ *
+ * @adapter: Pointer to the hardware structure.
+ * @flash_content: Flash content
+ * @content_size: Flash content size
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+static int bl_write_header(struct rsi_hw *adapter,
+ u8 *flash_content, u32 content_size)
+{
+ struct rsi_host_intf_ops *hif_ops = adapter->host_intf_ops;
+ struct bl_header bl_hdr;
+ u32 write_addr, write_len;
+
+#define CHECK_SUM_OFFSET 20
+#define LEN_OFFSET 8
+#define ADDR_OFFSET 16
+
+ bl_hdr.flags = 0;
+ bl_hdr.image_no = cpu_to_le32(adapter->priv->coex_mode);
+ bl_hdr.check_sum = cpu_to_le32(
+ *(u32 *)&flash_content[CHECK_SUM_OFFSET]);
+ bl_hdr.flash_start_address = cpu_to_le32(
+ *(u32 *)&flash_content[ADDR_OFFSET]);
+ bl_hdr.flash_len = cpu_to_le32(*(u32 *)&flash_content[LEN_OFFSET]);
+ write_len = sizeof(struct bl_header);
+
+ if (adapter->rsi_host_intf == RSI_HOST_INTF_USB) {
+ write_addr = PING_BUFFER_ADDRESS;
+ if ((hif_ops->write_reg_multiple(adapter,
+ write_addr,
+ (u8 *)&bl_hdr,
+ write_len)) < 0) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Failed to load Version/CRC structure\n",
+ __func__);
+ goto fail;
+ }
+ } else {
+ write_addr = PING_BUFFER_ADDRESS >> 16;
+ if ((hif_ops->master_access_msword(adapter, write_addr)) < 0) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Unable to set ms word to common reg\n",
+ __func__);
+ goto fail;
+ }
+ write_addr = RSI_SD_REQUEST_MASTER |
+ (PING_BUFFER_ADDRESS & 0xFFFF);
+ if ((hif_ops->write_reg_multiple(adapter,
+ write_addr,
+ (u8 *)&bl_hdr,
+ write_len)) < 0) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Failed to load Version/CRC structure\n",
+ __func__);
+ goto fail;
+ }
+ }
+ return 0;
+
+fail:
+ return -EINVAL;
+}
+
+/**
+ * read_flash_capacity() - This function reads the flash size from device
+ *
+ * @adapter: Pointer to the hardware structure.
+ *
+ * Return: flash capacity on success, 0 on failure.
+ */
+static u32 read_flash_capacity(struct rsi_hw *adapter)
+{
+ u32 flash_sz = 0;
+
+ if ((adapter->host_intf_ops->master_reg_read(adapter,
+ FLASH_SIZE_ADDR,
+ &flash_sz, 2)) < 0) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Flash size reading failed..\n",
+ __func__);
+ return 0;
+ }
+ rsi_dbg(INIT_ZONE, "Flash capacity: %d KiloBytes\n", flash_sz);
+
+ return (flash_sz * 1024); /* Return size in kbytes */
+}
+
+/**
+ * ping_pong_write() - This function writes the flash contents throgh ping
+ * pong buffers
+ *
+ * @adapter: Pointer to the hardware structure.
+ * @cmd: command ping/pong write
+ * @addr: address to write
+ * @size: size
+ *
+ * Return: 0 on success, -1 on failure.
+ */
+static int ping_pong_write(struct rsi_hw *adapter, u8 cmd, u8 *addr, u32 size)
+{
+ struct rsi_host_intf_ops *hif_ops = adapter->host_intf_ops;
+ u32 block_size = 0;
+ u32 cmd_addr;
+ u16 cmd_resp = 0, cmd_req = 0;
+ u8 *str;
+
+ if (adapter->rsi_host_intf == RSI_HOST_INTF_SDIO)
+ block_size = RSI_USB_BLOCK_SIZE;
+ else
+ block_size = RSI_SDIO_BLOCK_SIZE;
+
+ if (cmd == PING_WRITE) {
+ cmd_addr = PING_BUFFER_ADDRESS;
+ cmd_resp = PONG_AVAIL;
+ cmd_req = PING_VALID;
+ str = "PING_VALID";
+ } else {
+ cmd_addr = PONG_BUFFER_ADDRESS;
+ cmd_resp = PING_AVAIL;
+ cmd_req = PONG_VALID;
+ str = "PONG_VALID";
+ }
+
+ if (hif_ops->load_data_master_write(adapter,
+ cmd_addr,
+ size,
+ block_size,
+ addr)) {
+ rsi_dbg(ERR_ZONE, "%s: Unable to write blk at addr %0x\n",
+ __func__, *addr);
+ goto fail;
+ }
+ if (bl_cmd(adapter, cmd_req, cmd_resp, str) < 0) {
+ bl_stop_cmd_timer(adapter);
+ goto fail;
+ }
+ return 0;
+
+fail:
+ return -EINVAL;
+}
+
+/**
+ * auto_fw_upgrade() - This function loads the firmware to device
+ *
+ * @adapter: Pointer to the hardware structure.
+ * @flash_content: Firmware to load
+ * @content_size: Size of the firmware
+ *
+ * Return: 0 on success, -1 on failure.
+ */
+static int auto_fw_upgrade(struct rsi_hw *adapter,
+ u8 *flash_content,
+ u32 content_size)
+{
+ u8 cmd;
+ u8 *temp_flash_content;
+ u32 temp_content_size;
+ u32 num_flash;
+ u32 index;
+ u32 flash_start_address;
+
+ temp_flash_content = flash_content;
+
+ if (content_size > MAX_FLASH_FILE_SIZE) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Flash Content size is more than 400K %u\n",
+ __func__, MAX_FLASH_FILE_SIZE);
+ goto fail;
+ }
+
+ flash_start_address = cpu_to_le32(
+ *(u32 *)&flash_content[FLASHING_START_ADDRESS]);
+ rsi_dbg(INFO_ZONE, "flash start address: %08x\n", flash_start_address);
+
+ if (flash_start_address < FW_IMAGE_MIN_ADDRESS) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Fw image Flash Start Address is less than 64K\n",
+ __func__);
+ goto fail;
+ }
+
+ if (flash_start_address % FLASH_SECTOR_SIZE) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Flash Start Address is not multiple of 4K\n",
+ __func__);
+ goto fail;
+ }
+
+ if ((flash_start_address + content_size) > adapter->flash_capacity) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Flash Content will cross max flash size\n",
+ __func__);
+ goto fail;
+ }
+
+ temp_content_size = content_size;
+ num_flash = content_size / FLASH_WRITE_CHUNK_SIZE;
+
+ rsi_dbg(INFO_ZONE, "content_size: %d\n", content_size);
+ rsi_dbg(INFO_ZONE, "num_flash: %d\n", num_flash);
+
+ for (index = 0; index <= num_flash; index++) {
+ rsi_dbg(INFO_ZONE, "flash index: %d\n", index);
+ if (index != num_flash) {
+ content_size = FLASH_WRITE_CHUNK_SIZE;
+ rsi_dbg(INFO_ZONE,
+ "QSPI content_size:%d\n",
+ content_size);
+ } else {
+ content_size =
+ temp_content_size % FLASH_WRITE_CHUNK_SIZE;
+ rsi_dbg(INFO_ZONE,
+ "Writing last sector content_size:%d\n",
+ content_size);
+ if (!content_size) {
+ rsi_dbg(INFO_ZONE, "INSTRUCTION SIZE ZERO\n");
+ break;
+ }
+ }
+
+ if (index % 2)
+ cmd = PING_WRITE;
+ else
+ cmd = PONG_WRITE;
+
+ if (ping_pong_write(adapter,
+ cmd,
+ flash_content,
+ content_size)) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Unable to load %d block\n",
+ __func__, index);
+ goto fail;
+ }
+
+ rsi_dbg(INFO_ZONE,
+ "%s: Successfully loaded block %d instructions\n",
+ __func__, index);
+ flash_content += content_size;
+ }
+
+ if (bl_cmd(adapter, EOF_REACHED, FW_LOADING_SUCCESSFUL,
+ "EOF_REACHED") < 0) {
+ bl_stop_cmd_timer(adapter);
+ goto fail;
+ }
+ rsi_dbg(INFO_ZONE, "FW loading is done and FW is running..\n");
+ return 0;
+
+fail:
+ return -EINVAL;
+}
+
+/**
+ * rsi_load_9113_firmware () - This function loads the TA firmware for 9113
+ * module.
+ *
+ * @adapter: Pointer to the rsi hw.
+ *
+ * Return: status: 0 on success, negative error code on failure.
+ */
+int rsi_load_9113_firmware(struct rsi_hw *adapter)
+{
+ struct rsi_host_intf_ops *hif_ops = adapter->host_intf_ops;
+ const struct firmware *fw_entry = NULL;
+ u32 regout_val = 0;
+ u16 tmp_regout_val = 0;
+ u8 *flash_content = NULL;
+ u32 content_size = 0;
+ struct ta_metadata *metadata_p;
+
+ bl_start_cmd_timer(adapter, BL_CMD_TIMEOUT);
+
+ while (!adapter->blcmd_timer_expired) {
+ if ((hif_ops->master_reg_read(adapter,
+ SWBL_REGOUT,
+ ®out_val,
+ 2)) < 0) {
+ rsi_dbg(ERR_ZONE,
+ "%s: REGOUT read failed\n", __func__);
+ goto fail;
+ }
+ mdelay(1);
+ if ((regout_val >> 8) == REGOUT_VALID)
+ break;
+ }
+ if (adapter->blcmd_timer_expired) {
+ rsi_dbg(ERR_ZONE, "%s: REGOUT read timedout\n", __func__);
+ rsi_dbg(ERR_ZONE,
+ "%s: Soft boot loader not present\n", __func__);
+ goto fail;
+ }
+ bl_stop_cmd_timer(adapter);
+
+ rsi_dbg(INFO_ZONE, "Received Board Version Number: %x\n",
+ (regout_val & 0xff));
+
+ if ((hif_ops->master_reg_write(adapter,
+ SWBL_REGOUT,
+ (REGOUT_INVALID | REGOUT_INVALID << 8),
+ 2)) < 0) {
+ rsi_dbg(ERR_ZONE, "%s: REGOUT writing failed..\n", __func__);
+ goto fail;
+ }
+ mdelay(1);
+
+ if ((bl_cmd(adapter, CONFIG_AUTO_READ_MODE, CMD_PASS,
+ "AUTO_READ_CMD")) < 0)
+ goto fail;
+
+ adapter->flash_capacity = read_flash_capacity(adapter);
+ if (adapter->flash_capacity <= 0) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Unable to read flash size from EEPROM\n",
+ __func__);
+ goto fail;
+ }
+
+ metadata_p = &metadata_flash_content[adapter->priv->coex_mode];
+
+ rsi_dbg(INIT_ZONE, "%s: loading file %s\n", __func__, metadata_p->name);
+
+ if ((request_firmware(&fw_entry, metadata_p->name,
+ adapter->device)) < 0) {
+ rsi_dbg(ERR_ZONE, "%s: Failed to open file %s\n",
+ __func__, metadata_p->name);
+ goto fail;
+ }
+ flash_content = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
+ if (!flash_content) {
+ rsi_dbg(ERR_ZONE, "%s: Failed to copy firmware\n", __func__);
+ goto fail;
+ }
+ content_size = fw_entry->size;
+ rsi_dbg(INFO_ZONE, "FW Length = %d bytes\n", content_size);
+
+ if (bl_write_header(adapter, flash_content, content_size)) {
+ rsi_dbg(ERR_ZONE,
+ "%s: RPS Image header loading failed\n",
+ __func__);
+ goto fail;
+ }
+
+ /* Check whether firmware in the device and firmware to load
+ * is same or not using crc check
+ */
+ bl_start_cmd_timer(adapter, BL_CMD_TIMEOUT);
+ if (bl_write_cmd(adapter, CHECK_CRC, CMD_PASS, &tmp_regout_val) < 0) {
+ bl_stop_cmd_timer(adapter);
+ rsi_dbg(ERR_ZONE,
+ "%s: CHECK_CRC Command writing failed..\n",
+ __func__);
+ if ((tmp_regout_val & 0xff) == CMD_FAIL) {
+ rsi_dbg(ERR_ZONE,
+ "CRC Fail.. Proceeding to Upgrade mode\n");
+ goto fw_upgrade;
+ }
+ }
+ bl_stop_cmd_timer(adapter);
+
+ if (bl_cmd(adapter, POLLING_MODE, CMD_PASS, "POLLING_MODE") < 0)
+ goto fail;
+
+load_image_cmd:
+ if ((bl_cmd(adapter,
+ LOAD_HOSTED_FW,
+ LOADING_INITIATED,
+ "LOAD_HOSTED_FW")) < 0)
+ goto fail;
+ rsi_dbg(INFO_ZONE, "Load Image command passed..\n");
+ goto success;
+
+fw_upgrade:
+ /* After burning the RPS header, firmware has to be
+ * burned using the below steps
+ */
+ if (bl_cmd(adapter, BURN_HOSTED_FW, SEND_RPS_FILE, "FW_UPGRADE") < 0)
+ goto fail;
+
+ rsi_dbg(INFO_ZONE, "Burn Command Pass.. Upgrading the firmware\n");
+
+ if (auto_fw_upgrade(adapter, flash_content, content_size) == 0) {
+ rsi_dbg(ERR_ZONE,
+ "***** Auto firmware upgrade successful *****\n");
+ goto load_image_cmd;
+ }
+
+ bl_cmd(adapter, CONFIG_AUTO_READ_MODE, CMD_PASS, "AUTO_READ_MODE");
+ goto fail;
+
+ rsi_dbg(INFO_ZONE, "SWBL FLASHING THROUGH SWBL PASSED...\n");
+
+success:
+ kfree(flash_content);
+ release_firmware(fw_entry);
+ return 0;
+
+fail:
+ kfree(flash_content);
+ release_firmware(fw_entry);
+ return -EINVAL;
+}
+
+/**
+ * rsi_hal_device_init() - This function initializes the Device
+ * @adapter: Pointer to the hardware structure
+ *
+ * Return: status: 0 on success, -1 on failure.
+ */
+int rsi_hal_device_init(struct rsi_hw *adapter, enum rsi_dev_model dev_model)
+{
+#ifdef CONFIG_RSI_HCI
+ adapter->priv->coex_mode = 4;
+#else
+ adapter->priv->coex_mode = 1;
+#endif
+
+ adapter->device_model = dev_model;
+ switch (adapter->device_model) {
+ case RSI_DEV_9110:
+ /* Add code for 9110 */
+ break;
+ case RSI_DEV_9113:
+ if (rsi_load_9113_firmware(adapter)) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Failed to load TA instructions\n",
+ __func__);
+ return -EINVAL;
+ }
+ break;
+ case RSI_DEV_9116:
+ /* Add code for 9116 */
+ break;
+ default:
+ return -EINVAL;
+ }
+ adapter->common_hal_fsm = COMMAN_HAL_WAIT_FOR_CARD_READY;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rsi_hal_device_init);
+
diff --git a/drivers/net/wireless/rsi/rsi_hal.h b/drivers/net/wireless/rsi/rsi_hal.h
new file mode 100644
index 0000000..77ededc
--- /dev/null
+++ b/drivers/net/wireless/rsi/rsi_hal.h
@@ -0,0 +1,152 @@
+/**
+ * Copyright (c) 2014 Redpine Signals Inc.
+ *
+ * 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 __RSI_HAL_H__
+#define __RSI_HAL_H__
+
+#define TA_LOAD_ADDRESS 0x00
+#define FLASH_WRITE_CHUNK_SIZE (4 * 1024)
+#define USB_FLASH_READ_CHUNK_SIZE ((2 * 1024) - 4)
+#define SDIO_FLASH_READ_CHUNK_SIZE (2 * 1024)
+#define FLASH_SECTOR_SIZE (4 * 1024)
+#define STARTING_BLOCK_INDEX 0
+#define FLASH_BLOCK_SIZE (32 * 1024)
+
+#define FLASH_SIZE_ADDR 0x04000016
+#define PING_BUFFER_ADDRESS 0x19000
+#define PONG_BUFFER_ADDRESS 0x1a000
+#define SWBL_REGIN 0x41050034
+#define SWBL_REGOUT 0x4105003c
+#define PING_WRITE 0x1
+#define PONG_WRITE 0x2
+
+#define BL_CMD_TIMEOUT 2000
+#define BL_BURN_TIMEOUT (50 * 1000)
+
+#define MASTER_READ_MODE 1
+#define EEPROM_READ_MODE 2
+
+#define REGIN_VALID 0xA
+#define REGIN_INPUT 0xA0
+#define REGOUT_VALID 0xAB
+#define REGOUT_INVALID (~0xAB)
+#define CMD_PASS 0xAA
+#define CMD_FAIL 0xCC
+#define INVALID_ADDR 0x4C
+
+#define BURN_BL 0x23
+#define LOAD_HOSTED_FW 'A'
+#define BURN_HOSTED_FW 'B'
+#define PING_VALID 'I'
+#define PONG_VALID 'O'
+#define PING_AVAIL 'I'
+#define PONG_AVAIL 'O'
+#define EOF_REACHED 'E'
+#define CHECK_CRC 'K'
+#define POLLING_MODE 'P'
+#define CONFIG_AUTO_READ_MODE 'R'
+#define JUMP_TO_ZERO_PC 'J'
+#define FW_LOADING_SUCCESSFUL 'S'
+#define LOADING_INITIATED '1'
+
+/* Boot loader commands */
+#define HOST_INTF_REG_OUT 0x4105003C
+#define HOST_INTF_REG_IN 0x41050034
+#define BOARD_READY 0xABCD
+#define REG_READ 0xD1
+#define REG_WRITE 0xD2
+#define SEND_RPS_FILE '2'
+#define BOOTUP_OPTIONS_LAST_CONFIG_NOT_SAVED 0xF1
+#define BOOTUP_OPTIONS_CHECKSUM_FAIL 0xF2
+#define INVALID_OPTION 0xF3
+#define CHECKSUM_SUCCESS 0xAA
+#define CHECKSUM_FAILURE 0xCC
+#define CHECKSUM_INVALID_ADDRESS 0x4C
+
+#define EEPROM_VERSION_OFFSET 77
+#define CALIB_CRC_OFFSET 4092
+#define MAGIC_WORD 0x5A
+#define MAGIC_WORD_OFFSET_1 40
+#define MAGIC_WORD_OFFSET_2 424
+#define FW_IMAGE_MIN_ADDRESS (68 * 1024)
+#define FLASH_MAX_ADDRESS (4 * 1024 * 1024) //4MB
+#define MAX_FLASH_FILE_SIZE (400 * 1024) //400K
+#define FLASHING_START_ADDRESS 16
+#define CALIB_VALUES_START_ADDR 16
+#define SOC_FLASH_ADDR 0x04000000
+#define EEPROM_DATA_SIZE 4096
+#define CALIB_DATA_SIZE (EEPROM_DATA_SIZE - CALIB_VALUES_START_ADDR)
+#define BL_HEADER 32
+
+#define BT_CARD_READY_IND 0x89
+#define WLAN_CARD_READY_IND 0x0
+#define COMMON_HAL_CARD_READY_IND 0x0
+#define ZIGB_CARD_READY_IND 0xff
+
+#define COMMAN_HAL_WAIT_FOR_CARD_READY 1
+#define COMMON_HAL_SEND_CONFIG_PARAMS 2
+#define COMMON_HAL_TX_ACCESS 3
+#define COMMON_HAL_WAIT_FOR_PROTO_CARD_READY 4
+#define HEX_FILE 1
+#define BIN_FILE 0
+#define UNIX_FILE_TYPE 8
+#define DOS_FILE_TYPE 9
+#define LMAC_INSTRUCTIONS_SIZE (16 * 1024) /* 16Kbytes */
+
+#define ULP_RESET_REG 0x161
+#define WATCH_DOG_TIMER_1 0x16c
+#define WATCH_DOG_TIMER_2 0x16d
+#define WATCH_DOG_DELAY_TIMER_1 0x16e
+#define WATCH_DOG_DELAY_TIMER_2 0x16f
+#define WATCH_DOG_TIMER_ENABLE 0x170
+
+#define RESTART_WDT BIT(11)
+#define BYPASS_ULP_ON_WDT BIT(1)
+
+#define RF_SPI_PROG_REG_BASE_ADDR 0x40080000
+
+#define GSPI_CTRL_REG0 (RF_SPI_PROG_REG_BASE_ADDR)
+#define GSPI_CTRL_REG1 (RF_SPI_PROG_REG_BASE_ADDR + 0x2)
+#define GSPI_DATA_REG0 (RF_SPI_PROG_REG_BASE_ADDR + 0x4)
+#define GSPI_DATA_REG1 (RF_SPI_PROG_REG_BASE_ADDR + 0x6)
+#define GSPI_DATA_REG2 (RF_SPI_PROG_REG_BASE_ADDR + 0x8)
+
+#define GSPI_DMA_MODE BIT(13)
+
+#define GSPI_2_ULP BIT(12)
+#define GSPI_TRIG BIT(7)
+#define GSPI_READ BIT(6)
+#define GSPI_RF_SPI_ACTIVE BIT(8)
+
+#define RSI_USB_BLOCK_SIZE 256
+#define RSI_SDIO_BLOCK_SIZE 252
+
+struct bl_header {
+ u32 flags;
+ u32 image_no;
+ u32 check_sum;
+ u32 flash_start_address;
+ u32 flash_len;
+} __packed;
+
+struct ta_metadata {
+ char *name;
+ unsigned int address;
+};
+
+int rsi_hal_device_init(struct rsi_hw *adapter, enum rsi_dev_model dev_model);
+
+#endif
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index dcd0957..2c2c0bb 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -204,10 +204,23 @@ struct rsi_common {
struct cqm_info cqm_info;
bool hw_data_qs_blocked;
+ u8 coex_mode;
+};
+
+enum host_intf {
+ RSI_HOST_INTF_SDIO = 0,
+ RSI_HOST_INTF_USB
+};
+
+enum rsi_dev_model {
+ RSI_DEV_9110 = 0,
+ RSI_DEV_9113,
+ RSI_DEV_9116
};
struct rsi_hw {
struct rsi_common *priv;
+ enum rsi_dev_model device_model;
struct ieee80211_hw *hw;
struct ieee80211_vif *vifs[RSI_MAX_VIFS];
struct ieee80211_tx_queue_params edca_params[NUM_EDCA_QUEUES];
@@ -215,16 +228,43 @@ struct rsi_hw {
struct device *device;
u8 sc_nvifs;
+ enum host_intf rsi_host_intf;
#ifdef CONFIG_RSI_DEBUGFS
struct rsi_debugfs *dfsentry;
u8 num_debugfs_entries;
#endif
+
+ struct timer_list bl_cmd_timer;
+ u8 blcmd_timer_expired;
+ u32 flash_capacity;
+ u32 tx_blk_size;
+ u32 common_hal_fsm;
void *rsi_dev;
+ struct rsi_host_intf_ops *host_intf_ops;
int (*host_intf_read_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len);
int (*host_intf_write_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len);
int (*check_hw_queue_status)(struct rsi_hw *adapter, u8 q_num);
int (*rx_urb_submit)(struct rsi_hw *adapter);
int (*determine_event_timeout)(struct rsi_hw *adapter);
};
+
+struct rsi_host_intf_ops {
+ int (*read_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len);
+ int (*write_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len);
+ int (*master_access_msword)(struct rsi_hw *adapter, u16 ms_word);
+ int (*read_reg_multiple)(struct rsi_hw *adapter, u32 addr,
+ u8 *data, u16 count);
+ int (*write_reg_multiple)(struct rsi_hw *adapter, u32 addr,
+ u8 *data, u16 count);
+ int (*master_reg_read)(struct rsi_hw *adapter, u32 addr,
+ u32 *read_buf, u16 size);
+ int (*master_reg_write)(struct rsi_hw *adapter,
+ unsigned long addr, unsigned long data,
+ u16 size);
+ int (*load_data_master_write)(struct rsi_hw *adapter, u32 addr,
+ u32 instructions_size, u16 block_size,
+ u8 *fw);
+};
+
#endif
--
2.4.11
^ permalink raw reply related
* [PATCH 3/3] rsi: Remove old firmware loading method for RS9113 chip set
From: Prameela Rani Garnepudi @ 2016-12-08 5:10 UTC (permalink / raw)
To: linux-wireless
Cc: kvalo, johannes.berg, hofrat, xypron.glpk, prameela.garnepudi,
Prameela Rani Garnepudi
Older firmware loading method is not being used by any RSI
module. Hence removing that part of code doesn't impact.
New device ID is added which is widely used for current
RSI chip sets. Changes done in usb and sdio inteface files
to support new firmware loading method.
Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
---
drivers/net/wireless/rsi/rsi_91x_sdio.c | 221 ++++++++++++++++++++++++++--
drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 190 +-----------------------
drivers/net/wireless/rsi/rsi_91x_usb.c | 162 ++++++++++++++++++--
drivers/net/wireless/rsi/rsi_91x_usb_ops.c | 125 ----------------
drivers/net/wireless/rsi/rsi_sdio.h | 4 +-
drivers/net/wireless/rsi/rsi_usb.h | 14 +-
6 files changed, 369 insertions(+), 347 deletions(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index 8428858..4eb59f0 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -1,6 +1,8 @@
/**
* Copyright (c) 2014 Redpine Signals Inc.
*
+ * Developers:
+ * Fariya Fathima 2014 <fariya.f@redpinesignals.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.
@@ -18,6 +20,7 @@
#include <linux/module.h>
#include "rsi_sdio.h"
#include "rsi_common.h"
+#include "rsi_hal.h"
/**
* rsi_sdio_set_cmd52_arg() - This function prepares cmd 52 read/write arg.
@@ -473,8 +476,6 @@ void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit)
rsi_dbg(ERR_ZONE, "%s: unable to send ack\n", __func__);
}
-
-
/**
* rsi_sdio_read_register_multiple() - This function read multiple bytes of
* information from the SD card.
@@ -487,8 +488,8 @@ void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit)
*/
static int rsi_sdio_read_register_multiple(struct rsi_hw *adapter,
u32 addr,
- u32 count,
- u8 *data)
+ u8 *data,
+ u16 count)
{
struct rsi_91x_sdiodev *dev =
(struct rsi_91x_sdiodev *)adapter->rsi_dev;
@@ -518,7 +519,7 @@ static int rsi_sdio_read_register_multiple(struct rsi_hw *adapter,
int rsi_sdio_write_register_multiple(struct rsi_hw *adapter,
u32 addr,
u8 *data,
- u32 count)
+ u16 count)
{
struct rsi_91x_sdiodev *dev =
(struct rsi_91x_sdiodev *)adapter->rsi_dev;
@@ -552,6 +553,176 @@ int rsi_sdio_write_register_multiple(struct rsi_hw *adapter,
return status;
}
+int rsi_sdio_load_data_master_write(struct rsi_hw *adapter,
+ u32 base_address,
+ u32 instructions_sz,
+ u16 block_size,
+ u8 *ta_firmware)
+{
+ u32 num_blocks;
+ u16 msb_address;
+ u32 offset, ii;
+ u8 temp_buf[block_size];
+ u16 lsb_address;
+
+ num_blocks = instructions_sz / block_size;
+ msb_address = base_address >> 16;
+
+ rsi_dbg(INFO_ZONE, "ins_size: %d\n", instructions_sz);
+ rsi_dbg(INFO_ZONE, "num_blocks: %d\n", num_blocks);
+
+ /* Loading DM ms word in the sdio slave */
+ if (rsi_sdio_master_access_msword(adapter, msb_address)) {
+ rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__);
+ return -EINVAL;
+ }
+
+ for (offset = 0, ii = 0; ii < num_blocks; ii++, offset += block_size) {
+ memset(temp_buf, 0, block_size);
+ memcpy(temp_buf, ta_firmware + offset, block_size);
+ lsb_address = (u16)base_address;
+ if (rsi_sdio_write_register_multiple(adapter,
+ (lsb_address | RSI_SD_REQUEST_MASTER),
+ temp_buf, block_size)) {
+ rsi_dbg(ERR_ZONE, "%s: failed to write\n", __func__);
+ return -EINVAL;
+ }
+ rsi_dbg(INFO_ZONE, "%s: loading block: %d\n", __func__, ii);
+ base_address += block_size;
+
+ if ((base_address >> 16) != msb_address) {
+ msb_address += 1;
+
+ /* Loading DM ms word in the sdio slave */
+ if (rsi_sdio_master_access_msword(adapter,
+ msb_address)) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Unable to set ms word reg\n",
+ __func__);
+ return -EINVAL;
+ }
+ }
+ }
+
+ if (instructions_sz % block_size) {
+ memset(temp_buf, 0, block_size);
+ memcpy(temp_buf,
+ ta_firmware + offset,
+ instructions_sz % block_size);
+ lsb_address = (u16)base_address;
+ if (rsi_sdio_write_register_multiple(adapter,
+ lsb_address | RSI_SD_REQUEST_MASTER,
+ temp_buf,
+ instructions_sz % block_size)) {
+ return -EINVAL;
+ }
+ rsi_dbg(INFO_ZONE,
+ "Written Last Block in Address 0x%x Successfully\n",
+ offset | RSI_SD_REQUEST_MASTER);
+ }
+ return 0;
+}
+
+int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,
+ u32 *read_buf, u16 size)
+{
+ u32 *data = NULL;
+ u16 ms_addr = 0;
+ u32 align[2] = {};
+ u32 addr_on_bus;
+
+ data = PTR_ALIGN(&align[0], 8);
+
+ ms_addr = (addr >> 16);
+ if (rsi_sdio_master_access_msword(adapter, ms_addr)) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Unable to set ms word to common reg\n",
+ __func__);
+ return -EINVAL;
+ }
+ addr = addr & 0xFFFF;
+
+ addr_on_bus = (addr & 0xFF000000);
+ if ((addr_on_bus == (FLASH_SIZE_ADDR & 0xFF000000)) ||
+ (addr_on_bus == 0x0)) {
+ addr_on_bus = (addr & ~(0x3));
+ } else
+ addr_on_bus = addr;
+
+ /* Bringing TA out of reset */
+ if (rsi_sdio_read_register_multiple(adapter,
+ (addr_on_bus | RSI_SD_REQUEST_MASTER),
+ (u8 *)data, 4)) {
+ rsi_dbg(ERR_ZONE, "%s: AHB register read failed\n", __func__);
+ return -EINVAL;
+ }
+ if (size == 2) {
+ if ((addr & 0x3) == 0)
+ *read_buf = *data;
+ else
+ *read_buf = (*data >> 16);
+ *read_buf = (*read_buf & 0xFFFF);
+ } else if (size == 1) {
+ if ((addr & 0x3) == 0)
+ *read_buf = *data;
+ else if ((addr & 0x3) == 1)
+ *read_buf = (*data >> 8);
+ else if ((addr & 0x3) == 2)
+ *read_buf = (*data >> 16);
+ else
+ *read_buf = (*data >> 24);
+ *read_buf = (*read_buf & 0xFF);
+ } else { /*size is 4 */
+ *read_buf = *data;
+ }
+
+ return 0;
+}
+
+int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
+ unsigned long addr,
+ unsigned long data,
+ u16 size)
+{
+ unsigned long data1[2];
+ unsigned long *data_aligned;
+
+ data_aligned = PTR_ALIGN(&data1[0], 8);
+
+ if (size == 2) {
+ *data_aligned = ((data << 16) | (data & 0xFFFF));
+ } else if (size == 1) {
+ u32 temp_data;
+
+ temp_data = (data & 0xFF);
+ *data_aligned = ((temp_data << 24) |
+ (temp_data << 16) |
+ (temp_data << 8) |
+ (temp_data));
+ } else {
+ *data_aligned = data;
+ }
+ size = 4;
+
+ if (rsi_sdio_master_access_msword(adapter, (addr >> 16))) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Unable to set ms word to common reg\n",
+ __func__);
+ return -EINVAL;
+ }
+ addr = addr & 0xFFFF;
+
+ /* Bringing TA out of reset */
+ if (rsi_sdio_write_register_multiple(adapter,
+ (addr | RSI_SD_REQUEST_MASTER),
+ (u8 *)data_aligned, size)) {
+ rsi_dbg(ERR_ZONE,
+ "%s: Unable to do AHB reg write\n", __func__);
+ return -EINVAL;
+ }
+ return 0;
+}
+
/**
* rsi_sdio_host_intf_write_pkt() - This function writes the packet to device.
* @adapter: Pointer to the adapter structure.
@@ -614,8 +785,8 @@ int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter,
status = rsi_sdio_read_register_multiple(adapter,
length,
- length, /*num of bytes*/
- (u8 *)pkt);
+ pkt,
+ length);
if (status)
rsi_dbg(ERR_ZONE, "%s: Failed to read frame: %d\n", __func__,
@@ -691,6 +862,17 @@ static int rsi_init_sdio_interface(struct rsi_hw *adapter,
return status;
}
+static struct rsi_host_intf_ops sdio_host_intf_ops = {
+ .write_pkt = rsi_sdio_host_intf_write_pkt,
+ .read_pkt = rsi_sdio_host_intf_read_pkt,
+ .master_access_msword = rsi_sdio_master_access_msword,
+ .master_reg_read = rsi_sdio_master_reg_read,
+ .master_reg_write = rsi_sdio_master_reg_write,
+ .read_reg_multiple = rsi_sdio_read_register_multiple,
+ .write_reg_multiple = rsi_sdio_write_register_multiple,
+ .load_data_master_write = rsi_sdio_load_data_master_write,
+};
+
/**
* rsi_probe() - This function is called by kernel when the driver provided
* Vendor and device IDs are matched. All the initialization
@@ -713,6 +895,8 @@ static int rsi_probe(struct sdio_func *pfunction,
__func__);
return 1;
}
+ adapter->rsi_host_intf = RSI_HOST_INTF_SDIO;
+ adapter->host_intf_ops = &sdio_host_intf_ops;
if (rsi_init_sdio_interface(adapter, pfunction)) {
rsi_dbg(ERR_ZONE, "%s: Failed to init sdio interface\n",
@@ -720,14 +904,6 @@ static int rsi_probe(struct sdio_func *pfunction,
goto fail;
}
- if (rsi_sdio_device_init(adapter->priv)) {
- rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__);
- sdio_claim_host(pfunction);
- sdio_disable_func(pfunction);
- sdio_release_host(pfunction);
- goto fail;
- }
-
sdio_claim_host(pfunction);
if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) {
rsi_dbg(ERR_ZONE, "%s: Failed to request IRQ\n", __func__);
@@ -738,6 +914,21 @@ static int rsi_probe(struct sdio_func *pfunction,
sdio_release_host(pfunction);
rsi_dbg(INIT_ZONE, "%s: Registered Interrupt handler\n", __func__);
+ if (rsi_hal_device_init(adapter, RSI_DEV_9113)) {
+ rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__);
+ sdio_claim_host(pfunction);
+ sdio_disable_func(pfunction);
+ sdio_release_host(pfunction);
+ goto fail;
+ }
+ rsi_dbg(INFO_ZONE, "===> RSI Device Init Done <===\n");
+
+ if (rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR)) {
+ rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__);
+ return -1;
+ }
+ rsi_dbg(INIT_ZONE, "%s: Setting ms word to 0x41050000\n", __func__);
+
return 0;
fail:
rsi_91x_deinit(adapter);
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
index 40d7231..df2a63b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
@@ -27,8 +27,7 @@
*
* Return: status: 0 on success, -1 on failure.
*/
-static int rsi_sdio_master_access_msword(struct rsi_hw *adapter,
- u16 ms_word)
+int rsi_sdio_master_access_msword(struct rsi_hw *adapter, u16 ms_word)
{
u8 byte;
u8 function = 0;
@@ -61,171 +60,6 @@ static int rsi_sdio_master_access_msword(struct rsi_hw *adapter,
}
/**
- * rsi_copy_to_card() - This function includes the actual funtionality of
- * copying the TA firmware to the card.Basically this
- * function includes opening the TA file,reading the
- * TA file and writing their values in blocks of data.
- * @common: Pointer to the driver private structure.
- * @fw: Pointer to the firmware value to be written.
- * @len: length of firmware file.
- * @num_blocks: Number of blocks to be written to the card.
- *
- * Return: 0 on success and -1 on failure.
- */
-static int rsi_copy_to_card(struct rsi_common *common,
- const u8 *fw,
- u32 len,
- u32 num_blocks)
-{
- struct rsi_hw *adapter = common->priv;
- struct rsi_91x_sdiodev *dev =
- (struct rsi_91x_sdiodev *)adapter->rsi_dev;
- u32 indx, ii;
- u32 block_size = dev->tx_blk_size;
- u32 lsb_address;
- __le32 data[] = { TA_HOLD_THREAD_VALUE, TA_SOFT_RST_CLR,
- TA_PC_ZERO, TA_RELEASE_THREAD_VALUE };
- u32 address[] = { TA_HOLD_THREAD_REG, TA_SOFT_RESET_REG,
- TA_TH0_PC_REG, TA_RELEASE_THREAD_REG };
- u32 base_address;
- u16 msb_address;
-
- base_address = TA_LOAD_ADDRESS;
- msb_address = base_address >> 16;
-
- for (indx = 0, ii = 0; ii < num_blocks; ii++, indx += block_size) {
- lsb_address = ((u16) base_address | RSI_SD_REQUEST_MASTER);
- if (rsi_sdio_write_register_multiple(adapter,
- lsb_address,
- (u8 *)(fw + indx),
- block_size)) {
- rsi_dbg(ERR_ZONE,
- "%s: Unable to load %s blk\n", __func__,
- FIRMWARE_RSI9113);
- return -1;
- }
- rsi_dbg(INIT_ZONE, "%s: loading block: %d\n", __func__, ii);
- base_address += block_size;
- if ((base_address >> 16) != msb_address) {
- msb_address += 1;
- if (rsi_sdio_master_access_msword(adapter,
- msb_address)) {
- rsi_dbg(ERR_ZONE,
- "%s: Unable to set ms word reg\n",
- __func__);
- return -1;
- }
- }
- }
-
- if (len % block_size) {
- lsb_address = ((u16) base_address | RSI_SD_REQUEST_MASTER);
- if (rsi_sdio_write_register_multiple(adapter,
- lsb_address,
- (u8 *)(fw + indx),
- len % block_size)) {
- rsi_dbg(ERR_ZONE,
- "%s: Unable to load f/w\n", __func__);
- return -1;
- }
- }
- rsi_dbg(INIT_ZONE,
- "%s: Succesfully loaded TA instructions\n", __func__);
-
- if (rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR)) {
- rsi_dbg(ERR_ZONE,
- "%s: Unable to set ms word to common reg\n",
- __func__);
- return -1;
- }
-
- for (ii = 0; ii < ARRAY_SIZE(data); ii++) {
- /* Bringing TA out of reset */
- if (rsi_sdio_write_register_multiple(adapter,
- (address[ii] |
- RSI_SD_REQUEST_MASTER),
- (u8 *)&data[ii],
- 4)) {
- rsi_dbg(ERR_ZONE,
- "%s: Unable to hold TA threads\n", __func__);
- return -1;
- }
- }
-
- rsi_dbg(INIT_ZONE, "%s: loaded firmware\n", __func__);
- return 0;
-}
-
-/**
- * rsi_load_ta_instructions() - This function includes the actual funtionality
- * of loading the TA firmware.This function also
- * includes opening the TA file,reading the TA
- * file and writing their value in blocks of data.
- * @common: Pointer to the driver private structure.
- *
- * Return: status: 0 on success, -1 on failure.
- */
-static int rsi_load_ta_instructions(struct rsi_common *common)
-{
- struct rsi_hw *adapter = common->priv;
- struct rsi_91x_sdiodev *dev =
- (struct rsi_91x_sdiodev *)adapter->rsi_dev;
- u32 len;
- u32 num_blocks;
- const u8 *fw;
- const struct firmware *fw_entry = NULL;
- u32 block_size = dev->tx_blk_size;
- int status = 0;
- u32 base_address;
- u16 msb_address;
-
- if (rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR)) {
- rsi_dbg(ERR_ZONE,
- "%s: Unable to set ms word to common reg\n",
- __func__);
- return -1;
- }
- base_address = TA_LOAD_ADDRESS;
- msb_address = (base_address >> 16);
-
- if (rsi_sdio_master_access_msword(adapter, msb_address)) {
- rsi_dbg(ERR_ZONE,
- "%s: Unable to set ms word reg\n", __func__);
- return -1;
- }
-
- status = request_firmware(&fw_entry, FIRMWARE_RSI9113, adapter->device);
- if (status < 0) {
- rsi_dbg(ERR_ZONE, "%s Firmware file %s not found\n",
- __func__, FIRMWARE_RSI9113);
- return status;
- }
-
- /* Copy firmware into DMA-accessible memory */
- fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
- if (!fw) {
- status = -ENOMEM;
- goto out;
- }
- len = fw_entry->size;
-
- if (len % 4)
- len += (4 - (len % 4));
-
- num_blocks = (len / block_size);
-
- rsi_dbg(INIT_ZONE, "%s: Instruction size:%d\n", __func__, len);
- rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks);
-
- status = rsi_copy_to_card(common, fw, len, num_blocks);
- kfree(fw);
-
-out:
- release_firmware(fw_entry);
- return status;
-}
-
-/**
* rsi_process_pkt() - This Function reads rx_blocks register and figures out
* the size of the rx pkt.
* @common: Pointer to the driver private structure.
@@ -472,28 +306,6 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
}
/**
- * rsi_device_init() - This Function Initializes The HAL.
- * @common: Pointer to the driver private structure.
- *
- * Return: 0 on success, -1 on failure.
- */
-int rsi_sdio_device_init(struct rsi_common *common)
-{
- if (rsi_load_ta_instructions(common))
- return -1;
-
- if (rsi_sdio_master_access_msword(common->priv, MISC_CFG_BASE_ADDR)) {
- rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n",
- __func__);
- return -1;
- }
- rsi_dbg(INIT_ZONE,
- "%s: Setting ms word to 0x41050000\n", __func__);
-
- return 0;
-}
-
-/**
* rsi_sdio_read_buffer_status_register() - This function is used to the read
* buffer status register and set
* relevant fields in
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
index ef5d394..c78a2c7 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
@@ -1,6 +1,9 @@
/**
* Copyright (c) 2014 Redpine Signals Inc.
*
+ * Developers:
+ * Prameela Rani Garnepudi 2016 <prameela.garnepudi@redpinesignals.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.
@@ -17,6 +20,16 @@
#include <linux/module.h>
#include "rsi_usb.h"
+#include "rsi_hal.h"
+
+static struct rsi_host_intf_ops usb_host_intf_ops = {
+ .write_pkt = rsi_usb_host_intf_write_pkt,
+ .master_reg_read = rsi_usb_master_reg_read,
+ .master_reg_write = rsi_usb_master_reg_write,
+ .read_reg_multiple = rsi_usb_read_register_multiple,
+ .write_reg_multiple = rsi_usb_write_register_multiple,
+ .load_data_master_write = rsi_usb_load_data_master_write,
+};
/**
* rsi_usb_card_write() - This function writes to the USB Card.
@@ -151,7 +164,7 @@ static int rsi_find_bulk_in_and_out_endpoints(struct usb_interface *interface,
*/
static int rsi_usb_reg_read(struct usb_device *usbdev,
u32 reg,
- u16 *value,
+ u32 *value,
u16 len)
{
u8 *buf;
@@ -274,6 +287,63 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter)
}
/**
+ * rsi_usb_read_register_multiple() - This function reads multiple
+ * bytes of data from the address.
+ * @adapter: Pointer to the adapter structure.
+ * @addr: Address of the register.
+ * @data: Read data.
+ * @len: Number of bytes to read.
+ *
+ * Return: status: 0 on success, a negative error code on failure.
+ */
+int rsi_usb_read_register_multiple(struct rsi_hw *adapter,
+ u32 addr,
+ u8 *data,
+ u16 count)
+{
+ struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
+ u8 *buf;
+ u16 transfer;
+ int status = 0;
+ u16 reg_val, index;
+
+ if (addr == 0)
+ return -EINVAL;
+
+ buf = kzalloc(4096, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ reg_val = ((u16 *)&addr)[1] & 0xffff;
+ index = ((u16 *)&addr)[0] & 0xffff;
+ while (count) {
+ transfer = min_t(u16, count, 4096);
+ status = usb_control_msg(dev->usbdev,
+ usb_rcvctrlpipe(dev->usbdev, 0),
+ USB_VENDOR_REGISTER_READ,
+ USB_TYPE_VENDOR,
+ reg_val,
+ index,
+ (void *)buf,
+ transfer,
+ USB_CTRL_GET_TIMEOUT);
+ if (status < 0) {
+ rsi_dbg(ERR_ZONE,
+ "Reg read failed with error code :%d\n",
+ status);
+ kfree(buf);
+ return status;
+ }
+ memcpy(data, buf, transfer);
+ count -= transfer;
+ data += transfer;
+ addr += transfer;
+ }
+ kfree(buf);
+ return status;
+}
+
+/**
* rsi_usb_write_register_multiple() - This function writes multiple bytes of
* information to multiple registers.
* @adapter: Pointer to the adapter structure.
@@ -286,7 +356,7 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter)
int rsi_usb_write_register_multiple(struct rsi_hw *adapter,
u32 addr,
u8 *data,
- u32 count)
+ u16 count)
{
struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
u8 *buf;
@@ -333,9 +403,7 @@ int rsi_usb_write_register_multiple(struct rsi_hw *adapter,
*
* Return: 0 on success, a negative error code on failure.
*/
-static int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter,
- u8 *pkt,
- u32 len)
+int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter, u8 *pkt, u32 len)
{
u32 queueno = ((pkt[1] >> 4) & 0xf);
u8 endpoint;
@@ -348,6 +416,72 @@ static int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter,
len);
}
+int rsi_usb_master_reg_read(struct rsi_hw *adapter,
+ u32 reg,
+ u32 *value,
+ u16 len)
+{
+ struct usb_device *usbdev =
+ ((struct rsi_91x_usbdev *)adapter->rsi_dev)->usbdev;
+
+ return rsi_usb_reg_read(usbdev, reg, value, len);
+}
+
+int rsi_usb_master_reg_write(struct rsi_hw *adapter,
+ unsigned long reg,
+ unsigned long value,
+ u16 len)
+{
+ struct usb_device *usbdev =
+ ((struct rsi_91x_usbdev *)adapter->rsi_dev)->usbdev;
+
+ return rsi_usb_reg_write(usbdev, reg, value, len);
+}
+
+int rsi_usb_load_data_master_write(struct rsi_hw *adapter,
+ u32 base_address,
+ u32 instructions_sz,
+ u16 block_size,
+ u8 *ta_firmware)
+{
+ u16 num_blocks;
+ u32 cur_indx, ii;
+ u8 temp_buf[256];
+
+ num_blocks = instructions_sz / block_size;
+ rsi_dbg(INFO_ZONE, "num_blocks: %d\n", num_blocks);
+
+ for (cur_indx = 0, ii = 0;
+ ii < num_blocks;
+ ii++, cur_indx += block_size) {
+ memset(temp_buf, 0, block_size);
+ memcpy(temp_buf, ta_firmware + cur_indx, block_size);
+ if ((rsi_usb_write_register_multiple(adapter,
+ base_address,
+ (u8 *)(temp_buf),
+ block_size)) < 0)
+ return -1;
+
+ rsi_dbg(INFO_ZONE, "%s: loading block: %d\n", __func__, ii);
+ base_address += block_size;
+ }
+
+ if (instructions_sz % block_size) {
+ memset(temp_buf, 0, block_size);
+ memcpy(temp_buf, ta_firmware + cur_indx,
+ instructions_sz % block_size);
+ if ((rsi_usb_write_register_multiple(adapter,
+ base_address,
+ (u8 *)temp_buf,
+ instructions_sz % block_size)) < 0)
+ return -1;
+ rsi_dbg(INFO_ZONE,
+ "Written Last Block in Address 0x%x Successfully\n",
+ cur_indx);
+ }
+ return 0;
+}
+
/**
* rsi_deinit_usb_interface() - This function deinitializes the usb interface.
* @adapter: Pointer to the adapter structure.
@@ -416,6 +550,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
adapter->host_intf_write_pkt = rsi_usb_host_intf_write_pkt;
adapter->check_hw_queue_status = rsi_usb_check_queue_status;
adapter->determine_event_timeout = rsi_usb_event_timeout;
+ adapter->host_intf_ops = &usb_host_intf_ops;
rsi_init_event(&rsi_dev->rx_thread.event);
status = rsi_create_kthread(common, &rsi_dev->rx_thread,
@@ -456,7 +591,7 @@ static int rsi_probe(struct usb_interface *pfunction,
{
struct rsi_hw *adapter;
struct rsi_91x_usbdev *dev;
- u16 fw_status;
+ u32 fw_status;
int status;
rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__);
@@ -467,6 +602,7 @@ static int rsi_probe(struct usb_interface *pfunction,
__func__);
return -ENOMEM;
}
+ adapter->rsi_host_intf = RSI_HOST_INTF_USB;
status = rsi_init_usb_interface(adapter, pfunction);
if (status) {
@@ -480,25 +616,20 @@ static int rsi_probe(struct usb_interface *pfunction,
dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
status = rsi_usb_reg_read(dev->usbdev, FW_STATUS_REG, &fw_status, 2);
- if (status)
+ if (status < 0)
goto err1;
else
fw_status &= 1;
if (!fw_status) {
- status = rsi_usb_device_init(adapter->priv);
+ rsi_dbg(INIT_ZONE, "Loading firmware...\n");
+ status = rsi_hal_device_init(adapter, RSI_DEV_9113);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed in device init\n",
__func__);
goto err1;
}
-
- status = rsi_usb_reg_write(dev->usbdev,
- USB_INTERNAL_REG_1,
- RSI_USB_READY_MAGIC_NUM, 1);
- if (status)
- goto err1;
- rsi_dbg(INIT_ZONE, "%s: Performed device init\n", __func__);
+ rsi_dbg(INIT_ZONE, "%s: Device Init Done\n", __func__);
}
status = rsi_rx_urb_submit(adapter);
@@ -554,6 +685,7 @@ static const struct usb_device_id rsi_dev_table[] = {
{ USB_DEVICE(0x041B, 0x0301) },
{ USB_DEVICE(0x041B, 0x0201) },
{ USB_DEVICE(0x041B, 0x9330) },
+ { USB_DEVICE(0x1618, 0x9113) },
{ /* Blank */},
};
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
index de49008..d3e0a07 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c
@@ -19,67 +19,6 @@
#include "rsi_usb.h"
/**
- * rsi_copy_to_card() - This function includes the actual funtionality of
- * copying the TA firmware to the card.Basically this
- * function includes opening the TA file,reading the TA
- * file and writing their values in blocks of data.
- * @common: Pointer to the driver private structure.
- * @fw: Pointer to the firmware value to be written.
- * @len: length of firmware file.
- * @num_blocks: Number of blocks to be written to the card.
- *
- * Return: 0 on success and -1 on failure.
- */
-static int rsi_copy_to_card(struct rsi_common *common,
- const u8 *fw,
- u32 len,
- u32 num_blocks)
-{
- struct rsi_hw *adapter = common->priv;
- struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
- u32 indx, ii;
- u32 block_size = dev->tx_blk_size;
- u32 lsb_address;
- u32 base_address;
-
- base_address = TA_LOAD_ADDRESS;
-
- for (indx = 0, ii = 0; ii < num_blocks; ii++, indx += block_size) {
- lsb_address = base_address;
- if (rsi_usb_write_register_multiple(adapter,
- lsb_address,
- (u8 *)(fw + indx),
- block_size)) {
- rsi_dbg(ERR_ZONE,
- "%s: Unable to load %s blk\n", __func__,
- FIRMWARE_RSI9113);
- return -EIO;
- }
- rsi_dbg(INIT_ZONE, "%s: loading block: %d\n", __func__, ii);
- base_address += block_size;
- }
-
- if (len % block_size) {
- lsb_address = base_address;
- if (rsi_usb_write_register_multiple(adapter,
- lsb_address,
- (u8 *)(fw + indx),
- len % block_size)) {
- rsi_dbg(ERR_ZONE,
- "%s: Unable to load %s blk\n", __func__,
- FIRMWARE_RSI9113);
- return -EIO;
- }
- }
- rsi_dbg(INIT_ZONE,
- "%s: Succesfully loaded %s instructions\n", __func__,
- FIRMWARE_RSI9113);
-
- rsi_dbg(INIT_ZONE, "%s: loaded firmware\n", __func__);
- return 0;
-}
-
-/**
* rsi_usb_rx_thread() - This is a kernel thread to receive the packets from
* the USB device.
* @common: Pointer to the driver private structure.
@@ -119,67 +58,3 @@ void rsi_usb_rx_thread(struct rsi_common *common)
complete_and_exit(&dev->rx_thread.completion, 0);
}
-
-/**
- * rsi_load_ta_instructions() - This function includes the actual funtionality
- * of loading the TA firmware.This function also
- * includes opening the TA file,reading the TA
- * file and writing their value in blocks of data.
- * @common: Pointer to the driver private structure.
- *
- * Return: status: 0 on success, -1 on failure.
- */
-static int rsi_load_ta_instructions(struct rsi_common *common)
-{
- struct rsi_hw *adapter = common->priv;
- struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
- const struct firmware *fw_entry = NULL;
- u32 block_size = dev->tx_blk_size;
- const u8 *fw;
- u32 num_blocks, len;
- int status = 0;
-
- status = request_firmware(&fw_entry, FIRMWARE_RSI9113, adapter->device);
- if (status < 0) {
- rsi_dbg(ERR_ZONE, "%s Firmware file %s not found\n",
- __func__, FIRMWARE_RSI9113);
- return status;
- }
-
- /* Copy firmware into DMA-accessible memory */
- fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
- if (!fw) {
- status = -ENOMEM;
- goto out;
- }
- len = fw_entry->size;
-
- if (len % 4)
- len += (4 - (len % 4));
-
- num_blocks = (len / block_size);
-
- rsi_dbg(INIT_ZONE, "%s: Instruction size:%d\n", __func__, len);
- rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks);
-
- status = rsi_copy_to_card(common, fw, len, num_blocks);
- kfree(fw);
-
-out:
- release_firmware(fw_entry);
- return status;
-}
-
-/**
- * rsi_device_init() - This Function Initializes The HAL.
- * @common: Pointer to the driver private structure.
- *
- * Return: 0 on success, -1 on failure.
- */
-int rsi_usb_device_init(struct rsi_common *common)
-{
- if (rsi_load_ta_instructions(common))
- return -EIO;
-
- return 0;
- }
diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h
index c7e8f2b..ad68f53 100644
--- a/drivers/net/wireless/rsi/rsi_sdio.h
+++ b/drivers/net/wireless/rsi/rsi_sdio.h
@@ -116,14 +116,14 @@ struct rsi_91x_sdiodev {
void rsi_interrupt_handler(struct rsi_hw *adapter);
int rsi_init_sdio_slave_regs(struct rsi_hw *adapter);
-int rsi_sdio_device_init(struct rsi_common *common);
int rsi_sdio_read_register(struct rsi_hw *adapter, u32 addr, u8 *data);
int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter, u8 *pkt, u32 length);
int rsi_sdio_write_register(struct rsi_hw *adapter, u8 function,
u32 addr, u8 *data);
int rsi_sdio_write_register_multiple(struct rsi_hw *adapter, u32 addr,
- u8 *data, u32 count);
+ u8 *data, u16 count);
void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit);
int rsi_sdio_determine_event_timeout(struct rsi_hw *adapter);
int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num);
+int rsi_sdio_master_access_msword(struct rsi_hw *adapter, u16 ms_word);
#endif
diff --git a/drivers/net/wireless/rsi/rsi_usb.h b/drivers/net/wireless/rsi/rsi_usb.h
index ebea0c4..afd58da 100644
--- a/drivers/net/wireless/rsi/rsi_usb.h
+++ b/drivers/net/wireless/rsi/rsi_usb.h
@@ -63,6 +63,18 @@ static inline int rsi_usb_event_timeout(struct rsi_hw *adapter)
int rsi_usb_device_init(struct rsi_common *common);
int rsi_usb_write_register_multiple(struct rsi_hw *adapter, u32 addr,
- u8 *data, u32 count);
+ u8 *data, u16 count);
void rsi_usb_rx_thread(struct rsi_common *common);
+int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter, u8 *pkt, u32 len);
+int rsi_usb_master_reg_read(struct rsi_hw *adapter, u32 reg,
+ u32 *value, u16 len);
+int rsi_usb_master_reg_write(struct rsi_hw *adapter, unsigned long reg,
+ unsigned long value, u16 len);
+int rsi_usb_read_register_multiple(struct rsi_hw *adapter, u32 addr,
+ u8 *data, u16 count);
+int rsi_usb_load_data_master_write(struct rsi_hw *adapter,
+ u32 base_address,
+ u32 instructions_sz,
+ u16 block_size,
+ u8 *ta_firmware);
#endif
--
2.4.11
^ permalink raw reply related
* [PATCH v2 1/2] net: rfkill: Cleanup error handling in rfkill_init()
From: Michał Kępień @ 2016-12-08 7:30 UTC (permalink / raw)
To: Johannes Berg, David S . Miller; +Cc: linux-wireless, netdev, linux-kernel
Use a separate label per error condition in rfkill_init() to make it a
bit cleaner and easier to extend.
Signed-off-by: Michał Kępień <kernel@kempniu.pl>
---
No changes from v1.
net/rfkill/core.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 884027f..f28e441 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -1266,24 +1266,25 @@ static int __init rfkill_init(void)
error = class_register(&rfkill_class);
if (error)
- goto out;
+ goto error_class;
error = misc_register(&rfkill_miscdev);
- if (error) {
- class_unregister(&rfkill_class);
- goto out;
- }
+ if (error)
+ goto error_misc;
#ifdef CONFIG_RFKILL_INPUT
error = rfkill_handler_init();
- if (error) {
- misc_deregister(&rfkill_miscdev);
- class_unregister(&rfkill_class);
- goto out;
- }
+ if (error)
+ goto error_input;
#endif
- out:
+ return 0;
+
+error_input:
+ misc_deregister(&rfkill_miscdev);
+error_misc:
+ class_unregister(&rfkill_class);
+error_class:
return error;
}
subsys_initcall(rfkill_init);
--
2.10.2
^ permalink raw reply related
* [PATCH v2 2/2] net: rfkill: Add rfkill-any LED trigger
From: Michał Kępień @ 2016-12-08 7:30 UTC (permalink / raw)
To: Johannes Berg, David S . Miller; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <20161208073052.12988-1-kernel@kempniu.pl>
Add a new "global" (i.e. not per-rfkill device) LED trigger, rfkill-any,
which may be useful on laptops with a single "radio LED" and multiple
radio transmitters. The trigger is meant to turn a LED on whenever
there is at least one radio transmitter active and turn it off
otherwise.
Signed-off-by: Michał Kępień <kernel@kempniu.pl>
---
Changes from v1:
- take rfkill_global_mutex before calling rfkill_set_block() in
rfkill_resume(); the need for doing this was previously obviated by
908209c ("rfkill: don't impose global states on resume"), but given
that __rfkill_any_led_trigger_event() is called from
rfkill_set_block() unconditionally, each caller of the latter needs
to take care of locking rfkill_global_mutex,
- declare __rfkill_any_led_trigger_event() even when
CONFIG_RFKILL_LEDS=n to prevent implicit declaration errors,
- remove the #ifdef surrounding rfkill_any_led_trigger_{,un}register()
calls to prevent compilation warnings about functions and a label
being defined but not used,
- move the rfkill_any_led_trigger_register() call in rfkill_init()
before the rfkill_handler_init() call to avoid the need to call
rfkill_handler_exit() from rfkill_init() and thus prevent a section
mismatch.
net/rfkill/core.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index f28e441..cd50b11 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -176,6 +176,47 @@ static void rfkill_led_trigger_unregister(struct rfkill *rfkill)
{
led_trigger_unregister(&rfkill->led_trigger);
}
+
+static struct led_trigger rfkill_any_led_trigger;
+
+static void __rfkill_any_led_trigger_event(void)
+{
+ enum led_brightness brightness = LED_OFF;
+ struct rfkill *rfkill;
+
+ list_for_each_entry(rfkill, &rfkill_list, node) {
+ if (!(rfkill->state & RFKILL_BLOCK_ANY)) {
+ brightness = LED_FULL;
+ break;
+ }
+ }
+
+ led_trigger_event(&rfkill_any_led_trigger, brightness);
+}
+
+static void rfkill_any_led_trigger_event(void)
+{
+ mutex_lock(&rfkill_global_mutex);
+ __rfkill_any_led_trigger_event();
+ mutex_unlock(&rfkill_global_mutex);
+}
+
+static void rfkill_any_led_trigger_activate(struct led_classdev *led_cdev)
+{
+ rfkill_any_led_trigger_event();
+}
+
+static int rfkill_any_led_trigger_register(void)
+{
+ rfkill_any_led_trigger.name = "rfkill-any";
+ rfkill_any_led_trigger.activate = rfkill_any_led_trigger_activate;
+ return led_trigger_register(&rfkill_any_led_trigger);
+}
+
+static void rfkill_any_led_trigger_unregister(void)
+{
+ led_trigger_unregister(&rfkill_any_led_trigger);
+}
#else
static void rfkill_led_trigger_event(struct rfkill *rfkill)
{
@@ -189,6 +230,23 @@ static inline int rfkill_led_trigger_register(struct rfkill *rfkill)
static inline void rfkill_led_trigger_unregister(struct rfkill *rfkill)
{
}
+
+static void __rfkill_any_led_trigger_event(void)
+{
+}
+
+static void rfkill_any_led_trigger_event(void)
+{
+}
+
+static int rfkill_any_led_trigger_register(void)
+{
+ return 0;
+}
+
+static void rfkill_any_led_trigger_unregister(void)
+{
+}
#endif /* CONFIG_RFKILL_LEDS */
static void rfkill_fill_event(struct rfkill_event *ev, struct rfkill *rfkill,
@@ -297,6 +355,7 @@ static void rfkill_set_block(struct rfkill *rfkill, bool blocked)
spin_unlock_irqrestore(&rfkill->lock, flags);
rfkill_led_trigger_event(rfkill);
+ __rfkill_any_led_trigger_event();
if (prev != curr)
rfkill_event(rfkill);
@@ -477,6 +536,7 @@ bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
spin_unlock_irqrestore(&rfkill->lock, flags);
rfkill_led_trigger_event(rfkill);
+ rfkill_any_led_trigger_event();
if (!rfkill->registered)
return ret;
@@ -523,6 +583,7 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)
schedule_work(&rfkill->uevent_work);
rfkill_led_trigger_event(rfkill);
+ rfkill_any_led_trigger_event();
return blocked;
}
@@ -572,6 +633,7 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)
schedule_work(&rfkill->uevent_work);
rfkill_led_trigger_event(rfkill);
+ rfkill_any_led_trigger_event();
}
}
EXPORT_SYMBOL(rfkill_set_states);
@@ -815,8 +877,10 @@ static int rfkill_resume(struct device *dev)
rfkill->suspended = false;
if (!rfkill->persistent) {
+ mutex_lock(&rfkill_global_mutex);
cur = !!(rfkill->state & RFKILL_BLOCK_SW);
rfkill_set_block(rfkill, cur);
+ mutex_unlock(&rfkill_global_mutex);
}
if (rfkill->ops->poll && !rfkill->polling_paused)
@@ -988,6 +1052,7 @@ int __must_check rfkill_register(struct rfkill *rfkill)
#endif
}
+ __rfkill_any_led_trigger_event();
rfkill_send_events(rfkill, RFKILL_OP_ADD);
mutex_unlock(&rfkill_global_mutex);
@@ -1020,6 +1085,7 @@ void rfkill_unregister(struct rfkill *rfkill)
mutex_lock(&rfkill_global_mutex);
rfkill_send_events(rfkill, RFKILL_OP_DEL);
list_del_init(&rfkill->node);
+ __rfkill_any_led_trigger_event();
mutex_unlock(&rfkill_global_mutex);
rfkill_led_trigger_unregister(rfkill);
@@ -1272,6 +1338,10 @@ static int __init rfkill_init(void)
if (error)
goto error_misc;
+ error = rfkill_any_led_trigger_register();
+ if (error)
+ goto error_led_trigger;
+
#ifdef CONFIG_RFKILL_INPUT
error = rfkill_handler_init();
if (error)
@@ -1281,6 +1351,8 @@ static int __init rfkill_init(void)
return 0;
error_input:
+ rfkill_any_led_trigger_unregister();
+error_led_trigger:
misc_deregister(&rfkill_miscdev);
error_misc:
class_unregister(&rfkill_class);
@@ -1294,6 +1366,7 @@ static void __exit rfkill_exit(void)
#ifdef CONFIG_RFKILL_INPUT
rfkill_handler_exit();
#endif
+ rfkill_any_led_trigger_unregister();
misc_deregister(&rfkill_miscdev);
class_unregister(&rfkill_class);
}
--
2.10.2
^ permalink raw reply related
* Re: Non-working mwifiex_sdio with SD8897
From: Takashi Iwai @ 2016-12-08 10:18 UTC (permalink / raw)
To: Amitkumar Karwar
Cc: Nishant Sarmukadam, linux-wireless@vger.kernel.org, Oliver Neukum
In-Reply-To: <d7abecd9e9074f53bd1369cdd93d3472@SC-EXCH04.marvell.com>
[-- Attachment #1: Type: text/plain, Size: 5439 bytes --]
Hi Amitkumar,
On Thu, 08 Dec 2016 06:40:48 +0100,
Amitkumar Karwar wrote:
>
> Hi Takashi,
>
> > From: Takashi Iwai [mailto:tiwai@suse.de]
> > Sent: Friday, December 02, 2016 10:19 PM
> > To: Amitkumar Karwar; Nishant Sarmukadam
> > Cc: linux-wireless@vger.kernel.org; Oliver Neukum
> > Subject: Non-working mwifiex_sdio with SD8897
> >
> > Hi,
> >
> > we've got an Intel Cherry Trail-based system with Marvell SD8897 chip
> > over MMC (sdhci), and WiFi / BT always fails at starting (or better to
> > say, it never worked properly).
> >
> > For avoiding the race between WiFi and BT, I blacklisted btmrvl_sdio,
> > so let's concentrate only on mwifiex_sdio now.
> >
> > At the beginning of the driver loading, it looks fine:
> >
> > mwifiex_sdio mmc1:0001:1: info: FW download over, size 802164 bytes
> > mwifiex_sdio mmc1:0001:1: WLAN FW is active mwifiex_sdio mmc1:0001:1:
> > info: MWIFIEX VERSION: mwifiex 1.0 (15.68.7.p77) mwifiex_sdio
> > mmc1:0001:1: driver_version = mwifiex 1.0 (15.68.7.p77)
> > cfg80211: Regulatory domain changed to country: US .....
> >
> > Then it gets a timeout
> >
> > mwifiex_sdio mmc1:0001:1: mwifiex_cmd_timeout_func: Timeout cmd id =
> > 0x107, act = 0x0 mwifiex_sdio mmc1:0001:1: num_data_h2c_failure = 0
> > mwifiex_sdio mmc1:0001:1: num_cmd_h2c_failure = 0 mwifiex_sdio
> > mmc1:0001:1: is_cmd_timedout = 1 mwifiex_sdio mmc1:0001:1:
> > num_tx_timeout = 0 mwifiex_sdio mmc1:0001:1: last_cmd_index = 4
> > mwifiex_sdio mmc1:0001:1: last_cmd_id: 1e 00 0c 01 1e 00 20 00 07 01
> > mwifiex_sdio mmc1:0001:1: last_cmd_act: 00 00 01 00 00 00 08 00 00 00
> > mwifiex_sdio mmc1:0001:1: last_cmd_resp_index = 3 mwifiex_sdio
> > mmc1:0001:1: last_cmd_resp_id: 1e 80 0c 81 1e 80 20 80 20 80
> > mwifiex_sdio mmc1:0001:1: last_event_index = 1 mwifiex_sdio
> > mmc1:0001:1: last_event: 00 00 0b 00 00 00 00 00 00 00 mwifiex_sdio
> > mmc1:0001:1: data_sent=0 cmd_sent=0 mwifiex_sdio mmc1:0001:1:
> > ps_mode=1 ps_state=1 mwifiex_sdio mmc1:0001:1: ===mwifiex driverinfo
> > dump start=== mwifiex_sdio mmc1:0001:1: info: MWIFIEX VERSION: mwifiex
> > 1.0 (15.68.7.p77) mwifiex_sdio mmc1:0001:1: SDIO register dump start
> > mwifiex_sdio mmc1:0001:1: SDIO Func0 (0x0-0x9): 43 03 02 02 03 02 00 02
> > 03 00 mwifiex_sdio mmc1:0001:1: SDIO Func1 (0x0-0xb): 02 ff c3 40 00
> > 00 00 00 ff ff ff ff mwifiex_sdio mmc1:0001:1: SDIO Func1: (0x4c) 00
> > (0x50) 08 (0x54) 07 (0x55) 0c (0x58) 10 (0x59) 00 (0x5c) 00 (0x5d) 00
> > mwifiex_sdio mmc1:0001:1: SDIO Func1 (0xc0-0xca): dc fe 6c 00 10 00 3f
> > 36 36 02 20 mwifiex_sdio mmc1:0001:1: SDIO Func1 (0xc0-0xca): dc fe 76
> > 00 1a 00 3f 36 36 02 20 mwifiex_sdio mmc1:0001:1: SDIO register dump
> > end mwifiex_sdio mmc1:0001:1: ===mwifiex driverinfo dump end===
> > mwifiex_sdio mmc1:0001:1: == mwifiex firmware dump start ==
> > mwifiex_sdio mmc1:0001:1: Ignore scan. Card removed or firmware in bad
> > state mwifiex_sdio mmc1:0001:1: scan failed: -14 mwifiex_sdio
> > mmc1:0001:1: == mwifiex firmware dump end == mwifiex_sdio mmc1:0001:1:
> > == mwifiex dump information to /sys/class/devcoredump start
> > mwifiex_sdio mmc1:0001:1: == mwifiex dump information to
> > /sys/class/devcoredump end
> >
>
> Could you please try attached 7.p87 firmware? I will be submitting it upstream soon.
Thanks! I tried it, but unfortunately the issue still remains.
> If it doesn't help, please share devcoredump logs for analysis.
>
> Here is the procedure to collect it. Issue below command within 5 minutes when "mwifiex dump information to
> > /sys/class/devcoredump end" message is displayed.
>
> cat /sys/class/devcoredump/devcd*/data > data.txt
Below is the data I got after the reboot.
One interesting thing is that sometimes the coredump isn't triggered
even after the failure, typically after the cold boot:
[ 8.186609] mwifiex_sdio mmc1:0001:1: info: FW download over, size 800344 bytes
[ 8.962342] mwifiex_sdio mmc1:0001:1: WLAN FW is active
[ 10.560374] r8169 0000:01:00.0 eth0: link up
[ 10.656031] NET: Registered protocol family 17
[ 10.933670] fuse init (API version 7.23)
[ 18.975002] mwifiex_sdio mmc1:0001:1: mwifiex_cmd_timeout_func: Timeout cmd id = 0xa9, act = 0x0
[ 18.975034] mwifiex_sdio mmc1:0001:1: num_data_h2c_failure = 0
[ 18.975042] mwifiex_sdio mmc1:0001:1: num_cmd_h2c_failure = 0
[ 18.975050] mwifiex_sdio mmc1:0001:1: is_cmd_timedout = 1
[ 18.975057] mwifiex_sdio mmc1:0001:1: num_tx_timeout = 0
[ 18.975064] mwifiex_sdio mmc1:0001:1: last_cmd_index = 1
[ 18.975074] mwifiex_sdio mmc1:0001:1: last_cmd_id: 00 00 a9 00 00 00 00 00 00 00
[ 18.975082] mwifiex_sdio mmc1:0001:1: last_cmd_act: 00 00 00 00 00 00 00 00 00 00
[ 18.975089] mwifiex_sdio mmc1:0001:1: last_cmd_resp_index = 0
[ 18.975096] mwifiex_sdio mmc1:0001:1: last_cmd_resp_id: 00 00 00 00 00 00 00 00 00 00
[ 18.975106] mwifiex_sdio mmc1:0001:1: last_event_index = 0
[ 18.975113] mwifiex_sdio mmc1:0001:1: last_event: 00 00 00 00 00 00 00 00 00 00
[ 18.975121] mwifiex_sdio mmc1:0001:1: data_sent=1 cmd_sent=0
[ 18.975131] mwifiex_sdio mmc1:0001:1: ps_mode=0 ps_state=0
[ 19.026928] mwifiex_sdio mmc1:0001:1: info: mwifiex_fw_dpc: unregister device
[ 19.027449] mmc1:0001:1: pending IRQ with no handler
[ 19.027503] mmc1:0001:1: pending IRQ with no handler
[ 19.027546] mwifiex: info: mwifiex_free_adapter: free adapter
If you need any other information, let me know.
thanks,
Takashi
---
[-- Attachment #2: mw-dump-4.9-warm-reboot.txt.gz --]
[-- Type: application/octet-stream, Size: 85263 bytes --]
[-- Attachment #3: mw-dump-4.9-warm-reboot2.txt.gz --]
[-- Type: application/octet-stream, Size: 85477 bytes --]
[-- Attachment #4: mw-dump-4.4-warm-reboot.txt.gz --]
[-- Type: application/octet-stream, Size: 84800 bytes --]
^ permalink raw reply
* Re: [PATCH 1/1] orinoco: fix improper return value
From: Arend Van Spriel @ 2016-12-08 10:30 UTC (permalink / raw)
To: Pan Bian, Kalle Valo, linux-wireless, netdev; +Cc: linux-kernel
In-Reply-To: <1481157602-4011-1-git-send-email-bianpan2016@163.com>
On 8-12-2016 1:40, Pan Bian wrote:
> Function orinoco_ioctl_commit() returns 0 (indicates success) when the
> call to orinoco_lock() fails. Thus, the return value is inconsistent with
> the execution status. It may be better to return "-EBUSY" when the call
> to orinoco_lock() fails.
>
> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=188671
>
> Signed-off-by: Pan Bian <bianpan2016@163.com>
> ---
> drivers/net/wireless/intersil/orinoco/wext.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/intersil/orinoco/wext.c b/drivers/net/wireless/intersil/orinoco/wext.c
> index 1d4dae4..fee57ea 100644
> --- a/drivers/net/wireless/intersil/orinoco/wext.c
> +++ b/drivers/net/wireless/intersil/orinoco/wext.c
> @@ -1314,7 +1314,7 @@ static int orinoco_ioctl_commit(struct net_device *dev,
> return 0;
>
> if (orinoco_lock(priv, &flags) != 0)
> - return err;
> + return -EBUSY;
Actually, orinoco_lock will return either -EBUSY or 0 so maybe better to
just do:
err = orinoco_lock(priv, &flags);
if (err < 0)
return err;
Regards,
Arend
> err = orinoco_commit(priv);
>
>
^ permalink raw reply
* Re: Non-working mwifiex_sdio with SD8897
From: Takashi Iwai @ 2016-12-08 10:37 UTC (permalink / raw)
To: Amitkumar Karwar
Cc: Nishant Sarmukadam, linux-wireless@vger.kernel.org, Oliver Neukum
In-Reply-To: <s5h8trqohao.wl-tiwai@suse.de>
On Thu, 08 Dec 2016 11:18:23 +0100,
Takashi Iwai wrote:
>
> Hi Amitkumar,
>
> On Thu, 08 Dec 2016 06:40:48 +0100,
> Amitkumar Karwar wrote:
> >
> > Hi Takashi,
> >
> > > From: Takashi Iwai [mailto:tiwai@suse.de]
> > > Sent: Friday, December 02, 2016 10:19 PM
> > > To: Amitkumar Karwar; Nishant Sarmukadam
> > > Cc: linux-wireless@vger.kernel.org; Oliver Neukum
> > > Subject: Non-working mwifiex_sdio with SD8897
> > >
> > > Hi,
> > >
> > > we've got an Intel Cherry Trail-based system with Marvell SD8897 chip
> > > over MMC (sdhci), and WiFi / BT always fails at starting (or better to
> > > say, it never worked properly).
> > >
> > > For avoiding the race between WiFi and BT, I blacklisted btmrvl_sdio,
> > > so let's concentrate only on mwifiex_sdio now.
> > >
> > > At the beginning of the driver loading, it looks fine:
> > >
> > > mwifiex_sdio mmc1:0001:1: info: FW download over, size 802164 bytes
> > > mwifiex_sdio mmc1:0001:1: WLAN FW is active mwifiex_sdio mmc1:0001:1:
> > > info: MWIFIEX VERSION: mwifiex 1.0 (15.68.7.p77) mwifiex_sdio
> > > mmc1:0001:1: driver_version = mwifiex 1.0 (15.68.7.p77)
> > > cfg80211: Regulatory domain changed to country: US .....
> > >
> > > Then it gets a timeout
> > >
> > > mwifiex_sdio mmc1:0001:1: mwifiex_cmd_timeout_func: Timeout cmd id =
> > > 0x107, act = 0x0 mwifiex_sdio mmc1:0001:1: num_data_h2c_failure = 0
> > > mwifiex_sdio mmc1:0001:1: num_cmd_h2c_failure = 0 mwifiex_sdio
> > > mmc1:0001:1: is_cmd_timedout = 1 mwifiex_sdio mmc1:0001:1:
> > > num_tx_timeout = 0 mwifiex_sdio mmc1:0001:1: last_cmd_index = 4
> > > mwifiex_sdio mmc1:0001:1: last_cmd_id: 1e 00 0c 01 1e 00 20 00 07 01
> > > mwifiex_sdio mmc1:0001:1: last_cmd_act: 00 00 01 00 00 00 08 00 00 00
> > > mwifiex_sdio mmc1:0001:1: last_cmd_resp_index = 3 mwifiex_sdio
> > > mmc1:0001:1: last_cmd_resp_id: 1e 80 0c 81 1e 80 20 80 20 80
> > > mwifiex_sdio mmc1:0001:1: last_event_index = 1 mwifiex_sdio
> > > mmc1:0001:1: last_event: 00 00 0b 00 00 00 00 00 00 00 mwifiex_sdio
> > > mmc1:0001:1: data_sent=0 cmd_sent=0 mwifiex_sdio mmc1:0001:1:
> > > ps_mode=1 ps_state=1 mwifiex_sdio mmc1:0001:1: ===mwifiex driverinfo
> > > dump start=== mwifiex_sdio mmc1:0001:1: info: MWIFIEX VERSION: mwifiex
> > > 1.0 (15.68.7.p77) mwifiex_sdio mmc1:0001:1: SDIO register dump start
> > > mwifiex_sdio mmc1:0001:1: SDIO Func0 (0x0-0x9): 43 03 02 02 03 02 00 02
> > > 03 00 mwifiex_sdio mmc1:0001:1: SDIO Func1 (0x0-0xb): 02 ff c3 40 00
> > > 00 00 00 ff ff ff ff mwifiex_sdio mmc1:0001:1: SDIO Func1: (0x4c) 00
> > > (0x50) 08 (0x54) 07 (0x55) 0c (0x58) 10 (0x59) 00 (0x5c) 00 (0x5d) 00
> > > mwifiex_sdio mmc1:0001:1: SDIO Func1 (0xc0-0xca): dc fe 6c 00 10 00 3f
> > > 36 36 02 20 mwifiex_sdio mmc1:0001:1: SDIO Func1 (0xc0-0xca): dc fe 76
> > > 00 1a 00 3f 36 36 02 20 mwifiex_sdio mmc1:0001:1: SDIO register dump
> > > end mwifiex_sdio mmc1:0001:1: ===mwifiex driverinfo dump end===
> > > mwifiex_sdio mmc1:0001:1: == mwifiex firmware dump start ==
> > > mwifiex_sdio mmc1:0001:1: Ignore scan. Card removed or firmware in bad
> > > state mwifiex_sdio mmc1:0001:1: scan failed: -14 mwifiex_sdio
> > > mmc1:0001:1: == mwifiex firmware dump end == mwifiex_sdio mmc1:0001:1:
> > > == mwifiex dump information to /sys/class/devcoredump start
> > > mwifiex_sdio mmc1:0001:1: == mwifiex dump information to
> > > /sys/class/devcoredump end
> > >
> >
> > Could you please try attached 7.p87 firmware? I will be submitting it upstream soon.
>
> Thanks! I tried it, but unfortunately the issue still remains.
It seems that the problem is rather in the MMC / SDIO side.
When the power management of the SD host PCI controller is turned off
(i.e. echo on > /sys/devices/pci0000:00/0000:00:11.0/power/control),
the WiFi starts working.
I'm not sure whether it's a bug in sdhci driver or something else
missing. In anyway, thank you for your help!
Takashi
^ permalink raw reply
* Re: [PATCH 10/14] rtlwifi: Add BTC_TRACE_STRING to new btcoex
From: Kalle Valo @ 2016-12-08 11:43 UTC (permalink / raw)
To: Dan Carpenter; +Cc: Greg KH, devel, Ping-Ke Shih, linux-wireless, Larry Finger
In-Reply-To: <20161207133219.GM8176@mwanda>
Dan Carpenter <dan.carpenter@oracle.com> writes:
> On Wed, Dec 07, 2016 at 02:16:06PM +0200, Kalle Valo wrote:
>> We have disccused this before, but for wireless it's not really that
>> simple. AFAIK with dyndbg you can only control the messages per line
>> (painful to enable group of messages) or per file (enables too many
>> messages). In wireless we have cases when we need to enable group of
>> messages, but not all.
>
> You can turn them on by the function or a range of lines, then disable
> the spammy lines. With these new debug macros you can't do that so this
> is a step backwards.
>From my point of view dyndbg is step backwards. Line numbers change all
the time and you can't have simple instructions like this for users and
developers working with the driver:
https://wireless.wiki.kernel.org/en/users/drivers/ath10k/debug#debug_log_messages
I don't want waste time with this anymore as we seem to just disagree.
My point here was that in wireless we have used log wrappers before and
will continue to use them in certain drivers as dyndbg is not enough.
But it would make me very happy if someone would add a similar grouping
functionality to dyndbg to make it easy to enable a set of debug
messages in a driver.
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH 10/14] rtlwifi: Add BTC_TRACE_STRING to new btcoex
From: Dan Carpenter @ 2016-12-08 11:50 UTC (permalink / raw)
To: Kalle Valo; +Cc: devel, Ping-Ke Shih, linux-wireless, Larry Finger
In-Reply-To: <87y3zqbq8h.fsf@kamboji.qca.qualcomm.com>
I don't have a problem with the ath debug printks. Larry asked me for
examples of better debug functions and the ath code is an example.
Literally, any existing debug functions are better than the
BTC_TRACE_STRING() stuff.
On Thu, Dec 08, 2016 at 01:43:42PM +0200, Kalle Valo wrote:
> But it would make me very happy if someone would add a similar grouping
> functionality to dyndbg to make it easy to enable a set of debug
> messages in a driver.
Thats seems like a reasonable thing as well.
regards,
dan carpenter
^ permalink raw reply
* Re: [PATCH 10/14] rtlwifi: Add BTC_TRACE_STRING to new btcoex
From: Dan Carpenter @ 2016-12-08 11:54 UTC (permalink / raw)
To: Kalle Valo; +Cc: devel, Ping-Ke Shih, linux-wireless, Larry Finger
In-Reply-To: <20161208115049.GR8176@mwanda>
On Thu, Dec 08, 2016 at 02:50:49PM +0300, Dan Carpenter wrote:
> On Thu, Dec 08, 2016 at 01:43:42PM +0200, Kalle Valo wrote:
> > But it would make me very happy if someone would add a similar grouping
> > functionality to dyndbg to make it easy to enable a set of debug
> > messages in a driver.
>
> Thats seems like a reasonable thing as well.
I actually like the ath code... We could easily change it to be more
generic and make it a top level function for everyone to use.
regards,
dan carpenter
^ permalink raw reply
* wireless-drivers-next is closed for 4.10
From: Kalle Valo @ 2016-12-08 12:53 UTC (permalink / raw)
To: linux-wireless
In-Reply-To: <87oa0zwymr.fsf@kamboji.qca.qualcomm.com>
Kalle Valo <kvalo@codeaurora.org> writes:
> Linus said that he will release 4.9 either next Sunday or a week after,
> which means that the merge window is getting close. If there's something
> you absolutely need to have in 4.10 better send them NOW to not miss the
> window.
Dave closed net-next earlier than normally so wireless-drivers-next is
closed as well:
https://www.spinics.net/lists/netdev/msg409280.html
I had two patches pending in w-d-next but now I'll need to submit those
to net-next after the merge window and they will go to 4.11.
> Important bug fixes can go to 4.10 also after the merge window, but not
> new features.
wireless-drivers is open for bug fixes going to 4.10.
--
Kalle Valo
^ permalink raw reply
* [PATCH] cfg80211/mac80211: fix BSS leaks when abandoning assoc attempts
From: Johannes Berg @ 2016-12-08 16:28 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
When mac80211 abandons an association attempt, it may free
all the data structures, but inform cfg80211 and userspace
about it only by sending the deauth frame it received, in
which case cfg80211 has no link to the BSS struct that was
used and will not cfg80211_unhold_bss() it.
Fix this by providing a way to inform cfg80211 of this with
the BSS entry passed, so that it can clean up properly, and
use this ability in the appropriate places in mac80211.
This isn't ideal: some code is more or less duplicated and
tracing is missing. However, it's a fairly small change and
it's thus easier to backport - cleanups can come later.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/net/cfg80211.h | 11 +++++++++++
net/mac80211/mlme.c | 21 ++++++++++++---------
net/wireless/core.h | 1 +
net/wireless/mlme.c | 12 ++++++++++++
net/wireless/sme.c | 14 ++++++++++++++
5 files changed, 50 insertions(+), 9 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ef42749f785f..ca2ac1ce5862 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -4675,6 +4675,17 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss);
/**
+ * cfg80211_abandon_assoc - notify cfg80211 of abandoned association attempt
+ * @dev: network device
+ * @bss: The BSS entry with which association was abandoned.
+ *
+ * Call this whenever - for reasons reported through other API, like deauth RX,
+ * an association attempt was abandoned.
+ * This function may sleep. The caller must hold the corresponding wdev's mutex.
+ */
+void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss);
+
+/**
* cfg80211_tx_mlme_mgmt - notification of transmitted deauth/disassoc frame
* @dev: network device
* @buf: 802.11 frame (header + body)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 68172d5d2ca0..8a6344518674 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2514,7 +2514,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
}
static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
- bool assoc)
+ bool assoc, bool abandon)
{
struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
@@ -2537,6 +2537,9 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
mutex_lock(&sdata->local->mtx);
ieee80211_vif_release_channel(sdata);
mutex_unlock(&sdata->local->mtx);
+
+ if (abandon)
+ cfg80211_abandon_assoc(sdata->dev, assoc_data->bss);
}
kfree(assoc_data);
@@ -2769,7 +2772,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
bssid, reason_code,
ieee80211_get_reason_code_string(reason_code));
- ieee80211_destroy_assoc_data(sdata, false);
+ ieee80211_destroy_assoc_data(sdata, false, true);
cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
return;
@@ -3178,14 +3181,14 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
if (status_code != WLAN_STATUS_SUCCESS) {
sdata_info(sdata, "%pM denied association (code=%d)\n",
mgmt->sa, status_code);
- ieee80211_destroy_assoc_data(sdata, false);
+ ieee80211_destroy_assoc_data(sdata, false, false);
event.u.mlme.status = MLME_DENIED;
event.u.mlme.reason = status_code;
drv_event_callback(sdata->local, sdata, &event);
} else {
if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) {
/* oops -- internal error -- send timeout for now */
- ieee80211_destroy_assoc_data(sdata, false);
+ ieee80211_destroy_assoc_data(sdata, false, false);
cfg80211_assoc_timeout(sdata->dev, bss);
return;
}
@@ -3198,7 +3201,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
* recalc after assoc_data is NULL but before associated
* is set can cause the interface to go idle
*/
- ieee80211_destroy_assoc_data(sdata, true);
+ ieee80211_destroy_assoc_data(sdata, true, false);
/* get uapsd queues configuration */
uapsd_queues = 0;
@@ -3897,7 +3900,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
.u.mlme.status = MLME_TIMEOUT,
};
- ieee80211_destroy_assoc_data(sdata, false);
+ ieee80211_destroy_assoc_data(sdata, false, false);
cfg80211_assoc_timeout(sdata->dev, bss);
drv_event_callback(sdata->local, sdata, &event);
}
@@ -4036,7 +4039,7 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)
WLAN_REASON_DEAUTH_LEAVING,
false, frame_buf);
if (ifmgd->assoc_data)
- ieee80211_destroy_assoc_data(sdata, false);
+ ieee80211_destroy_assoc_data(sdata, false, true);
if (ifmgd->auth_data)
ieee80211_destroy_auth_data(sdata, false);
cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
@@ -4945,7 +4948,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
IEEE80211_STYPE_DEAUTH,
req->reason_code, tx,
frame_buf);
- ieee80211_destroy_assoc_data(sdata, false);
+ ieee80211_destroy_assoc_data(sdata, false, true);
ieee80211_report_disconnect(sdata, frame_buf,
sizeof(frame_buf), true,
req->reason_code);
@@ -5020,7 +5023,7 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
sdata_lock(sdata);
if (ifmgd->assoc_data) {
struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
- ieee80211_destroy_assoc_data(sdata, false);
+ ieee80211_destroy_assoc_data(sdata, false, false);
cfg80211_assoc_timeout(sdata->dev, bss);
}
if (ifmgd->auth_data)
diff --git a/net/wireless/core.h b/net/wireless/core.h
index fb2fcd5581fe..9820fa251daa 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -409,6 +409,7 @@ void cfg80211_sme_disassoc(struct wireless_dev *wdev);
void cfg80211_sme_deauth(struct wireless_dev *wdev);
void cfg80211_sme_auth_timeout(struct wireless_dev *wdev);
void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev);
+void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev);
/* internal helpers */
bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index bd1f7a159d6a..4646cf5695b9 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -149,6 +149,18 @@ void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss)
}
EXPORT_SYMBOL(cfg80211_assoc_timeout);
+void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss)
+{
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct wiphy *wiphy = wdev->wiphy;
+
+ cfg80211_sme_abandon_assoc(wdev);
+
+ cfg80211_unhold_bss(bss_from_pub(bss));
+ cfg80211_put_bss(wiphy, bss);
+}
+EXPORT_SYMBOL(cfg80211_abandon_assoc);
+
void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 2b5bb380414b..5e0d19380302 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -39,6 +39,7 @@ struct cfg80211_conn {
CFG80211_CONN_ASSOCIATING,
CFG80211_CONN_ASSOC_FAILED,
CFG80211_CONN_DEAUTH,
+ CFG80211_CONN_ABANDON,
CFG80211_CONN_CONNECTED,
} state;
u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
@@ -206,6 +207,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
NULL, 0,
WLAN_REASON_DEAUTH_LEAVING, false);
+ /* fall through */
+ case CFG80211_CONN_ABANDON:
/* free directly, disconnected event already sent */
cfg80211_sme_free(wdev);
return 0;
@@ -423,6 +426,17 @@ void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
schedule_work(&rdev->conn_work);
}
+void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev)
+{
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+
+ if (!wdev->conn)
+ return;
+
+ wdev->conn->state = CFG80211_CONN_ABANDON;
+ schedule_work(&rdev->conn_work);
+}
+
static int cfg80211_sme_get_conn_ies(struct wireless_dev *wdev,
const u8 *ies, size_t ies_len,
const u8 **out_ies, size_t *out_ies_len)
--
2.9.3
^ permalink raw reply related
* Re: ATH9 driver issues on ARM64
From: Kalle Valo @ 2016-12-08 17:36 UTC (permalink / raw)
To: Bharat Kumar Gogada
Cc: Bjorn Helgaas, linux-kernel@vger.kernel.org,
linux-pci@vger.kernel.org, Marc Zyngier,
Janusz.Dziedzic@tieto.com, rmanohar@qti.qualcomm.com,
ath9k-devel@qca.qualcomm.com, linux-wireless
In-Reply-To: <8520D5D51A55D047800579B094147198263A72F5@XAP-PVEXMBX02.xlnx.xilinx.com>
Bharat Kumar Gogada <bharat.kumar.gogada@xilinx.com> writes:
> > [+cc Kalle, ath9k list]
Thanks, but please also CC linux-wireless. Full thread below for the
folks there.
>> On Thu, Dec 08, 2016 at 01:49:42PM +0000, Bharat Kumar Gogada wrote:
>> > Hi,
>> >
>> > Did anyone test Atheros ATH9 driver(drivers/net/wireless/ath/ath9k/)
>> > on ARM64. The end point is TP link wifi card with which supports
>> > only legacy interrupts.
>>
>> If it works on other arches and the arm64 PCI enumeration works, my
>> first guess would be an INTx issue, e.g., maybe the driver is waiting
>> for an interrupt that never arrives.
> We are not sure for now.
>>
>> > We are trying to test it on ARM64 with
>> > (drivers/pci/host/pcie-xilinx-nwl.c) as root port.
>> >
>> > EP is getting enumerated and able to link up.
>> >
>> > But when we start scan system gets hanged.
>>
>> When you say the system hangs when you start a scan, I assume you mean
>> a wifi scan, not the PCI enumeration. A problem with a wifi scan
>> might cause a *process* to hang, but it shouldn't hang the entire
>> system.
>>
> Yes wifi scan.
>> > When we took trace we see that after we start scan assert message is
>> > sent but there is no de assert from end point.
>>
>> Are you talking about a trace from a PCIe analyzer? Do you see an
>> Assert_INTx PCIe message on the link?
>>
> Yes lecroy trace, yes we do see Assert_INTx and Deassert_INTx happening when we do interface link up.
> When we have less debug prints in Atheros driver, and do wifi scan we see Assert_INTx but never Deassert_INTx,
>> > What might cause end point not sending de assert ?
>>
>> If the endpoint doesn't send a Deassert_INTx message, I expect that
>> would mean the driver didn't service the interrupt and remove the
>> condition that caused the device to assert the interrupt in the first
>> place.
>>
>> If the driver didn't receive the interrupt, it couldn't service it, of
>> course. You could add a printk in the ath9k interrupt service
>> routine to see if you ever get there.
>>
> The interrupt behavior is changing w.r.t amount of debug prints we add. (I kept many prints to aid debug)
> root@Xilinx-ZCU102-2016_3:~# iw dev wlan0 scan
> [ 83.064675] ath9k: ath9k_iowrite32 ffffff800a400024
> [ 83.069486] ath9k: ath9k_ioread32 ffffff800a400024
> [ 83.074257] ath9k_hw_kill_interrupts 793
> [ 83.078260] ath9k: ath9k_iowrite32 ffffff800a400024
> [ 83.083107] ath9k: ath9k_ioread32 ffffff800a400024
> [ 83.087882] ath9k_hw_kill_interrupts 793
> [ 83.095450] ath9k_hw_enable_interrupts 821
> [ 83.099557] ath9k_hw_enable_interrupts 825
> [ 83.103721] ath9k_hw_enable_interrupts 832
> [ 83.107887] ath9k: ath9k_iowrite32 ffffff800a400024
> [ 83.112748] AR_SREV_9100 0
> [ 83.115438] ath9k_hw_enable_interrupts 848
> [ 83.119607] ath9k: ath9k_ioread32 ffffff800a400024
> [ 83.124389] ath9k_hw_intrpend 762
> [ 83.127761] (AR_SREV_9340(ah) val 0
> [ 83.131234] ath9k_hw_intrpend 767
> [ 83.134628] ath_isr 603
> [ 83.137134] ath9k: ath9k_iowrite32 ffffff800a400024
> [ 83.141995] ath9k: ath9k_ioread32 ffffff800a400024
> [ 83.146771] ath9k_hw_kill_interrupts 793
> [ 83.150864] ath9k_hw_enable_interrupts 821
> [ 83.154971] ath9k_hw_enable_interrupts 825
> [ 83.159135] ath9k_hw_enable_interrupts 832
> [ 83.163300] ath9k: ath9k_iowrite32 ffffff800a400024
> [ 83.168161] AR_SREV_9100 0
> [ 83.170852] ath9k_hw_enable_interrupts 848
> [ 83.170855] ath9k_hw_intrpend 762
> [ 83.178398] (AR_SREV_9340(ah) val 0
> [ 83.181873] ath9k_hw_intrpend 767
> [ 83.185265] ath_isr 603
> [ 83.187773] ath9k: ath9k_iowrite32 ffffff800a400024
> [ 83.192635] ath9k: ath9k_ioread32 ffffff800a400024
> [ 83.197411] ath9k_hw_kill_interrupts 793
> [ 83.201414] ath9k: ath9k_ioread32 ffffff800a400024
> [ 83.206258] ath9k_hw_enable_interrupts 821
> [ 83.210368] ath9k_hw_enable_interrupts 825
> [ 83.214531] ath9k_hw_enable_interrupts 832
> [ 83.218698] ath9k: ath9k_iowrite32 ffffff800a400024
> [ 83.223558] AR_SREV_9100 0
> [ 83.226243] ath9k_hw_enable_interrupts 848
> [ 83.226246] ath9k_hw_intrpend 762
> [ 83.233794] (AR_SREV_9340(ah) val 0
> [ 83.237268] ath9k_hw_intrpend 767
> [ 83.240661] ath_isr 603
> [ 83.243169] ath9k: ath9k_iowrite32 ffffff800a400024
> [ 83.248030] ath9k: ath9k_ioread32 ffffff800a400024
> [ 83.252806] ath9k_hw_kill_interrupts 793
> [ 83.256811] ath9k: ath9k_ioread32 ffffff800a400024
> [ 83.261651] ath9k_hw_enable_interrupts 821
> [ 83.265753] ath9k_hw_enable_interrupts 825
> [ 83.269919] ath9k_hw_enable_interrupts 832
> [ 83.274083] ath9k: ath9k_iowrite32 ffffff800a400024
> [ 83.278945] AR_SREV_9100 0
> [ 83.281630] ath9k_hw_enable_interrupts 848
> [ 83.281633] ath9k_hw_intrpend 762
> [ 83.281634] (AR_SREV_9340(ah) val 0
> [ 83.281637] ath9k_hw_intrpend 767
> [ 83.281648] ath_isr 603
> [ 83.281649] ath9k: ath9k_iowrite32 ffffff800a400024
> [ 83.281651] ath9k: ath9k_ioread32 ffffff800a400024
> [ 83.281654] ath9k_hw_kill_interrupts 793
> [ 83.312192] ath9k: ath9k_ioread32 ffffff800a400024
> [ 83.317030] ath9k_hw_enable_interrupts 821
> [ 83.321132] ath9k_hw_enable_interrupts 825
> [ 83.325297] ath9k_hw_enable_interrupts 832
> [ 83.329463] ath9k: ath9k_iowrite32 ffffff800a400024
> [ 83.334324] AR_SREV_9100 0
> [ 83.337014] ath9k_hw_enable_interrupts 848
> ..
> ..
> This log continues until I turn off board without obtaining scanning result.
>
> In between I get following cpu stall outputs :
> 230.457179] INFO: rcu_sched self-detected stall on CPU
> [ 230.457185] 2-...: (31314 ticks this GP) idle=2d1/140000000000001/0 softirq=1400/1400 fqs=36713
> [ 230.457189] (t=36756 jiffies g=161 c=160 q=16169)
> [ 230.457191] Task dump for CPU 2:
> [ 230.457196] kworker/u8:4 R running task 0 1342 2 0x00000002
> [ 230.457207] Workqueue: phy0 ieee80211_scan_work
> [ 230.457208] Call trace:
> [ 230.457214] [<ffffff8008089860>] dump_backtrace+0x0/0x198
> [ 230.457219] [<ffffff8008089a0c>] show_stack+0x14/0x20
> [ 230.457224] [<ffffff80080c0930>] sched_show_task+0x98/0xf8
> [ 230.457228] [<ffffff80080c2628>] dump_cpu_task+0x40/0x50
> [ 230.457233] [<ffffff80080e14a8>] rcu_dump_cpu_stacks+0xa0/0xf0
> [ 230.457239] [<ffffff80080e4cd8>] rcu_check_callbacks+0x468/0x748
> [ 230.457243] [<ffffff80080e7cfc>] update_process_times+0x3c/0x68
> [ 230.457249] [<ffffff80080f6dfc>] tick_sched_handle.isra.5+0x3c/0x50
> [ 230.457253] [<ffffff80080f6e54>] tick_sched_timer+0x44/0x90
> [ 230.457257] [<ffffff80080e86b0>] __hrtimer_run_queues+0xf0/0x178
> ** 10 printk messages dropped ** [ 230.457302] f8c0: 0000000000000000 0000000005f5e0ff 000000000001379a 3866666666666620
> [ 230.457306] f8e0: ffffff800a1b4065 0000000000000006 ffffff800a129000 ffffffc87b8010a8
> [ 230.457310] f900: ffffff808a1b4057 ffffff800a1c3000 ffffff800a1b3000 ffffff800a13b000
> [ 230.457314] f920: 0000000000000140 0000000000000006 ffffff800a1b3b10 ffffff800a1c39e8
> [ 230.457318] f940: 000000000000002f ffffff800a1b8a98 ffffff800a1b3ae8 ffffffc87b07f990
> [ 230.457322] f960: ffffff80080d6230 ffffffc87b07f990 ffffff80080d6234 0000000060000145
> ** 1 printk messages dropped ** [ 230.457329] [<ffffff8008085720>] el1_irq+0xa0/0x100
> ** 9 printk messages dropped ** [ 230.457373] [<ffffff800885ad60>] ieee80211_hw_config+0x50/0x290
> [ 230.457377] [<ffffff8008863690>] ieee80211_scan_work+0x1f8/0x480
> [ 230.457383] [<ffffff80080b15d0>] process_one_work+0x120/0x378
> [ 230.457386] [<ffffff80080b1870>] worker_thread+0x48/0x4b0
> [ 230.457391] [<ffffff80080b7108>] kthread+0xd0/0xe8
> [ 230.457395] [<ffffff8008085dd0>] ret_from_fork+0x10/0x40
> [ 230.480389] ath9k_hw_intrpend 762
>
>
> [ 545.487987] ath9k: ath9k_ioread32 ffffff800a400024
> [ 545.526189] INFO: rcu_sched self-detected stall on CPU
> [ 545.526195] 2-...: (97636 ticks this GP) idle=2d1/140000000000001/0 softirq=1400/1400 fqs=115374
> [ 545.526199] (t=115523 jiffies g=161 c=160 q=51066)
> [ 545.526201] Task dump for CPU 2:
> [ 545.526206] kworker/u8:4 R running task 0 1342 2 0x00000002
> ** 3 printk messages dropped ** [ 545.526231] [<ffffff8008089a0c>] show_stack+0x14/0x20
> ** 9 printk messages dropped ** [ 545.526280] [<ffffff80086a71e8>] arch_timer_handler_phys+0x30/0x40
> [ 545.526284] [<ffffff80080dbe18>] handle_percpu_devid_irq+0x78/0xa0
> [ 545.526291] [<ffffff80080d760c>] generic_handle_irq+0x24/0x38
> [ 545.526296] [<ffffff80080d7944>] __handle_domain_irq+0x5c/0xb8
> [ 545.526299] [<ffffff80080824bc>] gic_handle_irq+0x64/0xc0
> [ 545.526302] Exception stack(0xffffffc87b07f870 to 0xffffffc87b07f990)
> [ 545.526306] f860: 0000000000009732 ffffff800a1eaaa8
> ** 8 printk messages dropped ** [ 545.526341] f980: ffffff800a1c39e8 0000000000000036
> [ 545.526345] [<ffffff8008085720>] el1_irq+0xa0/0x100
> [ 545.526349] [<ffffff80080d6234>] console_unlock+0x384/0x5b0
> [ 545.526353] [<ffffff80080d673c>] vprintk_emit+0x2dc/0x4b0
> [ 545.526357] [<ffffff80080d6a50>] vprintk_default+0x38/0x40
> [ 545.526362] [<ffffff8008129704>] printk+0x58/0x60
> [ 545.526366] [<ffffff800859e3e4>] ath9k_iowrite32+0x9c/0xa8
> [ 545.526372] [<ffffff80085c7ca8>] ath9k_hw_kill_interrupts+0x28/0xf0
> [ 545.526376] [<ffffff80085a18ec>] ath_reset+0x24/0x68
> ** 2 printk messages dropped ** [ 545.526391] [<ffffff800885ad60>] ieee80211_hw_config+0x50/0x290
> ** 11 printk messages dropped ** [ 545.532834] ath9k_hw_kill_interrupts 793
> [ 545.532890] ath9k_hw_enable_interrupts 821
>
>
> But if we have less debug prints it does not reach EP handler sometimes, due to following
> Condition in "kernel/irq/chip.c" in function handle_simple_irq
>
> if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
> desc->istate |= IRQS_PENDING;
> goto out_unlock;
> }
> Here irqd_irq_disabled is being set to 1.
>
> With lesser debug prints it stops after following prints:
> root@Xilinx-ZCU102-2016_3:~# iw dev wlan0 scan
> [ 54.781045] ath9k_hw_kill_interrupts 793
> [ 54.785007] ath9k_hw_kill_interrupts 793
> [ 54.792535] ath9k_hw_enable_interrupts 821
> [ 54.796642] ath9k_hw_enable_interrupts 825
> [ 54.800807] ath9k_hw_enable_interrupts 832
> [ 54.804973] AR_SREV_9100 0
> [ 54.807663] ath9k_hw_enable_interrupts 848
> [ 54.811843] ath9k_hw_intrpend 762
> [ 54.815211] (AR_SREV_9340(ah) val 0
> [ 54.818684] ath9k_hw_intrpend 767
> [ 54.822078] ath_isr 603
> [ 54.824587] ath9k_hw_kill_interrupts 793
> [ 54.828601] ath9k_hw_enable_interrupts 821
> [ 54.832750] ath9k_hw_enable_interrupts 825
> [ 54.836916] ath9k_hw_enable_interrupts 832
> [ 54.841082] AR_SREV_9100 0
> [ 54.843772] ath9k_hw_enable_interrupts 848
> [ 54.843775] ath9k_hw_intrpend 762
> [ 54.851319] (AR_SREV_9340(ah) val 0
> [ 54.854793] ath9k_hw_intrpend 767
> [ 54.858185] ath_isr 603
> [ 54.860696] ath9k_hw_kill_interrupts 793
> [ 54.864776] ath9k_hw_enable_interrupts 821
> [ 54.867061] ath9k_hw_kill_interrupts 793
> [ 54.872870] ath9k_hw_enable_interrupts 825
> [ 54.877036] ath9k_hw_enable_interrupts 832
> [ 54.881202] AR_SREV_9100 0
> [ 54.883892] ath9k_hw_enable_interrupts 848
> [ 75.963129] INFO: rcu_sched detected stalls on CPUs/tasks:
> [ 75.968602] 0-...: (2 GPs behind) idle=9d5/140000000000001/0 softirq=1103/1109 fqs=519
> [ 75.976675] (detected by 2, t=5274 jiffies, g=64, c=63, q=11)
> [ 75.982485] Task dump for CPU 0:
> [ 75.985696] ksoftirqd/0 R running task 0 3 2 0x00000002
> [ 75.992726] Call trace:
> [ 75.995165] [<ffffff8008086b3c>] __switch_to+0xc4/0xd0
> [ 76.000281] [<ffffffc87b830500>] 0xffffffc87b830500
> [ 139.059027] INFO: rcu_sched detected stalls on CPUs/tasks:
> [ 139.064430] 0-...: (2 GPs behind) idle=9d5/140000000000001/0 softirq=1103/1109 fqs=2097
> [ 139.072593] (detected by 2, t=21049 jiffies, g=64, c=63, q=11)
> [ 139.078489] Task dump for CPU 0:
> [ 139.081700] ksoftirqd/0 R running task 0 3 2 0x00000002
> [ 139.088731] Call trace:
> [ 139.091165] [<ffffff8008086b3c>] __switch_to+0xc4/0xd0
> [ 139.096285] [<ffffffc87b830500>] 0xffffffc87b830500
>
>
>> > We are not seeing any issues on 32-bit ARM platform and X86
>> > platform.
>>
>> Can you collect a dmesg log (or, if the system hang means you can't
>> collect that, a console log with "ignore_loglevel"), and "lspci -vv"
>> output as root? That should have clues about whether the INTx got
>> routed correctly. /proc/interrupts should also show whether we're
>> receiving interrupts from the device.
>
> Here is the lspci output:
> 00:00.0 PCI bridge: Xilinx Corporation Device d022 (prog-if 00 [Normal decode])
> Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
> Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
> Latency: 0
> Interrupt: pin A routed to IRQ 224
> Bus: primary=00, secondary=01, subordinate=0c, sec-latency=0
> I/O behind bridge: 00000000-00000fff
> Memory behind bridge: e0000000-e00fffff
> Prefetchable memory behind bridge: 00000000fff00000-00000000000fffff
> Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
> BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
> PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
> Capabilities: [40] Power Management version 3
> Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
> Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
> Capabilities: [60] Express (v2) Root Port (Slot-), MSI 00
> DevCap: MaxPayload 256 bytes, PhantFunc 0
> ExtTag- RBE+
> DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
> RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
> MaxPayload 128 bytes, MaxReadReq 512 bytes
> DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend+
> LnkCap: Port #0, Speed 5GT/s, Width x2, ASPM not supported, Exit Latency L0s unlimited, L1 unlimited
> ClockPM- Surprise- LLActRep- BwNot+ ASPMOptComp+
> LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk-
> ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
> LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
> RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible+
> RootCap: CRSVisible+
> RootSta: PME ReqID 0000, PMEStatus- PMEPending-
> DevCap2: Completion Timeout: Range B, TimeoutDis+, LTR-, OBFF Not Supported ARIFwd-
> DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled ARIFwd-
> LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-
> Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
> Compliance De-emphasis: -6dB
> LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete-, EqualizationPhase1-
> EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
> Capabilities: [100 v1] Device Serial Number 00-00-00-00-00-00-00-00
> Capabilities: [10c v1] Virtual Channel
> Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
> Arb: Fixed- WRR32- WRR64- WRR128-
> Ctrl: ArbSelect=Fixed
> Status: InProgress-
> VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
> Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
> Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
> Status: NegoPending- InProgress-
> Capabilities: [128 v1] Vendor Specific Information: ID=1234 Rev=1 Len=018 <?>
>
> 01:00.0 Network controller: Qualcomm Atheros AR93xx Wireless Network Adapter (rev 01)
> Subsystem: Qualcomm Atheros Device 3112
> Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
> Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
> Latency: 0, Cache Line Size: 128 bytes
> Interrupt: pin A routed to IRQ 224
> Region 0: Memory at e0000000 (64-bit, non-prefetchable) [size=128K]
> [virtual] Expansion ROM at e0020000 [disabled] [size=64K]
> Capabilities: [40] Power Management version 3
> Flags: PMEClk- DSI- D1+ D2- AuxCurrent=375mA PME(D0+,D1+,D2-,D3hot+,D3cold-)
> Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
> Capabilities: [50] MSI: Enable- Count=1/4 Maskable+ 64bit+
> Address: 0000000000000000 Data: 0000
> Masking: 00000000 Pending: 00000000
> Capabilities: [70] Express (v2) Endpoint, MSI 00
> DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <1us, L1 <8us
> ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 0.000W
> DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
> RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop-
> MaxPayload 128 bytes, MaxReadReq 512 bytes
> DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
> LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <2us, L1 <64us
> ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp-
> LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk-
> ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
> LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
> DevCap2: Completion Timeout: Not Supported, TimeoutDis+, LTR-, OBFF Not Supported
> DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled
> LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-
> Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
> Compliance De-emphasis: -6dB
> LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-, EqualizationPhase1-
> EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
> Capabilities: [100 v1] Advanced Error Reporting
> UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
> UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
> UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
> CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
> CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
> AERCap: First Error Pointer: 00, GenCap- CGenEn- ChkCap- ChkEn-
> Capabilities: [140 v1] Virtual Channel
> Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
> Arb: Fixed- WRR32- WRR64- WRR128-
> Ctrl: ArbSelect=Fixed
> Status: InProgress-
> VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
> Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
> Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
> Status: NegoPending- InProgress-
> Capabilities: [300 v1] Device Serial Number 00-00-00-00-00-00-00-00
> Kernel driver in use: ath9k
>
> Here is the cat /proc/interrupts (after we do interface up):
>
> root@:~# ifconfig wlan0 up
> [ 1548.926601] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
> root@Xilinx-ZCU102-2016_3:~# cat /proc/interrupts
> CPU0 CPU1 CPU2 CPU3
> 1: 0 0 0 0 GICv2 29 Edge arch_timer
> 2: 19873 20058 19089 17435 GICv2 30 Edge arch_timer
> 12: 0 0 0 0 GICv2 156 Level zynqmp-dma
> 13: 0 0 0 0 GICv2 157 Level zynqmp-dma
> 14: 0 0 0 0 GICv2 158 Level zynqmp-dma
> 15: 0 0 0 0 GICv2 159 Level zynqmp-dma
> 16: 0 0 0 0 GICv2 160 Level zynqmp-dma
> 17: 0 0 0 0 GICv2 161 Level zynqmp-dma
> 18: 0 0 0 0 GICv2 162 Level zynqmp-dma
> 19: 0 0 0 0 GICv2 163 Level zynqmp-dma
> 20: 0 0 0 0 GICv2 164 Level Mali_GP_MMU, Mali_GP, Mali_PP0_MMU, Mali_PP0, Mali_PP1_MMU, Mali_PP1
> 30: 0 0 0 0 GICv2 95 Level eth0, eth0
> 206: 314 0 0 0 GICv2 49 Level cdns-i2c
> 207: 40 0 0 0 GICv2 50 Level cdns-i2c
> 209: 0 0 0 0 GICv2 150 Level nwl_pcie:misc
> 214: 12 0 0 0 GICv2 47 Level ff0f0000.spi
> 215: 0 0 0 0 GICv2 58 Level ffa60000.rtc
> 216: 0 0 0 0 GICv2 59 Level ffa60000.rtc
> 217: 0 0 0 0 GICv2 165 Level ahci-ceva[fd0c0000.ahci]
> 218: 61 0 0 0 GICv2 81 Level mmc0
> 219: 0 0 0 0 GICv2 187 Level arm-smmu global fault
> 220: 471 0 0 0 GICv2 53 Level xuartps
> 223: 0 0 0 0 GICv2 154 Level fd4c0000.dma
> 224: 3 0 0 0 dummy 1 Edge ath9k
> 225: 0 0 0 0 GICv2 97 Level xhci-hcd:usb1
>
> Regards,
> Bharat
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH v2 2/2] cfg80211: Add support to sched scan to report better BSSs
From: Malinen, Jouni @ 2016-12-08 17:52 UTC (permalink / raw)
To: Arend Van Spriel
Cc: Vamsi, Krishna, Johannes Berg, linux-wireless@vger.kernel.org
In-Reply-To: <280cb669-2360-d4fc-779b-80196c944e2e@broadcom.com>
On Wed, Dec 07, 2016 at 09:03:23PM +0100, Arend Van Spriel wrote:
> On 7-12-2016 10:33, Vamsi, Krishna wrote:
> >> -----Original Message-----
> >> From: Johannes Berg [mailto:johannes@sipsolutions.net]
> >=20
> >> What about Arend's comment regarding this functionality overlapping wi=
th the
> >> BSS selection offload configuration?
> >>
> >> Do you think there's any ability to share attributes/functionality?
> >=20
> > Hi Johannes,
> >=20
> > I think the later comment from Luca on this which I pasted below is mor=
e agreeable.
> >=20
> > Yes, similar but not quite the same. The existing case is for finding =
BSSs that are worth waking the host up for (while disconnected), so it need=
s to be better than the RSSI passed (absolute number). Now this is about r=
elative RSSI as compared to the current connection, so RELATIVE_RSSI is dif=
ferent than RSSI and I think the same attribute should not be used, to avoi=
d confusion.
>=20
> I noticed the response from Luca, but did not get back on this. I know
> it is not the same, but what I meant is whether we could extend it so it
> also covers your scenario.
I'm not sure I see the point of trying to avoid the new RELATIVE_RSSI
attribute. We need to clearly specify that this new constraint is indeed
for relative comparison against the currently connected BSS.
As far as your second email is concerned, it might make more sense to
use the existing NL80211_ATTR_BSS_SELECT instead of the new
NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI_5G_PREF since they cover very
similar purpose in defining RSSI preference between bands. We can take a
look at doing so. One thing to be a careful about this is in what claims
there are about using NL80211_ATTR_BSS_SELECT for capability indication
in GET_WIPHY. I guess we can leave that as-is to apply for _CONNECT and
the new EXT_FEATURE flag we are adding for sched_scan applies for this
attribute in SCHED_SCAN.
--=20
Jouni Malinen PGP id EFC895FA=
^ permalink raw reply
* Re: [PATCH v2 2/2] cfg80211: Add support to sched scan to report better BSSs
From: Arend Van Spriel @ 2016-12-08 20:35 UTC (permalink / raw)
To: Malinen, Jouni
Cc: Vamsi, Krishna, Johannes Berg, linux-wireless@vger.kernel.org
In-Reply-To: <20161208175236.GA6121@jouni.qca.qualcomm.com>
On 8-12-2016 18:52, Malinen, Jouni wrote:
> On Wed, Dec 07, 2016 at 09:03:23PM +0100, Arend Van Spriel wrote:
>> On 7-12-2016 10:33, Vamsi, Krishna wrote:
>>>> -----Original Message-----
>>>> From: Johannes Berg [mailto:johannes@sipsolutions.net]
>>>
>>>> What about Arend's comment regarding this functionality overlapping with the
>>>> BSS selection offload configuration?
>>>>
>>>> Do you think there's any ability to share attributes/functionality?
>>>
>>> Hi Johannes,
>>>
>>> I think the later comment from Luca on this which I pasted below is more agreeable.
>>>
>>> Yes, similar but not quite the same. The existing case is for finding BSSs that are worth waking the host up for (while disconnected), so it needs to be better than the RSSI passed (absolute number). Now this is about relative RSSI as compared to the current connection, so RELATIVE_RSSI is different than RSSI and I think the same attribute should not be used, to avoid confusion.
>>
>> I noticed the response from Luca, but did not get back on this. I know
>> it is not the same, but what I meant is whether we could extend it so it
>> also covers your scenario.
>
> I'm not sure I see the point of trying to avoid the new RELATIVE_RSSI
> attribute. We need to clearly specify that this new constraint is indeed
> for relative comparison against the currently connected BSS.
Hi Jouni,
I am not saying it should be avoided. Just looking at it conceptually
the scheduled scan request holds so-called matchsets that specify the
constraints to determine whether a BSS was found that is worth notifying
the host/user-space about. As such I would expect the relative RSSI
attribute(s) to be part of the matchset. That way you can specify it
together with the currently connected SSID in a single matchset.
> As far as your second email is concerned, it might make more sense to
> use the existing NL80211_ATTR_BSS_SELECT instead of the new
> NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI_5G_PREF since they cover very
> similar purpose in defining RSSI preference between bands. We can take a
> look at doing so. One thing to be a careful about this is in what claims
> there are about using NL80211_ATTR_BSS_SELECT for capability indication
> in GET_WIPHY. I guess we can leave that as-is to apply for _CONNECT and
> the new EXT_FEATURE flag we are adding for sched_scan applies for this
> attribute in SCHED_SCAN.
The NL80211_ATTR_BSS_SELECT supports different methods for BSS
selection. One of them being RSSI_ADJUST which is similar to this. It
lets user-space specify the band and adjustment instead of having a band
implied in the attribute name. Agree that if reusing it for scheduled
scan you would still need the EXT_FEATURE flag.
Regards,
Arend
^ permalink raw reply
* Re: [PATCH] RFC: Universal scan proposal
From: Dmitry Shmidt @ 2016-12-08 22:35 UTC (permalink / raw)
To: Arend Van Spriel; +Cc: Johannes Berg, linux-wireless
In-Reply-To: <93d4475c-58bd-d497-3347-a988d551f374@broadcom.com>
On Wed, Dec 7, 2016 at 12:51 PM, Arend Van Spriel
<arend.vanspriel@broadcom.com> wrote:
> On 7-12-2016 19:39, Dmitry Shmidt wrote:
>> On Tue, Dec 6, 2016 at 10:44 PM, Johannes Berg
>> <johannes@sipsolutions.net> wrote:
>>>
>>>> Indeed, results are results. I just want to take care of two things:
>>>> 1) Memory consumption - we can clear stale scan results for
>>>> connection, but not for location if we are using history scan.
>>>
>>> Well eventually we also have to clear for location if we run out of
>>> memory, that usually means dumping them out to the host, no?
>>
>> Being out of memory and consuming more memory are different
>> things, but I agree - maybe we don't need to worry about it.
>>
>>>> 2) Use of insufficient results for connection - in case we had
>>>> history or hotlist scan only for very limited amount of channels,
>>>> then we may not have enough APs in our result for "sterling"
>>>> connection decision.
>>>
>>> I'm not entirely sure about this case - surely noticing "we can do
>>> better now" is still better than waiting for being able to make the
>>> perfect decision?
>>
>> Maybe we can just keep flag saying that currently available results
>> were not received by usual full scan.
>>
>>>>>> Report: none / batch / immediate
>>>>>
>>>>> Not sure I see much point in "none"??
>>>>>
>>>>> Can you define these more clearly? Do you think "batch" reporting
>>>>> should be like the gscan buckets? Or actually have full
>>>>> information?
>>>>
>>>> None - means that there is not need to report. It can be useful
>>>> in case of roaming scan, scheduling or hotlist scan - you didn't find
>>>> anything suitable - don't report that there is no scan results.
>>>
>>> But that seems more of a filtering thing, combined with "immediate" for
>>> anything passing the filter?
>>
>> We can use this approach as well.
>>
>>>>>> Request may have priority and can be inserted into
>>>>>> the head of the queue.
>>>>>> Types of scans:
>>>>>> - Normal scan
>>>>>> - Scheduled scan
>>>>>> - Hotlist (BSSID scan)
>>>>>> - Roaming
>>>>>> - AutoJoin
>>>>>
>>>>> I think somebody else said this but I didn't find it now - I think
>>>>> this would make more sense to define in terms of expected behaviour
>>>>> than use cases for each type of scan.
>>>>
>>>> I think Luca made this statement.
>>>
>>> Yeah - I just couldn't find it again on re-reading the thread :)
>>>
>>>> It is totally ok from SW point of
>>>> view - especially due to the fact that scan is scan. However,
>>>> I suspect it will be harder to handle from user experience. I mean
>>>> at the end wireless framework / driver / FW will convert special
>>>> scan type to usual scan with special params and response, but why
>>>> to put this burden on user?
>
> I don't think this will put burden on the user although it depends
> who/what you mean by this. If you mean the mere mortal end-user I would
> say no as indeed there must be some software entity (in user-space) that
> will have to initiate a nl80211 command with appropriate attributes
> according to whatever user-space is trying to accomplish.
>
>>> I just think it's more flexible and open-ended. The actual definition
>>> of the resulting parameters needs to be somewhere anyway - putting it
>>> into driver/firmware (vs. wifi framework or so) seems to duplicate it
>>> and certainly makes it harder to modify/extend in the future, no?
>>
>> So, let's summarize:
>> Instead of creating new type of generic scan with special types,
>> we want to go with additional expansion of scheduled scan options and
>> parameters (in order not to "multiply entities"), including ability to send
>> new scheduled scan request without stopping previous one.
>>
>> Is it Ok?
>
> Sounds ok. To me a generic scan command with type attribute is
> equivalent to having seperate commands for each type so there seems to
> be no gain. Now whether this all can be accomplished by extending the
> scheduled scan depends on the problem that you are trying to solve.
>
> Main purpose seems to be offloading different scanning tasks which could
> make scheduled scan a good candidate. Now I want to add gscan to this
> mix as it seems some concepts for that are in play in this discussion as
> well, eg. hotlist. gscan is like scheduled scan, but it supports
> multiple schedules. However, it is still a single request from a single
> user-space process. I think Luca mentioned supporting requests from
> different user-space processes. Is that also what you mean by "ability
> to send new scheduled scan request without stopping previous one" or is
> that still from a single user-space process. Do we need a limit to the
> amount of scheduled scan requests that can be handled simultaneously.
Supporting requests (or more precisely requests and results) differentiated
by user-space entity can be tricky. Right now we are not checking current
caller pid, right? Maybe it is also good idea - or maybe we can just
make result filtering per user-space caller?
> A maybe more important aspect of gscan is user-space control of result
> reporting and thus the frequency of waking up host and/or user-space. I
> suspect this would be needed in the scheduled scan extension as well, right?
It will be always up to user-space caller to make system more or less
power-efficient, right?
> Regards,
> Arend
^ permalink raw reply
* RE: ATH9 driver issues on ARM64
From: Bharat Kumar Gogada @ 2016-12-09 5:00 UTC (permalink / raw)
To: Kalle Valo
Cc: Bjorn Helgaas, linux-kernel@vger.kernel.org,
linux-pci@vger.kernel.org, Marc Zyngier,
Janusz.Dziedzic@tieto.com, ath9k-devel@qca.qualcomm.com,
linux-wireless@vger.kernel.org, rmanohar@qca.qualcomm.com
In-Reply-To: <874m2emif9.fsf@purkki.adurom.net>
Hi,
Can any one tell, when exactly the chip sends ASSERT & DEASSERT in driver.
It might help us to debug issue further.
Thanks & Regards,
Bharat=20
> > > [+cc Kalle, ath9k list]
>=20
> Thanks, but please also CC linux-wireless. Full thread below for the folk=
s there.
>=20
> >> On Thu, Dec 08, 2016 at 01:49:42PM +0000, Bharat Kumar Gogada wrote:
> >> > Hi,
> >> >
> >> > Did anyone test Atheros ATH9
> >> > driver(drivers/net/wireless/ath/ath9k/)
> >> > on ARM64. The end point is TP link wifi card with which supports
> >> > only legacy interrupts.
> >>
> >> If it works on other arches and the arm64 PCI enumeration works, my
> >> first guess would be an INTx issue, e.g., maybe the driver is waiting
> >> for an interrupt that never arrives.
> > We are not sure for now.
> >>
> >> > We are trying to test it on ARM64 with
> >> > (drivers/pci/host/pcie-xilinx-nwl.c) as root port.
> >> >
> >> > EP is getting enumerated and able to link up.
> >> >
> >> > But when we start scan system gets hanged.
> >>
> >> When you say the system hangs when you start a scan, I assume you
> >> mean a wifi scan, not the PCI enumeration. A problem with a wifi
> >> scan might cause a *process* to hang, but it shouldn't hang the
> >> entire system.
> >>
> > Yes wifi scan.
> >> > When we took trace we see that after we start scan assert message
> >> > is sent but there is no de assert from end point.
> >>
> >> Are you talking about a trace from a PCIe analyzer? Do you see an
> >> Assert_INTx PCIe message on the link?
> >>
> > Yes lecroy trace, yes we do see Assert_INTx and Deassert_INTx happening
> when we do interface link up.
> > When we have less debug prints in Atheros driver, and do wifi scan we
> > see Assert_INTx but never Deassert_INTx,
> >> > What might cause end point not sending de assert ?
> >>
> >> If the endpoint doesn't send a Deassert_INTx message, I expect that
> >> would mean the driver didn't service the interrupt and remove the
> >> condition that caused the device to assert the interrupt in the first
> >> place.
> >>
> >> If the driver didn't receive the interrupt, it couldn't service it,
> >> of course. You could add a printk in the ath9k interrupt service
> >> routine to see if you ever get there.
> >>
> > The interrupt behavior is changing w.r.t amount of debug prints we
> > add. (I kept many prints to aid debug) root@Xilinx-ZCU102-2016_3:~# iw =
dev
> wlan0 scan
> > [ 83.064675] ath9k: ath9k_iowrite32 ffffff800a400024
> > [ 83.069486] ath9k: ath9k_ioread32 ffffff800a400024
> > [ 83.074257] ath9k_hw_kill_interrupts 793
> > [ 83.078260] ath9k: ath9k_iowrite32 ffffff800a400024
> > [ 83.083107] ath9k: ath9k_ioread32 ffffff800a400024
> > [ 83.087882] ath9k_hw_kill_interrupts 793
> > [ 83.095450] ath9k_hw_enable_interrupts 821
> > [ 83.099557] ath9k_hw_enable_interrupts 825
> > [ 83.103721] ath9k_hw_enable_interrupts 832
> > [ 83.107887] ath9k: ath9k_iowrite32 ffffff800a400024
> > [ 83.112748] AR_SREV_9100 0
> > [ 83.115438] ath9k_hw_enable_interrupts 848
> > [ 83.119607] ath9k: ath9k_ioread32 ffffff800a400024
> > [ 83.124389] ath9k_hw_intrpend 762
> > [ 83.127761] (AR_SREV_9340(ah) val 0
> > [ 83.131234] ath9k_hw_intrpend 767
> > [ 83.134628] ath_isr 603
> > [ 83.137134] ath9k: ath9k_iowrite32 ffffff800a400024
> > [ 83.141995] ath9k: ath9k_ioread32 ffffff800a400024
> > [ 83.146771] ath9k_hw_kill_interrupts 793
> > [ 83.150864] ath9k_hw_enable_interrupts 821
> > [ 83.154971] ath9k_hw_enable_interrupts 825
> > [ 83.159135] ath9k_hw_enable_interrupts 832
> > [ 83.163300] ath9k: ath9k_iowrite32 ffffff800a400024
> > [ 83.168161] AR_SREV_9100 0
> > [ 83.170852] ath9k_hw_enable_interrupts 848
> > [ 83.170855] ath9k_hw_intrpend 762
> > [ 83.178398] (AR_SREV_9340(ah) val 0
> > [ 83.181873] ath9k_hw_intrpend 767
> > [ 83.185265] ath_isr 603
> > [ 83.187773] ath9k: ath9k_iowrite32 ffffff800a400024
> > [ 83.192635] ath9k: ath9k_ioread32 ffffff800a400024
> > [ 83.197411] ath9k_hw_kill_interrupts 793
> > [ 83.201414] ath9k: ath9k_ioread32 ffffff800a400024
> > [ 83.206258] ath9k_hw_enable_interrupts 821
> > [ 83.210368] ath9k_hw_enable_interrupts 825
> > [ 83.214531] ath9k_hw_enable_interrupts 832
> > [ 83.218698] ath9k: ath9k_iowrite32 ffffff800a400024
> > [ 83.223558] AR_SREV_9100 0
> > [ 83.226243] ath9k_hw_enable_interrupts 848
> > [ 83.226246] ath9k_hw_intrpend 762
> > [ 83.233794] (AR_SREV_9340(ah) val 0
> > [ 83.237268] ath9k_hw_intrpend 767
> > [ 83.240661] ath_isr 603
> > [ 83.243169] ath9k: ath9k_iowrite32 ffffff800a400024
> > [ 83.248030] ath9k: ath9k_ioread32 ffffff800a400024
> > [ 83.252806] ath9k_hw_kill_interrupts 793
> > [ 83.256811] ath9k: ath9k_ioread32 ffffff800a400024
> > [ 83.261651] ath9k_hw_enable_interrupts 821
> > [ 83.265753] ath9k_hw_enable_interrupts 825
> > [ 83.269919] ath9k_hw_enable_interrupts 832
> > [ 83.274083] ath9k: ath9k_iowrite32 ffffff800a400024
> > [ 83.278945] AR_SREV_9100 0
> > [ 83.281630] ath9k_hw_enable_interrupts 848
> > [ 83.281633] ath9k_hw_intrpend 762
> > [ 83.281634] (AR_SREV_9340(ah) val 0
> > [ 83.281637] ath9k_hw_intrpend 767
> > [ 83.281648] ath_isr 603
> > [ 83.281649] ath9k: ath9k_iowrite32 ffffff800a400024
> > [ 83.281651] ath9k: ath9k_ioread32 ffffff800a400024
> > [ 83.281654] ath9k_hw_kill_interrupts 793
> > [ 83.312192] ath9k: ath9k_ioread32 ffffff800a400024
> > [ 83.317030] ath9k_hw_enable_interrupts 821
> > [ 83.321132] ath9k_hw_enable_interrupts 825
> > [ 83.325297] ath9k_hw_enable_interrupts 832
> > [ 83.329463] ath9k: ath9k_iowrite32 ffffff800a400024
> > [ 83.334324] AR_SREV_9100 0
> > [ 83.337014] ath9k_hw_enable_interrupts 848
> > ..
> > ..
> > This log continues until I turn off board without obtaining scanning re=
sult.
> >
> > In between I get following cpu stall outputs :
> > 230.457179] INFO: rcu_sched self-detected stall on CPU
> > [ 230.457185] 2-...: (31314 ticks this GP)
> idle=3D2d1/140000000000001/0 softirq=3D1400/1400 fqs=3D36713
> > [ 230.457189] (t=3D36756 jiffies g=3D161 c=3D160 q=3D16169)
> > [ 230.457191] Task dump for CPU 2:
> > [ 230.457196] kworker/u8:4 R running task 0 1342 2 0x=
00000002
> > [ 230.457207] Workqueue: phy0 ieee80211_scan_work [ 230.457208] Call
> > trace:
> > [ 230.457214] [<ffffff8008089860>] dump_backtrace+0x0/0x198 [
> > 230.457219] [<ffffff8008089a0c>] show_stack+0x14/0x20 [ 230.457224]
> > [<ffffff80080c0930>] sched_show_task+0x98/0xf8 [ 230.457228]
> > [<ffffff80080c2628>] dump_cpu_task+0x40/0x50 [ 230.457233]
> > [<ffffff80080e14a8>] rcu_dump_cpu_stacks+0xa0/0xf0 [ 230.457239]
> > [<ffffff80080e4cd8>] rcu_check_callbacks+0x468/0x748 [ 230.457243]
> > [<ffffff80080e7cfc>] update_process_times+0x3c/0x68 [ 230.457249]
> > [<ffffff80080f6dfc>] tick_sched_handle.isra.5+0x3c/0x50
> > [ 230.457253] [<ffffff80080f6e54>] tick_sched_timer+0x44/0x90 [
> > 230.457257] [<ffffff80080e86b0>] __hrtimer_run_queues+0xf0/0x178
> > ** 10 printk messages dropped ** [ 230.457302] f8c0: 0000000000000000
> > 0000000005f5e0ff 000000000001379a 3866666666666620 [ 230.457306]
> > f8e0: ffffff800a1b4065 0000000000000006 ffffff800a129000
> > ffffffc87b8010a8 [ 230.457310] f900: ffffff808a1b4057
> > ffffff800a1c3000 ffffff800a1b3000 ffffff800a13b000 [ 230.457314]
> > f920: 0000000000000140 0000000000000006 ffffff800a1b3b10
> > ffffff800a1c39e8 [ 230.457318] f940: 000000000000002f
> > ffffff800a1b8a98 ffffff800a1b3ae8 ffffffc87b07f990 [ 230.457322]
> > f960: ffffff80080d6230 ffffffc87b07f990 ffffff80080d6234
> > 0000000060000145
> > ** 1 printk messages dropped ** [ 230.457329] [<ffffff8008085720>]
> > el1_irq+0xa0/0x100
> > ** 9 printk messages dropped ** [ 230.457373] [<ffffff800885ad60>]
> > ieee80211_hw_config+0x50/0x290 [ 230.457377] [<ffffff8008863690>]
> > ieee80211_scan_work+0x1f8/0x480 [ 230.457383] [<ffffff80080b15d0>]
> > process_one_work+0x120/0x378 [ 230.457386] [<ffffff80080b1870>]
> > worker_thread+0x48/0x4b0 [ 230.457391] [<ffffff80080b7108>]
> > kthread+0xd0/0xe8 [ 230.457395] [<ffffff8008085dd0>]
> ret_from_fork+0x10/0x40
> > [ 230.480389] ath9k_hw_intrpend 762
> >
> >
> > [ 545.487987] ath9k: ath9k_ioread32 ffffff800a400024 [ 545.526189]
> > INFO: rcu_sched self-detected stall on CPU
> > [ 545.526195] 2-...: (97636 ticks this GP)
> idle=3D2d1/140000000000001/0 softirq=3D1400/1400 fqs=3D115374
> > [ 545.526199] (t=3D115523 jiffies g=3D161 c=3D160 q=3D51066)
> > [ 545.526201] Task dump for CPU 2:
> > [ 545.526206] kworker/u8:4 R running task 0 1342 2 0x=
00000002
> > ** 3 printk messages dropped ** [ 545.526231] [<ffffff8008089a0c>]
> > show_stack+0x14/0x20
> > ** 9 printk messages dropped ** [ 545.526280] [<ffffff80086a71e8>]
> > arch_timer_handler_phys+0x30/0x40 [ 545.526284] [<ffffff80080dbe18>]
> > handle_percpu_devid_irq+0x78/0xa0 [ 545.526291] [<ffffff80080d760c>]
> > generic_handle_irq+0x24/0x38 [ 545.526296] [<ffffff80080d7944>]
> > __handle_domain_irq+0x5c/0xb8 [ 545.526299] [<ffffff80080824bc>]
> > gic_handle_irq+0x64/0xc0 [ 545.526302] Exception stack(0xffffffc87b07f=
870
> to 0xffffffc87b07f990)
> > [ 545.526306] f860: 0000000000009732=
ffffff800a1eaaa8
> > ** 8 printk messages dropped ** [ 545.526341] f980: ffffff800a1c39e8
> > 0000000000000036 [ 545.526345] [<ffffff8008085720>]
> > el1_irq+0xa0/0x100 [ 545.526349] [<ffffff80080d6234>]
> > console_unlock+0x384/0x5b0 [ 545.526353] [<ffffff80080d673c>]
> > vprintk_emit+0x2dc/0x4b0 [ 545.526357] [<ffffff80080d6a50>]
> > vprintk_default+0x38/0x40 [ 545.526362] [<ffffff8008129704>]
> > printk+0x58/0x60 [ 545.526366] [<ffffff800859e3e4>]
> > ath9k_iowrite32+0x9c/0xa8 [ 545.526372] [<ffffff80085c7ca8>]
> > ath9k_hw_kill_interrupts+0x28/0xf0
> > [ 545.526376] [<ffffff80085a18ec>] ath_reset+0x24/0x68
> > ** 2 printk messages dropped ** [ 545.526391] [<ffffff800885ad60>]
> ieee80211_hw_config+0x50/0x290
> > ** 11 printk messages dropped ** [ 545.532834] ath9k_hw_kill_interrupt=
s
> 793
> > [ 545.532890] ath9k_hw_enable_interrupts 821
> >
> >
> > But if we have less debug prints it does not reach EP handler
> > sometimes, due to following Condition in "kernel/irq/chip.c" in
> > function handle_simple_irq
> >
> > if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
> > desc->istate |=3D IRQS_PENDING;
> > goto out_unlock;
> > }
> > Here irqd_irq_disabled is being set to 1.
> >
> > With lesser debug prints it stops after following prints:
> > root@Xilinx-ZCU102-2016_3:~# iw dev wlan0 scan
> > [ 54.781045] ath9k_hw_kill_interrupts 793
> > [ 54.785007] ath9k_hw_kill_interrupts 793
> > [ 54.792535] ath9k_hw_enable_interrupts 821
> > [ 54.796642] ath9k_hw_enable_interrupts 825
> > [ 54.800807] ath9k_hw_enable_interrupts 832
> > [ 54.804973] AR_SREV_9100 0
> > [ 54.807663] ath9k_hw_enable_interrupts 848
> > [ 54.811843] ath9k_hw_intrpend 762
> > [ 54.815211] (AR_SREV_9340(ah) val 0
> > [ 54.818684] ath9k_hw_intrpend 767
> > [ 54.822078] ath_isr 603
> > [ 54.824587] ath9k_hw_kill_interrupts 793
> > [ 54.828601] ath9k_hw_enable_interrupts 821
> > [ 54.832750] ath9k_hw_enable_interrupts 825
> > [ 54.836916] ath9k_hw_enable_interrupts 832
> > [ 54.841082] AR_SREV_9100 0
> > [ 54.843772] ath9k_hw_enable_interrupts 848
> > [ 54.843775] ath9k_hw_intrpend 762
> > [ 54.851319] (AR_SREV_9340(ah) val 0
> > [ 54.854793] ath9k_hw_intrpend 767
> > [ 54.858185] ath_isr 603
> > [ 54.860696] ath9k_hw_kill_interrupts 793
> > [ 54.864776] ath9k_hw_enable_interrupts 821
> > [ 54.867061] ath9k_hw_kill_interrupts 793
> > [ 54.872870] ath9k_hw_enable_interrupts 825
> > [ 54.877036] ath9k_hw_enable_interrupts 832
> > [ 54.881202] AR_SREV_9100 0
> > [ 54.883892] ath9k_hw_enable_interrupts 848
> > [ 75.963129] INFO: rcu_sched detected stalls on CPUs/tasks:
> > [ 75.968602] 0-...: (2 GPs behind) idle=3D9d5/140000000000001/0
> softirq=3D1103/1109 fqs=3D519
> > [ 75.976675] (detected by 2, t=3D5274 jiffies, g=3D64, c=3D63, q=3D1=
1)
> > [ 75.982485] Task dump for CPU 0:
> > [ 75.985696] ksoftirqd/0 R running task 0 3 2 0x=
00000002
> > [ 75.992726] Call trace:
> > [ 75.995165] [<ffffff8008086b3c>] __switch_to+0xc4/0xd0
> > [ 76.000281] [<ffffffc87b830500>] 0xffffffc87b830500
> > [ 139.059027] INFO: rcu_sched detected stalls on CPUs/tasks:
> > [ 139.064430] 0-...: (2 GPs behind) idle=3D9d5/140000000000001/0
> softirq=3D1103/1109 fqs=3D2097
> > [ 139.072593] (detected by 2, t=3D21049 jiffies, g=3D64, c=3D63, q=3D=
11)
> > [ 139.078489] Task dump for CPU 0:
> > [ 139.081700] ksoftirqd/0 R running task 0 3 2 0x=
00000002
> > [ 139.088731] Call trace:
> > [ 139.091165] [<ffffff8008086b3c>] __switch_to+0xc4/0xd0 [
> > 139.096285] [<ffffffc87b830500>] 0xffffffc87b830500
> >
> >
> >> > We are not seeing any issues on 32-bit ARM platform and X86
> >> > platform.
> >>
> >> Can you collect a dmesg log (or, if the system hang means you can't
> >> collect that, a console log with "ignore_loglevel"), and "lspci -vv"
> >> output as root? That should have clues about whether the INTx got
> >> routed correctly. /proc/interrupts should also show whether we're
> >> receiving interrupts from the device.
> >
> > Here is the lspci output:
> > 00:00.0 PCI bridge: Xilinx Corporation Device d022 (prog-if 00 [Normal
> decode])
> > Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
> ParErr- Stepping- SERR- FastB2B- DisINTx-
> > Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=3Dfast >TAbort-
> <TAbort- <MAbort- >SERR- <PERR- INTx-
> > Latency: 0
> > Interrupt: pin A routed to IRQ 224
> > Bus: primary=3D00, secondary=3D01, subordinate=3D0c, sec-latency=3D0
> > I/O behind bridge: 00000000-00000fff
> > Memory behind bridge: e0000000-e00fffff
> > Prefetchable memory behind bridge: 00000000fff00000-
> 00000000000fffff
> > Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=3Dfast >TAbort-
> <TAbort- <MAbort- <SERR- <PERR-
> > BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
> > PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
> > Capabilities: [40] Power Management version 3
> > Flags: PMEClk- DSI- D1- D2- AuxCurrent=3D0mA
> PME(D0+,D1+,D2+,D3hot+,D3cold-)
> > Status: D0 NoSoftRst+ PME-Enable- DSel=3D0 DScale=3D0 PME-
> > Capabilities: [60] Express (v2) Root Port (Slot-), MSI 00
> > DevCap: MaxPayload 256 bytes, PhantFunc 0
> > ExtTag- RBE+
> > DevCtl: Report errors: Correctable- Non-Fatal- Fatal-
> Unsupported-
> > RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
> > MaxPayload 128 bytes, MaxReadReq 512 bytes
> > DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr-
> TransPend+
> > LnkCap: Port #0, Speed 5GT/s, Width x2, ASPM not supported,
> Exit Latency L0s unlimited, L1 unlimited
> > ClockPM- Surprise- LLActRep- BwNot+ ASPMOptComp+
> > LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk-
> > ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
> > LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+
> DLActive- BWMgmt- ABWMgmt-
> > RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna-
> CRSVisible+
> > RootCap: CRSVisible+
> > RootSta: PME ReqID 0000, PMEStatus- PMEPending-
> > DevCap2: Completion Timeout: Range B, TimeoutDis+, LTR-,
> OBFF Not Supported ARIFwd-
> > DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-,
> OBFF Disabled ARIFwd-
> > LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-
> > Transmit Margin: Normal Operating Range,
> EnterModifiedCompliance- ComplianceSOS-
> > Compliance De-emphasis: -6dB
> > LnkSta2: Current De-emphasis Level: -3.5dB,
> EqualizationComplete-, EqualizationPhase1-
> > EqualizationPhase2-, EqualizationPhase3-,
> LinkEqualizationRequest-
> > Capabilities: [100 v1] Device Serial Number 00-00-00-00-00-00-00-00
> > Capabilities: [10c v1] Virtual Channel
> > Caps: LPEVC=3D0 RefClk=3D100ns PATEntryBits=3D1
> > Arb: Fixed- WRR32- WRR64- WRR128-
> > Ctrl: ArbSelect=3DFixed
> > Status: InProgress-
> > VC0: Caps: PATOffset=3D00 MaxTimeSlots=3D1 RejSnoopTrans-
> > Arb: Fixed- WRR32- WRR64- WRR128- TWRR128-
> WRR256-
> > Ctrl: Enable+ ID=3D0 ArbSelect=3DFixed TC/VC=3Dff
> > Status: NegoPending- InProgress-
> > Capabilities: [128 v1] Vendor Specific Information: ID=3D1234 Rev=3D1
> > Len=3D018 <?>
> >
> > 01:00.0 Network controller: Qualcomm Atheros AR93xx Wireless Network
> Adapter (rev 01)
> > Subsystem: Qualcomm Atheros Device 3112
> > Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
> ParErr- Stepping- SERR- FastB2B- DisINTx-
> > Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=3Dfast >TAbort-
> <TAbort- <MAbort- >SERR- <PERR- INTx-
> > Latency: 0, Cache Line Size: 128 bytes
> > Interrupt: pin A routed to IRQ 224
> > Region 0: Memory at e0000000 (64-bit, non-prefetchable) [size=3D128K]
> > [virtual] Expansion ROM at e0020000 [disabled] [size=3D64K]
> > Capabilities: [40] Power Management version 3
> > Flags: PMEClk- DSI- D1+ D2- AuxCurrent=3D375mA
> PME(D0+,D1+,D2-,D3hot+,D3cold-)
> > Status: D0 NoSoftRst- PME-Enable- DSel=3D0 DScale=3D0 PME-
> > Capabilities: [50] MSI: Enable- Count=3D1/4 Maskable+ 64bit+
> > Address: 0000000000000000 Data: 0000
> > Masking: 00000000 Pending: 00000000
> > Capabilities: [70] Express (v2) Endpoint, MSI 00
> > DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency
> L0s <1us, L1 <8us
> > ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
> SlotPowerLimit 0.000W
> > DevCtl: Report errors: Correctable- Non-Fatal- Fatal-
> Unsupported-
> > RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop-
> > MaxPayload 128 bytes, MaxReadReq 512 bytes
> > DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr-
> TransPend-
> > LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Exit
> Latency L0s <2us, L1 <64us
> > ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp-
> > LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk-
> > ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
> > LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+
> DLActive- BWMgmt- ABWMgmt-
> > DevCap2: Completion Timeout: Not Supported, TimeoutDis+,
> LTR-, OBFF Not Supported
> > DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-,
> OBFF Disabled
> > LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance-
> SpeedDis-
> > Transmit Margin: Normal Operating Range,
> EnterModifiedCompliance- ComplianceSOS-
> > Compliance De-emphasis: -6dB
> > LnkSta2: Current De-emphasis Level: -6dB,
> EqualizationComplete-, EqualizationPhase1-
> > EqualizationPhase2-, EqualizationPhase3-,
> LinkEqualizationRequest-
> > Capabilities: [100 v1] Advanced Error Reporting
> > UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
> RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
> > UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt-
> RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
> > UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt-
> RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
> > CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout-
> NonFatalErr-
> > CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout-
> NonFatalErr+
> > AERCap: First Error Pointer: 00, GenCap- CGenEn-
> ChkCap- ChkEn-
> > Capabilities: [140 v1] Virtual Channel
> > Caps: LPEVC=3D0 RefClk=3D100ns PATEntryBits=3D1
> > Arb: Fixed- WRR32- WRR64- WRR128-
> > Ctrl: ArbSelect=3DFixed
> > Status: InProgress-
> > VC0: Caps: PATOffset=3D00 MaxTimeSlots=3D1 RejSnoopTrans-
> > Arb: Fixed- WRR32- WRR64- WRR128- TWRR128-
> WRR256-
> > Ctrl: Enable+ ID=3D0 ArbSelect=3DFixed TC/VC=3Dff
> > Status: NegoPending- InProgress-
> > Capabilities: [300 v1] Device Serial Number 00-00-00-00-00-00-00-00
> > Kernel driver in use: ath9k
> >
> > Here is the cat /proc/interrupts (after we do interface up):
> >
> > root@:~# ifconfig wlan0 up
> > [ 1548.926601] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
> > root@Xilinx-ZCU102-2016_3:~# cat /proc/interrupts
> > CPU0 CPU1 CPU2 CPU3
> > 1: 0 0 0 0 GICv2 29 Edge =
arch_timer
> > 2: 19873 20058 19089 17435 GICv2 30 Edge =
arch_timer
> > 12: 0 0 0 0 GICv2 156 Level =
zynqmp-dma
> > 13: 0 0 0 0 GICv2 157 Level =
zynqmp-dma
> > 14: 0 0 0 0 GICv2 158 Level =
zynqmp-dma
> > 15: 0 0 0 0 GICv2 159 Level =
zynqmp-dma
> > 16: 0 0 0 0 GICv2 160 Level =
zynqmp-dma
> > 17: 0 0 0 0 GICv2 161 Level =
zynqmp-dma
> > 18: 0 0 0 0 GICv2 162 Level =
zynqmp-dma
> > 19: 0 0 0 0 GICv2 163 Level =
zynqmp-dma
> > 20: 0 0 0 0 GICv2 164 Level =
Mali_GP_MMU, Mali_GP,
> Mali_PP0_MMU, Mali_PP0, Mali_PP1_MMU, Mali_PP1
> > 30: 0 0 0 0 GICv2 95 Level =
eth0, eth0
> > 206: 314 0 0 0 GICv2 49 Level =
cdns-i2c
> > 207: 40 0 0 0 GICv2 50 Level =
cdns-i2c
> > 209: 0 0 0 0 GICv2 150 Level =
nwl_pcie:misc
> > 214: 12 0 0 0 GICv2 47 Level =
ff0f0000.spi
> > 215: 0 0 0 0 GICv2 58 Level =
ffa60000.rtc
> > 216: 0 0 0 0 GICv2 59 Level =
ffa60000.rtc
> > 217: 0 0 0 0 GICv2 165 Level =
ahci-ceva[fd0c0000.ahci]
> > 218: 61 0 0 0 GICv2 81 Level =
mmc0
> > 219: 0 0 0 0 GICv2 187 Level =
arm-smmu global fault
> > 220: 471 0 0 0 GICv2 53 Level =
xuartps
> > 223: 0 0 0 0 GICv2 154 Level =
fd4c0000.dma
> > 224: 3 0 0 0 dummy 1 Edge =
ath9k
> > 225: 0 0 0 0 GICv2 97 Level =
xhci-hcd:usb1
> >
> > Regards,
> > Bharat
>=20
> --
> Kalle Valo
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox