tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: iwn



Presumably OK to commit?

Cheers,

Patrick


On Fri, Jan 04, 2013 at 01:15:56PM +0000, Patrick Welche wrote:
> On Sat, Dec 29, 2012 at 12:30:33PM +0000, Patrick Welche wrote:
> > Diro's note in
> > 
> >   http://mail-index.netbsd.org/tech-net/2012/12/08/msg003778.html
> > 
> > reminded me that I never applied the patch in
> > 
> >   http://mail-index.netbsd.org/tech-kern/2011/08/06/msg011131.html
> > 
> > I am writing this logged in via
> > 
> >   iwn0 at pci3 dev 0 function 0: Intel Centrino Advanced-N 6230 (rev. 0x34)
> > 
> > so it does work. The unclean part is that I had to comment out the
> > bluetooth coexistence code. This week I wrote some bluetooth coexistence
> > code, which doesn't fail, but now crystal callibration fails: 
> > 
> > Configuring WiMAX coexistence
> > sending crystal calibration 121, 121
> > iwn0: fatal firmware error
> > 
> > Do any of you know whether 121 makes any sense?
> > The code seems to just copy the values from an eeprom...
> > 
> > One thing I did change is
> >   IWN5000_CMD_WIMAX_COEX
> > which I think should be 92 rather than 90...
> 
> It turns out that the calibration error goes away when I set
> IWN5000_CMD_WIMAX_COEX back to 90. This suggests that the WIMAX_COEX
> code is broken, as 90 doesn't do much - but that is another problem...
> 
> Attached is a patch which allows the 6230 to work, and which has
> bluetooth coexistence code.
> 
> 
> Cheers,
> 
> Patrick

> Index: if_iwn.c
> ===================================================================
> RCS file: /cvsroot/src/sys/dev/pci/if_iwn.c,v
> retrieving revision 1.62
> diff -u -r1.62 if_iwn.c
> --- if_iwn.c  30 Jan 2012 19:41:20 -0000      1.62
> +++ if_iwn.c  4 Jan 2013 13:09:28 -0000
> @@ -35,6 +35,9 @@
>  #include <sys/socket.h>
>  #include <sys/systm.h>
>  #include <sys/malloc.h>
> +#ifdef notyetMODULE
> +#include <sys/module.h>
> +#endif
>  #include <sys/mutex.h>
>  #include <sys/conf.h>
>  #include <sys/kauth.h>
> @@ -227,6 +230,11 @@
>  static int   iwn_send_sensitivity(struct iwn_softc *);
>  static int   iwn_set_pslevel(struct iwn_softc *, int, int, int);
>  static int   iwn5000_runtime_calib(struct iwn_softc *);
> +
> +static int   iwn_config_bt_coex_bluetooth(struct iwn_softc *);
> +static int   iwn_config_bt_coex_prio_table(struct iwn_softc *);
> +static int   iwn_config_bt_coex_adv1(struct iwn_softc *);
> +
>  static int   iwn_config(struct iwn_softc *);
>  static int   iwn_scan(struct iwn_softc *, uint16_t);
>  static int   iwn_auth(struct iwn_softc *);
> @@ -618,6 +626,7 @@
>       ops->read_eeprom = iwn4965_read_eeprom;
>       ops->post_alive = iwn4965_post_alive;
>       ops->nic_config = iwn4965_nic_config;
> +     ops->config_bt_coex = iwn_config_bt_coex_bluetooth;
>       ops->update_sched = iwn4965_update_sched;
>       ops->get_temperature = iwn4965_get_temperature;
>       ops->get_rssi = iwn4965_get_rssi;
> @@ -657,6 +666,7 @@
>       ops->read_eeprom = iwn5000_read_eeprom;
>       ops->post_alive = iwn5000_post_alive;
>       ops->nic_config = iwn5000_nic_config;
> +     ops->config_bt_coex = iwn_config_bt_coex_bluetooth;
>       ops->update_sched = iwn5000_update_sched;
>       ops->get_temperature = iwn5000_get_temperature;
>       ops->get_rssi = iwn5000_get_rssi;
> @@ -717,7 +727,16 @@
>               break;
>       case IWN_HW_REV_TYPE_6005:
>               sc->limits = &iwn6000_sensitivity_limits;
> -             sc->fwname = "iwlwifi-6000g2a-5.ucode";
> +             /* Type 6030 cards return IWN_HW_REV_TYPE_6005 */
> +             if (pid == PCI_PRODUCT_INTEL_WIFI_LINK_1030_1 ||
> +                 pid == PCI_PRODUCT_INTEL_WIFI_LINK_1030_2 ||
> +                 pid == PCI_PRODUCT_INTEL_WIFI_LINK_6230_1 ||
> +                 pid == PCI_PRODUCT_INTEL_WIFI_LINK_6230_2) {
> +                     sc->fwname = "iwlwifi-6000g2b-5.ucode";
> +                     ops->config_bt_coex = iwn_config_bt_coex_adv1;
> +             }
> +             else
> +                     sc->fwname = "iwlwifi-6000g2a-5.ucode";
>               break;
>       default:
>               aprint_normal(": adapter type %d not supported\n", sc->hw_type);
> @@ -4107,16 +4126,108 @@
>  }
>  
>  static int
> +iwn_config_bt_coex_bluetooth(struct iwn_softc *sc)
> +{
> +     struct iwn_bluetooth bluetooth;
> +
> +     memset(&bluetooth, 0, sizeof bluetooth);
> +     bluetooth.flags = IWN_BT_COEX_ENABLE;
> +     bluetooth.lead_time = IWN_BT_LEAD_TIME_DEF;
> +     bluetooth.max_kill = IWN_BT_MAX_KILL_DEF;
> +
> +     DPRINTF(("configuring bluetooth coexistence\n"));
> +     return iwn_cmd(sc, IWN_CMD_BT_COEX, &bluetooth, sizeof bluetooth, 0);
> +}
> +
> +static int
> +iwn_config_bt_coex_prio_table(struct iwn_softc *sc)
> +{
> +     uint8_t prio_table[16];
> +
> +     memset(&prio_table, 0, sizeof prio_table);
> +     prio_table[ 0] =  6;    /* init calibration 1           */
> +     prio_table[ 1] =  7;    /* init calibration 2           */
> +     prio_table[ 2] =  2;    /* periodic calib low 1         */
> +     prio_table[ 3] =  3;    /* periodic calib low 2         */
> +     prio_table[ 4] =  4;    /* periodic calib high 1        */
> +     prio_table[ 5] =  5;    /* periodic calib high 2        */
> +     prio_table[ 6] =  6;    /* dtim                         */
> +     prio_table[ 7] =  8;    /* scan52                       */
> +     prio_table[ 8] = 10;    /* scan24                       */
> +
> +     DPRINTF(("sending priority lookup table\n"));
> +     return iwn_cmd(sc, IWN_CMD_BT_COEX_PRIO_TABLE,
> +                    &prio_table, sizeof prio_table, 0);
> +}
> +
> +static int
> +iwn_config_bt_coex_adv1(struct iwn_softc *sc)
> +{
> +     int error;
> +     struct iwn_bt_adv1 d;
> +
> +     memset(&d, 0, sizeof d);
> +     d.basic.bt.flags = IWN_BT_COEX_ENABLE;
> +     d.basic.bt.lead_time = IWN_BT_LEAD_TIME_DEF;
> +     d.basic.bt.max_kill = IWN_BT_MAX_KILL_DEF;
> +     d.basic.bt.bt3_timer_t7_value = IWN_BT_BT3_T7_DEF;
> +     d.basic.bt.kill_ack_mask = IWN_BT_KILL_ACK_MASK_DEF;
> +     d.basic.bt.kill_cts_mask = IWN_BT_KILL_CTS_MASK_DEF;
> +     d.basic.bt3_prio_sample_time = IWN_BT_BT3_PRIO_SAMPLE_DEF;
> +     d.basic.bt3_timer_t2_value = IWN_BT_BT3_T2_DEF;
> +     d.basic.bt3_lookup_table[ 0] = htole32(0xaaaaaaaa); /* Normal */
> +     d.basic.bt3_lookup_table[ 1] = htole32(0xaaaaaaaa);
> +     d.basic.bt3_lookup_table[ 2] = htole32(0xaeaaaaaa);
> +     d.basic.bt3_lookup_table[ 3] = htole32(0xaaaaaaaa);
> +     d.basic.bt3_lookup_table[ 4] = htole32(0xcc00ff28);
> +     d.basic.bt3_lookup_table[ 5] = htole32(0x0000aaaa);
> +     d.basic.bt3_lookup_table[ 6] = htole32(0xcc00aaaa);
> +     d.basic.bt3_lookup_table[ 7] = htole32(0x0000aaaa);
> +     d.basic.bt3_lookup_table[ 8] = htole32(0xc0004000);
> +     d.basic.bt3_lookup_table[ 9] = htole32(0x00004000);
> +     d.basic.bt3_lookup_table[10] = htole32(0xf0005000);
> +     d.basic.bt3_lookup_table[11] = htole32(0xf0005000);
> +     d.basic.reduce_txpower = 0; /* as not implemented */
> +     d.basic.valid = IWN_BT_ALL_VALID_MASK;
> +     d.prio_boost = IWN_BT_PRIO_BOOST_DEF;
> +     d.tx_prio_boost = 0;
> +     d.rx_prio_boost = 0;
> +
> +     DPRINTF(("configuring advanced bluetooth coexistence v1\n"));
> +     error = iwn_cmd(sc, IWN_CMD_BT_COEX, &d, sizeof d, 0);
> +     if (error != 0) {
> +             aprint_error_dev(sc->sc_dev,
> +                     "could not configure advanced bluetooth coexistence\n");
> +             return error;
> +     }
> +
> +     error = iwn_config_bt_coex_prio_table(sc);
> +     if (error != 0) {
> +             aprint_error_dev(sc->sc_dev,
> +                     "could not configure send BT priority table\n");
> +             return error;
> +     }
> +
> +     return error;
> +}
> +
> +static int
>  iwn_config(struct iwn_softc *sc)
>  {
>       struct iwn_ops *ops = &sc->ops;
>       struct ieee80211com *ic = &sc->sc_ic;
>       struct ifnet *ifp = ic->ic_ifp;
> -     struct iwn_bluetooth bluetooth;
>       uint32_t txmask;
>       uint16_t rxchain;
>       int error;
>  
> +     error = ops->config_bt_coex(sc);
> +     if (error != 0) {
> +             aprint_error_dev(sc->sc_dev,
> +                     "could not configure bluetooth coexistence\n");
> +             return error;
> +     }
> +
>       if (sc->hw_type == IWN_HW_REV_TYPE_6050 ||
>           sc->hw_type == IWN_HW_REV_TYPE_6005) {
>               /* Configure runtime DC calibration. */
> @@ -4141,19 +4252,6 @@
>               }
>       }
>  
> -     /* Configure bluetooth coexistence. */
> -     memset(&bluetooth, 0, sizeof bluetooth);
> -     bluetooth.flags = IWN_BT_COEX_CHAN_ANN | IWN_BT_COEX_BT_PRIO;
> -     bluetooth.lead_time = IWN_BT_LEAD_TIME_DEF;
> -     bluetooth.max_kill = IWN_BT_MAX_KILL_DEF;
> -     DPRINTF(("configuring bluetooth coexistence\n"));
> -     error = iwn_cmd(sc, IWN_CMD_BT_COEX, &bluetooth, sizeof bluetooth, 0);
> -     if (error != 0) {
> -             aprint_error_dev(sc->sc_dev,
> -                 "could not configure bluetooth coexistence\n");
> -             return error;
> -     }
> -
>       /* Set mode, channel, RX filter and enable RX. */
>       memset(&sc->rxon, 0, sizeof (struct iwn_rxon));
>       IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
> @@ -6110,3 +6208,39 @@
>       }
>  }
>  
> +#ifdef notyetMODULE
> +
> +MODULE(MODULE_CLASS_DRIVER, if_iwn, "pci");
> +
> +#ifdef _MODULE
> +#include "ioconf.c"
> +#endif
> +
> +static int
> +if_iwn_modcmd(modcmd_t cmd, void *data)
> +{
> +     int error = 0;
> +
> +     switch (cmd) {
> +     case MODULE_CMD_INIT:
> +#ifdef _MODULE
> +             error = config_init_component(cfdriver_ioconf_if_iwn,
> +                     cfattach_ioconf_if_iwn, cfdata_ioconf_if_iwn);
> +#endif
> +             return error;
> +     case MODULE_CMD_FINI:
> +#ifdef _MODULE
> +             error = config_fini_component(cfdriver_ioconf_if_iwn,
> +                     cfattach_ioconf_if_iwn, cfdata_ioconf_if_iwn);
> +#endif
> +             return error;
> +     case MODULE_CMD_AUTOUNLOAD:
> +#ifdef _MODULE
> +             /* XXX This is not optional! */
> +#endif
> +             return error;
> +     default:
> +             return ENOTTY;
> +     }
> +}
> +#endif
> Index: if_iwnreg.h
> ===================================================================
> RCS file: /cvsroot/src/sys/dev/pci/if_iwnreg.h,v
> retrieving revision 1.10
> diff -u -r1.10 if_iwnreg.h
> --- if_iwnreg.h       8 Oct 2011 09:15:08 -0000       1.10
> +++ if_iwnreg.h       4 Jan 2013 13:09:31 -0000
> @@ -18,6 +18,8 @@
>   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
>   */
>  
> +#include <sys/endian.h>
> +
>  /* XXX Added for NetBSD */
>  #define EDCA_NUM_AC          4
>  #define IEEE80211_TKIP_MICLEN        8
> @@ -210,6 +212,7 @@
>  #define IWN_HW_REV_TYPE_6000 7
>  #define IWN_HW_REV_TYPE_6050 8
>  #define IWN_HW_REV_TYPE_6005 11
> +/* Types 6030 and 6035 also return 11 */
>  
>  /* Possible flags for register IWN_GIO_CHICKEN. */
>  #define IWN_GIO_CHICKEN_L1A_NO_L0S_RX        (1 << 23)
> @@ -424,8 +427,8 @@
>  #define IWN_CMD_TIMING                        20
>  #define IWN_CMD_ADD_NODE              24
>  #define IWN_CMD_TX_DATA                       28
> -#define IWN_CMD_LINK_QUALITY          78
>  #define IWN_CMD_SET_LED                       72
> +#define IWN_CMD_LINK_QUALITY          78
>  #define IWN5000_CMD_WIMAX_COEX                90
>  #define IWN5000_CMD_CALIB_CONFIG     101
>  #define IWN_CMD_SET_POWER_MODE               119
> @@ -438,6 +441,7 @@
>  #define IWN_CMD_SET_CRITICAL_TEMP    164
>  #define IWN_CMD_SET_SENSITIVITY              168
>  #define IWN_CMD_PHY_CALIB            176
> +#define IWN_CMD_BT_COEX_PRIO_TABLE   204
>  
>       uint8_t flags;
>       uint8_t idx;
> @@ -834,22 +838,71 @@
>       uint8_t reserved;
>  } __packed;
>  
> -/* Structure for command IWN_CMD_BLUETOOTH. */
> +/* Structure for command IWN_CMD_BT_COEX. */
>  struct iwn_bluetooth {
>       uint8_t         flags;
>  #define IWN_BT_COEX_CHAN_ANN (1 << 0)
>  #define IWN_BT_COEX_BT_PRIO  (1 << 1)
>  #define IWN_BT_COEX_2_WIRE   (1 << 2)
> -
> +#define IWN_BT_COEX_ENABLE   IWN_BT_COEX_CHAN_ANN | IWN_BT_COEX_BT_PRIO
>       uint8_t         lead_time;
>  #define IWN_BT_LEAD_TIME_DEF 30
> -
>       uint8_t         max_kill;
>  #define IWN_BT_MAX_KILL_DEF  5
> -
> +     uint8_t         bt3_timer_t7_value;
> +#define IWN_BT_BT3_T7_DEF    1
> +     uint32_t        kill_ack_mask;
> +#define IWN_BT_KILL_ACK_MASK_DEF     htole32(0xffff0000)
> +     uint32_t        kill_cts_mask;
> +#define IWN_BT_KILL_CTS_MASK_DEF     htole32(0xffff0000)
> +} __packed;
> +
> +struct iwn_bt_basic {
> +     struct iwn_bluetooth bt;
> +     uint8_t         bt3_prio_sample_time;
> +#define IWN_BT_BT3_PRIO_SAMPLE_DEF   2
> +     uint8_t         bt3_timer_t2_value;
> +#define IWN_BT_BT3_T2_DEF    12
> +     uint16_t        bt4_reaction_time; /* unused */
> +     uint32_t        bt3_lookup_table[12];
> +     uint8_t         reduce_txpower; /* bit 0 */
> +     uint8_t         reserved;
> +     uint16_t        valid;
> +#define IWN_BT_VALID_ENABLE_FLAGS    htole16(1 << 0)
> +#define IWN_BT_VALID_BOOST           htole16(1 << 1)
> +#define IWN_BT_VALID_MAX_KILL                htole16(1 << 2)
> +#define IWN_BT_VALID_3W_TIMERS               htole16(1 << 3)
> +#define IWN_BT_VALID_KILL_ACK_MASK   htole16(1 << 4)
> +#define IWN_BT_VALID_KILL_CTS_MASK   htole16(1 << 5)
> +#define IWN_BT_VALID_REDUCED_TX_PWR  htole16(1 << 6)
> +#define IWN_BT_VALID_3W_LUT          htole16(1 << 7)
> +#define IWN_BT_ALL_VALID_MASK                (IWN_BT_VALID_ENABLE_FLAGS | \
> +                                      IWN_BT_VALID_BOOST | \
> +                                      IWN_BT_VALID_MAX_KILL | \
> +                                      IWN_BT_VALID_3W_TIMERS | \
> +                                      IWN_BT_VALID_KILL_ACK_MASK | \
> +                                      IWN_BT_VALID_KILL_CTS_MASK | \
> +                                      IWN_BT_VALID_REDUCED_TX_PWR | \
> +                                      IWN_BT_VALID_3W_LUT)
> +} __packed;
> +
> +struct iwn_bt_adv1 {
> +     struct iwn_bt_basic basic;
> +     uint8_t         prio_boost;
> +#define IWN_BT_PRIO_BOOST_DEF        0xf0
> +     /* set IWLAGN_BT_VALID_BOOST to "1" in "valid" bitmask for */
> +     uint8_t         tx_prio_boost;
> +     uint16_t        rx_prio_boost;
> +} __packed;
> +
> +struct iwn_bt_adv2 {
> +     struct iwn_bt_basic basic;
> +     uint32_t        prio_boost;
> +#define IWN_BT_PRIO_BOOST_DEF32      0xf0f0f0
>       uint8_t         reserved;
> -     uint32_t        kill_ack;
> -     uint32_t        kill_cts;
> +     /* set IWLAGN_BT_VALID_BOOST to "1" in "valid" bitmask for */
> +     uint8_t         tx_prio_boost;
> +     uint16_t        rx_prio_boost;
>  } __packed;
>  
>  /* Structure for command IWN_CMD_SET_CRITICAL_TEMP. */
> Index: if_iwnvar.h
> ===================================================================
> RCS file: /cvsroot/src/sys/dev/pci/if_iwnvar.h,v
> retrieving revision 1.13
> diff -u -r1.13 if_iwnvar.h
> --- if_iwnvar.h       15 May 2011 13:56:20 -0000      1.13
> +++ if_iwnvar.h       4 Jan 2013 13:09:31 -0000
> @@ -179,6 +179,7 @@
>       void            (*read_eeprom)(struct iwn_softc *);
>       int             (*post_alive)(struct iwn_softc *);
>       int             (*nic_config)(struct iwn_softc *);
> +     int             (*config_bt_coex)(struct iwn_softc *);
>       void            (*update_sched)(struct iwn_softc *, int, int, uint8_t,
>                           uint16_t);
>       int             (*get_temperature)(struct iwn_softc *);



Home | Main Index | Thread Index | Old Index