iwl-trans-pcie-int.h revision 1daf04b8ac51f911f32aedc77f7f6559924d8ab3
1ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach/****************************************************************************** 2ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * 3ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. 4ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * 5ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * Portions of this file are derived from the ipw3945 project, as well 6ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * as portions of the ieee80211 subsystem header files. 7ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * 8ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * This program is free software; you can redistribute it and/or modify it 9ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * under the terms of version 2 of the GNU General Public License as 10ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * published by the Free Software Foundation. 11ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * 12ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * This program is distributed in the hope that it will be useful, but WITHOUT 13ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * more details. 16ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * 17ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * You should have received a copy of the GNU General Public License along with 18ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * this program; if not, write to the Free Software Foundation, Inc., 19ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 20ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * 21ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * The full GNU General Public License is included in this distribution in the 22ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * file called LICENSE. 23ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * 24ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * Contact Information: 25ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * Intel Linux Wireless <ilw@linux.intel.com> 26ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 27ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * 28ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach *****************************************************************************/ 29ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach#ifndef __iwl_trans_int_pcie_h__ 30ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach#define __iwl_trans_int_pcie_h__ 31ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach 32a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach#include <linux/spinlock.h> 33a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach#include <linux/interrupt.h> 34a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach#include <linux/skbuff.h> 35522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach#include <linux/pci.h> 36a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach 37dda61a4482661d71034cc132d1f474f19ce34a4dEmmanuel Grumbach#include "iwl-fh.h" 38a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach#include "iwl-csr.h" 39a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach#include "iwl-shared.h" 40a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach#include "iwl-trans.h" 41a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach#include "iwl-debug.h" 42a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach#include "iwl-io.h" 43a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach 44a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbachstruct iwl_tx_queue; 45a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbachstruct iwl_queue; 46a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbachstruct iwl_host_cmd; 47dda61a4482661d71034cc132d1f474f19ce34a4dEmmanuel Grumbach 48ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach/*This file includes the declaration that are internal to the 49ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach * trans_pcie layer */ 50ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach 51e6bb4c9c00892c488f3218ea317dc6a71674faf4Emmanuel Grumbach/** 521f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach * struct isr_statistics - interrupt statistics 531f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach * 541f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach */ 551f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbachstruct isr_statistics { 561f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach u32 hw; 571f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach u32 sw; 581f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach u32 err_code; 591f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach u32 sch; 601f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach u32 alive; 611f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach u32 rfkill; 621f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach u32 ctkill; 631f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach u32 wakeup; 641f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach u32 rx; 651f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach u32 tx; 661f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach u32 unhandled; 671f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach}; 681f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach 691f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach/** 705a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * struct iwl_rx_queue - Rx queue 715a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @bd: driver's pointer to buffer of receive buffer descriptors (rbd) 725a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @bd_dma: bus address of buffer of receive buffer descriptors (rbd) 735a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @pool: 745a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @queue: 755a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @read: Shared index to newest available Rx buffer 765a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @write: Shared index to oldest written Rx packet 775a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @free_count: Number of pre-allocated buffers in rx_free 785a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @write_actual: 795a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @rx_free: list of free SKBs for use 805a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @rx_used: List of Rx buffers with no SKB 815a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @need_update: flag to indicate we need to update read/write index 825a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @rb_stts: driver's pointer to receive buffer status 835a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @rb_stts_dma: bus address of receive buffer status 845a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @lock: 855a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * 865a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers 875a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach */ 885a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbachstruct iwl_rx_queue { 895a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach __le32 *bd; 905a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach dma_addr_t bd_dma; 915a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; 925a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE]; 935a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach u32 read; 945a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach u32 write; 955a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach u32 free_count; 965a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach u32 write_actual; 975a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach struct list_head rx_free; 985a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach struct list_head rx_used; 995a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach int need_update; 1005a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach struct iwl_rb_status *rb_stts; 1015a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach dma_addr_t rb_stts_dma; 1025a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach spinlock_t lock; 1035a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach}; 1045a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach 105a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbachstruct iwl_dma_ptr { 106a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach dma_addr_t dma; 107a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach void *addr; 108a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach size_t size; 109a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach}; 110a72b8b088c3465b28192c1a14ba97be8223a8cecEmmanuel Grumbach 111e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach/* 112e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach * This queue number is required for proper operation 113e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach * because the ucode will stop/start the scheduler as 114e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach * required. 115e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach */ 116e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach#define IWL_IPAN_MCAST_QUEUE 8 117e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach 118522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbachstruct iwl_cmd_meta { 119522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach /* only for SYNC commands, iff the reply skb is wanted */ 120522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach struct iwl_host_cmd *source; 121522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach 122522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach u32 flags; 123522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach 124522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach DEFINE_DMA_UNMAP_ADDR(mapping); 125522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach DEFINE_DMA_UNMAP_LEN(len); 126522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach}; 127522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach 128522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach/* 129522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * Generic queue structure 130522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * 131522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * Contains common data for Rx and Tx queues. 132522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * 133522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * Note the difference between n_bd and n_window: the hardware 134522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * always assumes 256 descriptors, so n_bd is always 256 (unless 135522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * there might be HW changes in the future). For the normal TX 136522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * queues, n_window, which is the size of the software queue data 137522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * is also 256; however, for the command queue, n_window is only 138522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * 32 since we don't need so many commands pending. Since the HW 139522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * still uses 256 BDs for DMA though, n_bd stays 256. As a result, 140522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * the software buffers (in the variables @meta, @txb in struct 141522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * iwl_tx_queue) only have 32 entries, while the HW buffers (@tfds 142522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * in the same struct) have 256. 143522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * This means that we end up with the following: 144522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 | 145522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * SW entries: | 0 | ... | 31 | 146522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * where N is a number between 0 and 7. This means that the SW 147522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * data is a window overlayed over the HW queue. 148522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach */ 149522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbachstruct iwl_queue { 150522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach int n_bd; /* number of BDs in this queue */ 151522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach int write_ptr; /* 1-st empty entry (index) host_w*/ 152522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach int read_ptr; /* last used entry (index) host_r*/ 153522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach /* use for monitoring and recovering the stuck queue */ 154522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach dma_addr_t dma_addr; /* physical addr for BD's */ 155522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach int n_window; /* safe queue window */ 156522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach u32 id; 157522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach int low_mark; /* low watermark, resume queue if free 158522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * space more than this */ 159522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach int high_mark; /* high watermark, stop queue if free 160522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * space less than this */ 161522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach}; 162522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach 163522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach/** 164522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * struct iwl_tx_queue - Tx Queue for DMA 165522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * @q: generic Rx/Tx queue descriptor 166522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * @bd: base of circular buffer of TFDs 167522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * @cmd: array of command/TX buffer pointers 168522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * @meta: array of meta data for each command/tx buffer 169522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * @dma_addr_cmd: physical address of cmd/tx buffer array 170522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * @txb: array of per-TFD driver data 171522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * @time_stamp: time (in jiffies) of last read_ptr change 172522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * @need_update: indicates need to update read/write index 173522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled 174522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * @sta_id: valid if sched_retry is set 175522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * @tid: valid if sched_retry is set 176522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * 177522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame 178522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach * descriptors) and required locking structures. 179522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach */ 180522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach#define TFD_TX_CMD_SLOTS 256 181522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach#define TFD_CMD_SLOTS 32 182522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach 183522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbachstruct iwl_tx_queue { 184522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach struct iwl_queue q; 185522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach struct iwl_tfd *tfds; 186522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach struct iwl_device_cmd **cmd; 187522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach struct iwl_cmd_meta *meta; 188522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach struct sk_buff **skbs; 189522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach unsigned long time_stamp; 190522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach u8 need_update; 191522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach u8 sched_retry; 192522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach u8 active; 193522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach u8 swq_id; 194522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach 195522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach u16 sta_id; 196522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach u16 tid; 197522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach}; 198522376d206da66cecc90929134ad70c0446e874bEmmanuel Grumbach 1995a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach/** 200e6bb4c9c00892c488f3218ea317dc6a71674faf4Emmanuel Grumbach * struct iwl_trans_pcie - PCIe transport specific data 2015a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @rxq: all the RX queue data 2025a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @rx_replenish: work that will be called when buffers need to be allocated 2035a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach * @trans: pointer to the generic transport area 204105183b156b7c220b47c3162e087101a0a6abc9fEmmanuel Grumbach * @scd_base_addr: scheduler sram base address in SRAM 205105183b156b7c220b47c3162e087101a0a6abc9fEmmanuel Grumbach * @scd_bc_tbls: pointer to the byte count table of the scheduler 2069d6b2cb1ccf9c1e00a0891eff78b93eb1a1fc372Emmanuel Grumbach * @kw: keep warm address 207e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach * @ac_to_fifo: to what fifo is a specifc AC mapped ? 208e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach * @ac_to_queue: to what tx queue is a specifc AC mapped ? 209e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach * @mcast_queue: 2108ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach * @txq: Tx DMA processing queues 2118ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach * @txq_ctx_active_msk: what queue is active 2128ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach * queue_stopped: tracks what queue is stopped 2138ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach * queue_stop_count: tracks what SW queue is stopped 214e6bb4c9c00892c488f3218ea317dc6a71674faf4Emmanuel Grumbach */ 215e6bb4c9c00892c488f3218ea317dc6a71674faf4Emmanuel Grumbachstruct iwl_trans_pcie { 2165a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach struct iwl_rx_queue rxq; 2175a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach struct work_struct rx_replenish; 2185a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach struct iwl_trans *trans; 2190c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach 2200c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach /* INT ICT Table */ 2210c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach __le32 *ict_tbl; 2220c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach void *ict_tbl_vir; 2230c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach dma_addr_t ict_tbl_dma; 2240c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach dma_addr_t aligned_ict_tbl_dma; 2250c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach int ict_index; 2260c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach u32 inta; 2270c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach bool use_ict; 2280c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach struct tasklet_struct irq_tasklet; 2291f7b6172db86e9ab2b4cd794441bb2c40ab287fcEmmanuel Grumbach struct isr_statistics isr_stats; 2300c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach 2310c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach u32 inta_mask; 232105183b156b7c220b47c3162e087101a0a6abc9fEmmanuel Grumbach u32 scd_base_addr; 233105183b156b7c220b47c3162e087101a0a6abc9fEmmanuel Grumbach struct iwl_dma_ptr scd_bc_tbls; 2349d6b2cb1ccf9c1e00a0891eff78b93eb1a1fc372Emmanuel Grumbach struct iwl_dma_ptr kw; 235e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach 236e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach const u8 *ac_to_fifo[NUM_IWL_RXON_CTX]; 237e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach const u8 *ac_to_queue[NUM_IWL_RXON_CTX]; 238e13c0c59e0ec38558ac853d56555e915b4dc7dc2Emmanuel Grumbach u8 mcast_queue[NUM_IWL_RXON_CTX]; 2398ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach 2408ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach struct iwl_tx_queue *txq; 2418ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach unsigned long txq_ctx_active_msk; 2428ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach#define IWL_MAX_HW_QUEUES 32 2438ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; 2448ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach atomic_t queue_stop_count[4]; 245e6bb4c9c00892c488f3218ea317dc6a71674faf4Emmanuel Grumbach}; 246e6bb4c9c00892c488f3218ea317dc6a71674faf4Emmanuel Grumbach 2475a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ 2485a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach ((struct iwl_trans_pcie *) ((_iwl_trans)->trans_specific)) 2495a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbach 250253a634ccd1b291282cd0cade219bd90eb0371ebEmmanuel Grumbach/***************************************************** 251253a634ccd1b291282cd0cade219bd90eb0371ebEmmanuel Grumbach* RX 252253a634ccd1b291282cd0cade219bd90eb0371ebEmmanuel Grumbach******************************************************/ 253ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbachvoid iwl_bg_rx_replenish(struct work_struct *data); 2540c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbachvoid iwl_irq_tasklet(struct iwl_trans *trans); 2555a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbachvoid iwlagn_rx_replenish(struct iwl_trans *trans); 2565a878bf60b2bb1f1509f49b8b1784e3c9f204c64Emmanuel Grumbachvoid iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, 257ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach struct iwl_rx_queue *q); 258ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach 259253a634ccd1b291282cd0cade219bd90eb0371ebEmmanuel Grumbach/***************************************************** 2601a361cd838173879672cb0f0ebe1e7654d7edff6Emmanuel Grumbach* ICT 2611a361cd838173879672cb0f0ebe1e7654d7edff6Emmanuel Grumbach******************************************************/ 2626bb7884758965ad0afd67801f0f41cefd53d0b0cEmmanuel Grumbachint iwl_reset_ict(struct iwl_trans *trans); 2630c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbachvoid iwl_disable_ict(struct iwl_trans *trans); 2640c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbachint iwl_alloc_isr_ict(struct iwl_trans *trans); 2650c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbachvoid iwl_free_isr_ict(struct iwl_trans *trans); 2661a361cd838173879672cb0f0ebe1e7654d7edff6Emmanuel Grumbachirqreturn_t iwl_isr_ict(int irq, void *data); 2671a361cd838173879672cb0f0ebe1e7654d7edff6Emmanuel Grumbach 2681a361cd838173879672cb0f0ebe1e7654d7edff6Emmanuel Grumbach/***************************************************** 269253a634ccd1b291282cd0cade219bd90eb0371ebEmmanuel Grumbach* TX / HCMD 270253a634ccd1b291282cd0cade219bd90eb0371ebEmmanuel Grumbach******************************************************/ 271fd656935cd05f522d7db97386633f6a0d7751218Emmanuel Grumbachvoid iwl_txq_update_write_ptr(struct iwl_trans *trans, 272fd656935cd05f522d7db97386633f6a0d7751218Emmanuel Grumbach struct iwl_tx_queue *txq); 2736d8f6eeb350696050a1f5cf8f9d0daabab68eaf5Emmanuel Grumbachint iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, 274253a634ccd1b291282cd0cade219bd90eb0371ebEmmanuel Grumbach struct iwl_tx_queue *txq, 275253a634ccd1b291282cd0cade219bd90eb0371ebEmmanuel Grumbach dma_addr_t addr, u16 len, u8 reset); 2766d8f6eeb350696050a1f5cf8f9d0daabab68eaf5Emmanuel Grumbachint iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id); 2776d8f6eeb350696050a1f5cf8f9d0daabab68eaf5Emmanuel Grumbachint iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); 2783e10caeb55b2693b38f1f80c67c79d918fc42e42Emmanuel Grumbachvoid iwl_tx_cmd_complete(struct iwl_trans *trans, 279247c61d625154e18a105d663281c52376a882762Emmanuel Grumbach struct iwl_rx_mem_buffer *rxb, int handler_status); 2806d8f6eeb350696050a1f5cf8f9d0daabab68eaf5Emmanuel Grumbachvoid iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, 28148d42c426947d8ffba0caa3cf9c58be6903302e0Emmanuel Grumbach struct iwl_tx_queue *txq, 28248d42c426947d8ffba0caa3cf9c58be6903302e0Emmanuel Grumbach u16 byte_cnt); 2837f01d567c5b9e136d9b070e00be88169d5b2227eEmmanuel Grumbachvoid iwl_trans_pcie_txq_agg_disable(struct iwl_trans *trans, int txq_id); 2847f01d567c5b9e136d9b070e00be88169d5b2227eEmmanuel Grumbachint iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, 2857f01d567c5b9e136d9b070e00be88169d5b2227eEmmanuel Grumbach enum iwl_rxon_context_id ctx, int sta_id, 2867f01d567c5b9e136d9b070e00be88169d5b2227eEmmanuel Grumbach int tid); 2876d8f6eeb350696050a1f5cf8f9d0daabab68eaf5Emmanuel Grumbachvoid iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index); 288c91bd12489f50809af94c46d7c4c4d98b70c6f47Emmanuel Grumbachvoid iwl_trans_tx_queue_set_status(struct iwl_trans *trans, 28948d42c426947d8ffba0caa3cf9c58be6903302e0Emmanuel Grumbach struct iwl_tx_queue *txq, 29048d42c426947d8ffba0caa3cf9c58be6903302e0Emmanuel Grumbach int tx_fifo_id, int scd_retry); 291288712a6ccf47b9df104f800616f6659ecadc940Emmanuel Grumbachint iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans, 292288712a6ccf47b9df104f800616f6659ecadc940Emmanuel Grumbach enum iwl_rxon_context_id ctx, int sta_id, 293288712a6ccf47b9df104f800616f6659ecadc940Emmanuel Grumbach int tid, u16 *ssn); 294c91bd12489f50809af94c46d7c4c4d98b70c6f47Emmanuel Grumbachvoid iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, 295c91bd12489f50809af94c46d7c4c4d98b70c6f47Emmanuel Grumbach enum iwl_rxon_context_id ctx, 296c91bd12489f50809af94c46d7c4c4d98b70c6f47Emmanuel Grumbach int sta_id, int tid, int frame_limit); 2976d8f6eeb350696050a1f5cf8f9d0daabab68eaf5Emmanuel Grumbachvoid iwlagn_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, 29839644e9ac5329dc92d9547976c8f30f18da90097Emmanuel Grumbach int index, enum dma_data_direction dma_dir); 299464021ffc1c080283e67729d966d76612728a08cEmmanuel Grumbachint iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, 300464021ffc1c080283e67729d966d76612728a08cEmmanuel Grumbach struct sk_buff_head *skbs); 3018ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbachint iwl_queue_space(const struct iwl_queue *q); 302253a634ccd1b291282cd0cade219bd90eb0371ebEmmanuel Grumbach 3037ff94706a055f3e21710b08ffbe3979d7db615dbEmmanuel Grumbach/***************************************************** 3047ff94706a055f3e21710b08ffbe3979d7db615dbEmmanuel Grumbach* Error handling 3057ff94706a055f3e21710b08ffbe3979d7db615dbEmmanuel Grumbach******************************************************/ 3066bb7884758965ad0afd67801f0f41cefd53d0b0cEmmanuel Grumbachint iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, 3076bb7884758965ad0afd67801f0f41cefd53d0b0cEmmanuel Grumbach char **buf, bool display); 30816db88ba51d669ef63c58990771a47208913152cEmmanuel Grumbachint iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display); 30916db88ba51d669ef63c58990771a47208913152cEmmanuel Grumbachvoid iwl_dump_csr(struct iwl_trans *trans); 31016db88ba51d669ef63c58990771a47208913152cEmmanuel Grumbach 3118ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach/***************************************************** 3128ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach* Helpers 3138ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach******************************************************/ 3140c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbachstatic inline void iwl_disable_interrupts(struct iwl_trans *trans) 3150c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach{ 3160c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach clear_bit(STATUS_INT_ENABLED, &trans->shrd->status); 3170c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach 3180c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach /* disable interrupts from uCode/NIC to host */ 31983ed90155f98bd949735c2cc22d832b557a6d7d1Emmanuel Grumbach iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000); 3200c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach 3210c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach /* acknowledge/clear/reset any interrupts still pending 3220c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach * from uCode or flow handler (Rx/Tx DMA) */ 32383ed90155f98bd949735c2cc22d832b557a6d7d1Emmanuel Grumbach iwl_write32(bus(trans), CSR_INT, 0xffffffff); 32483ed90155f98bd949735c2cc22d832b557a6d7d1Emmanuel Grumbach iwl_write32(bus(trans), CSR_FH_INT_STATUS, 0xffffffff); 3250c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach IWL_DEBUG_ISR(trans, "Disabled interrupts\n"); 3260c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach} 3270c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach 3280c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbachstatic inline void iwl_enable_interrupts(struct iwl_trans *trans) 3290c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach{ 3300c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach struct iwl_trans_pcie *trans_pcie = 3310c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach IWL_TRANS_GET_PCIE_TRANS(trans); 3320c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach 3330c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); 3340c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach set_bit(STATUS_INT_ENABLED, &trans->shrd->status); 33583ed90155f98bd949735c2cc22d832b557a6d7d1Emmanuel Grumbach iwl_write32(bus(trans), CSR_INT_MASK, trans_pcie->inta_mask); 3360c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach} 3370c325769a394559941acda83e888a1d9b1ef8b7fEmmanuel Grumbach 338e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach/* 339e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach * we have 8 bits used like this: 340e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach * 341e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach * 7 6 5 4 3 2 1 0 342e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach * | | | | | | | | 343e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach * | | | | | | +-+-------- AC queue (0-3) 344e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach * | | | | | | 345e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach * | +-+-+-+-+------------ HW queue ID 346e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach * | 347e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach * +---------------------- unused 348e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach */ 349e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbachstatic inline void iwl_set_swq_id(struct iwl_tx_queue *txq, u8 ac, u8 hwq) 350e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach{ 351e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach BUG_ON(ac > 3); /* only have 2 bits */ 352e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach BUG_ON(hwq > 31); /* only use 5 bits */ 353e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach 354e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach txq->swq_id = (hwq << 2) | ac; 355e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach} 356e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach 3571daf04b8ac51f911f32aedc77f7f6559924d8ab3Emmanuel Grumbachstatic inline u8 iwl_get_queue_ac(struct iwl_tx_queue *txq) 3581daf04b8ac51f911f32aedc77f7f6559924d8ab3Emmanuel Grumbach{ 3591daf04b8ac51f911f32aedc77f7f6559924d8ab3Emmanuel Grumbach return txq->swq_id & 0x3; 3601daf04b8ac51f911f32aedc77f7f6559924d8ab3Emmanuel Grumbach} 3611daf04b8ac51f911f32aedc77f7f6559924d8ab3Emmanuel Grumbach 362e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbachstatic inline void iwl_wake_queue(struct iwl_trans *trans, 36381a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach struct iwl_tx_queue *txq, const char *msg) 364e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach{ 365e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach u8 queue = txq->swq_id; 366e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach u8 ac = queue & 3; 367e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach u8 hwq = (queue >> 2) & 0x1f; 3688ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach struct iwl_trans_pcie *trans_pcie = 3698ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach IWL_TRANS_GET_PCIE_TRANS(trans); 370e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach 37181a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach if (test_and_clear_bit(hwq, trans_pcie->queue_stopped)) { 37281a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach if (atomic_dec_return(&trans_pcie->queue_stop_count[ac]) <= 0) { 373859cfb0a99369cf51dc2125ebc3476382a15c322Emmanuel Grumbach iwl_wake_sw_queue(priv(trans), ac); 37481a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach IWL_DEBUG_TX_QUEUES(trans, "Wake hwq %d ac %d. %s", 37581a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach hwq, ac, msg); 37681a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach } else { 37781a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach IWL_DEBUG_TX_QUEUES(trans, "Don't wake hwq %d ac %d" 37881a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach " stop count %d. %s", 37981a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach hwq, ac, atomic_read(&trans_pcie-> 38081a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach queue_stop_count[ac]), msg); 38181a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach } 38281a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach } 383e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach} 384e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach 385e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbachstatic inline void iwl_stop_queue(struct iwl_trans *trans, 38681a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach struct iwl_tx_queue *txq, const char *msg) 387e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach{ 388e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach u8 queue = txq->swq_id; 389e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach u8 ac = queue & 3; 390e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach u8 hwq = (queue >> 2) & 0x1f; 3918ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach struct iwl_trans_pcie *trans_pcie = 3928ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach IWL_TRANS_GET_PCIE_TRANS(trans); 393e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach 39481a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach if (!test_and_set_bit(hwq, trans_pcie->queue_stopped)) { 39581a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach if (atomic_inc_return(&trans_pcie->queue_stop_count[ac]) > 0) { 396859cfb0a99369cf51dc2125ebc3476382a15c322Emmanuel Grumbach iwl_stop_sw_queue(priv(trans), ac); 39781a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach IWL_DEBUG_TX_QUEUES(trans, "Stop hwq %d ac %d" 39881a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach " stop count %d. %s", 39981a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach hwq, ac, atomic_read(&trans_pcie-> 40081a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach queue_stop_count[ac]), msg); 40181a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach } else { 40281a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach IWL_DEBUG_TX_QUEUES(trans, "Don't stop hwq %d ac %d" 40381a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach " stop count %d. %s", 40481a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach hwq, ac, atomic_read(&trans_pcie-> 40581a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach queue_stop_count[ac]), msg); 40681a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach } 40781a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach } else { 40881a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach IWL_DEBUG_TX_QUEUES(trans, "stop hwq %d, but it is stopped/ %s", 40981a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach hwq, msg); 41081a3de1ce2929fef2b112c048c50bc52b686f94dEmmanuel Grumbach } 411e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach} 412e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach 413e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach#ifdef ieee80211_stop_queue 414e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach#undef ieee80211_stop_queue 415e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach#endif 416e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach 417e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue 418e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach 419e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach#ifdef ieee80211_wake_queue 420e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach#undef ieee80211_wake_queue 421e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach#endif 422e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach 423e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue 424e20d434170c3a7f388d5e916825499c9c0738606Emmanuel Grumbach 4258ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbachstatic inline void iwl_txq_ctx_activate(struct iwl_trans_pcie *trans_pcie, 4268ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach int txq_id) 4278ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach{ 4288ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach set_bit(txq_id, &trans_pcie->txq_ctx_active_msk); 4298ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach} 4308ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach 4318ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbachstatic inline void iwl_txq_ctx_deactivate(struct iwl_trans_pcie *trans_pcie, 4328ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach int txq_id) 4338ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach{ 4348ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach clear_bit(txq_id, &trans_pcie->txq_ctx_active_msk); 4358ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach} 4368ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach 4378ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbachstatic inline int iwl_queue_used(const struct iwl_queue *q, int i) 4388ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach{ 4398ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach return q->write_ptr >= q->read_ptr ? 4408ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach (i >= q->read_ptr && i < q->write_ptr) : 4418ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach !(i < q->read_ptr && i >= q->write_ptr); 4428ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach} 4438ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach 4448ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbachstatic inline u8 get_cmd_index(struct iwl_queue *q, u32 index) 4458ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach{ 4468ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach return index & (q->n_window - 1); 4478ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach} 4488ad71bef4a9d8173cbcfbb2f796b08d33d4ca01bEmmanuel Grumbach 4497a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach#define IWL_TX_FIFO_BK 0 /* shared */ 4507a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach#define IWL_TX_FIFO_BE 1 4517a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach#define IWL_TX_FIFO_VI 2 /* shared */ 4527a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach#define IWL_TX_FIFO_VO 3 4537a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach#define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK 4547a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach#define IWL_TX_FIFO_BE_IPAN 4 4557a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI 4567a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach#define IWL_TX_FIFO_VO_IPAN 5 4577a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach/* re-uses the VO FIFO, uCode will properly flush/schedule */ 4587a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach#define IWL_TX_FIFO_AUX 5 4597a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach#define IWL_TX_FIFO_UNUSED -1 4607a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach 4617a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach/* AUX (TX during scan dwell) queue */ 4627a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach#define IWL_AUX_QUEUE 10 4637a10e3e4076d09779da5a02b0ab6ce551d964d48Emmanuel Grumbach 464ab697a9f1e73ba817955e15bd899a8a0627f9fd6Emmanuel Grumbach#endif /* __iwl_trans_int_pcie_h__ */ 465