diff options
author | Paul Mundt <lethal@linux-sh.org> | 2011-05-24 10:32:20 +0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-05-24 10:32:20 +0400 |
commit | 9fb4c7fbbcb1e947567d13b82e429ae47a46e337 (patch) | |
tree | 6c5f11f347d0f58565381f92680a7a9cc63c0bd8 /drivers/net/wireless/rtlwifi/cam.c | |
parent | dc3e5b6a6e842116ec2436161adf31877f09b6b9 (diff) | |
parent | d762f4383100c2a87b1a3f2d678cd3b5425655b4 (diff) | |
download | linux-9fb4c7fbbcb1e947567d13b82e429ae47a46e337.tar.xz |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/net/wireless/rtlwifi/cam.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/cam.c | 106 |
1 files changed, 85 insertions, 21 deletions
diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index 52c9c1367cac..7295af0536b7 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c @@ -23,6 +23,8 @@ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, * Hsinchu 300, Taiwan. * + * Larry Finger <Larry.Finger@lwfinger.net> + * *****************************************************************************/ #include "wifi.h" @@ -49,7 +51,7 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, u32 target_content = 0; u8 entry_i; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, ("key_cont_128:\n %x:%x:%x:%x:%x:%x\n", key_cont_128[0], key_cont_128[1], key_cont_128[2], key_cont_128[3], @@ -68,15 +70,13 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_program_entry(): " - "WRITE %x: %x\n", + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("WRITE %x: %x\n", rtlpriv->cfg->maps[WCAMI], target_content)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, ("The Key ID is %d\n", entry_no)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_program_entry(): " - "WRITE %x: %x\n", + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("WRITE %x: %x\n", rtlpriv->cfg->maps[RWCAM], target_command)); } else if (entry_i == 1) { @@ -91,12 +91,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_program_entry(): WRITE A4: %x\n", - target_content)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_program_entry(): WRITE A0: %x\n", - target_command)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("WRITE A4: %x\n", target_content)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("WRITE A0: %x\n", target_command)); } else { @@ -113,16 +111,14 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, target_command); udelay(100); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_program_entry(): WRITE A4: %x\n", - target_content)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_program_entry(): WRITE A0: %x\n", - target_command)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("WRITE A4: %x\n", target_content)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + ("WRITE A0: %x\n", target_command)); } } - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, ("after set key, usconfig:%x\n", us_config)); } @@ -289,3 +285,71 @@ void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index) } EXPORT_SYMBOL(rtl_cam_empty_entry); + +u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> 4; + u8 entry_idx = 0; + u8 i, *addr; + + if (NULL == sta_addr) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, + ("sta_addr is NULL.\n")); + return TOTAL_CAM_ENTRY; + } + /* Does STA already exist? */ + for (i = 4; i < TOTAL_CAM_ENTRY; i++) { + addr = rtlpriv->sec.hwsec_cam_sta_addr[i]; + if (memcmp(addr, sta_addr, ETH_ALEN) == 0) + return i; + } + /* Get a free CAM entry. */ + for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) { + if ((bitmap & BIT(0)) == 0) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, + ("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n", + rtlpriv->sec.hwsec_cam_bitmap, entry_idx)); + rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx; + memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx], + sta_addr, ETH_ALEN); + return entry_idx; + } + bitmap = bitmap >> 1; + } + return TOTAL_CAM_ENTRY; +} +EXPORT_SYMBOL(rtl_cam_get_free_entry); + +void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 bitmap; + u8 i, *addr; + + if (NULL == sta_addr) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, + ("sta_addr is NULL.\n")); + } + + if ((sta_addr[0]|sta_addr[1]|sta_addr[2]|sta_addr[3]|\ + sta_addr[4]|sta_addr[5]) == 0) { + RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, + ("sta_addr is 00:00:00:00:00:00.\n")); + return; + } + /* Does STA already exist? */ + for (i = 4; i < TOTAL_CAM_ENTRY; i++) { + addr = rtlpriv->sec.hwsec_cam_sta_addr[i]; + bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> i; + if (((bitmap & BIT(0)) == BIT(0)) && + (memcmp(addr, sta_addr, ETH_ALEN) == 0)) { + /* Remove from HW Security CAM */ + memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN); + rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); + printk(KERN_INFO "&&&&&&&&&del entry %d\n", i); + } + } + return; +} +EXPORT_SYMBOL(rtl_cam_del_entry); |