Date: Mon, 19 Sep 2016 22:36:30 +0000 (UTC) From: =?UTF-8?Q?Imre_Vad=c3=a1sz?= <ivadasz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r306007 - head/sys/dev/iwm Message-ID: <201609192236.u8JMaUI8081855@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ivadasz Date: Mon Sep 19 22:36:30 2016 New Revision: 306007 URL: https://svnweb.freebsd.org/changeset/base/306007 Log: [iwm] Improve reliability of iwm_release on disassociation a bit. * We need to first call ivp->iv_newstate(), to enqueue the deauth/deassoc mgmt frame, then flush the tx queue, before actually calling iwm_release(). * cycling a wlan connection via wpa_cli frontend to wpa_supplicant, by issuing disconnect and reconnect commandos works quite well. (There is still an issue when disconnecting/reconnecting too quickly) * Reassociating or roaming via wpa_supplicant is still broken. Approved by: adrian (mentor) Differential Revision: https://reviews.freebsd.org/D7943 Modified: head/sys/dev/iwm/if_iwm.c Modified: head/sys/dev/iwm/if_iwm.c ============================================================================== --- head/sys/dev/iwm/if_iwm.c Mon Sep 19 22:26:37 2016 (r306006) +++ head/sys/dev/iwm/if_iwm.c Mon Sep 19 22:36:30 2016 (r306007) @@ -329,6 +329,8 @@ static int iwm_tx(struct iwm_softc *, st struct ieee80211_node *, int); static int iwm_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); +static int iwm_mvm_flush_tx_path(struct iwm_softc *sc, + uint32_t tfd_msk, uint32_t flags); static int iwm_mvm_send_add_sta_cmd_status(struct iwm_softc *, struct iwm_mvm_add_sta_cmd_v7 *, int *); @@ -3517,7 +3519,6 @@ iwm_raw_xmit(struct ieee80211_node *ni, * mvm/tx.c */ -#if 0 /* * Note that there are transports that buffer frames before they reach * the firmware. This means that after flush_tx_path is called, the @@ -3527,23 +3528,21 @@ iwm_raw_xmit(struct ieee80211_node *ni, * 3) wait for the transport queues to be empty */ int -iwm_mvm_flush_tx_path(struct iwm_softc *sc, int tfd_msk, int sync) +iwm_mvm_flush_tx_path(struct iwm_softc *sc, uint32_t tfd_msk, uint32_t flags) { + int ret; struct iwm_tx_path_flush_cmd flush_cmd = { .queues_ctl = htole32(tfd_msk), .flush_ctl = htole16(IWM_DUMP_TX_FIFO_FLUSH), }; - int ret; - ret = iwm_mvm_send_cmd_pdu(sc, IWM_TXPATH_FLUSH, - sync ? IWM_CMD_SYNC : IWM_CMD_ASYNC, + ret = iwm_mvm_send_cmd_pdu(sc, IWM_TXPATH_FLUSH, flags, sizeof(flush_cmd), &flush_cmd); if (ret) device_printf(sc->sc_dev, "Flushing tx queue failed: %d\n", ret); return ret; } -#endif /* * BEGIN mvm/sta.c @@ -3899,6 +3898,8 @@ iwm_assoc(struct ieee80211vap *vap, stru static int iwm_release(struct iwm_softc *sc, struct iwm_node *in) { + uint32_t tfd_msk; + /* * Ok, so *technically* the proper set of calls for going * from RUN back to SCAN is: @@ -3918,7 +3919,18 @@ iwm_release(struct iwm_softc *sc, struct * back to nothing anyway, we'll just do a complete device reset. * Up your's, device! */ - /* iwm_mvm_flush_tx_path(sc, 0xf, 1); */ + /* + * Just using 0xf for the queues mask is fine as long as we only + * get here from RUN state. + */ + tfd_msk = 0xf; + mbufq_drain(&sc->sc_snd); + iwm_mvm_flush_tx_path(sc, tfd_msk, IWM_CMD_SYNC); + /* + * We seem to get away with just synchronously sending the + * IWM_TXPATH_FLUSH command. + */ +// iwm_trans_wait_tx_queue_empty(sc, tfd_msk); iwm_stop_device(sc); iwm_init_hw(sc); if (in) @@ -4125,7 +4137,17 @@ iwm_newstate(struct ieee80211vap *vap, e if (((in = IWM_NODE(vap->iv_bss)) != NULL)) in->in_assoc = 0; - iwm_release(sc, NULL); + if (nstate == IEEE80211_S_INIT) { + IWM_UNLOCK(sc); + IEEE80211_LOCK(ic); + error = ivp->iv_newstate(vap, nstate, arg); + IEEE80211_UNLOCK(ic); + IWM_LOCK(sc); + iwm_release(sc, NULL); + IWM_UNLOCK(sc); + IEEE80211_LOCK(ic); + return error; + } /* * It's impossible to directly go RUN->SCAN. If we iwm_release()
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609192236.u8JMaUI8081855>