[RFC 0/4] wireless: Per-sta NoAck and offload support

2018-03-27 Thread Vasanthakumar Thiagarajan
Adds infrastructure for driver to offload NoAck functionality, driver
like ath10k could make use of it. Also extends the current ndev wide
NoAck policy to per-station, with sta level NoAck policy configuration
userspace could selectively turn off/on Noack based on various connection
parameters of the station.

Vasanthakumar Thiagarajan (4):
  mac80211: Add NoAck policy functionality offload infrastructure
  nl80211/mac80211: Extend NoAck policy command with peer MAC address
  mac80211: Apply per-peer NoAck tid bitmap configuration
  mac80211: Advertise per-peer NoAck policy support

 include/net/cfg80211.h   |  9 +++--
 include/net/mac80211.h   | 18 ++
 include/uapi/linux/nl80211.h | 12 +++-
 net/mac80211/cfg.c   | 45 +---
 net/mac80211/debugfs.c   |  1 +
 net/mac80211/driver-ops.h| 22 ++
 net/mac80211/iface.c |  4 
 net/mac80211/main.c  |  8 
 net/mac80211/sta_info.h  |  3 +++
 net/mac80211/trace.h | 28 +++
 net/mac80211/tx.c|  3 ++-
 net/mac80211/wme.c   | 35 +-
 net/wireless/nl80211.c   | 12 +++-
 net/wireless/rdev-ops.h  |  7 ---
 net/wireless/trace.h | 11 +++
 15 files changed, 202 insertions(+), 16 deletions(-)

-- 
1.9.1



[RFC 4/4] mac80211: Advertise per-peer NoAck policy support

2018-03-27 Thread Vasanthakumar Thiagarajan
This enables per-peer NoAck handling in mac80211 when
the functionality is not offloaded to the drivers.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@codeaurora.org>
---
 net/mac80211/main.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 78f2574..2b136fb 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -565,6 +565,10 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t 
priv_data_len,
 
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RRM);
 
+   if (!ops->set_noack_tid_bitmap)
+   wiphy_ext_feature_set(wiphy,
+ NL80211_EXT_FEATURE_PER_STA_NOACK_MAP);
+
wiphy->bss_priv_size = sizeof(struct ieee80211_bss);
 
local = wiphy_priv(wiphy);
-- 
1.9.1



[RFC 2/4] nl80211/mac80211: Extend NoAck policy command with peer MAC address

2018-03-27 Thread Vasanthakumar Thiagarajan
Provides peer level NoAck policy configuration by extending
NL80211_CMD_SET_NOACK_MAP command with peer MAC address.
If user space does not give any peer mac address, the driver
should retain the existing functionality of applying the NoAck
policy for all the staions connected to the netdev. Peer specific
configuration takes precedence over netdev level configuration when
both are set by the user. Drivers supporting per-sta NoAck policy
must advertise the support through the extended flag index
NL80211_EXT_FEATURE_PER_STA_NOACK_MAP.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@codeaurora.org>
---
 include/net/cfg80211.h   |  9 +++--
 include/uapi/linux/nl80211.h | 12 +++-
 net/mac80211/cfg.c   |  1 +
 net/wireless/nl80211.c   | 12 +++-
 net/wireless/rdev-ops.h  |  7 ---
 net/wireless/trace.h | 11 +++
 6 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fc40843..b974d32 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2872,7 +2872,12 @@ struct cfg80211_external_auth_params {
  * @probe_client: probe an associated client, must return a cookie that it
  * later passes to cfg80211_probe_status().
  *
- * @set_noack_map: Set the NoAck Map for the TIDs.
+ * @set_noack_map: Set the NoAck Map for the TIDs. When peer is not %NULL NoAck
+ * map will be applied for that particular peer. When peer is %NULL NoAck
+ * map will be applied for all the connected stations (except the ones
+ * which already have per-peer TID map configured) on the netdev.
+ * Driver should return -ENOSPC when the it does not have room for
+ * additional entries for per-peer NoAck map.
  *
  * @get_channel: Get the current operating channel for the virtual interface.
  * For monitor interfaces, it should return %NULL unless there's a single
@@ -3180,7 +3185,7 @@ struct cfg80211_ops {
 
int (*set_noack_map)(struct wiphy *wiphy,
  struct net_device *dev,
- u16 noack_map);
+ const u8 *peer, u16 noack_map);
 
int (*get_channel)(struct wiphy *wiphy,
   struct wireless_dev *wdev,
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 60fefc5..7425ea6 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -784,7 +784,14 @@
  * messages. Note that per PHY only one application may register.
  *
  * @NL80211_CMD_SET_NOACK_MAP: sets a bitmap for the individual TIDs whether
- *  No Acknowledgement Policy should be applied.
+ * No Acknowledgement Policy should be applied. %NL80211_ATTR_MAC is used
+ * to apply No Acknowledgement policy for a particular connected station.
+ * Station specific NoAck policy configuration is valid only for STA's
+ * current connection, i.e. the configuration will not be used when the
+ * station connects back after disconnection/roaming.
+ * When user-space does not include %NL80211_ATTR_MAC, the No
+ * Acknowledgement Policy setting should be treated as per-netdev
+ * configuration.
  *
  * @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels
  * independently of the userspace SME, send this event indicating
@@ -5005,6 +5012,8 @@ enum nl80211_feature_flags {
  * channel change triggered by radar detection event.
  * No need to start CAC from user-space, no need to react to
  * "radar detected" event.
+ * @NL80211_EXT_FEATURE_PER_STA_NOACK_MAP: Driver supports STA specific NoAck
+ * policy functionality.
  *
  * @NUM_NL80211_EXT_FEATURES: number of extended features.
  * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -5036,6 +5045,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_LOW_POWER_SCAN,
NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN,
NL80211_EXT_FEATURE_DFS_OFFLOAD,
+   NL80211_EXT_FEATURE_PER_STA_NOACK_MAP,
 
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index a2f0eae..621ef38 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -341,6 +341,7 @@ static void ieee80211_del_nan_func(struct wiphy *wiphy,
 
 static int ieee80211_set_noack_map(struct wiphy *wiphy,
  struct net_device *dev,
+ const u8 *peer,
  u16 noack_map)
 {
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index fe27ab4..8d7f055a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3095,16 +3095,26 @@ static int nl80211_set_noack_map(struct sk_buff *skb, 
struct genl_info *info)
struct cfg80211_registered_device *rdev = 

[RFC 1/4] mac80211: Add NoAck policy functionality offload infrastructure

2018-03-27 Thread Vasanthakumar Thiagarajan
Add infrastructure for drivers to implement NoAck policy functionlity.
Driver like ath10k does not use the per-packet TID NoAck policy
configuration.  Instead NoAck map is sent to the firmware/hardware
in control path. Firmware takes care of setting up QOS header and
hw with NoAck policy based on the TID NoAck map.

Drivers having this support should advertise it through a new hw_flag,
IEEE80211_HW_SUPPORTS_NOACK_POLICY, and must implement callback
set_noack_tid_bitmap(). Supporting drivers would receive TID NoAck map
through set_noack_tid_bitmap() instead of receiving as part of every
tx skb.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@codeaurora.org>
---
 include/net/mac80211.h| 15 +++
 net/mac80211/cfg.c| 10 --
 net/mac80211/debugfs.c|  1 +
 net/mac80211/driver-ops.h | 21 +
 net/mac80211/iface.c  |  4 
 net/mac80211/main.c   |  4 
 net/mac80211/trace.h  | 25 +
 net/mac80211/tx.c |  3 ++-
 net/mac80211/wme.c|  3 ++-
 9 files changed, 82 insertions(+), 4 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index d39fd68..5a49c90 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2081,6 +2081,13 @@ struct ieee80211_txq {
  * the frame, as it is not synced with the AP/P2P GO yet, and thus the
  * deauthentication frame might not be transmitted.
  *
+ * @IEEE80211_HW_SUPPORTS_NOACK_POLICY: Hardware (or driver) manages noack
+ * policy handling. Hardware (or driver) takes care of setting
+ * noack policy in the qos header and does not wait for the ack based
+ * on the noack TID map. Driver advertising this support must implement
+ * callback @set_noack_tid_bitmap to receive the user configured noack TID
+ * bitmap.
+ *
  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
  */
 enum ieee80211_hw_flags {
@@ -2125,6 +2132,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_SUPPORTS_TX_FRAG,
IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA,
IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP,
+   IEEE80211_HW_SUPPORTS_NOACK_POLICY,
 
/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
@@ -3490,6 +3498,10 @@ enum ieee80211_reconfig_type {
  * @del_nan_func: Remove a NAN function. The driver must call
  * ieee80211_nan_func_terminated() with
  * NL80211_NAN_FUNC_TERM_REASON_USER_REQUEST reason code upon removal.
+ *
+ * @set_noack_tid_bitmap: Set NoAck policy TID bitmap for a virtual interface.
+ * Drivers advertising NoAck policy handing support
+ * (%IEEE80211_HW_SUPPORTS_NOACK_POLICY) must implement this callback.
  */
 struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -3771,6 +3783,9 @@ struct ieee80211_ops {
void (*del_nan_func)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
u8 instance_id);
+
+   int (*set_noack_tid_bitmap)(struct ieee80211_hw *hw,
+   struct ieee80211_vif *vif, u8 noack_map);
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 5c4b105..a2f0eae 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -347,9 +347,15 @@ static int ieee80211_set_noack_map(struct wiphy *wiphy,
 
sdata->noack_map = noack_map;
 
-   ieee80211_check_fast_xmit_iface(sdata);
+   if (!ieee80211_hw_check(>local->hw, SUPPORTS_NOACK_POLICY)) {
+   ieee80211_check_fast_xmit_iface(sdata);
+   return 0;
+   }
 
-   return 0;
+   if (!ieee80211_sdata_running(sdata))
+   return 0;
+
+   return drv_set_noack_tid_bitmap(sdata->local, sdata, noack_map);
 }
 
 static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index a75653a..b6e6243 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -213,6 +213,7 @@ static ssize_t reset_write(struct file *file, const char 
__user *user_buf,
FLAG(SUPPORTS_TX_FRAG),
FLAG(SUPPORTS_TDLS_BUFFER_STA),
FLAG(DEAUTH_NEED_MGD_TX_PREP),
+   FLAG(SUPPORTS_NOACK_POLICY),
 #undef FLAG
 };
 
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 4d82fe7..a0a2d3c 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1250,4 +1250,25 @@ static inline void drv_del_nan_func(struct 
ieee80211_local *local,
trace_drv_return_void(local);
 }
 
+static inline int drv_set_noack_tid_bitmap(struct ieee80211_local *local,
+  struct ieee80211_sub_if_data *sdata,
+  u16 noack_map)
+{
+   int ret;
+
+   might_sleep();
+   if (!check_sdata_in_driver(sdata))
+   return -EIO;
+
+   if (!local->ops->set_noack_tid_bitmap)
+   return -EOPNOTSUPP;
+
+   trace_drv_se

[RFC 3/4] mac80211: Apply per-peer NoAck tid bitmap configuration

2018-03-27 Thread Vasanthakumar Thiagarajan
Use per-peer noack tid bitmap, if it is configured,
when setting up the qos header. If no per-peer configuration
is set, use the existing nedev wide noack policy configuration.
Also modifies callback set_noack_tid_bitmap() with the provision
to send per-peer NoAck policy configuration to the drivers supporting
the NoAck offload functionality (IEEE80211_HW_SUPPORTS_NOACK_POLICY).

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@codeaurora.org>
---
 include/net/mac80211.h|  7 +--
 net/mac80211/cfg.c| 42 +-
 net/mac80211/driver-ops.h |  5 +++--
 net/mac80211/iface.c  |  2 +-
 net/mac80211/sta_info.h   |  3 +++
 net/mac80211/trace.h  |  9 ++---
 net/mac80211/tx.c |  2 +-
 net/mac80211/wme.c| 34 +-
 8 files changed, 89 insertions(+), 15 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 5a49c90..a5ed552 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3499,7 +3499,9 @@ enum ieee80211_reconfig_type {
  * ieee80211_nan_func_terminated() with
  * NL80211_NAN_FUNC_TERM_REASON_USER_REQUEST reason code upon removal.
  *
- * @set_noack_tid_bitmap: Set NoAck policy TID bitmap for a virtual interface.
+ * @set_noack_tid_bitmap: Set NoAck policy TID bitmap. Apply the TID NoAck
+ * configuration for a particular station when @sta is non-NULL. When @sta
+ * is NULL, apply TID NoAck configuration at virtual interface level.
  * Drivers advertising NoAck policy handing support
  * (%IEEE80211_HW_SUPPORTS_NOACK_POLICY) must implement this callback.
  */
@@ -3785,7 +3787,8 @@ struct ieee80211_ops {
u8 instance_id);
 
int (*set_noack_tid_bitmap)(struct ieee80211_hw *hw,
-   struct ieee80211_vif *vif, u8 noack_map);
+   struct ieee80211_vif *vif,
+   struct ieee80211_sta *sta, u8 noack_map);
 };
 
 /**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 621ef38..1efc9cf 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -345,18 +345,50 @@ static int ieee80211_set_noack_map(struct wiphy *wiphy,
  u16 noack_map)
 {
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+   struct sta_info *sta;
+   int ret;
 
-   sdata->noack_map = noack_map;
+   if (!peer) {
+   sdata->noack_map = noack_map;
 
-   if (!ieee80211_hw_check(>local->hw, SUPPORTS_NOACK_POLICY)) {
-   ieee80211_check_fast_xmit_iface(sdata);
-   return 0;
+   if (!ieee80211_hw_check(>local->hw, 
SUPPORTS_NOACK_POLICY)) {
+   ieee80211_check_fast_xmit_iface(sdata);
+   return 0;
+   }
+
+   if (!ieee80211_sdata_running(sdata))
+   return 0;
+
+   return drv_set_noack_tid_bitmap(sdata->local, sdata, NULL,
+   noack_map);
}
 
+   /* NoAck policy is for a connected client on the dev */
+
if (!ieee80211_sdata_running(sdata))
+   return -ENETDOWN;
+
+   mutex_lock(>local->sta_mtx);
+
+   sta = sta_info_get_bss(sdata, peer);
+   if (!sta) {
+   mutex_unlock(>local->sta_mtx);
+   return -ENOENT;
+   }
+
+   sta->noack_map = noack_map;
+
+   if (!ieee80211_hw_check(>local->hw, SUPPORTS_NOACK_POLICY)) {
+   ieee80211_check_fast_xmit(sta);
+   mutex_unlock(>local->sta_mtx);
return 0;
+   }
+
+   ret = drv_set_noack_tid_bitmap(sdata->local, sdata, sta, noack_map);
 
-   return drv_set_noack_tid_bitmap(sdata->local, sdata, noack_map);
+   mutex_unlock(>local->sta_mtx);
+
+   return ret;
 }
 
 static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index a0a2d3c..8a2154a 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1252,6 +1252,7 @@ static inline void drv_del_nan_func(struct 
ieee80211_local *local,
 
 static inline int drv_set_noack_tid_bitmap(struct ieee80211_local *local,
   struct ieee80211_sub_if_data *sdata,
+  struct sta_info *sta,
   u16 noack_map)
 {
int ret;
@@ -1263,9 +1264,9 @@ static inline int drv_set_noack_tid_bitmap(struct 
ieee80211_local *local,
if (!local->ops->set_noack_tid_bitmap)
return -EOPNOTSUPP;
 
-   trace_drv_set_noack_tid_bitmap(local, sdata, noack_map);
+   trace_drv_set_noack_tid_bitmap(local, sdata, >sta, noack_map);
ret = local->ops->set_noa

Re: [PATCH] ath10k: Add sta rx packet stats per tid

2018-03-02 Thread Vasanthakumar Thiagarajan
On Wednesday 28 February 2018 06:47 PM, Kalle Valo wrote:
> Vasanthakumar Thiagarajan <vthia...@codeaurora.org> writes:
> 
>> Added per tid sta counters for the following
>>
>> - Total number MSDUs received from firmware
>> - Number of MSDUs received with errors like decryption, crc, mic ,etc.
>> - Number of MSDUs dropped in the driver
>> - A-MPDU/A-MSDU subframe stats
>> - Number of MSDUS passed to mac80211
>>
>> All stats other than A-MPDU stats are only for received data frames.
>> A-MPDU stats might have stats for management frames when monitor
>> interface is active where management frames are notified both in wmi
>> and HTT interfaces.
>>
>> These per tid stats can be enabled with tid bitmask through a debugfs
>> like below
>>
>>   echo  > 
>> /sys/kernel/debug/ieee80211/phyX/ath10k/sta_tid_stats_mask
>>
>>   tid 16 (tid_bitmask 0x1) is used for non-qos data/management frames
>>
>> The stats are read from
>> /sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations//dump_tid_stats
>>
>> Sample output:
>>
>>   To enable rx stats for tid 0, 5 and 6,
>>
>>   echo 0x0061 > 
>> /sys/kernel/debug/ieee80211/phy0/ath10k/sta_tid_stats_mask
>>
>> cat 
>> /sys/kernel/debug/ieee80211/phy0/netdev\:wlan15/stations/8c\:fd\:f0\:0a\:8e\:df/dump_tid_stats
>>
>>  Driver Rx pkt stats per tid, ([tid] count)
>>  --
>> MSDUs from FW   [00] 2567[05] 3178[06] 1089
>> MSDUs unchained [00] 0   [05] 0   [06] 0
>> MSDUs locally dropped:chained   [00] 0   [05] 0   [06] 0
>> MSDUs locally dropped:filtered  [00] 0   [05] 0   [06] 0
>> MSDUs queued for mac80211   [00] 2567[05] 3178[06] 1089
>> MSDUs with error:fcs_err[00] 0   [05] 0   [06] 2
>> MSDUs with error:tkip_err   [00] 0   [05] 0   [06] 0
>> MSDUs with error:crypt_err  [00] 0   [05] 0   [06] 0
>> MSDUs with error:peer_idx_inval [00] 0   [05] 0   [06] 0
>>
>> A-MPDU num subframes upto 10[00] 2567[05] 3178[06] 1087
>> A-MPDU num subframes 11-20  [00] 0   [05] 0   [06] 0
>> A-MPDU num subframes 21-30  [00] 0   [05] 0   [06] 0
>> A-MPDU num subframes 31-40  [00] 0   [05] 0   [06] 0
>> A-MPDU num subframes 41-50  [00] 0   [05] 0   [06] 0
>> A-MPDU num subframes 51-60  [00] 0   [05] 0   [06] 0
>> A-MPDU num subframes >60[00] 0   [05] 0   [06] 0
>>
>> A-MSDU num subframes 1  [00] 2567[05] 3178    [06] 1089
>> A-MSDU num subframes 2  [00] 0   [05] 0   [06] 0
>> A-MSDU num subframes 3  [00] 0   [05] 0   [06] 0
>> A-MSDU num subframes 4  [00] 0   [05] 0   [06] 0
>> A-MSDU num subframes >4 [00] 0   [05] 0   [06] 0
>>
>> Signed-off-by: Vasanthakumar Thiagarajan <vthia...@codeaurora.org>
> 
> This added new ath10k-check warnings, I fixed those in the pending
> branch:
> 
> drivers/net/wireless/ath/ath10k/debug.h:203: Alignment should match open 
> parenthesis
> drivers/net/wireless/ath/ath10k/debug.h:226: Alignment should match open 
> parenthesis
> drivers/net/wireless/ath/ath10k/debugfs_sta.c:24: Alignment should match open 
> parenthesis
> drivers/net/wireless/ath/ath10k/debugfs_sta.c:40: Alignment should match open 
> parenthesis
> drivers/net/wireless/ath/ath10k/debugfs_sta.c:60: Alignment should match open 
> parenthesis
> 
> Also I fixed the typo "rages" in debug.h. My changes:

Thanks for fixing it. In most of the cases, fixing above warnings would result 
in lines > 80 chars.
May be we need not be very strict about > 80 char limit?

Vasanth

[PATCH] ath10k: Add sta rx packet stats per tid

2018-01-31 Thread Vasanthakumar Thiagarajan
Added per tid sta counters for the following

- Total number MSDUs received from firmware
- Number of MSDUs received with errors like decryption, crc, mic ,etc.
- Number of MSDUs dropped in the driver
- A-MPDU/A-MSDU subframe stats
- Number of MSDUS passed to mac80211

All stats other than A-MPDU stats are only for received data frames.
A-MPDU stats might have stats for management frames when monitor
interface is active where management frames are notified both in wmi
and HTT interfaces.

These per tid stats can be enabled with tid bitmask through a debugfs
like below

 echo  > /sys/kernel/debug/ieee80211/phyX/ath10k/sta_tid_stats_mask

 tid 16 (tid_bitmask 0x1) is used for non-qos data/management frames

The stats are read from
/sys/kernel/debug/ieee80211/phyX/netdev\:wlanX/stations//dump_tid_stats

Sample output:

 To enable rx stats for tid 0, 5 and 6,

 echo 0x0061 > /sys/kernel/debug/ieee80211/phy0/ath10k/sta_tid_stats_mask

cat 
/sys/kernel/debug/ieee80211/phy0/netdev\:wlan15/stations/8c\:fd\:f0\:0a\:8e\:df/dump_tid_stats

Driver Rx pkt stats per tid, ([tid] count)
--
MSDUs from FW   [00] 2567[05] 3178[06] 1089
MSDUs unchained [00] 0   [05] 0   [06] 0
MSDUs locally dropped:chained   [00] 0   [05] 0   [06] 0
MSDUs locally dropped:filtered  [00] 0   [05] 0   [06] 0
MSDUs queued for mac80211   [00] 2567[05] 3178[06] 1089
MSDUs with error:fcs_err[00] 0   [05] 0   [06] 2
MSDUs with error:tkip_err   [00] 0   [05] 0   [06] 0
MSDUs with error:crypt_err  [00] 0   [05] 0   [06] 0
MSDUs with error:peer_idx_inval [00] 0   [05] 0   [06] 0

A-MPDU num subframes upto 10[00] 2567[05] 3178[06] 1087
A-MPDU num subframes 11-20  [00] 0   [05] 0   [06] 0
A-MPDU num subframes 21-30  [00] 0   [05] 0   [06] 0
A-MPDU num subframes 31-40  [00] 0   [05] 0   [06] 0
A-MPDU num subframes 41-50  [00] 0   [05] 0   [06] 0
A-MPDU num subframes 51-60  [00] 0   [05] 0   [06] 0
A-MPDU num subframes >60[00] 0   [05] 0   [06] 0

A-MSDU num subframes 1  [00] 2567[05] 3178[06] 1089
A-MSDU num subframes 2  [00] 0   [05] 0   [06] 0
A-MSDU num subframes 3  [00] 0   [05] 0   [06] 0
A-MSDU num subframes 4  [00] 0   [05] 0   [06] 0
A-MSDU num subframes >4 [00] 0   [05] 0   [06] 0

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@codeaurora.org>
---
 drivers/net/wireless/ath/ath10k/core.h|  45 
 drivers/net/wireless/ath/ath10k/debug.c   |  48 +
 drivers/net/wireless/ath/ath10k/debug.h   |  31 +++
 drivers/net/wireless/ath/ath10k/debugfs_sta.c | 286 ++
 drivers/net/wireless/ath/ath10k/htt_rx.c  |  71 ++-
 5 files changed, 471 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index fe6b30356d3b..c624b96f8b84 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2005-2011 Atheros Communications Inc.
  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -354,6 +355,45 @@ struct ath10k_txq {
unsigned long num_push_allowed;
 };
 
+enum ath10k_pkt_rx_err {
+   ATH10K_PKT_RX_ERR_FCS,
+   ATH10K_PKT_RX_ERR_TKIP,
+   ATH10K_PKT_RX_ERR_CRYPT,
+   ATH10K_PKT_RX_ERR_PEER_IDX_INVAL,
+   ATH10K_PKT_RX_ERR_MAX,
+};
+
+enum ath10k_ampdu_subfrm_num {
+   ATH10K_AMPDU_SUBFRM_NUM_10,
+   ATH10K_AMPDU_SUBFRM_NUM_20,
+   ATH10K_AMPDU_SUBFRM_NUM_30,
+   ATH10K_AMPDU_SUBFRM_NUM_40,
+   ATH10K_AMPDU_SUBFRM_NUM_50,
+   ATH10K_AMPDU_SUBFRM_NUM_60,
+   ATH10K_AMPDU_SUBFRM_NUM_MORE,
+   ATH10K_AMPDU_SUBFRM_NUM_MAX,
+};
+
+enum ath10k_amsdu_subfrm_num {
+   ATH10K_AMSDU_SUBFRM_NUM_1,
+   ATH10K_AMSDU_SUBFRM_NUM_2,
+   ATH10K_AMSDU_SUBFRM_NUM_3,
+   ATH10K_AMSDU_SUBFRM_NUM_4,
+   ATH10K_AMSDU_SUBFRM_NUM_MORE,
+   ATH10K_AMSDU_SUBFRM_NUM_MAX,
+};
+
+struct ath10k_sta_tid_stats {
+   unsigned long int rx_pkt_from_fw;
+   unsigned long int rx_pkt_unchained;
+   unsigned long int rx_pkt_drop_chained;
+   unsigned long int rx_pkt_drop_filter;
+   unsigned long int rx_pkt_err[ATH10K_PKT_RX_ERR_MAX];
+   unsigned long int rx_pkt_queued_for_mac;
+   unsigned long int rx_pkt_ampdu[ATH10K_AM

Re: [v3] ath10k: rebuild crypto header in rx data frames

2017-10-31 Thread Vasanthakumar Thiagarajan

Sorry top posting.

The issues in raw mode with CCMP-256, GCMP and GCMP-256 were already known and
the same was captured in the commit log. As mentioned in the commit log, raw 
mode
with these ciphers does not work even without this particular patch and it 
needs some cleanup
like done in the follow up patch https://patchwork.kernel.org/patch/10029099/.

Vasanth

From: Sebastian Gottschall <s.gottsch...@dd-wrt.com>
Sent: Tuesday, October 31, 2017 8:24 PM
To: Kalle Valo
Cc: ath...@lists.infradead.org; linux-wireless@vger.kernel.org; Vasanthakumar 
Thiagarajan
Subject: Re: [v3] ath10k: rebuild crypto header in rx data frames

the same is for the MIC

+   /* MIC */
+   if ((status->flag & RX_FLAG_MIC_STRIPPED) &&
+   enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2)
+   skb_trim(msdu, msdu->len - 8);


this code looks wrong too

Am 30.10.2017 um 10:32 schrieb Sebastian Gottschall:
> will check it tomorrow including gcmp-256, ccmp-256. was out for
> weekend :-)
>
> Am 30.10.2017 um 09:39 schrieb Kalle Valo:
>> Kalle Valo <kv...@qca.qualcomm.com> wrote:
>>
>>> Rx data frames notified through HTT_T2H_MSG_TYPE_RX_IND and
>>> HTT_T2H_MSG_TYPE_RX_FRAG_IND expect PN/TSC check to be done
>>> on host (mac80211) rather than firmware. Rebuild cipher header
>>> in every received data frames (that are notified through those
>>> HTT interfaces) from the rx_hdr_status tlv available in the
>>> rx descriptor of the first msdu. Skip setting RX_FLAG_IV_STRIPPED
>>> flag for the packets which requires mac80211 PN/TSC check support
>>> and set appropriate RX_FLAG for stripped crypto tail. Hw QCA988X,
>>> QCA9887, QCA99X0, QCA9984, QCA9888 and QCA4019 currently need the
>>> rebuilding of cipher header to perform PN/TSC check for replay
>>> attack.
>>>
>>> Please note that removing crypto tail for CCMP-256, GCMP and
>>> GCMP-256 ciphers
>>> in raw mode needs to be fixed. Since Rx with these ciphers in raw
>>> mode does not work in the current form even without this patch and
>>> removing crypto tail for these chipers needs clean up, raw mode related
>>> issues in CCMP-256, GCMP and GCMP-256 can be addressed in follow up
>>> patches.
>>>
>>> Tested-by: Manikanta Pubbisetty <mpubb...@qti.qualcomm.com>
>>> Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
>>> Signed-off-by: Kalle Valo <kv...@qca.qualcomm.com>
>> Patch applied to ath-current branch of ath.git, thanks.
>>
>> 7eccb738fce5 ath10k: rebuild crypto header in rx data frames
>>
>

--
Mit freundlichen Grüssen / Regards

Sebastian Gottschall / CTO

NewMedia-NET GmbH - DD-WRT
Firmensitz:  Stubenwaldallee 21a, 64625 Bensheim
Registergericht: Amtsgericht Darmstadt, HRB 25473
Geschäftsführer: Peter Steinhäuser, Christian Scheele
http://www.dd-wrt.com
email: s.gottsch...@dd-wrt.com
Tel.: +496251-582650 / Fax: +496251-5826565



[PATCH] ath10k: Fix data rx for CCMP-256, GCMP and GCMP-256 in raw mode

2017-10-26 Thread Vasanthakumar Thiagarajan
Make sure 16-byte mic is removed from the rx data packet
tail when CCMP-256, GCMP and GCMP-256 ciphers are used
in raw decap mode. This fixed rx traffic failures in those
ciphers in raw mode. Split the helper returning crypto
tail length into two, one to get the ICV length and other
to get the mic lengh for the cipher to make it clean.

Fixes: 2ea9f12cefe4 ("ath10k: add new cipher suite support")
Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---

This patch depends on https://patchwork.kernel.org/patch/10028621/

 drivers/net/wireless/ath/ath10k/htt_rx.c | 51 
 1 file changed, 38 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 5beb6ee0f091..656385f80929 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -566,18 +566,16 @@ static int ath10k_htt_rx_crypto_param_len(struct ath10k 
*ar,
 
 #define MICHAEL_MIC_LEN 8
 
-static int ath10k_htt_rx_crypto_tail_len(struct ath10k *ar,
-enum htt_rx_mpdu_encrypt_type type)
+static int ath10k_htt_rx_crypto_mic_len(struct ath10k *ar,
+   enum htt_rx_mpdu_encrypt_type type)
 {
switch (type) {
case HTT_RX_MPDU_ENCRYPT_NONE:
-   return 0;
case HTT_RX_MPDU_ENCRYPT_WEP40:
case HTT_RX_MPDU_ENCRYPT_WEP104:
-   return IEEE80211_WEP_ICV_LEN;
case HTT_RX_MPDU_ENCRYPT_TKIP_WITHOUT_MIC:
case HTT_RX_MPDU_ENCRYPT_TKIP_WPA:
-   return IEEE80211_TKIP_ICV_LEN;
+   return 0;
case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2:
return IEEE80211_CCMP_MIC_LEN;
case HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2:
@@ -594,6 +592,31 @@ static int ath10k_htt_rx_crypto_tail_len(struct ath10k *ar,
return 0;
 }
 
+static int ath10k_htt_rx_crypto_icv_len(struct ath10k *ar,
+   enum htt_rx_mpdu_encrypt_type type)
+{
+   switch (type) {
+   case HTT_RX_MPDU_ENCRYPT_NONE:
+   case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2:
+   case HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2:
+   case HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2:
+   case HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2:
+   return 0;
+   case HTT_RX_MPDU_ENCRYPT_WEP40:
+   case HTT_RX_MPDU_ENCRYPT_WEP104:
+   return IEEE80211_WEP_ICV_LEN;
+   case HTT_RX_MPDU_ENCRYPT_TKIP_WITHOUT_MIC:
+   case HTT_RX_MPDU_ENCRYPT_TKIP_WPA:
+   return IEEE80211_TKIP_ICV_LEN;
+   case HTT_RX_MPDU_ENCRYPT_WEP128:
+   case HTT_RX_MPDU_ENCRYPT_WAPI:
+   break;
+   }
+
+   ath10k_warn(ar, "unsupported encryption type %d\n", type);
+   return 0;
+}
+
 struct amsdu_subframe_hdr {
u8 dst[ETH_ALEN];
u8 src[ETH_ALEN];
@@ -1063,25 +1086,27 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k 
*ar,
/* Tail */
if (status->flag & RX_FLAG_IV_STRIPPED) {
skb_trim(msdu, msdu->len -
-ath10k_htt_rx_crypto_tail_len(ar, enctype));
+ath10k_htt_rx_crypto_mic_len(ar, enctype));
+
+   skb_trim(msdu, msdu->len -
+ath10k_htt_rx_crypto_icv_len(ar, enctype));
} else {
/* MIC */
-   if ((status->flag & RX_FLAG_MIC_STRIPPED) &&
-   enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2)
-   skb_trim(msdu, msdu->len - 8);
+   if (status->flag & RX_FLAG_MIC_STRIPPED)
+   skb_trim(msdu, msdu->len -
+ath10k_htt_rx_crypto_mic_len(ar, enctype));
 
/* ICV */
-   if (status->flag & RX_FLAG_ICV_STRIPPED &&
-   enctype != HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2)
+   if (status->flag & RX_FLAG_ICV_STRIPPED)
skb_trim(msdu, msdu->len -
-ath10k_htt_rx_crypto_tail_len(ar, enctype));
+ath10k_htt_rx_crypto_icv_len(ar, enctype));
}
 
/* MMIC */
if ((status->flag & RX_FLAG_MMIC_STRIPPED) &&
!ieee80211_has_morefrags(hdr->frame_control) &&
enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
-   skb_trim(msdu, msdu->len - 8);
+   skb_trim(msdu, msdu->len - MICHAEL_MIC_LEN);
 
/* Head */
if (status->flag & RX_FLAG_IV_STRIPPED) {
-- 
1.9.1



Re: [PATCH] ath10k: rebuild crypto header in RX data frames

2017-10-23 Thread Vasanthakumar Thiagarajan
On Saturday 21 October 2017 01:41 AM, Sebastian Gottschall wrote:
> i suggest the following patch on top of yours. please tell me if my thoughts 
> are correct here. its mainly a guess

I agree we need to take care of this for newly added ciphers as well. How about 
making it as a separate patch 
to make the patch bit smaller and to reduce the difficulties in back porting it 
for ciphers supported for long 
time?

Vasanth

[PATCH] cfg80211: Fix dfs state propagation for non-DFS center channel

2017-04-18 Thread Vasanthakumar Thiagarajan
When part of a bigger bandwidth (160 MHz) channel falls in DFS
channel range it is possible that the  center frequency may not
necessarily be a radar channel. Remove the sanity check on channel
flag for IEEE80211_CHAN_RADAR in regulatory_propagate_dfs_state(),
this should fix the dfs state propagation for non-DFS center freq
which has DFS channels in it's bandwidth, should also fix unnecessary
WARN_ON() spam in regulatory_propagate_dfs_state().

Fixes: 8976672736d6 ("cfg80211: Share Channel DFS state across wiphys of same 
DFS domain")
Reported-by: Johannes Berg <johan...@sipsolutions.net>
Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 net/wireless/reg.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index a38f315..5fae296 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -3244,9 +3244,6 @@ void regulatory_propagate_dfs_state(struct wiphy *wiphy,
if (WARN_ON(!cfg80211_chandef_valid(chandef)))
return;
 
-   if (WARN_ON(!(chandef->chan->flags & IEEE80211_CHAN_RADAR)))
-   return;
-
list_for_each_entry(rdev, _rdev_list, list) {
if (wiphy == >wiphy)
continue;
-- 
1.9.1



Re: [PATCH V2 3/3] cfg80211: Share Channel DFS state across wiphys of same DFS domain

2017-04-18 Thread Vasanthakumar Thiagarajan
On Tuesday 18 April 2017 04:20 PM, Johannes Berg wrote:
>
>> +void regulatory_propagate_dfs_state(struct wiphy *wiphy,
>> +struct cfg80211_chan_def
>> *chandef,
>> +enum nl80211_dfs_state
>> dfs_state,
>> +enum nl80211_radar_event event)
>> +{
>> +struct cfg80211_registered_device *rdev;
>> +
>> +ASSERT_RTNL();
>> +
>> +if (WARN_ON(!cfg80211_chandef_valid(chandef)))
>> +return;
>> +
>> +if (WARN_ON(!(chandef->chan->flags & IEEE80211_CHAN_RADAR)))
>> +return;
>
>
> This warn on reliably triggers for me when I run the "ap_vht160" hwsim
> test from wpa_supplicant.
>
> I think there might be some confusion about this when parts of the 160
> MHz channel require radar and parts don't? But I haven't looked into
> this at all.

Correct, when some part of a bigger bandwidth channel falls in DFS channel range
channel definition of that channel's center freq is may not be a radar channel 
and
bailing out based on the channel flag there is not right.

Sorry for the bug and thanks for reporting it.

>
> Please send me a fix ASAP so Jouni doesn't shout at me for test
> failures :)

Sure.

Vasanth

[PATCH V2 2/3] cfg80211: Disallow moving out of operating DFS channel in non-ETSI

2017-02-27 Thread Vasanthakumar Thiagarajan
For non-ETSI regulatory domain, CAC result on DFS channel
may not be valid once moving out of that channel (as done
during remain-on-channel, scannning and off-channel tx).
Running CAC on an operating DFS channel after every off-channel
operation will only add complexity and disturb the current
link. Better do not allow any off-channel switch from a DFS
operating channel in non-ETSI domain.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 net/wireless/nl80211.c | 52 ++
 1 file changed, 52 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d516527..b15903b 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6556,6 +6556,19 @@ static int nl80211_parse_random_mac(struct nlattr 
**attrs,
return 0;
 }
 
+static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
+{
+   ASSERT_WDEV_LOCK(wdev);
+
+   if (!cfg80211_beaconing_iface_active(wdev))
+   return true;
+
+   if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
+   return true;
+
+   return regulatory_pre_cac_allowed(wdev->wiphy);
+}
+
 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 {
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6681,6 +6694,25 @@ static int nl80211_trigger_scan(struct sk_buff *skb, 
struct genl_info *info)
 
request->n_channels = i;
 
+   wdev_lock(wdev);
+   if (!cfg80211_off_channel_oper_allowed(wdev)) {
+   struct ieee80211_channel *chan;
+
+   if (request->n_channels != 1) {
+   wdev_unlock(wdev);
+   err = -EBUSY;
+   goto out_free;
+   }
+
+   chan = request->channels[0];
+   if (chan->center_freq != wdev->chandef.chan->center_freq) {
+   wdev_unlock(wdev);
+   err = -EBUSY;
+   goto out_free;
+   }
+   }
+   wdev_unlock(wdev);
+
i = 0;
if (n_ssids) {
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], 
tmp) {
@@ -9103,6 +9135,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct wireless_dev *wdev = info->user_ptr[1];
struct cfg80211_chan_def chandef;
+   const struct cfg80211_chan_def *compat_chandef;
struct sk_buff *msg;
void *hdr;
u64 cookie;
@@ -9131,6 +9164,18 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
if (err)
return err;
 
+   wdev_lock(wdev);
+   if (!cfg80211_off_channel_oper_allowed(wdev) &&
+   !cfg80211_chandef_identical(>chandef, )) {
+   compat_chandef = cfg80211_chandef_compatible(>chandef,
+);
+   if (compat_chandef != ) {
+   wdev_unlock(wdev);
+   return -EBUSY;
+   }
+   }
+   wdev_unlock(wdev);
+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;
@@ -9306,6 +9351,13 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct 
genl_info *info)
if (!chandef.chan && params.offchan)
return -EINVAL;
 
+   wdev_lock(wdev);
+   if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
+   wdev_unlock(wdev);
+   return -EBUSY;
+   }
+   wdev_unlock(wdev);
+
params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
 
-- 
1.9.1



[PATCH V2 3/3] cfg80211: Share Channel DFS state across wiphys of same DFS domain

2017-02-27 Thread Vasanthakumar Thiagarajan
Sharing DFS channel state across multiple wiphys (radios) could
be useful with multiple radios on the system. When one radio
completes CAC and markes the channel available another radio
can use this information and start beaconing without really doing
CAC.

Whenever there is a state change in dfs channel associated to
a particular wiphy the the same state change is propagated to
other wiphys having the same DFS reg domain configuration.
Also when a new wiphy is created the dfs channel state of
other existing wiphys of same DFS domain is copied.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---

V2:

- Add a sanity check on the chandef in regulatory_propagate_dfs_state()
  to make sure the channel is valid before proceeding with dfs state
  propagation for the channel.

 net/wireless/chan.c |  30 ++---
 net/wireless/core.c |  37 
 net/wireless/core.h |   6 +++
 net/wireless/mlme.c |  10 +
 net/wireless/reg.c  | 120 
 net/wireless/reg.h  |  22 ++
 6 files changed, 218 insertions(+), 7 deletions(-)

diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 099f13c..b8aa5a7 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -531,16 +531,11 @@ bool cfg80211_beaconing_iface_active(struct wireless_dev 
*wdev)
return active;
 }
 
-bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
- struct ieee80211_channel *chan)
+static bool cfg80211_is_wiphy_oper_chan(struct wiphy *wiphy,
+   struct ieee80211_channel *chan)
 {
struct wireless_dev *wdev;
 
-   ASSERT_RTNL();
-
-   if (!(chan->flags & IEEE80211_CHAN_RADAR))
-   return false;
-
list_for_each_entry(wdev, >wdev_list, list) {
wdev_lock(wdev);
if (!cfg80211_beaconing_iface_active(wdev)) {
@@ -558,6 +553,27 @@ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
return false;
 }
 
+bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
+ struct ieee80211_channel *chan)
+{
+   struct cfg80211_registered_device *rdev;
+
+   ASSERT_RTNL();
+
+   if (!(chan->flags & IEEE80211_CHAN_RADAR))
+   return false;
+
+   list_for_each_entry(rdev, _rdev_list, list) {
+   if (!reg_dfs_domain_same(wiphy, >wiphy))
+   continue;
+
+   if (cfg80211_is_wiphy_oper_chan(>wiphy, chan))
+   return true;
+   }
+
+   return false;
+}
+
 static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
 u32 center_freq,
 u32 bandwidth)
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 04143df..a5630e9 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -357,6 +357,38 @@ static void cfg80211_sched_scan_stop_wk(struct work_struct 
*work)
rtnl_unlock();
 }
 
+static void cfg80211_propagate_radar_detect_wk(struct work_struct *work)
+{
+   struct cfg80211_registered_device *rdev;
+
+   rdev = container_of(work, struct cfg80211_registered_device,
+   propagate_radar_detect_wk);
+
+   rtnl_lock();
+
+   regulatory_propagate_dfs_state(>wiphy, >radar_chandef,
+  NL80211_DFS_UNAVAILABLE,
+  NL80211_RADAR_DETECTED);
+
+   rtnl_unlock();
+}
+
+static void cfg80211_propagate_cac_done_wk(struct work_struct *work)
+{
+   struct cfg80211_registered_device *rdev;
+
+   rdev = container_of(work, struct cfg80211_registered_device,
+   propagate_cac_done_wk);
+
+   rtnl_lock();
+
+   regulatory_propagate_dfs_state(>wiphy, >cac_done_chandef,
+  NL80211_DFS_AVAILABLE,
+  NL80211_RADAR_CAC_FINISHED);
+
+   rtnl_unlock();
+}
+
 /* exported functions */
 
 struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
@@ -456,6 +488,9 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, 
int sizeof_priv,
spin_lock_init(>destroy_list_lock);
INIT_WORK(>destroy_work, cfg80211_destroy_iface_wk);
INIT_WORK(>sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
+   INIT_WORK(>propagate_radar_detect_wk,
+ cfg80211_propagate_radar_detect_wk);
+   INIT_WORK(>propagate_cac_done_wk, cfg80211_propagate_cac_done_wk);
 
 #ifdef CONFIG_CFG80211_DEFAULT_PS
rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
@@ -915,6 +950,8 @@ void wiphy_unregister(struct wiphy *wiphy)
flush_work(>destroy_work);
flush_work(>sched_scan_stop_wk);
flush_work(>mlme_unreg_wk);
+   flush_work(>propagate_radar_dete

[PATCH V2 1/3] cfg80211: Make pre-CAC results valid only for ETSI domain

2017-02-27 Thread Vasanthakumar Thiagarajan
DFS requirement for ETSI domain (section 4.7.1.4 in
ETSI EN 301 893 V1.8.1) is the only one which explicitly
states that once DFS channel is marked as available afer
the CAC, this channel will remain in available state even
moving to a different operating channel. But the same is
not explicitly stated in FCC DFS requirement. Also, Pre-CAC
requriements are not explicitly mentioned in FCC requirement.
Current implementation in keeping DFS channel in available
state is same as described in ETSI domain.

For ETSI DFS domain, this patch gives a grace period of 2 seconds
since the completion of successful CAC before moving the channel's
DFS state to 'usable' from 'available' state. The same grace period
is checked against the channel's dfs_state_entered timestamp while
deciding if a DFS channel is available for operation. There is a new
radar event, NL80211_RADAR_PRE_CAC_EXPIRED, reported when DFS channel
is moved from available to usable state after the grace period. Also
make sure the DFS channel state is reset to usable once the beaconing
operation on that channel is brought down (like stop_ap, leave_ibss
and leave_mesh) in non-ETSI domain.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 include/uapi/linux/nl80211.h |   5 +++
 net/wireless/ap.c|   5 +++
 net/wireless/chan.c  | 101 +++
 net/wireless/core.h  |  10 +
 net/wireless/ibss.c  |   1 +
 net/wireless/mesh.c  |   1 +
 net/wireless/mlme.c  |  40 +
 net/wireless/reg.c   |  28 
 net/wireless/reg.h   |  14 ++
 9 files changed, 196 insertions(+), 9 deletions(-)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 9a499b1..cd4dfef 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4913,12 +4913,17 @@ enum nl80211_smps_mode {
  * change to the channel status.
  * @NL80211_RADAR_NOP_FINISHED: The Non-Occupancy Period for this channel is
  * over, channel becomes usable.
+ * @NL80211_RADAR_PRE_CAC_EXPIRED: Channel Availability Check done on this
+ * non-operating channel is expired and no longer valid. New CAC must
+ * be done on this channel before starting the operation. This is not
+ * applicable for ETSI dfs domain where pre-CAC is valid for ever.
  */
 enum nl80211_radar_event {
NL80211_RADAR_DETECTED,
NL80211_RADAR_CAC_FINISHED,
NL80211_RADAR_CAC_ABORTED,
NL80211_RADAR_NOP_FINISHED,
+   NL80211_RADAR_PRE_CAC_EXPIRED,
 };
 
 /**
diff --git a/net/wireless/ap.c b/net/wireless/ap.c
index bdad1f9..25666d3 100644
--- a/net/wireless/ap.c
+++ b/net/wireless/ap.c
@@ -32,6 +32,11 @@ int __cfg80211_stop_ap(struct cfg80211_registered_device 
*rdev,
rdev_set_qos_map(rdev, dev, NULL);
if (notify)
nl80211_send_ap_stopped(wdev);
+
+   /* Should we apply the grace period during beaconing interface
+* shutdown also?
+*/
+   cfg80211_sched_dfs_chan_update(rdev);
}
 
return err;
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 5497d022..099f13c 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -456,6 +456,107 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
return (r1 + r2 > 0);
 }
 
+/*
+ * Checks if center frequency of chan falls with in the bandwidth
+ * range of chandef.
+ */
+bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
+ struct ieee80211_channel *chan)
+{
+   int width;
+   u32 cf_offset, freq;
+
+   if (chandef->chan->center_freq == chan->center_freq)
+   return true;
+
+   width = cfg80211_chandef_get_width(chandef);
+   if (width <= 20)
+   return false;
+
+   cf_offset = width / 2 - 10;
+
+   for (freq = chandef->center_freq1 - width / 2 + 10;
+freq <= chandef->center_freq1 + width / 2 - 10; freq += 20) {
+   if (chan->center_freq == freq)
+   return true;
+   }
+
+   if (!chandef->center_freq2)
+   return false;
+
+   for (freq = chandef->center_freq2 - width / 2 + 10;
+freq <= chandef->center_freq2 + width / 2 - 10; freq += 20) {
+   if (chan->center_freq == freq)
+   return true;
+   }
+
+   return false;
+}
+
+bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev)
+{
+   bool active = false;
+
+   ASSERT_WDEV_LOCK(wdev);
+
+   if (!wdev->chandef.chan)
+   return false;
+
+   switch (wdev->iftype) {
+   case NL80211_IFTYPE_AP:
+   case NL80211_IFTYPE_P2P_GO:
+   active = wdev->beacon_interval != 0;
+   break;
+   case NL80211_IFTYPE_ADHOC:
+   active =

[PATCH V2 0/3] Pre-CAC and sharing DFS state across multiple radios

2017-02-27 Thread Vasanthakumar Thiagarajan
Currently irrespective of dfs domain and radar detection activity
pre-CAC results for a wiphy are retained till the wiphy is detroyed.
This may not be preferred in non-ETSI dfs domain where pre-CAC is not
explicitly mentioned in the respective DFS requirement spec. This patch
set modifies the current behaviour of pre-CAC for non-ETSI domain by
giving 2 seconds grace period for dfs master interface to start operating
on the CAC completed channel.

This patch set also adds support to share dfs channel state across
multiple radios of the same regulatory configuration.

Vasanthakumar Thiagarajan (3):
  cfg80211: Make pre-CAC results valid only for ETSI domain
  cfg80211: Disallow moving out of operating DFS channel in non-ETSI
  cfg80211: Share Channel DFS state across wiphys of same DFS domain

 include/uapi/linux/nl80211.h |   5 ++
 net/wireless/ap.c|   5 ++
 net/wireless/chan.c  | 117 ++
 net/wireless/core.c  |  37 +++
 net/wireless/core.h  |  16 +
 net/wireless/ibss.c  |   1 +
 net/wireless/mesh.c  |   1 +
 net/wireless/mlme.c  |  50 ---
 net/wireless/nl80211.c   |  52 +++
 net/wireless/reg.c   | 148 +++
 net/wireless/reg.h   |  36 +++
 11 files changed, 459 insertions(+), 9 deletions(-)

-- 
1.9.1



[PATCH 3/3] cfg80211: Share Channel DFS state across wiphys of same DFS domain

2017-02-20 Thread Vasanthakumar Thiagarajan
Sharing DFS channel state across multiple wiphys (radios) could
be useful with multiple radios on the system. When one radio
completes CAC and markes the channel available another radio
can use this information and start beaconing without really doing
CAC.

Whenever there is a state change in dfs channel associated to
a particular wiphy the the same state change is propagated to
other wiphys having the same DFS reg domain configuration.
Also when a new wiphy is created the dfs channel state of
other existing wiphys of same DFS domain is copied.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 net/wireless/chan.c |  30 ++
 net/wireless/core.c |  37 +
 net/wireless/core.h |   6 +++
 net/wireless/mlme.c |  10 +
 net/wireless/reg.c  | 117 
 net/wireless/reg.h  |  22 ++
 6 files changed, 215 insertions(+), 7 deletions(-)

diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 099f13c..b8aa5a7 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -531,16 +531,11 @@ bool cfg80211_beaconing_iface_active(struct wireless_dev 
*wdev)
return active;
 }
 
-bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
- struct ieee80211_channel *chan)
+static bool cfg80211_is_wiphy_oper_chan(struct wiphy *wiphy,
+   struct ieee80211_channel *chan)
 {
struct wireless_dev *wdev;
 
-   ASSERT_RTNL();
-
-   if (!(chan->flags & IEEE80211_CHAN_RADAR))
-   return false;
-
list_for_each_entry(wdev, >wdev_list, list) {
wdev_lock(wdev);
if (!cfg80211_beaconing_iface_active(wdev)) {
@@ -558,6 +553,27 @@ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
return false;
 }
 
+bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
+ struct ieee80211_channel *chan)
+{
+   struct cfg80211_registered_device *rdev;
+
+   ASSERT_RTNL();
+
+   if (!(chan->flags & IEEE80211_CHAN_RADAR))
+   return false;
+
+   list_for_each_entry(rdev, _rdev_list, list) {
+   if (!reg_dfs_domain_same(wiphy, >wiphy))
+   continue;
+
+   if (cfg80211_is_wiphy_oper_chan(>wiphy, chan))
+   return true;
+   }
+
+   return false;
+}
+
 static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
 u32 center_freq,
 u32 bandwidth)
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 04143df..a5630e9 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -357,6 +357,38 @@ static void cfg80211_sched_scan_stop_wk(struct work_struct 
*work)
rtnl_unlock();
 }
 
+static void cfg80211_propagate_radar_detect_wk(struct work_struct *work)
+{
+   struct cfg80211_registered_device *rdev;
+
+   rdev = container_of(work, struct cfg80211_registered_device,
+   propagate_radar_detect_wk);
+
+   rtnl_lock();
+
+   regulatory_propagate_dfs_state(>wiphy, >radar_chandef,
+  NL80211_DFS_UNAVAILABLE,
+  NL80211_RADAR_DETECTED);
+
+   rtnl_unlock();
+}
+
+static void cfg80211_propagate_cac_done_wk(struct work_struct *work)
+{
+   struct cfg80211_registered_device *rdev;
+
+   rdev = container_of(work, struct cfg80211_registered_device,
+   propagate_cac_done_wk);
+
+   rtnl_lock();
+
+   regulatory_propagate_dfs_state(>wiphy, >cac_done_chandef,
+  NL80211_DFS_AVAILABLE,
+  NL80211_RADAR_CAC_FINISHED);
+
+   rtnl_unlock();
+}
+
 /* exported functions */
 
 struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
@@ -456,6 +488,9 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, 
int sizeof_priv,
spin_lock_init(>destroy_list_lock);
INIT_WORK(>destroy_work, cfg80211_destroy_iface_wk);
INIT_WORK(>sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
+   INIT_WORK(>propagate_radar_detect_wk,
+ cfg80211_propagate_radar_detect_wk);
+   INIT_WORK(>propagate_cac_done_wk, cfg80211_propagate_cac_done_wk);
 
 #ifdef CONFIG_CFG80211_DEFAULT_PS
rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
@@ -915,6 +950,8 @@ void wiphy_unregister(struct wiphy *wiphy)
flush_work(>destroy_work);
flush_work(>sched_scan_stop_wk);
flush_work(>mlme_unreg_wk);
+   flush_work(>propagate_radar_detect_wk);
+   flush_work(>propagate_cac_done_wk);
 
 #ifdef CONFIG_PM
if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)
diff --git a/net/wireless/core.h b/net/wirele

[PATCH 1/3] cfg80211: Make pre-CAC results valid only for ETSI domain

2017-02-20 Thread Vasanthakumar Thiagarajan
DFS requirement for ETSI domain (section 4.7.1.4 in
ETSI EN 301 893 V1.8.1) is the only one which explicitly
states that once DFS channel is marked as available afer
the CAC, this channel will remain in available state even
moving to a different operating channel. But the same is
not explicitly stated in FCC DFS requirement. Also, Pre-CAC
requriements are not explicitly mentioned in FCC requirement.
Current implementation in keeping DFS channel in available
state is same as described in ETSI domain.

For ETSI DFS domain, this patch gives a grace period of 2 seconds
since the completion of successful CAC before moving the channel's
DFS state to 'usable' from 'available' state. The same grace period
is checked against the channel's dfs_state_entered timestamp while
deciding if a DFS channel is available for operation. There is a new
radar event, NL80211_RADAR_PRE_CAC_EXPIRED, reported when DFS channel
is moved from available to usable state after the grace period. Also
make sure the DFS channel state is reset to usable once the beaconing
operation on that channel is brought down (like stop_ap, leave_ibss
and leave_mesh) in non-ETSI domain.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 include/uapi/linux/nl80211.h |   5 +++
 net/wireless/ap.c|   5 +++
 net/wireless/chan.c  | 101 +++
 net/wireless/core.h  |  10 +
 net/wireless/ibss.c  |   1 +
 net/wireless/mesh.c  |   1 +
 net/wireless/mlme.c  |  40 +
 net/wireless/reg.c   |  28 
 net/wireless/reg.h   |  14 ++
 9 files changed, 196 insertions(+), 9 deletions(-)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 9a499b1..cd4dfef 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4913,12 +4913,17 @@ enum nl80211_smps_mode {
  * change to the channel status.
  * @NL80211_RADAR_NOP_FINISHED: The Non-Occupancy Period for this channel is
  * over, channel becomes usable.
+ * @NL80211_RADAR_PRE_CAC_EXPIRED: Channel Availability Check done on this
+ * non-operating channel is expired and no longer valid. New CAC must
+ * be done on this channel before starting the operation. This is not
+ * applicable for ETSI dfs domain where pre-CAC is valid for ever.
  */
 enum nl80211_radar_event {
NL80211_RADAR_DETECTED,
NL80211_RADAR_CAC_FINISHED,
NL80211_RADAR_CAC_ABORTED,
NL80211_RADAR_NOP_FINISHED,
+   NL80211_RADAR_PRE_CAC_EXPIRED,
 };
 
 /**
diff --git a/net/wireless/ap.c b/net/wireless/ap.c
index bdad1f9..25666d3 100644
--- a/net/wireless/ap.c
+++ b/net/wireless/ap.c
@@ -32,6 +32,11 @@ int __cfg80211_stop_ap(struct cfg80211_registered_device 
*rdev,
rdev_set_qos_map(rdev, dev, NULL);
if (notify)
nl80211_send_ap_stopped(wdev);
+
+   /* Should we apply the grace period during beaconing interface
+* shutdown also?
+*/
+   cfg80211_sched_dfs_chan_update(rdev);
}
 
return err;
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 5497d022..099f13c 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -456,6 +456,107 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
return (r1 + r2 > 0);
 }
 
+/*
+ * Checks if center frequency of chan falls with in the bandwidth
+ * range of chandef.
+ */
+bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
+ struct ieee80211_channel *chan)
+{
+   int width;
+   u32 cf_offset, freq;
+
+   if (chandef->chan->center_freq == chan->center_freq)
+   return true;
+
+   width = cfg80211_chandef_get_width(chandef);
+   if (width <= 20)
+   return false;
+
+   cf_offset = width / 2 - 10;
+
+   for (freq = chandef->center_freq1 - width / 2 + 10;
+freq <= chandef->center_freq1 + width / 2 - 10; freq += 20) {
+   if (chan->center_freq == freq)
+   return true;
+   }
+
+   if (!chandef->center_freq2)
+   return false;
+
+   for (freq = chandef->center_freq2 - width / 2 + 10;
+freq <= chandef->center_freq2 + width / 2 - 10; freq += 20) {
+   if (chan->center_freq == freq)
+   return true;
+   }
+
+   return false;
+}
+
+bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev)
+{
+   bool active = false;
+
+   ASSERT_WDEV_LOCK(wdev);
+
+   if (!wdev->chandef.chan)
+   return false;
+
+   switch (wdev->iftype) {
+   case NL80211_IFTYPE_AP:
+   case NL80211_IFTYPE_P2P_GO:
+   active = wdev->beacon_interval != 0;
+   break;
+   case NL80211_IFTYPE_ADHOC:
+   active =

[PATCH 2/3] cfg80211: Disallow moving out of operating DFS channel in non-ETSI

2017-02-20 Thread Vasanthakumar Thiagarajan
For non-ETSI regulatory domain, CAC result on DFS channel
may not be valid once moving out of that channel (as done
during remain-on-channel, scannning and off-channel tx).
Running CAC on an operating DFS channel after every off-channel
operation will only add complexity and disturb the current
link. Better do not allow any off-channel switch from a DFS
operating channel in non-ETSI domain.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 net/wireless/nl80211.c | 52 ++
 1 file changed, 52 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d516527..b15903b 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6556,6 +6556,19 @@ static int nl80211_parse_random_mac(struct nlattr 
**attrs,
return 0;
 }
 
+static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
+{
+   ASSERT_WDEV_LOCK(wdev);
+
+   if (!cfg80211_beaconing_iface_active(wdev))
+   return true;
+
+   if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
+   return true;
+
+   return regulatory_pre_cac_allowed(wdev->wiphy);
+}
+
 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 {
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6681,6 +6694,25 @@ static int nl80211_trigger_scan(struct sk_buff *skb, 
struct genl_info *info)
 
request->n_channels = i;
 
+   wdev_lock(wdev);
+   if (!cfg80211_off_channel_oper_allowed(wdev)) {
+   struct ieee80211_channel *chan;
+
+   if (request->n_channels != 1) {
+   wdev_unlock(wdev);
+   err = -EBUSY;
+   goto out_free;
+   }
+
+   chan = request->channels[0];
+   if (chan->center_freq != wdev->chandef.chan->center_freq) {
+   wdev_unlock(wdev);
+   err = -EBUSY;
+   goto out_free;
+   }
+   }
+   wdev_unlock(wdev);
+
i = 0;
if (n_ssids) {
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], 
tmp) {
@@ -9103,6 +9135,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct wireless_dev *wdev = info->user_ptr[1];
struct cfg80211_chan_def chandef;
+   const struct cfg80211_chan_def *compat_chandef;
struct sk_buff *msg;
void *hdr;
u64 cookie;
@@ -9131,6 +9164,18 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
if (err)
return err;
 
+   wdev_lock(wdev);
+   if (!cfg80211_off_channel_oper_allowed(wdev) &&
+   !cfg80211_chandef_identical(>chandef, )) {
+   compat_chandef = cfg80211_chandef_compatible(>chandef,
+);
+   if (compat_chandef != ) {
+   wdev_unlock(wdev);
+   return -EBUSY;
+   }
+   }
+   wdev_unlock(wdev);
+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;
@@ -9306,6 +9351,13 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct 
genl_info *info)
if (!chandef.chan && params.offchan)
return -EINVAL;
 
+   wdev_lock(wdev);
+   if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
+   wdev_unlock(wdev);
+   return -EBUSY;
+   }
+   wdev_unlock(wdev);
+
params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
 
-- 
1.9.1



[PATCH 0/3] Pre-CAC and sharing DFS state across multiple radios

2017-02-20 Thread Vasanthakumar Thiagarajan
Currently irrespective of dfs domain and radar detection activity
pre-CAC results for a wiphy are retained till the wiphy is detroyed.
This may not be preferred in non-ETSI dfs domain where pre-CAC is not
explicitly mentioned in the respective DFS requirement spec. This patch
set modifies the current behaviour of pre-CAC for non-ETSI domain by
giving 2 seconds grace period for dfs master interface to start operating
on the CAC completed channel.

This patch set also adds support to share dfs channel state across
multiple radios of the same regulatory configuration.

Vasanthakumar Thiagarajan (3):
  cfg80211: Make pre-CAC results valid only for ETSI domain
  cfg80211: Disallow moving out of operating DFS channel in non-ETSI
  cfg80211: Share Channel DFS state across wiphys of same DFS domain

 include/uapi/linux/nl80211.h |   5 ++
 net/wireless/ap.c|   5 ++
 net/wireless/chan.c  | 117 ++
 net/wireless/core.c  |  37 +++
 net/wireless/core.h  |  16 +
 net/wireless/ibss.c  |   1 +
 net/wireless/mesh.c  |   1 +
 net/wireless/mlme.c  |  50 ---
 net/wireless/nl80211.c   |  52 
 net/wireless/reg.c   | 145 +++
 net/wireless/reg.h   |  36 +++
 11 files changed, 456 insertions(+), 9 deletions(-)

-- 
1.9.1



[RFC V2 2/3] cfg80211: Disallow moving out of operating DFS channel in non-ETSI

2017-02-16 Thread Vasanthakumar Thiagarajan
For non-ETSI regulatory domain, CAC result on DFS channel
may not be valid once moving out of that channel (as done
during remain-on-channel, scannning and off-channel tx).
Running CAC on an operating DFS channel after every off-channel
operation will only add complexity and disturb the current
link. Better do not allow any off-channel switch from a DFS
operating channel in non-ETSI domain.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---

V2:
Addressing below comments from Johannes

- Add locking assertion to cfg80211_off_channel_oper_allowed()
- Protect wdev->chandef access with wdev_lock()

 net/wireless/nl80211.c | 52 ++
 1 file changed, 52 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 63dfa60..94c84bd 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6506,6 +6506,19 @@ static int nl80211_parse_random_mac(struct nlattr 
**attrs,
return 0;
 }
 
+static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
+{
+   ASSERT_WDEV_LOCK(wdev);
+
+   if (!cfg80211_beaconing_iface_active(wdev))
+   return true;
+
+   if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
+   return true;
+
+   return regulatory_pre_cac_allowed(wdev->wiphy);
+}
+
 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 {
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6631,6 +6644,25 @@ static int nl80211_trigger_scan(struct sk_buff *skb, 
struct genl_info *info)
 
request->n_channels = i;
 
+   wdev_lock(wdev);
+   if (!cfg80211_off_channel_oper_allowed(wdev)) {
+   struct ieee80211_channel *chan;
+
+   if (request->n_channels != 1) {
+   wdev_unlock(wdev);
+   err = -EBUSY;
+   goto out_free;
+   }
+
+   chan = request->channels[0];
+   if (chan->center_freq != wdev->chandef.chan->center_freq) {
+   wdev_unlock(wdev);
+   err = -EBUSY;
+   goto out_free;
+   }
+   }
+   wdev_unlock(wdev);
+
i = 0;
if (n_ssids) {
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], 
tmp) {
@@ -9053,6 +9085,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct wireless_dev *wdev = info->user_ptr[1];
struct cfg80211_chan_def chandef;
+   const struct cfg80211_chan_def *compat_chandef;
struct sk_buff *msg;
void *hdr;
u64 cookie;
@@ -9081,6 +9114,18 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
if (err)
return err;
 
+   wdev_lock(wdev);
+   if (!cfg80211_off_channel_oper_allowed(wdev) &&
+   !cfg80211_chandef_identical(>chandef, )) {
+   compat_chandef = cfg80211_chandef_compatible(>chandef,
+);
+   if (compat_chandef != ) {
+   wdev_unlock(wdev);
+   return -EBUSY;
+   }
+   }
+   wdev_unlock(wdev);
+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;
@@ -9256,6 +9301,13 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct 
genl_info *info)
if (!chandef.chan && params.offchan)
return -EINVAL;
 
+   wdev_lock(wdev);
+   if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
+   wdev_unlock(wdev);
+   return -EBUSY;
+   }
+   wdev_unlock(wdev);
+
params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
 
-- 
1.9.1



[RFC V2 1/3] cfg80211: Make pre-CAC results valid only for ETSI domain

2017-02-16 Thread Vasanthakumar Thiagarajan
DFS requirement for ETSI domain (section 4.7.1.4 in
ETSI EN 301 893 V1.8.1) is the only one which explicitly
states that once DFS channel is marked as available afer
the CAC, this channel will remain in available state even
moving to a different operating channel. But the same is
not explicitly stated in FCC DFS requirement. Also, Pre-CAC
requriements are not explicitly mentioned in FCC requirement.
Current implementation in keeping DFS channel in available
state is same as described in ETSI domain.

For ETSI DFS domain, this patch gives a grace period of 2 seconds
since the completion of successful CAC before moving the channel's
DFS state to 'usable' from 'available' state. The same grace period
is checked against the channel's dfs_state_entered timestamp while
deciding if a DFS channel is available for operation. There is a new
radar event, NL80211_RADAR_PRE_CAC_EXPIRED, reported when DFS channel
is moved from available to usable state after the grace period. Also
make sure the DFS channel state is reset to usable once the beaconing
operation on that channel is brought down (like stop_ap, leave_ibss
and leave_mesh) in non-ETSI domain.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---

V2:
Address below comments from Johannes
 
- Make 5G specific function names generic
- Rewrite helper function which checks if the 20Mhz channel
  in operating bandwidth with comment.
- Remove regulatory_get_pre_cac_timeout() and use 
regulatory_pre_cac_allowed()
  directly.

 include/uapi/linux/nl80211.h |   5 +++
 net/wireless/ap.c|   5 +++
 net/wireless/chan.c  | 101 +++
 net/wireless/core.h  |  10 +
 net/wireless/ibss.c  |   1 +
 net/wireless/mesh.c  |   1 +
 net/wireless/mlme.c  |  40 +
 net/wireless/reg.c   |  28 
 net/wireless/reg.h   |  14 ++
 9 files changed, 196 insertions(+), 9 deletions(-)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index d6c62ee..9d2d2b1 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4893,12 +4893,17 @@ enum nl80211_smps_mode {
  * change to the channel status.
  * @NL80211_RADAR_NOP_FINISHED: The Non-Occupancy Period for this channel is
  * over, channel becomes usable.
+ * @NL80211_RADAR_PRE_CAC_EXPIRED: Channel Availability Check done on this
+ * non-operating channel is expired and no longer valid. New CAC must
+ * be done on this channel before starting the operation. This is not
+ * applicable for ETSI dfs domain where pre-CAC is valid for ever.
  */
 enum nl80211_radar_event {
NL80211_RADAR_DETECTED,
NL80211_RADAR_CAC_FINISHED,
NL80211_RADAR_CAC_ABORTED,
NL80211_RADAR_NOP_FINISHED,
+   NL80211_RADAR_PRE_CAC_EXPIRED,
 };
 
 /**
diff --git a/net/wireless/ap.c b/net/wireless/ap.c
index bdad1f9..25666d3 100644
--- a/net/wireless/ap.c
+++ b/net/wireless/ap.c
@@ -32,6 +32,11 @@ int __cfg80211_stop_ap(struct cfg80211_registered_device 
*rdev,
rdev_set_qos_map(rdev, dev, NULL);
if (notify)
nl80211_send_ap_stopped(wdev);
+
+   /* Should we apply the grace period during beaconing interface
+* shutdown also?
+*/
+   cfg80211_sched_dfs_chan_update(rdev);
}
 
return err;
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 5497d022..099f13c 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -456,6 +456,107 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
return (r1 + r2 > 0);
 }
 
+/*
+ * Checks if center frequency of chan falls with in the bandwidth
+ * range of chandef.
+ */
+bool cfg80211_is_sub_chan(struct cfg80211_chan_def *chandef,
+ struct ieee80211_channel *chan)
+{
+   int width;
+   u32 cf_offset, freq;
+
+   if (chandef->chan->center_freq == chan->center_freq)
+   return true;
+
+   width = cfg80211_chandef_get_width(chandef);
+   if (width <= 20)
+   return false;
+
+   cf_offset = width / 2 - 10;
+
+   for (freq = chandef->center_freq1 - width / 2 + 10;
+freq <= chandef->center_freq1 + width / 2 - 10; freq += 20) {
+   if (chan->center_freq == freq)
+   return true;
+   }
+
+   if (!chandef->center_freq2)
+   return false;
+
+   for (freq = chandef->center_freq2 - width / 2 + 10;
+freq <= chandef->center_freq2 + width / 2 - 10; freq += 20) {
+   if (chan->center_freq == freq)
+   return true;
+   }
+
+   return false;
+}
+
+bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev)
+{
+   bool active = false;
+
+   ASSERT_WD

[RFC V2 3/3] cfg80211: Share Channel DFS state across wiphys of same DFS domain

2017-02-16 Thread Vasanthakumar Thiagarajan
Sharing DFS channel state across multiple wiphys (radios) could
be useful with multiple radios on the system. When one radio
completes CAC and markes the channel available another radio
can use this information and start beaconing without really doing
CAC.

Whenever there is a state change in dfs channel associated to
a particular wiphy the the same state change is propagated to
other wiphys having the same DFS reg domain configuration.
Also when a new wiphy is created the dfs channel state of
other existing wiphys of same DFS domain is copied.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---

V2:
- Make 5G specific DFS chan state share logic generic (Johannes)

 net/wireless/chan.c |  30 ++
 net/wireless/core.c |  37 +
 net/wireless/core.h |   6 +++
 net/wireless/mlme.c |  10 +
 net/wireless/reg.c  | 117 
 net/wireless/reg.h  |  22 ++
 6 files changed, 215 insertions(+), 7 deletions(-)

diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 099f13c..b8aa5a7 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -531,16 +531,11 @@ bool cfg80211_beaconing_iface_active(struct wireless_dev 
*wdev)
return active;
 }
 
-bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
- struct ieee80211_channel *chan)
+static bool cfg80211_is_wiphy_oper_chan(struct wiphy *wiphy,
+   struct ieee80211_channel *chan)
 {
struct wireless_dev *wdev;
 
-   ASSERT_RTNL();
-
-   if (!(chan->flags & IEEE80211_CHAN_RADAR))
-   return false;
-
list_for_each_entry(wdev, >wdev_list, list) {
wdev_lock(wdev);
if (!cfg80211_beaconing_iface_active(wdev)) {
@@ -558,6 +553,27 @@ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
return false;
 }
 
+bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
+ struct ieee80211_channel *chan)
+{
+   struct cfg80211_registered_device *rdev;
+
+   ASSERT_RTNL();
+
+   if (!(chan->flags & IEEE80211_CHAN_RADAR))
+   return false;
+
+   list_for_each_entry(rdev, _rdev_list, list) {
+   if (!reg_dfs_domain_same(wiphy, >wiphy))
+   continue;
+
+   if (cfg80211_is_wiphy_oper_chan(>wiphy, chan))
+   return true;
+   }
+
+   return false;
+}
+
 static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
 u32 center_freq,
 u32 bandwidth)
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 903fc419..d61c408 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -357,6 +357,38 @@ static void cfg80211_sched_scan_stop_wk(struct work_struct 
*work)
rtnl_unlock();
 }
 
+static void cfg80211_propagate_radar_detect_wk(struct work_struct *work)
+{
+   struct cfg80211_registered_device *rdev;
+
+   rdev = container_of(work, struct cfg80211_registered_device,
+   propagate_radar_detect_wk);
+
+   rtnl_lock();
+
+   regulatory_propagate_dfs_state(>wiphy, >radar_chandef,
+  NL80211_DFS_UNAVAILABLE,
+  NL80211_RADAR_DETECTED);
+
+   rtnl_unlock();
+}
+
+static void cfg80211_propagate_cac_done_wk(struct work_struct *work)
+{
+   struct cfg80211_registered_device *rdev;
+
+   rdev = container_of(work, struct cfg80211_registered_device,
+   propagate_cac_done_wk);
+
+   rtnl_lock();
+
+   regulatory_propagate_dfs_state(>wiphy, >cac_done_chandef,
+  NL80211_DFS_AVAILABLE,
+  NL80211_RADAR_CAC_FINISHED);
+
+   rtnl_unlock();
+}
+
 /* exported functions */
 
 struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
@@ -456,6 +488,9 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, 
int sizeof_priv,
spin_lock_init(>destroy_list_lock);
INIT_WORK(>destroy_work, cfg80211_destroy_iface_wk);
INIT_WORK(>sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
+   INIT_WORK(>propagate_radar_detect_wk,
+ cfg80211_propagate_radar_detect_wk);
+   INIT_WORK(>propagate_cac_done_wk, cfg80211_propagate_cac_done_wk);
 
 #ifdef CONFIG_CFG80211_DEFAULT_PS
rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
@@ -914,6 +949,8 @@ void wiphy_unregister(struct wiphy *wiphy)
flush_work(>destroy_work);
flush_work(>sched_scan_stop_wk);
flush_work(>mlme_unreg_wk);
+   flush_work(>propagate_radar_detect_wk);
+   flush_work(>propagate_cac_done_wk);
 
 #ifdef CONFIG_PM
if (rdev->wiphy.wowlan_config &am

[RFC V2 0/3] Pre-CAC and sharing DFS state across multiple radios

2017-02-16 Thread Vasanthakumar Thiagarajan
Currently irrespective of dfs domain and radar detection activity
pre-CAC results for a wiphy are retained till the wiphy is detroyed.
This may not be preferred in non-ETSI dfs domain where pre-CAC is not
explicitly mentioned in the respective DFS requirement spec. This patch
set modifies the current behaviour of pre-CAC for non-ETSI domain by
giving 2 seconds grace period for dfs master interface to start operating
on the CAC completed channel.

This patch set also adds support to share dfs channel state across
multiple radios of the same regulatory configuration.

Vasanthakumar Thiagarajan (3):
  cfg80211: Make pre-CAC results valid only for ETSI domain
  cfg80211: Disallow moving out of operating DFS channel in non-ETSI
  cfg80211: Share Channel DFS state across wiphys of same DFS domain

 include/uapi/linux/nl80211.h |   5 ++
 net/wireless/ap.c|   5 ++
 net/wireless/chan.c  | 117 ++
 net/wireless/core.c  |  37 +++
 net/wireless/core.h  |  16 +
 net/wireless/ibss.c  |   1 +
 net/wireless/mesh.c  |   1 +
 net/wireless/mlme.c  |  50 ---
 net/wireless/nl80211.c   |  52 
 net/wireless/reg.c   | 145 +++
 net/wireless/reg.h   |  36 +++
 11 files changed, 456 insertions(+), 9 deletions(-)

-- 
1.9.1



[RFC 3/3] cfg80211: Share Channel DFS state across wiphys of same DFS domain

2017-01-25 Thread Vasanthakumar Thiagarajan
Sharing DFS channel state across multiple wiphys (radios) could
be useful with multiple radios on the system. When one radio
completes CAC and marks the channel available another radio
can use this information and start beaconing without really doing
CAC.

Whenever there is a state change in DFS channel associated to
a particular wiphy the the same state change is propagated to
other wiphys having the same DFS reg domain configuration.
Also when a new wiphy is created the DFS channel state of
other existing wiphys of same DFS domain is copied.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 net/wireless/chan.c |  24 +--
 net/wireless/core.c |  37 +
 net/wireless/core.h |   6 +++
 net/wireless/mlme.c |  11 +-
 net/wireless/reg.c  | 112 
 net/wireless/reg.h  |  22 +++
 6 files changed, 207 insertions(+), 5 deletions(-)

diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 090309a..40f1097 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -532,21 +532,37 @@ bool cfg80211_beaconing_iface_active(struct wireless_dev 
*wdev)
return active;
 }
 
+static bool cfg80211_5ghz_is_wiphy_oper_chan(struct wiphy *wiphy,
+struct ieee80211_channel *chan)
+{
+   struct wireless_dev *wdev;
+
+   list_for_each_entry(wdev, >wdev_list, list) {
+   if (!cfg80211_beaconing_iface_active(wdev))
+   continue;
+
+   if (cfg80211_5ghz_sub_chan(>chandef, chan))
+   return true;
+   }
+
+   return false;
+}
+
 bool cfg80211_5ghz_any_wiphy_oper_chan(struct wiphy *wiphy,
   struct ieee80211_channel *chan)
 {
-   struct wireless_dev *wdev;
+   struct cfg80211_registered_device *rdev;
 
ASSERT_RTNL();
 
if (!(chan->flags & IEEE80211_CHAN_RADAR))
return false;
 
-   list_for_each_entry(wdev, >wdev_list, list) {
-   if (!cfg80211_beaconing_iface_active(wdev))
+   list_for_each_entry(rdev, _rdev_list, list) {
+   if (!reg_dfs_domain_same(wiphy, >wiphy))
continue;
 
-   if (cfg80211_5ghz_sub_chan(>chandef, chan))
+   if (cfg80211_5ghz_is_wiphy_oper_chan(>wiphy, chan))
return true;
}
 
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 903fc419..c3fe44b 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -357,6 +357,38 @@ static void cfg80211_sched_scan_stop_wk(struct work_struct 
*work)
rtnl_unlock();
 }
 
+static void cfg80211_propagate_radar_detect_wk(struct work_struct *work)
+{
+   struct cfg80211_registered_device *rdev;
+
+   rdev = container_of(work, struct cfg80211_registered_device,
+   porpagate_radar_detect_wk);
+
+   rtnl_lock();
+
+   regulatory_propagate_dfs_state(>wiphy, >radar_chandef,
+  NL80211_DFS_UNAVAILABLE,
+  NL80211_RADAR_DETECTED);
+
+   rtnl_unlock();
+}
+
+static void cfg80211_propagate_cac_done_wk(struct work_struct *work)
+{
+   struct cfg80211_registered_device *rdev;
+
+   rdev = container_of(work, struct cfg80211_registered_device,
+   propagate_cac_done_wk);
+
+   rtnl_lock();
+
+   regulatory_propagate_dfs_state(>wiphy, >cac_done_chandef,
+  NL80211_DFS_AVAILABLE,
+  NL80211_RADAR_CAC_FINISHED);
+
+   rtnl_unlock();
+}
+
 /* exported functions */
 
 struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
@@ -456,6 +488,9 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, 
int sizeof_priv,
spin_lock_init(>destroy_list_lock);
INIT_WORK(>destroy_work, cfg80211_destroy_iface_wk);
INIT_WORK(>sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
+   INIT_WORK(>porpagate_radar_detect_wk,
+ cfg80211_propagate_radar_detect_wk);
+   INIT_WORK(>propagate_cac_done_wk, cfg80211_propagate_cac_done_wk);
 
 #ifdef CONFIG_CFG80211_DEFAULT_PS
rdev->wiphy.flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
@@ -914,6 +949,8 @@ void wiphy_unregister(struct wiphy *wiphy)
flush_work(>destroy_work);
flush_work(>sched_scan_stop_wk);
flush_work(>mlme_unreg_wk);
+   flush_work(>porpagate_radar_detect_wk);
+   flush_work(>propagate_cac_done_wk);
 
 #ifdef CONFIG_PM
if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup)
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 327fe95..607c8be 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -97,6 +97,12 @@ struct cfg80211_registered_device {
 
struct work_struct sch

[RFC 2/3] cfg80211: Disallow moving out of operating DFS channel in non-ETSI

2017-01-25 Thread Vasanthakumar Thiagarajan
For non-ETSI regulatory domain, CAC result on DFS channel
may not be valid once moving out of that channel (as done
during remain-on-channel, scannning and off-channel tx).
Running CAC on an operating DFS channel after every off-channel
operation will only add complexity and disturb the current
link. Better do not allow any off-channel switch from a DFS
operating channel in non-ETSI domain.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 net/wireless/nl80211.c | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 63dfa60..c614af4 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6506,6 +6506,17 @@ static int nl80211_parse_random_mac(struct nlattr 
**attrs,
return 0;
 }
 
+static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
+{
+   if (!cfg80211_beaconing_iface_active(wdev))
+   return true;
+
+   if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
+   return true;
+
+   return regulatory_pre_cac_allowed(wdev->wiphy);
+}
+
 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 {
struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6631,6 +6642,21 @@ static int nl80211_trigger_scan(struct sk_buff *skb, 
struct genl_info *info)
 
request->n_channels = i;
 
+   if (!cfg80211_off_channel_oper_allowed(wdev)) {
+   struct ieee80211_channel *chan;
+
+   if (request->n_channels != 1) {
+   err = -EBUSY;
+   goto out_free;
+   }
+
+   chan = request->channels[0];
+   if (chan->center_freq != wdev->chandef.chan->center_freq) {
+   err = -EBUSY;
+   goto out_free;
+   }
+   }
+
i = 0;
if (n_ssids) {
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], 
tmp) {
@@ -9053,6 +9079,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct wireless_dev *wdev = info->user_ptr[1];
struct cfg80211_chan_def chandef;
+   const struct cfg80211_chan_def *compat_chandef;
struct sk_buff *msg;
void *hdr;
u64 cookie;
@@ -9081,6 +9108,14 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
if (err)
return err;
 
+   if (!(cfg80211_off_channel_oper_allowed(wdev) ||
+ cfg80211_chandef_identical(>chandef, ))) {
+   compat_chandef = cfg80211_chandef_compatible(>chandef,
+);
+   if (compat_chandef != )
+   return -EBUSY;
+   }
+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg)
return -ENOMEM;
@@ -9256,6 +9291,9 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct 
genl_info *info)
if (!chandef.chan && params.offchan)
return -EINVAL;
 
+   if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev))
+   return -EBUSY;
+
params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
 
-- 
1.9.1



[RFC 1/3] cfg80211: Make pre-CAC results valid only for ETSI domain

2017-01-25 Thread Vasanthakumar Thiagarajan
DFS requirement for ETSI domain (section 4.7.1.4 in
ETSI EN 301 893 V1.8.1) is the only one which explicitly
states that once DFS channel is marked as available afer
the CAC, this channel will remain in available state even
moving to a different operating channel. But the same is
not explicitly stated in FCC DFS requirement. Also, Pre-CAC
requriements are not explicitly mentioned in FCC requirement.
Current implementation in keeping DFS channel in available
state is same as described in ETSI domain.

For ETSI DFS domain, this patch gives a grace period of 2 seconds
since the completion of successful CAC before moving the channel's
DFS state to 'usable' from 'available' state. The same grace period
is checked against the channel's dfs_state_entered timestamp while
deciding if a DFS channel is available for operation. There is a new
radar event, NL80211_RADAR_PRE_CAC_EXPIRED, reported when DFS channel
is moved from available to usable state after the grace period. Also
make sure the DFS channel state is reset to usable once the beaconing
operation on that channel is brought down (like stop_ap, leave_ibss
and leave_mesh) in non-ETSI domain.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 include/uapi/linux/nl80211.h |  5 +++
 net/wireless/ap.c|  5 +++
 net/wireless/chan.c  | 96 
 net/wireless/core.h  |  7 
 net/wireless/ibss.c  |  1 +
 net/wireless/mesh.c  |  1 +
 net/wireless/mlme.c  | 41 ++-
 net/wireless/reg.c   | 47 ++
 net/wireless/reg.h   | 14 +++
 9 files changed, 208 insertions(+), 9 deletions(-)

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index d6c62ee..9d2d2b1 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4893,12 +4893,17 @@ enum nl80211_smps_mode {
  * change to the channel status.
  * @NL80211_RADAR_NOP_FINISHED: The Non-Occupancy Period for this channel is
  * over, channel becomes usable.
+ * @NL80211_RADAR_PRE_CAC_EXPIRED: Channel Availability Check done on this
+ * non-operating channel is expired and no longer valid. New CAC must
+ * be done on this channel before starting the operation. This is not
+ * applicable for ETSI dfs domain where pre-CAC is valid for ever.
  */
 enum nl80211_radar_event {
NL80211_RADAR_DETECTED,
NL80211_RADAR_CAC_FINISHED,
NL80211_RADAR_CAC_ABORTED,
NL80211_RADAR_NOP_FINISHED,
+   NL80211_RADAR_PRE_CAC_EXPIRED,
 };
 
 /**
diff --git a/net/wireless/ap.c b/net/wireless/ap.c
index bdad1f9..25666d3 100644
--- a/net/wireless/ap.c
+++ b/net/wireless/ap.c
@@ -32,6 +32,11 @@ int __cfg80211_stop_ap(struct cfg80211_registered_device 
*rdev,
rdev_set_qos_map(rdev, dev, NULL);
if (notify)
nl80211_send_ap_stopped(wdev);
+
+   /* Should we apply the grace period during beaconing interface
+* shutdown also?
+*/
+   cfg80211_sched_dfs_chan_update(rdev);
}
 
return err;
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 5497d022..090309a 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -456,6 +456,102 @@ bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
return (r1 + r2 > 0);
 }
 
+static bool cfg80211_5ghz_sub_chan(struct cfg80211_chan_def *chandef,
+  struct ieee80211_channel *chan)
+{
+   u32 start_freq_seg0 = 0, end_freq_seg0 = 0;
+   u32 start_freq_seg1 = 0, end_freq_seg1 = 0;
+
+   if (chandef->chan->center_freq == chan->center_freq)
+   return true;
+
+   switch (chandef->width) {
+   case NL80211_CHAN_WIDTH_40:
+   start_freq_seg0 = chandef->center_freq1 - 20;
+   end_freq_seg0 = chandef->center_freq1 + 20;
+   break;
+   case NL80211_CHAN_WIDTH_80P80:
+   start_freq_seg1 = chandef->center_freq2 - 40;
+   end_freq_seg1 = chandef->center_freq2 + 40;
+   /* fall through */
+   case NL80211_CHAN_WIDTH_80:
+   start_freq_seg0 = chandef->center_freq1 - 40;
+   end_freq_seg0 = chandef->center_freq1 + 40;
+   break;
+   case NL80211_CHAN_WIDTH_160:
+   start_freq_seg0 = chandef->center_freq1 - 80;
+   end_freq_seg0 = chandef->center_freq1 + 80;
+   break;
+   case NL80211_CHAN_WIDTH_20_NOHT:
+   case NL80211_CHAN_WIDTH_20:
+   case NL80211_CHAN_WIDTH_5:
+   case NL80211_CHAN_WIDTH_10:
+   break;
+   }
+
+   if (chan->center_freq > start_freq_seg0 &&
+   chan->center_freq < end_freq_seg0)
+   return true;
+
+   return chan->center_freq > start_freq_seg1 &&
+ 

[RFC 0/3] Pre-CAC and sharing DFS state across multiple radios

2017-01-25 Thread Vasanthakumar Thiagarajan
Currently irrespective of dfs domain and radar detection activity
pre-CAC results for a wiphy are retained till the wiphy is detroyed.
This may not be preferred in non-ETSI dfs domain where pre-CAC is not
explicitly mentioned in the respective DFS requirement spec. This patch
set modifies the current behaviour of pre-CAC for non-ETSI domain by
giving 2 seconds grace period for dfs master interface to start operating
on the CAC completed channel.

This patch set also adds support to share dfs channel state across
multiple radios of the same regulatory configuration.

Vasanthakumar Thiagarajan (3):
  cfg80211: Make pre-CAC results valid only for ETSI domain
  cfg80211: Disallow moving out of operating DFS channel in non-ETSI
  cfg80211: Share Channel DFS state across wiphys of same DFS domain

 include/uapi/linux/nl80211.h |   5 ++
 net/wireless/ap.c|   5 ++
 net/wireless/chan.c  | 112 ++
 net/wireless/core.c  |  37 ++
 net/wireless/core.h  |  13 
 net/wireless/ibss.c  |   1 +
 net/wireless/mesh.c  |   1 +
 net/wireless/mlme.c  |  52 +++---
 net/wireless/nl80211.c   |  38 +++
 net/wireless/reg.c   | 159 +++
 net/wireless/reg.h   |  36 ++
 11 files changed, 449 insertions(+), 10 deletions(-)

-- 
1.9.1



[RFC 3/3] mac80211: Add receive path for ethernet frame format

2016-12-14 Thread Vasanthakumar Thiagarajan
Implement rx path which does fewer processing on the
received data frame which has already gone through
802.11 header decapsulation and other functionalities
which require 802.11 header in the low level driver
or hardware. Currently this rx path is restricted
to AP and STA mode, but can be extended for Adhoc
mode as well.

This rx path only checks if the driver has advertised
it's support of 802.11 header encap/decap offload for
data frames. It is upto the low level driver to make
sure if the frame that it passes is in ethernet format
and the sta pointer is valid.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 include/net/mac80211.h |  19 +
 net/mac80211/rx.c  | 189 -
 2 files changed, 206 insertions(+), 2 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 225abaa..75c55e2 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1088,6 +1088,9 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info 
*info)
  * @RX_FLAG_ALLOW_SAME_PN: Allow the same PN as same packet before.
  * This is used for AMSDU subframes which can have the same PN as
  * the first subframe.
+ * @RX_FLAG_MCAST: If the receiver address (addr1) in the frame is multicast.
+ * This is used with the data frames by the drivers supporting 802.11 hdr
+ * decap offload.
  */
 enum mac80211_rx_flags {
RX_FLAG_MMIC_ERROR  = BIT(0),
@@ -1123,6 +1126,7 @@ enum mac80211_rx_flags {
RX_FLAG_RADIOTAP_VENDOR_DATA= BIT(31),
RX_FLAG_MIC_STRIPPED= BIT_ULL(32),
RX_FLAG_ALLOW_SAME_PN   = BIT_ULL(33),
+   RX_FLAG_MCAST   = BIT_ULL(34),
 };
 
 #define RX_FLAG_STBC_SHIFT 26
@@ -3989,6 +3993,21 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw 
*hw,
 }
 
 /**
+ * ieee80211_rx_decap_offl - Receive frames in 802.11 decapsulated format
+ *
+ * Low level driver capable of 802.11 header decap uses this function. The 
frame
+ * will be in ethernet format.
+ * This function may not be called in IRQ context. Calls to this function
+ * for a single hardware must be synchronized against each other.
+ *
+ * @hw: the hardware this frame came in on
+ * @sta : the station the frame was received from, must not be %NULL
+ * @skb: the buffer to receive, owned by mac80211 after this call
+ */
+void ieee80211_rx_decap_offl(struct ieee80211_hw *hw, struct ieee80211_sta 
*sta,
+struct sk_buff *skb);
+
+/**
  * ieee80211_sta_ps_transition - PS transition for connected sta
  *
  * When operating in AP mode with the %IEEE80211_HW_AP_LINK_PS
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 2e8a902..3cb8d6e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2103,13 +2103,14 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx, 
bool *port_control)
return 0;
 }
 
+static const u8 pae_group_addr[ETH_ALEN] __aligned(2)
+   = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x03 };
+
 /*
  * requires that rx->skb is a frame with ethernet header
  */
 static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc)
 {
-   static const u8 pae_group_addr[ETH_ALEN] __aligned(2)
-   = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x03 };
struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
 
/*
@@ -4180,3 +4181,187 @@ void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, 
struct sk_buff *skb)
tasklet_schedule(>tasklet);
 }
 EXPORT_SYMBOL(ieee80211_rx_irqsafe);
+
+/* Receive path for decap offloaded data frames */
+
+static void
+ieee80211_rx_handle_decap_offl(struct ieee80211_sub_if_data *sdata,
+struct sta_info *sta, struct sk_buff *skb)
+{
+   struct ieee80211_local *local = sdata->local;
+   struct ieee80211_vif *vif = >vif;
+   struct net_device *dev = sdata->dev;
+   struct ieee80211_rx_status *status;
+   struct ieee80211_key *key = NULL;
+   struct ieee80211_rx_data rx;
+   int i;
+   struct ethhdr *ehdr;
+
+   ehdr = (struct ethhdr *)skb->data;
+   status = IEEE80211_SKB_RXCB(skb);
+
+   /* TODO: Extend ieee80211_rx_decap_offl() with bssid so that Ethernet
+* encap/decap can be supported in Adhoc interface type as well.
+* Adhoc interface depends on bssid to udpate last_rx.
+*/
+   if (vif->type != NL80211_IFTYPE_STATION &&
+   vif->type != NL80211_IFTYPE_AP_VLAN &&
+   vif->type != NL80211_IFTYPE_AP)
+   goto drop;
+
+   I802_DEBUG_INC(local->dot11ReceivedFragmentCount);
+
+   if (!(status->flag & RX_FLAG_MCAST)) {
+   sta->rx_stats.last_rx = jiffies;
+   sta->rx_stats.last_rate = sta_stats_encode_rate(status);
+   }
+
+   if (sdata->vif.type == NL80211_IFTYPE_STATION &&
+   !is_multicas

[RFC 2/3] mac80211: Implement data xmit for 802.11 encap offload

2016-12-14 Thread Vasanthakumar Thiagarajan
Driver (or hw) supporting 802.11 encapsulation offload
for data frames can make use of this new xmit path.

This patch defines new ndo_ops, all these callbacks are same as
ieee80211_dataif_ops other than ndo_start_xmit() which does
minimal processing leaving 802.11 encap related to driver.
This patch makes netdev_ops registration dynamic based on the
interface type, at any time the netdev_ops of netdev will be
assigned to either the ndo_ops defined to do 802.11 encap or
the ones defined for 802.11 encap offload. There is a new hw
config notification, IEEE80211_CONF_CHANGE_80211_HDR_OFFL, to make
the driver aware of any configuration change in 802.11 encap/decap
offload.

There is a field, no_80211_encap, added to ieee80211_tx_info:control
to mark if the 802.11 encapsulation is offloaded to driver.
There is also a new callback for tx completion status indication
to handle data frames using 802.11 encap offload. Currently ath10k
fw is capable of doing 802.11 encapsulation/decapsulationi offload.
With the corresponding driver changes, using 802.11 encap/decap offload
might improve performance.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 include/net/mac80211.h |  33 ++-
 net/mac80211/cfg.c |   8 ++
 net/mac80211/ieee80211_i.h |  12 +++
 net/mac80211/iface.c   | 147 +
 net/mac80211/key.c |  16 +++-
 net/mac80211/main.c|   3 +
 net/mac80211/status.c  |  83 -
 net/mac80211/tx.c  | 225 -
 8 files changed, 519 insertions(+), 8 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 1e3c8b5..225abaa 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -910,7 +910,12 @@ struct ieee80211_tx_info {
};
struct ieee80211_key_conf *hw_key;
u32 flags;
-   /* 4 bytes free */
+   /* XXX: This frame is not encaptulated with 802.11
+* header. Should this be added to %IEEE80211_TX_CTRL_*
+* flags?.
+*/
+   bool no_80211_encap;
+   /* 3 bytes free */
} control;
struct {
u64 cookie;
@@ -1269,6 +1274,8 @@ enum ieee80211_conf_flags {
  * @IEEE80211_CONF_CHANGE_SMPS: Spatial multiplexing powersave mode changed
  * Note that this is only valid if channel contexts are not used,
  * otherwise each channel context has the number of chains listed.
+ * @IEEE80211_CONF_CHANGE_80211_HDR_OFFL: Offload configuration
+ * implementing 802.11 encap/decap for data frames changed.
  */
 enum ieee80211_conf_changed {
IEEE80211_CONF_CHANGE_SMPS  = BIT(1),
@@ -1279,6 +1286,7 @@ enum ieee80211_conf_changed {
IEEE80211_CONF_CHANGE_CHANNEL   = BIT(6),
IEEE80211_CONF_CHANGE_RETRY_LIMITS  = BIT(7),
IEEE80211_CONF_CHANGE_IDLE  = BIT(8),
+   IEEE80211_CONF_CHANGE_80211_HDR_OFFL= BIT(9),
 };
 
 /**
@@ -1333,6 +1341,9 @@ enum ieee80211_smps_mode {
  * configured for an HT channel.
  * Note that this is only valid if channel contexts are not used,
  * otherwise each channel context has the number of chains listed.
+ *
+ * @encap_decap_80211_offloaded: Whether 802.11 header encap/decap offload
+ * is enabled
  */
 struct ieee80211_conf {
u32 flags;
@@ -1346,6 +1357,7 @@ struct ieee80211_conf {
struct cfg80211_chan_def chandef;
bool radar_enabled;
enum ieee80211_smps_mode smps_mode;
+   bool encap_decap_80211_offloaded;
 };
 
 /**
@@ -4178,6 +4190,25 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
 struct sk_buff *skb);
 
 /**
+ * ieee80211_tx_status_8023 - transmit status callback for 802.3 frame format
+ *
+ * Call this function for all transmitted data frames after their transmit
+ * completion. This callback should only be called for data frames which
+ * are are using driver's (or hardware's) offload capability of encap/decap
+ * 802.11 frames.
+ *
+ * This function may not be called in IRQ context. Calls to this function
+ * for a single hardware must be synchronized against each other.
+ *
+ * @hw: the hardware the frame was transmitted by
+ * @vif: the interface for which the frame was transmitted
+ * @skb: the frame that was transmitted, owned by mac80211 after this call
+ */
+void ieee80211_tx_status_8023(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct sk_buff *skb);
+
+/**
  * ieee80211_report_low_ack - report non-responding station
  *
  * When operating in AP-mode, call this function to report a non-responding
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 47e99ab8..0e53873 100644
--- a/net/mac80211

[RFC 1/3] mac80211: Add provision for 802.11 encap/decap offload

2016-12-14 Thread Vasanthakumar Thiagarajan
Drivers can have the capability to offload 802.11 encap/decap
to firmware or hardware for data frames. This patch adds a new
hw_flag for driver to advertise the offload support. Drivers
advertising the support have also to implement new ieee80211_ops
callback, get_vif_80211_hdr_offload(), to notify if the 802.11 encap/decap
offload is supported for a particular vif type. Transmit and receive
path offloading 802.11 header (including cipher headers) encap/decap
for data frames will be implemented in separate patches.

Drivers advertising this capability should also implement other
functionalities which deal with 802.11 frame format like below

- Hardware encryption/Decryption
- ADDBA/DELBA offload
- Aggregation and deaggregation of A-MSDU offload
- Fragmentation and defragmentation offload
- Rx reordering of A-MPDU subframe offload
- PN/TSC check offload
- Rx duplication check offload
- Hardware rate control
- Powersave offload

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 include/net/mac80211.h| 16 
 net/mac80211/debugfs.c|  1 +
 net/mac80211/driver-ops.h | 21 +
 net/mac80211/main.c   |  4 
 net/mac80211/trace.h  | 33 +
 5 files changed, 75 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index b4faadb..1e3c8b5 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2014,6 +2014,11 @@ struct ieee80211_txq {
  * @IEEE80211_HW_TX_FRAG_LIST: Hardware (or driver) supports sending frag_list
  * skbs, needed for zero-copy software A-MSDU.
  *
+ * @IEEE80211_HW_SUPPORTS_80211_ENCAP_DECAP: Hardware/driver supports 802.11
+ * encap/decap for data frames. Supporting driver have to implement
+ * get_vif_80211_encap_decap_offload() to pass if 802.11 encap/decap
+ * offload is supported for the vif.
+ *
  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
  */
 enum ieee80211_hw_flags {
@@ -2054,6 +2059,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_USES_RSS,
IEEE80211_HW_TX_AMSDU,
IEEE80211_HW_TX_FRAG_LIST,
+   IEEE80211_HW_SUPPORTS_80211_ENCAP_DECAP,
 
/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
@@ -3401,6 +3407,12 @@ enum ieee80211_reconfig_type {
  * synchronization which is needed in case driver has in its RSS queues
  * pending frames that were received prior to the control path action
  * currently taken (e.g. disassociation) but are not processed yet.
+ *
+ * @get_vif_80211_hdr_offload: Called to check if driver or hardware
+ * supports 802.11 encap/decap offload for data frames for the vif.
+ * Drivers implementing this callback should advertise the support
+ * through hw_flags (%IEEE80211_HW_SUPPORTS_80211_ENCAP_DECAP).
+ * This callback can sleep.
  */
 struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -3639,6 +3651,10 @@ struct ieee80211_ops {
void (*wake_tx_queue)(struct ieee80211_hw *hw,
  struct ieee80211_txq *txq);
void (*sync_rx_queues)(struct ieee80211_hw *hw);
+
+   int (*get_vif_80211_hdr_offload)(struct ieee80211_hw *hw,
+struct ieee80211_vif *vif,
+bool is_4addr, bool *supported);
 };
 
 /**
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 2906c10..f49fea5 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -302,6 +302,7 @@ static const char *hw_flag_names[] = {
FLAG(USES_RSS),
FLAG(TX_AMSDU),
FLAG(TX_FRAG_LIST),
+   FLAG(SUPPORTS_80211_ENCAP_DECAP),
 #undef FLAG
 };
 
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 184473c..22847d2 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1179,4 +1179,25 @@ static inline void drv_wake_tx_queue(struct 
ieee80211_local *local,
local->ops->wake_tx_queue(>hw, >txq);
 }
 
+static inline int
+drv_get_vif_80211_hdr_offload(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ bool use_4addr, bool *supported)
+{
+   int ret = -EOPNOTSUPP;
+
+   might_sleep();
+
+   if (local->ops->get_vif_80211_hdr_offload)
+   ret = local->ops->get_vif_80211_hdr_offload(>hw,
+   >vif,
+   use_4addr,
+   supported);
+
+   trace_drv_get_vif_80211_hdr_offload(local, sdata, use_4addr,
+   *supported, ret);
+
+   return ret;
+}
+
 #endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d00ea9b..2095

[RFC 0/3] Add new data path for ethernet frame format

2016-12-14 Thread Vasanthakumar Thiagarajan
This patch set adds a new data path to offload 802.11 header
encap/decap to driver or hardware. Drivers having support
for ieee80211 header encap/decap and other offload functionalities
which can't be done before encap or after decap can make use of
this new data path. Currently it is implemented for STA and AP
interface type, this can be extend other interface types like
adhoc.  

With ath10k driver changes using this new Tx/Rx path, 10 - 15%
CPU usage and upto ~20Mbps TCP performance improvements are
observed with this ethernet data path. This patch set is
prepared on a older mac80211 code base on top of
commit 7d27a0ba7adc ("cfg80211: Add mesh peer AID setting API").
Sorry, I could not get a chance to rework it on top of latest
mac80211 code base.

TODO (from initial review):

- Consider ieee8011 header and cipher header size also while updating 
tx/rx stats for
  ethernet frame format.
- Any optimization to reduce the amount of code change.
- Improve commit log and doc

Vasanthakumar Thiagarajan (3):
  mac80211: Add provision for 802.11 encap/decap offload
  mac80211: Implement data xmit for 802.11 encap offload
  mac80211: Add receive path for ethernet frame format

 include/net/mac80211.h |  68 +-
 net/mac80211/cfg.c |   8 ++
 net/mac80211/debugfs.c |   1 +
 net/mac80211/driver-ops.h  |  21 +
 net/mac80211/ieee80211_i.h |  12 +++
 net/mac80211/iface.c   | 147 +
 net/mac80211/key.c |  16 +++-
 net/mac80211/main.c|   7 ++
 net/mac80211/rx.c  | 189 -
 net/mac80211/status.c  |  83 -
 net/mac80211/trace.h   |  33 +++
 net/mac80211/tx.c  | 225 -
 12 files changed, 800 insertions(+), 10 deletions(-)

-- 
1.9.1



[PATCH] ath10k: Fix kernel panic due to race in accessing arvif list

2016-10-10 Thread Vasanthakumar Thiagarajan
arvifs list is traversed within data_lock spin_lock in tasklet
context to fill channel information from the corresponding vif.
This means any access to arvifs list for add/del operations
should also be protected with the same spin_lock to avoid the
race. Fix this by performing list add/del on arvfis within the
data_lock. This could fix kernel panic something like the below.

 LR is at ath10k_htt_rx_pktlog_completion_handler+0x100/0xb6c [ath10k_core]
 PC is at ath10k_htt_rx_pktlog_completion_handler+0x1c0/0xb6c [ath10k_core]
 Internal error: Oops: 17 [#1] PREEMPT SMP ARM
 [] (ath10k_htt_rx_pktlog_completion_handler+0x2f4/0xb6c 
[ath10k_core])
 [] (ath10k_htt_txrx_compl_task+0x8b4/0x1188 [ath10k_core])
 [] (tasklet_action+0x8c/0xec)
 [] (__do_softirq+0xdc/0x208)
 [] (irq_exit+0x84/0xe0)
 [] (__handle_domain_irq+0x80/0xa0)
 [] (gic_handle_irq+0x38/0x5c)
 [] (__irq_svc+0x40/0x74)

(gdb) list *(ath10k_htt_rx_pktlog_completion_handler+0x1c0)
0x136c0 is in ath10k_htt_rx_h_channel 
(drivers/net/wireless/ath/ath10k/htt_rx.c:769)
764 struct cfg80211_chan_def def;
765
766 lockdep_assert_held(>data_lock);
767
768 list_for_each_entry(arvif, >arvifs, list) {
769 if (arvif->vdev_id == vdev_id &&
770 ath10k_mac_vif_chan(arvif->vif, ) == 0)
771 return def.chan;
772 }
773

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/mac.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index 2e5d2ca..691b7b5 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4931,7 +4931,9 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
}
 
ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
+   spin_lock_bh(>data_lock);
list_add(>list, >arvifs);
+   spin_unlock_bh(>data_lock);
 
/* It makes no sense to have firmware do keepalives. mac80211 already
 * takes care of this with idle connection polling.
@@ -5082,7 +5084,9 @@ err_peer_delete:
 err_vdev_delete:
ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
ar->free_vdev_map |= 1LL << arvif->vdev_id;
+   spin_lock_bh(>data_lock);
list_del(>list);
+   spin_unlock_bh(>data_lock);
 
 err:
if (arvif->beacon_buf) {
@@ -5128,7 +5132,9 @@ static void ath10k_remove_interface(struct ieee80211_hw 
*hw,
arvif->vdev_id, ret);
 
ar->free_vdev_map |= 1LL << arvif->vdev_id;
+   spin_lock_bh(>data_lock);
list_del(>list);
+   spin_unlock_bh(>data_lock);
 
if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
-- 
1.9.1



[PATCH] ath10k: Fix rfc1042 header retrieval in QCA4019 with eth decap mode

2016-07-27 Thread Vasanthakumar Thiagarajan
Chipset from QCA99X0 onwards (QCA99X0, QCA9984, QCA4019 & future)
rx_hdr_status is not padded to align in 4-byte boundary. Define a
new hw_params field to handle different alignment behaviour between
different hw. This patch fixes improper retrieval of rfc1042 header
with QCA4019. This patch along with "ath10k: Properly remove padding
from the start of rx payload" will fix traffic failure in ethernet
decap mode for QCA4019.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/core.c   | 12 
 drivers/net/wireless/ath/ath10k/htt_rx.c |  5 +++--
 drivers/net/wireless/ath/ath10k/hw.h |  3 +++
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 74d0ace..ea6a8f4 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -68,6 +68,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
},
.hw_rx_desc_ops = _rx_desc_ops,
+   .decap_align_bytes = 4,
},
{
.id = QCA9887_HW_1_0_VERSION,
@@ -87,6 +88,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.board_ext_size = QCA9887_BOARD_EXT_DATA_SZ,
},
.hw_rx_desc_ops = _rx_desc_ops,
+   .decap_align_bytes = 4,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -105,6 +107,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
},
.hw_rx_desc_ops = _rx_desc_ops,
+   .decap_align_bytes = 4,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -123,6 +126,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
},
.hw_rx_desc_ops = _rx_desc_ops,
+   .decap_align_bytes = 4,
},
{
.id = QCA6174_HW_3_0_VERSION,
@@ -141,6 +145,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
},
.hw_rx_desc_ops = _rx_desc_ops,
+   .decap_align_bytes = 4,
},
{
.id = QCA6174_HW_3_2_VERSION,
@@ -160,6 +165,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
},
.hw_rx_desc_ops = _rx_desc_ops,
+   .decap_align_bytes = 4,
},
{
.id = QCA99X0_HW_2_0_DEV_VERSION,
@@ -183,6 +189,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
},
.hw_rx_desc_ops = _rx_desc_ops,
+   .decap_align_bytes = 1,
},
{
.id = QCA9984_HW_1_0_DEV_VERSION,
@@ -206,6 +213,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
},
.hw_rx_desc_ops = _rx_desc_ops,
+   .decap_align_bytes = 1,
},
{
.id = QCA9888_HW_2_0_DEV_VERSION,
@@ -228,6 +236,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
},
.hw_rx_desc_ops = _rx_desc_ops,
+   .decap_align_bytes = 1,
},
{
.id = QCA9377_HW_1_0_DEV_VERSION,
@@ -246,6 +255,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
},
.hw_rx_desc_ops = _rx_desc_ops,
+   .decap_align_bytes = 4,
},
{
.id = QCA9377_HW_1_1_DEV_VERSION,
@@ -264,6 +274,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
},
.hw_rx_desc_ops = _rx_desc_ops,
+   .decap_align_bytes = 4,
},
{
.id = QCA4019_HW_1_0_DEV_VERSION,
@@ -288,6 +299,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_ext_size = QCA4019_BOARD_EXT_DATA_SZ,
},
.hw_rx_desc_ops = _rx_desc_ops,
+   .decap_align_bytes = 1,
},
 };
 
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 36c4809..97d5b07 1006

[PATCH 3/4] ath10k: Properly remove padding from the start of rx payload

2016-07-27 Thread Vasanthakumar Thiagarajan
In QCA99X0 (QCA99X0, QCA9984, QCA9888 and QCA4019) family chips,
hw adds padding at the begining of the rx payload to make L3
header 4-byte aligned. In the chips doing this type of padding,
the number of bytes padded will be indicated through msdu_end:info1.
Define a hw_rx_desc_ops wrapper to retrieve the number of padded
bytes and use this while doing undecap. This should fix padding
related issues with ethernt decap format with QCA99X0, QCA9984,
QCA9888 and QCA4019 hw.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/htt_rx.c | 36 +++-
 drivers/net/wireless/ath/ath10k/hw.h |  9 
 2 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 78db5d6..36c4809 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -1056,9 +1056,11 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k 
*ar,
  const u8 first_hdr[64])
 {
struct ieee80211_hdr *hdr;
+   struct htt_rx_desc *rxd;
size_t hdr_len;
u8 da[ETH_ALEN];
u8 sa[ETH_ALEN];
+   int l3_pad_bytes;
 
/* Delivered decapped frame:
 * [nwifi 802.11 header] <-- replaced with 802.11 hdr
@@ -1072,19 +1074,12 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k 
*ar,
 */
 
/* pull decapped header and copy SA & DA */
-   if ((ar->hw_params.hw_4addr_pad == ATH10K_HW_4ADDR_PAD_BEFORE) &&
-   ieee80211_has_a4(((struct ieee80211_hdr 
*)first_hdr)->frame_control)) {
-   /* The QCA99X0 4 address mode pad 2 bytes at the
-* beginning of MSDU
-*/
-   hdr = (struct ieee80211_hdr *)(msdu->data + 2);
-   /* The skb length need be extended 2 as the 2 bytes at the tail
-* be excluded due to the padding
-*/
-   skb_put(msdu, 2);
-   } else {
-   hdr = (struct ieee80211_hdr *)(msdu->data);
-   }
+   rxd = (void *)msdu->data - sizeof(*rxd);
+
+   l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(>hw_params, rxd);
+   skb_put(msdu, l3_pad_bytes);
+
+   hdr = (struct ieee80211_hdr *)(msdu->data + l3_pad_bytes);
 
hdr_len = ath10k_htt_rx_nwifi_hdrlen(ar, hdr);
ether_addr_copy(da, ieee80211_get_DA(hdr));
@@ -1151,6 +1146,8 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
void *rfc1042;
u8 da[ETH_ALEN];
u8 sa[ETH_ALEN];
+   int l3_pad_bytes;
+   struct htt_rx_desc *rxd;
 
/* Delivered decapped frame:
 * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc
@@ -1161,6 +1158,11 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k 
*ar,
if (WARN_ON_ONCE(!rfc1042))
return;
 
+   rxd = (void *)msdu->data - sizeof(*rxd);
+   l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(>hw_params, rxd);
+   skb_put(msdu, l3_pad_bytes);
+   skb_pull(msdu, l3_pad_bytes);
+
/* pull decapped header and copy SA & DA */
eth = (struct ethhdr *)msdu->data;
ether_addr_copy(da, eth->h_dest);
@@ -1191,6 +1193,8 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k 
*ar,
 {
struct ieee80211_hdr *hdr;
size_t hdr_len;
+   int l3_pad_bytes;
+   struct htt_rx_desc *rxd;
 
/* Delivered decapped frame:
 * [amsdu header] <-- replaced with 802.11 hdr
@@ -1198,7 +1202,11 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k 
*ar,
 * [payload]
 */
 
-   skb_pull(msdu, sizeof(struct amsdu_subframe_hdr));
+   rxd = (void *)msdu->data - sizeof(*rxd);
+   l3_pad_bytes = ath10k_rx_desc_get_l3_pad_bytes(>hw_params, rxd);
+
+   skb_put(msdu, l3_pad_bytes);
+   skb_pull(msdu, sizeof(struct amsdu_subframe_hdr) + l3_pad_bytes);
 
hdr = (struct ieee80211_hdr *)first_hdr;
hdr_len = ieee80211_hdrlen(hdr->frame_control);
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index a281544..cdd2ce4 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -423,6 +423,15 @@ struct ath10k_hw_rx_desc_ops {
 extern const struct ath10k_hw_rx_desc_ops qca988x_rx_desc_ops;
 extern const struct ath10k_hw_rx_desc_ops qca99x0_rx_desc_ops;
 
+static inline int
+ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
+   struct htt_rx_desc *rxd)
+{
+   if (hw->hw_rx_desc_ops->rx_desc_get_l3_pad_bytes)
+   return hw->hw_rx_desc_ops->rx_desc_get_l3_pad_bytes(rxd);
+   return 0;
+}
+
 /* Target specific defines for MAIN firmware */
 #define TARGET_NUM_VDEVS   8
 #define T

[PATCH 4/4] ath10k: Remove 4-addr padding related hw_param configuration

2016-07-27 Thread Vasanthakumar Thiagarajan
hw_4addr_pad was added to handle different types of padding
in 4-address rx frame. But this padding is not very specific
to 4-address, it can happen even with three address + ethernet
decap mode. Since the  padding information can be obtained
through Rx desc for QCA99X0 and newer chips, this hw_param
is not needed any more.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/core.c | 9 -
 drivers/net/wireless/ath/ath10k/hw.h   | 8 
 2 files changed, 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 9c5e93b..74d0ace 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -60,7 +60,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.otp_exe_param = 0,
.channel_counters_freq_hz = 88000,
.max_probe_resp_desc_thres = 0,
-   .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
.cal_data_len = 2116,
.fw = {
.dir = QCA988X_HW_2_0_FW_DIR,
@@ -80,7 +79,6 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.otp_exe_param = 0,
.channel_counters_freq_hz = 88000,
.max_probe_resp_desc_thres = 0,
-   .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
.cal_data_len = 2116,
.fw = {
.dir = QCA9887_HW_1_0_FW_DIR,
@@ -117,7 +115,6 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.otp_exe_param = 0,
.channel_counters_freq_hz = 88000,
.max_probe_resp_desc_thres = 0,
-   .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
.cal_data_len = 8124,
.fw = {
.dir = QCA6174_HW_2_1_FW_DIR,
@@ -136,7 +133,6 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.otp_exe_param = 0,
.channel_counters_freq_hz = 88000,
.max_probe_resp_desc_thres = 0,
-   .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
.cal_data_len = 8124,
.fw = {
.dir = QCA6174_HW_3_0_FW_DIR,
@@ -155,7 +151,6 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.otp_exe_param = 0,
.channel_counters_freq_hz = 88000,
.max_probe_resp_desc_thres = 0,
-   .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_AFTER,
.cal_data_len = 8124,
.fw = {
/* uses same binaries as hw3.0 */
@@ -177,7 +172,6 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.cck_rate_map_rev2 = true,
.channel_counters_freq_hz = 15,
.max_probe_resp_desc_thres = 24,
-   .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
.tx_chain_mask = 0xf,
.rx_chain_mask = 0xf,
.max_spatial_stream = 4,
@@ -201,7 +195,6 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.cck_rate_map_rev2 = true,
.channel_counters_freq_hz = 15,
.max_probe_resp_desc_thres = 24,
-   .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
.tx_chain_mask = 0xf,
.rx_chain_mask = 0xf,
.max_spatial_stream = 4,
@@ -224,7 +217,6 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.continuous_frag_desc = true,
.channel_counters_freq_hz = 15,
.max_probe_resp_desc_thres = 24,
-   .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
.tx_chain_mask = 3,
.rx_chain_mask = 3,
.max_spatial_stream = 2,
@@ -285,7 +277,6 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.cck_rate_map_rev2 = true,
.channel_counters_freq_hz = 125000,
.max_probe_resp_desc_thres = 24,
-   .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
.tx_chain_mask = 0x3,
.rx_chain_mask = 0x3,
.max_spatial_stream = 2,
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index cdd2ce4..1620e76 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -338,11 +338,6 @@ enum ath10k_hw_rate_rev2_cck {
ATH10K_HW_RATE_REV2_CCK_SP_11M,
 };
 
-enum ath10k_hw_4addr_pad {
-   ATH10K_HW_4ADDR_PAD_AFTER,
-   ATH10K_HW_4ADDR_PAD_BEFORE,
-};
-
 enum ath10k_hw_cc_wraparound_type {
ATH10K_HW_CC_WRAP_DISABLED = 0,
 
@@ -395,9 +390,6 @@ struct ath10k_hw_params {
 */
u32 max_probe_resp_desc_thres;
 
-   /* The padding bytes's lo

[PATCH 2/4] ath10k: Add provision for Rx descriptor abstraction

2016-07-27 Thread Vasanthakumar Thiagarajan
There are slight differences in Rx hw descriptor information
among different chips. So far driver does not use those new
information for any functionalities, but there is one important
information which is available from QCA99X0 onwards to indicate
the number of bytes that hw padded at the begining of the rx
payload and this information is needed to undecap the rx
packet. Add an abstraction for Rx desc to make use of the
new desc information available. The callback that this patch
defines to retrieve the padding bytes will be used in follow-up
patch.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/core.c | 12 
 drivers/net/wireless/ath/ath10k/hw.c   | 13 +
 drivers/net/wireless/ath/ath10k/hw.h   | 12 
 3 files changed, 37 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index e889829..9c5e93b 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -68,6 +68,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.board_size = QCA988X_BOARD_DATA_SZ,
.board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
},
+   .hw_rx_desc_ops = _rx_desc_ops,
},
{
.id = QCA9887_HW_1_0_VERSION,
@@ -87,6 +88,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.board_size = QCA9887_BOARD_DATA_SZ,
.board_ext_size = QCA9887_BOARD_EXT_DATA_SZ,
},
+   .hw_rx_desc_ops = _rx_desc_ops,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -104,6 +106,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_size = QCA6174_BOARD_DATA_SZ,
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
},
+   .hw_rx_desc_ops = _rx_desc_ops,
},
{
.id = QCA6174_HW_2_1_VERSION,
@@ -122,6 +125,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_size = QCA6174_BOARD_DATA_SZ,
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
},
+   .hw_rx_desc_ops = _rx_desc_ops,
},
{
.id = QCA6174_HW_3_0_VERSION,
@@ -140,6 +144,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_size = QCA6174_BOARD_DATA_SZ,
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
},
+   .hw_rx_desc_ops = _rx_desc_ops,
},
{
.id = QCA6174_HW_3_2_VERSION,
@@ -159,6 +164,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_size = QCA6174_BOARD_DATA_SZ,
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
},
+   .hw_rx_desc_ops = _rx_desc_ops,
},
{
.id = QCA99X0_HW_2_0_DEV_VERSION,
@@ -182,6 +188,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_size = QCA99X0_BOARD_DATA_SZ,
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
},
+   .hw_rx_desc_ops = _rx_desc_ops,
},
{
.id = QCA9984_HW_1_0_DEV_VERSION,
@@ -205,6 +212,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_size = QCA99X0_BOARD_DATA_SZ,
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
},
+   .hw_rx_desc_ops = _rx_desc_ops,
},
{
.id = QCA9888_HW_2_0_DEV_VERSION,
@@ -227,6 +235,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_size = QCA99X0_BOARD_DATA_SZ,
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
},
+   .hw_rx_desc_ops = _rx_desc_ops,
},
{
.id = QCA9377_HW_1_0_DEV_VERSION,
@@ -244,6 +253,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_size = QCA9377_BOARD_DATA_SZ,
.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
},
+   .hw_rx_desc_ops = _rx_desc_ops,
},
{
.id = QCA9377_HW_1_1_DEV_VERSION,
@@ -261,6 +271,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_size = QCA9377_BOARD_DATA_SZ,
.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
},
+   .hw_rx_desc_ops = _rx_desc_ops,
},
{
.id = QCA4019_HW_1_0_DEV_VERSION,
@@ -285,6 +296,7 @@ static const struct ath10k_hw_

[PATCH 1/4] ath10k: Move ath10k_hw_params definition to hw.h

2016-07-27 Thread Vasanthakumar Thiagarajan
This is to prepare for rx descriptor abstraction where we'll
be dereferencing ath10k_hw_params member in hw.h. Moreover
hw.h looks more suitable to house ath10k_hw_params definition
than core.h

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/core.h | 48 +-
 drivers/net/wireless/ath/ath10k/hw.h   | 48 ++
 2 files changed, 49 insertions(+), 47 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index 30ae5bf..5ace413 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -715,53 +715,7 @@ struct ath10k {
struct ath10k_htc htc;
struct ath10k_htt htt;
 
-   struct ath10k_hw_params {
-   u32 id;
-   u16 dev_id;
-   const char *name;
-   u32 patch_load_addr;
-   int uart_pin;
-   u32 otp_exe_param;
-
-   /* Type of hw cycle counter wraparound logic, for more info
-* refer enum ath10k_hw_cc_wraparound_type.
-*/
-   enum ath10k_hw_cc_wraparound_type cc_wraparound_type;
-
-   /* Some of chip expects fragment descriptor to be continuous
-* memory for any TX operation. Set continuous_frag_desc flag
-* for the hardware which have such requirement.
-*/
-   bool continuous_frag_desc;
-
-   /* CCK hardware rate table mapping for the newer chipsets
-* like QCA99X0, QCA4019 got revised. The CCK h/w rate values
-* are in a proper order with respect to the rate/preamble
-*/
-   bool cck_rate_map_rev2;
-
-   u32 channel_counters_freq_hz;
-
-   /* Mgmt tx descriptors threshold for limiting probe response
-* frames.
-*/
-   u32 max_probe_resp_desc_thres;
-
-   /* The padding bytes's location is different on various chips */
-   enum ath10k_hw_4addr_pad hw_4addr_pad;
-
-   u32 tx_chain_mask;
-   u32 rx_chain_mask;
-   u32 max_spatial_stream;
-   u32 cal_data_len;
-
-   struct ath10k_hw_params_fw {
-   const char *dir;
-   const char *board;
-   size_t board_size;
-   size_t board_ext_size;
-   } fw;
-   } hw_params;
+   struct ath10k_hw_params hw_params;
 
/* contains the firmware images used with ATH10K_FIRMWARE_MODE_NORMAL */
struct ath10k_fw_components normal_mode_fw;
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index e014cd7..1315557 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -363,6 +363,54 @@ enum ath10k_hw_cc_wraparound_type {
ATH10K_HW_CC_WRAP_SHIFTED_EACH = 2,
 };
 
+struct ath10k_hw_params {
+   u32 id;
+   u16 dev_id;
+   const char *name;
+   u32 patch_load_addr;
+   int uart_pin;
+   u32 otp_exe_param;
+
+   /* Type of hw cycle counter wraparound logic, for more info
+* refer enum ath10k_hw_cc_wraparound_type.
+*/
+   enum ath10k_hw_cc_wraparound_type cc_wraparound_type;
+
+   /* Some of chip expects fragment descriptor to be continuous
+* memory for any TX operation. Set continuous_frag_desc flag
+* for the hardware which have such requirement.
+*/
+   bool continuous_frag_desc;
+
+   /* CCK hardware rate table mapping for the newer chipsets
+* like QCA99X0, QCA4019 got revised. The CCK h/w rate values
+* are in a proper order with respect to the rate/preamble
+*/
+   bool cck_rate_map_rev2;
+
+   u32 channel_counters_freq_hz;
+
+   /* Mgmt tx descriptors threshold for limiting probe response
+* frames.
+*/
+   u32 max_probe_resp_desc_thres;
+
+   /* The padding bytes's location is different on various chips */
+   enum ath10k_hw_4addr_pad hw_4addr_pad;
+
+   u32 tx_chain_mask;
+   u32 rx_chain_mask;
+   u32 max_spatial_stream;
+   u32 cal_data_len;
+
+   struct ath10k_hw_params_fw {
+   const char *dir;
+   const char *board;
+   size_t board_size;
+   size_t board_ext_size;
+   } fw;
+};
+
 /* Target specific defines for MAIN firmware */
 #define TARGET_NUM_VDEVS   8
 #define TARGET_NUM_PEER_AST2
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/4] ath10k: Padding related clean ups in rx

2016-07-27 Thread Vasanthakumar Thiagarajan
This patch set adds abstraction for rx_hw_desc processing so that
we can make use of newer desc fields notifying padding information
which is done on rx payload. "ath10k: Properly remove padding from
the start of rx payload" fixes padding related bug in ethernet decap
mode for QCA99X0, QCA9984 qnd QCA4019 but even fixing this bug will
not make ethernet decap mode work, there needs to be some more fix
wich would follow this patch series.

Vasanthakumar Thiagarajan (4):
  ath10k: Move ath10k_hw_params definition to hw.h
  ath10k: Add provision for Rx descriptor abstraction
  ath10k: Properly remove padding from the start of rx payload
  ath10k: Remove 4-addr padding related hw_param configuration

 drivers/net/wireless/ath/ath10k/core.c   | 21 ++
 drivers/net/wireless/ath/ath10k/core.h   | 48 +
 drivers/net/wireless/ath/ath10k/htt_rx.c | 36 +---
 drivers/net/wireless/ath/ath10k/hw.c | 13 ++
 drivers/net/wireless/ath/ath10k/hw.h | 71 +---
 5 files changed, 114 insertions(+), 75 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ath10k: Fix possible wrong rx_busy time reporting in QCA4019

2016-07-01 Thread Vasanthakumar Thiagarajan
As hw cycle counters in QCA4019 wraparound independantly in QCA4019
it is possible cycle counter and rx clear counter would wraparound
at the same time. Current logic assumes only one of the counters
would wraparound at anytime. Fix this by moving 'else' part to
another 'if'.

Fixes: 8e100354a98 ("ath10k: fix cycle counter wraparound handling for QCA4019")
Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/hw.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c
index bd86e7a..7462627 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -198,7 +198,8 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct 
survey_info *survey,
case ATH10K_HW_CC_WRAP_SHIFTED_EACH:
if (cc < cc_prev)
cc_fix = 0x7fff;
-   else
+
+   if (rcc < rcc_prev)
rcc_fix = 0x7fff;
break;
case ATH10K_HW_CC_WRAP_DISABLED:
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] ath10k: Define an enum to enable cycle counter wraparound logic

2016-06-03 Thread Vasanthakumar Thiagarajan
QCA988X hw implements a different cycle counter wraparound
behaviour when compared to QCA4019. To properly handle different
wraparound logic for these chipsets replace already available
bool hw_params member, has_shifted_cc_wraparound, with an
enum which could be extended to handle different wraparound
behaviour. This patch keeps the existing logic functionally
same and a prepares cycle counter wraparound handling to
extend for other chips.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/core.c |  4 ++--
 drivers/net/wireless/ath/ath10k/core.h |  8 +++-
 drivers/net/wireless/ath/ath10k/hw.c   |  4 +++-
 drivers/net/wireless/ath/ath10k/hw.h   | 11 +++
 4 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index cedf127..8f66653 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -55,7 +55,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.name = "qca988x hw2.0",
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
-   .has_shifted_cc_wraparound = true,
+   .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
.otp_exe_param = 0,
.channel_counters_freq_hz = 88000,
.max_probe_resp_desc_thres = 0,
@@ -224,7 +224,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.name = "qca4019 hw1.0",
.patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
-   .has_shifted_cc_wraparound = true,
+   .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
.otp_exe_param = 0x001,
.continuous_frag_desc = true,
.channel_counters_freq_hz = 125000,
diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index 4462c3f..b42b21f 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -710,12 +710,10 @@ struct ath10k {
int uart_pin;
u32 otp_exe_param;
 
-   /* This is true if given HW chip has a quirky Cycle Counter
-* wraparound which resets to 0x7fff instead of 0. All
-* other CC related counters (e.g. Rx Clear Count) are divided
-* by 2 so they never wraparound themselves.
+   /* Type of hw cycle counter wraparound logic, for more info
+* refer enum ath10k_hw_cc_wraparound_type.
 */
-   bool has_shifted_cc_wraparound;
+   enum ath10k_hw_cc_wraparound_type cc_wraparound_type;
 
/* Some of chip expects fragment descriptor to be continuous
 * memory for any TX operation. Set continuous_frag_desc flag
diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c
index f544d48..31ec164 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -179,11 +179,13 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct 
survey_info *survey,
u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
 {
u32 cc_fix = 0;
+   enum ath10k_hw_cc_wraparound_type wraparound_type;
 
survey->filled |= SURVEY_INFO_TIME |
  SURVEY_INFO_TIME_BUSY;
 
-   if (ar->hw_params.has_shifted_cc_wraparound && cc < cc_prev) {
+   wraparound_type = ar->hw_params.cc_wraparound_type;
+   if (wraparound_type == ATH10K_HW_CC_WRAP_SHIFTED_ALL && cc < cc_prev) {
cc_fix = 0x7fff;
survey->filled &= ~SURVEY_INFO_TIME_BUSY;
}
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index f41c91c..64e45b2 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -331,6 +331,17 @@ enum ath10k_hw_4addr_pad {
ATH10K_HW_4ADDR_PAD_BEFORE,
 };
 
+enum ath10k_hw_cc_wraparound_type {
+   ATH10K_HW_CC_WRAP_DISABLED = 0,
+
+   /* This type is when the HW chip has a quirky Cycle Counter
+* wraparound which resets to 0x7fff instead of 0. All
+* other CC related counters (e.g. Rx Clear Count) are divided
+* by 2 so they never wraparound themselves.
+*/
+   ATH10K_HW_CC_WRAP_SHIFTED_ALL = 1,
+};
+
 /* Target specific defines for MAIN firmware */
 #define TARGET_NUM_VDEVS   8
 #define TARGET_NUM_PEER_AST2
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] ath10k: Fix cycle counter wraparound handling for QCA4019

2016-06-03 Thread Vasanthakumar Thiagarajan
In QCA4019, cycle counter wraparound is not tied to rx
clear counter. Each counter would wraparound individually
and after wraparound the respective counter will be reset
to 0x7fff while other counter still running unaffected.
Define a new wraparound type for this behaviour and handle
it separately so that rx clear counter wraparound is also
handled just like cycle counter. With this type of
wraparound we can accurately compute and report channel
active/busy time when any of the counter overflows.

Fixes: ee9ca147c59 ("ath10k: Fix survey reporting with QCA4019")
Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/core.c |  2 +-
 drivers/net/wireless/ath/ath10k/hw.c   | 24 
 drivers/net/wireless/ath/ath10k/hw.h   |  9 +
 3 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 8f66653..5ede9a4 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -224,7 +224,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.name = "qca4019 hw1.0",
.patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
-   .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
+   .cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
.otp_exe_param = 0x001,
.continuous_frag_desc = true,
.channel_counters_freq_hz = 125000,
diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c
index 31ec164..bd86e7a 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -179,19 +179,35 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct 
survey_info *survey,
u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
 {
u32 cc_fix = 0;
+   u32 rcc_fix = 0;
enum ath10k_hw_cc_wraparound_type wraparound_type;
 
survey->filled |= SURVEY_INFO_TIME |
  SURVEY_INFO_TIME_BUSY;
 
wraparound_type = ar->hw_params.cc_wraparound_type;
-   if (wraparound_type == ATH10K_HW_CC_WRAP_SHIFTED_ALL && cc < cc_prev) {
-   cc_fix = 0x7fff;
-   survey->filled &= ~SURVEY_INFO_TIME_BUSY;
+
+   if (cc < cc_prev || rcc < rcc_prev) {
+   switch (wraparound_type) {
+   case ATH10K_HW_CC_WRAP_SHIFTED_ALL:
+   if (cc < cc_prev) {
+   cc_fix = 0x7fff;
+   survey->filled &= ~SURVEY_INFO_TIME_BUSY;
+   }
+   break;
+   case ATH10K_HW_CC_WRAP_SHIFTED_EACH:
+   if (cc < cc_prev)
+   cc_fix = 0x7fff;
+   else
+   rcc_fix = 0x7fff;
+   break;
+   case ATH10K_HW_CC_WRAP_DISABLED:
+   break;
+   }
}
 
cc -= cc_prev - cc_fix;
-   rcc -= rcc_prev;
+   rcc -= rcc_prev - rcc_fix;
 
survey->time = CCNT_TO_MSEC(ar, cc);
survey->time_busy = CCNT_TO_MSEC(ar, rcc);
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 64e45b2..7657c60 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -340,6 +340,15 @@ enum ath10k_hw_cc_wraparound_type {
 * by 2 so they never wraparound themselves.
 */
ATH10K_HW_CC_WRAP_SHIFTED_ALL = 1,
+
+   /* Each hw counter wrapsaround independently. When the
+* counter overflows the repestive counter is right shifted
+* by 1, i.e reset to 0x7fff, and other counters will be
+* running unaffected. In this type of wraparound, it should
+* be possible to report accurate Rx busy time unlike the
+* first type.
+*/
+   ATH10K_HW_CC_WRAP_SHIFTED_EACH = 2,
 };
 
 /* Target specific defines for MAIN firmware */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ath10k: Fix some of the macro definitions of HTT_RX_IND message

2016-06-02 Thread Vasanthakumar Thiagarajan
Only five bits are defined to pass tid information in HTT_RX_IND
message, so the mask which can be used to extract tid should be 0x1f
instead of the current 0x3f. Also, macros which can be used to extract
flush_valid and release_valid bits have to be left shifted one bit less
because these information follow the tid right after. This patch does
not really fix anything functionally because these macros are not used
currently.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/htt.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.h 
b/drivers/net/wireless/ath/ath10k/htt.h
index 911c535..430a83e 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -485,10 +485,10 @@ struct htt_mgmt_tx_completion {
__le32 status;
 } __packed;
 
-#define HTT_RX_INDICATION_INFO0_EXT_TID_MASK  (0x3F)
+#define HTT_RX_INDICATION_INFO0_EXT_TID_MASK  (0x1F)
 #define HTT_RX_INDICATION_INFO0_EXT_TID_LSB   (0)
-#define HTT_RX_INDICATION_INFO0_FLUSH_VALID   (1 << 6)
-#define HTT_RX_INDICATION_INFO0_RELEASE_VALID (1 << 7)
+#define HTT_RX_INDICATION_INFO0_FLUSH_VALID   (1 << 5)
+#define HTT_RX_INDICATION_INFO0_RELEASE_VALID (1 << 6)
 
 #define HTT_RX_INDICATION_INFO1_FLUSH_START_SEQNO_MASK   0x003F
 #define HTT_RX_INDICATION_INFO1_FLUSH_START_SEQNO_LSB0
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] ath10k: Fix survey reporting with QCA4019

2016-05-06 Thread Vasanthakumar Thiagarajan
In QCA4019, cycle counter wraparound in same fashion
as QCA988X. When the cycle counter wraparound it
resets to 0x7fff. Set has_shifted_cc_wraparound to
true for QCA4019 to enable the code path to handle cycle
counter wraparound for consistent survey report.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index e94cb87..f6018be 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -202,6 +202,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.name = "qca4019 hw1.0",
.patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
+   .has_shifted_cc_wraparound = true,
.otp_exe_param = 0x001,
.continuous_frag_desc = true,
.channel_counters_freq_hz = 125000,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] ath10k: suppress warnings when getting wmi peer_rate_code_list event

2016-05-06 Thread Vasanthakumar Thiagarajan
In 10.4, fw sends WMI PEER_RATECODE_LIST_EVENTID after successful
peer_assoc cmd. As of now this event is not of much use and not
implemented. Change the debug level and messsage as appropriate
to suppress "Unknown eventid: 36898".

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/wmi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.c 
b/drivers/net/wireless/ath/ath10k/wmi.c
index 39a54a5..2a14b16 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -5213,6 +5213,7 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, 
struct sk_buff *skb)
ath10k_wmi_event_vdev_stopped(ar, skb);
break;
case WMI_10_4_WOW_WAKEUP_HOST_EVENTID:
+   case WMI_10_4_PEER_RATECODE_LIST_EVENTID:
ath10k_dbg(ar, ATH10K_DBG_WMI,
   "received event id %d not implemented\n", id);
break;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/4] ath10k: Define rx_ppdu_end for QCA9984

2016-04-20 Thread Vasanthakumar Thiagarajan
QCA9984 Rx descriptor has two 32-bit words of location information
when compared to one 32-bit word in QCA99X0. To handle this difference in
rx descriptor ppdu_end, define a new ppdu_end for QCA9984 descriptor
which has the new structure to represent rx_location_info.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/rx_desc.h | 46 +++
 1 file changed, 46 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h 
b/drivers/net/wireless/ath/ath10k/rx_desc.h
index 3e7dfaa..9ceebea 100644
--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
@@ -996,6 +996,41 @@ struct rx_pkt_end {
__le32 phy_timestamp_2;
 } __packed;
 
+#define RX_LOCATION_INFO0_RTT_FAC_LEGACY_MASK  0x3fff
+#define RX_LOCATION_INFO0_RTT_FAC_LEGACY_LSB   0
+#define RX_LOCATION_INFO0_RTT_FAC_VHT_MASK 0x1fff8000
+#define RX_LOCATION_INFO0_RTT_FAC_VHT_LSB  15
+#define RX_LOCATION_INFO0_RTT_STRONGEST_CHAIN_MASK 0xc000
+#define RX_LOCATION_INFO0_RTT_STRONGEST_CHAIN_LSB  30
+#define RX_LOCATION_INFO0_RTT_FAC_LEGACY_STATUSBIT(14)
+#define RX_LOCATION_INFO0_RTT_FAC_VHT_STATUS   BIT(29)
+
+#define RX_LOCATION_INFO1_RTT_PREAMBLE_TYPE_MASK   0x000c
+#define RX_LOCATION_INFO1_RTT_PREAMBLE_TYPE_LSB2
+#define RX_LOCATION_INFO1_PKT_BW_MASK  0x0030
+#define RX_LOCATION_INFO1_PKT_BW_LSB   4
+#define RX_LOCATION_INFO1_SKIP_P_SKIP_BTCF_MASK0xff00
+#define RX_LOCATION_INFO1_SKIP_P_SKIP_BTCF_LSB 8
+#define RX_LOCATION_INFO1_RTT_MSC_RATE_MASK0x000f
+#define RX_LOCATION_INFO1_RTT_MSC_RATE_LSB 16
+#define RX_LOCATION_INFO1_RTT_PBD_LEG_BW_MASK  0x0030
+#define RX_LOCATION_INFO1_RTT_PBD_LEG_BW_LSB   20
+#define RX_LOCATION_INFO1_TIMING_BACKOFF_MASK  0x07c0
+#define RX_LOCATION_INFO1_TIMING_BACKOFF_LSB   22
+#define RX_LOCATION_INFO1_RTT_TX_FRAME_PHASE_MASK  0x1800
+#define RX_LOCATION_INFO1_RTT_TX_FRAME_PHASE_LSB   27
+#define RX_LOCATION_INFO1_RTT_CFR_STATUS   BIT(0)
+#define RX_LOCATION_INFO1_RTT_CIR_STATUS   BIT(1)
+#define RX_LOCATION_INFO1_RTT_GI_TYPE  BIT(7)
+#define RX_LOCATION_INFO1_RTT_MAC_PHY_PHASEBIT(29)
+#define RX_LOCATION_INFO1_RTT_TX_DATA_START_X_PHASEBIT(30)
+#define RX_LOCATION_INFO1_RX_LOCATION_VALIDBIT(31)
+
+struct rx_location_info {
+   __le32 rx_location_info0; /* %RX_LOCATION_INFO0_ */
+   __le32 rx_location_info1; /* %RX_LOCATION_INFO1_ */
+} __packed;
+
 enum rx_phy_ppdu_end_info0 {
RX_PHY_PPDU_END_INFO0_ERR_RADAR   = BIT(2),
RX_PHY_PPDU_END_INFO0_ERR_RX_ABORT= BIT(3),
@@ -1074,12 +1109,23 @@ struct rx_ppdu_end_qca99x0 {
__le16 info1; /* %RX_PPDU_END_INFO1_ */
 } __packed;
 
+struct rx_ppdu_end_qca9984 {
+   struct rx_pkt_end rx_pkt_end;
+   struct rx_location_info rx_location_info;
+   struct rx_phy_ppdu_end rx_phy_ppdu_end;
+   __le32 rx_timing_offset; /* %RX_PPDU_END_RX_TIMING_OFFSET_ */
+   __le32 rx_info; /* %RX_PPDU_END_RX_INFO_ */
+   __le16 bb_length;
+   __le16 info1; /* %RX_PPDU_END_INFO1_ */
+} __packed;
+
 struct rx_ppdu_end {
struct rx_ppdu_end_common common;
union {
struct rx_ppdu_end_qca988x qca988x;
struct rx_ppdu_end_qca6174 qca6174;
struct rx_ppdu_end_qca99x0 qca99x0;
+   struct rx_ppdu_end_qca9984 qca9984;
} __packed;
 } __packed;
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/4] ath10k: Clean up growing hw checks during safe and full reset

2016-04-20 Thread Vasanthakumar Thiagarajan
Store pci chip secific reset funtions in struct ath10k_pci
as callbacks during early ath10k_pci_probe() and use the
callback to perform chip specific resets. This patch essentially
adds two callback in ath10k_pci, one for doing soft reset and
the other for hard reset. By using callbacks we can get rid of
those hw revision checks in ath10k_pci_safe_chip_reset() and
ath10k_pci_chip_reset(). As such this patch does not fix
any issue.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/pci.c | 44 ++-
 drivers/net/wireless/ath/ath10k/pci.h |  6 +
 2 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index cdd8a30..6614fd7 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -2293,16 +2293,20 @@ static int ath10k_pci_warm_reset(struct ath10k *ar)
return 0;
 }
 
+static int ath10k_pci_qca99x0_soft_chip_reset(struct ath10k *ar)
+{
+   ath10k_pci_irq_disable(ar);
+   return ath10k_pci_qca99x0_chip_reset(ar);
+}
+
 static int ath10k_pci_safe_chip_reset(struct ath10k *ar)
 {
-   if (QCA_REV_988X(ar) || QCA_REV_6174(ar)) {
-   return ath10k_pci_warm_reset(ar);
-   } else if (QCA_REV_99X0(ar)) {
-   ath10k_pci_irq_disable(ar);
-   return ath10k_pci_qca99x0_chip_reset(ar);
-   } else {
+   struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+   if (!ar_pci->pci_soft_reset)
return -ENOTSUPP;
-   }
+
+   return ar_pci->pci_soft_reset(ar);
 }
 
 static int ath10k_pci_qca988x_chip_reset(struct ath10k *ar)
@@ -2437,16 +2441,12 @@ static int ath10k_pci_qca99x0_chip_reset(struct ath10k 
*ar)
 
 static int ath10k_pci_chip_reset(struct ath10k *ar)
 {
-   if (QCA_REV_988X(ar))
-   return ath10k_pci_qca988x_chip_reset(ar);
-   else if (QCA_REV_6174(ar))
-   return ath10k_pci_qca6174_chip_reset(ar);
-   else if (QCA_REV_9377(ar))
-   return ath10k_pci_qca6174_chip_reset(ar);
-   else if (QCA_REV_99X0(ar))
-   return ath10k_pci_qca99x0_chip_reset(ar);
-   else
+   struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+
+   if (WARN_ON(!ar_pci->pci_hard_reset))
return -ENOTSUPP;
+
+   return ar_pci->pci_hard_reset(ar);
 }
 
 static int ath10k_pci_hif_power_up(struct ath10k *ar)
@@ -2976,24 +2976,34 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
enum ath10k_hw_rev hw_rev;
u32 chip_id;
bool pci_ps;
+   int (*pci_soft_reset)(struct ath10k *ar);
+   int (*pci_hard_reset)(struct ath10k *ar);
 
switch (pci_dev->device) {
case QCA988X_2_0_DEVICE_ID:
hw_rev = ATH10K_HW_QCA988X;
pci_ps = false;
+   pci_soft_reset = ath10k_pci_warm_reset;
+   pci_hard_reset = ath10k_pci_qca988x_chip_reset;
break;
case QCA6164_2_1_DEVICE_ID:
case QCA6174_2_1_DEVICE_ID:
hw_rev = ATH10K_HW_QCA6174;
pci_ps = true;
+   pci_soft_reset = ath10k_pci_warm_reset;
+   pci_hard_reset = ath10k_pci_qca6174_chip_reset;
break;
case QCA99X0_2_0_DEVICE_ID:
hw_rev = ATH10K_HW_QCA99X0;
pci_ps = false;
+   pci_soft_reset = ath10k_pci_qca99x0_soft_chip_reset;
+   pci_hard_reset = ath10k_pci_qca99x0_chip_reset;
break;
case QCA9377_1_0_DEVICE_ID:
hw_rev = ATH10K_HW_QCA9377;
pci_ps = true;
+   pci_soft_reset = NULL;
+   pci_hard_reset = ath10k_pci_qca6174_chip_reset;
break;
default:
WARN_ON(1);
@@ -3018,6 +3028,8 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
ar->dev_id = pci_dev->device;
ar_pci->pci_ps = pci_ps;
ar_pci->bus_ops = _pci_bus_ops;
+   ar_pci->pci_soft_reset = pci_soft_reset;
+   ar_pci->pci_hard_reset = pci_hard_reset;
 
ar->id.vendor = pdev->vendor;
ar->id.device = pdev->device;
diff --git a/drivers/net/wireless/ath/ath10k/pci.h 
b/drivers/net/wireless/ath/ath10k/pci.h
index 959dc32..6eca1df 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -234,6 +234,12 @@ struct ath10k_pci {
 
const struct ath10k_bus_ops *bus_ops;
 
+   /* Chip specific pci reset routine used to do a safe reset */
+   int (*pci_soft_reset)(struct ath10k *ar);
+
+   /* Chip specific pci full reset function */
+   int (*pci_hard_reset)(struct ath10k *ar);
+
/* Keep this entry in the last, memory for struct ath10k_ahb is
 * allocated (ahb support enabled case) in the continuation of
 * this struct.
-- 
1.9

[PATCH 1/4] ath10k: Move rx_location_info out of struct rx_pkt_end

2016-04-20 Thread Vasanthakumar Thiagarajan
Define rx_location_info in struct rx_ppdu_end_qca99x0 after
rx_pkt_end. This is to prepare rx_ppdu_end for QCA9984 chip.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/rx_desc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h 
b/drivers/net/wireless/ath/ath10k/rx_desc.h
index ca8d168..3e7dfaa 100644
--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
@@ -994,7 +994,6 @@ struct rx_pkt_end {
__le32 info0; /* %RX_PKT_END_INFO0_ */
__le32 phy_timestamp_1;
__le32 phy_timestamp_2;
-   __le32 rx_location_info; /* %RX_LOCATION_INFO_ */
 } __packed;
 
 enum rx_phy_ppdu_end_info0 {
@@ -1067,6 +1066,7 @@ struct rx_phy_ppdu_end {
 
 struct rx_ppdu_end_qca99x0 {
struct rx_pkt_end rx_pkt_end;
+   __le32 rx_location_info; /* %RX_LOCATION_INFO_ */
struct rx_phy_ppdu_end rx_phy_ppdu_end;
__le32 rx_timing_offset; /* %RX_PPDU_END_RX_TIMING_OFFSET_ */
__le32 rx_info; /* %RX_PPDU_END_RX_INFO_ */
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/4] Add support for QCA9984

2016-04-20 Thread Vasanthakumar Thiagarajan
This patch set adds QCA9984/QCA9994 1.0 support. Boot sequence is same as
QCA99X0.

Vasanthakumar Thiagarajan (4):
  ath10k: Move rx_location_info out of struct rx_pkt_end
  ath10k: Clean up growing hw checks during safe and full reset
  ath10k: Define rx_ppdu_end for QCA9984
  ath10k: Enable support for QCA9984

 drivers/net/wireless/ath/ath10k/core.c| 23 
 drivers/net/wireless/ath/ath10k/hw.h  | 11 ++
 drivers/net/wireless/ath/ath10k/pci.c | 58 ++-
 drivers/net/wireless/ath/ath10k/pci.h |  6 
 drivers/net/wireless/ath/ath10k/rx_desc.h | 48 -
 5 files changed, 129 insertions(+), 17 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ath10k: Advertise force AP scan feature

2016-03-15 Thread Vasanthakumar Thiagarajan
Results obtained from scan can be used for spectrum management by
doing something like building information of preferred channel
lists and sharing them with stations around. It is to be noted
that traffic to the connected stations would be affected during
the scan.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/mac.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index ebff9c0..48b789c 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -7697,7 +7697,8 @@ int ath10k_mac_register(struct ath10k *ar)
ar->hw->wiphy->max_remain_on_channel_duration = 5000;
 
ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
-   ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
+   ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
+  NL80211_FEATURE_AP_SCAN;
 
ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations;
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] mac80211: Allow probe response frame rx to user space in AP mode

2016-03-06 Thread Vasanthakumar Thiagarajan
Especially during off-channel scan user space might be interested
in probe reponse frames along with beacon to build a list
of preferred channel and bssid which could be sent to the stations
around for better spectrum management. Do not drop probe response
frame in AP mode and advertise driver's capability to receive probe
response frame in AP mode to user space.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 net/mac80211/main.c | 2 ++
 net/mac80211/rx.c   | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 8190bf2..c8a97da 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -401,6 +401,7 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+   BIT(IEEE80211_STYPE_PROBE_RESP >> 4) |
BIT(IEEE80211_STYPE_DISASSOC >> 4) |
BIT(IEEE80211_STYPE_AUTH >> 4) |
BIT(IEEE80211_STYPE_DEAUTH >> 4) |
@@ -412,6 +413,7 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+   BIT(IEEE80211_STYPE_PROBE_RESP >> 4) |
BIT(IEEE80211_STYPE_DISASSOC >> 4) |
BIT(IEEE80211_STYPE_AUTH >> 4) |
BIT(IEEE80211_STYPE_DEAUTH >> 4) |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 9127957..9d8f8ea 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -3464,6 +3464,8 @@ static bool ieee80211_accept_frame(struct 
ieee80211_rx_data *rx)
return false;
if (ieee80211_is_public_action(hdr, skb->len))
return true;
+   if (ieee80211_is_probe_resp(hdr->frame_control))
+   return true;
return ieee80211_is_beacon(hdr->frame_control);
}
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V2 0/3] Fix few WMI/HTT interfaces

2015-11-05 Thread Vasanthakumar Thiagarajan

On Thursday 05 November 2015 04:33 PM, Kalle Valo wrote:

Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com> writes:


On Wed, Nov 04, 2015 at 07:59:39PM +0200, Kalle Valo wrote:

Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com> writes:


This patch set fixes mismatch in peer_assoc complete wmi command for
version 10.4 and peer_id configuration for HTT version < 3.4.

V2:
- Add cover letter
- Rename ath10k_mac_need_offchan_tx_work() to
  ath10k_mac_tx_frm_has_freq(). Add htt-op-version check
  to the helper and use it in ath10k_htt_tx() while configuring
  peerid.

Vasanthakumar Thiagarajan (3):
   ath10k: Fix peer assoc complete WMI command for 10.4
   ath10k: Rename the helper which is used for off-channel tx
   ath10k: Fix peerid configuration in htt tx desc for htt version < 3.4


These had a conflict but you didn't use ath.git as the baseline so I
can't easily fix them. Please try always to use clean ath.git master
branch as the baseline for your patches.

Applying: ath10k: Fix peer assoc complete WMI command for 10.4
fatal: sha1 information is lacking or useless 
(drivers/net/wireless/ath/ath10k/wmi.h).
Repository lacks necessary blobs to fall back on 3-way merge.
Cannot fall back to three-way merge.
Patch failed at 0001 ath10k: Fix peer assoc complete WMI command for 10.4


Sorry for this. I prepared these patches on ath:master on top of my other 
pending
patch set. Not sure what went wrong.


If you have two patchsets you shouldn't have them on the same branch,
unless they have a strict dependency with each other of course. I prefer
that you have two separate topic branches which both use the master
branch as the baseline as then it's easiest for me to handle conflicts
etc.



Sure, thanks.

Vasanth
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V3 3/3] ath10k: Fix peerid configuration in htt tx desc for htt version < 3.4

2015-11-04 Thread Vasanthakumar Thiagarajan
Of a word in struct htt_data_tx_desc htt version >= 3.4 firmware uses
LSB 16-bit for frequency configuration which is used for offchannel tx
and MSB 16-bit is for peerid. But other firmwares using version 2.X
(10.1, 10.2.2, 10.2.4 and 10.4) are using 32-bit for peerid in htt tx
desc. So far no issue is found with the existing code setting peerid and
freq for HTT version 2.X, this could be mainly because of 0 as frequecy
(home channel) is being always passed with those firmwares. There may be
issues when non-zero freq is passed with firmware using < 3.4 htt version.
To be safe use target_version_major and target_version_minor along with
htt-op-version before configuring peer id and freq in htt tx desc. This
patch extends ath10k_mac_tx_frm_has_freq() to check for htt_op_version_tlv
and uses the helper while setting peerid in htt_tx_desc.

Fixes: 8d6d36243610 ("ath10k: fix offchan reliability")
Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/htt.h|  9 +++--
 drivers/net/wireless/ath/ath10k/htt_tx.c | 11 +--
 drivers/net/wireless/ath/ath10k/mac.c|  5 +++--
 drivers/net/wireless/ath/ath10k/mac.h|  1 +
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.h 
b/drivers/net/wireless/ath/ath10k/htt.h
index 74ccfb29..2b87ed6 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -166,8 +166,13 @@ struct htt_data_tx_desc {
__le16 len;
__le16 id;
__le32 frags_paddr;
-   __le16 peerid;
-   __le16 freq;
+   union {
+   __le32 peerid;
+   struct {
+   __le16 peerid;
+   __le16 freq;
+   } __packed offchan_tx;
+   } __packed;
u8 prefetch[0]; /* start of frame, for FW classification engine */
 } __packed;
 
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c 
b/drivers/net/wireless/ath/ath10k/htt_tx.c
index bd8f264..8f76b9d 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -688,8 +688,15 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff 
*msdu)
skb_cb->htt.txbuf->cmd_tx.len = __cpu_to_le16(msdu->len);
skb_cb->htt.txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
-   skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le16(HTT_INVALID_PEERID);
-   skb_cb->htt.txbuf->cmd_tx.freq = __cpu_to_le16(skb_cb->htt.freq);
+   if (ath10k_mac_tx_frm_has_freq(ar)) {
+   skb_cb->htt.txbuf->cmd_tx.offchan_tx.peerid =
+   __cpu_to_le16(HTT_INVALID_PEERID);
+   skb_cb->htt.txbuf->cmd_tx.offchan_tx.freq =
+   __cpu_to_le16(skb_cb->htt.freq);
+   } else {
+   skb_cb->htt.txbuf->cmd_tx.peerid =
+   __cpu_to_le32(HTT_INVALID_PEERID);
+   }
 
trace_ath10k_htt_tx(ar, msdu_id, msdu->len, vdev_id, tid);
ath10k_dbg(ar, ATH10K_DBG_HTT,
diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index 363a99c..76484a9 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3287,7 +3287,7 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
}
 }
 
-static bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
+bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
 {
/* FIXME: Not really sure since when the behaviour changed. At some
 * point new firmware stopped requiring creation of peer entries for
@@ -3296,7 +3296,8 @@ static bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
 * because that's when the `freq` was introduced to TX_FRM HTT command.
 */
return (ar->htt.target_version_major >= 3 &&
-   ar->htt.target_version_minor >= 4);
+   ar->htt.target_version_minor >= 4 &&
+   ar->htt.op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
 }
 
 static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
diff --git a/drivers/net/wireless/ath/ath10k/mac.h 
b/drivers/net/wireless/ath/ath10k/mac.h
index e3cefe4..f504804 100644
--- a/drivers/net/wireless/ath/ath10k/mac.h
+++ b/drivers/net/wireless/ath/ath10k/mac.h
@@ -74,6 +74,7 @@ void ath10k_mac_tx_lock(struct ath10k *ar, int reason);
 void ath10k_mac_tx_unlock(struct ath10k *ar, int reason);
 void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason);
 void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason);
+bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar);
 
 static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif)
 {
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsu

[PATCH V3 0/3] Fix few WMI/HTT interfaces

2015-11-04 Thread Vasanthakumar Thiagarajan
This patch set fixes mismatch in peer_assoc complete wmi command for
version 10.4 and peer_id configuration for HTT version < 3.4.

V2:
- Add cover letter
- Rename ath10k_mac_need_offchan_tx_work() to
  ath10k_mac_tx_frm_has_freq(). Add htt-op-version check
  to the helper and use it in ath10k_htt_tx() while configuring
  peerid.

V3:
- Rebase on top of ath:master TOT

Vasanthakumar Thiagarajan (3):
  ath10k: Fix peer assoc complete WMI command for 10.4
  ath10k: Rename the helper which is used for off-channel tx
  ath10k: Fix peerid configuration in htt tx desc for htt version < 3.4

 drivers/net/wireless/ath/ath10k/htt.h|  9 ++--
 drivers/net/wireless/ath/ath10k/htt_tx.c | 11 --
 drivers/net/wireless/ath/ath10k/mac.c|  9 
 drivers/net/wireless/ath/ath10k/mac.h|  1 +
 drivers/net/wireless/ath/ath10k/wmi.c| 37 +++-
 drivers/net/wireless/ath/ath10k/wmi.h|  5 +
 6 files changed, 63 insertions(+), 9 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V3 2/3] ath10k: Rename the helper which is used for off-channel tx

2015-11-04 Thread Vasanthakumar Thiagarajan
Rename ath10k_mac_need_offchan_tx_work() to ath10k_mac_tx_frm_has_freq()
to make it more meaningful. This helper will be used in the future
change. No functionality change.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/mac.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index a53e213..363a99c 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3287,7 +3287,7 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
}
 }
 
-static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
+static bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
 {
/* FIXME: Not really sure since when the behaviour changed. At some
 * point new firmware stopped requiring creation of peer entries for
@@ -3295,8 +3295,8 @@ static bool ath10k_mac_need_offchan_tx_work(struct ath10k 
*ar)
 * tx credit replenishment and reliability). Assuming it's at least 3.4
 * because that's when the `freq` was introduced to TX_FRM HTT command.
 */
-   return !(ar->htt.target_version_major >= 3 &&
-ar->htt.target_version_minor >= 4);
+   return (ar->htt.target_version_major >= 3 &&
+   ar->htt.target_version_minor >= 4);
 }
 
 static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
@@ -3680,7 +3680,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
spin_unlock_bh(>data_lock);
 
-   if (ath10k_mac_need_offchan_tx_work(ar)) {
+   if (!ath10k_mac_tx_frm_has_freq(ar)) {
ATH10K_SKB_CB(skb)->htt.freq = 0;
ATH10K_SKB_CB(skb)->htt.is_offchan = true;
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V3 1/3] ath10k: Fix peer assoc complete WMI command for 10.4

2015-11-04 Thread Vasanthakumar Thiagarajan
There is an extra 4-byte member when compared to WMI 10.2 added to
assoc complete command in WMI 10.4. This new member is used for 160Mhz
related configuration. This WMI command mismatch between host and
firmware does not cause any real issues because this new member is not
used in 10.4 firmwares so far (10.4.1.00030-1). This difference in WMI
command interface brings in a new wmi_ops for 10.4 gen_peer_assoc().
No noticeable functionality differences with this change can be seen
with the current 10.4 firmwares, but the WMI interface has to be
fixed to work with future 10.4 firmwares which may be using this new
member.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/wmi.c | 37 ++-
 drivers/net/wireless/ath/ath10k/wmi.h |  5 +
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.c 
b/drivers/net/wireless/ath/ath10k/wmi.c
index 56806d9..9021079 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -6376,6 +6376,16 @@ ath10k_wmi_peer_assoc_fill_10_2(struct ath10k *ar, void 
*buf,
cmd->info0 = __cpu_to_le32(info0);
 }
 
+static void
+ath10k_wmi_peer_assoc_fill_10_4(struct ath10k *ar, void *buf,
+   const struct wmi_peer_assoc_complete_arg *arg)
+{
+   struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf;
+
+   ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg);
+   cmd->peer_bw_rxnss_override = 0;
+}
+
 static int
 ath10k_wmi_peer_assoc_check_arg(const struct wmi_peer_assoc_complete_arg *arg)
 {
@@ -6465,6 +6475,31 @@ ath10k_wmi_10_2_op_gen_peer_assoc(struct ath10k *ar,
 }
 
 static struct sk_buff *
+ath10k_wmi_10_4_op_gen_peer_assoc(struct ath10k *ar,
+ const struct wmi_peer_assoc_complete_arg *arg)
+{
+   size_t len = sizeof(struct wmi_10_4_peer_assoc_complete_cmd);
+   struct sk_buff *skb;
+   int ret;
+
+   ret = ath10k_wmi_peer_assoc_check_arg(arg);
+   if (ret)
+   return ERR_PTR(ret);
+
+   skb = ath10k_wmi_alloc_skb(ar, len);
+   if (!skb)
+   return ERR_PTR(-ENOMEM);
+
+   ath10k_wmi_peer_assoc_fill_10_4(ar, skb->data, arg);
+
+   ath10k_dbg(ar, ATH10K_DBG_WMI,
+  "wmi peer assoc vdev %d addr %pM (%s)\n",
+  arg->vdev_id, arg->addr,
+  arg->peer_reassoc ? "reassociate" : "new");
+   return skb;
+}
+
+static struct sk_buff *
 ath10k_wmi_10_2_op_gen_pdev_get_temperature(struct ath10k *ar)
 {
struct sk_buff *skb;
@@ -7584,6 +7619,7 @@ static const struct wmi_ops wmi_10_4_ops = {
.gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
.gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
.gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
+   .gen_peer_assoc = ath10k_wmi_10_4_op_gen_peer_assoc,
.gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
.gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
.gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
@@ -7603,7 +7639,6 @@ static const struct wmi_ops wmi_10_4_ops = {
.fw_stats_fill = ath10k_wmi_10_4_op_fw_stats_fill,
 
/* shared with 10.2 */
-   .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
.gen_request_stats = ath10k_wmi_op_gen_request_stats,
.gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature,
 };
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h 
b/drivers/net/wireless/ath/ath10k/wmi.h
index a35c91e..80d3f1c 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -5799,6 +5799,11 @@ struct wmi_10_2_peer_assoc_complete_cmd {
__le32 info0; /* WMI_PEER_ASSOC_INFO0_ */
 } __packed;
 
+struct wmi_10_4_peer_assoc_complete_cmd {
+   struct wmi_10_2_peer_assoc_complete_cmd cmd;
+   __le32 peer_bw_rxnss_override;
+} __packed;
+
 struct wmi_peer_assoc_complete_arg {
u8 addr[ETH_ALEN];
u32 vdev_id;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V2 0/3] Fix few WMI/HTT interfaces

2015-11-04 Thread Vasanthakumar Thiagarajan
On Wed, Nov 04, 2015 at 07:59:39PM +0200, Kalle Valo wrote:
> Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com> writes:
> 
> > This patch set fixes mismatch in peer_assoc complete wmi command for
> > version 10.4 and peer_id configuration for HTT version < 3.4.
> >
> > V2:
> > - Add cover letter
> > - Rename ath10k_mac_need_offchan_tx_work() to
> >   ath10k_mac_tx_frm_has_freq(). Add htt-op-version check
> >   to the helper and use it in ath10k_htt_tx() while configuring
> >   peerid.
> >
> > Vasanthakumar Thiagarajan (3):
> >   ath10k: Fix peer assoc complete WMI command for 10.4
> >   ath10k: Rename the helper which is used for off-channel tx
> >   ath10k: Fix peerid configuration in htt tx desc for htt version < 3.4
> 
> These had a conflict but you didn't use ath.git as the baseline so I
> can't easily fix them. Please try always to use clean ath.git master
> branch as the baseline for your patches.
> 
> Applying: ath10k: Fix peer assoc complete WMI command for 10.4
> fatal: sha1 information is lacking or useless 
> (drivers/net/wireless/ath/ath10k/wmi.h).
> Repository lacks necessary blobs to fall back on 3-way merge.
> Cannot fall back to three-way merge.
> Patch failed at 0001 ath10k: Fix peer assoc complete WMI command for 10.4

Sorry for this. I prepared these patches on ath:master on top of my other 
pending
patch set. Not sure what went wrong. Ill resend this. Thanks.

Vasanth
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 0/3] Fix few WMI/HTT interfaces

2015-11-04 Thread Vasanthakumar Thiagarajan
This patch set fixes mismatch in peer_assoc complete wmi command for
version 10.4 and peer_id configuration for HTT version < 3.4.

V2:
- Add cover letter
- Rename ath10k_mac_need_offchan_tx_work() to
  ath10k_mac_tx_frm_has_freq(). Add htt-op-version check
  to the helper and use it in ath10k_htt_tx() while configuring
  peerid.

Vasanthakumar Thiagarajan (3):
  ath10k: Fix peer assoc complete WMI command for 10.4
  ath10k: Rename the helper which is used for off-channel tx
  ath10k: Fix peerid configuration in htt tx desc for htt version < 3.4

 drivers/net/wireless/ath/ath10k/htt.h|  9 ++--
 drivers/net/wireless/ath/ath10k/htt_tx.c | 11 --
 drivers/net/wireless/ath/ath10k/mac.c|  9 
 drivers/net/wireless/ath/ath10k/mac.h|  1 +
 drivers/net/wireless/ath/ath10k/wmi.c| 37 +++-
 drivers/net/wireless/ath/ath10k/wmi.h|  5 +
 6 files changed, 63 insertions(+), 9 deletions(-)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 2/3] ath10k: Rename the helper which is used for off-channel tx

2015-11-04 Thread Vasanthakumar Thiagarajan
Rename ath10k_mac_need_offchan_tx_work() to ath10k_mac_tx_frm_has_freq()
to make it more meaningful. This helper will be used in the future
change. No functionality change.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/mac.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index a7411fe..f121021 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3280,7 +3280,7 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
}
 }
 
-static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
+static bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
 {
/* FIXME: Not really sure since when the behaviour changed. At some
 * point new firmware stopped requiring creation of peer entries for
@@ -3288,8 +3288,8 @@ static bool ath10k_mac_need_offchan_tx_work(struct ath10k 
*ar)
 * tx credit replenishment and reliability). Assuming it's at least 3.4
 * because that's when the `freq` was introduced to TX_FRM HTT command.
 */
-   return !(ar->htt.target_version_major >= 3 &&
-ar->htt.target_version_minor >= 4);
+   return (ar->htt.target_version_major >= 3 &&
+   ar->htt.target_version_minor >= 4);
 }
 
 static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
@@ -3673,7 +3673,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
spin_unlock_bh(>data_lock);
 
-   if (ath10k_mac_need_offchan_tx_work(ar)) {
+   if (!ath10k_mac_tx_frm_has_freq(ar)) {
ATH10K_SKB_CB(skb)->htt.freq = 0;
ATH10K_SKB_CB(skb)->htt.is_offchan = true;
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 3/3] ath10k: Fix peerid configuration in htt tx desc for htt version < 3.4

2015-11-04 Thread Vasanthakumar Thiagarajan
Of a word in struct htt_data_tx_desc htt version >= 3.4 firmware uses
LSB 16-bit for frequency configuration which is used for offchannel tx
and MSB 16-bit is for peerid. But other firmwares using version 2.X
(10.1, 10.2.2, 10.2.4 and 10.4) are using 32-bit for peerid in htt tx
desc. So far no issue is found with the existing code setting peerid and
freq for HTT version 2.X, this could be mainly because of 0 as frequecy
(home channel) is being always passed with those firmwares. There may be
issues when non-zero freq is passed with firmware using < 3.4 htt version.
To be safe use target_version_major and target_version_minor along with
htt-op-version before configuring peer id and freq in htt tx desc. This
patch extends ath10k_mac_tx_frm_has_freq() to check for htt_op_version_tlv
and uses the helper while setting peerid in htt_tx_desc.

Fixes: 8d6d36243610 ("ath10k: fix offchan reliability")
Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/htt.h|  9 +++--
 drivers/net/wireless/ath/ath10k/htt_tx.c | 11 +--
 drivers/net/wireless/ath/ath10k/mac.c|  5 +++--
 drivers/net/wireless/ath/ath10k/mac.h|  1 +
 4 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.h 
b/drivers/net/wireless/ath/ath10k/htt.h
index 2bad50e..44fb4f2 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -166,8 +166,13 @@ struct htt_data_tx_desc {
__le16 len;
__le16 id;
__le32 frags_paddr;
-   __le16 peerid;
-   __le16 freq;
+   union {
+   __le32 peerid;
+   struct {
+   __le16 peerid;
+   __le16 freq;
+   } __packed offchan_tx;
+   } __packed;
u8 prefetch[0]; /* start of frame, for FW classification engine */
 } __packed;
 
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c 
b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 1682397..2dcea48 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -681,8 +681,15 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff 
*msdu)
skb_cb->htt.txbuf->cmd_tx.len = __cpu_to_le16(msdu->len);
skb_cb->htt.txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
-   skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le16(HTT_INVALID_PEERID);
-   skb_cb->htt.txbuf->cmd_tx.freq = __cpu_to_le16(skb_cb->htt.freq);
+   if (ath10k_mac_tx_frm_has_freq(ar)) {
+   skb_cb->htt.txbuf->cmd_tx.offchan_tx.peerid =
+   __cpu_to_le16(HTT_INVALID_PEERID);
+   skb_cb->htt.txbuf->cmd_tx.offchan_tx.freq =
+   __cpu_to_le16(skb_cb->htt.freq);
+   } else {
+   skb_cb->htt.txbuf->cmd_tx.peerid =
+   __cpu_to_le32(HTT_INVALID_PEERID);
+   }
 
trace_ath10k_htt_tx(ar, msdu_id, msdu->len, vdev_id, tid);
ath10k_dbg(ar, ATH10K_DBG_HTT,
diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index f121021..7fe51bf 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3280,7 +3280,7 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
}
 }
 
-static bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
+bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
 {
/* FIXME: Not really sure since when the behaviour changed. At some
 * point new firmware stopped requiring creation of peer entries for
@@ -3289,7 +3289,8 @@ static bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
 * because that's when the `freq` was introduced to TX_FRM HTT command.
 */
return (ar->htt.target_version_major >= 3 &&
-   ar->htt.target_version_minor >= 4);
+   ar->htt.target_version_minor >= 4 &&
+   ar->htt.op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
 }
 
 static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
diff --git a/drivers/net/wireless/ath/ath10k/mac.h 
b/drivers/net/wireless/ath/ath10k/mac.h
index e3cefe4..f504804 100644
--- a/drivers/net/wireless/ath/ath10k/mac.h
+++ b/drivers/net/wireless/ath/ath10k/mac.h
@@ -74,6 +74,7 @@ void ath10k_mac_tx_lock(struct ath10k *ar, int reason);
 void ath10k_mac_tx_unlock(struct ath10k *ar, int reason);
 void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason);
 void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason);
+bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar);
 
 static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif)
 {
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsu

[PATCH V2 1/3] ath10k: Fix peer assoc complete WMI command for 10.4

2015-11-04 Thread Vasanthakumar Thiagarajan
There is an extra 4-byte member when compared to WMI 10.2 added to
assoc complete command in WMI 10.4. This new member is used for 160Mhz
related configuration. This WMI command mismatch between host and
firmware does not cause any real issues because this new member is not
used in 10.4 firmwares so far (10.4.1.00030-1). This difference in WMI
command interface brings in a new wmi_ops for 10.4 gen_peer_assoc().
No noticeable functionality differences with this change can be seen
with the current 10.4 firmwares, but the WMI interface has to be
fixed to work with future 10.4 firmwares which may be using this new
member.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/wmi.c | 37 ++-
 drivers/net/wireless/ath/ath10k/wmi.h |  5 +
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.c 
b/drivers/net/wireless/ath/ath10k/wmi.c
index 7569db0..e8614ab 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -6328,6 +6328,16 @@ ath10k_wmi_peer_assoc_fill_10_2(struct ath10k *ar, void 
*buf,
cmd->info0 = __cpu_to_le32(info0);
 }
 
+static void
+ath10k_wmi_peer_assoc_fill_10_4(struct ath10k *ar, void *buf,
+   const struct wmi_peer_assoc_complete_arg *arg)
+{
+   struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf;
+
+   ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg);
+   cmd->peer_bw_rxnss_override = 0;
+}
+
 static int
 ath10k_wmi_peer_assoc_check_arg(const struct wmi_peer_assoc_complete_arg *arg)
 {
@@ -6417,6 +6427,31 @@ ath10k_wmi_10_2_op_gen_peer_assoc(struct ath10k *ar,
 }
 
 static struct sk_buff *
+ath10k_wmi_10_4_op_gen_peer_assoc(struct ath10k *ar,
+ const struct wmi_peer_assoc_complete_arg *arg)
+{
+   size_t len = sizeof(struct wmi_10_4_peer_assoc_complete_cmd);
+   struct sk_buff *skb;
+   int ret;
+
+   ret = ath10k_wmi_peer_assoc_check_arg(arg);
+   if (ret)
+   return ERR_PTR(ret);
+
+   skb = ath10k_wmi_alloc_skb(ar, len);
+   if (!skb)
+   return ERR_PTR(-ENOMEM);
+
+   ath10k_wmi_peer_assoc_fill_10_4(ar, skb->data, arg);
+
+   ath10k_dbg(ar, ATH10K_DBG_WMI,
+  "wmi peer assoc vdev %d addr %pM (%s)\n",
+  arg->vdev_id, arg->addr,
+  arg->peer_reassoc ? "reassociate" : "new");
+   return skb;
+}
+
+static struct sk_buff *
 ath10k_wmi_10_2_op_gen_pdev_get_temperature(struct ath10k *ar)
 {
struct sk_buff *skb;
@@ -7536,6 +7571,7 @@ static const struct wmi_ops wmi_10_4_ops = {
.gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
.gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
.gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
+   .gen_peer_assoc = ath10k_wmi_10_4_op_gen_peer_assoc,
.gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
.gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
.gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
@@ -7555,7 +7591,6 @@ static const struct wmi_ops wmi_10_4_ops = {
.fw_stats_fill = ath10k_wmi_10_4_op_fw_stats_fill,
 
/* shared with 10.2 */
-   .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
.gen_request_stats = ath10k_wmi_op_gen_request_stats,
 };
 
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h 
b/drivers/net/wireless/ath/ath10k/wmi.h
index a8ea93e..ab6d218 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -5741,6 +5741,11 @@ struct wmi_10_2_peer_assoc_complete_cmd {
__le32 info0; /* WMI_PEER_ASSOC_INFO0_ */
 } __packed;
 
+struct wmi_10_4_peer_assoc_complete_cmd {
+   struct wmi_10_2_peer_assoc_complete_cmd cmd;
+   __le32 peer_bw_rxnss_override;
+} __packed;
+
 struct wmi_peer_assoc_complete_arg {
u8 addr[ETH_ALEN];
u32 vdev_id;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] ath10k: Fix peerid configuration in htt tx desc for htt version < 3.4

2015-11-02 Thread Vasanthakumar Thiagarajan
Of a word in struct htt_data_tx_desc htt version >= 3.4 firmware uses LSB 16-bit
for frequency configuration which is used for offchannel tx and MSB 16-bit
is for peerid. But other firmwares using version 2.X (10.1, 10.2.2, 10.2.4
and 10.4) are using 32-bit for peerid in htt tx desc. So far no issue is found
with the existing code setting peerid and freq for HTT version 2.X, this could
be mainly because of 0 as frequecy (home channel) is being always passed with
those firmwares. There may be issues when non-zero freq is passed with firmware
using < 3.4 htt version. To be safe use target_version_major and 
target_version_minor
along with htt-op-version before configuring peer id and freq in htt tx desc.

Fixes: 8d6d36243610 ("ath10k: fix offchan reliability")
Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/htt.h|  9 +++--
 drivers/net/wireless/ath/ath10k/htt_tx.c | 13 +++--
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.h 
b/drivers/net/wireless/ath/ath10k/htt.h
index 2bad50e..44fb4f2 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -166,8 +166,13 @@ struct htt_data_tx_desc {
__le16 len;
__le16 id;
__le32 frags_paddr;
-   __le16 peerid;
-   __le16 freq;
+   union {
+   __le32 peerid;
+   struct {
+   __le16 peerid;
+   __le16 freq;
+   } __packed offchan_tx;
+   } __packed;
u8 prefetch[0]; /* start of frame, for FW classification engine */
 } __packed;
 
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c 
b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 1682397..bf19247 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -681,8 +681,17 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff 
*msdu)
skb_cb->htt.txbuf->cmd_tx.len = __cpu_to_le16(msdu->len);
skb_cb->htt.txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
-   skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le16(HTT_INVALID_PEERID);
-   skb_cb->htt.txbuf->cmd_tx.freq = __cpu_to_le16(skb_cb->htt.freq);
+   if (ar->htt.target_version_major >= 3 &&
+   ar->htt.target_version_minor >= 4 &&
+   ar->htt.op_version == ATH10K_FW_HTT_OP_VERSION_TLV) {
+   skb_cb->htt.txbuf->cmd_tx.offchan_tx.peerid =
+   __cpu_to_le16(HTT_INVALID_PEERID);
+   skb_cb->htt.txbuf->cmd_tx.offchan_tx.freq =
+   __cpu_to_le16(skb_cb->htt.freq);
+   } else {
+   skb_cb->htt.txbuf->cmd_tx.peerid =
+   __cpu_to_le32(HTT_INVALID_PEERID);
+   }
 
trace_ath10k_htt_tx(ar, msdu_id, msdu->len, vdev_id, tid);
ath10k_dbg(ar, ATH10K_DBG_HTT,
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] ath10k: Fix peer assoc complete WMI command for 10.4

2015-11-02 Thread Vasanthakumar Thiagarajan
There is an extra 4-byte member when compared to WMI 10.2 added to assoc
complete command in WMI 10.4. This new member is used for 160Mhz related
configuration. This WMI command mismatch between host and firmware does
not cause any real issues because this new member is not used in 10.4
firmwares so far (10.4.1.00030-1). This difference in WMI command interface
brings in a new wmi_ops for 10.4 gen_peer_assoc(). No noticeable functionality
differences with this change can be seen with the current 10.4 firmwares, but
the WMI interface has to be fixed to work with future 10.4 firmwares which may
be using this new member.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/wmi.c | 37 ++-
 drivers/net/wireless/ath/ath10k/wmi.h |  5 +
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.c 
b/drivers/net/wireless/ath/ath10k/wmi.c
index 7569db0..e8614ab 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -6328,6 +6328,16 @@ ath10k_wmi_peer_assoc_fill_10_2(struct ath10k *ar, void 
*buf,
cmd->info0 = __cpu_to_le32(info0);
 }
 
+static void
+ath10k_wmi_peer_assoc_fill_10_4(struct ath10k *ar, void *buf,
+   const struct wmi_peer_assoc_complete_arg *arg)
+{
+   struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf;
+
+   ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg);
+   cmd->peer_bw_rxnss_override = 0;
+}
+
 static int
 ath10k_wmi_peer_assoc_check_arg(const struct wmi_peer_assoc_complete_arg *arg)
 {
@@ -6417,6 +6427,31 @@ ath10k_wmi_10_2_op_gen_peer_assoc(struct ath10k *ar,
 }
 
 static struct sk_buff *
+ath10k_wmi_10_4_op_gen_peer_assoc(struct ath10k *ar,
+ const struct wmi_peer_assoc_complete_arg *arg)
+{
+   size_t len = sizeof(struct wmi_10_4_peer_assoc_complete_cmd);
+   struct sk_buff *skb;
+   int ret;
+
+   ret = ath10k_wmi_peer_assoc_check_arg(arg);
+   if (ret)
+   return ERR_PTR(ret);
+
+   skb = ath10k_wmi_alloc_skb(ar, len);
+   if (!skb)
+   return ERR_PTR(-ENOMEM);
+
+   ath10k_wmi_peer_assoc_fill_10_4(ar, skb->data, arg);
+
+   ath10k_dbg(ar, ATH10K_DBG_WMI,
+  "wmi peer assoc vdev %d addr %pM (%s)\n",
+  arg->vdev_id, arg->addr,
+  arg->peer_reassoc ? "reassociate" : "new");
+   return skb;
+}
+
+static struct sk_buff *
 ath10k_wmi_10_2_op_gen_pdev_get_temperature(struct ath10k *ar)
 {
struct sk_buff *skb;
@@ -7536,6 +7571,7 @@ static const struct wmi_ops wmi_10_4_ops = {
.gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
.gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
.gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
+   .gen_peer_assoc = ath10k_wmi_10_4_op_gen_peer_assoc,
.gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
.gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
.gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
@@ -7555,7 +7591,6 @@ static const struct wmi_ops wmi_10_4_ops = {
.fw_stats_fill = ath10k_wmi_10_4_op_fw_stats_fill,
 
/* shared with 10.2 */
-   .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
.gen_request_stats = ath10k_wmi_op_gen_request_stats,
 };
 
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h 
b/drivers/net/wireless/ath/ath10k/wmi.h
index a8ea93e..ab6d218 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -5741,6 +5741,11 @@ struct wmi_10_2_peer_assoc_complete_cmd {
__le32 info0; /* WMI_PEER_ASSOC_INFO0_ */
 } __packed;
 
+struct wmi_10_4_peer_assoc_complete_cmd {
+   struct wmi_10_2_peer_assoc_complete_cmd cmd;
+   __le32 peer_bw_rxnss_override;
+} __packed;
+
 struct wmi_peer_assoc_complete_arg {
u8 addr[ETH_ALEN];
u32 vdev_id;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] ath10k: Fix peerid configuration in htt tx desc for htt version < 3.4

2015-11-02 Thread Vasanthakumar Thiagarajan

On Monday 02 November 2015 03:57 PM, Michal Kazior wrote:

On 2 November 2015 at 09:33, Vasanthakumar Thiagarajan
<vthia...@qti.qualcomm.com> wrote:

Of a word in struct htt_data_tx_desc htt version >= 3.4 firmware uses LSB 16-bit
for frequency configuration which is used for offchannel tx and MSB 16-bit
is for peerid. But other firmwares using version 2.X (10.1, 10.2.2, 10.2.4
and 10.4) are using 32-bit for peerid in htt tx desc. So far no issue is found
with the existing code setting peerid and freq for HTT version 2.X, this could
be mainly because of 0 as frequecy (home channel) is being always passed with
those firmwares. There may be issues when non-zero freq is passed with firmware
using < 3.4 htt version. To be safe use target_version_major and 
target_version_minor
along with htt-op-version before configuring peer id and freq in htt tx desc.

Fixes: 8d6d36243610 ("ath10k: fix offchan reliability")
Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
  drivers/net/wireless/ath/ath10k/htt.h|  9 +++--
  drivers/net/wireless/ath/ath10k/htt_tx.c | 13 +++--
  2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt.h 
b/drivers/net/wireless/ath/ath10k/htt.h
index 2bad50e..44fb4f2 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -166,8 +166,13 @@ struct htt_data_tx_desc {
 __le16 len;
 __le16 id;
 __le32 frags_paddr;
-   __le16 peerid;
-   __le16 freq;
+   union {
+   __le32 peerid;
+   struct {
+   __le16 peerid;
+   __le16 freq;
+   } __packed offchan_tx;
+   } __packed;
 u8 prefetch[0]; /* start of frame, for FW classification engine */
  } __packed;

diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c 
b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 1682397..bf19247 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -681,8 +681,17 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff 
*msdu)
 skb_cb->htt.txbuf->cmd_tx.len = __cpu_to_le16(msdu->len);
 skb_cb->htt.txbuf->cmd_tx.id = __cpu_to_le16(msdu_id);
 skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
-   skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le16(HTT_INVALID_PEERID);
-   skb_cb->htt.txbuf->cmd_tx.freq = __cpu_to_le16(skb_cb->htt.freq);
+   if (ar->htt.target_version_major >= 3 &&
+   ar->htt.target_version_minor >= 4 &&
+   ar->htt.op_version == ATH10K_FW_HTT_OP_VERSION_TLV) {


Hmm.. I think it'd be better to rename
ath10k_mac_need_offchan_tx_work() to, e.g.
ath10k_htt_tx_frm_has_freq() and add the htt.op_version check to it.



Sure, thanks.

Vasanth

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/3] ath10k: Add new service defines for 10.4

2015-10-29 Thread Vasanthakumar Thiagarajan
No functional changes, adds new wmi service bits for
10.4 firmware to be sync with 10.4 firmware.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/wmi.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.h 
b/drivers/net/wireless/ath/ath10k/wmi.h
index cec887a..103dd8c 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -175,6 +175,8 @@ enum wmi_service {
WMI_SERVICE_AUX_SPECTRAL_INTF,
WMI_SERVICE_AUX_CHAN_LOAD_INTF,
WMI_SERVICE_BSS_CHANNEL_INFO_64,
+   WMI_SERVICE_EXT_RES_CFG_SUPPORT,
+   WMI_SERVICE_MESH,
 
/* keep last */
WMI_SERVICE_MAX,
@@ -286,6 +288,8 @@ enum wmi_10_4_service {
WMI_10_4_SERVICE_AUX_SPECTRAL_INTF,
WMI_10_4_SERVICE_AUX_CHAN_LOAD_INTF,
WMI_10_4_SERVICE_BSS_CHANNEL_INFO_64,
+   WMI_10_4_SERVICE_EXT_RES_CFG_SUPPORT,
+   WMI_10_4_SERVICE_MESH,
 };
 
 static inline char *wmi_service_name(int service_id)
@@ -375,6 +379,8 @@ static inline char *wmi_service_name(int service_id)
SVCSTR(WMI_SERVICE_AUX_SPECTRAL_INTF);
SVCSTR(WMI_SERVICE_AUX_CHAN_LOAD_INTF);
SVCSTR(WMI_SERVICE_BSS_CHANNEL_INFO_64);
+   SVCSTR(WMI_SERVICE_EXT_RES_CFG_SUPPORT);
+   SVCSTR(WMI_SERVICE_MESH);
default:
return NULL;
}
@@ -600,6 +606,10 @@ static inline void wmi_10_4_svc_map(const __le32 *in, 
unsigned long *out,
   WMI_SERVICE_AUX_CHAN_LOAD_INTF, len);
SVCMAP(WMI_10_4_SERVICE_BSS_CHANNEL_INFO_64,
   WMI_SERVICE_BSS_CHANNEL_INFO_64, len);
+   SVCMAP(WMI_10_4_SERVICE_EXT_RES_CFG_SUPPORT,
+  WMI_SERVICE_EXT_RES_CFG_SUPPORT, len);
+   SVCMAP(WMI_10_4_SERVICE_MESH,
+  WMI_SERVICE_MESH, len);
 }
 
 #undef SVCMAP
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/3] Add new WMI defines to 10.4

2015-10-29 Thread Vasanthakumar Thiagarajan
This patch set does not have any real functionality changes.
Adds new WMI defines to be in sync with 10.4 firmware.

Vasanthakumar Thiagarajan (3):
  ath10k: Add new service defines for 10.4
  ath10k: Add new WMI cmd/event defines for 10.4
  ath10k: Add new pdev params defines to 10.4

 drivers/net/wireless/ath/ath10k/wmi.h | 20 
 1 file changed, 20 insertions(+)

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] ath10k: Add new pdev params defines to 10.4

2015-10-29 Thread Vasanthakumar Thiagarajan
No functionality change, just sync to the latest
pdev params that 10.4 firmware defines.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/wmi.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.h 
b/drivers/net/wireless/ath/ath10k/wmi.h
index 3076581..a9073b0 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -3660,6 +3660,12 @@ enum wmi_10_4_pdev_param {
WMI_10_4_PDEV_PARAM_WAPI_MBSSID_OFFSET,
WMI_10_4_PDEV_PARAM_ARP_SRCADDR,
WMI_10_4_PDEV_PARAM_ARP_DSTADDR,
+   WMI_10_4_PDEV_PARAM_TXPOWER_DECR_DB,
+   WMI_10_4_PDEV_PARAM_RX_BATCHMODE,
+   WMI_10_4_PDEV_PARAM_PACKET_AGGR_DELAY,
+   WMI_10_4_PDEV_PARAM_ATF_OBSS_NOISE_SCH,
+   WMI_10_4_PDEV_PARAM_ATF_OBSS_NOISE_SCALING_FACTOR,
+   WMI_10_4_PDEV_PARAM_CUST_TXPOWER_SCALE,
 };
 
 struct wmi_pdev_set_param_cmd {
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/3] ath10k: Add new WMI cmd/event defines for 10.4

2015-10-29 Thread Vasanthakumar Thiagarajan
No real functionality change, add WMI command/event
defines to be in sync with 10.4 firmware.

Signed-off-by: Vasanthakumar Thiagarajan <vthia...@qti.qualcomm.com>
---
 drivers/net/wireless/ath/ath10k/wmi.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.h 
b/drivers/net/wireless/ath/ath10k/wmi.h
index 103dd8c..3076581 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -1582,6 +1582,9 @@ enum wmi_10_4_cmd_id {
WMI_10_4_MU_CAL_START_CMDID,
WMI_10_4_SET_CCA_PARAMS_CMDID,
WMI_10_4_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
+   WMI_10_4_EXT_RESOURCE_CFG_CMDID,
+   WMI_10_4_VDEV_SET_IE_CMDID,
+   WMI_10_4_SET_LTEU_CONFIG_CMDID,
WMI_10_4_PDEV_UTF_CMDID = WMI_10_4_END_CMDID - 1,
 };
 
@@ -1644,6 +1647,7 @@ enum wmi_10_4_event_id {
WMI_10_4_PDEV_TEMPERATURE_EVENTID,
WMI_10_4_PDEV_NFCAL_POWER_ALL_CHANNELS_EVENTID,
WMI_10_4_PDEV_BSS_CHAN_INFO_EVENTID,
+   WMI_10_4_MU_REPORT_EVENTID,
WMI_10_4_PDEV_UTF_EVENTID = WMI_10_4_END_EVENTID - 1,
 };
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ath10k: Fix DMA alloc failure for target requested memory chunks

2015-08-28 Thread Vasanthakumar Thiagarajan
During long hours of stress testing like AP interface up/down along
with continuous ping flood from a station doing connect/disconnect,
it is observed that the system is not able to allocate DMA consistent
memory of size  512KB chunks as requested by firmware in WMI_SERVICE_EVENTID.
With the system memory getting fragmented during the run based on the
size of the memory requested, the failure to return physically continguous
memory of high order can happen. Once the system gets to this situation,
bringing up the wifi interface will fail and a system reboot may be needed
to make it work again. This problem is obseved with QCA99X0.

To fix this issue, allocate the DMA memory requested by firmware during
device probe time and keep it during the life time of the device. WMI service
ready event handler is changed to allocate the memory chunks if it is
not already allocated or if the memory allocated for the previous ready
event is not same as the current requested ones. After this patch the
memory usage when wifi is inactive will be inceased by few 100KB to
3MB based on the target type.

Failure happens with the following stack trace

[29557.488773] kworker/u4:1: page allocation failure: order:8, mode:0xd0
[29557.494297] CPU: 0 PID: 8402 Comm: kworker/u4:1 Not tainted 3.14.43 #7
[29557.500793] Workqueue: ath10k_aux_wq ath10k_wmi_event_service_ready_work 
[ath10k_core]
[29557.508602] [c021e9b0] (unwind_backtrace) from [c021ba90] 
(show_stack+0x10/0x14)
[29557.516580] [c021ba90] (show_stack) from [c03bdddc] 
(dump_stack+0x88/0xcc)
[29557.523612] [c03bdddc] (dump_stack) from [c0290e34] 
(warn_alloc_failed+0xdc/0x108)
[29557.531515] [c0290e34] (warn_alloc_failed) from [c0292d88] 
(__alloc_pages_nodemask+0x4f0/0x654)
[29557.540485] [c0292d88] (__alloc_pages_nodemask) from [c0222b48] 
(__dma_alloc_buffer.isra.20+0x2c/0x104)
[29557.550260] [c0222b48] (__dma_alloc_buffer.isra.20) from [c0222c34] 
(__alloc_remap_buffer.isra.23+0x14/0xb8)
[29557.560413] [c0222c34] (__alloc_remap_buffer.isra.23) from [c022305c] 
(__dma_alloc+0x224/0x2b8)
[29557.569490] [c022305c] (__dma_alloc) from [c0223208] 
(arm_dma_alloc+0x84/0x90)
[29557.577010] [c0223208] (arm_dma_alloc) from [bf5159d0] 
(ath10k_wmi_event_service_ready_work+0x2f8/0x420 [ath10k_core])
[29557.588055] [bf5159d0] (ath10k_wmi_event_service_ready_work [ath10k_core]) 
from [c024260c] (process_one_work+0x20c/0x328)
[29557.599305] [c024260c] (process_one_work) from [c02432d0] 
(worker_thread+0x228/0x360)
[29557.607470] [c02432d0] (worker_thread) from [c0247f88] 
(kthread+0xd8/0xec)
[29557.614750] [c0247f88] (kthread) from [c0208d18] 
(ret_from_fork+0x14/0x3c)
[29557.712751] Normal: 696*4kB (UEMR) 512*8kB (UEMR) 367*16kB (UEMR) 404*32kB 
(UEMR) 455*64kB (UEMR) 424*128kB (UEMR) 379*256kB (UMR) 327*512kB (UMR) 
1*1024kB (R) 0*2048kB 0*4096kB = 374544kB

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/core.c |  1 +
 drivers/net/wireless/ath/ath10k/wmi.c  | 76 +++---
 drivers/net/wireless/ath/ath10k/wmi.h  |  1 +
 3 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index b87b986..6e5aeed 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1714,6 +1714,7 @@ void ath10k_core_destroy(struct ath10k *ar)
destroy_workqueue(ar-workqueue_aux);
 
ath10k_debug_destroy(ar);
+   ath10k_wmi_free_host_mem(ar);
ath10k_mac_destroy(ar);
 }
 EXPORT_SYMBOL(ath10k_core_destroy);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c 
b/drivers/net/wireless/ath/ath10k/wmi.c
index ce01107..87d9de2 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -3917,6 +3917,53 @@ static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, 
u32 req_id,
return 0;
 }
 
+static bool
+ath10k_wmi_is_host_mem_allocated(struct ath10k *ar,
+const struct wlan_host_mem_req **mem_reqs,
+u32 num_mem_reqs)
+{
+   u32 req_id, num_units, unit_size, num_unit_info;
+   u32 pool_size;
+   int i, j;
+   bool found;
+
+   if (ar-wmi.num_mem_chunks != num_mem_reqs)
+   return false;
+
+   for (i = 0; i  num_mem_reqs; ++i) {
+   req_id = __le32_to_cpu(mem_reqs[i]-req_id);
+   num_units = __le32_to_cpu(mem_reqs[i]-num_units);
+   unit_size = __le32_to_cpu(mem_reqs[i]-unit_size);
+   num_unit_info = __le32_to_cpu(mem_reqs[i]-num_unit_info);
+
+   if (num_unit_info  NUM_UNITS_IS_NUM_ACTIVE_PEERS) {
+   if (ar-num_active_peers)
+   num_units = ar-num_active_peers + 1;
+   else
+   num_units = ar-max_num_peers + 1;
+   } else if (num_unit_info  NUM_UNITS_IS_NUM_PEERS

[PATCH] ath10k: Fill in wmi 10.4 command handlers for addba/delba debug commands

2015-08-13 Thread Vasanthakumar Thiagarajan
WMI 10.4 uses the same command interface as QCA988X for addba/delba
debug wmi commands. Fill wmi_10_4_ops table with the functions used
for QCA988X for these commands.

With this change, the following debugfs entries can be used to
configure the aggregation mode and to send addba request,
addba response and delba respectively in manual aggregation mode
for QCA99X0 chip.

/sys/kernel/debug/ieee80211/phyX/netdev:wlanX/stations/XX:XX:XX:XX:XX:XX/aggr_mode
/sys/kernel/debug/ieee80211/phyX/netdev:wlanX/stations/XX:XX:XX:XX:XX:XX/addba
/sys/kernel/debug/ieee80211/phyX/netdev:wlanX/stations/XX:XX:XX:XX:XX:XX/addba_resp
/sys/kernel/debug/ieee80211/phyX/netdev:wlanX/stations/XX:XX:XX:XX:XX:XX/delba

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/wmi.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.c 
b/drivers/net/wireless/ath/ath10k/wmi.c
index 36b8f71..9769936 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -6482,6 +6482,10 @@ static const struct wmi_ops wmi_10_4_ops = {
.gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
.gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
.gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
+   .gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp,
+   .gen_addba_send = ath10k_wmi_op_gen_addba_send,
+   .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
+   .gen_delba_send = ath10k_wmi_op_gen_delba_send,
 
/* shared with 10.2 */
.gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] ath10k: Fix invalid survey reporting for QCA99X0

2015-08-12 Thread Vasanthakumar Thiagarajan
There are three WMI_CHAN_INFO events reported per channel
in QCA99X0 firmware. First one is a notification at the begining
of the channel dwell time with cmd_flag as CHAN_INFO_START(cmd_flag = 0),
second one is a notification at the end of the dwell time with cmd_flag
CHAN_INFO_PRE_COMPLETE (cmd_flag = 2) and the third is the indication
with CHAN_INFO_COMPLETE (cmd_flag = 1) which is the last indication for
the channel. Since there is a new state before the completion, the handler
is to fixed so that the counts are deducted from the ones reported with
CHAN_INFO_START rather than the ones reported with CHAN_INFO_PRE_COMPLETE.
Without this fix there will be lots of 0 msecs reported as active
and busy time.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/wmi.c | 6 --
 drivers/net/wireless/ath/ath10k/wmi.h | 1 +
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/wmi.c 
b/drivers/net/wireless/ath/ath10k/wmi.c
index e6d6b42..38e22e0 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -2412,8 +2412,10 @@ void ath10k_wmi_event_chan_info(struct ath10k *ar, 
struct sk_buff *skb)
ar-ch_info_can_report_survey = true;
}
 
-   ar-survey_last_rx_clear_count = rx_clear_count;
-   ar-survey_last_cycle_count = cycle_count;
+   if (!(cmd_flags  WMI_CHAN_INFO_FLAG_PRE_COMPLETE)) {
+   ar-survey_last_rx_clear_count = rx_clear_count;
+   ar-survey_last_cycle_count = cycle_count;
+   }
 
 exit:
spin_unlock_bh(ar-data_lock);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h 
b/drivers/net/wireless/ath/ath10k/wmi.h
index 0d4efc9..5825c5c 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -5585,6 +5585,7 @@ struct wmi_peer_sta_kickout_event {
 } __packed;
 
 #define WMI_CHAN_INFO_FLAG_COMPLETE BIT(0)
+#define WMI_CHAN_INFO_FLAG_PRE_COMPLETE BIT(1)
 
 /* Beacon filter wmi command info */
 #define BCN_FLT_MAX_SUPPORTED_IES  256
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] ath10k: Add cycle/rx_clear counters frequency to hw_params

2015-08-12 Thread Vasanthakumar Thiagarajan
The frequency at which cycle/rx_clear counters are running might
change from one target type to another. QCA99X0 is running the
counters at 150Mhz while QCA9888X and QCA6174 are running at 88Mhz.
Add a new entry to hw_params to store the target specific frequency
and use it in msecs conversion. This change fixes inconsistent
channel active/busy time.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/core.c | 5 +
 drivers/net/wireless/ath/ath10k/core.h | 2 ++
 drivers/net/wireless/ath/ath10k/hw.c   | 4 ++--
 drivers/net/wireless/ath/ath10k/hw.h   | 3 +--
 4 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 2551067..2efd4e4 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -53,6 +53,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.uart_pin = 7,
.has_shifted_cc_wraparound = true,
.otp_exe_param = 0,
+   .channel_counters_freq_hz = 88000,
.fw = {
.dir = QCA988X_HW_2_0_FW_DIR,
.fw = QCA988X_HW_2_0_FW_FILE,
@@ -68,6 +69,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
.uart_pin = 6,
.otp_exe_param = 0,
+   .channel_counters_freq_hz = 88000,
.fw = {
.dir = QCA6174_HW_2_1_FW_DIR,
.fw = QCA6174_HW_2_1_FW_FILE,
@@ -83,6 +85,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
.uart_pin = 6,
.otp_exe_param = 0,
+   .channel_counters_freq_hz = 88000,
.fw = {
.dir = QCA6174_HW_3_0_FW_DIR,
.fw = QCA6174_HW_3_0_FW_FILE,
@@ -98,6 +101,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
.uart_pin = 6,
.otp_exe_param = 0,
+   .channel_counters_freq_hz = 88000,
.fw = {
/* uses same binaries as hw3.0 */
.dir = QCA6174_HW_3_0_FW_DIR,
@@ -115,6 +119,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.uart_pin = 7,
.otp_exe_param = 0x0700,
.continuous_frag_desc = true,
+   .channel_counters_freq_hz = 15,
.fw = {
.dir = QCA99X0_HW_2_0_FW_DIR,
.fw = QCA99X0_HW_2_0_FW_FILE,
diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index 6a387ba..862f6d0 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -609,6 +609,8 @@ struct ath10k {
 */
bool continuous_frag_desc;
 
+   u32 channel_counters_freq_hz;
+
struct ath10k_hw_params_fw {
const char *dir;
const char *fw;
diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c
index fef7ccf..7b84d08 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -152,6 +152,6 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct 
survey_info *survey,
cc -= cc_prev - cc_fix;
rcc -= rcc_prev;
 
-   survey-time = CCNT_TO_MSEC(cc);
-   survey-time_busy = CCNT_TO_MSEC(rcc);
+   survey-time = CCNT_TO_MSEC(ar, cc);
+   survey-time_busy = CCNT_TO_MSEC(ar, rcc);
 }
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index d9de4a7..23afcda 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -552,8 +552,7 @@ enum ath10k_hw_rate_cck {
 #define SCRATCH_3_ADDRESS  ar-regs-scratch_3_address
 #define CPU_INTR_ADDRESS   0x0010
 
-/* Cycle counters are running at 88MHz */
-#define CCNT_TO_MSEC(x) ((x) / 88000)
+#define CCNT_TO_MSEC(ar, x) ((x) / ar-hw_params.channel_counters_freq_hz)
 
 /* Firmware indications to the Host via SCRATCH_3 register. */
 #define FW_INDICATOR_ADDRESS   ar-regs-fw_indicator_address
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ath10k: Add QCA99X0 to supported device list

2015-08-06 Thread Vasanthakumar Thiagarajan

On Wednesday 05 August 2015 05:51 PM, Felix Fietkau wrote:

On 2015-07-21 13:36, Vasanthakumar Thiagarajan wrote:

Add vendor/device id of QCA99X0 V2.0 to pci id table and
QCA99X0_HW_2_0_CHIP_ID_REV to ath10k_pci_supp_chips[] for
QCA99X0 to get detected by the driver.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com

I just tested a 99X0 card, and I'm getting this:

[8.742514] ath10k_pci :01:00.0: enabling device (0140 - 0142)
[8.747173] ath10k_pci :01:00.0: pci irq msi interrupts 1 irq_mode 0 
reset_mode 0
[   11.793314] ath10k_pci :01:00.0: failed to receive initialized event 
from target: 
[   11.793344] ath10k_pci :01:00.0: failed to wait for target after cold 
reset: -110
[   11.800814] ath10k_pci :01:00.0: failed to reset chip: -110
[   11.809228] ath10k_pci: probe of :01:00.0 failed with error -110

This is on an AP148 board with Linux 3.18, backports generated from
latest wireless-testing (2015-08-03) + all patches from kvalo's ath
tree.


Any idea about the version of AP148 that you are using?. By any chance did
you check if QCA988X is working on the same board?.

Vasanth

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ath10k: remove NULL ptr deref in variable init of ath10k_monitor_vdev_start

2015-07-27 Thread Vasanthakumar Thiagarajan

On Tuesday 28 July 2015 12:52 AM, John W. Linville wrote:

In ath10k_monitor_vdev_start, chandef is initialized to NULL and then
channel is immediately thereafter initialized to chandef-chan (i.e.
NULL-chan).  This appears to be some sort of cut-n-paste error, since
the same assignment is done later (i.e. after chandef has been properly
assigned to a non-NULL value).  So, let's just remove this brown paper
bag typo/thinko... :-)

Coverity CID #1309505

Signed-off-by: John W. Linville linvi...@tuxdriver.com
---
  drivers/net/wireless/ath/ath10k/mac.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index c9a7d5b5dffc..2823222dea92 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -836,7 +836,7 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
  static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
  {
struct cfg80211_chan_def *chandef = NULL;
-   struct ieee80211_channel *channel = chandef-chan;
+   struct ieee80211_channel *channel;
struct wmi_vdev_start_request_arg arg = {};
int ret = 0;



There is a similar change integrated recently, 
https://github.com/kvalo/ath/commit/19be9e9a7ac7e6050eab426283d2a87593cf6e82 .


Vasanth


--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ath10k: Add QCA99X0 to supported device list

2015-07-21 Thread Vasanthakumar Thiagarajan
Add vendor/device id of QCA99X0 V2.0 to pci id table and
QCA99X0_HW_2_0_CHIP_ID_REV to ath10k_pci_supp_chips[] for
QCA99X0 to get detected by the driver.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/pci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 5778e52..cc0e897 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -64,6 +64,7 @@ MODULE_PARM_DESC(reset_mode, 0: auto, 1: warm only (default: 
0));
 static const struct pci_device_id ath10k_pci_id_table[] = {
{ PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */
{ PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 
*/
+   { PCI_VDEVICE(ATHEROS, QCA99X0_2_0_DEVICE_ID) }, /* PCI-E QCA99X0 V2 */
{0}
 };
 
@@ -78,6 +79,7 @@ static const struct ath10k_pci_supp_chip 
ath10k_pci_supp_chips[] = {
{ QCA6174_2_1_DEVICE_ID, QCA6174_HW_3_0_CHIP_ID_REV },
{ QCA6174_2_1_DEVICE_ID, QCA6174_HW_3_1_CHIP_ID_REV },
{ QCA6174_2_1_DEVICE_ID, QCA6174_HW_3_2_CHIP_ID_REV },
+   { QCA99X0_2_0_DEVICE_ID, QCA99X0_HW_2_0_CHIP_ID_REV },
 };
 
 static void ath10k_pci_buffer_cleanup(struct ath10k *ar);
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2] ath10k: Delay device access after cold reset

2015-07-10 Thread Vasanthakumar Thiagarajan
It is observed that during cold reset pcie access right
after a write operation to SOC_GLOBAL_RESET_ADDRESS causes
Data Bus Error and system hard lockup. The reason
for bus error is that pcie needs some time to get
back to stable state for any transaction during cold reset. Add
delay of 20 msecs after write of SOC_GLOBAL_RESET_ADDRESS
to fix this issue. This patch is tested on QCA988X. This is
also tested on QCA99X0 which is WIP.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---

V2:
- Include tested hw in commit log.

 drivers/net/wireless/ath/ath10k/pci.c | 20 +++-
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 1b4634a..130746b 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -2761,7 +2761,6 @@ static int ath10k_pci_wait_for_target_init(struct ath10k 
*ar)
 
 static int ath10k_pci_cold_reset(struct ath10k *ar)
 {
-   int i;
u32 val;
 
ath10k_dbg(ar, ATH10K_DBG_BOOT, boot cold reset\n);
@@ -2777,23 +2776,18 @@ static int ath10k_pci_cold_reset(struct ath10k *ar)
val |= 1;
ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
 
-   for (i = 0; i  ATH_PCI_RESET_WAIT_MAX; i++) {
-   if (ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) 
- RTC_STATE_COLD_RESET_MASK)
-   break;
-   msleep(1);
-   }
+   /* After writing into SOC_GLOBAL_RESET to put device into
+* reset and pulling out of reset pcie may not be stable
+* for any immediate pcie register access and cause bus error,
+* add delay before any pcie access request to fix this issue.
+*/
+   msleep(20);
 
/* Pull Target, including PCIe, out of RESET. */
val = ~1;
ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
 
-   for (i = 0; i  ATH_PCI_RESET_WAIT_MAX; i++) {
-   if (!(ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) 
-   RTC_STATE_COLD_RESET_MASK))
-   break;
-   msleep(1);
-   }
+   msleep(20);
 
ath10k_dbg(ar, ATH10K_DBG_BOOT, boot cold reset complete\n);
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ath10k: Fix target to cpu address conversion logic

2015-07-03 Thread Vasanthakumar Thiagarajan
'commit 418ca5992e2f (ath10k: Make target cpu address to
CE address conversion chip specific)' mask 0x7fff is added
by mistake instead of 0x7ff. Fix this regression.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 130746b..a69bfa4 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -765,7 +765,7 @@ static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k 
*ar, u32 addr)
case ATH10K_HW_QCA6174:
val = (ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
  CORE_CTRL_ADDRESS) 
-  0x7fff)  21;
+  0x7ff)  21;
break;
case ATH10K_HW_QCA99X0:
val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS);
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ath10k: Delay device access after cold reset

2015-07-03 Thread Vasanthakumar Thiagarajan
It is observed that during cold reset pcie access right
after a write operation to SOC_GLOBAL_RESET_ADDRESS causes
Data Bus Error and system hard lockup. The reason
for bus error is that pcie needs some time to get
back to stable state for any transaction during cold reset. Add
delay of 20 msecs after write of SOC_GLOBAL_RESET_ADDRESS
to fix this issue.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/pci.c | 20 +++-
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 1b4634a..130746b 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -2761,7 +2761,6 @@ static int ath10k_pci_wait_for_target_init(struct ath10k 
*ar)
 
 static int ath10k_pci_cold_reset(struct ath10k *ar)
 {
-   int i;
u32 val;
 
ath10k_dbg(ar, ATH10K_DBG_BOOT, boot cold reset\n);
@@ -2777,23 +2776,18 @@ static int ath10k_pci_cold_reset(struct ath10k *ar)
val |= 1;
ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
 
-   for (i = 0; i  ATH_PCI_RESET_WAIT_MAX; i++) {
-   if (ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) 
- RTC_STATE_COLD_RESET_MASK)
-   break;
-   msleep(1);
-   }
+   /* After writing into SOC_GLOBAL_RESET to put device into
+* reset and pulling out of reset pcie may not be stable
+* for any immediate pcie register access and cause bus error,
+* add delay before any pcie access request to fix this issue.
+*/
+   msleep(20);
 
/* Pull Target, including PCIe, out of RESET. */
val = ~1;
ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
 
-   for (i = 0; i  ATH_PCI_RESET_WAIT_MAX; i++) {
-   if (!(ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) 
-   RTC_STATE_COLD_RESET_MASK))
-   break;
-   msleep(1);
-   }
+   msleep(20);
 
ath10k_dbg(ar, ATH10K_DBG_BOOT, boot cold reset complete\n);
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V2 09/10] ath10k: Add support for code swap

2015-06-29 Thread Vasanthakumar Thiagarajan

On Monday 29 June 2015 04:51 PM, Kalle Valo wrote:

Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com writes:


Code swap is a mechanism to use host memory to store
some fw binary code segment. Ath10k host driver allocates
and loads the code swap binary into the host memory and
configures the target with the host allocated memory
information at the address taken from code swap binary.
This patch adds code swap support for firmware binary.
Code swap binary for firmware bin is available in
ATH10K_FW_IE_FW_CODE_SWAP_IMAGE.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com


[...]


+static struct ath10k_swap_code_seg_info *
+ath10k_swap_code_seg_alloc(struct ath10k *ar, size_t swap_bin_len)
+{
+   struct ath10k_swap_code_seg_info *seg_info;
+   void *virt_addr;
+   dma_addr_t paddr;
+
+   swap_bin_len = roundup(swap_bin_len, 2);
+   if (swap_bin_len  ATH10K_SWAP_CODE_SEG_BIN_LEN_MAX) {
+   ath10k_err(ar, refusing code swap bin because it is too big %zd  
%d\n,
+  swap_bin_len, ATH10K_SWAP_CODE_SEG_BIN_LEN_MAX);


kbuild found a bug here, I fixed it with the patch below. Please review:

--- a/drivers/net/wireless/ath/ath10k/swap.c
+++ b/drivers/net/wireless/ath/ath10k/swap.c
@@ -106,7 +106,7 @@ ath10k_swap_code_seg_alloc(struct ath10k *ar, size_t 
swap_bin_len)

 swap_bin_len = roundup(swap_bin_len, 2);
 if (swap_bin_len  ATH10K_SWAP_CODE_SEG_BIN_LEN_MAX) {
-   ath10k_err(ar, refusing code swap bin because it is too big %zd  
%d\n,
+   ath10k_err(ar, refusing code swap bin because it is too big %zu  
%d\n,
swap_bin_len, ATH10K_SWAP_CODE_SEG_BIN_LEN_MAX);
 return NULL;
 }


Looks good. Thanks.


Vasanth

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 01/10] ath10k: Add a table to store hw specific values

2015-06-18 Thread Vasanthakumar Thiagarajan
This is to prepare ath10k to support newer chip set.
Values like CE_COUNT, MSI_ASSIGN_CE_MAX and
RTC_STATE_V_ON can be different for different
chips.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/core.c |  2 ++
 drivers/net/wireless/ath/ath10k/core.h |  1 +
 drivers/net/wireless/ath/ath10k/hw.c   | 14 ++
 drivers/net/wireless/ath/ath10k/hw.h   | 18 +++---
 4 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index f5db432..b17541b 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1514,9 +1514,11 @@ struct ath10k *ath10k_core_create(size_t priv_size, 
struct device *dev,
switch (hw_rev) {
case ATH10K_HW_QCA988X:
ar-regs = qca988x_regs;
+   ar-hw_values = qca988x_values;
break;
case ATH10K_HW_QCA6174:
ar-regs = qca6174_regs;
+   ar-hw_values = qca6174_values;
break;
default:
ath10k_err(ar, unsupported core hardware revision %d\n,
diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index e9f9304..993cd36 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -560,6 +560,7 @@ struct ath10k {
struct completion target_suspend;
 
const struct ath10k_hw_regs *regs;
+   const struct ath10k_hw_values *hw_values;
struct ath10k_bmi bmi;
struct ath10k_wmi wmi;
struct ath10k_htc htc;
diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c
index 5997f00..48bcd2c 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -58,6 +58,20 @@ const struct ath10k_hw_regs qca6174_regs = {
.scratch_3_address  = 0x0028,
 };
 
+const struct ath10k_hw_values qca988x_values = {
+   .rtc_state_val_on   = 3,
+   .ce_count   = 8,
+   .msi_assign_ce_max  = 7,
+   .num_target_ce_config_wlan  = 7,
+};
+
+const struct ath10k_hw_values qca6174_values = {
+   .rtc_state_val_on   = 3,
+   .ce_count   = 8,
+   .msi_assign_ce_max  = 7,
+   .num_target_ce_config_wlan  = 7,
+};
+
 void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
 {
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 85cca29..b218388 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -169,6 +169,16 @@ struct ath10k_hw_regs {
 extern const struct ath10k_hw_regs qca988x_regs;
 extern const struct ath10k_hw_regs qca6174_regs;
 
+struct ath10k_hw_values {
+   u32 rtc_state_val_on;
+   u8 ce_count;
+   u8 msi_assign_ce_max;
+   u8 num_target_ce_config_wlan;
+};
+
+extern const struct ath10k_hw_values qca988x_values;
+extern const struct ath10k_hw_values qca6174_values;
+
 void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev);
 
@@ -310,8 +320,10 @@ enum ath10k_hw_rate_cck {
 #define TARGET_TLV_NUM_MSDU_DESC   (1024 + 32)
 #define TARGET_TLV_NUM_WOW_PATTERNS22
 
+#define NUM_TARGET_CE_CONFIG_WLAN ar-hw_values-num_target_ce_config_wlan
+
 /* Number of Copy Engines supported */
-#define CE_COUNT 8
+#define CE_COUNT ar-hw_values-ce_count
 
 /*
  * Total number of PCIe MSI interrupts requested for all interrupt sources.
@@ -335,10 +347,10 @@ enum ath10k_hw_rate_cck {
 
 /* MSIs for Copy Engines */
 #define MSI_ASSIGN_CE_INITIAL  1
-#define MSI_ASSIGN_CE_MAX  7
+#define MSI_ASSIGN_CE_MAX  ar-hw_values-msi_assign_ce_max
 
 /* as of IP3.7.1 */
-#define RTC_STATE_V_ON 3
+#define RTC_STATE_V_ON ar-hw_values-rtc_state_val_on
 
 #define RTC_STATE_COLD_RESET_MASK  
ar-regs-rtc_state_cold_reset_mask
 #define RTC_STATE_V_LSB0
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 02/10] ath10k: Add new reg_address/mask to hw register table

2015-06-18 Thread Vasanthakumar Thiagarajan
Add more register address and mask which can be different
for newer chip to hw_reg table.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/ce.h |  6 --
 drivers/net/wireless/ath/ath10k/hw.c | 22 ++
 drivers/net/wireless/ath/ath10k/hw.h | 17 -
 3 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.h 
b/drivers/net/wireless/ath/ath10k/ce.h
index 0eddb20..93939de 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -423,8 +423,10 @@ static inline u32 ath10k_ce_base_address(struct ath10k 
*ar, unsigned int ce_id)
 
 #define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1)  (nentries_mask))
 
-#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB  8
-#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK 0xff00
+#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB \
+   ar-regs-ce_wrap_intr_sum_host_msi_lsb
+#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK \
+   ar-regs-ce_wrap_intr_sum_host_msi_mask
 #define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(x) \
(((x)  CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK)  \
CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB)
diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c
index 48bcd2c..cb09867 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -34,8 +34,15 @@ const struct ath10k_hw_regs qca988x_regs = {
.ce7_base_address   = 0x00059000,
.soc_reset_control_si0_rst_mask = 0x0001,
.soc_reset_control_ce_rst_mask  = 0x0004,
-   .soc_chip_id_address= 0x00ec,
-   .scratch_3_address  = 0x0030,
+   .soc_chip_id_address= 0x00ec,
+   .scratch_3_address  = 0x0030,
+   .fw_indicator_address   = 0x9030,
+   .pcie_local_base_address= 0x0008,
+   .ce_wrap_intr_sum_host_msi_lsb  = 0x0008,
+   .ce_wrap_intr_sum_host_msi_mask = 0xff00,
+   .pcie_intr_fw_mask  = 0x0400,
+   .pcie_intr_ce_mask_all  = 0x0007f800,
+   .pcie_intr_clr_address  = 0x0014,
 };
 
 const struct ath10k_hw_regs qca6174_regs = {
@@ -54,8 +61,15 @@ const struct ath10k_hw_regs qca6174_regs = {
.ce7_base_address   = 0x00036000,
.soc_reset_control_si0_rst_mask = 0x,
.soc_reset_control_ce_rst_mask  = 0x0001,
-   .soc_chip_id_address= 0x000f0,
-   .scratch_3_address  = 0x0028,
+   .soc_chip_id_address= 0x00f0,
+   .scratch_3_address  = 0x0028,
+   .fw_indicator_address   = 0x9028,
+   .pcie_local_base_address= 0x0008,
+   .ce_wrap_intr_sum_host_msi_lsb  = 0x0008,
+   .ce_wrap_intr_sum_host_msi_mask = 0xff00,
+   .pcie_intr_fw_mask  = 0x0400,
+   .pcie_intr_ce_mask_all  = 0x0007f800,
+   .pcie_intr_clr_address  = 0x0014,
 };
 
 const struct ath10k_hw_values qca988x_values = {
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index b218388..5d04317 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -164,6 +164,13 @@ struct ath10k_hw_regs {
u32 soc_reset_control_ce_rst_mask;
u32 soc_chip_id_address;
u32 scratch_3_address;
+   u32 fw_indicator_address;
+   u32 pcie_local_base_address;
+   u32 ce_wrap_intr_sum_host_msi_lsb;
+   u32 ce_wrap_intr_sum_host_msi_mask;
+   u32 pcie_intr_fw_mask;
+   u32 pcie_intr_ce_mask_all;
+   u32 pcie_intr_clr_address;
 };
 
 extern const struct ath10k_hw_regs qca988x_regs;
@@ -386,7 +393,7 @@ enum ath10k_hw_rate_cck {
 #define CE7_BASE_ADDRESS   ar-regs-ce7_base_address
 #define DBI_BASE_ADDRESS   0x0006
 #define WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x0006c000
-#define PCIE_LOCAL_BASE_ADDRESS0x0008
+#define PCIE_LOCAL_BASE_ADDRESS
ar-regs-pcie_local_base_address
 
 #define SOC_RESET_CONTROL_ADDRESS  0x
 #define SOC_RESET_CONTROL_OFFSET   0x
@@ -460,7 +467,7 @@ enum ath10k_hw_rate_cck {
 #define CORE_CTRL_ADDRESS  0x
 #define PCIE_INTR_ENABLE_ADDRESS   0x0008
 #define PCIE_INTR_CAUSE_ADDRESS0x000c
-#define PCIE_INTR_CLR_ADDRESS  0x0014
+#define PCIE_INTR_CLR_ADDRESS  ar-regs-pcie_intr_clr_address
 #define SCRATCH_3_ADDRESS  ar-regs

[PATCH V2 06/10] ath10k: Add chip reset sequence for QCA99X0

2015-06-18 Thread Vasanthakumar Thiagarajan
QCA99X0 supports only cold reset. Also, made
ath10k_pci_irq_msi_fw_mask() and ath10k_pci_irq_msi_fw_unmask()
non-99X0 specific till we get proper register configuration
to mask/unmask irq/MSI.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/pci.c | 81 ++-
 1 file changed, 71 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index df7d74e..1b4634a 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -82,7 +82,7 @@ static const struct ath10k_pci_supp_chip 
ath10k_pci_supp_chips[] = {
 
 static void ath10k_pci_buffer_cleanup(struct ath10k *ar);
 static int ath10k_pci_cold_reset(struct ath10k *ar);
-static int ath10k_pci_warm_reset(struct ath10k *ar);
+static int ath10k_pci_safe_chip_reset(struct ath10k *ar);
 static int ath10k_pci_wait_for_target_init(struct ath10k *ar);
 static int ath10k_pci_init_irq(struct ath10k *ar);
 static int ath10k_pci_deinit_irq(struct ath10k *ar);
@@ -91,6 +91,7 @@ static void ath10k_pci_free_irq(struct ath10k *ar);
 static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
   struct ath10k_ce_pipe *rx_pipe,
   struct bmi_xfer *xfer);
+static int ath10k_pci_qca99x0_chip_reset(struct ath10k *ar);
 
 static const struct ce_attr host_ce_config_wlan[] = {
/* CE0: host-target HTC control and raw streams */
@@ -1427,20 +1428,42 @@ static void ath10k_pci_irq_msi_fw_mask(struct ath10k 
*ar)
 {
u32 val;
 
-   val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS);
-   val = ~CORE_CTRL_PCIE_REG_31_MASK;
-
-   ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS, val);
+   switch (ar-hw_rev) {
+   case ATH10K_HW_QCA988X:
+   case ATH10K_HW_QCA6174:
+   val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
+   CORE_CTRL_ADDRESS);
+   val = ~CORE_CTRL_PCIE_REG_31_MASK;
+   ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS +
+  CORE_CTRL_ADDRESS, val);
+   break;
+   case ATH10K_HW_QCA99X0:
+   /* TODO: Find appropriate register configuration for QCA99X0
+*  to mask irq/MSI.
+*/
+break;
+   }
 }
 
 static void ath10k_pci_irq_msi_fw_unmask(struct ath10k *ar)
 {
u32 val;
 
-   val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS);
-   val |= CORE_CTRL_PCIE_REG_31_MASK;
-
-   ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS, val);
+   switch (ar-hw_rev) {
+   case ATH10K_HW_QCA988X:
+   case ATH10K_HW_QCA6174:
+   val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
+   CORE_CTRL_ADDRESS);
+   val |= CORE_CTRL_PCIE_REG_31_MASK;
+   ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS +
+  CORE_CTRL_ADDRESS, val);
+   break;
+   case ATH10K_HW_QCA99X0:
+   /* TODO: Find appropriate register configuration for QCA99X0
+*  to unmask irq/MSI.
+*/
+   break;
+   }
 }
 
 static void ath10k_pci_irq_disable(struct ath10k *ar)
@@ -1602,7 +1625,7 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
 * masked. To prevent the device from asserting the interrupt reset it
 * before proceeding with cleanup.
 */
-   ath10k_pci_warm_reset(ar);
+   ath10k_pci_safe_chip_reset(ar);
 
ath10k_pci_irq_disable(ar);
ath10k_pci_irq_sync(ar);
@@ -2114,6 +2137,18 @@ static int ath10k_pci_warm_reset(struct ath10k *ar)
return 0;
 }
 
+static int ath10k_pci_safe_chip_reset(struct ath10k *ar)
+{
+   if (QCA_REV_988X(ar) || QCA_REV_6174(ar)) {
+   return ath10k_pci_warm_reset(ar);
+   } else if (QCA_REV_99X0(ar)) {
+   ath10k_pci_irq_disable(ar);
+   return ath10k_pci_qca99x0_chip_reset(ar);
+   } else {
+   return -ENOTSUPP;
+   }
+}
+
 static int ath10k_pci_qca988x_chip_reset(struct ath10k *ar)
 {
int i, ret;
@@ -2220,12 +2255,38 @@ static int ath10k_pci_qca6174_chip_reset(struct ath10k 
*ar)
return 0;
 }
 
+static int ath10k_pci_qca99x0_chip_reset(struct ath10k *ar)
+{
+   int ret;
+
+   ath10k_dbg(ar, ATH10K_DBG_BOOT, boot qca99x0 chip reset\n);
+
+   ret = ath10k_pci_cold_reset(ar);
+   if (ret) {
+   ath10k_warn(ar, failed to cold reset: %d\n, ret);
+   return ret;
+   }
+
+   ret = ath10k_pci_wait_for_target_init(ar);
+   if (ret) {
+   ath10k_warn(ar, failed to wait for target after cold reset: 
%d\n,
+   ret);
+   return ret

Re: [PATCH 00/10] Add QCA99X0 support

2015-06-18 Thread Vasanthakumar Thiagarajan
On Thu, Jun 18, 2015 at 09:20:51AM +0300, Kalle Valo wrote:
 Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com writes:
 
  This patch set adds changes for QCA99X0 chip in pci probe,
  Copy Engine init and firmware downloads. Since it is still
  work in progress the support for this chip is not yet
  advertised in pci device table.
 
  Vasanthakumar Thiagarajan (10):
ath10k: Add a table to store hw specific values
ath10k: Add new reg_address/mask to hw register table
ath10k: Add hw register/values for QCA99X0 chip
ath10k: Copy Engine related changes for QCA99X0
ath10k: Make target cpu address to CE address conversion chip specific
ath10k: Add chip reset sequence for QCA99X0
ath10k: Extend CE src desc flags for interrupt indication
ath10k: Fix BMI communication timeout for QCA99X0
ath10k: Add support for code swap
ath10k: Add BMI param value to execute otp to hw_param
 
 These patches don't apply and don't have proper sha1 ids. Please rebase.
 And remember always to use ath.git master branch as the baseline, don't
 apply any custom patches because that will break 3-way merge.
 
 Applying: ath10k: Add a table to store hw specific values
 Applying: ath10k: Add new reg_address/mask to hw register table
 Applying: ath10k: Add hw register/values for QCA99X0 chip
 fatal: sha1 information is lacking or useless 
 (drivers/net/wireless/ath/ath10k/core.c).
 Repository lacks necessary blobs to fall back on 3-way merge.
 Cannot fall back to three-way merge.
 Patch failed at 0003 ath10k: Add hw register/values for QCA99X0 chip

Sorry about this. Im sending the rebased patches on top of ath.git master tot

Vasanth
--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 05/10] ath10k: Make target cpu address to CE address conversion chip specific

2015-06-18 Thread Vasanthakumar Thiagarajan
Make the helper converting target virtual address space to CE address
space a target type specific to support QCA99X0. Also make this as
function instead of macro.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/pci.c | 25 ++---
 drivers/net/wireless/ath/ath10k/pci.h | 12 
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index c2aecfe..df7d74e 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -755,6 +755,26 @@ static void ath10k_pci_rx_replenish_retry(unsigned long 
ptr)
ath10k_pci_rx_post(ar);
 }
 
+static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr)
+{
+   u32 val = 0;
+
+   switch (ar-hw_rev) {
+   case ATH10K_HW_QCA988X:
+   case ATH10K_HW_QCA6174:
+   val = (ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
+ CORE_CTRL_ADDRESS) 
+  0x7fff)  21;
+   break;
+   case ATH10K_HW_QCA99X0:
+   val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS);
+   break;
+   }
+
+   val |= 0x10 | (addr  0xf);
+   return val;
+}
+
 /*
  * Diagnostic read/write access is provided for startup/config/debug usage.
  * Caller must guarantee proper alignment, when applicable, and single user
@@ -817,8 +837,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 
address, void *data,
 * convert it from Target CPU virtual address space
 * to CE address space
 */
-   address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci-mem,
-address);
+   address = ath10k_pci_targ_cpu_to_ce_addr(ar, address);
 
ret = ath10k_ce_send_nolock(ce_diag, NULL, (u32)address, 
nbytes, 0,
0);
@@ -976,7 +995,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 
address,
 * to
 *CE address space
 */
-   address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci-mem, address);
+   address = ath10k_pci_targ_cpu_to_ce_addr(ar, address);
 
remaining_bytes = orig_nbytes;
ce_data = ce_data_base;
diff --git a/drivers/net/wireless/ath/ath10k/pci.h 
b/drivers/net/wireless/ath/ath10k/pci.h
index eea0a01..8d364fb 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -237,18 +237,6 @@ static inline struct ath10k_pci *ath10k_pci_priv(struct 
ath10k *ar)
 #define CDC_WAR_MAGIC_STR   0xceef
 #define CDC_WAR_DATA_CE 4
 
-/*
- * TODO: Should be a function call specific to each Target-type.
- * This convoluted macro converts from Target CPU Virtual Address Space to CE
- * Address Space. As part of this process, we conservatively fetch the current
- * PCIE_BAR. MOST of the time, this should match the upper bits of PCI space
- * for this device; but that's not guaranteed.
- */
-#define TARG_CPU_SPACE_TO_CE_SPACE(ar, pci_addr, addr) \
-   (((ath10k_pci_read32(ar, (SOC_CORE_BASE_ADDRESS |   \
- CORE_CTRL_ADDRESS))  0x7ff)  21) | \
-0x10 | ((addr)  0xf))
-
 /* Wait up to this many Ms for a Diagnostic Access CE operation to complete */
 #define DIAG_ACCESS_CE_TIMEOUT_MS 10
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 03/10] ath10k: Add hw register/values for QCA99X0 chip

2015-06-18 Thread Vasanthakumar Thiagarajan
This is to prepare the driver for QCA99X0 chip support.
This commit adds hw_params, hw register table and hw_values
table for QCA99X0 chip. Please note this is only a partial patch adding
support for QCA99X0, so the device id is not yet added to pci device
table.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/core.c  | 18 
 drivers/net/wireless/ath/ath10k/hw.c| 44 +
 drivers/net/wireless/ath/ath10k/hw.h| 18 
 drivers/net/wireless/ath/ath10k/pci.c   |  5 
 drivers/net/wireless/ath/ath10k/targaddrs.h |  3 ++
 5 files changed, 88 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index b17541b..f239e96 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -101,6 +101,20 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
},
},
+   {
+   .id = QCA99X0_HW_2_0_DEV_VERSION,
+   .name = qca99x0 hw2.0,
+   .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
+   .uart_pin = 7,
+   .fw = {
+   .dir = QCA99X0_HW_2_0_FW_DIR,
+   .fw = QCA99X0_HW_2_0_FW_FILE,
+   .otp = QCA99X0_HW_2_0_OTP_FILE,
+   .board = QCA99X0_HW_2_0_BOARD_DATA_FILE,
+   .board_size = QCA99X0_BOARD_DATA_SZ,
+   .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
+   },
+   },
 };
 
 static const char *const ath10k_core_fw_feature_str[] = {
@@ -1520,6 +1534,10 @@ struct ath10k *ath10k_core_create(size_t priv_size, 
struct device *dev,
ar-regs = qca6174_regs;
ar-hw_values = qca6174_values;
break;
+   case ATH10K_HW_QCA99X0:
+   ar-regs = qca99x0_regs;
+   ar-hw_values = qca99x0_values;
+   break;
default:
ath10k_err(ar, unsupported core hardware revision %d\n,
   hw_rev);
diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c
index cb09867..e5fe33d9 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -72,6 +72,43 @@ const struct ath10k_hw_regs qca6174_regs = {
.pcie_intr_clr_address  = 0x0014,
 };
 
+const struct ath10k_hw_regs qca99x0_regs = {
+   .rtc_state_cold_reset_mask  = 0x0400,
+   .rtc_soc_base_address   = 0x0008,
+   .rtc_wmac_base_address  = 0x,
+   .soc_core_base_address  = 0x00082000,
+   .ce_wrapper_base_address= 0x0004d000,
+   .ce0_base_address   = 0x0004a000,
+   .ce1_base_address   = 0x0004a400,
+   .ce2_base_address   = 0x0004a800,
+   .ce3_base_address   = 0x0004ac00,
+   .ce4_base_address   = 0x0004b000,
+   .ce5_base_address   = 0x0004b400,
+   .ce6_base_address   = 0x0004b800,
+   .ce7_base_address   = 0x0004bc00,
+   /* Note: qca99x0 supports upto 12 Copy Engines. Other than address of
+* CE0 and CE1 no other copy engine is directly referred in the code.
+* It is not really neccessary to assign address for newly supported
+* CEs in this address table.
+*  Copy Engine Address
+*  CE8 0x0004c000
+*  CE9 0x0004c400
+*  CE100x0004c800
+*  CE110x0004cc00
+*/
+   .soc_reset_control_si0_rst_mask = 0x0001,
+   .soc_reset_control_ce_rst_mask  = 0x0100,
+   .soc_chip_id_address= 0x00ec,
+   .scratch_3_address  = 0x00040050,
+   .fw_indicator_address   = 0x00040050,
+   .pcie_local_base_address= 0x,
+   .ce_wrap_intr_sum_host_msi_lsb  = 0x000c,
+   .ce_wrap_intr_sum_host_msi_mask = 0x00fff000,
+   .pcie_intr_fw_mask  = 0x0010,
+   .pcie_intr_ce_mask_all  = 0x000fff00,
+   .pcie_intr_clr_address  = 0x0010,
+};
+
 const struct ath10k_hw_values qca988x_values = {
.rtc_state_val_on   = 3,
.ce_count   = 8,
@@ -86,6 +123,13 @@ const struct ath10k_hw_values qca6174_values = {
.num_target_ce_config_wlan  = 7,
 };
 
+const struct ath10k_hw_values qca99x0_values = {
+   .rtc_state_val_on

[PATCH V2 04/10] ath10k: Copy Engine related changes for QCA99X0

2015-06-18 Thread Vasanthakumar Thiagarajan
QCA99X0 supports upto 12 Copy engines. Host and target
CE configuration table is updated to support new copy engine
pipes. This also fixes the assumption of diagnostic CE by making
CE_7 as the one instead of CE_COUNT - 1.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/ce.h  |  2 +-
 drivers/net/wireless/ath/ath10k/hw.h  |  3 ++
 drivers/net/wireless/ath/ath10k/pci.c | 69 ++-
 3 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.h 
b/drivers/net/wireless/ath/ath10k/ce.h
index 93939de..bb4b8f3 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -21,7 +21,7 @@
 #include hif.h
 
 /* Maximum number of Copy Engine's supported */
-#define CE_COUNT_MAX 8
+#define CE_COUNT_MAX 12
 #define CE_HTT_H2T_MSG_SRC_NENTRIES 4096
 
 /* Descriptor rings must be aligned to this boundary */
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 76caeab..5819659 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -343,6 +343,9 @@ enum ath10k_hw_rate_cck {
 #define TARGET_TLV_NUM_MSDU_DESC   (1024 + 32)
 #define TARGET_TLV_NUM_WOW_PATTERNS22
 
+/* Diagnostic Window */
+#define CE_DIAG_PIPE   7
+
 #define NUM_TARGET_CE_CONFIG_WLAN ar-hw_values-num_target_ce_config_wlan
 
 /* Number of Copy Engines supported */
diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 0007e70..c2aecfe 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -156,6 +156,38 @@ static const struct ce_attr host_ce_config_wlan[] = {
.src_sz_max = DIAG_TRANSFER_LIMIT,
.dest_nentries = 2,
},
+
+   /* CE8: target-host pktlog */
+   {
+   .flags = CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 2048,
+   .dest_nentries = 128,
+   },
+
+   /* CE9 target autonomous qcache memcpy */
+   {
+   .flags = CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 0,
+   .dest_nentries = 0,
+   },
+
+   /* CE10: target autonomous hif memcpy */
+   {
+   .flags = CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 0,
+   .dest_nentries = 0,
+   },
+
+   /* CE11: target autonomous hif memcpy */
+   {
+   .flags = CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 0,
+   .dest_nentries = 0,
+   },
 };
 
 /* Target firmware's Copy Engine configuration. */
@@ -233,6 +265,38 @@ static const struct ce_pipe_config target_ce_config_wlan[] 
= {
},
 
/* CE7 used only by Host */
+   {
+   .pipenum = __cpu_to_le32(7),
+   .pipedir = __cpu_to_le32(PIPEDIR_INOUT),
+   .nentries = __cpu_to_le32(0),
+   .nbytes_max = __cpu_to_le32(0),
+   .flags = __cpu_to_le32(0),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* CE8 target-host packtlog */
+   {
+   .pipenum = __cpu_to_le32(8),
+   .pipedir = __cpu_to_le32(PIPEDIR_IN),
+   .nentries = __cpu_to_le32(64),
+   .nbytes_max = __cpu_to_le32(2048),
+   .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* CE9 target autonomous qcache memcpy */
+   {
+   .pipenum = __cpu_to_le32(9),
+   .pipedir = __cpu_to_le32(PIPEDIR_INOUT),
+   .nentries = __cpu_to_le32(32),
+   .nbytes_max = __cpu_to_le32(2048),
+   .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* It not necessary to send target wlan configuration for CE10  CE11
+* as these CEs are not actively used in target.
+*/
 };
 
 /*
@@ -1771,7 +1835,8 @@ static int ath10k_pci_init_config(struct ath10k *ar)
 
ret = ath10k_pci_diag_write_mem(ar, pipe_cfg_targ_addr,
target_ce_config_wlan,
-   sizeof(target_ce_config_wlan));
+   sizeof(struct ce_pipe_config) *
+   NUM_TARGET_CE_CONFIG_WLAN);
 
if (ret != 0) {
ath10k_err(ar, Failed to write pipe cfg: %d\n, ret);
@@ -1885,7 +1950,7 @@ static int ath10k_pci_alloc_pipes(struct ath10k *ar)
}
 
/* Last CE is Diagnostic Window */
-   if (i == CE_COUNT - 1) {
+   if (i == CE_DIAG_PIPE) {
ar_pci-ce_diag = pipe-ce_hdl;
continue

[PATCH V2 07/10] ath10k: Extend CE src desc flags for interrupt indication

2015-06-18 Thread Vasanthakumar Thiagarajan
QCA99X0 uses two new copy engine src desc flags for interrupt
indication. Bit_2 is to mark if host interrupt is disabled after
processing the current desc and bit_3 is to mark if target interrupt
is diabled after the processing of current descriptor.
CE_DESC_FLAGS_META_DATA_MASK and CE_DESC_FLAGS_META_DATA_LSB are based
on the target type.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/ce.c | 1 +
 drivers/net/wireless/ath/ath10k/ce.h | 9 +++--
 drivers/net/wireless/ath/ath10k/hw.c | 6 ++
 drivers/net/wireless/ath/ath10k/hw.h | 2 ++
 4 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.c 
b/drivers/net/wireless/ath/ath10k/ce.c
index e508c65..cf28fbe 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -452,6 +452,7 @@ int ath10k_ce_completed_recv_next_nolock(struct 
ath10k_ce_pipe *ce_state,
 {
struct ath10k_ce_ring *dest_ring = ce_state-dest_ring;
unsigned int nentries_mask = dest_ring-nentries_mask;
+   struct ath10k *ar = ce_state-ar;
unsigned int sw_index = dest_ring-sw_index;
 
struct ce_desc *base = dest_ring-base_addr_owner_space;
diff --git a/drivers/net/wireless/ath/ath10k/ce.h 
b/drivers/net/wireless/ath/ath10k/ce.h
index bb4b8f3..5c903e15 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -38,8 +38,13 @@ struct ath10k_ce_pipe;
 
 #define CE_DESC_FLAGS_GATHER (1  0)
 #define CE_DESC_FLAGS_BYTE_SWAP  (1  1)
-#define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC
-#define CE_DESC_FLAGS_META_DATA_LSB  2
+
+/* Following desc flags are used in QCA99X0 */
+#define CE_DESC_FLAGS_HOST_INT_DIS (1  2)
+#define CE_DESC_FLAGS_TGT_INT_DIS  (1  3)
+
+#define CE_DESC_FLAGS_META_DATA_MASK ar-hw_values-ce_desc_meta_data_mask
+#define CE_DESC_FLAGS_META_DATA_LSB  ar-hw_values-ce_desc_meta_data_lsb
 
 struct ce_desc {
__le32 addr;
diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c
index e5fe33d9..1414e1f 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -114,6 +114,8 @@ const struct ath10k_hw_values qca988x_values = {
.ce_count   = 8,
.msi_assign_ce_max  = 7,
.num_target_ce_config_wlan  = 7,
+   .ce_desc_meta_data_mask = 0xFFFC,
+   .ce_desc_meta_data_lsb  = 2,
 };
 
 const struct ath10k_hw_values qca6174_values = {
@@ -121,6 +123,8 @@ const struct ath10k_hw_values qca6174_values = {
.ce_count   = 8,
.msi_assign_ce_max  = 7,
.num_target_ce_config_wlan  = 7,
+   .ce_desc_meta_data_mask = 0xFFFC,
+   .ce_desc_meta_data_lsb  = 2,
 };
 
 const struct ath10k_hw_values qca99x0_values = {
@@ -128,6 +132,8 @@ const struct ath10k_hw_values qca99x0_values = {
.ce_count   = 12,
.msi_assign_ce_max  = 12,
.num_target_ce_config_wlan  = 10,
+   .ce_desc_meta_data_mask = 0xFFF0,
+   .ce_desc_meta_data_lsb  = 4,
 };
 
 void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 5819659..35cd8ca 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -195,6 +195,8 @@ struct ath10k_hw_values {
u8 ce_count;
u8 msi_assign_ce_max;
u8 num_target_ce_config_wlan;
+   u16 ce_desc_meta_data_mask;
+   u8 ce_desc_meta_data_lsb;
 };
 
 extern const struct ath10k_hw_values qca988x_values;
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 09/10] ath10k: Add support for code swap

2015-06-18 Thread Vasanthakumar Thiagarajan
Code swap is a mechanism to use host memory to store
some fw binary code segment. Ath10k host driver allocates
and loads the code swap binary into the host memory and
configures the target with the host allocated memory
information at the address taken from code swap binary.
This patch adds code swap support for firmware binary.
Code swap binary for firmware bin is available in
ATH10K_FW_IE_FW_CODE_SWAP_IMAGE.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/Makefile |   3 +-
 drivers/net/wireless/ath/ath10k/core.c   |  24 
 drivers/net/wireless/ath/ath10k/core.h   |   7 ++
 drivers/net/wireless/ath/ath10k/hw.h |   3 +
 drivers/net/wireless/ath/ath10k/swap.c   | 208 +++
 drivers/net/wireless/ath/ath10k/swap.h   |  72 +++
 6 files changed, 316 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/wireless/ath/ath10k/swap.c
 create mode 100644 drivers/net/wireless/ath/ath10k/swap.h

diff --git a/drivers/net/wireless/ath/ath10k/Makefile 
b/drivers/net/wireless/ath/ath10k/Makefile
index 9729e69..c04fb00 100644
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -11,7 +11,8 @@ ath10k_core-y += mac.o \
 wmi-tlv.o \
 bmi.o \
 hw.o \
-p2p.o
+p2p.o \
+swap.o
 
 ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o
 ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index f239e96..c5f5d16 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -470,6 +470,13 @@ static int ath10k_download_fw(struct ath10k *ar, enum 
ath10k_firmware_mode mode)
data = ar-firmware_data;
data_len = ar-firmware_len;
mode_name = normal;
+   ret = ath10k_swap_code_seg_configure(ar,
+   ATH10K_SWAP_CODE_SEG_BIN_TYPE_FW);
+   if (ret) {
+   ath10k_err(ar, failed to configure fw code swap: %d\n,
+  ret);
+   return ret;
+   }
break;
case ATH10K_FIRMWARE_MODE_UTF:
data = ar-testmode.utf-data;
@@ -509,6 +516,8 @@ static void ath10k_core_free_firmware_files(struct ath10k 
*ar)
if (!IS_ERR(ar-cal_file))
release_firmware(ar-cal_file);
 
+   ath10k_swap_code_seg_release(ar);
+
ar-board = NULL;
ar-board_data = NULL;
ar-board_len = 0;
@@ -522,6 +531,7 @@ static void ath10k_core_free_firmware_files(struct ath10k 
*ar)
ar-firmware_len = 0;
 
ar-cal_file = NULL;
+
 }
 
 static int ath10k_fetch_cal_file(struct ath10k *ar)
@@ -795,6 +805,13 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k 
*ar, const char *name)
ath10k_dbg(ar, ATH10K_DBG_BOOT, found fw ie htt op 
version %d\n,
   ar-htt.op_version);
break;
+   case ATH10K_FW_IE_FW_CODE_SWAP_IMAGE:
+   ath10k_dbg(ar, ATH10K_DBG_BOOT,
+  found fw code swap image ie (%zd B)\n,
+  ie_len);
+   ar-swap.firmware_codeswap_data = data;
+   ar-swap.firmware_codeswap_len = ie_len;
+   break;
default:
ath10k_warn(ar, Unknown FW IE: %u\n,
le32_to_cpu(hdr-id));
@@ -1388,6 +1405,13 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
goto err_free_firmware_files;
}
 
+   ret = ath10k_swap_code_seg_init(ar);
+   if (ret) {
+   ath10k_err(ar, failed to initialize code swap segment: %d\n,
+  ret);
+   goto err_free_firmware_files;
+   }
+
mutex_lock(ar-conf_mutex);
 
ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index 993cd36..b9145f5 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -36,6 +36,7 @@
 #include spectral.h
 #include thermal.h
 #include wow.h
+#include swap.h
 
 #define MS(_v, _f) (((_v)  _f##_MASK)  _f##_LSB)
 #define SM(_v, _f) (((_v)  _f##_LSB)  _f##_MASK)
@@ -603,6 +604,12 @@ struct ath10k {
 
const struct firmware *cal_file;
 
+   struct {
+   const void *firmware_codeswap_data;
+   size_t firmware_codeswap_len;
+   struct ath10k_swap_code_seg_info *firmware_swap_code_seg_info;
+   } swap;
+
char spec_board_id[100];
bool spec_board_loaded;
 
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net

[PATCH V2 08/10] ath10k: Fix BMI communication timeout for QCA99X0

2015-06-18 Thread Vasanthakumar Thiagarajan
There is more than 1 sec delay in getting response from target
through BMI in QCA99X0. Increase the BMI communication timeout
to 2*HZ to fix BMI failures.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/bmi.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/bmi.h 
b/drivers/net/wireless/ath/ath10k/bmi.h
index 31a9906..df7c761 100644
--- a/drivers/net/wireless/ath/ath10k/bmi.h
+++ b/drivers/net/wireless/ath/ath10k/bmi.h
@@ -178,7 +178,7 @@ struct bmi_target_info {
 };
 
 /* in msec */
-#define BMI_COMMUNICATION_TIMEOUT_HZ (1*HZ)
+#define BMI_COMMUNICATION_TIMEOUT_HZ (2 * HZ)
 
 #define BMI_CE_NUM_TO_TARG 0
 #define BMI_CE_NUM_TO_HOST 1
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH V2 10/10] ath10k: Add BMI param value to execute otp to hw_param

2015-06-18 Thread Vasanthakumar Thiagarajan
BMI parameter value to execute downloaded otp binary
is different for QCA99X0. Have a member in hw_params
to hold hw specific BMI param.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/core.c | 8 +++-
 drivers/net/wireless/ath/ath10k/core.h | 1 +
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index c5f5d16..80f38b5 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -49,6 +49,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
.has_shifted_cc_wraparound = true,
+   .otp_exe_param = 0,
.fw = {
.dir = QCA988X_HW_2_0_FW_DIR,
.fw = QCA988X_HW_2_0_FW_FILE,
@@ -63,6 +64,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.name = qca6174 hw2.1,
.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
.uart_pin = 6,
+   .otp_exe_param = 0,
.fw = {
.dir = QCA6174_HW_2_1_FW_DIR,
.fw = QCA6174_HW_2_1_FW_FILE,
@@ -77,6 +79,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.name = qca6174 hw3.0,
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
.uart_pin = 6,
+   .otp_exe_param = 0,
.fw = {
.dir = QCA6174_HW_3_0_FW_DIR,
.fw = QCA6174_HW_3_0_FW_FILE,
@@ -91,6 +94,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.name = qca6174 hw3.2,
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
.uart_pin = 6,
+   .otp_exe_param = 0,
.fw = {
/* uses same binaries as hw3.0 */
.dir = QCA6174_HW_3_0_FW_DIR,
@@ -106,6 +110,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.name = qca99x0 hw2.0,
.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
+   .otp_exe_param = 0x0700,
.fw = {
.dir = QCA99X0_HW_2_0_FW_DIR,
.fw = QCA99X0_HW_2_0_FW_FILE,
@@ -413,6 +418,7 @@ out:
 static int ath10k_download_and_run_otp(struct ath10k *ar)
 {
u32 result, address = ar-hw_params.patch_load_addr;
+   u32 bmi_otp_exe_param = ar-hw_params.otp_exe_param;
int ret;
 
ret = ath10k_download_board_data(ar, ar-board_data, ar-board_len);
@@ -438,7 +444,7 @@ static int ath10k_download_and_run_otp(struct ath10k *ar)
return ret;
}
 
-   ret = ath10k_bmi_execute(ar, address, 0, result);
+   ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, result);
if (ret) {
ath10k_err(ar, could not execute otp (%d)\n, ret);
return ret;
diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index b9145f5..afd21d5 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -572,6 +572,7 @@ struct ath10k {
const char *name;
u32 patch_load_addr;
int uart_pin;
+   u32 otp_exe_param;
 
/* This is true if given HW chip has a quirky Cycle Counter
 * wraparound which resets to 0x7fff instead of 0. All
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 07/10] ath10k: Extend CE src desc flags for interrupt indication

2015-06-15 Thread Vasanthakumar Thiagarajan
QCA99X0 uses two new copy engine src desc flags for interrupt
indication. Bit_2 is to mark if host interrupt is disabled after
processing the current desc and bit_3 is to mark if target interrupt
is diabled after the processing of current descriptor.
CE_DESC_FLAGS_META_DATA_MASK and CE_DESC_FLAGS_META_DATA_LSB are based
on the target type.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/ce.c | 1 +
 drivers/net/wireless/ath/ath10k/ce.h | 9 +++--
 drivers/net/wireless/ath/ath10k/hw.c | 6 ++
 drivers/net/wireless/ath/ath10k/hw.h | 2 ++
 4 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.c 
b/drivers/net/wireless/ath/ath10k/ce.c
index e508c65..cf28fbe 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -452,6 +452,7 @@ int ath10k_ce_completed_recv_next_nolock(struct 
ath10k_ce_pipe *ce_state,
 {
struct ath10k_ce_ring *dest_ring = ce_state-dest_ring;
unsigned int nentries_mask = dest_ring-nentries_mask;
+   struct ath10k *ar = ce_state-ar;
unsigned int sw_index = dest_ring-sw_index;
 
struct ce_desc *base = dest_ring-base_addr_owner_space;
diff --git a/drivers/net/wireless/ath/ath10k/ce.h 
b/drivers/net/wireless/ath/ath10k/ce.h
index bb4b8f3..5c903e15 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -38,8 +38,13 @@ struct ath10k_ce_pipe;
 
 #define CE_DESC_FLAGS_GATHER (1  0)
 #define CE_DESC_FLAGS_BYTE_SWAP  (1  1)
-#define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC
-#define CE_DESC_FLAGS_META_DATA_LSB  2
+
+/* Following desc flags are used in QCA99X0 */
+#define CE_DESC_FLAGS_HOST_INT_DIS (1  2)
+#define CE_DESC_FLAGS_TGT_INT_DIS  (1  3)
+
+#define CE_DESC_FLAGS_META_DATA_MASK ar-hw_values-ce_desc_meta_data_mask
+#define CE_DESC_FLAGS_META_DATA_LSB  ar-hw_values-ce_desc_meta_data_lsb
 
 struct ce_desc {
__le32 addr;
diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c
index e5fe33d9..1414e1f 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -114,6 +114,8 @@ const struct ath10k_hw_values qca988x_values = {
.ce_count   = 8,
.msi_assign_ce_max  = 7,
.num_target_ce_config_wlan  = 7,
+   .ce_desc_meta_data_mask = 0xFFFC,
+   .ce_desc_meta_data_lsb  = 2,
 };
 
 const struct ath10k_hw_values qca6174_values = {
@@ -121,6 +123,8 @@ const struct ath10k_hw_values qca6174_values = {
.ce_count   = 8,
.msi_assign_ce_max  = 7,
.num_target_ce_config_wlan  = 7,
+   .ce_desc_meta_data_mask = 0xFFFC,
+   .ce_desc_meta_data_lsb  = 2,
 };
 
 const struct ath10k_hw_values qca99x0_values = {
@@ -128,6 +132,8 @@ const struct ath10k_hw_values qca99x0_values = {
.ce_count   = 12,
.msi_assign_ce_max  = 12,
.num_target_ce_config_wlan  = 10,
+   .ce_desc_meta_data_mask = 0xFFF0,
+   .ce_desc_meta_data_lsb  = 4,
 };
 
 void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 5819659..35cd8ca 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -195,6 +195,8 @@ struct ath10k_hw_values {
u8 ce_count;
u8 msi_assign_ce_max;
u8 num_target_ce_config_wlan;
+   u16 ce_desc_meta_data_mask;
+   u8 ce_desc_meta_data_lsb;
 };
 
 extern const struct ath10k_hw_values qca988x_values;
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/10] ath10k: Fix BMI communication timeout for QCA99X0

2015-06-15 Thread Vasanthakumar Thiagarajan
There is more than 1 sec delay in getting response from target
through BMI in QCA99X0. Increase the BMI communication timeout
to 2*HZ to fix BMI failures.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/bmi.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/bmi.h 
b/drivers/net/wireless/ath/ath10k/bmi.h
index 31a9906..df7c761 100644
--- a/drivers/net/wireless/ath/ath10k/bmi.h
+++ b/drivers/net/wireless/ath/ath10k/bmi.h
@@ -178,7 +178,7 @@ struct bmi_target_info {
 };
 
 /* in msec */
-#define BMI_COMMUNICATION_TIMEOUT_HZ (1*HZ)
+#define BMI_COMMUNICATION_TIMEOUT_HZ (2 * HZ)
 
 #define BMI_CE_NUM_TO_TARG 0
 #define BMI_CE_NUM_TO_HOST 1
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/10] ath10k: Add support for code swap

2015-06-15 Thread Vasanthakumar Thiagarajan
Code swap is a mechanism to use host memory to store
some fw binary code segment. Ath10k host driver allocates
and loads the code swap binary into the host memory and
configures the target with the host allocated memory
information at the address taken from code swap binary.
This patch adds code swap support for firmware binary.
Code swap binary for firmware bin is available in
ATH10K_FW_IE_FW_CODE_SWAP_IMAGE.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/Makefile |   3 +-
 drivers/net/wireless/ath/ath10k/core.c   |  24 
 drivers/net/wireless/ath/ath10k/core.h   |   7 ++
 drivers/net/wireless/ath/ath10k/hw.h |   3 +
 drivers/net/wireless/ath/ath10k/swap.c   | 208 +++
 drivers/net/wireless/ath/ath10k/swap.h   |  72 +++
 6 files changed, 316 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/wireless/ath/ath10k/swap.c
 create mode 100644 drivers/net/wireless/ath/ath10k/swap.h

diff --git a/drivers/net/wireless/ath/ath10k/Makefile 
b/drivers/net/wireless/ath/ath10k/Makefile
index 9729e69..c04fb00 100644
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -11,7 +11,8 @@ ath10k_core-y += mac.o \
 wmi-tlv.o \
 bmi.o \
 hw.o \
-p2p.o
+p2p.o \
+swap.o
 
 ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o
 ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index de85ec8..6346711 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -426,6 +426,13 @@ static int ath10k_download_fw(struct ath10k *ar, enum 
ath10k_firmware_mode mode)
data = ar-firmware_data;
data_len = ar-firmware_len;
mode_name = normal;
+   ret = ath10k_swap_code_seg_configure(ar,
+   ATH10K_SWAP_CODE_SEG_BIN_TYPE_FW);
+   if (ret) {
+   ath10k_err(ar, failed to configure fw code swap: %d\n,
+  ret);
+   return ret;
+   }
break;
case ATH10K_FIRMWARE_MODE_UTF:
data = ar-testmode.utf-data;
@@ -465,6 +472,8 @@ static void ath10k_core_free_firmware_files(struct ath10k 
*ar)
if (!IS_ERR(ar-cal_file))
release_firmware(ar-cal_file);
 
+   ath10k_swap_code_seg_release(ar);
+
ar-board = NULL;
ar-board_data = NULL;
ar-board_len = 0;
@@ -478,6 +487,7 @@ static void ath10k_core_free_firmware_files(struct ath10k 
*ar)
ar-firmware_len = 0;
 
ar-cal_file = NULL;
+
 }
 
 static int ath10k_fetch_cal_file(struct ath10k *ar)
@@ -751,6 +761,13 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k 
*ar, const char *name)
ath10k_dbg(ar, ATH10K_DBG_BOOT, found fw ie htt op 
version %d\n,
   ar-htt.op_version);
break;
+   case ATH10K_FW_IE_FW_CODE_SWAP_IMAGE:
+   ath10k_dbg(ar, ATH10K_DBG_BOOT,
+  found fw code swap image ie (%zd B)\n,
+  ie_len);
+   ar-swap.firmware_codeswap_data = data;
+   ar-swap.firmware_codeswap_len = ie_len;
+   break;
default:
ath10k_warn(ar, Unknown FW IE: %u\n,
le32_to_cpu(hdr-id));
@@ -1344,6 +1361,13 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
goto err_free_firmware_files;
}
 
+   ret = ath10k_swap_code_seg_init(ar);
+   if (ret) {
+   ath10k_err(ar, failed to initialize code swap segment: %d\n,
+  ret);
+   goto err_free_firmware_files;
+   }
+
mutex_lock(ar-conf_mutex);
 
ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index ae92f64..335b2fc 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -36,6 +36,7 @@
 #include spectral.h
 #include thermal.h
 #include wow.h
+#include swap.h
 
 #define MS(_v, _f) (((_v)  _f##_MASK)  _f##_LSB)
 #define SM(_v, _f) (((_v)  _f##_LSB)  _f##_MASK)
@@ -603,6 +604,12 @@ struct ath10k {
 
const struct firmware *cal_file;
 
+   struct {
+   const void *firmware_codeswap_data;
+   size_t firmware_codeswap_len;
+   struct ath10k_swap_code_seg_info *firmware_swap_code_seg_info;
+   } swap;
+
char spec_board_id[100];
bool spec_board_loaded;
 
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net

[PATCH 03/10] ath10k: Add hw register/values for QCA99X0 chip

2015-06-15 Thread Vasanthakumar Thiagarajan
This is to prepare the driver for QCA99X0 chip support.
This commit adds hw_params, hw register table and hw_values
table for QCA99X0 chip. Please note this is only a partial patch adding
support for QCA99X0, so the device id is not yet added to pci device
table.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/core.c  | 18 
 drivers/net/wireless/ath/ath10k/hw.c| 44 +
 drivers/net/wireless/ath/ath10k/hw.h| 18 
 drivers/net/wireless/ath/ath10k/pci.c   |  5 
 drivers/net/wireless/ath/ath10k/targaddrs.h |  3 ++
 5 files changed, 88 insertions(+)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 2a17664..de85ec8 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -101,6 +101,20 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
},
},
+   {
+   .id = QCA99X0_HW_2_0_DEV_VERSION,
+   .name = qca99x0 hw2.0,
+   .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
+   .uart_pin = 7,
+   .fw = {
+   .dir = QCA99X0_HW_2_0_FW_DIR,
+   .fw = QCA99X0_HW_2_0_FW_FILE,
+   .otp = QCA99X0_HW_2_0_OTP_FILE,
+   .board = QCA99X0_HW_2_0_BOARD_DATA_FILE,
+   .board_size = QCA99X0_BOARD_DATA_SZ,
+   .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
+   },
+   },
 };
 
 static void ath10k_send_suspend_complete(struct ath10k *ar)
@@ -1476,6 +1490,10 @@ struct ath10k *ath10k_core_create(size_t priv_size, 
struct device *dev,
ar-regs = qca6174_regs;
ar-hw_values = qca6174_values;
break;
+   case ATH10K_HW_QCA99X0:
+   ar-regs = qca99x0_regs;
+   ar-hw_values = qca99x0_values;
+   break;
default:
ath10k_err(ar, unsupported core hardware revision %d\n,
   hw_rev);
diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c
index cb09867..e5fe33d9 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -72,6 +72,43 @@ const struct ath10k_hw_regs qca6174_regs = {
.pcie_intr_clr_address  = 0x0014,
 };
 
+const struct ath10k_hw_regs qca99x0_regs = {
+   .rtc_state_cold_reset_mask  = 0x0400,
+   .rtc_soc_base_address   = 0x0008,
+   .rtc_wmac_base_address  = 0x,
+   .soc_core_base_address  = 0x00082000,
+   .ce_wrapper_base_address= 0x0004d000,
+   .ce0_base_address   = 0x0004a000,
+   .ce1_base_address   = 0x0004a400,
+   .ce2_base_address   = 0x0004a800,
+   .ce3_base_address   = 0x0004ac00,
+   .ce4_base_address   = 0x0004b000,
+   .ce5_base_address   = 0x0004b400,
+   .ce6_base_address   = 0x0004b800,
+   .ce7_base_address   = 0x0004bc00,
+   /* Note: qca99x0 supports upto 12 Copy Engines. Other than address of
+* CE0 and CE1 no other copy engine is directly referred in the code.
+* It is not really neccessary to assign address for newly supported
+* CEs in this address table.
+*  Copy Engine Address
+*  CE8 0x0004c000
+*  CE9 0x0004c400
+*  CE100x0004c800
+*  CE110x0004cc00
+*/
+   .soc_reset_control_si0_rst_mask = 0x0001,
+   .soc_reset_control_ce_rst_mask  = 0x0100,
+   .soc_chip_id_address= 0x00ec,
+   .scratch_3_address  = 0x00040050,
+   .fw_indicator_address   = 0x00040050,
+   .pcie_local_base_address= 0x,
+   .ce_wrap_intr_sum_host_msi_lsb  = 0x000c,
+   .ce_wrap_intr_sum_host_msi_mask = 0x00fff000,
+   .pcie_intr_fw_mask  = 0x0010,
+   .pcie_intr_ce_mask_all  = 0x000fff00,
+   .pcie_intr_clr_address  = 0x0010,
+};
+
 const struct ath10k_hw_values qca988x_values = {
.rtc_state_val_on   = 3,
.ce_count   = 8,
@@ -86,6 +123,13 @@ const struct ath10k_hw_values qca6174_values = {
.num_target_ce_config_wlan  = 7,
 };
 
+const struct ath10k_hw_values qca99x0_values = {
+   .rtc_state_val_on

[PATCH 10/10] ath10k: Add BMI param value to execute otp to hw_param

2015-06-15 Thread Vasanthakumar Thiagarajan
BMI parameter value to execute downloaded otp binary
is different for QCA99X0. Have a member in hw_params
to hold hw specific BMI param.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/core.c | 8 +++-
 drivers/net/wireless/ath/ath10k/core.h | 1 +
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 6346711..c6a39eeb 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -49,6 +49,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
.has_shifted_cc_wraparound = true,
+   .otp_exe_param = 0,
.fw = {
.dir = QCA988X_HW_2_0_FW_DIR,
.fw = QCA988X_HW_2_0_FW_FILE,
@@ -63,6 +64,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.name = qca6174 hw2.1,
.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
.uart_pin = 6,
+   .otp_exe_param = 0,
.fw = {
.dir = QCA6174_HW_2_1_FW_DIR,
.fw = QCA6174_HW_2_1_FW_FILE,
@@ -77,6 +79,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.name = qca6174 hw3.0,
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
.uart_pin = 6,
+   .otp_exe_param = 0,
.fw = {
.dir = QCA6174_HW_3_0_FW_DIR,
.fw = QCA6174_HW_3_0_FW_FILE,
@@ -91,6 +94,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] 
= {
.name = qca6174 hw3.2,
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
.uart_pin = 6,
+   .otp_exe_param = 0,
.fw = {
/* uses same binaries as hw3.0 */
.dir = QCA6174_HW_3_0_FW_DIR,
@@ -106,6 +110,7 @@ static const struct ath10k_hw_params 
ath10k_hw_params_list[] = {
.name = qca99x0 hw2.0,
.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
+   .otp_exe_param = 0x0700,
.fw = {
.dir = QCA99X0_HW_2_0_FW_DIR,
.fw = QCA99X0_HW_2_0_FW_FILE,
@@ -369,6 +374,7 @@ out:
 static int ath10k_download_and_run_otp(struct ath10k *ar)
 {
u32 result, address = ar-hw_params.patch_load_addr;
+   u32 bmi_otp_exe_param = ar-hw_params.otp_exe_param;
int ret;
 
ret = ath10k_download_board_data(ar, ar-board_data, ar-board_len);
@@ -394,7 +400,7 @@ static int ath10k_download_and_run_otp(struct ath10k *ar)
return ret;
}
 
-   ret = ath10k_bmi_execute(ar, address, 0, result);
+   ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, result);
if (ret) {
ath10k_err(ar, could not execute otp (%d)\n, ret);
return ret;
diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index 335b2fc..e9bf28e 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -572,6 +572,7 @@ struct ath10k {
const char *name;
u32 patch_load_addr;
int uart_pin;
+   u32 otp_exe_param;
 
/* This is true if given HW chip has a quirky Cycle Counter
 * wraparound which resets to 0x7fff instead of 0. All
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 06/10] ath10k: Add chip reset sequence for QCA99X0

2015-06-15 Thread Vasanthakumar Thiagarajan
QCA99X0 supports only cold reset. Also, made
ath10k_pci_irq_msi_fw_mask() and ath10k_pci_irq_msi_fw_unmask()
non-99X0 specific till we get proper register configuration
to mask/unmask irq/MSI.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/pci.c | 81 ++-
 1 file changed, 71 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 422232c..fe41b61 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -82,7 +82,7 @@ static const struct ath10k_pci_supp_chip 
ath10k_pci_supp_chips[] = {
 
 static void ath10k_pci_buffer_cleanup(struct ath10k *ar);
 static int ath10k_pci_cold_reset(struct ath10k *ar);
-static int ath10k_pci_warm_reset(struct ath10k *ar);
+static int ath10k_pci_safe_chip_reset(struct ath10k *ar);
 static int ath10k_pci_wait_for_target_init(struct ath10k *ar);
 static int ath10k_pci_init_irq(struct ath10k *ar);
 static int ath10k_pci_deinit_irq(struct ath10k *ar);
@@ -91,6 +91,7 @@ static void ath10k_pci_free_irq(struct ath10k *ar);
 static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
   struct ath10k_ce_pipe *rx_pipe,
   struct bmi_xfer *xfer);
+static int ath10k_pci_qca99x0_chip_reset(struct ath10k *ar);
 
 static const struct ce_attr host_ce_config_wlan[] = {
/* CE0: host-target HTC control and raw streams */
@@ -1415,20 +1416,42 @@ static void ath10k_pci_irq_msi_fw_mask(struct ath10k 
*ar)
 {
u32 val;
 
-   val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS);
-   val = ~CORE_CTRL_PCIE_REG_31_MASK;
-
-   ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS, val);
+   switch (ar-hw_rev) {
+   case ATH10K_HW_QCA988X:
+   case ATH10K_HW_QCA6174:
+   val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
+   CORE_CTRL_ADDRESS);
+   val = ~CORE_CTRL_PCIE_REG_31_MASK;
+   ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS +
+  CORE_CTRL_ADDRESS, val);
+   break;
+   case ATH10K_HW_QCA99X0:
+   /* TODO: Find appropriate register configuration for QCA99X0
+*  to mask irq/MSI.
+*/
+break;
+   }
 }
 
 static void ath10k_pci_irq_msi_fw_unmask(struct ath10k *ar)
 {
u32 val;
 
-   val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS);
-   val |= CORE_CTRL_PCIE_REG_31_MASK;
-
-   ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS, val);
+   switch (ar-hw_rev) {
+   case ATH10K_HW_QCA988X:
+   case ATH10K_HW_QCA6174:
+   val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
+   CORE_CTRL_ADDRESS);
+   val |= CORE_CTRL_PCIE_REG_31_MASK;
+   ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS +
+  CORE_CTRL_ADDRESS, val);
+   break;
+   case ATH10K_HW_QCA99X0:
+   /* TODO: Find appropriate register configuration for QCA99X0
+*  to unmask irq/MSI.
+*/
+   break;
+   }
 }
 
 static void ath10k_pci_irq_disable(struct ath10k *ar)
@@ -1590,7 +1613,7 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
 * masked. To prevent the device from asserting the interrupt reset it
 * before proceeding with cleanup.
 */
-   ath10k_pci_warm_reset(ar);
+   ath10k_pci_safe_chip_reset(ar);
 
ath10k_pci_irq_disable(ar);
ath10k_pci_irq_sync(ar);
@@ -2102,6 +2125,18 @@ static int ath10k_pci_warm_reset(struct ath10k *ar)
return 0;
 }
 
+static int ath10k_pci_safe_chip_reset(struct ath10k *ar)
+{
+   if (QCA_REV_988X(ar) || QCA_REV_6174(ar)) {
+   return ath10k_pci_warm_reset(ar);
+   } else if (QCA_REV_99X0(ar)) {
+   ath10k_pci_irq_disable(ar);
+   return ath10k_pci_qca99x0_chip_reset(ar);
+   } else {
+   return -ENOTSUPP;
+   }
+}
+
 static int ath10k_pci_qca988x_chip_reset(struct ath10k *ar)
 {
int i, ret;
@@ -2208,12 +2243,38 @@ static int ath10k_pci_qca6174_chip_reset(struct ath10k 
*ar)
return 0;
 }
 
+static int ath10k_pci_qca99x0_chip_reset(struct ath10k *ar)
+{
+   int ret;
+
+   ath10k_dbg(ar, ATH10K_DBG_BOOT, boot qca99x0 chip reset\n);
+
+   ret = ath10k_pci_cold_reset(ar);
+   if (ret) {
+   ath10k_warn(ar, failed to cold reset: %d\n, ret);
+   return ret;
+   }
+
+   ret = ath10k_pci_wait_for_target_init(ar);
+   if (ret) {
+   ath10k_warn(ar, failed to wait for target after cold reset: 
%d\n,
+   ret);
+   return ret

[PATCH 00/10] Add QCA99X0 support

2015-06-15 Thread Vasanthakumar Thiagarajan
This patch set adds changes for QCA99X0 chip in pci probe,
Copy Engine init and firmware downloads. Since it is still
work in progress the support for this chip is not yet
advertised in pci device table.

Vasanthakumar Thiagarajan (10):
  ath10k: Add a table to store hw specific values
  ath10k: Add new reg_address/mask to hw register table
  ath10k: Add hw register/values for QCA99X0 chip
  ath10k: Copy Engine related changes for QCA99X0
  ath10k: Make target cpu address to CE address conversion chip specific
  ath10k: Add chip reset sequence for QCA99X0
  ath10k: Extend CE src desc flags for interrupt indication
  ath10k: Fix BMI communication timeout for QCA99X0
  ath10k: Add support for code swap
  ath10k: Add BMI param value to execute otp to hw_param

 drivers/net/wireless/ath/ath10k/Makefile|   3 +-
 drivers/net/wireless/ath/ath10k/bmi.h   |   2 +-
 drivers/net/wireless/ath/ath10k/ce.c|   1 +
 drivers/net/wireless/ath/ath10k/ce.h|  17 ++-
 drivers/net/wireless/ath/ath10k/core.c  |  52 ++-
 drivers/net/wireless/ath/ath10k/core.h  |   9 ++
 drivers/net/wireless/ath/ath10k/hw.c|  86 +++-
 drivers/net/wireless/ath/ath10k/hw.h|  61 ++--
 drivers/net/wireless/ath/ath10k/pci.c   | 180 ++--
 drivers/net/wireless/ath/ath10k/pci.h   |  12 --
 drivers/net/wireless/ath/ath10k/swap.c  | 208 
 drivers/net/wireless/ath/ath10k/swap.h  |  72 ++
 drivers/net/wireless/ath/ath10k/targaddrs.h |   3 +
 13 files changed, 659 insertions(+), 47 deletions(-)
 create mode 100644 drivers/net/wireless/ath/ath10k/swap.c
 create mode 100644 drivers/net/wireless/ath/ath10k/swap.h

-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/10] ath10k: Add new reg_address/mask to hw register table

2015-06-15 Thread Vasanthakumar Thiagarajan
Add more register address and mask which can be different
for newer chip to hw_reg table.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/ce.h |  6 --
 drivers/net/wireless/ath/ath10k/hw.c | 22 ++
 drivers/net/wireless/ath/ath10k/hw.h | 17 -
 3 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.h 
b/drivers/net/wireless/ath/ath10k/ce.h
index 0eddb20..93939de 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -423,8 +423,10 @@ static inline u32 ath10k_ce_base_address(struct ath10k 
*ar, unsigned int ce_id)
 
 #define CE_RING_IDX_INCR(nentries_mask, idx) (((idx) + 1)  (nentries_mask))
 
-#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB  8
-#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK 0xff00
+#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB \
+   ar-regs-ce_wrap_intr_sum_host_msi_lsb
+#define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK \
+   ar-regs-ce_wrap_intr_sum_host_msi_mask
 #define CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_GET(x) \
(((x)  CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_MASK)  \
CE_WRAPPER_INTERRUPT_SUMMARY_HOST_MSI_LSB)
diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c
index 48bcd2c..cb09867 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -34,8 +34,15 @@ const struct ath10k_hw_regs qca988x_regs = {
.ce7_base_address   = 0x00059000,
.soc_reset_control_si0_rst_mask = 0x0001,
.soc_reset_control_ce_rst_mask  = 0x0004,
-   .soc_chip_id_address= 0x00ec,
-   .scratch_3_address  = 0x0030,
+   .soc_chip_id_address= 0x00ec,
+   .scratch_3_address  = 0x0030,
+   .fw_indicator_address   = 0x9030,
+   .pcie_local_base_address= 0x0008,
+   .ce_wrap_intr_sum_host_msi_lsb  = 0x0008,
+   .ce_wrap_intr_sum_host_msi_mask = 0xff00,
+   .pcie_intr_fw_mask  = 0x0400,
+   .pcie_intr_ce_mask_all  = 0x0007f800,
+   .pcie_intr_clr_address  = 0x0014,
 };
 
 const struct ath10k_hw_regs qca6174_regs = {
@@ -54,8 +61,15 @@ const struct ath10k_hw_regs qca6174_regs = {
.ce7_base_address   = 0x00036000,
.soc_reset_control_si0_rst_mask = 0x,
.soc_reset_control_ce_rst_mask  = 0x0001,
-   .soc_chip_id_address= 0x000f0,
-   .scratch_3_address  = 0x0028,
+   .soc_chip_id_address= 0x00f0,
+   .scratch_3_address  = 0x0028,
+   .fw_indicator_address   = 0x9028,
+   .pcie_local_base_address= 0x0008,
+   .ce_wrap_intr_sum_host_msi_lsb  = 0x0008,
+   .ce_wrap_intr_sum_host_msi_mask = 0xff00,
+   .pcie_intr_fw_mask  = 0x0400,
+   .pcie_intr_ce_mask_all  = 0x0007f800,
+   .pcie_intr_clr_address  = 0x0014,
 };
 
 const struct ath10k_hw_values qca988x_values = {
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index b218388..5d04317 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -164,6 +164,13 @@ struct ath10k_hw_regs {
u32 soc_reset_control_ce_rst_mask;
u32 soc_chip_id_address;
u32 scratch_3_address;
+   u32 fw_indicator_address;
+   u32 pcie_local_base_address;
+   u32 ce_wrap_intr_sum_host_msi_lsb;
+   u32 ce_wrap_intr_sum_host_msi_mask;
+   u32 pcie_intr_fw_mask;
+   u32 pcie_intr_ce_mask_all;
+   u32 pcie_intr_clr_address;
 };
 
 extern const struct ath10k_hw_regs qca988x_regs;
@@ -386,7 +393,7 @@ enum ath10k_hw_rate_cck {
 #define CE7_BASE_ADDRESS   ar-regs-ce7_base_address
 #define DBI_BASE_ADDRESS   0x0006
 #define WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x0006c000
-#define PCIE_LOCAL_BASE_ADDRESS0x0008
+#define PCIE_LOCAL_BASE_ADDRESS
ar-regs-pcie_local_base_address
 
 #define SOC_RESET_CONTROL_ADDRESS  0x
 #define SOC_RESET_CONTROL_OFFSET   0x
@@ -460,7 +467,7 @@ enum ath10k_hw_rate_cck {
 #define CORE_CTRL_ADDRESS  0x
 #define PCIE_INTR_ENABLE_ADDRESS   0x0008
 #define PCIE_INTR_CAUSE_ADDRESS0x000c
-#define PCIE_INTR_CLR_ADDRESS  0x0014
+#define PCIE_INTR_CLR_ADDRESS  ar-regs-pcie_intr_clr_address
 #define SCRATCH_3_ADDRESS  ar-regs

[PATCH 05/10] ath10k: Make target cpu address to CE address conversion chip specific

2015-06-15 Thread Vasanthakumar Thiagarajan
Make the helper converting target virtual address space to CE address
space a target type specific to support QCA99X0. Also make this as
function instead of macro.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/pci.c | 25 ++---
 drivers/net/wireless/ath/ath10k/pci.h | 12 
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 980390a..422232c 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -743,6 +743,26 @@ static void ath10k_pci_rx_replenish_retry(unsigned long 
ptr)
ath10k_pci_rx_post(ar);
 }
 
+static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr)
+{
+   u32 val = 0;
+
+   switch (ar-hw_rev) {
+   case ATH10K_HW_QCA988X:
+   case ATH10K_HW_QCA6174:
+   val = (ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
+ CORE_CTRL_ADDRESS) 
+  0x7fff)  21;
+   break;
+   case ATH10K_HW_QCA99X0:
+   val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS);
+   break;
+   }
+
+   val |= 0x10 | (addr  0xf);
+   return val;
+}
+
 /*
  * Diagnostic read/write access is provided for startup/config/debug usage.
  * Caller must guarantee proper alignment, when applicable, and single user
@@ -805,8 +825,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 
address, void *data,
 * convert it from Target CPU virtual address space
 * to CE address space
 */
-   address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci-mem,
-address);
+   address = ath10k_pci_targ_cpu_to_ce_addr(ar, address);
 
ret = ath10k_ce_send_nolock(ce_diag, NULL, (u32)address, 
nbytes, 0,
0);
@@ -964,7 +983,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 
address,
 * to
 *CE address space
 */
-   address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci-mem, address);
+   address = ath10k_pci_targ_cpu_to_ce_addr(ar, address);
 
remaining_bytes = orig_nbytes;
ce_data = ce_data_base;
diff --git a/drivers/net/wireless/ath/ath10k/pci.h 
b/drivers/net/wireless/ath/ath10k/pci.h
index d7696dd..67f8d07 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -236,18 +236,6 @@ static inline struct ath10k_pci *ath10k_pci_priv(struct 
ath10k *ar)
 #define CDC_WAR_MAGIC_STR   0xceef
 #define CDC_WAR_DATA_CE 4
 
-/*
- * TODO: Should be a function call specific to each Target-type.
- * This convoluted macro converts from Target CPU Virtual Address Space to CE
- * Address Space. As part of this process, we conservatively fetch the current
- * PCIE_BAR. MOST of the time, this should match the upper bits of PCI space
- * for this device; but that's not guaranteed.
- */
-#define TARG_CPU_SPACE_TO_CE_SPACE(ar, pci_addr, addr) \
-   (((ath10k_pci_read32(ar, (SOC_CORE_BASE_ADDRESS |   \
- CORE_CTRL_ADDRESS))  0x7ff)  21) | \
-0x10 | ((addr)  0xf))
-
 /* Wait up to this many Ms for a Diagnostic Access CE operation to complete */
 #define DIAG_ACCESS_CE_TIMEOUT_MS 10
 
-- 
1.9.1

--
To unsubscribe from this list: send the line unsubscribe linux-wireless in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 04/10] ath10k: Copy Engine related changes for QCA99X0

2015-06-15 Thread Vasanthakumar Thiagarajan
QCA99X0 supports upto 12 Copy engines. Host and target
CE configuration table is updated to support new copy engine
pipes. This also fixes the assumption of diagnostic CE by making
CE_7 as the one instead of CE_COUNT - 1.

Signed-off-by: Vasanthakumar Thiagarajan vthia...@qti.qualcomm.com
---
 drivers/net/wireless/ath/ath10k/ce.h  |  2 +-
 drivers/net/wireless/ath/ath10k/hw.h  |  3 ++
 drivers/net/wireless/ath/ath10k/pci.c | 69 ++-
 3 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/ce.h 
b/drivers/net/wireless/ath/ath10k/ce.h
index 93939de..bb4b8f3 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -21,7 +21,7 @@
 #include hif.h
 
 /* Maximum number of Copy Engine's supported */
-#define CE_COUNT_MAX 8
+#define CE_COUNT_MAX 12
 #define CE_HTT_H2T_MSG_SRC_NENTRIES 4096
 
 /* Descriptor rings must be aligned to this boundary */
diff --git a/drivers/net/wireless/ath/ath10k/hw.h 
b/drivers/net/wireless/ath/ath10k/hw.h
index 76caeab..5819659 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -343,6 +343,9 @@ enum ath10k_hw_rate_cck {
 #define TARGET_TLV_NUM_MSDU_DESC   (1024 + 32)
 #define TARGET_TLV_NUM_WOW_PATTERNS22
 
+/* Diagnostic Window */
+#define CE_DIAG_PIPE   7
+
 #define NUM_TARGET_CE_CONFIG_WLAN ar-hw_values-num_target_ce_config_wlan
 
 /* Number of Copy Engines supported */
diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 190f7f3..980390a 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -156,6 +156,38 @@ static const struct ce_attr host_ce_config_wlan[] = {
.src_sz_max = DIAG_TRANSFER_LIMIT,
.dest_nentries = 2,
},
+
+   /* CE8: target-host pktlog */
+   {
+   .flags = CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 2048,
+   .dest_nentries = 128,
+   },
+
+   /* CE9 target autonomous qcache memcpy */
+   {
+   .flags = CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 0,
+   .dest_nentries = 0,
+   },
+
+   /* CE10: target autonomous hif memcpy */
+   {
+   .flags = CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 0,
+   .dest_nentries = 0,
+   },
+
+   /* CE11: target autonomous hif memcpy */
+   {
+   .flags = CE_ATTR_FLAGS,
+   .src_nentries = 0,
+   .src_sz_max = 0,
+   .dest_nentries = 0,
+   },
 };
 
 /* Target firmware's Copy Engine configuration. */
@@ -233,6 +265,38 @@ static const struct ce_pipe_config target_ce_config_wlan[] 
= {
},
 
/* CE7 used only by Host */
+   {
+   .pipenum = __cpu_to_le32(7),
+   .pipedir = __cpu_to_le32(PIPEDIR_INOUT),
+   .nentries = __cpu_to_le32(0),
+   .nbytes_max = __cpu_to_le32(0),
+   .flags = __cpu_to_le32(0),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* CE8 target-host packtlog */
+   {
+   .pipenum = __cpu_to_le32(8),
+   .pipedir = __cpu_to_le32(PIPEDIR_IN),
+   .nentries = __cpu_to_le32(64),
+   .nbytes_max = __cpu_to_le32(2048),
+   .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* CE9 target autonomous qcache memcpy */
+   {
+   .pipenum = __cpu_to_le32(9),
+   .pipedir = __cpu_to_le32(PIPEDIR_INOUT),
+   .nentries = __cpu_to_le32(32),
+   .nbytes_max = __cpu_to_le32(2048),
+   .flags = __cpu_to_le32(CE_ATTR_FLAGS | CE_ATTR_DIS_INTR),
+   .reserved = __cpu_to_le32(0),
+   },
+
+   /* It not necessary to send target wlan configuration for CE10  CE11
+* as these CEs are not actively used in target.
+*/
 };
 
 /*
@@ -1759,7 +1823,8 @@ static int ath10k_pci_init_config(struct ath10k *ar)
 
ret = ath10k_pci_diag_write_mem(ar, pipe_cfg_targ_addr,
target_ce_config_wlan,
-   sizeof(target_ce_config_wlan));
+   sizeof(struct ce_pipe_config) *
+   NUM_TARGET_CE_CONFIG_WLAN);
 
if (ret != 0) {
ath10k_err(ar, Failed to write pipe cfg: %d\n, ret);
@@ -1873,7 +1938,7 @@ static int ath10k_pci_alloc_pipes(struct ath10k *ar)
}
 
/* Last CE is Diagnostic Window */
-   if (i == CE_COUNT - 1) {
+   if (i == CE_DIAG_PIPE) {
ar_pci-ce_diag = pipe-ce_hdl;
continue

  1   2   >