001-19-v6.9-wifi-rtl8xxxu-add-hw-crypto-support-for-AP-mode.patch 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. From b837f78fbffa5f8e7e7c59879db54793abf161ec Mon Sep 17 00:00:00 2001
  2. From: Martin Kaistra <[email protected]>
  3. Date: Fri, 22 Dec 2023 11:14:40 +0100
  4. Subject: [PATCH 19/21] wifi: rtl8xxxu: add hw crypto support for AP mode
  5. Add a custom function for allocating entries in the sec cam. This allows
  6. us to store multiple keys with the same keyidx.
  7. The maximum number of sec cam entries for 8188f is 16 according to the
  8. vendor driver. Add the number to rtl8xxxu_fileops, so that other chips
  9. which might support more entries, can set a different number there.
  10. Set the bssid as mac address for group keys instead of just using the
  11. ethernet broadcast address and use BIT(6) in the sec cam ctrl entry
  12. for differentiating them from pairwise keys like in the vendor driver.
  13. Add the TXDESC_EN_DESC_ID bit and the hw_key_idx to tx
  14. broadcast/multicast packets in AP mode.
  15. Finally, allow the usage of rtl8xxxu_set_key() for AP mode.
  16. Signed-off-by: Martin Kaistra <[email protected]>
  17. Reviewed-by: Ping-Ke Shih <[email protected]>
  18. Signed-off-by: Kalle Valo <[email protected]>
  19. Link: https://msgid.link/[email protected]
  20. ---
  21. .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 5 ++
  22. .../realtek/rtl8xxxu/rtl8xxxu_8188f.c | 1 +
  23. .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 48 +++++++++++++++----
  24. 3 files changed, 44 insertions(+), 10 deletions(-)
  25. --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
  26. +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
  27. @@ -498,6 +498,7 @@ struct rtl8xxxu_txdesc40 {
  28. #define DESC_RATE_ID_SHIFT 16
  29. #define DESC_RATE_ID_MASK 0xf
  30. #define TXDESC_NAVUSEHDR BIT(20)
  31. +#define TXDESC_EN_DESC_ID BIT(21)
  32. #define TXDESC_SEC_RC4 0x00400000
  33. #define TXDESC_SEC_AES 0x00c00000
  34. #define TXDESC_PKT_OFFSET_SHIFT 26
  35. @@ -1775,6 +1776,7 @@ struct rtl8xxxu_cfo_tracking {
  36. #define RTL8XXXU_MAX_MAC_ID_NUM 128
  37. #define RTL8XXXU_BC_MC_MACID 0
  38. #define RTL8XXXU_BC_MC_MACID1 1
  39. +#define RTL8XXXU_MAX_SEC_CAM_NUM 64
  40. struct rtl8xxxu_priv {
  41. struct ieee80211_hw *hw;
  42. @@ -1908,6 +1910,7 @@ struct rtl8xxxu_priv {
  43. char led_name[32];
  44. struct led_classdev led_cdev;
  45. DECLARE_BITMAP(mac_id_map, RTL8XXXU_MAX_MAC_ID_NUM);
  46. + DECLARE_BITMAP(cam_map, RTL8XXXU_MAX_SEC_CAM_NUM);
  47. };
  48. struct rtl8xxxu_sta_info {
  49. @@ -1919,6 +1922,7 @@ struct rtl8xxxu_sta_info {
  50. struct rtl8xxxu_vif {
  51. int port_num;
  52. + u8 hw_key_idx;
  53. };
  54. struct rtl8xxxu_rx_urb {
  55. @@ -1993,6 +1997,7 @@ struct rtl8xxxu_fileops {
  56. u16 max_aggr_num;
  57. u8 supports_ap:1;
  58. u16 max_macid_num;
  59. + u16 max_sec_cam_num;
  60. u32 adda_1t_init;
  61. u32 adda_1t_path_on;
  62. u32 adda_2t_path_on_a;
  63. --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c
  64. +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188f.c
  65. @@ -1751,6 +1751,7 @@ struct rtl8xxxu_fileops rtl8188fu_fops =
  66. .max_aggr_num = 0x0c14,
  67. .supports_ap = 1,
  68. .max_macid_num = 16,
  69. + .max_sec_cam_num = 16,
  70. .adda_1t_init = 0x03c00014,
  71. .adda_1t_path_on = 0x03c00014,
  72. .trxff_boundary = 0x3f7f,
  73. --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
  74. +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
  75. @@ -4559,8 +4559,10 @@ static void rtl8xxxu_cam_write(struct rt
  76. * This is a bit of a hack - the lower bits of the cipher
  77. * suite selector happens to match the cipher index in the CAM
  78. */
  79. - addr = key->keyidx << CAM_CMD_KEY_SHIFT;
  80. + addr = key->hw_key_idx << CAM_CMD_KEY_SHIFT;
  81. ctrl = (key->cipher & 0x0f) << 2 | key->keyidx | CAM_WRITE_VALID;
  82. + if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
  83. + ctrl |= BIT(6);
  84. for (j = 5; j >= 0; j--) {
  85. switch (j) {
  86. @@ -5546,13 +5548,14 @@ static void rtl8xxxu_tx(struct ieee80211
  87. struct rtl8xxxu_tx_urb *tx_urb;
  88. struct ieee80211_sta *sta = NULL;
  89. struct ieee80211_vif *vif = tx_info->control.vif;
  90. + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
  91. struct device *dev = &priv->udev->dev;
  92. u32 queue, rts_rate;
  93. u16 pktlen = skb->len;
  94. int tx_desc_size = priv->fops->tx_desc_size;
  95. u8 macid;
  96. int ret;
  97. - bool ampdu_enable, sgi = false, short_preamble = false;
  98. + bool ampdu_enable, sgi = false, short_preamble = false, bmc = false;
  99. if (skb_headroom(skb) < tx_desc_size) {
  100. dev_warn(dev,
  101. @@ -5594,10 +5597,14 @@ static void rtl8xxxu_tx(struct ieee80211
  102. tx_desc->txdw0 =
  103. TXDESC_OWN | TXDESC_FIRST_SEGMENT | TXDESC_LAST_SEGMENT;
  104. if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
  105. - is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
  106. + is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
  107. tx_desc->txdw0 |= TXDESC_BROADMULTICAST;
  108. + bmc = true;
  109. + }
  110. +
  111. tx_desc->txdw1 = cpu_to_le32(queue << TXDESC_QUEUE_SHIFT);
  112. + macid = rtl8xxxu_get_macid(priv, sta);
  113. if (tx_info->control.hw_key) {
  114. switch (tx_info->control.hw_key->cipher) {
  115. @@ -5612,6 +5619,10 @@ static void rtl8xxxu_tx(struct ieee80211
  116. default:
  117. break;
  118. }
  119. + if (bmc && rtlvif->hw_key_idx != 0xff) {
  120. + tx_desc->txdw1 |= TXDESC_EN_DESC_ID;
  121. + macid = rtlvif->hw_key_idx;
  122. + }
  123. }
  124. /* (tx_info->flags & IEEE80211_TX_CTL_AMPDU) && */
  125. @@ -5655,7 +5666,6 @@ static void rtl8xxxu_tx(struct ieee80211
  126. else
  127. rts_rate = 0;
  128. - macid = rtl8xxxu_get_macid(priv, sta);
  129. priv->fops->fill_txdesc(hw, hdr, tx_info, tx_desc, sgi, short_preamble,
  130. ampdu_enable, rts_rate, macid);
  131. @@ -6667,6 +6677,7 @@ static int rtl8xxxu_add_interface(struct
  132. priv->vifs[port_num] = vif;
  133. rtlvif->port_num = port_num;
  134. + rtlvif->hw_key_idx = 0xff;
  135. rtl8xxxu_set_linktype(priv, vif->type, port_num);
  136. ether_addr_copy(priv->mac_addr, vif->addr);
  137. @@ -6843,11 +6854,19 @@ static int rtl8xxxu_set_rts_threshold(st
  138. return 0;
  139. }
  140. +static int rtl8xxxu_get_free_sec_cam(struct ieee80211_hw *hw)
  141. +{
  142. + struct rtl8xxxu_priv *priv = hw->priv;
  143. +
  144. + return find_first_zero_bit(priv->cam_map, priv->fops->max_sec_cam_num);
  145. +}
  146. +
  147. static int rtl8xxxu_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
  148. struct ieee80211_vif *vif,
  149. struct ieee80211_sta *sta,
  150. struct ieee80211_key_conf *key)
  151. {
  152. + struct rtl8xxxu_vif *rtlvif = (struct rtl8xxxu_vif *)vif->drv_priv;
  153. struct rtl8xxxu_priv *priv = hw->priv;
  154. struct device *dev = &priv->udev->dev;
  155. u8 mac_addr[ETH_ALEN];
  156. @@ -6859,9 +6878,6 @@ static int rtl8xxxu_set_key(struct ieee8
  157. dev_dbg(dev, "%s: cmd %02x, cipher %08x, index %i\n",
  158. __func__, cmd, key->cipher, key->keyidx);
  159. - if (vif->type != NL80211_IFTYPE_STATION)
  160. - return -EOPNOTSUPP;
  161. -
  162. if (key->keyidx > 3)
  163. return -EOPNOTSUPP;
  164. @@ -6885,7 +6901,7 @@ static int rtl8xxxu_set_key(struct ieee8
  165. ether_addr_copy(mac_addr, sta->addr);
  166. } else {
  167. dev_dbg(dev, "%s: group key\n", __func__);
  168. - eth_broadcast_addr(mac_addr);
  169. + ether_addr_copy(mac_addr, vif->bss_conf.bssid);
  170. }
  171. val16 = rtl8xxxu_read16(priv, REG_CR);
  172. @@ -6899,16 +6915,28 @@ static int rtl8xxxu_set_key(struct ieee8
  173. switch (cmd) {
  174. case SET_KEY:
  175. - key->hw_key_idx = key->keyidx;
  176. +
  177. + retval = rtl8xxxu_get_free_sec_cam(hw);
  178. + if (retval < 0)
  179. + return -EOPNOTSUPP;
  180. +
  181. + key->hw_key_idx = retval;
  182. +
  183. + if (vif->type == NL80211_IFTYPE_AP && !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
  184. + rtlvif->hw_key_idx = key->hw_key_idx;
  185. +
  186. key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
  187. rtl8xxxu_cam_write(priv, key, mac_addr);
  188. + set_bit(key->hw_key_idx, priv->cam_map);
  189. retval = 0;
  190. break;
  191. case DISABLE_KEY:
  192. rtl8xxxu_write32(priv, REG_CAM_WRITE, 0x00000000);
  193. val32 = CAM_CMD_POLLING | CAM_CMD_WRITE |
  194. - key->keyidx << CAM_CMD_KEY_SHIFT;
  195. + key->hw_key_idx << CAM_CMD_KEY_SHIFT;
  196. rtl8xxxu_write32(priv, REG_CAM_CMD, val32);
  197. + rtlvif->hw_key_idx = 0xff;
  198. + clear_bit(key->hw_key_idx, priv->cam_map);
  199. retval = 0;
  200. break;
  201. default: