Merge Quantenna SDK v37.4.0.46.
Change-Id: I6f8c6f5a56ba623b38c02ef6512b8c8618ca621f
diff --git a/drivers/net/wireless/quantenna/pcie2/host/common/qdpc_init.c b/drivers/net/wireless/quantenna/pcie2/host/common/qdpc_init.c
index 2c7d63b..09c8112 100644
--- a/drivers/net/wireless/quantenna/pcie2/host/common/qdpc_init.c
+++ b/drivers/net/wireless/quantenna/pcie2/host/common/qdpc_init.c
@@ -56,6 +56,18 @@
module_param(tlp_mps, uint, 0644);
MODULE_PARM_DESC(tlp_mps, "Default PCIe Max_Payload_Size");
+/*
+ * Define EP state during host suspend
+ * 0 = EP does not power off
+ * 1 = EP power off
+ */
+#define EP_SUSPEND_MODE_RUNNING 0
+#define EP_SUSPEND_MODE_PWR_OFF 1
+static unsigned int suspend_mode = EP_SUSPEND_MODE_RUNNING;
+module_param(suspend_mode, uint, 0644);
+MODULE_PARM_DESC(suspend_mode, "Default suspend behavior");
+static unsigned int suspend_flag = 0;
+
/* Quantenna PCIE vendor and device identifiers */
static struct pci_device_id qdpc_pcie_ids[] = {
{PCI_DEVICE(QDPC_VENDOR_ID, QDPC_DEVICE_ID),},
@@ -70,6 +82,8 @@
static void qdpc_nl_recv_msg(struct sk_buff *skb);
int qdpc_init_netdev(struct net_device **net_dev, struct pci_dev *pdev);
pci_ers_result_t qdpc_pcie_slot_reset(struct pci_dev *dev);
+static void qdpc_pcie_shutdown(struct pci_dev *pdev);
+
char qdpc_pcie_driver_name[] = "qdpc_host";
@@ -87,6 +101,7 @@
.resume = qdpc_pcie_resume,
#endif
.err_handler = &qdpc_err_hdl,
+ .shutdown = qdpc_pcie_shutdown,
};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
@@ -487,7 +502,7 @@
#endif
pci_disable_device(pdev);
- writel(TOPAZ_SET_INT(IPC_RESET_EP), vmp->ep_ipc_reg);
+ writel(TOPAZ_SET_INT(IPC_RESET_EP), (volatile void *)(vmp->ep_ipc_reg));
qdpc_unmap_iomem(vmp);
free_netdev(ndev);
@@ -539,13 +554,16 @@
ndev->flags &= ~IFF_RUNNING;
*priv->ep_pmstate = cpu_to_le32(PCI_D3hot);
barrier();
- writel(TOPAZ_SET_INT(IPC_EP_PM_CTRL), priv->ep_ipc_reg);
+ writel(TOPAZ_SET_INT(IPC_EP_PM_CTRL), (volatile void *)(priv->ep_ipc_reg));
msleep(100);
pci_save_state(pdev);
pci_disable_device(pdev);
qdpc_pcie_set_power_state(pdev, PCI_D3hot);
+ if (suspend_mode == EP_SUSPEND_MODE_PWR_OFF)
+ suspend_flag = 1;
+
return 0;
}
@@ -555,12 +573,15 @@
struct vmac_priv *priv;
int ret;
- if (ndev == NULL)
- return -EINVAL;
+ if (ndev == NULL) {
+ ret = -EINVAL;
+ goto out;
+ }
priv = netdev_priv(ndev);
if (le32_to_cpu(*priv->ep_pmstate) == PCI_D0) {
- return 0;
+ ret = 0;
+ goto out;
}
printk("%s start power management resume\n", qdpc_pcie_driver_name);
@@ -568,25 +589,41 @@
ret = pci_enable_device(pdev);
if (ret) {
PRINT_ERROR("%s: pci_enable_device failed on resume\n", __func__);
- return ret;
+ goto out;
}
pci_restore_state(pdev);
+ pdev->state_saved = true;
qdpc_pcie_set_power_state(pdev, PCI_D0);
{
*priv->ep_pmstate = cpu_to_le32(PCI_D0);
barrier();
- writel(TOPAZ_SET_INT(IPC_EP_PM_CTRL), priv->ep_ipc_reg);
+ writel(TOPAZ_SET_INT(IPC_EP_PM_CTRL), (volatile void *)(priv->ep_ipc_reg));
msleep(5000);
}
+ if ( (suspend_mode == EP_SUSPEND_MODE_PWR_OFF) &&
+ (pdev->driver && pdev->driver->err_handler && pdev->driver->err_handler->slot_reset) ) {
+ printk("slot_reset in %s(), Device name: %s\n", __FUNCTION__, dev_name(&pdev->dev));
+ if(pdev->driver->err_handler->slot_reset(pdev) == PCI_ERS_RESULT_RECOVERED)
+ printk("Recovery OK\n");
+ else {
+ printk("Recovery Error");
+ ret = -EINVAL;
+ goto out;
+ }
+ }
+
/* Set ep_ready to resume tx traffic */
priv->ep_ready = 1;
ndev->flags |= IFF_RUNNING;
- return 0;
+out:
+ if (suspend_mode == EP_SUSPEND_MODE_PWR_OFF)
+ suspend_flag = 0;
+ return ret;
}
static int __init qdpc_init_module(void)
@@ -646,12 +683,16 @@
{
struct vmac_priv *priv = NULL;
- if (pdev->state_saved == true) {
- pci_restore_state(pdev);
- pdev->state_saved = true;
- } else {
- printk("Recovery Error: No saved state\n");
- goto out;
+ if (suspend_mode == EP_SUSPEND_MODE_PWR_OFF && suspend_flag)
+ suspend_flag = 0;
+ else {
+ if (pdev->state_saved == true) {
+ pci_restore_state(pdev);
+ pdev->state_saved = true;
+ } else {
+ printk("Recovery Error: No saved state\n");
+ goto out;
+ }
}
if (pci_enable_device(pdev)) {
@@ -723,6 +764,13 @@
return PCI_ERS_RESULT_DISCONNECT;
}
+static void qdpc_pcie_shutdown(struct pci_dev *pdev)
+{
+ qdpc_pcie_remove(pdev);
+
+ return;
+}
+
static int qdpc_bringup_fw(struct vmac_priv *priv)
{
__iomem qdpc_pcie_bda_t *bda = priv->bda;
diff --git a/drivers/net/wireless/quantenna/pcie2/host/common/topaz_vnet.c b/drivers/net/wireless/quantenna/pcie2/host/common/topaz_vnet.c
index d21f7bf..08bf5ec 100644
--- a/drivers/net/wireless/quantenna/pcie2/host/common/topaz_vnet.c
+++ b/drivers/net/wireless/quantenna/pcie2/host/common/topaz_vnet.c
@@ -791,7 +791,7 @@
}
}
if ((ndev->stats.rx_packets & RX_DONE_INTR_MSK) == 0)
- writel(TOPAZ_SET_INT(IPC_RC_RX_DONE), vmp->ep_ipc_reg);
+ writel(TOPAZ_SET_INT(IPC_RC_RX_DONE), (volatile void *)(vmp->ep_ipc_reg));
dump_rx_bd(vmp);
@@ -893,12 +893,11 @@
i = vmp->tx_reclaim_start;
while (i != end_idx) {
- tbdp = &vmp->tx_bd_base[i];
struct sk_buff *skb;
skb = vmp->tx_skb[i];
if (!skb)
break;
-
+ tbdp = &vmp->tx_bd_base[i];
ndev->stats.tx_packets++;
ndev->stats.tx_bytes += skb->len;
@@ -1013,7 +1012,7 @@
vmp->txqueue_stopped = 1;
*vmp->txqueue_wake = 0;
barrier();
- writel(TOPAZ_SET_INT(IPC_RC_STOP_TX), vmp->ep_ipc_reg);
+ writel(TOPAZ_SET_INT(IPC_RC_STOP_TX), (volatile void *)(vmp->ep_ipc_reg));
vmp->tx_stop_queue_cnt++;
netif_stop_queue(ndev);
}
@@ -1111,7 +1110,7 @@
dump_tx_bd(vmp);
- writel(TOPAZ_SET_INT(IPC_EP_RX_PKT), vmp->ep_ipc_reg);
+ writel(TOPAZ_SET_INT(IPC_EP_RX_PKT), (volatile void *)(vmp->ep_ipc_reg));
#ifdef RC_TXDONE_TIMER
vmac_tx_teardown(ndev, bda);
@@ -1166,7 +1165,7 @@
if (vmp->tx_skb[vmp->tx_reclaim_start] == NULL) {
del_timer(&vmp->tx_timer);
} else {
- writel(TOPAZ_SET_INT(IPC_EP_RX_PKT), vmp->ep_ipc_reg);
+ writel(TOPAZ_SET_INT(IPC_EP_RX_PKT), (volatile void *)(vmp->ep_ipc_reg));
mod_timer(&vmp->tx_timer, jiffies + 1);
}
spin_unlock(&vmp->tx_lock);
diff --git a/drivers/net/wireless/quantenna/pcie2/include/qdpc_version.h b/drivers/net/wireless/quantenna/pcie2/include/qdpc_version.h
index 3b01b8e..3e81707 100644
--- a/drivers/net/wireless/quantenna/pcie2/include/qdpc_version.h
+++ b/drivers/net/wireless/quantenna/pcie2/include/qdpc_version.h
@@ -1 +1 @@
-#define DRV_VERSION "v37.4.0.38"
+#define DRV_VERSION "v37.4.0.46"