From: Debabrata Purohit Date: Mon, 18 Feb 2019 18:16:32 +0000 (+0000) Subject: [RAMEN9610-12302][common][9610] wlbt: support HIP version 3 in NAPI enabled config X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=e04e03eaf2b5c7ead7e71cfa3cd9dc11ed8aa54e;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [RAMEN9610-12302][common][9610] wlbt: support HIP version 3 in NAPI enabled config NAPI is supported for HIP config version 4 onwards. But if in kernel config NAPI is enabled, and the firmware is HIP config version 3, then it causes a fatal kernel panic. Resoultion: add support for both config version 3 and config version 4 when NAPI is enabled in kernel config. Change-Id: I08e7769db73ba3decbc2d4c6a1843b10a7b7f96a SCSC-Bug-Id: SSB-49603 Signed-off-by: Debabrata Purohit --- diff --git a/drivers/net/wireless/scsc/ba.c b/drivers/net/wireless/scsc/ba.c index 1bf1e4d43259..b268562ce354 100755 --- a/drivers/net/wireless/scsc/ba.c +++ b/drivers/net/wireless/scsc/ba.c @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ @@ -105,9 +105,17 @@ void slsi_ba_process_complete(struct net_device *dev) static void slsi_ba_signal_process_complete(struct net_device *dev) { struct netdev_vif *ndev_vif = netdev_priv(dev); +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + struct slsi_dev *sdev = ndev_vif->sdev; + u32 conf_hip4_ver = 0; +#endif atomic_set(&ndev_vif->ba_flush, 1); -#ifndef CONFIG_SCSC_WLAN_RX_NAPI +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + conf_hip4_ver = scsc_wifi_get_hip_config_version(&sdev->hip4_inst.hip_control->init); + if (conf_hip4_ver == 3) + slsi_skb_schedule_work(&ndev_vif->rx_data); +#else slsi_skb_schedule_work(&ndev_vif->rx_data); #endif } @@ -263,6 +271,11 @@ static void slsi_ba_aging_timeout_handler(unsigned long data) u8 gap = 1; u16 temp_sn; struct net_device *dev = ba_session_rx->dev; +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + struct netdev_vif *ndev_vif = netdev_priv(dev); + struct slsi_dev *sdev = ndev_vif->sdev; + u32 conf_hip4_ver = 0; +#endif SLSI_NET_DBG3(dev, SLSI_RX_BA, "\n"); @@ -305,7 +318,11 @@ static void slsi_ba_aging_timeout_handler(unsigned long data) slsi_spinlock_unlock(&ba_session_rx->ba_lock); /* Process the data now marked as completed */ #ifdef CONFIG_SCSC_WLAN_RX_NAPI - slsi_ba_process_complete(dev); + conf_hip4_ver = scsc_wifi_get_hip_config_version(&sdev->hip4_inst.hip_control->init); + if (conf_hip4_ver == 4) + slsi_ba_process_complete(dev); + else + slsi_ba_signal_process_complete(dev); #else slsi_ba_signal_process_complete(dev); #endif diff --git a/drivers/net/wireless/scsc/dev.h b/drivers/net/wireless/scsc/dev.h index 11f8a55b3161..186e6efc1e33 100755 --- a/drivers/net/wireless/scsc/dev.h +++ b/drivers/net/wireless/scsc/dev.h @@ -684,9 +684,8 @@ struct netdev_vif { struct mutex vif_mutex; #endif struct slsi_sig_send sig_wait; -#ifndef CONFIG_SCSC_WLAN_RX_NAPI + struct slsi_skb_work rx_data; -#endif struct slsi_skb_work rx_mlme; u16 ifnum; enum nl80211_iftype iftype; @@ -1136,9 +1135,6 @@ struct llc_snap_hdr { u16 snap_type; } __packed; -#ifdef CONFIG_SCSC_WLAN_RX_NAPI -int slsi_rx_data_napi(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb, bool from_ba); -#endif void slsi_rx_data_deliver_skb(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); void slsi_rx_dbg_sap_work(struct work_struct *work); void slsi_rx_netdev_data_work(struct work_struct *work); diff --git a/drivers/net/wireless/scsc/hip4.c b/drivers/net/wireless/scsc/hip4.c index 8d80f4142217..45258139aa89 100755 --- a/drivers/net/wireless/scsc/hip4.c +++ b/drivers/net/wireless/scsc/hip4.c @@ -77,11 +77,11 @@ static ktime_t bh_end_ctrl; static ktime_t intr_received_data; static ktime_t bh_init_data; static ktime_t bh_end_data; -#else +#endif static ktime_t intr_received; static ktime_t bh_init; static ktime_t bh_end; -#endif + static ktime_t wdt; static ktime_t send; static ktime_t closing; @@ -533,11 +533,18 @@ static void hip4_dump_dbg(struct slsi_hip4 *hip, struct mbulk *m, struct sk_buff { unsigned int i = 0; scsc_mifram_ref ref; - #ifdef CONFIG_SCSC_WLAN_RX_NAPI - SLSI_ERR_NODEV("intr_tohost_fb 0x%x\n", hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_RFB]); - SLSI_ERR_NODEV("intr_tohost_ctrl 0x%x\n", hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_CTRL]); - SLSI_ERR_NODEV("intr_tohost_dat 0x%x\n", hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]); + u32 conf_hip4_ver = 0; + + conf_hip4_ver = scsc_wifi_get_hip_config_version(&hip->hip_control->init); + + if (conf_hip4_ver == 4) { + SLSI_ERR_NODEV("intr_tohost_fb 0x%x\n", hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_RFB]); + SLSI_ERR_NODEV("intr_tohost_ctrl 0x%x\n", hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_CTRL]); + SLSI_ERR_NODEV("intr_tohost_dat 0x%x\n", hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]); + } else { + SLSI_ERR_NODEV("intr_tohost 0x%x\n", hip->hip_priv->intr_tohost); + } #else SLSI_ERR_NODEV("intr_tohost 0x%x\n", hip->hip_priv->intr_tohost); #endif @@ -564,15 +571,21 @@ static void hip4_dump_dbg(struct slsi_hip4 *hip, struct mbulk *m, struct sk_buff SLSI_ERR_NODEV("time: wdt %lld\n", ktime_to_ns(wdt)); SLSI_ERR_NODEV("time: send %lld\n", ktime_to_ns(send)); #ifdef CONFIG_SCSC_WLAN_RX_NAPI - SLSI_ERR_NODEV("time: intr_fb %lld\n", ktime_to_ns(intr_received_fb)); - SLSI_ERR_NODEV("time: bh_init_fb %lld\n", ktime_to_ns(bh_init_fb)); - SLSI_ERR_NODEV("time: bh_end_fb %lld\n", ktime_to_ns(bh_end_fb)); - SLSI_ERR_NODEV("time: intr_ctrl %lld\n", ktime_to_ns(intr_received_ctrl)); - SLSI_ERR_NODEV("time: bh_init_ctrl %lld\n", ktime_to_ns(bh_init_ctrl)); - SLSI_ERR_NODEV("time: bh_end_ctrl %lld\n", ktime_to_ns(bh_end_ctrl)); - SLSI_ERR_NODEV("time: intr_data %lld\n", ktime_to_ns(intr_received_data)); - SLSI_ERR_NODEV("time: bh_init_data %lld\n", ktime_to_ns(bh_init_data)); - SLSI_ERR_NODEV("time: bh_end_data %lld\n", ktime_to_ns(bh_end_data)); + if (conf_hip4_ver == 4) { + SLSI_ERR_NODEV("time: intr_fb %lld\n", ktime_to_ns(intr_received_fb)); + SLSI_ERR_NODEV("time: bh_init_fb %lld\n", ktime_to_ns(bh_init_fb)); + SLSI_ERR_NODEV("time: bh_end_fb %lld\n", ktime_to_ns(bh_end_fb)); + SLSI_ERR_NODEV("time: intr_ctrl %lld\n", ktime_to_ns(intr_received_ctrl)); + SLSI_ERR_NODEV("time: bh_init_ctrl %lld\n", ktime_to_ns(bh_init_ctrl)); + SLSI_ERR_NODEV("time: bh_end_ctrl %lld\n", ktime_to_ns(bh_end_ctrl)); + SLSI_ERR_NODEV("time: intr_data %lld\n", ktime_to_ns(intr_received_data)); + SLSI_ERR_NODEV("time: bh_init_data %lld\n", ktime_to_ns(bh_init_data)); + SLSI_ERR_NODEV("time: bh_end_data %lld\n", ktime_to_ns(bh_end_data)); + } else { + SLSI_ERR_NODEV("time: intr %lld\n", ktime_to_ns(intr_received)); + SLSI_ERR_NODEV("time: bh_init %lld\n", ktime_to_ns(bh_init)); + SLSI_ERR_NODEV("time: bh_end %lld\n", ktime_to_ns(bh_end)); + } #else SLSI_ERR_NODEV("time: intr %lld\n", ktime_to_ns(intr_received)); SLSI_ERR_NODEV("time: bh_init %lld\n", ktime_to_ns(bh_init)); @@ -878,6 +891,9 @@ static void hip4_watchdog(unsigned long data) struct scsc_service *service; ktime_t intr_ov; unsigned long flags; +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + u32 conf_hip4_ver = 0; +#endif if (!hip || !sdev || !sdev->service || !hip->hip_priv) return; @@ -889,13 +905,25 @@ static void hip4_watchdog(unsigned long data) wdt = ktime_get(); #ifdef CONFIG_SCSC_WLAN_RX_NAPI - /* if intr_received > wdt skip as intr has been unblocked */ - if (test_and_clear_bit(HIP4_MIF_Q_FH_RFB, hip->hip_priv->irq_bitmap)) - intr_ov = ktime_add_ms(intr_received_fb, jiffies_to_msecs(HZ)); - if (test_and_clear_bit(HIP4_MIF_Q_TH_CTRL, hip->hip_priv->irq_bitmap)) - intr_ov = ktime_add_ms(intr_received_ctrl, jiffies_to_msecs(HZ)); - if (test_and_clear_bit(HIP4_MIF_Q_TH_DAT, hip->hip_priv->irq_bitmap)) - intr_ov = ktime_add_ms(intr_received_data, jiffies_to_msecs(HZ)); + conf_hip4_ver = scsc_wifi_get_hip_config_version(&hip->hip_control->init); + + if (conf_hip4_ver == 4) { + /* if intr_received > wdt skip as intr has been unblocked */ + if (test_and_clear_bit(HIP4_MIF_Q_FH_RFB, hip->hip_priv->irq_bitmap)) + intr_ov = ktime_add_ms(intr_received_fb, jiffies_to_msecs(HZ)); + if (test_and_clear_bit(HIP4_MIF_Q_TH_CTRL, hip->hip_priv->irq_bitmap)) + intr_ov = ktime_add_ms(intr_received_ctrl, jiffies_to_msecs(HZ)); + if (test_and_clear_bit(HIP4_MIF_Q_TH_DAT, hip->hip_priv->irq_bitmap)) + intr_ov = ktime_add_ms(intr_received_data, jiffies_to_msecs(HZ)); + } else { + /* if intr_received > wdt skip as intr has been unblocked */ + if (ktime_compare(intr_received, wdt) > 0) { + wdt = ktime_set(0, 0); + goto exit; + } + + intr_ov = ktime_add_ms(intr_received, jiffies_to_msecs(HZ)); + } #else /* if intr_received > wdt skip as intr has been unblocked */ if (ktime_compare(intr_received, wdt) > 0) { @@ -924,11 +952,19 @@ static void hip4_watchdog(unsigned long data) SLSI_INFO_NODEV("Hip4 watchdog triggered\n"); #ifdef CONFIG_SCSC_WLAN_RX_NAPI - for (u8 i = 0; i < MIF_HIP_CFG_Q_NUM; i++) { - if (scsc_service_mifintrbit_bit_mask_status_get(service) & (1 << hip->hip_priv->intr_tohost_mul[i])) { + if (conf_hip4_ver == 4) { + for (u8 i = 0; i < MIF_HIP_CFG_Q_NUM; i++) { + if (scsc_service_mifintrbit_bit_mask_status_get(service) & (1 << hip->hip_priv->intr_tohost_mul[i])) { + /* Interrupt might be pending! */ + SLSI_INFO_NODEV("%d: Interrupt Masked. Unmask to restart Interrupt processing\n", i); + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[i]); + } + } + } else { + if (scsc_service_mifintrbit_bit_mask_status_get(service) & (1 << hip->hip_priv->intr_tohost)) { /* Interrupt might be pending! */ - SLSI_INFO_NODEV("%d: Interrupt Masked. Unmask to restart Interrupt processing\n", i); - scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[i]); + SLSI_INFO_NODEV("Interrupt Masked. Unmask to restart Interrupt processing\n"); + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost); } } #else @@ -945,8 +981,16 @@ exit: #ifdef CONFIG_SCSC_WLAN_RX_NAPI static void hip4_irq_handler_stub(int irq, void *data) { + struct slsi_hip4 *hip = (struct slsi_hip4 *)data; + struct slsi_dev *sdev = container_of(hip, struct slsi_dev, hip4_inst); + /* should not happen */ WARN_ON(1); + + /* mask all interrupts or else will get stuck in interrupt loop */ + scsc_service_mifintrbit_bit_mask(sdev->service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_CTRL]); + scsc_service_mifintrbit_bit_mask(sdev->service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_DAT]); + scsc_service_mifintrbit_bit_mask(sdev->service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_RFB]); } static void hip4_wq_fb(struct work_struct *data) @@ -1380,7 +1424,7 @@ static void hip4_irq_handler_dat(int irq, void *data) SCSC_HIP4_SAMPLER_INT_OUT(hip->hip_priv->minor, 0); } -#else /* #ifdef CONFIG_SCSC_WLAN_RX_NAPI */ +#endif /* #ifdef CONFIG_SCSC_WLAN_RX_NAPI */ static bool slsi_check_rx_flowcontrol(struct slsi_dev *sdev) { @@ -1849,7 +1893,6 @@ end: SCSC_HIP4_SAMPLER_INT_OUT(hip->hip_priv->minor, 1); SCSC_HIP4_SAMPLER_INT_OUT(hip->hip_priv->minor, 2); } -#endif /* #ifdef CONFIG_SCSC_WLAN_RX_NAPI */ #ifdef CONFIG_SCSC_QOS static void hip4_pm_qos_work(struct work_struct *data) @@ -2007,8 +2050,9 @@ int hip4_init(struct slsi_hip4 *hip) /* Set driver is not ready to receive interrupts */ atomic_set(&hip->hip_priv->rx_ready, 0); -#ifdef CONFIG_SCSC_WLAN_RX_NAPI + /***** VERSION 4 *******/ /* TOHOST Handler allocator */ +#ifdef CONFIG_SCSC_WLAN_RX_NAPI /* Q0 FH CTRL */ hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_CTRL] = scsc_service_mifintrbit_register_tohost(service, hip4_irq_handler_stub, hip); @@ -2030,14 +2074,14 @@ int hip4_init(struct slsi_hip4 *hip) scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]); /* Q5 TH RFB - Use the same stub interrupt handler */ hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_RFB] = hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_CTRL]; -#else +#endif + /***** VERSION 3 *******/ /* TOHOST Handler allocator */ hip->hip_priv->intr_tohost = scsc_service_mifintrbit_register_tohost(service, hip4_irq_handler, hip); /* Mask the interrupt to prevent intr been kicked during start */ scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost); -#endif /* FROMHOST Handler allocator */ hip->hip_priv->intr_fromhost = @@ -2172,9 +2216,8 @@ int hip4_init(struct slsi_hip4 *hip) tasklet_init(&hip->hip_priv->intr_tasklet, hip4_irq_data_tasklet, (unsigned long)hip); INIT_WORK(&hip->hip_priv->intr_wq_ctrl, hip4_wq_ctrl); INIT_WORK(&hip->hip_priv->intr_wq_fb, hip4_wq_fb); -#else - INIT_WORK(&hip->hip_priv->intr_wq, hip4_wq); #endif + INIT_WORK(&hip->hip_priv->intr_wq, hip4_wq); rwlock_init(&hip->hip_priv->rw_scoreboard); @@ -2412,9 +2455,13 @@ int hip4_setup(struct slsi_hip4 *hip) atomic_set(&hip->hip_priv->rx_ready, 1); #ifdef CONFIG_SCSC_WLAN_RX_NAPI - scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_RFB]); - scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_CTRL]); - scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]); + if (conf_hip4_ver == 4) { + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_FH_RFB]); + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_CTRL]); + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[HIP4_MIF_Q_TH_DAT]); + } else { + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost); + } #else scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost); #endif @@ -2426,6 +2473,9 @@ void hip4_suspend(struct slsi_hip4 *hip) { struct slsi_dev *sdev; struct scsc_service *service; +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + u32 conf_hip4_ver = 0; +#endif if (!hip || !hip->hip_priv) return; @@ -2445,8 +2495,14 @@ void hip4_suspend(struct slsi_hip4 *hip) atomic_set(&hip->hip_priv->in_suspend, 1); #ifdef CONFIG_SCSC_WLAN_RX_NAPI - for (u8 i = 0; i < MIF_HIP_CFG_Q_NUM; i++) - scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[i]); + conf_hip4_ver = scsc_wifi_get_hip_config_version(&hip->hip_control->init); + + if (conf_hip4_ver == 4) { + for (u8 i = 0; i < MIF_HIP_CFG_Q_NUM; i++) + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost_mul[i]); + } else { + scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost); + } #else scsc_service_mifintrbit_bit_unmask(service, hip->hip_priv->intr_tohost); #endif @@ -2473,6 +2529,9 @@ void hip4_freeze(struct slsi_hip4 *hip) { struct slsi_dev *sdev; struct scsc_service *service; +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + u32 conf_hip4_ver = 0; +#endif if (!hip || !hip->hip_priv) return; @@ -2491,12 +2550,19 @@ void hip4_freeze(struct slsi_hip4 *hip) hip4_dump_dbg(hip, NULL, NULL, service); #ifdef CONFIG_SCSC_WLAN_RX_NAPI - for (u8 i = 0; i < MIF_HIP_CFG_Q_NUM; i++) - scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost_mul[i]); + conf_hip4_ver = scsc_wifi_get_hip_config_version(&hip->hip_control->init); + + if (conf_hip4_ver == 4) { + for (u8 i = 0; i < MIF_HIP_CFG_Q_NUM; i++) + scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost_mul[i]); - tasklet_kill(&hip->hip_priv->intr_tasklet); - cancel_work_sync(&hip->hip_priv->intr_wq_ctrl); - cancel_work_sync(&hip->hip_priv->intr_wq_fb); + tasklet_kill(&hip->hip_priv->intr_tasklet); + cancel_work_sync(&hip->hip_priv->intr_wq_ctrl); + cancel_work_sync(&hip->hip_priv->intr_wq_fb); + } else { + scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost); + cancel_work_sync(&hip->hip_priv->intr_wq); + } #else scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost); cancel_work_sync(&hip->hip_priv->intr_wq); @@ -2512,6 +2578,9 @@ void hip4_deinit(struct slsi_hip4 *hip) { struct slsi_dev *sdev = container_of(hip, struct slsi_dev, hip4_inst); struct scsc_service *service; +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + u32 conf_hip4_ver = 0; +#endif if (!sdev || !sdev->service) return; @@ -2543,16 +2612,24 @@ void hip4_deinit(struct slsi_hip4 *hip) atomic_set(&hip->hip_priv->closing, 1); #ifdef CONFIG_SCSC_WLAN_RX_NAPI - for (u8 i = 0; i < MIF_HIP_CFG_Q_NUM; i++) - scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost_mul[i]); + conf_hip4_ver = scsc_wifi_get_hip_config_version(&hip->hip_control->init); - netif_napi_del(&hip->hip_priv->napi); - tasklet_kill(&hip->hip_priv->intr_tasklet); - cancel_work_sync(&hip->hip_priv->intr_wq_ctrl); - cancel_work_sync(&hip->hip_priv->intr_wq_fb); + if (conf_hip4_ver == 4) { + for (u8 i = 0; i < MIF_HIP_CFG_Q_NUM; i++) + scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost_mul[i]); - for (i = 0; i < MIF_HIP_CFG_Q_NUM; i++) - scsc_service_mifintrbit_unregister_tohost(service, hip->hip_priv->intr_tohost_mul[i]); + netif_napi_del(&hip->hip_priv->napi); + tasklet_kill(&hip->hip_priv->intr_tasklet); + cancel_work_sync(&hip->hip_priv->intr_wq_ctrl); + cancel_work_sync(&hip->hip_priv->intr_wq_fb); + + for (i = 0; i < MIF_HIP_CFG_Q_NUM; i++) + scsc_service_mifintrbit_unregister_tohost(service, hip->hip_priv->intr_tohost_mul[i]); + } else { + scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost); + cancel_work_sync(&hip->hip_priv->intr_wq); + scsc_service_mifintrbit_unregister_tohost(service, hip->hip_priv->intr_tohost); + } #else scsc_service_mifintrbit_bit_mask(service, hip->hip_priv->intr_tohost); cancel_work_sync(&hip->hip_priv->intr_wq); diff --git a/drivers/net/wireless/scsc/hip4.h b/drivers/net/wireless/scsc/hip4.h index 85b59ddea054..04f92e8da295 100755 --- a/drivers/net/wireless/scsc/hip4.h +++ b/drivers/net/wireless/scsc/hip4.h @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ @@ -241,9 +241,8 @@ struct hip4_priv { struct work_struct intr_wq_ctrl; struct work_struct intr_wq_fb; struct napi_struct napi; -#else - struct work_struct intr_wq; #endif + struct work_struct intr_wq; /* Interrupts cache < v4 */ /* TOHOST */ diff --git a/drivers/net/wireless/scsc/mgt.c b/drivers/net/wireless/scsc/mgt.c index f80ca486d438..7357cb0d8ae7 100755 --- a/drivers/net/wireless/scsc/mgt.c +++ b/drivers/net/wireless/scsc/mgt.c @@ -2056,9 +2056,8 @@ void slsi_vif_deactivated(struct slsi_dev *sdev, struct net_device *dev) /* MUST be done first to ensure that other code doesn't treat the VIF as still active */ ndev_vif->activated = false; -#ifndef CONFIG_SCSC_WLAN_RX_NAPI slsi_skb_queue_purge(&ndev_vif->rx_data.queue); -#endif + for (i = 0; i < (SLSI_ADHOC_PEER_CONNECTIONS_MAX); i++) { struct slsi_peer *peer = ndev_vif->peer_sta_record[i]; diff --git a/drivers/net/wireless/scsc/netif.c b/drivers/net/wireless/scsc/netif.c index 2dfcc8b653c1..b723e17e8df6 100755 --- a/drivers/net/wireless/scsc/netif.c +++ b/drivers/net/wireless/scsc/netif.c @@ -1135,16 +1135,13 @@ int slsi_netif_add_locked(struct slsi_dev *sdev, const char *name, int ifnum) INIT_DELAYED_WORK(&ndev_vif->scan_timeout_work, slsi_scan_ind_timeout_handle); -#ifndef CONFIG_SCSC_WLAN_RX_NAPI ret = slsi_skb_work_init(sdev, dev, &ndev_vif->rx_data, "slsi_wlan_rx_data", slsi_rx_netdev_data_work); if (ret) goto exit_with_error; -#endif + ret = slsi_skb_work_init(sdev, dev, &ndev_vif->rx_mlme, "slsi_wlan_rx_mlme", slsi_rx_netdev_mlme_work); if (ret) { -#ifndef CONFIG_SCSC_WLAN_RX_NAPI slsi_skb_work_deinit(&ndev_vif->rx_data); -#endif goto exit_with_error; } @@ -1337,10 +1334,9 @@ void slsi_netif_remove_locked(struct slsi_dev *sdev, struct net_device *dev) cancel_delayed_work(&ndev_vif->scan_timeout_work); ndev_vif->scan[SLSI_SCAN_HW_ID].requeue_timeout_work = false; -#ifndef CONFIG_SCSC_WLAN_RX_NAPI slsi_skb_work_deinit(&ndev_vif->rx_data); -#endif slsi_skb_work_deinit(&ndev_vif->rx_mlme); + for (i = 0; i < SLSI_SCAN_MAX; i++) slsi_purge_scan_results(ndev_vif, i); diff --git a/drivers/net/wireless/scsc/sap_ma.c b/drivers/net/wireless/scsc/sap_ma.c index 502d81de100c..26fa07b8aad8 100755 --- a/drivers/net/wireless/scsc/sap_ma.c +++ b/drivers/net/wireless/scsc/sap_ma.c @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2014 - 2018 Samsung Electronics Co., Ltd. All rights reserved + * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ #include @@ -198,6 +198,9 @@ void slsi_rx_data_deliver_skb(struct slsi_dev *sdev, struct net_device *dev, str struct ethhdr *eth_hdr; bool is_amsdu = slsi_rx_is_amsdu(skb); u8 trafic_q = slsi_frame_priority_to_ac_queue(fapi_get_u16(skb, u.ma_unitdata_ind.priority)); +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + u32 conf_hip4_ver = 0; +#endif __skb_queue_head_init(&msdu_list); @@ -314,10 +317,17 @@ void slsi_rx_data_deliver_skb(struct slsi_dev *sdev, struct net_device *dev, str slsi_dbg_untrack_skb(rx_skb); SLSI_DBG4(sdev, SLSI_RX, "pass %u bytes to local stack\n", rx_skb->len); +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + conf_hip4_ver = scsc_wifi_get_hip_config_version(&sdev->hip4_inst.hip_control->init); + if (conf_hip4_ver == 4) { #ifdef CONFIG_SCSC_WLAN_RX_NAPI_GRO - napi_gro_receive(&sdev->hip4_inst.hip_priv->napi, rx_skb); -#elif defined(CONFIG_SCSC_WLAN_RX_NAPI) - netif_receive_skb(rx_skb); + napi_gro_receive(&sdev->hip4_inst.hip_priv->napi, rx_skb); +#else + netif_receive_skb(rx_skb); +#endif + } else { + netif_rx_ni(rx_skb); + } #else netif_rx_ni(rx_skb); #endif @@ -487,7 +497,7 @@ static int slsi_rx_napi_process(struct slsi_dev *sdev, struct sk_buff *skb) } return 0; } -#else +#endif void slsi_rx_netdev_data_work(struct work_struct *work) { struct slsi_skb_work *w = container_of(work, struct slsi_skb_work, work); @@ -571,10 +581,12 @@ static int slsi_rx_queue_data(struct slsi_dev *sdev, struct sk_buff *skb) err: return -EINVAL; } -#endif static int sap_ma_rx_handler(struct slsi_dev *sdev, struct sk_buff *skb) { +#ifdef CONFIG_SCSC_WLAN_RX_NAPI + u32 conf_hip4_ver = 0; +#endif #ifdef CONFIG_SCSC_SMAPPER u16 sig_len; u32 err; @@ -595,7 +607,11 @@ static int sap_ma_rx_handler(struct slsi_dev *sdev, struct sk_buff *skb) #endif case MA_UNITDATA_CFM: #ifdef CONFIG_SCSC_WLAN_RX_NAPI - return slsi_rx_napi_process(sdev, skb); + conf_hip4_ver = scsc_wifi_get_hip_config_version(&sdev->hip4_inst.hip_control->init); + if (conf_hip4_ver == 4) + return slsi_rx_napi_process(sdev, skb); + else + return slsi_rx_queue_data(sdev, skb); #else return slsi_rx_queue_data(sdev, skb); #endif