📄 aironet4500_core.c
字号:
udelay(100); outw(0x6,dev->base_addr + 0x34); outw(0x6,dev->base_addr + 0x34); WAIT61x3; AWC_IN(dev->base_addr + 0x26); AWC_OUT(dev->base_addr + 0x26, 0); WAIT61x3; udelay(60); outw(0x4, dev->base_addr); udelay(1000); WAIT61x3; AWC_IN(dev->base_addr + 0x26); AWC_OUT(dev->base_addr + 0x26, 0); WAIT61x3; udelay(60);*/ status = awc_issue_command_no_ack(dev, AWC_COMMAND_SOFT_RESET,0,0,0); // awc_command_busy_clear_wait(dev); return status;};intawc_issue_noop(struct net_device * dev){ int retval; AWC_OUT(dev->base_addr + 0x28, 0); AWC_OUT(dev->base_addr + 0x2A, 0); udelay(1000); retval= awc_issue_blocking_command(dev, AWC_COMMAND_NOOP); udelay(1000); return retval;};EXPORT_SYMBOL(awc_enable_MAC);intawc_enable_MAC(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; AWC_ENTRY_EXIT_DEBUG(" entry awc_enable_MAC "); if (priv->mac_enabled){ AWC_ENTRY_EXIT_DEBUG(" mac already enabled exit \n"); return 0; } udelay(500); if (awc_issue_blocking_command(dev, AWC_COMMAND_ENABLE)){ AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ; } udelay(500); priv->mac_enabled = 1; AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0;};EXPORT_SYMBOL(awc_disable_MAC);intawc_disable_MAC(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; AWC_ENTRY_EXIT_DEBUG(" entry awc_disable_MAC "); if (!priv->mac_enabled){ AWC_ENTRY_EXIT_DEBUG(" mac allready disabled exit \n"); return 0; } udelay(1000); if (awc_issue_blocking_command(dev, AWC_COMMAND_DISABLE)){ AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ; } udelay(1000); priv->mac_enabled = 0; AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0;};intawc_read_all_rids(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; int status,i; AWC_ENTRY_EXIT_DEBUG(" entry awc_read_all_rids "); for (i=0; i< AWC_NOF_RIDS && priv->rid_dir[i].selector ; i++){ status = awc_readrid_dir(dev,&priv->rid_dir[i]); udelay(50); if (status) return status; } priv->rids_read = 1; AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0;}intawc_write_all_rids(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; int i,status ; AWC_ENTRY_EXIT_DEBUG(" entry awc_write_all_rids "); for (i=0;i < 5 && i< AWC_NOF_RIDS && priv->rid_dir[i].selector ; i++){ status = awc_writerid_dir(dev,&priv->rid_dir[i]); udelay(10); if(status) return status; } AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0;}/************************** FID QUEUES ****************************//**************************** TX ALLOC / DEALLOC ***************/int awc_tx_alloc(struct net_device * dev) { struct awc_command cmd; int k=0; int tot=0; struct awc_fid * fid = NULL; AWC_ENTRY_EXIT_DEBUG(" entry awc_tx_alloc "); AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0x0A,0, 0,0,0,NULL); cmd.par0 = dev->mtu + AWC_TX_HEAD_SIZE + 8 ; DEBUG(32,"about to allocate %x bytes ",cmd.priv->large_buff_mem); DEBUG(32,"in %x large buffers ",cmd.priv->large_buff_mem / (dev->mtu + AWC_TX_HEAD_SIZE + 8) ); k=0;tot=0; AWC_BAP_LOCK_NOT_CLI(cmd); while (k < cmd.priv->large_buff_mem / (dev->mtu + AWC_TX_HEAD_SIZE + 8) ) { fid = kmalloc(sizeof(struct awc_fid),GFP_KERNEL ); if (!fid) goto final; memset(fid, 0, sizeof(struct awc_fid)); if (awc_issue_command_and_block(&cmd)) goto final; while ( awc_event_status_Alloc(cmd.port) == 0) ; fid->u.tx.fid = awc_Tx_Allocated_Fid(cmd.port); fid->u.tx.fid_size = dev->mtu + AWC_TX_HEAD_SIZE ; DEBUG(32,"allocated large tx fid %x ",fid->u.tx.fid); if(fid->u.tx.fid == 0 || cmd.status != 0xA){ printk(KERN_ERR "%s bad tx_alloc\n",dev->name); fid->busy =1; goto final; } else { fid->busy =0; tot++; } awc_event_ack_Alloc(cmd.port); // shoudlnt goto final after that awc_fid_queue_push_tail(&cmd.priv->tx_large_ready,fid); k++; } cmd.priv->tx_buffs_total = tot; DEBUG(32,"allocated %d large tx buffs\n",tot); cmd.par0 = AWC_TX_ALLOC_SMALL_SIZE ; k =0; tot = 0; while (k < cmd.priv->small_buff_no) { fid = kmalloc(sizeof(struct awc_fid),GFP_KERNEL ); if (!fid) goto final; memset(fid, 0, sizeof(struct awc_fid)); cmd.par0 = AWC_TX_ALLOC_SMALL_SIZE ; if (awc_issue_command_and_block(&cmd)) goto final; while ( awc_event_status_Alloc(cmd.port) == 0) ; fid->u.tx.fid = awc_Tx_Allocated_Fid(cmd.port); fid->u.tx.fid_size = AWC_TX_ALLOC_SMALL_SIZE; DEBUG(32,"allocated large tx fid %x ",fid->u.tx.fid); if(fid->u.tx.fid == 0 || cmd.status != 0xA){ printk(KERN_ERR "%s bad tx_alloc\n",dev->name); fid->busy =1; goto final; } else { fid->busy =0; tot++; } awc_event_ack_Alloc(cmd.port); // shoudlnt goto final after that awc_fid_queue_push_tail(&cmd.priv->tx_small_ready,fid); k++; } cmd.priv->tx_small_buffs_total = tot; DEBUG(32,"allocated %d small tx buffs\n",tot); AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0; final: if (fid ) kfree(fid); printk(KERN_CRIT "%s awc tx prealloc failed \n",dev->name); AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ;};int awc_tx_dealloc_fid(struct net_device * dev,struct awc_fid * fid){ struct awc_command cmd; int fid_handle = 0; AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0x0C,0, 0,0,0,NULL); AWC_BAP_LOCK_NOT_CLI(cmd); if (fid->u.tx.fid){ fid_handle = cmd.par0 = fid->u.tx.fid; fid->u.tx.fid = 0; fid->busy =0; kfree(fid); if (!cmd.priv->ejected) if (awc_issue_command_and_block(&cmd)) goto final; //awc_event_ack_Alloc(cmd.port); } AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0; final: printk(KERN_ERR "awc_tx_dealloc failed for fid %x \n",fid_handle); AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ;};intawc_tx_dealloc(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv;// int k=0; struct awc_fid * fid; AWC_ENTRY_EXIT_DEBUG(" entry awc_tx_dealloc "); while (NULL != (fid = awc_fid_queue_pop_head(&priv->tx_large_ready))) awc_tx_dealloc_fid(dev,fid); while (NULL != (fid = awc_fid_queue_pop_head(&priv->tx_small_ready))) awc_tx_dealloc_fid(dev,fid); while (NULL != (fid = awc_fid_queue_pop_head(&priv->tx_post_process))) awc_tx_dealloc_fid(dev,fid); while (NULL != (fid = awc_fid_queue_pop_head(&priv->tx_in_transmit))) awc_tx_dealloc_fid(dev,fid); return 0;};inline struct awc_fid *awc_tx_fid_lookup_and_remove(struct net_device * dev, u16 fid_handle){ struct awc_private * priv = (struct awc_private *)dev->priv;// int k = 0; unsigned long flags; struct awc_fid * fid = NULL; int cnt=0; AWC_ENTRY_EXIT_DEBUG(" entry awc_tx_fid_lookup "); my_spin_lock_irqsave(&(priv->queues_lock),flags); fid = priv->tx_in_transmit.head; cnt = 0; while (fid){ if (fid->u.tx.fid == fid_handle){ awc_fid_queue_remove(&priv->tx_in_transmit, fid); my_spin_unlock_irqrestore(&(priv->queues_lock),flags); return fid; } fid = fid->next; // printk("iT\n"); if (cnt++ > 200) { // printk("bbb in awc_fid_queue\n"); my_spin_unlock_irqrestore(&(priv->queues_lock),flags); return 0; }; }; cnt=0; fid = priv->tx_post_process.head; while (fid){ if (fid->u.tx.fid == fid_handle){ awc_fid_queue_remove(&priv->tx_post_process, fid); my_spin_unlock_irqrestore(&(priv->queues_lock),flags); return fid; } fid = fid->next; // printk("pp\n"); if (cnt++ > 200) { // printk("bbb in awc_fid_queue\n"); my_spin_unlock_irqrestore(&(priv->queues_lock),flags); return 0; }; }; cnt=0; fid = priv->tx_large_ready.head; while (fid){ if (fid->u.tx.fid == fid_handle){ awc_fid_queue_remove(&priv->tx_large_ready, fid); my_spin_unlock_irqrestore(&(priv->queues_lock),flags); return fid; } fid = fid->next; // printk("lr\n"); if (cnt++ > 200) { // printk("bbb in awc_fid_queue\n"); my_spin_unlock_irqrestore(&(priv->queues_lock),flags); return 0; }; }; cnt=0; fid = priv->tx_small_ready.head; while (fid){ if (fid->u.tx.fid == fid_handle){ awc_fid_queue_remove(&priv->tx_small_ready, fid); my_spin_unlock_irqrestore(&(priv->queues_lock),flags); return fid; } fid = fid->next; // printk("sr\n"); if (cnt++ > 200) { // printk("bbb in awc_fid_queue\n"); my_spin_unlock_irqrestore(&(priv->queues_lock),flags); return 0; }; }; my_spin_unlock_irqrestore(&(priv->queues_lock),flags); printk(KERN_ERR "%s tx fid %x not found \n",dev->name, fid_handle); AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return NULL;}int awc_queues_init(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; struct awc_fid * fid = NULL; int retv =0; int k = 0; awc_fid_queue_init(&priv->tx_in_transmit); awc_fid_queue_init(&priv->tx_post_process); awc_fid_queue_init(&priv->tx_large_ready); awc_fid_queue_init(&priv->tx_small_ready); awc_fid_queue_init(&priv->rx_ready); awc_fid_queue_init(&priv->rx_post_process); retv = awc_tx_alloc(dev); k = 0; while (k < AWC_RX_BUFFS){ fid = kmalloc(sizeof(struct awc_fid),GFP_KERNEL); if (!fid) return -1; awc_fid_queue_push_tail(&priv->rx_ready,fid); k++; }; if (retv) return retv; return 0; };int awc_queues_destroy(struct net_device * dev){ struct awc_private * priv = (struct awc_private *)dev->priv; struct awc_fid * fid = NULL; int retv =0; while (NULL != (fid = awc_fid_queue_pop_head(&priv->rx_ready))){ kfree(fid); } while (NULL != (fid = awc_fid_queue_pop_head(&priv->rx_post_process))){ kfree(fid); } retv = awc_tx_dealloc(dev); return retv; };/****************************** 802.11router ******************/inline int awc_802_11_copy_path_skb(struct net_device * dev, struct awc_fid * rx_buff){ struct awc_private * priv = (struct awc_private * )dev->priv; AWC_ENTRY_EXIT_DEBUG("awc_802_11_copy_path_skb");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -