tech-net archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: iwn
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