Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d98c3edc authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'wireless-drivers-next-for-davem-2015-05-21' of...

Merge tag 'wireless-drivers-next-for-davem-2015-05-21' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next



Kalle Valo says:

====================
ath10k:

* enable channel 144 on 5 GHz
* enable Adaptive Noise Immunity (ANI) by default
* add Wake on Wireless LAN (WOW) patterns support
* add basic Tunneled Direct Link Setup (TDLS) support
* add multi-channel support for QCA6174
* enable IBSS RSN support
* enable Bluetooth Coexistance whenever firmware supports it
* add more versatile way to set bitrates used by the firmware

ath9k:

* spectral scan: add support for multiple FFT frames per report

iwlwifi:

* major rework of the scan code (Luca)
* some work on the thermal code (Chaya Rachel)
* some work on the firwmare debugging infrastructure

brcmfmac:

* SDIO suspend and resume fixes
* wiphy band info and changes in regulatory settings
* add support for BCM4324 SDIO and BCM4358 PCIe
* enable support of PCIe devices on router platforms (Hante)
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 4029685a 6e651045
Loading
Loading
Loading
Loading
+11 −9
Original line number Diff line number Diff line
@@ -226,6 +226,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
		chip->of_node	= cc->core->dev.of_node;
#endif
	switch (bus->chipinfo.id) {
	case BCMA_CHIP_ID_BCM4707:
	case BCMA_CHIP_ID_BCM5357:
	case BCMA_CHIP_ID_BCM53572:
		chip->ngpio	= 32;
@@ -235,16 +236,17 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
	}

	/*
	 * On MIPS we register GPIO devices (LEDs, buttons) using absolute GPIO
	 * pin numbers. We don't have Device Tree there and we can't really use
	 * relative (per chip) numbers.
	 * So let's use predictable base for BCM47XX and "random" for all other.
	 * Register SoC GPIO devices with absolute GPIO pin base.
	 * On MIPS, we don't have Device Tree and we can't use relative (per chip)
	 * GPIO numbers.
	 * On some ARM devices, user space may want to access some system GPIO
	 * pins directly, which is easier to do with a predictable GPIO base.
	 */
#if IS_BUILTIN(CONFIG_BCM47XX)
	if (IS_BUILTIN(CONFIG_BCM47XX) ||
	    cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
		chip->base		= bus->num * BCMA_GPIO_MAX_PINS;
#else
	else
		chip->base		= -1;
#endif

	err = bcma_gpio_irq_domain_init(cc);
	if (err)
+2 −0
Original line number Diff line number Diff line
@@ -251,6 +251,7 @@ void ath_printk(const char *level, const struct ath_common *common,
 * @ATH_DBG_DFS: radar datection
 * @ATH_DBG_WOW: Wake on Wireless
 * @ATH_DBG_DYNACK: dynack handling
 * @ATH_DBG_SPECTRAL_SCAN: FFT spectral scan
 * @ATH_DBG_ANY: enable all debugging
 *
 * The debug level is used to control the amount and type of debugging output
@@ -280,6 +281,7 @@ enum ATH_DEBUG {
	ATH_DBG_WOW		= 0x00020000,
	ATH_DBG_CHAN_CTX	= 0x00040000,
	ATH_DBG_DYNACK		= 0x00080000,
	ATH_DBG_SPECTRAL_SCAN	= 0x00100000,
	ATH_DBG_ANY		= 0xffffffff
};

+3 −1
Original line number Diff line number Diff line
@@ -10,13 +10,15 @@ ath10k_core-y += mac.o \
		 wmi.o \
		 wmi-tlv.o \
		 bmi.o \
		 hw.o
		 hw.o \
		 p2p.o

ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o
ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o
ath10k_core-$(CONFIG_THERMAL) += thermal.o
ath10k_core-$(CONFIG_MAC80211_DEBUGFS) += debugfs_sta.o
ath10k_core-$(CONFIG_PM) += wow.o

obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o
ath10k_pci-y += pci.o \
+121 −40
Original line number Diff line number Diff line
@@ -482,31 +482,79 @@ static int ath10k_fetch_cal_file(struct ath10k *ar)
	return 0;
}

static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar)
static int ath10k_core_fetch_spec_board_file(struct ath10k *ar)
{
	int ret = 0;
	char filename[100];

	if (ar->hw_params.fw.fw == NULL) {
		ath10k_err(ar, "firmware file not defined\n");
		return -EINVAL;
	scnprintf(filename, sizeof(filename), "board-%s-%s.bin",
		  ath10k_bus_str(ar->hif.bus), ar->spec_board_id);

	ar->board = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, filename);
	if (IS_ERR(ar->board))
		return PTR_ERR(ar->board);

	ar->board_data = ar->board->data;
	ar->board_len = ar->board->size;
	ar->spec_board_loaded = true;

	return 0;
}

	if (ar->hw_params.fw.board == NULL) {
		ath10k_err(ar, "board data file not defined");
static int ath10k_core_fetch_generic_board_file(struct ath10k *ar)
{
	if (!ar->hw_params.fw.board) {
		ath10k_err(ar, "failed to find board file fw entry\n");
		return -EINVAL;
	}

	ar->board = ath10k_fetch_fw_file(ar,
					 ar->hw_params.fw.dir,
					 ar->hw_params.fw.board);
	if (IS_ERR(ar->board)) {
		ret = PTR_ERR(ar->board);
		ath10k_err(ar, "could not fetch board data (%d)\n", ret);
		goto err;
	}
	if (IS_ERR(ar->board))
		return PTR_ERR(ar->board);

	ar->board_data = ar->board->data;
	ar->board_len = ar->board->size;
	ar->spec_board_loaded = false;

	return 0;
}

static int ath10k_core_fetch_board_file(struct ath10k *ar)
{
	int ret;

	if (strlen(ar->spec_board_id) > 0) {
		ret = ath10k_core_fetch_spec_board_file(ar);
		if (ret) {
			ath10k_info(ar, "failed to load spec board file, falling back to generic: %d\n",
				    ret);
			goto generic;
		}

		ath10k_dbg(ar, ATH10K_DBG_BOOT, "found specific board file for %s\n",
			   ar->spec_board_id);
		return 0;
	}

generic:
	ret = ath10k_core_fetch_generic_board_file(ar);
	if (ret) {
		ath10k_err(ar, "failed to fetch generic board data: %d\n", ret);
		return ret;
	}

	return 0;
}

static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar)
{
	int ret = 0;

	if (ar->hw_params.fw.fw == NULL) {
		ath10k_err(ar, "firmware file not defined\n");
		return -EINVAL;
	}

	ar->firmware = ath10k_fetch_fw_file(ar,
					    ar->hw_params.fw.dir,
@@ -675,6 +723,17 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
			ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie wmi op version %d\n",
				   ar->wmi.op_version);
			break;
		case ATH10K_FW_IE_HTT_OP_VERSION:
			if (ie_len != sizeof(u32))
				break;

			version = (__le32 *)data;

			ar->htt.op_version = le32_to_cpup(version);

			ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie htt op version %d\n",
				   ar->htt.op_version);
			break;
		default:
			ath10k_warn(ar, "Unknown FW IE: %u\n",
				    le32_to_cpu(hdr->id));
@@ -695,27 +754,6 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
		goto err;
	}

	/* now fetch the board file */
	if (ar->hw_params.fw.board == NULL) {
		ath10k_err(ar, "board data file not defined");
		ret = -EINVAL;
		goto err;
	}

	ar->board = ath10k_fetch_fw_file(ar,
					 ar->hw_params.fw.dir,
					 ar->hw_params.fw.board);
	if (IS_ERR(ar->board)) {
		ret = PTR_ERR(ar->board);
		ath10k_err(ar, "could not fetch board data '%s/%s' (%d)\n",
			   ar->hw_params.fw.dir, ar->hw_params.fw.board,
			   ret);
		goto err;
	}

	ar->board_data = ar->board->data;
	ar->board_len = ar->board->size;

	return 0;

err:
@@ -730,6 +768,19 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
	/* calibration file is optional, don't check for any errors */
	ath10k_fetch_cal_file(ar);

	ret = ath10k_core_fetch_board_file(ar);
	if (ret) {
		ath10k_err(ar, "failed to fetch board file: %d\n", ret);
		return ret;
	}

	ar->fw_api = 5;
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);

	ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API5_FILE);
	if (ret == 0)
		goto success;

	ar->fw_api = 4;
	ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);

@@ -958,6 +1009,8 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
		ar->max_num_stations = TARGET_NUM_STATIONS;
		ar->max_num_vdevs = TARGET_NUM_VDEVS;
		ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC;
		ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
			WMI_STAT_PEER;
		break;
	case ATH10K_FW_WMI_OP_VERSION_10_1:
	case ATH10K_FW_WMI_OP_VERSION_10_2:
@@ -966,12 +1019,17 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
		ar->max_num_stations = TARGET_10X_NUM_STATIONS;
		ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;
		ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
		ar->fw_stats_req_mask = WMI_STAT_PEER;
		break;
	case ATH10K_FW_WMI_OP_VERSION_TLV:
		ar->max_num_peers = TARGET_TLV_NUM_PEERS;
		ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
		ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
		ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS;
		ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;
		ar->wow.max_num_patterns = TARGET_TLV_NUM_WOW_PATTERNS;
		ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
			WMI_STAT_PEER;
		break;
	case ATH10K_FW_WMI_OP_VERSION_UNSET:
	case ATH10K_FW_WMI_OP_VERSION_MAX:
@@ -979,6 +1037,29 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
		return -EINVAL;
	}

	/* Backwards compatibility for firmwares without
	 * ATH10K_FW_IE_HTT_OP_VERSION.
	 */
	if (ar->htt.op_version == ATH10K_FW_HTT_OP_VERSION_UNSET) {
		switch (ar->wmi.op_version) {
		case ATH10K_FW_WMI_OP_VERSION_MAIN:
			ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_MAIN;
			break;
		case ATH10K_FW_WMI_OP_VERSION_10_1:
		case ATH10K_FW_WMI_OP_VERSION_10_2:
		case ATH10K_FW_WMI_OP_VERSION_10_2_4:
			ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_10_1;
			break;
		case ATH10K_FW_WMI_OP_VERSION_TLV:
			ar->htt.op_version = ATH10K_FW_HTT_OP_VERSION_TLV;
			break;
		case ATH10K_FW_WMI_OP_VERSION_UNSET:
		case ATH10K_FW_WMI_OP_VERSION_MAX:
			WARN_ON(1);
			return -EINVAL;
		}
	}

	return 0;
}

@@ -1080,9 +1161,8 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)

	if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
		status = ath10k_wmi_wait_for_service_ready(ar);
		if (status <= 0) {
		if (status) {
			ath10k_warn(ar, "wmi service ready event not received");
			status = -ETIMEDOUT;
			goto err_hif_stop;
		}
	}
@@ -1098,9 +1178,8 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
	}

	status = ath10k_wmi_wait_for_unified_ready(ar);
	if (status <= 0) {
	if (status) {
		ath10k_err(ar, "wmi unified ready event not received\n");
		status = -ETIMEDOUT;
		goto err_hif_stop;
	}

@@ -1151,6 +1230,7 @@ EXPORT_SYMBOL(ath10k_core_start);
int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt)
{
	int ret;
	unsigned long time_left;

	reinit_completion(&ar->target_suspend);

@@ -1160,9 +1240,9 @@ int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt)
		return ret;
	}

	ret = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);
	time_left = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);

	if (ret == 0) {
	if (!time_left) {
		ath10k_warn(ar, "suspend timed out - target pause event never came\n");
		return -ETIMEDOUT;
	}
@@ -1386,6 +1466,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
	init_completion(&ar->scan.completed);
	init_completion(&ar->scan.on_channel);
	init_completion(&ar->target_suspend);
	init_completion(&ar->wow.wakeup_completed);

	init_completion(&ar->install_key_done);
	init_completion(&ar->vdev_setup_done);
+42 −6
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include "../dfs_pattern_detector.h"
#include "spectral.h"
#include "thermal.h"
#include "wow.h"

#define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB)
#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
@@ -43,15 +44,16 @@
#define ATH10K_SCAN_ID 0
#define WMI_READY_TIMEOUT (5 * HZ)
#define ATH10K_FLUSH_TIMEOUT_HZ (5*HZ)
#define ATH10K_NUM_CHANS 38
#define ATH10K_CONNECTION_LOSS_HZ (3*HZ)
#define ATH10K_NUM_CHANS 39

/* Antenna noise floor */
#define ATH10K_DEFAULT_NOISE_FLOOR -95

#define ATH10K_MAX_NUM_MGMT_PENDING 128

/* number of failed packets */
#define ATH10K_KICKOUT_THRESHOLD 50
/* number of failed packets (20 packets with 16 sw reties each) */
#define ATH10K_KICKOUT_THRESHOLD (20 * 16)

/*
 * Use insanely high numbers to make sure that the firmware implementation
@@ -82,6 +84,8 @@ struct ath10k_skb_cb {
	dma_addr_t paddr;
	u8 eid;
	u8 vdev_id;
	enum ath10k_hw_txrx_mode txmode;
	bool is_protected;

	struct {
		u8 tid;
@@ -280,6 +284,15 @@ struct ath10k_sta {
#endif
};

struct ath10k_chanctx {
	/* Used to story copy of chanctx_conf to avoid inconsistencies. Ideally
	 * mac80211 should allow some sort of explicit locking to guarantee
	 * that the publicly available chanctx_conf can be accessed safely at
	 * all times.
	 */
	struct ieee80211_chanctx_conf conf;
};

#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ)

enum ath10k_beacon_state {
@@ -301,6 +314,7 @@ struct ath10k_vif {
	enum ath10k_beacon_state beacon_state;
	void *beacon_buf;
	dma_addr_t beacon_paddr;
	unsigned long tx_paused; /* arbitrary values defined by target */

	struct ath10k *ar;
	struct ieee80211_vif *vif;
@@ -334,13 +348,13 @@ struct ath10k_vif {
		} ap;
	} u;

	u8 fixed_rate;
	u8 fixed_nss;
	u8 force_sgi;
	bool use_cts_prot;
	int num_legacy_stations;
	int txpower;
	struct wmi_wmm_params_all_arg wmm_params;
	struct work_struct ap_csa_work;
	struct delayed_work connection_loss_work;
	struct cfg80211_bitrate_mask bitrate_mask;
};

struct ath10k_vif_iter {
@@ -440,6 +454,12 @@ enum ath10k_fw_features {
	 */
	ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT = 5,

	/* Some firmware revisions have an incomplete WoWLAN implementation
	 * despite WMI service bit being advertised. This feature flag is used
	 * to distinguish whether WoWLAN is really supported or not.
	 */
	ATH10K_FW_FEATURE_WOWLAN_SUPPORT = 6,

	/* keep last */
	ATH10K_FW_FEATURE_COUNT,
};
@@ -498,6 +518,11 @@ static inline const char *ath10k_scan_state_str(enum ath10k_scan_state state)
	return "unknown";
}

enum ath10k_tx_pause_reason {
	ATH10K_TX_PAUSE_Q_FULL,
	ATH10K_TX_PAUSE_MAX,
};

struct ath10k {
	struct ath_common ath_common;
	struct ieee80211_hw *hw;
@@ -511,12 +536,15 @@ struct ath10k {
	u32 fw_version_minor;
	u16 fw_version_release;
	u16 fw_version_build;
	u32 fw_stats_req_mask;
	u32 phy_capability;
	u32 hw_min_tx_power;
	u32 hw_max_tx_power;
	u32 ht_cap_info;
	u32 vht_cap_info;
	u32 num_rf_chains;
	/* protected by conf_mutex */
	bool ani_enabled;

	DECLARE_BITMAP(fw_features, ATH10K_FW_FEATURE_COUNT);

@@ -565,6 +593,9 @@ struct ath10k {

	const struct firmware *cal_file;

	char spec_board_id[100];
	bool spec_board_loaded;

	int fw_api;
	enum ath10k_cal_mode cal_mode;

@@ -593,6 +624,7 @@ struct ath10k {
	struct cfg80211_chan_def chandef;

	unsigned long long free_vdev_map;
	struct ath10k_vif *monitor_arvif;
	bool monitor;
	int monitor_vdev_id;
	bool monitor_started;
@@ -633,6 +665,7 @@ struct ath10k {
	int max_num_peers;
	int max_num_stations;
	int max_num_vdevs;
	int max_num_tdls_vdevs;

	struct work_struct offchan_tx_work;
	struct sk_buff_head offchan_tx_queue;
@@ -655,6 +688,8 @@ struct ath10k {

	struct dfs_pattern_detector *dfs_detector;

	unsigned long tx_paused; /* see ATH10K_TX_PAUSE_ */

#ifdef CONFIG_ATH10K_DEBUGFS
	struct ath10k_debug debug;
#endif
@@ -686,6 +721,7 @@ struct ath10k {
	} stats;

	struct ath10k_thermal thermal;
	struct ath10k_wow wow;

	/* must be last */
	u8 drv_priv[0] __aligned(sizeof(void *));
Loading