|
@@ -30,6 +30,52 @@
|
|
|
#include <proto/802.1d.h>
|
|
|
#include <proto/802.11.h>
|
|
|
|
|
|
+struct sk_buff *BCMFASTPATH pkt_buf_get_skb(struct osl_info *osh, uint len)
|
|
|
+{
|
|
|
+ struct sk_buff *skb;
|
|
|
+
|
|
|
+ skb = dev_alloc_skb(len);
|
|
|
+ if (skb) {
|
|
|
+ skb_put(skb, len);
|
|
|
+ skb->priority = 0;
|
|
|
+
|
|
|
+ osh->pktalloced++;
|
|
|
+ }
|
|
|
+
|
|
|
+ return skb;
|
|
|
+}
|
|
|
+
|
|
|
+/* Free the driver packet. Free the tag if present */
|
|
|
+void BCMFASTPATH pkt_buf_free_skb(struct osl_info *osh,
|
|
|
+ struct sk_buff *skb, bool send)
|
|
|
+{
|
|
|
+ struct sk_buff *nskb;
|
|
|
+ int nest = 0;
|
|
|
+
|
|
|
+ ASSERT(skb);
|
|
|
+
|
|
|
+ /* perversion: we use skb->next to chain multi-skb packets */
|
|
|
+ while (skb) {
|
|
|
+ nskb = skb->next;
|
|
|
+ skb->next = NULL;
|
|
|
+
|
|
|
+ if (skb->destructor)
|
|
|
+ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if
|
|
|
+ * destructor exists
|
|
|
+ */
|
|
|
+ dev_kfree_skb_any(skb);
|
|
|
+ else
|
|
|
+ /* can free immediately (even in_irq()) if destructor
|
|
|
+ * does not exist
|
|
|
+ */
|
|
|
+ dev_kfree_skb(skb);
|
|
|
+
|
|
|
+ osh->pktalloced--;
|
|
|
+ nest++;
|
|
|
+ skb = nskb;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/* copy a buffer into a pkt buffer chain */
|
|
|
uint pktfrombuf(struct osl_info *osh, struct sk_buff *p, uint offset, int len,
|
|
|
unsigned char *buf)
|