Author: bschmidt
Date: Sat Jun 18 12:10:06 2011
New Revision: 223251
URL: http://svn.freebsd.org/changeset/base/223251

Log:
  MFC r220866-220867:
  - Pull some features out of the firmware:
    - If a ENH_SENS TLV section exit the firmware is capable of doing
      enhanced sensitivity calibration.
    - Newer devices/firmwares have more calibration commands therefore
      hardcoding the noise gain/reset commands no longer works. It is
      supposed to use the next index after the newest calibration type
      support. Read the command index of the TLV section if available.
  - Enable DC calibration for all 6000 series devices, except those
    with an internal PA.
  - Override the chainmask also for the 6050.

Modified:
  stable/8/sys/dev/iwn/if_iwn.c
  stable/8/sys/dev/iwn/if_iwnreg.h
  stable/8/sys/dev/iwn/if_iwnvar.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/iwn/if_iwn.c
==============================================================================
--- stable/8/sys/dev/iwn/if_iwn.c       Sat Jun 18 12:07:06 2011        
(r223250)
+++ stable/8/sys/dev/iwn/if_iwn.c       Sat Jun 18 12:10:06 2011        
(r223251)
@@ -772,6 +772,8 @@ iwn5000_attach(struct iwn_softc *sc, uin
        sc->fw_data_maxsz = IWN5000_FW_DATA_MAXSZ;
        sc->fwsz = IWN5000_FWSZ;
        sc->sched_txfact_addr = IWN5000_SCHED_TXFACT;
+       sc->reset_noise_gain = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
+       sc->noise_gain = IWN5000_PHY_CALIB_NOISE_GAIN;
 
        switch (sc->hw_type) {
        case IWN_HW_REV_TYPE_5100:
@@ -807,6 +809,9 @@ iwn5000_attach(struct iwn_softc *sc, uin
        case IWN_HW_REV_TYPE_6050:
                sc->limits = &iwn6000_sensitivity_limits;
                sc->fwname = "iwn6050fw";
+               /* Override chains masks, ROM is known to be broken. */
+               sc->txchainmask = IWN_ANT_AB;
+               sc->rxchainmask = IWN_ANT_AB;
                break;
        case IWN_HW_REV_TYPE_6005:
                sc->limits = &iwn6000_sensitivity_limits;
@@ -2385,7 +2390,9 @@ iwn5000_rx_calib_results(struct iwn_soft
 
        switch (calib->code) {
        case IWN5000_PHY_CALIB_DC:
-               if (sc->hw_type == IWN_HW_REV_TYPE_5150)
+               if ((sc->sc_flags & IWN_FLAG_INTERNAL_PA) == 0 &&
+                   (sc->hw_type == IWN_HW_REV_TYPE_5150 ||
+                    sc->hw_type >= IWN_HW_REV_TYPE_6000))
                        idx = 0;
                break;
        case IWN5000_PHY_CALIB_LO:
@@ -4367,7 +4374,7 @@ iwn5000_init_gains(struct iwn_softc *sc)
        struct iwn_phy_calib cmd;
 
        memset(&cmd, 0, sizeof cmd);
-       cmd.code = IWN5000_PHY_CALIB_RESET_NOISE_GAIN;
+       cmd.code = sc->reset_noise_gain;
        cmd.ngroups = 1;
        cmd.isvalid = 1;
        DPRINTF(sc, IWN_DEBUG_CALIBRATE,
@@ -4419,7 +4426,7 @@ iwn5000_set_gains(struct iwn_softc *sc)
        div = (sc->hw_type == IWN_HW_REV_TYPE_6050) ? 20 : 30;
 
        memset(&cmd, 0, sizeof cmd);
-       cmd.code = IWN5000_PHY_CALIB_NOISE_GAIN;
+       cmd.code = sc->noise_gain;
        cmd.ngroups = 1;
        cmd.isvalid = 1;
        /* Get first available RX antenna as referential. */
@@ -5900,7 +5907,7 @@ iwn_read_firmware_tlv(struct iwn_softc *
        const struct iwn_fw_tlv *tlv;
        const uint8_t *ptr, *end;
        uint64_t altmask;
-       uint32_t len;
+       uint32_t len, tmp;
 
        if (fw->size < sizeof (*hdr)) {
                device_printf(sc->sc_dev, "%s: firmware too short: %zu bytes\n",
@@ -5965,6 +5972,17 @@ iwn_read_firmware_tlv(struct iwn_softc *
                        fw->boot.text = ptr;
                        fw->boot.textsz = len;
                        break;
+               case IWN_FW_TLV_ENH_SENS:
+                       if (!len)
+                               sc->sc_flags |= IWN_FLAG_ENH_SENS;
+                       break;
+               case IWN_FW_TLV_PHY_CALIB:
+                       tmp = htole32(*ptr);
+                       if (tmp < 253) {
+                               sc->reset_noise_gain = tmp;
+                               sc->noise_gain = tmp + 1;
+                       }
+                       break;
                default:
                        DPRINTF(sc, IWN_DEBUG_RESET,
                            "TLV type %d not handled\n", le16toh(tlv->type));

Modified: stable/8/sys/dev/iwn/if_iwnreg.h
==============================================================================
--- stable/8/sys/dev/iwn/if_iwnreg.h    Sat Jun 18 12:07:06 2011        
(r223250)
+++ stable/8/sys/dev/iwn/if_iwnreg.h    Sat Jun 18 12:10:06 2011        
(r223251)
@@ -1322,6 +1322,8 @@ struct iwn_fw_tlv {
 #define IWN_FW_TLV_INIT_DATA           4
 #define IWN_FW_TLV_BOOT_TEXT           5
 #define IWN_FW_TLV_PBREQ_MAXLEN                6
+#define IWN_FW_TLV_ENH_SENS            14
+#define IWN_FW_TLV_PHY_CALIB           15
 
        uint16_t        alt;
        uint32_t        len;

Modified: stable/8/sys/dev/iwn/if_iwnvar.h
==============================================================================
--- stable/8/sys/dev/iwn/if_iwnvar.h    Sat Jun 18 12:07:06 2011        
(r223250)
+++ stable/8/sys/dev/iwn/if_iwnvar.h    Sat Jun 18 12:10:06 2011        
(r223251)
@@ -222,6 +222,8 @@ struct iwn_softc {
        uint32_t                fw_data_maxsz;
        uint32_t                fwsz;
        bus_size_t              sched_txfact_addr;
+       uint32_t                reset_noise_gain;
+       uint32_t                noise_gain;
 
        /* TX scheduler rings. */
        struct iwn_dma_info     sched_dma;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to