diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2011-07-11 10:35:34 -0400 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2011-07-16 10:38:46 -0400 |
commit | ab697a9f1e73ba817955e15bd899a8a0627f9fd6 (patch) | |
tree | 238ec4488413f008da43ee9914484500f81df60f /drivers/net/wireless/iwlwifi/iwl-rx.c | |
parent | 4caab328eeea02b244765c355f9d875f8f5f6093 (diff) |
iwlagn: move rx transport functions to iwl-trans-rx-pcie.c
Also create a new file: iwl-trans-int-pcie.h which will include
the non static functions that are shared among the current pcie transport layer.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-rx.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rx.c | 136 |
1 files changed, 0 insertions, 136 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index bd63b785f68..05fd75fb59a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -41,142 +41,6 @@ | |||
41 | #include "iwl-agn-calib.h" | 41 | #include "iwl-agn-calib.h" |
42 | #include "iwl-agn.h" | 42 | #include "iwl-agn.h" |
43 | 43 | ||
44 | /****************************************************************************** | ||
45 | * | ||
46 | * RX path functions | ||
47 | * | ||
48 | ******************************************************************************/ | ||
49 | |||
50 | /* | ||
51 | * Rx theory of operation | ||
52 | * | ||
53 | * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs), | ||
54 | * each of which point to Receive Buffers to be filled by the NIC. These get | ||
55 | * used not only for Rx frames, but for any command response or notification | ||
56 | * from the NIC. The driver and NIC manage the Rx buffers by means | ||
57 | * of indexes into the circular buffer. | ||
58 | * | ||
59 | * Rx Queue Indexes | ||
60 | * The host/firmware share two index registers for managing the Rx buffers. | ||
61 | * | ||
62 | * The READ index maps to the first position that the firmware may be writing | ||
63 | * to -- the driver can read up to (but not including) this position and get | ||
64 | * good data. | ||
65 | * The READ index is managed by the firmware once the card is enabled. | ||
66 | * | ||
67 | * The WRITE index maps to the last position the driver has read from -- the | ||
68 | * position preceding WRITE is the last slot the firmware can place a packet. | ||
69 | * | ||
70 | * The queue is empty (no good data) if WRITE = READ - 1, and is full if | ||
71 | * WRITE = READ. | ||
72 | * | ||
73 | * During initialization, the host sets up the READ queue position to the first | ||
74 | * INDEX position, and WRITE to the last (READ - 1 wrapped) | ||
75 | * | ||
76 | * When the firmware places a packet in a buffer, it will advance the READ index | ||
77 | * and fire the RX interrupt. The driver can then query the READ index and | ||
78 | * process as many packets as possible, moving the WRITE index forward as it | ||
79 | * resets the Rx queue buffers with new memory. | ||
80 | * | ||
81 | * The management in the driver is as follows: | ||
82 | * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When | ||
83 | * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled | ||
84 | * to replenish the iwl->rxq->rx_free. | ||
85 | * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the | ||
86 | * iwl->rxq is replenished and the READ INDEX is updated (updating the | ||
87 | * 'processed' and 'read' driver indexes as well) | ||
88 | * + A received packet is processed and handed to the kernel network stack, | ||
89 | * detached from the iwl->rxq. The driver 'processed' index is updated. | ||
90 | * + The Host/Firmware iwl->rxq is replenished at tasklet time from the rx_free | ||
91 | * list. If there are no allocated buffers in iwl->rxq->rx_free, the READ | ||
92 | * INDEX is not incremented and iwl->status(RX_STALLED) is set. If there | ||
93 | * were enough free buffers and RX_STALLED is set it is cleared. | ||
94 | * | ||
95 | * | ||
96 | * Driver sequence: | ||
97 | * | ||
98 | * iwl_rx_queue_alloc() Allocates rx_free | ||
99 | * iwl_rx_replenish() Replenishes rx_free list from rx_used, and calls | ||
100 | * iwl_rx_queue_restock | ||
101 | * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx | ||
102 | * queue, updates firmware pointers, and updates | ||
103 | * the WRITE index. If insufficient rx_free buffers | ||
104 | * are available, schedules iwl_rx_replenish | ||
105 | * | ||
106 | * -- enable interrupts -- | ||
107 | * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the | ||
108 | * READ INDEX, detaching the SKB from the pool. | ||
109 | * Moves the packet buffer from queue to rx_used. | ||
110 | * Calls iwl_rx_queue_restock to refill any empty | ||
111 | * slots. | ||
112 | * ... | ||
113 | * | ||
114 | */ | ||
115 | |||
116 | /** | ||
117 | * iwl_rx_queue_space - Return number of free slots available in queue. | ||
118 | */ | ||
119 | int iwl_rx_queue_space(const struct iwl_rx_queue *q) | ||
120 | { | ||
121 | int s = q->read - q->write; | ||
122 | if (s <= 0) | ||
123 | s += RX_QUEUE_SIZE; | ||
124 | /* keep some buffer to not confuse full and empty queue */ | ||
125 | s -= 2; | ||
126 | if (s < 0) | ||
127 | s = 0; | ||
128 | return s; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue | ||
133 | */ | ||
134 | void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) | ||
135 | { | ||
136 | unsigned long flags; | ||
137 | u32 reg; | ||
138 | |||
139 | spin_lock_irqsave(&q->lock, flags); | ||
140 | |||
141 | if (q->need_update == 0) | ||
142 | goto exit_unlock; | ||
143 | |||
144 | if (priv->cfg->base_params->shadow_reg_enable) { | ||
145 | /* shadow register enabled */ | ||
146 | /* Device expects a multiple of 8 */ | ||
147 | q->write_actual = (q->write & ~0x7); | ||
148 | iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write_actual); | ||
149 | } else { | ||
150 | /* If power-saving is in use, make sure device is awake */ | ||
151 | if (test_bit(STATUS_POWER_PMI, &priv->status)) { | ||
152 | reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); | ||
153 | |||
154 | if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { | ||
155 | IWL_DEBUG_INFO(priv, | ||
156 | "Rx queue requesting wakeup," | ||
157 | " GP1 = 0x%x\n", reg); | ||
158 | iwl_set_bit(priv, CSR_GP_CNTRL, | ||
159 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||
160 | goto exit_unlock; | ||
161 | } | ||
162 | |||
163 | q->write_actual = (q->write & ~0x7); | ||
164 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, | ||
165 | q->write_actual); | ||
166 | |||
167 | /* Else device is assumed to be awake */ | ||
168 | } else { | ||
169 | /* Device expects a multiple of 8 */ | ||
170 | q->write_actual = (q->write & ~0x7); | ||
171 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, | ||
172 | q->write_actual); | ||
173 | } | ||
174 | } | ||
175 | q->need_update = 0; | ||
176 | |||
177 | exit_unlock: | ||
178 | spin_unlock_irqrestore(&q->lock, flags); | ||
179 | } | ||
180 | 44 | ||
181 | /****************************************************************************** | 45 | /****************************************************************************** |
182 | * | 46 | * |