Going back over the full list of commands the Linux driver sends to an
ax200 device when it connects to an access point, I have noticed some
that are missing from our driver.

One of those is the SOC_CONFIGURATION command which provides some low-level
details about the hardware device to firmware. This command doesn't seem to
be needed with the ax200 device we currently support. But it does not hurt
and will be needed for other devices this driver intends to support in the
future.

ok?

diff 275365c274c71989968d3bae8c5244a411c26876 
812326fa38786e39e6b9062983fda1ea32c571ac
blob - 585527d032e511ae31b3c06c212f6f99d494494e
blob + 05a96a041a182e2326bc3f745e20150e5053e064
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -409,6 +409,7 @@ void        iwx_fill_sf_command(struct iwx_softc *, struct 
iw
            struct ieee80211_node *);
 int    iwx_sf_config(struct iwx_softc *, int);
 int    iwx_send_bt_init_conf(struct iwx_softc *);
+int    iwx_send_soc_conf(struct iwx_softc *);
 int    iwx_send_update_mcc_cmd(struct iwx_softc *, const char *);
 int    iwx_init_hw(struct iwx_softc *);
 int    iwx_init(struct ifnet *);
@@ -437,7 +438,6 @@ int iwx_resume(struct iwx_softc *);
 void   iwx_radiotap_attach(struct iwx_softc *);
 #endif
 
-#ifdef notyet
 uint8_t
 iwx_lookup_cmd_ver(struct iwx_softc *sc, uint8_t grp, uint8_t cmd)
 {
@@ -452,7 +452,6 @@ iwx_lookup_cmd_ver(struct iwx_softc *sc, uint8_t grp, 
 
        return IWX_FW_CMD_VER_UNKNOWN;
 }
-#endif
 
 int
 iwx_is_mimo_ht_plcp(uint8_t ht_plcp)
@@ -6255,6 +6254,44 @@ iwx_send_bt_init_conf(struct iwx_softc *sc)
 }
 
 int
+iwx_send_soc_conf(struct iwx_softc *sc)
+{
+       struct iwx_soc_configuration_cmd cmd;
+       int err;
+       uint32_t cmd_id, flags = 0;
+
+       memset(&cmd, 0, sizeof(cmd));
+
+       /*
+        * In VER_1 of this command, the discrete value is considered
+        * an integer; In VER_2, it's a bitmask.  Since we have only 2
+        * values in VER_1, this is backwards-compatible with VER_2,
+        * as long as we don't set any other flag bits.
+        */
+       if (!sc->sc_integrated) { /* VER_1 */
+               flags = IWX_SOC_CONFIG_CMD_FLAGS_DISCRETE;
+       } else { /* VER_2 */
+               uint8_t scan_cmd_ver;
+               if (sc->sc_ltr_delay != IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE)
+                       flags |= (sc->sc_ltr_delay &
+                           IWX_SOC_FLAGS_LTR_APPLY_DELAY_MASK);
+               scan_cmd_ver = iwx_lookup_cmd_ver(sc, IWX_LONG_GROUP,
+                   IWX_SCAN_REQ_UMAC);
+               if (scan_cmd_ver >= 2 && sc->sc_low_latency_xtal)
+                       flags |= IWX_SOC_CONFIG_CMD_FLAGS_LOW_LATENCY;
+       }
+       cmd.flags = htole32(flags);
+
+       cmd.latency = htole32(sc->sc_xtal_latency);
+
+       cmd_id = iwx_cmd_id(IWX_SOC_CONFIGURATION_CMD, IWX_SYSTEM_GROUP, 0);
+       err = iwx_send_cmd_pdu(sc, cmd_id, 0, sizeof(cmd), &cmd);
+       if (err)
+               printf("%s: failed to set soc latency: %d\n", DEVNAME(sc), err);
+       return err;
+}
+
+int
 iwx_send_update_mcc_cmd(struct iwx_softc *sc, const char *alpha2)
 {
        struct iwx_mcc_update_cmd mcc_cmd;
@@ -6346,6 +6383,10 @@ iwx_init_hw(struct iwx_softc *sc)
                return err;
        }
 
+       err = iwx_send_soc_conf(sc);
+       if (err)
+               return err;
+
        err = iwx_send_dqa_cmd(sc);
        if (err)
                return err;
@@ -7207,6 +7248,9 @@ iwx_rx_pkt(struct iwx_softc *sc, struct iwx_rx_data *d
                case IWX_WIDE_ID(IWX_DATA_PATH_GROUP, IWX_DQA_ENABLE_CMD):
                        break;
 
+               case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_SOC_CONFIGURATION_CMD):
+                       break;
+
                case IWX_WIDE_ID(IWX_SYSTEM_GROUP, IWX_INIT_EXTENDED_CFG_CMD):
                        break;
 
@@ -7673,6 +7717,9 @@ iwx_attach(struct device *parent, struct device *self,
                sc->sc_fwdmasegsz = IWX_FWDMASEGSZ_8000;
                sc->sc_nvm_max_section_size = 32768;
                sc->sc_integrated = 1;
+               sc->sc_ltr_delay = IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE;
+               sc->sc_low_latency_xtal = 0;
+               sc->sc_xtal_latency = 0;
                sc->sc_tx_with_siso_diversity = 0;
                break;
        default:
blob - 04653f5d23e199b791eef8421b881a6a1854343a
blob + f49a482ac2e6f5196c0c2de5c0426d5c87735070
--- sys/dev/pci/if_iwxreg.h
+++ sys/dev/pci/if_iwxreg.h
@@ -1866,6 +1866,31 @@ struct iwx_alive_resp_v4 {
        struct iwx_umac_alive umac_data;
 } __packed; /* ALIVE_RES_API_S_VER_4 */
 
+#define IWX_SOC_CONFIG_CMD_FLAGS_DISCRETE      (1 << 0)
+#define IWX_SOC_CONFIG_CMD_FLAGS_LOW_LATENCY   (1 << 1)
+
+#define IWX_SOC_FLAGS_LTR_APPLY_DELAY_MASK             0xc
+#define IWX_SOC_FLAGS_LTR_APPLY_DELAY_NONE             0
+#define IWX_SOC_FLAGS_LTR_APPLY_DELAY_200              1
+#define IWX_SOC_FLAGS_LTR_APPLY_DELAY_2500             2
+#define IWX_SOC_FLAGS_LTR_APPLY_DELAY_1820             3
+
+/**
+ * struct iwx_soc_configuration_cmd - Set device stabilization latency
+ *
+ * @flags: soc settings flags.  In VER_1, we can only set the DISCRETE
+ *     flag, because the FW treats the whole value as an integer. In
+ *     VER_2, we can set the bits independently.
+ * @latency: time for SOC to ensure stable power & XTAL
+ */
+struct iwx_soc_configuration_cmd {
+       uint32_t flags;
+       uint32_t latency;
+} __packed; /*
+            * SOC_CONFIGURATION_CMD_S_VER_1 (see description above)
+            * SOC_CONFIGURATION_CMD_S_VER_2
+            */
+
 /**
  * commands driver may send before finishing init flow
  * @IWX_INIT_DEBUG_CFG: driver is going to send debug config command
blob - bcc35edb65d7aaa96a0b190eaebf6fdd44d65314
blob + ea95ff156fc9b75d8b198f979ee0f79edaa9ef1a
--- sys/dev/pci/if_iwxvar.h
+++ sys/dev/pci/if_iwxvar.h
@@ -496,6 +496,10 @@ struct iwx_softc {
        int sc_integrated;
        int sc_tx_with_siso_diversity;
        int sc_max_tfd_queue_size;
+       int sc_ltr_delay;
+       int sc_xtal_latency;
+       int sc_low_latency_xtal;
+
 
 #if NBPFILTER > 0
        caddr_t                 sc_drvbpf;

 

Reply via email to