diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2008-10-24 02:48:55 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-10-31 19:02:27 -0400 |
commit | 127901ab69bbb263fb2b46e850cf20c57ac321d3 (patch) | |
tree | 35ab1fa324ca430ab486e9bc63cfea41966b1c49 /drivers/net/wireless | |
parent | 951891c7ef844919d30aac7b1fc7396fd8be23ff (diff) |
iwlwifi: refactor tx byte count table usage
This patch drops unreadable usage of IWL_SET/GET_BITS16 in byte count
tables handling
This patch also cleans a bit the byte count table code and adds
WARN_ON traps on invalid values
This patch is pure cleanup, no functional changes.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 38 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000-hw.h | 29 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-fh.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-helpers.h | 102 |
6 files changed, 62 insertions, 185 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index b66dd093084d..f3f41a6a7c8c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h | |||
@@ -111,7 +111,6 @@ | |||
111 | #define PCI_CFG_CMD_REG_INT_DIS_MSK 0x04 | 111 | #define PCI_CFG_CMD_REG_INT_DIS_MSK 0x04 |
112 | #define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000) | 112 | #define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000) |
113 | 113 | ||
114 | #define TFD_QUEUE_SIZE_MAX (256) | ||
115 | 114 | ||
116 | #define IWL_NUM_SCAN_RATES (2) | 115 | #define IWL_NUM_SCAN_RATES (2) |
117 | 116 | ||
@@ -815,8 +814,6 @@ enum { | |||
815 | * up to 7 DMA channels (FIFOs). Each Tx queue is supported by a circular array | 814 | * up to 7 DMA channels (FIFOs). Each Tx queue is supported by a circular array |
816 | * in DRAM containing 256 Transmit Frame Descriptors (TFDs). | 815 | * in DRAM containing 256 Transmit Frame Descriptors (TFDs). |
817 | */ | 816 | */ |
818 | #define IWL49_MAX_WIN_SIZE 64 | ||
819 | #define IWL49_QUEUE_SIZE 256 | ||
820 | #define IWL49_NUM_FIFOS 7 | 817 | #define IWL49_NUM_FIFOS 7 |
821 | #define IWL49_CMD_FIFO_NUM 4 | 818 | #define IWL49_CMD_FIFO_NUM 4 |
822 | #define IWL49_NUM_QUEUES 16 | 819 | #define IWL49_NUM_QUEUES 16 |
@@ -882,26 +879,7 @@ struct iwl_tfd { | |||
882 | 879 | ||
883 | 880 | ||
884 | /** | 881 | /** |
885 | * struct iwl4965_queue_byte_cnt_entry | 882 | * struct iwl4965_schedq_bc_tbl |
886 | * | ||
887 | * Byte Count Table Entry | ||
888 | * | ||
889 | * Bit fields: | ||
890 | * 15-12: reserved | ||
891 | * 11- 0: total to-be-transmitted byte count of frame (does not include command) | ||
892 | */ | ||
893 | struct iwl4965_queue_byte_cnt_entry { | ||
894 | __le16 val; | ||
895 | /* __le16 byte_cnt:12; */ | ||
896 | #define IWL_byte_cnt_POS 0 | ||
897 | #define IWL_byte_cnt_LEN 12 | ||
898 | #define IWL_byte_cnt_SYM val | ||
899 | /* __le16 rsvd:4; */ | ||
900 | } __attribute__ ((packed)); | ||
901 | |||
902 | |||
903 | /** | ||
904 | * struct iwl4965_sched_queue_byte_cnt_tbl | ||
905 | * | 883 | * |
906 | * Byte Count table | 884 | * Byte Count table |
907 | * | 885 | * |
@@ -915,15 +893,12 @@ struct iwl4965_queue_byte_cnt_entry { | |||
915 | * count table for the chosen Tx queue. If the TFD index is 0-63, the driver | 893 | * count table for the chosen Tx queue. If the TFD index is 0-63, the driver |
916 | * must duplicate the byte count entry in corresponding index 256-319. | 894 | * must duplicate the byte count entry in corresponding index 256-319. |
917 | * | 895 | * |
918 | * "dont_care" padding puts each byte count table on a 1024-byte boundary; | 896 | * padding puts each byte count table on a 1024-byte boundary; |
919 | * 4965 assumes tables are separated by 1024 bytes. | 897 | * 4965 assumes tables are separated by 1024 bytes. |
920 | */ | 898 | */ |
921 | struct iwl4965_sched_queue_byte_cnt_tbl { | 899 | struct iwl4965_schedq_bc_tbl { |
922 | struct iwl4965_queue_byte_cnt_entry tfd_offset[IWL49_QUEUE_SIZE + | 900 | __le16 tfd_offset[TFD_QUEUE_BC_SIZE]; |
923 | IWL49_MAX_WIN_SIZE]; | 901 | u8 pad[1024 - (TFD_QUEUE_BC_SIZE) * sizeof(__le16)]; |
924 | u8 dont_care[1024 - | ||
925 | (IWL49_QUEUE_SIZE + IWL49_MAX_WIN_SIZE) * | ||
926 | sizeof(__le16)]; | ||
927 | } __attribute__ ((packed)); | 902 | } __attribute__ ((packed)); |
928 | 903 | ||
929 | 904 | ||
@@ -951,8 +926,7 @@ struct iwl4965_sched_queue_byte_cnt_tbl { | |||
951 | * 31- 0: Not used | 926 | * 31- 0: Not used |
952 | */ | 927 | */ |
953 | struct iwl4965_shared { | 928 | struct iwl4965_shared { |
954 | struct iwl4965_sched_queue_byte_cnt_tbl | 929 | struct iwl4965_schedq_bc_tbl queues_bc_tbls[IWL49_NUM_QUEUES]; |
955 | queues_byte_cnt_tbls[IWL49_NUM_QUEUES]; | ||
956 | __le32 rb_closed; | 930 | __le32 rb_closed; |
957 | 931 | ||
958 | /* __le32 rb_closed_stts_rb_num:12; */ | 932 | /* __le32 rb_closed_stts_rb_num:12; */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index aad32a3ffd19..1f22140bec1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -716,7 +716,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv) | |||
716 | /* Tel 4965 where to find Tx byte count tables */ | 716 | /* Tel 4965 where to find Tx byte count tables */ |
717 | iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR, | 717 | iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR, |
718 | (priv->shared_phys + | 718 | (priv->shared_phys + |
719 | offsetof(struct iwl4965_shared, queues_byte_cnt_tbls)) >> 10); | 719 | offsetof(struct iwl4965_shared, queues_bc_tbls)) >> 10); |
720 | 720 | ||
721 | /* Disable chain mode for all queues */ | 721 | /* Disable chain mode for all queues */ |
722 | iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0); | 722 | iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0); |
@@ -1668,21 +1668,22 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv, | |||
1668 | struct iwl_tx_queue *txq, | 1668 | struct iwl_tx_queue *txq, |
1669 | u16 byte_cnt) | 1669 | u16 byte_cnt) |
1670 | { | 1670 | { |
1671 | int len; | ||
1672 | int txq_id = txq->q.id; | ||
1673 | struct iwl4965_shared *shared_data = priv->shared_virt; | 1671 | struct iwl4965_shared *shared_data = priv->shared_virt; |
1672 | int txq_id = txq->q.id; | ||
1673 | int write_ptr = txq->q.write_ptr; | ||
1674 | int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; | ||
1675 | __le16 bc_ent; | ||
1674 | 1676 | ||
1675 | len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; | 1677 | WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); |
1676 | 1678 | ||
1679 | bc_ent = cpu_to_le16(len & 0xFFF); | ||
1677 | /* Set up byte count within first 256 entries */ | 1680 | /* Set up byte count within first 256 entries */ |
1678 | IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. | 1681 | shared_data->queues_bc_tbls[txq_id].tfd_offset[write_ptr] = bc_ent; |
1679 | tfd_offset[txq->q.write_ptr], byte_cnt, len); | ||
1680 | 1682 | ||
1681 | /* If within first 64 entries, duplicate at end */ | 1683 | /* If within first 64 entries, duplicate at end */ |
1682 | if (txq->q.write_ptr < IWL49_MAX_WIN_SIZE) | 1684 | if (write_ptr < TFD_QUEUE_SIZE_BC_DUP) |
1683 | IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. | 1685 | shared_data->queues_bc_tbls[txq_id]. |
1684 | tfd_offset[IWL49_QUEUE_SIZE + txq->q.write_ptr], | 1686 | tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; |
1685 | byte_cnt, len); | ||
1686 | } | 1687 | } |
1687 | 1688 | ||
1688 | /** | 1689 | /** |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index fa0644321e4f..49ede54bfad9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h | |||
@@ -76,30 +76,31 @@ | |||
76 | /* EERPROM */ | 76 | /* EERPROM */ |
77 | #define IWL_5000_EEPROM_IMG_SIZE 2048 | 77 | #define IWL_5000_EEPROM_IMG_SIZE 2048 |
78 | 78 | ||
79 | |||
80 | #define IWL50_MAX_WIN_SIZE 64 | ||
81 | #define IWL50_QUEUE_SIZE 256 | ||
82 | #define IWL50_CMD_FIFO_NUM 7 | 79 | #define IWL50_CMD_FIFO_NUM 7 |
83 | #define IWL50_NUM_QUEUES 20 | 80 | #define IWL50_NUM_QUEUES 20 |
84 | #define IWL50_NUM_AMPDU_QUEUES 10 | 81 | #define IWL50_NUM_AMPDU_QUEUES 10 |
85 | #define IWL50_FIRST_AMPDU_QUEUE 10 | 82 | #define IWL50_FIRST_AMPDU_QUEUE 10 |
86 | 83 | ||
87 | #define IWL_sta_id_POS 12 | ||
88 | #define IWL_sta_id_LEN 4 | ||
89 | #define IWL_sta_id_SYM val | ||
90 | |||
91 | /* Fixed (non-configurable) rx data from phy */ | 84 | /* Fixed (non-configurable) rx data from phy */ |
92 | 85 | ||
93 | /* Base physical address of iwl5000_shared is provided to SCD_DRAM_BASE_ADDR | 86 | /** |
94 | * and &iwl5000_shared.val0 is provided to FH_RSCSR_CHNL0_STTS_WPTR_REG */ | 87 | * struct iwl5000_schedq_bc_tbl scheduler byte count table |
95 | struct iwl5000_sched_queue_byte_cnt_tbl { | 88 | * base physical address of iwl5000_shared |
96 | struct iwl4965_queue_byte_cnt_entry tfd_offset[IWL50_QUEUE_SIZE + | 89 | * is provided to SCD_DRAM_BASE_ADDR |
97 | IWL50_MAX_WIN_SIZE]; | 90 | * @tfd_offset 0-12 - tx command byte count |
91 | * 12-16 - station index | ||
92 | */ | ||
93 | struct iwl5000_schedq_bc_tbl { | ||
94 | __le16 tfd_offset[TFD_QUEUE_BC_SIZE]; | ||
98 | } __attribute__ ((packed)); | 95 | } __attribute__ ((packed)); |
99 | 96 | ||
97 | /** | ||
98 | * struct iwl5000_shared | ||
99 | * @rb_closed | ||
100 | * address is provided to FH_RSCSR_CHNL0_STTS_WPTR_REG | ||
101 | */ | ||
100 | struct iwl5000_shared { | 102 | struct iwl5000_shared { |
101 | struct iwl5000_sched_queue_byte_cnt_tbl | 103 | struct iwl5000_schedq_bc_tbl queues_bc_tbls[IWL50_NUM_QUEUES]; |
102 | queues_byte_cnt_tbls[IWL50_NUM_QUEUES]; | ||
103 | __le32 rb_closed; | 104 | __le32 rb_closed; |
104 | 105 | ||
105 | /* __le32 rb_closed_stts_rb_num:12; */ | 106 | /* __le32 rb_closed_stts_rb_num:12; */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index b4b7e8b2a429..0c9281e9f2ad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -723,7 +723,7 @@ static int iwl5000_alive_notify(struct iwl_priv *priv) | |||
723 | 723 | ||
724 | iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR, | 724 | iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR, |
725 | (priv->shared_phys + | 725 | (priv->shared_phys + |
726 | offsetof(struct iwl5000_shared, queues_byte_cnt_tbls)) >> 10); | 726 | offsetof(struct iwl5000_shared, queues_bc_tbls)) >> 10); |
727 | iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, | 727 | iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, |
728 | IWL50_SCD_QUEUECHAIN_SEL_ALL( | 728 | IWL50_SCD_QUEUECHAIN_SEL_ALL( |
729 | priv->hw_params.max_txq_num)); | 729 | priv->hw_params.max_txq_num)); |
@@ -891,15 +891,17 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv, | |||
891 | u16 byte_cnt) | 891 | u16 byte_cnt) |
892 | { | 892 | { |
893 | struct iwl5000_shared *shared_data = priv->shared_virt; | 893 | struct iwl5000_shared *shared_data = priv->shared_virt; |
894 | int write_ptr = txq->q.write_ptr; | ||
894 | int txq_id = txq->q.id; | 895 | int txq_id = txq->q.id; |
895 | u8 sec_ctl = 0; | 896 | u8 sec_ctl = 0; |
896 | u8 sta = 0; | 897 | u8 sta_id = 0; |
897 | int len; | 898 | u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; |
899 | __le16 bc_ent; | ||
898 | 900 | ||
899 | len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; | 901 | WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); |
900 | 902 | ||
901 | if (txq_id != IWL_CMD_QUEUE_NUM) { | 903 | if (txq_id != IWL_CMD_QUEUE_NUM) { |
902 | sta = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id; | 904 | sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id; |
903 | sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl; | 905 | sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl; |
904 | 906 | ||
905 | switch (sec_ctl & TX_CMD_SEC_MSK) { | 907 | switch (sec_ctl & TX_CMD_SEC_MSK) { |
@@ -915,40 +917,36 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv, | |||
915 | } | 917 | } |
916 | } | 918 | } |
917 | 919 | ||
918 | IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. | 920 | bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12)); |
919 | tfd_offset[txq->q.write_ptr], byte_cnt, len); | ||
920 | 921 | ||
921 | IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. | 922 | shared_data->queues_bc_tbls[txq_id].tfd_offset[write_ptr] = bc_ent; |
922 | tfd_offset[txq->q.write_ptr], sta_id, sta); | ||
923 | 923 | ||
924 | if (txq->q.write_ptr < IWL50_MAX_WIN_SIZE) { | 924 | if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) |
925 | IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. | 925 | shared_data->queues_bc_tbls[txq_id]. |
926 | tfd_offset[IWL50_QUEUE_SIZE + txq->q.write_ptr], | 926 | tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; |
927 | byte_cnt, len); | ||
928 | IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. | ||
929 | tfd_offset[IWL50_QUEUE_SIZE + txq->q.write_ptr], | ||
930 | sta_id, sta); | ||
931 | } | ||
932 | } | 927 | } |
933 | 928 | ||
934 | static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, | 929 | static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, |
935 | struct iwl_tx_queue *txq) | 930 | struct iwl_tx_queue *txq) |
936 | { | 931 | { |
937 | int txq_id = txq->q.id; | ||
938 | struct iwl5000_shared *shared_data = priv->shared_virt; | 932 | struct iwl5000_shared *shared_data = priv->shared_virt; |
939 | u8 sta = 0; | 933 | int txq_id = txq->q.id; |
934 | int read_ptr = txq->q.read_ptr; | ||
935 | u8 sta_id = 0; | ||
936 | __le16 bc_ent; | ||
937 | |||
938 | WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); | ||
940 | 939 | ||
941 | if (txq_id != IWL_CMD_QUEUE_NUM) | 940 | if (txq_id != IWL_CMD_QUEUE_NUM) |
942 | sta = txq->cmd[txq->q.read_ptr]->cmd.tx.sta_id; | 941 | sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id; |
943 | 942 | ||
944 | shared_data->queues_byte_cnt_tbls[txq_id].tfd_offset[txq->q.read_ptr]. | 943 | bc_ent = cpu_to_le16(1 | (sta_id << 12)); |
945 | val = cpu_to_le16(1 | (sta << 12)); | 944 | shared_data->queues_bc_tbls[txq_id]. |
945 | tfd_offset[read_ptr] = bc_ent; | ||
946 | 946 | ||
947 | if (txq->q.write_ptr < IWL50_MAX_WIN_SIZE) { | 947 | if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) |
948 | shared_data->queues_byte_cnt_tbls[txq_id]. | 948 | shared_data->queues_bc_tbls[txq_id]. |
949 | tfd_offset[IWL50_QUEUE_SIZE + txq->q.read_ptr]. | 949 | tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; |
950 | val = cpu_to_le16(1 | (sta << 12)); | ||
951 | } | ||
952 | } | 950 | } |
953 | 951 | ||
954 | static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, | 952 | static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 8c48d8870218..f2688d551830 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h | |||
@@ -393,4 +393,9 @@ | |||
393 | /* TCSR: tx_config register values */ | 393 | /* TCSR: tx_config register values */ |
394 | #define FH_RSCSR_FRAME_SIZE_MSK (0x00003FFF) /* bits 0-13 */ | 394 | #define FH_RSCSR_FRAME_SIZE_MSK (0x00003FFF) /* bits 0-13 */ |
395 | 395 | ||
396 | #define TFD_QUEUE_SIZE_MAX (256) | ||
397 | #define TFD_QUEUE_SIZE_BC_DUP (64) | ||
398 | #define TFD_QUEUE_BC_SIZE (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP) | ||
399 | |||
400 | |||
396 | #endif /* !__iwl_fh_h__ */ | 401 | #endif /* !__iwl_fh_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 029d19c7075c..4f0fa215d32e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h | |||
@@ -32,108 +32,6 @@ | |||
32 | 32 | ||
33 | #include <linux/ctype.h> | 33 | #include <linux/ctype.h> |
34 | 34 | ||
35 | /* | ||
36 | * The structures defined by the hardware/uCode interface | ||
37 | * have bit-wise operations. For each bit-field there is | ||
38 | * a data symbol in the structure, the start bit position | ||
39 | * and the length of the bit-field. | ||
40 | * | ||
41 | * iwl_get_bits and iwl_set_bits will return or set the | ||
42 | * appropriate bits on a 32-bit value. | ||
43 | * | ||
44 | * IWL_GET_BITS and IWL_SET_BITS use symbol expansion to | ||
45 | * expand out to the appropriate call to iwl_get_bits | ||
46 | * and iwl_set_bits without having to reference all of the | ||
47 | * numerical constants and defines provided in the hardware | ||
48 | * definition | ||
49 | */ | ||
50 | |||
51 | /** | ||
52 | * iwl_get_bits - Extract a hardware bit-field value | ||
53 | * @src: source hardware value (__le32) | ||
54 | * @pos: bit-position (0-based) of first bit of value | ||
55 | * @len: length of bit-field | ||
56 | * | ||
57 | * iwl_get_bits will return the bit-field in cpu endian ordering. | ||
58 | * | ||
59 | * NOTE: If used from IWL_GET_BITS then pos and len are compile-constants and | ||
60 | * will collapse to minimal code by the compiler. | ||
61 | */ | ||
62 | static inline u32 iwl_get_bits(__le32 src, u8 pos, u8 len) | ||
63 | { | ||
64 | u32 tmp = le32_to_cpu(src); | ||
65 | |||
66 | tmp >>= pos; | ||
67 | tmp &= (1UL << len) - 1; | ||
68 | return tmp; | ||
69 | } | ||
70 | |||
71 | /** | ||
72 | * iwl_set_bits - Set a hardware bit-field value | ||
73 | * @dst: Address of __le32 hardware value | ||
74 | * @pos: bit-position (0-based) of first bit of value | ||
75 | * @len: length of bit-field | ||
76 | * @val: cpu endian value to encode into the bit-field | ||
77 | * | ||
78 | * iwl_set_bits will encode val into dst, masked to be len bits long at bit | ||
79 | * position pos. | ||
80 | * | ||
81 | * NOTE: If used IWL_SET_BITS pos and len will be compile-constants and | ||
82 | * will collapse to minimal code by the compiler. | ||
83 | */ | ||
84 | static inline void iwl_set_bits(__le32 *dst, u8 pos, u8 len, int val) | ||
85 | { | ||
86 | u32 tmp = le32_to_cpu(*dst); | ||
87 | |||
88 | tmp &= ~(((1UL << len) - 1) << pos); | ||
89 | tmp |= (val & ((1UL << len) - 1)) << pos; | ||
90 | *dst = cpu_to_le32(tmp); | ||
91 | } | ||
92 | |||
93 | static inline void iwl_set_bits16(__le16 *dst, u8 pos, u8 len, int val) | ||
94 | { | ||
95 | u16 tmp = le16_to_cpu(*dst); | ||
96 | |||
97 | tmp &= ~((1UL << (pos + len)) - (1UL << pos)); | ||
98 | tmp |= (val & ((1UL << len) - 1)) << pos; | ||
99 | *dst = cpu_to_le16(tmp); | ||
100 | } | ||
101 | |||
102 | /* | ||
103 | * The bit-field definitions in iwl-xxxx-hw.h are in the form of: | ||
104 | * | ||
105 | * struct example { | ||
106 | * __le32 val1; | ||
107 | * #define IWL_name_POS 8 | ||
108 | * #define IWL_name_LEN 4 | ||
109 | * #define IWL_name_SYM val1 | ||
110 | * }; | ||
111 | * | ||
112 | * The IWL_SET_BITS and IWL_GET_BITS macros are provided to allow the driver | ||
113 | * to call: | ||
114 | * | ||
115 | * struct example bar; | ||
116 | * u32 val = IWL_GET_BITS(bar, name); | ||
117 | * val = val * 2; | ||
118 | * IWL_SET_BITS(bar, name, val); | ||
119 | * | ||
120 | * All cpu / host ordering, masking, and shifts are performed by the macros | ||
121 | * and iwl_{get,set}_bits. | ||
122 | * | ||
123 | */ | ||
124 | #define IWL_SET_BITS(s, sym, v) \ | ||
125 | iwl_set_bits(&(s).IWL_ ## sym ## _SYM, IWL_ ## sym ## _POS, \ | ||
126 | IWL_ ## sym ## _LEN, (v)) | ||
127 | |||
128 | #define IWL_SET_BITS16(s, sym, v) \ | ||
129 | iwl_set_bits16(&(s).IWL_ ## sym ## _SYM, IWL_ ## sym ## _POS, \ | ||
130 | IWL_ ## sym ## _LEN, (v)) | ||
131 | |||
132 | #define IWL_GET_BITS(s, sym) \ | ||
133 | iwl_get_bits((s).IWL_ ## sym ## _SYM, IWL_ ## sym ## _POS, \ | ||
134 | IWL_ ## sym ## _LEN) | ||
135 | |||
136 | |||
137 | #define KELVIN_TO_CELSIUS(x) ((x)-273) | 35 | #define KELVIN_TO_CELSIUS(x) ((x)-273) |
138 | #define CELSIUS_TO_KELVIN(x) ((x)+273) | 36 | #define CELSIUS_TO_KELVIN(x) ((x)+273) |
139 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) | 37 | #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) |