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:33 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2011-11-13 05:34:29 -0500
commit66b693c3b84876d33afd35b9d717d8b9d07384c8 (patch)
treeef47e8bba54045d903dbe28d81eb30f78e127330 /drivers/net/wireless/ath/ath6kl/sdio.c
parentbd24a50fe66ef1f64a84a3d02e0f464bb394bb9b (diff)
ath6kl: move bmi calls to hif driver
In preparation for USB support which has it's own method for bmi. 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.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index beb5f9bf26af..080be036a27e 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -845,6 +845,166 @@ static int ath6kl_sdio_resume(struct ath6kl *ar)
845 return 0; 845 return 0;
846} 846}
847 847
848static int ath6kl_sdio_bmi_credits(struct ath6kl *ar)
849{
850 u32 addr;
851 unsigned long timeout;
852 int ret;
853
854 ar->bmi.cmd_credits = 0;
855
856 /* Read the counter register to get the command credits */
857 addr = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
858
859 timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
860 while (time_before(jiffies, timeout) && !ar->bmi.cmd_credits) {
861
862 /*
863 * Hit the credit counter with a 4-byte access, the first byte
864 * read will hit the counter and cause a decrement, while the
865 * remaining 3 bytes has no effect. The rationale behind this
866 * is to make all HIF accesses 4-byte aligned.
867 */
868 ret = ath6kl_sdio_read_write_sync(ar, addr,
869 (u8 *)&ar->bmi.cmd_credits, 4,
870 HIF_RD_SYNC_BYTE_INC);
871 if (ret) {
872 ath6kl_err("Unable to decrement the command credit "
873 "count register: %d\n", ret);
874 return ret;
875 }
876
877 /* The counter is only 8 bits.
878 * Ignore anything in the upper 3 bytes
879 */
880 ar->bmi.cmd_credits &= 0xFF;
881 }
882
883 if (!ar->bmi.cmd_credits) {
884 ath6kl_err("bmi communication timeout\n");
885 return -ETIMEDOUT;
886 }
887
888 return 0;
889}
890
891static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar)
892{
893 unsigned long timeout;
894 u32 rx_word = 0;
895 int ret = 0;
896
897 timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
898 while ((time_before(jiffies, timeout)) && !rx_word) {
899 ret = ath6kl_sdio_read_write_sync(ar,
900 RX_LOOKAHEAD_VALID_ADDRESS,
901 (u8 *)&rx_word, sizeof(rx_word),
902 HIF_RD_SYNC_BYTE_INC);
903 if (ret) {
904 ath6kl_err("unable to read RX_LOOKAHEAD_VALID\n");
905 return ret;
906 }
907
908 /* all we really want is one bit */
909 rx_word &= (1 << ENDPOINT1);
910 }
911
912 if (!rx_word) {
913 ath6kl_err("bmi_recv_buf FIFO empty\n");
914 return -EINVAL;
915 }
916
917 return ret;
918}
919
920static int ath6kl_sdio_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
921{
922 int ret;
923 u32 addr;
924
925 ret = ath6kl_sdio_bmi_credits(ar);
926 if (ret)
927 return ret;
928
929 addr = ar->mbox_info.htc_addr;
930
931 ret = ath6kl_sdio_read_write_sync(ar, addr, buf, len,
932 HIF_WR_SYNC_BYTE_INC);
933 if (ret)
934 ath6kl_err("unable to send the bmi data to the device\n");
935
936 return ret;
937}
938
939static int ath6kl_sdio_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
940{
941 int ret;
942 u32 addr;
943
944 /*
945 * During normal bootup, small reads may be required.
946 * Rather than issue an HIF Read and then wait as the Target
947 * adds successive bytes to the FIFO, we wait here until
948 * we know that response data is available.
949 *
950 * This allows us to cleanly timeout on an unexpected
951 * Target failure rather than risk problems at the HIF level.
952 * In particular, this avoids SDIO timeouts and possibly garbage
953 * data on some host controllers. And on an interconnect
954 * such as Compact Flash (as well as some SDIO masters) which
955 * does not provide any indication on data timeout, it avoids
956 * a potential hang or garbage response.
957 *
958 * Synchronization is more difficult for reads larger than the
959 * size of the MBOX FIFO (128B), because the Target is unable
960 * to push the 129th byte of data until AFTER the Host posts an
961 * HIF Read and removes some FIFO data. So for large reads the
962 * Host proceeds to post an HIF Read BEFORE all the data is
963 * actually available to read. Fortunately, large BMI reads do
964 * not occur in practice -- they're supported for debug/development.
965 *
966 * So Host/Target BMI synchronization is divided into these cases:
967 * CASE 1: length < 4
968 * Should not happen
969 *
970 * CASE 2: 4 <= length <= 128
971 * Wait for first 4 bytes to be in FIFO
972 * If CONSERVATIVE_BMI_READ is enabled, also wait for
973 * a BMI command credit, which indicates that the ENTIRE
974 * response is available in the the FIFO
975 *
976 * CASE 3: length > 128
977 * Wait for the first 4 bytes to be in FIFO
978 *
979 * For most uses, a small timeout should be sufficient and we will
980 * usually see a response quickly; but there may be some unusual
981 * (debug) cases of BMI_EXECUTE where we want an larger timeout.
982 * For now, we use an unbounded busy loop while waiting for
983 * BMI_EXECUTE.
984 *
985 * If BMI_EXECUTE ever needs to support longer-latency execution,
986 * especially in production, this code needs to be enhanced to sleep
987 * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently
988 * a function of Host processor speed.
989 */
990 if (len >= 4) { /* NB: Currently, always true */
991 ret = ath6kl_bmi_get_rx_lkahd(ar);
992 if (ret)
993 return ret;
994 }
995
996 addr = ar->mbox_info.htc_addr;
997 ret = ath6kl_sdio_read_write_sync(ar, addr, buf, len,
998 HIF_RD_SYNC_BYTE_INC);
999 if (ret) {
1000 ath6kl_err("Unable to read the bmi data from the device: %d\n",
1001 ret);
1002 return ret;
1003 }
1004
1005 return 0;
1006}
1007
848static void ath6kl_sdio_stop(struct ath6kl *ar) 1008static void ath6kl_sdio_stop(struct ath6kl *ar)
849{ 1009{
850 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); 1010 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
@@ -889,6 +1049,8 @@ static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
889 .cleanup_scatter = ath6kl_sdio_cleanup_scatter, 1049 .cleanup_scatter = ath6kl_sdio_cleanup_scatter,
890 .suspend = ath6kl_sdio_suspend, 1050 .suspend = ath6kl_sdio_suspend,
891 .resume = ath6kl_sdio_resume, 1051 .resume = ath6kl_sdio_resume,
1052 .bmi_read = ath6kl_sdio_bmi_read,
1053 .bmi_write = ath6kl_sdio_bmi_write,
892 .power_on = ath6kl_sdio_power_on, 1054 .power_on = ath6kl_sdio_power_on,
893 .power_off = ath6kl_sdio_power_off, 1055 .power_off = ath6kl_sdio_power_off,
894 .stop = ath6kl_sdio_stop, 1056 .stop = ath6kl_sdio_stop,