aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2500usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c140
1 files changed, 60 insertions, 80 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index e6bae4ae4c47..40eb64358821 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -57,7 +57,7 @@ static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
57 __le16 reg; 57 __le16 reg;
58 rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, 58 rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ,
59 USB_VENDOR_REQUEST_IN, offset, 59 USB_VENDOR_REQUEST_IN, offset,
60 &reg, sizeof(u16), REGISTER_TIMEOUT); 60 &reg, sizeof(reg), REGISTER_TIMEOUT);
61 *value = le16_to_cpu(reg); 61 *value = le16_to_cpu(reg);
62} 62}
63 63
@@ -68,7 +68,7 @@ static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
68 __le16 reg; 68 __le16 reg;
69 rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ, 69 rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ,
70 USB_VENDOR_REQUEST_IN, offset, 70 USB_VENDOR_REQUEST_IN, offset,
71 &reg, sizeof(u16), REGISTER_TIMEOUT); 71 &reg, sizeof(reg), REGISTER_TIMEOUT);
72 *value = le16_to_cpu(reg); 72 *value = le16_to_cpu(reg);
73} 73}
74 74
@@ -89,7 +89,7 @@ static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
89 __le16 reg = cpu_to_le16(value); 89 __le16 reg = cpu_to_le16(value);
90 rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, 90 rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE,
91 USB_VENDOR_REQUEST_OUT, offset, 91 USB_VENDOR_REQUEST_OUT, offset,
92 &reg, sizeof(u16), REGISTER_TIMEOUT); 92 &reg, sizeof(reg), REGISTER_TIMEOUT);
93} 93}
94 94
95static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev, 95static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
@@ -99,7 +99,7 @@ static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
99 __le16 reg = cpu_to_le16(value); 99 __le16 reg = cpu_to_le16(value);
100 rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE, 100 rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE,
101 USB_VENDOR_REQUEST_OUT, offset, 101 USB_VENDOR_REQUEST_OUT, offset,
102 &reg, sizeof(u16), REGISTER_TIMEOUT); 102 &reg, sizeof(reg), REGISTER_TIMEOUT);
103} 103}
104 104
105static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, 105static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
@@ -112,21 +112,32 @@ static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
112 REGISTER_TIMEOUT16(length)); 112 REGISTER_TIMEOUT16(length));
113} 113}
114 114
115static u16 rt2500usb_bbp_check(struct rt2x00_dev *rt2x00dev) 115static int rt2500usb_regbusy_read(struct rt2x00_dev *rt2x00dev,
116 const unsigned int offset,
117 struct rt2x00_field16 field,
118 u16 *reg)
116{ 119{
117 u16 reg;
118 unsigned int i; 120 unsigned int i;
119 121
120 for (i = 0; i < REGISTER_BUSY_COUNT; i++) { 122 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
121 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR8, &reg); 123 rt2500usb_register_read_lock(rt2x00dev, offset, reg);
122 if (!rt2x00_get_field16(reg, PHY_CSR8_BUSY)) 124 if (!rt2x00_get_field16(*reg, field))
123 break; 125 return 1;
124 udelay(REGISTER_BUSY_DELAY); 126 udelay(REGISTER_BUSY_DELAY);
125 } 127 }
126 128
127 return reg; 129 ERROR(rt2x00dev, "Indirect register access failed: "
130 "offset=0x%.08x, value=0x%.08x\n", offset, *reg);
131 *reg = ~0;
132
133 return 0;
128} 134}
129 135
136#define WAIT_FOR_BBP(__dev, __reg) \
137 rt2500usb_regbusy_read((__dev), PHY_CSR8, PHY_CSR8_BUSY, (__reg))
138#define WAIT_FOR_RF(__dev, __reg) \
139 rt2500usb_regbusy_read((__dev), PHY_CSR10, PHY_CSR10_RF_BUSY, (__reg))
140
130static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev, 141static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
131 const unsigned int word, const u8 value) 142 const unsigned int word, const u8 value)
132{ 143{
@@ -135,30 +146,19 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
135 mutex_lock(&rt2x00dev->csr_mutex); 146 mutex_lock(&rt2x00dev->csr_mutex);
136 147
137 /* 148 /*
138 * Wait until the BBP becomes ready. 149 * Wait until the BBP becomes available, afterwards we
139 */ 150 * can safely write the new data into the register.
140 reg = rt2500usb_bbp_check(rt2x00dev);
141 if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
142 goto exit_fail;
143
144 /*
145 * Write the data into the BBP.
146 */ 151 */
147 reg = 0; 152 if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
148 rt2x00_set_field16(&reg, PHY_CSR7_DATA, value); 153 reg = 0;
149 rt2x00_set_field16(&reg, PHY_CSR7_REG_ID, word); 154 rt2x00_set_field16(&reg, PHY_CSR7_DATA, value);
150 rt2x00_set_field16(&reg, PHY_CSR7_READ_CONTROL, 0); 155 rt2x00_set_field16(&reg, PHY_CSR7_REG_ID, word);
151 156 rt2x00_set_field16(&reg, PHY_CSR7_READ_CONTROL, 0);
152 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
153
154 mutex_unlock(&rt2x00dev->csr_mutex);
155 157
156 return; 158 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
159 }
157 160
158exit_fail:
159 mutex_unlock(&rt2x00dev->csr_mutex); 161 mutex_unlock(&rt2x00dev->csr_mutex);
160
161 ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
162} 162}
163 163
164static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, 164static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -169,77 +169,57 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
169 mutex_lock(&rt2x00dev->csr_mutex); 169 mutex_lock(&rt2x00dev->csr_mutex);
170 170
171 /* 171 /*
172 * Wait until the BBP becomes ready. 172 * Wait until the BBP becomes available, afterwards we
173 */ 173 * can safely write the read request into the register.
174 reg = rt2500usb_bbp_check(rt2x00dev); 174 * After the data has been written, we wait until hardware
175 if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) 175 * returns the correct value, if at any time the register
176 goto exit_fail; 176 * doesn't become available in time, reg will be 0xffffffff
177 177 * which means we return 0xff to the caller.
178 /*
179 * Write the request into the BBP.
180 */ 178 */
181 reg = 0; 179 if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
182 rt2x00_set_field16(&reg, PHY_CSR7_REG_ID, word); 180 reg = 0;
183 rt2x00_set_field16(&reg, PHY_CSR7_READ_CONTROL, 1); 181 rt2x00_set_field16(&reg, PHY_CSR7_REG_ID, word);
182 rt2x00_set_field16(&reg, PHY_CSR7_READ_CONTROL, 1);
184 183
185 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); 184 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
186 185
187 /* 186 if (WAIT_FOR_BBP(rt2x00dev, &reg))
188 * Wait until the BBP becomes ready. 187 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg);
189 */ 188 }
190 reg = rt2500usb_bbp_check(rt2x00dev);
191 if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
192 goto exit_fail;
193 189
194 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg);
195 *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); 190 *value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
196 191
197 mutex_unlock(&rt2x00dev->csr_mutex); 192 mutex_unlock(&rt2x00dev->csr_mutex);
198
199 return;
200
201exit_fail:
202 mutex_unlock(&rt2x00dev->csr_mutex);
203
204 ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
205 *value = 0xff;
206} 193}
207 194
208static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, 195static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
209 const unsigned int word, const u32 value) 196 const unsigned int word, const u32 value)
210{ 197{
211 u16 reg; 198 u16 reg;
212 unsigned int i;
213 199
214 if (!word) 200 if (!word)
215 return; 201 return;
216 202
217 mutex_lock(&rt2x00dev->csr_mutex); 203 mutex_lock(&rt2x00dev->csr_mutex);
218 204
219 for (i = 0; i < REGISTER_BUSY_COUNT; i++) { 205 /*
220 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, &reg); 206 * Wait until the RF becomes available, afterwards we
221 if (!rt2x00_get_field16(reg, PHY_CSR10_RF_BUSY)) 207 * can safely write the new data into the register.
222 goto rf_write; 208 */
223 udelay(REGISTER_BUSY_DELAY); 209 if (WAIT_FOR_RF(rt2x00dev, &reg)) {
224 } 210 reg = 0;
225 211 rt2x00_set_field16(&reg, PHY_CSR9_RF_VALUE, value);
226 mutex_unlock(&rt2x00dev->csr_mutex); 212 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR9, reg);
227 ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n");
228 return;
229
230rf_write:
231 reg = 0;
232 rt2x00_set_field16(&reg, PHY_CSR9_RF_VALUE, value);
233 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR9, reg);
234 213
235 reg = 0; 214 reg = 0;
236 rt2x00_set_field16(&reg, PHY_CSR10_RF_VALUE, value >> 16); 215 rt2x00_set_field16(&reg, PHY_CSR10_RF_VALUE, value >> 16);
237 rt2x00_set_field16(&reg, PHY_CSR10_RF_NUMBER_OF_BITS, 20); 216 rt2x00_set_field16(&reg, PHY_CSR10_RF_NUMBER_OF_BITS, 20);
238 rt2x00_set_field16(&reg, PHY_CSR10_RF_IF_SELECT, 0); 217 rt2x00_set_field16(&reg, PHY_CSR10_RF_IF_SELECT, 0);
239 rt2x00_set_field16(&reg, PHY_CSR10_RF_BUSY, 1); 218 rt2x00_set_field16(&reg, PHY_CSR10_RF_BUSY, 1);
240 219
241 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg); 220 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg);
242 rt2x00_rf_write(rt2x00dev, word, value); 221 rt2x00_rf_write(rt2x00dev, word, value);
222 }
243 223
244 mutex_unlock(&rt2x00dev->csr_mutex); 224 mutex_unlock(&rt2x00dev->csr_mutex);
245} 225}