diff options
author | David S. Miller <davem@davemloft.net> | 2008-11-26 18:28:40 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-26 18:28:40 -0500 |
commit | b5ddedc9cc01b1d86015af08c5f1694191804530 (patch) | |
tree | db08f24da9ef4dcec0976ee4de4d77e5e596057e /drivers/net/wireless/rt2x00/rt61pci.c | |
parent | 244e6c2d0724bc4908a1995804704bdee3b31528 (diff) | |
parent | b235507cc5e552b9e75678d596727249e8fba01b (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt61pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 161 |
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 | */ |
58 | static 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, ®); | 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 | ||
73 | static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev, | 66 | static 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, ®)) { |
91 | rt2x00_set_field32(®, PHY_CSR3_VALUE, value); | 78 | reg = 0; |
92 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); | 79 | rt2x00_set_field32(®, PHY_CSR3_VALUE, value); |
93 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | 80 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); |
94 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); | 81 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); |
95 | 82 | rt2x00_set_field32(®, 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 | ||
101 | exit_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 | ||
107 | static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev, | 90 | static 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, ®)) { |
118 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) | 106 | reg = 0; |
119 | goto exit_fail; | 107 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); |
108 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | ||
109 | rt2x00_set_field32(®, 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(®, PHY_CSR3_REGNUM, word); | ||
126 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | ||
127 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); | ||
128 | 112 | ||
129 | rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); | 113 | WAIT_FOR_BBP(rt2x00dev, ®); |
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 | ||
143 | exit_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 | ||
150 | static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev, | 121 | static 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, ®); | 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, ®)) { |
166 | } | 136 | reg = 0; |
167 | 137 | rt2x00_set_field32(®, PHY_CSR4_VALUE, value); | |
168 | mutex_unlock(&rt2x00dev->csr_mutex); | 138 | rt2x00_set_field32(®, PHY_CSR4_NUMBER_OF_BITS, 21); |
169 | ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n"); | 139 | rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); |
170 | return; | 140 | rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); |
171 | |||
172 | rf_write: | ||
173 | reg = 0; | ||
174 | rt2x00_set_field32(®, PHY_CSR4_VALUE, value); | ||
175 | rt2x00_set_field32(®, PHY_CSR4_NUMBER_OF_BITS, 21); | ||
176 | rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); | ||
177 | rt2x00_set_field32(®, 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, ®); | 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, ®)) { | |
204 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_OWNER, 1); | 168 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_OWNER, 1); |
205 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); | 169 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); |
206 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0); | 170 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0); |
207 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG1, arg1); | 171 | rt2x00_set_field32(®, 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, ®); | ||
211 | rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); | ||
212 | rt2x00_set_field32(®, 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, ®); |
175 | rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); | ||
176 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); | ||
177 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); | ||
178 | } | ||
218 | 179 | ||
219 | exit_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 | ||