diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 177 |
1 files changed, 5 insertions, 172 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index ad45249454f0..8d06cf1a3193 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -207,173 +207,6 @@ static inline u8 get_cmd_index(struct iwl4965_queue *q, u32 index, int is_huge) | |||
207 | return index & (q->n_window - 1); | 207 | return index & (q->n_window - 1); |
208 | } | 208 | } |
209 | 209 | ||
210 | /** | ||
211 | * iwl4965_queue_init - Initialize queue's high/low-water and read/write indexes | ||
212 | */ | ||
213 | static int iwl4965_queue_init(struct iwl_priv *priv, struct iwl4965_queue *q, | ||
214 | int count, int slots_num, u32 id) | ||
215 | { | ||
216 | q->n_bd = count; | ||
217 | q->n_window = slots_num; | ||
218 | q->id = id; | ||
219 | |||
220 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap | ||
221 | * and iwl_queue_dec_wrap are broken. */ | ||
222 | BUG_ON(!is_power_of_2(count)); | ||
223 | |||
224 | /* slots_num must be power-of-two size, otherwise | ||
225 | * get_cmd_index is broken. */ | ||
226 | BUG_ON(!is_power_of_2(slots_num)); | ||
227 | |||
228 | q->low_mark = q->n_window / 4; | ||
229 | if (q->low_mark < 4) | ||
230 | q->low_mark = 4; | ||
231 | |||
232 | q->high_mark = q->n_window / 8; | ||
233 | if (q->high_mark < 2) | ||
234 | q->high_mark = 2; | ||
235 | |||
236 | q->write_ptr = q->read_ptr = 0; | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * iwl4965_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue | ||
243 | */ | ||
244 | static int iwl4965_tx_queue_alloc(struct iwl_priv *priv, | ||
245 | struct iwl4965_tx_queue *txq, u32 id) | ||
246 | { | ||
247 | struct pci_dev *dev = priv->pci_dev; | ||
248 | |||
249 | /* Driver private data, only for Tx (not command) queues, | ||
250 | * not shared with device. */ | ||
251 | if (id != IWL_CMD_QUEUE_NUM) { | ||
252 | txq->txb = kmalloc(sizeof(txq->txb[0]) * | ||
253 | TFD_QUEUE_SIZE_MAX, GFP_KERNEL); | ||
254 | if (!txq->txb) { | ||
255 | IWL_ERROR("kmalloc for auxiliary BD " | ||
256 | "structures failed\n"); | ||
257 | goto error; | ||
258 | } | ||
259 | } else | ||
260 | txq->txb = NULL; | ||
261 | |||
262 | /* Circular buffer of transmit frame descriptors (TFDs), | ||
263 | * shared with device */ | ||
264 | txq->bd = pci_alloc_consistent(dev, | ||
265 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, | ||
266 | &txq->q.dma_addr); | ||
267 | |||
268 | if (!txq->bd) { | ||
269 | IWL_ERROR("pci_alloc_consistent(%zd) failed\n", | ||
270 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX); | ||
271 | goto error; | ||
272 | } | ||
273 | txq->q.id = id; | ||
274 | |||
275 | return 0; | ||
276 | |||
277 | error: | ||
278 | if (txq->txb) { | ||
279 | kfree(txq->txb); | ||
280 | txq->txb = NULL; | ||
281 | } | ||
282 | |||
283 | return -ENOMEM; | ||
284 | } | ||
285 | |||
286 | /** | ||
287 | * iwl4965_tx_queue_init - Allocate and initialize one tx/cmd queue | ||
288 | */ | ||
289 | int iwl4965_tx_queue_init(struct iwl_priv *priv, | ||
290 | struct iwl4965_tx_queue *txq, int slots_num, u32 txq_id) | ||
291 | { | ||
292 | struct pci_dev *dev = priv->pci_dev; | ||
293 | int len; | ||
294 | int rc = 0; | ||
295 | |||
296 | /* | ||
297 | * Alloc buffer array for commands (Tx or other types of commands). | ||
298 | * For the command queue (#4), allocate command space + one big | ||
299 | * command for scan, since scan command is very huge; the system will | ||
300 | * not have two scans at the same time, so only one is needed. | ||
301 | * For normal Tx queues (all other queues), no super-size command | ||
302 | * space is needed. | ||
303 | */ | ||
304 | len = sizeof(struct iwl_cmd) * slots_num; | ||
305 | if (txq_id == IWL_CMD_QUEUE_NUM) | ||
306 | len += IWL_MAX_SCAN_SIZE; | ||
307 | txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd); | ||
308 | if (!txq->cmd) | ||
309 | return -ENOMEM; | ||
310 | |||
311 | /* Alloc driver data array and TFD circular buffer */ | ||
312 | rc = iwl4965_tx_queue_alloc(priv, txq, txq_id); | ||
313 | if (rc) { | ||
314 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
315 | |||
316 | return -ENOMEM; | ||
317 | } | ||
318 | txq->need_update = 0; | ||
319 | |||
320 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | ||
321 | * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ | ||
322 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); | ||
323 | |||
324 | /* Initialize queue's high/low-water marks, and head/tail indexes */ | ||
325 | iwl4965_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); | ||
326 | |||
327 | /* Tell device where to find queue */ | ||
328 | iwl4965_hw_tx_queue_init(priv, txq); | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * iwl4965_tx_queue_free - Deallocate DMA queue. | ||
335 | * @txq: Transmit queue to deallocate. | ||
336 | * | ||
337 | * Empty queue by removing and destroying all BD's. | ||
338 | * Free all buffers. | ||
339 | * 0-fill, but do not free "txq" descriptor structure. | ||
340 | */ | ||
341 | void iwl4965_tx_queue_free(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) | ||
342 | { | ||
343 | struct iwl4965_queue *q = &txq->q; | ||
344 | struct pci_dev *dev = priv->pci_dev; | ||
345 | int len; | ||
346 | |||
347 | if (q->n_bd == 0) | ||
348 | return; | ||
349 | |||
350 | /* first, empty all BD's */ | ||
351 | for (; q->write_ptr != q->read_ptr; | ||
352 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) | ||
353 | iwl4965_hw_txq_free_tfd(priv, txq); | ||
354 | |||
355 | len = sizeof(struct iwl_cmd) * q->n_window; | ||
356 | if (q->id == IWL_CMD_QUEUE_NUM) | ||
357 | len += IWL_MAX_SCAN_SIZE; | ||
358 | |||
359 | /* De-alloc array of command/tx buffers */ | ||
360 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
361 | |||
362 | /* De-alloc circular buffer of TFDs */ | ||
363 | if (txq->q.n_bd) | ||
364 | pci_free_consistent(dev, sizeof(struct iwl4965_tfd_frame) * | ||
365 | txq->q.n_bd, txq->bd, txq->q.dma_addr); | ||
366 | |||
367 | /* De-alloc array of per-TFD driver data */ | ||
368 | if (txq->txb) { | ||
369 | kfree(txq->txb); | ||
370 | txq->txb = NULL; | ||
371 | } | ||
372 | |||
373 | /* 0-fill queue descriptor structure */ | ||
374 | memset(txq, 0, sizeof(*txq)); | ||
375 | } | ||
376 | |||
377 | const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 210 | const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
378 | 211 | ||
379 | /*************** STATION TABLE MANAGEMENT **** | 212 | /*************** STATION TABLE MANAGEMENT **** |
@@ -516,7 +349,7 @@ int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
516 | { | 349 | { |
517 | struct iwl4965_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; | 350 | struct iwl4965_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; |
518 | struct iwl4965_queue *q = &txq->q; | 351 | struct iwl4965_queue *q = &txq->q; |
519 | struct iwl4965_tfd_frame *tfd; | 352 | struct iwl_tfd_frame *tfd; |
520 | u32 *control_flags; | 353 | u32 *control_flags; |
521 | struct iwl_cmd *out_cmd; | 354 | struct iwl_cmd *out_cmd; |
522 | u32 idx; | 355 | u32 idx; |
@@ -1931,7 +1764,7 @@ static int iwl4965_tx_skb(struct iwl_priv *priv, | |||
1931 | struct sk_buff *skb, struct ieee80211_tx_control *ctl) | 1764 | struct sk_buff *skb, struct ieee80211_tx_control *ctl) |
1932 | { | 1765 | { |
1933 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1766 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1934 | struct iwl4965_tfd_frame *tfd; | 1767 | struct iwl_tfd_frame *tfd; |
1935 | u32 *control_flags; | 1768 | u32 *control_flags; |
1936 | int txq_id = ctl->queue; | 1769 | int txq_id = ctl->queue; |
1937 | struct iwl4965_tx_queue *txq = NULL; | 1770 | struct iwl4965_tx_queue *txq = NULL; |
@@ -2515,7 +2348,7 @@ int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
2515 | if (txq_id != IWL_CMD_QUEUE_NUM) { | 2348 | if (txq_id != IWL_CMD_QUEUE_NUM) { |
2516 | iwl4965_txstatus_to_ieee(priv, | 2349 | iwl4965_txstatus_to_ieee(priv, |
2517 | &(txq->txb[txq->q.read_ptr])); | 2350 | &(txq->txb[txq->q.read_ptr])); |
2518 | iwl4965_hw_txq_free_tfd(priv, txq); | 2351 | iwl_hw_txq_free_tfd(priv, txq); |
2519 | } else if (nfreed > 1) { | 2352 | } else if (nfreed > 1) { |
2520 | IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, | 2353 | IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, |
2521 | q->write_ptr, q->read_ptr); | 2354 | q->write_ptr, q->read_ptr); |
@@ -4677,7 +4510,7 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
4677 | return ret; | 4510 | return ret; |
4678 | } | 4511 | } |
4679 | 4512 | ||
4680 | ret = priv->cfg->ops->lib->hw_nic_init(priv); | 4513 | ret = iwl_hw_nic_init(priv); |
4681 | if (ret) { | 4514 | if (ret) { |
4682 | IWL_ERROR("Unable to init nic\n"); | 4515 | IWL_ERROR("Unable to init nic\n"); |
4683 | return ret; | 4516 | return ret; |
@@ -6940,7 +6773,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
6940 | 6773 | ||
6941 | if (priv->rxq.bd) | 6774 | if (priv->rxq.bd) |
6942 | iwl_rx_queue_free(priv, &priv->rxq); | 6775 | iwl_rx_queue_free(priv, &priv->rxq); |
6943 | iwl4965_hw_txq_ctx_free(priv); | 6776 | iwl_hw_txq_ctx_free(priv); |
6944 | 6777 | ||
6945 | iwlcore_clear_stations_table(priv); | 6778 | iwlcore_clear_stations_table(priv); |
6946 | iwl_eeprom_free(priv); | 6779 | iwl_eeprom_free(priv); |