On Wed, Jul 01, 2015 at 09:47:15PM +0300, Mikhail wrote:
> Hello, inlined patch adds support for hostap mode for 8188eu chip.
>
Hi,
do you have newer version of this? I might have use for this..:)
-Artturi
> One known issue is documented in urtwn(4), I would like to know if
> people with other hw will see it too, or if it's my local issue.
>
> If you want to help, please test the patch and in case of problems
> provide as much as you can from this list:
>
> - commands with which you started the AP
> - dmesg | grep urtwn
> - ifconfig
> - tcpdump -i urtwn0 -y IEEE802_11 -w test.pcap (command must be run on
> the AP before problem occurs; I assume mailing the file to maillist
> isn't appropriate, so mail it to me directly)
> - if you can - sniff from the client (or, ideally, from third PC) too,
> since previous command won't give radiotap headers and won't show
> beacons.
>
> Patch has been tested with tl-wn725n, and mac mini as a client, running
> 802.11g and wpa2, speed is about 3-4 mbits in presence of ~20 ssids.
> Also, usual client mode with 8188eu chip is confirmed to work as before.
>
> Since the patch touches some bits in STA mode initialization, it would
> be helpful, if people with non-8188eu chip test it too in usual client
> mode.
>
> Any feedback and advice are appreciated.
>
> diff --git share/man/man4/urtwn.4 share/man/man4/urtwn.4
> index d2007a7..00928d4 100644
> --- share/man/man4/urtwn.4
> +++ share/man/man4/urtwn.4
> @@ -58,6 +58,8 @@ capture packets from networks which it wouldn't normally
> have access to,
> or to scan for access points.
> .El
> .Pp
> +The RTL8188EUS chip can also operate in Host AP mode.
> +.Pp
> The
> .Nm
> driver can be configured to use
> @@ -180,3 +182,8 @@ adapters.
> Additional work is required in
> .Xr ieee80211 9
> before those features can be supported.
> +.Pp
> +Beacon transmission, when operating in Host AP mode, is not started
> +immidiatelly, but with timeout of around 40 seconds, it means that if you
> +associate within this time frame, your client card will eventually disconnect
> +you, assuming that you've left range of AP.
> diff --git sys/dev/usb/if_urtwn.c sys/dev/usb/if_urtwn.c
> index db47398..18a4200 100644
> --- sys/dev/usb/if_urtwn.c
> +++ sys/dev/usb/if_urtwn.c
> @@ -216,6 +216,7 @@ void urtwn_rxeof(struct usbd_xfer *, void *,
> usbd_status);
> void urtwn_txeof(struct usbd_xfer *, void *,
> usbd_status);
> +int urtwn_txbcn(struct urtwn_softc *, struct ieee80211_node *);
> int urtwn_tx(struct urtwn_softc *, struct mbuf *,
> struct ieee80211_node *);
> void urtwn_start(struct ifnet *);
> @@ -347,6 +348,11 @@ urtwn_attach(struct device *parent, struct device *self,
> void *aux)
> IEEE80211_C_WEP | /* WEP. */
> IEEE80211_C_RSN; /* WPA/RSN. */
>
> +#ifndef IEEE80211_STA_ONLY
> + if (sc->chip & URTWN_CHIP_88E)
> + ic->ic_caps |= IEEE80211_C_HOSTAP; /* HostAp mode supported */
> +#endif
> +
> #ifndef IEEE80211_NO_HT
> /* Set HT capabilities. */
> ic->ic_htcaps =
> @@ -1319,7 +1325,7 @@ urtwn_newstate_cb(struct urtwn_softc *sc, void *arg)
> struct ieee80211_node *ni;
> enum ieee80211_state ostate;
> uint32_t reg;
> - int s;
> + int s, error;
>
> s = splnet();
> ostate = ic->ic_state;
> @@ -1422,22 +1428,62 @@ urtwn_newstate_cb(struct urtwn_softc *sc, void *arg)
> }
> ni = ic->ic_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);
> + 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]));
>
> - /* 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);
> + } else 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_bss->ni_chan, NULL);
> +
> + /* Push beacon frame into the chip */
> + error = urtwn_txbcn(sc, ni);
> + if (error != 0)
> + printf("%s: unable to push beacon into the"
> + " chip\n", sc->sc_dev.dv_xname);
> + }
>
> /* Flush all AC queues. */
> urtwn_write_1(sc, R92C_TXPAUSE, 0);
> @@ -1445,11 +1491,6 @@ urtwn_newstate_cb(struct urtwn_softc *sc, void *arg)
> /* 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);
>
> @@ -1953,6 +1994,35 @@ urtwn_txeof(struct usbd_xfer *xfer, void *priv,
> splx(s);
> }
>
> +/*
> + * 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 urtwn_softc *sc, struct ieee80211_node *ni)
> +{
> + int i, bcnsent = 0;
> + uint32_t reg;
> + struct ieee80211com *ic = &sc->sc_ic;
> +
> + reg = urtwn_read_1(sc, R92C_TDECTRL + 2);
> + reg |= 1;
> + urtwn_write_1(sc, R92C_TDECTRL + 2, reg);
> +
> + for (i = 0; i < 100; i++) {
> + struct mbuf *m;
> +
> + m = ieee80211_beacon_alloc(ic, ni);
> + urtwn_tx(sc, m, ni);
> + DELAY(100);
> + bcnsent = urtwn_read_1(sc, R92C_TDECTRL + 2) & 1;
> + if (bcnsent == 1)
> + return (0);
> + }
> +
> + return (1);
> +}
> +
> int
> urtwn_tx(struct urtwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
> {
> @@ -1963,11 +2033,12 @@ urtwn_tx(struct urtwn_softc *sc, struct mbuf *m,
> struct ieee80211_node *ni)
> struct r92c_tx_desc *txd;
> struct usbd_pipe *pipe;
> uint16_t qos, sum;
> - uint8_t raid, type, tid, qid;
> + uint8_t raid, type, tid, qid, subtype;
> int i, hasqos, xferlen, error;
>
> wh = mtod(m, 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_get_txkey(ic, wh, ni);
> @@ -2031,7 +2102,7 @@ urtwn_tx(struct urtwn_softc *sc, struct mbuf *m, struct
> ieee80211_node *ni)
> 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 {
> @@ -2057,9 +2128,20 @@ urtwn_tx(struct urtwn_softc *sc, struct mbuf *m,
> struct ieee80211_node *ni)
> txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));
>
> } else {
> + /*
> + * If beacon frame is pushed into wrong queue, 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(R88E_TXDW1_MACID, 0) |
> SM(R92C_TXDW1_RAID, R92C_RAID_11B));
>
> /* Force CCK1. */
> diff --git sys/dev/usb/if_urtwnreg.h sys/dev/usb/if_urtwnreg.h
> index db023ca..f6abdd2 100644
> --- sys/dev/usb/if_urtwnreg.h
> +++ sys/dev/usb/if_urtwnreg.h
> @@ -161,6 +161,7 @@
> #define R92C_RDG_PIFS 0x513
> #define R92C_SIFS_CCK 0x514
> #define R92C_SIFS_OFDM 0x516
> +#define R92C_TSFTR_SYN_OFFSET 0x518
> #define R92C_AGGR_BREAK_TIME 0x51a
> #define R92C_SLOT 0x51b
> #define R92C_TX_PTCL_CTRL 0x520
> @@ -171,6 +172,7 @@
> #define R92C_RD_NAV_NXT 0x544
> #define R92C_NAV_PROT_LEN 0x546
> #define R92C_BCN_CTRL 0x550
> +#define R92C_BCN_CTRL_1 0x551
> #define R92C_MBID_NUM 0x552
> #define R92C_DUAL_TSF_RST 0x553
> #define R92C_BCN_INTERVAL 0x554
> @@ -1013,7 +1015,9 @@ struct r92c_tx_desc {
> #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
>