⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmd.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 4 页
字号:
 */int libertas_allocate_cmd_buffer(wlan_private * priv){	int ret = 0;	u32 ulbufsize;	u32 i;	struct cmd_ctrl_node *tempcmd_array;	u8 *ptempvirtualaddr;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_HOST);	/* Allocate and initialize cmdCtrlNode */	ulbufsize = sizeof(struct cmd_ctrl_node) * MRVDRV_NUM_OF_CMD_BUFFER;	if (!(tempcmd_array = kzalloc(ulbufsize, GFP_KERNEL))) {		lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n");		ret = -1;		goto done;	}	adapter->cmd_array = tempcmd_array;	/* Allocate and initialize command buffers */	ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;	for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {		if (!(ptempvirtualaddr = kzalloc(ulbufsize, GFP_KERNEL))) {			lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");			ret = -1;			goto done;		}		/* Update command buffer virtual */		tempcmd_array[i].bufvirtualaddr = ptempvirtualaddr;	}	for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {		init_waitqueue_head(&tempcmd_array[i].cmdwait_q);		libertas_cleanup_and_insert_cmd(priv, &tempcmd_array[i]);	}	ret = 0;done:	lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);	return ret;}/** *  @brief This function frees the command buffer. * *  @param priv		A pointer to wlan_private structure *  @return 		0 or -1 */int libertas_free_cmd_buffer(wlan_private * priv){	u32 ulbufsize; /* Someone needs to die for this. Slowly and painfully */	unsigned int i;	struct cmd_ctrl_node *tempcmd_array;	wlan_adapter *adapter = priv->adapter;	lbs_deb_enter(LBS_DEB_HOST);	/* need to check if cmd array is allocated or not */	if (adapter->cmd_array == NULL) {		lbs_deb_host("FREE_CMD_BUF: cmd_array is NULL\n");		goto done;	}	tempcmd_array = adapter->cmd_array;	/* Release shared memory buffers */	ulbufsize = MRVDRV_SIZE_OF_CMD_BUFFER;	for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) {		if (tempcmd_array[i].bufvirtualaddr) {			kfree(tempcmd_array[i].bufvirtualaddr);			tempcmd_array[i].bufvirtualaddr = NULL;		}	}	/* Release cmd_ctrl_node */	if (adapter->cmd_array) {		kfree(adapter->cmd_array);		adapter->cmd_array = NULL;	}done:	lbs_deb_leave(LBS_DEB_HOST);	return 0;}/** *  @brief This function gets a free command node if available in *  command free queue. * *  @param priv		A pointer to wlan_private structure *  @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL */struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv){	struct cmd_ctrl_node *tempnode;	wlan_adapter *adapter = priv->adapter;	unsigned long flags;	lbs_deb_enter(LBS_DEB_HOST);	if (!adapter)		return NULL;	spin_lock_irqsave(&adapter->driver_lock, flags);	if (!list_empty(&adapter->cmdfreeq)) {		tempnode = (struct cmd_ctrl_node *)adapter->cmdfreeq.next;		list_del((struct list_head *)tempnode);	} else {		lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");		tempnode = NULL;	}	spin_unlock_irqrestore(&adapter->driver_lock, flags);	if (tempnode)		cleanup_cmdnode(tempnode);	lbs_deb_leave(LBS_DEB_HOST);	return tempnode;}/** *  @brief This function cleans command node. * *  @param ptempnode	A pointer to cmdCtrlNode structure *  @return 		n/a */static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode){	lbs_deb_enter(LBS_DEB_HOST);	if (!ptempnode)		return;	ptempnode->cmdwaitqwoken = 1;	wake_up_interruptible(&ptempnode->cmdwait_q);	ptempnode->status = 0;	ptempnode->cmd_oid = (u32) 0;	ptempnode->wait_option = 0;	ptempnode->pdata_buf = NULL;	if (ptempnode->bufvirtualaddr != NULL)		memset(ptempnode->bufvirtualaddr, 0, MRVDRV_SIZE_OF_CMD_BUFFER);	lbs_deb_leave(LBS_DEB_HOST);}/** *  @brief This function initializes the command node. * *  @param priv		A pointer to wlan_private structure *  @param ptempnode	A pointer to cmd_ctrl_node structure *  @param cmd_oid	cmd oid: treated as sub command *  @param wait_option	wait option: wait response or not *  @param pdata_buf	A pointer to informaion buffer *  @return 		0 or -1 */void libertas_set_cmd_ctrl_node(wlan_private * priv,		    struct cmd_ctrl_node *ptempnode,		    u32 cmd_oid, u16 wait_option, void *pdata_buf){	lbs_deb_enter(LBS_DEB_HOST);	if (!ptempnode)		return;	ptempnode->cmd_oid = cmd_oid;	ptempnode->wait_option = wait_option;	ptempnode->pdata_buf = pdata_buf;	lbs_deb_leave(LBS_DEB_HOST);}/** *  @brief This function executes next command in command *  pending queue. It will put fimware back to PS mode *  if applicable. * *  @param priv     A pointer to wlan_private structure *  @return 	   0 or -1 */int libertas_execute_next_command(wlan_private * priv){	wlan_adapter *adapter = priv->adapter;	struct cmd_ctrl_node *cmdnode = NULL;	struct cmd_ds_command *cmdptr;	unsigned long flags;	int ret = 0;	// Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the	// only caller to us is libertas_thread() and we get even when a	// data packet is received	lbs_deb_enter(LBS_DEB_THREAD);	spin_lock_irqsave(&adapter->driver_lock, flags);	if (adapter->cur_cmd) {		lbs_pr_alert( "EXEC_NEXT_CMD: already processing command!\n");		spin_unlock_irqrestore(&adapter->driver_lock, flags);		ret = -1;		goto done;	}	if (!list_empty(&adapter->cmdpendingq)) {		cmdnode = (struct cmd_ctrl_node *)		    adapter->cmdpendingq.next;	}	spin_unlock_irqrestore(&adapter->driver_lock, flags);	if (cmdnode) {		cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;		if (is_command_allowed_in_ps(cmdptr->command)) {			if ((adapter->psstate == PS_STATE_SLEEP) ||			    (adapter->psstate == PS_STATE_PRE_SLEEP)) {				lbs_deb_host(				       "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n",				       le16_to_cpu(cmdptr->command),				       adapter->psstate);				ret = -1;				goto done;			}			lbs_deb_host("EXEC_NEXT_CMD: OK to send command "			       "0x%04x in psstate %d\n",				    le16_to_cpu(cmdptr->command),				    adapter->psstate);		} else if (adapter->psstate != PS_STATE_FULL_POWER) {			/*			 * 1. Non-PS command:			 * Queue it. set needtowakeup to TRUE if current state			 * is SLEEP, otherwise call libertas_ps_wakeup to send Exit_PS.			 * 2. PS command but not Exit_PS:			 * Ignore it.			 * 3. PS command Exit_PS:			 * Set needtowakeup to TRUE if current state is SLEEP,			 * otherwise send this command down to firmware			 * immediately.			 */			if (cmdptr->command !=			    cpu_to_le16(CMD_802_11_PS_MODE)) {				/*  Prepare to send Exit PS,				 *  this non PS command will be sent later */				if ((adapter->psstate == PS_STATE_SLEEP)				    || (adapter->psstate == PS_STATE_PRE_SLEEP)				    ) {					/* w/ new scheme, it will not reach here.					   since it is blocked in main_thread. */					adapter->needtowakeup = 1;				} else					libertas_ps_wakeup(priv, 0);				ret = 0;				goto done;			} else {				/*				 * PS command. Ignore it if it is not Exit_PS.				 * otherwise send it down immediately.				 */				struct cmd_ds_802_11_ps_mode *psm =				    &cmdptr->params.psmode;				lbs_deb_host(				       "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",				       psm->action);				if (psm->action !=				    cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {					lbs_deb_host(					       "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");					list_del((struct list_head *)cmdnode);					libertas_cleanup_and_insert_cmd(priv, cmdnode);					ret = 0;					goto done;				}				if ((adapter->psstate == PS_STATE_SLEEP) ||				    (adapter->psstate == PS_STATE_PRE_SLEEP)) {					lbs_deb_host(					       "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");					list_del((struct list_head *)cmdnode);					libertas_cleanup_and_insert_cmd(priv, cmdnode);					adapter->needtowakeup = 1;					ret = 0;					goto done;				}				lbs_deb_host(				       "EXEC_NEXT_CMD: sending EXIT_PS\n");			}		}		list_del((struct list_head *)cmdnode);		lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",			    le16_to_cpu(cmdptr->command));		DownloadcommandToStation(priv, cmdnode);	} else {		/*		 * check if in power save mode, if yes, put the device back		 * to PS mode		 */		if ((adapter->psmode != WLAN802_11POWERMODECAM) &&		    (adapter->psstate == PS_STATE_FULL_POWER) &&		    (adapter->connect_status == LIBERTAS_CONNECTED)) {			if (adapter->secinfo.WPAenabled ||			    adapter->secinfo.WPA2enabled) {				/* check for valid WPA group keys */				if (adapter->wpa_mcast_key.len ||				    adapter->wpa_unicast_key.len) {					lbs_deb_host(					       "EXEC_NEXT_CMD: WPA enabled and GTK_SET"					       " go back to PS_SLEEP");					libertas_ps_sleep(priv, 0);				}			} else {				lbs_deb_host(				       "EXEC_NEXT_CMD: cmdpendingq empty, "				       "go back to PS_SLEEP");				libertas_ps_sleep(priv, 0);			}		}	}	ret = 0;done:	lbs_deb_leave(LBS_DEB_THREAD);	return ret;}void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str){	union iwreq_data iwrq;	u8 buf[50];	lbs_deb_enter(LBS_DEB_WEXT);	memset(&iwrq, 0, sizeof(union iwreq_data));	memset(buf, 0, sizeof(buf));	snprintf(buf, sizeof(buf) - 1, "%s", str);	iwrq.data.length = strlen(buf) + 1 + IW_EV_LCP_LEN;	/* Send Event to upper layer */	lbs_deb_wext("event indication string %s\n", (char *)buf);	lbs_deb_wext("event indication length %d\n", iwrq.data.length);	lbs_deb_wext("sending wireless event IWEVCUSTOM for %s\n", str);	wireless_send_event(priv->dev, IWEVCUSTOM, &iwrq, buf);	lbs_deb_leave(LBS_DEB_WEXT);}static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size){	unsigned long flags;	wlan_adapter *adapter = priv->adapter;	int ret = 0;	lbs_deb_enter(LBS_DEB_HOST);	lbs_deb_host("SEND_SLEEPC_CMD: before download, cmd size %d\n",	       size);	lbs_deb_hex(LBS_DEB_HOST, "sleep confirm command", cmdptr, size);	ret = priv->hw_host_to_card(priv, MVMS_CMD, cmdptr, size);	priv->dnld_sent = DNLD_RES_RECEIVED;	spin_lock_irqsave(&adapter->driver_lock, flags);	if (adapter->intcounter || adapter->currenttxskb)		lbs_deb_host("SEND_SLEEPC_CMD: intcounter %d, currenttxskb %p\n",		       adapter->intcounter, adapter->currenttxskb);	spin_unlock_irqrestore(&adapter->driver_lock, flags);	if (ret) {		lbs_pr_alert(		       "SEND_SLEEPC_CMD: Host to Card failed for Confirm Sleep\n");	} else {		spin_lock_irqsave(&adapter->driver_lock, flags);		if (!adapter->intcounter) {			adapter->psstate = PS_STATE_SLEEP;		} else {			lbs_deb_host("SEND_SLEEPC_CMD: after sent, intcounter %d\n",			       adapter->intcounter);		}		spin_unlock_irqrestore(&adapter->driver_lock, flags);		lbs_deb_host("SEND_SLEEPC_CMD: sent confirm sleep\n");	}	lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);	return ret;}void libertas_ps_sleep(wlan_private * priv, int wait_option){	lbs_deb_enter(LBS_DEB_HOST);	/*	 * PS is currently supported only in Infrastructure mode	 * Remove this check if it is to be supported in IBSS mode also	 */	libertas_prepare_and_send_command(priv, CMD_802_11_PS_MODE,			      CMD_SUBCMD_ENTER_PS, wait_option, 0, NULL);	lbs_deb_leave(LBS_DEB_HOST);}/** *  @brief This function sends Exit_PS command to firmware. * *  @param priv    	A pointer to wlan_private structure *  @param wait_option	wait response or not *  @return 	   	n/a */void libertas_ps_wakeup(wlan_private * priv, int wait_option){	__le32 Localpsmode;	lbs_deb_enter(LBS_DEB_HOST);	Localpsmode = cpu_to_le32(WLAN802_11POWERMODECAM);	libertas_prepare_and_send_command(priv, CMD_802_11_PS_MODE,			      CMD_SUBCMD_EXIT_PS,			      wait_option, 0, &Localpsmode);	lbs_deb_leave(LBS_DEB_HOST);}/** *  @brief This function checks condition and prepares to *  send sleep confirm command to firmware if ok. * *  @param priv    	A pointer to wlan_private structure *  @param psmode  	Power Saving mode *  @return 	   	n/a */void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode){	unsigned long flags =0;	wlan_adapter *adapter = priv->adapter;	u8 allowed = 1;	lbs_deb_enter(LBS_DEB_HOST);	if (priv->dnld_sent) {		allowed = 0;		lbs_deb_host("dnld_sent was set");	}	spin_lock_irqsave(&adapter->driver_lock, flags);	if (adapter->cur_cmd) {		allowed = 0;		lbs_deb_host("cur_cmd was set");	}	if (adapter->intcounter > 0) {		allowed = 0;		lbs_deb_host("intcounter %d", adapter->intcounter);	}	spin_unlock_irqrestore(&adapter->driver_lock, flags);	if (allowed) {		lbs_deb_host("sending libertas_ps_confirm_sleep\n");		sendconfirmsleep(priv, (u8 *) & adapter->libertas_ps_confirm_sleep,				 sizeof(struct PS_CMD_ConfirmSleep));	} else {		lbs_deb_host("sleep confirm has been delayed\n");	}	lbs_deb_leave(LBS_DEB_HOST);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -