I had almost forgotten that wifi hacking can be fun if it results
in something working.

Tested between two laptops (hostap) and with Berlin's freifunk
network (ibss). Seems to work but I have no idea about long
term stability yet. Additional testing much appreciated.

Index: sys/dev/usb/if_urtwn.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_urtwn.c,v
retrieving revision 1.32
diff -u -p -r1.32 if_urtwn.c
--- sys/dev/usb/if_urtwn.c      30 Sep 2013 05:18:57 -0000      1.32
+++ sys/dev/usb/if_urtwn.c      16 Jan 2014 00:26:03 -0000
@@ -240,6 +240,10 @@ void               urtwn_lc_calib(struct urtwn_softc 
 void           urtwn_temp_calib(struct urtwn_softc *);
 int            urtwn_init(struct ifnet *);
 void           urtwn_stop(struct ifnet *);
+#ifndef IEEE80211_STA_ONLY
+void           urtwn_newassoc(struct ieee80211com *, struct ieee80211_node *,
+                   int);
+#endif
 
 /* Aliases. */
 #define        urtwn_bb_write  urtwn_write_4
@@ -332,6 +336,10 @@ urtwn_attach(struct device *parent, stru
        /* Set device capabilities. */
        ic->ic_caps =
            IEEE80211_C_MONITOR |       /* Monitor mode supported. */
+#ifndef IEEE80211_STA_ONLY
+           IEEE80211_C_IBSS |          /* IBSS mode supported */
+           IEEE80211_C_HOSTAP |        /* HostAp mode supported */
+#endif
            IEEE80211_C_SHPREAMBLE |    /* Short preamble supported. */
            IEEE80211_C_SHSLOT |        /* Short slot time supported. */
            IEEE80211_C_WEP |           /* WEP. */
@@ -377,6 +385,9 @@ urtwn_attach(struct device *parent, stru
 
        if_attach(ifp);
        ieee80211_ifattach(ifp);
+#ifndef IEEE80211_STA_ONLY
+       ic->ic_newassoc = urtwn_newassoc;
+#endif
        ic->ic_updateedca = urtwn_updateedca;
 #ifdef notyet
        ic->ic_set_key = urtwn_set_key;
@@ -1153,6 +1164,17 @@ urtwn_next_scan(void *arg)
        usbd_ref_decr(sc->sc_udev);
 }
 
+#ifndef IEEE80211_STA_ONLY
+void
+urtwn_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, int isnew)
+{
+       DPRINTF(("new node %s\n", ether_sprintf(ni->ni_macaddr)));
+       /* start with lowest Tx rate */
+       ni->ni_txrate = 0;
+}
+#endif
+
+
 int
 urtwn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
 {
@@ -1175,6 +1197,9 @@ urtwn_newstate_cb(struct urtwn_softc *sc
        enum ieee80211_state ostate;
        uint32_t reg;
        int s;
+#ifndef IEEE80211_STA_ONLY
+       u_int8_t msr;
+#endif
 
        s = splnet();
        ostate = ic->ic_state;
@@ -1270,6 +1295,8 @@ urtwn_newstate_cb(struct urtwn_softc *sc
                }
                ni = ic->ic_bss;
 
+               urtwn_set_chan(sc, ni->ni_chan, NULL);
+
                /* Set media status to 'Associated'. */
                reg = urtwn_read_4(sc, R92C_CR);
                reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_INFRA);
@@ -1298,6 +1325,33 @@ urtwn_newstate_cb(struct urtwn_softc *sc
                    urtwn_read_4(sc, R92C_RCR) |
                    R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN);
 
+#ifndef IEEE80211_STA_ONLY
+               if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
+                       urtwn_write_2(sc, R92C_BCNTCFG, 0x000f);
+
+                       /* Allow Rx from any BSSID. */
+                       urtwn_write_4(sc, R92C_RCR,
+                           urtwn_read_4(sc, R92C_RCR) &
+                           ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN));
+
+                       /* Reset TSF timer to zero. */
+                       reg = urtwn_read_4(sc, R92C_TCR);
+                       reg &= ~0x01;
+                       urtwn_write_4(sc, R92C_TCR, reg);
+                       reg |= 0x01;
+                       urtwn_write_4(sc, R92C_TCR, reg);
+               }
+
+               msr = urtwn_read_1(sc, R92C_MSR);
+               msr &= 0xfc;
+               if (ic->ic_opmode == IEEE80211_M_HOSTAP)
+                       msr |= R92C_MSR_AP;
+               else if (ic->ic_opmode == IEEE80211_M_IBSS)
+                       msr |= R92C_MSR_ADHOC;
+               else
+                       msr |= R92C_MSR_INFRA;
+               urtwn_write_1(sc, R92C_MSR, msr);
+#endif
                /* Enable TSF synchronization. */
                urtwn_tsf_sync_enable(sc);
 
@@ -3118,8 +3172,8 @@ urtwn_init(struct ifnet *ifp)
 
        /* Initialize beacon parameters. */
        urtwn_write_2(sc, R92C_TBTT_PROHIBIT, 0x6404);
-       urtwn_write_1(sc, R92C_DRVERLYINT, 0x05);
-       urtwn_write_1(sc, R92C_BCNDMATIM, 0x02);
+       urtwn_write_1(sc, R92C_DRVERLYINT, R92C_DRIVER_EARLY_INT_TIME); /* ms */
+       urtwn_write_1(sc, R92C_BCNDMATIM, R92C_DMA_ATIME_INT_TIME);
        urtwn_write_2(sc, R92C_BCNTCFG, 0x660f);
 
        /* Setup AMPDU aggregation. */
Index: sys/dev/usb/if_urtwnreg.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_urtwnreg.h,v
retrieving revision 1.4
diff -u -p -r1.4 if_urtwnreg.h
--- sys/dev/usb/if_urtwnreg.h   15 Apr 2013 09:23:01 -0000      1.4
+++ sys/dev/usb/if_urtwnreg.h   16 Jan 2014 00:03:21 -0000
@@ -82,6 +82,7 @@
 #define R92C_SYS_CFG                   0x0f0
 /* MAC General Configuration. */
 #define R92C_CR                                0x100
+#define R92C_MSR                       0x102
 #define R92C_PBP                       0x104
 #define R92C_TRXDMA_CTRL               0x10c
 #define R92C_TRXFF_BNDY                        0x114
@@ -187,6 +188,7 @@
 /* WMAC Configuration. */
 #define R92C_APSD_CTRL                 0x600
 #define R92C_BWOPMODE                  0x603
+#define R92C_TCR                       0x604
 #define R92C_RCR                       0x608
 #define R92C_RX_DRVINFO_SZ             0x60f
 #define R92C_MACID                     0x610
@@ -356,6 +358,12 @@
 #define R92C_CR_NETTYPE_INFRA  2
 #define R92C_CR_NETTYPE_AP     3
 
+/* Bits for R92C_MSR. */
+#define R92C_MSR_NOLINK        0x00
+#define R92C_MSR_ADHOC 0x01
+#define R92C_MSR_INFRA 0x02
+#define R92C_MSR_AP    0x03
+
 /* Bits for R92C_PBP. */
 #define R92C_PBP_PSRX_M                0x0f
 #define R92C_PBP_PSRX_S                0
@@ -454,6 +462,12 @@
 #define R92C_BCN_CTRL_TXBCN_RPT                0x04
 #define R92C_BCN_CTRL_EN_BCN           0x08
 #define R92C_BCN_CTRL_DIS_TSF_UDT0     0x10
+
+/* Bits for R92C_DRVERLYINT */
+#define R92C_DRIVER_EARLY_INT_TIME     0x05
+
+/* Bits for R92C_BCNDMATIM */
+#define R92C_DMA_ATIME_INT_TIME                0x02
 
 /* Bits for R92C_APSD_CTRL. */
 #define R92C_APSD_CTRL_OFF             0x40
Index: share/man/man4/urtwn.4
===================================================================
RCS file: /cvs/src/share/man/man4/urtwn.4,v
retrieving revision 1.26
diff -u -p -r1.26 urtwn.4
--- share/man/man4/urtwn.4      30 Sep 2013 05:18:56 -0000      1.26
+++ share/man/man4/urtwn.4      16 Jan 2014 00:27:53 -0000
@@ -50,6 +50,18 @@ Also known as
 mode, this is used when associating with an access point, through
 which all traffic passes.
 This mode is the default.
+.It IBSS mode
+Also known as
+.Em IEEE ad-hoc
+mode or
+.Em peer-to-peer
+mode.
+This is the standardized method of operating without an access point.
+Stations associate with a service set.
+However, actual connections between stations are peer-to-peer.
+.It Host AP
+In this mode the driver acts as an access point (base station)
+for other cards.
 .It monitor mode
 In this mode the driver is able to receive packets without
 associating with an access point.

Reply via email to