linux/drivers/net/wireless/quantenna/qtnfmac/util.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/* Copyright (c) 2015-2016 Quantenna Communications. All rights reserved. */
   3
   4#include "util.h"
   5#include "qtn_hw_ids.h"
   6
   7void qtnf_sta_list_init(struct qtnf_sta_list *list)
   8{
   9        if (unlikely(!list))
  10                return;
  11
  12        INIT_LIST_HEAD(&list->head);
  13        atomic_set(&list->size, 0);
  14}
  15
  16struct qtnf_sta_node *qtnf_sta_list_lookup(struct qtnf_sta_list *list,
  17                                           const u8 *mac)
  18{
  19        struct qtnf_sta_node *node;
  20
  21        if (unlikely(!mac))
  22                return NULL;
  23
  24        list_for_each_entry(node, &list->head, list) {
  25                if (ether_addr_equal(node->mac_addr, mac))
  26                        return node;
  27        }
  28
  29        return NULL;
  30}
  31
  32struct qtnf_sta_node *qtnf_sta_list_lookup_index(struct qtnf_sta_list *list,
  33                                                 size_t index)
  34{
  35        struct qtnf_sta_node *node;
  36
  37        if (qtnf_sta_list_size(list) <= index)
  38                return NULL;
  39
  40        list_for_each_entry(node, &list->head, list) {
  41                if (index-- == 0)
  42                        return node;
  43        }
  44
  45        return NULL;
  46}
  47
  48struct qtnf_sta_node *qtnf_sta_list_add(struct qtnf_vif *vif,
  49                                        const u8 *mac)
  50{
  51        struct qtnf_sta_list *list = &vif->sta_list;
  52        struct qtnf_sta_node *node;
  53
  54        if (unlikely(!mac))
  55                return NULL;
  56
  57        node = qtnf_sta_list_lookup(list, mac);
  58
  59        if (node)
  60                goto done;
  61
  62        node = kzalloc(sizeof(*node), GFP_KERNEL);
  63        if (unlikely(!node))
  64                goto done;
  65
  66        ether_addr_copy(node->mac_addr, mac);
  67        list_add_tail(&node->list, &list->head);
  68        atomic_inc(&list->size);
  69        ++vif->generation;
  70
  71done:
  72        return node;
  73}
  74
  75bool qtnf_sta_list_del(struct qtnf_vif *vif, const u8 *mac)
  76{
  77        struct qtnf_sta_list *list = &vif->sta_list;
  78        struct qtnf_sta_node *node;
  79        bool ret = false;
  80
  81        node = qtnf_sta_list_lookup(list, mac);
  82
  83        if (node) {
  84                list_del(&node->list);
  85                atomic_dec(&list->size);
  86                kfree(node);
  87                ++vif->generation;
  88                ret = true;
  89        }
  90
  91        return ret;
  92}
  93
  94void qtnf_sta_list_free(struct qtnf_sta_list *list)
  95{
  96        struct qtnf_sta_node *node, *tmp;
  97
  98        atomic_set(&list->size, 0);
  99
 100        list_for_each_entry_safe(node, tmp, &list->head, list) {
 101                list_del(&node->list);
 102                kfree(node);
 103        }
 104
 105        INIT_LIST_HEAD(&list->head);
 106}
 107
 108const char *qtnf_chipid_to_string(unsigned long chip_id)
 109{
 110        switch (chip_id) {
 111        case QTN_CHIP_ID_TOPAZ:
 112                return "Topaz";
 113        case QTN_CHIP_ID_PEARL:
 114                return "Pearl revA";
 115        case QTN_CHIP_ID_PEARL_B:
 116                return "Pearl revB";
 117        case QTN_CHIP_ID_PEARL_C:
 118                return "Pearl revC";
 119        default:
 120                return "unknown";
 121        }
 122}
 123EXPORT_SYMBOL_GPL(qtnf_chipid_to_string);
 124