Search Linux Wireless

[PATCH v2 42/50] wilc1000: simplify code by adding header/padding to skb

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When a packet is moved to the chip queue, push the header and add
necessary padding to the socket-buffer directly.

Signed-off-by: David Mosberger-Tang <davidm@xxxxxxxxxx>
---
 .../net/wireless/microchip/wilc1000/netdev.c  |  4 ++
 .../net/wireless/microchip/wilc1000/wlan.c    | 65 +++++++++----------
 2 files changed, 33 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c
index 71cb15f042cdd..d9fbff4bfcd30 100644
--- a/drivers/net/wireless/microchip/wilc1000/netdev.c
+++ b/drivers/net/wireless/microchip/wilc1000/netdev.c
@@ -924,6 +924,10 @@ struct wilc_vif *wilc_netdev_ifc_init(struct wilc *wl, const char *name,
 	if (!ndev)
 		return ERR_PTR(-ENOMEM);
 
+	ndev->needed_headroom = ETH_CONFIG_PKT_HDR_OFFSET;
+	/* we may need up to 3 bytes of padding: */
+	ndev->needed_tailroom = 3;
+
 	vif = netdev_priv(ndev);
 	ndev->ieee80211_ptr = &vif->priv.wdev;
 	strcpy(ndev->name, name);
diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c
index f89ea4839aa61..08f3e96bf72cf 100644
--- a/drivers/net/wireless/microchip/wilc1000/wlan.c
+++ b/drivers/net/wireless/microchip/wilc1000/wlan.c
@@ -626,30 +626,39 @@ static u32 tx_hdr_len(u8 type)
 	}
 }
 
-static u32 vmm_table_entry(struct sk_buff *tqe, u32 vmm_sz)
+static u32 vmm_table_entry(struct sk_buff *tqe)
 {
 	struct wilc_skb_tx_cb *tx_cb = WILC_SKB_TX_CB(tqe);
 	u32 entry;
 
-	entry = vmm_sz / 4;
+	entry = tqe->len / 4;
 	if (tx_cb->type == WILC_CFG_PKT)
 		entry |= WILC_VMM_CFG_PKT;
 	return cpu_to_le32(entry);
 }
 
 /**
- * set_header() - set WILC-specific header
+ * add_hdr_and_pad() - prepare a packet for the chip queue
  * @wilc: Pointer to the wilc structure.
  * @tqe: The packet to add to the chip queue.
+ * @hdr_len: The size of the header to add.
  * @vmm_sz: The final size of the packet, including VMM header and padding.
- * @hdr: Pointer to the header to set
+ *
+ * Bring a packet into the form required by the chip by adding a
+ * header and padding as needed.
  */
-static void set_header(struct wilc *wilc, struct sk_buff *tqe,
-		       u32 vmm_sz, void *hdr)
+static void add_hdr_and_pad(struct wilc *wilc, struct sk_buff *tqe,
+			    u32 hdr_len, u32 vmm_sz)
 {
 	struct wilc_skb_tx_cb *tx_cb = WILC_SKB_TX_CB(tqe);
 	u32 mgmt_pkt = 0, vmm_hdr, prio, data_len = tqe->len;
 	struct wilc_vif *vif;
+	void *hdr;
+
+	/* grow skb with header and pad bytes, all initialized to 0: */
+	hdr = skb_push(tqe, hdr_len);
+	if (vmm_sz > tqe->len)
+		skb_put(tqe, vmm_sz - tqe->len);
 
 	/* add the VMM header word: */
 	if (tx_cb->type == WILC_MGMT_PKT)
@@ -687,8 +696,8 @@ static int schedule_packets(struct wilc *wilc,
 	static const u8 ac_preserve_ratio[NQUEUES] = {1, 1, 1, 1};
 	u8 ac_desired_ratio[NQUEUES];
 	const u8 *num_pkts_to_add;
+	u32 vmm_sz, hdr_len;
 	bool ac_exist = 0;
-	int vmm_sz = 0;
 	struct sk_buff *tqe;
 	struct wilc_skb_tx_cb *tx_cb;
 
@@ -710,8 +719,8 @@ static int schedule_packets(struct wilc *wilc,
 					continue;
 
 				tx_cb = WILC_SKB_TX_CB(tqe);
-				vmm_sz = tx_hdr_len(tx_cb->type);
-				vmm_sz += tqe->len;
+				hdr_len = tx_hdr_len(tx_cb->type);
+				vmm_sz = hdr_len + tqe->len;
 				vmm_sz = ALIGN(vmm_sz, 4);
 
 				if (wilc->chipq_bytes + vmm_sz > WILC_TX_BUFF_SIZE) {
@@ -721,12 +730,13 @@ static int schedule_packets(struct wilc *wilc,
 				}
 				atomic_dec(&wilc->txq_entries);
 
+				add_hdr_and_pad(wilc, tqe, hdr_len, vmm_sz);
+
 				__skb_queue_tail(&wilc->chipq, tqe);
 				wilc->chipq_bytes += tqe->len;
 
-				vmm_table[vmm_table_len] = vmm_table_entry(tqe, vmm_sz);
+				vmm_table[vmm_table_len] = vmm_table_entry(tqe);
 				vmm_table_len++;
-
 			}
 		}
 		num_pkts_to_add = ac_preserve_ratio;
@@ -747,20 +757,13 @@ static int schedule_packets(struct wilc *wilc,
  */
 static int fill_vmm_table(struct wilc *wilc, u32 vmm_table[WILC_VMM_TBL_SIZE])
 {
-	int vmm_table_len = 0, vmm_sz = 0;
+	int vmm_table_len = 0;
 	struct sk_buff *tqe;
-	struct wilc_skb_tx_cb *tx_cb;
 
-	if (unlikely(wilc->chipq_bytes > 0)) {
+	if (unlikely(wilc->chipq_bytes > 0))
 		/* fill in packets that are already on the chipq: */
-		skb_queue_walk(&wilc->chipq, tqe) {
-			tx_cb = WILC_SKB_TX_CB(tqe);
-			vmm_sz = tx_hdr_len(tx_cb->type);
-			vmm_sz += tqe->len;
-			vmm_sz = ALIGN(vmm_sz, 4);
-			vmm_table[vmm_table_len++] = vmm_table_entry(tqe, vmm_sz);
-		}
-	}
+		skb_queue_walk(&wilc->chipq, tqe)
+			vmm_table[vmm_table_len++] = vmm_table_entry(tqe);
 
 	vmm_table_len = schedule_packets(wilc, vmm_table_len, vmm_table);
 	if (vmm_table_len > 0) {
@@ -872,15 +875,12 @@ static int copy_packets(struct wilc *wilc, int entries)
 	u8 ac_pkt_num_to_chip[NQUEUES] = {0, 0, 0, 0};
 	struct wilc_skb_tx_cb *tx_cb;
 	u8 *txb = wilc->tx_buffer;
-	int i, vmm_sz;
+	int i;
+	struct sk_buff *tqe;
 	u32 offset;
 
 	offset = 0;
-	i = 0;
 	do {
-		struct sk_buff *tqe;
-		u32 buffer_offset;
-
 		tqe = __skb_dequeue(&wilc->chipq);
 		if (WARN_ON(!tqe))
 			break;
@@ -889,15 +889,8 @@ static int copy_packets(struct wilc *wilc, int entries)
 		tx_cb = WILC_SKB_TX_CB(tqe);
 		ac_pkt_num_to_chip[tx_cb->q_num]++;
 
-		buffer_offset = tx_hdr_len(tx_cb->type);
-		vmm_sz = buffer_offset;
-		vmm_sz += tqe->len;
-		vmm_sz = ALIGN(vmm_sz, 4);
-
-		set_header(wilc, tqe, vmm_sz, txb + offset);
-		memcpy(&txb[offset + buffer_offset], tqe->data, tqe->len);
-		offset += vmm_sz;
-		i++;
+		memcpy(&txb[offset], tqe->data, tqe->len);
+		offset += tqe->len;
 		wilc_wlan_tx_packet_done(tqe, 1);
 	} while (--entries);
 	for (i = 0; i < NQUEUES; i++)
-- 
2.25.1




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux