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