Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.14.15.
 1// SPDX-License-Identifier: GPL-2.0
 2/*
 3 * Wifi Band Exclusion Interface for WLAN
 4 * Copyright (C) 2023 Advanced Micro Devices
 5 *
 6 */
 7
 8#include <linux/acpi_amd_wbrf.h>
 9#include <linux/units.h>
10#include <net/cfg80211.h>
11#include "ieee80211_i.h"
12
13void ieee80211_check_wbrf_support(struct ieee80211_local *local)
14{
15	struct wiphy *wiphy = local->hw.wiphy;
16	struct device *dev;
17
18	if (!wiphy)
19		return;
20
21	dev = wiphy->dev.parent;
22	if (!dev)
23		return;
24
25	local->wbrf_supported = acpi_amd_wbrf_supported_producer(dev);
26}
27
28static void get_chan_freq_boundary(u32 center_freq, u32 bandwidth, u64 *start, u64 *end)
29{
30	bandwidth *= KHZ_PER_MHZ;
31	center_freq *= KHZ_PER_MHZ;
32
33	*start = center_freq - bandwidth / 2;
34	*end = center_freq + bandwidth / 2;
35
36	/* Frequency in Hz is expected */
37	*start = *start * HZ_PER_KHZ;
38	*end = *end * HZ_PER_KHZ;
39}
40
41static void get_ranges_from_chandef(struct cfg80211_chan_def *chandef,
42				    struct wbrf_ranges_in_out *ranges_in)
43{
44	u64 start_freq1, end_freq1;
45	u64 start_freq2, end_freq2;
46	int bandwidth;
47
48	bandwidth = nl80211_chan_width_to_mhz(chandef->width);
49
50	get_chan_freq_boundary(chandef->center_freq1, bandwidth, &start_freq1, &end_freq1);
51
52	ranges_in->band_list[0].start = start_freq1;
53	ranges_in->band_list[0].end = end_freq1;
54	ranges_in->num_of_ranges = 1;
55
56	if (chandef->width == NL80211_CHAN_WIDTH_80P80) {
57		get_chan_freq_boundary(chandef->center_freq2, bandwidth, &start_freq2, &end_freq2);
58
59		ranges_in->band_list[1].start = start_freq2;
60		ranges_in->band_list[1].end = end_freq2;
61		ranges_in->num_of_ranges++;
62	}
63}
64
65void ieee80211_add_wbrf(struct ieee80211_local *local, struct cfg80211_chan_def *chandef)
66{
67	struct wbrf_ranges_in_out ranges_in = {0};
68	struct device *dev;
69
70	if (!local->wbrf_supported)
71		return;
72
73	dev = local->hw.wiphy->dev.parent;
74
75	get_ranges_from_chandef(chandef, &ranges_in);
76
77	acpi_amd_wbrf_add_remove(dev, WBRF_RECORD_ADD, &ranges_in);
78}
79
80void ieee80211_remove_wbrf(struct ieee80211_local *local, struct cfg80211_chan_def *chandef)
81{
82	struct wbrf_ranges_in_out ranges_in = {0};
83	struct device *dev;
84
85	if (!local->wbrf_supported)
86		return;
87
88	dev = local->hw.wiphy->dev.parent;
89
90	get_ranges_from_chandef(chandef, &ranges_in);
91
92	acpi_amd_wbrf_add_remove(dev, WBRF_RECORD_REMOVE, &ranges_in);
93}