Skip to content

Commit

Permalink
Update to latest 4.7 kernel.
Browse files Browse the repository at this point in the history
Supports disabling fw dblog hex logging in the kernel
logs, ability to dump CSI on 10.4 CT firmware (but firmware
is currently not working right, so this doesn't really work),
ability to configure max-amsdu using fwcfg file, and DMAR
debugging at least when compiled against CT kernels with
DMAR debugging hacks in it.

Signed-off-by: Ben Greear <greearb@candelatech.com>
  • Loading branch information
greearb committed May 9, 2017
1 parent 587b624 commit 483668a
Show file tree
Hide file tree
Showing 12 changed files with 298 additions and 13 deletions.
120 changes: 120 additions & 0 deletions ath10k/core.c
Expand Up @@ -357,6 +357,70 @@ void ath10k_core_get_fw_features_str(struct ath10k *ar,
}
}

#if defined CONFIG_DMAR_TABLE && !defined STANDALONE_CT
void ath10k_dbg_dma_map(struct ath10k* ar, unsigned long long addr, unsigned long len, const char* dbg)
{
unsigned int i = ar->next_dma_dbg_idx++;

if (ar->next_dma_dbg_idx >= MAX_DMA_DBG_ENTRIES)
ar->next_dma_dbg_idx = 0;

ar->dma_dbg[i].addr = addr;
ar->dma_dbg[i].len = len;
ar->dma_dbg[i].type = dbg;
ar->dma_dbg[i].at = jiffies;
}
EXPORT_SYMBOL(ath10k_dbg_dma_map);

struct ath10k* ar_array[MAX_AR];

/* DMAR debugging hack, see dmar.c */
extern void (*dmar_fault_dbg_hook)(int type, u8 fault_reason, u16 source_id, unsigned long long addr,
const char* reason, int fault_type);

static void ath10k_dmar_dbg_hook(int type, u8 fault_reason, u16 source_id, unsigned long long addr,
const char* reason, int fault_type)
{
unsigned int pci_src = source_id >> 8;
//unsigned int pci_slot = PCI_SLOT(source_id & 0xFF);
//unsigned int pci_func = source_id & 0xFF;
int i, q;

/* This sucks, must be a better way. */
char fault_dev[40];
sprintf(fault_dev, "0000:%02x:00.0", pci_src);

pr_err("ath10k, dmar-dbg-hook, fault-dev: %s, addr: 0x%llx searching for matching device, jiffies: %lu\n",
fault_dev, addr, jiffies);

for (i = 0; i<MAX_AR; i++) {
struct ath10k* ar = ar_array[i];
const char* ar_dev_name;

if (!ar)
continue;

ar_dev_name = dev_name(ar->dev);
if (strcmp(fault_dev, ar_dev_name) != 0)
continue;

/* found it */
ath10k_err(ar, "DMAR error reported, addr: 0x%llx reason: %s\n",
addr, reason);

for (q = 0; q<MAX_DMA_DBG_ENTRIES; q++) {
if ((ar->dma_dbg[q].addr > (addr - 4096)) &&
(ar->dma_dbg[q].addr < (addr + ar->dma_dbg[q].len + 4096))) {
ath10k_err(ar, "[%i] addr: 0x%llx len: %lu at: %llu type: %s\n",
q, ar->dma_dbg[q].addr, ar->dma_dbg[q].len, ar->dma_dbg[q].at, ar->dma_dbg[q].type);
}
}
}
}
#else
#warning "Not compiling DMAR debug hook on this platform.";
#endif

static void ath10k_send_suspend_complete(struct ath10k *ar)
{
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot suspend complete\n");
Expand Down Expand Up @@ -1067,6 +1131,17 @@ static int ath10k_fetch_fwcfg_file(struct ath10k *ar)
ar->fwcfg.flags |= ATH10K_FWCFG_BMISS_VDEVS;
}
}
else if (strcasecmp(filename, "max_amsdus") == 0) {
if (kstrtol(val, 0, &t) == 0) {
ar->fwcfg.max_amsdus = t;
ar->fwcfg.flags |= ATH10K_FWCFG_MAX_AMSDUS;
if (ar->fwcfg.max_amsdus > 31) {
ath10k_warn(ar, "Invalid fwcfg max_amsdus value: %d. Must not be greater than 31.\n",
ar->fwcfg.max_amsdus);
ar->fwcfg.max_amsdus = 31;
}
}
}
else {
ath10k_warn(ar, "Unknown fwcfg key name -:%s:-, val: %s\n",
filename, val);
Expand Down Expand Up @@ -2119,6 +2194,12 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
if (ar->fwcfg.flags & ATH10K_FWCFG_BMISS_VDEVS)
ar->bmiss_offload_max_vdev = ar->fwcfg.bmiss_vdevs;

if (!(test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags))) {
/* Don't disable raw-mode hack, but otherwise allow override */
if (ar->fwcfg.flags & ATH10K_FWCFG_MAX_AMSDUS)
ar->htt.max_num_amsdu = ar->fwcfg.max_amsdus;
}

/* Some firmware may compile out beacon-miss logic to save firmware RAM
* and instruction RAM.
*/
Expand Down Expand Up @@ -2385,6 +2466,9 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
if (ar->eeprom_overrides.ct_pshack)
ath10k_wmi_pdev_set_special(ar, SET_SPECIAL_ID_PSHACK,
ar->eeprom_overrides.ct_pshack);
if (ar->eeprom_overrides.ct_csi)
ath10k_wmi_pdev_set_special(ar, SET_SPECIAL_ID_CSI,
ar->eeprom_overrides.ct_csi);
}

return 0;
Expand Down Expand Up @@ -2689,6 +2773,10 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
if (!ar)
return NULL;

#if defined CONFIG_DMAR_TABLE && !defined STANDALONE_CT
dmar_fault_dbg_hook = ath10k_dmar_dbg_hook;
#endif

ar->eeprom_overrides.max_txpower = 0xFFFF;
ar->sta_xretry_kickout_thresh = DEFAULT_ATH10K_KICKOUT_THRESHOLD;

Expand Down Expand Up @@ -2775,6 +2863,18 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
if (ret)
goto err_free_aux_wq;

#if defined CONFIG_DMAR_TABLE && !defined STANDALONE_CT
{
int i;
for (i = 0; i<MAX_AR; i++) {
if (!ar_array[i]) {
ar_array[i] = ar;
break;
}
}
}
#endif

return ar;

err_free_aux_wq:
Expand All @@ -2791,6 +2891,20 @@ EXPORT_SYMBOL(ath10k_core_create);

void ath10k_core_destroy(struct ath10k *ar)
{
#if defined CONFIG_DMAR_TABLE && !defined STANDALONE_CT
int i;
int any_left = 0;

for (i = 0; i<MAX_AR; i++) {
if (ar_array[i] == ar) {
ar_array[i] = NULL;
}
else if (ar_array[i]) {
any_left = 1;
}
}
#endif

flush_workqueue(ar->workqueue);
destroy_workqueue(ar->workqueue);

Expand All @@ -2800,6 +2914,12 @@ void ath10k_core_destroy(struct ath10k *ar)
ath10k_debug_destroy(ar);
ath10k_wmi_free_host_mem(ar);
ath10k_mac_destroy(ar);

#if defined CONFIG_DMAR_TABLE && !defined STANDALONE_CT
if (!any_left) {
dmar_fault_dbg_hook = NULL;
}
#endif
}
EXPORT_SYMBOL(ath10k_core_destroy);

Expand Down
25 changes: 25 additions & 0 deletions ath10k/core.h
Expand Up @@ -807,12 +807,31 @@ struct ath10k_fw_components {
struct ath10k_fw_file fw_file;
};

#if defined CONFIG_DMAR_TABLE && !defined STANDALONE_CT
#define MAX_DMA_DBG_ENTRIES 5000
struct dma_dbg_entry {
unsigned long long addr;
unsigned long long at; /* jiffies */
unsigned long len;
const char* type;
};

void ath10k_dbg_dma_map(struct ath10k* ar, unsigned long long addr, unsigned long len, const char* dbg);
#else
#define ath10k_dbg_dma_map(a, b, c, d) /* NOP */
#endif

struct ath10k {
struct ath_common ath_common;
struct ieee80211_hw *hw;
struct device *dev;
u8 mac_addr[ETH_ALEN];

#if defined CONFIG_DMAR_TABLE && !defined STANDALONE_CT
unsigned int next_dma_dbg_idx;
struct dma_dbg_entry dma_dbg[MAX_DMA_DBG_ENTRIES];
#endif

struct ieee80211_iface_combination if_comb[8];

enum ath10k_hw_rev hw_rev;
Expand Down Expand Up @@ -923,6 +942,7 @@ struct ath10k {
#define ATH10K_FWCFG_SKID_LIMIT (1<<10)
#define ATH10K_FWCFG_REGDOM (1<<11)
#define ATH10K_FWCFG_BMISS_VDEVS (1<<12)
#define ATH10K_FWCFG_MAX_AMSDUS (1<<13)

u32 flags; /* let us know which fields have been set */
char calname[100];
Expand All @@ -940,6 +960,7 @@ struct ath10k {
u32 skid_limit;
int regdom;
u32 bmiss_vdevs; /* To disable, set to 0 */
u32 max_amsdus;
} fwcfg;

struct {
Expand Down Expand Up @@ -1137,6 +1158,7 @@ struct ath10k {
* Units are actually 1/1024 of a second, but pretty close to ms, at least.
*/
u32 ct_pshack;
u32 ct_csi;
} eeprom_overrides;

/* must be last */
Expand All @@ -1152,6 +1174,9 @@ static inline bool ath10k_peer_stats_enabled(struct ath10k *ar)
return false;
}

#define MAX_AR 50
extern struct ath10k* ar_array[MAX_AR];

struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
enum ath10k_bus bus,
enum ath10k_hw_rev hw_rev,
Expand Down
6 changes: 6 additions & 0 deletions ath10k/debug.c
Expand Up @@ -1056,6 +1056,7 @@ static ssize_t ath10k_read_debug_level(struct file *file,
"WMI-PRINT: 0x2000\n"
"PCI-PS: 0x4000\n"
"AHB: 0x8000\n"
"NO-FW-DBGLOG:0x10000000\n"
"MAC2: 0x20000000\n"
"INFO-AS-DBG: 0x40000000\n"
"FW: 0x80000000\n"
Expand Down Expand Up @@ -2994,6 +2995,10 @@ static ssize_t ath10k_write_ct_special(struct file *file,
ar->eeprom_overrides.ct_pshack = val;
ath10k_warn(ar, "Setting CT-PSHACK override to 0x%x\n", val);
}
else if (id == SET_SPECIAL_ID_CSI) {
ar->eeprom_overrides.ct_csi = val;
ath10k_warn(ar, "Setting CT-CSI dump override to 0x%x\n", val);
}
/* Below here are local driver hacks, and not necessarily passed directly to firmware. */
else if (id == 0x1001) {
/* Set station failed-transmit kickout threshold. */
Expand Down Expand Up @@ -3046,6 +3051,7 @@ static ssize_t ath10k_read_ct_special(struct file *file,
"id: 0xB WMI WD Keepalive(ms): 0xFFFFFFFF disables, otherwise suggest 8000+.\n"
"id: 0xC Power-Save hack: 0x1 ignore PS sleep message from STA\n"
"id: 0x2 mark mcast as 'data-is-buffered' regardless\n"
"id: 0xD Enable CSI reporting for at least probe requests.\n"
"\nBelow here are not actually sent to firmware directly, but configure the driver.\n"
"id: 0x1001 set sta-kickout threshold due to tx-failures (0 means disable. Default is 20 * 16.)\n"
"\n";
Expand Down
1 change: 1 addition & 0 deletions ath10k/debug.h
Expand Up @@ -42,6 +42,7 @@ enum ath10k_debug_mask {
ATH10K_DBG_WMI_PRINT = 0x00002000,
ATH10K_DBG_PCI_PS = 0x00004000,
ATH10K_DBG_AHB = 0x00008000,
ATH10K_DBG_NO_DBGLOG = 0x10000000, /* Don't print DBGLOG firmware hex messages in kernel logs. */
ATH10K_DBG_MAC2 = 0x20000000, /* more verbose MAC debugging */
ATH10K_DBG_INFO_AS_DBG = 0x40000000,
ATH10K_DBG_FW = 0x80000000,
Expand Down
6 changes: 5 additions & 1 deletion ath10k/htc.c
Expand Up @@ -52,8 +52,10 @@ static inline void ath10k_htc_restore_tx_skb(struct ath10k_htc *htc,
struct sk_buff *skb)
{
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
struct ath10k *ar = htc->ar;

dma_unmap_single(htc->ar->dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
ath10k_dbg_dma_map(ar, skb_cb->paddr, skb->len, "unmap: htc-restore-tx-skb");
dma_unmap_single(ar->dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
skb_pull(skb, sizeof(struct ath10k_htc_hdr));
}

Expand Down Expand Up @@ -148,6 +150,7 @@ int ath10k_htc_send(struct ath10k_htc *htc,
ret = -EIO;
goto err_credits;
}
ath10k_dbg_dma_map(ar, skb_cb->paddr, skb->len, "HTC_SEND-MAP-SKB");

sg_item.transfer_id = ep->eid;
sg_item.transfer_context = skb;
Expand All @@ -162,6 +165,7 @@ int ath10k_htc_send(struct ath10k_htc *htc,
return 0;

err_unmap:
ath10k_dbg_dma_map(ar, skb_cb->paddr, skb->len, "unmap: htc-send-failure");
dma_unmap_single(dev, skb_cb->paddr, skb->len, DMA_TO_DEVICE);
err_credits:
if (ep->tx_credit_flow_enabled) {
Expand Down
4 changes: 2 additions & 2 deletions ath10k/htt.c
Expand Up @@ -267,8 +267,8 @@ int ath10k_htt_setup(struct ath10k_htt *htt)
htt->max_num_ampdu,
htt->max_num_amsdu);
if (status) {
ath10k_warn(ar, "failed to setup amsdu/ampdu limit: %d\n",
status);
ath10k_warn(ar, "failed to setup amsdu=%d/ampdu=%d limit: %d\n",
htt->max_num_ampdu, htt->max_num_amsdu, status);
return status;
}

Expand Down
15 changes: 11 additions & 4 deletions ath10k/htt_rx.c
Expand Up @@ -55,11 +55,13 @@ static void ath10k_htt_rx_ring_free(struct ath10k_htt *htt)
struct ath10k_skb_rxcb *rxcb;
struct hlist_node *n;
int i;
struct ath10k *ar = htt->ar;

if (htt->rx_ring.in_ord_rx) {
hash_for_each_safe(htt->rx_ring.skb_table, i, n, rxcb, hlist) {
skb = ATH10K_RXCB_SKB(rxcb);
dma_unmap_single(htt->ar->dev, rxcb->paddr,
ath10k_dbg_dma_map(ar, rxcb->paddr, skb->len + skb_tailroom(skb), "unmap: htt-rx-ring-free");
dma_unmap_single(ar->dev, rxcb->paddr,
skb->len + skb_tailroom(skb),
DMA_FROM_DEVICE);
hash_del(&rxcb->hlist);
Expand All @@ -72,7 +74,8 @@ static void ath10k_htt_rx_ring_free(struct ath10k_htt *htt)
continue;

rxcb = ATH10K_SKB_RXCB(skb);
dma_unmap_single(htt->ar->dev, rxcb->paddr,
ath10k_dbg_dma_map(ar, rxcb->paddr, skb->len + skb_tailroom(skb), "unmap: htt-rx-ring-free(not-in-ord-rx)");
dma_unmap_single(ar->dev, rxcb->paddr,
skb->len + skb_tailroom(skb),
DMA_FROM_DEVICE);
dev_kfree_skb_any(skb);
Expand All @@ -92,6 +95,7 @@ static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num)
struct sk_buff *skb;
dma_addr_t paddr;
int ret = 0, idx;
struct ath10k *ar = htt->ar;

/* The Full Rx Reorder firmware has no way of telling the host
* implicitly when it copied HTT Rx Ring buffers to MAC Rx Ring.
Expand All @@ -117,15 +121,16 @@ static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num)
rx_desc = (struct htt_rx_desc *)skb->data;
rx_desc->attention.flags = __cpu_to_le32(0);

paddr = dma_map_single(htt->ar->dev, skb->data,
paddr = dma_map_single(ar->dev, skb->data,
skb->len + skb_tailroom(skb),
DMA_FROM_DEVICE);

if (unlikely(dma_mapping_error(htt->ar->dev, paddr))) {
if (unlikely(dma_mapping_error(ar->dev, paddr))) {
dev_kfree_skb_any(skb);
ret = -ENOMEM;
goto fail;
}
ath10k_dbg_dma_map(ar, paddr, skb->len, "HTT-RX-RING-FILL");

rxcb = ATH10K_SKB_RXCB(skb);
rxcb->paddr = paddr;
Expand Down Expand Up @@ -271,6 +276,7 @@ static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt)
htt->rx_ring.sw_rd_idx.msdu_payld = idx;
htt->rx_ring.fill_cnt--;

ath10k_dbg_dma_map(ar, ATH10K_SKB_RXCB(msdu)->paddr, msdu->len + skb_tailroom(msdu), "unmap: htt-rx-netbuf-pop");
dma_unmap_single(htt->ar->dev,
ATH10K_SKB_RXCB(msdu)->paddr,
msdu->len + skb_tailroom(msdu),
Expand Down Expand Up @@ -399,6 +405,7 @@ static struct sk_buff *ath10k_htt_rx_pop_paddr(struct ath10k_htt *htt,
hash_del(&rxcb->hlist);
htt->rx_ring.fill_cnt--;

ath10k_dbg_dma_map(ar, rxcb->paddr, msdu->len + skb_tailroom(msdu), "unmap: htt-rx-pop-paddr");
dma_unmap_single(htt->ar->dev, rxcb->paddr,
msdu->len + skb_tailroom(msdu),
DMA_FROM_DEVICE);
Expand Down

0 comments on commit 483668a

Please sign in to comment.