1d27a76faSLarry Finger // SPDX-License-Identifier: GPL-2.0
2d27a76faSLarry Finger /* Copyright(c) 2009-2012 Realtek Corporation.*/
3d27a76faSLarry Finger
4f1d2b4d3SLarry Finger #include "wifi.h"
5f1d2b4d3SLarry Finger #include "cam.h"
6f1d2b4d3SLarry Finger #include <linux/export.h>
7f1d2b4d3SLarry Finger
rtl_cam_reset_sec_info(struct ieee80211_hw * hw)8f1d2b4d3SLarry Finger void rtl_cam_reset_sec_info(struct ieee80211_hw *hw)
9f1d2b4d3SLarry Finger {
10f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
11f1d2b4d3SLarry Finger
12f1d2b4d3SLarry Finger rtlpriv->sec.use_defaultkey = false;
13f1d2b4d3SLarry Finger rtlpriv->sec.pairwise_enc_algorithm = NO_ENCRYPTION;
14f1d2b4d3SLarry Finger rtlpriv->sec.group_enc_algorithm = NO_ENCRYPTION;
15f1d2b4d3SLarry Finger memset(rtlpriv->sec.key_buf, 0, KEY_BUF_SIZE * MAX_KEY_LEN);
16f1d2b4d3SLarry Finger memset(rtlpriv->sec.key_len, 0, KEY_BUF_SIZE);
17f1d2b4d3SLarry Finger rtlpriv->sec.pairwise_key = NULL;
18f1d2b4d3SLarry Finger }
19f1d2b4d3SLarry Finger
rtl_cam_program_entry(struct ieee80211_hw * hw,u32 entry_no,u8 * mac_addr,u8 * key_cont_128,u16 us_config)20f1d2b4d3SLarry Finger static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no,
21f1d2b4d3SLarry Finger u8 *mac_addr, u8 *key_cont_128, u16 us_config)
22f1d2b4d3SLarry Finger {
23f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
24f1d2b4d3SLarry Finger
25f1d2b4d3SLarry Finger u32 target_command;
26f1d2b4d3SLarry Finger u32 target_content = 0;
271e75622cSPing-Ke Shih int entry_i;
28f1d2b4d3SLarry Finger
29f1d2b4d3SLarry Finger RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_DMESG, "Key content :",
30f1d2b4d3SLarry Finger key_cont_128, 16);
31f1d2b4d3SLarry Finger
321e75622cSPing-Ke Shih /* 0-1 config + mac, 2-5 fill 128key,6-7 are reserved */
331e75622cSPing-Ke Shih for (entry_i = CAM_CONTENT_COUNT - 1; entry_i >= 0; entry_i--) {
34f1d2b4d3SLarry Finger target_command = entry_i + CAM_CONTENT_COUNT * entry_no;
35f1d2b4d3SLarry Finger target_command = target_command | BIT(31) | BIT(16);
36f1d2b4d3SLarry Finger
37f1d2b4d3SLarry Finger if (entry_i == 0) {
38f1d2b4d3SLarry Finger target_content = (u32) (*(mac_addr + 0)) << 16 |
39f1d2b4d3SLarry Finger (u32) (*(mac_addr + 1)) << 24 | (u32) us_config;
40f1d2b4d3SLarry Finger
41f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
42f1d2b4d3SLarry Finger target_content);
43f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
44f1d2b4d3SLarry Finger target_command);
45f1d2b4d3SLarry Finger
46f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD,
47f1d2b4d3SLarry Finger "WRITE %x: %x\n",
48f1d2b4d3SLarry Finger rtlpriv->cfg->maps[WCAMI], target_content);
49f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD,
50f1d2b4d3SLarry Finger "The Key ID is %d\n", entry_no);
51f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD,
52f1d2b4d3SLarry Finger "WRITE %x: %x\n",
53f1d2b4d3SLarry Finger rtlpriv->cfg->maps[RWCAM], target_command);
54f1d2b4d3SLarry Finger
55f1d2b4d3SLarry Finger } else if (entry_i == 1) {
56f1d2b4d3SLarry Finger
57f1d2b4d3SLarry Finger target_content = (u32) (*(mac_addr + 5)) << 24 |
58f1d2b4d3SLarry Finger (u32) (*(mac_addr + 4)) << 16 |
59f1d2b4d3SLarry Finger (u32) (*(mac_addr + 3)) << 8 |
60f1d2b4d3SLarry Finger (u32) (*(mac_addr + 2));
61f1d2b4d3SLarry Finger
62f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
63f1d2b4d3SLarry Finger target_content);
64f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
65f1d2b4d3SLarry Finger target_command);
66f1d2b4d3SLarry Finger
67f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD,
68f1d2b4d3SLarry Finger "WRITE A4: %x\n", target_content);
69f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD,
70f1d2b4d3SLarry Finger "WRITE A0: %x\n", target_command);
71f1d2b4d3SLarry Finger
72f1d2b4d3SLarry Finger } else {
73f1d2b4d3SLarry Finger
74f1d2b4d3SLarry Finger target_content =
75f1d2b4d3SLarry Finger (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 3)) <<
76f1d2b4d3SLarry Finger 24 | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 2))
77f1d2b4d3SLarry Finger << 16 |
78f1d2b4d3SLarry Finger (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 1)) << 8
79f1d2b4d3SLarry Finger | (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 0));
80f1d2b4d3SLarry Finger
81f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI],
82f1d2b4d3SLarry Finger target_content);
83f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
84f1d2b4d3SLarry Finger target_command);
85f1d2b4d3SLarry Finger
86f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD,
87f1d2b4d3SLarry Finger "WRITE A4: %x\n", target_content);
88f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD,
89f1d2b4d3SLarry Finger "WRITE A0: %x\n", target_command);
90f1d2b4d3SLarry Finger }
91f1d2b4d3SLarry Finger }
92f1d2b4d3SLarry Finger
93f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD,
94f1d2b4d3SLarry Finger "after set key, usconfig:%x\n", us_config);
95f1d2b4d3SLarry Finger }
96f1d2b4d3SLarry Finger
rtl_cam_add_one_entry(struct ieee80211_hw * hw,u8 * mac_addr,u32 ul_key_id,u32 ul_entry_idx,u32 ul_enc_alg,u32 ul_default_key,u8 * key_content)97f1d2b4d3SLarry Finger u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr,
98f1d2b4d3SLarry Finger u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg,
99f1d2b4d3SLarry Finger u32 ul_default_key, u8 *key_content)
100f1d2b4d3SLarry Finger {
101f1d2b4d3SLarry Finger u32 us_config;
102f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
103f1d2b4d3SLarry Finger
104f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
105f1d2b4d3SLarry Finger "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n",
106f1d2b4d3SLarry Finger ul_entry_idx, ul_key_id, ul_enc_alg,
107f1d2b4d3SLarry Finger ul_default_key, mac_addr);
108f1d2b4d3SLarry Finger
109f1d2b4d3SLarry Finger if (ul_key_id == TOTAL_CAM_ENTRY) {
110f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
111f1d2b4d3SLarry Finger "ulKeyId exceed!\n");
112f1d2b4d3SLarry Finger return 0;
113f1d2b4d3SLarry Finger }
114f1d2b4d3SLarry Finger
115f1d2b4d3SLarry Finger if (ul_default_key == 1)
116f1d2b4d3SLarry Finger us_config = CFG_VALID | ((u16) (ul_enc_alg) << 2);
117f1d2b4d3SLarry Finger else
118f1d2b4d3SLarry Finger us_config = CFG_VALID | ((ul_enc_alg) << 2) | ul_key_id;
119f1d2b4d3SLarry Finger
120f1d2b4d3SLarry Finger rtl_cam_program_entry(hw, ul_entry_idx, mac_addr,
121f1d2b4d3SLarry Finger (u8 *)key_content, us_config);
122f1d2b4d3SLarry Finger
123f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "end\n");
124f1d2b4d3SLarry Finger
125f1d2b4d3SLarry Finger return 1;
126f1d2b4d3SLarry Finger
127f1d2b4d3SLarry Finger }
128f1d2b4d3SLarry Finger EXPORT_SYMBOL(rtl_cam_add_one_entry);
129f1d2b4d3SLarry Finger
rtl_cam_delete_one_entry(struct ieee80211_hw * hw,u8 * mac_addr,u32 ul_key_id)130f1d2b4d3SLarry Finger int rtl_cam_delete_one_entry(struct ieee80211_hw *hw,
131f1d2b4d3SLarry Finger u8 *mac_addr, u32 ul_key_id)
132f1d2b4d3SLarry Finger {
133f1d2b4d3SLarry Finger u32 ul_command;
134f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
135f1d2b4d3SLarry Finger
136f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id);
137f1d2b4d3SLarry Finger
138f1d2b4d3SLarry Finger ul_command = ul_key_id * CAM_CONTENT_COUNT;
139f1d2b4d3SLarry Finger ul_command = ul_command | BIT(31) | BIT(16);
140f1d2b4d3SLarry Finger
141f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], 0);
142f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
143f1d2b4d3SLarry Finger
144f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
145f108a420SLarry Finger "%s: WRITE A4: %x\n", __func__, 0);
146f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
147f108a420SLarry Finger "%s: WRITE A0: %x\n", __func__, ul_command);
148f1d2b4d3SLarry Finger
149f1d2b4d3SLarry Finger return 0;
150f1d2b4d3SLarry Finger
151f1d2b4d3SLarry Finger }
152f1d2b4d3SLarry Finger EXPORT_SYMBOL(rtl_cam_delete_one_entry);
153f1d2b4d3SLarry Finger
rtl_cam_reset_all_entry(struct ieee80211_hw * hw)154f1d2b4d3SLarry Finger void rtl_cam_reset_all_entry(struct ieee80211_hw *hw)
155f1d2b4d3SLarry Finger {
156f1d2b4d3SLarry Finger u32 ul_command;
157f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
158f1d2b4d3SLarry Finger
159f1d2b4d3SLarry Finger ul_command = BIT(31) | BIT(30);
160f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
161f1d2b4d3SLarry Finger }
162f1d2b4d3SLarry Finger EXPORT_SYMBOL(rtl_cam_reset_all_entry);
163f1d2b4d3SLarry Finger
rtl_cam_mark_invalid(struct ieee80211_hw * hw,u8 uc_index)164f1d2b4d3SLarry Finger void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index)
165f1d2b4d3SLarry Finger {
166f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
167f1d2b4d3SLarry Finger
168f1d2b4d3SLarry Finger u32 ul_command;
169f1d2b4d3SLarry Finger u32 ul_content;
170a9908605SYang Li u32 ul_enc_algo;
171f1d2b4d3SLarry Finger
172f1d2b4d3SLarry Finger switch (rtlpriv->sec.pairwise_enc_algorithm) {
173f1d2b4d3SLarry Finger case WEP40_ENCRYPTION:
174f1d2b4d3SLarry Finger ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
175f1d2b4d3SLarry Finger break;
176f1d2b4d3SLarry Finger case WEP104_ENCRYPTION:
177f1d2b4d3SLarry Finger ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
178f1d2b4d3SLarry Finger break;
179f1d2b4d3SLarry Finger case TKIP_ENCRYPTION:
180f1d2b4d3SLarry Finger ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
181f1d2b4d3SLarry Finger break;
182f1d2b4d3SLarry Finger case AESCCMP_ENCRYPTION:
183f1d2b4d3SLarry Finger ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
184f1d2b4d3SLarry Finger break;
185f1d2b4d3SLarry Finger default:
186f1d2b4d3SLarry Finger ul_enc_algo = rtlpriv->cfg->maps[SEC_CAM_AES];
187f1d2b4d3SLarry Finger }
188f1d2b4d3SLarry Finger
189f1d2b4d3SLarry Finger ul_content = (uc_index & 3) | ((u16) (ul_enc_algo) << 2);
190f1d2b4d3SLarry Finger
191f1d2b4d3SLarry Finger ul_content |= BIT(15);
192f1d2b4d3SLarry Finger ul_command = CAM_CONTENT_COUNT * uc_index;
193f1d2b4d3SLarry Finger ul_command = ul_command | BIT(31) | BIT(16);
194f1d2b4d3SLarry Finger
195f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
196f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
197f1d2b4d3SLarry Finger
198f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
199f108a420SLarry Finger "%s: WRITE A4: %x\n", __func__, ul_content);
200f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
201f108a420SLarry Finger "%s: WRITE A0: %x\n", __func__, ul_command);
202f1d2b4d3SLarry Finger }
203f1d2b4d3SLarry Finger EXPORT_SYMBOL(rtl_cam_mark_invalid);
204f1d2b4d3SLarry Finger
rtl_cam_empty_entry(struct ieee80211_hw * hw,u8 uc_index)205f1d2b4d3SLarry Finger void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index)
206f1d2b4d3SLarry Finger {
207f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
208f1d2b4d3SLarry Finger
209f1d2b4d3SLarry Finger u32 ul_command;
210f1d2b4d3SLarry Finger u32 ul_content;
211*e80affdeSColin Ian King u32 ul_encalgo;
212f1d2b4d3SLarry Finger u8 entry_i;
213f1d2b4d3SLarry Finger
214f1d2b4d3SLarry Finger switch (rtlpriv->sec.pairwise_enc_algorithm) {
215f1d2b4d3SLarry Finger case WEP40_ENCRYPTION:
216f1d2b4d3SLarry Finger ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP40];
217f1d2b4d3SLarry Finger break;
218f1d2b4d3SLarry Finger case WEP104_ENCRYPTION:
219f1d2b4d3SLarry Finger ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_WEP104];
220f1d2b4d3SLarry Finger break;
221f1d2b4d3SLarry Finger case TKIP_ENCRYPTION:
222f1d2b4d3SLarry Finger ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_TKIP];
223f1d2b4d3SLarry Finger break;
224f1d2b4d3SLarry Finger case AESCCMP_ENCRYPTION:
225f1d2b4d3SLarry Finger ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
226f1d2b4d3SLarry Finger break;
227f1d2b4d3SLarry Finger default:
228f1d2b4d3SLarry Finger ul_encalgo = rtlpriv->cfg->maps[SEC_CAM_AES];
229f1d2b4d3SLarry Finger }
230f1d2b4d3SLarry Finger
231f1d2b4d3SLarry Finger for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) {
232f1d2b4d3SLarry Finger
233f1d2b4d3SLarry Finger if (entry_i == 0) {
234f1d2b4d3SLarry Finger ul_content =
235f1d2b4d3SLarry Finger (uc_index & 0x03) | ((u16) (ul_encalgo) << 2);
236f1d2b4d3SLarry Finger ul_content |= BIT(15);
237f1d2b4d3SLarry Finger
238f1d2b4d3SLarry Finger } else {
239f1d2b4d3SLarry Finger ul_content = 0;
240f1d2b4d3SLarry Finger }
241f1d2b4d3SLarry Finger
242f1d2b4d3SLarry Finger ul_command = CAM_CONTENT_COUNT * uc_index + entry_i;
243f1d2b4d3SLarry Finger ul_command = ul_command | BIT(31) | BIT(16);
244f1d2b4d3SLarry Finger
245f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[WCAMI], ul_content);
246f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command);
247f1d2b4d3SLarry Finger
248f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD,
249f108a420SLarry Finger "%s: WRITE A4: %x\n", __func__, ul_content);
250f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD,
251f108a420SLarry Finger "%s: WRITE A0: %x\n", __func__, ul_command);
252f1d2b4d3SLarry Finger }
253f1d2b4d3SLarry Finger
254f1d2b4d3SLarry Finger }
255f1d2b4d3SLarry Finger EXPORT_SYMBOL(rtl_cam_empty_entry);
256f1d2b4d3SLarry Finger
rtl_cam_get_free_entry(struct ieee80211_hw * hw,u8 * sta_addr)257f1d2b4d3SLarry Finger u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)
258f1d2b4d3SLarry Finger {
259f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
260f1d2b4d3SLarry Finger u32 bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> 4;
261f1d2b4d3SLarry Finger u8 entry_idx = 0;
262f1d2b4d3SLarry Finger u8 i, *addr;
263f1d2b4d3SLarry Finger
264f1d2b4d3SLarry Finger if (NULL == sta_addr) {
265b03d968bSLarry Finger pr_err("sta_addr is NULL.\n");
266f1d2b4d3SLarry Finger return TOTAL_CAM_ENTRY;
267f1d2b4d3SLarry Finger }
268f1d2b4d3SLarry Finger /* Does STA already exist? */
269f1d2b4d3SLarry Finger for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
270f1d2b4d3SLarry Finger addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
271f1d2b4d3SLarry Finger if (ether_addr_equal_unaligned(addr, sta_addr))
272f1d2b4d3SLarry Finger return i;
273f1d2b4d3SLarry Finger }
274f1d2b4d3SLarry Finger /* Get a free CAM entry. */
275f1d2b4d3SLarry Finger for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) {
276f1d2b4d3SLarry Finger if ((bitmap & BIT(0)) == 0) {
277b03d968bSLarry Finger pr_err("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n",
278f1d2b4d3SLarry Finger rtlpriv->sec.hwsec_cam_bitmap, entry_idx);
279f1d2b4d3SLarry Finger rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx;
280f1d2b4d3SLarry Finger memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx],
281f1d2b4d3SLarry Finger sta_addr, ETH_ALEN);
282f1d2b4d3SLarry Finger return entry_idx;
283f1d2b4d3SLarry Finger }
284f1d2b4d3SLarry Finger bitmap = bitmap >> 1;
285f1d2b4d3SLarry Finger }
286f1d2b4d3SLarry Finger return TOTAL_CAM_ENTRY;
287f1d2b4d3SLarry Finger }
288f1d2b4d3SLarry Finger EXPORT_SYMBOL(rtl_cam_get_free_entry);
289f1d2b4d3SLarry Finger
rtl_cam_del_entry(struct ieee80211_hw * hw,u8 * sta_addr)290f1d2b4d3SLarry Finger void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
291f1d2b4d3SLarry Finger {
292f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
293f1d2b4d3SLarry Finger u32 bitmap;
294f1d2b4d3SLarry Finger u8 i, *addr;
295f1d2b4d3SLarry Finger
296f1d2b4d3SLarry Finger if (NULL == sta_addr) {
297b03d968bSLarry Finger pr_err("sta_addr is NULL.\n");
298f1d2b4d3SLarry Finger return;
299f1d2b4d3SLarry Finger }
300f1d2b4d3SLarry Finger
301f1d2b4d3SLarry Finger if (is_zero_ether_addr(sta_addr)) {
302b03d968bSLarry Finger pr_err("sta_addr is %pM\n", sta_addr);
303f1d2b4d3SLarry Finger return;
304f1d2b4d3SLarry Finger }
305f1d2b4d3SLarry Finger /* Does STA already exist? */
306f1d2b4d3SLarry Finger for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
307f1d2b4d3SLarry Finger addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
308f1d2b4d3SLarry Finger bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> i;
309f1d2b4d3SLarry Finger if (((bitmap & BIT(0)) == BIT(0)) &&
310f1d2b4d3SLarry Finger (ether_addr_equal_unaligned(addr, sta_addr))) {
311f1d2b4d3SLarry Finger /* Remove from HW Security CAM */
312f1d2b4d3SLarry Finger eth_zero_addr(rtlpriv->sec.hwsec_cam_sta_addr[i]);
313f1d2b4d3SLarry Finger rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i);
314f108a420SLarry Finger rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG,
315f1d2b4d3SLarry Finger "&&&&&&&&&del entry %d\n", i);
316f1d2b4d3SLarry Finger }
317f1d2b4d3SLarry Finger }
318f1d2b4d3SLarry Finger return;
319f1d2b4d3SLarry Finger }
320f1d2b4d3SLarry Finger EXPORT_SYMBOL(rtl_cam_del_entry);
321