brintos

brintos / linux-shallow public Read only

0
0
Text · 27.4 KiB · 3b51b7f Raw
1131 lines · c
1// SPDX-License-Identifier: ISC2/*3 * Copyright (c) 2007-2011 Atheros Communications Inc.4 * Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc.5 * Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>6 */7 8#include <linux/module.h>9#include <linux/usb.h>10 11#include "debug.h"12#include "core.h"13#include "bmi.h"14#include "hif.h"15#include "htc.h"16#include "usb.h"17 18static void ath10k_usb_post_recv_transfers(struct ath10k *ar,19					   struct ath10k_usb_pipe *recv_pipe);20 21/* inlined helper functions */22 23static inline enum ath10k_htc_ep_id24eid_from_htc_hdr(struct ath10k_htc_hdr *htc_hdr)25{26	return (enum ath10k_htc_ep_id)htc_hdr->eid;27}28 29static inline bool is_trailer_only_msg(struct ath10k_htc_hdr *htc_hdr)30{31	return __le16_to_cpu(htc_hdr->len) == htc_hdr->trailer_len;32}33 34/* pipe/urb operations */35static struct ath10k_urb_context *36ath10k_usb_alloc_urb_from_pipe(struct ath10k_usb_pipe *pipe)37{38	struct ath10k_urb_context *urb_context = NULL;39	unsigned long flags;40 41	/* bail if this pipe is not initialized */42	if (!pipe->ar_usb)43		return NULL;44 45	spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags);46	if (!list_empty(&pipe->urb_list_head)) {47		urb_context = list_first_entry(&pipe->urb_list_head,48					       struct ath10k_urb_context, link);49		list_del(&urb_context->link);50		pipe->urb_cnt--;51	}52	spin_unlock_irqrestore(&pipe->ar_usb->cs_lock, flags);53 54	return urb_context;55}56 57static void ath10k_usb_free_urb_to_pipe(struct ath10k_usb_pipe *pipe,58					struct ath10k_urb_context *urb_context)59{60	unsigned long flags;61 62	/* bail if this pipe is not initialized */63	if (!pipe->ar_usb)64		return;65 66	spin_lock_irqsave(&pipe->ar_usb->cs_lock, flags);67 68	pipe->urb_cnt++;69	list_add(&urb_context->link, &pipe->urb_list_head);70 71	spin_unlock_irqrestore(&pipe->ar_usb->cs_lock, flags);72}73 74static void ath10k_usb_cleanup_recv_urb(struct ath10k_urb_context *urb_context)75{76	dev_kfree_skb(urb_context->skb);77	urb_context->skb = NULL;78 79	ath10k_usb_free_urb_to_pipe(urb_context->pipe, urb_context);80}81 82static void ath10k_usb_free_pipe_resources(struct ath10k *ar,83					   struct ath10k_usb_pipe *pipe)84{85	struct ath10k_urb_context *urb_context;86 87	if (!pipe->ar_usb) {88		/* nothing allocated for this pipe */89		return;90	}91 92	ath10k_dbg(ar, ATH10K_DBG_USB,93		   "usb free resources lpipe %d hpipe 0x%x urbs %d avail %d\n",94		   pipe->logical_pipe_num, pipe->usb_pipe_handle,95		   pipe->urb_alloc, pipe->urb_cnt);96 97	if (pipe->urb_alloc != pipe->urb_cnt) {98		ath10k_dbg(ar, ATH10K_DBG_USB,99			   "usb urb leak lpipe %d hpipe 0x%x urbs %d avail %d\n",100			   pipe->logical_pipe_num, pipe->usb_pipe_handle,101			   pipe->urb_alloc, pipe->urb_cnt);102	}103 104	for (;;) {105		urb_context = ath10k_usb_alloc_urb_from_pipe(pipe);106 107		if (!urb_context)108			break;109 110		kfree(urb_context);111	}112}113 114static void ath10k_usb_cleanup_pipe_resources(struct ath10k *ar)115{116	struct ath10k_usb *ar_usb = ath10k_usb_priv(ar);117	int i;118 119	for (i = 0; i < ATH10K_USB_PIPE_MAX; i++)120		ath10k_usb_free_pipe_resources(ar, &ar_usb->pipes[i]);121}122 123/* hif usb rx/tx completion functions */124 125static void ath10k_usb_recv_complete(struct urb *urb)126{127	struct ath10k_urb_context *urb_context = urb->context;128	struct ath10k_usb_pipe *pipe = urb_context->pipe;129	struct ath10k *ar = pipe->ar_usb->ar;130	struct sk_buff *skb;131	int status = 0;132 133	ath10k_dbg(ar, ATH10K_DBG_USB_BULK,134		   "usb recv pipe %d stat %d len %d urb 0x%pK\n",135		   pipe->logical_pipe_num, urb->status, urb->actual_length,136		   urb);137 138	if (urb->status != 0) {139		status = -EIO;140		switch (urb->status) {141		case -ECONNRESET:142		case -ENOENT:143		case -ESHUTDOWN:144			/* no need to spew these errors when device145			 * removed or urb killed due to driver shutdown146			 */147			status = -ECANCELED;148			break;149		default:150			ath10k_dbg(ar, ATH10K_DBG_USB_BULK,151				   "usb recv pipe %d ep 0x%2.2x failed: %d\n",152				   pipe->logical_pipe_num,153				   pipe->ep_address, urb->status);154			break;155		}156		goto cleanup_recv_urb;157	}158 159	if (urb->actual_length == 0)160		goto cleanup_recv_urb;161 162	skb = urb_context->skb;163 164	/* we are going to pass it up */165	urb_context->skb = NULL;166	skb_put(skb, urb->actual_length);167 168	/* note: queue implements a lock */169	skb_queue_tail(&pipe->io_comp_queue, skb);170	schedule_work(&pipe->io_complete_work);171 172cleanup_recv_urb:173	ath10k_usb_cleanup_recv_urb(urb_context);174 175	if (status == 0 &&176	    pipe->urb_cnt >= pipe->urb_cnt_thresh) {177		/* our free urbs are piling up, post more transfers */178		ath10k_usb_post_recv_transfers(ar, pipe);179	}180}181 182static void ath10k_usb_transmit_complete(struct urb *urb)183{184	struct ath10k_urb_context *urb_context = urb->context;185	struct ath10k_usb_pipe *pipe = urb_context->pipe;186	struct ath10k *ar = pipe->ar_usb->ar;187	struct sk_buff *skb;188 189	if (urb->status != 0) {190		ath10k_dbg(ar, ATH10K_DBG_USB_BULK,191			   "pipe: %d, failed:%d\n",192			   pipe->logical_pipe_num, urb->status);193	}194 195	skb = urb_context->skb;196	urb_context->skb = NULL;197	ath10k_usb_free_urb_to_pipe(urb_context->pipe, urb_context);198 199	/* note: queue implements a lock */200	skb_queue_tail(&pipe->io_comp_queue, skb);201	schedule_work(&pipe->io_complete_work);202}203 204/* pipe operations */205static void ath10k_usb_post_recv_transfers(struct ath10k *ar,206					   struct ath10k_usb_pipe *recv_pipe)207{208	struct ath10k_urb_context *urb_context;209	struct urb *urb;210	int usb_status;211 212	for (;;) {213		urb_context = ath10k_usb_alloc_urb_from_pipe(recv_pipe);214		if (!urb_context)215			break;216 217		urb_context->skb = dev_alloc_skb(ATH10K_USB_RX_BUFFER_SIZE);218		if (!urb_context->skb)219			goto err;220 221		urb = usb_alloc_urb(0, GFP_ATOMIC);222		if (!urb)223			goto err;224 225		usb_fill_bulk_urb(urb,226				  recv_pipe->ar_usb->udev,227				  recv_pipe->usb_pipe_handle,228				  urb_context->skb->data,229				  ATH10K_USB_RX_BUFFER_SIZE,230				  ath10k_usb_recv_complete, urb_context);231 232		ath10k_dbg(ar, ATH10K_DBG_USB_BULK,233			   "usb bulk recv submit %d 0x%x ep 0x%2.2x len %d buf 0x%pK\n",234			   recv_pipe->logical_pipe_num,235			   recv_pipe->usb_pipe_handle, recv_pipe->ep_address,236			   ATH10K_USB_RX_BUFFER_SIZE, urb_context->skb);237 238		usb_anchor_urb(urb, &recv_pipe->urb_submitted);239		usb_status = usb_submit_urb(urb, GFP_ATOMIC);240 241		if (usb_status) {242			ath10k_dbg(ar, ATH10K_DBG_USB_BULK,243				   "usb bulk recv failed: %d\n",244				   usb_status);245			usb_unanchor_urb(urb);246			usb_free_urb(urb);247			goto err;248		}249		usb_free_urb(urb);250	}251 252	return;253 254err:255	ath10k_usb_cleanup_recv_urb(urb_context);256}257 258static void ath10k_usb_flush_all(struct ath10k *ar)259{260	struct ath10k_usb *ar_usb = ath10k_usb_priv(ar);261	int i;262 263	for (i = 0; i < ATH10K_USB_PIPE_MAX; i++) {264		if (ar_usb->pipes[i].ar_usb) {265			usb_kill_anchored_urbs(&ar_usb->pipes[i].urb_submitted);266			cancel_work_sync(&ar_usb->pipes[i].io_complete_work);267		}268	}269}270 271static void ath10k_usb_start_recv_pipes(struct ath10k *ar)272{273	struct ath10k_usb *ar_usb = ath10k_usb_priv(ar);274 275	ar_usb->pipes[ATH10K_USB_PIPE_RX_DATA].urb_cnt_thresh = 1;276 277	ath10k_usb_post_recv_transfers(ar,278				       &ar_usb->pipes[ATH10K_USB_PIPE_RX_DATA]);279}280 281static void ath10k_usb_tx_complete(struct ath10k *ar, struct sk_buff *skb)282{283	struct ath10k_htc_hdr *htc_hdr;284	struct ath10k_htc_ep *ep;285 286	htc_hdr = (struct ath10k_htc_hdr *)skb->data;287	ep = &ar->htc.endpoint[htc_hdr->eid];288	ath10k_htc_notify_tx_completion(ep, skb);289	/* The TX complete handler now owns the skb... */290}291 292static void ath10k_usb_rx_complete(struct ath10k *ar, struct sk_buff *skb)293{294	struct ath10k_htc *htc = &ar->htc;295	struct ath10k_htc_hdr *htc_hdr;296	enum ath10k_htc_ep_id eid;297	struct ath10k_htc_ep *ep;298	u16 payload_len;299	u8 *trailer;300	int ret;301 302	htc_hdr = (struct ath10k_htc_hdr *)skb->data;303	eid = eid_from_htc_hdr(htc_hdr);304	ep = &ar->htc.endpoint[eid];305 306	if (ep->service_id == 0) {307		ath10k_warn(ar, "ep %d is not connected\n", eid);308		goto out_free_skb;309	}310 311	payload_len = le16_to_cpu(htc_hdr->len);312	if (!payload_len) {313		ath10k_warn(ar, "zero length frame received, firmware crashed?\n");314		goto out_free_skb;315	}316 317	if (payload_len < htc_hdr->trailer_len) {318		ath10k_warn(ar, "malformed frame received, firmware crashed?\n");319		goto out_free_skb;320	}321 322	if (htc_hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT) {323		trailer = skb->data + sizeof(*htc_hdr) + payload_len -324			  htc_hdr->trailer_len;325 326		ret = ath10k_htc_process_trailer(htc,327						 trailer,328						 htc_hdr->trailer_len,329						 eid,330						 NULL,331						 NULL);332		if (ret)333			goto out_free_skb;334 335		if (is_trailer_only_msg(htc_hdr))336			goto out_free_skb;337 338		/* strip off the trailer from the skb since it should not339		 * be passed on to upper layers340		 */341		skb_trim(skb, skb->len - htc_hdr->trailer_len);342	}343 344	skb_pull(skb, sizeof(*htc_hdr));345	ep->ep_ops.ep_rx_complete(ar, skb);346	/* The RX complete handler now owns the skb... */347 348	if (test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) {349		local_bh_disable();350		napi_schedule(&ar->napi);351		local_bh_enable();352	}353 354	return;355 356out_free_skb:357	dev_kfree_skb(skb);358}359 360static void ath10k_usb_io_comp_work(struct work_struct *work)361{362	struct ath10k_usb_pipe *pipe = container_of(work,363						    struct ath10k_usb_pipe,364						    io_complete_work);365	struct ath10k *ar = pipe->ar_usb->ar;366	struct sk_buff *skb;367 368	while ((skb = skb_dequeue(&pipe->io_comp_queue))) {369		if (pipe->flags & ATH10K_USB_PIPE_FLAG_TX)370			ath10k_usb_tx_complete(ar, skb);371		else372			ath10k_usb_rx_complete(ar, skb);373	}374}375 376#define ATH10K_USB_MAX_DIAG_CMD (sizeof(struct ath10k_usb_ctrl_diag_cmd_write))377#define ATH10K_USB_MAX_DIAG_RESP (sizeof(struct ath10k_usb_ctrl_diag_resp_read))378 379static void ath10k_usb_destroy(struct ath10k *ar)380{381	struct ath10k_usb *ar_usb = ath10k_usb_priv(ar);382 383	ath10k_usb_flush_all(ar);384	ath10k_usb_cleanup_pipe_resources(ar);385	usb_set_intfdata(ar_usb->interface, NULL);386 387	kfree(ar_usb->diag_cmd_buffer);388	kfree(ar_usb->diag_resp_buffer);389}390 391static int ath10k_usb_hif_start(struct ath10k *ar)392{393	int i;394	struct ath10k_usb *ar_usb = ath10k_usb_priv(ar);395 396	ath10k_core_napi_enable(ar);397	ath10k_usb_start_recv_pipes(ar);398 399	/* set the TX resource avail threshold for each TX pipe */400	for (i = ATH10K_USB_PIPE_TX_CTRL;401	     i <= ATH10K_USB_PIPE_TX_DATA_HP; i++) {402		ar_usb->pipes[i].urb_cnt_thresh =403		    ar_usb->pipes[i].urb_alloc / 2;404	}405 406	return 0;407}408 409static int ath10k_usb_hif_tx_sg(struct ath10k *ar, u8 pipe_id,410				struct ath10k_hif_sg_item *items, int n_items)411{412	struct ath10k_usb *ar_usb = ath10k_usb_priv(ar);413	struct ath10k_usb_pipe *pipe = &ar_usb->pipes[pipe_id];414	struct ath10k_urb_context *urb_context;415	struct sk_buff *skb;416	struct urb *urb;417	int ret, i;418 419	for (i = 0; i < n_items; i++) {420		urb_context = ath10k_usb_alloc_urb_from_pipe(pipe);421		if (!urb_context) {422			ret = -ENOMEM;423			goto err;424		}425 426		skb = items[i].transfer_context;427		urb_context->skb = skb;428 429		urb = usb_alloc_urb(0, GFP_ATOMIC);430		if (!urb) {431			ret = -ENOMEM;432			goto err_free_urb_to_pipe;433		}434 435		usb_fill_bulk_urb(urb,436				  ar_usb->udev,437				  pipe->usb_pipe_handle,438				  skb->data,439				  skb->len,440				  ath10k_usb_transmit_complete, urb_context);441 442		if (!(skb->len % pipe->max_packet_size)) {443			/* hit a max packet boundary on this pipe */444			urb->transfer_flags |= URB_ZERO_PACKET;445		}446 447		usb_anchor_urb(urb, &pipe->urb_submitted);448		ret = usb_submit_urb(urb, GFP_ATOMIC);449		if (ret) {450			ath10k_dbg(ar, ATH10K_DBG_USB_BULK,451				   "usb bulk transmit failed: %d\n", ret);452			usb_unanchor_urb(urb);453			usb_free_urb(urb);454			ret = -EINVAL;455			goto err_free_urb_to_pipe;456		}457 458		usb_free_urb(urb);459	}460 461	return 0;462 463err_free_urb_to_pipe:464	ath10k_usb_free_urb_to_pipe(urb_context->pipe, urb_context);465err:466	return ret;467}468 469static void ath10k_usb_hif_stop(struct ath10k *ar)470{471	ath10k_usb_flush_all(ar);472	ath10k_core_napi_sync_disable(ar);473}474 475static u16 ath10k_usb_hif_get_free_queue_number(struct ath10k *ar, u8 pipe_id)476{477	struct ath10k_usb *ar_usb = ath10k_usb_priv(ar);478 479	return ar_usb->pipes[pipe_id].urb_cnt;480}481 482static int ath10k_usb_submit_ctrl_out(struct ath10k *ar,483				      u8 req, u16 value, u16 index, void *data,484				      u32 size)485{486	struct ath10k_usb *ar_usb = ath10k_usb_priv(ar);487	u8 *buf = NULL;488	int ret;489 490	if (size > 0) {491		buf = kmemdup(data, size, GFP_KERNEL);492		if (!buf)493			return -ENOMEM;494	}495 496	/* note: if successful returns number of bytes transferred */497	ret = usb_control_msg(ar_usb->udev,498			      usb_sndctrlpipe(ar_usb->udev, 0),499			      req,500			      USB_DIR_OUT | USB_TYPE_VENDOR |501			      USB_RECIP_DEVICE, value, index, buf,502			      size, 1000);503 504	if (ret < 0) {505		ath10k_warn(ar, "Failed to submit usb control message: %d\n",506			    ret);507		kfree(buf);508		return ret;509	}510 511	kfree(buf);512 513	return 0;514}515 516static int ath10k_usb_submit_ctrl_in(struct ath10k *ar,517				     u8 req, u16 value, u16 index, void *data,518				     u32 size)519{520	struct ath10k_usb *ar_usb = ath10k_usb_priv(ar);521	u8 *buf = NULL;522	int ret;523 524	if (size > 0) {525		buf = kmalloc(size, GFP_KERNEL);526		if (!buf)527			return -ENOMEM;528	}529 530	/* note: if successful returns number of bytes transferred */531	ret = usb_control_msg(ar_usb->udev,532			      usb_rcvctrlpipe(ar_usb->udev, 0),533			      req,534			      USB_DIR_IN | USB_TYPE_VENDOR |535			      USB_RECIP_DEVICE, value, index, buf,536			      size, 2000);537 538	if (ret < 0) {539		ath10k_warn(ar, "Failed to read usb control message: %d\n",540			    ret);541		kfree(buf);542		return ret;543	}544 545	memcpy((u8 *)data, buf, size);546 547	kfree(buf);548 549	return 0;550}551 552static int ath10k_usb_ctrl_msg_exchange(struct ath10k *ar,553					u8 req_val, u8 *req_buf, u32 req_len,554					u8 resp_val, u8 *resp_buf,555					u32 *resp_len)556{557	int ret;558 559	/* send command */560	ret = ath10k_usb_submit_ctrl_out(ar, req_val, 0, 0,561					 req_buf, req_len);562	if (ret)563		goto err;564 565	/* get response */566	if (resp_buf) {567		ret = ath10k_usb_submit_ctrl_in(ar, resp_val, 0, 0,568						resp_buf, *resp_len);569		if (ret)570			goto err;571	}572 573	return 0;574err:575	return ret;576}577 578static int ath10k_usb_hif_diag_read(struct ath10k *ar, u32 address, void *buf,579				    size_t buf_len)580{581	struct ath10k_usb *ar_usb = ath10k_usb_priv(ar);582	struct ath10k_usb_ctrl_diag_cmd_read *cmd;583	u32 resp_len;584	int ret;585 586	if (buf_len < sizeof(struct ath10k_usb_ctrl_diag_resp_read))587		return -EINVAL;588 589	cmd = (struct ath10k_usb_ctrl_diag_cmd_read *)ar_usb->diag_cmd_buffer;590	memset(cmd, 0, sizeof(*cmd));591	cmd->cmd = ATH10K_USB_CTRL_DIAG_CC_READ;592	cmd->address = cpu_to_le32(address);593	resp_len = sizeof(struct ath10k_usb_ctrl_diag_resp_read);594 595	ret = ath10k_usb_ctrl_msg_exchange(ar,596					   ATH10K_USB_CONTROL_REQ_DIAG_CMD,597					   (u8 *)cmd,598					   sizeof(*cmd),599					   ATH10K_USB_CONTROL_REQ_DIAG_RESP,600					   ar_usb->diag_resp_buffer, &resp_len);601	if (ret)602		return ret;603 604	if (resp_len != sizeof(struct ath10k_usb_ctrl_diag_resp_read))605		return -EMSGSIZE;606 607	memcpy(buf, ar_usb->diag_resp_buffer,608	       sizeof(struct ath10k_usb_ctrl_diag_resp_read));609 610	return 0;611}612 613static int ath10k_usb_hif_diag_write(struct ath10k *ar, u32 address,614				     const void *data, int nbytes)615{616	struct ath10k_usb *ar_usb = ath10k_usb_priv(ar);617	struct ath10k_usb_ctrl_diag_cmd_write *cmd;618	int ret;619 620	if (nbytes != sizeof(cmd->value))621		return -EINVAL;622 623	cmd = (struct ath10k_usb_ctrl_diag_cmd_write *)ar_usb->diag_cmd_buffer;624	memset(cmd, 0, sizeof(*cmd));625	cmd->cmd = cpu_to_le32(ATH10K_USB_CTRL_DIAG_CC_WRITE);626	cmd->address = cpu_to_le32(address);627	memcpy(&cmd->value, data, nbytes);628 629	ret = ath10k_usb_ctrl_msg_exchange(ar,630					   ATH10K_USB_CONTROL_REQ_DIAG_CMD,631					   (u8 *)cmd,632					   sizeof(*cmd),633					   0, NULL, NULL);634	if (ret)635		return ret;636 637	return 0;638}639 640static int ath10k_usb_bmi_exchange_msg(struct ath10k *ar,641				       void *req, u32 req_len,642				       void *resp, u32 *resp_len)643{644	int ret;645 646	if (req) {647		ret = ath10k_usb_submit_ctrl_out(ar,648						 ATH10K_USB_CONTROL_REQ_SEND_BMI_CMD,649						 0, 0, req, req_len);650		if (ret) {651			ath10k_warn(ar,652				    "unable to send the bmi data to the device: %d\n",653				    ret);654			return ret;655		}656	}657 658	if (resp) {659		ret = ath10k_usb_submit_ctrl_in(ar,660						ATH10K_USB_CONTROL_REQ_RECV_BMI_RESP,661						0, 0, resp, *resp_len);662		if (ret) {663			ath10k_warn(ar,664				    "Unable to read the bmi data from the device: %d\n",665				    ret);666			return ret;667		}668	}669 670	return 0;671}672 673static void ath10k_usb_hif_get_default_pipe(struct ath10k *ar,674					    u8 *ul_pipe, u8 *dl_pipe)675{676	*ul_pipe = ATH10K_USB_PIPE_TX_CTRL;677	*dl_pipe = ATH10K_USB_PIPE_RX_CTRL;678}679 680static int ath10k_usb_hif_map_service_to_pipe(struct ath10k *ar, u16 svc_id,681					      u8 *ul_pipe, u8 *dl_pipe)682{683	switch (svc_id) {684	case ATH10K_HTC_SVC_ID_RSVD_CTRL:685	case ATH10K_HTC_SVC_ID_WMI_CONTROL:686		*ul_pipe = ATH10K_USB_PIPE_TX_CTRL;687		/* due to large control packets, shift to data pipe */688		*dl_pipe = ATH10K_USB_PIPE_RX_DATA;689		break;690	case ATH10K_HTC_SVC_ID_HTT_DATA_MSG:691		*ul_pipe = ATH10K_USB_PIPE_TX_DATA_LP;692		/* Disable rxdata2 directly, it will be enabled693		 * if FW enable rxdata2694		 */695		*dl_pipe = ATH10K_USB_PIPE_RX_DATA;696		break;697	default:698		return -EPERM;699	}700 701	return 0;702}703 704static int ath10k_usb_hif_power_up(struct ath10k *ar,705				   enum ath10k_firmware_mode fw_mode)706{707	return 0;708}709 710static void ath10k_usb_hif_power_down(struct ath10k *ar)711{712	ath10k_usb_flush_all(ar);713}714 715#ifdef CONFIG_PM716 717static int ath10k_usb_hif_suspend(struct ath10k *ar)718{719	return -EOPNOTSUPP;720}721 722static int ath10k_usb_hif_resume(struct ath10k *ar)723{724	return -EOPNOTSUPP;725}726#endif727 728static const struct ath10k_hif_ops ath10k_usb_hif_ops = {729	.tx_sg			= ath10k_usb_hif_tx_sg,730	.diag_read		= ath10k_usb_hif_diag_read,731	.diag_write		= ath10k_usb_hif_diag_write,732	.exchange_bmi_msg	= ath10k_usb_bmi_exchange_msg,733	.start			= ath10k_usb_hif_start,734	.stop			= ath10k_usb_hif_stop,735	.map_service_to_pipe	= ath10k_usb_hif_map_service_to_pipe,736	.get_default_pipe	= ath10k_usb_hif_get_default_pipe,737	.get_free_queue_number	= ath10k_usb_hif_get_free_queue_number,738	.power_up		= ath10k_usb_hif_power_up,739	.power_down		= ath10k_usb_hif_power_down,740#ifdef CONFIG_PM741	.suspend		= ath10k_usb_hif_suspend,742	.resume			= ath10k_usb_hif_resume,743#endif744};745 746static u8 ath10k_usb_get_logical_pipe_num(u8 ep_address, int *urb_count)747{748	u8 pipe_num = ATH10K_USB_PIPE_INVALID;749 750	switch (ep_address) {751	case ATH10K_USB_EP_ADDR_APP_CTRL_IN:752		pipe_num = ATH10K_USB_PIPE_RX_CTRL;753		*urb_count = RX_URB_COUNT;754		break;755	case ATH10K_USB_EP_ADDR_APP_DATA_IN:756		pipe_num = ATH10K_USB_PIPE_RX_DATA;757		*urb_count = RX_URB_COUNT;758		break;759	case ATH10K_USB_EP_ADDR_APP_INT_IN:760		pipe_num = ATH10K_USB_PIPE_RX_INT;761		*urb_count = RX_URB_COUNT;762		break;763	case ATH10K_USB_EP_ADDR_APP_DATA2_IN:764		pipe_num = ATH10K_USB_PIPE_RX_DATA2;765		*urb_count = RX_URB_COUNT;766		break;767	case ATH10K_USB_EP_ADDR_APP_CTRL_OUT:768		pipe_num = ATH10K_USB_PIPE_TX_CTRL;769		*urb_count = TX_URB_COUNT;770		break;771	case ATH10K_USB_EP_ADDR_APP_DATA_LP_OUT:772		pipe_num = ATH10K_USB_PIPE_TX_DATA_LP;773		*urb_count = TX_URB_COUNT;774		break;775	case ATH10K_USB_EP_ADDR_APP_DATA_MP_OUT:776		pipe_num = ATH10K_USB_PIPE_TX_DATA_MP;777		*urb_count = TX_URB_COUNT;778		break;779	case ATH10K_USB_EP_ADDR_APP_DATA_HP_OUT:780		pipe_num = ATH10K_USB_PIPE_TX_DATA_HP;781		*urb_count = TX_URB_COUNT;782		break;783	default:784		/* note: there may be endpoints not currently used */785		break;786	}787 788	return pipe_num;789}790 791static int ath10k_usb_alloc_pipe_resources(struct ath10k *ar,792					   struct ath10k_usb_pipe *pipe,793					   int urb_cnt)794{795	struct ath10k_urb_context *urb_context;796	int i;797 798	INIT_LIST_HEAD(&pipe->urb_list_head);799	init_usb_anchor(&pipe->urb_submitted);800 801	for (i = 0; i < urb_cnt; i++) {802		urb_context = kzalloc(sizeof(*urb_context), GFP_KERNEL);803		if (!urb_context)804			return -ENOMEM;805 806		urb_context->pipe = pipe;807 808		/* we are only allocate the urb contexts here, the actual URB809		 * is allocated from the kernel as needed to do a transaction810		 */811		pipe->urb_alloc++;812		ath10k_usb_free_urb_to_pipe(pipe, urb_context);813	}814 815	ath10k_dbg(ar, ATH10K_DBG_USB,816		   "usb alloc resources lpipe %d hpipe 0x%x urbs %d\n",817		   pipe->logical_pipe_num, pipe->usb_pipe_handle,818		   pipe->urb_alloc);819 820	return 0;821}822 823static int ath10k_usb_setup_pipe_resources(struct ath10k *ar,824					   struct usb_interface *interface)825{826	struct ath10k_usb *ar_usb = ath10k_usb_priv(ar);827	struct usb_host_interface *iface_desc = interface->cur_altsetting;828	struct usb_endpoint_descriptor *endpoint;829	struct ath10k_usb_pipe *pipe;830	int ret, i, urbcount;831	u8 pipe_num;832 833	ath10k_dbg(ar, ATH10K_DBG_USB, "usb setting up pipes using interface\n");834 835	/* walk descriptors and setup pipes */836	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {837		endpoint = &iface_desc->endpoint[i].desc;838 839		if (ATH10K_USB_IS_BULK_EP(endpoint->bmAttributes)) {840			ath10k_dbg(ar, ATH10K_DBG_USB,841				   "usb %s bulk ep 0x%2.2x maxpktsz %d\n",842				   ATH10K_USB_IS_DIR_IN843				   (endpoint->bEndpointAddress) ?844				   "rx" : "tx", endpoint->bEndpointAddress,845				   le16_to_cpu(endpoint->wMaxPacketSize));846		} else if (ATH10K_USB_IS_INT_EP(endpoint->bmAttributes)) {847			ath10k_dbg(ar, ATH10K_DBG_USB,848				   "usb %s int ep 0x%2.2x maxpktsz %d interval %d\n",849				   ATH10K_USB_IS_DIR_IN850				   (endpoint->bEndpointAddress) ?851				   "rx" : "tx", endpoint->bEndpointAddress,852				   le16_to_cpu(endpoint->wMaxPacketSize),853				   endpoint->bInterval);854		} else if (ATH10K_USB_IS_ISOC_EP(endpoint->bmAttributes)) {855			/* TODO for ISO */856			ath10k_dbg(ar, ATH10K_DBG_USB,857				   "usb %s isoc ep 0x%2.2x maxpktsz %d interval %d\n",858				   ATH10K_USB_IS_DIR_IN859				   (endpoint->bEndpointAddress) ?860				   "rx" : "tx", endpoint->bEndpointAddress,861				   le16_to_cpu(endpoint->wMaxPacketSize),862				   endpoint->bInterval);863		}864 865		/* Ignore broken descriptors. */866		if (usb_endpoint_maxp(endpoint) == 0)867			continue;868 869		urbcount = 0;870 871		pipe_num =872		    ath10k_usb_get_logical_pipe_num(endpoint->bEndpointAddress,873						    &urbcount);874		if (pipe_num == ATH10K_USB_PIPE_INVALID)875			continue;876 877		pipe = &ar_usb->pipes[pipe_num];878		if (pipe->ar_usb)879			/* hmmm..pipe was already setup */880			continue;881 882		pipe->ar_usb = ar_usb;883		pipe->logical_pipe_num = pipe_num;884		pipe->ep_address = endpoint->bEndpointAddress;885		pipe->max_packet_size = le16_to_cpu(endpoint->wMaxPacketSize);886 887		if (ATH10K_USB_IS_BULK_EP(endpoint->bmAttributes)) {888			if (ATH10K_USB_IS_DIR_IN(pipe->ep_address)) {889				pipe->usb_pipe_handle =890				    usb_rcvbulkpipe(ar_usb->udev,891						    pipe->ep_address);892			} else {893				pipe->usb_pipe_handle =894				    usb_sndbulkpipe(ar_usb->udev,895						    pipe->ep_address);896			}897		} else if (ATH10K_USB_IS_INT_EP(endpoint->bmAttributes)) {898			if (ATH10K_USB_IS_DIR_IN(pipe->ep_address)) {899				pipe->usb_pipe_handle =900				    usb_rcvintpipe(ar_usb->udev,901						   pipe->ep_address);902			} else {903				pipe->usb_pipe_handle =904				    usb_sndintpipe(ar_usb->udev,905						   pipe->ep_address);906			}907		} else if (ATH10K_USB_IS_ISOC_EP(endpoint->bmAttributes)) {908			/* TODO for ISO */909			if (ATH10K_USB_IS_DIR_IN(pipe->ep_address)) {910				pipe->usb_pipe_handle =911				    usb_rcvisocpipe(ar_usb->udev,912						    pipe->ep_address);913			} else {914				pipe->usb_pipe_handle =915				    usb_sndisocpipe(ar_usb->udev,916						    pipe->ep_address);917			}918		}919 920		pipe->ep_desc = endpoint;921 922		if (!ATH10K_USB_IS_DIR_IN(pipe->ep_address))923			pipe->flags |= ATH10K_USB_PIPE_FLAG_TX;924 925		ret = ath10k_usb_alloc_pipe_resources(ar, pipe, urbcount);926		if (ret)927			return ret;928	}929 930	return 0;931}932 933static int ath10k_usb_create(struct ath10k *ar,934			     struct usb_interface *interface)935{936	struct ath10k_usb *ar_usb = ath10k_usb_priv(ar);937	struct usb_device *dev = interface_to_usbdev(interface);938	struct ath10k_usb_pipe *pipe;939	int ret, i;940 941	usb_set_intfdata(interface, ar_usb);942	spin_lock_init(&ar_usb->cs_lock);943	ar_usb->udev = dev;944	ar_usb->interface = interface;945 946	for (i = 0; i < ATH10K_USB_PIPE_MAX; i++) {947		pipe = &ar_usb->pipes[i];948		INIT_WORK(&pipe->io_complete_work,949			  ath10k_usb_io_comp_work);950		skb_queue_head_init(&pipe->io_comp_queue);951	}952 953	ar_usb->diag_cmd_buffer = kzalloc(ATH10K_USB_MAX_DIAG_CMD, GFP_KERNEL);954	if (!ar_usb->diag_cmd_buffer) {955		ret = -ENOMEM;956		goto err;957	}958 959	ar_usb->diag_resp_buffer = kzalloc(ATH10K_USB_MAX_DIAG_RESP,960					   GFP_KERNEL);961	if (!ar_usb->diag_resp_buffer) {962		ret = -ENOMEM;963		goto err;964	}965 966	ret = ath10k_usb_setup_pipe_resources(ar, interface);967	if (ret)968		goto err;969 970	return 0;971 972err:973	ath10k_usb_destroy(ar);974	return ret;975}976 977static int ath10k_usb_napi_poll(struct napi_struct *ctx, int budget)978{979	struct ath10k *ar = container_of(ctx, struct ath10k, napi);980	int done;981 982	done = ath10k_htt_rx_hl_indication(ar, budget);983	ath10k_dbg(ar, ATH10K_DBG_USB, "napi poll: done: %d, budget:%d\n", done, budget);984 985	if (done < budget)986		napi_complete_done(ctx, done);987 988	return done;989}990 991/* ath10k usb driver registered functions */992static int ath10k_usb_probe(struct usb_interface *interface,993			    const struct usb_device_id *id)994{995	struct ath10k *ar;996	struct ath10k_usb *ar_usb;997	struct usb_device *dev = interface_to_usbdev(interface);998	int ret, vendor_id, product_id;999	enum ath10k_hw_rev hw_rev;1000	struct ath10k_bus_params bus_params = {};1001 1002	/* Assumption: All USB based chipsets (so far) are QCA9377 based.1003	 * If there will be newer chipsets that does not use the hw reg1004	 * setup as defined in qca6174_regs and qca6174_values, this1005	 * assumption is no longer valid and hw_rev must be setup differently1006	 * depending on chipset.1007	 */1008	hw_rev = ATH10K_HW_QCA9377;1009 1010	ar = ath10k_core_create(sizeof(*ar_usb), &dev->dev, ATH10K_BUS_USB,1011				hw_rev, &ath10k_usb_hif_ops);1012	if (!ar) {1013		dev_err(&dev->dev, "failed to allocate core\n");1014		return -ENOMEM;1015	}1016 1017	netif_napi_add(ar->napi_dev, &ar->napi, ath10k_usb_napi_poll);1018 1019	usb_get_dev(dev);1020	vendor_id = le16_to_cpu(dev->descriptor.idVendor);1021	product_id = le16_to_cpu(dev->descriptor.idProduct);1022 1023	ath10k_dbg(ar, ATH10K_DBG_BOOT,1024		   "usb new func vendor 0x%04x product 0x%04x\n",1025		   vendor_id, product_id);1026 1027	ar_usb = ath10k_usb_priv(ar);1028	ret = ath10k_usb_create(ar, interface);1029	if (ret)1030		goto err;1031	ar_usb->ar = ar;1032 1033	ar->dev_id = product_id;1034	ar->id.vendor = vendor_id;1035	ar->id.device = product_id;1036 1037	bus_params.dev_type = ATH10K_DEV_TYPE_HL;1038	/* TODO: don't know yet how to get chip_id with USB */1039	bus_params.chip_id = 0;1040	bus_params.hl_msdu_ids = true;1041	ret = ath10k_core_register(ar, &bus_params);1042	if (ret) {1043		ath10k_warn(ar, "failed to register driver core: %d\n", ret);1044		goto err_usb_destroy;1045	}1046 1047	/* TODO: remove this once USB support is fully implemented */1048	ath10k_warn(ar, "Warning: ath10k USB support is incomplete, don't expect anything to work!\n");1049 1050	return 0;1051 1052err_usb_destroy:1053	ath10k_usb_destroy(ar);1054 1055err:1056	ath10k_core_destroy(ar);1057 1058	usb_put_dev(dev);1059 1060	return ret;1061}1062 1063static void ath10k_usb_remove(struct usb_interface *interface)1064{1065	struct ath10k_usb *ar_usb;1066 1067	ar_usb = usb_get_intfdata(interface);1068	if (!ar_usb)1069		return;1070 1071	ath10k_core_unregister(ar_usb->ar);1072	netif_napi_del(&ar_usb->ar->napi);1073	ath10k_usb_destroy(ar_usb->ar);1074	usb_put_dev(interface_to_usbdev(interface));1075	ath10k_core_destroy(ar_usb->ar);1076}1077 1078#ifdef CONFIG_PM1079 1080static int ath10k_usb_pm_suspend(struct usb_interface *interface,1081				 pm_message_t message)1082{1083	struct ath10k_usb *ar_usb = usb_get_intfdata(interface);1084 1085	ath10k_usb_flush_all(ar_usb->ar);1086	return 0;1087}1088 1089static int ath10k_usb_pm_resume(struct usb_interface *interface)1090{1091	struct ath10k_usb *ar_usb = usb_get_intfdata(interface);1092	struct ath10k *ar = ar_usb->ar;1093 1094	ath10k_usb_post_recv_transfers(ar,1095				       &ar_usb->pipes[ATH10K_USB_PIPE_RX_DATA]);1096 1097	return 0;1098}1099 1100#else1101 1102#define ath10k_usb_pm_suspend NULL1103#define ath10k_usb_pm_resume NULL1104 1105#endif1106 1107/* table of devices that work with this driver */1108static struct usb_device_id ath10k_usb_ids[] = {1109	{USB_DEVICE(0x13b1, 0x0042)}, /* Linksys WUSB6100M */1110	{ /* Terminating entry */ },1111};1112 1113MODULE_DEVICE_TABLE(usb, ath10k_usb_ids);1114 1115static struct usb_driver ath10k_usb_driver = {1116	.name = "ath10k_usb",1117	.probe = ath10k_usb_probe,1118	.suspend = ath10k_usb_pm_suspend,1119	.resume = ath10k_usb_pm_resume,1120	.disconnect = ath10k_usb_remove,1121	.id_table = ath10k_usb_ids,1122	.supports_autosuspend = true,1123	.disable_hub_initiated_lpm = 1,1124};1125 1126module_usb_driver(ath10k_usb_driver);1127 1128MODULE_AUTHOR("Atheros Communications, Inc.");1129MODULE_DESCRIPTION("Driver support for Qualcomm Atheros USB 802.11ac WLAN devices");1130MODULE_LICENSE("Dual BSD/GPL");1131