From: Youngsoo Date: Fri, 15 Mar 2019 09:07:23 +0000 (+0900) Subject: [common][RAMEN9610-13443][9610] wlbt: host update 6.64.2 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=3f83a99255a9d24923d4ee6de4b2db968eb293f7;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [common][RAMEN9610-13443][9610] wlbt: host update 6.64.2 1. Protect SMAPPER from possible spurious interrupts 2. slsi_convert_tlv_data_to_value should be outside 3. NAPI: config RPS 4. NAPI: increase retry time when no space in FB queue 5. NAPI: false watchdog trigger 6. [9610][7885][7872][7570] wlbt: Notify CFG regarding the Disconnection, on ... 7. [9610][7885][7872][7570] wlbt: Perform Dual Interface registration in ... 8. wlbt: update host induced error code 9. increment scsc_release to 6.64.2 Change-Id: I0bc936a5ce4ecdd905b1deba629db7f816fc43f3 Signed-off-by: Youngsoo --- diff --git a/drivers/misc/samsung/scsc/mx250_fm.c b/drivers/misc/samsung/scsc/mx250_fm.c index 93c5f695082b..bfc642a467ce 100755 --- a/drivers/misc/samsung/scsc/mx250_fm.c +++ b/drivers/misc/samsung/scsc/mx250_fm.c @@ -245,7 +245,7 @@ static int mx250_fm_re(bool ldo_on) 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); @@ -255,7 +255,7 @@ 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); diff --git a/drivers/misc/samsung/scsc/mxman.c b/drivers/misc/samsung/scsc/mxman.c index f056e7bfbfcd..50779fa3998d 100755 --- a/drivers/misc/samsung/scsc/mxman.c +++ b/drivers/misc/samsung/scsc/mxman.c @@ -1260,7 +1260,7 @@ static void print_panic_code(u16 code) 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; diff --git a/drivers/misc/samsung/scsc/mxman.h b/drivers/misc/samsung/scsc/mxman.h index d671389e0367..6ac3fab902f1 100755 --- a/drivers/misc/samsung/scsc/mxman.h +++ b/drivers/misc/samsung/scsc/mxman.h @@ -88,11 +88,11 @@ void mxman_register_gdb_channel(struct scsc_mx *mx, mxmgmt_channel_handler handl 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 diff --git a/drivers/misc/samsung/scsc/scsc_service.c b/drivers/misc/samsung/scsc/scsc_service.c index f4d31035c937..c333d20ad446 100755 --- a/drivers/misc/samsung/scsc/scsc_service.c +++ b/drivers/misc/samsung/scsc/scsc_service.c @@ -488,7 +488,7 @@ void scsc_mx_service_service_failed(struct scsc_service *service, const char *re 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) { @@ -504,7 +504,7 @@ void scsc_mx_service_service_failed(struct scsc_service *service, const char *re } - 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); } diff --git a/drivers/net/wireless/scsc/cfg80211_ops.c b/drivers/net/wireless/scsc/cfg80211_ops.c index afdb61aab91a..b3f6f9f1dda2 100755 --- a/drivers/net/wireless/scsc/cfg80211_ops.c +++ b/drivers/net/wireless/scsc/cfg80211_ops.c @@ -1095,6 +1095,11 @@ int slsi_disconnect(struct wiphy *wiphy, struct net_device *dev, */ 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; } diff --git a/drivers/net/wireless/scsc/dev.c b/drivers/net/wireless/scsc/dev.c index 361bffca2c3b..65159c5e5d65 100644 --- a/drivers/net/wireless/scsc/dev.c +++ b/drivers/net/wireless/scsc/dev.c @@ -365,6 +365,7 @@ struct slsi_dev *slsi_dev_attach(struct device *dev, struct scsc_mx *core, struc 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"); @@ -372,14 +373,11 @@ struct slsi_dev *slsi_dev_attach(struct device *dev, struct scsc_mx *core, struc } 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 @@ -398,8 +396,16 @@ struct slsi_dev *slsi_dev_attach(struct device *dev, struct scsc_mx *core, struc 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; @@ -409,6 +415,14 @@ err_nan_registered: 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]); diff --git a/drivers/net/wireless/scsc/hip4.c b/drivers/net/wireless/scsc/hip4.c index 882e4ffef04f..59b14d3976b0 100755 --- a/drivers/net/wireless/scsc/hip4.c +++ b/drivers/net/wireless/scsc/hip4.c @@ -486,8 +486,9 @@ static inline ktime_t ktime_add_ms(const ktime_t kt, const u64 msec) } #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 */ @@ -1311,8 +1312,12 @@ static int hip4_napi_poll(struct napi_struct *napi, int budget) 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); @@ -1326,7 +1331,6 @@ static int hip4_napi_poll(struct napi_struct *napi, int budget) 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]); } @@ -1395,14 +1399,14 @@ consume_dat_mbulk: 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 @@ -1423,7 +1427,6 @@ consume_dat_mbulk: 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]); } diff --git a/drivers/net/wireless/scsc/hip4.h b/drivers/net/wireless/scsc/hip4.h index 05eaf674867a..519c307f5262 100755 --- a/drivers/net/wireless/scsc/hip4.h +++ b/drivers/net/wireless/scsc/hip4.h @@ -153,6 +153,8 @@ struct hip4_hip_config_version_4 { 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; diff --git a/drivers/net/wireless/scsc/hip4_smapper.c b/drivers/net/wireless/scsc/hip4_smapper.c index c3c65a7fbe20..fcfac525da20 100644 --- a/drivers/net/wireless/scsc/hip4_smapper.c +++ b/drivers/net/wireless/scsc/hip4_smapper.c @@ -1,12 +1,13 @@ /****************************************************************************** * - * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved * *****************************************************************************/ #include #include #include +#include #include "debug.h" #include "dev.h" @@ -164,8 +165,25 @@ static void hip4_smapper_refill_isr(int irq, void *data) 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 */ diff --git a/drivers/net/wireless/scsc/mgt.c b/drivers/net/wireless/scsc/mgt.c index ba196db097ac..65e5248e23d4 100755 --- a/drivers/net/wireless/scsc/mgt.c +++ b/drivers/net/wireless/scsc/mgt.c @@ -711,6 +711,8 @@ static void slsi_stop_chip(struct slsi_dev *sdev) 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); @@ -869,8 +871,7 @@ static void slsi_stop_net_dev_locked(struct slsi_dev *sdev, struct net_device *d return; } - if (!hw_available) - complete_all(&ndev_vif->sig_wait.completion); + complete_all(&ndev_vif->sig_wait.completion); slsi_scan_cleanup(sdev, dev); diff --git a/drivers/net/wireless/scsc/mgt.h b/drivers/net/wireless/scsc/mgt.h index 3ae64360cd0b..ba0a5c7ada73 100755 --- a/drivers/net/wireless/scsc/mgt.h +++ b/drivers/net/wireless/scsc/mgt.h @@ -58,6 +58,7 @@ #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 diff --git a/drivers/net/wireless/scsc/mib.h b/drivers/net/wireless/scsc/mib.h old mode 100644 new mode 100755 index cc6f5ab3dddd..d869efe35cc0 --- a/drivers/net/wireless/scsc/mib.h +++ b/drivers/net/wireless/scsc/mib.h @@ -732,7 +732,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * 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 @@ -2009,17 +2009,18 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf #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 @@ -2028,7 +2029,7 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * 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 @@ -2189,6 +2190,20 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #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) @@ -2869,9 +2884,10 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * 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 @@ -2890,6 +2906,32 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #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) @@ -4581,9 +4623,9 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf * 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 @@ -7083,6 +7125,19 @@ void slsi_mib_buf_append(struct slsi_mib_data *dst, size_t bufferLength, u8 *buf *******************************************************************************/ #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) diff --git a/drivers/net/wireless/scsc/mlme.c b/drivers/net/wireless/scsc/mlme.c index 4d8d3a793737..efe6eaa53095 100755 --- a/drivers/net/wireless/scsc/mlme.c +++ b/drivers/net/wireless/scsc/mlme.c @@ -2612,11 +2612,12 @@ int slsi_mlme_get_sinfo_mib(struct slsi_dev *sdev, struct net_device *dev, { 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)); @@ -2637,9 +2638,9 @@ int slsi_mlme_get_sinfo_mib(struct slsi_dev *sdev, struct net_device *dev, /* 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) { @@ -2693,26 +2694,32 @@ int slsi_mlme_get_sinfo_mib(struct slsi_dev *sdev, struct net_device *dev, 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); diff --git a/drivers/net/wireless/scsc/netif.c b/drivers/net/wireless/scsc/netif.c index e138d5a09ffd..3c833eb23466 100755 --- a/drivers/net/wireless/scsc/netif.c +++ b/drivers/net/wireless/scsc/netif.c @@ -1041,6 +1041,80 @@ static void slsi_if_setup(struct net_device *dev) #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; @@ -1174,6 +1248,10 @@ int slsi_netif_add_locked(struct slsi_dev *sdev, const char *name, int ifnum) 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: @@ -1229,6 +1307,7 @@ int slsi_netif_init(struct slsi_dev *sdev) 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(); @@ -1239,13 +1318,16 @@ int slsi_netif_init(struct slsi_dev *sdev) 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); @@ -1348,6 +1430,9 @@ void slsi_netif_remove_locked(struct slsi_dev *sdev, struct net_device *dev) 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); diff --git a/drivers/net/wireless/scsc/procfs.c b/drivers/net/wireless/scsc/procfs.c index 030a79a83c5f..fc8e91558585 100755 --- a/drivers/net/wireless/scsc/procfs.c +++ b/drivers/net/wireless/scsc/procfs.c @@ -1102,9 +1102,11 @@ int slsi_create_proc_dir(struct slsi_dev *sdev) 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; } diff --git a/drivers/net/wireless/scsc/sap_ma.c b/drivers/net/wireless/scsc/sap_ma.c index 4a09c1302ef6..fc76ad3bf471 100755 --- a/drivers/net/wireless/scsc/sap_ma.c +++ b/drivers/net/wireless/scsc/sap_ma.c @@ -301,7 +301,6 @@ void slsi_rx_data_deliver_skb(struct slsi_dev *sdev, struct net_device *dev, str } if (peer) { - peer->sinfo.rx_packets++; peer->sinfo.rx_bytes += rx_skb->len; } ndev_vif->stats.rx_packets++; diff --git a/drivers/net/wireless/scsc/tx.c b/drivers/net/wireless/scsc/tx.c index e60b42aa93a7..8f9dd06e5bf2 100755 --- a/drivers/net/wireless/scsc/tx.c +++ b/drivers/net/wireless/scsc/tx.c @@ -29,17 +29,23 @@ MODULE_PARM_DESC(msdu_enable, "MSDU frame format, Y: enable (default), N: disabl #include -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; } @@ -101,10 +107,8 @@ static int slsi_tx_eapol(struct slsi_dev *sdev, struct net_device *dev, struct s 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; @@ -123,10 +127,9 @@ static int slsi_tx_eapol(struct slsi_dev *sdev, struct net_device *dev, struct s /* 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; } @@ -406,7 +409,6 @@ int slsi_tx_data(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff * /* 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; } diff --git a/drivers/net/wireless/scsc/utils.h b/drivers/net/wireless/scsc/utils.h index 57d937f104d6..b40653f2e037 100755 --- a/drivers/net/wireless/scsc/utils.h +++ b/drivers/net/wireless/scsc/utils.h @@ -26,19 +26,6 @@ struct slsi_skb_cb { 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; @@ -53,6 +40,19 @@ static inline struct slsi_skb_cb *slsi_skb_cb_init(struct sk_buff *skb) } #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 diff --git a/include/scsc/scsc_release.h b/include/scsc/scsc_release.h index 9574cd19432a..6cddcf7deb56 100644 --- a/include/scsc/scsc_release.h +++ b/include/scsc/scsc_release.h @@ -10,8 +10,8 @@ #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