diff options
author | Samuel Ortiz <samuel.ortiz@intel.com> | 2009-01-19 18:30:26 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-01-29 16:00:56 -0500 |
commit | 7aaa1d79e3a2d573ac469744506f17b1c9386840 (patch) | |
tree | b003f298588e7f6a9f97764387f1c62a17c18b9e /drivers/net/wireless/iwlwifi/iwl3945-base.c | |
parent | 4f3602c8a3cf8d31e8b08b82d7ea9b0c30f28965 (diff) |
iwlwifi: Add TFD library operations
The TFD structures for 3945 and agn HWs are fundamentally different. We thus
need to define operations for attaching and freeing them. This will allow us
to share a fair amount of code (cmd and tx queue related) between both
drivers.
Signed-off-by: Samuel Ortiz <samuel.ortiz@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 34 |
1 files changed, 9 insertions, 25 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 66b7e22d7e84..4474a4c3ddcd 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -274,7 +274,7 @@ void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq) | |||
274 | /* first, empty all BD's */ | 274 | /* first, empty all BD's */ |
275 | for (; q->write_ptr != q->read_ptr; | 275 | for (; q->write_ptr != q->read_ptr; |
276 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) | 276 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) |
277 | iwl3945_hw_txq_free_tfd(priv, txq); | 277 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); |
278 | 278 | ||
279 | len = sizeof(struct iwl_cmd) * q->n_window; | 279 | len = sizeof(struct iwl_cmd) * q->n_window; |
280 | if (q->id == IWL_CMD_QUEUE_NUM) | 280 | if (q->id == IWL_CMD_QUEUE_NUM) |
@@ -453,12 +453,10 @@ static int iwl3945_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
453 | { | 453 | { |
454 | struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; | 454 | struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; |
455 | struct iwl_queue *q = &txq->q; | 455 | struct iwl_queue *q = &txq->q; |
456 | struct iwl3945_tfd *tfd; | ||
457 | struct iwl_cmd *out_cmd; | 456 | struct iwl_cmd *out_cmd; |
458 | u32 idx; | 457 | u32 idx; |
459 | u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); | 458 | u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); |
460 | dma_addr_t phys_addr; | 459 | dma_addr_t phys_addr; |
461 | int pad; | ||
462 | int ret, len; | 460 | int ret, len; |
463 | unsigned long flags; | 461 | unsigned long flags; |
464 | 462 | ||
@@ -481,9 +479,6 @@ static int iwl3945_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
481 | 479 | ||
482 | spin_lock_irqsave(&priv->hcmd_lock, flags); | 480 | spin_lock_irqsave(&priv->hcmd_lock, flags); |
483 | 481 | ||
484 | tfd = &txq->tfds39[q->write_ptr]; | ||
485 | memset(tfd, 0, sizeof(*tfd)); | ||
486 | |||
487 | idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE); | 482 | idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE); |
488 | out_cmd = txq->cmd[idx]; | 483 | out_cmd = txq->cmd[idx]; |
489 | 484 | ||
@@ -509,10 +504,9 @@ static int iwl3945_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
509 | pci_unmap_len_set(&out_cmd->meta, len, len); | 504 | pci_unmap_len_set(&out_cmd->meta, len, len); |
510 | phys_addr += offsetof(struct iwl_cmd, hdr); | 505 | phys_addr += offsetof(struct iwl_cmd, hdr); |
511 | 506 | ||
512 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size); | 507 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, |
513 | 508 | phys_addr, fix_size, | |
514 | pad = U32_PAD(cmd->len); | 509 | 1, U32_PAD(cmd->len)); |
515 | tfd->control_flags |= cpu_to_le32(TFD_CTL_PAD_SET(pad)); | ||
516 | 510 | ||
517 | IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, " | 511 | IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, " |
518 | "%d bytes at %d[%d]:%d\n", | 512 | "%d bytes at %d[%d]:%d\n", |
@@ -2158,7 +2152,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
2158 | { | 2152 | { |
2159 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 2153 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
2160 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 2154 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
2161 | struct iwl3945_tfd *tfd; | ||
2162 | struct iwl3945_tx_cmd *tx; | 2155 | struct iwl3945_tx_cmd *tx; |
2163 | struct iwl_tx_queue *txq = NULL; | 2156 | struct iwl_tx_queue *txq = NULL; |
2164 | struct iwl_queue *q = NULL; | 2157 | struct iwl_queue *q = NULL; |
@@ -2243,9 +2236,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
2243 | 2236 | ||
2244 | spin_lock_irqsave(&priv->lock, flags); | 2237 | spin_lock_irqsave(&priv->lock, flags); |
2245 | 2238 | ||
2246 | /* Set up first empty TFD within this queue's circular TFD buffer */ | ||
2247 | tfd = &txq->tfds39[q->write_ptr]; | ||
2248 | memset(tfd, 0, sizeof(*tfd)); | ||
2249 | idx = get_cmd_index(q, q->write_ptr, 0); | 2239 | idx = get_cmd_index(q, q->write_ptr, 0); |
2250 | 2240 | ||
2251 | /* Set up driver data for this TFD */ | 2241 | /* Set up driver data for this TFD */ |
@@ -2304,7 +2294,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
2304 | 2294 | ||
2305 | /* Add buffer containing Tx command and MAC(!) header to TFD's | 2295 | /* Add buffer containing Tx command and MAC(!) header to TFD's |
2306 | * first entry */ | 2296 | * first entry */ |
2307 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); | 2297 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, |
2298 | txcmd_phys, len, 1, 0); | ||
2308 | 2299 | ||
2309 | if (info->control.hw_key) | 2300 | if (info->control.hw_key) |
2310 | iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0); | 2301 | iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0); |
@@ -2315,18 +2306,11 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
2315 | if (len) { | 2306 | if (len) { |
2316 | phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, | 2307 | phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, |
2317 | len, PCI_DMA_TODEVICE); | 2308 | len, PCI_DMA_TODEVICE); |
2318 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len); | 2309 | priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, |
2310 | phys_addr, len, | ||
2311 | 0, U32_PAD(len)); | ||
2319 | } | 2312 | } |
2320 | 2313 | ||
2321 | if (!len) | ||
2322 | /* If there is no payload, then we use only one Tx buffer */ | ||
2323 | tfd->control_flags = cpu_to_le32(TFD_CTL_COUNT_SET(1)); | ||
2324 | else | ||
2325 | /* Else use 2 buffers. | ||
2326 | * Tell 3945 about any padding after MAC header */ | ||
2327 | tfd->control_flags = cpu_to_le32(TFD_CTL_COUNT_SET(2) | | ||
2328 | TFD_CTL_PAD_SET(U32_PAD(len))); | ||
2329 | |||
2330 | /* Total # bytes to be transmitted */ | 2314 | /* Total # bytes to be transmitted */ |
2331 | len = (u16)skb->len; | 2315 | len = (u16)skb->len; |
2332 | tx->len = cpu_to_le16(len); | 2316 | tx->len = cpu_to_le16(len); |