Author: adrian
Date: Mon Apr 25 16:13:04 2016
New Revision: 298582
URL: https://svnweb.freebsd.org/changeset/base/298582

Log:
  [iwn] fix firmware command use in iwm_auth().
  
  The iwm firmware has separate commands for add, modify and delete for
  various things (mac, phy context, etc.)  The openbsd driver has a habit
  of just completely resetting the NIC each time, which is technically
  mostly okay (as long as the reset doesn't actually fail!) but it means
  a lot of the code is doing ADD when it should do MODIFY.
  
  The firmware responds in kind - it just asserts.
  
  This fixes auth attempts that occur after the NIC has been already
  configured.
  
  (I'm sure there are more instances of this!)
  
  Tested:
  
  iwm0: <Intel Dual Band Wireless AC 7260> mem 0xf1400000-0xf1401fff irq 17 at 
device 0.0 on pci2
  iwm0: revision: 0x140, firmware 25.228 (API ver. 9)
  
  .. STA mode.
  
  Submitted by: Masachika ISHIZUKA <i...@amail.plala.or.jp>

Modified:
  head/sys/dev/iwm/if_iwm.c
  head/sys/dev/iwm/if_iwm_binding.c
  head/sys/dev/iwm/if_iwm_binding.h
  head/sys/dev/iwm/if_iwm_time_event.c
  head/sys/dev/iwm/if_iwm_time_event.h

Modified: head/sys/dev/iwm/if_iwm.c
==============================================================================
--- head/sys/dev/iwm/if_iwm.c   Mon Apr 25 15:46:42 2016        (r298581)
+++ head/sys/dev/iwm/if_iwm.c   Mon Apr 25 16:13:04 2016        (r298582)
@@ -3159,7 +3159,6 @@ iwm_auth(struct ieee80211vap *vap, struc
        struct iwm_node *in;
        struct iwm_vap *iv = IWM_VAP(vap);
        uint32_t duration;
-       uint32_t min_duration;
        int error;
 
        /*
@@ -3201,7 +3200,25 @@ iwm_auth(struct ieee80211vap *vap, struc
        if (iv->is_uploaded) {
                if ((error = iwm_mvm_mac_ctxt_changed(sc, vap)) != 0) {
                        device_printf(sc->sc_dev,
-                           "%s: failed to add MAC\n", __func__);
+                           "%s: failed to update MAC\n", __func__);
+                       goto out;
+               }
+               if ((error = iwm_mvm_phy_ctxt_changed(sc, &sc->sc_phyctxt[0],
+                   in->in_ni.ni_chan, 1, 1)) != 0) {
+                       device_printf(sc->sc_dev,
+                           "%s: failed update phy ctxt\n", __func__);
+                       goto out;
+               }
+               in->in_phyctxt = &sc->sc_phyctxt[0];
+
+               if ((error = iwm_mvm_binding_update(sc, in)) != 0) {
+                       device_printf(sc->sc_dev,
+                           "%s: binding update cmd\n", __func__);
+                       goto out;
+               }
+               if ((error = iwm_mvm_update_sta(sc, in)) != 0) {
+                       device_printf(sc->sc_dev,
+                           "%s: failed to update sta\n", __func__);
                        goto out;
                }
        } else {
@@ -3210,61 +3227,36 @@ iwm_auth(struct ieee80211vap *vap, struc
                            "%s: failed to add MAC\n", __func__);
                        goto out;
                }
-       }
-
-       if ((error = iwm_mvm_phy_ctxt_changed(sc, &sc->sc_phyctxt[0],
-           in->in_ni.ni_chan, 1, 1)) != 0) {
-               device_printf(sc->sc_dev,
-                   "%s: failed add phy ctxt\n", __func__);
-               goto out;
-       }
-       in->in_phyctxt = &sc->sc_phyctxt[0];
-
-       if ((error = iwm_mvm_binding_add_vif(sc, in)) != 0) {
-               device_printf(sc->sc_dev,
-                   "%s: binding cmd\n", __func__);
-               goto out;
-       }
-
-       if ((error = iwm_mvm_add_sta(sc, in)) != 0) {
-               device_printf(sc->sc_dev,
-                   "%s: failed to add MAC\n", __func__);
-               goto out;
-       }
-
-       /* a bit superfluous? */
-       while (sc->sc_auth_prot)
-               msleep(&sc->sc_auth_prot, &sc->sc_mtx, 0, "iwmauth", 0);
-       sc->sc_auth_prot = 1;
-
-       duration = min(IWM_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS,
-           200 + in->in_ni.ni_intval);
-       min_duration = min(IWM_MVM_TE_SESSION_PROTECTION_MIN_TIME_MS,
-           100 + in->in_ni.ni_intval);
-       iwm_mvm_protect_session(sc, in, duration, min_duration, 500);
-
-       IWM_DPRINTF(sc, IWM_DEBUG_RESET,
-           "%s: waiting for auth_prot\n", __func__);
-       while (sc->sc_auth_prot != 2) {
-               /*
-                * well, meh, but if the kernel is sleeping for half a
-                * second, we have bigger problems
-                */
-               if (sc->sc_auth_prot == 0) {
+               if ((error = iwm_mvm_phy_ctxt_changed(sc, &sc->sc_phyctxt[0],
+                   in->in_ni.ni_chan, 1, 1)) != 0) {
                        device_printf(sc->sc_dev,
-                           "%s: missed auth window!\n", __func__);
+                           "%s: failed add phy ctxt!\n", __func__);
                        error = ETIMEDOUT;
                        goto out;
-               } else if (sc->sc_auth_prot == -1) {
+               }
+               in->in_phyctxt = &sc->sc_phyctxt[0];
+
+               if ((error = iwm_mvm_binding_add_vif(sc, in)) != 0) {
+                       device_printf(sc->sc_dev,
+                           "%s: binding add cmd\n", __func__);
+                       goto out;
+               }
+               if ((error = iwm_mvm_add_sta(sc, in)) != 0) {
                        device_printf(sc->sc_dev,
-                           "%s: no time event, denied!\n", __func__);
-                       sc->sc_auth_prot = 0;
-                       error = EAUTH;
+                           "%s: failed to add sta\n", __func__);
                        goto out;
                }
-               msleep(&sc->sc_auth_prot, &sc->sc_mtx, 0, "iwmau2", 0);
        }
-       IWM_DPRINTF(sc, IWM_DEBUG_RESET, "<-%s\n", __func__);
+
+       /*
+        * Prevent the FW from wandering off channel during association
+        * by "protecting" the session with a time event.
+        */
+       /* XXX duration is in units of TU, not MS */
+       duration = IWM_MVM_TE_SESSION_PROTECTION_MAX_TIME_MS;
+       iwm_mvm_protect_session(sc, in, duration, 500 /* XXX magic number */);
+       DELAY(100);
+
        error = 0;
 out:
        ieee80211_free_node(ni);

Modified: head/sys/dev/iwm/if_iwm_binding.c
==============================================================================
--- head/sys/dev/iwm/if_iwm_binding.c   Mon Apr 25 15:46:42 2016        
(r298581)
+++ head/sys/dev/iwm/if_iwm_binding.c   Mon Apr 25 16:13:04 2016        
(r298582)
@@ -201,13 +201,13 @@ iwm_mvm_binding_cmd(struct iwm_softc *sc
 }
 
 int
-iwm_mvm_binding_update(struct iwm_softc *sc, struct iwm_node *in, int add)
+iwm_mvm_binding_update(struct iwm_softc *sc, struct iwm_node *in)
 {
-       return iwm_mvm_binding_cmd(sc, in, IWM_FW_CTXT_ACTION_ADD);
+       return iwm_mvm_binding_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY);
 }
 
 int
 iwm_mvm_binding_add_vif(struct iwm_softc *sc, struct iwm_node *in)
 {
-       return iwm_mvm_binding_update(sc, in, IWM_FW_CTXT_ACTION_ADD);
+       return iwm_mvm_binding_cmd(sc, in, IWM_FW_CTXT_ACTION_ADD);
 }

Modified: head/sys/dev/iwm/if_iwm_binding.h
==============================================================================
--- head/sys/dev/iwm/if_iwm_binding.h   Mon Apr 25 15:46:42 2016        
(r298581)
+++ head/sys/dev/iwm/if_iwm_binding.h   Mon Apr 25 16:13:04 2016        
(r298582)
@@ -107,8 +107,7 @@
 
 extern int iwm_mvm_binding_cmd(struct iwm_softc *sc, struct iwm_node *in,
            uint32_t action);
-extern int iwm_mvm_binding_update(struct iwm_softc *sc, struct iwm_node *in,
-           int add);
+extern int iwm_mvm_binding_update(struct iwm_softc *sc, struct iwm_node *in);
 extern int iwm_mvm_binding_add_vif(struct iwm_softc *sc, struct iwm_node *in);
 
 #endif /* __IF_IWM_BINDING_H__ */

Modified: head/sys/dev/iwm/if_iwm_time_event.c
==============================================================================
--- head/sys/dev/iwm/if_iwm_time_event.c        Mon Apr 25 15:46:42 2016        
(r298581)
+++ head/sys/dev/iwm/if_iwm_time_event.c        Mon Apr 25 16:13:04 2016        
(r298582)
@@ -244,7 +244,7 @@ iwm_mvm_time_event_send_add(struct iwm_s
 
 void
 iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_node *in,
-       uint32_t duration, uint32_t min_duration, uint32_t max_delay)
+       uint32_t duration, uint32_t max_delay)
 {
        struct iwm_time_event_cmd_v2 time_cmd;
 

Modified: head/sys/dev/iwm/if_iwm_time_event.h
==============================================================================
--- head/sys/dev/iwm/if_iwm_time_event.h        Mon Apr 25 15:46:42 2016        
(r298581)
+++ head/sys/dev/iwm/if_iwm_time_event.h        Mon Apr 25 16:13:04 2016        
(r298582)
@@ -108,6 +108,6 @@
 #define        __IF_IWM_TIME_EVENT_H__
 
 extern void iwm_mvm_protect_session(struct iwm_softc *sc, struct iwm_node *in,
-           uint32_t duration, uint32_t min_duration, uint32_t max_delay);
+           uint32_t duration, uint32_t max_delay);
 
 #endif /* __IF_IWM_TIME_EVENT_H__ */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to