Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 1 | /****************************************************************************** |
| 2 | * |
| 3 | * This file is provided under a dual BSD/GPLv2 license. When using or |
| 4 | * redistributing this file, you may do so under either license. |
| 5 | * |
| 6 | * GPL LICENSE SUMMARY |
| 7 | * |
Reinette Chatre | 1f44780 | 2010-01-15 13:43:41 -0800 | [diff] [blame] | 8 | * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 9 | * |
| 10 | * This program is free software; you can redistribute it and/or modify |
Ian Schram | 01ebd06 | 2007-10-25 17:15:22 +0800 | [diff] [blame] | 11 | * it under the terms of version 2 of the GNU General Public License as |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 12 | * published by the Free Software Foundation. |
| 13 | * |
| 14 | * This program is distributed in the hope that it will be useful, but |
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 | * General Public License for more details. |
| 18 | * |
| 19 | * You should have received a copy of the GNU General Public License |
| 20 | * along with this program; if not, write to the Free Software |
| 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, |
| 22 | * USA |
| 23 | * |
| 24 | * The full GNU General Public License is included in this distribution |
| 25 | * in the file called LICENSE.GPL. |
| 26 | * |
| 27 | * Contact Information: |
Winkler, Tomas | 759ef89 | 2008-12-09 11:28:58 -0800 | [diff] [blame] | 28 | * Intel Linux Wireless <ilw@linux.intel.com> |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 |
| 30 | * |
| 31 | * BSD LICENSE |
| 32 | * |
Reinette Chatre | 1f44780 | 2010-01-15 13:43:41 -0800 | [diff] [blame] | 33 | * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 34 | * All rights reserved. |
| 35 | * |
| 36 | * Redistribution and use in source and binary forms, with or without |
| 37 | * modification, are permitted provided that the following conditions |
| 38 | * are met: |
| 39 | * |
| 40 | * * Redistributions of source code must retain the above copyright |
| 41 | * notice, this list of conditions and the following disclaimer. |
| 42 | * * Redistributions in binary form must reproduce the above copyright |
| 43 | * notice, this list of conditions and the following disclaimer in |
| 44 | * the documentation and/or other materials provided with the |
| 45 | * distribution. |
| 46 | * * Neither the name Intel Corporation nor the names of its |
| 47 | * contributors may be used to endorse or promote products derived |
| 48 | * from this software without specific prior written permission. |
| 49 | * |
| 50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 61 | *****************************************************************************/ |
| 62 | |
| 63 | #ifndef __iwl_prph_h__ |
| 64 | #define __iwl_prph_h__ |
| 65 | |
Ben Cahill | e385144 | 2007-11-29 11:10:07 +0800 | [diff] [blame] | 66 | /* |
| 67 | * Registers in this file are internal, not PCI bus memory mapped. |
| 68 | * Driver accesses these via HBUS_TARG_PRPH_* registers. |
| 69 | */ |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 70 | #define PRPH_BASE (0x00000) |
| 71 | #define PRPH_END (0xFFFFF) |
| 72 | |
| 73 | /* APMG (power management) constants */ |
| 74 | #define APMG_BASE (PRPH_BASE + 0x3000) |
| 75 | #define APMG_CLK_CTRL_REG (APMG_BASE + 0x0000) |
| 76 | #define APMG_CLK_EN_REG (APMG_BASE + 0x0004) |
| 77 | #define APMG_CLK_DIS_REG (APMG_BASE + 0x0008) |
| 78 | #define APMG_PS_CTRL_REG (APMG_BASE + 0x000c) |
| 79 | #define APMG_PCIDEV_STT_REG (APMG_BASE + 0x0010) |
| 80 | #define APMG_RFKILL_REG (APMG_BASE + 0x0014) |
| 81 | #define APMG_RTC_INT_STT_REG (APMG_BASE + 0x001c) |
| 82 | #define APMG_RTC_INT_MSK_REG (APMG_BASE + 0x0020) |
Wey-Yi Guy | 02c06e4 | 2009-07-17 09:30:14 -0700 | [diff] [blame] | 83 | #define APMG_DIGITAL_SVR_REG (APMG_BASE + 0x0058) |
| 84 | #define APMG_ANALOG_SVR_REG (APMG_BASE + 0x006C) |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 85 | |
| 86 | #define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200) |
| 87 | #define APMG_CLK_VAL_BSM_CLK_RQT (0x00000800) |
| 88 | |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 89 | |
Tomas Winkler | 4c43e0d | 2008-08-04 16:00:39 +0800 | [diff] [blame] | 90 | #define APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS (0x00400000) |
| 91 | #define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000) |
| 92 | #define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000) |
| 93 | #define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000) |
| 94 | #define APMG_PS_CTRL_VAL_PWR_SRC_MAX (0x01000000) /* 3945 only */ |
| 95 | #define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x02000000) |
Wey-Yi Guy | 02c06e4 | 2009-07-17 09:30:14 -0700 | [diff] [blame] | 96 | #define APMG_SVR_VOLTAGE_CONFIG_BIT_MSK (0x000001E0) /* bit 8:5 */ |
| 97 | #define APMG_SVR_DIGITAL_VOLTAGE_1_32 (0x00000060) |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 98 | |
Tomas Winkler | 4c43e0d | 2008-08-04 16:00:39 +0800 | [diff] [blame] | 99 | #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 100 | |
| 101 | /** |
| 102 | * BSM (Bootstrap State Machine) |
| 103 | * |
| 104 | * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program |
| 105 | * in special SRAM that does not power down when the embedded control |
| 106 | * processor is sleeping (e.g. for periodic power-saving shutdowns of radio). |
| 107 | * |
| 108 | * When powering back up after sleeps (or during initial uCode load), the BSM |
| 109 | * internally loads the short bootstrap program from the special SRAM into the |
| 110 | * embedded processor's instruction SRAM, and starts the processor so it runs |
| 111 | * the bootstrap program. |
| 112 | * |
| 113 | * This bootstrap program loads (via PCI busmaster DMA) instructions and data |
| 114 | * images for a uCode program from host DRAM locations. The host driver |
| 115 | * indicates DRAM locations and sizes for instruction and data images via the |
| 116 | * four BSM_DRAM_* registers. Once the bootstrap program loads the new program, |
| 117 | * the new program starts automatically. |
| 118 | * |
| 119 | * The uCode used for open-source drivers includes two programs: |
| 120 | * |
| 121 | * 1) Initialization -- performs hardware calibration and sets up some |
| 122 | * internal data, then notifies host via "initialize alive" notification |
| 123 | * (struct iwl_init_alive_resp) that it has completed all of its work. |
| 124 | * After signal from host, it then loads and starts the runtime program. |
| 125 | * The initialization program must be used when initially setting up the |
| 126 | * NIC after loading the driver. |
| 127 | * |
| 128 | * 2) Runtime/Protocol -- performs all normal runtime operations. This |
| 129 | * notifies host via "alive" notification (struct iwl_alive_resp) that it |
| 130 | * is ready to be used. |
| 131 | * |
| 132 | * When initializing the NIC, the host driver does the following procedure: |
| 133 | * |
| 134 | * 1) Load bootstrap program (instructions only, no data image for bootstrap) |
| 135 | * into bootstrap memory. Use dword writes starting at BSM_SRAM_LOWER_BOUND |
| 136 | * |
| 137 | * 2) Point (via BSM_DRAM_*) to the "initialize" uCode data and instruction |
| 138 | * images in host DRAM. |
| 139 | * |
| 140 | * 3) Set up BSM to copy from BSM SRAM into uCode instruction SRAM when asked: |
| 141 | * BSM_WR_MEM_SRC_REG = 0 |
| 142 | * BSM_WR_MEM_DST_REG = RTC_INST_LOWER_BOUND |
| 143 | * BSM_WR_MEM_DWCOUNT_REG = # dwords in bootstrap instruction image |
| 144 | * |
| 145 | * 4) Load bootstrap into instruction SRAM: |
| 146 | * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START |
| 147 | * |
| 148 | * 5) Wait for load completion: |
| 149 | * Poll BSM_WR_CTRL_REG for BSM_WR_CTRL_REG_BIT_START = 0 |
| 150 | * |
| 151 | * 6) Enable future boot loads whenever NIC's power management triggers it: |
| 152 | * BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START_EN |
| 153 | * |
| 154 | * 7) Start the NIC by removing all reset bits: |
| 155 | * CSR_RESET = 0 |
| 156 | * |
| 157 | * The bootstrap uCode (already in instruction SRAM) loads initialization |
| 158 | * uCode. Initialization uCode performs data initialization, sends |
| 159 | * "initialize alive" notification to host, and waits for a signal from |
| 160 | * host to load runtime code. |
| 161 | * |
| 162 | * 4) Point (via BSM_DRAM_*) to the "runtime" uCode data and instruction |
| 163 | * images in host DRAM. The last register loaded must be the instruction |
Tomas Winkler | a96a27f | 2008-10-23 23:48:56 -0700 | [diff] [blame] | 164 | * byte count register ("1" in MSbit tells initialization uCode to load |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 165 | * the runtime uCode): |
Tomas Winkler | a96a27f | 2008-10-23 23:48:56 -0700 | [diff] [blame] | 166 | * BSM_DRAM_INST_BYTECOUNT_REG = byte count | BSM_DRAM_INST_LOAD |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 167 | * |
| 168 | * 5) Wait for "alive" notification, then issue normal runtime commands. |
| 169 | * |
| 170 | * Data caching during power-downs: |
| 171 | * |
| 172 | * Just before the embedded controller powers down (e.g for automatic |
| 173 | * power-saving modes, or for RFKILL), uCode stores (via PCI busmaster DMA) |
| 174 | * a current snapshot of the embedded processor's data SRAM into host DRAM. |
| 175 | * This caches the data while the embedded processor's memory is powered down. |
| 176 | * Location and size are controlled by BSM_DRAM_DATA_* registers. |
| 177 | * |
| 178 | * NOTE: Instruction SRAM does not need to be saved, since that doesn't |
| 179 | * change during operation; the original image (from uCode distribution |
| 180 | * file) can be used for reload. |
| 181 | * |
| 182 | * When powering back up, the BSM loads the bootstrap program. Bootstrap looks |
| 183 | * at the BSM_DRAM_* registers, which now point to the runtime instruction |
| 184 | * image and the cached (modified) runtime data (*not* the initialization |
| 185 | * uCode). Bootstrap reloads these runtime images into SRAM, and restarts the |
| 186 | * uCode from where it left off before the power-down. |
| 187 | * |
| 188 | * NOTE: Initialization uCode does *not* run as part of the save/restore |
| 189 | * procedure. |
| 190 | * |
| 191 | * This save/restore method is mostly for autonomous power management during |
| 192 | * normal operation (result of POWER_TABLE_CMD). Platform suspend/resume and |
| 193 | * RFKILL should use complete restarts (with total re-initialization) of uCode, |
| 194 | * allowing total shutdown (including BSM memory). |
| 195 | * |
| 196 | * Note that, during normal operation, the host DRAM that held the initial |
| 197 | * startup data for the runtime code is now being used as a backup data cache |
| 198 | * for modified data! If you need to completely re-initialize the NIC, make |
| 199 | * sure that you use the runtime data image from the uCode distribution file, |
| 200 | * not the modified/saved runtime data. You may want to store a separate |
| 201 | * "clean" runtime data image in DRAM to avoid disk reads of distribution file. |
| 202 | */ |
| 203 | |
| 204 | /* BSM bit fields */ |
| 205 | #define BSM_WR_CTRL_REG_BIT_START (0x80000000) /* start boot load now */ |
| 206 | #define BSM_WR_CTRL_REG_BIT_START_EN (0x40000000) /* enable boot after pwrup*/ |
| 207 | #define BSM_DRAM_INST_LOAD (0x80000000) /* start program load now */ |
| 208 | |
| 209 | /* BSM addresses */ |
| 210 | #define BSM_BASE (PRPH_BASE + 0x3400) |
| 211 | #define BSM_END (PRPH_BASE + 0x3800) |
| 212 | |
| 213 | #define BSM_WR_CTRL_REG (BSM_BASE + 0x000) /* ctl and status */ |
| 214 | #define BSM_WR_MEM_SRC_REG (BSM_BASE + 0x004) /* source in BSM mem */ |
| 215 | #define BSM_WR_MEM_DST_REG (BSM_BASE + 0x008) /* dest in SRAM mem */ |
| 216 | #define BSM_WR_DWCOUNT_REG (BSM_BASE + 0x00C) /* bytes */ |
| 217 | #define BSM_WR_STATUS_REG (BSM_BASE + 0x010) /* bit 0: 1 == done */ |
| 218 | |
| 219 | /* |
| 220 | * Pointers and size regs for bootstrap load and data SRAM save/restore. |
| 221 | * NOTE: 3945 pointers use bits 31:0 of DRAM address. |
| 222 | * 4965 pointers use bits 35:4 of DRAM address. |
| 223 | */ |
| 224 | #define BSM_DRAM_INST_PTR_REG (BSM_BASE + 0x090) |
| 225 | #define BSM_DRAM_INST_BYTECOUNT_REG (BSM_BASE + 0x094) |
| 226 | #define BSM_DRAM_DATA_PTR_REG (BSM_BASE + 0x098) |
| 227 | #define BSM_DRAM_DATA_BYTECOUNT_REG (BSM_BASE + 0x09C) |
| 228 | |
| 229 | /* |
| 230 | * BSM special memory, stays powered on during power-save sleeps. |
| 231 | * Read/write, address range from LOWER_BOUND to (LOWER_BOUND + SIZE -1) |
| 232 | */ |
| 233 | #define BSM_SRAM_LOWER_BOUND (PRPH_BASE + 0x3800) |
| 234 | #define BSM_SRAM_SIZE (1024) /* bytes */ |
| 235 | |
Ben Cahill | e385144 | 2007-11-29 11:10:07 +0800 | [diff] [blame] | 236 | |
| 237 | /* 3945 Tx scheduler registers */ |
Emmanuel Grumbach | 7088310 | 2007-10-25 17:15:39 +0800 | [diff] [blame] | 238 | #define ALM_SCD_BASE (PRPH_BASE + 0x2E00) |
| 239 | #define ALM_SCD_MODE_REG (ALM_SCD_BASE + 0x000) |
| 240 | #define ALM_SCD_ARASTAT_REG (ALM_SCD_BASE + 0x004) |
| 241 | #define ALM_SCD_TXFACT_REG (ALM_SCD_BASE + 0x010) |
| 242 | #define ALM_SCD_TXF4MF_REG (ALM_SCD_BASE + 0x014) |
| 243 | #define ALM_SCD_TXF5MF_REG (ALM_SCD_BASE + 0x020) |
| 244 | #define ALM_SCD_SBYP_MODE_1_REG (ALM_SCD_BASE + 0x02C) |
| 245 | #define ALM_SCD_SBYP_MODE_2_REG (ALM_SCD_BASE + 0x030) |
| 246 | |
Emmanuel Grumbach | 038669e | 2008-04-23 17:15:04 -0700 | [diff] [blame] | 247 | /** |
| 248 | * Tx Scheduler |
| 249 | * |
Tomas Winkler | a96a27f | 2008-10-23 23:48:56 -0700 | [diff] [blame] | 250 | * The Tx Scheduler selects the next frame to be transmitted, choosing TFDs |
Emmanuel Grumbach | 038669e | 2008-04-23 17:15:04 -0700 | [diff] [blame] | 251 | * (Transmit Frame Descriptors) from up to 16 circular Tx queues resident in |
| 252 | * host DRAM. It steers each frame's Tx command (which contains the frame |
| 253 | * data) into one of up to 7 prioritized Tx DMA FIFO channels within the |
| 254 | * device. A queue maps to only one (selectable by driver) Tx DMA channel, |
| 255 | * but one DMA channel may take input from several queues. |
| 256 | * |
Johannes Berg | edc1a3a | 2010-02-24 01:57:19 -0800 | [diff] [blame] | 257 | * Tx DMA FIFOs have dedicated purposes. For 4965, they are used as follows |
Johannes Berg | 6819886 | 2009-11-06 14:52:53 -0800 | [diff] [blame] | 258 | * (cf. default_queue_to_tx_fifo in iwl-4965.c): |
Emmanuel Grumbach | 038669e | 2008-04-23 17:15:04 -0700 | [diff] [blame] | 259 | * |
| 260 | * 0 -- EDCA BK (background) frames, lowest priority |
| 261 | * 1 -- EDCA BE (best effort) frames, normal priority |
| 262 | * 2 -- EDCA VI (video) frames, higher priority |
| 263 | * 3 -- EDCA VO (voice) and management frames, highest priority |
| 264 | * 4 -- Commands (e.g. RXON, etc.) |
Johannes Berg | edc1a3a | 2010-02-24 01:57:19 -0800 | [diff] [blame] | 265 | * 5 -- unused (HCCA) |
| 266 | * 6 -- unused (HCCA) |
Emmanuel Grumbach | 038669e | 2008-04-23 17:15:04 -0700 | [diff] [blame] | 267 | * 7 -- not used by driver (device-internal only) |
| 268 | * |
Johannes Berg | edc1a3a | 2010-02-24 01:57:19 -0800 | [diff] [blame] | 269 | * For 5000 series and up, they are used differently |
Johannes Berg | 6819886 | 2009-11-06 14:52:53 -0800 | [diff] [blame] | 270 | * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c): |
| 271 | * |
| 272 | * 0 -- EDCA BK (background) frames, lowest priority |
| 273 | * 1 -- EDCA BE (best effort) frames, normal priority |
| 274 | * 2 -- EDCA VI (video) frames, higher priority |
| 275 | * 3 -- EDCA VO (voice) and management frames, highest priority |
Johannes Berg | edc1a3a | 2010-02-24 01:57:19 -0800 | [diff] [blame] | 276 | * 4 -- unused |
| 277 | * 5 -- unused |
| 278 | * 6 -- unused |
Johannes Berg | 6819886 | 2009-11-06 14:52:53 -0800 | [diff] [blame] | 279 | * 7 -- Commands |
| 280 | * |
Emmanuel Grumbach | 038669e | 2008-04-23 17:15:04 -0700 | [diff] [blame] | 281 | * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6. |
Johannes Berg | 6819886 | 2009-11-06 14:52:53 -0800 | [diff] [blame] | 282 | * In addition, driver can map the remaining queues to Tx DMA/FIFO |
| 283 | * channels 0-3 to support 11n aggregation via EDCA DMA channels. |
Emmanuel Grumbach | 038669e | 2008-04-23 17:15:04 -0700 | [diff] [blame] | 284 | * |
| 285 | * The driver sets up each queue to work in one of two modes: |
| 286 | * |
| 287 | * 1) Scheduler-Ack, in which the scheduler automatically supports a |
| 288 | * block-ack (BA) window of up to 64 TFDs. In this mode, each queue |
| 289 | * contains TFDs for a unique combination of Recipient Address (RA) |
| 290 | * and Traffic Identifier (TID), that is, traffic of a given |
| 291 | * Quality-Of-Service (QOS) priority, destined for a single station. |
| 292 | * |
| 293 | * In scheduler-ack mode, the scheduler keeps track of the Tx status of |
| 294 | * each frame within the BA window, including whether it's been transmitted, |
| 295 | * and whether it's been acknowledged by the receiving station. The device |
| 296 | * automatically processes block-acks received from the receiving STA, |
| 297 | * and reschedules un-acked frames to be retransmitted (successful |
| 298 | * Tx completion may end up being out-of-order). |
| 299 | * |
| 300 | * The driver must maintain the queue's Byte Count table in host DRAM |
| 301 | * (struct iwl4965_sched_queue_byte_cnt_tbl) for this mode. |
| 302 | * This mode does not support fragmentation. |
| 303 | * |
| 304 | * 2) FIFO (a.k.a. non-Scheduler-ACK), in which each TFD is processed in order. |
| 305 | * The device may automatically retry Tx, but will retry only one frame |
| 306 | * at a time, until receiving ACK from receiving station, or reaching |
| 307 | * retry limit and giving up. |
| 308 | * |
| 309 | * The command queue (#4) must use this mode! |
| 310 | * This mode does not require use of the Byte Count table in host DRAM. |
| 311 | * |
| 312 | * Driver controls scheduler operation via 3 means: |
| 313 | * 1) Scheduler registers |
| 314 | * 2) Shared scheduler data base in internal 4956 SRAM |
| 315 | * 3) Shared data in host DRAM |
| 316 | * |
| 317 | * Initialization: |
| 318 | * |
| 319 | * When loading, driver should allocate memory for: |
| 320 | * 1) 16 TFD circular buffers, each with space for (typically) 256 TFDs. |
| 321 | * 2) 16 Byte Count circular buffers in 16 KBytes contiguous memory |
| 322 | * (1024 bytes for each queue). |
| 323 | * |
| 324 | * After receiving "Alive" response from uCode, driver must initialize |
| 325 | * the scheduler (especially for queue #4, the command queue, otherwise |
| 326 | * the driver can't issue commands!): |
Ben Cahill | e385144 | 2007-11-29 11:10:07 +0800 | [diff] [blame] | 327 | */ |
Emmanuel Grumbach | 67dc320 | 2007-10-25 17:15:38 +0800 | [diff] [blame] | 328 | |
Emmanuel Grumbach | 038669e | 2008-04-23 17:15:04 -0700 | [diff] [blame] | 329 | /** |
| 330 | * Max Tx window size is the max number of contiguous TFDs that the scheduler |
| 331 | * can keep track of at one time when creating block-ack chains of frames. |
| 332 | * Note that "64" matches the number of ack bits in a block-ack packet. |
| 333 | * Driver should use SCD_WIN_SIZE and SCD_FRAME_LIMIT values to initialize |
| 334 | * IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) values. |
| 335 | */ |
| 336 | #define SCD_WIN_SIZE 64 |
| 337 | #define SCD_FRAME_LIMIT 64 |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 338 | |
Emmanuel Grumbach | 038669e | 2008-04-23 17:15:04 -0700 | [diff] [blame] | 339 | /* SCD registers are internal, must be accessed via HBUS_TARG_PRPH regs */ |
| 340 | #define IWL49_SCD_START_OFFSET 0xa02c00 |
| 341 | |
| 342 | /* |
| 343 | * 4965 tells driver SRAM address for internal scheduler structs via this reg. |
| 344 | * Value is valid only after "Alive" response from uCode. |
| 345 | */ |
| 346 | #define IWL49_SCD_SRAM_BASE_ADDR (IWL49_SCD_START_OFFSET + 0x0) |
| 347 | |
| 348 | /* |
| 349 | * Driver may need to update queue-empty bits after changing queue's |
| 350 | * write and read pointers (indexes) during (re-)initialization (i.e. when |
| 351 | * scheduler is not tracking what's happening). |
| 352 | * Bit fields: |
| 353 | * 31-16: Write mask -- 1: update empty bit, 0: don't change empty bit |
| 354 | * 15-00: Empty state, one for each queue -- 1: empty, 0: non-empty |
| 355 | * NOTE: This register is not used by Linux driver. |
| 356 | */ |
| 357 | #define IWL49_SCD_EMPTY_BITS (IWL49_SCD_START_OFFSET + 0x4) |
| 358 | |
| 359 | /* |
| 360 | * Physical base address of array of byte count (BC) circular buffers (CBs). |
| 361 | * Each Tx queue has a BC CB in host DRAM to support Scheduler-ACK mode. |
| 362 | * This register points to BC CB for queue 0, must be on 1024-byte boundary. |
| 363 | * Others are spaced by 1024 bytes. |
| 364 | * Each BC CB is 2 bytes * (256 + 64) = 740 bytes, followed by 384 bytes pad. |
| 365 | * (Index into a queue's BC CB) = (index into queue's TFD CB) = (SSN & 0xff). |
| 366 | * Bit fields: |
| 367 | * 25-00: Byte Count CB physical address [35:10], must be 1024-byte aligned. |
| 368 | */ |
| 369 | #define IWL49_SCD_DRAM_BASE_ADDR (IWL49_SCD_START_OFFSET + 0x10) |
| 370 | |
| 371 | /* |
| 372 | * Enables any/all Tx DMA/FIFO channels. |
| 373 | * Scheduler generates requests for only the active channels. |
| 374 | * Set this to 0xff to enable all 8 channels (normal usage). |
| 375 | * Bit fields: |
| 376 | * 7- 0: Enable (1), disable (0), one bit for each channel 0-7 |
| 377 | */ |
| 378 | #define IWL49_SCD_TXFACT (IWL49_SCD_START_OFFSET + 0x1c) |
Emmanuel Grumbach | 038669e | 2008-04-23 17:15:04 -0700 | [diff] [blame] | 379 | /* |
| 380 | * Queue (x) Write Pointers (indexes, really!), one for each Tx queue. |
| 381 | * Initialized and updated by driver as new TFDs are added to queue. |
| 382 | * NOTE: If using Block Ack, index must correspond to frame's |
| 383 | * Start Sequence Number; index = (SSN & 0xff) |
| 384 | * NOTE: Alternative to HBUS_TARG_WRPTR, which is what Linux driver uses? |
| 385 | */ |
| 386 | #define IWL49_SCD_QUEUE_WRPTR(x) (IWL49_SCD_START_OFFSET + 0x24 + (x) * 4) |
| 387 | |
| 388 | /* |
| 389 | * Queue (x) Read Pointers (indexes, really!), one for each Tx queue. |
| 390 | * For FIFO mode, index indicates next frame to transmit. |
| 391 | * For Scheduler-ACK mode, index indicates first frame in Tx window. |
| 392 | * Initialized by driver, updated by scheduler. |
| 393 | */ |
| 394 | #define IWL49_SCD_QUEUE_RDPTR(x) (IWL49_SCD_START_OFFSET + 0x64 + (x) * 4) |
| 395 | |
| 396 | /* |
| 397 | * Select which queues work in chain mode (1) vs. not (0). |
| 398 | * Use chain mode to build chains of aggregated frames. |
| 399 | * Bit fields: |
| 400 | * 31-16: Reserved |
| 401 | * 15-00: Mode, one bit for each queue -- 1: Chain mode, 0: one-at-a-time |
| 402 | * NOTE: If driver sets up queue for chain mode, it should be also set up |
| 403 | * Scheduler-ACK mode as well, via SCD_QUEUE_STATUS_BITS(x). |
| 404 | */ |
| 405 | #define IWL49_SCD_QUEUECHAIN_SEL (IWL49_SCD_START_OFFSET + 0xd0) |
| 406 | |
| 407 | /* |
| 408 | * Select which queues interrupt driver when scheduler increments |
| 409 | * a queue's read pointer (index). |
| 410 | * Bit fields: |
| 411 | * 31-16: Reserved |
| 412 | * 15-00: Interrupt enable, one bit for each queue -- 1: enabled, 0: disabled |
| 413 | * NOTE: This functionality is apparently a no-op; driver relies on interrupts |
| 414 | * from Rx queue to read Tx command responses and update Tx queues. |
| 415 | */ |
| 416 | #define IWL49_SCD_INTERRUPT_MASK (IWL49_SCD_START_OFFSET + 0xe4) |
| 417 | |
| 418 | /* |
| 419 | * Queue search status registers. One for each queue. |
| 420 | * Sets up queue mode and assigns queue to Tx DMA channel. |
| 421 | * Bit fields: |
| 422 | * 19-10: Write mask/enable bits for bits 0-9 |
| 423 | * 9: Driver should init to "0" |
| 424 | * 8: Scheduler-ACK mode (1), non-Scheduler-ACK (i.e. FIFO) mode (0). |
| 425 | * Driver should init to "1" for aggregation mode, or "0" otherwise. |
| 426 | * 7-6: Driver should init to "0" |
| 427 | * 5: Window Size Left; indicates whether scheduler can request |
| 428 | * another TFD, based on window size, etc. Driver should init |
| 429 | * this bit to "1" for aggregation mode, or "0" for non-agg. |
| 430 | * 4-1: Tx FIFO to use (range 0-7). |
| 431 | * 0: Queue is active (1), not active (0). |
| 432 | * Other bits should be written as "0" |
| 433 | * |
| 434 | * NOTE: If enabling Scheduler-ACK mode, chain mode should also be enabled |
| 435 | * via SCD_QUEUECHAIN_SEL. |
| 436 | */ |
| 437 | #define IWL49_SCD_QUEUE_STATUS_BITS(x)\ |
| 438 | (IWL49_SCD_START_OFFSET + 0x104 + (x) * 4) |
| 439 | |
| 440 | /* Bit field positions */ |
| 441 | #define IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE (0) |
| 442 | #define IWL49_SCD_QUEUE_STTS_REG_POS_TXF (1) |
| 443 | #define IWL49_SCD_QUEUE_STTS_REG_POS_WSL (5) |
| 444 | #define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK (8) |
| 445 | |
| 446 | /* Write masks */ |
| 447 | #define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (10) |
| 448 | #define IWL49_SCD_QUEUE_STTS_REG_MSK (0x0007FC00) |
| 449 | |
| 450 | /** |
| 451 | * 4965 internal SRAM structures for scheduler, shared with driver ... |
| 452 | * |
| 453 | * Driver should clear and initialize the following areas after receiving |
| 454 | * "Alive" response from 4965 uCode, i.e. after initial |
| 455 | * uCode load, or after a uCode load done for error recovery: |
| 456 | * |
| 457 | * SCD_CONTEXT_DATA_OFFSET (size 128 bytes) |
| 458 | * SCD_TX_STTS_BITMAP_OFFSET (size 256 bytes) |
| 459 | * SCD_TRANSLATE_TBL_OFFSET (size 32 bytes) |
| 460 | * |
| 461 | * Driver accesses SRAM via HBUS_TARG_MEM_* registers. |
| 462 | * Driver reads base address of this scheduler area from SCD_SRAM_BASE_ADDR. |
| 463 | * All OFFSET values must be added to this base address. |
| 464 | */ |
| 465 | |
| 466 | /* |
| 467 | * Queue context. One 8-byte entry for each of 16 queues. |
| 468 | * |
| 469 | * Driver should clear this entire area (size 0x80) to 0 after receiving |
| 470 | * "Alive" notification from uCode. Additionally, driver should init |
| 471 | * each queue's entry as follows: |
| 472 | * |
| 473 | * LS Dword bit fields: |
| 474 | * 0-06: Max Tx window size for Scheduler-ACK. Driver should init to 64. |
| 475 | * |
| 476 | * MS Dword bit fields: |
| 477 | * 16-22: Frame limit. Driver should init to 10 (0xa). |
| 478 | * |
| 479 | * Driver should init all other bits to 0. |
| 480 | * |
| 481 | * Init must be done after driver receives "Alive" response from 4965 uCode, |
| 482 | * and when setting up queue for aggregation. |
| 483 | */ |
| 484 | #define IWL49_SCD_CONTEXT_DATA_OFFSET 0x380 |
| 485 | #define IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) \ |
| 486 | (IWL49_SCD_CONTEXT_DATA_OFFSET + ((x) * 8)) |
| 487 | |
| 488 | #define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS (0) |
| 489 | #define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK (0x0000007F) |
| 490 | #define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16) |
| 491 | #define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) |
| 492 | |
| 493 | /* |
| 494 | * Tx Status Bitmap |
| 495 | * |
| 496 | * Driver should clear this entire area (size 0x100) to 0 after receiving |
| 497 | * "Alive" notification from uCode. Area is used only by device itself; |
| 498 | * no other support (besides clearing) is required from driver. |
| 499 | */ |
| 500 | #define IWL49_SCD_TX_STTS_BITMAP_OFFSET 0x400 |
| 501 | |
| 502 | /* |
| 503 | * RAxTID to queue translation mapping. |
| 504 | * |
| 505 | * When queue is in Scheduler-ACK mode, frames placed in a that queue must be |
| 506 | * for only one combination of receiver address (RA) and traffic ID (TID), i.e. |
| 507 | * one QOS priority level destined for one station (for this wireless link, |
| 508 | * not final destination). The SCD_TRANSLATE_TABLE area provides 16 16-bit |
| 509 | * mappings, one for each of the 16 queues. If queue is not in Scheduler-ACK |
| 510 | * mode, the device ignores the mapping value. |
| 511 | * |
| 512 | * Bit fields, for each 16-bit map: |
| 513 | * 15-9: Reserved, set to 0 |
| 514 | * 8-4: Index into device's station table for recipient station |
| 515 | * 3-0: Traffic ID (tid), range 0-15 |
| 516 | * |
| 517 | * Driver should clear this entire area (size 32 bytes) to 0 after receiving |
| 518 | * "Alive" notification from uCode. To update a 16-bit map value, driver |
| 519 | * must read a dword-aligned value from device SRAM, replace the 16-bit map |
| 520 | * value of interest, and write the dword value back into device SRAM. |
| 521 | */ |
| 522 | #define IWL49_SCD_TRANSLATE_TBL_OFFSET 0x500 |
| 523 | |
| 524 | /* Find translation table dword to read/write for given queue */ |
| 525 | #define IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \ |
| 526 | ((IWL49_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc) |
| 527 | |
Tomas Winkler | 30e553e | 2008-05-29 16:35:16 +0800 | [diff] [blame] | 528 | #define IWL_SCD_TXFIFO_POS_TID (0) |
| 529 | #define IWL_SCD_TXFIFO_POS_RA (4) |
| 530 | #define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF) |
Emmanuel Grumbach | 038669e | 2008-04-23 17:15:04 -0700 | [diff] [blame] | 531 | |
Wey-Yi Guy | f4388ad | 2010-04-12 18:32:11 -0700 | [diff] [blame] | 532 | /* agn SCD */ |
| 533 | #define IWLAGN_SCD_QUEUE_STTS_REG_POS_TXF (0) |
| 534 | #define IWLAGN_SCD_QUEUE_STTS_REG_POS_ACTIVE (3) |
| 535 | #define IWLAGN_SCD_QUEUE_STTS_REG_POS_WSL (4) |
| 536 | #define IWLAGN_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (19) |
| 537 | #define IWLAGN_SCD_QUEUE_STTS_REG_MSK (0x00FF0000) |
Ron Rindjunsky | 99da1b4 | 2008-05-15 13:54:13 +0800 | [diff] [blame] | 538 | |
Wey-Yi Guy | f4388ad | 2010-04-12 18:32:11 -0700 | [diff] [blame] | 539 | #define IWLAGN_SCD_QUEUE_CTX_REG1_CREDIT_POS (8) |
| 540 | #define IWLAGN_SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00) |
| 541 | #define IWLAGN_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS (24) |
| 542 | #define IWLAGN_SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK (0xFF000000) |
| 543 | #define IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS (0) |
| 544 | #define IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK (0x0000007F) |
| 545 | #define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16) |
| 546 | #define IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) |
Ron Rindjunsky | 99da1b4 | 2008-05-15 13:54:13 +0800 | [diff] [blame] | 547 | |
Wey-Yi Guy | f4388ad | 2010-04-12 18:32:11 -0700 | [diff] [blame] | 548 | #define IWLAGN_SCD_CONTEXT_DATA_OFFSET (0x600) |
| 549 | #define IWLAGN_SCD_TX_STTS_BITMAP_OFFSET (0x7B1) |
| 550 | #define IWLAGN_SCD_TRANSLATE_TBL_OFFSET (0x7E0) |
Ron Rindjunsky | 99da1b4 | 2008-05-15 13:54:13 +0800 | [diff] [blame] | 551 | |
Wey-Yi Guy | f4388ad | 2010-04-12 18:32:11 -0700 | [diff] [blame] | 552 | #define IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(x)\ |
| 553 | (IWLAGN_SCD_CONTEXT_DATA_OFFSET + ((x) * 8)) |
Ron Rindjunsky | 99da1b4 | 2008-05-15 13:54:13 +0800 | [diff] [blame] | 554 | |
Wey-Yi Guy | f4388ad | 2010-04-12 18:32:11 -0700 | [diff] [blame] | 555 | #define IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \ |
| 556 | ((IWLAGN_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc) |
Ron Rindjunsky | 99da1b4 | 2008-05-15 13:54:13 +0800 | [diff] [blame] | 557 | |
Wey-Yi Guy | f4388ad | 2010-04-12 18:32:11 -0700 | [diff] [blame] | 558 | #define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(x) (((1<<(x)) - 1) &\ |
Ron Rindjunsky | 99da1b4 | 2008-05-15 13:54:13 +0800 | [diff] [blame] | 559 | (~(1<<IWL_CMD_QUEUE_NUM))) |
| 560 | |
Wey-Yi Guy | f4388ad | 2010-04-12 18:32:11 -0700 | [diff] [blame] | 561 | #define IWLAGN_SCD_BASE (PRPH_BASE + 0xa02c00) |
Emmanuel Grumbach | b559e66 | 2007-10-25 17:15:40 +0800 | [diff] [blame] | 562 | |
Wey-Yi Guy | f4388ad | 2010-04-12 18:32:11 -0700 | [diff] [blame] | 563 | #define IWLAGN_SCD_SRAM_BASE_ADDR (IWLAGN_SCD_BASE + 0x0) |
| 564 | #define IWLAGN_SCD_DRAM_BASE_ADDR (IWLAGN_SCD_BASE + 0x8) |
| 565 | #define IWLAGN_SCD_AIT (IWLAGN_SCD_BASE + 0x0c) |
| 566 | #define IWLAGN_SCD_TXFACT (IWLAGN_SCD_BASE + 0x10) |
| 567 | #define IWLAGN_SCD_ACTIVE (IWLAGN_SCD_BASE + 0x14) |
| 568 | #define IWLAGN_SCD_QUEUE_WRPTR(x) (IWLAGN_SCD_BASE + 0x18 + (x) * 4) |
| 569 | #define IWLAGN_SCD_QUEUE_RDPTR(x) (IWLAGN_SCD_BASE + 0x68 + (x) * 4) |
| 570 | #define IWLAGN_SCD_QUEUECHAIN_SEL (IWLAGN_SCD_BASE + 0xe8) |
| 571 | #define IWLAGN_SCD_AGGR_SEL (IWLAGN_SCD_BASE + 0x248) |
| 572 | #define IWLAGN_SCD_INTERRUPT_MASK (IWLAGN_SCD_BASE + 0x108) |
| 573 | #define IWLAGN_SCD_QUEUE_STATUS_BITS(x) (IWLAGN_SCD_BASE + 0x10c + (x) * 4) |
Emmanuel Grumbach | b559e66 | 2007-10-25 17:15:40 +0800 | [diff] [blame] | 574 | |
Emmanuel Grumbach | 038669e | 2008-04-23 17:15:04 -0700 | [diff] [blame] | 575 | /*********************** END TX SCHEDULER *************************************/ |
| 576 | |
Zhu Yi | b481de9 | 2007-09-25 17:54:57 -0700 | [diff] [blame] | 577 | #endif /* __iwl_prph_h__ */ |