aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-dev.h
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-05-13 14:57:40 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2011-05-13 15:00:41 -0400
commit4ce7cc2b09553a91d4aea014c39674685715173a (patch)
tree0a2e4b8ae8852a6404c479a7b605ae4b0af6b72d /drivers/net/wireless/iwlwifi/iwl-dev.h
parent4c42db0f04e55d48f0ea9f424144a5211b7a155c (diff)
iwlagn: support multiple TBs per command
The current "huge" command handling is a bit confusing, and very limited since only one command may be huge at a time. Additionally, we often copy data around quite pointlessly since we could instead map the existing scan buffer for example and use it directly. This patch makes that possible. The first change is that multiple buffers may be given to each command (this change was prepared earlier so callsites don't need to change). Each of those can be mapped attached to a TB in the TFD, and the command header can use a TB (the first one) in the TFD as well. Doing this allows getting rid of huge commands in favour of mapping existing buffers. The beacon transmission is also optimised to not copy the SKB at all but use multiple TBs. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-dev.h')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h46
1 files changed, 28 insertions, 18 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 38254bdfabbb..3e3b8b8939d6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -110,8 +110,6 @@ struct iwl_cmd_meta {
110 struct iwl_device_cmd *cmd, 110 struct iwl_device_cmd *cmd,
111 struct iwl_rx_packet *pkt); 111 struct iwl_rx_packet *pkt);
112 112
113 /* The CMD_SIZE_HUGE flag bit indicates that the command
114 * structure is stored at the end of the shared queue memory. */
115 u32 flags; 113 u32 flags;
116 114
117 DEFINE_DMA_UNMAP_ADDR(mapping); 115 DEFINE_DMA_UNMAP_ADDR(mapping);
@@ -121,7 +119,23 @@ struct iwl_cmd_meta {
121/* 119/*
122 * Generic queue structure 120 * Generic queue structure
123 * 121 *
124 * Contains common data for Rx and Tx queues 122 * Contains common data for Rx and Tx queues.
123 *
124 * Note the difference between n_bd and n_window: the hardware
125 * always assumes 256 descriptors, so n_bd is always 256 (unless
126 * there might be HW changes in the future). For the normal TX
127 * queues, n_window, which is the size of the software queue data
128 * is also 256; however, for the command queue, n_window is only
129 * 32 since we don't need so many commands pending. Since the HW
130 * still uses 256 BDs for DMA though, n_bd stays 256. As a result,
131 * the software buffers (in the variables @meta, @txb in struct
132 * iwl_tx_queue) only have 32 entries, while the HW buffers (@tfds
133 * in the same struct) have 256.
134 * This means that we end up with the following:
135 * HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 |
136 * SW entries: | 0 | ... | 31 |
137 * where N is a number between 0 and 7. This means that the SW
138 * data is a window overlayed over the HW queue.
125 */ 139 */
126struct iwl_queue { 140struct iwl_queue {
127 int n_bd; /* number of BDs in this queue */ 141 int n_bd; /* number of BDs in this queue */
@@ -163,7 +177,7 @@ struct iwl_tx_info {
163 177
164struct iwl_tx_queue { 178struct iwl_tx_queue {
165 struct iwl_queue q; 179 struct iwl_queue q;
166 void *tfds; 180 struct iwl_tfd *tfds;
167 struct iwl_device_cmd **cmd; 181 struct iwl_device_cmd **cmd;
168 struct iwl_cmd_meta *meta; 182 struct iwl_cmd_meta *meta;
169 struct iwl_tx_info *txb; 183 struct iwl_tx_info *txb;
@@ -245,7 +259,6 @@ enum {
245 CMD_SYNC = 0, 259 CMD_SYNC = 0,
246 CMD_SIZE_NORMAL = 0, 260 CMD_SIZE_NORMAL = 0,
247 CMD_NO_SKB = 0, 261 CMD_NO_SKB = 0,
248 CMD_SIZE_HUGE = (1 << 0),
249 CMD_ASYNC = (1 << 1), 262 CMD_ASYNC = (1 << 1),
250 CMD_WANT_SKB = (1 << 2), 263 CMD_WANT_SKB = (1 << 2),
251 CMD_MAPPED = (1 << 3), 264 CMD_MAPPED = (1 << 3),
@@ -257,8 +270,8 @@ enum {
257 * struct iwl_device_cmd 270 * struct iwl_device_cmd
258 * 271 *
259 * For allocation of the command and tx queues, this establishes the overall 272 * For allocation of the command and tx queues, this establishes the overall
260 * size of the largest command we send to uCode, except for a scan command 273 * size of the largest command we send to uCode, except for commands that
261 * (which is relatively huge; space is allocated separately). 274 * aren't fully copied and use other TFD space.
262 */ 275 */
263struct iwl_device_cmd { 276struct iwl_device_cmd {
264 struct iwl_cmd_header hdr; /* uCode API */ 277 struct iwl_cmd_header hdr; /* uCode API */
@@ -275,7 +288,11 @@ struct iwl_device_cmd {
275 288
276#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) 289#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
277 290
278#define IWL_MAX_CMD_TFDS 1 291#define IWL_MAX_CMD_TFDS 2
292
293enum iwl_hcmd_dataflag {
294 IWL_HCMD_DFL_NOCOPY = BIT(0),
295};
279 296
280struct iwl_host_cmd { 297struct iwl_host_cmd {
281 const void *data[IWL_MAX_CMD_TFDS]; 298 const void *data[IWL_MAX_CMD_TFDS];
@@ -285,6 +302,7 @@ struct iwl_host_cmd {
285 struct iwl_rx_packet *pkt); 302 struct iwl_rx_packet *pkt);
286 u32 flags; 303 u32 flags;
287 u16 len[IWL_MAX_CMD_TFDS]; 304 u16 len[IWL_MAX_CMD_TFDS];
305 u8 dataflags[IWL_MAX_CMD_TFDS];
288 u8 id; 306 u8 id;
289}; 307};
290 308
@@ -687,17 +705,8 @@ static inline int iwl_queue_used(const struct iwl_queue *q, int i)
687} 705}
688 706
689 707
690static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge) 708static inline u8 get_cmd_index(struct iwl_queue *q, u32 index)
691{ 709{
692 /*
693 * This is for init calibration result and scan command which
694 * required buffer > TFD_MAX_PAYLOAD_SIZE,
695 * the big buffer at end of command array
696 */
697 if (is_huge)
698 return q->n_window; /* must be power of 2 */
699
700 /* Otherwise, use normal size buffers */
701 return index & (q->n_window - 1); 710 return index & (q->n_window - 1);
702} 711}
703 712
@@ -1451,6 +1460,7 @@ struct iwl_priv {
1451 struct work_struct beacon_update; 1460 struct work_struct beacon_update;
1452 struct iwl_rxon_context *beacon_ctx; 1461 struct iwl_rxon_context *beacon_ctx;
1453 struct sk_buff *beacon_skb; 1462 struct sk_buff *beacon_skb;
1463 void *beacon_cmd;
1454 1464
1455 struct work_struct tt_work; 1465 struct work_struct tt_work;
1456 struct work_struct ct_enter; 1466 struct work_struct ct_enter;