int mx250_fm_request(void)
{
- SCSC_TAG_DEBUG(FM, "mx250: %s\n", __func__);
+ SCSC_TAG_INFO(FM, "request\n");
return mx250_fm_re(true);
}
EXPORT_SYMBOL(mx250_fm_request);
*/
int mx250_fm_release(void)
{
- SCSC_TAG_DEBUG(FM, "mx250: %s\n", __func__);
+ SCSC_TAG_INFO(FM, "release\n");
return mx250_fm_re(false);
}
EXPORT_SYMBOL(mx250_fm_release);
break;
case SCSC_PANIC_ORIGIN_HOST:
SCSC_TAG_INFO(MXMAN, "WLBT HOST detected FW failure, service:\n");
- switch (subcode) {
+ switch (subcode >> SCSC_SYSERR_HOST_SERVICE_SHIFT) {
case SCSC_SERVICE_ID_WLAN:
SCSC_TAG_INFO(MXMAN, " WLAN\n");
break;
void mxman_send_gdb_channel(struct scsc_mx *mx, void *data, size_t length);
#ifdef CONFIG_SCSC_CHV_SUPPORT
-
#define SCSC_CHV_ARGV_ADDR_OFFSET 0x200008
extern int chv_run;
-
#endif
+#define SCSC_SYSERR_HOST_SERVICE_SHIFT 4
+
#endif
struct srvman *srvman = scsc_mx_get_srvman(mx);
u16 host_panic_code;
- host_panic_code = (SCSC_PANIC_CODE_HOST << 15) | service->id;
+ host_panic_code = (SCSC_PANIC_CODE_HOST << 15) | (service->id << SCSC_SYSERR_HOST_SERVICE_SHIFT);
srvman_set_error(srvman);
switch (service->id) {
}
- SCSC_TAG_INFO(MXMAN, "Reporting host panic code 0x%02x\n", host_panic_code);
+ SCSC_TAG_INFO(MXMAN, "Reporting host hang code 0x%02x\n", host_panic_code);
mxman_fail(scsc_mx_get_mxman(mx), host_panic_code, reason);
}
*/
if (!ndev_vif->activated) {
r = 0;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
+ cfg80211_disconnected(dev, reason_code, NULL, 0, false, GFP_KERNEL);
+#else
+ cfg80211_disconnected(dev, reason_code, NULL, 0, GFP_KERNEL);
+#endif
SLSI_NET_INFO(dev, "Vif is already Deactivated\n");
goto exit;
}
SLSI_ERR(sdev, "failed to register with p2p netdev\n");
goto err_wlan_registered;
}
+#ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
#if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000)
if (slsi_netif_register(sdev, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]) != 0) {
SLSI_ERR(sdev, "failed to register with p2px_wlan1 netdev\n");
}
rcu_assign_pointer(sdev->netdev_ap, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]);
#endif
+#endif
#if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
if (slsi_netif_register(sdev, sdev->netdev[SLSI_NET_INDEX_NAN]) != 0) {
SLSI_ERR(sdev, "failed to register with NAN netdev\n");
-#if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000)
- slsi_netif_remove(sdev, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]);
- rcu_assign_pointer(sdev->netdev_ap, NULL);
-#endif
- goto err_p2p_registered;
+ goto err_p2px_wlan_registered;
}
#endif
#endif
SLSI_ERR(sdev, "Cannot allocate workqueue\n");
#if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
goto err_nan_registered;
+#else
+#ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
+#if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000)
+ goto err_p2px_wlan_registered;
#else
goto err_p2p_registered;
+#endif
+#else
+ goto err_p2p_registered;
+#endif
#endif
}
return sdev;
slsi_netif_remove(sdev, sdev->netdev[SLSI_NET_INDEX_NAN]);
#endif
+#ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
+#if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000)
+err_p2px_wlan_registered:
+ slsi_netif_remove(sdev, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]);
+ rcu_assign_pointer(sdev->netdev_ap, NULL);
+#endif
+#endif
+
err_p2p_registered:
slsi_netif_remove(sdev, sdev->netdev[SLSI_NET_INDEX_P2P]);
}
#endif
-#define FB_NO_SPC_NUM_RET 10
+#define FB_NO_SPC_NUM_RET 100
#define FB_NO_SPC_SLEEP_MS 10
+#define FB_NO_SPC_DELAY_US 1000
/* Update scoreboard index */
/* Function can be called from BH context */
spin_lock_bh(&hip_priv->rx_lock);
SCSC_HIP4_SAMPLER_INT_BH(hip->hip_priv->minor, 0);
- if (ktime_compare(bh_init_data, bh_end_data) < 0)
+ if (ktime_compare(bh_init_data, bh_end_data) <= 0) {
bh_init_data = ktime_get();
+ if (!atomic_read(&hip->hip_priv->closing)) {
+ atomic_set(&hip->hip_priv->watchdog_timer_active, 0);
+ }
+ }
clear_bit(HIP4_MIF_Q_TH_DAT, hip->hip_priv->irq_bitmap);
idx_r = hip4_read_index(hip, HIP4_MIF_Q_TH_DAT, ridx);
bh_end_data = ktime_get();
napi_complete(napi);
if (!atomic_read(&hip->hip_priv->closing)) {
- atomic_set(&hip->hip_priv->watchdog_timer_active, 0);
/* Nothing more to drain, unmask interrupt */
scsc_service_mifintrbit_bit_unmask(sdev->service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]);
}
while ((ref = to_free[i++])) {
/* Set the number of retries */
- retry = 100;
+ retry = FB_NO_SPC_NUM_RET;
while (hip4_q_add_signal(hip, HIP4_MIF_Q_TH_RFB, ref, service) && retry > 0) {
SLSI_WARN_NODEV("Dat: Not enough space in FB, retry: %d/%d\n", retry, FB_NO_SPC_NUM_RET);
- udelay(FB_NO_SPC_SLEEP_MS);
+ udelay(FB_NO_SPC_DELAY_US);
retry--;
if (retry == 0)
- SLSI_ERR_NODEV("Dat: FB has not been freed for %d us\n", FB_NO_SPC_NUM_RET * FB_NO_SPC_SLEEP_MS);
+ SLSI_ERR_NODEV("Dat: FB has not been freed for %d us\n", FB_NO_SPC_NUM_RET * FB_NO_SPC_DELAY_US);
#ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING
SCSC_HIP4_SAMPLER_QFULL(hip_priv->minor, HIP4_MIF_Q_TH_RFB);
#endif
bh_end_data = ktime_get();
napi_complete(napi);
if (!atomic_read(&hip->hip_priv->closing)) {
- atomic_set(&hip->hip_priv->watchdog_timer_active, 0);
/* Nothing more to drain, unmask interrupt */
scsc_service_mifintrbit_bit_unmask(sdev->service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]);
}
u8 smapper_entries_banks[16]; /* num entries banks */
u8 smapper_pow_sz[16]; /* Power of size of entry i.e. 12 = 4096B */
u32 smapper_bank_addr[16]; /* Bank start addr */
+#else
+ u8 reserved_nosmapper[99];
#endif
u8 reserved4[16];
} __packed;
/******************************************************************************
*
- * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
*
*****************************************************************************/
#include <scsc/scsc_mx.h>
#include <scsc/scsc_mifram.h>
#include <scsc/scsc_logring.h>
+#include <linux/ratelimit.h>
#include "debug.h"
#include "dev.h"
struct hip4_smapper_bank *bank;
enum smapper_banks i;
unsigned long flags;
+ static DEFINE_RATELIMIT_STATE(ratelimit, 1 * HZ, 1);
control = &(hip->hip_priv->smapper_control);
+#ifdef CONFIG_SCSC_QOS
+ /* Ignore request if TPUT is low or platform is in suspend */
+ if (hip->hip_priv->pm_qos_state == SCSC_QOS_DISABLED ||
+ atomic_read(&hip->hip_priv->in_suspend) ||
+ *control->mbox_ptr == 0x0) {
+#else
+ /* Ignore if platform is in suspend */
+ if (atomic_read(&hip->hip_priv->in_suspend) ||
+ *control->mbox_ptr == 0x0) {
+#endif
+ if (__ratelimit(&ratelimit))
+ SLSI_DBG1_NODEV(SLSI_SMAPPER, "Ignore SMAPPER request. Invalid state.\n");
+ /* Clear interrupt */
+ scsc_service_mifintrbit_bit_clear(sdev->service, control->th_req);
+ return;
+ }
spin_lock_irqsave(&control->smapper_lock, flags);
/* Check if FW has requested a BANK configuration */
if (sdev->netdev_up_count)
return;
+ complete_all(&sdev->sig_wait.completion);
+
#ifdef CONFIG_SCSC_LOG_COLLECTION
sdev->collect_mib.enabled = false;
scsc_log_collector_unregister_client(&slsi_hcf_client);
return;
}
- if (!hw_available)
- complete_all(&ndev_vif->sig_wait.completion);
+ complete_all(&ndev_vif->sig_wait.completion);
slsi_scan_cleanup(sdev, dev);
#define SLSI_EAP_MSGTYPE_POS (27)
#define SLSI_EAP_MSGTYPE_M8 (12)
#define SLSI_EAP_WPS_DWELL_TIME (100000) /*100 ms */
+#define SLSI_EAP_TYPE_IDENTITY (1)
#define SLSI_80211_AC_VO 0
#define SLSI_80211_AC_VI 1
* TYPE : SlsiUint16
* MIN : 1
* MAX : 100
- * DEFAULT : 30
+ * DEFAULT : 25
* DESCRIPTION :
* The threshold in percentage of CCA busy time when a channel would be
* considered busy
#define SLSI_PSID_UNIFI_TRAFFIC_THRESHOLD_TO_SETUP_BA 0x08AE
/*******************************************************************************
- * NAME : UnifiDplaneTxAmsduFrameSizeMax
+ * NAME : UnifiDplaneTxAmsduHwCapability
* PSID : 2223 (0x08AF)
* PER INTERFACE?: NO
* TYPE : SlsiUint16
* MIN : 0
* MAX : 65535
- * DEFAULT : 4098
+ * DEFAULT :
* DESCRIPTION :
- * Defines the maximum A-MSDU frame size
+ * Returns 0 if A-MSDU size limited to 4K. Returns 1 is A-MSDU size is
+ * limited to 8K. This value is chip specific and limited by HW.
*******************************************************************************/
-#define SLSI_PSID_UNIFI_DPLANE_TX_AMSDU_FRAME_SIZE_MAX 0x08AF
+#define SLSI_PSID_UNIFI_DPLANE_TX_AMSDU_HW_CAPABILITY 0x08AF
/*******************************************************************************
* NAME : UnifiDplaneTxAmsduSubframeCountMax
* TYPE : SlsiUint16
* MIN : 1
* MAX : 4
- * DEFAULT : 2
+ * DEFAULT : 3
* DESCRIPTION :
* Defines the maximum number of A-MSDU sub-frames per A-MSDU. A value of 1
* indicates A-MSDU aggregation has been disabled
*******************************************************************************/
#define SLSI_PSID_UNIFI_RADIO_ON_TIME_NAN 0x08BC
+/*******************************************************************************
+ * NAME : UnifiOutputRadioInfoToKernelLog
+ * PSID : 2239 (0x08BF)
+ * PER INTERFACE?: NO
+ * TYPE : SlsiBool
+ * MIN : 0
+ * MAX : 1
+ * DEFAULT : FALSE
+ * DESCRIPTION :
+ * Print messages about the radio status to the Android Kernel Log. See
+ * document SC-508266-TC.
+ *******************************************************************************/
+#define SLSI_PSID_UNIFI_OUTPUT_RADIO_INFO_TO_KERNEL_LOG 0x08BF
+
/*******************************************************************************
* NAME : UnifiNoAckActivationCount
* PSID : 2240 (0x08C0)
* DESCRIPTION :
* Enable reporting of the following events for Android logging: - firmware
* connectivity events - fate of management frames sent by the host through
- * the MLME SAP It can take the following values: - 0: reporting is disabled
- * - 1: partial reporting is enabled. Beacons and EAPOL frames will not be
- * reported - 2: full reporting is enabled. Beacons and EAPOL frames are
+ * the MLME SAP It can take the following values: - 0: reporting for non
+ * mandetory triggers disabled. EAPOL, security, btm frames and roam
+ * triggers are reported. - 1: partial reporting is enabled. Beacons frames
+ * will not be reported. - 2: full reporting is enabled. Beacons frames are
* included.
*******************************************************************************/
#define SLSI_PSID_UNIFI_LOGGER_ENABLED 0x0910
*******************************************************************************/
#define SLSI_PSID_UNIFI_MA_PACKET_FATE_ENABLED 0x0911
+/*******************************************************************************
+ * NAME : UnifiFrameRxCounters
+ * PSID : 2326 (0x0916)
+ * PER INTERFACE?: NO
+ * TYPE : SlsiUint32
+ * MIN : 0
+ * MAX : 4294967295
+ * DEFAULT :
+ * DESCRIPTION :
+ * Frame RX Counters used by the host. These are required by MCD.
+ *******************************************************************************/
+#define SLSI_PSID_UNIFI_FRAME_RX_COUNTERS 0x0916
+
+/*******************************************************************************
+ * NAME : UnifiFrameTxCounters
+ * PSID : 2327 (0x0917)
+ * PER INTERFACE?: NO
+ * TYPE : SlsiUint32
+ * MIN : 0
+ * MAX : 4294967295
+ * DEFAULT :
+ * DESCRIPTION :
+ * Frame TX Counters used by the host. These are required by MCD.
+ *******************************************************************************/
+#define SLSI_PSID_UNIFI_FRAME_TX_COUNTERS 0x0917
+
/*******************************************************************************
* NAME : UnifiLaaNssSpeculationIntervalSlotTime
* PSID : 2330 (0x091A)
* PSID : 2583 (0x0A17)
* PER INTERFACE?: NO
* TYPE : SlsiUint16
- * MIN : 0
- * MAX : 65535
- * DEFAULT : 3
+ * MIN : 3
+ * MAX : 10
+ * DEFAULT : 8
* DESCRIPTION :
* Channel switch announcement count which will be used in the Channel
* announcement IE when using wifi sharing
*******************************************************************************/
#define SLSI_PSID_UNIFI_DUAL_BAND_CONCURRENCY 0x17EB
+/*******************************************************************************
+ * NAME : UnifiLoggerMaxDelayedEvents
+ * PSID : 6124 (0x17EC)
+ * PER INTERFACE?: NO
+ * TYPE : SlsiUint16
+ * MIN : 0
+ * MAX : 65535
+ * DEFAULT : 10
+ * DESCRIPTION :
+ * Maximum number of events to keep when host is suspended.
+ *******************************************************************************/
+#define SLSI_PSID_UNIFI_LOGGER_MAX_DELAYED_EVENTS 0x17EC
+
/*******************************************************************************
* NAME : UnifiRegulatoryParameters
* PSID : 8011 (0x1F4B)
{ SLSI_PSID_UNIFI_TX_DATA_RATE, { 0, 0 } }, /* to get STATION_INFO_TX_BITRATE*/
{ SLSI_PSID_UNIFI_RSSI, { 0, 0 } }, /* to get STATION_INFO_SIGNAL_AVG*/
{ SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 3, 0 } }, /* bad_fcs_count*/
- { SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 10, 0 } }, /* mpdus_failed_transmit*/
{ SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 25, 0 } }, /* mac_bad_sig_count*/
{ SLSI_PSID_UNIFI_THROUGHPUT_DEBUG, { 30, 0 } }, /* rx_error_count*/
+ { SLSI_PSID_UNIFI_FRAME_TX_COUNTERS, { 1, 0 } }, /*tx good count*/
+ { SLSI_PSID_UNIFI_FRAME_TX_COUNTERS, { 2, 0 } }, /*tx bad count*/
+ { SLSI_PSID_UNIFI_FRAME_RX_COUNTERS, { 1, 0 } }, /*rx good count*/
};
- int tx_counter = 0;
int rx_counter = 0;
WARN_ON(!SLSI_MUTEX_IS_LOCKED(ndev_vif->vif_mutex));
/* Fixed fields len (5) : 2 bytes(PSID) + 2 bytes (Len) + 1 byte (VLDATA header ) [10 for 2 PSIDs]
* Data : 3 bytes for SLSI_PSID_UNIFI_TX_DATA_RATE , 1 byte for SLSI_PSID_UNIFI_RSSI
- * 10*5 bytes for 5 Throughput Mib's
+ * 10*6 bytes for 3 Throughput Mib's and 3 counter Mib's
*/
- mibrsp.dataLength = 64;
+ mibrsp.dataLength = 74;
mibrsp.data = kmalloc(mibrsp.dataLength, GFP_KERNEL);
if (!mibrsp.data) {
rx_counter += values[2].u.uintValue; /*bad_fcs_count*/
else
SLSI_ERR(sdev, "invalid type. iter:%d", 2);
-
if (values[3].type == SLSI_MIB_TYPE_UINT)
- tx_counter += values[3].u.uintValue; /*mpdus_failed_transmit*/
+ rx_counter += values[3].u.uintValue; /*mac_bad_sig_count*/
else
SLSI_ERR(sdev, "invalid type. iter:%d", 3);
if (values[4].type == SLSI_MIB_TYPE_UINT)
- rx_counter += values[4].u.uintValue; /*mac_bad_sig_count*/
+ rx_counter += values[4].u.uintValue; /*rx_error_count*/
else
SLSI_ERR(sdev, "invalid type. iter:%d", 4);
if (values[5].type == SLSI_MIB_TYPE_UINT)
- rx_counter += values[5].u.uintValue; /*rx_error_count*/
+ peer->sinfo.tx_packets = values[5].u.uintValue; /*tx good count*/
else
SLSI_ERR(sdev, "invalid type. iter:%d", 5);
+ if (values[6].type == SLSI_MIB_TYPE_UINT)
+ peer->sinfo.tx_failed = values[6].u.uintValue; /*tx bad count*/
+ else
+ SLSI_ERR(sdev, "invalid type. iter:%d", 6);
+ if (values[7].type == SLSI_MIB_TYPE_UINT)
+ peer->sinfo.rx_packets = values[7].u.uintValue; /*rx good count*/
+ else
+ SLSI_ERR(sdev, "invalid type. iter:%d", 7);
- peer->sinfo.tx_failed = tx_counter;
peer->sinfo.rx_dropped_misc = rx_counter;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
peer->sinfo.filled |= BIT(NL80211_STA_INFO_TX_FAILED) | BIT(NL80211_STA_INFO_RX_DROP_MISC) |
- BIT(NL80211_STA_INFO_TX_PACKETS);
+ BIT(NL80211_STA_INFO_TX_PACKETS) | BIT(NL80211_STA_INFO_RX_PACKETS);
#endif
} else {
SLSI_NET_DBG1(dev, SLSI_MLME, "mlme_get_req failed(result:0x%4x)\n", r);
#endif
}
+#ifdef CONFIG_SCSC_WLAN_RX_NAPI
+
+#ifdef CONFIG_SOC_EXYNOS9610
+#define SCSC_NETIF_RPS_CPUS_MASK "fe"
+#else
+#define SCSC_NETIF_RPS_CPUS_MASK "0"
+#endif
+
+static void slsi_netif_rps_map_clear(struct net_device *dev)
+{
+ struct rps_map *map;
+
+ map = rcu_dereference_protected(dev->_rx->rps_map, 1);
+ if (map) {
+ RCU_INIT_POINTER(dev->_rx->rps_map, NULL);
+ kfree_rcu(map, rcu);
+ SLSI_NET_INFO(dev, "clear rps_cpus map\n");
+ }
+}
+
+static int slsi_netif_rps_map_set(struct net_device *dev, char *buf, size_t len)
+{
+ struct rps_map *old_map, *map;
+ cpumask_var_t mask;
+ int err, cpu, i;
+ static DEFINE_SPINLOCK(rps_map_lock);
+
+ if (!alloc_cpumask_var(&mask, GFP_KERNEL))
+ return -ENOMEM;
+
+ err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits);
+ if (err) {
+ free_cpumask_var(mask);
+ SLSI_NET_WARN(dev, "CPU bitmap parse failed\n");
+ return err;
+ }
+
+ map = kzalloc(max_t(unsigned int, RPS_MAP_SIZE(cpumask_weight(mask)), L1_CACHE_BYTES), GFP_KERNEL);
+ if (!map) {
+ free_cpumask_var(mask);
+ SLSI_NET_WARN(dev, "CPU mask alloc failed\n");
+ return -ENOMEM;
+ }
+
+ i = 0;
+ for_each_cpu_and(cpu, mask, cpu_online_mask)
+ map->cpus[i++] = cpu;
+
+ if (i) {
+ map->len = i;
+ } else {
+ kfree(map);
+ map = NULL;
+ }
+
+ spin_lock(&rps_map_lock);
+ old_map = rcu_dereference_protected(dev->_rx->rps_map, lockdep_is_held(&rps_map_lock));
+ rcu_assign_pointer(dev->_rx->rps_map, map);
+ spin_unlock(&rps_map_lock);
+
+ if (map)
+ static_key_slow_inc(&rps_needed);
+ if (old_map)
+ static_key_slow_dec(&rps_needed);
+
+ if (old_map)
+ kfree_rcu(old_map, rcu);
+
+ free_cpumask_var(mask);
+ SLSI_NET_INFO(dev, "rps_cpus map set(%s)\n", buf);
+ return len;
+}
+#endif
+
int slsi_netif_add_locked(struct slsi_dev *sdev, const char *name, int ifnum)
{
struct net_device *dev = NULL;
ndev_vif->probe_req_ies = NULL;
ndev_vif->probe_req_ie_len = 0;
ndev_vif->drv_in_p2p_procedure = false;
+
+#ifdef CONFIG_SCSC_WLAN_RX_NAPI
+ slsi_netif_rps_map_set(dev, SCSC_NETIF_RPS_CPUS_MASK, strlen(SCSC_NETIF_RPS_CPUS_MASK));
+#endif
return 0;
exit_with_error:
SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
return -EINVAL;
}
+#ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
#if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000)
if (slsi_netif_add_locked(sdev, CONFIG_SCSC_AP_INTERFACE_NAME, SLSI_NET_INDEX_P2PX_SWLAN) != 0) {
rtnl_lock();
return -EINVAL;
}
#endif
+#endif
#if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
if (slsi_netif_add_locked(sdev, "nan%d", SLSI_NET_INDEX_NAN) != 0) {
rtnl_lock();
slsi_netif_remove_locked(sdev, sdev->netdev[SLSI_NET_INDEX_WLAN]);
slsi_netif_remove_locked(sdev, sdev->netdev[SLSI_NET_INDEX_P2P]);
+#ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
#if defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION >= 90000)
slsi_netif_remove_locked(sdev, sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN]);
+#endif
#endif
rtnl_unlock();
SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
slsi_roam_channel_cache_prune(dev, 0);
kfree(ndev_vif->probe_req_ies);
+#ifdef CONFIG_SCSC_WLAN_RX_NAPI
+ slsi_netif_rps_map_clear(dev);
+#endif
if (atomic_read(&ndev_vif->is_registered)) {
atomic_set(&ndev_vif->is_registered, 0);
unregister_netdevice(dev);
SLSI_PROCFS_ADD_FILE(sdev, big_data, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
SLSI_PROCFS_ADD_FILE(sdev, throughput_stats, parent, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
SLSI_PROCFS_SEQ_ADD_FILE(sdev, tcp_ack_suppression, sdev->procfs_dir, S_IRUSR | S_IRGRP);
+ return 0;
}
err:
+ SLSI_DBG1(sdev, SLSI_HIP, "Failure in creation of proc directories\n");
return -EINVAL;
}
}
if (peer) {
- peer->sinfo.rx_packets++;
peer->sinfo.rx_bytes += rx_skb->len;
}
ndev_vif->stats.rx_packets++;
#include <linux/spinlock.h>
-int slsi_is_wps_msg_start_or_m17(u8 *eapol, u16 eap_length)
+int slsi_get_dwell_time_for_wps(struct slsi_dev *sdev, struct netdev_vif *ndev_vif, u8 *eapol, u16 eap_length)
{
/* Note that Message should not be M8.This check is to identify only WSC_START message or M1-M7 */
- /*Return 1 If opcode type WSC msg and Msg Type M1-M7 or if opcode is WSC start.*/
+ /*Return 100ms If opcode type WSC msg and Msg Type M1-M7 or if opcode is WSC start.*/
if (eapol[SLSI_EAP_CODE_POS] == SLSI_EAP_PACKET_REQUEST ||
- eapol[SLSI_EAP_CODE_POS] == SLSI_EAP_PACKET_RESPONSE)
+ eapol[SLSI_EAP_CODE_POS] == SLSI_EAP_PACKET_RESPONSE) {
if (eapol[SLSI_EAP_TYPE_POS] == SLSI_EAP_TYPE_EXPANDED && eap_length >= SLSI_EAP_OPCODE_POS - 3 &&
((eapol[SLSI_EAP_OPCODE_POS] == SLSI_EAP_OPCODE_WSC_MSG && eap_length >= SLSI_EAP_MSGTYPE_POS - 3 &&
eapol[SLSI_EAP_MSGTYPE_POS] != SLSI_EAP_MSGTYPE_M8) ||
eapol[SLSI_EAP_OPCODE_POS] == SLSI_EAP_OPCODE_WSC_START))
- return 1;
+ return SLSI_EAP_WPS_DWELL_TIME;
+ /* This is to check if a frame is EAP request identity and on P2P vif.If yes then set dwell time to 100ms */
+ if (SLSI_IS_VIF_INDEX_P2P_GROUP(sdev, ndev_vif) &&
+ eapol[SLSI_EAP_CODE_POS] == SLSI_EAP_PACKET_REQUEST &&
+ eapol[SLSI_EAP_TYPE_POS] == SLSI_EAP_TYPE_IDENTITY)
+ return SLSI_EAP_WPS_DWELL_TIME;
+ }
return 0;
}
SLSI_INFO(sdev, "Send EAP-Success (%d)\n", eap_length);
else if (eapol[SLSI_EAP_CODE_POS] == SLSI_EAP_PACKET_FAILURE)
SLSI_INFO(sdev, "Send EAP-Failure (%d)\n", eap_length);
-
- /*Identify WPS_START & M1-M7 and set dwell time to 100ms */
- if (slsi_is_wps_msg_start_or_m17(eapol, eap_length))
- dwell_time = SLSI_EAP_WPS_DWELL_TIME;
+ /* Need to set dwell time for wps exchange and EAP identity frame for P2P */
+ dwell_time = slsi_get_dwell_time_for_wps(sdev, ndev_vif, eapol, eap_length);
}
}
break;
/* EAPOL/WAI frames are send via the MLME */
tx_bytes_tmp = skb->len; // len copy to avoid null pointer of skb
ret = slsi_mlme_send_frame_data(sdev, dev, skb, msg_type, 0, dwell_time, 0);
- if (!ret) {
- peer->sinfo.tx_packets++;
+ if (!ret)
peer->sinfo.tx_bytes += tx_bytes_tmp; //skb->len;
- }
+
slsi_spinlock_unlock(&ndev_vif->peer_lock);
return ret;
}
/* What about the original if we passed in a copy ? */
if (original_skb)
slsi_kfree_skb(original_skb);
- peer->sinfo.tx_packets++;
peer->sinfo.tx_bytes += len;
return ret;
}
struct sk_buff *skb_addr;
};
-static inline u32 slsi_convert_tlv_data_to_value(u8 *data, u16 length)
-{
- u32 value = 0;
- int i;
-
- if (length > 4)
- return 0;
- for (i = 0; i < length; i++)
- value |= ((u32)data[i]) << i * 8;
-
- return value;
-}
-
static inline struct slsi_skb_cb *slsi_skb_cb_get(struct sk_buff *skb)
{
return (struct slsi_skb_cb *)skb->cb;
}
#endif
+static inline u32 slsi_convert_tlv_data_to_value(u8 *data, u16 length)
+{
+ u32 value = 0;
+ int i;
+
+ if (length > 4)
+ return 0;
+ for (i = 0; i < length; i++)
+ value |= ((u32)data[i]) << i * 8;
+
+ return value;
+}
+
#ifdef __cplusplus
extern "C" {
#endif
#define SCSC_RELEASE_SOLUTION "mx250"
#define SCSC_RELEASE_PRODUCT 6
-#define SCSC_RELEASE_ITERATION 63
-#define SCSC_RELEASE_CANDIDATE 1
+#define SCSC_RELEASE_ITERATION 64
+#define SCSC_RELEASE_CANDIDATE 2
#define SCSC_RELEASE_POINT 0