aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-trans.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2011-06-14 03:13:24 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2011-07-01 10:57:34 -0400
commitc85eb6196958ae54eba3ff0660d2b5af3d58521a (patch)
tree9b4e0e85127ff1481f0ebd0614edf48a90816a4c /drivers/net/wireless/iwlwifi/iwl-trans.c
parent300d0834ebd3f3c57b0063c2fd6bc26d8405626c (diff)
iwlagn: introduce transport layer and implement rx_init
The transport layer is responsible for all the queues, DMA rings etc... This is the beginning of the separation of all the code that is tighly related to HW design to the aforementioned transport layer. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-trans.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c
new file mode 100644
index 000000000000..ccf73ff63956
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.c
@@ -0,0 +1,155 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called LICENSE.GPL.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63 #include "iwl-dev.h"
64#include "iwl-trans.h"
65
66static int iwl_trans_rx_alloc(struct iwl_priv *priv)
67{
68 struct iwl_rx_queue *rxq = &priv->rxq;
69 struct device *dev = priv->bus.dev;
70
71 memset(&priv->rxq, 0, sizeof(priv->rxq));
72
73 spin_lock_init(&rxq->lock);
74 INIT_LIST_HEAD(&rxq->rx_free);
75 INIT_LIST_HEAD(&rxq->rx_used);
76
77 if (WARN_ON(rxq->bd || rxq->rb_stts))
78 return -EINVAL;
79
80 /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */
81 /*Every descriptor is an __le32, hence its */
82 rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma,
83 GFP_KERNEL);
84 if (!rxq->bd)
85 goto err_bd;
86 memset(rxq->bd, 0, 4 * RX_QUEUE_SIZE);
87
88 /*Allocate the driver's pointer to receive buffer status */
89 rxq->rb_stts = dma_alloc_coherent(dev, sizeof(*rxq->rb_stts),
90 &rxq->rb_stts_dma, GFP_KERNEL);
91 if (!rxq->rb_stts)
92 goto err_rb_stts;
93 memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts));
94
95 return 0;
96
97err_rb_stts:
98 dma_free_coherent(dev, 4 * RX_QUEUE_SIZE, rxq->bd, rxq->bd_dma);
99 memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
100 rxq->bd = NULL;
101err_bd:
102 return -ENOMEM;
103}
104
105static int iwl_trans_rx_init(struct iwl_priv *priv)
106{
107 struct iwl_rx_queue *rxq = &priv->rxq;
108 int i, err;
109 unsigned long flags;
110
111 if (!rxq->bd) {
112 err = iwl_trans_rx_alloc(priv);
113 if (err)
114 return err;
115 }
116
117 spin_lock_irqsave(&rxq->lock, flags);
118 INIT_LIST_HEAD(&rxq->rx_free);
119 INIT_LIST_HEAD(&rxq->rx_used);
120
121 /* Fill the rx_used queue with _all_ of the Rx buffers */
122 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
123 /* In the reset function, these buffers may have been allocated
124 * to an SKB, so we need to unmap and free potential storage */
125 if (rxq->pool[i].page != NULL) {
126 dma_unmap_page(priv->bus.dev, rxq->pool[i].page_dma,
127 PAGE_SIZE << priv->hw_params.rx_page_order,
128 DMA_FROM_DEVICE);
129 __iwl_free_pages(priv, rxq->pool[i].page);
130 rxq->pool[i].page = NULL;
131 }
132 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
133 }
134
135 for (i = 0; i < RX_QUEUE_SIZE; i++)
136 rxq->queue[i] = NULL;
137
138 /* Set us so that we have processed and used all buffers, but have
139 * not restocked the Rx queue with fresh buffers */
140 rxq->read = rxq->write = 0;
141 rxq->write_actual = 0;
142 rxq->free_count = 0;
143 spin_unlock_irqrestore(&rxq->lock, flags);
144
145 return 0;
146}
147
148static const struct iwl_trans_ops trans_ops = {
149 .rx_init = iwl_trans_rx_init,
150};
151
152void iwl_trans_register(struct iwl_trans *trans)
153{
154 trans->ops = &trans_ops;
155}