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

📄 main.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		struct net_device *dev){	wlan_private *priv = dev->priv;	int ret;	lbs_deb_enter(LBS_DEB_MESH);	if(priv->adapter->monitormode != WLAN_MONITOR_OFF) {		netif_stop_queue(dev);		return -EOPNOTSUPP;	}	SET_MESH_FRAME(skb);	ret = libertas_hard_start_xmit(skb, priv->dev);	lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);	return ret;}/** * @brief Mark non-mesh packets and handover them to libertas_hard_start_xmit * */static int libertas_pre_start_xmit(struct sk_buff *skb, struct net_device *dev){	wlan_private *priv = dev->priv;	int ret;	lbs_deb_enter(LBS_DEB_NET);	if(priv->adapter->monitormode != WLAN_MONITOR_OFF) {		netif_stop_queue(dev);		return -EOPNOTSUPP;	}	UNSET_MESH_FRAME(skb);	ret = libertas_hard_start_xmit(skb, dev);	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);	return ret;}static void libertas_tx_timeout(struct net_device *dev){	wlan_private *priv = (wlan_private *) dev->priv;	lbs_deb_enter(LBS_DEB_TX);	lbs_pr_err("tx watch dog timeout\n");	priv->dnld_sent = DNLD_RES_RECEIVED;	dev->trans_start = jiffies;	if (priv->adapter->currenttxskb) {		if (priv->adapter->monitormode != WLAN_MONITOR_OFF) {			/* If we are here, we have not received feedback from			   the previous packet.  Assume TX_FAIL and move on. */			priv->adapter->eventcause = 0x01000000;			libertas_send_tx_feedback(priv);		} else			wake_up_interruptible(&priv->waitq);	} else if (priv->adapter->connect_status == LIBERTAS_CONNECTED) {		netif_wake_queue(priv->dev);		if (priv->mesh_dev)			netif_wake_queue(priv->mesh_dev);	}	lbs_deb_leave(LBS_DEB_TX);}/** *  @brief This function returns the network statistics * *  @param dev     A pointer to wlan_private structure *  @return 	   A pointer to net_device_stats structure */static struct net_device_stats *libertas_get_stats(struct net_device *dev){	wlan_private *priv = (wlan_private *) dev->priv;	return &priv->stats;}static int libertas_set_mac_address(struct net_device *dev, void *addr){	int ret = 0;	wlan_private *priv = (wlan_private *) dev->priv;	wlan_adapter *adapter = priv->adapter;	struct sockaddr *phwaddr = addr;	lbs_deb_enter(LBS_DEB_NET);	/* In case it was called from the mesh device */	dev = priv->dev ;	memset(adapter->current_addr, 0, ETH_ALEN);	/* dev->dev_addr is 8 bytes */	lbs_deb_hex(LBS_DEB_NET, "dev->dev_addr", dev->dev_addr, ETH_ALEN);	lbs_deb_hex(LBS_DEB_NET, "addr", phwaddr->sa_data, ETH_ALEN);	memcpy(adapter->current_addr, phwaddr->sa_data, ETH_ALEN);	ret = libertas_prepare_and_send_command(priv, CMD_802_11_MAC_ADDRESS,				    CMD_ACT_SET,				    CMD_OPTION_WAITFORRSP, 0, NULL);	if (ret) {		lbs_deb_net("set MAC address failed\n");		ret = -1;		goto done;	}	lbs_deb_hex(LBS_DEB_NET, "adapter->macaddr", adapter->current_addr, ETH_ALEN);	memcpy(dev->dev_addr, adapter->current_addr, ETH_ALEN);	if (priv->mesh_dev)		memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);done:	lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret);	return ret;}static int libertas_copy_multicast_address(wlan_adapter * adapter,				     struct net_device *dev){	int i = 0;	struct dev_mc_list *mcptr = dev->mc_list;	for (i = 0; i < dev->mc_count; i++) {		memcpy(&adapter->multicastlist[i], mcptr->dmi_addr, ETH_ALEN);		mcptr = mcptr->next;	}	return i;}static void libertas_set_multicast_list(struct net_device *dev){	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	int oldpacketfilter;	DECLARE_MAC_BUF(mac);	lbs_deb_enter(LBS_DEB_NET);	oldpacketfilter = adapter->currentpacketfilter;	if (dev->flags & IFF_PROMISC) {		lbs_deb_net("enable promiscuous mode\n");		adapter->currentpacketfilter |=		    CMD_ACT_MAC_PROMISCUOUS_ENABLE;		adapter->currentpacketfilter &=		    ~(CMD_ACT_MAC_ALL_MULTICAST_ENABLE |		      CMD_ACT_MAC_MULTICAST_ENABLE);	} else {		/* Multicast */		adapter->currentpacketfilter &=		    ~CMD_ACT_MAC_PROMISCUOUS_ENABLE;		if (dev->flags & IFF_ALLMULTI || dev->mc_count >		    MRVDRV_MAX_MULTICAST_LIST_SIZE) {			lbs_deb_net( "enabling all multicast\n");			adapter->currentpacketfilter |=			    CMD_ACT_MAC_ALL_MULTICAST_ENABLE;			adapter->currentpacketfilter &=			    ~CMD_ACT_MAC_MULTICAST_ENABLE;		} else {			adapter->currentpacketfilter &=			    ~CMD_ACT_MAC_ALL_MULTICAST_ENABLE;			if (!dev->mc_count) {				lbs_deb_net("no multicast addresses, "				       "disabling multicast\n");				adapter->currentpacketfilter &=				    ~CMD_ACT_MAC_MULTICAST_ENABLE;			} else {				int i;				adapter->currentpacketfilter |=				    CMD_ACT_MAC_MULTICAST_ENABLE;				adapter->nr_of_multicastmacaddr =				    libertas_copy_multicast_address(adapter, dev);				lbs_deb_net("multicast addresses: %d\n",				       dev->mc_count);				for (i = 0; i < dev->mc_count; i++) {					lbs_deb_net("Multicast address %d:%s\n",					       i, print_mac(mac,					       adapter->multicastlist[i]));				}				/* send multicast addresses to firmware */				libertas_prepare_and_send_command(priv,						      CMD_MAC_MULTICAST_ADR,						      CMD_ACT_SET, 0, 0,						      NULL);			}		}	}	if (adapter->currentpacketfilter != oldpacketfilter) {		libertas_set_mac_packet_filter(priv);	}	lbs_deb_leave(LBS_DEB_NET);}/** *  @brief This function handles the major jobs in the WLAN driver. *  It handles all events generated by firmware, RX data received *  from firmware and TX data sent from kernel. * *  @param data    A pointer to wlan_thread structure *  @return 	   0 */static int libertas_thread(void *data){	struct net_device *dev = data;	wlan_private *priv = dev->priv;	wlan_adapter *adapter = priv->adapter;	wait_queue_t wait;	u8 ireg = 0;	lbs_deb_enter(LBS_DEB_THREAD);	init_waitqueue_entry(&wait, current);	set_freezable();	for (;;) {		lbs_deb_thread( "main-thread 111: intcounter=%d "		       "currenttxskb=%p dnld_sent=%d\n",		       adapter->intcounter,		       adapter->currenttxskb, priv->dnld_sent);		add_wait_queue(&priv->waitq, &wait);		set_current_state(TASK_INTERRUPTIBLE);		spin_lock_irq(&adapter->driver_lock);		if ((adapter->psstate == PS_STATE_SLEEP) ||		    (!adapter->intcounter		     && (priv->dnld_sent || adapter->cur_cmd ||			 list_empty(&adapter->cmdpendingq)))) {			lbs_deb_thread(			       "main-thread sleeping... Conn=%d IntC=%d PS_mode=%d PS_State=%d\n",			       adapter->connect_status, adapter->intcounter,			       adapter->psmode, adapter->psstate);			spin_unlock_irq(&adapter->driver_lock);			schedule();		} else			spin_unlock_irq(&adapter->driver_lock);		lbs_deb_thread(		       "main-thread 222 (waking up): intcounter=%d currenttxskb=%p "		       "dnld_sent=%d\n", adapter->intcounter,		       adapter->currenttxskb, priv->dnld_sent);		set_current_state(TASK_RUNNING);		remove_wait_queue(&priv->waitq, &wait);		try_to_freeze();		lbs_deb_thread("main-thread 333: intcounter=%d currenttxskb=%p "		       "dnld_sent=%d\n",		       adapter->intcounter,		       adapter->currenttxskb, priv->dnld_sent);		if (kthread_should_stop()		    || adapter->surpriseremoved) {			lbs_deb_thread(			       "main-thread: break from main thread: surpriseremoved=0x%x\n",			       adapter->surpriseremoved);			break;		}		spin_lock_irq(&adapter->driver_lock);		if (adapter->intcounter) {			u8 int_status;			adapter->intcounter = 0;			int_status = priv->hw_get_int_status(priv, &ireg);			if (int_status) {				lbs_deb_thread(				       "main-thread: reading HOST_INT_STATUS_REG failed\n");				spin_unlock_irq(&adapter->driver_lock);				continue;			}			adapter->hisregcpy |= ireg;		}		lbs_deb_thread("main-thread 444: intcounter=%d currenttxskb=%p "		       "dnld_sent=%d\n",		       adapter->intcounter,		       adapter->currenttxskb, priv->dnld_sent);		/* command response? */		if (adapter->hisregcpy & MRVDRV_CMD_UPLD_RDY) {			lbs_deb_thread("main-thread: cmd response ready\n");			adapter->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY;			spin_unlock_irq(&adapter->driver_lock);			libertas_process_rx_command(priv);			spin_lock_irq(&adapter->driver_lock);		}		/* Any Card Event */		if (adapter->hisregcpy & MRVDRV_CARDEVENT) {			lbs_deb_thread("main-thread: Card Event Activity\n");			adapter->hisregcpy &= ~MRVDRV_CARDEVENT;			if (priv->hw_read_event_cause(priv)) {				lbs_pr_alert(				       "main-thread: hw_read_event_cause failed\n");				spin_unlock_irq(&adapter->driver_lock);				continue;			}			spin_unlock_irq(&adapter->driver_lock);			libertas_process_event(priv);		} else			spin_unlock_irq(&adapter->driver_lock);		/* Check if we need to confirm Sleep Request received previously */		if (adapter->psstate == PS_STATE_PRE_SLEEP) {			if (!priv->dnld_sent && !adapter->cur_cmd) {				if (adapter->connect_status ==				    LIBERTAS_CONNECTED) {					lbs_deb_thread(					       "main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p "					       "dnld_sent=%d cur_cmd=%p, confirm now\n",					       adapter->intcounter,					       adapter->currenttxskb,					       priv->dnld_sent,					       adapter->cur_cmd);					libertas_ps_confirm_sleep(priv,						       (u16) adapter->psmode);				} else {					/* workaround for firmware sending					 * deauth/linkloss event immediately					 * after sleep request, remove this					 * after firmware fixes it					 */					adapter->psstate = PS_STATE_AWAKE;					lbs_pr_alert(					       "main-thread: ignore PS_SleepConfirm in non-connected state\n");				}			}		}		/* The PS state is changed during processing of Sleep Request		 * event above		 */		if ((priv->adapter->psstate == PS_STATE_SLEEP) ||		    (priv->adapter->psstate == PS_STATE_PRE_SLEEP))			continue;		/* Execute the next command */		if (!priv->dnld_sent && !priv->adapter->cur_cmd)			libertas_execute_next_command(priv);		/* Wake-up command waiters which can't sleep in		 * libertas_prepare_and_send_command		 */		if (!adapter->nr_cmd_pending)			wake_up_all(&adapter->cmd_pending);		libertas_tx_runqueue(priv);	}	del_timer(&adapter->command_timer);	adapter->nr_cmd_pending = 0;	wake_up_all(&adapter->cmd_pending);	lbs_deb_leave(LBS_DEB_THREAD);	return 0;}/** *  @brief This function downloads firmware image, gets *  HW spec from firmware and set basic parameters to *  firmware. * *  @param priv    A pointer to wlan_private structure *  @return 	   0 or -1 */static int wlan_setup_firmware(wlan_private * priv){	int ret = -1;	wlan_adapter *adapter = priv->adapter;	struct cmd_ds_mesh_access mesh_access;	lbs_deb_enter(LBS_DEB_FW);	/*	 * Read MAC address from HW	 */	memset(adapter->current_addr, 0xff, ETH_ALEN);	ret = libertas_prepare_and_send_command(priv, CMD_GET_HW_SPEC,				    0, CMD_OPTION_WAITFORRSP, 0, NULL);	if (ret) {		ret = -1;		goto done;	}	libertas_set_mac_packet_filter(priv);	/* Get the supported Data rates */	ret = libertas_prepare_and_send_command(priv, CMD_802_11_DATA_RATE,				    CMD_ACT_GET_TX_RATE,				    CMD_OPTION_WAITFORRSP, 0, NULL);	if (ret) {		ret = -1;		goto done;	}	/* Disable mesh autostart */	if (priv->mesh_dev) {		memset(&mesh_access, 0, sizeof(mesh_access));		mesh_access.data[0] = cpu_to_le32(0);		ret = libertas_prepare_and_send_command(priv,				CMD_MESH_ACCESS,				CMD_ACT_MESH_SET_AUTOSTART_ENABLED,				CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access);		if (ret) {			ret = -1;			goto done;		}		priv->mesh_autostart_enabled = 0;	}       /* Set the boot2 version in firmware */       ret = libertas_prepare_and_send_command(priv, CMD_SET_BOOT2_VER,                                   0, CMD_OPTION_WAITFORRSP, 0, NULL);	ret = 0;done:	lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);	return ret;}/** *  This function handles the timeout of command sending. *  It will re-send the same command again. */static void command_timer_fn(unsigned long data){	wlan_private *priv = (wlan_private *)data;	wlan_adapter *adapter = priv->adapter;	struct cmd_ctrl_node *ptempnode;	struct cmd_ds_command *cmd;	unsigned long flags;	ptempnode = adapter->cur_cmd;	if (ptempnode == NULL) {		lbs_deb_fw("ptempnode empty\n");		return;	}	cmd = (struct cmd_ds_command *)ptempnode->bufvirtualaddr;	if (!cmd) {		lbs_deb_fw("cmd is NULL\n");		return;	}	lbs_deb_fw("command_timer_fn fired, cmd %x\n", cmd->command);	if (!adapter->fw_ready)		return;	spin_lock_irqsave(&adapter->driver_lock, flags);	adapter->cur_cmd = NULL;	spin_unlock_irqrestore(&adapter->driver_lock, flags);	lbs_deb_fw("re-sending same command because of timeout\n");	libertas_queue_cmd(adapter, ptempnode, 0);	wake_up_interruptible(&priv->waitq);	return;}static int libertas_init_adapter(wlan_private * priv){	wlan_adapter *adapter = priv->adapter;	size_t bufsize;	int i, ret = 0;	/* Allocate buffer to store the BSSID list */	bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor);	adapter->networks = kzalloc(bufsize, GFP_KERNEL);	if (!adapter->networks) {		lbs_pr_err("Out of memory allocating beacons\n");		ret = -1;		goto out;	}	/* Initialize scan result lists */	INIT_LIST_HEAD(&adapter->network_free_list);	INIT_LIST_HEAD(&adapter->network_list);	for (i = 0; i < MAX_NETWORK_COUNT; i++) {		list_add_tail(&adapter->networks[i].list,			      &adapter->network_free_list);	}	adapter->libertas_ps_confirm_sleep.seqnum = cpu_to_le16(++adapter->seqnum);	adapter->libertas_ps_confirm_sleep.command =	    cpu_to_le16(CMD_802_11_PS_MODE);	adapter->libertas_ps_confirm_sleep.size =	    cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep));	adapter->libertas_ps_confirm_sleep.action =	    cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED);	memset(adapter->current_addr, 0xff, ETH_ALEN);	adapter->connect_status = LIBERTAS_DISCONNECTED;	adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;	adapter->mode = IW_MODE_INFRA;	adapter->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;	adapter->currentpacketfilter = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;	adapter->radioon = RADIO_ON;	adapter->auto_rate = 1;	adapter->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;	adapter->psmode = WLAN802_11POWERMODECAM;	adapter->psstate = PS_STATE_FULL_POWER;	mutex_init(&adapter->lock);	memset(&adapter->tx_queue_ps, 0, NR_TX_QUEUE*sizeof(struct sk_buff*));	adapter->tx_queue_idx = 0;	spin_lock_init(&adapter->txqueue_lock);	setup_timer(&adapter->command_timer, command_timer_fn,	            (unsigned long)priv);

⌨️ 快捷键说明

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