diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-05-15 06:55:29 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-21 21:48:11 -0400 |
commit | e039fa4a4195ac4ee895e6f3d1334beed63256fe (patch) | |
tree | cfd0762d73df96b73052378be7b157c4ac6e7035 /drivers/net/wireless/iwlwifi/iwl-tx.c | |
parent | e24549485f859be6518929bb1c9c0257d79f033d (diff) |
mac80211: move TX info into skb->cb
This patch converts mac80211 and all drivers to have transmit
information and status in skb->cb rather than allocating extra
memory for it and copying all the data around. To make it fit,
a union is used where only data that is necessary for all steps
is kept outside of the union.
A number of fixes were done by Ivo, as well as the rt2x00 part
of this patch.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-tx.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 40 |
1 files changed, 19 insertions, 21 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 4b5149c8c32e..a61293ba3f6b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -502,7 +502,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv) | |||
502 | */ | 502 | */ |
503 | static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, | 503 | static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, |
504 | struct iwl_tx_cmd *tx_cmd, | 504 | struct iwl_tx_cmd *tx_cmd, |
505 | struct ieee80211_tx_control *ctrl, | 505 | struct ieee80211_tx_info *info, |
506 | struct ieee80211_hdr *hdr, | 506 | struct ieee80211_hdr *hdr, |
507 | int is_unicast, u8 std_id) | 507 | int is_unicast, u8 std_id) |
508 | { | 508 | { |
@@ -510,7 +510,7 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, | |||
510 | __le32 tx_flags = tx_cmd->tx_flags; | 510 | __le32 tx_flags = tx_cmd->tx_flags; |
511 | 511 | ||
512 | tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 512 | tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
513 | if (!(ctrl->flags & IEEE80211_TXCTL_NO_ACK)) { | 513 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { |
514 | tx_flags |= TX_CMD_FLG_ACK_MSK; | 514 | tx_flags |= TX_CMD_FLG_ACK_MSK; |
515 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) | 515 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) |
516 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | 516 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; |
@@ -538,10 +538,10 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, | |||
538 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; | 538 | tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; |
539 | } | 539 | } |
540 | 540 | ||
541 | if (ctrl->flags & IEEE80211_TXCTL_USE_RTS_CTS) { | 541 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { |
542 | tx_flags |= TX_CMD_FLG_RTS_MSK; | 542 | tx_flags |= TX_CMD_FLG_RTS_MSK; |
543 | tx_flags &= ~TX_CMD_FLG_CTS_MSK; | 543 | tx_flags &= ~TX_CMD_FLG_CTS_MSK; |
544 | } else if (ctrl->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) { | 544 | } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) { |
545 | tx_flags &= ~TX_CMD_FLG_RTS_MSK; | 545 | tx_flags &= ~TX_CMD_FLG_RTS_MSK; |
546 | tx_flags |= TX_CMD_FLG_CTS_MSK; | 546 | tx_flags |= TX_CMD_FLG_CTS_MSK; |
547 | } | 547 | } |
@@ -570,7 +570,7 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, | |||
570 | 570 | ||
571 | static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, | 571 | static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, |
572 | struct iwl_tx_cmd *tx_cmd, | 572 | struct iwl_tx_cmd *tx_cmd, |
573 | struct ieee80211_tx_control *ctrl, | 573 | struct ieee80211_tx_info *info, |
574 | u16 fc, int sta_id, | 574 | u16 fc, int sta_id, |
575 | int is_hcca) | 575 | int is_hcca) |
576 | { | 576 | { |
@@ -580,7 +580,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, | |||
580 | u16 rate_flags = 0; | 580 | u16 rate_flags = 0; |
581 | int rate_idx; | 581 | int rate_idx; |
582 | 582 | ||
583 | rate_idx = min(ieee80211_get_tx_rate(priv->hw, ctrl)->hw_value & 0xffff, | 583 | rate_idx = min(ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xffff, |
584 | IWL_RATE_COUNT - 1); | 584 | IWL_RATE_COUNT - 1); |
585 | 585 | ||
586 | rate_plcp = iwl_rates[rate_idx].plcp; | 586 | rate_plcp = iwl_rates[rate_idx].plcp; |
@@ -637,18 +637,18 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, | |||
637 | } | 637 | } |
638 | 638 | ||
639 | static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv, | 639 | static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv, |
640 | struct ieee80211_tx_control *ctl, | 640 | struct ieee80211_tx_info *info, |
641 | struct iwl_tx_cmd *tx_cmd, | 641 | struct iwl_tx_cmd *tx_cmd, |
642 | struct sk_buff *skb_frag, | 642 | struct sk_buff *skb_frag, |
643 | int sta_id) | 643 | int sta_id) |
644 | { | 644 | { |
645 | struct ieee80211_key_conf *keyconf = ctl->hw_key; | 645 | struct ieee80211_key_conf *keyconf = info->control.hw_key; |
646 | 646 | ||
647 | switch (keyconf->alg) { | 647 | switch (keyconf->alg) { |
648 | case ALG_CCMP: | 648 | case ALG_CCMP: |
649 | tx_cmd->sec_ctl = TX_CMD_SEC_CCM; | 649 | tx_cmd->sec_ctl = TX_CMD_SEC_CCM; |
650 | memcpy(tx_cmd->key, keyconf->key, keyconf->keylen); | 650 | memcpy(tx_cmd->key, keyconf->key, keyconf->keylen); |
651 | if (ctl->flags & IEEE80211_TXCTL_AMPDU) | 651 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
652 | tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK; | 652 | tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK; |
653 | IWL_DEBUG_TX("tx_cmd with aes hwcrypto\n"); | 653 | IWL_DEBUG_TX("tx_cmd with aes hwcrypto\n"); |
654 | break; | 654 | break; |
@@ -690,13 +690,13 @@ static void iwl_update_tx_stats(struct iwl_priv *priv, u16 fc, u16 len) | |||
690 | /* | 690 | /* |
691 | * start REPLY_TX command process | 691 | * start REPLY_TX command process |
692 | */ | 692 | */ |
693 | int iwl_tx_skb(struct iwl_priv *priv, | 693 | int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) |
694 | struct sk_buff *skb, struct ieee80211_tx_control *ctl) | ||
695 | { | 694 | { |
696 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 695 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
696 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
697 | struct iwl_tfd_frame *tfd; | 697 | struct iwl_tfd_frame *tfd; |
698 | u32 *control_flags; | 698 | u32 *control_flags; |
699 | int txq_id = ctl->queue; | 699 | int txq_id = info->queue; |
700 | struct iwl_tx_queue *txq = NULL; | 700 | struct iwl_tx_queue *txq = NULL; |
701 | struct iwl_queue *q = NULL; | 701 | struct iwl_queue *q = NULL; |
702 | dma_addr_t phys_addr; | 702 | dma_addr_t phys_addr; |
@@ -726,7 +726,7 @@ int iwl_tx_skb(struct iwl_priv *priv, | |||
726 | goto drop_unlock; | 726 | goto drop_unlock; |
727 | } | 727 | } |
728 | 728 | ||
729 | if ((ieee80211_get_tx_rate(priv->hw, ctl)->hw_value & 0xFF) == | 729 | if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == |
730 | IWL_INVALID_RATE) { | 730 | IWL_INVALID_RATE) { |
731 | IWL_ERROR("ERROR: No TX rate available.\n"); | 731 | IWL_ERROR("ERROR: No TX rate available.\n"); |
732 | goto drop_unlock; | 732 | goto drop_unlock; |
@@ -782,7 +782,7 @@ int iwl_tx_skb(struct iwl_priv *priv, | |||
782 | seq_number += 0x10; | 782 | seq_number += 0x10; |
783 | #ifdef CONFIG_IWL4965_HT | 783 | #ifdef CONFIG_IWL4965_HT |
784 | /* aggregation is on for this <sta,tid> */ | 784 | /* aggregation is on for this <sta,tid> */ |
785 | if (ctl->flags & IEEE80211_TXCTL_AMPDU) | 785 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
786 | txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; | 786 | txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; |
787 | priv->stations[sta_id].tid[tid].tfds_in_queue++; | 787 | priv->stations[sta_id].tid[tid].tfds_in_queue++; |
788 | #endif /* CONFIG_IWL4965_HT */ | 788 | #endif /* CONFIG_IWL4965_HT */ |
@@ -803,8 +803,6 @@ int iwl_tx_skb(struct iwl_priv *priv, | |||
803 | /* Set up driver data for this TFD */ | 803 | /* Set up driver data for this TFD */ |
804 | memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); | 804 | memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); |
805 | txq->txb[q->write_ptr].skb[0] = skb; | 805 | txq->txb[q->write_ptr].skb[0] = skb; |
806 | memcpy(&(txq->txb[q->write_ptr].status.control), | ||
807 | ctl, sizeof(struct ieee80211_tx_control)); | ||
808 | 806 | ||
809 | /* Set up first empty entry in queue's array of Tx/cmd buffers */ | 807 | /* Set up first empty entry in queue's array of Tx/cmd buffers */ |
810 | out_cmd = &txq->cmd[idx]; | 808 | out_cmd = &txq->cmd[idx]; |
@@ -854,8 +852,8 @@ int iwl_tx_skb(struct iwl_priv *priv, | |||
854 | * first entry */ | 852 | * first entry */ |
855 | iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); | 853 | iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); |
856 | 854 | ||
857 | if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) | 855 | if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) |
858 | iwl_tx_cmd_build_hwcrypto(priv, ctl, tx_cmd, skb, sta_id); | 856 | iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); |
859 | 857 | ||
860 | /* Set up TFD's 2nd entry to point directly to remainder of skb, | 858 | /* Set up TFD's 2nd entry to point directly to remainder of skb, |
861 | * if any (802.11 null frames have no payload). */ | 859 | * if any (802.11 null frames have no payload). */ |
@@ -874,10 +872,10 @@ int iwl_tx_skb(struct iwl_priv *priv, | |||
874 | len = (u16)skb->len; | 872 | len = (u16)skb->len; |
875 | tx_cmd->len = cpu_to_le16(len); | 873 | tx_cmd->len = cpu_to_le16(len); |
876 | /* TODO need this for burst mode later on */ | 874 | /* TODO need this for burst mode later on */ |
877 | iwl_tx_cmd_build_basic(priv, tx_cmd, ctl, hdr, unicast, sta_id); | 875 | iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, unicast, sta_id); |
878 | 876 | ||
879 | /* set is_hcca to 0; it probably will never be implemented */ | 877 | /* set is_hcca to 0; it probably will never be implemented */ |
880 | iwl_tx_cmd_build_rate(priv, tx_cmd, ctl, fc, sta_id, 0); | 878 | iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0); |
881 | 879 | ||
882 | iwl_update_tx_stats(priv, fc, len); | 880 | iwl_update_tx_stats(priv, fc, len); |
883 | 881 | ||
@@ -919,7 +917,7 @@ int iwl_tx_skb(struct iwl_priv *priv, | |||
919 | spin_unlock_irqrestore(&priv->lock, flags); | 917 | spin_unlock_irqrestore(&priv->lock, flags); |
920 | } | 918 | } |
921 | 919 | ||
922 | ieee80211_stop_queue(priv->hw, ctl->queue); | 920 | ieee80211_stop_queue(priv->hw, info->queue); |
923 | } | 921 | } |
924 | 922 | ||
925 | return 0; | 923 | return 0; |