> 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;