aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorKalle Valo <kvalo@qca.qualcomm.com>2011-11-11 05:17:51 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2011-11-13 05:34:29 -0500
commitc71114959dc952a509822f22251d01004b3b94cc (patch)
tree704414e7921140cb2506e2525da0b9caf31e10fd /drivers/net/wireless
parent1f4c894d3a35e88331c01e681d033a2000c3667b (diff)
ath6kl: move diag commands to hif driver
This is preparation for USB support which will have different diag commands. Based on code by Kevin Fang. Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif-ops.h20
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.h2
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c76
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c100
4 files changed, 126 insertions, 72 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h
index 0c4c602464b7..2fe1dadfc77a 100644
--- a/drivers/net/wireless/ath/ath6kl/hif-ops.h
+++ b/drivers/net/wireless/ath/ath6kl/hif-ops.h
@@ -91,6 +91,26 @@ static inline int ath6kl_hif_suspend(struct ath6kl *ar,
91 return ar->hif_ops->suspend(ar, wow); 91 return ar->hif_ops->suspend(ar, wow);
92} 92}
93 93
94/*
95 * Read from the ATH6KL through its diagnostic window. No cooperation from
96 * the Target is required for this.
97 */
98static inline int ath6kl_hif_diag_read32(struct ath6kl *ar, u32 address,
99 u32 *value)
100{
101 return ar->hif_ops->diag_read32(ar, address, value);
102}
103
104/*
105 * Write to the ATH6KL through its diagnostic window. No cooperation from
106 * the Target is required for this.
107 */
108static inline int ath6kl_hif_diag_write32(struct ath6kl *ar, u32 address,
109 __le32 value)
110{
111 return ar->hif_ops->diag_write32(ar, address, value);
112}
113
94static inline int ath6kl_hif_bmi_read(struct ath6kl *ar, u8 *buf, u32 len) 114static inline int ath6kl_hif_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
95{ 115{
96 return ar->hif_ops->bmi_read(ar, buf, len); 116 return ar->hif_ops->bmi_read(ar, buf, len);
diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h
index 42004e9069b6..15b5d98c7dc4 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.h
+++ b/drivers/net/wireless/ath/ath6kl/hif.h
@@ -244,6 +244,8 @@ struct ath6kl_hif_ops {
244 void (*cleanup_scatter)(struct ath6kl *ar); 244 void (*cleanup_scatter)(struct ath6kl *ar);
245 int (*suspend)(struct ath6kl *ar, struct cfg80211_wowlan *wow); 245 int (*suspend)(struct ath6kl *ar, struct cfg80211_wowlan *wow);
246 int (*resume)(struct ath6kl *ar); 246 int (*resume)(struct ath6kl *ar);
247 int (*diag_read32)(struct ath6kl *ar, u32 address, u32 *value);
248 int (*diag_write32)(struct ath6kl *ar, u32 address, __le32 value);
247 int (*bmi_read)(struct ath6kl *ar, u8 *buf, u32 len); 249 int (*bmi_read)(struct ath6kl *ar, u8 *buf, u32 len);
248 int (*bmi_write)(struct ath6kl *ar, u8 *buf, u32 len); 250 int (*bmi_write)(struct ath6kl *ar, u8 *buf, u32 len);
249 int (*power_on)(struct ath6kl *ar); 251 int (*power_on)(struct ath6kl *ar);
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 1195f9408857..ea848944fdc4 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -175,64 +175,6 @@ void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie)
175 ar->cookie_count++; 175 ar->cookie_count++;
176} 176}
177 177
178/* set the window address register (using 4-byte register access ). */
179static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
180{
181 int status;
182 s32 i;
183 __le32 addr_val;
184
185 /*
186 * Write bytes 1,2,3 of the register to set the upper address bytes,
187 * the LSB is written last to initiate the access cycle
188 */
189
190 for (i = 1; i <= 3; i++) {
191 /*
192 * Fill the buffer with the address byte value we want to
193 * hit 4 times. No need to worry about endianness as the
194 * same byte is copied to all four bytes of addr_val at
195 * any time.
196 */
197 memset((u8 *)&addr_val, ((u8 *)&addr)[i], 4);
198
199 /*
200 * Hit each byte of the register address with a 4-byte
201 * write operation to the same address, this is a harmless
202 * operation.
203 */
204 status = hif_read_write_sync(ar, reg_addr + i, (u8 *)&addr_val,
205 4, HIF_WR_SYNC_BYTE_FIX);
206 if (status)
207 break;
208 }
209
210 if (status) {
211 ath6kl_err("failed to write initial bytes of 0x%x to window reg: 0x%X\n",
212 addr, reg_addr);
213 return status;
214 }
215
216 /*
217 * Write the address register again, this time write the whole
218 * 4-byte value. The effect here is that the LSB write causes the
219 * cycle to start, the extra 3 byte write to bytes 1,2,3 has no
220 * effect since we are writing the same values again
221 */
222 addr_val = cpu_to_le32(addr);
223 status = hif_read_write_sync(ar, reg_addr,
224 (u8 *)&(addr_val),
225 4, HIF_WR_SYNC_BYTE_INC);
226
227 if (status) {
228 ath6kl_err("failed to write 0x%x to window reg: 0x%X\n",
229 addr, reg_addr);
230 return status;
231 }
232
233 return 0;
234}
235
236/* 178/*
237 * Read from the hardware through its diagnostic window. No cooperation 179 * Read from the hardware through its diagnostic window. No cooperation
238 * from the firmware is required for this. 180 * from the firmware is required for this.
@@ -241,14 +183,7 @@ int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value)
241{ 183{
242 int ret; 184 int ret;
243 185
244 /* set window register to start read cycle */ 186 ret = ath6kl_hif_diag_read32(ar, address, value);
245 ret = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS, address);
246 if (ret)
247 return ret;
248
249 /* read the data */
250 ret = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *) value,
251 sizeof(*value), HIF_RD_SYNC_BYTE_INC);
252 if (ret) { 187 if (ret) {
253 ath6kl_warn("failed to read32 through diagnose window: %d\n", 188 ath6kl_warn("failed to read32 through diagnose window: %d\n",
254 ret); 189 ret);
@@ -266,18 +201,15 @@ int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value)
266{ 201{
267 int ret; 202 int ret;
268 203
269 /* set write data */ 204 ret = ath6kl_hif_diag_write32(ar, address, value);
270 ret = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *) &value, 205
271 sizeof(value), HIF_WR_SYNC_BYTE_INC);
272 if (ret) { 206 if (ret) {
273 ath6kl_err("failed to write 0x%x during diagnose window to 0x%d\n", 207 ath6kl_err("failed to write 0x%x during diagnose window to 0x%d\n",
274 address, value); 208 address, value);
275 return ret; 209 return ret;
276 } 210 }
277 211
278 /* set window register, which starts the write cycle */ 212 return 0;
279 return ath6kl_set_addrwin_reg(ar, WINDOW_WRITE_ADDR_ADDRESS,
280 address);
281} 213}
282 214
283int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length) 215int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length)
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 46a9bd66b94c..b633c8026cf5 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -845,6 +845,104 @@ static int ath6kl_sdio_resume(struct ath6kl *ar)
845 return 0; 845 return 0;
846} 846}
847 847
848/* set the window address register (using 4-byte register access ). */
849static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
850{
851 int status;
852 u8 addr_val[4];
853 s32 i;
854
855 /*
856 * Write bytes 1,2,3 of the register to set the upper address bytes,
857 * the LSB is written last to initiate the access cycle
858 */
859
860 for (i = 1; i <= 3; i++) {
861 /*
862 * Fill the buffer with the address byte value we want to
863 * hit 4 times.
864 */
865 memset(addr_val, ((u8 *)&addr)[i], 4);
866
867 /*
868 * Hit each byte of the register address with a 4-byte
869 * write operation to the same address, this is a harmless
870 * operation.
871 */
872 status = ath6kl_sdio_read_write_sync(ar, reg_addr + i, addr_val,
873 4, HIF_WR_SYNC_BYTE_FIX);
874 if (status)
875 break;
876 }
877
878 if (status) {
879 ath6kl_err("%s: failed to write initial bytes of 0x%x "
880 "to window reg: 0x%X\n", __func__,
881 addr, reg_addr);
882 return status;
883 }
884
885 /*
886 * Write the address register again, this time write the whole
887 * 4-byte value. The effect here is that the LSB write causes the
888 * cycle to start, the extra 3 byte write to bytes 1,2,3 has no
889 * effect since we are writing the same values again
890 */
891 status = ath6kl_sdio_read_write_sync(ar, reg_addr, (u8 *)(&addr),
892 4, HIF_WR_SYNC_BYTE_INC);
893
894 if (status) {
895 ath6kl_err("%s: failed to write 0x%x to window reg: 0x%X\n",
896 __func__, addr, reg_addr);
897 return status;
898 }
899
900 return 0;
901}
902
903static int ath6kl_sdio_diag_read32(struct ath6kl *ar, u32 address, u32 *data)
904{
905 int status;
906
907 /* set window register to start read cycle */
908 status = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS,
909 address);
910
911 if (status)
912 return status;
913
914 /* read the data */
915 status = ath6kl_sdio_read_write_sync(ar, WINDOW_DATA_ADDRESS,
916 (u8 *)data, sizeof(u32), HIF_RD_SYNC_BYTE_INC);
917 if (status) {
918 ath6kl_err("%s: failed to read from window data addr\n",
919 __func__);
920 return status;
921 }
922
923 return status;
924}
925
926static int ath6kl_sdio_diag_write32(struct ath6kl *ar, u32 address,
927 __le32 data)
928{
929 int status;
930 u32 val = (__force u32) data;
931
932 /* set write data */
933 status = ath6kl_sdio_read_write_sync(ar, WINDOW_DATA_ADDRESS,
934 (u8 *) &val, sizeof(u32), HIF_WR_SYNC_BYTE_INC);
935 if (status) {
936 ath6kl_err("%s: failed to write 0x%x to window data addr\n",
937 __func__, data);
938 return status;
939 }
940
941 /* set window register, which starts the write cycle */
942 return ath6kl_set_addrwin_reg(ar, WINDOW_WRITE_ADDR_ADDRESS,
943 address);
944}
945
848static int ath6kl_sdio_bmi_credits(struct ath6kl *ar) 946static int ath6kl_sdio_bmi_credits(struct ath6kl *ar)
849{ 947{
850 u32 addr; 948 u32 addr;
@@ -1049,6 +1147,8 @@ static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
1049 .cleanup_scatter = ath6kl_sdio_cleanup_scatter, 1147 .cleanup_scatter = ath6kl_sdio_cleanup_scatter,
1050 .suspend = ath6kl_sdio_suspend, 1148 .suspend = ath6kl_sdio_suspend,
1051 .resume = ath6kl_sdio_resume, 1149 .resume = ath6kl_sdio_resume,
1150 .diag_read32 = ath6kl_sdio_diag_read32,
1151 .diag_write32 = ath6kl_sdio_diag_write32,
1052 .bmi_read = ath6kl_sdio_bmi_read, 1152 .bmi_read = ath6kl_sdio_bmi_read,
1053 .bmi_write = ath6kl_sdio_bmi_write, 1153 .bmi_write = ath6kl_sdio_bmi_write,
1054 .power_on = ath6kl_sdio_power_on, 1154 .power_on = ath6kl_sdio_power_on,