Browse Source

qcacmn: Linearize nbuf in intra-bss forwaring case

with fragmented pkts re-injected back to REO destination
ring as frag_list, we need to linearize these nbufs while
handling intra-bss forwarding cases.

Change-Id: Id692974ac5d80f369fafae39aec32e2066dffb0b
Tallapragada Kalyan 7 years ago
parent
commit
32e74e669d
3 changed files with 34 additions and 0 deletions
  1. 10 0
      dp/wifi3.0/dp_rx.c
  2. 6 0
      qdf/inc/qdf_nbuf.h
  3. 18 0
      qdf/linux/src/i_qdf_nbuf.h

+ 10 - 0
dp/wifi3.0/dp_rx.c

@@ -394,6 +394,16 @@ dp_rx_intrabss_fwd(struct dp_soc *soc,
 			memset(nbuf->cb, 0x0, sizeof(nbuf->cb));
 			len = qdf_nbuf_len(nbuf);
 
+			/* linearize the nbuf just before we send to
+			 * dp_tx_send()
+			 */
+			if (qdf_unlikely(qdf_nbuf_get_ext_list(nbuf))) {
+				if (qdf_nbuf_linearize(nbuf) == -ENOMEM)
+					return false;
+
+				nbuf = qdf_nbuf_unshare(nbuf);
+			}
+
 			if (!dp_tx_send(sa_peer->vdev, nbuf)) {
 				DP_STATS_INC_PKT(sa_peer, rx.intra_bss.pkts,
 						1, len);

+ 6 - 0
qdf/inc/qdf_nbuf.h

@@ -2495,6 +2495,12 @@ qdf_nbuf_expand(qdf_nbuf_t buf, uint32_t headroom, uint32_t tailroom)
 	return __qdf_nbuf_expand(buf, headroom, tailroom);
 }
 
+static inline int
+qdf_nbuf_linearize(qdf_nbuf_t buf)
+{
+	return __qdf_nbuf_linearize(buf);
+}
+
 static inline qdf_nbuf_t
 qdf_nbuf_unshare(qdf_nbuf_t buf)
 {

+ 18 - 0
qdf/linux/src/i_qdf_nbuf.h

@@ -1491,6 +1491,24 @@ __qdf_nbuf_realloc_tailroom(struct sk_buff *skb, uint32_t tailroom)
 	return NULL;
 }
 
+/**
+ * __qdf_nbuf_linearize() - skb linearize
+ * @skb: sk buff
+ *
+ * create a version of the specified nbuf whose contents
+ * can be safely modified without affecting other
+ * users.If the nbuf is non-linear then this function
+ * linearize. if unable to linearize returns -ENOMEM on
+ * success 0 is returned
+ *
+ * Return: 0 on Success, -ENOMEM on failure is returned.
+ */
+static inline int
+__qdf_nbuf_linearize(struct sk_buff *skb)
+{
+	return skb_linearize(skb);
+}
+
 /**
  * __qdf_nbuf_unshare() - skb unshare
  * @skb: sk buff