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