> From: Rinaldini Julien <julien.rinald...@heig-vd.ch>
> Date: Mon, 22 Aug 2011 20:17:01 +0000
> 
> Hi,
> 
> I have a thinkpad x220 with a "Intel Centrino Advanced-N 6205" wireless card.
> 
> I installed the iwn firmware as it is said in the manpage.
> 
> ifconfig see my card but when I try to up it with "ifconfig iwn0 up" I got
> some error. Here is my dmesg, see at end for information related to iwn:

Here's the diff I'm currently running with.  It adds some missing code
and disables some of the run-time calibration.  But it seems to work
reasonably well.

Some of this is probably going to end up in the tree soon.  Still need
to figure out why the firmware doesn't like the run-time calibration
commands...


Index: if_iwn.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwn.c,v
retrieving revision 1.110
diff -u -p -r1.110 if_iwn.c
--- if_iwn.c    16 Jun 2011 19:48:22 -0000      1.110
+++ if_iwn.c    22 Aug 2011 20:49:30 -0000
@@ -207,6 +207,7 @@ int         iwn_send_sensitivity(struct iwn_sof
 int            iwn_set_pslevel(struct iwn_softc *, int, int, int);
 int            iwn_send_temperature_offset(struct iwn_softc *);
 int            iwn_send_btcoex(struct iwn_softc *);
+int            iwn5000_runtime_calib(struct iwn_softc *);
 int            iwn_config(struct iwn_softc *);
 int            iwn_scan(struct iwn_softc *, uint16_t);
 int            iwn_auth(struct iwn_softc *);
@@ -263,6 +264,7 @@ void                iwn_hw_stop(struct iwn_softc *);
 int            iwn_init(struct ifnet *);
 void           iwn_stop(struct ifnet *, int);
 
+#define IWN_DEBUG
 #ifdef IWN_DEBUG
 #define DPRINTF(x)     do { if (iwn_debug > 0) printf x; } while (0)
 #define DPRINTFN(n, x) do { if (iwn_debug >= (n)) printf x; } while (0)
@@ -2333,9 +2335,11 @@ iwn_notif_intr(struct iwn_softc *sc)
                         */
                        DPRINTF(("beacons missed %d/%d\n",
                            letoh32(miss->consecutive), letoh32(miss->total)));
+#if 0
                        if (ic->ic_state == IEEE80211_S_RUN &&
                            letoh32(miss->consecutive) > 5)
                                (void)iwn_init_sensitivity(sc);
+#endif
                        break;
                }
                case IWN_UC_READY:
@@ -3733,6 +3737,7 @@ void
 iwn_collect_noise(struct iwn_softc *sc,
     const struct iwn_rx_general_stats *stats)
 {
+#if 0
        struct iwn_ops *ops = &sc->ops;
        struct iwn_calib_state *calib = &sc->calib;
        uint32_t val;
@@ -3768,13 +3773,14 @@ iwn_collect_noise(struct iwn_softc *sc,
 
 #ifdef notyet
        /* XXX Disable RX chains with no antennas connected. */
-       sc->rxon.rxchain = htole16(IWN_RXCHAIN_SEL(sc->chainmask));
+       sc->rxon.rxchain = htole16(IWN_RXCHAIN_SEL(sc->chainmask);
        (void)iwn_cmd(sc, IWN_CMD_RXON, &sc->rxon, sc->rxonsz, 1);
 #endif
 
        /* Enable power-saving mode if requested by user. */
        if (sc->sc_ic.ic_flags & IEEE80211_F_PMGTON)
                (void)iwn_set_pslevel(sc, 0, 3, 1);
+#endif
 }
 
 int
@@ -4126,6 +4132,18 @@ iwn_send_btcoex(struct iwn_softc *sc)
 }
 
 int
+iwn5000_runtime_calib(struct iwn_softc *sc)
+{
+       struct iwn5000_calib_config cmd;
+
+       memset(&cmd, 0, sizeof cmd);
+       cmd.ucode.once.enable = 0xffffffff;
+       cmd.ucode.once.start = IWN5000_CALIB_DC;
+       DPRINTF(("configuring runtime calibration\n"));
+       return iwn_cmd(sc, IWN5000_CMD_CALIB_CONFIG, &cmd, sizeof(cmd), 0);
+}
+
+int
 iwn_config(struct iwn_softc *sc)
 {
        struct iwn_ops *ops = &sc->ops;
@@ -4145,6 +4163,17 @@ iwn_config(struct iwn_softc *sc)
                }
        }
 
+       if (sc->hw_type == IWN_HW_REV_TYPE_6050 ||
+           sc->hw_type == IWN_HW_REV_TYPE_6005) {
+               /* Configure runtime DC calibration. */
+               error = iwn5000_runtime_calib(sc);
+               if (error != 0) {
+                       printf("%s: could not configure runtime calibration\n",
+                           sc->sc_dev.dv_xname);
+                       return error;
+               }
+       }
+
        /* Configure valid TX chains for >=5000 Series. */
        if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
                txmask = htole32(sc->txchainmask);
@@ -5345,6 +5374,8 @@ iwn_read_firmware_tlv(struct iwn_softc *
                case IWN_FW_TLV_BOOT_TEXT:
                        fw->boot.text = ptr;
                        fw->boot.textsz = len;
+                       break;
+               case IWN_FW_TLV_PHY_CALIB_SIZE:
                        break;
                default:
                        DPRINTF(("TLV type %d not handled\n",
Index: if_iwnreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_iwnreg.h,v
retrieving revision 1.42
diff -u -p -r1.42 if_iwnreg.h
--- if_iwnreg.h 9 Jan 2011 15:45:37 -0000       1.42
+++ if_iwnreg.h 22 Aug 2011 20:49:30 -0000
@@ -727,6 +727,8 @@ struct iwn5000_wimax_coex {
 struct iwn5000_calib_elem {
        uint32_t        enable;
        uint32_t        start;
+#define IWN5000_CALIB_DC       (1 << 1)
+
        uint32_t        send;
        uint32_t        apply;
        uint32_t        reserved;
@@ -916,8 +918,8 @@ struct iwn_phy_calib {
 #define IWN5000_PHY_CALIB_TX_IQ_PERIODIC       17
 #define IWN5000_PHY_CALIB_TEMP_OFFSET          18
 
-#define IWN5000_PHY_CALIB_RESET_NOISE_GAIN     18
-#define IWN5000_PHY_CALIB_NOISE_GAIN           19
+#define IWN5000_PHY_CALIB_RESET_NOISE_GAIN     19
+#define IWN5000_PHY_CALIB_NOISE_GAIN           20
 
        uint8_t group;
        uint8_t ngroups;
@@ -1313,6 +1315,7 @@ 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_PHY_CALIB_SIZE      15
 
        uint16_t        alt;
        uint32_t        len;

Reply via email to