aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl4965-base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c177
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 */
213static 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 */
244static 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 */
289int 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 */
341void 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
377const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 210const 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);