Merge "qca-wifi: Multi-Link Repeater Enhancements"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
4207ea2ebb
@@ -21,6 +21,7 @@
|
|||||||
#include <qdf_module.h>
|
#include <qdf_module.h>
|
||||||
#include <qdf_list.h>
|
#include <qdf_list.h>
|
||||||
#include <qdf_util.h>
|
#include <qdf_util.h>
|
||||||
|
#include <qdf_lock.h>
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/etherdevice.h>
|
#include <linux/etherdevice.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
@@ -34,8 +35,7 @@
|
|||||||
#include "if_upperproto.h"
|
#include "if_upperproto.h"
|
||||||
|
|
||||||
|
|
||||||
#define QCA_MULTI_LINK_FAST_LANE_LIST_SIZE 6
|
#define QCA_MULTI_LINK_RADIO_LIST_SIZE 6
|
||||||
#define QCA_MULTI_LINK_NO_BACKHAUL_LIST_SIZE 32
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qca_multi_link_needs_enq - rptr return status
|
* qca_multi_link_needs_enq - rptr return status
|
||||||
@@ -61,15 +61,55 @@ typedef enum qca_multi_link_status {
|
|||||||
} qca_multi_link_status_t;
|
} qca_multi_link_status_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct qca_multi_link_list_node - rptr list node
|
* struct qca_multi_link_statistics - rptr drop statistics
|
||||||
* @list: linked list node
|
|
||||||
* @wiphy: wiphy pointer
|
|
||||||
*/
|
*/
|
||||||
struct qca_multi_link_list_node {
|
typedef struct qca_multi_link_statistics {
|
||||||
|
uint32_t ap_rx_sec_sta_null;
|
||||||
|
uint32_t sta_rx_sec_sta_mcast_no_fdb;
|
||||||
|
uint32_t sta_rx_sec_sta_mcast_dup_pkts;
|
||||||
|
uint32_t sta_rx_sec_sta_mcast_drop_sec;
|
||||||
|
uint32_t sta_rx_sec_sta_mcast_drop;
|
||||||
|
uint32_t sta_rx_sec_sta_ucast_src_eth;
|
||||||
|
uint32_t sta_rx_sec_sta_ucast_src_dif_band;
|
||||||
|
uint32_t sta_rx_sec_sta_ucast_no_ap;
|
||||||
|
uint32_t sta_rx_pri_sta_mcast_no_fdb;
|
||||||
|
uint32_t sta_rx_pri_sta_mcast_drop;
|
||||||
|
uint32_t sta_tx_sec_sta_alwys_prim;
|
||||||
|
uint32_t sta_tx_sec_sta_mcast_no_fdb;
|
||||||
|
uint32_t sta_tx_sec_sta_src_eth;
|
||||||
|
uint32_t sta_tx_sec_sta_mcast_drop_sec;
|
||||||
|
uint32_t sta_tx_sec_sta_drop_dif_band;
|
||||||
|
uint32_t sta_tx_pri_sta_drop_no_fdb;
|
||||||
|
uint32_t sta_tx_pri_sta_drop_dif_band;
|
||||||
|
} qca_ml_global_stats_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct qca_multi_link_radio_list_node - rptr list node
|
||||||
|
* @node: linked list node
|
||||||
|
* @wiphy: wiphy pointer
|
||||||
|
* @no_backhaul: is no_backhaul radio
|
||||||
|
* @is_fast_lane: is fast_lane radio
|
||||||
|
* @sta_dev: radio's station net device
|
||||||
|
*/
|
||||||
|
typedef struct qca_multi_link_radio_list_node {
|
||||||
qdf_list_node_t node;
|
qdf_list_node_t node;
|
||||||
struct wiphy *wiphy;
|
struct wiphy *wiphy;
|
||||||
};
|
bool no_backhaul;
|
||||||
|
bool is_fast_lane;
|
||||||
|
struct net_device *sta_dev;
|
||||||
|
} qca_multi_link_radio_node_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct qca_multi_link_parameters - rptr list node
|
||||||
|
* @rptr_processing_enable: repeater is enabled
|
||||||
|
* @loop_detected: is loop detected
|
||||||
|
* @always_primary: is always primary flag enabled
|
||||||
|
* @force_client_mcast_traffic: is force client mcast flag enabled
|
||||||
|
* @drop_secondary_mcast: is drop secondary mcast flag enabled
|
||||||
|
* @primary_wiphy: primary radio pointer
|
||||||
|
* @total_stavaps_up: total number of backhauls
|
||||||
|
* @radio_list: list of radio participating in repeater
|
||||||
|
*/
|
||||||
typedef struct qca_multi_link_parameters {
|
typedef struct qca_multi_link_parameters {
|
||||||
bool rptr_processing_enable;
|
bool rptr_processing_enable;
|
||||||
bool loop_detected;
|
bool loop_detected;
|
||||||
@@ -78,12 +118,13 @@ typedef struct qca_multi_link_parameters {
|
|||||||
bool drop_secondary_mcast;
|
bool drop_secondary_mcast;
|
||||||
struct wiphy *primary_wiphy;
|
struct wiphy *primary_wiphy;
|
||||||
uint8_t total_stavaps_up;
|
uint8_t total_stavaps_up;
|
||||||
qdf_list_t no_backhaul_list;
|
qdf_list_t radio_list;
|
||||||
qdf_list_t fast_lane_list;
|
qdf_spinlock_t radio_lock;
|
||||||
|
qca_ml_global_stats_t qca_ml_stats;
|
||||||
} qca_multi_link_parameters_t;
|
} qca_multi_link_parameters_t;
|
||||||
|
|
||||||
void qca_multi_link_init_module(void);
|
|
||||||
void qca_multi_link_deinit_module(void);
|
void qca_multi_link_deinit_module(void);
|
||||||
|
void qca_multi_link_init_module(void);
|
||||||
uint8_t qca_multi_link_get_num_sta(void);
|
uint8_t qca_multi_link_get_num_sta(void);
|
||||||
void qca_multi_link_append_num_sta(bool inc_or_dec);
|
void qca_multi_link_append_num_sta(bool inc_or_dec);
|
||||||
bool qca_multi_link_is_dbdc_processing_reqd(struct net_device *net_dev);
|
bool qca_multi_link_is_dbdc_processing_reqd(struct net_device *net_dev);
|
||||||
@@ -93,10 +134,15 @@ void qca_multi_link_set_always_primary(bool val);
|
|||||||
void qca_multi_link_set_dbdc_enable(bool val);
|
void qca_multi_link_set_dbdc_enable(bool val);
|
||||||
struct wiphy *qca_multi_link_get_primary_radio(void);
|
struct wiphy *qca_multi_link_get_primary_radio(void);
|
||||||
void qca_multi_link_set_primary_radio(struct wiphy *primary_wiphy);
|
void qca_multi_link_set_primary_radio(struct wiphy *primary_wiphy);
|
||||||
bool qca_multi_link_add_fastlane_radio(struct wiphy *fl_wiphy);
|
bool qca_multi_link_remove_radio(struct wiphy *wiphy);
|
||||||
|
bool qca_multi_link_add_radio(struct wiphy *wiphy);
|
||||||
bool qca_multi_link_remove_fastlane_radio(struct wiphy *fl_wiphy);
|
bool qca_multi_link_remove_fastlane_radio(struct wiphy *fl_wiphy);
|
||||||
bool qca_multi_link_add_no_backhaul_radio(struct wiphy *no_bl_wiphy);
|
bool qca_multi_link_add_fastlane_radio(struct wiphy *fl_wiphy);
|
||||||
bool qca_multi_link_remove_no_backhaul_radio(struct wiphy *no_bl_wiphy);
|
bool qca_multi_link_remove_no_backhaul_radio(struct wiphy *no_bl_wiphy);
|
||||||
|
bool qca_multi_link_add_no_backhaul_radio(struct wiphy *no_bl_wiphy);
|
||||||
|
bool qca_multi_link_remove_station_vap(struct wiphy *wiphy);
|
||||||
|
bool qca_multi_link_add_station_vap(struct wiphy *wiphy,
|
||||||
|
struct net_device *sta_dev);
|
||||||
bool qca_multi_link_ap_rx(struct net_device *net_dev, qdf_nbuf_t nbuf);
|
bool qca_multi_link_ap_rx(struct net_device *net_dev, qdf_nbuf_t nbuf);
|
||||||
bool qca_multi_link_sta_rx(struct net_device *net_dev, qdf_nbuf_t nbuf);
|
bool qca_multi_link_sta_rx(struct net_device *net_dev, qdf_nbuf_t nbuf);
|
||||||
bool qca_multi_link_sta_tx(struct net_device *net_dev, qdf_nbuf_t nbuf);
|
bool qca_multi_link_sta_tx(struct net_device *net_dev, qdf_nbuf_t nbuf);
|
||||||
|
@@ -19,66 +19,69 @@
|
|||||||
static bool is_initialized;
|
static bool is_initialized;
|
||||||
qca_multi_link_parameters_t qca_multi_link_cfg;
|
qca_multi_link_parameters_t qca_multi_link_cfg;
|
||||||
|
|
||||||
static inline bool is_fast_lane_radio(struct wiphy *fl_wiphy)
|
static inline qca_multi_link_radio_node_t *
|
||||||
|
qca_multi_link_find_radio_node(struct wiphy *wiphy)
|
||||||
{
|
{
|
||||||
qdf_list_node_t *node = NULL, *next_node = NULL;
|
qdf_list_node_t *node = NULL, *next_node = NULL;
|
||||||
|
|
||||||
if (!fl_wiphy) {
|
if (!wiphy) {
|
||||||
return false;
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_WARN,
|
||||||
|
FL(" Radio wiphy pointer is NULL\n"));
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qdf_list_empty(&qca_multi_link_cfg.fast_lane_list)) {
|
if (qdf_list_empty(&qca_multi_link_cfg.radio_list)) {
|
||||||
return false;
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG,
|
||||||
|
FL(" Radio list is empty\n"));
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_list_peek_front(&qca_multi_link_cfg.fast_lane_list,
|
qdf_list_peek_front(&qca_multi_link_cfg.radio_list,
|
||||||
(qdf_list_node_t **)&next_node);
|
(qdf_list_node_t **)&next_node);
|
||||||
while (next_node) {
|
while (next_node) {
|
||||||
struct qca_multi_link_list_node *fast_lane_node
|
qca_multi_link_radio_node_t *radio_node
|
||||||
= (struct qca_multi_link_list_node *)next_node;
|
= (qca_multi_link_radio_node_t *)next_node;
|
||||||
if (fast_lane_node->wiphy == fl_wiphy) {
|
if (radio_node->wiphy == wiphy) {
|
||||||
return true;
|
return radio_node;
|
||||||
} else {
|
} else {
|
||||||
node = next_node;
|
node = next_node;
|
||||||
next_node = NULL;
|
next_node = NULL;
|
||||||
if ((qdf_list_peek_next(&qca_multi_link_cfg.fast_lane_list, node, &next_node))
|
if ((qdf_list_peek_next(&qca_multi_link_cfg.radio_list,
|
||||||
!= QDF_STATUS_SUCCESS) {
|
node, (qdf_list_node_t **)&next_node))
|
||||||
return false;
|
!= QDF_STATUS_SUCCESS) {
|
||||||
}
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool is_fast_lane_radio(struct wiphy *fl_wiphy)
|
||||||
|
{
|
||||||
|
qca_multi_link_radio_node_t *radio_node = NULL;
|
||||||
|
|
||||||
|
qdf_spin_lock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
radio_node = qca_multi_link_find_radio_node(fl_wiphy);
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
if (!radio_node) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return radio_node->is_fast_lane;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_no_backhaul_radio(struct wiphy *no_bl_wiphy)
|
static inline bool is_no_backhaul_radio(struct wiphy *no_bl_wiphy)
|
||||||
{
|
{
|
||||||
qdf_list_node_t *node = NULL, *next_node = NULL;
|
qca_multi_link_radio_node_t *radio_node = NULL;
|
||||||
|
|
||||||
if (!no_bl_wiphy) {
|
qdf_spin_lock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
radio_node = qca_multi_link_find_radio_node(no_bl_wiphy);
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
if (!radio_node) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qdf_list_empty(&qca_multi_link_cfg.no_backhaul_list)) {
|
return radio_node->no_backhaul;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
qdf_list_peek_front(&qca_multi_link_cfg.no_backhaul_list,
|
|
||||||
(qdf_list_node_t **)&next_node);
|
|
||||||
while (next_node) {
|
|
||||||
struct qca_multi_link_list_node *no_bl_node
|
|
||||||
= (struct qca_multi_link_list_node *)next_node;
|
|
||||||
if (no_bl_node->wiphy == no_bl_wiphy) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
node = next_node;
|
|
||||||
next_node = NULL;
|
|
||||||
if ((qdf_list_peek_next(&qca_multi_link_cfg.no_backhaul_list, node, &next_node))
|
|
||||||
!= QDF_STATUS_SUCCESS) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_other_fast_lane_radio_primary(struct wiphy *fl_wiphy)
|
static inline bool is_other_fast_lane_radio_primary(struct wiphy *fl_wiphy)
|
||||||
@@ -89,20 +92,24 @@ static inline bool is_other_fast_lane_radio_primary(struct wiphy *fl_wiphy)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qdf_list_empty(&qca_multi_link_cfg.fast_lane_list)) {
|
if (qdf_list_empty(&qca_multi_link_cfg.radio_list)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_list_peek_front(&qca_multi_link_cfg.fast_lane_list,
|
qdf_spin_lock(&qca_multi_link_cfg.radio_lock);
|
||||||
(qdf_list_node_t **)&next_node);
|
qdf_list_peek_front(&qca_multi_link_cfg.radio_list,
|
||||||
|
(qdf_list_node_t **)&next_node);
|
||||||
while (next_node) {
|
while (next_node) {
|
||||||
struct qca_multi_link_list_node *fast_lane_node
|
qca_multi_link_radio_node_t *radio_node
|
||||||
= (struct qca_multi_link_list_node *)next_node;
|
= (qca_multi_link_radio_node_t *)next_node;
|
||||||
if ((fast_lane_node->wiphy != fl_wiphy)
|
if ((radio_node->wiphy != fl_wiphy) &&
|
||||||
&& (fast_lane_node->wiphy == qca_multi_link_cfg.primary_wiphy)) {
|
(radio_node->is_fast_lane) &&
|
||||||
|
(radio_node->wiphy == qca_multi_link_cfg.primary_wiphy)) {
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,6 +209,26 @@ static inline bool qca_multi_link_drop_always_primary(bool is_primary, qdf_nbuf_
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qca_multi_link_get_station_vap() - get the radio station vap pointer for a radio
|
||||||
|
* @primary_wiphy: wiphy pointer of radio device
|
||||||
|
*
|
||||||
|
* Return: station vap netdevice pointer
|
||||||
|
*/
|
||||||
|
static struct net_device *qca_multi_link_get_station_vap(struct wiphy *wiphy)
|
||||||
|
{
|
||||||
|
qca_multi_link_radio_node_t *radio_node = NULL;
|
||||||
|
|
||||||
|
qdf_spin_lock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
radio_node = qca_multi_link_find_radio_node(wiphy);
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
if (!radio_node || !radio_node->sta_dev) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return radio_node->sta_dev;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qca_multi_link_deinit_module() - De-initialize the repeater base structute
|
* qca_multi_link_deinit_module() - De-initialize the repeater base structute
|
||||||
* Return: void
|
* Return: void
|
||||||
@@ -214,9 +241,9 @@ void qca_multi_link_deinit_module(void)
|
|||||||
qca_multi_link_cfg.total_stavaps_up = 0;
|
qca_multi_link_cfg.total_stavaps_up = 0;
|
||||||
qca_multi_link_cfg.loop_detected = 0;
|
qca_multi_link_cfg.loop_detected = 0;
|
||||||
qca_multi_link_cfg.primary_wiphy = NULL;
|
qca_multi_link_cfg.primary_wiphy = NULL;
|
||||||
qdf_list_destroy(&qca_multi_link_cfg.fast_lane_list);
|
qdf_list_destroy(&qca_multi_link_cfg.radio_list);
|
||||||
qdf_list_destroy(&qca_multi_link_cfg.no_backhaul_list);
|
|
||||||
is_initialized = false;
|
is_initialized = false;
|
||||||
|
qdf_spinlock_destroy(&qca_multi_link_cfg.radio_lock);
|
||||||
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_INFO,
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_INFO,
|
||||||
FL("\n******QCA RPtr De-Init Done***********\n"));
|
FL("\n******QCA RPtr De-Init Done***********\n"));
|
||||||
@@ -238,9 +265,10 @@ void qca_multi_link_init_module(void)
|
|||||||
qca_multi_link_cfg.total_stavaps_up = 0;
|
qca_multi_link_cfg.total_stavaps_up = 0;
|
||||||
qca_multi_link_cfg.loop_detected = 0;
|
qca_multi_link_cfg.loop_detected = 0;
|
||||||
qca_multi_link_cfg.primary_wiphy = NULL;
|
qca_multi_link_cfg.primary_wiphy = NULL;
|
||||||
qdf_list_create(&qca_multi_link_cfg.fast_lane_list, QCA_MULTI_LINK_FAST_LANE_LIST_SIZE);
|
qdf_list_create(&qca_multi_link_cfg.radio_list, QCA_MULTI_LINK_RADIO_LIST_SIZE);
|
||||||
qdf_list_create(&qca_multi_link_cfg.no_backhaul_list, QCA_MULTI_LINK_NO_BACKHAUL_LIST_SIZE);
|
qdf_spinlock_create(&qca_multi_link_cfg.radio_lock);
|
||||||
|
|
||||||
|
memset(&qca_multi_link_cfg.qca_ml_stats, 0x0, sizeof(qca_multi_link_radio_node_t));
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_INFO,
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_INFO,
|
||||||
FL("\n******QCA Repeater Initialization Done***********\n"));
|
FL("\n******QCA Repeater Initialization Done***********\n"));
|
||||||
}
|
}
|
||||||
@@ -299,7 +327,8 @@ qdf_export_symbol(qca_multi_link_append_num_sta);
|
|||||||
bool qca_multi_link_is_dbdc_processing_reqd(struct net_device *net_dev)
|
bool qca_multi_link_is_dbdc_processing_reqd(struct net_device *net_dev)
|
||||||
{
|
{
|
||||||
if (qca_multi_link_cfg.total_stavaps_up > 2)
|
if (qca_multi_link_cfg.total_stavaps_up > 2)
|
||||||
return (qca_multi_link_cfg.loop_detected && qca_multi_link_cfg.rptr_processing_enable);
|
return (qca_multi_link_cfg.loop_detected &&
|
||||||
|
qca_multi_link_cfg.rptr_processing_enable);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -382,11 +411,89 @@ void qca_multi_link_set_primary_radio(struct wiphy *primary_wiphy)
|
|||||||
}
|
}
|
||||||
qca_multi_link_cfg.primary_wiphy = primary_wiphy;
|
qca_multi_link_cfg.primary_wiphy = primary_wiphy;
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_INFO,
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_INFO,
|
||||||
FL("\nSetting primary radio for wiphy%p\n"), primary_wiphy);
|
FL("\n******Setting primary radio for wiphy****%p\n"), primary_wiphy);
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_export_symbol(qca_multi_link_set_primary_radio);
|
qdf_export_symbol(qca_multi_link_set_primary_radio);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qca_multi_link_remove_radio() - remove the radio pointer from repeater list
|
||||||
|
* @primary_wiphy: wiphy pointer of radio device
|
||||||
|
*
|
||||||
|
* Return: false: addition not successful
|
||||||
|
* true: addition is successful
|
||||||
|
*/
|
||||||
|
bool qca_multi_link_remove_radio(struct wiphy *wiphy)
|
||||||
|
{
|
||||||
|
qca_multi_link_radio_node_t *radio_node = NULL;
|
||||||
|
|
||||||
|
qdf_spin_lock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
radio_node = qca_multi_link_find_radio_node(wiphy);
|
||||||
|
if (!radio_node) {
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_list_remove_node(&qca_multi_link_cfg.radio_list, &radio_node->node);
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
qdf_mem_free(radio_node);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_export_symbol(qca_multi_link_remove_radio);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qca_multi_link_add_radio() - add the radio pointer to repeater list
|
||||||
|
* @primary_wiphy: wiphy pointer of radio device
|
||||||
|
*
|
||||||
|
* Return: false: addition not successful
|
||||||
|
* true: addition is successful
|
||||||
|
*/
|
||||||
|
bool qca_multi_link_add_radio(struct wiphy *wiphy)
|
||||||
|
{
|
||||||
|
qca_multi_link_radio_node_t *radio_node = NULL;
|
||||||
|
|
||||||
|
if (!wiphy) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_WARN,
|
||||||
|
FL(" Radio could not be set - wiphy is NULL\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if Radio is already present in reppeater list.
|
||||||
|
*/
|
||||||
|
qdf_spin_lock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
radio_node = qca_multi_link_find_radio_node(wiphy);
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
if (radio_node) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_WARN,
|
||||||
|
FL(" Radio node already present\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_node = qdf_mem_malloc(sizeof(qca_multi_link_radio_node_t));
|
||||||
|
if (!radio_node) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG,
|
||||||
|
FL("Could not allocate node for wiphy%p\n"), wiphy);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_spin_lock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
radio_node->wiphy = wiphy;
|
||||||
|
if (qdf_list_insert_front(&qca_multi_link_cfg.radio_list, &radio_node->node)
|
||||||
|
== QDF_STATUS_SUCCESS) {
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG,
|
||||||
|
FL("Adding radio node for wiphy%p\n"), wiphy);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
qdf_mem_free(radio_node);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_export_symbol(qca_multi_link_add_radio);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qca_multi_link_add_fastlane_radio() - add the fast lane radio pointer to list
|
* qca_multi_link_add_fastlane_radio() - add the fast lane radio pointer to list
|
||||||
* @primary_wiphy: wiphy pointer of fast-lane radio device
|
* @primary_wiphy: wiphy pointer of fast-lane radio device
|
||||||
@@ -396,27 +503,18 @@ qdf_export_symbol(qca_multi_link_set_primary_radio);
|
|||||||
*/
|
*/
|
||||||
bool qca_multi_link_add_fastlane_radio(struct wiphy *fl_wiphy)
|
bool qca_multi_link_add_fastlane_radio(struct wiphy *fl_wiphy)
|
||||||
{
|
{
|
||||||
struct qca_multi_link_list_node *fast_lane_node;
|
qca_multi_link_radio_node_t *radio_node = NULL;
|
||||||
|
|
||||||
if (!fl_wiphy) {
|
qdf_spin_lock(&qca_multi_link_cfg.radio_lock);
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_WARN,
|
radio_node = qca_multi_link_find_radio_node(fl_wiphy);
|
||||||
FL(" Fast lane radio could not be set - wiphy is NULL\n"));
|
if (!radio_node) {
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fast_lane_node = qdf_mem_malloc(sizeof(struct qca_multi_link_list_node));
|
radio_node->is_fast_lane = true;
|
||||||
if (!fast_lane_node) {
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG,
|
return true;
|
||||||
FL("Could not allocate fast-lane node for wiphy%p\n"), fl_wiphy);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
fast_lane_node->wiphy = fl_wiphy;
|
|
||||||
if (qdf_list_insert_front(&qca_multi_link_cfg.fast_lane_list, &fast_lane_node->node)
|
|
||||||
== QDF_STATUS_SUCCESS) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_export_symbol(qca_multi_link_add_fastlane_radio);
|
qdf_export_symbol(qca_multi_link_add_fastlane_radio);
|
||||||
@@ -430,33 +528,18 @@ qdf_export_symbol(qca_multi_link_add_fastlane_radio);
|
|||||||
*/
|
*/
|
||||||
bool qca_multi_link_remove_fastlane_radio(struct wiphy *fl_wiphy)
|
bool qca_multi_link_remove_fastlane_radio(struct wiphy *fl_wiphy)
|
||||||
{
|
{
|
||||||
qdf_list_node_t *node = NULL, *next_node = NULL;
|
qca_multi_link_radio_node_t *radio_node = NULL;
|
||||||
|
|
||||||
if (!fl_wiphy) {
|
qdf_spin_lock(&qca_multi_link_cfg.radio_lock);
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_WARN,
|
radio_node = qca_multi_link_find_radio_node(fl_wiphy);
|
||||||
FL(" Fast lane radio could not be removed - wiphy is NULL\n"));
|
if (!radio_node) {
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_list_peek_front(&qca_multi_link_cfg.fast_lane_list,
|
radio_node->is_fast_lane = false;
|
||||||
(qdf_list_node_t **)&next_node);
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
while (next_node) {
|
return true;
|
||||||
struct qca_multi_link_list_node *fast_lane_node
|
|
||||||
= (struct qca_multi_link_list_node *)next_node;
|
|
||||||
if (fast_lane_node->wiphy == fl_wiphy) {
|
|
||||||
qdf_list_remove_node(&qca_multi_link_cfg.fast_lane_list, next_node);
|
|
||||||
qdf_mem_free(fast_lane_node);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
node = next_node;
|
|
||||||
next_node = NULL;
|
|
||||||
if ((qdf_list_peek_next(&qca_multi_link_cfg.fast_lane_list, node,
|
|
||||||
(qdf_list_node_t **)&next_node)) != QDF_STATUS_SUCCESS) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_export_symbol(qca_multi_link_remove_fastlane_radio);
|
qdf_export_symbol(qca_multi_link_remove_fastlane_radio);
|
||||||
@@ -470,27 +553,18 @@ qdf_export_symbol(qca_multi_link_remove_fastlane_radio);
|
|||||||
*/
|
*/
|
||||||
bool qca_multi_link_add_no_backhaul_radio(struct wiphy *no_bl_wiphy)
|
bool qca_multi_link_add_no_backhaul_radio(struct wiphy *no_bl_wiphy)
|
||||||
{
|
{
|
||||||
struct qca_multi_link_list_node *no_bl_node;
|
qca_multi_link_radio_node_t *radio_node = NULL;
|
||||||
|
|
||||||
if (!no_bl_wiphy) {
|
qdf_spin_lock(&qca_multi_link_cfg.radio_lock);
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_WARN,
|
radio_node = qca_multi_link_find_radio_node(no_bl_wiphy);
|
||||||
FL(" No backhaul radio could not be set - wiphy is NULL\n"));
|
if (!radio_node) {
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
no_bl_node = qdf_mem_malloc(sizeof(struct qca_multi_link_list_node));
|
radio_node->no_backhaul = true;
|
||||||
if (!no_bl_node) {
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG,
|
return true;
|
||||||
FL("Could not allocate back-haul node for wiphy%p\n"), no_bl_node);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
no_bl_node->wiphy = no_bl_wiphy;
|
|
||||||
if (qdf_list_insert_front(&qca_multi_link_cfg.no_backhaul_list, &no_bl_node->node)
|
|
||||||
== QDF_STATUS_SUCCESS) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_export_symbol(qca_multi_link_add_no_backhaul_radio);
|
qdf_export_symbol(qca_multi_link_add_no_backhaul_radio);
|
||||||
@@ -504,37 +578,81 @@ qdf_export_symbol(qca_multi_link_add_no_backhaul_radio);
|
|||||||
*/
|
*/
|
||||||
bool qca_multi_link_remove_no_backhaul_radio(struct wiphy *no_bl_wiphy)
|
bool qca_multi_link_remove_no_backhaul_radio(struct wiphy *no_bl_wiphy)
|
||||||
{
|
{
|
||||||
qdf_list_node_t *node = NULL, *next_node = NULL;
|
qca_multi_link_radio_node_t *radio_node = NULL;
|
||||||
|
|
||||||
if (!no_bl_wiphy) {
|
qdf_spin_lock(&qca_multi_link_cfg.radio_lock);
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_WARN,
|
radio_node = qca_multi_link_find_radio_node(no_bl_wiphy);
|
||||||
FL(" No backhaul radio could not be removed - wiphy is NULL\n"));
|
if (!radio_node) {
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_list_peek_front(&qca_multi_link_cfg.no_backhaul_list,
|
radio_node->no_backhaul = false;
|
||||||
(qdf_list_node_t **)&next_node);
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
while (next_node) {
|
return true;
|
||||||
struct qca_multi_link_list_node *no_bl_node
|
|
||||||
= (struct qca_multi_link_list_node *)next_node;
|
|
||||||
if (no_bl_node->wiphy == no_bl_wiphy) {
|
|
||||||
qdf_list_remove_node(&qca_multi_link_cfg.no_backhaul_list, next_node);
|
|
||||||
qdf_mem_free(no_bl_node);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
node = next_node;
|
|
||||||
next_node = NULL;
|
|
||||||
if ((qdf_list_peek_next(&qca_multi_link_cfg.no_backhaul_list, node, &next_node))
|
|
||||||
!= QDF_STATUS_SUCCESS) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_export_symbol(qca_multi_link_remove_no_backhaul_radio);
|
qdf_export_symbol(qca_multi_link_remove_no_backhaul_radio);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qca_multi_link_remove_station_vap() - remove the radio station vap pointer for a radio
|
||||||
|
* @primary_wiphy: wiphy pointer of radio device
|
||||||
|
*
|
||||||
|
* Return: false: addition not successful
|
||||||
|
* true: addition is successful
|
||||||
|
*/
|
||||||
|
bool qca_multi_link_remove_station_vap(struct wiphy *wiphy)
|
||||||
|
{
|
||||||
|
qca_multi_link_radio_node_t *radio_node = NULL;
|
||||||
|
|
||||||
|
qdf_spin_lock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
radio_node = qca_multi_link_find_radio_node(wiphy);
|
||||||
|
if (!radio_node) {
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_node->sta_dev = NULL;
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_export_symbol(qca_multi_link_remove_station_vap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qca_multi_link_add_station_vap() - add the station vap pointer for a radio
|
||||||
|
* @primary_wiphy: wiphy pointer of radio device
|
||||||
|
*
|
||||||
|
* Return: false: addition not successful
|
||||||
|
* true: addition is successful
|
||||||
|
*/
|
||||||
|
bool qca_multi_link_add_station_vap(struct wiphy *wiphy, struct net_device *sta_dev)
|
||||||
|
{
|
||||||
|
qca_multi_link_radio_node_t *radio_node = NULL;
|
||||||
|
|
||||||
|
qdf_spin_lock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
radio_node = qca_multi_link_find_radio_node(wiphy);
|
||||||
|
if (!radio_node) {
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (radio_node->sta_dev) {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_WARN,
|
||||||
|
FL("STA Device already mapped for wiphy%p\n"), wiphy);
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
radio_node->sta_dev = sta_dev;
|
||||||
|
qdf_spin_unlock(&qca_multi_link_cfg.radio_lock);
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG,
|
||||||
|
FL("STA Device mapped for wiphy%p\n"), wiphy);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_export_symbol(qca_multi_link_add_station_vap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qca_multi_link_secondary_ap_rx() - Processing for frames recieved on Secondary AP VAP
|
* qca_multi_link_secondary_ap_rx() - Processing for frames recieved on Secondary AP VAP
|
||||||
* @net_device: net device handle
|
* @net_device: net device handle
|
||||||
@@ -599,13 +717,16 @@ static qca_multi_link_status_t qca_multi_link_secondary_ap_rx(struct net_device
|
|||||||
/*
|
/*
|
||||||
* Find the station vap corresponding to the AP vap.
|
* Find the station vap corresponding to the AP vap.
|
||||||
*/
|
*/
|
||||||
sta_dev = qca_multi_link_tbl_find_sta_or_ap(ap_dev, 1);
|
sta_dev = qca_multi_link_get_station_vap(ap_wiphy);
|
||||||
if (!sta_dev) {
|
if (!sta_dev) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG,
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG,
|
||||||
FL("Null STA device found %pM - Give to bridge\n"), eh->ether_shost);
|
FL("Null STA device found %pM - Give to bridge\n"), eh->ether_shost);
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.ap_rx_sec_sta_null++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qca_multi_link_tbl_add_or_refresh_entry(ap_dev, eh->ether_shost,
|
||||||
|
QCA_MULTI_LINK_ENTRY_USER_ADDED);
|
||||||
dev_hold(sta_dev);
|
dev_hold(sta_dev);
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG,
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG,
|
||||||
FL("shost %pM dhost %pM \n"), eh->ether_shost, eh->ether_dhost);
|
FL("shost %pM dhost %pM \n"), eh->ether_shost, eh->ether_dhost);
|
||||||
@@ -728,6 +849,7 @@ static qca_multi_link_status_t qca_multi_link_secondary_sta_rx(struct net_device
|
|||||||
* Always drop mcast packets on secondary radio when loop has been detected.
|
* Always drop mcast packets on secondary radio when loop has been detected.
|
||||||
*/
|
*/
|
||||||
if (qca_multi_link_cfg.loop_detected) {
|
if (qca_multi_link_cfg.loop_detected) {
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_rx_sec_sta_mcast_drop++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -739,13 +861,14 @@ static qca_multi_link_status_t qca_multi_link_secondary_sta_rx(struct net_device
|
|||||||
if (qal_status != QDF_STATUS_SUCCESS) {
|
if (qal_status != QDF_STATUS_SUCCESS) {
|
||||||
if (!qca_multi_link_cfg.loop_detected
|
if (!qca_multi_link_cfg.loop_detected
|
||||||
&& !qca_multi_link_cfg.drop_secondary_mcast) {
|
&& !qca_multi_link_cfg.drop_secondary_mcast) {
|
||||||
/*
|
/*
|
||||||
* This condition is to allow packets on Secondary Station
|
* This condition is to allow packets on Secondary Station
|
||||||
* when stations are connected to different RootAPs and loop is not
|
* when stations are connected to different RootAPs and loop is not
|
||||||
* detected.
|
* detected.
|
||||||
*/
|
*/
|
||||||
return QCA_MULTI_LINK_PKT_ALLOW;
|
return QCA_MULTI_LINK_PKT_ALLOW;
|
||||||
} else {
|
} else {
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_rx_sec_sta_mcast_no_fdb++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -769,10 +892,12 @@ static qca_multi_link_status_t qca_multi_link_secondary_sta_rx(struct net_device
|
|||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_INFO, FL("\n****Wifi Rptr Loop Detected****\n"));
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_INFO, FL("\n****Wifi Rptr Loop Detected****\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_rx_sec_sta_mcast_dup_pkts++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qca_multi_link_drop_secondary_mcast(nbuf)) {
|
if (qca_multi_link_drop_secondary_mcast(nbuf)) {
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_rx_sec_sta_mcast_drop_sec++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -787,6 +912,7 @@ static qca_multi_link_status_t qca_multi_link_secondary_sta_rx(struct net_device
|
|||||||
return QCA_MULTI_LINK_PKT_ALLOW;
|
return QCA_MULTI_LINK_PKT_ALLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_rx_sec_sta_mcast_drop++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -807,6 +933,7 @@ static qca_multi_link_status_t qca_multi_link_secondary_sta_rx(struct net_device
|
|||||||
* on secondary stations.
|
* on secondary stations.
|
||||||
*/
|
*/
|
||||||
if (!qca_ml_entry.qal_fdb_ieee80211_ptr) {
|
if (!qca_ml_entry.qal_fdb_ieee80211_ptr) {
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_rx_sec_sta_ucast_src_eth++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -818,16 +945,17 @@ static qca_multi_link_status_t qca_multi_link_secondary_sta_rx(struct net_device
|
|||||||
&& (qca_ml_entry.qal_fdb_ieee80211_ptr->wiphy == sta_wiphy)) {
|
&& (qca_ml_entry.qal_fdb_ieee80211_ptr->wiphy == sta_wiphy)) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG, FL("Unicast Sec STA to AP direct enq for\
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG, FL("Unicast Sec STA to AP direct enq for\
|
||||||
shost %pM dhost %pM \n"), eh->ether_shost, eh->ether_dhost);
|
shost %pM dhost %pM \n"), eh->ether_shost, eh->ether_dhost);
|
||||||
/*
|
/*
|
||||||
* Holding the AP dev so that it cannot be brought down
|
* Holding the AP dev so that it cannot be brought down
|
||||||
* while we are enqueueing.
|
* while we are enqueueing.
|
||||||
*/
|
*/
|
||||||
dev_hold(qca_ml_entry.qal_fdb_dev);
|
dev_hold(qca_ml_entry.qal_fdb_dev);
|
||||||
qca_ml_entry.qal_fdb_dev->netdev_ops->ndo_start_xmit(nbuf, qca_ml_entry.qal_fdb_dev);
|
qca_ml_entry.qal_fdb_dev->netdev_ops->ndo_start_xmit(nbuf, qca_ml_entry.qal_fdb_dev);
|
||||||
dev_put(qca_ml_entry.qal_fdb_dev);
|
dev_put(qca_ml_entry.qal_fdb_dev);
|
||||||
return QCA_MULTI_LINK_PKT_CONSUMED;
|
return QCA_MULTI_LINK_PKT_CONSUMED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_rx_sec_sta_ucast_src_dif_band++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@@ -843,7 +971,8 @@ static qca_multi_link_status_t qca_multi_link_secondary_sta_rx(struct net_device
|
|||||||
ap_dev = qca_multi_link_tbl_find_sta_or_ap(sta_dev, 0);
|
ap_dev = qca_multi_link_tbl_find_sta_or_ap(sta_dev, 0);
|
||||||
if (!ap_dev) {
|
if (!ap_dev) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG,
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG,
|
||||||
FL("Null AP device found %pM - Give to bridge\n"), eh->ether_shost);
|
FL("Null AP device found %pM - Drop\n"), eh->ether_shost);
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_rx_sec_sta_ucast_no_ap++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -913,6 +1042,7 @@ static qca_multi_link_status_t qca_multi_link_primary_sta_rx(struct net_device *
|
|||||||
*/
|
*/
|
||||||
return QCA_MULTI_LINK_PKT_ALLOW;
|
return QCA_MULTI_LINK_PKT_ALLOW;
|
||||||
}
|
}
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_rx_pri_sta_mcast_no_fdb++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -931,13 +1061,15 @@ static qca_multi_link_status_t qca_multi_link_primary_sta_rx(struct net_device *
|
|||||||
* Drop the loopback mcast packets from ethernet devices behind the repeater.
|
* Drop the loopback mcast packets from ethernet devices behind the repeater.
|
||||||
*/
|
*/
|
||||||
if (!qca_ml_entry.qal_fdb_ieee80211_ptr) {
|
if (!qca_ml_entry.qal_fdb_ieee80211_ptr) {
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_rx_pri_sta_mcast_drop++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qca_ml_entry.qal_fdb_ieee80211_ptr->wiphy != sta_wiphy) {
|
if (qca_ml_entry.qal_fdb_ieee80211_ptr->wiphy != sta_wiphy) {
|
||||||
if (!qca_multi_link_cfg.loop_detected) {
|
if (qca_ml_entry.qal_fdb_is_local &&
|
||||||
if (qca_ml_entry.qal_fdb_is_local
|
(qca_ml_entry.qal_fdb_ieee80211_ptr->iftype
|
||||||
&& (qca_ml_entry.qal_fdb_ieee80211_ptr->iftype == NL80211_IFTYPE_STATION)) {
|
== NL80211_IFTYPE_STATION)) {
|
||||||
|
if (!qca_multi_link_cfg.loop_detected) {
|
||||||
qca_multi_link_cfg.loop_detected = true;
|
qca_multi_link_cfg.loop_detected = true;
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_INFO,
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_INFO,
|
||||||
FL("\n****Wifi Rptr Loop Detected****\n"));
|
FL("\n****Wifi Rptr Loop Detected****\n"));
|
||||||
@@ -954,6 +1086,7 @@ static qca_multi_link_status_t qca_multi_link_primary_sta_rx(struct net_device *
|
|||||||
return QCA_MULTI_LINK_PKT_ALLOW;
|
return QCA_MULTI_LINK_PKT_ALLOW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_rx_pri_sta_mcast_drop++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -966,6 +1099,7 @@ static qca_multi_link_status_t qca_multi_link_primary_sta_rx(struct net_device *
|
|||||||
return QCA_MULTI_LINK_PKT_ALLOW;
|
return QCA_MULTI_LINK_PKT_ALLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_rx_pri_sta_mcast_drop++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1052,6 +1186,7 @@ static qca_multi_link_status_t qca_multi_link_secondary_sta_tx(struct net_device
|
|||||||
qdf_ether_header_t *eh = (qdf_ether_header_t *) qdf_nbuf_data(nbuf);
|
qdf_ether_header_t *eh = (qdf_ether_header_t *) qdf_nbuf_data(nbuf);
|
||||||
|
|
||||||
if (qca_multi_link_drop_always_primary(false, nbuf)) {
|
if (qca_multi_link_drop_always_primary(false, nbuf)) {
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_tx_sec_sta_alwys_prim++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1073,8 +1208,9 @@ static qca_multi_link_status_t qca_multi_link_secondary_sta_tx(struct net_device
|
|||||||
&qca_ml_entry);
|
&qca_ml_entry);
|
||||||
if (qal_status != QDF_STATUS_SUCCESS) {
|
if (qal_status != QDF_STATUS_SUCCESS) {
|
||||||
if (!is_mcast) {
|
if (!is_mcast) {
|
||||||
return QCA_MULTI_LINK_PKT_ALLOW;
|
return QCA_MULTI_LINK_PKT_ALLOW;
|
||||||
}
|
}
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_tx_sec_sta_mcast_no_fdb++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1083,6 +1219,7 @@ static qca_multi_link_status_t qca_multi_link_secondary_sta_tx(struct net_device
|
|||||||
* ieee80211_ptr pointer will be NULL for ethernet devices.
|
* ieee80211_ptr pointer will be NULL for ethernet devices.
|
||||||
* Packets from ethernet devices or bridge are allowed only on Primary radio.
|
* Packets from ethernet devices or bridge are allowed only on Primary radio.
|
||||||
*/
|
*/
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_tx_sec_sta_src_eth++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1095,6 +1232,7 @@ static qca_multi_link_status_t qca_multi_link_secondary_sta_tx(struct net_device
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (qca_multi_link_drop_secondary_mcast(nbuf)) {
|
if (qca_multi_link_drop_secondary_mcast(nbuf)) {
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_tx_sec_sta_mcast_drop_sec++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1105,6 +1243,7 @@ static qca_multi_link_status_t qca_multi_link_secondary_sta_tx(struct net_device
|
|||||||
if (qca_ml_entry.qal_fdb_ieee80211_ptr->wiphy != sta_dev->ieee80211_ptr->wiphy) {
|
if (qca_ml_entry.qal_fdb_ieee80211_ptr->wiphy != sta_dev->ieee80211_ptr->wiphy) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG, FL("STA TX: Diff Band Primary drop\
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG, FL("STA TX: Diff Band Primary drop\
|
||||||
shost %pM dhost %pM \n"), eh->ether_shost, eh->ether_dhost);
|
shost %pM dhost %pM \n"), eh->ether_shost, eh->ether_dhost);
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_tx_sec_sta_drop_dif_band++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1152,6 +1291,7 @@ static qca_multi_link_status_t qca_multi_link_primary_sta_tx(struct net_device *
|
|||||||
* as they will be received from bridge only.
|
* as they will be received from bridge only.
|
||||||
*/
|
*/
|
||||||
if (qal_status != QDF_STATUS_SUCCESS) {
|
if (qal_status != QDF_STATUS_SUCCESS) {
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_tx_pri_sta_drop_no_fdb++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1186,6 +1326,7 @@ static qca_multi_link_status_t qca_multi_link_primary_sta_tx(struct net_device *
|
|||||||
if (qca_ml_entry.qal_fdb_ieee80211_ptr->wiphy != sta_dev->ieee80211_ptr->wiphy) {
|
if (qca_ml_entry.qal_fdb_ieee80211_ptr->wiphy != sta_dev->ieee80211_ptr->wiphy) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG, FL("STA TX: Diff Band Primary drop\
|
QDF_TRACE(QDF_MODULE_ID_RPTR, QDF_TRACE_LEVEL_DEBUG, FL("STA TX: Diff Band Primary drop\
|
||||||
shost %pM dhost %pM \n"), eh->ether_shost, eh->ether_dhost);
|
shost %pM dhost %pM \n"), eh->ether_shost, eh->ether_dhost);
|
||||||
|
qca_multi_link_cfg.qca_ml_stats.sta_tx_pri_sta_drop_dif_band++;
|
||||||
return QCA_MULTI_LINK_PKT_DROP;
|
return QCA_MULTI_LINK_PKT_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qca_multi_link_tbl.h"
|
#include "qca_multi_link_tbl.h"
|
||||||
|
#include "qca_multi_link.h"
|
||||||
#include "qdf_module.h"
|
#include "qdf_module.h"
|
||||||
#include "qdf_trace.h"
|
#include "qdf_trace.h"
|
||||||
|
|
||||||
@@ -179,6 +180,10 @@ QDF_STATUS qca_multi_link_tbl_delete_entry(struct net_device *net_dev, uint8_t *
|
|||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!qca_multi_link_is_dbdc_processing_reqd(net_dev)) {
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 24)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 24)
|
||||||
fdb_port = br_port_get_rcu(net_dev);
|
fdb_port = br_port_get_rcu(net_dev);
|
||||||
if (!fdb_port) {
|
if (!fdb_port) {
|
||||||
|
Reference in New Issue
Block a user