qcacld-3.0: Add TDLS connection tracker in WLAN host

TDLS implicit trigger mode works based on data traffic without
user intervention. When the traffic meets setup threshold,
TDLS connection is initiated and when the traffic
reaches a teardown threshold/rssi TDLS connection
is torn down.
Add TDLS connection tracker in the host driver to determine,
when to initiate and teardown the TDLS connection based
on data traffic.

Change-Id: I995ea9c391372515faabe5086b638f254b6b93d7
CRs-Fixed: 996988
Cette révision appartient à :
Kabilan Kannan
2016-05-03 19:28:44 -07:00
révisé par Vishwajith Upendra
Parent 805cfb5863
révision 36090ce8b4
7 fichiers modifiés avec 966 ajouts et 60 suppressions

Voir le fichier

@@ -554,6 +554,7 @@ struct cds_conc_connection_info {
bool cds_is_connection_in_progress(void);
void cds_dump_concurrency_info(void);
void cds_set_tdls_ct_mode(hdd_context_t *hdd_ctx);
void cds_set_concurrency_mode(enum tQDF_ADAPTER_MODE mode);
void cds_clear_concurrency_mode(enum tQDF_ADAPTER_MODE mode);
uint32_t cds_get_connection_count(void);

Voir le fichier

@@ -3371,6 +3371,41 @@ void cds_dump_concurrency_info(void)
}
}
/**
* cds_set_tdls_ct_mode() - Set the tdls connection tracker mode
* @hdd_ctx: hdd context
*
* This routine is called to set the tdls connection tracker operation status
*
* Return: NONE
*/
void cds_set_tdls_ct_mode(hdd_context_t *hdd_ctx)
{
bool state = false;
/* If any concurrency is detected, skip tdls pkt tracker */
if (((1 << QDF_STA_MODE) == hdd_ctx->concurrency_mode) &&
(hdd_ctx->no_of_active_sessions[QDF_STA_MODE] == 1) &&
(hdd_ctx->config->fEnableTDLSImplicitTrigger) &&
(eTDLS_SUPPORT_DISABLED != hdd_ctx->tdls_mode)) {
if (hdd_ctx->config->fTDLSExternalControl) {
if (hdd_ctx->tdls_external_peer_count)
state = true;
goto set_state;
} else {
state = true;
}
}
set_state:
mutex_lock(&hdd_ctx->tdls_lock);
hdd_ctx->enable_tdls_connection_tracker = state;
mutex_unlock(&hdd_ctx->tdls_lock);
cds_info("enable_tdls_connection_tracker %d",
hdd_ctx->enable_tdls_connection_tracker);
}
/**
* cds_set_concurrency_mode() - To set concurrency mode
* @mode: adapter mode
@@ -3402,6 +3437,10 @@ void cds_set_concurrency_mode(enum tQDF_ADAPTER_MODE mode)
default:
break;
}
/* set tdls connection tracker state */
cds_set_tdls_ct_mode(hdd_ctx);
cds_info("concurrency_mode = 0x%x Number of open sessions for mode %d = %d",
hdd_ctx->concurrency_mode, mode,
hdd_ctx->no_of_open_sessions[mode]);
@@ -3438,6 +3477,10 @@ void cds_clear_concurrency_mode(enum tQDF_ADAPTER_MODE mode)
default:
break;
}
/* set tdls connection tracker state */
cds_set_tdls_ct_mode(hdd_ctx);
cds_info("concurrency_mode = 0x%x Number of open sessions for mode %d = %d",
hdd_ctx->concurrency_mode, mode,
hdd_ctx->no_of_open_sessions[mode]);
@@ -3550,8 +3593,13 @@ void cds_incr_active_session(enum tQDF_ADAPTER_MODE mode,
default:
break;
}
/* set tdls connection tracker state */
cds_set_tdls_ct_mode(hdd_ctx);
cds_info("No.# of active sessions for mode %d = %d",
mode, hdd_ctx->no_of_active_sessions[mode]);
/*
* Get PCL logic makes use of the connection info structure.
* Let us set the PCL to the FW before updating the connection
@@ -3826,8 +3874,13 @@ void cds_decr_active_session(enum tQDF_ADAPTER_MODE mode,
default:
break;
}
/* set tdls connection tracker state */
cds_set_tdls_ct_mode(hdd_ctx);
cds_info("No.# of active sessions for mode %d = %d",
mode, hdd_ctx->no_of_active_sessions[mode]);
cds_decr_connection_count(session_id);
qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
}

Voir le fichier

@@ -1257,10 +1257,13 @@ struct hdd_context_s {
uint16_t connected_peer_count;
tdls_scan_context_t tdls_scan_ctxt;
/* Lock to avoid race condition during TDLS operations */
qdf_spinlock_t tdls_ct_spinlock;
struct mutex tdls_lock;
uint8_t tdls_off_channel;
uint16_t tdls_channel_offset;
int32_t tdls_fw_off_chan_mode;
bool enable_tdls_connection_tracker;
uint8_t tdls_external_peer_count;
#endif
void *hdd_ipa;

Voir le fichier

@@ -63,8 +63,12 @@
#define TDLS_PEER_LIST_SIZE 256
#define TDLS_CT_MAC_AGE_OUT_TIME (30*60*1000) /* Age out time is 30 mins */
#define EXTTDLS_EVENT_BUF_SIZE (4096)
#define TDLS_CT_MAC_MAX_TABLE_SIZE 8
/**
* struct tdls_config_params_t - tdls config params
*
@@ -72,6 +76,7 @@
* @tx_period_t: tx period
* @tx_packet_n: tx packets number
* @discovery_tries_n: discovery tries
* @idle_timeout_t: idle traffic time out value
* @idle_packet_n: idle packet number
* @rssi_trigger_threshold: rssi trigger threshold
* @rssi_teardown_threshold: rssi tear down threshold
@@ -82,6 +87,7 @@ typedef struct {
uint32_t tx_period_t;
uint32_t tx_packet_n;
uint32_t discovery_tries_n;
uint32_t idle_timeout_t;
uint32_t idle_packet_n;
int32_t rssi_trigger_threshold;
int32_t rssi_teardown_threshold;
@@ -285,11 +291,25 @@ typedef struct {
struct _hddTdlsPeer_t;
/**
* struct tdls_ct_mac_table - connection tracker peer mac address table
* @mac_address: peer mac address
* @tx_packet_cnt: number of tx pkts
* @rx_packet_cnt: number of rx pkts
* @peer_timestamp_ms: time stamp of latest peer traffic
*/
struct tdls_ct_mac_table {
struct qdf_mac_addr mac_address;
uint32_t tx_packet_cnt;
uint32_t rx_packet_cnt;
uint32_t peer_timestamp_ms;
};
/**
* struct tdlsCtx_t - tdls context
*
* @peer_list: peer list
* @pAdapter: pointer to adapter
* @peer_update_timer: connection tracker timer
* @peerDiscoverTimer: peer discovery timer
* @peerDiscoveryTimeoutTimer: peer discovery timeout timer
* @threshold_config: threshold config
@@ -298,12 +318,15 @@ struct _hddTdlsPeer_t;
* @ap_rssi: ap rssi
* @curr_candidate: current candidate
* @implicit_setup: implicit setup work queue
* @ct_peer_mac_table: linear mac address table for counting the packets
* @valid_mac_entries: number of valid mac entry in @ct_peer_mac_table
* @magic: magic
*
*/
typedef struct {
struct list_head peer_list[TDLS_PEER_LIST_SIZE];
hdd_adapter_t *pAdapter;
qdf_mc_timer_t peer_update_timer;
qdf_mc_timer_t peerDiscoveryTimeoutTimer;
tdls_config_params_t threshold_config;
int32_t discovery_peer_cnt;
@@ -311,6 +334,8 @@ typedef struct {
int8_t ap_rssi;
struct _hddTdlsPeer_t *curr_candidate;
struct work_struct implicit_setup;
struct tdls_ct_mac_table ct_peer_mac_table[TDLS_CT_MAC_MAX_TABLE_SIZE];
uint8_t valid_mac_entries;
uint32_t magic;
} tdlsCtx_t;
@@ -342,6 +367,8 @@ typedef struct {
* @op_class_for_pref_off_chan: op class for preferred off channel
* @pref_off_chan_num: preferred off channel number
* @op_class_for_pref_off_chan_is_set: op class for preferred off channel set
* @peer_idle_timer: time to check idle traffic in tdls peers
* @is_peer_idle_timer_initialised: Flag to check idle timer init
* @reason: reason
* @state_change_notification: state change notification
*/
@@ -371,6 +398,8 @@ typedef struct _hddTdlsPeer_t {
uint8_t op_class_for_pref_off_chan;
uint8_t pref_off_chan_num;
uint8_t op_class_for_pref_off_chan_is_set;
qdf_mc_timer_t peer_idle_timer;
bool is_peer_idle_timer_initialised;
tTDLSLinkReason reason;
cfg80211_exttdls_callback state_change_notification;
} hddTdlsPeer_t;
@@ -451,14 +480,16 @@ int wlan_hdd_tdls_get_link_establish_params(hdd_adapter_t *pAdapter,
tCsrTdlsLinkEstablishParams *
tdlsLinkEstablishParams);
hddTdlsPeer_t *wlan_hdd_tdls_get_peer(hdd_adapter_t *pAdapter,
const uint8_t *mac);
const uint8_t *mac,
bool need_mutex_lock);
int wlan_hdd_tdls_set_cap(hdd_adapter_t *pAdapter, const uint8_t *mac,
tTDLSCapType cap);
void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer,
tTDLSLinkStatus status,
tTDLSLinkReason reason);
tTDLSLinkReason reason,
bool lock_needed);
void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter,
const uint8_t *mac,
tTDLSLinkStatus linkStatus,
@@ -503,7 +534,8 @@ void wlan_hdd_tdls_tncrement_peer_count(hdd_adapter_t *pAdapter);
void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter);
hddTdlsPeer_t *wlan_hdd_tdls_is_progress(hdd_context_t *pHddCtx,
const uint8_t *mac, uint8_t skip_self);
const uint8_t *mac, uint8_t skip_self,
bool need_lock);
int wlan_hdd_tdls_copy_scan_context(hdd_context_t *pHddCtx,
struct wiphy *wiphy,
@@ -630,10 +662,13 @@ hddTdlsPeer_t *wlan_hdd_tdls_find_first_connected_peer(hdd_adapter_t *adapter);
int hdd_set_tdls_offchannel(hdd_context_t *hdd_ctx, int offchannel);
int hdd_set_tdls_secoffchanneloffset(hdd_context_t *hdd_ctx, int offchanoffset);
int hdd_set_tdls_offchannelmode(hdd_adapter_t *adapter, int offchanmode);
void wlan_hdd_tdls_update_tx_pkt_cnt(hdd_adapter_t *adapter,
struct sk_buff *skb);
void wlan_hdd_tdls_update_rx_pkt_cnt(hdd_adapter_t *adapter,
struct sk_buff *skb);
int hdd_set_tdls_scan_type(hdd_context_t *hdd_ctx, int val);
void hdd_tdls_context_init(hdd_context_t *hdd_ctx);
void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx);
#else
static inline void hdd_tdls_notify_mode_change(hdd_adapter_t *adapter,
hdd_context_t *hddctx)
@@ -646,7 +681,14 @@ wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_context_t *hddctx)
static inline void wlan_hdd_tdls_exit(hdd_adapter_t *adapter)
{
}
static inline void wlan_hdd_tdls_update_tx_pkt_cnt(hdd_adapter_t *adapter,
struct sk_buff *skb)
{
}
static inline void wlan_hdd_tdls_update_rx_pkt_cnt(hdd_adapter_t *adapter,
struct sk_buff *skb)
{
}
static inline void hdd_tdls_context_init(hdd_context_t *hdd_ctx) { }
static inline void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx) { }
#endif /* End of FEATURE_WLAN_TDLS */

Voir le fichier

@@ -3315,7 +3315,8 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
curr_peer =
wlan_hdd_tdls_get_peer(pAdapter,
pRoamInfo->peerMac.bytes);
pRoamInfo->peerMac.bytes,
true);
if (!curr_peer) {
hddLog(LOGE, FL("curr_peer is null"));
status = QDF_STATUS_E_FAILURE;

Fichier diff supprimé car celui-ci est trop grand Voir la Diff

Voir le fichier

@@ -315,6 +315,10 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
bool granted;
uint8_t STAId = WLAN_MAX_STA_COUNT;
hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station;
#ifdef QCA_PKT_PROTO_TRACE
uint8_t proto_type = 0;
#endif /* QCA_PKT_PROTO_TRACE */
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
#ifdef QCA_WIFI_FTM
if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
@@ -466,7 +470,25 @@ int hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb->queue_mapping = hdd_linux_up_to_ac_map[up];
}
#ifdef QCA_PKT_PROTO_TRACE
if ((hdd_ctx->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_EAPOL) ||
(hdd_ctx->config->gEnableDebugLog & CDS_PKT_TRAC_TYPE_DHCP)) {
proto_type = cds_pkt_get_proto_type(skb,
hdd_ctx->config->gEnableDebugLog,
0);
if (CDS_PKT_TRAC_TYPE_EAPOL & proto_type) {
cds_pkt_trace_buf_update("ST:T:EPL");
} else if (CDS_PKT_TRAC_TYPE_DHCP & proto_type) {
cds_pkt_trace_buf_update("ST:T:DHC");
}
}
#endif /* QCA_PKT_PROTO_TRACE */
pAdapter->stats.tx_bytes += skb->len;
if (hdd_ctx->enable_tdls_connection_tracker)
wlan_hdd_tdls_update_tx_pkt_cnt(pAdapter, skb);
++pAdapter->stats.tx_packets;
/* Zero out skb's context buffer for the driver to use */
@@ -805,6 +827,9 @@ QDF_STATUS hdd_rx_packet_cbk(void *context, qdf_nbuf_t rxBuf)
qdf_nbuf_data_addr(rxBuf),
sizeof(qdf_nbuf_data(rxBuf)), QDF_RX));
if (pHddCtx->enable_tdls_connection_tracker)
wlan_hdd_tdls_update_rx_pkt_cnt(pAdapter, skb);
skb->dev = pAdapter->dev;
skb->protocol = eth_type_trans(skb, skb->dev);
++pAdapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index];