qcacmn: Disable coex channels in the current_chan_list

The 5G cellular RF band and wifi frequency band of UNII-1
(IEEE channels 36, 40, 44, 48) and UNII-2A band (52, 56,
60, 64) can coexist.

UNII-1 and UNII-2A are represented by bits 0x1 and 0x2 respectively in
this implementation. The user space command should set the bits by
applying the following algorithm:

1) To disable only the UNII-1 band channels, set the value as 0x1.
2) To disable only the UNII-2A band channels, set the value as 0x2.
3) To disable both the UNII-1 and UNII-2A band channels, set the
   value as 0x3.
4) To restore both the UNII-1 and UNII-2A band channels, set the
   value as 0x0.

Change-Id: I8ff747e53b079ee9e0dc762980aee0eea32b23a5
CRs-Fixed: 2571546
This commit is contained in:
Hariharan Basuthkar 2019-11-21 10:35:23 +05:30 • committed by nshrivas
commit 52ccb5e615
10 changed files with 292 additions and 1 deletions

View file

@ -989,6 +989,8 @@ struct wlan_lmac_if_reg_rx_ops {
bool dfs_enable);
QDF_STATUS (*reg_modify_pdev_chan_range)(struct
wlan_objmgr_pdev *pdev);
QDF_STATUS (*reg_disable_chan_coex)(struct wlan_objmgr_pdev *pdev,
uint8_t unii_5g_bitmap);
bool (*reg_ignore_fw_reg_offload_ind)(struct wlan_objmgr_psoc *psoc);
};

View file

@ -323,6 +323,9 @@ static void wlan_lmac_if_umac_reg_rx_ops_register(
rx_ops->reg_rx_ops.reg_ignore_fw_reg_offload_ind =
tgt_reg_ignore_fw_reg_offload_ind;
rx_ops->reg_rx_ops.reg_disable_chan_coex =
wlan_reg_disable_chan_coex;
}
#ifdef CONVERGED_P2P_ENABLE

View file

@ -615,6 +615,134 @@ reg_modify_chan_list_for_srd_channels(struct wlan_objmgr_pdev *pdev,
}
#endif
#ifdef DISABLE_UNII_SHARED_BANDS
/**
* reg_is_reg_unii_band_1_set() - Check UNII bitmap
* @unii_bitmap: 5G UNII band bitmap
*
* This function checks the input bitmap to disable UNII-1 band channels.
*
* Return: Return true if UNII-1 channels need to be disabled,
* else return false.
*/
static bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap)
{
return !!(unii_bitmap & BIT(REG_UNII_BAND_1));
}
/**
* reg_is_reg_unii_band_2a_set() - Check UNII bitmap
* @unii_bitmap: 5G UNII band bitmap
*
* This function checks the input bitmap to disable UNII-2A band channels.
*
* Return: Return true if UNII-2A channels need to be disabled,
* else return false.
*/
static bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap)
{
return !!(unii_bitmap & BIT(REG_UNII_BAND_2A));
}
/**
* reg_is_5g_enum() - Check if channel enum is a 5G channel enum
* @chan_enum: channel enum
*
* Return: Return true if the input channel enum is 5G, else return false.
*/
static bool reg_is_5g_enum(enum channel_enum chan_enum)
{
return (chan_enum >= MIN_5GHZ_CHANNEL && chan_enum <= MAX_5GHZ_CHANNEL);
}
/**
* reg_remove_unii_chan_from_chan_list() - Remove UNII band channels
* @chan_list: Pointer to current channel list
* @start_enum: starting enum value
* @end_enum: ending enum value
*
* Remove channels in a unii band based in on the input start_enum and end_enum.
* Disable the state and flags. Set disable_coex flag to true.
*
* return: void.
*/
static void
reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list,
enum channel_enum start_enum,
enum channel_enum end_enum)
{
enum channel_enum chan_enum;
if (!(reg_is_5g_enum(start_enum) && reg_is_5g_enum(end_enum))) {
reg_err_rl("start_enum or end_enum is invalid");
return;
}
for (chan_enum = start_enum; chan_enum <= end_enum; chan_enum++) {
chan_list[chan_enum].state = CHANNEL_STATE_DISABLE;
chan_list[chan_enum].chan_flags |= REGULATORY_CHAN_DISABLED;
}
}
/**
* reg_modify_disable_chan_list_for_unii1_and_unii2a() - Disable UNII-1 and
* UNII2A band
* @pdev_priv_obj: Pointer to pdev private object
*
* This function disables the UNII-1 and UNII-2A band channels
* based on input unii_5g_bitmap.
*
* Return: void.
*/
static void
reg_modify_disable_chan_list_for_unii1_and_unii2a(
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
{
uint8_t unii_bitmap = pdev_priv_obj->unii_5g_bitmap;
struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
if (reg_is_reg_unii_band_1_set(unii_bitmap)) {
reg_remove_unii_chan_from_chan_list(chan_list,
MIN_UNII_1_BAND_CHANNEL,
MAX_UNII_1_BAND_CHANNEL);
}
if (reg_is_reg_unii_band_2a_set(unii_bitmap)) {
reg_remove_unii_chan_from_chan_list(chan_list,
MIN_UNII_2A_BAND_CHANNEL,
MAX_UNII_2A_BAND_CHANNEL);
}
}
#else
static inline bool reg_is_reg_unii_band_1_set(uint8_t unii_bitmap)
{
return false;
}
static inline bool reg_is_reg_unii_band_2a_set(uint8_t unii_bitmap)
{
return false;
}
static inline bool reg_is_5g_enum(enum channel_enum chan_enum)
{
return false;
}
static inline void
reg_remove_unii_chan_from_chan_list(struct regulatory_channel *chan_list,
enum channel_enum start_enum,
enum channel_enum end_enum)
{
}
static inline void
reg_modify_disable_chan_list_for_unii1_and_unii2a(
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
{
}
#endif
void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj
*pdev_priv_obj)
{
@ -630,6 +758,8 @@ void reg_compute_pdev_current_chan_list(struct wlan_regulatory_pdev_priv_obj
reg_modify_chan_list_for_band(pdev_priv_obj->cur_chan_list,
pdev_priv_obj->band_capability);
reg_modify_disable_chan_list_for_unii1_and_unii2a(pdev_priv_obj);
reg_modify_chan_list_for_dfs_channels(pdev_priv_obj->cur_chan_list,
pdev_priv_obj->dfs_enabled);

View file

@ -156,6 +156,25 @@ QDF_STATUS wlan_regulatory_psoc_obj_destroyed_notification(
return status;
}
#ifdef DISABLE_UNII_SHARED_BANDS
/**
* reg_reset_unii_5g_bitmap() - Reset the value of unii_5g_bitmap.
* @pdev_priv_obj: pointer to wlan_regulatory_pdev_priv_obj.
*
* Return : void
*/
static void
reg_reset_unii_5g_bitmap(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
{
pdev_priv_obj->unii_5g_bitmap = 0x0;
}
#else
static void inline
reg_reset_unii_5g_bitmap(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
{
}
#endif
QDF_STATUS wlan_regulatory_pdev_obj_created_notification(
struct wlan_objmgr_pdev *pdev, void *arg_list)
{
@ -193,6 +212,7 @@ QDF_STATUS wlan_regulatory_pdev_obj_created_notification(
pdev_priv_obj->indoor_chan_enabled =
psoc_priv_obj->indoor_chan_enabled;
pdev_priv_obj->en_chan_144 = true;
reg_reset_unii_5g_bitmap(pdev_priv_obj);
qdf_spinlock_create(&pdev_priv_obj->reg_rules_lock);

View file

@ -156,6 +156,9 @@ struct wlan_regulatory_pdev_priv_obj {
char current_country[REG_ALPHA2_LEN + 1];
uint16_t reg_dmn_pair;
uint16_t ctry_code;
#ifdef DISABLE_UNII_SHARED_BANDS
uint8_t unii_5g_bitmap;
#endif
enum dfs_reg dfs_region;
uint32_t phybitmap;
struct wlan_objmgr_pdev *pdev_ptr;

View file

@ -2731,6 +2731,75 @@ QDF_STATUS reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev)
return status;
}
#ifdef DISABLE_UNII_SHARED_BANDS
/**
* reg_is_reg_unii_band_1_or_reg_unii_band_2a() - Check the input bitmap
* @unii_5g_bitmap: 5G UNII band bitmap
*
* This function checks if either REG_UNII_BAND_1 or REG_UNII_BAND_2A,
* are present in the 5G UNII band bitmap.
*
* Return: Return true if REG_UNII_BAND_1 or REG_UNII_BAND_2A, are present in
* the UNII 5g bitmap else return false.
*/
static bool
reg_is_reg_unii_band_1_or_reg_unii_band_2a(uint8_t unii_5g_bitmap)
{
if (!unii_5g_bitmap)
return false;
return ((unii_5g_bitmap & (BIT(REG_UNII_BAND_1) |
BIT(REG_UNII_BAND_2A))) == unii_5g_bitmap);
}
QDF_STATUS reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev,
uint8_t unii_5g_bitmap)
{
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
struct wlan_objmgr_psoc *psoc;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
reg_err("psoc is NULL");
return QDF_STATUS_E_INVAL;
}
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_err_rl("reg pdev priv obj is NULL");
return QDF_STATUS_E_FAILURE;
}
if (unii_5g_bitmap &&
!reg_is_reg_unii_band_1_or_reg_unii_band_2a(unii_5g_bitmap)) {
reg_err_rl("Invalid unii_5g_bitmap = %d", unii_5g_bitmap);
return QDF_STATUS_E_FAILURE;
}
if (pdev_priv_obj->unii_5g_bitmap == unii_5g_bitmap) {
reg_debug_rl("UNII bitmask for 5G channels is already set %d",
unii_5g_bitmap);
return QDF_STATUS_SUCCESS;
}
reg_debug_rl("Setting UNII bitmask for 5G: %d", unii_5g_bitmap);
pdev_priv_obj->unii_5g_bitmap = unii_5g_bitmap;
reg_compute_pdev_current_chan_list(pdev_priv_obj);
reg_tx_ops = reg_get_psoc_tx_ops(psoc);
if (reg_tx_ops->fill_umac_legacy_chanlist) {
reg_tx_ops->fill_umac_legacy_chanlist(pdev,
pdev_priv_obj->cur_chan_list);
}
return QDF_STATUS_SUCCESS;
}
#endif
#ifdef CONFIG_CHAN_FREQ_API
QDF_STATUS reg_get_channel_list_with_power_for_freq(struct wlan_objmgr_pdev
*pdev,

View file

@ -734,6 +734,19 @@ bool reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev);
*/
QDF_STATUS reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev);
#ifdef DISABLE_UNII_SHARED_BANDS
/**
* reg_disable_chan_coex() - Disable Coexisting channels based on the input
* bitmask.
* @pdev: pointer to wlan_objmgr_pdev.
* unii_5g_bitmap: UNII 5G bitmap.
*
* Return : QDF_STATUS
*/
QDF_STATUS reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev,
uint8_t unii_5g_bitmap);
#endif
#ifdef CONFIG_CHAN_FREQ_API
/**
* reg_get_chan_enum_for_freq() - Get channel enum for given channel frequency

View file

@ -435,6 +435,18 @@ enum channel_enum {
INVALID_CHANNEL = 0xBAD,
#ifdef DISABLE_UNII_SHARED_BANDS
MIN_UNII_1_BAND_CHANNEL = CHAN_ENUM_5180,
MAX_UNII_1_BAND_CHANNEL = CHAN_ENUM_5240,
NUM_UNII_1_BAND_CHANNELS = (MAX_UNII_1_BAND_CHANNEL -
MIN_UNII_1_BAND_CHANNEL + 1),
MIN_UNII_2A_BAND_CHANNEL = CHAN_ENUM_5260,
MAX_UNII_2A_BAND_CHANNEL = CHAN_ENUM_5320,
NUM_UNII_2A_BAND_CHANNELS = (MAX_UNII_2A_BAND_CHANNEL -
MIN_UNII_2A_BAND_CHANNEL + 1),
#endif
#ifdef CONFIG_BAND_6GHZ
MIN_6GHZ_CHANNEL = CHAN_ENUM_5945,
MAX_6GHZ_CHANNEL = CHAN_ENUM_7105,
@ -659,7 +671,6 @@ struct regulatory_channel {
bool nol_history;
};
/**
* struct regulatory: regulatory information
* @reg_domain: regulatory domain pair
@ -833,6 +844,18 @@ enum reg_wifi_band {
REG_BAND_UNKNOWN
};
#ifdef DISABLE_UNII_SHARED_BANDS
/**
* enum reg_unii_band
* @REG_UNII_BAND_1: Disable UNII-1 band channels
* @REG_UNII_BAND_2A: Disable UNII-2A band channels
*/
enum reg_unii_band {
REG_UNII_BAND_1 = 0x0,
REG_UNII_BAND_2A = 0x1,
};
#endif
#define REG_BAND_MASK_ALL (BIT(REG_BAND_2G) | BIT(REG_BAND_5G) \
| BIT(REG_BAND_6G))

View file

@ -894,6 +894,26 @@ bool wlan_reg_is_regdmn_en302502_applicable(struct wlan_objmgr_pdev *pdev);
*/
QDF_STATUS wlan_reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev);
/**
* wlan_reg_disable_chan_coex() - Disable Coexisting channels based on the input
* bitmask
* @pdev: pointer to wlan_objmgr_pdev.
* unii_5g_bitmap: UNII 5G bitmap.
*
* Return : QDF_STATUS
*/
#ifdef DISABLE_UNII_SHARED_BANDS
QDF_STATUS wlan_reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev,
uint8_t unii_5g_bitmap);
#else
static inline QDF_STATUS
wlan_reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev,
uint8_t unii_5g_bitmap)
{
return QDF_STATUS_SUCCESS;
}
#endif
#ifdef CONFIG_CHAN_FREQ_API
/**
* wlan_reg_is_same_band_freqs() - Check if two channel frequencies

View file

@ -833,6 +833,14 @@ QDF_STATUS wlan_reg_modify_pdev_chan_range(struct wlan_objmgr_pdev *pdev)
return reg_modify_pdev_chan_range(pdev);
}
#ifdef DISABLE_UNII_SHARED_BANDS
QDF_STATUS wlan_reg_disable_chan_coex(struct wlan_objmgr_pdev *pdev,
uint8_t unii_5g_bitmap)
{
return reg_disable_chan_coex(pdev, unii_5g_bitmap);
}
#endif
#ifdef CONFIG_CHAN_FREQ_API
bool wlan_reg_is_same_band_freqs(uint16_t freq1, uint16_t freq2)
{