---help---
          This will enable the support for the Atheros wireless drivers.
          ath5k, ath9k and ar9170 drivers share some common code, this option
-         enables the common ath.ko module which currently shares just common
-         regulatory EEPROM helpers but will likely be extended later to share
-         more between modules.
+         enables the common ath.ko module which shares common helpers.
 
          For more information and documentation on this module you can visit:
 
 
--- /dev/null
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ATH_H
+#define ATH_H
+
+#include <linux/skbuff.h>
+
+struct ath_common {
+       u16 cachelsz;
+};
+
+struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
+                               u32 len,
+                               gfp_t gfp_mask);
+
+#endif /* ATH_H */
 
 #include "hw.h"
 #include "rc.h"
 #include "debug.h"
+#include "../ath.h"
 
 struct ath_node;
 
        struct ieee80211_hw *hw;
        struct device *dev;
 
+       struct ath_common common;
+
        spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */
        struct ath_wiphy *pri_wiphy;
        struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may
        u32 sc_flags; /* SC_OP_* */
        u16 curtxpow;
        u16 curaid;
-       u16 cachelsz;
        u8 nbcnvifs;
        u16 nvifs;
        u8 tx_chainmask;
 
         */
        ath_read_cachesize(sc, &csz);
        /* XXX assert csz is non-zero */
-       sc->cachelsz = csz << 2;        /* convert to bytes */
+       sc->common.cachelsz = csz << 2; /* convert to bytes */
 
        ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
        if (!ah) {
 
        return (tsf & ~0x7fff) | rstamp;
 }
 
-static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask)
-{
-       struct sk_buff *skb;
-       u32 off;
-
-       /*
-        * Cache-line-align.  This is important (for the
-        * 5210 at least) as not doing so causes bogus data
-        * in rx'd frames.
-        */
-
-       /* Note: the kernel can allocate a value greater than
-        * what we ask it to give us. We really only need 4 KB as that
-        * is this hardware supports and in fact we need at least 3849
-        * as that is the MAX AMSDU size this hardware supports.
-        * Unfortunately this means we may get 8 KB here from the
-        * kernel... and that is actually what is observed on some
-        * systems :( */
-       skb = __dev_alloc_skb(len + sc->cachelsz - 1, gfp_mask);
-       if (skb != NULL) {
-               off = ((unsigned long) skb->data) % sc->cachelsz;
-               if (off != 0)
-                       skb_reserve(skb, sc->cachelsz - off);
-       } else {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "skbuff alloc of size %u failed\n", len);
-               return NULL;
-       }
-
-       return skb;
-}
-
 /*
  * For Decrypt or Demic errors, we only mark packet status here and always push
  * up the frame up to let mac80211 handle the actual error case, be it no
        spin_lock_init(&sc->rx.rxbuflock);
 
        sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
-                                min(sc->cachelsz, (u16)64));
+                                min(sc->common.cachelsz, (u16)64));
 
        DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
-               sc->cachelsz, sc->rx.bufsize);
+               sc->common.cachelsz, sc->rx.bufsize);
 
        /* Initialize rx descriptors */
 
        }
 
        list_for_each_entry(bf, &sc->rx.rxbuf, list) {
-               skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
+               skb = ath_rxbuf_alloc(&sc->common, sc->rx.bufsize, GFP_KERNEL);
                if (skb == NULL) {
                        error = -ENOMEM;
                        goto err;
 
                /* Ensure we always have an skb to requeue once we are done
                 * processing the current buffer's skb */
-               requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_ATOMIC);
+               requeue_skb = ath_rxbuf_alloc(&sc->common, sc->rx.bufsize, GFP_ATOMIC);
 
                /* If there is no memory we ignore the current RX'd frame,
                 * tell hardware it can give us a new frame using the old
 
 #include <linux/kernel.h>
 #include <linux/module.h>
 
+#include "ath.h"
+
 MODULE_AUTHOR("Atheros Communications");
 MODULE_DESCRIPTION("Shared library for Atheros wireless LAN cards.");
 MODULE_LICENSE("Dual BSD/GPL");
+
+struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
+                               u32 len,
+                               gfp_t gfp_mask)
+{
+       struct sk_buff *skb;
+       u32 off;
+
+       /*
+        * Cache-line-align.  This is important (for the
+        * 5210 at least) as not doing so causes bogus data
+        * in rx'd frames.
+        */
+
+       /* Note: the kernel can allocate a value greater than
+        * what we ask it to give us. We really only need 4 KB as that
+        * is this hardware supports and in fact we need at least 3849
+        * as that is the MAX AMSDU size this hardware supports.
+        * Unfortunately this means we may get 8 KB here from the
+        * kernel... and that is actually what is observed on some
+        * systems :( */
+       skb = __dev_alloc_skb(len + common->cachelsz - 1, gfp_mask);
+       if (skb != NULL) {
+               off = ((unsigned long) skb->data) % common->cachelsz;
+               if (off != 0)
+                       skb_reserve(skb, common->cachelsz - off);
+       } else {
+               printk(KERN_ERR "skbuff alloc of size %u failed\n", len);
+               return NULL;
+       }
+
+       return skb;
+}
+EXPORT_SYMBOL(ath_rxbuf_alloc);