From: Viktor Barna <viktor.barna@xxxxxxxxxx> (Part of the split. Please, take a look at the cover letter for more details). Signed-off-by: Viktor Barna <viktor.barna@xxxxxxxxxx> --- drivers/net/wireless/celeno/cl8k/vif.c | 162 +++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 drivers/net/wireless/celeno/cl8k/vif.c diff --git a/drivers/net/wireless/celeno/cl8k/vif.c b/drivers/net/wireless/celeno/cl8k/vif.c new file mode 100644 index 000000000000..7592f0d32e7a --- /dev/null +++ b/drivers/net/wireless/celeno/cl8k/vif.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Copyright(c) 2019-2022, Celeno Communications Ltd. */ + +#include <linux/list.h> + +#include "hw.h" +#include "mac_addr.h" +#include "vif.h" + +void cl_vif_init(struct cl_hw *cl_hw) +{ + rwlock_init(&cl_hw->vif_db.lock); + INIT_LIST_HEAD(&cl_hw->vif_db.head); +} + +void cl_vif_add(struct cl_hw *cl_hw, struct cl_vif *cl_vif) +{ + struct cl_vif_db *vif_db = &cl_hw->vif_db; + + write_lock_bh(&vif_db->lock); + list_add_tail(&cl_vif->list, &vif_db->head); + + if (cl_vif->vif->type != NL80211_IFTYPE_STATION) + vif_db->num_iface_bcn++; + + /* Multicast vif set */ + cl_hw->mc_vif = cl_vif; + + write_unlock_bh(&vif_db->lock); +} + +void cl_vif_remove(struct cl_hw *cl_hw, struct cl_vif *cl_vif) +{ + struct cl_vif_db *vif_db = &cl_hw->vif_db; + + write_lock_bh(&vif_db->lock); + /* Multicast vif unset */ + if (cl_hw->mc_vif == cl_vif) + cl_hw->mc_vif = cl_vif_get_next(cl_hw, cl_hw->mc_vif); + + list_del(&cl_vif->list); + + if (cl_vif->vif->type != NL80211_IFTYPE_STATION) + vif_db->num_iface_bcn--; + write_unlock_bh(&vif_db->lock); + + cl_bcmc_cfm_poll_empty_per_vif(cl_hw, cl_vif); +} + +struct cl_vif *cl_vif_get_next(struct cl_hw *cl_hw, struct cl_vif *cl_vif) +{ + if (list_is_last(&cl_vif->list, &cl_hw->vif_db.head)) + return list_first_entry_or_null(&cl_hw->vif_db.head, + struct cl_vif, list); + else + return list_next_entry(cl_vif, list); +} + +struct cl_vif *cl_vif_get_by_dev(struct cl_hw *cl_hw, struct net_device *dev) +{ + struct cl_vif *cl_vif = NULL, *cl_vif_ret = NULL; + + read_lock_bh(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) + if (cl_vif->dev == dev) { + cl_vif_ret = cl_vif; + goto unlock; + } + +unlock: + read_unlock_bh(&cl_hw->vif_db.lock); + return cl_vif_ret; +} + +struct cl_vif *cl_vif_get_by_mac(struct cl_hw *cl_hw, u8 *mac_addr) +{ + struct cl_vif *cl_vif, *cl_vif_ret = NULL; + + read_lock(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) + if (cl_mac_addr_compare(cl_vif->vif->addr, mac_addr)) { + cl_vif_ret = cl_vif; + goto unlock; + } + +unlock: + read_unlock(&cl_hw->vif_db.lock); + return cl_vif_ret; +} + +struct cl_vif *cl_vif_get_first(struct cl_hw *cl_hw) +{ + return list_first_entry_or_null(&cl_hw->vif_db.head, struct cl_vif, list); +} + +struct cl_vif *cl_vif_get_first_ap(struct cl_hw *cl_hw) +{ + struct cl_vif *cl_vif, *cl_vif_ret = NULL; + + read_lock_bh(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) + if (cl_vif->vif->type == NL80211_IFTYPE_AP || + cl_vif->vif->type == NL80211_IFTYPE_MESH_POINT || + cl_hw->conf->ce_listener_en) { + cl_vif_ret = cl_vif; + goto unlock; + } + +unlock: + read_unlock_bh(&cl_hw->vif_db.lock); + return cl_vif_ret; +} + +struct net_device *cl_vif_get_first_net_device(struct cl_hw *cl_hw) +{ + struct cl_vif *cl_vif = NULL; + struct net_device *dev = NULL; + + read_lock_bh(&cl_hw->vif_db.lock); + cl_vif = list_first_entry_or_null(&cl_hw->vif_db.head, struct cl_vif, list); + if (cl_vif) + dev = cl_vif->dev; + read_unlock_bh(&cl_hw->vif_db.lock); + + return dev; +} + +struct net_device *cl_vif_get_dev_by_index(struct cl_hw *cl_hw, u8 index) +{ + struct cl_vif *cl_vif = NULL; + struct net_device *dev = NULL; + + read_lock_bh(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) + if (cl_vif->vif_index == index) { + dev = cl_vif->dev; + goto unlock; + } + +unlock: + read_unlock_bh(&cl_hw->vif_db.lock); + return dev; +} + +void cl_vif_ap_tx_enable(struct cl_hw *cl_hw, bool enable) +{ + struct cl_vif *cl_vif; + struct ieee80211_vif *vif; + + read_lock_bh(&cl_hw->vif_db.lock); + list_for_each_entry(cl_vif, &cl_hw->vif_db.head, list) { + vif = cl_vif->vif; + + if (vif->type != NL80211_IFTYPE_AP) + continue; + + cl_vif->tx_en = enable; + cl_dbg_verbose(cl_hw, "Set tx_en=%u for vif_index=%u\n", + enable, cl_vif->vif_index); + } + read_unlock_bh(&cl_hw->vif_db.lock); +} -- 2.36.1