亚洲欧美第一页_禁久久精品乱码_粉嫩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一区二区三区免费野_久草精品视频
亚洲视频免费看| 麻豆高清免费国产一区| 久久不见久久见中文字幕免费| 成人av电影观看| 精品三级在线看| 图片区日韩欧美亚洲| 91在线观看美女| 国产欧美一区二区精品久导航| 午夜国产精品一区| 色哟哟在线观看一区二区三区| 国产日产欧美一区二区三区| 免费成人性网站| 欧美日韩一区二区三区四区五区| 国产精品久久夜| 风流少妇一区二区| 国产亲近乱来精品视频| 国内精品不卡在线| 日韩欧美国产三级| 视频一区二区三区在线| 欧美日韩亚洲不卡| 亚洲成人先锋电影| 欧美日韩中文字幕精品| 亚洲国产欧美一区二区三区丁香婷| 97久久人人超碰| 国产精品精品国产色婷婷| 国产69精品一区二区亚洲孕妇| 精品久久久久久亚洲综合网| 久久精品av麻豆的观看方式| 91精品国产综合久久蜜臀| 亚洲成a人v欧美综合天堂下载| 91成人免费在线| 亚洲风情在线资源站| 欧美三级乱人伦电影| 爽爽淫人综合网网站| 91精品国产综合久久精品| 日韩av电影一区| 精品国产一二三区| 国产九九视频一区二区三区| 国产午夜精品一区二区三区嫩草| 国产成人免费视频网站高清观看视频| 久久久久久免费网| 成人一区在线观看| 亚洲精品国产一区二区精华液| 一本色道久久综合亚洲精品按摩| 亚洲精品成人在线| 欧美在线三级电影| 美女网站色91| 久久久久久久久久久99999| 成人免费视频国产在线观看| 亚洲激情男女视频| 欧美欧美欧美欧美| 韩日欧美一区二区三区| 国产精品久久一卡二卡| 欧美亚洲综合一区| 老司机精品视频线观看86| 久久综合久久综合亚洲| 成人av电影在线播放| 亚洲一区日韩精品中文字幕| 欧美精品1区2区| 国产成人一区在线| 一区二区不卡在线视频 午夜欧美不卡在| 欧美日精品一区视频| 国产成人精品免费看| 亚洲视频免费在线观看| 日韩午夜激情av| fc2成人免费人成在线观看播放| 亚洲精品高清在线| 精品国产乱码久久久久久闺蜜 | 久久一区二区三区四区| 91在线视频网址| 美国欧美日韩国产在线播放| 国产精品夫妻自拍| 日韩欧美一级片| 色综合天天天天做夜夜夜夜做| 麻豆国产欧美日韩综合精品二区 | 国产精品一区二区久久精品爱涩 | 国产精品视频第一区| 欧美美女黄视频| 99视频精品全部免费在线| 裸体健美xxxx欧美裸体表演| 亚洲区小说区图片区qvod| 欧美精品一区二区久久婷婷| 在线观看视频一区二区| 国产不卡视频在线播放| 秋霞国产午夜精品免费视频| 玉米视频成人免费看| 国产网站一区二区| 日韩精品一区二区在线观看| 欧美日韩一区二区在线观看| 99国产欧美另类久久久精品| 精品一区二区免费| 日本欧美一区二区在线观看| 一二三四区精品视频| 成人免费在线播放视频| wwwwww.欧美系列| 日韩一区二区三区视频在线| 欧美日韩一区二区三区不卡| 91美女精品福利| 懂色av中文字幕一区二区三区| 狠狠色狠狠色合久久伊人| 亚洲成在线观看| 一个色在线综合| 亚洲综合小说图片| 亚洲乱码国产乱码精品精可以看| 国产精品美女久久久久久久久| 久久久欧美精品sm网站| 久久夜色精品国产噜噜av| 日韩免费看网站| 日韩精品一区二区三区蜜臀 | 国产亚洲精品精华液| 精品国产伦一区二区三区观看体验| 欧美浪妇xxxx高跟鞋交| 欧美久久久久久久久| 欧美精品乱人伦久久久久久| 欧美日韩国产成人在线免费| 欧美日韩午夜在线视频| 91麻豆精品国产91久久久资源速度 | 欧美日韩情趣电影| 777欧美精品| 日韩一二在线观看| 精品福利一二区| 国产亚洲一本大道中文在线| 国产精品日韩成人| 亚洲视频香蕉人妖| 午夜精品视频在线观看| 男人的j进女人的j一区| 精品一区二区三区免费毛片爱| 精品一区二区三区不卡| 国产成人综合在线播放| 99国产精品99久久久久久| 一本大道综合伊人精品热热| 欧美一级在线视频| 日韩三级av在线播放| 久久久综合九色合综国产精品| 亚洲另类色综合网站| 精品一区二区免费| 国产91精品久久久久久久网曝门| 国产凹凸在线观看一区二区| 不卡av电影在线播放| 欧美午夜精品一区二区三区| 91精品国产一区二区三区蜜臀| 久久蜜桃一区二区| 亚洲精品日韩专区silk| 日韩电影一二三区| 亚洲成在人线在线播放| 懂色av一区二区三区免费观看 | 国产精品第一页第二页第三页| 久久超碰97人人做人人爱| 欧美日本精品一区二区三区| 亚洲人成人一区二区在线观看| 国产很黄免费观看久久| 欧美大尺度电影在线| 日本va欧美va精品| 欧美日产国产精品| 亚洲成av人片一区二区| 日本高清无吗v一区| 国产精品免费丝袜| www.色精品| 国产精品国产三级国产aⅴ无密码| 国产高清一区日本| 日本一区二区三区视频视频| 国产精品123区| 久久久久久夜精品精品免费| 国产精品一级片在线观看| 久久综合久久综合亚洲| 国产精品亚洲午夜一区二区三区| 亚洲精品在线观看网站| 国精产品一区一区三区mba视频| 欧美一区二区观看视频| 麻豆成人av在线| 欧美变态tickling挠脚心| 极品美女销魂一区二区三区| 久久尤物电影视频在线观看| 国产乱码精品一区二区三区忘忧草| 精品粉嫩超白一线天av| 国产精品88av| 亚洲欧美综合另类在线卡通| 色美美综合视频| 亚洲自拍另类综合| 69久久99精品久久久久婷婷 | 国产午夜精品一区二区| 成人午夜视频免费看| 亚洲女厕所小便bbb| 欧美体内she精高潮| 免费亚洲电影在线| 精品国产91九色蝌蚪| 成+人+亚洲+综合天堂| 伊人色综合久久天天人手人婷| 欧美日韩日日夜夜| 美国十次了思思久久精品导航| 久久久久国产精品麻豆ai换脸| 成人免费三级在线| 亚洲韩国精品一区| 精品福利视频一区二区三区| 99国产精品久久久久久久久久| 亚洲韩国精品一区| 久久久国产精华| 在线视频中文字幕一区二区| 看国产成人h片视频| 中文字幕一区二区5566日韩|