Linux 3.9-rc8
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / iwlwifi / iwl-io.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2003 - 2013 Intel Corporation. All rights reserved.
4  *
5  * Portions of this file are derived from the ipw3945 project.
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of version 2 of the GNU General Public License as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19  *
20  * The full GNU General Public License is included in this distribution in the
21  * file called LICENSE.
22  *
23  * Contact Information:
24  *  Intel Linux Wireless <ilw@linux.intel.com>
25  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26  *
27  *****************************************************************************/
28 #include <linux/delay.h>
29 #include <linux/device.h>
30 #include <linux/export.h>
31
32 #include "iwl-io.h"
33 #include "iwl-csr.h"
34 #include "iwl-debug.h"
35
36 #define IWL_POLL_INTERVAL 10    /* microseconds */
37
38 int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
39                  u32 bits, u32 mask, int timeout)
40 {
41         int t = 0;
42
43         do {
44                 if ((iwl_read32(trans, addr) & mask) == (bits & mask))
45                         return t;
46                 udelay(IWL_POLL_INTERVAL);
47                 t += IWL_POLL_INTERVAL;
48         } while (t < timeout);
49
50         return -ETIMEDOUT;
51 }
52 EXPORT_SYMBOL_GPL(iwl_poll_bit);
53
54 u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
55 {
56         u32 value = 0x5a5a5a5a;
57         unsigned long flags;
58         if (iwl_trans_grab_nic_access(trans, false, &flags)) {
59                 value = iwl_read32(trans, reg);
60                 iwl_trans_release_nic_access(trans, &flags);
61         }
62
63         return value;
64 }
65 EXPORT_SYMBOL_GPL(iwl_read_direct32);
66
67 void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
68 {
69         unsigned long flags;
70
71         if (iwl_trans_grab_nic_access(trans, false, &flags)) {
72                 iwl_write32(trans, reg, value);
73                 iwl_trans_release_nic_access(trans, &flags);
74         }
75 }
76 EXPORT_SYMBOL_GPL(iwl_write_direct32);
77
78 int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
79                         int timeout)
80 {
81         int t = 0;
82
83         do {
84                 if ((iwl_read_direct32(trans, addr) & mask) == mask)
85                         return t;
86                 udelay(IWL_POLL_INTERVAL);
87                 t += IWL_POLL_INTERVAL;
88         } while (t < timeout);
89
90         return -ETIMEDOUT;
91 }
92 EXPORT_SYMBOL_GPL(iwl_poll_direct_bit);
93
94 static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs)
95 {
96         u32 val = iwl_trans_read_prph(trans, ofs);
97         trace_iwlwifi_dev_ioread_prph32(trans->dev, ofs, val);
98         return val;
99 }
100
101 static inline void __iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
102 {
103         trace_iwlwifi_dev_iowrite_prph32(trans->dev, ofs, val);
104         iwl_trans_write_prph(trans, ofs, val);
105 }
106
107 u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
108 {
109         unsigned long flags;
110         u32 val = 0x5a5a5a5a;
111
112         if (iwl_trans_grab_nic_access(trans, false, &flags)) {
113                 val = __iwl_read_prph(trans, ofs);
114                 iwl_trans_release_nic_access(trans, &flags);
115         }
116         return val;
117 }
118 EXPORT_SYMBOL_GPL(iwl_read_prph);
119
120 void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
121 {
122         unsigned long flags;
123
124         if (iwl_trans_grab_nic_access(trans, false, &flags)) {
125                 __iwl_write_prph(trans, ofs, val);
126                 iwl_trans_release_nic_access(trans, &flags);
127         }
128 }
129 EXPORT_SYMBOL_GPL(iwl_write_prph);
130
131 void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
132 {
133         unsigned long flags;
134
135         if (iwl_trans_grab_nic_access(trans, false, &flags)) {
136                 __iwl_write_prph(trans, ofs,
137                                  __iwl_read_prph(trans, ofs) | mask);
138                 iwl_trans_release_nic_access(trans, &flags);
139         }
140 }
141 EXPORT_SYMBOL_GPL(iwl_set_bits_prph);
142
143 void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
144                             u32 bits, u32 mask)
145 {
146         unsigned long flags;
147
148         if (iwl_trans_grab_nic_access(trans, false, &flags)) {
149                 __iwl_write_prph(trans, ofs,
150                                  (__iwl_read_prph(trans, ofs) & mask) | bits);
151                 iwl_trans_release_nic_access(trans, &flags);
152         }
153 }
154 EXPORT_SYMBOL_GPL(iwl_set_bits_mask_prph);
155
156 void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
157 {
158         unsigned long flags;
159         u32 val;
160
161         if (iwl_trans_grab_nic_access(trans, false, &flags)) {
162                 val = __iwl_read_prph(trans, ofs);
163                 __iwl_write_prph(trans, ofs, (val & ~mask));
164                 iwl_trans_release_nic_access(trans, &flags);
165         }
166 }
167 EXPORT_SYMBOL_GPL(iwl_clear_bits_prph);