Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F162848710
D4038.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D4038.diff
View Options
Index: head/sys/dev/usb/wlan/if_urtwn.c
===================================================================
--- head/sys/dev/usb/wlan/if_urtwn.c
+++ head/sys/dev/usb/wlan/if_urtwn.c
@@ -228,10 +228,14 @@
static void urtwn_update_beacon(struct ieee80211vap *, int);
static int urtwn_tx_beacon(struct urtwn_softc *sc,
struct urtwn_vap *);
+static void urtwn_tsf_task_adhoc(void *, int);
static void urtwn_tsf_sync_enable(struct urtwn_softc *,
struct ieee80211vap *);
static void urtwn_set_led(struct urtwn_softc *, int, int);
static void urtwn_set_mode(struct urtwn_softc *, uint8_t);
+static void urtwn_ibss_recv_mgmt(struct ieee80211_node *,
+ struct mbuf *, int,
+ const struct ieee80211_rx_stats *, int, int);
static int urtwn_newstate(struct ieee80211vap *,
enum ieee80211_state, int);
static void urtwn_watchdog(void *);
@@ -449,6 +453,7 @@
ic->ic_caps =
IEEE80211_C_STA /* station mode */
| IEEE80211_C_MONITOR /* monitor mode */
+ | IEEE80211_C_IBSS /* adhoc mode */
| IEEE80211_C_HOSTAP /* hostap mode */
| IEEE80211_C_SHPREAMBLE /* short preamble supported */
| IEEE80211_C_SHSLOT /* short slot time supported */
@@ -592,13 +597,18 @@
return (NULL);
}
- if (opmode == IEEE80211_M_HOSTAP)
+ if (opmode == IEEE80211_M_HOSTAP || opmode == IEEE80211_M_IBSS)
urtwn_init_beacon(sc, uvp);
/* override state transition machine */
uvp->newstate = vap->iv_newstate;
vap->iv_newstate = urtwn_newstate;
vap->iv_update_beacon = urtwn_update_beacon;
+ if (opmode == IEEE80211_M_IBSS) {
+ uvp->recv_mgmt = vap->iv_recv_mgmt;
+ vap->iv_recv_mgmt = urtwn_ibss_recv_mgmt;
+ TASK_INIT(&uvp->tsf_task_adhoc, 0, urtwn_tsf_task_adhoc, vap);
+ }
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
@@ -610,13 +620,13 @@
static void
urtwn_vap_delete(struct ieee80211vap *vap)
{
+ struct ieee80211com *ic = vap->iv_ic;
struct urtwn_vap *uvp = URTWN_VAP(vap);
- enum ieee80211_opmode opmode = vap->iv_opmode;
- if (opmode == IEEE80211_M_HOSTAP) {
- if (uvp->bcn_mbuf != NULL)
- m_freem(uvp->bcn_mbuf);
- }
+ if (uvp->bcn_mbuf != NULL)
+ m_freem(uvp->bcn_mbuf);
+ if (vap->iv_opmode == IEEE80211_M_IBSS)
+ ieee80211_draintask(ic, &uvp->tsf_task_adhoc);
ieee80211_vap_detach(vap);
free(uvp, M_80211_VAP);
}
@@ -1611,8 +1621,50 @@
}
static void
+urtwn_tsf_task_adhoc(void *arg, int pending)
+{
+ struct ieee80211vap *vap = arg;
+ struct urtwn_softc *sc = vap->iv_ic->ic_softc;
+ struct ieee80211_node *ni;
+ uint32_t reg;
+
+ URTWN_LOCK(sc);
+ ni = ieee80211_ref_node(vap->iv_bss);
+ reg = urtwn_read_1(sc, R92C_BCN_CTRL);
+
+ /* Accept beacons with the same BSSID. */
+ urtwn_set_rx_bssid_all(sc, 0);
+
+ /* Enable synchronization. */
+ reg &= ~R92C_BCN_CTRL_DIS_TSF_UDT0;
+ urtwn_write_1(sc, R92C_BCN_CTRL, reg);
+
+ /* Synchronize. */
+ usb_pause_mtx(&sc->sc_mtx, hz * ni->ni_intval * 5 / 1000);
+
+ /* Disable synchronization. */
+ reg |= R92C_BCN_CTRL_DIS_TSF_UDT0;
+ urtwn_write_1(sc, R92C_BCN_CTRL, reg);
+
+ /* Remove beacon filter. */
+ urtwn_set_rx_bssid_all(sc, 1);
+
+ /* Enable beaconing. */
+ urtwn_write_1(sc, R92C_MBID_NUM,
+ urtwn_read_1(sc, R92C_MBID_NUM) | R92C_MBID_TXBCN_RPT0);
+ reg |= R92C_BCN_CTRL_EN_BCN;
+
+ urtwn_write_1(sc, R92C_BCN_CTRL, reg);
+ ieee80211_free_node(ni);
+ URTWN_UNLOCK(sc);
+}
+
+static void
urtwn_tsf_sync_enable(struct urtwn_softc *sc, struct ieee80211vap *vap)
{
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct urtwn_vap *uvp = URTWN_VAP(vap);
+
/* Reset TSF. */
urtwn_write_1(sc, R92C_DUAL_TSF_RST, R92C_DUAL_TSF_RST0);
@@ -1623,6 +1675,9 @@
urtwn_read_1(sc, R92C_BCN_CTRL) &
~R92C_BCN_CTRL_DIS_TSF_UDT0);
break;
+ case IEEE80211_M_IBSS:
+ ieee80211_runtask(ic, &uvp->tsf_task_adhoc);
+ break;
case IEEE80211_M_HOSTAP:
/* Enable beaconing. */
urtwn_write_1(sc, R92C_MBID_NUM,
@@ -1674,6 +1729,37 @@
urtwn_write_1(sc, R92C_MSR, reg);
}
+static void
+urtwn_ibss_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype,
+ const struct ieee80211_rx_stats *rxs,
+ int rssi, int nf)
+{
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct urtwn_softc *sc = vap->iv_ic->ic_softc;
+ struct urtwn_vap *uvp = URTWN_VAP(vap);
+ uint64_t ni_tstamp, curr_tstamp;
+
+ uvp->recv_mgmt(ni, m, subtype, rxs, rssi, nf);
+
+ if (vap->iv_state == IEEE80211_S_RUN &&
+ (subtype == IEEE80211_FC0_SUBTYPE_BEACON ||
+ subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)) {
+ ni_tstamp = le64toh(ni->ni_tstamp.tsf);
+#ifdef D3831
+ URTWN_LOCK(sc);
+ urtwn_get_tsf(sc, &curr_tstamp);
+ URTWN_UNLOCK(sc);
+ curr_tstamp = le64toh(curr_tstamp);
+
+ if (ni_tstamp >= curr_tstamp)
+ (void) ieee80211_ibss_merge(ni);
+#else
+ (void) sc;
+ (void) curr_tstamp;
+#endif
+ }
+}
+
static int
urtwn_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
@@ -1757,6 +1843,9 @@
case IEEE80211_M_STA:
mode = R92C_MSR_INFRA;
break;
+ case IEEE80211_M_IBSS:
+ mode = R92C_MSR_ADHOC;
+ break;
case IEEE80211_M_HOSTAP:
mode = R92C_MSR_AP;
break;
@@ -1794,13 +1883,14 @@
if (vap->iv_opmode != IEEE80211_M_HOSTAP)
reg |= R92C_RCR_CBSSID_DATA;
-
- reg |= R92C_RCR_CBSSID_BCN;
+ if (vap->iv_opmode != IEEE80211_M_IBSS)
+ reg |= R92C_RCR_CBSSID_BCN;
urtwn_write_4(sc, R92C_RCR, reg);
}
- if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
+ if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
+ vap->iv_opmode == IEEE80211_M_IBSS) {
error = urtwn_setup_beacon(sc, ni);
if (error != 0) {
device_printf(sc->sc_dev,
@@ -3007,6 +3097,7 @@
R92C_RXFLTMAP_SUBTYPE(IEEE80211_FC0_SUBTYPE_BEACON));
break;
case IEEE80211_M_MONITOR:
+ case IEEE80211_M_IBSS:
break;
default:
device_printf(sc->sc_dev, "%s: undefined opmode %d\n",
@@ -3335,7 +3426,9 @@
URTWN_LOCK(sc);
/* Receive beacons / probe responses from any BSSID. */
- urtwn_set_rx_bssid_all(sc, 1);
+ if (ic->ic_opmode != IEEE80211_M_IBSS)
+ urtwn_set_rx_bssid_all(sc, 1);
+
/* Set gain for scanning. */
urtwn_set_gain(sc, 0x20);
URTWN_UNLOCK(sc);
@@ -3348,8 +3441,9 @@
URTWN_LOCK(sc);
/* Restore limitations. */
- if (ic->ic_promisc == 0)
+ if (ic->ic_promisc == 0 && ic->ic_opmode != IEEE80211_M_IBSS)
urtwn_set_rx_bssid_all(sc, 0);
+
/* Set gain under link. */
urtwn_set_gain(sc, 0x32);
URTWN_UNLOCK(sc);
@@ -3393,6 +3487,9 @@
case IEEE80211_M_HOSTAP:
mask2 |= R92C_RCR_CBSSID_BCN;
break;
+ case IEEE80211_M_IBSS:
+ mask2 |= R92C_RCR_CBSSID_DATA;
+ break;
default:
device_printf(sc->sc_dev, "%s: undefined opmode %d\n",
__func__, vap->iv_opmode);
Index: head/sys/dev/usb/wlan/if_urtwnvar.h
===================================================================
--- head/sys/dev/usb/wlan/if_urtwnvar.h
+++ head/sys/dev/usb/wlan/if_urtwnvar.h
@@ -87,13 +87,18 @@
};
struct urtwn_vap {
- struct ieee80211vap vap;
+ struct ieee80211vap vap;
- struct r92c_tx_desc bcn_desc;
- struct mbuf *bcn_mbuf;
-
- int (*newstate)(struct ieee80211vap *,
- enum ieee80211_state, int);
+ struct r92c_tx_desc bcn_desc;
+ struct mbuf *bcn_mbuf;
+ struct task tsf_task_adhoc;
+
+ int (*newstate)(struct ieee80211vap *,
+ enum ieee80211_state, int);
+ void (*recv_mgmt)(struct ieee80211_node *,
+ struct mbuf *, int,
+ const struct ieee80211_rx_stats *,
+ int, int);
};
#define URTWN_VAP(vap) ((struct urtwn_vap *)(vap))
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jul 18, 2:18 PM (19 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35198668
Default Alt Text
D4038.diff (7 KB)
Attached To
Mode
D4038: urtwn(4): add IBSS mode support
Attached
Detach File
Event Timeline
Log In to Comment