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

Commit 75ae83d6 authored by John W. Linville's avatar John W. Linville
Browse files

Merge tag 'for-linville-20131001' of git://github.com/kvalo/ath

parents c21a7d66 6e712d42
Loading
Loading
Loading
Loading
+27 −15
Original line number Diff line number Diff line
@@ -22,7 +22,8 @@

void ath10k_bmi_start(struct ath10k *ar)
{
	ath10k_dbg(ATH10K_DBG_CORE, "BMI started\n");
	ath10k_dbg(ATH10K_DBG_BMI, "bmi start\n");

	ar->bmi.done_sent = false;
}

@@ -32,8 +33,10 @@ int ath10k_bmi_done(struct ath10k *ar)
	u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.done);
	int ret;

	ath10k_dbg(ATH10K_DBG_BMI, "bmi done\n");

	if (ar->bmi.done_sent) {
		ath10k_dbg(ATH10K_DBG_CORE, "%s skipped\n", __func__);
		ath10k_dbg(ATH10K_DBG_BMI, "bmi skipped\n");
		return 0;
	}

@@ -46,7 +49,6 @@ int ath10k_bmi_done(struct ath10k *ar)
		return ret;
	}

	ath10k_dbg(ATH10K_DBG_CORE, "BMI done\n");
	return 0;
}

@@ -59,6 +61,8 @@ int ath10k_bmi_get_target_info(struct ath10k *ar,
	u32 resplen = sizeof(resp.get_target_info);
	int ret;

	ath10k_dbg(ATH10K_DBG_BMI, "bmi get target info\n");

	if (ar->bmi.done_sent) {
		ath10k_warn("BMI Get Target Info Command disallowed\n");
		return -EBUSY;
@@ -80,6 +84,7 @@ int ath10k_bmi_get_target_info(struct ath10k *ar,

	target_info->version = __le32_to_cpu(resp.get_target_info.version);
	target_info->type    = __le32_to_cpu(resp.get_target_info.type);

	return 0;
}

@@ -92,15 +97,14 @@ int ath10k_bmi_read_memory(struct ath10k *ar,
	u32 rxlen;
	int ret;

	ath10k_dbg(ATH10K_DBG_BMI, "bmi read address 0x%x length %d\n",
		   address, length);

	if (ar->bmi.done_sent) {
		ath10k_warn("command disallowed\n");
		return -EBUSY;
	}

	ath10k_dbg(ATH10K_DBG_CORE,
		   "%s: (device: 0x%p, address: 0x%x, length: %d)\n",
		   __func__, ar, address, length);

	while (length) {
		rxlen = min_t(u32, length, BMI_MAX_DATA_SIZE);

@@ -133,15 +137,14 @@ int ath10k_bmi_write_memory(struct ath10k *ar,
	u32 txlen;
	int ret;

	ath10k_dbg(ATH10K_DBG_BMI, "bmi write address 0x%x length %d\n",
		   address, length);

	if (ar->bmi.done_sent) {
		ath10k_warn("command disallowed\n");
		return -EBUSY;
	}

	ath10k_dbg(ATH10K_DBG_CORE,
		   "%s: (device: 0x%p, address: 0x%x, length: %d)\n",
		   __func__, ar, address, length);

	while (length) {
		txlen = min(length, BMI_MAX_DATA_SIZE - hdrlen);

@@ -180,15 +183,14 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param)
	u32 resplen = sizeof(resp.execute);
	int ret;

	ath10k_dbg(ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n",
		   address, *param);

	if (ar->bmi.done_sent) {
		ath10k_warn("command disallowed\n");
		return -EBUSY;
	}

	ath10k_dbg(ATH10K_DBG_CORE,
		   "%s: (device: 0x%p, address: 0x%x, param: %d)\n",
		   __func__, ar, address, *param);

	cmd.id            = __cpu_to_le32(BMI_EXECUTE);
	cmd.execute.addr  = __cpu_to_le32(address);
	cmd.execute.param = __cpu_to_le32(*param);
@@ -216,6 +218,9 @@ int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length)
	u32 txlen;
	int ret;

	ath10k_dbg(ATH10K_DBG_BMI, "bmi lz data buffer 0x%p length %d\n",
		   buffer, length);

	if (ar->bmi.done_sent) {
		ath10k_warn("command disallowed\n");
		return -EBUSY;
@@ -250,6 +255,9 @@ int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address)
	u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.lz_start);
	int ret;

	ath10k_dbg(ATH10K_DBG_BMI, "bmi lz stream start address 0x%x\n",
		   address);

	if (ar->bmi.done_sent) {
		ath10k_warn("command disallowed\n");
		return -EBUSY;
@@ -275,6 +283,10 @@ int ath10k_bmi_fast_download(struct ath10k *ar,
	u32 trailer_len = length - head_len;
	int ret;

	ath10k_dbg(ATH10K_DBG_BMI,
		   "bmi fast download address 0x%x buffer 0x%p length %d\n",
		   address, buffer, length);

	ret = ath10k_bmi_lz_stream_start(ar, address);
	if (ret)
		return ret;
+26 −87
Original line number Diff line number Diff line
@@ -338,33 +338,19 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state,
	return ret;
}

void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist, u32 buffer,
				unsigned int nbytes, u32 flags)
{
	unsigned int num_items = sendlist->num_items;
	struct ce_sendlist_item *item;

	item = &sendlist->item[num_items];
	item->data = buffer;
	item->u.nbytes = nbytes;
	item->flags = flags;
	sendlist->num_items++;
}

int ath10k_ce_sendlist_send(struct ath10k_ce_pipe *ce_state,
			    void *per_transfer_context,
			    struct ce_sendlist *sendlist,
			    unsigned int transfer_id)
			    unsigned int transfer_id,
			    u32 paddr, unsigned int nbytes,
			    u32 flags)
{
	struct ath10k_ce_ring *src_ring = ce_state->src_ring;
	struct ce_sendlist_item *item;
	struct ath10k *ar = ce_state->ar;
	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
	unsigned int nentries_mask = src_ring->nentries_mask;
	unsigned int num_items = sendlist->num_items;
	unsigned int sw_index;
	unsigned int write_index;
	int i, delta, ret = -ENOMEM;
	int delta, ret = -ENOMEM;

	spin_lock_bh(&ar_pci->ce_lock);

@@ -373,30 +359,12 @@ int ath10k_ce_sendlist_send(struct ath10k_ce_pipe *ce_state,

	delta = CE_RING_DELTA(nentries_mask, write_index, sw_index - 1);

	if (delta >= num_items) {
		/*
		 * Handle all but the last item uniformly.
		 */
		for (i = 0; i < num_items - 1; i++) {
			item = &sendlist->item[i];
			ret = ath10k_ce_send_nolock(ce_state,
						    CE_SENDLIST_ITEM_CTXT,
						    (u32) item->data,
						    item->u.nbytes, transfer_id,
						    item->flags |
						    CE_SEND_FLAG_GATHER);
			if (ret)
				ath10k_warn("CE send failed for item: %d\n", i);
		}
		/*
		 * Provide valid context pointer for final item.
		 */
		item = &sendlist->item[i];
	if (delta >= 1) {
		ret = ath10k_ce_send_nolock(ce_state, per_transfer_context,
					    (u32) item->data, item->u.nbytes,
					    transfer_id, item->flags);
					    paddr, nbytes,
					    transfer_id, flags);
		if (ret)
			ath10k_warn("CE send failed for last item: %d\n", i);
			ath10k_warn("CE send failed: %d\n", ret);
	}

	spin_unlock_bh(&ar_pci->ce_lock);
@@ -742,11 +710,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
	struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
	u32 ctrl_addr = ce_state->ctrl_addr;
	void *transfer_context;
	u32 buf;
	unsigned int nbytes;
	unsigned int id;
	unsigned int flags;
	int ret;

	ret = ath10k_pci_wake(ar);
@@ -759,38 +722,15 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
	ath10k_ce_engine_int_status_clear(ar, ctrl_addr,
					  HOST_IS_COPY_COMPLETE_MASK);

	if (ce_state->recv_cb) {
		/*
		 * Pop completed recv buffers and call the registered
		 * recv callback for each
		 */
		while (ath10k_ce_completed_recv_next_nolock(ce_state,
							    &transfer_context,
							    &buf, &nbytes,
							    &id, &flags) == 0) {
	spin_unlock_bh(&ar_pci->ce_lock);
			ce_state->recv_cb(ce_state, transfer_context, buf,
					  nbytes, id, flags);
			spin_lock_bh(&ar_pci->ce_lock);
		}
	}

	if (ce_state->send_cb) {
		/*
		 * Pop completed send buffers and call the registered
		 * send callback for each
		 */
		while (ath10k_ce_completed_send_next_nolock(ce_state,
							    &transfer_context,
							    &buf,
							    &nbytes,
							    &id) == 0) {
			spin_unlock_bh(&ar_pci->ce_lock);
			ce_state->send_cb(ce_state, transfer_context,
					  buf, nbytes, id);
	if (ce_state->recv_cb)
		ce_state->recv_cb(ce_state);

	if (ce_state->send_cb)
		ce_state->send_cb(ce_state);

	spin_lock_bh(&ar_pci->ce_lock);
		}
	}

	/*
	 * Misc CE interrupts are not being handled, but still need
@@ -881,11 +821,7 @@ void ath10k_ce_disable_interrupts(struct ath10k *ar)
}

void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state,
				void (*send_cb)(struct ath10k_ce_pipe *ce_state,
						void *transfer_context,
						u32 buffer,
						unsigned int nbytes,
						unsigned int transfer_id),
				void (*send_cb)(struct ath10k_ce_pipe *),
				int disable_interrupts)
{
	struct ath10k *ar = ce_state->ar;
@@ -898,12 +834,7 @@ void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state,
}

void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state,
				void (*recv_cb)(struct ath10k_ce_pipe *ce_state,
						void *transfer_context,
						u32 buffer,
						unsigned int nbytes,
						unsigned int transfer_id,
						unsigned int flags))
				void (*recv_cb)(struct ath10k_ce_pipe *))
{
	struct ath10k *ar = ce_state->ar;
	struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
@@ -1010,6 +941,10 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
	ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0);
	ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries);

	ath10k_dbg(ATH10K_DBG_BOOT,
		   "boot ce src ring id %d entries %d base_addr %p\n",
		   ce_id, nentries, src_ring->base_addr_owner_space);

	return 0;
}

@@ -1091,6 +1026,10 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
	ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0);
	ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries);

	ath10k_dbg(ATH10K_DBG_BOOT,
		   "boot ce dest ring id %d entries %d base_addr %p\n",
		   ce_id, nentries, dest_ring->base_addr_owner_space);

	return 0;
}

+8 −62
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@

/* Descriptor rings must be aligned to this boundary */
#define CE_DESC_RING_ALIGN	8
#define CE_SENDLIST_ITEMS_MAX	12
#define CE_SEND_FLAG_GATHER	0x00010000

/*
@@ -116,41 +115,14 @@ struct ath10k_ce_pipe {

	u32 ctrl_addr;

	void (*send_cb) (struct ath10k_ce_pipe *ce_state,
			 void *per_transfer_send_context,
			 u32 buffer,
			 unsigned int nbytes,
			 unsigned int transfer_id);
	void (*recv_cb) (struct ath10k_ce_pipe *ce_state,
			 void *per_transfer_recv_context,
			 u32 buffer,
			 unsigned int nbytes,
			 unsigned int transfer_id,
			 unsigned int flags);
	void (*send_cb)(struct ath10k_ce_pipe *);
	void (*recv_cb)(struct ath10k_ce_pipe *);

	unsigned int src_sz_max;
	struct ath10k_ce_ring *src_ring;
	struct ath10k_ce_ring *dest_ring;
};

struct ce_sendlist_item {
	/* e.g. buffer or desc list */
	dma_addr_t data;
	union {
		/* simple buffer */
		unsigned int nbytes;
		/* Rx descriptor list */
		unsigned int ndesc;
	} u;
	/* externally-specified flags; OR-ed with internal flags */
	u32 flags;
};

struct ce_sendlist {
	unsigned int num_items;
	struct ce_sendlist_item item[CE_SENDLIST_ITEMS_MAX];
};

/* Copy Engine settable attributes */
struct ce_attr;

@@ -181,20 +153,9 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state,
		   unsigned int flags);

void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state,
				void (*send_cb)(struct ath10k_ce_pipe *ce_state,
						void *transfer_context,
						u32 buffer,
						unsigned int nbytes,
						unsigned int transfer_id),
				void (*send_cb)(struct ath10k_ce_pipe *),
				int disable_interrupts);

/* Append a simple buffer (address/length) to a sendlist. */
void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist,
				u32 buffer,
				unsigned int nbytes,
				/* OR-ed with internal flags */
				u32 flags);

/*
 * Queue a "sendlist" of buffers to be sent using gather to a single
 * anonymous destination buffer
@@ -206,10 +167,10 @@ void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist,
 * Implemenation note: Pushes multiple buffers with Gather to Source ring.
 */
int ath10k_ce_sendlist_send(struct ath10k_ce_pipe *ce_state,
			    void *per_transfer_send_context,
			    struct ce_sendlist *sendlist,
			    /* 14 bits */
			    unsigned int transfer_id);
			    void *per_transfer_context,
			    unsigned int transfer_id,
			    u32 paddr, unsigned int nbytes,
			    u32 flags);

/*==================Recv=======================*/

@@ -228,12 +189,7 @@ int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state,
			       u32 buffer);

void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state,
				void (*recv_cb)(struct ath10k_ce_pipe *ce_state,
						void *transfer_context,
						u32 buffer,
						unsigned int nbytes,
						unsigned int transfer_id,
						unsigned int flags));
				void (*recv_cb)(struct ath10k_ce_pipe *));

/* recv flags */
/* Data is byte-swapped */
@@ -325,16 +281,6 @@ struct ce_attr {
	unsigned int dest_nentries;
};

/*
 * When using sendlist_send to transfer multiple buffer fragments, the
 * transfer context of each fragment, except last one, will be filled
 * with CE_SENDLIST_ITEM_CTXT. ce_completed_send will return success for
 * each fragment done with send and the transfer context would be
 * CE_SENDLIST_ITEM_CTXT. Upper layer could use this to identify the
 * status of a send completion.
 */
#define CE_SENDLIST_ITEM_CTXT	((void *)0xcecebeef)

#define SR_BA_ADDRESS		0x0000
#define SR_SIZE_ADDRESS		0x0004
#define DR_BA_ADDRESS		0x0008
+20 −4
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {

static void ath10k_send_suspend_complete(struct ath10k *ar)
{
	ath10k_dbg(ATH10K_DBG_CORE, "%s\n", __func__);
	ath10k_dbg(ATH10K_DBG_BOOT, "boot suspend complete\n");

	ar->is_target_paused = true;
	wake_up(&ar->event_queue);
@@ -101,7 +101,7 @@ static int ath10k_init_connect_htc(struct ath10k *ar)
		goto timeout;
	}

	ath10k_dbg(ATH10K_DBG_CORE, "core wmi ready\n");
	ath10k_dbg(ATH10K_DBG_BOOT, "boot wmi ready\n");
	return 0;

timeout:
@@ -203,8 +203,8 @@ static int ath10k_push_board_ext_data(struct ath10k *ar,
		return ret;
	}

	ath10k_dbg(ATH10K_DBG_CORE,
		   "ath10k: Board extended Data download addr: 0x%x\n",
	ath10k_dbg(ATH10K_DBG_BOOT,
		   "boot push board extended data addr 0x%x\n",
		   board_ext_data_addr);

	if (board_ext_data_addr == 0)
@@ -435,6 +435,13 @@ static int ath10k_init_uart(struct ath10k *ar)
		return ret;
	}

	/* Set the UART baud rate to 19200. */
	ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200);
	if (ret) {
		ath10k_warn("could not set the baud rate (%d)\n", ret);
		return ret;
	}

	ath10k_info("UART prints enabled\n");
	return 0;
}
@@ -630,6 +637,10 @@ int ath10k_core_start(struct ath10k *ar)
	if (status)
		goto err_disconnect_htc;

	status = ath10k_debug_start(ar);
	if (status)
		goto err_disconnect_htc;

	ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;

	return 0;
@@ -647,6 +658,7 @@ EXPORT_SYMBOL(ath10k_core_start);

void ath10k_core_stop(struct ath10k *ar)
{
	ath10k_debug_stop(ar);
	ath10k_htc_stop(&ar->htc);
	ath10k_htt_detach(&ar->htt);
	ath10k_wmi_detach(ar);
@@ -710,6 +722,9 @@ static int ath10k_core_check_chip_id(struct ath10k *ar)
{
	u32 hw_revision = MS(ar->chip_id, SOC_CHIP_ID_REV);

	ath10k_dbg(ATH10K_DBG_BOOT, "boot chip_id 0x%08x hw_revision 0x%x\n",
		   ar->chip_id, hw_revision);

	/* Check that we are not using hw1.0 (some of them have same pci id
	 * as hw2.0) before doing anything else as ath10k crashes horribly
	 * due to missing hw1.0 workarounds. */
@@ -777,6 +792,7 @@ void ath10k_core_unregister(struct ath10k *ar)
	 * Otherwise we will fail to submit commands to FW and mac80211 will be
	 * unhappy about callback failures. */
	ath10k_mac_unregister(ar);

	ath10k_core_free_firmware_files(ar);
}
EXPORT_SYMBOL(ath10k_core_unregister);
+8 −14
Original line number Diff line number Diff line
@@ -52,18 +52,12 @@ struct ath10k_skb_cb {

	struct {
		u8 vdev_id;
		u16 msdu_id;
		u8 tid;
		bool is_offchan;
		bool is_conf;
		bool discard;
		bool no_ack;
		u8 refcount;
		struct sk_buff *txfrag;
		struct sk_buff *msdu;
	} __packed htt;

	/* 4 bytes left on 64bit arch */
		u8 frag_len;
		u8 pad_len;
	} __packed htt;
} __packed;

static inline struct ath10k_skb_cb *ATH10K_SKB_CB(struct sk_buff *skb)
@@ -112,11 +106,7 @@ struct ath10k_wmi {
	enum ath10k_htc_ep_id eid;
	struct completion service_ready;
	struct completion unified_ready;
	atomic_t pending_tx_count;
	wait_queue_head_t wq;

	struct sk_buff_head wmi_event_list;
	struct work_struct wmi_event_work;
	wait_queue_head_t tx_credits_wq;
};

struct ath10k_peer_stat {
@@ -203,6 +193,7 @@ struct ath10k_vif {
	enum wmi_vdev_subtype vdev_subtype;
	u32 beacon_interval;
	u32 dtim_period;
	struct sk_buff *beacon;

	struct ath10k *ar;
	struct ieee80211_vif *vif;
@@ -246,6 +237,9 @@ struct ath10k_debug {
	u32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE];

	struct completion event_stats_compl;

	unsigned long htt_stats_mask;
	struct delayed_work htt_stats_dwork;
};

enum ath10k_state {
Loading