aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt61pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt61pci.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c161
1 files changed, 59 insertions, 102 deletions
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 89ac34fbadf2..d54443c25fe3 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -55,20 +55,13 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
55 * the access attempt is considered to have failed, 55 * the access attempt is considered to have failed,
56 * and we will print an error. 56 * and we will print an error.
57 */ 57 */
58static u32 rt61pci_bbp_check(struct rt2x00_dev *rt2x00dev) 58#define WAIT_FOR_BBP(__dev, __reg) \
59{ 59 rt2x00pci_regbusy_read((__dev), PHY_CSR3, PHY_CSR3_BUSY, (__reg))
60 u32 reg; 60#define WAIT_FOR_RF(__dev, __reg) \
61 unsigned int i; 61 rt2x00pci_regbusy_read((__dev), PHY_CSR4, PHY_CSR4_BUSY, (__reg))
62 62#define WAIT_FOR_MCU(__dev, __reg) \
63 for (i = 0; i < REGISTER_BUSY_COUNT; i++) { 63 rt2x00pci_regbusy_read((__dev), H2M_MAILBOX_CSR, \
64 rt2x00pci_register_read(rt2x00dev, PHY_CSR3, &reg); 64 H2M_MAILBOX_CSR_OWNER, (__reg))
65 if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY))
66 break;
67 udelay(REGISTER_BUSY_DELAY);
68 }
69
70 return reg;
71}
72 65
73static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev, 66static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev,
74 const unsigned int word, const u8 value) 67 const unsigned int word, const u8 value)
@@ -78,30 +71,20 @@ static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev,
78 mutex_lock(&rt2x00dev->csr_mutex); 71 mutex_lock(&rt2x00dev->csr_mutex);
79 72
80 /* 73 /*
81 * Wait until the BBP becomes ready. 74 * Wait until the BBP becomes available, afterwards we
82 */ 75 * can safely write the new data into the register.
83 reg = rt61pci_bbp_check(rt2x00dev);
84 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
85 goto exit_fail;
86
87 /*
88 * Write the data into the BBP.
89 */ 76 */
90 reg = 0; 77 if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
91 rt2x00_set_field32(&reg, PHY_CSR3_VALUE, value); 78 reg = 0;
92 rt2x00_set_field32(&reg, PHY_CSR3_REGNUM, word); 79 rt2x00_set_field32(&reg, PHY_CSR3_VALUE, value);
93 rt2x00_set_field32(&reg, PHY_CSR3_BUSY, 1); 80 rt2x00_set_field32(&reg, PHY_CSR3_REGNUM, word);
94 rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 0); 81 rt2x00_set_field32(&reg, PHY_CSR3_BUSY, 1);
95 82 rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 0);
96 rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg);
97 mutex_unlock(&rt2x00dev->csr_mutex);
98 83
99 return; 84 rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg);
85 }
100 86
101exit_fail:
102 mutex_unlock(&rt2x00dev->csr_mutex); 87 mutex_unlock(&rt2x00dev->csr_mutex);
103
104 ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
105} 88}
106 89
107static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev, 90static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -112,72 +95,53 @@ static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev,
112 mutex_lock(&rt2x00dev->csr_mutex); 95 mutex_lock(&rt2x00dev->csr_mutex);
113 96
114 /* 97 /*
115 * Wait until the BBP becomes ready. 98 * Wait until the BBP becomes available, afterwards we
99 * can safely write the read request into the register.
100 * After the data has been written, we wait until hardware
101 * returns the correct value, if at any time the register
102 * doesn't become available in time, reg will be 0xffffffff
103 * which means we return 0xff to the caller.
116 */ 104 */
117 reg = rt61pci_bbp_check(rt2x00dev); 105 if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
118 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) 106 reg = 0;
119 goto exit_fail; 107 rt2x00_set_field32(&reg, PHY_CSR3_REGNUM, word);
108 rt2x00_set_field32(&reg, PHY_CSR3_BUSY, 1);
109 rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 1);
120 110
121 /* 111 rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg);
122 * Write the request into the BBP.
123 */
124 reg = 0;
125 rt2x00_set_field32(&reg, PHY_CSR3_REGNUM, word);
126 rt2x00_set_field32(&reg, PHY_CSR3_BUSY, 1);
127 rt2x00_set_field32(&reg, PHY_CSR3_READ_CONTROL, 1);
128 112
129 rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); 113 WAIT_FOR_BBP(rt2x00dev, &reg);
130 114 }
131 /*
132 * Wait until the BBP becomes ready.
133 */
134 reg = rt61pci_bbp_check(rt2x00dev);
135 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
136 goto exit_fail;
137 115
138 *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); 116 *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
139 mutex_unlock(&rt2x00dev->csr_mutex);
140
141 return;
142 117
143exit_fail:
144 mutex_unlock(&rt2x00dev->csr_mutex); 118 mutex_unlock(&rt2x00dev->csr_mutex);
145
146 ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
147 *value = 0xff;
148} 119}
149 120
150static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev, 121static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev,
151 const unsigned int word, const u32 value) 122 const unsigned int word, const u32 value)
152{ 123{
153 u32 reg; 124 u32 reg;
154 unsigned int i;
155 125
156 if (!word) 126 if (!word)
157 return; 127 return;
158 128
159 mutex_lock(&rt2x00dev->csr_mutex); 129 mutex_lock(&rt2x00dev->csr_mutex);
160 130
161 for (i = 0; i < REGISTER_BUSY_COUNT; i++) { 131 /*
162 rt2x00pci_register_read(rt2x00dev, PHY_CSR4, &reg); 132 * Wait until the RF becomes available, afterwards we
163 if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY)) 133 * can safely write the new data into the register.
164 goto rf_write; 134 */
165 udelay(REGISTER_BUSY_DELAY); 135 if (WAIT_FOR_RF(rt2x00dev, &reg)) {
166 } 136 reg = 0;
167 137 rt2x00_set_field32(&reg, PHY_CSR4_VALUE, value);
168 mutex_unlock(&rt2x00dev->csr_mutex); 138 rt2x00_set_field32(&reg, PHY_CSR4_NUMBER_OF_BITS, 21);
169 ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n"); 139 rt2x00_set_field32(&reg, PHY_CSR4_IF_SELECT, 0);
170 return; 140 rt2x00_set_field32(&reg, PHY_CSR4_BUSY, 1);
171
172rf_write:
173 reg = 0;
174 rt2x00_set_field32(&reg, PHY_CSR4_VALUE, value);
175 rt2x00_set_field32(&reg, PHY_CSR4_NUMBER_OF_BITS, 21);
176 rt2x00_set_field32(&reg, PHY_CSR4_IF_SELECT, 0);
177 rt2x00_set_field32(&reg, PHY_CSR4_BUSY, 1);
178 141
179 rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg); 142 rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg);
180 rt2x00_rf_write(rt2x00dev, word, value); 143 rt2x00_rf_write(rt2x00dev, word, value);
144 }
181 145
182 mutex_unlock(&rt2x00dev->csr_mutex); 146 mutex_unlock(&rt2x00dev->csr_mutex);
183} 147}
@@ -196,32 +160,25 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev,
196 160
197 mutex_lock(&rt2x00dev->csr_mutex); 161 mutex_lock(&rt2x00dev->csr_mutex);
198 162
199 rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CSR, &reg); 163 /*
200 164 * Wait until the MCU becomes available, afterwards we
201 if (rt2x00_get_field32(reg, H2M_MAILBOX_CSR_OWNER)) 165 * can safely write the new data into the register.
202 goto exit_fail; 166 */
203 167 if (WAIT_FOR_MCU(rt2x00dev, &reg)) {
204 rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_OWNER, 1); 168 rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_OWNER, 1);
205 rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token); 169 rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
206 rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG0, arg0); 170 rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG0, arg0);
207 rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG1, arg1); 171 rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG1, arg1);
208 rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, reg); 172 rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, reg);
209
210 rt2x00pci_register_read(rt2x00dev, HOST_CMD_CSR, &reg);
211 rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
212 rt2x00_set_field32(&reg, HOST_CMD_CSR_INTERRUPT_MCU, 1);
213 rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg);
214
215 mutex_unlock(&rt2x00dev->csr_mutex);
216 173
217 return; 174 rt2x00pci_register_read(rt2x00dev, HOST_CMD_CSR, &reg);
175 rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
176 rt2x00_set_field32(&reg, HOST_CMD_CSR_INTERRUPT_MCU, 1);
177 rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg);
178 }
218 179
219exit_fail:
220 mutex_unlock(&rt2x00dev->csr_mutex); 180 mutex_unlock(&rt2x00dev->csr_mutex);
221 181
222 ERROR(rt2x00dev,
223 "mcu request error. Request 0x%02x failed for token 0x%02x.\n",
224 command, token);
225} 182}
226#endif /* CONFIG_RT2X00_LIB_LEDS */ 183#endif /* CONFIG_RT2X00_LIB_LEDS */
227 184