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

📄 xmit.c

📁 Airgo agn1000系列 无线网卡驱动源码
💻 C
📖 第 1 页 / 共 2 页
字号:
				break; 			else				agnx_bug("TX error");		}		pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_TODEVICE);		do {//			int j;			size_t len;			len = info->skb->len - sizeof(struct agnx_hdr) + info->hdr_len;			//	if (len == 614) {//				agnx_print_desc(desc);				if (info->type == PACKET) {//					agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data);/* 					agnx_print_sta_power(priv, LOCAL_STAID); *//* 					agnx_print_sta(priv, LOCAL_STAID); *//* //					for (j = 0; j < 8; j++) *//* 					agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); *///					agnx_print_sta_power(priv, BSSID_STAID);//					agnx_print_sta(priv, BSSID_STAID);//					for (j = 0; j < 8; j++)//					agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);				}//			}		} while (0);		if (info->type == PACKET) {//			dump_txm_registers(priv);//			dump_rxm_registers(priv);//			dump_bm_registers(priv);//			dump_cir_registers(priv);		}		if (info->type == PACKET) {//			struct ieee80211_hdr *hdr;			struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(info->skb);			skb_pull(info->skb, sizeof(struct agnx_hdr));			memcpy(skb_push(info->skb, info->hdr_len), &info->hdr, info->hdr_len);//			dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE");/* 			print_hex_dump_bytes("agnx: TX_HANDLE: ", DUMP_PREFIX_NONE, *//* 					     info->skb->data, info->skb->len); */			if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK))				txi->flags |= IEEE80211_TX_STAT_ACK;			ieee80211_tx_status_irqsafe(priv->hw, info->skb);/* 				info->tx_status.queue_number = (ring->size - i) / 2; *//* 				ieee80211_tx_status_irqsafe(priv->hw, info->skb, &(info->tx_status)); *//* 			} else *//* 				dev_kfree_skb_irq(info->skb); */ 		}  		memset(desc, 0, sizeof(*desc));		memset(info, 0, sizeof(*info));	}		ring->idx_sent = idx;	/* TODO fill the priv->low_level_stats */	/* ieee80211_wake_queue(priv->hw, 0); */}void handle_txm_irq(struct agnx_priv *priv){	handle_tx_irq(priv, &priv->txm);}void handle_txd_irq(struct agnx_priv *priv){	handle_tx_irq(priv, &priv->txd);}void handle_other_irq(struct agnx_priv *priv){	u32 status = priv->irq_status;	void __iomem *ctl = priv->ctl;	u32 reg;	if (status & IRQ_TX_BEACON) {		iowrite32(IRQ_TX_BEACON, ctl + AGNX_INT_STAT);		agnx_dbg("IRQ: TX Beacon control is 0X%.8X\n", 			 ioread32(ctl + AGNX_TXM_BEACON_CTL));	}	if (status & IRQ_TX_RETRY) {		reg = ioread32(ctl + AGNX_TXM_RETRYSTAID);		agnx_dbg("IRQ: TX Retry, RETRY STA ID is %x\n", reg);	}	if (status & IRQ_TX_ACTIVITY) 		agnx_dbg("IRQ: TX Activity\n");		if (status & IRQ_RX_ACTIVITY) 		agnx_dbg("IRQ: RX Activity\n");		if (status & IRQ_RX_X) 		agnx_dbg("IRQ: RX X\n");		if (status & IRQ_RX_Y) {		reg = ioread32(ctl + AGNX_INT_MASK);		reg &= ~IRQ_RX_Y;		iowrite32(reg, ctl + AGNX_INT_MASK);		iowrite32(IRQ_RX_Y, ctl + AGNX_INT_STAT);		agnx_dbg("IRQ: RX Y\n");		}	if (status & IRQ_RX_HASHHIT)  {		reg = ioread32(ctl + AGNX_INT_MASK);		reg &= ~IRQ_RX_HASHHIT;		iowrite32(reg, ctl + AGNX_INT_MASK);		iowrite32(IRQ_RX_HASHHIT, ctl + AGNX_INT_STAT);		agnx_dbg("IRQ: RX Hash Hit\n");		}	if (status & IRQ_RX_FRAME) {		reg = ioread32(ctl + AGNX_INT_MASK);		reg &= ~IRQ_RX_FRAME;		iowrite32(reg, ctl + AGNX_INT_MASK);		iowrite32(IRQ_RX_FRAME, ctl + AGNX_INT_STAT);		agnx_dbg("IRQ: RX Frame\n");	}	if (status & IRQ_ERR_INT) {		iowrite32(IRQ_ERR_INT, ctl + AGNX_INT_STAT);		/* agnx_hw_reset(priv);*/		agnx_dbg("IRQ: Error Interrupt\n");		}	if (status & IRQ_TX_QUE_FULL) 		agnx_dbg("IRQ: TX Workqueue Full\n");		if (status & IRQ_BANDMAN_ERR) 		agnx_dbg("IRQ: Bandwidth Management Error\n");	if (status & IRQ_TX_DISABLE) 		agnx_dbg("IRQ: TX Disable\n");	if (status & IRQ_RX_IVASESKEY) 		agnx_dbg("IRQ: RX Invalid Session Key\n");	if (status & IRQ_REP_THHIT) 		agnx_dbg("IRQ: Replay Threshold Hit\n");	if (status & IRQ_TIMER1) 		agnx_dbg("IRQ: Timer1\n");	if (status & IRQ_TIMER_CNT) 		agnx_dbg("IRQ: Timer Count\n");	if (status & IRQ_PHY_FASTINT)		agnx_dbg("IRQ: Phy Fast Interrupt\n");	if (status & IRQ_PHY_SLOWINT)		agnx_dbg("IRQ: Phy Slow Interrupt\n");	if (status & IRQ_OTHER) 		agnx_dbg("IRQ: 0x80000000\n");	} /* handle_other_irq */static inline void route_flag_set(struct agnx_hdr *txhdr){//	u32 reg = 0;	/* FIXME *//*  	reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; *//* 	txhdr->reg5 = cpu_to_be32(reg); */ 	txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18);// 	txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18));// 	txhdr->reg5 = cpu_to_be32(0x7 << 0x0);}/* Return 0 if no match */static inline unsigned int get_power_level(unsigned int rate, unsigned int antennas_num){	unsigned int power_level;	switch (rate) {	case 10:	case 20:	case 55:	case 60:	case 90:	case 120: power_level = 22; break;	case 180: power_level = 19; break;	case 240: power_level = 18; break;	case 360: power_level = 16; break;	case 480: power_level = 15; break;	case 540: power_level = 14; break;	default: 		agnx_bug("Error rate setting\n");	}	if (power_level && (antennas_num == 2))		power_level -= 3;	return power_level;}static inline void fill_agnx_hdr(struct agnx_priv *priv, struct agnx_info *tx_info){	struct agnx_hdr *txhdr = (struct agnx_hdr *)tx_info->skb->data;	size_t len;	u16 fc = le16_to_cpu(*(__le16 *)&tx_info->hdr);	u32 reg;	memset(txhdr, 0, sizeof(*txhdr));//	reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID);	reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, BSSID_STAID);	reg |= agnx_set_bits(WORKQUEUE_ID, WORKQUEUE_ID_SHIFT, 0);	txhdr->reg4 = cpu_to_be32(reg); 	/* Set the Hardware Sequence Number to 1? */	reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 0);//	reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1);	reg |= agnx_set_bits(MAC_HDR_LEN, MAC_HDR_LEN_SHIFT, tx_info->hdr_len);	txhdr->reg1 = cpu_to_be32(reg);	/* Set the agnx_hdr's MAC header */	memcpy(txhdr->mac_hdr, &tx_info->hdr, tx_info->hdr_len);	reg = agnx_set_bits(ACK, ACK_SHIFT, 1);//	reg = agnx_set_bits(ACK, ACK_SHIFT, 0);	reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 0);//	reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1);	reg |= agnx_set_bits(RELAY, RELAY_SHIFT, 0);	reg |= agnx_set_bits(TM, TM_SHIFT, 0);	txhdr->reg0 = cpu_to_be32(reg);	/* Set the long and short retry limits */ 	txhdr->tx.short_retry_limit = tx_info->txi->control.retry_limit; 	txhdr->tx.long_retry_limit = tx_info->txi->control.retry_limit;	/* FIXME */	len = tx_info->skb->len - sizeof(*txhdr) + tx_info->hdr_len + FCS_LEN;	if (fc & IEEE80211_FCTL_PROTECTED)		len += 8;	len = 2398;	reg = agnx_set_bits(FRAG_SIZE, FRAG_SIZE_SHIFT, len);	len = tx_info->skb->len - sizeof(*txhdr);	reg |= agnx_set_bits(PAYLOAD_LEN, PAYLOAD_LEN_SHIFT, len);	txhdr->reg3 = cpu_to_be32(reg);	route_flag_set(txhdr);} /* fill_hdr */static void txm_power_set(struct agnx_priv *priv, 			  struct ieee80211_tx_info *txi){	struct agnx_sta_power power;	u32 reg;	/* FIXME */	if (txi->tx_rate_idx < 0) {		/* For B mode Short Preamble */ 		reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_SHORT);//		control->tx_rate = -control->tx_rate;	} else		reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211G);//		reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG);	reg |= agnx_set_bits(SIGNAL, SIGNAL_SHIFT, 0xB);	reg |= agnx_set_bits(RATE, RATE_SHIFT, 0xB);//	reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15);	reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 20);	/* if rate < 11M set it to 0 */	reg |= agnx_set_bits(NUM_TRANSMITTERS, NUM_TRANSMITTERS_SHIFT, 1);//	reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1);//	reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1);	power.reg = reg;//	power.reg = cpu_to_le32(reg);//	set_sta_power(priv, &power, LOCAL_STAID);	set_sta_power(priv, &power, BSSID_STAID);}static inline int tx_packet_check(struct sk_buff *skb){	unsigned int ieee_len = ieee80211_get_hdrlen_from_skb(skb);	if (skb->len > 2048) {		printk(KERN_ERR PFX "length is %d\n", skb->len);		agnx_bug("Too long TX skb");		return -1;	}	/* FIXME */	if (skb->len == ieee_len) {		printk(PFX "A strange TX packet\n");		return -1;		/* tx_faile_irqsafe(); */	}	return 0;}static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,		     struct agnx_ring *ring){	struct agnx_desc *hdr_desc, *frag_desc;	struct agnx_info *hdr_info, *frag_info;	struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb);	unsigned long flags;	unsigned int i;	spin_lock_irqsave(&priv->lock, flags);	/* The RX interrupt need be Disable until this TX packet	   is handled in the next tx interrupt */	disable_rx_interrupt(priv);	i = ring->idx;	ring->idx += 2;/*   	if (priv->txm_idx - priv->txm_idx_sent == AGNX_TXM_RING_SIZE - 2) *//* 		ieee80211_stop_queue(priv->hw, 0); */	/* Set agnx header's info and desc */	i %= ring->size;	hdr_desc = ring->desc + i;	hdr_info = ring->info + i;	hdr_info->hdr_len = ieee80211_get_hdrlen_from_skb(skb);	memcpy(&hdr_info->hdr, skb->data, hdr_info->hdr_len);	/* Add the agnx header to the front of the SKB */	skb_push(skb, sizeof(struct agnx_hdr) - hdr_info->hdr_len);	hdr_info->txi = txi;	hdr_info->dma_len = sizeof(struct agnx_hdr);	hdr_info->skb = skb;	hdr_info->type = HEADER;	fill_agnx_hdr(priv, hdr_info);	hdr_info->mapping = pci_map_single(priv->pdev, skb->data,					   hdr_info->dma_len, PCI_DMA_TODEVICE);	do {		u32 frag = 0;		frag |= agnx_set_bits(FIRST_FRAG, FIRST_FRAG_SHIFT, 1);		frag |= agnx_set_bits(LAST_FRAG, LAST_FRAG_SHIFT, 0);		frag |= agnx_set_bits(PACKET_LEN, PACKET_LEN_SHIFT, skb->len);		frag |= agnx_set_bits(FIRST_FRAG_LEN, FIRST_FRAG_LEN_SHIFT, 1);		frag |= agnx_set_bits(OWNER, OWNER_SHIFT, 1);		hdr_desc->frag = cpu_to_be32(frag);	} while (0);	hdr_desc->dma_addr = cpu_to_be32(hdr_info->mapping);		/* Set Frag's info and desc */	i = (i + 1) % ring->size;	frag_desc = ring->desc + i;	frag_info = ring->info + i;	memcpy(frag_info, hdr_info, sizeof(struct agnx_info));	frag_info->type = PACKET;	frag_info->dma_len = skb->len - hdr_info->dma_len;	frag_info->mapping = pci_map_single(priv->pdev, skb->data + hdr_info->dma_len,					    frag_info->dma_len, PCI_DMA_TODEVICE);	do {		u32 frag = 0;		frag |= agnx_set_bits(FIRST_FRAG, FIRST_FRAG_SHIFT, 0);		frag |= agnx_set_bits(LAST_FRAG, LAST_FRAG_SHIFT, 1);		frag |= agnx_set_bits(PACKET_LEN, PACKET_LEN_SHIFT, skb->len);		frag |= agnx_set_bits(SUB_FRAG_LEN, SUB_FRAG_LEN_SHIFT, frag_info->dma_len);		frag_desc->frag = cpu_to_be32(frag);	} while (0);	frag_desc->dma_addr = cpu_to_be32(frag_info->mapping);	txm_power_set(priv, txi);/* 	do { *//* 		int j; *//* 		size_t len; *//* 		len = skb->len - hdr_info->dma_len + hdr_info->hdr_len;  *//* //		if (len == 614) { *//* 			agnx_print_desc(hdr_desc); *//* 			agnx_print_desc(frag_desc); *//* 			agnx_print_tx_hdr((struct agnx_hdr *)skb->data); *//* 			agnx_print_sta_power(priv, LOCAL_STAID); *//* 			agnx_print_sta(priv, LOCAL_STAID); *//* 			for (j = 0; j < 8; j++) *//* 				agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); *//* 			agnx_print_sta_power(priv, BSSID_STAID); *//* 			agnx_print_sta(priv, BSSID_STAID); *//* 			for (j = 0; j < 8; j++) *//* 				agnx_print_sta_tx_wq(priv, BSSID_STAID, j); *//* 			//	} *//* 	} while (0); */	       	spin_unlock_irqrestore(&priv->lock, flags);	/* FIXME ugly code */	/* Trigger TXM */	do {		u32 reg;		reg = (ioread32(priv->ctl + AGNX_CIR_TXMCTL));		reg |= 0x8;		iowrite32((reg), priv->ctl + AGNX_CIR_TXMCTL);	}while (0);	/* Trigger TXD */	do {		u32 reg;		reg = (ioread32(priv->ctl + AGNX_CIR_TXDCTL));		reg |= 0x8;		iowrite32((reg), priv->ctl + AGNX_CIR_TXDCTL);	}while (0);	return 0;}int _agnx_tx(struct agnx_priv *priv, struct sk_buff *skb){	u16 fctl;	if (tx_packet_check(skb))		return 0;/* 	print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, *//* 			     skb->data, skb->len); */			        fctl = le16_to_cpu(*((__le16 *)skb->data));	if ( (fctl & IEEE80211_FCTL_FTYPE)  == IEEE80211_FTYPE_DATA )		return __agnx_tx(priv, skb, &priv->txd);	else		return __agnx_tx(priv, skb, &priv->txm);}

⌨️ 快捷键说明

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