static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar) { __le32 regdump_val[REGISTER_DUMP_LEN_MAX]; u32 i, address, regdump_addr = 0; int ret; if (ar->target_type != TARGET_TYPE_AR6003) return; /* the reg dump pointer is copied to the host interest area */ address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state)); address = TARG_VTOP(ar->target_type, address); /* read RAM location through diagnostic window */ ret = ath6kl_diag_read32(ar, address, ®dump_addr); if (ret || !regdump_addr) { ath6kl_warn("failed to get ptr to register dump area: %d\n", ret); return; } ath6kl_dbg(ATH6KL_DBG_IRQ, "register dump data address 0x%x\n", regdump_addr); regdump_addr = TARG_VTOP(ar->target_type, regdump_addr); /* fetch register dump data */ ret = ath6kl_diag_read(ar, regdump_addr, (u8 *)®dump_val[0], REG_DUMP_COUNT_AR6003 * (sizeof(u32))); if (ret) { ath6kl_warn("failed to get register dump: %d\n", ret); return; } ath6kl_info("crash dump:\n"); ath6kl_info("hw 0x%x fw %s\n", ar->wiphy->hw_version, ar->wiphy->fw_version); BUILD_BUG_ON(REG_DUMP_COUNT_AR6003 % 4); for (i = 0; i < REG_DUMP_COUNT_AR6003 / 4; i++) { ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n", 4 * i, le32_to_cpu(regdump_val[i]), le32_to_cpu(regdump_val[i + 1]), le32_to_cpu(regdump_val[i + 2]), le32_to_cpu(regdump_val[i + 3])); } }
static int ath6kl_dt_parse_vreg_info(struct device *dev, struct ath6kl_power_vreg_data **vreg_data, const char *vreg_name) { int len, ret = 0; const __be32 *prop; char prop_name[MAX_PROP_SIZE]; struct ath6kl_power_vreg_data *vreg; struct device_node *np = dev->of_node; ath6kl_dbg(ATH6KL_DBG_BOOT, "vreg dev tree parse for %s\n", vreg_name); snprintf(prop_name, MAX_PROP_SIZE, "%s-supply", vreg_name); if (of_parse_phandle(np, prop_name, 0)) { vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL); if (!vreg) { ath6kl_err("No memory for vreg: %s\n", vreg_name); ret = -ENOMEM; goto err; } vreg->name = vreg_name; snprintf(prop_name, MAX_PROP_SIZE, "%s-voltage-level", vreg_name); prop = of_get_property(np, prop_name, &len); if (!prop || (len != (2 * sizeof(__be32)))) { ath6kl_dbg(ATH6KL_DBG_BOOT, "%s %s property\n", prop ? "invalid format" : "no", prop_name); } else { vreg->low_vol_level = be32_to_cpup(&prop[0]); vreg->high_vol_level = be32_to_cpup(&prop[1]); } *vreg_data = vreg; ath6kl_dbg(ATH6KL_DBG_BOOT, "%s: vol=[%d %d]uV\n", vreg->name, vreg->low_vol_level, vreg->high_vol_level); } else ath6kl_info("%s: is not provided in device tree\n", vreg_name); err: return ret; }
static int ap_keepalive_update_check_txrx_time(struct ath6kl_vif *vif) { struct ath6kl *ar = vif->ar; struct wmi_ap_mode_stat *ap_stats = &vif->ap_stats; struct wmi_per_sta_stat *per_sta_stat; struct ath6kl_sta *conn; int i, action; if (test_bit(STATS_UPDATE_PEND, &vif->flags)) { ath6kl_info("somebody still query now and ignore it this time.\n"); return -EBUSY; } /* Now, tranfer to host time and update to vif->sta_list[]. */ for (i = 0; i < AP_MAX_NUM_STA; i++) { per_sta_stat = &ap_stats->sta[i]; if (per_sta_stat->aid) { conn = ath6kl_find_sta_by_aid(vif, per_sta_stat->aid); if (conn) { action = _ap_keepalive_update_check_txrx_time(vif, conn, per_sta_stat->last_txrx_time); if (action == AP_KA_ACTION_POLL) { ath6kl_wmi_ap_poll_sta(ar->wmi, vif->fw_vif_idx, conn->aid); } else if (action == AP_KA_ACTION_REMOVE) { ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH, conn->mac, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); } } else { ath6kl_err("can't find this AID %d in STA list\n", per_sta_stat->aid); } } } return 0; }
static void ath6kl_hif_dump(struct ath6kl *ar, u32 fw_dump_addr, u32 len) { __le32 regdump_val[MAX_DUMP_BYTE_NUM_ONE_ITERATION / 4]; u32 read_len = 0; u32 i = 0,count; int ret; u32 phy_addr = TARG_VTOP(ar->target_type, fw_dump_addr); len = (len + 3) & (~0x3); fw_dump_addr = (fw_dump_addr + 3) & (~0x3); while(len) { read_len = len; if(read_len > MAX_DUMP_BYTE_NUM_ONE_ITERATION) read_len = MAX_DUMP_BYTE_NUM_ONE_ITERATION; phy_addr = TARG_VTOP(ar->target_type, fw_dump_addr); ret = ath6kl_diag_read(ar, phy_addr, (u8 *) ®dump_val[0], read_len); if (ret) { ath6kl_warn("failed to get register dump: %d\n", ret); return; } count = read_len / 4; for (i = 0; i < count; i += 4) { ath6kl_info("0x%08x: 0x%08x 0x%08x 0x%08x 0x%08x\n", le32_to_cpu(fw_dump_addr + 4 * i), le32_to_cpu(regdump_val[i]), le32_to_cpu(regdump_val[i + 1]), le32_to_cpu(regdump_val[i + 2]), le32_to_cpu(regdump_val[i + 3])); } len -= read_len; fw_dump_addr += read_len; } }