[haiku-commits] haiku: hrev52040 - in src: add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn libs/compat/freebsd11_wlan/net80211 libs/compat/freebsd11_network

  • From: waddlesplash <waddlesplash@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 27 Jun 2018 20:27:28 -0400 (EDT)

hrev52040 adds 8 changesets to branch 'master'
old head: cbadcae1d0f3a95658f74fbc8a4102e66e563cde
new head: 97f9cb046c11d6ec546ef67f7dee3f155d34f085
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=97f9cb046c11+%5Ecbadcae1d0f3

----------------------------------------------------------------------------

83fee6c8b6b5: freebsd11_network: Even more changes for freebsd11_wlan.
  
  The net80211 code now fully compiles with 
-Werror=implicit-function-declaration,
  however, it is not yet fully patched for Haiku usage.

2ed3d6d1b597: freebsd11_network: Remove IFT_IEEE80211 logic.
  
  Previous versions of FreeBSD created a base ifp of type IFT_IEEE80211
  in addition to the ifp created for each VAP. We ignored these, so that
  the devices we displayed (/dev/.../0, etc.) were numbered properly.
  
  FreeBSD 11 no longer does this and instead uses an ieee80211com as its base
  type, so this logic is not needed.

ace07f705104: freebsd11_wlan: Adapt _haiku module for FreeBSD 11.
  
  Mostly just additions of new primitives and hook functions that are
  relatively straightforward and mostly copied from FreeBSD. The one
  notable set of changes is the ones relating to gDevices, as the hacks
  we used previously to hide the base device are now no longer needed
  (as the previous commit noted.)

af8988cdb666: freebsd11_wlan: Adapt net80211 code for Haiku's usage.
  
  Changes mostly ported from the FreeBSD 9 code, but some of it is new.
  Hopefully in the future, this diff can be reused almost wholesale,
  instead of having to re-create it as was done in past upgrades.

688153aaec25: iprowifi4965: Sync with FreeBSD 11.1.
  
  Tested and verified as working on my Lenovo ThinkPad T61.

a549026d25fa: freebsd11_network: Actually set numBytes instead of silently 
truncating it.
  
  If numBytes was greater than MCLBYTES (presently 1 << 11 = 2048), then the 
data beyond
  MCLBYTES would be silently discarded instead of being written. Now, we store 
the
  result of the min_c in numBytes, so the caller knows how much was written.
  
  I turn on the printf that's commented out here and found that in practice this
  seems to never happen (it's larger than the ethernet limit), so it seems 
unlikely
  to fix any "transmission mysteriously failed" bugs.
  
  Also backported this to the FreeBSD 9 layer.

8b4aff3eaca2: freebsd11_network: Enable INVARIANTS at KDEBUG_LEVEL_2.
  
  They were already enabled for the net80211 code (and thus all the Wi-Fi 
drivers)
  unconditionally; now we enable them conditionally based on KDEBUG_LEVEL_2
  for the freebsd11_network core code also.
  
  Includes fixes to the build, since there were some issues with INVARIANTS 
otherwise.

97f9cb046c11: freebsd11 / iprowifi4965: GCC2 fixes.

                              [ Augustin Cavalier <waddlesplash@xxxxxxxxx> ]

----------------------------------------------------------------------------

52 files changed, 5172 insertions(+), 1199 deletions(-)
.../drivers/network/wlan/iprowifi4965/Jamfile    |    9 +-
.../network/wlan/iprowifi4965/dev/iwn/if_iwn.c   | 3800 +++++++++++++-----
.../wlan/iprowifi4965/dev/iwn/if_iwn_chip_cfg.h  |  413 ++
.../wlan/iprowifi4965/dev/iwn/if_iwn_debug.h     |  123 +
.../wlan/iprowifi4965/dev/iwn/if_iwn_devid.h     |  333 ++
.../wlan/iprowifi4965/dev/iwn/if_iwn_ioctl.h     |   30 +
.../wlan/iprowifi4965/dev/iwn/if_iwnreg.h        |  589 ++-
.../wlan/iprowifi4965/dev/iwn/if_iwnvar.h        |  117 +-
src/libs/compat/Jamfile                          |    1 +
src/libs/compat/freebsd11_network/bus.cpp        |    9 +
.../freebsd11_network/compat/net/if_types.h      |    2 -
.../compat/freebsd11_network/compat/sys/_task.h  |    4 +-
.../compat/freebsd11_network/compat/sys/bus.h    |    2 +
.../freebsd11_network/compat/sys/callout.h       |    3 +-
.../freebsd11_network/compat/sys/haiku-module.h  |    3 -
.../freebsd11_network/compat/sys/mbuf-fbsd.h     |    9 +
.../compat/freebsd11_network/compat/sys/mbuf.h   |   63 +-
.../compat/freebsd11_network/compat/sys/param.h  |   10 +-
.../compat/freebsd11_network/compat/sys/socket.h |    2 +-
.../compat/freebsd11_network/compat/sys/systm.h  |    6 +
.../freebsd11_network/compat/sys/taskqueue.h     |   25 +-
src/libs/compat/freebsd11_network/device.c       |    8 +-
src/libs/compat/freebsd11_network/fbsd_mbuf.c    |   44 +
.../compat/freebsd11_network/fbsd_subr_sbuf.c    |    3 +
src/libs/compat/freebsd11_network/if.c           |   29 +-
src/libs/compat/freebsd11_network/mbuf.c         |   17 +
src/libs/compat/freebsd11_network/taskqueue.c    |  158 +-
src/libs/compat/freebsd11_network/unit.c         |   13 +-
.../compat/freebsd11_wlan/net80211/ieee80211.c   |   17 +-
.../compat/freebsd11_wlan/net80211/ieee80211.h   |    2 +
.../freebsd11_wlan/net80211/ieee80211_crypto.c   |   10 +
.../freebsd11_wlan/net80211/ieee80211_haiku.cpp  |  169 +-
.../freebsd11_wlan/net80211/ieee80211_haiku.h    |  163 +-
.../freebsd11_wlan/net80211/ieee80211_ht.c       |    2 +-
.../freebsd11_wlan/net80211/ieee80211_ht.h       |    1 +
.../freebsd11_wlan/net80211/ieee80211_hwmp.c     |    2 +-
.../freebsd11_wlan/net80211/ieee80211_ioctl.c    |   29 +-
.../freebsd11_wlan/net80211/ieee80211_ioctl.h    |   27 +-
.../freebsd11_wlan/net80211/ieee80211_mesh.c     |    2 +-
.../freebsd11_wlan/net80211/ieee80211_mesh.h     |    2 +
.../freebsd11_wlan/net80211/ieee80211_output.c   |    9 +-
.../freebsd11_wlan/net80211/ieee80211_phy.c      |    2 +-
.../freebsd11_wlan/net80211/ieee80211_phy.h      |   12 +-
.../freebsd11_wlan/net80211/ieee80211_proto.c    |    2 +-
.../freebsd11_wlan/net80211/ieee80211_proto.h    |    5 +-
.../freebsd11_wlan/net80211/ieee80211_ratectl.c  |   26 +
.../freebsd11_wlan/net80211/ieee80211_ratectl.h  |   13 +
.../freebsd11_wlan/net80211/ieee80211_scan.c     |   17 +
.../freebsd11_wlan/net80211/ieee80211_scan_sta.c |   16 +
.../freebsd11_wlan/net80211/ieee80211_scan_sw.c  |    2 +-
.../freebsd11_wlan/net80211/ieee80211_var.h      |    8 +-
src/libs/compat/freebsd_network/device.c         |    8 +-

############################################################################

Commit:      83fee6c8b6b5475880299ff5e187cf7a6edae8c2
URL:         https://git.haiku-os.org/haiku/commit/?id=83fee6c8b6b5
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Sun Jun 10 19:12:55 2018 UTC

freebsd11_network: Even more changes for freebsd11_wlan.

The net80211 code now fully compiles with -Werror=implicit-function-declaration,
however, it is not yet fully patched for Haiku usage.

----------------------------------------------------------------------------

diff --git a/src/libs/compat/freebsd11_network/bus.cpp 
b/src/libs/compat/freebsd11_network/bus.cpp
index cd6d600e24..816878d0b3 100644
--- a/src/libs/compat/freebsd11_network/bus.cpp
+++ b/src/libs/compat/freebsd11_network/bus.cpp
@@ -447,6 +447,15 @@ bus_bind_intr(device_t dev, struct resource *res, int cpu)
        return 0;
 }
 
+
+int bus_describe_intr(device_t dev, struct resource *irq, void *cookie,
+       const char* fmt, ...)
+{
+       UNIMPLEMENTED();
+       return B_ERROR;
+}
+
+
 //     #pragma mark - bus functions
 
 
diff --git a/src/libs/compat/freebsd11_network/compat/sys/_task.h 
b/src/libs/compat/freebsd11_network/compat/sys/_task.h
index a94e6b8ca9..6ce6c552ff 100644
--- a/src/libs/compat/freebsd11_network/compat/sys/_task.h
+++ b/src/libs/compat/freebsd11_network/compat/sys/_task.h
@@ -10,11 +10,11 @@
 #include <util/list.h>
 
 
-typedef void (*task_handler_t)(void *context, int pending);
+typedef void (*task_fn_t)(void *context, int pending);
 
 struct task {
        int ta_priority;
-       task_handler_t ta_handler;
+       task_fn_t ta_handler;
        void *ta_argument;
        int ta_pending;
 
diff --git a/src/libs/compat/freebsd11_network/compat/sys/bus.h 
b/src/libs/compat/freebsd11_network/compat/sys/bus.h
index 4ec6188528..476c847145 100644
--- a/src/libs/compat/freebsd11_network/compat/sys/bus.h
+++ b/src/libs/compat/freebsd11_network/compat/sys/bus.h
@@ -109,6 +109,8 @@ int bus_setup_intr(device_t dev, struct resource *r, int 
flags,
        driver_filter_t filter, driver_intr_t handler, void *arg, void 
**_cookie);
 int bus_teardown_intr(device_t dev, struct resource *r, void *cookie);
 int bus_bind_intr(device_t dev, struct resource *r, int cpu);
+int bus_describe_intr(device_t dev, struct resource *irq, void *cookie,
+       const char* fmt, ...);
 
 const char *device_get_name(device_t dev);
 const char *device_get_nameunit(device_t dev);
diff --git a/src/libs/compat/freebsd11_network/compat/sys/callout.h 
b/src/libs/compat/freebsd11_network/compat/sys/callout.h
index 9d4da3b944..e78fb24e01 100644
--- a/src/libs/compat/freebsd11_network/compat/sys/callout.h
+++ b/src/libs/compat/freebsd11_network/compat/sys/callout.h
@@ -25,7 +25,8 @@ struct callout {
 };
 
 
-#define CALLOUT_MPSAFE 0x0001
+#define        CALLOUT_MPSAFE                  0x0008 /* deprecated */
+#define        CALLOUT_RETURNUNLOCKED  0x0010 /* handler returns with mtx 
unlocked */
 
 
 void callout_init(struct callout *c, int mpsafe);
diff --git a/src/libs/compat/freebsd11_network/compat/sys/mbuf-fbsd.h 
b/src/libs/compat/freebsd11_network/compat/sys/mbuf-fbsd.h
index ff60d98d46..59fa9d4062 100644
--- a/src/libs/compat/freebsd11_network/compat/sys/mbuf-fbsd.h
+++ b/src/libs/compat/freebsd11_network/compat/sys/mbuf-fbsd.h
@@ -114,6 +114,15 @@
        *_mmp = _mm;                                                    \
 } while (0)
 
+static __inline void
+m_clrprotoflags(struct mbuf *m)
+{
+       while (m) {
+               m->m_flags &= ~M_PROTOFLAGS;
+               m = m->m_next;
+       }
+}
+
 /* mbufq */
 
 struct mbufq {
diff --git a/src/libs/compat/freebsd11_network/compat/sys/mbuf.h 
b/src/libs/compat/freebsd11_network/compat/sys/mbuf.h
index 18c9c76405..302bdbed08 100644
--- a/src/libs/compat/freebsd11_network/compat/sys/mbuf.h
+++ b/src/libs/compat/freebsd11_network/compat/sys/mbuf.h
@@ -26,26 +26,44 @@
 
 #define MT_DATA                1
 
-#define M_EXT          0x00000001
-#define M_PKTHDR       0x00000002
-#define M_RDONLY       0x00000008
-#define M_PROTO1       0x00000010
-#define M_PROTO2       0x00000020
-#define M_PROTO3       0x00000040
-#define M_PROTO4       0x00000080
-#define M_PROTO5       0x00000100
-#define M_BCAST                0x00000200
-#define M_MCAST                0x00000400
-#define M_FRAG         0x00000800
-#define M_FIRSTFRAG    0x00001000
-#define M_LASTFRAG     0x00002000
-#define M_VLANTAG      0x00010000
-#define M_PROTO6       0x00080000
-#define M_PROTO7       0x00100000
-#define M_PROTO8       0x00200000
-
-#define M_COPYFLAGS (M_PKTHDR | M_RDONLY | M_BCAST | M_MCAST | M_FRAG \
-       | M_FIRSTFRAG | M_LASTFRAG | M_VLANTAG)
+/*
+ * mbuf flags of global significance and layer crossing.
+ * Those of only protocol/layer specific significance are to be mapped
+ * to M_PROTO[1-12] and cleared at layer handoff boundaries.
+ * NB: Limited to the lower 24 bits.
+ */
+#define        M_EXT           0x00000001 /* has associated external storage */
+#define        M_PKTHDR        0x00000002 /* start of record */
+#define        M_EOR           0x00000004 /* end of record */
+#define        M_RDONLY        0x00000008 /* associated data is marked 
read-only */
+#define        M_BCAST         0x00000010 /* send/received as link-level 
broadcast */
+#define        M_MCAST         0x00000020 /* send/received as link-level 
multicast */
+#define        M_PROMISC       0x00000040 /* packet was not for us */
+#define        M_VLANTAG       0x00000080 /* ether_vtag is valid */
+#define        M_UNUSED_8      0x00000100 /* --available-- */
+#define        M_NOFREE        0x00000200 /* do not free mbuf, embedded in 
cluster */
+
+#define        M_PROTO1        0x00001000 /* protocol-specific */
+#define        M_PROTO2        0x00002000 /* protocol-specific */
+#define        M_PROTO3        0x00004000 /* protocol-specific */
+#define        M_PROTO4        0x00008000 /* protocol-specific */
+#define        M_PROTO5        0x00010000 /* protocol-specific */
+#define        M_PROTO6        0x00020000 /* protocol-specific */
+#define        M_PROTO7        0x00040000 /* protocol-specific */
+#define        M_PROTO8        0x00080000 /* protocol-specific */
+#define        M_PROTO9        0x00100000 /* protocol-specific */
+#define        M_PROTO10       0x00200000 /* protocol-specific */
+#define        M_PROTO11       0x00400000 /* protocol-specific */
+#define        M_PROTO12       0x00800000 /* protocol-specific */
+
+#define        M_PROTOFLAGS \
+       
(M_PROTO1|M_PROTO2|M_PROTO3|M_PROTO4|M_PROTO5|M_PROTO6|M_PROTO7|M_PROTO8|\
+        M_PROTO9|M_PROTO10|M_PROTO11|M_PROTO12)
+       // Flags to purge when crossing layers.
+
+#define M_COPYFLAGS \
+       (M_PKTHDR|M_EOR|M_RDONLY|M_BCAST|M_MCAST|M_PROMISC|M_VLANTAG| \
+        M_PROTOFLAGS)
        // Flags preserved when copying m_pkthdr
 
 #define M_MOVE_PKTHDR(to, from)        m_move_pkthdr((to), (from))
@@ -160,6 +178,7 @@ struct mbuf {
 #define m_dat          M_dat.M_databuf
 
 
+void                   m_catpkt(struct mbuf *m, struct mbuf *n);
 void                   m_adj(struct mbuf*, int);
 void                   m_align(struct mbuf*, int);
 int                            m_append(struct mbuf*, int, c_caddr_t);
@@ -177,6 +196,9 @@ struct mbuf*        m_devget(char*, int, int, struct ifnet*,
 struct mbuf*   m_dup(struct mbuf*, int);
 int                            m_dup_pkthdr(struct mbuf*, struct mbuf*, int);
 
+void                   m_demote_pkthdr(struct mbuf *m);
+void                   m_demote(struct mbuf *m0, int all, int flags);
+
 void                   m_extadd(struct mbuf*, caddr_t, u_int, void(*) (void*, 
void*),
        void*, void*, int, int);
 
@@ -184,6 +206,7 @@ u_int                       m_fixhdr(struct mbuf*);
 struct mbuf*   m_free(struct mbuf*);
 void                   m_freem(struct mbuf*);
 struct mbuf*   m_get(int, short);
+struct mbuf*   m_get2(int size, int how, short type, int flags);
 struct mbuf*   m_gethdr(int, short);
 struct mbuf*   m_getjcl(int, short, int, int);
 u_int                  m_length(struct mbuf*, struct mbuf**);
diff --git a/src/libs/compat/freebsd11_network/compat/sys/param.h 
b/src/libs/compat/freebsd11_network/compat/sys/param.h
index 51e09e4a6d..55beb81508 100644
--- a/src/libs/compat/freebsd11_network/compat/sys/param.h
+++ b/src/libs/compat/freebsd11_network/compat/sys/param.h
@@ -17,7 +17,7 @@
 
 
 /* The version this compatibility layer is based on */
-#define __FreeBSD_version 800107
+#define __FreeBSD_version 1101000
 
 #define MAXBSIZE       0x10000
 
@@ -49,6 +49,14 @@
 #define ALIGN_BYTES            (sizeof(unsigned long) - 1)
 #define ALIGN(x)               ((((unsigned long)x) + ALIGN_BYTES) & 
~ALIGN_BYTES)
 
+#ifdef __x86_64__
+#define        ALIGNED_POINTER(p, t)   1
+#elif defined(__i386__)
+#define        ALIGNED_POINTER(p, t)   1
+#else
+#error Need definition of ALIGNED_POINTER for this arch!
+#endif
+
 /* Macros for counting and rounding. */
 #ifndef howmany
 #define        howmany(x, y)   (((x)+((y)-1))/(y))
diff --git a/src/libs/compat/freebsd11_network/compat/sys/socket.h 
b/src/libs/compat/freebsd11_network/compat/sys/socket.h
index dc83ed2edd..1da6b72147 100644
--- a/src/libs/compat/freebsd11_network/compat/sys/socket.h
+++ b/src/libs/compat/freebsd11_network/compat/sys/socket.h
@@ -13,6 +13,6 @@
 
 
 // TODO Should be incorporated into Haikus socket.h with a number below AF_MAX
-#define AF_IEEE80211   AF_MAX + 1      /* IEEE 802.11 protocol */
+#define AF_IEEE80211   (AF_MAX + 1)    /* IEEE 802.11 protocol */
 
 #endif /* _FBSD_COMPAT_SYS_SOCKET_H_ */
diff --git a/src/libs/compat/freebsd11_network/compat/sys/taskqueue.h 
b/src/libs/compat/freebsd11_network/compat/sys/taskqueue.h
index 64b2e5a8bb..de2592bf88 100644
--- a/src/libs/compat/freebsd11_network/compat/sys/taskqueue.h
+++ b/src/libs/compat/freebsd11_network/compat/sys/taskqueue.h
@@ -8,11 +8,18 @@
 
 #include <sys/queue.h>
 #include <sys/_task.h>
+#include <sys/callout.h>
 
 
 #define PI_NET (B_REAL_TIME_DISPLAY_PRIORITY - 1)
 
-#define TASK_INIT(taskp, prio, hand, arg) task_init(taskp, prio, hand, arg)
+
+struct timeout_task {
+       struct taskqueue *q;
+       struct task t;
+       struct callout c;
+       int    f;
+};
 
 
 typedef void (*taskqueue_enqueue_fn)(void *context);
@@ -25,9 +32,17 @@ int taskqueue_start_threads(struct taskqueue **tq, int 
count, int pri,
        const char *name, ...) __printflike(4, 5);
 void taskqueue_free(struct taskqueue *tq);
 void taskqueue_drain(struct taskqueue *tq, struct task *task);
+void taskqueue_drain_timeout(struct taskqueue *queue,
+       struct timeout_task *timeout_task);
 void taskqueue_block(struct taskqueue *queue);
 void taskqueue_unblock(struct taskqueue *queue);
 int taskqueue_enqueue(struct taskqueue *tq, struct task *task);
+int taskqueue_enqueue_timeout(struct taskqueue *queue,
+       struct timeout_task *ttask, int ticks);
+int taskqueue_cancel(struct taskqueue *queue, struct task *task,
+       u_int *pendp);
+int taskqueue_cancel_timeout(struct taskqueue *queue,
+       struct timeout_task *timeout_task, u_int *pendp);
 
 void taskqueue_thread_enqueue(void *context);
 
@@ -39,6 +54,12 @@ int taskqueue_enqueue_fast(struct taskqueue *queue, struct 
task *task);
 struct taskqueue *taskqueue_create_fast(const char *name, int mflags,
        taskqueue_enqueue_fn enqueue, void *context);
 
-void task_init(struct task *, int prio, task_handler_t handler, void *arg);
+void task_init(struct task *, int prio, task_fn_t handler, void *arg);
+#define TASK_INIT(taskp, prio, hand, arg) task_init(taskp, prio, hand, arg)
+
+void timeout_task_init(struct taskqueue *queue, struct timeout_task 
*timeout_task,
+       int priority, task_fn_t func, void *context);
+#define        TIMEOUT_TASK_INIT(queue, timeout_task, priority, func, context) 
\
+       timeout_task_init(queue, timeout_task, priority, func, context);
 
 #endif
diff --git a/src/libs/compat/freebsd11_network/fbsd_mbuf.c 
b/src/libs/compat/freebsd11_network/fbsd_mbuf.c
index 7a0e6db63f..ca0cc819a8 100644
--- a/src/libs/compat/freebsd11_network/fbsd_mbuf.c
+++ b/src/libs/compat/freebsd11_network/fbsd_mbuf.c
@@ -197,6 +197,21 @@ nospace:
        return (NULL);
 }
 
+/*
+ * Concatenate two pkthdr mbuf chains.
+ */
+void
+m_catpkt(struct mbuf *m, struct mbuf *n)
+{
+       M_ASSERTPKTHDR(m);
+       M_ASSERTPKTHDR(n);
+
+       m->m_pkthdr.len += n->m_pkthdr.len;
+       m_demote(n, 1, 0);
+
+       m_cat(m, n);
+}
+
 void
 m_adj(struct mbuf *mp, int req_len)
 {
@@ -647,6 +662,35 @@ mb_dupcl(struct mbuf *n, struct mbuf *m)
        n->m_flags |= M_EXT;
 }
 
+void
+m_demote_pkthdr(struct mbuf *m)
+{
+       M_ASSERTPKTHDR(m);
+
+       m_tag_delete_chain(m, NULL);
+       m->m_flags &= ~M_PKTHDR;
+       bzero(&m->m_pkthdr, sizeof(struct pkthdr));
+}
+
+/*
+ * Clean up mbuf (chain) from any tags and packet headers.
+ * If "all" is set then the first mbuf in the chain will be
+ * cleaned too.
+ */
+void
+m_demote(struct mbuf *m0, int all, int flags)
+{
+       struct mbuf *m;
+
+       for (m = all ? m0 : m0->m_next; m != NULL; m = m->m_next) {
+               KASSERT(m->m_nextpkt == NULL, ("%s: m_nextpkt in m %p, m0 %p",
+                       __func__, m, m0));
+               if (m->m_flags & M_PKTHDR)
+                       m_demote_pkthdr(m);
+               m->m_flags = m->m_flags & (M_EXT | M_RDONLY | M_NOFREE | flags);
+       }
+}
+
 /*
  * Partition an mbuf chain in two pieces, returning the tail --
  * all but the first len0 bytes.  In case of failure, it returns NULL and
diff --git a/src/libs/compat/freebsd11_network/mbuf.c 
b/src/libs/compat/freebsd11_network/mbuf.c
index aa0eca497f..b29617f791 100644
--- a/src/libs/compat/freebsd11_network/mbuf.c
+++ b/src/libs/compat/freebsd11_network/mbuf.c
@@ -154,6 +154,23 @@ m_get(int how, short type)
 }
 
 
+struct mbuf *
+m_get2(int size, int how, short type, int flags)
+{
+       if (size <= MHLEN || (size <= MLEN && (flags & M_PKTHDR) == 0)) {
+               size = MCLBYTES;
+       } else if (size <= MJUMPAGESIZE) {
+               size = MJUMPAGESIZE;
+       } else if (size <= MJUM9BYTES) {
+               size = MJUM9BYTES;
+       } else /* (size > MJUM9BYTES) */ {
+               return NULL;
+       }
+
+       return m_getjcl(how, type, flags, size);
+}
+
+
 struct mbuf *
 m_gethdr(int how, short type)
 {
diff --git a/src/libs/compat/freebsd11_network/taskqueue.c 
b/src/libs/compat/freebsd11_network/taskqueue.c
index fe2feb8512..4574ca50f5 100644
--- a/src/libs/compat/freebsd11_network/taskqueue.c
+++ b/src/libs/compat/freebsd11_network/taskqueue.c
@@ -12,6 +12,7 @@
 
 #include <stdio.h>
 
+#include <compat/sys/callout.h>
 #include <compat/sys/taskqueue.h>
 #include <compat/sys/haiku-module.h>
 
@@ -20,10 +21,12 @@
 #define TQ_FLAGS_BLOCKED       (1 << 1)
 #define TQ_FLAGS_PENDING       (1 << 2)
 
+#define        DT_CALLOUT_ARMED                (1 << 0)
+#define        DT_DRAIN_IN_PROGRESS    (1 << 1)
 
 struct taskqueue {
        char tq_name[64];
-       mutex tq_mutex;
+       struct mtx tq_mutex;
        struct list tq_list;
        taskqueue_enqueue_fn tq_enqueue;
        void *tq_arg;
@@ -34,6 +37,7 @@ struct taskqueue {
        thread_id tq_thread_storage;
        int tq_threadcount;
        int tq_flags;
+       int tq_callouts;
 };
 
 struct taskqueue *taskqueue_fast = NULL;
@@ -54,7 +58,7 @@ _taskqueue_create(const char *name, int mflags, int fast,
        if (fast) {
                B_INITIALIZE_SPINLOCK(&tq->tq_spinlock);
        } else {
-               mutex_init_etc(&tq->tq_mutex, name, MUTEX_FLAG_CLONE_NAME);
+               mtx_init(&tq->tq_mutex, name, NULL, MTX_DEF);
        }
 
        strlcpy(tq->tq_name, name, sizeof(tq->tq_name));
@@ -66,6 +70,7 @@ _taskqueue_create(const char *name, int mflags, int fast,
        tq->tq_threads = NULL;
        tq->tq_threadcount = 0;
        tq->tq_flags = TQ_FLAGS_ACTIVE;
+       tq->tq_callouts = 0;
 
        return tq;
 }
@@ -78,7 +83,7 @@ tq_lock(struct taskqueue *taskQueue, cpu_status *status)
                *status = disable_interrupts();
                acquire_spinlock(&taskQueue->tq_spinlock);
        } else {
-               mutex_lock(&taskQueue->tq_mutex);
+               mtx_lock(&taskQueue->tq_mutex);
        }
 }
 
@@ -90,7 +95,7 @@ tq_unlock(struct taskqueue *taskQueue, cpu_status status)
                release_spinlock(&taskQueue->tq_spinlock);
                restore_interrupts(status);
        } else {
-               mutex_unlock(&taskQueue->tq_mutex);
+               mtx_unlock(&taskQueue->tq_mutex);
        }
 }
 
@@ -218,7 +223,7 @@ taskqueue_free(struct taskqueue *taskQueue)
        /* lock and  drain list? */
        taskQueue->tq_flags &= ~TQ_FLAGS_ACTIVE;
        if (!taskQueue->tq_fast)
-               mutex_destroy(&taskQueue->tq_mutex);
+               mtx_destroy(&taskQueue->tq_mutex);
        if (taskQueue->tq_sem != -1) {
                int i;
 
@@ -252,6 +257,32 @@ taskqueue_drain(struct taskqueue *taskQueue, struct task 
*task)
 }
 
 
+void
+taskqueue_drain_timeout(struct taskqueue *queue,
+       struct timeout_task *timeout_task)
+{
+       cpu_status status;
+       /*
+        * Set flag to prevent timer from re-starting during drain:
+        */
+       tq_lock(queue, &status);
+       KASSERT((timeout_task->f & DT_DRAIN_IN_PROGRESS) == 0,
+               ("Drain already in progress"));
+       timeout_task->f |= DT_DRAIN_IN_PROGRESS;
+       tq_unlock(queue, status);
+
+       callout_drain(&timeout_task->c);
+       taskqueue_drain(queue, &timeout_task->t);
+
+       /*
+        * Clear flag to allow timer to re-start:
+        */
+       tq_lock(queue, &status);
+       timeout_task->f &= ~DT_DRAIN_IN_PROGRESS;
+       tq_unlock(queue, status);
+}
+
+
 int
 taskqueue_enqueue(struct taskqueue *taskQueue, struct task *task)
 {
@@ -273,6 +304,109 @@ taskqueue_enqueue(struct taskqueue *taskQueue, struct 
task *task)
 }
 
 
+static void
+taskqueue_timeout_func(void *arg)
+{
+       struct taskqueue *queue;
+       struct timeout_task *timeout_task;
+
+       timeout_task = arg;
+       queue = timeout_task->q;
+       KASSERT((timeout_task->f & DT_CALLOUT_ARMED) != 0, ("Stray timeout"));
+       timeout_task->f &= ~DT_CALLOUT_ARMED;
+       queue->tq_callouts--;
+       taskqueue_enqueue(timeout_task->q, &timeout_task->t);
+}
+
+
+int
+taskqueue_enqueue_timeout(struct taskqueue *queue,
+       struct timeout_task *ttask, int ticks)
+{
+       int res;
+       cpu_status status;
+
+       tq_lock(queue, &status);
+       KASSERT(timeout_task->q == NULL || timeout_task->q == queue,
+               ("Migrated queue"));
+       ttask->q = queue;
+       res = ttask->t.ta_pending;
+       if (ttask->f & DT_DRAIN_IN_PROGRESS) {
+               /* Do nothing */
+               tq_unlock(queue, status);
+               res = -1;
+       } else if (ticks == 0) {
+               tq_unlock(queue, status);
+               taskqueue_enqueue(queue, &ttask->t);
+       } else {
+               if ((ttask->f & DT_CALLOUT_ARMED) != 0) {
+                       res++;
+               } else {
+                       queue->tq_callouts++;
+                       ttask->f |= DT_CALLOUT_ARMED;
+                       if (ticks < 0)
+                               ticks = -ticks; /* Ignore overflow. */
+               }
+               tq_unlock(queue, status);
+               if (ticks > 0) {
+                       callout_reset(&ttask->c, ticks,
+                               taskqueue_timeout_func, ttask);
+               }
+       }
+       return (res);
+}
+
+
+static int
+taskqueue_cancel_locked(struct taskqueue *queue, struct task *task,
+       u_int *pendp)
+{
+       if (task->ta_pending > 0)
+               list_remove_item(&queue->tq_list, task);
+       if (pendp != NULL)
+               *pendp = task->ta_pending;
+       task->ta_pending = 0;
+       return 0;
+}
+
+
+int
+taskqueue_cancel(struct taskqueue *queue, struct task *task, u_int *pendp)
+{
+       int error;
+       cpu_status status;
+
+       tq_lock(queue, &status);
+       error = taskqueue_cancel_locked(queue, task, pendp);
+       tq_unlock(queue, status);
+
+       return (error);
+}
+
+
+int
+taskqueue_cancel_timeout(struct taskqueue *queue,
+       struct timeout_task *timeout_task, u_int *pendp)
+{
+       u_int pending, pending1;
+       int error;
+       cpu_status status;
+
+       tq_lock(queue, &status);
+       pending = !!(callout_stop(&timeout_task->c) > 0);
+       error = taskqueue_cancel_locked(queue, &timeout_task->t, &pending1);
+       if ((timeout_task->f & DT_CALLOUT_ARMED) != 0) {
+               timeout_task->f &= ~DT_CALLOUT_ARMED;
+               queue->tq_callouts--;
+       }
+       tq_unlock(queue, status);
+
+       if (pendp != NULL)
+               *pendp = pending + pending1;
+       return (error);
+}
+
+
 void
 taskqueue_thread_enqueue(void *context)
 {
@@ -297,7 +431,7 @@ taskqueue_create_fast(const char *name, int mflags,
 
 
 void
-task_init(struct task *task, int prio, task_handler_t handler, void *context)
+task_init(struct task *task, int prio, task_fn_t handler, void *context)
 {
        task->ta_priority = prio;
        task->ta_handler = handler;
@@ -306,6 +440,18 @@ task_init(struct task *task, int prio, task_handler_t 
handler, void *context)
 }
 
 
+void
+timeout_task_init(struct taskqueue *queue, struct timeout_task *timeout_task,
+       int priority, task_fn_t func, void *context)
+{
+       TASK_INIT(&timeout_task->t, priority, func, context);
+       callout_init_mtx(&timeout_task->c, &queue->tq_mutex,
+               CALLOUT_RETURNUNLOCKED);
+       timeout_task->q = queue;
+       timeout_task->f = 0;
+}
+
+
 status_t
 init_taskqueues()
 {

############################################################################

Commit:      2ed3d6d1b597d3002ad0aef1a358c35325d41d7a
URL:         https://git.haiku-os.org/haiku/commit/?id=2ed3d6d1b597
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Tue Jun 26 02:13:18 2018 UTC

freebsd11_network: Remove IFT_IEEE80211 logic.

Previous versions of FreeBSD created a base ifp of type IFT_IEEE80211
in addition to the ifp created for each VAP. We ignored these, so that
the devices we displayed (/dev/.../0, etc.) were numbered properly.

FreeBSD 11 no longer does this and instead uses an ieee80211com as its base
type, so this logic is not needed.

----------------------------------------------------------------------------

diff --git a/src/libs/compat/freebsd11_network/compat/net/if_types.h 
b/src/libs/compat/freebsd11_network/compat/net/if_types.h
index 25766e4b1a..3e2f73000f 100644
--- a/src/libs/compat/freebsd11_network/compat/net/if_types.h
+++ b/src/libs/compat/freebsd11_network/compat/net/if_types.h
@@ -9,6 +9,4 @@
 #include <posix/net/if_types.h>
 
 
-#define        IFT_IEEE80211              0x47
-
 #endif /* _FBSD_COMPAT_NET_IF_TYPES_H_ */
diff --git a/src/libs/compat/freebsd11_network/compat/sys/haiku-module.h 
b/src/libs/compat/freebsd11_network/compat/sys/haiku-module.h
index 126ba8ccfa..7b9f5e7107 100644
--- a/src/libs/compat/freebsd11_network/compat/sys/haiku-module.h
+++ b/src/libs/compat/freebsd11_network/compat/sys/haiku-module.h
@@ -79,7 +79,6 @@ status_t start_wlan(device_t);
 status_t stop_wlan(device_t);
 status_t wlan_control(void*, uint32, void*, size_t);
 status_t wlan_close(void*);
-status_t wlan_if_l2com_alloc(void*);
 
 /* we define the driver methods with HAIKU_FBSD_DRIVERS_GLUE to
  * force the rest of the stuff to be linked back with the driver.
@@ -118,8 +117,6 @@ status_t wlan_if_l2com_alloc(void*);
                size_t length)                                                  
                                                \
                { return B_BAD_VALUE; }                                         
                                        \
        status_t wlan_close(void* cookie)                                       
                                \
-               { return B_OK; }                                                
                                                \
-       status_t wlan_if_l2com_alloc(void* ifp)                                 
                        \
                { return B_OK; }
 
 #define HAIKU_FBSD_DRIVER_GLUE(publicname, name, busname)                      
        \
diff --git a/src/libs/compat/freebsd11_network/if.c 
b/src/libs/compat/freebsd11_network/if.c
index f8e80b432e..b9f6fe200f 100644
--- a/src/libs/compat/freebsd11_network/if.c
+++ b/src/libs/compat/freebsd11_network/if.c
@@ -174,12 +174,6 @@ if_alloc(u_char type)
                        IFP2AC(ifp)->ac_ifp = ifp;
                        break;
                }
-               case IFT_IEEE80211:
-               {
-                       if (wlan_if_l2com_alloc(ifp) != B_OK)
-                               goto err2;
-                       break;
-               }
        }
 
        ifp->link_state_sem = -1;
@@ -210,7 +204,6 @@ if_alloc(u_char type)
 err3:
        switch (type) {
                case IFT_ETHER:
-               case IFT_IEEE80211:
                        _kernel_free(ifp->if_l2com);
                        break;
        }
@@ -239,7 +232,6 @@ if_free(struct ifnet *ifp)
        IF_ADDR_LOCK_DESTROY(ifp);
        switch (ifp->if_type) {
                case IFT_ETHER:
-               case IFT_IEEE80211:
                        _kernel_free(ifp->if_l2com);
                        break;
        }
@@ -268,16 +260,7 @@ if_initname(struct ifnet *ifp, const char *name, int unit)
                gDriverName, ifp->if_index);
 
        driver_printf("%s: /dev/%s\n", gDriverName, ifp->device_name);
-
-       // For wlan devices we only want to see the cloned wlan device
-       // in the list.
-       // Remember: For each wlan device, there is a base device of type
-       //           IFT_IEEE80211. On top of that a clone device is created of
-       //           type IFT_ETHER.
-       //           Haiku shall only see the cloned device as it is the one
-       //           FreeBSD 8 uses for wireless i/o, too.
-       if (ifp->if_type == IFT_ETHER)
-               insert_into_device_name_list(ifp);
+       insert_into_device_name_list(ifp);
 
        ifp->root_device = find_root_device(unit);
 }
@@ -1008,7 +991,7 @@ if_getcapabilities(if_t ifp)
        return ((struct ifnet *)ifp)->if_capabilities;
 }
 
-int 
+int
 if_setcapenable(if_t ifp, int capabilities)
 {
        ((struct ifnet *)ifp)->if_capenable = capabilities;
@@ -1157,16 +1140,16 @@ if_getsoftc(if_t ifp)
        return ((struct ifnet *)ifp)->if_softc;
 }
 
-void 
+void
 if_setrcvif(struct mbuf *m, if_t ifp)
 {
        m->m_pkthdr.rcvif = (struct ifnet *)ifp;
 }
 
-void 
+void
 if_setvtag(struct mbuf *m, uint16_t tag)
 {
-       m->m_pkthdr.ether_vtag = tag;   
+       m->m_pkthdr.ether_vtag = tag;
 }
 
 uint16_t

############################################################################

Commit:      ace07f705104a139d0fd7bd2f4f05e1f13ec98f7
URL:         https://git.haiku-os.org/haiku/commit/?id=ace07f705104
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Tue Jun 26 02:17:58 2018 UTC

freebsd11_wlan: Adapt _haiku module for FreeBSD 11.

Mostly just additions of new primitives and hook functions that are
relatively straightforward and mostly copied from FreeBSD. The one
notable set of changes is the ones relating to gDevices, as the hacks
we used previously to hide the base device are now no longer needed
(as the previous commit noted.)

----------------------------------------------------------------------------

diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.cpp 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.cpp
index 54e7ce714b..3302422a27 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.cpp
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009, Colin Günther, coling@xxxxxx.
+ * Copyright 2018, Haiku, Inc.
  * All rights reserved. Distributed under the terms of the MIT License.
  */
 
@@ -96,6 +97,7 @@ get_ifnet(device_t device, int& i)
 status_t
 init_wlan_stack(void)
 {
+       mtx_init(&ic_list_mtx, "ieee80211com list", NULL, MTX_DEF);
        ieee80211_phy_init();
        ieee80211_auth_setup();
        ieee80211_ht_init();
@@ -118,35 +120,22 @@ uninit_wlan_stack(void)
 status_t
 start_wlan(device_t device)
 {
-       int i;
-       struct ifnet* ifp = get_ifnet(device, i);
-       if (ifp == NULL)
+       struct ieee80211com* ic = ieee80211_find_com(device->nameunit);
+       if (ic == NULL)
                return B_BAD_VALUE;
 
-// TODO: review this and find a cleaner solution!
-       // This ensures that the cloned device gets
-       // the same index assigned as the base device
-       // Resulting in the same device name
-       // e.g.: /dev/net/atheros/0 instead of
-       //       /dev/net/atheros/1
-       gDevices[i] = NULL;
-
-       struct ieee80211com* ic = (ieee80211com*)ifp->if_l2com;
-
        struct ieee80211vap* vap = ic->ic_vap_create(ic, "wlan",
                device_get_unit(device),
                IEEE80211_M_STA,                // mode
                0,                                              // flags
                NULL,                                   // BSSID
-               IF_LLADDR(ifp));                // MAC address
+               ic->ic_macaddr);                // MAC address
 
-       if (vap == NULL) {
-               gDevices[i] = ifp;
+       if (vap == NULL)
                return B_ERROR;
-       }
 
        // ic_vap_create() established that gDevices[i] links to vap->iv_ifp now
-       KASSERT(gDevices[i] == vap->iv_ifp,
+       KASSERT(gDevices[gDeviceCount - 1] == vap->iv_ifp,
                ("start_wlan: gDevices[i] != vap->iv_ifp"));
 
        vap->iv_ifp->scan_done_sem = create_sem(0, "wlan scan done");
@@ -168,12 +157,6 @@ stop_wlan(device_t device)
        if (ifp == NULL)
                return B_BAD_VALUE;
 
-       if (ifp->if_type == IFT_IEEE80211) {
-               // This happens when there was an error in starting the wlan 
before,
-               // resulting in never creating a clone device
-               return B_OK;
-       }
-
        delete_sem(ifp->scan_done_sem);
 
        struct ieee80211vap* vap = (ieee80211vap*)ifp->if_softc;
@@ -184,9 +167,6 @@ stop_wlan(device_t device)
        // ic_vap_delete freed gDevices[i]
        KASSERT(gDevices[i] == NULL, ("stop_wlan: gDevices[i] != NULL"));
 
-       // assign the base device ifp again
-       gDevices[i] = ic->ic_ifp;
-
        return B_OK;
 }
 
@@ -400,19 +380,6 @@ wlan_control(void* cookie, uint32 op, void* arg, size_t 
length)
 }
 
 
-status_t
-wlan_if_l2com_alloc(void* data)
-{
-       struct ifnet* ifp = (struct ifnet*)data;
-
-       ifp->if_l2com = _kernel_malloc(sizeof(struct ieee80211com), M_ZERO);
-       if (ifp->if_l2com == NULL)
-               return B_NO_MEMORY;
-       ((struct ieee80211com*)(ifp->if_l2com))->ic_ifp = ifp;
-       return B_OK;
-}
-
-
 void
 get_random_bytes(void* p, size_t n)
 {
@@ -553,6 +520,128 @@ ieee80211_process_callback(struct ieee80211_node* ni, 
struct mbuf* m,
 }
 
 
+int
+ieee80211_add_xmit_params(struct mbuf *m,
+       const struct ieee80211_bpf_params *params)
+{
+       struct m_tag *mtag;
+       struct ieee80211_tx_params *tx;
+
+       mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS,
+               sizeof(struct ieee80211_tx_params), M_NOWAIT);
+       if (mtag == NULL)
+               return (0);
+
+       tx = (struct ieee80211_tx_params *)(mtag+1);
+       memcpy(&tx->params, params, sizeof(struct ieee80211_bpf_params));
+       m_tag_prepend(m, mtag);
+       return (1);
+}
+
+
+int
+ieee80211_get_xmit_params(struct mbuf *m,
+       struct ieee80211_bpf_params *params)
+{
+       struct m_tag *mtag;
+       struct ieee80211_tx_params *tx;
+
+       mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_XMIT_PARAMS,
+               NULL);
+       if (mtag == NULL)
+               return (-1);
+       tx = (struct ieee80211_tx_params *)(mtag + 1);
+       memcpy(params, &tx->params, sizeof(struct ieee80211_bpf_params));
+       return (0);
+}
+
+
+/*
+ * Add RX parameters to the given mbuf.
+ *
+ * Returns 1 if OK, 0 on error.
+ */
+int
+ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats *rxs)
+{
+       struct m_tag *mtag;
+       struct ieee80211_rx_params *rx;
+
+       mtag = m_tag_alloc(MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS,
+               sizeof(struct ieee80211_rx_stats), M_NOWAIT);
+       if (mtag == NULL)
+               return (0);
+
+       rx = (struct ieee80211_rx_params *)(mtag + 1);
+       memcpy(&rx->params, rxs, sizeof(*rxs));
+       m_tag_prepend(m, mtag);
+       return (1);
+}
+
+
+int
+ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs)
+{
+       struct m_tag *mtag;
+       struct ieee80211_rx_params *rx;
+
+       mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS,
+               NULL);
+       if (mtag == NULL)
+               return (-1);
+       rx = (struct ieee80211_rx_params *)(mtag + 1);
+       memcpy(rxs, &rx->params, sizeof(*rxs));
+       return (0);
+}
+
+
+/*
+ * Transmit a frame to the parent interface.
+ */
+int
+ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m)
+{
+       int error;
+
+       /*
+        * Assert the IC TX lock is held - this enforces the
+        * processing -> queuing order is maintained
+        */
+       IEEE80211_TX_LOCK_ASSERT(ic);
+       error = ic->ic_transmit(ic, m);
+       if (error) {
+               struct ieee80211_node *ni;
+
+               ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
+
+               /* XXX number of fragments */
+               if_inc_counter(ni->ni_vap->iv_ifp, IFCOUNTER_OERRORS, 1);
+               ieee80211_free_node(ni);
+               ieee80211_free_mbuf(m);
+       }
+       return (error);
+}
+
+
+/*
+ * Transmit a frame to the VAP interface.
+ */
+int
+ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m)
+{
+       struct ifnet *ifp = vap->iv_ifp;
+
+       /*
+        * When transmitting via the VAP, we shouldn't hold
+        * any IC TX lock as the VAP TX path will acquire it.
+        */
+       IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
+
+       return (ifp->if_transmit(ifp, m));
+
+}
+
+
 void
 ieee80211_sysctl_vattach(struct ieee80211vap* vap)
 {
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.h 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.h
index c2735078f1..023ca91097 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.h
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_haiku.h
@@ -35,8 +35,8 @@
 
 #      ifdef __cplusplus
 // Those includes are needed to avoid C/C++ function export clashes
-#              include <new>
-#              include <thread.h>
+#      include <new>
+#      include <thread.h>
 extern "C" {
 #      endif
 
@@ -80,6 +80,51 @@ typedef struct {
 #define        IEEE80211_UNLOCK(_ic)      mtx_unlock(IEEE80211_LOCK_OBJ(_ic))
 #define        IEEE80211_LOCK_ASSERT(_ic) \
        mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_OWNED)
+#define        IEEE80211_UNLOCK_ASSERT(_ic) \
+       mtx_assert(IEEE80211_LOCK_OBJ(_ic), MA_NOTOWNED)
+
+/*
+ * Transmit lock.
+ *
+ * This is a (mostly) temporary lock designed to serialise all of the
+ * transmission operations throughout the stack.
+ */
+typedef struct {
+       char            name[16];               /* e.g. "ath0_tx_lock" */
+       struct mtx      mtx;
+} ieee80211_tx_lock_t;
+#define        IEEE80211_TX_LOCK_INIT(_ic, _name) do {                         
\
+       ieee80211_tx_lock_t *cl = &(_ic)->ic_txlock;                    \
+       snprintf(cl->name, sizeof(cl->name), "%s_tx_lock", _name);      \
+       mtx_init(&cl->mtx, cl->name, NULL, MTX_DEF);    \
+} while (0)
+#define        IEEE80211_TX_LOCK_OBJ(_ic)      (&(_ic)->ic_txlock.mtx)
+#define        IEEE80211_TX_LOCK_DESTROY(_ic) 
mtx_destroy(IEEE80211_TX_LOCK_OBJ(_ic))
+#define        IEEE80211_TX_LOCK(_ic)     mtx_lock(IEEE80211_TX_LOCK_OBJ(_ic))
+#define        IEEE80211_TX_UNLOCK(_ic)           
mtx_unlock(IEEE80211_TX_LOCK_OBJ(_ic))
+#define        IEEE80211_TX_LOCK_ASSERT(_ic) \
+       mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_OWNED)
+#define        IEEE80211_TX_UNLOCK_ASSERT(_ic) \
+       mtx_assert(IEEE80211_TX_LOCK_OBJ(_ic), MA_NOTOWNED)
+
+/*
+ * Stageq / ni_tx_superg lock
+ */
+typedef struct {
+       char            name[16];               /* e.g. "ath0_ff_lock" */
+       struct mtx      mtx;
+} ieee80211_ff_lock_t;
+#define IEEE80211_FF_LOCK_INIT(_ic, _name) do {                                
\
+       ieee80211_ff_lock_t *fl = &(_ic)->ic_fflock;                    \
+       snprintf(fl->name, sizeof(fl->name), "%s_ff_lock", _name);      \
+       mtx_init(&fl->mtx, fl->name, NULL, MTX_DEF);                    \
+} while (0)
+#define IEEE80211_FF_LOCK_OBJ(_ic)     (&(_ic)->ic_fflock.mtx)
+#define IEEE80211_FF_LOCK_DESTROY(_ic) mtx_destroy(IEEE80211_FF_LOCK_OBJ(_ic))
+#define IEEE80211_FF_LOCK(_ic)         mtx_lock(IEEE80211_FF_LOCK_OBJ(_ic))
+#define IEEE80211_FF_UNLOCK(_ic)       mtx_unlock(IEEE80211_FF_LOCK_OBJ(_ic))
+#define IEEE80211_FF_LOCK_ASSERT(_ic) \
+       mtx_assert(IEEE80211_FF_LOCK_OBJ(_ic), MA_OWNED)
 
 /*
  * Node locking definitions.
@@ -172,6 +217,34 @@ typedef struct mtx ieee80211_scan_table_lock_t;
 #define        IEEE80211_SCAN_TABLE_LOCK(_st)          
mtx_lock(&(_st)->st_lock)
 #define        IEEE80211_SCAN_TABLE_UNLOCK(_st)        
mtx_unlock(&(_st)->st_lock)
 
+typedef struct mtx ieee80211_scan_iter_lock_t;
+#define        IEEE80211_SCAN_ITER_LOCK_INIT(_st, _name) \
+       mtx_init(&(_st)->st_scanlock, _name, "802.11 scangen", MTX_DEF)
+#define        IEEE80211_SCAN_ITER_LOCK_DESTROY(_st)   
mtx_destroy(&(_st)->st_scanlock)
+#define        IEEE80211_SCAN_ITER_LOCK(_st)           
mtx_lock(&(_st)->st_scanlock)
+#define        IEEE80211_SCAN_ITER_UNLOCK(_st) mtx_unlock(&(_st)->st_scanlock)
+
+/*
+ * Mesh node/routing definitions.
+ */
+typedef struct mtx ieee80211_rte_lock_t;
+#define        MESH_RT_ENTRY_LOCK_INIT(_rt, _name) \
+       mtx_init(&(rt)->rt_lock, _name, "802.11s route entry", MTX_DEF)
+#define        MESH_RT_ENTRY_LOCK_DESTROY(_rt) \
+       mtx_destroy(&(_rt)->rt_lock)
+#define        MESH_RT_ENTRY_LOCK(rt)  mtx_lock(&(rt)->rt_lock)
+#define        MESH_RT_ENTRY_LOCK_ASSERT(rt) mtx_assert(&(rt)->rt_lock, 
MA_OWNED)
+#define        MESH_RT_ENTRY_UNLOCK(rt)        mtx_unlock(&(rt)->rt_lock)
+
+typedef struct mtx ieee80211_rt_lock_t;
+#define        MESH_RT_LOCK(ms)        mtx_lock(&(ms)->ms_rt_lock)
+#define        MESH_RT_LOCK_ASSERT(ms) mtx_assert(&(ms)->ms_rt_lock, MA_OWNED)
+#define        MESH_RT_UNLOCK(ms)      mtx_unlock(&(ms)->ms_rt_lock)
+#define        MESH_RT_LOCK_INIT(ms, name) \
+       mtx_init(&(ms)->ms_rt_lock, name, "802.11s routing table", MTX_DEF)
+#define        MESH_RT_LOCK_DESTROY(ms) \
+       mtx_destroy(&(ms)->ms_rt_lock)
+
 /*
  * Node reference counting definitions.
  *
@@ -208,10 +281,10 @@ void      ieee80211_vap_destroy(struct ieee80211vap *);
 #define        msecs_to_ticks(ms)      (((ms)*hz)/1000)
 #define        ticks_to_msecs(t)       (1000*(t) / hz)
 #define        ticks_to_secs(t)        ((t) / hz)
-#define time_after(a,b)        ((long long)(b) - (long long)(a) < 0)
-#define time_before(a,b)       time_after(b,a)
-#define time_after_eq(a,b)     ((long long)(a) - (long long)(b) >= 0)
-#define time_before_eq(a,b)    time_after_eq(b,a)
+#define ieee80211_time_after(a,b)      ((long)(b) - (long)(a) < 0)
+#define ieee80211_time_before(a,b)     ieee80211_time_after(b,a)
+#define ieee80211_time_after_eq(a,b)   ((long)(a) - (long)(b) >= 0)
+#define ieee80211_time_before_eq(a,b)  ieee80211_time_after_eq(b,a)
 
 struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
 
@@ -223,6 +296,9 @@ struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int 
headroom, int pktlen);
 #define        M_FF            M_PROTO6                /* fast frame */
 #define        M_TXCB          M_PROTO7                /* do tx complete 
callback */
 #define        M_AMPDU_MPDU    M_PROTO8                /* ok for A-MPDU 
aggregation */
+#define        M_FRAG          M_PROTO9                /* frame fragmentation 
*/
+#define        M_FIRSTFRAG     M_PROTO10               /* first frame fragment 
*/
+#define        M_LASTFRAG      M_PROTO11               /* last frame fragment 
*/
 #define        M_80211_TX \
        (M_FRAG|M_FIRSTFRAG|M_LASTFRAG|M_ENCAP|M_EAPOL|M_PWR_SAV|\
         M_MORE_DATA|M_FF|M_TXCB|M_AMPDU_MPDU)
@@ -268,7 +344,9 @@ struct ieee80211_cb {
        void    (*func)(struct ieee80211_node *, void *, int status);
        void    *arg;
 };
-#define        NET80211_TAG_CALLBACK   0       /* xmit complete callback */
+#define        NET80211_TAG_CALLBACK           0 /* xmit complete callback */
+#define        NET80211_TAG_XMIT_PARAMS        1 /* See below; this is after 
the bpf_params definition */
+#define        NET80211_TAG_RECV_PARAMS        2
 
 int    ieee80211_add_callback(struct mbuf *m,
                void (*func)(struct ieee80211_node *, void *, int), void *arg);
@@ -278,6 +356,9 @@ void        get_random_bytes(void *, size_t);
 
 struct ieee80211com;
 
+int ieee80211_parent_xmitpkt(struct ieee80211com *ic, struct mbuf *m);
+int ieee80211_vap_xmitpkt(struct ieee80211vap *vap, struct mbuf *m);
+
 void   ieee80211_sysctl_attach(struct ieee80211com *);
 void   ieee80211_sysctl_detach(struct ieee80211com *);
 void   ieee80211_sysctl_vattach(struct ieee80211vap *);
@@ -327,7 +408,7 @@ void        ieee80211_scan_sta_uninit(void);
  */
 #define        IEEE80211_RATECTL_MODULE(alg, version)                          
\
        _IEEE80211_POLICY_MODULE(ratectl, alg, version);                \
-       
+
 #define IEEE80211_RATECTL_ALG(name, alg, v) \
        void \
        ieee80211_ratectl_##name##_load() { \
@@ -336,8 +417,7 @@ void        ieee80211_scan_sta_uninit(void);
 \
 \
        void \
-       ieee80211_ratectl_##name##_unload() \
-       { \
+       ieee80211_ratectl_##name##_unload() { \
                ieee80211_ratectl_unregister(alg); \
        }
 
@@ -353,11 +433,6 @@ typedef int ieee80211_ioctl_setfunc(struct ieee80211vap *,
 SET_DECLARE(ieee80211_ioctl_setset, ieee80211_ioctl_setfunc);
 #define        IEEE80211_IOCTL_SET(_name, _set) 
TEXT_SET(ieee80211_ioctl_setset, _set)
 
-#ifdef __cplusplus
-}
-#endif
-#endif /* _KERNEL */
-
 /*
  * Structure prepended to raw packets sent through the bpf
  * interface when set to DLT_IEEE802_11_RADIO.  This allows
@@ -392,4 +467,60 @@ struct ieee80211_bpf_params {
        uint8_t         ibp_rate3;      /* series 4 IEEE tx rate */
 };
 
+int ieee80211_add_xmit_params(struct mbuf *m, const struct 
ieee80211_bpf_params *params);
+int ieee80211_get_xmit_params(struct mbuf *m, struct ieee80211_bpf_params 
*params);
+
+#define        IEEE80211_MAX_CHAINS            3
+#define        IEEE80211_MAX_EVM_PILOTS        6
+
+struct ieee80211_tx_params {
+       struct ieee80211_bpf_params params;
+};
+
+#define        IEEE80211_R_NF          0x0000001       /* global NF value 
valid */
+#define        IEEE80211_R_RSSI        0x0000002       /* global RSSI value 
valid */
+#define        IEEE80211_R_C_CHAIN     0x0000004       /* RX chain count valid 
*/
+#define        IEEE80211_R_C_NF        0x0000008       /* per-chain NF value 
valid */
+#define        IEEE80211_R_C_RSSI      0x0000010       /* per-chain RSSI value 
valid */
+#define        IEEE80211_R_C_EVM       0x0000020       /* per-chain EVM valid 
*/
+#define        IEEE80211_R_C_HT40      0x0000040       /* RX'ed packet is 
40mhz, pilots 4,5 valid */
+#define        IEEE80211_R_FREQ        0x0000080       /* Freq value 
populated, MHz */
+#define        IEEE80211_R_IEEE        0x0000100       /* IEEE value populated 
*/
+#define        IEEE80211_R_BAND        0x0000200       /* Frequency band 
populated */
+
+struct ieee80211_rx_stats {
+       uint32_t r_flags;               /* IEEE80211_R_* flags */
+       uint8_t c_chain;                /* number of RX chains involved */
+       int16_t c_nf_ctl[IEEE80211_MAX_CHAINS]; /* per-chain NF */
+       int16_t c_nf_ext[IEEE80211_MAX_CHAINS]; /* per-chain NF */
+       int16_t c_rssi_ctl[IEEE80211_MAX_CHAINS];       /* per-chain RSSI */
+       int16_t c_rssi_ext[IEEE80211_MAX_CHAINS];       /* per-chain RSSI */
+       uint8_t nf;                     /* global NF */
+       uint8_t rssi;                   /* global RSSI */
+       uint8_t evm[IEEE80211_MAX_CHAINS][IEEE80211_MAX_EVM_PILOTS];
+                                       /* per-chain, per-pilot EVM values */
+       uint16_t c_freq;
+       uint8_t c_ieee;
+};
+
+struct ieee80211_rx_params {
+       struct ieee80211_rx_stats params;
+};
+
+int ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats 
*rxs);
+int ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _KERNEL */
+
+#define        IEEE80211_MALLOC        malloc
+#define        IEEE80211_FREE          free
+
+/* XXX TODO: get rid of WAITOK, fix all the users of it? */
+#define        IEEE80211_M_NOWAIT      M_NOWAIT
+#define        IEEE80211_M_WAITOK      M_WAITOK
+#define        IEEE80211_M_ZERO        M_ZERO
+
 #endif /* _FBSD_COMPAT_NET80211_IEEE80211_HAIKU_H_ */

############################################################################

Commit:      af8988cdb6664339b2958b32863554c70d2fe76f
URL:         https://git.haiku-os.org/haiku/commit/?id=af8988cdb666
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Tue Jun 26 02:19:39 2018 UTC

freebsd11_wlan: Adapt net80211 code for Haiku's usage.

Changes mostly ported from the FreeBSD 9 code, but some of it is new.
Hopefully in the future, this diff can be reused almost wholesale,
instead of having to re-create it as was done in past upgrades.

----------------------------------------------------------------------------

diff --git a/src/libs/compat/Jamfile b/src/libs/compat/Jamfile
index 1b4bd3b639..335d905250 100644
--- a/src/libs/compat/Jamfile
+++ b/src/libs/compat/Jamfile
@@ -3,3 +3,4 @@ SubDir HAIKU_TOP src libs compat ;
 SubInclude HAIKU_TOP src libs compat freebsd_network ;
 SubInclude HAIKU_TOP src libs compat freebsd_wlan ;
 SubInclude HAIKU_TOP src libs compat freebsd11_network ;
+SubInclude HAIKU_TOP src libs compat freebsd11_wlan ;
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211.c 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211.c
index 8ca766b7f3..4b1aec43fc 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD: releng/11.1/sys/net80211/ieee80211.c 
300232 2016-05-19 21:08
 #include <net/if_dl.h>
 #include <net/if_media.h>
 #include <net/if_types.h>
+#include <net/vnet.h>
 #include <net/ethernet.h>
 
 #include <net80211/ieee80211_var.h>
@@ -259,7 +260,7 @@ ic_printf(struct ieee80211com *ic, const char * fmt, ...)
 }
 
 static LIST_HEAD(, ieee80211com) ic_head = LIST_HEAD_INITIALIZER(ic_head);
-static struct mtx ic_list_mtx;
+struct mtx ic_list_mtx;
 MTX_SYSINIT(ic_list, &ic_list_mtx, "ieee80211com list", MTX_DEF);
 
 static int
@@ -273,6 +274,7 @@ sysctl_ieee80211coms(SYSCTL_HANDLER_ARGS)
        error = sysctl_wire_old_buffer(req, 0);
        if (error)
                return (error);
+#ifndef __HAIKU__
        sbuf_new_for_sysctl(&sb, NULL, 8, req);
        sbuf_clear_flags(&sb, SBUF_INCLUDENUL);
        sp = "";
@@ -284,6 +286,7 @@ sysctl_ieee80211coms(SYSCTL_HANDLER_ARGS)
        mtx_unlock(&ic_list_mtx);
        error = sbuf_finish(&sb);
        sbuf_delete(&sb);
+#endif
        return (error);
 }
 
@@ -308,8 +311,10 @@ ieee80211_ifattach(struct ieee80211com *ic)
            taskqueue_thread_enqueue, &ic->ic_tq);
        taskqueue_start_threads(&ic->ic_tq, 1, PI_NET, "%s net80211 taskq",
            ic->ic_name);
+#ifndef __HAIKU__
        ic->ic_ierrors = counter_u64_alloc(M_WAITOK);
        ic->ic_oerrors = counter_u64_alloc(M_WAITOK);
+#endif
        /*
         * Fill in 802.11 available channel set, mark all
         * available channels as active, and pick a default
@@ -337,6 +342,9 @@ ieee80211_ifattach(struct ieee80211com *ic)
        ieee80211_scan_attach(ic);
        ieee80211_regdomain_attach(ic);
        ieee80211_dfs_attach(ic);
+#if defined(__HAIKU__)
+       ieee80211_ratectl_attach(ic);
+#endif
 
        ieee80211_sysctl_attach(ic);
 
@@ -371,6 +379,9 @@ ieee80211_ifdetach(struct ieee80211com *ic)
        ieee80211_waitfor_parent(ic);
 
        ieee80211_sysctl_detach(ic);
+#if defined(__HAIKU__)
+       ieee80211_ratectl_detach(ic);
+#endif
        ieee80211_dfs_detach(ic);
        ieee80211_regdomain_detach(ic);
        ieee80211_scan_detach(ic);
@@ -384,8 +395,10 @@ ieee80211_ifdetach(struct ieee80211com *ic)
        ieee80211_power_detach(ic);
        ieee80211_node_detach(ic);
 
+#ifndef __HAIKU__
        counter_u64_free(ic->ic_ierrors);
        counter_u64_free(ic->ic_oerrors);
+#endif
 
        taskqueue_free(ic->ic_tq);
        IEEE80211_TX_LOCK_DESTROY(ic);
@@ -444,12 +457,14 @@ ieee80211_get_counter(struct ifnet *ifp, ift_counter cnt)
 
        rv = if_get_counter_default(ifp, cnt);
        switch (cnt) {
+#ifndef __HAIKU__
        case IFCOUNTER_OERRORS:
                rv += counter_u64_fetch(ic->ic_oerrors);
                break;
        case IFCOUNTER_IERRORS:
                rv += counter_u64_fetch(ic->ic_ierrors);
                break;
+#endif
        default:
                break;
        }
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211.h 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211.h
index c79cb4b77c..3e436d459a 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211.h
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211.h
@@ -32,6 +32,8 @@
  * 802.11 protocol definitions.
  */
 
+extern struct mtx ic_list_mtx;
+
 #define        IEEE80211_ADDR_LEN      6               /* size of 802.11 
address */
 /* is 802.11 address multicast/broadcast? */
 #define        IEEE80211_IS_MULTICAST(_a)      (*(_a) & 0x01)
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_crypto.c 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_crypto.c
index 3a781600dc..ca49d87491 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_crypto.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_crypto.c
@@ -142,6 +142,11 @@ ieee80211_crypto_attach(struct ieee80211com *ic)
 {
        /* NB: we assume everything is pre-zero'd */
        ciphers[IEEE80211_CIPHER_NONE] = &ieee80211_cipher_none;
+#if defined(__HAIKU__)
+       ieee80211_crypto_ccmp_load();
+       ieee80211_crypto_tkip_load();
+       ieee80211_crypto_wep_load();
+#endif
 }
 
 /*
@@ -150,6 +155,11 @@ ieee80211_crypto_attach(struct ieee80211com *ic)
 void
 ieee80211_crypto_detach(struct ieee80211com *ic)
 {
+#if defined(__HAIKU__)
+       ieee80211_crypto_ccmp_unload();
+       ieee80211_crypto_tkip_unload();
+       ieee80211_crypto_wep_unload();
+#endif
 }
 
 /*
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.c 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.c
index fa4bb7a101..3c70026a6f 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.c
@@ -170,7 +170,7 @@ static      ieee80211_send_action_func 
ht_send_action_ba_addba;
 static ieee80211_send_action_func ht_send_action_ba_delba;
 static ieee80211_send_action_func ht_send_action_ht_txchwidth;
 
-static void
+void
 ieee80211_ht_init(void)
 {
        /*
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.h 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.h
index dcd2992ac2..4c73a63850 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.h
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ht.h
@@ -30,6 +30,7 @@
 /*
  * 802.11n protocol implementation definitions.
  */
+void ieee80211_ht_init(void);
 
 #define        IEEE80211_AGGR_BAWMAX   64      /* max block ack window size */
 /* threshold for aging overlapping non-HT bss */
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_hwmp.c 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_hwmp.c
index ba2f884336..7901c92c5f 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_hwmp.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_hwmp.c
@@ -208,7 +208,7 @@ SYSCTL_PROC(_net_wlan_hwmp, OID_AUTO, inact, CTLTYPE_INT | 
CTLFLAG_RW,
        "mesh route inactivity timeout (ms)");
 
 
-static void
+void
 ieee80211_hwmp_init(void)
 {
        /* Default values as per amendment */
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.c 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.c
index 6103e10f6c..4e75f0cdc6 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.c
@@ -278,8 +278,12 @@ get_scan_result(void *arg, const struct 
ieee80211_scan_entry *se)
        sr->isr_len = len;
        sr->isr_ie_off = sizeof(struct ieee80211req_scan_result);
        sr->isr_ie_len = ielen;
+#ifdef __HAIKU__
+       memcpy(&sr->isr_chan, se->se_chan, sizeof(sr->isr_chan));
+#else
        sr->isr_freq = se->se_chan->ic_freq;
        sr->isr_flags = se->se_chan->ic_flags;
+#endif
        sr->isr_rssi = se->se_rssi;
        sr->isr_noise = se->se_noise;
        sr->isr_intval = se->se_intval;
@@ -397,8 +401,12 @@ get_sta_info(void *arg, struct ieee80211_node *ni)
        si->isi_len = len;
        si->isi_ie_off = sizeof(struct ieee80211req_sta_info);
        si->isi_ie_len = ielen;
+#ifdef __HAIKU__
+       memcpy(&si->isi_chan, ni->ni_chan, sizeof(si->isi_chan));
+#else
        si->isi_freq = ni->ni_chan->ic_freq;
        si->isi_flags = ni->ni_chan->ic_flags;
+#endif
        si->isi_state = ni->ni_flags;
        si->isi_authmode = ni->ni_authmode;
        vap->iv_ic->ic_node_getsignal(ni, &si->isi_rssi, &si->isi_noise);
@@ -1599,8 +1607,25 @@ ieee80211_ioctl_setmlme(struct ieee80211vap *vap, struct 
ieee80211req *ireq)
                return error;
        if  (vap->iv_opmode == IEEE80211_M_STA &&
            mlme.im_op == IEEE80211_MLME_ASSOC)
+#ifndef __HAIKU__
+               return setmlme_assoc_sta(vap, mlme.im_macaddr,
+                       vap->iv_des_ssid[0].len, vap->iv_des_ssid[0].ssid);
+#else
+               /*      The wpa_supplicant (rightfully) supplies the SSID with 
this request.
+                       However, with the code above it gets ignored and the 
desired SSID,
+                       as set by IEEE80211_IOC_SSID is used instead. This 
still works if
+                       the wpa_supplicant is the only client in use and 
IEEE80211_IOC_SSID
+                       is never used, as then the mlme.im_macaddr is used as 
the only
+                       identifying element. If we used IEEE80211_IOC_SSID 
before though,
+                       for example because we joined an open network from the 
net_server
+                       directly, there will always be a mismatch between the 
desired SSID
+                       and the one the wpa_supplicant tries to associate with 
using this
+                       MLME request. No association is then possible. As there 
is no
+                       obvious reason why the request supplied SSID shouldn't 
be used, we
+                       simply do so. */
                return setmlme_assoc_sta(vap, mlme.im_macaddr,
-                   vap->iv_des_ssid[0].len, vap->iv_des_ssid[0].ssid);
+                       mlme.im_ssid_len, mlme.im_ssid);
+#endif
        else if ((vap->iv_opmode == IEEE80211_M_IBSS || 
            vap->iv_opmode == IEEE80211_M_AHDEMO) && 
            mlme.im_op == IEEE80211_MLME_ASSOC)
@@ -3351,7 +3376,9 @@ ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t 
data)
                         * 3. In monitor (or adhoc-demo) mode.
                         */
                        if (ifp->if_bridge == NULL ||
+#ifndef __HAIKU__
                            (ifp->if_flags & IFF_PPROMISC) != 0 ||
+#endif
                            vap->iv_opmode == IEEE80211_M_MONITOR ||
                            (vap->iv_opmode == IEEE80211_M_AHDEMO &&
                            (vap->iv_caps & IEEE80211_C_TDMA) == 0)) {
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.h 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.h
index 36b0b55b21..69799c498e 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.h
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ioctl.h
@@ -422,8 +422,12 @@ struct ieee80211req_sta_info {
        uint16_t        isi_len;                /* total length (mult of 4) */
        uint16_t        isi_ie_off;             /* offset to IE data */
        uint16_t        isi_ie_len;             /* IE length */
+#ifdef __HAIKU__
+       struct ieee80211_channel        isi_chan;       /* Handing out the 
conmplete channel info */
+#else
        uint16_t        isi_freq;               /* MHz */
        uint32_t        isi_flags;              /* channel flags */
+#endif
        uint32_t        isi_state;              /* state flags */
        uint8_t         isi_authmode;           /* authentication algorithm */
        int8_t          isi_rssi;               /* receive signal strength */
@@ -578,7 +582,7 @@ struct ieee80211req_sta_vlan {
        uint16_t        sv_vlan;
 };
 
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__HAIKU__)
 /*
  * FreeBSD-style ioctls.
  */
@@ -731,6 +735,23 @@ struct ieee80211req {
 #define        IEEE80211_IOC_QUIET_OFFSET      207     /* Quiet Offset */
 #define        IEEE80211_IOC_QUIET_DUR         208     /* Quiet Duration */
 #define        IEEE80211_IOC_QUIET_COUNT       209     /* Quiet Count */
+
+#ifdef __HAIKU__
+/*
+       These are here to allow overcoming a difference between Haiku and
+       FreeBSD drivers. In FreeBSD a device can be set into the down state
+       but is still fully configurable using the ioctl interface. The Haiku
+       network stack on the other hand opens and closes the driver on the
+       transition form up to down and vice versa. This difference can become
+       problematic with ported software that depends on the original behaviour.
+       Therefore IEEE80211_IOC_HAIKU_COMPAT_WLAN_{UP|DOWN} provide a way to
+       achieve the behaviour of setting and clearing IFF_UP without opening
+       or closing the driver itself.
+*/
+#define IEEE80211_IOC_HAIKU_COMPAT_WLAN_UP             0x6000
+#define IEEE80211_IOC_HAIKU_COMPAT_WLAN_DOWN   0x6001
+#endif /* __HAIKU__ */
+
 /*
  * Parameters for controlling a scan requested with
  * IEEE80211_IOC_SCAN_REQ.
@@ -802,8 +823,12 @@ struct ieee80211req_scan_result {
        uint16_t        isr_len;                /* total length (mult of 4) */
        uint16_t        isr_ie_off;             /* offset to SSID+IE data */
        uint16_t        isr_ie_len;             /* IE length */
+#ifdef __HAIKU__
+       struct ieee80211_channel        isr_chan;       /* Handing out the 
conmplete channel info */
+#else
        uint16_t        isr_freq;               /* MHz */
        uint16_t        isr_flags;              /* channel flags */
+#endif
        int8_t          isr_noise;
        int8_t          isr_rssi;
        uint16_t        isr_intval;             /* beacon interval */
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.c 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.c
index 7148d830f7..fe0bb1aad1 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.c
@@ -545,7 +545,7 @@ mesh_gatemode_cb(void *arg)
        mesh_gatemode_setup(vap);
 }
 
-static void
+void
 ieee80211_mesh_init(void)
 {
 
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.h 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.h
index cc6e0ca5e3..a71b4b92cc 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.h
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_mesh.h
@@ -40,6 +40,8 @@
 /*
  * 802.11s Information Elements.
 */
+void ieee80211_mesh_init(void);
+
 /* Mesh Configuration */
 #define IEEE80211_MESH_CONF_SZ         (7)
 struct ieee80211_meshconf_ie {
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_output.c 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_output.c
index 846dddb31a..6d22921500 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_output.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_output.c
@@ -581,8 +581,13 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m,
         * Hand to the 802.3 code if not tagged as
         * a raw 802.11 frame.
         */
+#ifdef __HAIKU__
+       if (!dst || dst->sa_family != AF_IEEE80211)
+               return ieee80211_vap_xmitpkt(vap, m);
+#else
        if (dst->sa_family != AF_IEEE80211)
                return vap->iv_output(ifp, m, dst, ro);
+#endif
 #ifdef MAC
        error = mac_ifnet_check_transmit(ifp, m);
        if (error)
@@ -629,7 +634,7 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m,
                 * Permit packets w/ bpf params through regardless
                 * (see below about sa_len).
                 */
-               if (dst->sa_len == 0)
+               if (dst && dst->sa_len == 0)
                        senderr(EHOSTUNREACH);
                ni = ieee80211_ref_node(vap->iv_bss);
        }
@@ -665,7 +670,7 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m,
         * NB: we assume sa_data is suitably aligned to cast.
         */
        ret = ieee80211_raw_output(vap, ni, m,
-           (const struct ieee80211_bpf_params *)(dst->sa_len ?
+               (const struct ieee80211_bpf_params *)((dst && dst->sa_len) ?
                dst->sa_data : NULL));
        IEEE80211_TX_UNLOCK(ic);
        return (ret);
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.c 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.c
index e390cfe95d..7a0009786b 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.c
@@ -347,7 +347,7 @@ ieee80211_setup_ratetable(struct ieee80211_rate_table *rt)
 }
 
 /* Setup all rate tables */
-static void
+void
 ieee80211_phy_init(void)
 {
        static struct ieee80211_rate_table * const ratetables[] = {
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.h 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.h
index 9a262557d6..312c97fbb6 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.h
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_phy.h
@@ -32,6 +32,7 @@
 /*
  * IEEE 802.11 PHY-related definitions.
  */
+void ieee80211_phy_init(void);
 
 /*
  * Contention window (slots).
@@ -128,7 +129,7 @@ ieee80211_rate2phytype(const struct ieee80211_rate_table 
*rt, uint8_t rate)
 
        uint8_t rix = rt->rateCodeToIndex[rate & IEEE80211_RATE_VAL];
        KASSERT(rix != (uint8_t)-1, ("rate %d has no info", rate));
-       return rt->info[rix].phy;
+       return (enum ieee80211_phytype)rt->info[rix].phy;
 }
 
 static __inline__ int
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.c 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.c
index d3237a94a6..645267999a 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.c
@@ -447,7 +447,7 @@ static const struct ieee80211_authenticator auth_internal = 
{
 /*
  * Setup internal authenticators once; they are never unregistered.
  */
-static void
+void
 ieee80211_auth_setup(void)
 {
        ieee80211_authenticator_register(IEEE80211_AUTH_OPEN, &auth_internal);
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.h 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.h
index 89b9f2b6fe..1a0bf498a8 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.h
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_proto.h
@@ -31,6 +31,7 @@
 /*
  * 802.11 protocol implementation definitions.
  */
+void ieee80211_auth_setup(void);
 
 enum ieee80211_state {
        IEEE80211_S_INIT        = 0,    /* default state */
@@ -165,7 +166,7 @@ void        ieee80211_addbasicrates(struct 
ieee80211_rateset *,
 static __inline int
 ieee80211_hdrsize(const void *data)
 {
-       const struct ieee80211_frame *wh = data;
+       const struct ieee80211_frame *wh = (struct ieee80211_frame *)data;
        int size = sizeof(struct ieee80211_frame);
 
        /* NB: we don't handle control frames */
@@ -184,7 +185,7 @@ ieee80211_hdrsize(const void *data)
 static __inline int
 ieee80211_anyhdrsize(const void *data)
 {
-       const struct ieee80211_frame *wh = data;
+       const struct ieee80211_frame *wh = (struct ieee80211_frame *)data;
 
        if ((wh->i_fc[0]&IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) {
                switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) {
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.c 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.c
index e8b525f308..23d94c3df6 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.c
@@ -53,6 +53,30 @@ static const char *ratectl_modnames[IEEE80211_RATECTL_MAX] = 
{
 
 MALLOC_DEFINE(M_80211_RATECTL, "80211ratectl", "802.11 rate control");
 
+#if defined(__HAIKU__)
+/*
+ * Setup ratectl support for a device/shared instance.
+ */
+void
+ieee80211_ratectl_attach(struct ieee80211com *ic)
+{
+       ieee80211_ratectl_none_load();
+       ieee80211_ratectl_amrr_load();
+       ieee80211_ratectl_rssadapt_load();
+}
+
+/*
+ * Teardown ratectl support.
+ */
+void
+ieee80211_ratectl_detach(struct ieee80211com *ic)
+{
+       ieee80211_ratectl_none_unload();
+       ieee80211_ratectl_amrr_unload();
+       ieee80211_ratectl_rssadapt_unload();
+}
+#endif
+
 void
 ieee80211_ratectl_register(int type, const struct ieee80211_ratectl *ratectl)
 {
@@ -90,6 +114,7 @@ ieee80211_ratectl_sysctl_stats(SYSCTL_HANDLER_ARGS)
        error = sysctl_wire_old_buffer(req, 0);
        if (error)
                return (error);
+#ifndef __HAIKU__
        sbuf_new_for_sysctl(&sb, NULL, 8, req);
        sbuf_clear_flags(&sb, SBUF_INCLUDENUL);
 
@@ -101,6 +126,7 @@ ieee80211_ratectl_sysctl_stats(SYSCTL_HANDLER_ARGS)
 
        error = sbuf_finish(&sb);
        sbuf_delete(&sb);
+#endif
        return (error);
 }
 
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.h 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.h
index 2bd6b00af1..2cafb71fda 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.h
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_ratectl.h
@@ -25,6 +25,8 @@
  * $FreeBSD: releng/11.1/sys/net80211/ieee80211_ratectl.h 296925 2016-03-16 
02:07:04Z adrian $
  */
 
+#include <sys/sbuf.h>
+
 enum ieee80211_ratealgs {
        IEEE80211_RATECTL_AMRR          = 0,
        IEEE80211_RATECTL_RSSADAPT      = 1,
@@ -61,6 +63,17 @@ void ieee80211_ratectl_unregister(int);
 void   ieee80211_ratectl_init(struct ieee80211vap *);
 void   ieee80211_ratectl_set(struct ieee80211vap *, int);
 
+#if defined (__HAIKU__)
+void ieee80211_ratectl_attach(struct ieee80211com *ic);
+void ieee80211_ratectl_detach(struct ieee80211com *ic);
+void ieee80211_ratectl_none_load(void);
+void ieee80211_ratectl_none_unload(void);
+void ieee80211_ratectl_amrr_load(void);
+void ieee80211_ratectl_amrr_unload(void);
+void ieee80211_ratectl_rssadapt_load(void);
+void ieee80211_ratectl_rssadapt_unload(void);
+#endif
+
 MALLOC_DECLARE(M_80211_RATECTL);
 
 static __inline void
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan.c 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan.c
index 273ff593b6..67572a0384 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan.c
@@ -80,6 +80,10 @@ ieee80211_scan_attach(struct ieee80211com *ic)
                ieee80211_swscan_attach(ic);
        else
                ic->ic_scan_methods->sc_attach(ic);
+
+#if defined(__HAIKU__)
+       ieee80211_scan_sta_init();
+#endif
 }
 
 void
@@ -93,6 +97,10 @@ ieee80211_scan_detach(struct ieee80211com *ic)
         * I'll do that later.
         */
        ic->ic_scan_methods->sc_detach(ic);
+
+#if defined(__HAIKU__)
+       ieee80211_scan_sta_uninit();
+#endif
 }
 
 static const struct ieee80211_roamparam defroam[IEEE80211_MODE_MAX] = {
@@ -375,6 +383,15 @@ ieee80211_check_scan(struct ieee80211vap *vap, int flags,
                flags |= IEEE80211_SCAN_FLUSH;
        }
 
+#ifdef __HAIKU__
+       /* We never want to join if not explicitly looking for an SSID */
+       if (nssid == 0 && (flags & IEEE80211_SCAN_NOJOIN) == 0) {
+               IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
+                       "%s: setting nojoin due to no configured ssid\n", 
__func__);
+               flags |= IEEE80211_SCAN_NOJOIN;
+       }
+#endif
+
        /*
         * XXX TODO: separate things out a bit better.
         */
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sta.c 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sta.c
index 69c782fe2a..c69bb4056f 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sta.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sta.c
@@ -1933,3 +1933,19 @@ static const struct ieee80211_scanner mesh_default = {
 };
 IEEE80211_SCANNER_ALG(mesh, IEEE80211_M_MBSS, mesh_default);
 #endif /* IEEE80211_SUPPORT_MESH */
+
+#if defined(__HAIKU__)
+void
+ieee80211_scan_sta_init()
+{
+       ieee80211_scanner_register(IEEE80211_M_STA, &sta_default);
+       ieee80211_scanner_register(IEEE80211_M_IBSS, &adhoc_default);
+}
+
+void
+ieee80211_scan_sta_uninit()
+{
+       ieee80211_scanner_unregister(IEEE80211_M_STA, &sta_default);
+       ieee80211_scanner_unregister(IEEE80211_M_IBSS, &adhoc_default);
+}
+#endif /* __HAIKU__ */
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sw.c 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sw.c
index e4000460a8..5e45e2a948 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sw.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_scan_sw.c
@@ -617,7 +617,7 @@ scan_start(void *arg, int pending)
                        /* Enable station power save mode */
                        vap->iv_sta_ps(vap, 1);
                        /* Wait until null data frame will be ACK'ed */
-                       mtx_sleep(vap, IEEE80211_LOCK_OBJ(ic), PCATCH,
+                       msleep(vap, IEEE80211_LOCK_OBJ(ic), PCATCH,
                            "sta_ps", msecs_to_ticks(10));
                        if (ss_priv->ss_iflags & ISCAN_ABORT) {
                                scan_done(ss, 0);
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_var.h 
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_var.h
index f52afc5370..97c05ef390 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211_var.h
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211_var.h
@@ -38,6 +38,8 @@
 #include <net80211/ieee80211_freebsd.h>
 #elif defined(__linux__)
 #include <net80211/ieee80211_linux.h>
+#elif defined(__HAIKU__)
+#include <net80211/ieee80211_haiku.h>
 #else
 #error "No support for your operating system!"
 #endif

############################################################################

Commit:      688153aaec257e765cd987ad79c85d5206ff7157
URL:         https://git.haiku-os.org/haiku/commit/?id=688153aaec25
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Tue Jun 26 02:21:28 2018 UTC

iprowifi4965: Sync with FreeBSD 11.1.

Tested and verified as working on my Lenovo ThinkPad T61.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/Jamfile 
b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/Jamfile
index 8309c2987f..7e4074fffa 100644
--- a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/Jamfile
+++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/Jamfile
@@ -1,8 +1,8 @@
 SubDir HAIKU_TOP src add-ons kernel drivers network wlan iprowifi4965 ;
 
-UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ]
+UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_network compat ]
        : true ;
-UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_wlan ] : true ;
+UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_wlan ] : true ;
 UsePrivateHeaders net system ;
 UsePrivateKernelHeaders ;
 
@@ -20,8 +20,8 @@ KernelAddon iprowifi4965 :
        if_iwn.c
        glue.c
        :
-       libfreebsd_wlan.a
-       libfreebsd_network.a
+       libfreebsd11_wlan.a
+       libfreebsd11_network.a
        ;
 
 HAIKU_WIFI_FIRMWARE_PACKAGES on iprowifi4965 =
@@ -37,4 +37,3 @@ HAIKU_WIFI_FIRMWARE_ARCHIVES on iprowifi4965 =
        iwlwifi-6000-ucode-9.221.4.1.tgz iwlwifi-6000g2a-ucode-18.168.6.1.tgz
        iwlwifi-6000g2b-ucode-18.168.6.1.tgz iwlwifi-6050-ucode-41.28.5.1.tgz ;
 HAIKU_WIFI_FIRMWARE_DO_EXTRACT on iprowifi4965 = true ;
-
diff --git 
a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c 
b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c
index ac0c794839..73950202f1 100644
--- a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c
+++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c
@@ -1,9 +1,10 @@
 /*-
- * Copyright (c) 2007-2009
- *     Damien Bergamini <damien.bergamini@xxxxxxx>
- * Copyright (c) 2008
- *     Benjamin Close <benjsc@xxxxxxxxxxx>
+ * Copyright (c) 2007-2009 Damien Bergamini <damien.bergamini@xxxxxxx>
+ * Copyright (c) 2008 Benjamin Close <benjsc@xxxxxxxxxxx>
  * Copyright (c) 2008 Sam Leffler, Errno Consulting
+ * Copyright (c) 2011 Intel Corporation
+ * Copyright (c) 2013 Cedric GROSS <c.gross@xxxxxxxxxxx>
+ * Copyright (c) 2013 Adrian Chadd <adrian@xxxxxxxxxxx>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -35,11 +36,13 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/malloc.h>
 #include <sys/bus.h>
+#include <sys/conf.h>
 #include <sys/rman.h>
 #include <sys/endian.h>
 #include <sys/firmware.h>
 #include <sys/limits.h>
 #include <sys/module.h>
+#include <sys/priv.h>
 #include <sys/queue.h>
 #include <sys/taskqueue.h>
 
@@ -50,19 +53,13 @@ __FBSDID("$FreeBSD$");
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
 
-#include <net/bpf.h>
 #include <net/if.h>
-#include <net/if_arp.h>
-#include <net/ethernet.h>
+#include <net/if_var.h>
 #include <net/if_dl.h>
 #include <net/if_media.h>
-#include <net/if_types.h>
 
 #include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
 #include <netinet/if_ether.h>
-#include <netinet/ip.h>
 
 #include <net80211/ieee80211_var.h>
 #include <net80211/ieee80211_radiotap.h>
@@ -71,6 +68,10 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/iwn/if_iwnreg.h>
 #include <dev/iwn/if_iwnvar.h>
+#include <dev/iwn/if_iwn_devid.h>
+#include <dev/iwn/if_iwn_chip_cfg.h>
+#include <dev/iwn/if_iwn_debug.h>
+#include <dev/iwn/if_iwn_ioctl.h>
 
 struct iwn_ident {
        uint16_t        vendor;
@@ -79,45 +80,49 @@ struct iwn_ident {
 };
 
 static const struct iwn_ident iwn_ident_table[] = {
-       { 0x8086, 0x0082, "Intel Centrino Advanced-N 6205"              },
-       { 0x8086, 0x0083, "Intel Centrino Wireless-N 1000"              },
-       { 0x8086, 0x0084, "Intel Centrino Wireless-N 1000"              },
-       { 0x8086, 0x0085, "Intel Centrino Advanced-N 6205"              },
-       { 0x8086, 0x0087, "Intel Centrino Advanced-N + WiMAX 6250"      },
-       { 0x8086, 0x0089, "Intel Centrino Advanced-N + WiMAX 6250"      },
-       { 0x8086, 0x008a, "Intel Centrino Wireless-N 1030"              },
-       { 0x8086, 0x008b, "Intel Centrino Wireless-N 1030"              },
-       { 0x8086, 0x0090, "Intel Centrino Advanced-N 6230"              },
-       { 0x8086, 0x0091, "Intel Centrino Advanced-N 6230"              },
-#ifdef __HAIKU__
-       { 0x8086, 0x088e, "Intel Centrino Advanced-N 6235"              },
-       { 0x8086, 0x088f, "Intel Centrino Advanced-N 6235"              },
-#endif
-       { 0x8086, 0x0885, "Intel Centrino Wireless-N + WiMAX 6150"      },
-       { 0x8086, 0x0886, "Intel Centrino Wireless-N + WiMAX 6150"      },
-       { 0x8086, 0x0896, "Intel Centrino Wireless-N 130"               },
-       { 0x8086, 0x0887, "Intel Centrino Wireless-N 130"               },
-#ifdef __HAIKU__
-       { 0x8086, 0x0888, "Intel Centrino Wireless-N 2230"              },
-#endif
-       { 0x8086, 0x08ae, "Intel Centrino Wireless-N 100"               },
-       { 0x8086, 0x08af, "Intel Centrino Wireless-N 100"               },
-       { 0x8086, 0x4229, "Intel Wireless WiFi Link 4965"               },
-       { 0x8086, 0x422b, "Intel Centrino Ultimate-N 6300"              },
-       { 0x8086, 0x422c, "Intel Centrino Advanced-N 6200"              },
-       { 0x8086, 0x422d, "Intel Wireless WiFi Link 4965"               },
-       { 0x8086, 0x4230, "Intel Wireless WiFi Link 4965"               },
-       { 0x8086, 0x4232, "Intel WiFi Link 5100"                        },
-       { 0x8086, 0x4233, "Intel Wireless WiFi Link 4965"               },
-       { 0x8086, 0x4235, "Intel Ultimate N WiFi Link 5300"             },
-       { 0x8086, 0x4236, "Intel Ultimate N WiFi Link 5300"             },
-       { 0x8086, 0x4237, "Intel WiFi Link 5100"                        },
-       { 0x8086, 0x4238, "Intel Centrino Ultimate-N 6300"              },
-       { 0x8086, 0x4239, "Intel Centrino Advanced-N 6200"              },
-       { 0x8086, 0x423a, "Intel WiMAX/WiFi Link 5350"                  },
-       { 0x8086, 0x423b, "Intel WiMAX/WiFi Link 5350"                  },
-       { 0x8086, 0x423c, "Intel WiMAX/WiFi Link 5150"                  },
-       { 0x8086, 0x423d, "Intel WiMAX/WiFi Link 5150"                  },
+       { 0x8086, IWN_DID_6x05_1, "Intel Centrino Advanced-N 6205"              
},
+       { 0x8086, IWN_DID_1000_1, "Intel Centrino Wireless-N 1000"              
},
+       { 0x8086, IWN_DID_1000_2, "Intel Centrino Wireless-N 1000"              
},
+       { 0x8086, IWN_DID_6x05_2, "Intel Centrino Advanced-N 6205"              
},
+       { 0x8086, IWN_DID_6050_1, "Intel Centrino Advanced-N + WiMAX 6250"      
},
+       { 0x8086, IWN_DID_6050_2, "Intel Centrino Advanced-N + WiMAX 6250"      
},
+       { 0x8086, IWN_DID_x030_1, "Intel Centrino Wireless-N 1030"              
},
+       { 0x8086, IWN_DID_x030_2, "Intel Centrino Wireless-N 1030"              
},
+       { 0x8086, IWN_DID_x030_3, "Intel Centrino Advanced-N 6230"              
},
+       { 0x8086, IWN_DID_x030_4, "Intel Centrino Advanced-N 6230"              
},
+       { 0x8086, IWN_DID_6150_1, "Intel Centrino Wireless-N + WiMAX 6150"      
},
+       { 0x8086, IWN_DID_6150_2, "Intel Centrino Wireless-N + WiMAX 6150"      
},
+       { 0x8086, IWN_DID_2x00_1, "Intel(R) Centrino(R) Wireless-N 2200 BGN"    
},
+       { 0x8086, IWN_DID_2x00_2, "Intel(R) Centrino(R) Wireless-N 2200 BGN"    
},
+       /* XXX 2200D is IWN_SDID_2x00_4; there's no way to express this here! */
+       { 0x8086, IWN_DID_2x30_1, "Intel Centrino Wireless-N 2230"              
},
+       { 0x8086, IWN_DID_2x30_2, "Intel Centrino Wireless-N 2230"              
},
+       { 0x8086, IWN_DID_130_1, "Intel Centrino Wireless-N 130"                
},
+       { 0x8086, IWN_DID_130_2, "Intel Centrino Wireless-N 130"                
},
+       { 0x8086, IWN_DID_100_1, "Intel Centrino Wireless-N 100"                
},
+       { 0x8086, IWN_DID_100_2, "Intel Centrino Wireless-N 100"                
},
+       { 0x8086, IWN_DID_105_1, "Intel Centrino Wireless-N 105"                
},
+       { 0x8086, IWN_DID_105_2, "Intel Centrino Wireless-N 105"                
},
+       { 0x8086, IWN_DID_135_1, "Intel Centrino Wireless-N 135"                
},
+       { 0x8086, IWN_DID_135_2, "Intel Centrino Wireless-N 135"                
},
+       { 0x8086, IWN_DID_4965_1, "Intel Wireless WiFi Link 4965"               
},
+       { 0x8086, IWN_DID_6x00_1, "Intel Centrino Ultimate-N 6300"              
},
+       { 0x8086, IWN_DID_6x00_2, "Intel Centrino Advanced-N 6200"              
},
+       { 0x8086, IWN_DID_4965_2, "Intel Wireless WiFi Link 4965"               
},
+       { 0x8086, IWN_DID_4965_3, "Intel Wireless WiFi Link 4965"               
},
+       { 0x8086, IWN_DID_5x00_1, "Intel WiFi Link 5100"                        
},
+       { 0x8086, IWN_DID_4965_4, "Intel Wireless WiFi Link 4965"               
},
+       { 0x8086, IWN_DID_5x00_3, "Intel Ultimate N WiFi Link 5300"             
},
+       { 0x8086, IWN_DID_5x00_4, "Intel Ultimate N WiFi Link 5300"             
},
+       { 0x8086, IWN_DID_5x00_2, "Intel WiFi Link 5100"                        
},
+       { 0x8086, IWN_DID_6x00_3, "Intel Centrino Ultimate-N 6300"              
},
+       { 0x8086, IWN_DID_6x00_4, "Intel Centrino Advanced-N 6200"              
},
+       { 0x8086, IWN_DID_5x50_1, "Intel WiMAX/WiFi Link 5350"                  
},
+       { 0x8086, IWN_DID_5x50_2, "Intel WiMAX/WiFi Link 5350"                  
},
+       { 0x8086, IWN_DID_5x50_3, "Intel WiMAX/WiFi Link 5150"                  
},
+       { 0x8086, IWN_DID_5x50_4, "Intel WiMAX/WiFi Link 5150"                  
},
+       { 0x8086, IWN_DID_6035_1, "Intel Centrino Advanced 6235"                
},
+       { 0x8086, IWN_DID_6035_2, "Intel Centrino Advanced 6235"                
},
        { 0, 0, NULL }
 };
 
@@ -125,6 +130,7 @@ static int  iwn_probe(device_t);
 static int     iwn_attach(device_t);
 static int     iwn4965_attach(struct iwn_softc *, uint16_t);
 static int     iwn5000_attach(struct iwn_softc *, uint16_t);
+static int     iwn_config_specific(struct iwn_softc *, uint16_t);
 static void    iwn_radiotap_attach(struct iwn_softc *);
 static void    iwn_sysctlattach(struct iwn_softc *);
 static struct ieee80211vap *iwn_vap_create(struct ieee80211com *,
@@ -163,14 +169,20 @@ static void       iwn5000_ict_reset(struct iwn_softc *);
 static int     iwn_read_eeprom(struct iwn_softc *,
                    uint8_t macaddr[IEEE80211_ADDR_LEN]);
 static void    iwn4965_read_eeprom(struct iwn_softc *);
+#ifdef IWN_DEBUG
 static void    iwn4965_print_power_group(struct iwn_softc *, int);
+#endif
 static void    iwn5000_read_eeprom(struct iwn_softc *);
 static uint32_t        iwn_eeprom_channel_flags(struct iwn_eeprom_chan *);
-static void    iwn_read_eeprom_band(struct iwn_softc *, int);
-static void    iwn_read_eeprom_ht40(struct iwn_softc *, int);
+static void    iwn_read_eeprom_band(struct iwn_softc *, int, int, int *,
+                   struct ieee80211_channel[]);
+static void    iwn_read_eeprom_ht40(struct iwn_softc *, int, int, int *,
+                   struct ieee80211_channel[]);
 static void    iwn_read_eeprom_channels(struct iwn_softc *, int, uint32_t);
 static struct iwn_eeprom_chan *iwn_find_eeprom_channel(struct iwn_softc *,
                    struct ieee80211_channel *);
+static void    iwn_getradiocaps(struct ieee80211com *, int, int *,
+                   struct ieee80211_channel[]);
 static int     iwn_setregdomain(struct ieee80211com *,
                    struct ieee80211_regdomain *, int,
                    struct ieee80211_channel[]);
@@ -197,7 +209,7 @@ static void iwn5000_tx_done(struct iwn_softc *, struct 
iwn_rx_desc *,
                    struct iwn_rx_data *);
 static void    iwn_tx_done(struct iwn_softc *, struct iwn_rx_desc *, int,
                    uint8_t);
-static void    iwn_ampdu_tx_done(struct iwn_softc *, int, int, int, void *);
+static void    iwn_ampdu_tx_done(struct iwn_softc *, int, int, int, int, void 
*);
 static void    iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *);
 static void    iwn_notif_intr(struct iwn_softc *);
 static void    iwn_wakeup_intr(struct iwn_softc *);
@@ -216,12 +228,14 @@ static int        iwn_tx_data(struct iwn_softc *, struct 
mbuf *,
 static int     iwn_tx_data_raw(struct iwn_softc *, struct mbuf *,
                    struct ieee80211_node *,
                    const struct ieee80211_bpf_params *params);
+static void    iwn_xmit_task(void *arg0, int pending);
 static int     iwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
                    const struct ieee80211_bpf_params *);
-static void    iwn_start(struct ifnet *);
-static void    iwn_start_locked(struct ifnet *);
+static int     iwn_transmit(struct ieee80211com *, struct mbuf *);
+static void    iwn_scan_timeout(void *);
 static void    iwn_watchdog(void *);
-static int     iwn_ioctl(struct ifnet *, u_long, caddr_t);
+static int     iwn_ioctl(struct ieee80211com *, u_long , void *);
+static void    iwn_parent(struct ieee80211com *);
 static int     iwn_cmd(struct iwn_softc *, int, const void *, int, int);
 static int     iwn4965_add_node(struct iwn_softc *, struct iwn_node_info *,
                    int);
@@ -231,7 +245,7 @@ static int  iwn_set_link_quality(struct iwn_softc *,
                    struct ieee80211_node *);
 static int     iwn_add_broadcast_node(struct iwn_softc *, int);
 static int     iwn_updateedca(struct ieee80211com *);
-static void    iwn_update_mcast(struct ifnet *);
+static void    iwn_update_mcast(struct ieee80211com *);
 static void    iwn_set_led(struct iwn_softc *, uint8_t, uint8_t, uint8_t);
 static int     iwn_set_critical_temp(struct iwn_softc *);
 static int     iwn_set_timing(struct iwn_softc *, struct ieee80211_node *);
@@ -254,14 +268,17 @@ static int        iwn4965_set_gains(struct iwn_softc *);
 static int     iwn5000_set_gains(struct iwn_softc *);
 static void    iwn_tune_sensitivity(struct iwn_softc *,
                    const struct iwn_rx_stats *);
+static void    iwn_save_stats_counters(struct iwn_softc *,
+                   const struct iwn_stats *);
 static int     iwn_send_sensitivity(struct iwn_softc *);
+static void    iwn_check_rx_recovery(struct iwn_softc *, struct iwn_stats *);
 static int     iwn_set_pslevel(struct iwn_softc *, int, int, int);
 static int     iwn_send_btcoex(struct iwn_softc *);
 static int     iwn_send_advanced_btcoex(struct iwn_softc *);
 static int     iwn5000_runtime_calib(struct iwn_softc *);
 static int     iwn_config(struct iwn_softc *);
-static uint8_t *ieee80211_add_ssid(uint8_t *, const uint8_t *, u_int);
-static int     iwn_scan(struct iwn_softc *);
+static int     iwn_scan(struct iwn_softc *, struct ieee80211vap *,
+                   struct ieee80211_scan_state *, struct ieee80211_channel *);
 static int     iwn_auth(struct iwn_softc *, struct ieee80211vap *vap);
 static int     iwn_run(struct iwn_softc *, struct ieee80211vap *vap);
 static int     iwn_ampdu_rx_start(struct ieee80211_node *,
@@ -288,8 +305,8 @@ static int  iwn5000_query_calibration(struct iwn_softc *);
 static int     iwn5000_send_calibration(struct iwn_softc *);
 static int     iwn5000_send_wimax_coex(struct iwn_softc *);
 static int     iwn5000_crystal_calib(struct iwn_softc *);
-static int     iwn6000_temp_offset_calib(struct iwn_softc *);
-static int     iwn2000_temp_offset_calib(struct iwn_softc *);
+static int     iwn5000_temp_offset_calib(struct iwn_softc *);
+static int     iwn5000_temp_offset_calibv2(struct iwn_softc *);
 static int     iwn4965_post_alive(struct iwn_softc *);
 static int     iwn5000_post_alive(struct iwn_softc *);
 static int     iwn4965_load_bootcode(struct iwn_softc *, const uint8_t *,
@@ -303,6 +320,7 @@ static int  iwn_read_firmware_leg(struct iwn_softc *,
 static int     iwn_read_firmware_tlv(struct iwn_softc *,
                    struct iwn_fw_info *, uint16_t);
 static int     iwn_read_firmware(struct iwn_softc *);
+static void    iwn_unload_firmware(struct iwn_softc *);
 static int     iwn_clock_wait(struct iwn_softc *);
 static int     iwn_apm_init(struct iwn_softc *);
 static void    iwn_apm_stop_master(struct iwn_softc *);
@@ -314,8 +332,9 @@ static int  iwn_hw_init(struct iwn_softc *);
 static void    iwn_hw_stop(struct iwn_softc *);
 static void    iwn_radio_on(void *, int);
 static void    iwn_radio_off(void *, int);
+static void    iwn_panicked(void *, int);
 static void    iwn_init_locked(struct iwn_softc *);
-static void    iwn_init(void *);
+static void    iwn_init(struct iwn_softc *);
 static void    iwn_stop_locked(struct iwn_softc *);
 static void    iwn_stop(struct iwn_softc *);
 static void    iwn_scan_start(struct ieee80211com *);
@@ -323,77 +342,9 @@ static void        iwn_scan_end(struct ieee80211com *);
 static void    iwn_set_channel(struct ieee80211com *);
 static void    iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long);
 static void    iwn_scan_mindwell(struct ieee80211_scan_state *);
-static void    iwn_hw_reset(void *, int);
-
-#define IWN_DEBUG
-#ifdef IWN_DEBUG
-enum {
-       IWN_DEBUG_XMIT          = 0x00000001,   /* basic xmit operation */
-       IWN_DEBUG_RECV          = 0x00000002,   /* basic recv operation */
-       IWN_DEBUG_STATE         = 0x00000004,   /* 802.11 state transitions */
-       IWN_DEBUG_TXPOW         = 0x00000008,   /* tx power processing */
-       IWN_DEBUG_RESET         = 0x00000010,   /* reset processing */
-       IWN_DEBUG_OPS           = 0x00000020,   /* iwn_ops processing */
-       IWN_DEBUG_BEACON        = 0x00000040,   /* beacon handling */
-       IWN_DEBUG_WATCHDOG      = 0x00000080,   /* watchdog timeout */
-       IWN_DEBUG_INTR          = 0x00000100,   /* ISR */
-       IWN_DEBUG_CALIBRATE     = 0x00000200,   /* periodic calibration */
-       IWN_DEBUG_NODE          = 0x00000400,   /* node management */
-       IWN_DEBUG_LED           = 0x00000800,   /* led management */
-       IWN_DEBUG_CMD           = 0x00001000,   /* cmd submission */
-       IWN_DEBUG_FATAL         = 0x80000000,   /* fatal errors */
-       IWN_DEBUG_ANY           = 0xffffffff
-};
-
-#define DPRINTF(sc, m, fmt, ...) do {                  \
-       if (sc->sc_debug & (m))                         \
-               printf(fmt, __VA_ARGS__);               \
-} while (0)
-
-static const char *
-iwn_intr_str(uint8_t cmd)
-{
-       switch (cmd) {
-       /* Notifications */
-       case IWN_UC_READY:              return "UC_READY";
-       case IWN_ADD_NODE_DONE:         return "ADD_NODE_DONE";
-       case IWN_TX_DONE:               return "TX_DONE";
-       case IWN_START_SCAN:            return "START_SCAN";
-       case IWN_STOP_SCAN:             return "STOP_SCAN";
-       case IWN_RX_STATISTICS:         return "RX_STATS";
-       case IWN_BEACON_STATISTICS:     return "BEACON_STATS";
-       case IWN_STATE_CHANGED:         return "STATE_CHANGED";
-       case IWN_BEACON_MISSED:         return "BEACON_MISSED";
-       case IWN_RX_PHY:                return "RX_PHY";
-       case IWN_MPDU_RX_DONE:          return "MPDU_RX_DONE";
-       case IWN_RX_DONE:               return "RX_DONE";
-
-       /* Command Notifications */
-       case IWN_CMD_RXON:              return "IWN_CMD_RXON";
-       case IWN_CMD_RXON_ASSOC:        return "IWN_CMD_RXON_ASSOC";
-       case IWN_CMD_EDCA_PARAMS:       return "IWN_CMD_EDCA_PARAMS";
-       case IWN_CMD_TIMING:            return "IWN_CMD_TIMING";
-       case IWN_CMD_LINK_QUALITY:      return "IWN_CMD_LINK_QUALITY";
-       case IWN_CMD_SET_LED:           return "IWN_CMD_SET_LED";
-       case IWN5000_CMD_WIMAX_COEX:    return "IWN5000_CMD_WIMAX_COEX";
-       case IWN5000_CMD_CALIB_CONFIG:  return "IWN5000_CMD_CALIB_CONFIG";
-       case IWN5000_CMD_CALIB_RESULT:  return "IWN5000_CMD_CALIB_RESULT";
-       case IWN5000_CMD_CALIB_COMPLETE: return "IWN5000_CMD_CALIB_COMPLETE";
-       case IWN_CMD_SET_POWER_MODE:    return "IWN_CMD_SET_POWER_MODE";
-       case IWN_CMD_SCAN:              return "IWN_CMD_SCAN";
-       case IWN_CMD_SCAN_RESULTS:      return "IWN_CMD_SCAN_RESULTS";
-       case IWN_CMD_TXPOWER:           return "IWN_CMD_TXPOWER";
-       case IWN_CMD_TXPOWER_DBM:       return "IWN_CMD_TXPOWER_DBM";
-       case IWN5000_CMD_TX_ANT_CONFIG: return "IWN5000_CMD_TX_ANT_CONFIG";
-       case IWN_CMD_BT_COEX:           return "IWN_CMD_BT_COEX";
-       case IWN_CMD_SET_CRITICAL_TEMP: return "IWN_CMD_SET_CRITICAL_TEMP";
-       case IWN_CMD_SET_SENSITIVITY:   return "IWN_CMD_SET_SENSITIVITY";
-       case IWN_CMD_PHY_CALIB:         return "IWN_CMD_PHY_CALIB";
-       }
-       return "UNKNOWN INTR NOTIF/CMD";
-}
-#else
-#define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
+#ifdef IWN_DEBUG
+static char    *iwn_get_csr_string(int);
+static void    iwn_debug_register(struct iwn_softc *);
 #endif
 
 static device_method_t iwn_methods[] = {
@@ -423,6 +374,21 @@ MODULE_DEPEND(iwn, firmware, 1, 1, 1);
 MODULE_DEPEND(iwn, pci, 1, 1, 1);
 MODULE_DEPEND(iwn, wlan, 1, 1, 1);
 
+#ifndef __HAIKU__
+static d_ioctl_t iwn_cdev_ioctl;
+static d_open_t iwn_cdev_open;
+static d_close_t iwn_cdev_close;
+
+static struct cdevsw  = {
+       .d_version = D_VERSION,
+       .d_flags = 0,
+       .d_open = iwn_cdev_open,
+       .d_close = iwn_cdev_close,
+       .d_ioctl = iwn_cdev_ioctl,
+       .d_name = "iwn",
+};
+#endif
+
 static int
 iwn_probe(device_t dev)
 {
@@ -438,17 +404,35 @@ iwn_probe(device_t dev)
        return ENXIO;
 }
 
+static int
+iwn_is_3stream_device(struct iwn_softc *sc)
+{
+       /* XXX for now only 5300, until the 5350 can be tested */
+       if (sc->hw_type == IWN_HW_REV_TYPE_5300)
+               return (1);
+       return (0);
+}
+
 static int
 iwn_attach(device_t dev)
 {
-       struct iwn_softc *sc = (struct iwn_softc *)device_get_softc(dev);
+       struct iwn_softc *sc = device_get_softc(dev);
        struct ieee80211com *ic;
-       struct ifnet *ifp;
        int i, error, rid;
-       uint8_t macaddr[IEEE80211_ADDR_LEN];
 
        sc->sc_dev = dev;
 
+#ifdef IWN_DEBUG
+       error = resource_int_value(device_get_name(sc->sc_dev),
+           device_get_unit(sc->sc_dev), "debug", &(sc->sc_debug));
+       if (error != 0)
+               sc->sc_debug = 0;
+#else
+       sc->sc_debug = 0;
+#endif
+
+       DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: begin\n",__func__);
+
        /*
         * Get the offset of the PCI Express Capability Structure in PCI
         * Configuration Space.
@@ -492,7 +476,14 @@ iwn_attach(device_t dev)
        IWN_LOCK_INIT(sc);
 
        /* Read hardware revision and attach. */
-       sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> 4) & 0xf;
+       sc->hw_type = (IWN_READ(sc, IWN_HW_REV) >> IWN_HW_REV_TYPE_SHIFT)
+           & IWN_HW_REV_TYPE_MASK;
+       sc->subdevice_id = pci_get_subdevice(dev);
+
+       /*
+        * 4965 versus 5000 and later have different methods.
+        * Let's set those up first.
+        */
        if (sc->hw_type == IWN_HW_REV_TYPE_4965)
                error = iwn4965_attach(sc, pci_get_device(dev));
        else
@@ -503,6 +494,16 @@ iwn_attach(device_t dev)
                goto fail;
        }
 
+       /*
+        * Next, let's setup the various parameters of each NIC.
+        */
+       error = iwn_config_specific(sc, pci_get_device(dev));
+       if (error != 0) {
+               device_printf(dev, "could not attach device, error %d\n",
+                   error);
+               goto fail;
+       }
+
        if ((error = iwn_hw_prepare(sc)) != 0) {
                device_printf(dev, "hardware not ready, error %d\n", error);
                goto fail;
@@ -558,14 +559,9 @@ iwn_attach(device_t dev)
        /* Clear pending interrupts. */
        IWN_WRITE(sc, IWN_INT, 0xffffffff);
 
-       ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
-       if (ifp == NULL) {
-               device_printf(dev, "can not allocate ifnet structure\n");
-               goto fail;
-       }
-
-       ic = ifp->if_l2com;
-       ic->ic_ifp = ifp;
+       ic = &sc->sc_ic;
+       ic->ic_softc = sc;
+       ic->ic_name = device_get_nameunit(dev);
        ic->ic_phytype = IEEE80211_T_OFDM;      /* not only, but not used */
        ic->ic_opmode = IEEE80211_M_STA;        /* default to BSS mode */
 
@@ -573,7 +569,9 @@ iwn_attach(device_t dev)
        ic->ic_caps =
                  IEEE80211_C_STA               /* station mode supported */
                | IEEE80211_C_MONITOR           /* monitor mode supported */
+#if 0
                | IEEE80211_C_BGSCAN            /* background scanning */
+#endif
                | IEEE80211_C_TXPMGT            /* tx power management */
                | IEEE80211_C_SHSLOT            /* short slot time supported */
                | IEEE80211_C_WPA
@@ -582,10 +580,11 @@ iwn_attach(device_t dev)
                | IEEE80211_C_IBSS              /* ibss/adhoc mode */
 #endif
                | IEEE80211_C_WME               /* WME */
+               | IEEE80211_C_PMGT              /* Station-side power mgmt */
                ;
 
        /* Read MAC address, channels, etc from EEPROM. */
-       if ((error = iwn_read_eeprom(sc, macaddr)) != 0) {
+       if ((error = iwn_read_eeprom(sc, ic->ic_macaddr)) != 0) {
                device_printf(dev, "could not read EEPROM, error %d\n",
                    error);
                goto fail;
@@ -603,12 +602,25 @@ iwn_attach(device_t dev)
        if (bootverbose) {
                device_printf(dev, "MIMO %dT%dR, %.4s, address %6D\n",
                    sc->ntxchains, sc->nrxchains, sc->eeprom_domain,
-                   macaddr, ":");
+                   ic->ic_macaddr, ":");
        }
 
        if (sc->sc_flags & IWN_FLAG_HAS_11N) {
                ic->ic_rxstream = sc->nrxchains;
                ic->ic_txstream = sc->ntxchains;
+
+               /*
+                * Some of the 3 antenna devices (ie, the 4965) only supports
+                * 2x2 operation.  So correct the number of streams if
+                * it's not a 3-stream device.
+                */
+               if (! iwn_is_3stream_device(sc)) {
+                       if (ic->ic_rxstream > 2)
+                               ic->ic_rxstream = 2;
+                       if (ic->ic_txstream > 2)
+                               ic->ic_txstream = 2;
+               }
+
                ic->ic_htcaps =
                          IEEE80211_HTCAP_SMPS_OFF      /* SMPS mode disabled */
                        | IEEE80211_HTCAP_SHORTGI20     /* short GI in 20MHz */
@@ -631,19 +643,12 @@ iwn_attach(device_t dev)
                        ;
        }
 
-       if_initname(ifp, device_get_name(dev), device_get_unit(dev));
-       ifp->if_softc = sc;
-       ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
-       ifp->if_init = iwn_init;
-       ifp->if_ioctl = iwn_ioctl;
-       ifp->if_start = iwn_start;
-       IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
-       ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
-       IFQ_SET_READY(&ifp->if_snd);
-
-       ieee80211_ifattach(ic, macaddr);
+       ieee80211_ifattach(ic);
        ic->ic_vap_create = iwn_vap_create;
+       ic->ic_ioctl = iwn_ioctl;
+       ic->ic_parent = iwn_parent;
        ic->ic_vap_delete = iwn_vap_delete;
+       ic->ic_transmit = iwn_transmit;
        ic->ic_raw_xmit = iwn_raw_xmit;
        ic->ic_node_alloc = iwn_node_alloc;
        sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start;
@@ -664,15 +669,28 @@ iwn_attach(device_t dev)
        ic->ic_set_channel = iwn_set_channel;
        ic->ic_scan_curchan = iwn_scan_curchan;
        ic->ic_scan_mindwell = iwn_scan_mindwell;
+       ic->ic_getradiocaps = iwn_getradiocaps;
        ic->ic_setregdomain = iwn_setregdomain;
 
        iwn_radiotap_attach(sc);
 
        callout_init_mtx(&sc->calib_to, &sc->sc_mtx, 0);
+       callout_init_mtx(&sc->scan_timeout, &sc->sc_mtx, 0);
        callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0);
-       TASK_INIT(&sc->sc_reinit_task, 0, iwn_hw_reset, sc);
        TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc);
        TASK_INIT(&sc->sc_radiooff_task, 0, iwn_radio_off, sc);
+       TASK_INIT(&sc->sc_panic_task, 0, iwn_panicked, sc);
+       TASK_INIT(&sc->sc_xmit_task, 0, iwn_xmit_task, sc);
+
+       mbufq_init(&sc->sc_xmit_queue, 1024);
+
+       sc->sc_tq = taskqueue_create("iwn_taskq", M_WAITOK,
+           taskqueue_thread_enqueue, &sc->sc_tq);
+       error = taskqueue_start_threads(&sc->sc_tq, 1, 0, "iwn_taskq");
+       if (error != 0) {
+               device_printf(dev, "can't start threads, error %d\n", error);
+               goto fail;
+       }
 
        iwn_sysctlattach(sc);
 
@@ -687,19 +705,524 @@ iwn_attach(device_t dev)
                goto fail;
        }
 
+#if 0
+       device_printf(sc->sc_dev, "%s: rx_stats=%d, rx_stats_bt=%d\n",
+           __func__,
+           sizeof(struct iwn_stats),
+           sizeof(struct iwn_stats_bt));
+#endif
+
        if (bootverbose)
                ieee80211_announce(ic);
+       DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end\n",__func__);
+
+       /* Add debug ioctl right at the end */
+#ifndef __HAIKU__
+       sc->sc_cdev = make_dev(&iwn_cdevsw, device_get_unit(dev),
+           UID_ROOT, GID_WHEEL, 0600, "%s", device_get_nameunit(dev));
+       if (sc->sc_cdev == NULL) {
+               device_printf(dev, "failed to create debug character device\n");
+       } else {
+               sc->sc_cdev->si_drv1 = sc;
+       }
+#else
+       sc->sc_cdev = NULL;
+#endif
        return 0;
 fail:
        iwn_detach(dev);
+       DPRINTF(sc, IWN_DEBUG_TRACE, "->%s: end in error\n",__func__);
        return error;
 }
 
+/*
+ * Define specific configuration based on device id and subdevice id
+ * pid : PCI device id
+ */
+static int
+iwn_config_specific(struct iwn_softc *sc, uint16_t pid)
+{
+
+       switch (pid) {
+/* 4965 series */
+       case IWN_DID_4965_1:
+       case IWN_DID_4965_2:
+       case IWN_DID_4965_3:
+       case IWN_DID_4965_4:
+               sc->base_params = &iwn4965_base_params;
+               sc->limits = &iwn4965_sensitivity_limits;
+               sc->fwname = "iwn4965fw";
+               /* Override chains masks, ROM is known to be broken. */
+               sc->txchainmask = IWN_ANT_AB;
+               sc->rxchainmask = IWN_ANT_ABC;
+               /* Enable normal btcoex */
+               sc->sc_flags |= IWN_FLAG_BTCOEX;
+               break;
+/* 1000 Series */
+       case IWN_DID_1000_1:
+       case IWN_DID_1000_2:
+               switch(sc->subdevice_id) {
+                       case    IWN_SDID_1000_1:
+                       case    IWN_SDID_1000_2:
+                       case    IWN_SDID_1000_3:
+                       case    IWN_SDID_1000_4:
+                       case    IWN_SDID_1000_5:
+                       case    IWN_SDID_1000_6:
+                       case    IWN_SDID_1000_7:
+                       case    IWN_SDID_1000_8:
+                       case    IWN_SDID_1000_9:
+                       case    IWN_SDID_1000_10:
+                       case    IWN_SDID_1000_11:
+                       case    IWN_SDID_1000_12:
+                               sc->limits = &iwn1000_sensitivity_limits;
+                               sc->base_params = &iwn1000_base_params;
+                               sc->fwname = "iwn1000fw";
+                               break;

[ *** diff truncated: 7868 lines dropped *** ]


############################################################################

Commit:      a549026d25fa95dd66e9a8f57b801930ad585d98
URL:         https://git.haiku-os.org/haiku/commit/?id=a549026d25fa
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Wed Jun 27 22:35:48 2018 UTC

freebsd11_network: Actually set numBytes instead of silently truncating it.

If numBytes was greater than MCLBYTES (presently 1 << 11 = 2048), then the data 
beyond
MCLBYTES would be silently discarded instead of being written. Now, we store the
result of the min_c in numBytes, so the caller knows how much was written.

I turn on the printf that's commented out here and found that in practice this
seems to never happen (it's larger than the ethernet limit), so it seems 
unlikely
to fix any "transmission mysteriously failed" bugs.

Also backported this to the FreeBSD 9 layer.

----------------------------------------------------------------------------

############################################################################

Commit:      8b4aff3eaca2e1379e93c41bdf515e44e26649b9
URL:         https://git.haiku-os.org/haiku/commit/?id=8b4aff3eaca2
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Wed Jun 27 22:47:32 2018 UTC

freebsd11_network: Enable INVARIANTS at KDEBUG_LEVEL_2.

They were already enabled for the net80211 code (and thus all the Wi-Fi drivers)
unconditionally; now we enable them conditionally based on KDEBUG_LEVEL_2
for the freebsd11_network core code also.

Includes fixes to the build, since there were some issues with INVARIANTS 
otherwise.

----------------------------------------------------------------------------

############################################################################

Revision:    hrev52040
Commit:      97f9cb046c11d6ec546ef67f7dee3f155d34f085
URL:         https://git.haiku-os.org/haiku/commit/?id=97f9cb046c11
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Thu Jun 28 00:26:53 2018 UTC

freebsd11 / iprowifi4965: GCC2 fixes.

----------------------------------------------------------------------------


Other related posts:

  • » [haiku-commits] haiku: hrev52040 - in src: add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn libs/compat/freebsd11_wlan/net80211 libs/compat/freebsd11_network - waddlesplash