[PATCH] staging: wilc1000: Fix lines ending with parentheses

2017-12-15 Thread Aditya Shankar
This patch fixes the "Lines should not end with a '('"
problem reported by checkpatch

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/linux_mon.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_mon.c 
b/drivers/staging/wilc1000/linux_mon.c
index 1c740af..a793c42 100644
--- a/drivers/staging/wilc1000/linux_mon.c
+++ b/drivers/staging/wilc1000/linux_mon.c
@@ -84,9 +84,9 @@ void WILC_WFI_monitor_rx(u8 *buff, u32 size)
cb_hdr->hdr.it_len =
cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr));
 
-   cb_hdr->hdr.it_present = cpu_to_le32(
-   (1 << IEEE80211_RADIOTAP_RATE) |
-   (1 << IEEE80211_RADIOTAP_TX_FLAGS));
+   cb_hdr->hdr.it_present =
+   cpu_to_le32((1 << IEEE80211_RADIOTAP_RATE) |
+   (1 << IEEE80211_RADIOTAP_TX_FLAGS));
 
cb_hdr->rate = 5; /* txrate->bitrate / 5; */
 
@@ -216,9 +216,9 @@ static netdev_tx_t WILC_WFI_mon_xmit(struct sk_buff *skb,
cb_hdr->hdr.it_len =
cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr));
 
-   cb_hdr->hdr.it_present = cpu_to_le32(
-   (1 << IEEE80211_RADIOTAP_RATE) |
-   (1 << IEEE80211_RADIOTAP_TX_FLAGS));
+   cb_hdr->hdr.it_present =
+   cpu_to_le32((1 << IEEE80211_RADIOTAP_RATE) |
+   (1 << IEEE80211_RADIOTAP_TX_FLAGS));
 
cb_hdr->rate = 5; /* txrate->bitrate / 5; */
cb_hdr->tx_flags = 0x0004;
-- 
2.7.4




[PATCH v2] staging: wilc1000: Fix problems reported by checkpatch

2017-12-15 Thread Aditya Shankar
This commit fixes below style problems in multiple lines
Fix checkpatch WARNING: line over 80 characters

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/linux_mon.c | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/wilc1000/linux_mon.c 
b/drivers/staging/wilc1000/linux_mon.c
index 91d49c4..1c740af 100644
--- a/drivers/staging/wilc1000/linux_mon.c
+++ b/drivers/staging/wilc1000/linux_mon.c
@@ -69,7 +69,8 @@ void WILC_WFI_monitor_rx(u8 *buff, u32 size)
if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
/* hostapd callback mgmt frame */
 
-   skb = dev_alloc_skb(size + sizeof(struct 
wilc_wfi_radiotap_cb_hdr));
+   skb = dev_alloc_skb(size +
+   sizeof(struct wilc_wfi_radiotap_cb_hdr));
if (!skb)
return;
 
@@ -80,7 +81,8 @@ void WILC_WFI_monitor_rx(u8 *buff, u32 size)
 
cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */
 
-   cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct 
wilc_wfi_radiotap_cb_hdr));
+   cb_hdr->hdr.it_len =
+   cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr));
 
cb_hdr->hdr.it_present = cpu_to_le32(
(1 << IEEE80211_RADIOTAP_RATE) |
@@ -96,7 +98,8 @@ void WILC_WFI_monitor_rx(u8 *buff, u32 size)
}
 
} else {
-   skb = dev_alloc_skb(size + sizeof(struct 
wilc_wfi_radiotap_hdr));
+   skb = dev_alloc_skb(size +
+   sizeof(struct wilc_wfi_radiotap_hdr));
 
if (!skb)
return;
@@ -105,7 +108,8 @@ void WILC_WFI_monitor_rx(u8 *buff, u32 size)
hdr = skb_push(skb, sizeof(*hdr));
memset(hdr, 0, sizeof(struct wilc_wfi_radiotap_hdr));
hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */
-   hdr->hdr.it_len = cpu_to_le16(sizeof(struct 
wilc_wfi_radiotap_hdr));
+   hdr->hdr.it_len =
+   cpu_to_le16(sizeof(struct wilc_wfi_radiotap_hdr));
hdr->hdr.it_present = cpu_to_le32
(1 << IEEE80211_RADIOTAP_RATE); /* | */
hdr->rate = 5; /* txrate->bitrate / 5; */
@@ -197,7 +201,8 @@ static netdev_tx_t WILC_WFI_mon_xmit(struct sk_buff *skb,
skb_pull(skb, rtap_len);
 
if (skb->data[0] == 0xc0 && (!(memcmp(broadcast, >data[4], 6 {
-   skb2 = dev_alloc_skb(skb->len + sizeof(struct 
wilc_wfi_radiotap_cb_hdr));
+   skb2 = dev_alloc_skb(skb->len +
+sizeof(struct wilc_wfi_radiotap_cb_hdr));
if (!skb2)
return -ENOMEM;
 
@@ -208,7 +213,8 @@ static netdev_tx_t WILC_WFI_mon_xmit(struct sk_buff *skb,
 
cb_hdr->hdr.it_version = 0; /* PKTHDR_RADIOTAP_VERSION; */
 
-   cb_hdr->hdr.it_len = cpu_to_le16(sizeof(struct 
wilc_wfi_radiotap_cb_hdr));
+   cb_hdr->hdr.it_len =
+   cpu_to_le16(sizeof(struct wilc_wfi_radiotap_cb_hdr));
 
cb_hdr->hdr.it_present = cpu_to_le32(
(1 << IEEE80211_RADIOTAP_RATE) |
-- 
2.7.4




[PATCH] staging: wilc1000: Fix bssid buffer offset in Txq

2017-11-03 Thread Aditya Shankar
Commit 46949b48568b ("staging: wilc1000: New cfg packet
format in handle_set_wfi_drv_handler") updated the frame
format sent from host to the firmware. The code to update
the bssid offset in the new frame was part of a second
patch in the series which did not make it in and thus
causes connection problems after associating to an AP.

This fix adds the proper offset of the bssid value in the
Tx queue buffer to fix the connection issues.

Fixes: Commit 46949b48568b ("staging: wilc1000: New cfg packet format in 
handle_set_wfi_drv_handler")
Cc: sta...@vger.kernel.org
Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 9addef1..f49dfa8 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -714,7 +714,7 @@ int wilc_wlan_handle_txq(struct net_device *dev, u32 
*txq_count)
char *bssid = ((struct tx_complete_data 
*)(tqe->priv))->bssid;
 
buffer_offset = ETH_ETHERNET_HDR_OFFSET;
-   memcpy([offset + 4], bssid, 6);
+   memcpy([offset + 8], bssid, 6);
} else {
buffer_offset = HOST_HDR_OFFSET;
}
-- 
2.7.4



[PATCH v2 6/8] staging: wilc1000: Get packet count from firmware

2017-06-26 Thread Aditya Shankar
Add a new function to get packet count from the firmware.

31:25   24  23:17   16  15:98   7:2 1   0
VO CNT  VO ACM  VI CNT  VI ACM  BE CNT  BE ACM  BK CNT  BK ACM  VMM ready

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 655f229..b3e1136 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -443,6 +443,14 @@ static inline int ac_balance(u8 *count, u8 *ratio)
return 0;
 }
 
+static inline void ac_pkt_count(u32 reg, u8 *pkt_count)
+{
+   pkt_count[AC_BK_Q] = (reg & 0x00fa) >> BK_AC_COUNT_POS;
+   pkt_count[AC_BE_Q] = (reg & 0xfe00) >> BE_AC_COUNT_POS;
+   pkt_count[AC_VI_Q] = (reg & 0x00fe) >> VI_AC_COUNT_POS;
+   pkt_count[AC_VO_Q] = (reg & 0xfe00) >> VO_AC_COUNT_POS;
+}
+
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
  u32 buffer_size, wilc_tx_complete_func_t func)
 {
-- 
2.7.4




[PATCH v2 7/8] staging: wilc1000: Change ac based on acm status

2017-06-26 Thread Aditya Shankar
Add a new function to check and alter the ac if needed
based on the acm status for a particular queue.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index b3e1136..e323fd4 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -451,6 +451,16 @@ static inline void ac_pkt_count(u32 reg, u8 *pkt_count)
pkt_count[AC_VO_Q] = (reg & 0xfe00) >> VO_AC_COUNT_POS;
 }
 
+static inline u8 ac_change(struct wilc *wilc, u8 *ac)
+{
+   do {
+   if (wilc->txq[*ac].acm == 0)
+   return 0;
+   (*ac)++;
+   } while (*ac < NQUEUES);
+   return 1;
+}
+
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
  u32 buffer_size, wilc_tx_complete_func_t func)
 {
-- 
2.7.4




[PATCH v2 3/8] staging: wilc1000: WMM classification of data

2017-06-26 Thread Aditya Shankar
This patch adds a new function to classify data to available
WMM access categories based on the DSCP value in the header.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.c | 51 
 1 file changed, 51 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 8c997ba..d1ed3ba8 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -375,6 +375,57 @@ static inline void ac_q_limit(u8 ac, u16 *q_limit)
  sum) + 1;
 }
 
+static inline u8 ac_classify(struct wilc *wilc, struct txq_entry_t *tqe)
+{
+   u8 *eth_hdr_ptr;
+   u8 *buffer = tqe->buffer;
+   u8 ac;
+   u16 h_proto;
+
+   spin_lock_irqsave(>txq_spinlock, wilc->txq_spinlock_flags);
+
+   eth_hdr_ptr = [0];
+   h_proto = ntohs(*((unsigned short *)_hdr_ptr[12]));
+   if (h_proto == ETH_P_IP) {
+   u8 *ip_hdr_ptr;
+   u32 IHL, DSCP;
+
+   ip_hdr_ptr = [ETHERNET_HDR_LEN];
+   IHL = (ip_hdr_ptr[0] & 0xf) << 2;
+   DSCP = (ip_hdr_ptr[1] & 0xfc);
+
+   switch (DSCP) {
+   case 0x20:
+   case 0x40:
+   case 0x08:
+   ac = AC_BK_Q;
+   break;
+   case 0x80:
+   case 0xA0:
+   case 0x28:
+   ac = AC_VI_Q;
+   break;
+   case 0xC0:
+   case 0xd0:
+   case 0xE0:
+   case 0x88:
+   case 0xB8:
+   ac = AC_VO_Q;
+   break;
+   default:
+   ac = AC_BE_Q;
+   break;
+   }
+   } else {
+   ac  = AC_BE_Q;
+   }
+
+   tqe->q_num = ac;
+   spin_unlock_irqrestore(>txq_spinlock, wilc->txq_spinlock_flags);
+
+   return ac;
+}
+
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
  u32 buffer_size, wilc_tx_complete_func_t func)
 {
-- 
2.7.4




[PATCH v2 8/8] staging: wilc1000: Update ACM bit status

2017-06-26 Thread Aditya Shankar
Add a new function to update ACM bit status for a queue
for all access categories.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index e323fd4..929166a 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -461,6 +461,14 @@ static inline u8 ac_change(struct wilc *wilc, u8 *ac)
return 1;
 }
 
+static inline void ac_acm_bit(struct wilc *wilc, u32 reg)
+{
+   wilc->txq[AC_BK_Q].acm = (reg & 0x0002) >> BK_AC_ACM_STAT_POS;
+   wilc->txq[AC_BE_Q].acm = (reg & 0x0100) >> BE_AC_ACM_STAT_POS;
+   wilc->txq[AC_VI_Q].acm = (reg & 0x0001) >> VI_AC_ACM_STAT_POS;
+   wilc->txq[AC_VO_Q].acm = (reg & 0x0100) >> VO_AC_ACM_STAT_POS;
+}
+
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
  u32 buffer_size, wilc_tx_complete_func_t func)
 {
-- 
2.7.4




[PATCH v2 5/8] staging: wilc1000: Add new variable for ac queue management

2017-06-26 Thread Aditya Shankar
This patch adds a new variable in the wilc struct to manage
ac queues.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wfi_netdevice.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/staging/wilc1000/wilc_wfi_netdevice.h 
b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
index c89bf43..e830bc5 100644
--- a/drivers/staging/wilc1000/wilc_wfi_netdevice.h
+++ b/drivers/staging/wilc1000/wilc_wfi_netdevice.h
@@ -200,6 +200,7 @@ struct wilc {
 
struct txq_entry_t *txq_head;
struct txq_entry_t *txq_tail;
+   struct txq_handle txq[NQUEUES];
int txq_entries;
int txq_exit;
 
-- 
2.7.4




[PATCH v2 2/8] staging: wilc1000: Add function to calculate ac queue limit

2017-06-26 Thread Aditya Shankar
This patch adds a function which calculates the queue limit
for a given access category queue.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.c | 42 
 1 file changed, 42 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 9addef1..8c997ba 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -333,6 +333,48 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, 
u8 *buffer,
return 1;
 }
 
+static inline void ac_q_limit(u8 ac, u16 *q_limit)
+{
+   static bool initialized;
+   static u8 buffer[AC_BUFFER_SIZE];
+   static u16 cnt[NQUEUES];
+   u8 factors[NQUEUES] = {1, 1, 1, 1};
+   static u16 sum;
+   u16 i;
+   static u16 end_index;
+
+   if (!initialized) {
+   for (i = 0; i < AC_BUFFER_SIZE; i++)
+   buffer[i] = i % NQUEUES;
+
+   for (i = 0; i < NQUEUES; i++) {
+   cnt[i] = AC_BUFFER_SIZE * factors[i] / NQUEUES;
+   sum += cnt[i];
+   }
+   end_index = AC_BUFFER_SIZE - 1;
+   initialized = 1;
+   }
+   if (end_index > AC_BUFFER_SIZE - 1)
+   end_index = AC_BUFFER_SIZE - 1;
+
+   cnt[buffer[end_index]] -= factors[buffer[end_index]];
+   cnt[ac] += factors[ac];
+   sum += (factors[ac] - factors[buffer[end_index]]);
+
+   buffer[end_index] = ac;
+   if (end_index > 0)
+   end_index--;
+   else
+   end_index = AC_BUFFER_SIZE - 1;
+
+   for (i = 0; i < NQUEUES; i++)
+   if (!sum)
+   q_limit[i] = 1;
+   else
+   q_limit[i] = (cnt[i] * FLOW_CONTROL_UPPER_THRESHOLD /
+ sum) + 1;
+}
+
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
  u32 buffer_size, wilc_tx_complete_func_t func)
 {
-- 
2.7.4




[PATCH v2 0/8] Enable access category classification on Tx path

2017-06-26 Thread Aditya Shankar
This patch series adds changes made to implement access
category based data classification and manages buffers allocation
between different access categories on the Tx path.

Aditya Shankar (8):
  staging: wilc1000: Add support for AC classification.
  staging: wilc1000: Add function to calculate ac queue limit
  staging: wilc1000: WMM classification of data
  staging: wilc1000: Add function to balance packet count
  staging: wilc1000: Add new variable for ac queue management
  staging: wilc1000: Get packet count from firmware
  staging: wilc1000: Change ac based on acm status
  staging: wilc1000: Update ACM bit status

Change in v2:
Add a missing patch in the patchset

 drivers/staging/wilc1000/wilc_wfi_netdevice.h |   1 +
 drivers/staging/wilc1000/wilc_wlan.c  | 136 ++
 drivers/staging/wilc1000/wilc_wlan.h  |  25 +
 3 files changed, 162 insertions(+)

-- 
2.7.4




[PATCH v2 4/8] staging: wilc1000: Add function to balance packet count

2017-06-26 Thread Aditya Shankar
Add a new function to track the cound of packets and
determine the ratio of current number of packets to
maximum count of packets.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index d1ed3ba8..655f229 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -426,6 +426,23 @@ static inline u8 ac_classify(struct wilc *wilc, struct 
txq_entry_t *tqe)
return ac;
 }
 
+static inline int ac_balance(u8 *count, u8 *ratio)
+{
+   u8 i, max_count = 0;
+
+   if (!count || !ratio)
+   return -1;
+
+   for (i = 0; i < NQUEUES; i++)
+   if (count[i] > max_count)
+   max_count = count[i];
+
+   for (i = 0; i < NQUEUES; i++)
+   ratio[i] = max_count - count[i];
+
+   return 0;
+}
+
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
  u32 buffer_size, wilc_tx_complete_func_t func)
 {
-- 
2.7.4




[PATCH v2 1/8] staging: wilc1000: Add support for AC classification.

2017-06-26 Thread Aditya Shankar
This patch adds new variables and defines for adding access
category classification

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.h | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.h 
b/drivers/staging/wilc1000/wilc_wlan.h
index 7a5eba9..c97f94a 100644
--- a/drivers/staging/wilc1000/wilc_wlan.h
+++ b/drivers/staging/wilc1000/wilc_wlan.h
@@ -133,6 +133,17 @@
 
 #define MODALIAS   "WILC_SPI"
 #define GPIO_NUM   0x44
+
+#define NQUEUES4
+#define VO_AC_COUNT_POS25
+#define VO_AC_ACM_STAT_POS 24
+#define VI_AC_COUNT_POS17
+#define VI_AC_ACM_STAT_POS 16
+#define BE_AC_COUNT_POS9
+#define BE_AC_ACM_STAT_POS 8
+#define BK_AC_COUNT_POS2
+#define BK_AC_ACM_STAT_POS 1
+#define AC_BUFFER_SIZE 1000
 /***/
 /*E0 and later Interrupt flags.*/
 /***/
@@ -206,11 +217,25 @@ typedef void (*wilc_debug_func)(u32, char *, ...);
  *  Tx/Rx Queue Structure
  *
  /
+struct txq_handle {
+   struct txq_entry_t *txq_head;
+   struct txq_entry_t *txq_tail;
+   u16 count;
+   u8 acm;
+};
+
+enum ip_pkt_priority {
+   AC_VO_Q = 0,
+   AC_VI_Q = 1,
+   AC_BE_Q = 2,
+   AC_BK_Q = 3
+};
 
 struct txq_entry_t {
struct txq_entry_t *next;
struct txq_entry_t *prev;
int type;
+   u8 q_num;
int tcp_pending_ack_idx;
u8 *buffer;
int buffer_size;
-- 
2.7.4




[PATCH 7/7] staging: wilc1000: Update ACM bit status

2017-06-26 Thread Aditya Shankar
Add a new function to update ACM bit status for a queue
for all access categories.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index e323fd4..929166a 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -461,6 +461,14 @@ static inline u8 ac_change(struct wilc *wilc, u8 *ac)
return 1;
 }
 
+static inline void ac_acm_bit(struct wilc *wilc, u32 reg)
+{
+   wilc->txq[AC_BK_Q].acm = (reg & 0x0002) >> BK_AC_ACM_STAT_POS;
+   wilc->txq[AC_BE_Q].acm = (reg & 0x0100) >> BE_AC_ACM_STAT_POS;
+   wilc->txq[AC_VI_Q].acm = (reg & 0x0001) >> VI_AC_ACM_STAT_POS;
+   wilc->txq[AC_VO_Q].acm = (reg & 0x0100) >> VO_AC_ACM_STAT_POS;
+}
+
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
  u32 buffer_size, wilc_tx_complete_func_t func)
 {
-- 
2.7.4




[PATCH 6/7] staging: wilc1000: Change ac based on acm status

2017-06-26 Thread Aditya Shankar
Add a new function to check and alter the ac if needed
based on the acm status for a particular queue.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index b3e1136..e323fd4 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -451,6 +451,16 @@ static inline void ac_pkt_count(u32 reg, u8 *pkt_count)
pkt_count[AC_VO_Q] = (reg & 0xfe00) >> VO_AC_COUNT_POS;
 }
 
+static inline u8 ac_change(struct wilc *wilc, u8 *ac)
+{
+   do {
+   if (wilc->txq[*ac].acm == 0)
+   return 0;
+   (*ac)++;
+   } while (*ac < NQUEUES);
+   return 1;
+}
+
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
  u32 buffer_size, wilc_tx_complete_func_t func)
 {
-- 
2.7.4




[PATCH 1/7] staging: wilc1000: Add support for AC classification.

2017-06-26 Thread Aditya Shankar
This patch adds new variables and defines for adding access
category classification

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.h | 25 +
 1 file changed, 25 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.h 
b/drivers/staging/wilc1000/wilc_wlan.h
index 7a5eba9..c97f94a 100644
--- a/drivers/staging/wilc1000/wilc_wlan.h
+++ b/drivers/staging/wilc1000/wilc_wlan.h
@@ -133,6 +133,17 @@
 
 #define MODALIAS   "WILC_SPI"
 #define GPIO_NUM   0x44
+
+#define NQUEUES4
+#define VO_AC_COUNT_POS25
+#define VO_AC_ACM_STAT_POS 24
+#define VI_AC_COUNT_POS17
+#define VI_AC_ACM_STAT_POS 16
+#define BE_AC_COUNT_POS9
+#define BE_AC_ACM_STAT_POS 8
+#define BK_AC_COUNT_POS2
+#define BK_AC_ACM_STAT_POS 1
+#define AC_BUFFER_SIZE 1000
 /***/
 /*E0 and later Interrupt flags.*/
 /***/
@@ -206,11 +217,25 @@ typedef void (*wilc_debug_func)(u32, char *, ...);
  *  Tx/Rx Queue Structure
  *
  /
+struct txq_handle {
+   struct txq_entry_t *txq_head;
+   struct txq_entry_t *txq_tail;
+   u16 count;
+   u8 acm;
+};
+
+enum ip_pkt_priority {
+   AC_VO_Q = 0,
+   AC_VI_Q = 1,
+   AC_BE_Q = 2,
+   AC_BK_Q = 3
+};
 
 struct txq_entry_t {
struct txq_entry_t *next;
struct txq_entry_t *prev;
int type;
+   u8 q_num;
int tcp_pending_ack_idx;
u8 *buffer;
int buffer_size;
-- 
2.7.4




[PATCH 4/7] staging: wilc1000: Add function to balance packet count

2017-06-26 Thread Aditya Shankar
Add a new function to track the cound of packets and
determine the ratio of current number of packets to
maximum count of packets.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index d1ed3ba8..655f229 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -426,6 +426,23 @@ static inline u8 ac_classify(struct wilc *wilc, struct 
txq_entry_t *tqe)
return ac;
 }
 
+static inline int ac_balance(u8 *count, u8 *ratio)
+{
+   u8 i, max_count = 0;
+
+   if (!count || !ratio)
+   return -1;
+
+   for (i = 0; i < NQUEUES; i++)
+   if (count[i] > max_count)
+   max_count = count[i];
+
+   for (i = 0; i < NQUEUES; i++)
+   ratio[i] = max_count - count[i];
+
+   return 0;
+}
+
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
  u32 buffer_size, wilc_tx_complete_func_t func)
 {
-- 
2.7.4




[PATCH 5/7] staging: wilc1000: Get packet count from firmware

2017-06-26 Thread Aditya Shankar
Add a new function to get packet count from the firmware.

31:25   24  23:17   16  15:98   7:2 1   0
VO CNT  VO ACM  VI CNT  VI ACM  BE CNT  BE ACM  BK CNT  BK ACM  VMM ready

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 655f229..b3e1136 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -443,6 +443,14 @@ static inline int ac_balance(u8 *count, u8 *ratio)
return 0;
 }
 
+static inline void ac_pkt_count(u32 reg, u8 *pkt_count)
+{
+   pkt_count[AC_BK_Q] = (reg & 0x00fa) >> BK_AC_COUNT_POS;
+   pkt_count[AC_BE_Q] = (reg & 0xfe00) >> BE_AC_COUNT_POS;
+   pkt_count[AC_VI_Q] = (reg & 0x00fe) >> VI_AC_COUNT_POS;
+   pkt_count[AC_VO_Q] = (reg & 0xfe00) >> VO_AC_COUNT_POS;
+}
+
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
  u32 buffer_size, wilc_tx_complete_func_t func)
 {
-- 
2.7.4




[PATCH 0/7] Enable access category classification on Tx path

2017-06-26 Thread Aditya Shankar
This patch series adds changes made to implement access
category based data classification and manages buffers allocation
between different access categories on the Tx path.

Aditya Shankar (7):
  staging: wilc1000: Add support for AC classification.
  staging: wilc1000: Add function to calculate ac queue limit
  staging: wilc1000: WMM classification of data
  staging: wilc1000: Add function to balance packet count
  staging: wilc1000: Get packet count from firmware
  staging: wilc1000: Change ac based on acm status
  staging: wilc1000: Update ACM bit status

 drivers/staging/wilc1000/wilc_wlan.c | 136 +++
 drivers/staging/wilc1000/wilc_wlan.h |  25 +++
 2 files changed, 161 insertions(+)

-- 
2.7.4




[PATCH 3/7] staging: wilc1000: WMM classification of data

2017-06-26 Thread Aditya Shankar
This patch adds a new function to classify data to available
WMM access categories based on the DSCP value in the header.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.c | 51 
 1 file changed, 51 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 8c997ba..d1ed3ba8 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -375,6 +375,57 @@ static inline void ac_q_limit(u8 ac, u16 *q_limit)
  sum) + 1;
 }
 
+static inline u8 ac_classify(struct wilc *wilc, struct txq_entry_t *tqe)
+{
+   u8 *eth_hdr_ptr;
+   u8 *buffer = tqe->buffer;
+   u8 ac;
+   u16 h_proto;
+
+   spin_lock_irqsave(>txq_spinlock, wilc->txq_spinlock_flags);
+
+   eth_hdr_ptr = [0];
+   h_proto = ntohs(*((unsigned short *)_hdr_ptr[12]));
+   if (h_proto == ETH_P_IP) {
+   u8 *ip_hdr_ptr;
+   u32 IHL, DSCP;
+
+   ip_hdr_ptr = [ETHERNET_HDR_LEN];
+   IHL = (ip_hdr_ptr[0] & 0xf) << 2;
+   DSCP = (ip_hdr_ptr[1] & 0xfc);
+
+   switch (DSCP) {
+   case 0x20:
+   case 0x40:
+   case 0x08:
+   ac = AC_BK_Q;
+   break;
+   case 0x80:
+   case 0xA0:
+   case 0x28:
+   ac = AC_VI_Q;
+   break;
+   case 0xC0:
+   case 0xd0:
+   case 0xE0:
+   case 0x88:
+   case 0xB8:
+   ac = AC_VO_Q;
+   break;
+   default:
+   ac = AC_BE_Q;
+   break;
+   }
+   } else {
+   ac  = AC_BE_Q;
+   }
+
+   tqe->q_num = ac;
+   spin_unlock_irqrestore(>txq_spinlock, wilc->txq_spinlock_flags);
+
+   return ac;
+}
+
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
  u32 buffer_size, wilc_tx_complete_func_t func)
 {
-- 
2.7.4




[PATCH 2/7] staging: wilc1000: Add function to calculate ac queue limit

2017-06-26 Thread Aditya Shankar
This patch adds a function which calculates the queue limit
for a given access category queue.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan.c | 42 
 1 file changed, 42 insertions(+)

diff --git a/drivers/staging/wilc1000/wilc_wlan.c 
b/drivers/staging/wilc1000/wilc_wlan.c
index 9addef1..8c997ba 100644
--- a/drivers/staging/wilc1000/wilc_wlan.c
+++ b/drivers/staging/wilc1000/wilc_wlan.c
@@ -333,6 +333,48 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, 
u8 *buffer,
return 1;
 }
 
+static inline void ac_q_limit(u8 ac, u16 *q_limit)
+{
+   static bool initialized;
+   static u8 buffer[AC_BUFFER_SIZE];
+   static u16 cnt[NQUEUES];
+   u8 factors[NQUEUES] = {1, 1, 1, 1};
+   static u16 sum;
+   u16 i;
+   static u16 end_index;
+
+   if (!initialized) {
+   for (i = 0; i < AC_BUFFER_SIZE; i++)
+   buffer[i] = i % NQUEUES;
+
+   for (i = 0; i < NQUEUES; i++) {
+   cnt[i] = AC_BUFFER_SIZE * factors[i] / NQUEUES;
+   sum += cnt[i];
+   }
+   end_index = AC_BUFFER_SIZE - 1;
+   initialized = 1;
+   }
+   if (end_index > AC_BUFFER_SIZE - 1)
+   end_index = AC_BUFFER_SIZE - 1;
+
+   cnt[buffer[end_index]] -= factors[buffer[end_index]];
+   cnt[ac] += factors[ac];
+   sum += (factors[ac] - factors[buffer[end_index]]);
+
+   buffer[end_index] = ac;
+   if (end_index > 0)
+   end_index--;
+   else
+   end_index = AC_BUFFER_SIZE - 1;
+
+   for (i = 0; i < NQUEUES; i++)
+   if (!sum)
+   q_limit[i] = 1;
+   else
+   q_limit[i] = (cnt[i] * FLOW_CONTROL_UPPER_THRESHOLD /
+ sum) + 1;
+}
+
 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
  u32 buffer_size, wilc_tx_complete_func_t func)
 {
-- 
2.7.4




Re: [PATCH v5] staging: wilc1000: New cfg packet format in handle_set_wfi_drv_handler

2017-06-13 Thread Aditya Shankar
On Tue, 13 Jun 2017 15:38:27 +0530
Aditya Shankar <aditya.shan...@microchip.com> wrote:

> Change the config packet format used in handle_set_wfi_drv_handler()
> to align the host driver with the new format used in the wilc firmware.
> 
> The change updates the format in which the host driver provides the
> firmware with the drv_handler index and also uses two new
> fields viz. "mode" and 'name" in the config packet along with this index
> to directly provide details about the interface and its mode to the
> firmware instead of having multiple if-else statements in the host driver
> to decide which interface to configure.
> 
> This change requires users to move to the newer version of the wilc
> firmware(14.02 or higher) available on the vendor tree on github or on the
> linux-firmware project.
> 
> Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
> Reviewed-by: Arend Van Spriel <arend.vanspr...@broadcom.com>
> ---
> Change in v2: Fix build warning
> Change in v3: Address review comments from v2
> Change in v4:
> - Address review comments from v3.
> - The new firmwaie is available as part of the commit below
> http://lkml.kernel.org/r/1496479001-2733-1-git-send-email-aditya.shan...@microchip.com
> Change in v5: remove repeated code
> - Will update the firmware name as part of a separate patch.
> ---
>  drivers/staging/wilc1000/host_interface.c | 63 
> +--
>  drivers/staging/wilc1000/host_interface.h |  9 +++-
>  drivers/staging/wilc1000/linux_wlan.c | 37 -
>  drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  2 +-
>  drivers/staging/wilc1000/wilc_wfi_netdevice.h |  1 +
>  drivers/staging/wilc1000/wilc_wlan_if.h   |  2 +-
>  6 files changed, 67 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/staging/wilc1000/host_interface.c 
> b/drivers/staging/wilc1000/host_interface.c
> index c8e3229..be806fc 100644
> --- a/drivers/staging/wilc1000/host_interface.c
> +++ b/drivers/staging/wilc1000/host_interface.c
> @@ -329,25 +329,50 @@ static void handle_set_channel(struct wilc_vif *vif,
>   netdev_err(vif->ndev, "Failed to set channel\n");
>  }
>  
> -static void handle_set_wfi_drv_handler(struct wilc_vif *vif,
> -struct drv_handler *hif_drv_handler)
> +static int handle_set_wfi_drv_handler(struct wilc_vif *vif,
> +   struct drv_handler *hif_drv_handler)
>  {
>   int ret = 0;
>   struct wid wid;
> + u8 *currbyte, *buffer;
> + struct host_if_drv *hif_drv = NULL;
> +
> + if (!vif->hif_drv)
> + return -EINVAL;
> +
> + if (!hif_drv_handler)
> + return -EINVAL;
> +
> + hif_drv = vif->hif_drv;
> +
> + buffer = kzalloc(DRV_HANDLER_SIZE, GFP_KERNEL);
> + if (!buffer)
> + return -ENOMEM;
> +
> + currbyte = buffer;
> + *currbyte = hif_drv->driver_handler_id & DRV_HANDLER_MASK;
> + currbyte++;
> + *currbyte = (u32)0 & DRV_HANDLER_MASK;
> + currbyte++;
> + *currbyte = (u32)0 & DRV_HANDLER_MASK;
> + currbyte++;
> + *currbyte = (u32)0 & DRV_HANDLER_MASK;
> + currbyte++;
> + *currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
>  
>   wid.id = (u16)WID_SET_DRV_HANDLER;
>   wid.type = WID_STR;
> - wid.val = (s8 *)hif_drv_handler;
> - wid.size = sizeof(*hif_drv_handler);
> + wid.val = (s8 *)buffer;
> + wid.size = DRV_HANDLER_SIZE;
>  
>   ret = wilc_send_config_pkt(vif, SET_CFG, , 1,
> -hif_drv_handler->handler);
> -
> - if (!hif_drv_handler->handler)
> - complete(_driver_comp);
> -
> +hif_drv->driver_handler_id);
>   if (ret)
>   netdev_err(vif->ndev, "Failed to set driver handler\n");
> +
> + complete(_driver_comp);
> + kfree(buffer);
> + return ret;
>  }
>  
>  static void handle_set_operation_mode(struct wilc_vif *vif,
> @@ -2389,9 +2414,9 @@ static void Handle_SetMulticastFilter(struct wilc_vif 
> *vif,
>  
>   pu8CurrByte = wid.val;
>   *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
> - *pu8CurrByte++ = 0;
> - *pu8CurrByte++ = 0;
> - *pu8CurrByte++ = 0;
> + *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
> + *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
> + *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
>  
>  

[PATCH v5] staging: wilc1000: New cfg packet format in handle_set_wfi_drv_handler

2017-06-13 Thread Aditya Shankar
Change the config packet format used in handle_set_wfi_drv_handler()
to align the host driver with the new format used in the wilc firmware.

The change updates the format in which the host driver provides the
firmware with the drv_handler index and also uses two new
fields viz. "mode" and 'name" in the config packet along with this index
to directly provide details about the interface and its mode to the
firmware instead of having multiple if-else statements in the host driver
to decide which interface to configure.

This change requires users to move to the newer version of the wilc
firmware(14.02 or higher) available on the vendor tree on github or on the
linux-firmware project.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
Reviewed-by: Arend Van Spriel <arend.vanspr...@broadcom.com>
---
Change in v2: Fix build warning
Change in v3: Address review comments from v2
Change in v4:
- Address review comments from v3.
- The new firmwaie is available as part of the commit below
http://lkml.kernel.org/r/1496479001-2733-1-git-send-email-aditya.shan...@microchip.com
Change in v5: remove repeated code
- Will update the firmware name as part of a separate patch.
---
 drivers/staging/wilc1000/host_interface.c | 63 +--
 drivers/staging/wilc1000/host_interface.h |  9 +++-
 drivers/staging/wilc1000/linux_wlan.c | 37 -
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  2 +-
 drivers/staging/wilc1000/wilc_wfi_netdevice.h |  1 +
 drivers/staging/wilc1000/wilc_wlan_if.h   |  2 +-
 6 files changed, 67 insertions(+), 47 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index c8e3229..be806fc 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -329,25 +329,50 @@ static void handle_set_channel(struct wilc_vif *vif,
netdev_err(vif->ndev, "Failed to set channel\n");
 }
 
-static void handle_set_wfi_drv_handler(struct wilc_vif *vif,
-  struct drv_handler *hif_drv_handler)
+static int handle_set_wfi_drv_handler(struct wilc_vif *vif,
+ struct drv_handler *hif_drv_handler)
 {
int ret = 0;
struct wid wid;
+   u8 *currbyte, *buffer;
+   struct host_if_drv *hif_drv = NULL;
+
+   if (!vif->hif_drv)
+   return -EINVAL;
+
+   if (!hif_drv_handler)
+   return -EINVAL;
+
+   hif_drv = vif->hif_drv;
+
+   buffer = kzalloc(DRV_HANDLER_SIZE, GFP_KERNEL);
+   if (!buffer)
+   return -ENOMEM;
+
+   currbyte = buffer;
+   *currbyte = hif_drv->driver_handler_id & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
 
wid.id = (u16)WID_SET_DRV_HANDLER;
wid.type = WID_STR;
-   wid.val = (s8 *)hif_drv_handler;
-   wid.size = sizeof(*hif_drv_handler);
+   wid.val = (s8 *)buffer;
+   wid.size = DRV_HANDLER_SIZE;
 
ret = wilc_send_config_pkt(vif, SET_CFG, , 1,
-  hif_drv_handler->handler);
-
-   if (!hif_drv_handler->handler)
-   complete(_driver_comp);
-
+  hif_drv->driver_handler_id);
if (ret)
netdev_err(vif->ndev, "Failed to set driver handler\n");
+
+   complete(_driver_comp);
+   kfree(buffer);
+   return ret;
 }
 
 static void handle_set_operation_mode(struct wilc_vif *vif,
@@ -2389,9 +2414,9 @@ static void Handle_SetMulticastFilter(struct wilc_vif 
*vif,
 
pu8CurrByte = wid.val;
*pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
 
*pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
*pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
@@ -2449,6 +2474,7 @@ static void host_if_work(struct work_struct *work)
 {
struct host_if_msg *msg;
struct wilc *wilc;
+   int ret = 0;
 
msg = container_of(work, struct host_if_msg, work);
wilc = msg->vif->wilc;
@@ -2554,7 +2580,7 @@ static void host_if_work(struct work_struct *work)
break;
 
case HOST_IF_MSG_SET_WFIDRV_HANDLER:
-   handle_set_wfi_drv_handler(ms

[PATCH v4] staging: wilc1000: New cfg packet format in handle_set_wfi_drv_handler

2017-06-07 Thread Aditya Shankar
Change the config packet format used in handle_set_wfi_drv_handler()
to align the host driver with the new format used in the wilc firmware.

The change updates the format in which the host driver provides the
firmware with the drv_handler index and also uses two new
fields viz. "mode" and 'name" in the config packet along with this index
to directly provide details about the interface and its mode to the
firmware instead of having multiple if-else statements in the host driver
to decide which interface to configure.

This change requires users to move to the newer version of the wilc
firmware(14.02 or higher) available on the vendor tree on github or on the
linux-firmware project. The existing firmware files on the linux-firmware
project are very old and best not used.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
Reviewed-by: Arend Van Spriel <arend.vanspr...@broadcom.com>
---
Change in v2: Fix build warning
Change in v3: Address review comments from v2
Change in v4:
- Address review comments from v3.
- The new firmwaie is available as part of the commit below
http://lkml.kernel.org/r/1496479001-2733-1-git-send-email-aditya.shan...@microchip.com
- Will update the firmware name as part of a separate patch.
---
 drivers/staging/wilc1000/host_interface.c | 68 +--
 drivers/staging/wilc1000/host_interface.h |  9 ++-
 drivers/staging/wilc1000/linux_wlan.c | 37 
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  2 +-
 drivers/staging/wilc1000/wilc_wfi_netdevice.h |  1 +
 drivers/staging/wilc1000/wilc_wlan_if.h   |  2 +-
 6 files changed, 71 insertions(+), 48 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index c8e3229..f7c22d7 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -329,25 +329,53 @@ static void handle_set_channel(struct wilc_vif *vif,
netdev_err(vif->ndev, "Failed to set channel\n");
 }
 
-static void handle_set_wfi_drv_handler(struct wilc_vif *vif,
-  struct drv_handler *hif_drv_handler)
+static int handle_set_wfi_drv_handler(struct wilc_vif *vif,
+ struct drv_handler *hif_drv_handler)
 {
int ret = 0;
struct wid wid;
+   u8 *currbyte, *buffer;
+   struct host_if_drv *hif_drv = NULL;
+
+   if (!vif->hif_drv)
+   return -EINVAL;
+
+   if (!hif_drv_handler)
+   return -EINVAL;
+
+   hif_drv = vif->hif_drv;
+
+   buffer = kzalloc(DRV_HANDLER_SIZE, GFP_KERNEL);
+   if (!buffer)
+   return -ENOMEM;
+
+   currbyte = buffer;
+   *currbyte = hif_drv->driver_handler_id & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
 
wid.id = (u16)WID_SET_DRV_HANDLER;
wid.type = WID_STR;
-   wid.val = (s8 *)hif_drv_handler;
-   wid.size = sizeof(*hif_drv_handler);
+   wid.val = (s8 *)buffer;
+   wid.size = DRV_HANDLER_SIZE;
 
ret = wilc_send_config_pkt(vif, SET_CFG, , 1,
-  hif_drv_handler->handler);
-
-   if (!hif_drv_handler->handler)
-   complete(_driver_comp);
-
-   if (ret)
+  hif_drv->driver_handler_id);
+   if (ret) {
netdev_err(vif->ndev, "Failed to set driver handler\n");
+   complete(_driver_comp);
+   kfree(buffer);
+   return ret;
+   }
+   complete(_driver_comp);
+   kfree(buffer);
+   return 0;
 }
 
 static void handle_set_operation_mode(struct wilc_vif *vif,
@@ -2389,9 +2417,9 @@ static void Handle_SetMulticastFilter(struct wilc_vif 
*vif,
 
pu8CurrByte = wid.val;
*pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
 
*pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
*pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
@@ -2449,6 +2477,7 @@ static void host_if_work(struct work_struct *work)
 {
struct host_if_msg *msg;
struct wilc *wilc;
+   int ret = 0;
 
msg = container_of(work, struct host_if_msg, work);
wilc = msg->vif->wilc;
@@ -2554,7 +25

[PATCH] linux-firmware: wilc1000: Add unified firmware for wilc1000 WLAN

2017-06-03 Thread Aditya Shankar
This commit adds a new unified firmware for the wilc1000
staging driver with below items addressed.

- Single firmware supports STA, AP and P2P modes.
- Support suspend/resume on WILC1000.
- Verify PS stability for WILC1000.
- Bug fixes

Version of FW: v14.04

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 WHENCE   |   1 +
 atmel/wilc1000_wifi_firmware.bin | Bin 0 -> 136344 bytes
 2 files changed, 1 insertion(+)
 create mode 100755 atmel/wilc1000_wifi_firmware.bin

diff --git a/WHENCE b/WHENCE
index 2d17e2e..e24cbd0 100644
--- a/WHENCE
+++ b/WHENCE
@@ -3482,6 +3482,7 @@ Driver: wilc1000 - Atmel 802.11n WLAN driver for WILC1000
 File: atmel/wilc1000_fw.bin
 File: atmel/wilc1000_ap_fw.bin
 File: atmel/wilc1000_p2p_fw.bin
+File: atmel/wilc1000_wifi_firmware.bin
 
 License: Redistributable. See LICENSE.atmel for details
 
diff --git a/atmel/wilc1000_wifi_firmware.bin b/atmel/wilc1000_wifi_firmware.bin
new file mode 100755
index 
..13c74be16f250e446bfa6b5a6045d3b0e8e7954a
GIT binary patch
literal 136344
zcmbrn4|r77nLmDJ=H_G|moP8`x!S0cWW0$mB$E)yC`kzNw}KcXX3~l}fiR&^t+(
z@Fzr=T5ExJ$><g)RUe?Xh^U)EY8Y#~B+ibyWcv$|8nx6WV8tzBgb|sH(&%?tK|DM4+J$vl>|MdR$ZiALa
z?~06XJQcaf$J2WY+rA(9rPHpKPqtBYl5KyY>C5TK{L%lHHn8oj|IW6b?l5c@EyrFH
zm1Dm=$`sPb^B6aNc}SZQaGdPj47<H5g)%A=*CS1DIbkyNAv4*t!ounMQb%#l=4
zQOZT{vDZfBdADq)_Qc9#uQ|QzYLSy{XV5-d?6c2S1y|c8#qoap;=wP_lFO;IT3q$!
z%KsjARt^tWuZh%w~@(|elFDCG;}e{mw2Z(`0$HYZsonrdg!)I277Uo}MQ9ZaZ=
z)=Ml}?=oSW7=hkTrp;AfR~M;2@-5Ev6dO{^mBSAudlv0Vso>uAuE>%wA@3D%)*N
zFPo$~<zb{u0*v%_KC`;=IKt0lHEG*eIWT7+8Udoe?=+2#tEE15pSjpoW0
z=Gzzv=y}^GQQjw%H?bOdDKxW+tND*!%^#+GgI4#*OJZUU`)#h4%T1^KAq)DgaMzm+
znXXA}o!5f-n+=%1!Bt<qS{o_G-P{vZoF=nkz<cHoql&{wwKOQDMpIEI)rJSKOU=YX
zP<7zR!{fx`(jZ%mmfd(t@l+snKAy#Rmg1?zQ-!An_RAJau^1;#r4B!PAUq6P{K)
z+wnY%=TWq^8_ym*k2A5-AVfVDX09~4oRyX;;qJ%+n!!XiDMN>Dp0;vHoH1{2#af7+
zHjB95YZdo6Ekd6-`2Nez?K8|gUvLRa8}3PGu~WtrQ4vh?R@KP267=Oj<on`@I%caC
zrgeq8-aaCvvXXGg+r{1SxXTkviB%ST7CSL{qPyb5GSR-<7@2$W0%MVG(cb5xw=3ru
zwQAy9(BfvjMf(PRf2Qj;R^=I3UcK74=D-G*C$nNMyZoSMMRi@`+qHvTzHepac19)m
z!UG#tdQY%kZw2f4IRm!aYA<s;^$)TX<lZt3K}mBg=Fd3@vL{dYPemo}OweYFQiJ
zkb=_HD_ZKp8#vxpRty`$8`X6=j0j?>>zcD(j>d39B-ulg`rr}9lBhtdLbx0qSWCb`Au(MkgvIwb6Em;F^O5x;2vM1zOBG6ARM
z1RZ-@OLLV!;+NV|FdDJ2>y*^SSy#W*mdd)`l-kU!>$KE1j&=Q3Y8%hG-l95gZ=!`-
z`jXl(F0_!>W<(213ok2Or?gT^qLg1RWz<U9+eCYF;pJw%j5@_}D)yEW#MQaq!W_ps
zzWDpF+m)zSNcBYfKJEYM>o{vjNoA2N(f*2-BKX6~%JS*Yr!c`KR)DV97r)f-ioWB_
zUeF6gusFTL!z26K;tH%&9%k6n8buRqE{|yMEnHV=VG)nZ=W2=6>Z20vj`_Rhk7sG7
zRAxTGT;@U0he6iiJn`_8t~0J*^MehOQdt`C(A63{P}dx36`CS#uC|s_cyH5NH+Q(s
zyI!k06*BEYE3v-NI6WOL)Y}$RgTm?GtRvEO#FEP5zv|eskxPi){9$bmqv4+U>@%
zYsK?L`x$NSV^=`53q@as_^8rjAj)UZ{4R8H^g+<f)aovIJcW(jL87weC}E9TZ+i^Z
z;JmR@UX`9V1|LLadlB-K-9=reK&$`Z$Ry?d@-W*_F1Q?ieO$s^zQWwcTw>?bHt~e=
zlDNNug|$-oLB$l0LTt!z4aNg*0CJt8t8>+^B
zIohvd$wSz0N@p2g=~|#(R}w5SNwW+rRur`En>CRI$H$alTAn<W<&{ij@thvBD#Qb!
z6xGB7pczfEiqLsSRs5Twvr)7mDW_kG`8%SFsXh%?!2(1IX(u0gPs4Pjrkr52Pn)^8
zN1ErpMP#BYlL<p|VR+C}-ta#5&@I4Nq{)T!CGDvx4-eJ?7MZ2HzHeZ(c1k(FE$w}g
zoxH`sB*lxo+VYq`Xi7VpmdH

Re: [PATCH v3] staging: wilc1000: New cfg packet format in handle_set_wfi_drv_handler

2017-04-12 Thread Aditya Shankar
On Tue, 11 Apr 2017 19:35:46 +0200
Greg KH <gre...@linuxfoundation.org> wrote:

> On Tue, Apr 11, 2017 at 10:11:43PM +0530, Aditya Shankar wrote:
> > Change the config packet format used in handle_set_wfi_drv_handler()
> > to align the host driver with the new format used in the wilc firmware.  
> 
> So does this break devices with "old" firmware?
> 
> Where is the "new" firmware?  What is enforcing the usage only of new
> firmware?
> 
> thanks,
> 
> greg k-h

Yes, this new change would break devices with firmware older than ver 
14.2(released on our vendor tree in March 2016). The older firmware in the 
linux-firmware repository is close to 2 years old and not being used with the 
staging driver even before this change  was submitted. Developers picked up the 
firmware mostly from one of our vendor trees on github.

To resolve this confusion about firmware location, I submitted a patch to 
linux-firmware to make the latest firmware available through this channel. 
Below are the details. The driver currently does not enforce usage of new 
firmware but would fail to properly configure the older firmware.

---

From: Aditya Shankar <aditya.shan...@microchip.com>
To: <linux-firmw...@kernel.org>
CC: <linux-wireless@vger.kernel.org>, <ganesh.kris...@microchip.com>, "Aditya 
Shankar" <aditya.shan...@microchip.com>
Subject: [PATCH] linux-firmware: wilc1000: Update firmware for wilc1000
Date: Wed, 5 Apr 2017 13:57:19 +0530


This commit updates the wilc1000 firmware
to the latest version and replaces the three older
firmware binaries as we no longer need seperate binaries
for all the wlan modes.

---

Thanks,
Aditya


[PATCH v3] staging: wilc1000: New cfg packet format in handle_set_wfi_drv_handler

2017-04-11 Thread Aditya Shankar
Change the config packet format used in handle_set_wfi_drv_handler()
to align the host driver with the new format used in the wilc firmware.

The change updates the format in which the host driver provides the
firmware with the drv_handler index and also uses two new
fields viz. "mode" and 'name" in the config packet along with this index
to directly provide details about the interface and its mode to the
firmware instead of having multiple if-else statements in the host driver
to decide which interface to configure.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
Reviewed-by: Arend Van Spriel <arend.vanspr...@broadcom.com>
---
Change in v2: Fix build warning
Change in v3: Address review comments from v2
---
 drivers/staging/wilc1000/host_interface.c | 48 ++-
 drivers/staging/wilc1000/host_interface.h |  9 -
 drivers/staging/wilc1000/linux_wlan.c | 37 +
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  2 +-
 drivers/staging/wilc1000/wilc_wfi_netdevice.h |  1 +
 drivers/staging/wilc1000/wilc_wlan_if.h   |  2 +-
 6 files changed, 59 insertions(+), 40 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index c3a8af0..7352488 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -334,14 +334,39 @@ static void handle_set_wfi_drv_handler(struct wilc_vif 
*vif,
 {
int ret = 0;
struct wid wid;
+   u8 *currbyte, *buffer;
+   struct host_if_drv *hif_drv = NULL;
+
+   if (!vif->hif_drv)
+   return;
+
+   if (!hif_drv_handler)
+   return;
+
+   hif_drv = vif->hif_drv;
+   buffer = kzalloc(DRV_HANDLER_SIZE, GFP_ATOMIC);
+
+   if (!buffer)
+   return;
+
+   currbyte = buffer;
+   *currbyte = hif_drv->driver_handler_id & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
 
wid.id = (u16)WID_SET_DRV_HANDLER;
wid.type = WID_STR;
-   wid.val = (s8 *)hif_drv_handler;
-   wid.size = sizeof(*hif_drv_handler);
+   wid.val = (s8 *)buffer;
+   wid.size = DRV_HANDLER_SIZE;
 
ret = wilc_send_config_pkt(vif, SET_CFG, , 1,
-  hif_drv_handler->handler);
+  hif_drv->driver_handler_id);
 
if (!hif_drv_handler->handler)
complete(_driver_comp);
@@ -2403,9 +2428,9 @@ static void Handle_SetMulticastFilter(struct wilc_vif 
*vif,
 
pu8CurrByte = wid.val;
*pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
 
*pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
*pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
@@ -3099,7 +3124,8 @@ int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 
channel)
return 0;
 }
 
-int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mac_idx)
+int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode,
+u8 ifc_id)
 {
int result = 0;
struct host_if_msg msg;
@@ -3107,7 +3133,8 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int 
index, u8 mac_idx)
memset(, 0, sizeof(struct host_if_msg));
msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
msg.body.drv.handler = index;
-   msg.body.drv.mac_idx = mac_idx;
+   msg.body.drv.mode = mode;
+   msg.body.drv.name = ifc_id;
msg.vif = vif;
 
result = wilc_enqueue_cmd();
@@ -3330,6 +3357,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv 
**hif_drv_handler)
for (i = 0; i < wilc->vif_num; i++)
if (dev == wilc->vif[i]->ndev) {
wilc->vif[i]->hif_drv = hif_drv;
+   hif_drv->driver_handler_id = i + 1;
break;
}
 
@@ -3403,7 +3431,7 @@ int wilc_deinit(struct wilc_vif *vif)
del_timer_sync(_rssi);
del_timer_sync(_drv->remain_on_ch_timer);
 
-   wilc_set_wfi_drv_handler(vif, 0, 0);
+   wilc_set_wfi_drv_handler(vif, 0, 0, 0);
wait_for_completion(_driver_comp);
 
if (hif_drv->usr_scan_req.scan_result) {
@@ -3449,8 +3477,10 @@ void wilc_network_info_re

[PATCH v2] staging: wilc1000: New cfg packet format in handle_set_wfi_drv_handler

2017-04-09 Thread Aditya Shankar
Change the config packet format used in handle_set_wfi_drv_handler()
to align the host driver with the new format used in the wilc firmware.

The change updates the format in which the host driver provides the
firmware with the drv_handler index and also uses two new
fields viz. "mode" and 'name" in the config packet along with this index
to directly provide details about the interface and its mode to the
firmware instead of having multiple if-else statements in the host driver
to decide which interface to configure.

Change in v2:
Fixed build warning

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/host_interface.c | 54 +++
 drivers/staging/wilc1000/host_interface.h |  9 +++-
 drivers/staging/wilc1000/linux_wlan.c | 29 +++-
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  2 +-
 drivers/staging/wilc1000/wilc_wlan_if.h   |  2 +-
 5 files changed, 59 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index c3a8af0..ad1e625 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -198,6 +198,7 @@ struct host_if_msg {
union message_body body;
struct wilc_vif *vif;
struct work_struct work;
+   void *drv_handler;
 };
 
 struct join_bss_param {
@@ -334,14 +335,42 @@ static void handle_set_wfi_drv_handler(struct wilc_vif 
*vif,
 {
int ret = 0;
struct wid wid;
+   u8 *currbyte;
+   struct host_if_drv *hif_drv = NULL;
+   int driver_handler_id = 0;
+   u8 *buffer = kzalloc(DRV_HANDLER_SIZE, GFP_ATOMIC);
+
+   if (!vif->hif_drv)
+   return;
+
+   if (!hif_drv_handler)
+   return;
+
+   hif_drv = vif->hif_drv;
+
+   if (hif_drv)
+   driver_handler_id = hif_drv->driver_handler_id;
+   else
+   driver_handler_id = 0;
+
+   currbyte = buffer;
+   *currbyte = driver_handler_id & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
 
wid.id = (u16)WID_SET_DRV_HANDLER;
wid.type = WID_STR;
-   wid.val = (s8 *)hif_drv_handler;
-   wid.size = sizeof(*hif_drv_handler);
+   wid.val = (s8 *)buffer;
+   wid.size = DRV_HANDLER_SIZE;
 
ret = wilc_send_config_pkt(vif, SET_CFG, , 1,
-  hif_drv_handler->handler);
+  driver_handler_id);
 
if (!hif_drv_handler->handler)
complete(_driver_comp);
@@ -2403,9 +2432,9 @@ static void Handle_SetMulticastFilter(struct wilc_vif 
*vif,
 
pu8CurrByte = wid.val;
*pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
 
*pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
*pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
@@ -3099,7 +3128,8 @@ int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 
channel)
return 0;
 }
 
-int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mac_idx)
+int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, char
+*ifname)
 {
int result = 0;
struct host_if_msg msg;
@@ -3107,9 +3137,14 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int 
index, u8 mac_idx)
memset(, 0, sizeof(struct host_if_msg));
msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
msg.body.drv.handler = index;
-   msg.body.drv.mac_idx = mac_idx;
+   msg.body.drv.mode = mode;
msg.vif = vif;
 
+   if (!memcmp(ifname, "wlan0", 5))
+   msg.body.drv.name = 1;
+   else if (!memcmp(ifname, "p2p0", 4))
+   msg.body.drv.name = 0;
+
result = wilc_enqueue_cmd();
if (result) {
netdev_err(vif->ndev, "wilc mq send fail\n");
@@ -3330,6 +3365,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv 
**hif_drv_handler)
for (i = 0; i < wilc->vif_num; i++)
if (dev == wilc->vif[i]->ndev) {
wilc->vif[i]->hif_drv = hif_drv;
+   hif_drv->driver_handler_id = i + 1;
break;
}
 
@

[PATCH] staging: wilc1000: New cfg packet format in handle_set_wfi_drv_handler

2017-04-09 Thread Aditya Shankar
Change the config packet format used in handle_set_wfi_drv_handler()
to align the host driver with the new format used in the wilc firmware.

The change updates the format in which the host driver provides the
firmware with the drv_handler index and also uses two new
fields viz. "mode" and 'name" in the config packet along with this index
to directly provide details about the interface and its mode to the
firmware instead of having multiple if-else statements in the host driver
to decide which interface to configure.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/host_interface.c | 55 +++
 drivers/staging/wilc1000/host_interface.h |  9 +++-
 drivers/staging/wilc1000/linux_wlan.c | 29 +++-
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  2 +-
 drivers/staging/wilc1000/wilc_wlan_if.h   |  2 +-
 5 files changed, 60 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index c3a8af0..8493505 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -198,6 +198,7 @@ struct host_if_msg {
union message_body body;
struct wilc_vif *vif;
struct work_struct work;
+   void *drv_handler;
 };
 
 struct join_bss_param {
@@ -334,14 +335,43 @@ static void handle_set_wfi_drv_handler(struct wilc_vif 
*vif,
 {
int ret = 0;
struct wid wid;
+   u8 *currbyte;
+   struct host_if_drv *hif_drv = NULL;
+   int driver_handler_id = 0;
+
+   if (!vif->hif_drv)
+   return;
+
+   if (!hif_drv_handler)
+   return;
+
+   hif_drv = vif->hif_drv;
+
+   u8 *buffer = kzalloc(DRV_HANDLER_SIZE, GFP_ATOMIC);
+
+   if (hif_drv)
+   driver_handler_id = hif_drv->driver_handler_id;
+   else
+   driver_handler_id = 0;
+
+   currbyte = buffer;
+   *currbyte = driver_handler_id & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
 
wid.id = (u16)WID_SET_DRV_HANDLER;
wid.type = WID_STR;
-   wid.val = (s8 *)hif_drv_handler;
-   wid.size = sizeof(*hif_drv_handler);
+   wid.val = (s8 *)buffer;
+   wid.size = DRV_HANDLER_SIZE;
 
ret = wilc_send_config_pkt(vif, SET_CFG, , 1,
-  hif_drv_handler->handler);
+  driver_handler_id);
 
if (!hif_drv_handler->handler)
complete(_driver_comp);
@@ -2403,9 +2433,9 @@ static void Handle_SetMulticastFilter(struct wilc_vif 
*vif,
 
pu8CurrByte = wid.val;
*pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
 
*pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
*pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
@@ -3099,7 +3129,8 @@ int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 
channel)
return 0;
 }
 
-int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mac_idx)
+int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, char
+*ifname)
 {
int result = 0;
struct host_if_msg msg;
@@ -3107,9 +3138,14 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int 
index, u8 mac_idx)
memset(, 0, sizeof(struct host_if_msg));
msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
msg.body.drv.handler = index;
-   msg.body.drv.mac_idx = mac_idx;
+   msg.body.drv.mode = mode;
msg.vif = vif;
 
+   if (!memcmp(ifname, "wlan0", 5))
+   msg.body.drv.name = 1;
+   else if (!memcmp(ifname, "p2p0", 4))
+   msg.body.drv.name = 0;
+
result = wilc_enqueue_cmd();
if (result) {
netdev_err(vif->ndev, "wilc mq send fail\n");
@@ -3330,6 +3366,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv 
**hif_drv_handler)
for (i = 0; i < wilc->vif_num; i++)
if (dev == wilc->vif[i]->ndev) {
wilc->vif[i]->hif_drv = hif_drv;
+   hif_drv->driver_handler_id = i + 1;
break;
}
 
@@ -3403,7 +3440,7 @@ int wilc_deinit(struct wilc

Re: [PATCH] staging: wilc1000: Update handler assignment logic

2017-04-09 Thread Aditya Shankar
On Sat, 8 Apr 2017 13:00:15 +0200
Greg KH <gre...@linuxfoundation.org> wrote:

> On Fri, Apr 07, 2017 at 05:24:05PM +0530, Aditya Shankar wrote:
> > With this update, the host driver is consistent with the
> > implementation on the firmware side with respect to obtaining
> > the driver handler for all modes.
> > With this new format, the calls to set the wilc operation mode
> > is simplified.
> > 
> > Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
> > ---
> >  drivers/staging/wilc1000/host_interface.c | 56 
> > +++
> >  drivers/staging/wilc1000/host_interface.h |  9 +++-
> >  drivers/staging/wilc1000/linux_wlan.c | 29 ++--
> >  drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  2 +-
> >  drivers/staging/wilc1000/wilc_wlan_if.h   |  2 +-
> >  5 files changed, 61 insertions(+), 37 deletions(-)
> > 
> > diff --git a/drivers/staging/wilc1000/host_interface.c 
> > b/drivers/staging/wilc1000/host_interface.c
> > index c3a8af0..c04643e 100644
> > --- a/drivers/staging/wilc1000/host_interface.c
> > +++ b/drivers/staging/wilc1000/host_interface.c
> > @@ -198,6 +198,7 @@ struct host_if_msg {
> > union message_body body;
> > struct wilc_vif *vif;
> > struct work_struct work;
> > +   void *drv_handler;
> >  };
> >  
> >  struct join_bss_param {
> > @@ -334,14 +335,44 @@ static void handle_set_wfi_drv_handler(struct 
> > wilc_vif *vif,
> >  {
> > int ret = 0;
> > struct wid wid;
> > +   u8 *currbyte;
> > +   struct host_if_drv *hif_drv = NULL;
> > +   int driver_handler_id = 0;
> > +   u8 *buffer = kzalloc(DRV_HANDLER_SIZE, GFP_ATOMIC);
> > +
> > +   if (!vif->hif_drv)
> > +   return;
> > +
> > +   if (!hif_drv_handler)
> > +   return;
> > +
> > +   hif_drv = vif->hif_drv;
> > +
> > +   if (hif_drv)
> > +   driver_handler_id = hif_drv->driver_handler_id;
> > +   else
> > +   driver_handler_id = 0;
> > +
> > +   driver_handler_id = hif_drv->driver_handler_id;
> > +
> > +   currbyte = buffer;
> > +   *currbyte = driver_handler_id & DRV_HANDLER_MASK;
> > +   currbyte++;
> > +   *currbyte = (u32)0 & DRV_HANDLER_MASK;
> > +   currbyte++;
> > +   *currbyte = (u32)0 & DRV_HANDLER_MASK;
> > +   currbyte++;
> > +   *currbyte = (u32)0 & DRV_HANDLER_MASK;
> > +   currbyte++;
> > +   *currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
> >  
> > wid.id = (u16)WID_SET_DRV_HANDLER;
> > wid.type = WID_STR;
> > -   wid.val = (s8 *)hif_drv_handler;
> > -   wid.size = sizeof(*hif_drv_handler);
> > +   wid.val = (s8 *)buffer;
> > +   wid.size = DRV_HANDLER_SIZE;
> >  
> > ret = wilc_send_config_pkt(vif, SET_CFG, , 1,
> > -  hif_drv_handler->handler);
> > +  driver_handler_id);
> >  
> > if (!hif_drv_handler->handler)
> > complete(_driver_comp);
> > @@ -2403,9 +2434,9 @@ static void Handle_SetMulticastFilter(struct wilc_vif 
> > *vif,
> >  
> > pu8CurrByte = wid.val;
> > *pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
> > -   *pu8CurrByte++ = 0;
> > -   *pu8CurrByte++ = 0;
> > -   *pu8CurrByte++ = 0;
> > +   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
> > +   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
> > +   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
> >  
> > *pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
> > *pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
> > @@ -3099,7 +3130,8 @@ int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 
> > channel)
> > return 0;
> >  }
> >  
> > -int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mac_idx)
> > +int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, char
> > +*ifname)
> >  {
> > int result = 0;
> > struct host_if_msg msg;
> > @@ -3107,9 +3139,14 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, 
> > int index, u8 mac_idx)
> > memset(, 0, sizeof(struct host_if_msg));
> > msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
> > msg.body.drv.handler = index;
> > -   msg.body.drv.mac_idx = mac_idx;
> > +   msg.body.drv.mode = mode;
> > msg.vif = vif;
> >  
> > +   if (!memcmp(ifname, "wlan0", 5))
> > +   msg.body.drv.name = 1;
> > +   else if (!memcmp(ifname, "p2p0", 4))
> > +   msg.body.drv.name = 0;  
> 
> Does that code look correct to you?
> 
> Always use checkpatch before sending your patches out.
> 
> Also, your changelog is very vague, please explain what is happening
> in your patch much better.
> 
> thanks,
> 
> greg k-h

That's a mistake. I will re-send the patch with a new subject line 
as "staging: wilc1000: New cfg packet format in handle_set_wfi_drv_handler"
and an updated description instead of a v2 of the same change log.

Thanks,
Aditya 



[PATCH] staging: wilc1000: Fix problem with wrong vif index

2017-04-07 Thread Aditya Shankar
The vif->idx value is always 0 for two interfaces.

wl->vif_num = 0;

loop {
 ...

 vif->idx = wl->vif_num;
 ...
 wl->vif_num = i;
  
 i++;
 ...
}

At present, vif->idx is assigned the value of wl->vif_num
at the beginning of this block and device is initialized
based on this index value.
In the next iteration, wl->vif_num is still 0 as it is only updated
later but gets assigned to vif->idx in the beginning. This causes problems
later when we try to reference a particular interface and also while
configuring the firmware.

This patch moves the assignment to vif->idx from the beginning
of the block to after wl->vif_num is updated with latest value of i.

Fixes: commit 735bb39ca3be ("staging: wilc1000: simplify vif[i]->ndev accesses")
Cc: <sta...@vger.kernel.org>
Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/linux_wlan.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/wilc1000/linux_wlan.c 
b/drivers/staging/wilc1000/linux_wlan.c
index cd2f602..a2c2ce6 100644
--- a/drivers/staging/wilc1000/linux_wlan.c
+++ b/drivers/staging/wilc1000/linux_wlan.c
@@ -1232,11 +1232,12 @@ int wilc_netdev_init(struct wilc **wilc, struct device 
*dev, int io_type,
else
strcpy(ndev->name, "p2p%d");
 
-   vif->idx = wl->vif_num;
vif->wilc = *wilc;
vif->ndev = ndev;
wl->vif[i] = vif;
wl->vif_num = i;
+   vif->idx = wl->vif_num;
+
ndev->netdev_ops = _netdev_ops;
 
{
-- 
2.7.4




[PATCH] staging: wilc1000: Update handler assignment logic

2017-04-07 Thread Aditya Shankar
With this update, the host driver is consistent with the
implementation on the firmware side with respect to obtaining
the driver handler for all modes.
With this new format, the calls to set the wilc operation mode
is simplified.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/host_interface.c | 56 +++
 drivers/staging/wilc1000/host_interface.h |  9 +++-
 drivers/staging/wilc1000/linux_wlan.c | 29 ++--
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  2 +-
 drivers/staging/wilc1000/wilc_wlan_if.h   |  2 +-
 5 files changed, 61 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index c3a8af0..c04643e 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -198,6 +198,7 @@ struct host_if_msg {
union message_body body;
struct wilc_vif *vif;
struct work_struct work;
+   void *drv_handler;
 };
 
 struct join_bss_param {
@@ -334,14 +335,44 @@ static void handle_set_wfi_drv_handler(struct wilc_vif 
*vif,
 {
int ret = 0;
struct wid wid;
+   u8 *currbyte;
+   struct host_if_drv *hif_drv = NULL;
+   int driver_handler_id = 0;
+   u8 *buffer = kzalloc(DRV_HANDLER_SIZE, GFP_ATOMIC);
+
+   if (!vif->hif_drv)
+   return;
+
+   if (!hif_drv_handler)
+   return;
+
+   hif_drv = vif->hif_drv;
+
+   if (hif_drv)
+   driver_handler_id = hif_drv->driver_handler_id;
+   else
+   driver_handler_id = 0;
+
+   driver_handler_id = hif_drv->driver_handler_id;
+
+   currbyte = buffer;
+   *currbyte = driver_handler_id & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (u32)0 & DRV_HANDLER_MASK;
+   currbyte++;
+   *currbyte = (hif_drv_handler->name | (hif_drv_handler->mode << 1));
 
wid.id = (u16)WID_SET_DRV_HANDLER;
wid.type = WID_STR;
-   wid.val = (s8 *)hif_drv_handler;
-   wid.size = sizeof(*hif_drv_handler);
+   wid.val = (s8 *)buffer;
+   wid.size = DRV_HANDLER_SIZE;
 
ret = wilc_send_config_pkt(vif, SET_CFG, , 1,
-  hif_drv_handler->handler);
+  driver_handler_id);
 
if (!hif_drv_handler->handler)
complete(_driver_comp);
@@ -2403,9 +2434,9 @@ static void Handle_SetMulticastFilter(struct wilc_vif 
*vif,
 
pu8CurrByte = wid.val;
*pu8CurrByte++ = (strHostIfSetMulti->enabled & 0xFF);
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
-   *pu8CurrByte++ = 0;
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 8) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 16) & 0xFF);
+   *pu8CurrByte++ = ((strHostIfSetMulti->enabled >> 24) & 0xFF);
 
*pu8CurrByte++ = (strHostIfSetMulti->cnt & 0xFF);
*pu8CurrByte++ = ((strHostIfSetMulti->cnt >> 8) & 0xFF);
@@ -3099,7 +3130,8 @@ int wilc_set_mac_chnl_num(struct wilc_vif *vif, u8 
channel)
return 0;
 }
 
-int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mac_idx)
+int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int index, u8 mode, char
+*ifname)
 {
int result = 0;
struct host_if_msg msg;
@@ -3107,9 +3139,14 @@ int wilc_set_wfi_drv_handler(struct wilc_vif *vif, int 
index, u8 mac_idx)
memset(, 0, sizeof(struct host_if_msg));
msg.id = HOST_IF_MSG_SET_WFIDRV_HANDLER;
msg.body.drv.handler = index;
-   msg.body.drv.mac_idx = mac_idx;
+   msg.body.drv.mode = mode;
msg.vif = vif;
 
+   if (!memcmp(ifname, "wlan0", 5))
+   msg.body.drv.name = 1;
+   else if (!memcmp(ifname, "p2p0", 4))
+   msg.body.drv.name = 0;
+
result = wilc_enqueue_cmd();
if (result) {
netdev_err(vif->ndev, "wilc mq send fail\n");
@@ -3330,6 +3367,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv 
**hif_drv_handler)
for (i = 0; i < wilc->vif_num; i++)
if (dev == wilc->vif[i]->ndev) {
wilc->vif[i]->hif_drv = hif_drv;
+   hif_drv->driver_handler_id = i + 1;
break;
}
 
@@ -3403,7 +3441,7 @@ int wilc_deinit(struct wilc_vif *vif)
del_timer_sync(_rssi);
del_timer_sync(_drv->remain_on_ch_timer);
 
-   wilc_set_wfi_drv_handler(vif, 0, 0);
+   wilc_set_wfi_drv_handler(vif, 0, 0, 0);
wait_for_completion(_driver_comp);
 
if (hif_drv->u

[PATCH] staging: wilc1000: Use new format for configuring firmware

2017-04-07 Thread Aditya Shankar
The configuration packet format has changed in the newer wilc
firmware versions 14.2 and up. This update ensures that the
firmware is initialized correctly by the host and configured
in the required mode.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wlan_cfg.c | 59 +++-
 1 file changed, 36 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_wlan_cfg.c 
b/drivers/staging/wilc1000/wilc_wlan_cfg.c
index 926fc16..d3e5b1b 100644
--- a/drivers/staging/wilc1000/wilc_wlan_cfg.c
+++ b/drivers/staging/wilc1000/wilc_wlan_cfg.c
@@ -175,8 +175,9 @@ static int wilc_wlan_cfg_set_byte(u8 *frame, u32 offset, 
u16 id, u8 val8)
buf[0] = (u8)id;
buf[1] = (u8)(id >> 8);
buf[2] = 1;
-   buf[3] = val8;
-   return 4;
+   buf[3] = 0;
+   buf[4] = val8;
+   return 5;
 }
 
 static int wilc_wlan_cfg_set_hword(u8 *frame, u32 offset, u16 id, u16 val16)
@@ -191,10 +192,11 @@ static int wilc_wlan_cfg_set_hword(u8 *frame, u32 offset, 
u16 id, u16 val16)
buf[0] = (u8)id;
buf[1] = (u8)(id >> 8);
buf[2] = 2;
-   buf[3] = (u8)val16;
-   buf[4] = (u8)(val16 >> 8);
+   buf[3] = 0;
+   buf[4] = (u8)val16;
+   buf[5] = (u8)(val16 >> 8);
 
-   return 5;
+   return 6;
 }
 
 static int wilc_wlan_cfg_set_word(u8 *frame, u32 offset, u16 id, u32 val32)
@@ -209,19 +211,20 @@ static int wilc_wlan_cfg_set_word(u8 *frame, u32 offset, 
u16 id, u32 val32)
buf[0] = (u8)id;
buf[1] = (u8)(id >> 8);
buf[2] = 4;
-   buf[3] = (u8)val32;
-   buf[4] = (u8)(val32 >> 8);
-   buf[5] = (u8)(val32 >> 16);
-   buf[6] = (u8)(val32 >> 24);
+   buf[3] = 0;
+   buf[4] = (u8)val32;
+   buf[5] = (u8)(val32 >> 8);
+   buf[6] = (u8)(val32 >> 16);
+   buf[7] = (u8)(val32 >> 24);
 
-   return 7;
+   return 8;
 }
 
 static int wilc_wlan_cfg_set_str(u8 *frame, u32 offset, u16 id, u8 *str, u32 
size)
 {
u8 *buf;
 
-   if ((offset + size + 3) >= MAX_CFG_FRAME_SIZE)
+   if ((offset + size + 4) >= MAX_CFG_FRAME_SIZE)
return 0;
 
buf = [offset];
@@ -229,11 +232,12 @@ static int wilc_wlan_cfg_set_str(u8 *frame, u32 offset, 
u16 id, u8 *str, u32 siz
buf[0] = (u8)id;
buf[1] = (u8)(id >> 8);
buf[2] = (u8)size;
+   buf[3] = (u8)(size >> 8);
 
if ((str) && (size != 0))
-   memcpy([3], str, size);
+   memcpy([4], str, size);
 
-   return (size + 3);
+   return (size + 4);
 }
 
 static int wilc_wlan_cfg_set_bin(u8 *frame, u32 offset, u16 id, u8 *b, u32 
size)
@@ -284,12 +288,12 @@ static void wilc_wlan_parse_response_frame(u8 *info, int 
size)
break;
 
if (g_cfg_byte[i].id == wid) {
-   g_cfg_byte[i].val = info[3];
+   g_cfg_byte[i].val = info[4];
break;
}
i++;
} while (1);
-   len = 2;
+   len = 3;
break;
 
case WID_SHORT:
@@ -298,12 +302,14 @@ static void wilc_wlan_parse_response_frame(u8 *info, int 
size)
break;
 
if (g_cfg_hword[i].id == wid) {
-   g_cfg_hword[i].val = 
cpu_to_le16(info[3] | (info[4] << 8));
+   g_cfg_hword[i].val =
+   cpu_to_le16(info[4] |
+   (info[5] << 8));
break;
}
i++;
} while (1);
-   len = 3;
+   len = 4;
break;
 
case WID_INT:
@@ -312,12 +318,16 @@ static void wilc_wlan_parse_response_frame(u8 *info, int 
size)
break;
 
if (g_cfg_word[i].id == wid) {
-   g_cfg_word[i].val = cpu_to_le32(info[3] 
| (info[4] << 8) | (info[5] << 16) | (info[6] << 24));
+   g_cfg_word[i].val =
+   cpu_to_le32(info[4] |
+   (info[5] << 8) |
+   (info[6] << 16) |
+   (info[7] << 24));

[PATCH v2] staging: wilc1000: Connect to highest RSSI value for required SSID

2017-01-08 Thread Aditya Shankar
Connect to the highest rssi with the required SSID in the shadow
table if the connection criteria is based only on the SSID.
For the first matching SSID, an index to the table is saved.
Later the index is updated if matching SSID has a higher
RSSI value than the last saved index.

However if decision is made based on BSSID, there is only one match
in the table and corresponding index is used.

changes in v2:
initialize sel_bssi_idx to UINT_MAX.
Combine two checks for identifying
sel_bssi_idx value for a SSID.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c 
b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index c1a24f7..507bdf7 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -665,6 +665,7 @@ static int connect(struct wiphy *wiphy, struct net_device 
*dev,
 {
s32 s32Error = 0;
u32 i;
+   u32 sel_bssi_idx = UINT_MAX;
u8 u8security = NO_ENCRYPT;
enum AUTHTYPE tenuAuth_type = ANY;
 
@@ -688,18 +689,24 @@ static int connect(struct wiphy *wiphy, struct net_device 
*dev,
memcmp(last_scanned_shadow[i].ssid,
   sme->ssid,
   sme->ssid_len) == 0) {
-   if (!sme->bssid)
-   break;
-   else
+   if (!sme->bssid) {
+   if (sel_bssi_idx == UINT_MAX ||
+   last_scanned_shadow[i].rssi >
+   last_scanned_shadow[sel_bssi_idx].rssi)
+   sel_bssi_idx = i;
+   } else {
if (memcmp(last_scanned_shadow[i].bssid,
   sme->bssid,
-  ETH_ALEN) == 0)
+  ETH_ALEN) == 0) {
+   sel_bssi_idx = i;
break;
+   }
+   }
}
}
 
-   if (i < last_scanned_cnt) {
-   pstrNetworkInfo = _scanned_shadow[i];
+   if (sel_bssi_idx < last_scanned_cnt) {
+   pstrNetworkInfo = _scanned_shadow[sel_bssi_idx];
} else {
s32Error = -ENOENT;
wilc_connecting = 0;
-- 
2.7.4



Re: [PATCH] staging: wilc1000: Connect to highest RSSI value for required SSID

2017-01-08 Thread Aditya Shankar
On Thu, 5 Jan 2017 15:14:50 +0300
Dan Carpenter <dan.carpen...@oracle.com> wrote:

> On Thu, Jan 05, 2017 at 01:03:41PM +0530, Aditya Shankar wrote:
> > Connect to the highest rssi with the required SSID in the shadow
> > table if the connection criteria is based only on the SSID.
> > For the first matching SSID, an index to the table is saved.
> > Later the index is updated if matching SSID has a higher
> > RSSI value than the last saved index.
> > 
> > However if decision is made based on BSSID, there is only one match
> > in the table and corresponding index is used.
> > 
> > Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
> > ---
> >  drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 20 ++--
> >  1 file changed, 14 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c 
> > b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
> > index c1a24f7..32206b8 100644
> > --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
> > +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
> > @@ -665,6 +665,7 @@ static int connect(struct wiphy *wiphy, struct 
> > net_device *dev,
> >  {
> > s32 s32Error = 0;
> > u32 i;
> > +   u32 sel_bssi_idx = last_scanned_cnt + 1;  
> 
> 
> My understanding from reading the code is that "last_scanned_cnt + 1"
> is a randomly chosen invalid value.  Just saying:
> 
>   sel_bssi_idx = last_scanned_cnt;
> 
> would  also work because it's also invalid and slightly shorter to type.
> But I suggest that you go with something like UINT_MAX because that's
> more clearly invalid.

Thanks. Will change this.
> 
> > u8 u8security = NO_ENCRYPT;
> > enum AUTHTYPE tenuAuth_type = ANY;
> >  
> > @@ -688,18 +689,25 @@ static int connect(struct wiphy *wiphy, struct 
> > net_device *dev,
> > memcmp(last_scanned_shadow[i].ssid,
> >sme->ssid,
> >sme->ssid_len) == 0) {
> > -   if (!sme->bssid)
> > -   break;
> > -   else
> > +   if (!sme->bssid) {
> > +   if (sel_bssi_idx == (last_scanned_cnt + 1))
> > +   sel_bssi_idx = i;
> > +   else if (last_scanned_shadow[i].rssi >
> > +last_scanned_shadow[sel_bssi_idx].rssi)
> > +   sel_bssi_idx = i;  
> 
> Combine these with an ||.
> 
>   if (!sme->bssid) {
>   if (sel_bssi_idx == UINT_MAX ||
>   last_scanned_shadow[i].rssi >
>   last_scanned_shadow[sel_bssi_idx].rssi)
>   sel_bssi_idx = i;
>
>
> 
> In a separate patch, you can reverse the if statement at the start of
> the loop:
> 
>   if (sme->ssid_len != last_scanned_shadow[i].ssid_len ||
>   memcmp(last_scanned_shadow[i].ssid, sme->ssid,
>  sme->ssid_len) != 0)
>   continue;
> 
> That way you can pull these lines in a tab.
> 
> 
> > +   } else {
> > if (memcmp(last_scanned_shadow[i].bssid,
> >sme->bssid,
> > -  ETH_ALEN) == 0)
> > +  ETH_ALEN) == 0){  
> 
> Add a space before the curly brace.
> 
> regards,
> dan carpenter
> 
> 

I shall send an updated patch with the suggested changes and a separate
patch for the change at the beginning of the loop. 

Thanks for your review!

-- 
adiTya


[PATCH] staging: wilc1000: Connect to highest RSSI value for required SSID

2017-01-04 Thread Aditya Shankar
Connect to the highest rssi with the required SSID in the shadow
table if the connection criteria is based only on the SSID.
For the first matching SSID, an index to the table is saved.
Later the index is updated if matching SSID has a higher
RSSI value than the last saved index.

However if decision is made based on BSSID, there is only one match
in the table and corresponding index is used.

Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
---
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 20 ++--
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c 
b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index c1a24f7..32206b8 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -665,6 +665,7 @@ static int connect(struct wiphy *wiphy, struct net_device 
*dev,
 {
s32 s32Error = 0;
u32 i;
+   u32 sel_bssi_idx = last_scanned_cnt + 1;
u8 u8security = NO_ENCRYPT;
enum AUTHTYPE tenuAuth_type = ANY;
 
@@ -688,18 +689,25 @@ static int connect(struct wiphy *wiphy, struct net_device 
*dev,
memcmp(last_scanned_shadow[i].ssid,
   sme->ssid,
   sme->ssid_len) == 0) {
-   if (!sme->bssid)
-   break;
-   else
+   if (!sme->bssid) {
+   if (sel_bssi_idx == (last_scanned_cnt + 1))
+   sel_bssi_idx = i;
+   else if (last_scanned_shadow[i].rssi >
+last_scanned_shadow[sel_bssi_idx].rssi)
+   sel_bssi_idx = i;
+   } else {
if (memcmp(last_scanned_shadow[i].bssid,
   sme->bssid,
-  ETH_ALEN) == 0)
+  ETH_ALEN) == 0){
+   sel_bssi_idx = i;
break;
+   }
+   }
}
}
 
-   if (i < last_scanned_cnt) {
-   pstrNetworkInfo = _scanned_shadow[i];
+   if (sel_bssi_idx < last_scanned_cnt) {
+   pstrNetworkInfo = _scanned_shadow[sel_bssi_idx];
} else {
s32Error = -ENOENT;
wilc_connecting = 0;
-- 
2.7.4



Re: [PATCH 2/2] Revert "staging: wilc1000: Replace kthread with workqueue for host interface"

2016-10-06 Thread Aditya Shankar
On Fri, 30 Sep 2016 15:22:15 +0200
Greg KH <gre...@linuxfoundation.org> wrote:

> On Fri, Sep 30, 2016 at 03:43:18PM +0530, Aditya Shankar wrote:
> > This reverts commit 2518ac59eb27 ("staging: wilc1000: Replace kthread
> > with workqueue for host interface")
> > 
> > This commit breaks wilc1000 driver init. A crash was seen
> > everytime the wlan interface was brought up and wilc device
> > open was attempted. This change is being reverted until we
> > figure out the problem in this change. The driver is
> > usable now with this change reverted.
> > 
> > Signed-off-by: Aditya Shankar <aditya.shan...@microchip.com>
> > 
> > Conflicts:
> > drivers/staging/wilc1000/host_interface.c
> 
> What is this line doing here?
> 
> And shouldn't we add a cc: stable tag as well?  Or at the least, put a
> "fixes:" tag to let people know exactly what commit it is fixing (the
> id that it is reverting.)
> 
> thanks,
> 
> greg k-h

Apologies for this bad commit message.

I have an update on this wilc1000 crash issue. I've figured out
the cause for the crash and fixed it. Therefore,
I request you to ignore the patch I sent out to
revert the change causing the regression. The cause was a misplaced
call to destroy workqueue soon after creating it.
With this removed, the issue is not seen.

I will send out a separate patch to fix the issue.

Thanks,
Aditya