aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath6kl/sdio.c
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/ath/ath6kl/sdio.c
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/ath/ath6kl/sdio.c')
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c100
1 files changed, 100 insertions, 0 deletions
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,