root/drivers/staging/rtl8188eu/core/rtw_sta_mgt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _rtw_init_stainfo
  2. _rtw_init_sta_priv
  3. rtw_stainfo_offset
  4. rtw_get_stainfo_by_offset
  5. _rtw_free_sta_priv
  6. rtw_alloc_stainfo
  7. rtw_free_stainfo
  8. rtw_free_all_stainfo
  9. rtw_get_stainfo
  10. rtw_init_bcmc_stainfo
  11. rtw_get_bcmc_stainfo
  12. rtw_access_ctrl

   1 // SPDX-License-Identifier: GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
   5  *
   6  ******************************************************************************/
   7 #define _RTW_STA_MGT_C_
   8 
   9 #include <osdep_service.h>
  10 #include <drv_types.h>
  11 #include <recv_osdep.h>
  12 #include <xmit_osdep.h>
  13 #include <mlme_osdep.h>
  14 #include <sta_info.h>
  15 #include <linux/vmalloc.h>
  16 
  17 static void _rtw_init_stainfo(struct sta_info *psta)
  18 {
  19         memset((u8 *)psta, 0, sizeof(struct sta_info));
  20 
  21         spin_lock_init(&psta->lock);
  22         INIT_LIST_HEAD(&psta->list);
  23         INIT_LIST_HEAD(&psta->hash_list);
  24         _rtw_init_queue(&psta->sleep_q);
  25         psta->sleepq_len = 0;
  26 
  27         _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
  28         _rtw_init_sta_recv_priv(&psta->sta_recvpriv);
  29 
  30 #ifdef CONFIG_88EU_AP_MODE
  31 
  32         INIT_LIST_HEAD(&psta->asoc_list);
  33 
  34         INIT_LIST_HEAD(&psta->auth_list);
  35 
  36         psta->expire_to = 0;
  37 
  38         psta->flags = 0;
  39 
  40         psta->capability = 0;
  41 
  42         psta->bpairwise_key_installed = false;
  43 
  44         psta->nonerp_set = 0;
  45         psta->no_short_slot_time_set = 0;
  46         psta->no_short_preamble_set = 0;
  47         psta->no_ht_gf_set = 0;
  48         psta->no_ht_set = 0;
  49         psta->ht_20mhz_set = 0;
  50 
  51         psta->under_exist_checking = 0;
  52 
  53         psta->keep_alive_trycnt = 0;
  54 
  55 #endif  /*  CONFIG_88EU_AP_MODE */
  56 }
  57 
  58 u32 _rtw_init_sta_priv(struct sta_priv *pstapriv)
  59 {
  60         struct sta_info *psta;
  61         s32 i;
  62 
  63         pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * NUM_STA + 4);
  64 
  65         if (!pstapriv->pallocated_stainfo_buf)
  66                 return _FAIL;
  67 
  68         pstapriv->pstainfo_buf = pstapriv->pallocated_stainfo_buf + 4 -
  69                 ((size_t)(pstapriv->pallocated_stainfo_buf) & 3);
  70 
  71         _rtw_init_queue(&pstapriv->free_sta_queue);
  72 
  73         spin_lock_init(&pstapriv->sta_hash_lock);
  74 
  75         pstapriv->asoc_sta_count = 0;
  76         _rtw_init_queue(&pstapriv->sleep_q);
  77         _rtw_init_queue(&pstapriv->wakeup_q);
  78 
  79         psta = (struct sta_info *)(pstapriv->pstainfo_buf);
  80 
  81         for (i = 0; i < NUM_STA; i++) {
  82                 _rtw_init_stainfo(psta);
  83 
  84                 INIT_LIST_HEAD(&pstapriv->sta_hash[i]);
  85 
  86                 list_add_tail(&psta->list, get_list_head(&pstapriv->free_sta_queue));
  87 
  88                 psta++;
  89         }
  90 
  91 #ifdef CONFIG_88EU_AP_MODE
  92 
  93         pstapriv->sta_dz_bitmap = 0;
  94         pstapriv->tim_bitmap = 0;
  95 
  96         INIT_LIST_HEAD(&pstapriv->asoc_list);
  97         INIT_LIST_HEAD(&pstapriv->auth_list);
  98         spin_lock_init(&pstapriv->asoc_list_lock);
  99         spin_lock_init(&pstapriv->auth_list_lock);
 100         pstapriv->asoc_list_cnt = 0;
 101         pstapriv->auth_list_cnt = 0;
 102 
 103         pstapriv->auth_to = 3; /*  3*2 = 6 sec */
 104         pstapriv->assoc_to = 3;
 105         pstapriv->expire_to = 3; /*  3*2 = 6 sec */
 106         pstapriv->max_num_sta = NUM_STA;
 107 #endif
 108 
 109         return _SUCCESS;
 110 }
 111 
 112 inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta)
 113 {
 114         int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct sta_info);
 115 
 116         if (!stainfo_offset_valid(offset))
 117                 DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset);
 118 
 119         return offset;
 120 }
 121 
 122 inline struct sta_info *rtw_get_stainfo_by_offset(struct sta_priv *stapriv, int offset)
 123 {
 124         if (!stainfo_offset_valid(offset))
 125                 DBG_88E("%s invalid offset(%d), out of range!!!", __func__, offset);
 126 
 127         return (struct sta_info *)(stapriv->pstainfo_buf + offset * sizeof(struct sta_info));
 128 }
 129 
 130 u32 _rtw_free_sta_priv(struct sta_priv *pstapriv)
 131 {
 132         struct list_head *phead, *plist;
 133         struct sta_info *psta = NULL;
 134         struct recv_reorder_ctrl *preorder_ctrl;
 135         int index;
 136 
 137         if (pstapriv) {
 138                 /* delete all reordering_ctrl_timer */
 139                 spin_lock_bh(&pstapriv->sta_hash_lock);
 140                 for (index = 0; index < NUM_STA; index++) {
 141                         phead = &pstapriv->sta_hash[index];
 142                         plist = phead->next;
 143 
 144                         while (phead != plist) {
 145                                 int i;
 146 
 147                                 psta = container_of(plist, struct sta_info,
 148                                                     hash_list);
 149                                 plist = plist->next;
 150 
 151                                 for (i = 0; i < 16; i++) {
 152                                         preorder_ctrl = &psta->recvreorder_ctrl[i];
 153                                         del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
 154                                 }
 155                         }
 156                 }
 157                 spin_unlock_bh(&pstapriv->sta_hash_lock);
 158                 /*===============================*/
 159 
 160                 vfree(pstapriv->pallocated_stainfo_buf);
 161         }
 162 
 163         return _SUCCESS;
 164 }
 165 
 166 struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
 167 {
 168         s32 index;
 169         struct list_head *phash_list;
 170         struct sta_info *psta;
 171         struct __queue *pfree_sta_queue;
 172         struct recv_reorder_ctrl *preorder_ctrl;
 173         int i = 0;
 174         u16 wRxSeqInitialValue = 0xffff;
 175 
 176         pfree_sta_queue = &pstapriv->free_sta_queue;
 177 
 178         spin_lock_bh(&pfree_sta_queue->lock);
 179         psta = list_first_entry_or_null(&pfree_sta_queue->queue,
 180                                         struct sta_info, list);
 181         if (!psta) {
 182                 spin_unlock_bh(&pfree_sta_queue->lock);
 183         } else {
 184                 list_del_init(&psta->list);
 185                 spin_unlock_bh(&pfree_sta_queue->lock);
 186                 _rtw_init_stainfo(psta);
 187                 memcpy(psta->hwaddr, hwaddr, ETH_ALEN);
 188                 index = wifi_mac_hash(hwaddr);
 189                 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_, ("%s: index=%x", __func__, index));
 190                 if (index >= NUM_STA) {
 191                         RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("ERROR => %s: index >= NUM_STA", __func__));
 192                         psta = NULL;
 193                         goto exit;
 194                 }
 195                 phash_list = &pstapriv->sta_hash[index];
 196 
 197                 spin_lock_bh(&pstapriv->sta_hash_lock);
 198                 list_add_tail(&psta->hash_list, phash_list);
 199                 pstapriv->asoc_sta_count++;
 200                 spin_unlock_bh(&pstapriv->sta_hash_lock);
 201 
 202 /*  Commented by Albert 2009/08/13 */
 203 /*  For the SMC router, the sequence number of first packet of WPS handshake will be 0. */
 204 /*  In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable. */
 205 /*  So, we initialize the tid_rxseq variable as the 0xffff. */
 206 
 207                 for (i = 0; i < 16; i++)
 208                         memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2);
 209 
 210                 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_info_,
 211                          ("alloc number_%d stainfo  with hwaddr = %pM\n",
 212                          pstapriv->asoc_sta_count, hwaddr));
 213 
 214                 init_addba_retry_timer(pstapriv->padapter, psta);
 215 
 216                 /* for A-MPDU Rx reordering buffer control */
 217                 for (i = 0; i < 16; i++) {
 218                         preorder_ctrl = &psta->recvreorder_ctrl[i];
 219 
 220                         preorder_ctrl->padapter = pstapriv->padapter;
 221 
 222                         preorder_ctrl->enable = false;
 223 
 224                         preorder_ctrl->indicate_seq = 0xffff;
 225                         preorder_ctrl->wend_b = 0xffff;
 226                         preorder_ctrl->wsize_b = 64;/* 64; */
 227 
 228                         _rtw_init_queue(&preorder_ctrl->pending_recvframe_queue);
 229 
 230                         rtw_init_recv_timer(preorder_ctrl);
 231                 }
 232 
 233                 /* init for DM */
 234                 psta->rssi_stat.UndecoratedSmoothedPWDB = -1;
 235                 psta->rssi_stat.UndecoratedSmoothedCCK = -1;
 236 
 237                 /* init for the sequence number of received management frame */
 238                 psta->RxMgmtFrameSeqNum = 0xffff;
 239         }
 240 
 241 exit:
 242         return psta;
 243 }
 244 
 245 /*  using pstapriv->sta_hash_lock to protect */
 246 u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta)
 247 {
 248         int i;
 249         struct __queue *pfree_sta_queue;
 250         struct recv_reorder_ctrl *preorder_ctrl;
 251         struct sta_xmit_priv *pstaxmitpriv;
 252         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 253         struct sta_priv *pstapriv = &padapter->stapriv;
 254 
 255         if (!psta)
 256                 goto exit;
 257 
 258         pfree_sta_queue = &pstapriv->free_sta_queue;
 259 
 260         pstaxmitpriv = &psta->sta_xmitpriv;
 261 
 262         spin_lock_bh(&pxmitpriv->lock);
 263 
 264         rtw_free_xmitframe_queue(pxmitpriv, &psta->sleep_q);
 265         psta->sleepq_len = 0;
 266 
 267         rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vo_q.sta_pending);
 268 
 269         list_del_init(&pstaxmitpriv->vo_q.tx_pending);
 270 
 271         rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending);
 272 
 273         list_del_init(&pstaxmitpriv->vi_q.tx_pending);
 274 
 275         rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending);
 276 
 277         list_del_init(&pstaxmitpriv->bk_q.tx_pending);
 278 
 279         rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending);
 280 
 281         list_del_init(&pstaxmitpriv->be_q.tx_pending);
 282 
 283         spin_unlock_bh(&pxmitpriv->lock);
 284 
 285         list_del_init(&psta->hash_list);
 286         RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_,
 287                  ("\n free number_%d stainfo with hwaddr=0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
 288                  pstapriv->asoc_sta_count, psta->hwaddr[0], psta->hwaddr[1],
 289                  psta->hwaddr[2], psta->hwaddr[3], psta->hwaddr[4],
 290                  psta->hwaddr[5]));
 291         pstapriv->asoc_sta_count--;
 292 
 293         /*  re-init sta_info; 20061114 */
 294         _rtw_init_sta_xmit_priv(&psta->sta_xmitpriv);
 295         _rtw_init_sta_recv_priv(&psta->sta_recvpriv);
 296 
 297         del_timer_sync(&psta->addba_retry_timer);
 298 
 299         /* for A-MPDU Rx reordering buffer control, cancel reordering_ctrl_timer */
 300         for (i = 0; i < 16; i++) {
 301                 struct list_head *phead, *plist;
 302                 struct recv_frame *prframe;
 303                 struct __queue *ppending_recvframe_queue;
 304                 struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
 305 
 306                 preorder_ctrl = &psta->recvreorder_ctrl[i];
 307 
 308                 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
 309 
 310                 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
 311 
 312                 spin_lock_bh(&ppending_recvframe_queue->lock);
 313 
 314                 phead =         get_list_head(ppending_recvframe_queue);
 315                 plist = phead->next;
 316 
 317                 while (!list_empty(phead)) {
 318                         prframe = container_of(plist, struct recv_frame, list);
 319 
 320                         plist = plist->next;
 321 
 322                         list_del_init(&prframe->list);
 323 
 324                         rtw_free_recvframe(prframe, pfree_recv_queue);
 325                 }
 326 
 327                 spin_unlock_bh(&ppending_recvframe_queue->lock);
 328         }
 329 
 330         if (!(psta->state & WIFI_AP_STATE))
 331                 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, false);
 332 
 333 #ifdef CONFIG_88EU_AP_MODE
 334 
 335         spin_lock_bh(&pstapriv->auth_list_lock);
 336         if (!list_empty(&psta->auth_list)) {
 337                 list_del_init(&psta->auth_list);
 338                 pstapriv->auth_list_cnt--;
 339         }
 340         spin_unlock_bh(&pstapriv->auth_list_lock);
 341 
 342         psta->expire_to = 0;
 343 
 344         psta->sleepq_ac_len = 0;
 345         psta->qos_info = 0;
 346 
 347         psta->max_sp_len = 0;
 348         psta->uapsd_bk = 0;
 349         psta->uapsd_be = 0;
 350         psta->uapsd_vi = 0;
 351         psta->uapsd_vo = 0;
 352         psta->has_legacy_ac = 0;
 353 
 354         pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
 355         pstapriv->tim_bitmap &= ~BIT(psta->aid);
 356 
 357         if ((psta->aid > 0) && (pstapriv->sta_aid[psta->aid - 1] == psta)) {
 358                 pstapriv->sta_aid[psta->aid - 1] = NULL;
 359                 psta->aid = 0;
 360         }
 361 
 362         psta->under_exist_checking = 0;
 363 
 364 #endif  /*  CONFIG_88EU_AP_MODE */
 365 
 366         spin_lock_bh(&pfree_sta_queue->lock);
 367         list_add_tail(&psta->list, get_list_head(pfree_sta_queue));
 368         spin_unlock_bh(&pfree_sta_queue->lock);
 369 
 370 exit:
 371 
 372         return _SUCCESS;
 373 }
 374 
 375 /*  free all stainfo which in sta_hash[all] */
 376 void rtw_free_all_stainfo(struct adapter *padapter)
 377 {
 378         struct list_head *plist, *phead;
 379         s32 index;
 380         struct sta_info *psta = NULL;
 381         struct sta_priv *pstapriv = &padapter->stapriv;
 382         struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(padapter);
 383 
 384         if (pstapriv->asoc_sta_count == 1)
 385                 return;
 386 
 387         spin_lock_bh(&pstapriv->sta_hash_lock);
 388 
 389         for (index = 0; index < NUM_STA; index++) {
 390                 phead = &pstapriv->sta_hash[index];
 391                 plist = phead->next;
 392 
 393                 while (phead != plist) {
 394                         psta = container_of(plist, struct sta_info, hash_list);
 395 
 396                         plist = plist->next;
 397 
 398                         if (pbcmc_stainfo != psta)
 399                                 rtw_free_stainfo(padapter, psta);
 400                 }
 401         }
 402         spin_unlock_bh(&pstapriv->sta_hash_lock);
 403 }
 404 
 405 /* any station allocated can be searched by hash list */
 406 struct sta_info *rtw_get_stainfo(struct sta_priv *pstapriv, u8 *hwaddr)
 407 {
 408         struct list_head *plist, *phead;
 409         struct sta_info *psta = NULL;
 410         u32 index;
 411         u8 *addr;
 412         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 413 
 414         if (!hwaddr)
 415                 return NULL;
 416 
 417         if (is_multicast_ether_addr(hwaddr))
 418                 addr = bc_addr;
 419         else
 420                 addr = hwaddr;
 421 
 422         index = wifi_mac_hash(addr);
 423 
 424         spin_lock_bh(&pstapriv->sta_hash_lock);
 425 
 426         phead = &pstapriv->sta_hash[index];
 427         plist = phead->next;
 428 
 429         while (phead != plist) {
 430                 psta = container_of(plist, struct sta_info, hash_list);
 431 
 432                 if (!memcmp(psta->hwaddr, addr, ETH_ALEN)) {
 433                         /*  if found the matched address */
 434                         break;
 435                 }
 436                 psta = NULL;
 437                 plist = plist->next;
 438         }
 439 
 440         spin_unlock_bh(&pstapriv->sta_hash_lock);
 441         return psta;
 442 }
 443 
 444 u32 rtw_init_bcmc_stainfo(struct adapter *padapter)
 445 {
 446         struct sta_info *psta;
 447         u32 res = _SUCCESS;
 448         unsigned char bcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 449         struct sta_priv *pstapriv = &padapter->stapriv;
 450 
 451         psta = rtw_alloc_stainfo(pstapriv, bcast_addr);
 452 
 453         if (!psta) {
 454                 res = _FAIL;
 455                 RT_TRACE(_module_rtl871x_sta_mgt_c_, _drv_err_, ("rtw_alloc_stainfo fail"));
 456                 goto exit;
 457         }
 458 
 459         /*  default broadcast & multicast use macid 1 */
 460         psta->mac_id = 1;
 461 
 462 exit:
 463         return res;
 464 }
 465 
 466 struct sta_info *rtw_get_bcmc_stainfo(struct adapter *padapter)
 467 {
 468         struct sta_priv *pstapriv = &padapter->stapriv;
 469         u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
 470 
 471         return rtw_get_stainfo(pstapriv, bc_addr);
 472 }
 473 
 474 u8 rtw_access_ctrl(struct adapter *padapter, u8 *mac_addr)
 475 {
 476         u8 res = true;
 477 #ifdef CONFIG_88EU_AP_MODE
 478         struct list_head *plist, *phead;
 479         struct rtw_wlan_acl_node *paclnode;
 480         u8 match = false;
 481         struct sta_priv *pstapriv = &padapter->stapriv;
 482         struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
 483         struct __queue *pacl_node_q = &pacl_list->acl_node_q;
 484 
 485         spin_lock_bh(&pacl_node_q->lock);
 486         phead = get_list_head(pacl_node_q);
 487         plist = phead->next;
 488         while (phead != plist) {
 489                 paclnode = container_of(plist, struct rtw_wlan_acl_node, list);
 490                 plist = plist->next;
 491 
 492                 if (!memcmp(paclnode->addr, mac_addr, ETH_ALEN)) {
 493                         if (paclnode->valid) {
 494                                 match = true;
 495                                 break;
 496                         }
 497                 }
 498         }
 499         spin_unlock_bh(&pacl_node_q->lock);
 500 
 501         if (pacl_list->mode == 1)/* accept unless in deny list */
 502                 res = (match) ? false : true;
 503         else if (pacl_list->mode == 2)/* deny unless in accept list */
 504                 res = (match) ? true : false;
 505         else
 506                 res = true;
 507 
 508 #endif
 509 
 510         return res;
 511 }

/* [<][>][^][v][top][bottom][index][help] */