urtwn and hostap
Matthew Grooms
mgrooms at shrew.net
Thu Sep 17 16:30:10 UTC 2015
I just assumed that the card was doing the right thing with the beacon
since it was being loaded into a specific queue. Like I said, I'm
fumbling around here. Ok, I see the NetBSD commit now. It doesn't look
anything like the patch I was working with. It also doesn't look
specific to RTL8188E ...
http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/dev/usb/if_urtwn.c.diff?r1=1.25&r2=1.26&only_with_tag=MAIN
I should have checked NetBSD before hand :/
-Matthew
On 9/17/2015 10:22 AM, Adrian Chadd wrote:
> I think this patch is missing beacon updates - it just transmits the
> same beacon over and oveR?
>
>
> -a
>
>
> On 17 September 2015 at 08:12, Kevin Lo <kevlo at freebsd.org> wrote:
>> On Thu, Sep 17, 2015 at 01:39:30AM -0500, Matthew Grooms wrote:
>>> Seems to behave better now and hostap appears to be working ...
>>>
>>> #ifconfig wlan0 create wlandev urtwn0 wlanmode hostap
>>> #ifconfig wlan0 list caps
>>> drivercaps=2181c401<STA,HOSTAP,SHSLOT,SHPREAMBLE,MONITOR,WPA1,WPA2,BGSCAN>
>>>
>>> #ifconfig wlan0 up ssid freebsdap mode 11g channel 1
>>> #ifconfig bridge0 create up addm em0 addm wlan0
>>>
>>> #ifconfig wlan0
>>> wlan0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric
>>> 0 mtu 1500
>>> ether 00:c3:e1:16:11:32
>>> nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
>>> media: IEEE 802.11 Wireless Ethernet autoselect mode 11g <hostap>
>>> status: running
>>> ssid freebsdap channel 1 (2412 MHz 11g) bssid 00:c3:e1:16:11:32
>>> country US authmode OPEN privacy OFF txpower 0 scanvalid 60
>>> protmode CTS dtimperiod 1 -dfs
>>> groups: wlan
>>>
>>> #ifconfig bridge0
>>> bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu
>>> 1500
>>> ether 02:df:20:d2:42:00
>>> nd6 options=1<PERFORMNUD>
>>> groups: bridge
>>> id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
>>> maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
>>> root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
>>> member: wlan0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
>>> ifmaxaddr 0 port 3 priority 128 path cost 370370
>>> member: em0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
>>> ifmaxaddr 0 port 1 priority 128 path cost 20000
>>>
>>> The speed leaves a lot to be desired. Throughput for the associated host
>>> is typically about 2Mbit down and 6Mbit up. I'm assume that's indicative
>>> of a problem. Occasionally I also see the this message on the console
>>> when I'm bringing the adapter up ...
>>>
>>> wlan0: ieee80211_new_state_locked: pending INIT -> SCAN transition lost
>>>
>>> If I down and up the adapter again, it seems to correct itself. Not sure
>>> what that's all about. I am passing the USB adapter through to a VM
>>> inside of ESXi to test the patch, so maybe that has something to do with
>>> these quirks. I'll try to run some tests with the adapter associated to
>>> a physical AP tomorrow to get a baseline.
>> I knew OpenBSD had patches about hostap support for urtwn(4), but those
>> don't look quite right. I think that's why OpenBSD developers didn't
>> commit them. BTW, NetBSD adopted OpenBSD's patches, I tested it on NetBSD
>> about four months ago, the connection was not stable...
>>
>>> Thanks,
>>>
>>> -Matthew
>> Kevin
>>
>>> On 9/16/2015 11:24 AM, Adrian Chadd wrote:
>>>> The only one to look at is ath(4). I've not fixed/hacked on any other
>>>> hostap chips. :)
>>>>
>>>> if_ath_beacon.c has the logic - it gets a reference when creating a
>>>> beacon frame.
>>>>
>>>>
>>>>
>>>> -adrian
>>>>
>>>>
>>>> On 16 September 2015 at 09:21, Matthew Grooms <mgrooms at shrew.net> wrote:
>>>>> On 9/16/2015 10:58 AM, Adrian Chadd wrote:
>>>>>> I think the net80211 beacon create routine doesn't allocate a node
>>>>>> ref. Yeah, it doesn't. You have to do ieee80211_ref_node() after
>>>>>> calling becaon_create(), and deref it if the tx fails. The TX success
>>>>>> will free the node ref for you.
>>>>>>
>>>>> Got it. I'll take another look at one of the drivers that support hostap to
>>>>> make sure I'm following the same pattern. Thanks again for the feedback!
>>>>>
>>>>> -Matthew
>>>>>
>>>>>
>>>>>> -adrian
>>>>>>
>>>>>>
>>>>>> On 16 September 2015 at 04:27, Idwer Vollering <vidwer at gmail.com> wrote:
>>>>>>> 2015-09-16 8:06 GMT+02:00 Matthew Grooms <mgrooms at shrew.net>:
>>>>>>>
>>>>>>>> It looks like my screenshot got scrubbed. Here is my hopefully faithful
>>>>>>>> transcription ...
>>>>>>>>
>>>>>>>> Fatal trap 9: general protection fault while in kernel mode
>>>>>>>> cpuid = 3; apic id = 03
>>>>>>>> instruction pointer = 0x20:0xffffffff80a01105
>>>>>>>> stack pointer = 0x28:0xfffffe0092fe86f0
>>>>>>>> frame pointer = 0x28:0xfffffe0092fe8740
>>>>>>>> code segment = base 0x0, limit 0xfffff, type 0x1b
>>>>>>>> = DPL 0, pres 1, long 1, def32 0, gran
>>>>>>>> 1
>>>>>>>> processor eflags = interrupt enabled, resume, IOPL = 0
>>>>>>>> current process = 716 (ifconfig)
>>>>>>>> [thread pid 716 tid 100082 ]
>>>>>>>> Stopped at __mtx_lock_flags+0x55: movq (%r13),%rax
>>>>>>>> db> bt
>>>>>>>> Tracing pid 716 tid 100082 td 0xffffff800512814d0
>>>>>>>> __mtx_lock_flags() at __mtx_lock_flags+0x55/frame 0xfffffe0092fe8740
>>>>>>>> ieee80211_free_node() at ieee80211_free_node()_0x38/frame
>>>>>>>> 0xfffffe0092fe8780
>>>>>>>> ieee80211_node_vdetach() at ieee80211_node_vdetach()+0x2d/frame
>>>>>>>> 0xfffffe0092fe87a0
>>>>>>>> ieee80211_vap_detach() at ieee80211_vap_detach()+0x35e/frame
>>>>>>>> 0xfffffe0092fe87d0
>>>>>>>> urtwn_vap_delete() at urtwn_vap_delete()+0xe/frame 0xfffffe0092fe87f0
>>>>>>>> if_clone_destroyif() at if_clone_destroyif()+0x1aa/frame
>>>>>>>> 0xfffffe0092fe8840
>>>>>>>> if_clone_destroy() at if_clone_destroy()0x8e/frame 0xfffffe0092fe8860
>>>>>>>> kern_ioctl() at kern_ioctl()+0x230/frame 0xfffffe0092fe88c0
>>>>>>>> sys_ioctl() at sys_ioctl()+0x153/frame 0xfffffe0092fe89a0
>>>>>>>> amd64_syscall() at amd64_syscall()+0x282/frame 0xfffffe0092fe8ab0
>>>>>>>> Xfast_syscall() at Xfast_syscall()+0xfb/frame 0xfffffe0092fe8ab0
>>>>>>>> -- syscall (54, FreeBSD ELF64, sys_ioctl), rip = 0x8011e8c8a, rsp =
>>>>>>>> 0x7fffffffe2f8, rbp = 0x7fffffffe310 --
>>>>>>>> db>
>>>>>>> Assuming dumpdev="AUTO" is set in /etc/rc.conf, you should have
>>>>>>> entered 'dump' at the db> blinker :)
>>>>>>>
>>>>>>> The trap details are found in /var/crash/, run kgdb: "kgdb
>>>>>>> /boot/kernel/kernel /var/crash/vmcore.last", then run 'bt' and 'up' at
>>>>>>> its prompt.
>>>>>>>
>>>>>>>> -Matthew
>>>>>>>> _______________________________________________
>>>>>>>> freebsd-wireless at freebsd.org mailing list
>>>>>>>> https://lists.freebsd.org/mailman/listinfo/freebsd-wireless
>>>>>>>> To unsubscribe, send any mail to
>>>>>>>> "freebsd-wireless-unsubscribe at freebsd.org"
>>>>>>> _______________________________________________
>>>>>>> freebsd-wireless at freebsd.org mailing list
>>>>>>> https://lists.freebsd.org/mailman/listinfo/freebsd-wireless
>>>>>>> To unsubscribe, send any mail to
>>>>>>> "freebsd-wireless-unsubscribe at freebsd.org"
>>>>>> _______________________________________________
>>>>>> freebsd-wireless at freebsd.org mailing list
>>>>>> https://lists.freebsd.org/mailman/listinfo/freebsd-wireless
>>>>>> To unsubscribe, send any mail to
>>>>>> "freebsd-wireless-unsubscribe at freebsd.org"
>>>>> _______________________________________________
>>>>> freebsd-wireless at freebsd.org mailing list
>>>>> https://lists.freebsd.org/mailman/listinfo/freebsd-wireless
>>>>> To unsubscribe, send any mail to "freebsd-wireless-unsubscribe at freebsd.org"
>>> Index: sys/dev/usb/wlan/if_urtwn.c
>>> ===================================================================
>>> --- sys/dev/usb/wlan/if_urtwn.c (revision 287342)
>>> +++ sys/dev/usb/wlan/if_urtwn.c (working copy)
>>> @@ -181,6 +181,8 @@
>>> static struct mbuf * urtwn_rxeof(struct usb_xfer *, struct urtwn_data *,
>>> int *, int8_t *);
>>> static void urtwn_txeof(struct usb_xfer *, struct urtwn_data *);
>>> +int urtwn_txbcn(struct ieee80211vap *vap,
>>> + struct ieee80211_node *);
>>> static int urtwn_alloc_list(struct urtwn_softc *,
>>> struct urtwn_data[], int, int);
>>> static int urtwn_alloc_rx_list(struct urtwn_softc *);
>>> @@ -436,6 +438,10 @@
>>> | IEEE80211_C_WPA /* 802.11i */
>>> ;
>>>
>>> + if (sc->chip & URTWN_CHIP_88E)
>>> + ic->ic_caps |=
>>> + IEEE80211_C_HOSTAP; /* HostAp mode supported */
>>> +
>>> bands = 0;
>>> setbit(&bands, IEEE80211_MODE_11B);
>>> setbit(&bands, IEEE80211_MODE_11G);
>>> @@ -857,6 +863,39 @@
>>> sc->sc_txtimer = 0;
>>> }
>>>
>>> +/*
>>> + * Push a beacon frame into the chip and check if it was accepted. Beacon will
>>> + * be repeated by the chip every R92C_BCN_INTERVAL.
>>> + */
>>> +int
>>> +urtwn_txbcn(struct ieee80211vap *vap, struct ieee80211_node *ni)
>>> +{
>>> + struct ieee80211com *ic = ni->ni_ic;
>>> + struct urtwn_softc *sc = ic->ic_softc;
>>> + struct urtwn_data *bf;
>>> + struct mbuf *m;
>>> +
>>> + ieee80211_ref_node(ni);
>>> + m = ieee80211_beacon_alloc(ni, &URTWN_VAP(vap)->bo);
>>> +
>>> + bf = urtwn_getbuf(sc);
>>> + if (bf == NULL) {
>>> + ieee80211_free_node(ni);
>>> + m_freem(m);
>>> + return (ENOBUFS);
>>> + }
>>> +
>>> + if (urtwn_tx_start(sc, ni, m, bf) != 0) {
>>> + ieee80211_free_node(ni);
>>> + STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next);
>>> + return (EIO);
>>> + }
>>> +
>>> + sc->sc_txtimer = 5;
>>> +
>>> + return (0);
>>> +}
>>> +
>>> static void
>>> urtwn_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
>>> {
>>> @@ -1466,6 +1505,7 @@
>>> struct ieee80211_node *ni;
>>> enum ieee80211_state ostate;
>>> uint32_t reg;
>>> + int error;
>>>
>>> ostate = vap->iv_state;
>>> DPRINTF("%s -> %s\n", ieee80211_state_name[ostate],
>>> @@ -1553,23 +1593,68 @@
>>> }
>>>
>>> ni = ieee80211_ref_node(vap->iv_bss);
>>> - /* Set media status to 'Associated'. */
>>> - reg = urtwn_read_4(sc, R92C_CR);
>>> - reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_INFRA);
>>> - urtwn_write_4(sc, R92C_CR, reg);
>>>
>>> - /* Set BSSID. */
>>> - urtwn_write_4(sc, R92C_BSSID + 0, LE_READ_4(&ni->ni_bssid[0]));
>>> - urtwn_write_4(sc, R92C_BSSID + 4, LE_READ_2(&ni->ni_bssid[4]));
>>> + if (ic->ic_opmode == IEEE80211_M_STA) {
>>> + /* Set BSSID. */
>>> + urtwn_write_4(sc, R92C_BSSID + 0,
>>> + LE_READ_4(&ni->ni_bssid[0]));
>>> + urtwn_write_4(sc, R92C_BSSID + 4,
>>> + LE_READ_2(&ni->ni_bssid[4]));
>>>
>>> - if (ic->ic_curmode == IEEE80211_MODE_11B)
>>> - urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 0);
>>> - else /* 802.11b/g */
>>> - urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 3);
>>> + if (ic->ic_curmode == IEEE80211_MODE_11B)
>>> + urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 0);
>>> + else /* 802.11b/g */
>>> + urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 3);
>>>
>>> - /* Enable Rx of data frames. */
>>> - urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
>>> + /* Enable Rx of data frames. */
>>> + urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
>>>
>>> + /* Allow Rx from our BSSID only. */
>>> + urtwn_write_4(sc, R92C_RCR, urtwn_read_4(sc, R92C_RCR) |
>>> + R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN);
>>> +
>>> + /* Set media status to 'Associated'. */
>>> + reg = urtwn_read_4(sc, R92C_CR);
>>> + reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_INFRA);
>>> + urtwn_write_4(sc, R92C_CR, reg);
>>> + }
>>> +
>>> + if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
>>> + /* Set media status to 'AP'. */
>>> + reg = urtwn_read_4(sc, R92C_CR);
>>> + reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_AP);
>>> + urtwn_write_4(sc, R92C_CR, reg);
>>> +
>>> + /* Set BSSID. */
>>> + urtwn_write_4(sc, R92C_BSSID + 0,
>>> + LE_READ_4(&ni->ni_bssid[0]));
>>> + urtwn_write_4(sc, R92C_BSSID + 4,
>>> + LE_READ_2(&ni->ni_bssid[4]));
>>> +
>>> + /*
>>> + * If 3rd or 4th bits are set to zero chip will stop
>>> + * repeating beacon after first transmission for port0
>>> + * and port1 respectively. This will cause STAs to
>>> + * disconnect after short period of time.
>>> + */
>>> + reg = urtwn_read_1(sc, R92C_MBID_NUM);
>>> + reg |= 0x8;
>>> + reg |= 0x10;
>>> + urtwn_write_1(sc, R92C_MBID_NUM, reg);
>>> +
>>> + /* Invalidate cam entries */
>>> + urtwn_cam_init(sc);
>>> +
>>> + /* Set chan/bw */
>>> + urtwn_set_chan(sc, ic->ic_curchan, NULL);
>>> +
>>> + /* Push beacon frame into the chip */
>>> + error = urtwn_txbcn(vap, ni);
>>> + if (error != 0)
>>> + printf("%s: unable to push beacon into the"
>>> + " chip\n", device_get_nameunit(sc->sc_dev));
>>> + }
>>> +
>>> /* Flush all AC queues. */
>>> urtwn_write_1(sc, R92C_TXPAUSE, 0);
>>>
>>> @@ -1576,11 +1661,6 @@
>>> /* Set beacon interval. */
>>> urtwn_write_2(sc, R92C_BCN_INTERVAL, ni->ni_intval);
>>>
>>> - /* Allow Rx from our BSSID only. */
>>> - urtwn_write_4(sc, R92C_RCR,
>>> - urtwn_read_4(sc, R92C_RCR) |
>>> - R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN);
>>> -
>>> /* Enable TSF synchronization. */
>>> urtwn_tsf_sync_enable(sc);
>>>
>>> @@ -1754,7 +1834,7 @@
>>> struct ieee80211vap *vap = ni->ni_vap;
>>> struct usb_xfer *xfer;
>>> struct r92c_tx_desc *txd;
>>> - uint8_t raid, type;
>>> + uint8_t raid, type, subtype;
>>> uint16_t sum;
>>> int i, hasqos, xferlen;
>>> struct usb_xfer *urtwn_pipes[4] = {
>>> @@ -1771,6 +1851,7 @@
>>> */
>>> wh = mtod(m0, struct ieee80211_frame *);
>>> type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
>>> + subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
>>>
>>> if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
>>> k = ieee80211_crypto_encap(ni, m0);
>>> @@ -1819,7 +1900,7 @@
>>> if (sc->chip & URTWN_CHIP_88E) {
>>> txd->txdw1 |= htole32(
>>> SM(R88E_TXDW1_MACID, URTWN_MACID_BSS) |
>>> - SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
>>> + SM(R92C_TXDW1_QSEL, R88E_TXDW1_QSEL_BE) |
>>> SM(R92C_TXDW1_RAID, raid));
>>> txd->txdw2 |= htole32(R88E_TXDW2_AGGBK);
>>> } else {
>>> @@ -1843,9 +1924,20 @@
>>> /* Send data at OFDM54. */
>>> txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));
>>> } else {
>>> + /*
>>> + * If beacon frame is pushed into wrong queue, the chip won't
>>> + * start repeating it.
>>> + */
>>> + if (subtype == IEEE80211_FC0_SUBTYPE_BEACON &&
>>> + sc->chip & URTWN_CHIP_88E)
>>> + txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL,
>>> + R88E_TXDW1_QSEL_MGNT));
>>> + else
>>> + txd->txdw1 |= htole32(SM(R92C_TXDW1_QSEL,
>>> + R92C_TXDW1_QSEL_MGNT));
>>> +
>>> txd->txdw1 |= htole32(
>>> SM(R92C_TXDW1_MACID, 0) |
>>> - SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT) |
>>> SM(R92C_TXDW1_RAID, R92C_RAID_11B));
>>>
>>> /* Force CCK1. */
>>> Index: sys/dev/usb/wlan/if_urtwnreg.h
>>> ===================================================================
>>> --- sys/dev/usb/wlan/if_urtwnreg.h (revision 287342)
>>> +++ sys/dev/usb/wlan/if_urtwnreg.h (working copy)
>>> @@ -1019,7 +1019,9 @@
>>> #define R92C_TXDW1_QSEL_M 0x00001f00
>>> #define R92C_TXDW1_QSEL_S 8
>>> #define R92C_TXDW1_QSEL_BE 0x00
>>> +#define R88E_TXDW1_QSEL_BE 0x03
>>> #define R92C_TXDW1_QSEL_MGNT 0x12
>>> +#define R88E_TXDW1_QSEL_MGNT 0x10
>>> #define R92C_TXDW1_RAID_M 0x000f0000
>>> #define R92C_TXDW1_RAID_S 16
>>> #define R92C_TXDW1_CIPHER_M 0x00c00000
>>> _______________________________________________
>>> freebsd-wireless at freebsd.org mailing list
>>> https://lists.freebsd.org/mailman/listinfo/freebsd-wireless
>>> To unsubscribe, send any mail to "freebsd-wireless-unsubscribe at freebsd.org"
More information about the freebsd-wireless
mailing list