mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for 4.16. Major changes: ath9k * add MSI support (not enabled by default yet)
This commit is contained in:
commit
70c8de0c15
@ -321,6 +321,7 @@ struct ath10k_ce_ops {
|
||||
dma_addr_t buffer, u32 nbytes,
|
||||
u32 transfer_id, u32 flags);
|
||||
};
|
||||
|
||||
static inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id)
|
||||
{
|
||||
return CE0_BASE_ADDRESS + (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS) * ce_id;
|
||||
|
@ -1276,7 +1276,10 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
|
||||
len -= sizeof(*hdr);
|
||||
data = hdr->data;
|
||||
|
||||
if (len < ALIGN(ie_len, 4)) {
|
||||
/* jump over the padding */
|
||||
ie_len = ALIGN(ie_len, 4);
|
||||
|
||||
if (len < ie_len) {
|
||||
ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n",
|
||||
ie_id, ie_len, len);
|
||||
ret = -EINVAL;
|
||||
@ -1315,9 +1318,6 @@ static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* jump over the padding */
|
||||
ie_len = ALIGN(ie_len, 4);
|
||||
|
||||
len -= ie_len;
|
||||
data += ie_len;
|
||||
}
|
||||
@ -1448,6 +1448,9 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
|
||||
len -= sizeof(*hdr);
|
||||
data += sizeof(*hdr);
|
||||
|
||||
/* jump over the padding */
|
||||
ie_len = ALIGN(ie_len, 4);
|
||||
|
||||
if (len < ie_len) {
|
||||
ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n",
|
||||
ie_id, len, ie_len);
|
||||
@ -1553,9 +1556,6 @@ int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
|
||||
break;
|
||||
}
|
||||
|
||||
/* jump over the padding */
|
||||
ie_len = ALIGN(ie_len, 4);
|
||||
|
||||
len -= ie_len;
|
||||
data += ie_len;
|
||||
}
|
||||
|
@ -1856,6 +1856,7 @@ struct ath10k_htt_rx_ops {
|
||||
void* (*htt_get_vaddr_ring)(struct ath10k_htt *htt);
|
||||
void (*htt_reset_paddrs_ring)(struct ath10k_htt *htt, int idx);
|
||||
};
|
||||
|
||||
#define RX_HTT_HDR_STATUS_LEN 64
|
||||
|
||||
/* This structure layout is programmed via rx ring setup
|
||||
|
@ -1478,13 +1478,10 @@ static int ath10k_pci_dump_memory_section(struct ath10k *ar,
|
||||
if (!mem_region || !buf)
|
||||
return 0;
|
||||
|
||||
if (mem_region->section_table.size < 0)
|
||||
return 0;
|
||||
|
||||
cur_section = &mem_region->section_table.sections[0];
|
||||
|
||||
if (mem_region->start > cur_section->start) {
|
||||
ath10k_warn(ar, "incorrect memdump region 0x%x with section start addrress 0x%x.\n",
|
||||
ath10k_warn(ar, "incorrect memdump region 0x%x with section start address 0x%x.\n",
|
||||
mem_region->start, cur_section->start);
|
||||
return 0;
|
||||
}
|
||||
|
@ -922,6 +922,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
|
||||
AR_IMR_RXERR |
|
||||
AR_IMR_RXORN |
|
||||
AR_IMR_BCNMISC;
|
||||
u32 msi_cfg = 0;
|
||||
|
||||
if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
|
||||
AR_SREV_9561(ah))
|
||||
@ -929,22 +930,30 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
imr_reg |= AR_IMR_RXOK_HP;
|
||||
if (ah->config.rx_intr_mitigation)
|
||||
if (ah->config.rx_intr_mitigation) {
|
||||
imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
|
||||
else
|
||||
msi_cfg |= AR_INTCFG_MSI_RXINTM | AR_INTCFG_MSI_RXMINTR;
|
||||
} else {
|
||||
imr_reg |= AR_IMR_RXOK_LP;
|
||||
|
||||
msi_cfg |= AR_INTCFG_MSI_RXOK;
|
||||
}
|
||||
} else {
|
||||
if (ah->config.rx_intr_mitigation)
|
||||
if (ah->config.rx_intr_mitigation) {
|
||||
imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
|
||||
else
|
||||
msi_cfg |= AR_INTCFG_MSI_RXINTM | AR_INTCFG_MSI_RXMINTR;
|
||||
} else {
|
||||
imr_reg |= AR_IMR_RXOK;
|
||||
msi_cfg |= AR_INTCFG_MSI_RXOK;
|
||||
}
|
||||
}
|
||||
|
||||
if (ah->config.tx_intr_mitigation)
|
||||
if (ah->config.tx_intr_mitigation) {
|
||||
imr_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR;
|
||||
else
|
||||
msi_cfg |= AR_INTCFG_MSI_TXINTM | AR_INTCFG_MSI_TXMINTR;
|
||||
} else {
|
||||
imr_reg |= AR_IMR_TXOK;
|
||||
msi_cfg |= AR_INTCFG_MSI_TXOK;
|
||||
}
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
@ -952,6 +961,16 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
|
||||
ah->imrs2_reg |= AR_IMR_S2_GTT;
|
||||
REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
|
||||
|
||||
if (ah->msi_enabled) {
|
||||
ah->msi_reg = REG_READ(ah, AR_PCIE_MSI);
|
||||
ah->msi_reg |= AR_PCIE_MSI_HW_DBI_WR_EN;
|
||||
ah->msi_reg &= AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64;
|
||||
REG_WRITE(ah, AR_INTCFG, msi_cfg);
|
||||
ath_dbg(ath9k_hw_common(ah), ANY,
|
||||
"value of AR_INTCFG=0x%X, msi_cfg=0x%X\n",
|
||||
REG_READ(ah, AR_INTCFG), msi_cfg);
|
||||
}
|
||||
|
||||
if (!AR_SREV_9100(ah)) {
|
||||
REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
|
||||
REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
|
||||
|
@ -977,6 +977,9 @@ struct ath_hw {
|
||||
bool tpc_enabled;
|
||||
u8 tx_power[Ar5416RateSize];
|
||||
u8 tx_power_stbc[Ar5416RateSize];
|
||||
bool msi_enabled;
|
||||
u32 msi_mask;
|
||||
u32 msi_reg;
|
||||
};
|
||||
|
||||
struct ath_bus_ops {
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/relay.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
|
||||
#include "ath9k.h"
|
||||
@ -75,6 +76,10 @@ MODULE_PARM_DESC(use_chanctx, "Enable channel context for concurrency");
|
||||
|
||||
#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */
|
||||
|
||||
int ath9k_use_msi;
|
||||
module_param_named(use_msi, ath9k_use_msi, int, 0444);
|
||||
MODULE_PARM_DESC(use_msi, "Use MSI instead of INTx if possible");
|
||||
|
||||
bool is_ath9k_unloaded;
|
||||
|
||||
#ifdef CONFIG_MAC80211_LEDS
|
||||
@ -92,6 +97,56 @@ static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
static int __init set_use_msi(const struct dmi_system_id *dmi)
|
||||
{
|
||||
ath9k_use_msi = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct dmi_system_id ath9k_quirks[] __initconst = {
|
||||
{
|
||||
.callback = set_use_msi,
|
||||
.ident = "Dell Inspiron 24-3460",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 24-3460"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = set_use_msi,
|
||||
.ident = "Dell Vostro 3262",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3262"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = set_use_msi,
|
||||
.ident = "Dell Inspiron 3472",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 3472"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = set_use_msi,
|
||||
.ident = "Dell Vostro 15-3572",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 15-3572"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.callback = set_use_msi,
|
||||
.ident = "Dell Inspiron 14-3473",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 14-3473"),
|
||||
},
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static void ath9k_deinit_softc(struct ath_softc *sc);
|
||||
|
||||
static void ath9k_op_ps_wakeup(struct ath_common *common)
|
||||
@ -1100,6 +1155,8 @@ static int __init ath9k_init(void)
|
||||
goto err_pci_exit;
|
||||
}
|
||||
|
||||
dmi_check_system(ath9k_quirks);
|
||||
|
||||
return 0;
|
||||
|
||||
err_pci_exit:
|
||||
|
@ -832,6 +832,43 @@ static void __ath9k_hw_enable_interrupts(struct ath_hw *ah)
|
||||
}
|
||||
ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
|
||||
REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
|
||||
|
||||
if (ah->msi_enabled) {
|
||||
u32 _msi_reg = 0;
|
||||
u32 i = 0;
|
||||
u32 msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64;
|
||||
|
||||
ath_dbg(ath9k_hw_common(ah), INTERRUPT,
|
||||
"Enabling MSI, msi_mask=0x%X\n", ah->msi_mask);
|
||||
|
||||
REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, ah->msi_mask);
|
||||
REG_WRITE(ah, AR_INTR_PRIO_ASYNC_MASK, ah->msi_mask);
|
||||
ath_dbg(ath9k_hw_common(ah), INTERRUPT,
|
||||
"AR_INTR_PRIO_ASYNC_ENABLE=0x%X, AR_INTR_PRIO_ASYNC_MASK=0x%X\n",
|
||||
REG_READ(ah, AR_INTR_PRIO_ASYNC_ENABLE),
|
||||
REG_READ(ah, AR_INTR_PRIO_ASYNC_MASK));
|
||||
|
||||
if (ah->msi_reg == 0)
|
||||
ah->msi_reg = REG_READ(ah, AR_PCIE_MSI);
|
||||
|
||||
ath_dbg(ath9k_hw_common(ah), INTERRUPT,
|
||||
"AR_PCIE_MSI=0x%X, ah->msi_reg = 0x%X\n",
|
||||
AR_PCIE_MSI, ah->msi_reg);
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
REG_WRITE(ah, AR_PCIE_MSI,
|
||||
(ah->msi_reg | AR_PCIE_MSI_ENABLE)
|
||||
& msi_pend_addr_mask);
|
||||
_msi_reg = REG_READ(ah, AR_PCIE_MSI);
|
||||
i++;
|
||||
} while ((_msi_reg & AR_PCIE_MSI_ENABLE) == 0 && i < 200);
|
||||
|
||||
if (i >= 200)
|
||||
ath_err(ath9k_hw_common(ah),
|
||||
"%s: _msi_reg = 0x%X\n",
|
||||
__func__, _msi_reg);
|
||||
}
|
||||
}
|
||||
|
||||
void ath9k_hw_resume_interrupts(struct ath_hw *ah)
|
||||
@ -878,12 +915,21 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah)
|
||||
if (!(ints & ATH9K_INT_GLOBAL))
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
|
||||
if (ah->msi_enabled) {
|
||||
ath_dbg(common, INTERRUPT, "Clearing AR_INTR_PRIO_ASYNC_ENABLE\n");
|
||||
|
||||
REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0);
|
||||
REG_READ(ah, AR_INTR_PRIO_ASYNC_ENABLE);
|
||||
}
|
||||
|
||||
ath_dbg(common, INTERRUPT, "New interrupt mask 0x%x\n", ints);
|
||||
|
||||
mask = ints & ATH9K_INT_COMMON;
|
||||
mask2 = 0;
|
||||
|
||||
ah->msi_mask = 0;
|
||||
if (ints & ATH9K_INT_TX) {
|
||||
ah->msi_mask |= AR_INTR_PRIO_TX;
|
||||
if (ah->config.tx_intr_mitigation)
|
||||
mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
|
||||
else {
|
||||
@ -898,6 +944,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah)
|
||||
mask |= AR_IMR_TXEOL;
|
||||
}
|
||||
if (ints & ATH9K_INT_RX) {
|
||||
ah->msi_mask |= AR_INTR_PRIO_RXLP | AR_INTR_PRIO_RXHP;
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
mask |= AR_IMR_RXERR | AR_IMR_RXOK_HP;
|
||||
if (ah->config.rx_intr_mitigation) {
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <linux/module.h>
|
||||
#include "ath9k.h"
|
||||
|
||||
extern int ath9k_use_msi;
|
||||
|
||||
static const struct pci_device_id ath_pci_id_table[] = {
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
|
||||
@ -889,6 +891,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
u32 val;
|
||||
int ret = 0;
|
||||
char hw_name[64];
|
||||
int msi_enabled = 0;
|
||||
|
||||
if (pcim_enable_device(pdev))
|
||||
return -EIO;
|
||||
@ -960,7 +963,20 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
sc->mem = pcim_iomap_table(pdev)[0];
|
||||
sc->driver_data = id->driver_data;
|
||||
|
||||
ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc);
|
||||
if (ath9k_use_msi) {
|
||||
if (pci_enable_msi(pdev) == 0) {
|
||||
msi_enabled = 1;
|
||||
dev_err(&pdev->dev, "Using MSI\n");
|
||||
} else {
|
||||
dev_err(&pdev->dev, "Using INTx\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!msi_enabled)
|
||||
ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc);
|
||||
else
|
||||
ret = request_irq(pdev->irq, ath_isr, 0, "ath9k", sc);
|
||||
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "request_irq failed\n");
|
||||
goto err_irq;
|
||||
@ -974,6 +990,9 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
goto err_init;
|
||||
}
|
||||
|
||||
sc->sc_ah->msi_enabled = msi_enabled;
|
||||
sc->sc_ah->msi_reg = 0;
|
||||
|
||||
ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
|
||||
wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
|
||||
hw_name, (unsigned long)sc->mem, pdev->irq);
|
||||
|
@ -146,6 +146,14 @@
|
||||
#define AR_MACMISC_MISC_OBS_BUS_MSB_S 15
|
||||
#define AR_MACMISC_MISC_OBS_BUS_1 1
|
||||
|
||||
#define AR_INTCFG 0x005C
|
||||
#define AR_INTCFG_MSI_RXOK 0x00000000
|
||||
#define AR_INTCFG_MSI_RXINTM 0x00000004
|
||||
#define AR_INTCFG_MSI_RXMINTR 0x00000006
|
||||
#define AR_INTCFG_MSI_TXOK 0x00000000
|
||||
#define AR_INTCFG_MSI_TXINTM 0x00000010
|
||||
#define AR_INTCFG_MSI_TXMINTR 0x00000018
|
||||
|
||||
#define AR_DATABUF_SIZE 0x0060
|
||||
#define AR_DATABUF_SIZE_MASK 0x00000FFF
|
||||
|
||||
@ -1256,6 +1264,13 @@ enum {
|
||||
#define AR_PCIE_MSI (AR_SREV_9340(ah) ? 0x40d8 : \
|
||||
(AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094))
|
||||
#define AR_PCIE_MSI_ENABLE 0x00000001
|
||||
#define AR_PCIE_MSI_HW_DBI_WR_EN 0x02000000
|
||||
#define AR_PCIE_MSI_HW_INT_PENDING_ADDR 0xFFA0C1FF /* bits 8..11: value must be 0x5060 */
|
||||
#define AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64 0xFFA0C9FF /* bits 8..11: value must be 0x5064 */
|
||||
|
||||
#define AR_INTR_PRIO_TX 0x00000001
|
||||
#define AR_INTR_PRIO_RXLP 0x00000002
|
||||
#define AR_INTR_PRIO_RXHP 0x00000004
|
||||
|
||||
#define AR_INTR_PRIO_SYNC_ENABLE (AR_SREV_9340(ah) ? 0x4088 : 0x40c4)
|
||||
#define AR_INTR_PRIO_ASYNC_MASK (AR_SREV_9340(ah) ? 0x408c : 0x40c8)
|
||||
|
Loading…
Reference in New Issue
Block a user