亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? bcm43xx_dma.c

?? 無線網卡驅動,有很好的參考價值,在linux_2.6.21下可以直接使用,如果在其他平臺,可以參考移植
?? C
?? 第 1 頁 / 共 3 頁
字號:
/*  Broadcom BCM43xx wireless driver  DMA ringbuffer and descriptor allocation/management  Copyright (c) 2005, 2006 Michael Buesch <mbuesch@freenet.de>  Some code in this file is derived from the b44.c driver  Copyright (C) 2002 David S. Miller  Copyright (C) Pekka Pietikainen  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; see the file COPYING.  If not, write to  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,  Boston, MA 02110-1301, USA.*/#include "bcm43xx.h"#include "bcm43xx_dma.h"#include "bcm43xx_main.h"#include "bcm43xx_debugfs.h"#include "bcm43xx_power.h"#include "bcm43xx_xmit.h"#include <linux/dma-mapping.h>#include <linux/pci.h>#include <linux/delay.h>#include <linux/skbuff.h>static inline int free_slots(struct bcm43xx_dmaring *ring){	return (ring->nr_slots - ring->used_slots);}static inline int next_slot(struct bcm43xx_dmaring *ring, int slot){	assert(slot >= -1 && slot <= ring->nr_slots - 1);	if (slot == ring->nr_slots - 1)		return 0;	return slot + 1;}static inline int prev_slot(struct bcm43xx_dmaring *ring, int slot){	assert(slot >= 0 && slot <= ring->nr_slots - 1);	if (slot == 0)		return ring->nr_slots - 1;	return slot - 1;}/* Request a slot for usage. */static inlineint request_slot(struct bcm43xx_dmaring *ring){	int slot;	assert(ring->tx);	assert(!ring->suspended);	assert(free_slots(ring) != 0);	slot = next_slot(ring, ring->current_slot);	ring->current_slot = slot;	ring->used_slots++;	/* Check the number of available slots and suspend TX,	 * if we are running low on free slots.	 */	if (unlikely(free_slots(ring) < ring->suspend_mark)) {		netif_stop_queue(ring->bcm->net_dev);		ring->suspended = 1;	}#ifdef CONFIG_BCM43XX_DEBUG	if (ring->used_slots > ring->max_used_slots)		ring->max_used_slots = ring->used_slots;#endif /* CONFIG_BCM43XX_DEBUG*/	return slot;}/* Return a slot to the free slots. */static inlinevoid return_slot(struct bcm43xx_dmaring *ring, int slot){	assert(ring->tx);	ring->used_slots--;	/* Check if TX is suspended and check if we have	 * enough free slots to resume it again.	 */	if (unlikely(ring->suspended)) {		if (free_slots(ring) >= ring->resume_mark) {			ring->suspended = 0;			netif_wake_queue(ring->bcm->net_dev);		}	}}u16 bcm43xx_dmacontroller_base(int dma64bit, int controller_idx){	static const u16 map64[] = {		BCM43xx_MMIO_DMA64_BASE0,		BCM43xx_MMIO_DMA64_BASE1,		BCM43xx_MMIO_DMA64_BASE2,		BCM43xx_MMIO_DMA64_BASE3,		BCM43xx_MMIO_DMA64_BASE4,		BCM43xx_MMIO_DMA64_BASE5,	};	static const u16 map32[] = {		BCM43xx_MMIO_DMA32_BASE0,		BCM43xx_MMIO_DMA32_BASE1,		BCM43xx_MMIO_DMA32_BASE2,		BCM43xx_MMIO_DMA32_BASE3,		BCM43xx_MMIO_DMA32_BASE4,		BCM43xx_MMIO_DMA32_BASE5,	};	if (dma64bit) {		assert(controller_idx >= 0 &&		       controller_idx < ARRAY_SIZE(map64));		return map64[controller_idx];	}	assert(controller_idx >= 0 &&	       controller_idx < ARRAY_SIZE(map32));	return map32[controller_idx];}static inlinedma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,			  unsigned char *buf,			  size_t len,			  int tx){	dma_addr_t dmaaddr;	int direction = PCI_DMA_FROMDEVICE;	if (tx)		direction = PCI_DMA_TODEVICE;	dmaaddr = pci_map_single(ring->bcm->pci_dev,					 buf, len,					 direction);	return dmaaddr;}static inlinevoid unmap_descbuffer(struct bcm43xx_dmaring *ring,		      dma_addr_t addr,		      size_t len,		      int tx){	if (tx) {		pci_unmap_single(ring->bcm->pci_dev,				 addr, len,				 PCI_DMA_TODEVICE);	} else {		pci_unmap_single(ring->bcm->pci_dev,				 addr, len,				 PCI_DMA_FROMDEVICE);	}}static inlinevoid sync_descbuffer_for_cpu(struct bcm43xx_dmaring *ring,			     dma_addr_t addr,			     size_t len){	assert(!ring->tx);	pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,				    addr, len, PCI_DMA_FROMDEVICE);}static inlinevoid sync_descbuffer_for_device(struct bcm43xx_dmaring *ring,				dma_addr_t addr,				size_t len){	assert(!ring->tx);	pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,				    addr, len, PCI_DMA_TODEVICE);}/* Unmap and free a descriptor buffer. */static inlinevoid free_descriptor_buffer(struct bcm43xx_dmaring *ring,			    struct bcm43xx_dmadesc_meta *meta,			    int irq_context){	assert(meta->skb);	if (irq_context)		dev_kfree_skb_irq(meta->skb);	else		dev_kfree_skb(meta->skb);	meta->skb = NULL;}static int alloc_ringmemory(struct bcm43xx_dmaring *ring){	ring->descbase = pci_alloc_consistent(ring->bcm->pci_dev, BCM43xx_DMA_RINGMEMSIZE,					    &(ring->dmabase));	if (!ring->descbase) {		/* Allocation may have failed due to pci_alloc_consistent		   insisting on use of GFP_DMA, which is more restrictive		   than necessary...  */		struct dma_desc *rx_ring;		dma_addr_t rx_ring_dma;		rx_ring = kzalloc(BCM43xx_DMA_RINGMEMSIZE, GFP_KERNEL);		if (!rx_ring)			goto out_err;		rx_ring_dma = pci_map_single(ring->bcm->pci_dev, rx_ring,					     BCM43xx_DMA_RINGMEMSIZE,					     PCI_DMA_BIDIRECTIONAL);		if (pci_dma_mapping_error(rx_ring_dma) ||		    rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > ring->bcm->dma_mask) {			/* Sigh... */			if (!pci_dma_mapping_error(rx_ring_dma))				pci_unmap_single(ring->bcm->pci_dev,						 rx_ring_dma, BCM43xx_DMA_RINGMEMSIZE,						 PCI_DMA_BIDIRECTIONAL);			rx_ring_dma = pci_map_single(ring->bcm->pci_dev,						 rx_ring, BCM43xx_DMA_RINGMEMSIZE,						 PCI_DMA_BIDIRECTIONAL);			if (pci_dma_mapping_error(rx_ring_dma) ||			    rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > ring->bcm->dma_mask) {				assert(0);				if (!pci_dma_mapping_error(rx_ring_dma))					pci_unmap_single(ring->bcm->pci_dev,							 rx_ring_dma, BCM43xx_DMA_RINGMEMSIZE,							 PCI_DMA_BIDIRECTIONAL);				goto out_err;			}                }                ring->descbase = rx_ring;                ring->dmabase = rx_ring_dma;	}	memset(ring->descbase, 0, BCM43xx_DMA_RINGMEMSIZE);	return 0;out_err:	printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");	return -ENOMEM;}static void free_ringmemory(struct bcm43xx_dmaring *ring){	struct device *dev = &(ring->bcm->pci_dev->dev);	dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,			  ring->descbase, ring->dmabase);}/* Reset the RX DMA channel */int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,				   u16 mmio_base, int dma64){	int i;	u32 value;	u16 offset;	offset = dma64 ? BCM43xx_DMA64_RXCTL : BCM43xx_DMA32_RXCTL;	bcm43xx_write32(bcm, mmio_base + offset, 0);	for (i = 0; i < 1000; i++) {		offset = dma64 ? BCM43xx_DMA64_RXSTATUS : BCM43xx_DMA32_RXSTATUS;		value = bcm43xx_read32(bcm, mmio_base + offset);		if (dma64) {			value &= BCM43xx_DMA64_RXSTAT;			if (value == BCM43xx_DMA64_RXSTAT_DISABLED) {				i = -1;				break;			}		} else {			value &= BCM43xx_DMA32_RXSTATE;			if (value == BCM43xx_DMA32_RXSTAT_DISABLED) {				i = -1;				break;			}		}		udelay(10);	}	if (i != -1) {		printk(KERN_ERR PFX "Error: Wait on DMA RX status timed out.\n");		return -ENODEV;	}	return 0;}/* Reset the RX DMA channel */int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,				   u16 mmio_base, int dma64){	int i;	u32 value;	u16 offset;	for (i = 0; i < 1000; i++) {		offset = dma64 ? BCM43xx_DMA64_TXSTATUS : BCM43xx_DMA32_TXSTATUS;		value = bcm43xx_read32(bcm, mmio_base + offset);		if (dma64) {			value &= BCM43xx_DMA64_TXSTAT;			if (value == BCM43xx_DMA64_TXSTAT_DISABLED ||			    value == BCM43xx_DMA64_TXSTAT_IDLEWAIT ||			    value == BCM43xx_DMA64_TXSTAT_STOPPED)				break;		} else {			value &= BCM43xx_DMA32_TXSTATE;			if (value == BCM43xx_DMA32_TXSTAT_DISABLED ||			    value == BCM43xx_DMA32_TXSTAT_IDLEWAIT ||			    value == BCM43xx_DMA32_TXSTAT_STOPPED)				break;		}		udelay(10);	}	offset = dma64 ? BCM43xx_DMA64_TXCTL : BCM43xx_DMA32_TXCTL;	bcm43xx_write32(bcm, mmio_base + offset, 0);	for (i = 0; i < 1000; i++) {		offset = dma64 ? BCM43xx_DMA64_TXSTATUS : BCM43xx_DMA32_TXSTATUS;		value = bcm43xx_read32(bcm, mmio_base + offset);		if (dma64) {			value &= BCM43xx_DMA64_TXSTAT;			if (value == BCM43xx_DMA64_TXSTAT_DISABLED) {				i = -1;				break;			}		} else {			value &= BCM43xx_DMA32_TXSTATE;			if (value == BCM43xx_DMA32_TXSTAT_DISABLED) {				i = -1;				break;			}		}		udelay(10);	}	if (i != -1) {		printk(KERN_ERR PFX "Error: Wait on DMA TX status timed out.\n");		return -ENODEV;	}	/* ensure the reset is completed. */	udelay(300);	return 0;}static void fill_descriptor(struct bcm43xx_dmaring *ring,			    struct bcm43xx_dmadesc_generic *desc,			    dma_addr_t dmaaddr,			    u16 bufsize,			    int start, int end, int irq){	int slot;	slot = bcm43xx_dma_desc2idx(ring, desc);	assert(slot >= 0 && slot < ring->nr_slots);	if (ring->dma64) {		u32 ctl0 = 0, ctl1 = 0;		u32 addrlo, addrhi;		u32 addrext;		addrlo = (u32)(dmaaddr & 0xFFFFFFFF);		addrhi = (((u64)dmaaddr >> 32) & ~BCM43xx_DMA64_ROUTING);		addrext = (((u64)dmaaddr >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);		addrhi |= ring->routing;		if (slot == ring->nr_slots - 1)			ctl0 |= BCM43xx_DMA64_DCTL0_DTABLEEND;		if (start)			ctl0 |= BCM43xx_DMA64_DCTL0_FRAMESTART;		if (end)			ctl0 |= BCM43xx_DMA64_DCTL0_FRAMEEND;		if (irq)			ctl0 |= BCM43xx_DMA64_DCTL0_IRQ;		ctl1 |= (bufsize - ring->frameoffset)			& BCM43xx_DMA64_DCTL1_BYTECNT;		ctl1 |= (addrext << BCM43xx_DMA64_DCTL1_ADDREXT_SHIFT)			& BCM43xx_DMA64_DCTL1_ADDREXT_MASK;		desc->dma64.control0 = cpu_to_le32(ctl0);		desc->dma64.control1 = cpu_to_le32(ctl1);		desc->dma64.address_low = cpu_to_le32(addrlo);		desc->dma64.address_high = cpu_to_le32(addrhi);	} else {		u32 ctl;		u32 addr;		u32 addrext;		addr = (u32)(dmaaddr & ~BCM43xx_DMA32_ROUTING);		addrext = (u32)(dmaaddr & BCM43xx_DMA32_ROUTING)			   >> BCM43xx_DMA32_ROUTING_SHIFT;		addr |= ring->routing;		ctl = (bufsize - ring->frameoffset)		      & BCM43xx_DMA32_DCTL_BYTECNT;		if (slot == ring->nr_slots - 1)			ctl |= BCM43xx_DMA32_DCTL_DTABLEEND;		if (start)			ctl |= BCM43xx_DMA32_DCTL_FRAMESTART;		if (end)			ctl |= BCM43xx_DMA32_DCTL_FRAMEEND;		if (irq)			ctl |= BCM43xx_DMA32_DCTL_IRQ;		ctl |= (addrext << BCM43xx_DMA32_DCTL_ADDREXT_SHIFT)		       & BCM43xx_DMA32_DCTL_ADDREXT_MASK;		desc->dma32.control = cpu_to_le32(ctl);

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
666欧美在线视频| 国产欧美一区二区精品婷婷| 欧美一级二级三级蜜桃| 国产精品高潮久久久久无| 日韩高清在线观看| 日韩一区二区三区在线| xnxx国产精品| 亚洲a一区二区| aaa欧美大片| 久久一日本道色综合| 午夜精品在线看| 91国产视频在线观看| 国产精品国产精品国产专区不蜜 | 一区二区激情视频| 国产一区二区三区美女| 欧美酷刑日本凌虐凌虐| 一区二区三区日本| 99久久伊人精品| 国产婷婷一区二区| 国产高清成人在线| 精品国产三级a在线观看| 亚洲gay无套男同| 欧美性一二三区| 一区二区三区四区激情| 色综合一个色综合亚洲| 亚洲视频图片小说| 成人午夜大片免费观看| 国产喂奶挤奶一区二区三区| 国产精品一区二区在线观看不卡| 日韩欧美色综合网站| 日本不卡在线视频| 在线成人av网站| 日本欧美在线观看| 日韩欧美一级二级| 青青草原综合久久大伊人精品| 欧美日韩在线播放| 日韩电影一区二区三区四区| 欧美精品一二三四| 免费人成在线不卡| 91精品国产综合久久久久久漫画| 久久爱另类一区二区小说| 欧美电影一区二区| 精品在线免费视频| 久久综合九色综合欧美就去吻| 老司机精品视频在线| 久久综合九色欧美综合狠狠| 国产精品系列在线观看| 国产欧美一区二区三区网站| 99精品欧美一区二区三区小说 | 欧美激情一区三区| 国产精品91一区二区| 国产精品国产三级国产三级人妇| 成人av影院在线| 亚洲精品综合在线| 91精品国产手机| 国产成人免费在线| 亚洲精品欧美二区三区中文字幕| 欧美日韩一区二区三区在线看| 日韩电影在线一区二区三区| 26uuu色噜噜精品一区二区| 成人免费av资源| 亚洲一卡二卡三卡四卡无卡久久 | 99这里只有久久精品视频| 尤物av一区二区| 日韩久久久久久| 99久久综合色| 日韩成人精品在线| 中文字幕在线观看不卡视频| 欧美日韩国产经典色站一区二区三区| 免费在线欧美视频| 中文字幕亚洲不卡| 日韩欧美一区二区在线视频| 成人av电影在线播放| 天天综合日日夜夜精品| 欧美激情在线看| 日韩一级片网址| 日本久久精品电影| 国产精品自拍av| 亚洲成人福利片| 中文字幕第一区| 欧美一级午夜免费电影| a级高清视频欧美日韩| 免费观看久久久4p| 一区二区三区小说| 中文字幕va一区二区三区| 538在线一区二区精品国产| 99视频有精品| 国产精品一二三四五| 免费看精品久久片| 亚洲一区在线观看免费观看电影高清| 久久精品一区二区三区av| 欧美二区三区的天堂| 色www精品视频在线观看| 国产精品小仙女| 激情综合色播激情啊| 亚洲国产成人av网| 一区二区三区久久| 亚洲你懂的在线视频| 国产日韩av一区| 26uuu另类欧美亚洲曰本| 欧美一区二区三区四区高清| 欧美午夜片在线看| 日本韩国欧美在线| 91亚洲精品久久久蜜桃| 国产91精品一区二区麻豆网站| 久久er99精品| 久久99国产精品久久| 蜜臀精品一区二区三区在线观看| 午夜精品福利在线| 亚洲国产视频在线| 亚洲午夜精品在线| 亚洲影视在线播放| 国产成人亚洲综合色影视| 麻豆精品在线观看| 精品一区二区三区欧美| 久久精品99国产国产精| 免费人成黄页网站在线一区二区 | 韩国中文字幕2020精品| 日本在线不卡一区| 麻豆精品一二三| 麻豆专区一区二区三区四区五区| 免费在线观看视频一区| 另类小说一区二区三区| 精品一二三四区| 国产麻豆一精品一av一免费| 国产精品自拍一区| www.色精品| 91福利视频在线| 91.com视频| 久久综合网色—综合色88| 中文一区在线播放| 最新久久zyz资源站| 亚洲综合999| 日日摸夜夜添夜夜添精品视频| 日本一不卡视频| 国产一区二区三区黄视频| 成人av在线影院| 欧美午夜精品一区二区蜜桃| 日韩欧美中文一区| 久久精品亚洲精品国产欧美kt∨| 国产精品第四页| 亚洲成人免费观看| 国产综合成人久久大片91| 99精品视频一区| 91麻豆精品国产91久久久资源速度| 精品电影一区二区| 亚洲视频一二三区| 日本三级韩国三级欧美三级| 国产成人综合亚洲91猫咪| 在线视频欧美区| 日韩精品一区二区三区四区| 中文字幕一区视频| 日韩高清欧美激情| 高清beeg欧美| 91精品午夜视频| 中文字幕中文字幕一区| 日本亚洲最大的色成网站www| 岛国精品在线播放| 91超碰这里只有精品国产| 欧美国产97人人爽人人喊| 亚洲成av人影院| 成人av资源站| 精品av综合导航| 亚洲第一成年网| 不卡的看片网站| 欧美成人综合网站| 亚洲一区二区三区自拍| 国产一区二区三区精品视频| 欧美日韩精品一区视频| 亚洲国产精品av| 精品在线一区二区| 欧美日韩国产免费一区二区 | 欧美一区二区免费视频| 1000部国产精品成人观看| 国产精品亚洲专一区二区三区 | av一二三不卡影片| 精品国产伦一区二区三区观看体验| 一区二区三区精品| 成人精品小蝌蚪| 国产亚洲婷婷免费| 久久激情五月激情| 欧美一区二区三区免费在线看| 一卡二卡欧美日韩| 91猫先生在线| 国产精品激情偷乱一区二区∴| 国产一区二区三区精品视频| 日韩欧美成人午夜| 日韩黄色在线观看| 欧美精品乱人伦久久久久久| 一区二区国产盗摄色噜噜| 成人美女在线观看| 国产精品日产欧美久久久久| 国产一区二区精品久久| 精品裸体舞一区二区三区| 美女www一区二区| 精品日韩成人av| 精品在线亚洲视频| 久久久久久久久伊人| 国产精品自拍av| 国产日本欧美一区二区|