600-0004-rt2x00-rt2800lib-fix-beacon-generation-on-RT3593.patch 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. From dcfe3dd46242050f100162dce2bcad24d2c942c6 Mon Sep 17 00:00:00 2001
  2. From: Gabor Juhos <juhosg@openwrt.org>
  3. Date: Sat, 17 Aug 2013 19:31:42 +0200
  4. Subject: [PATCH] rt2x00: rt2800lib: fix beacon generation on RT3593
  5. On the RT3593 chipset, the beacon registers are located
  6. in the high 8KB part of the shared memory.
  7. The high part of the shared memory is only accessible
  8. if it is explicitly selected. Add a helper function
  9. in order to be able to control the SHR_MSEL bit in
  10. the PBF_SYS_CTRL register. Also add a few more helper
  11. functions and use those to select the correct part of
  12. the shared memory before and after accessing the beacon
  13. registers.
  14. The base addresses of the beacon registers are also
  15. different from the actually used values, so fix the
  16. 'rt2800_hw_beacon_base' function to return the correct
  17. values.
  18. Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
  19. ---
  20. Changes since v1: ---
  21. ---
  22. drivers/net/wireless/ralink/rt2x00/rt2800.h | 3 +++
  23. drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 44 +++++++++++++++++++++++++++++++
  24. 2 files changed, 47 insertions(+)
  25. --- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
  26. +++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
  27. @@ -574,6 +574,7 @@
  28. #define PBF_SYS_CTRL 0x0400
  29. #define PBF_SYS_CTRL_READY FIELD32(0x00000080)
  30. #define PBF_SYS_CTRL_HOST_RAM_WRITE FIELD32(0x00010000)
  31. +#define PBF_SYS_CTRL_SHR_MSEL FIELD32(0x00080000)
  32. /*
  33. * HOST-MCU shared memory
  34. @@ -2026,6 +2027,8 @@ struct mac_iveiv_entry {
  35. (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \
  36. (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))))
  37. +#define HW_BEACON_BASE_HIGH(__index) (0x4000 + (__index) * 512)
  38. +
  39. #define BEACON_BASE_TO_OFFSET(_base) (((_base) - 0x4000) / 64)
  40. /*
  41. --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
  42. +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
  43. @@ -82,6 +82,39 @@ static inline bool rt2800_is_305x_soc(st
  44. return false;
  45. }
  46. +static inline void rt2800_shared_mem_select(struct rt2x00_dev *rt2x00dev,
  47. + bool high)
  48. +{
  49. + u32 reg;
  50. +
  51. + if (WARN_ON_ONCE(!rt2800_has_high_shared_mem(rt2x00dev)))
  52. + return;
  53. +
  54. + rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
  55. + rt2x00_set_field32(&reg, PBF_SYS_CTRL_SHR_MSEL, high);
  56. + rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
  57. +}
  58. +
  59. +static inline bool rt2800_beacon_uses_high_mem(struct rt2x00_dev *rt2x00dev)
  60. +{
  61. + if (rt2x00_rt(rt2x00dev, RT3593))
  62. + return true;
  63. +
  64. + return false;
  65. +}
  66. +
  67. +static inline void rt2800_select_beacon_mem(struct rt2x00_dev *rt2x00dev)
  68. +{
  69. + if (rt2800_beacon_uses_high_mem(rt2x00dev))
  70. + rt2800_shared_mem_select(rt2x00dev, true);
  71. +}
  72. +
  73. +static inline void rt2800_deselect_beacon_mem(struct rt2x00_dev *rt2x00dev)
  74. +{
  75. + if (rt2800_beacon_uses_high_mem(rt2x00dev))
  76. + rt2800_shared_mem_select(rt2x00dev, false);
  77. +}
  78. +
  79. static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev,
  80. const unsigned int word, const u8 value)
  81. {
  82. @@ -948,6 +981,9 @@ EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
  83. static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
  84. unsigned int index)
  85. {
  86. + if (rt2x00_rt(rt2x00dev, RT3593))
  87. + return HW_BEACON_BASE_HIGH(index);
  88. +
  89. return HW_BEACON_BASE(index);
  90. }
  91. @@ -1046,8 +1082,12 @@ void rt2800_write_beacon(struct queue_en
  92. beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx);
  93. rt2800_shared_mem_lock(rt2x00dev);
  94. +
  95. + rt2800_select_beacon_mem(rt2x00dev);
  96. rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
  97. entry->skb->len + padding_len);
  98. + rt2800_deselect_beacon_mem(rt2x00dev);
  99. +
  100. rt2800_shared_mem_unlock(rt2x00dev);
  101. __set_bit(ENTRY_BCN_ENABLED, &entry->flags);
  102. @@ -1080,6 +1120,8 @@ static inline void rt2800_clear_beacon_r
  103. rt2800_shared_mem_lock(rt2x00dev);
  104. + rt2800_select_beacon_mem(rt2x00dev);
  105. +
  106. /*
  107. * For the Beacon base registers we only need to clear
  108. * the whole TXWI which (when set to 0) will invalidate
  109. @@ -1088,6 +1130,8 @@ static inline void rt2800_clear_beacon_r
  110. for (i = 0; i < txwi_desc_size; i += sizeof(__le32))
  111. rt2800_register_write(rt2x00dev, beacon_base + i, 0);
  112. + rt2800_deselect_beacon_mem(rt2x00dev);
  113. +
  114. rt2800_shared_mem_unlock(rt2x00dev);
  115. }