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

📄 sm_drv.c

📁 cx3110 drivers for linux 2.6 (基于SPI)
💻 C
📖 第 1 页 / 共 2 页
字号:
				mask &= ~SM_FRAMERX;			}		}				if(mask & SM_TRAP) {			struct s_sm_conf t;			int32_t result;						t.length = sizeof(long);			t.data = kmalloc(t.length, GFP_ATOMIC);						spin_lock_bh(&lp->sm_lock);			result = prism_softmac_trap(lp->sm_context, &t);			spin_unlock_bh(&lp->sm_lock);			if(result == SM_EOVERFLOW) {				kfree(t.data);				t.data = kmalloc(t.length, GFP_ATOMIC);				if(t.data != NULL) {					spin_lock_bh(&lp->sm_lock);					result = prism_softmac_trap(lp->sm_context, &t);					spin_unlock_bh(&lp->sm_lock);				} else {					printk(KERN_ERR "%s: could not allocate trap data\n", driver_name);					goto trap_error;				}			}						if(result >= SM_ENONE) {				mask |= result;								if(t.flags & SM_CONF_OPSET) {					/* This is a unsolicitated trap */					result = handle_sm_trap(dev, &t);					if(result >= SM_ENONE)						mask |= result;										kfree(t.data);				} else {					/* This is a response to a GET operation */					memcpy(&lp->getresp, &t, sizeof(struct s_sm_conf));										/* Wake up the app that requested this info.					 * This will also free t.data. 					 */					wake_up(&lp->getresp_waitq);				}			} else {				mask &= ~SM_TRAP;				kfree(t.data);			}					}			trap_error:		if(mask & SM_IC) {						if(lp->device_state == DEVSTATE_ACTIVE || lp->device_state == DEVSTATE_BOOTING)				tasklet_hi_schedule(&lp->tasklet);			mask &= ~SM_IC;		}	}}/****************************************************************************** *   Kernel API functions ******************************************************************************//* Create the net device instance that will be associated to the host interface */struct net_device *sm_drv_netdev_create(int ioaddr, int irq){	struct net_local *lp;	struct net_device * netdev;	DEBUG(DBG_CALLS, "sm_drv_netdev_create\n");	netdev = alloc_netdev(sizeof (struct net_local), "wlan%d", ether_setup);	if (!netdev) {		printk(KERN_ERR "net device not allocated\n");		return netdev;	}	netdev->base_addr          = ioaddr;	netdev->irq                = irq;	netdev->open               = &sm_drv_open;	netdev->stop               = &sm_drv_close;	netdev->hard_start_xmit    = &sm_drv_transmit;	netdev->get_stats          = &sm_drv_statistics;	netdev->wireless_handlers  = (struct iw_handler_def *) &sm_drv_we_handler_def;	netdev->watchdog_timeo     = SM_DRV_TX_TIMEOUT;	netdev->tx_timeout         = &sm_drv_tx_timeout;	netdev->type               = ARPHRD_ETHER;	lp = netdev->priv;	memset(lp, 0, sizeof(struct net_local));	spin_lock_init(&lp->sm_lock);	init_waitqueue_head(&lp->conf_waitq);	init_waitqueue_head(&lp->getresp_waitq);	/* Init the Softmac timer */	init_timer(&lp->softmac_timer);	lp->softmac_timer.function = driver_timer_expired;	lp->softmac_timer.data = (unsigned long)netdev;	/* Init the scan timer */	init_timer(&lp->scan_timer);	lp->scan_timer.function = send_scan_complete_timer;	lp->scan_timer.data = (unsigned long)netdev;	return netdev;}extern struct platform_device wlan_omap_device;extern unsigned int driver_type;int sm_drv_open(struct net_device *dev){	struct net_local *lp = dev->priv;	DEBUG(DBG_CALLS, "sm_drv_open\n");	if (cx3110x_spi_start(dev) < 0)		goto err_out;	lp->sm_pda = sm_drv_spi_get_pda(&(wlan_omap_device.dev));	if (!lp->sm_pda)		goto err_mcbsp_free_out;		lp->device_state = DEVSTATE_BOOTING;	lp->bss_type = DOT11_BSSTYPE_INFRA;		if (sm_drv_spi_request_irq(dev) < 0)		goto err_mcbsp_free_out;		/* We bring the interface up */	if (lp->hif_up(dev) < 0)		goto err_mcbsp_irq_free_out;		/* Wait for the chip to receive its first interrupt */	wait_for_completion_interruptible(&softmac_init_comp);		if (lp->sm_mode == SM_MODE_PROMISCUOUS) {		uint32_t commit = 0;				lp->bss_type = DOT11_BSSTYPE_NONE;		if (sm_drv_oid_set(dev, GEN_OID_COMMIT, (void*)&commit, sizeof(uint32_t)) < 0)			goto err_mcbsp_irq_free_out;		goto start_tcp_queue;	}		if (driver_type == SM_DRIVER_TYPE_UMAC) {		uint32_t scan_mode = SCAN_MODE_PASSIVE;		uint32_t authen = DOT11_AUTH_BOTH;		uint32_t wwr_mode = DOT11_WWR_MODE_11D; /* We don't need 802.11h */		uint32_t dot11d_conformance_mode = DOT11_CONFORMANCE_FAST;		uint32_t profile = DOT11_PROFILE_MIXED;		uint32_t bgr_scan_disable = 0;		int32_t  scan_threshold = -75;		uint32_t tx_lifetime = 4096, rx_lifetime = 4096;		struct obj_scan scan_params = {-1, 80, 200, 20000, 80, 140};		uint32_t commit = 0;				if (sm_drv_oid_set(dev, DOT11_OID_AUTHENABLE, (void *)&authen, sizeof(uint32_t)) < 0)			goto err_mcbsp_irq_free_out;				if (sm_drv_oid_set(dev, DOT11_OID_SCANMODE, (void*)&scan_mode, sizeof(uint32_t)) < 0)			goto err_mcbsp_irq_free_out;				if (sm_drv_oid_set(dev, DOT11_OID_WWRMODE, (void*)&wwr_mode, sizeof(uint32_t)) < 0)			goto err_mcbsp_irq_free_out;				if (sm_drv_oid_set(dev, DOT11_OID_CONFORMANCEMODE, (void*)&dot11d_conformance_mode, sizeof(uint32_t)) < 0)			goto err_mcbsp_irq_free_out;				if (sm_drv_oid_set(dev, DOT11_OID_PROFILES, (void*)&profile, sizeof(uint32_t)) < 0)			goto err_mcbsp_irq_free_out;				if (sm_drv_oid_set(dev, DOT11_OID_AUTOSCANDISABLE, (void*)&bgr_scan_disable, sizeof(uint32_t)) < 0)			goto err_mcbsp_irq_free_out;				if (sm_drv_oid_set(dev, DOT11_OID_SCANTHRESHOLD, (void*)&scan_threshold, sizeof(int32_t)) < 0)			goto err_mcbsp_irq_free_out;		if (sm_drv_oid_set(dev, DOT11_OID_MAXTXLIFETIME, (void*)&tx_lifetime, sizeof(uint32_t)) < 0)			goto err_mcbsp_irq_free_out;				if (sm_drv_oid_set(dev, DOT11_OID_MAXRXLIFETIME, (void*)&rx_lifetime, sizeof(uint32_t)) < 0)			goto err_mcbsp_irq_free_out;				if (sm_drv_oid_set(dev, DOT11_OID_SCAN, (void*)&scan_params, sizeof(struct obj_scan)) < 0)			goto err_mcbsp_irq_free_out;		/* WWR mode needs to be commited */		if (sm_drv_oid_set(dev, GEN_OID_COMMIT, (void*)&commit, sizeof(uint32_t)) < 0)			goto err_mcbsp_irq_free_out;	}	 start_tcp_queue:		netif_start_queue(dev);		return 0; err_mcbsp_irq_free_out:	sm_drv_spi_free_irq(dev); err_mcbsp_free_out:		cx3110x_spi_stop(dev); err_out:	return -ENXIO;}int sm_drv_close(struct net_device *dev){	struct net_local *lp = dev->priv;	struct spi_hif_local_data *hif_lp = HIF_LP(lp);	DEBUG(DBG_CALLS, "sm_drv_close \n");		sm_drv_disassociate(dev);	netif_stop_queue(dev);	        /* Disable all device interrupts */	lp->hif_cli(dev);	if(lp->device_state == DEVSTATE_ACTIVE || lp->device_state == DEVSTATE_BOOTING)		lp->device_state = DEVSTATE_IDLE;	flush_scheduled_work();	DEBUG(DBG_ALL, "Shut down SoftMAC\n");		hif_lp->initial_packets = 0;	if (lp->sm_initialization) {		/* shut down SoftMAC */		lp->sm_descr.mtu = 0;		lp->sm_initialization = 0;		hif_lp->upload_state = UPLOAD_STATE_BOOTING;		prism_softmac_destroy(lp->sm_context);	}	lp->hif_down(dev);	sm_drv_spi_free_irq(dev);	cx3110x_spi_stop(dev);	return 0;}int sm_drv_transmit(struct sk_buff *skb, struct net_device *dev){	struct s_sm_frame *frame;	struct net_local *lp = dev->priv;	int32_t callb_mask;	DEBUG(DBG_CALLS, "sm_drv_transmit\n"); again:	if(lp->queued_tx_frame) {		frame = lp->queued_tx_frame;	} else {		frame = skb_to_frame(dev, skb);		if(!frame) {			printk(KERN_ERR "sm_drv_transmit: Could not allocate frame for skb\n");			dev_kfree_skb(skb);			lp->stats.tx_errors++;			goto out;		}	}		spin_lock_bh(&lp->sm_lock);	callb_mask = prism_softmac_frame_tx( lp->sm_context, frame );	spin_unlock_bh(&lp->sm_lock);	if(callb_mask < 0) {		if(callb_mask == SM_EOVERFLOW) {			printk("sm_drv_transmit: Overflow, stopping TX queue\n");			printk(KERN_WARNING "sm_drv_transmit: Overflow, stopping TX queue\n");			/* We have to accept the packet, otherwise it gets lost. So we			 * temporarily store it and stop the queue. We retry this packet			 * once we have a sm_frame_tx_done			 */			lp->queued_tx_frame = frame;			netif_stop_queue(dev);		} else {			printk("sm_drv_transmit: sm_frame_tx returned error %d\n", callb_mask);			/* a normal frame failed, increment the parents device error counter */			lp->stats.tx_errors++;						/* Free the frame and the sk_buff */			frame_skb_free(dev, frame);			if(lp->queued_tx_frame) {				lp->queued_tx_frame = NULL;			}		}		goto out;	}	dev->trans_start = jiffies;	handle_sm_callback(dev, callb_mask);	/* If we transmitted a queued frame, now try to transmit the current frame */	if(lp->queued_tx_frame) {		lp->queued_tx_frame = NULL;		goto again;	} out:		return 0;}void sm_drv_tx_timeout(struct net_device *dev){	struct net_local *lp = dev->priv;	struct net_device_stats *statistics = &lp->stats;		DEBUG(DBG_CALLS, "sm_drv_tx_timeout \n");	/* increment the transmit error counter */	statistics->tx_errors++;	netif_wake_queue(dev);		return;}struct net_device_stats *sm_drv_statistics(struct net_device *dev){	struct net_local *lp = dev->priv;	DEBUG(DBG_CALLS, "sm_drv_statistics \n");	return &lp->stats;}int sm_drv_reset(struct net_device *dev, uint8_t sm_mode){	struct net_local *lp = dev->priv;	int ret;	if(lp->device_state == DEVSTATE_IDLE) {		printk(KERN_INFO "sm_srv_reset: Cannot reset device in Idle state\n");		return -1;	}	lp->sm_mode = sm_mode;	ret = sm_drv_close(dev);	if(ret == 0) {		ret = sm_drv_open(dev);	}	return ret;}

⌨️ 快捷键说明

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