Tue Mar 3 09:10:45 2015 UTC ()
workaround for interrupt coalescing bug not needed on 7265.
From OpenBSD if_iwm.c rev.1.25, if_iwmvar.h rev.1.7.


(nonaka)
diff -r1.16 -r1.17 src/sys/dev/pci/if_iwm.c
diff -r1.4 -r1.5 src/sys/dev/pci/if_iwmvar.h

cvs diff -r1.16 -r1.17 src/sys/dev/pci/if_iwm.c (expand / switch to unified diff)

--- src/sys/dev/pci/if_iwm.c 2015/03/02 12:07:27 1.16
+++ src/sys/dev/pci/if_iwm.c 2015/03/03 09:10:45 1.17
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_iwm.c,v 1.16 2015/03/02 12:07:27 nonaka Exp $ */ 1/* $NetBSD: if_iwm.c,v 1.17 2015/03/03 09:10:45 nonaka Exp $ */
2/* OpenBSD: if_iwm.c,v 1.18 2015/02/11 01:12:42 brad Exp */ 2/* OpenBSD: if_iwm.c,v 1.18 2015/02/11 01:12:42 brad Exp */
3 3
4/* 4/*
5 * Copyright (c) 2014 genua mbh <info@genua.de> 5 * Copyright (c) 2014 genua mbh <info@genua.de>
6 * Copyright (c) 2014 Fixup Software Ltd. 6 * Copyright (c) 2014 Fixup Software Ltd.
7 * 7 *
8 * Permission to use, copy, modify, and distribute this software for any 8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above 9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies. 10 * copyright notice and this permission notice appear in all copies.
11 * 11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
@@ -95,27 +95,27 @@ @@ -95,27 +95,27 @@
95 * purpose with or without fee is hereby granted, provided that the above 95 * purpose with or without fee is hereby granted, provided that the above
96 * copyright notice and this permission notice appear in all copies. 96 * copyright notice and this permission notice appear in all copies.
97 * 97 *
98 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 98 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
99 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 99 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
100 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 100 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
101 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 101 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
102 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 102 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
103 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 103 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
104 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 104 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
105 */ 105 */
106 106
107#include <sys/cdefs.h> 107#include <sys/cdefs.h>
108__KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.16 2015/03/02 12:07:27 nonaka Exp $"); 108__KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.17 2015/03/03 09:10:45 nonaka Exp $");
109 109
110#include <sys/param.h> 110#include <sys/param.h>
111#include <sys/conf.h> 111#include <sys/conf.h>
112#include <sys/kernel.h> 112#include <sys/kernel.h>
113#include <sys/kmem.h> 113#include <sys/kmem.h>
114#include <sys/mbuf.h> 114#include <sys/mbuf.h>
115#include <sys/mutex.h> 115#include <sys/mutex.h>
116#include <sys/proc.h> 116#include <sys/proc.h>
117#include <sys/socket.h> 117#include <sys/socket.h>
118#include <sys/sockio.h> 118#include <sys/sockio.h>
119#include <sys/systm.h> 119#include <sys/systm.h>
120 120
121#include <sys/cpu.h> 121#include <sys/cpu.h>
@@ -1479,45 +1479,47 @@ iwm_apm_init(struct iwm_softc *sc) @@ -1479,45 +1479,47 @@ iwm_apm_init(struct iwm_softc *sc)
1479 /* 1479 /*
1480 * Wait for clock stabilization; once stabilized, access to 1480 * Wait for clock stabilization; once stabilized, access to
1481 * device-internal resources is supported, e.g. iwm_write_prph() 1481 * device-internal resources is supported, e.g. iwm_write_prph()
1482 * and accesses to uCode SRAM. 1482 * and accesses to uCode SRAM.
1483 */ 1483 */
1484 if (!iwm_poll_bit(sc, IWM_CSR_GP_CNTRL, 1484 if (!iwm_poll_bit(sc, IWM_CSR_GP_CNTRL,
1485 IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 1485 IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
1486 IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000)) { 1486 IWM_CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000)) {
1487 aprint_error_dev(sc->sc_dev, 1487 aprint_error_dev(sc->sc_dev,
1488 "timeout waiting for clock stabilization\n"); 1488 "timeout waiting for clock stabilization\n");
1489 goto out; 1489 goto out;
1490 } 1490 }
1491 1491
1492 /* 1492 if (sc->host_interrupt_operation_mode) {
1493 * This is a bit of an abuse - This is needed for 7260 / 3160 1493 /*
1494 * only check host_interrupt_operation_mode even if this is 1494 * This is a bit of an abuse - This is needed for 7260 / 3160
1495 * not related to host_interrupt_operation_mode. 1495 * only check host_interrupt_operation_mode even if this is
1496 * 1496 * not related to host_interrupt_operation_mode.
1497 * Enable the oscillator to count wake up time for L1 exit. This 1497 *
1498 * consumes slightly more power (100uA) - but allows to be sure 1498 * Enable the oscillator to count wake up time for L1 exit. This
1499 * that we wake up from L1 on time. 1499 * consumes slightly more power (100uA) - but allows to be sure
1500 * 1500 * that we wake up from L1 on time.
1501 * This looks weird: read twice the same register, discard the 1501 *
1502 * value, set a bit, and yet again, read that same register 1502 * This looks weird: read twice the same register, discard the
1503 * just to discard the value. But that's the way the hardware 1503 * value, set a bit, and yet again, read that same register
1504 * seems to like it. 1504 * just to discard the value. But that's the way the hardware
1505 */ 1505 * seems to like it.
1506 iwm_read_prph(sc, IWM_OSC_CLK); 1506 */
1507 iwm_read_prph(sc, IWM_OSC_CLK); 1507 iwm_read_prph(sc, IWM_OSC_CLK);
1508 iwm_set_bits_prph(sc, IWM_OSC_CLK, IWM_OSC_CLK_FORCE_CONTROL); 1508 iwm_read_prph(sc, IWM_OSC_CLK);
1509 iwm_read_prph(sc, IWM_OSC_CLK); 1509 iwm_set_bits_prph(sc, IWM_OSC_CLK, IWM_OSC_CLK_FORCE_CONTROL);
1510 iwm_read_prph(sc, IWM_OSC_CLK); 1510 iwm_read_prph(sc, IWM_OSC_CLK);
 1511 iwm_read_prph(sc, IWM_OSC_CLK);
 1512 }
1511 1513
1512 /* 1514 /*
1513 * Enable DMA clock and wait for it to stabilize. 1515 * Enable DMA clock and wait for it to stabilize.
1514 * 1516 *
1515 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits 1517 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
1516 * do not disable clocks. This preserves any hardware bits already 1518 * do not disable clocks. This preserves any hardware bits already
1517 * set by default in "CLK_CTRL_REG" after reset. 1519 * set by default in "CLK_CTRL_REG" after reset.
1518 */ 1520 */
1519 iwm_write_prph(sc, IWM_APMG_CLK_EN_REG, IWM_APMG_CLK_VAL_DMA_CLK_RQT); 1521 iwm_write_prph(sc, IWM_APMG_CLK_EN_REG, IWM_APMG_CLK_VAL_DMA_CLK_RQT);
1520 //kpause("iwmapm", 0, mstohz(20), NULL); 1522 //kpause("iwmapm", 0, mstohz(20), NULL);
1521 DELAY(20); 1523 DELAY(20);
1522 1524
1523 /* Disable L1-Active */ 1525 /* Disable L1-Active */
@@ -1722,27 +1724,30 @@ iwm_nic_rx_init(struct iwm_softc *sc) @@ -1722,27 +1724,30 @@ iwm_nic_rx_init(struct iwm_softc *sc)
1722 * Note: Linux driver also sets this: 1724 * Note: Linux driver also sets this:
1723 * (IWM_RX_RB_TIMEOUT << IWM_FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS) | 1725 * (IWM_RX_RB_TIMEOUT << IWM_FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS) |
1724 * 1726 *
1725 * It causes weird behavior. YMMV. 1727 * It causes weird behavior. YMMV.
1726 */ 1728 */
1727 IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG, 1729 IWM_WRITE(sc, IWM_FH_MEM_RCSR_CHNL0_CONFIG_REG,
1728 IWM_FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | 1730 IWM_FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
1729 IWM_FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | /* HW bug */ 1731 IWM_FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | /* HW bug */
1730 IWM_FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | 1732 IWM_FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
1731 IWM_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K | 1733 IWM_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K |
1732 IWM_RX_QUEUE_SIZE_LOG << IWM_FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS); 1734 IWM_RX_QUEUE_SIZE_LOG << IWM_FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS);
1733 1735
1734 IWM_WRITE_1(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_TIMEOUT_DEF); 1736 IWM_WRITE_1(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_TIMEOUT_DEF);
1735 IWM_SETBITS(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_OPER_MODE); 1737
 1738 /* W/A for interrupt coalescing bug in 7260 and 3160 */
 1739 if (sc->host_interrupt_operation_mode)
 1740 IWM_SETBITS(sc, IWM_CSR_INT_COALESCING, IWM_HOST_INT_OPER_MODE);
1736 1741
1737 /* 1742 /*
1738 * Thus sayeth el jefe (iwlwifi) via a comment: 1743 * Thus sayeth el jefe (iwlwifi) via a comment:
1739 * 1744 *
1740 * This value should initially be 0 (before preparing any 1745 * This value should initially be 0 (before preparing any
1741 * RBs), should be 8 after preparing the first 8 RBs (for example) 1746 * RBs), should be 8 after preparing the first 8 RBs (for example)
1742 */ 1747 */
1743 IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, 8); 1748 IWM_WRITE(sc, IWM_FH_RSCSR_CHNL0_WPTR, 8);
1744 1749
1745 iwm_nic_unlock(sc); 1750 iwm_nic_unlock(sc);
1746 1751
1747 return 0; 1752 return 0;
1748} 1753}
@@ -6680,34 +6685,37 @@ iwm_attach(device_t parent, device_t sel @@ -6680,34 +6685,37 @@ iwm_attach(device_t parent, device_t sel
6680 if (intrstr != NULL) 6685 if (intrstr != NULL)
6681 aprint_error(" at %s", intrstr); 6686 aprint_error(" at %s", intrstr);
6682 aprint_error("\n"); 6687 aprint_error("\n");
6683 return; 6688 return;
6684 } 6689 }
6685 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 6690 aprint_normal_dev(self, "interrupting at %s\n", intrstr);
6686 6691
6687 sc->sc_wantresp = -1; 6692 sc->sc_wantresp = -1;
6688 6693
6689 switch (PCI_PRODUCT(sc->sc_pciid)) { 6694 switch (PCI_PRODUCT(sc->sc_pciid)) {
6690 case PCI_PRODUCT_INTEL_WIFI_LINK_7260_1: 6695 case PCI_PRODUCT_INTEL_WIFI_LINK_7260_1:
6691 case PCI_PRODUCT_INTEL_WIFI_LINK_7260_2: 6696 case PCI_PRODUCT_INTEL_WIFI_LINK_7260_2:
6692 sc->sc_fwname = "iwlwifi-7260-9.ucode"; 6697 sc->sc_fwname = "iwlwifi-7260-9.ucode";
 6698 sc->host_interrupt_operation_mode = 1;
6693 break; 6699 break;
6694 case PCI_PRODUCT_INTEL_WIFI_LINK_3160_1: 6700 case PCI_PRODUCT_INTEL_WIFI_LINK_3160_1:
6695 case PCI_PRODUCT_INTEL_WIFI_LINK_3160_2: 6701 case PCI_PRODUCT_INTEL_WIFI_LINK_3160_2:
6696 sc->sc_fwname = "iwlwifi-3160-9.ucode"; 6702 sc->sc_fwname = "iwlwifi-3160-9.ucode";
 6703 sc->host_interrupt_operation_mode = 1;
6697 break; 6704 break;
6698 case PCI_PRODUCT_INTEL_WIFI_LINK_7265_1: 6705 case PCI_PRODUCT_INTEL_WIFI_LINK_7265_1:
6699 case PCI_PRODUCT_INTEL_WIFI_LINK_7265_2: 6706 case PCI_PRODUCT_INTEL_WIFI_LINK_7265_2:
6700 sc->sc_fwname = "iwlwifi-7265-9.ucode"; 6707 sc->sc_fwname = "iwlwifi-7265-9.ucode";
 6708 sc->host_interrupt_operation_mode = 0;
6701 break; 6709 break;
6702 default: 6710 default:
6703 aprint_error_dev(self, "unknown product %#x", 6711 aprint_error_dev(self, "unknown product %#x",
6704 PCI_PRODUCT(sc->sc_pciid)); 6712 PCI_PRODUCT(sc->sc_pciid));
6705 return; 6713 return;
6706 } 6714 }
6707 DPRINTF(("%s: firmware=%s\n", DEVNAME(sc), sc->sc_fwname)); 6715 DPRINTF(("%s: firmware=%s\n", DEVNAME(sc), sc->sc_fwname));
6708 sc->sc_fwdmasegsz = IWM_FWDMASEGSZ; 6716 sc->sc_fwdmasegsz = IWM_FWDMASEGSZ;
6709 6717
6710 /* 6718 /*
6711 * We now start fiddling with the hardware 6719 * We now start fiddling with the hardware
6712 */ 6720 */
6713 6721

cvs diff -r1.4 -r1.5 src/sys/dev/pci/if_iwmvar.h (expand / switch to unified diff)

--- src/sys/dev/pci/if_iwmvar.h 2015/02/16 13:22:19 1.4
+++ src/sys/dev/pci/if_iwmvar.h 2015/03/03 09:10:45 1.5
@@ -1,15 +1,15 @@ @@ -1,15 +1,15 @@
1/* $NetBSD: if_iwmvar.h,v 1.4 2015/02/16 13:22:19 nonaka Exp $ */ 1/* $NetBSD: if_iwmvar.h,v 1.5 2015/03/03 09:10:45 nonaka Exp $ */
2/* OpenBSD: if_iwmvar.h,v 1.3 2015/02/07 07:10:44 phessler Exp */ 2/* OpenBSD: if_iwmvar.h,v 1.7 2015/03/02 13:51:10 jsg Exp */
3 3
4/* 4/*
5 * Copyright (c) 2014 genua mbh <info@genua.de> 5 * Copyright (c) 2014 genua mbh <info@genua.de>
6 * Copyright (c) 2014 Fixup Software Ltd. 6 * Copyright (c) 2014 Fixup Software Ltd.
7 * 7 *
8 * Permission to use, copy, modify, and distribute this software for any 8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above 9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies. 10 * copyright notice and this permission notice appear in all copies.
11 * 11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
@@ -463,26 +463,28 @@ struct iwm_softc { @@ -463,26 +463,28 @@ struct iwm_softc {
463 struct work sc_eswk; 463 struct work sc_eswk;
464 464
465 struct iwm_rx_phy_info sc_last_phy_info; 465 struct iwm_rx_phy_info sc_last_phy_info;
466 int sc_ampdu_ref; 466 int sc_ampdu_ref;
467 467
468 struct iwm_int_sta sc_aux_sta; 468 struct iwm_int_sta sc_aux_sta;
469 469
470 /* phy contexts. we only use the first one */ 470 /* phy contexts. we only use the first one */
471 struct iwm_mvm_phy_ctxt sc_phyctxt[IWM_NUM_PHY_CTX]; 471 struct iwm_mvm_phy_ctxt sc_phyctxt[IWM_NUM_PHY_CTX];
472 472
473 struct iwm_notif_statistics sc_stats; 473 struct iwm_notif_statistics sc_stats;
474 int sc_noise; 474 int sc_noise;
475 475
 476 int host_interrupt_operation_mode;
 477
476 struct bpf_if * sc_drvbpf; 478 struct bpf_if * sc_drvbpf;
477 479
478 union { 480 union {
479 struct iwm_rx_radiotap_header th; 481 struct iwm_rx_radiotap_header th;
480 uint8_t pad[IEEE80211_RADIOTAP_HDRLEN]; 482 uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
481 } sc_rxtapu; 483 } sc_rxtapu;
482#define sc_rxtap sc_rxtapu.th 484#define sc_rxtap sc_rxtapu.th
483 int sc_rxtap_len; 485 int sc_rxtap_len;
484 486
485 union { 487 union {
486 struct iwm_tx_radiotap_header th; 488 struct iwm_tx_radiotap_header th;
487 uint8_t pad[IEEE80211_RADIOTAP_HDRLEN]; 489 uint8_t pad[IEEE80211_RADIOTAP_HDRLEN];
488 } sc_txtapu; 490 } sc_txtapu;