Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 48 additions & 29 deletions drivers/net/wireless/ath/ath12k/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1851,10 +1851,22 @@ static struct ath12k_hw_group *ath12k_core_hw_group_alloc(struct ath12k_base *ab
return ag;
}

static void ath12k_core_free_wsi_info(struct ath12k_hw_group *ag)
{
int i;

for (i = 0; i < ag->num_devices; i++) {
of_node_put(ag->wsi_node[i]);
ag->wsi_node[i] = NULL;
}
ag->num_devices = 0;
}

static void ath12k_core_hw_group_free(struct ath12k_hw_group *ag)
{
mutex_lock(&ath12k_hw_group_mutex);

ath12k_core_free_wsi_info(ag);
list_del(&ag->list);
kfree(ag);

Expand All @@ -1880,52 +1892,59 @@ static struct ath12k_hw_group *ath12k_core_hw_group_find_by_dt(struct ath12k_bas
static int ath12k_core_get_wsi_info(struct ath12k_hw_group *ag,
struct ath12k_base *ab)
{
struct device_node *wsi_dev = ab->dev->of_node, *next_wsi_dev;
struct device_node *tx_endpoint, *next_rx_endpoint;
int device_count = 0;

next_wsi_dev = wsi_dev;
struct device_node *next_wsi_dev;
int device_count = 0, ret = 0;
struct device_node *wsi_dev;

if (!next_wsi_dev)
wsi_dev = of_node_get(ab->dev->of_node);
if (!wsi_dev)
return -ENODEV;

do {
ag->wsi_node[device_count] = next_wsi_dev;
if (device_count >= ATH12K_MAX_DEVICES) {
ath12k_warn(ab, "device count in DT %d is more than limit %d\n",
device_count, ATH12K_MAX_DEVICES);
ret = -EINVAL;
break;
}

ag->wsi_node[device_count++] = of_node_get(wsi_dev);

tx_endpoint = of_graph_get_endpoint_by_regs(next_wsi_dev, 0, -1);
struct device_node *tx_endpoint __free(device_node) =
of_graph_get_endpoint_by_regs(wsi_dev, 0, -1);
if (!tx_endpoint) {
of_node_put(next_wsi_dev);
return -ENODEV;
ret = -ENODEV;
break;
}

next_rx_endpoint = of_graph_get_remote_endpoint(tx_endpoint);
struct device_node *next_rx_endpoint __free(device_node) =
of_graph_get_remote_endpoint(tx_endpoint);
if (!next_rx_endpoint) {
of_node_put(next_wsi_dev);
of_node_put(tx_endpoint);
return -ENODEV;
ret = -ENODEV;
break;
}

of_node_put(tx_endpoint);
of_node_put(next_wsi_dev);

next_wsi_dev = of_graph_get_port_parent(next_rx_endpoint);
if (!next_wsi_dev) {
of_node_put(next_rx_endpoint);
return -ENODEV;
ret = -ENODEV;
break;
}

of_node_put(next_rx_endpoint);
of_node_put(wsi_dev);
wsi_dev = next_wsi_dev;
} while (ab->dev->of_node != wsi_dev);

device_count++;
if (device_count > ATH12K_MAX_DEVICES) {
ath12k_warn(ab, "device count in DT %d is more than limit %d\n",
device_count, ATH12K_MAX_DEVICES);
of_node_put(next_wsi_dev);
return -EINVAL;
if (ret) {
while (--device_count >= 0) {
of_node_put(ag->wsi_node[device_count]);
ag->wsi_node[device_count] = NULL;
}
} while (wsi_dev != next_wsi_dev);

of_node_put(next_wsi_dev);
of_node_put(wsi_dev);
return ret;
}

of_node_put(wsi_dev);
ag->num_devices = device_count;

return 0;
Expand Down Expand Up @@ -1996,9 +2015,9 @@ static struct ath12k_hw_group *ath12k_core_hw_group_assign(struct ath12k_base *a
ath12k_core_get_wsi_index(ag, ab)) {
ath12k_dbg(ab, ATH12K_DBG_BOOT,
"unable to get wsi info from dt, grouping single device");
ath12k_core_free_wsi_info(ag);
ag->id = ATH12K_INVALID_GROUP_ID;
ag->num_devices = 1;
memset(ag->wsi_node, 0, sizeof(ag->wsi_node));
wsi->index = 0;
}

Expand Down
5 changes: 4 additions & 1 deletion drivers/net/wireless/ath/ath12k/dp_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,9 @@ static int ath12k_dp_prepare_reo_update_elem(struct ath12k_dp *dp,

lockdep_assert_held(&dp->dp_lock);

if (!peer->primary_link)
return 0;

elem = kzalloc(sizeof(*elem), GFP_ATOMIC);
if (!elem)
return -ENOMEM;
Expand Down Expand Up @@ -1337,7 +1340,7 @@ void ath12k_dp_rx_deliver_msdu(struct ath12k_pdev_dp *dp_pdev, struct napi_struc
bool is_mcbc = rxcb->is_mcbc;
bool is_eapol = rxcb->is_eapol;

peer = ath12k_dp_peer_find_by_peerid(dp_pdev, rx_info->peer_id);
peer = ath12k_dp_peer_find_by_peerid(dp_pdev, rxcb->peer_id);

pubsta = peer ? peer->sta : NULL;

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath12k/mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,7 @@ struct ath12k_link_vif *ath12k_mac_get_arvif(struct ath12k *ar, u32 vdev_id)

/* To use the arvif returned, caller must have held rcu read lock.
*/
WARN_ON(!rcu_read_lock_any_held());
lockdep_assert_in_rcu_read_lock();
arvif_iter.vdev_id = vdev_id;
arvif_iter.ar = ar;

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath12k/p2p.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ static void ath12k_p2p_noa_update_vdev_iter(void *data, u8 *mac,
struct ath12k_p2p_noa_arg *arg = data;
struct ath12k_link_vif *arvif;

WARN_ON(!rcu_read_lock_any_held());
lockdep_assert_in_rcu_read_lock();
arvif = &ahvif->deflink;
if (!arvif->is_created || arvif->ar != arg->ar || arvif->vdev_id != arg->vdev_id)
return;
Expand Down
Loading
Loading