2017-06-26 11:44:39

by Aditya Shankar

[permalink] [raw]
Subject: [PATCH v2 0/8] Enable access category classification on Tx path

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


2017-06-26 11:44:41

by Aditya Shankar

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

This patch adds new variables and defines for adding access
category classification

Signed-off-by: Aditya Shankar <[email protected]>
---
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 NQUEUES 4
+#define VO_AC_COUNT_POS 25
+#define VO_AC_ACM_STAT_POS 24
+#define VI_AC_COUNT_POS 17
+#define VI_AC_ACM_STAT_POS 16
+#define BE_AC_COUNT_POS 9
+#define BE_AC_ACM_STAT_POS 8
+#define BK_AC_COUNT_POS 2
+#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

2017-06-26 11:45:04

by Aditya Shankar

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

Add a new function to get packet count from the firmware.

31:25 24 23:17 16 15:9 8 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 <[email protected]>
---
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 & 0x000000fa) >> BK_AC_COUNT_POS;
+ pkt_count[AC_BE_Q] = (reg & 0x0000fe00) >> BE_AC_COUNT_POS;
+ pkt_count[AC_VI_Q] = (reg & 0x00fe0000) >> VI_AC_COUNT_POS;
+ pkt_count[AC_VO_Q] = (reg & 0xfe000000) >> 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

2017-06-29 14:38:08

by Greg Kroah-Hartman

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

On Mon, Jun 26, 2017 at 05:13:27PM +0530, Aditya Shankar wrote:
> This patch adds a new variable in the wilc struct to manage
> ac queues.
>
> Signed-off-by: Aditya Shankar <[email protected]>
> ---
> drivers/staging/wilc1000/wilc_wfi_netdevice.h | 1 +
> 1 file changed, 1 insertion(+)

Wait, what is this whole patch series for? You are adding functions and
variables and not using this functionality at all! Why are you adding
new functionality to the driver now, and not working to get it out of
staging instead?

I'm going to go drop these patches from the tree now...

thanks,

greg k-h

2017-06-26 11:44:59

by Aditya Shankar

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

Add a new function to update ACM bit status for a queue
for all access categories.

Signed-off-by: Aditya Shankar <[email protected]>
---
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 & 0x00000002) >> BK_AC_ACM_STAT_POS;
+ wilc->txq[AC_BE_Q].acm = (reg & 0x00000100) >> BE_AC_ACM_STAT_POS;
+ wilc->txq[AC_VI_Q].acm = (reg & 0x00010000) >> VI_AC_ACM_STAT_POS;
+ wilc->txq[AC_VO_Q].acm = (reg & 0x01000000) >> 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

2017-06-26 11:44:49

by Aditya Shankar

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

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 <[email protected]>
---
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

2017-06-26 11:44:57

by Aditya Shankar

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

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 <[email protected]>
---
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 & 0xfe000000) >> 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

2017-06-26 11:44:56

by Aditya Shankar

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

This patch adds a new variable in the wilc struct to manage
ac queues.

Signed-off-by: Aditya Shankar <[email protected]>
---
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

2017-06-26 11:44:47

by Aditya Shankar

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

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 <[email protected]>
---
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(&wilc->txq_spinlock, wilc->txq_spinlock_flags);
+
+ eth_hdr_ptr = &buffer[0];
+ h_proto = ntohs(*((unsigned short *)&eth_hdr_ptr[12]));
+ if (h_proto == ETH_P_IP) {
+ u8 *ip_hdr_ptr;
+ u32 IHL, DSCP;
+
+ ip_hdr_ptr = &buffer[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(&wilc->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

2017-06-26 11:44:44

by Aditya Shankar

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

This patch adds a function which calculates the queue limit
for a given access category queue.

Signed-off-by: Aditya Shankar <[email protected]>
---
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