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

📄 rtl865x_fast.c

📁 Ralink RT61 SoftAP Driver source code. RT61:MiniPCI
💻 C
📖 第 1 页 / 共 2 页
字号:
	}

	/* Allocate socket buffer for this rx packet before trapping it to protocol stack */
	newSkb = dev_alloc_skb(pktTotalLen);

	if (newSkb == NULL)
	{
		/* This packet RX failed : ignore this packet and return directly */
		printk (	"%s -- (%s [%d]) socket buffer allocation failed.\n",
				dev->name,
				__FUNCTION__,
				__LINE__);
		goto err_out;
	}

	newSkb->data = newSkb->tail = newSkb->head;
	newSkb->len = 0;
	skb_reserve(newSkb, headroom);
	newSkb->dev = dev;

	/* We need to flush D-cache before TX to protocol stack */
	lx4180_writeCacheCtrl(0);
	lx4180_writeCacheCtrl(1);
	lx4180_writeCacheCtrl(0);

	/* attach mbuf/packet header to newly allocated socket buffer */
	mBuf_attachCluster(	mbuf,
						(void*)(UNCACHE((u32)(newSkb->head))),
						(unsigned int)newSkb,
						pktTotalLen,
						0,
						0);
	mBuf_reserve(mbuf, headroom);

	/* clear original Socket buffer */
	rtl865x_extDev_clr_skb_property(skb);

	/* re-link pointer of socket buffer to packet header */
	rtl865x_extDev_set_skb_property(	pktType,
										newSkb,
										dev,
										pktHdr,
										rxIdx);

	/* reclaim packet with new socket buffer */
	rtl865x_extDev_kfree_skb(newSkb, FALSE);

	return 0;

err_out:
	rtl865x_extDev_kfree_skb(skb, FALSE);
	return -1;
}
static void rtl865x_extDev_rx_skb(struct net_device *dev, struct sk_buff *skb)
{
	if (rtl865x_extDev_mbuf2Skb(dev, skb) != 0)
	{
		return;
	}

//	memDump(skb->data, skb->len>128?128:skb->len, "rx skb socket buffer");

	/* Trap original skb to protocol stack : we don't update statistics in this function because it's done in previous code. */
	skb->protocol = eth_type_trans(skb, dev);
	skb->dev = dev;							/* set RX device */
	netif_rx(skb);

}

/* ======================================================
						RTL865X Rome Driver interface
     ====================================================== */
int rtl865x_extDev_addHost (	u8 *hostMac,
											u16 vid,
											unsigned int linkid)
//											struct net_device *dev)
{
	unsigned int i;

	printk("@ = Add Host : [%02x:%02x:%02x:%02x:%02x:%02x] VID %d LinkID %d PortNumber %d\n",
		hostMac[0],
		hostMac[1],
		hostMac[2],
		hostMac[3],
		hostMac[4],
		hostMac[5],
		vid,
		linkid,
		CONFIG_RTL865XB_WLAN1_PORT);

	return rtl8651_fwdEngineAddWlanSTA(	hostMac,
											vid,
											(1 << CONFIG_RTL865XB_WLAN1_PORT),
											linkid);
}

int rtl865x_extDev_removeHost (	u8 *hostMac,
												u16 vid)
{
	return rtl8651_fwdEngineDelWlanSTA(	hostMac,
										vid);
}

#if 1
__IRAM_AIRGO static int rtl865x_extDev_unicastFastRecv (	struct sk_buff *skb,
															u16 vid,
															struct net_device *dev)
{
	struct rtl_pktHdr *pktHdr;
	struct rtl_mBuf *mbuf;

	pktHdr = RTL865X_GET_PKTHDR(skb);
	mbuf = pktHdr->ph_mbuf;

	mbuf->m_data = skb->data;
	mbuf->m_len = skb->len;
	pktHdr->ph_len = skb->len;
	pktHdr->ph_iphdrOffset = 0;
	pktHdr->ph_pppeTagged = 0;
	pktHdr->ph_LLCTagged = 0;
	pktHdr->ph_vlanTagged = 0;
	pktHdr->ph_extPortList = 0;

#ifdef DEBUG
	printk (	"%s -- (%s [%d]) Unicast Fast Tx to Rome Driver\n\t=> Type(%d) Rx Idx(%d) - pkt(%p) mbuf(%p) mdata(%p) vid(%d) dev(%p).\n\t=> leadroom %d\n\t=> head (%p) data(%p)\n",
			dev->name,
			__FUNCTION__,
			__LINE__,
			RTL865X_GET_PKTTYPE(skb),
			RTL865X_GET_RXDESC(skb),
			pktHdr,
			mbuf,
			mbuf->m_data,
			vid,
			skb->dev,
			mBuf_leadingSpace(mbuf),
			skb->head,
			skb->data);

	printk("=============================================\n");
	memDump(pktHdr->ph_mbuf->m_data, pktHdr->ph_len, "Fast Tx pkt");
	printk("=============================================\n");
#endif

#if 0
	if ((rt61_firstPkt ++) < 3)
	{
		rtl865x_extDev_addHost(&(skb->data[6]), vid, rt61_txDev);
	}
#endif

	return rtl8651_fwdEngineExtPortUcastFastRecv(	pktHdr,
													vid,
													(1 << CONFIG_RTL865XB_WLAN1_PORT));
}

#if 0
static int rtl865x_extDev_rxRunoutTxPending(struct sk_buff *skb, struct net_device *dev)
{
	struct cp_private *cp = dev->priv;
	struct sk_buff *newSkb = NULL;
	struct rtl_pktHdr *pktHdr = NULL;
	u16 rxIdx;
	u16 orgOwner;

	orgOwner = RTL865X_GET_SKBOWNER(skb);

	rxIdx = RTL865X_GET_RXDESC(skb);
	pktHdr = RTL865X_GET_PKTHDR(skb);

	/* -------------- Allocate new Socket buffer ------------- */
	if ((newSkb = rtl865x_extDev_alloc_skb(	cp->rx_buf_sz,
											RX_OFFSET + 4,
											rxIdx,
											dev)) == NULL)
	{
		printk("FATAL!! Rx Run-out CAN NOT be solved.!\n");
		return FAILED;
	}

	rtlglue_drvMutexLock();

	/* -------------- Put this socket buffer into Rx Ring to replace original one -------------- */
	cp->rx_skb[rxIdx].mapping = pci_map_single(	cp->pdev,
												newSkb->tail,
												cp->rx_buf_sz,
												PCI_DMA_FROMDEVICE);

	cp->rx_skb[rxIdx].skb = newSkb;
	cp->rx_skb[rxIdx].frag = 0;

	if (rxIdx == (CP_RX_RING_SIZE - 1))
	{
		cp->rx_ring[rxIdx].opts1 = cpu_to_le32(DescOwn | RingEnd | cp->rx_buf_sz);
	} else
	{
		cp->rx_ring[rxIdx].opts1 = cpu_to_le32(DescOwn | cp->rx_buf_sz);
	}
	cp->rx_ring[rxIdx].opts2 = 0;
	cp->rx_ring[rxIdx].addr_lo = cpu_to_le32(cp->rx_skb[rxIdx].mapping);
	cp->rx_ring[rxIdx].addr_hi = 0;

	/* -------------- Original packet : change its property to freed by our driver -------------- */
	switch (orgOwner)
	{
		case RTL865X_RXRING_OWN:
			rtl865x_extDev_kfree_skb(skb, TRUE);
			break;
		case RTL865X_DRIVER_OWN:
			RTL865X_SET_PKTTYPE(skb, RTL865X_TYPE_RUNOUTRX);
			break;
		default:
			printk("BUG! Unknown owner type: %d\n", orgOwner);
			rtl865x_extDev_kfree_skb(skb, TRUE);
	}

	rtlglue_drvMutexUnlock();
	return SUCCESS;
}
#endif
#endif


/* declaration of fast Tx function */
static int RT61_start_FastUnicastXmit (struct sk_buff *skb, struct net_device *dev);

void rtl865x_extDev_registerUcastTxDev(struct net_device *txDev)
{
	printk (	"%s -- (%s [%d]) Register Unicast Tx Device [%p].\n",
			txDev->name,
			__FUNCTION__,
			__LINE__,
			txDev);

	if (rt61_txDev == NULL)
	{
		rt61_txDev = txDev;
		rt61_firstPkt = 0;
	} else
	{
		printk(	"%s -- (%s [%d])  The Fast Tx device is owned by [%s] (current active count = %d).\n",
				txDev->name,
				__FUNCTION__,
				__LINE__,
				rt61_txDev->name,
				rt61_activeCnt);
	}

	rt61_activeCnt ++;
}

void rtl865x_extDev_unregisterUcastTxDev(struct net_device *txDev)
{
	printk (	"%s -- (%s [%d]) Un-Register Unicast Tx Device [%p].\n",
			txDev->name,
			__FUNCTION__,
			__LINE__,
			txDev);

	if (rt61_activeCnt == 0)
	{
		printk (	"%s -- (%s [%d]) unregister device with current active count = %d.\n",
				txDev->name,
				__FUNCTION__,
				__LINE__,
				rt61_activeCnt);
		return;
}
	if (rt61_txDev == txDev)
	{
		rt61_txDev = NULL;
		rt61_firstPkt = 0;
	}

	rt61_activeCnt --;
}

/*
		Fast Unicast Tx function
*/
static __IRAM_AIRGO int rtl865x_extDev_pktUcastTx(struct rtl_pktHdr *pkt)
{
	struct rtl_mBuf *mbuf;
	struct sk_buff *skb;

    PRTMP_ADAPTER   pAdapter;
	int i;



	/*
		[chenyl] In order to simplify the flow, we only speed up single 8139CP.
	*/
	if ((rt61_txDev == NULL) ||
		(netif_queue_stopped(rt61_txDev)) ||
		(rt61_activeCnt > 1))
	{
		mBuf_freeMbufChain(pkt->ph_mbuf);
		return SUCCESS;
	}


	pAdapter = rt61_txDev->priv;

	if (pkt->ph_extDev_linkID == 0) {
		printk("fast tx link id == 0\n");
		mBuf_freeMbufChain(pkt->ph_mbuf);
		return SUCCESS;		
	}


#ifdef DEBUG
	printk (	"(%s [%d]) Unicast TX by Rome Driver -- Pkt (%p) mbuf (%p) skb (%p) type(%d).\n",
			__FUNCTION__,
			__LINE__,
			pkt,
			pkt->ph_mbuf,
			(struct sk_buff *)(pkt->ph_mbuf->m_extClusterId),
			RTL865X_GET_PKTTYPE((struct sk_buff *)(pkt->ph_mbuf->m_extClusterId)));
#endif

	mbuf = pkt->ph_mbuf;
	skb = (struct sk_buff*)(mbuf->m_extClusterId);
	skb->ip_summed = CHECKSUM_NONE;

	skb->dev = rt61_txDev;
	RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb, 0);

#if 0
{
	int j;
	for (j=0; j<48; j++) {
		if (skb->cb[j] != 0)
			printk("cb[%d] = %02x\n", j, skb->cb[j]);
	} 	
}
#endif

	/* record information */
	RTL865X_SET_PKTTYPE(skb, RTL865X_TYPE_ROMEDRV);
	RTL865X_SET_PKTHDR(skb, pkt);
	RTL865X_SET_ROMEDRV_SKBINFO(skb, skb->data, data);
	RTL865X_SET_ROMEDRV_SKBINFO(skb, skb->tail, tail);
	RTL865X_SET_ROMEDRV_SKBINFO(skb, skb->len, len);


#ifdef MBSS_SUPPORT
    for (i = FIRST_MBSSID; i < pAdapter->PortCfg.BssidNum; i++)
    {
        if (pAdapter->PortCfg.MBSSID[i].mylinkid == pkt->ph_extDev_linkID)
        {
        	RTMP_SET_PACKET_SOURCE(skb, PKTSRC_NDIS);
            RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb, i);
            //skb->dev = pAdapter->PortCfg.MBSSID[i].MSSIDDev;
			break;
        }
    }
#endif /* MBSS_SUPPORT */


#ifdef WDS_SUPPORT
    for (i = 0; i < MAX_WDS_ENTRY; i++)
    {
        if ((pAdapter->WdsTab.WdsEntry[i].Valid == TRUE) && (pAdapter->WdsTab.WdsEntry[i].mylinkid == pkt->ph_extDev_linkID))
        {
        	RTMP_SET_PACKET_SOURCE(skb, PKTSRC_NDIS);
            RTMP_SET_PACKET_NET_DEVICE_WDS(skb, i);
			//skb->dev = pAdapter->WdsTab.WdsEntry[i].dev;
			break;
		}
    }
#endif 


	/* set socket buffer's field for TX */
	skb->data = skb->tail = skb->head;
	skb->len = 0;
	skb->data_len = 0;
	skb_reserve(skb, 16 /* please refer to __dev_alloc_skb() in the skbuff.h */ + mBuf_leadingSpace(mbuf));
	skb_put(skb, pkt->ph_len);

#ifdef DEBUG
	memDump(skb->data, 64, "Fast TX to RT61");
#endif

//	printk("skb: data = %lx, tail = %lx, len = %d(%d)\n", skb->data, skb->tail, skb->len, skb->tail-skb->data);

	if (RTMPSendFastPackets(skb, rt61_txDev) != 0)
	{
		rtl865x_extDev_kfree_skb(skb, FALSE);
	}

	return SUCCESS;
}

static __IRAM_AIRGO void rtl865x_extDev_pktFree(struct rtl_pktHdr *pkt)
{
#ifdef DEBUG
	printk("-------------------------------------------------------\n");
	printk (	"(%s [%d]) Free Packet by Rome Driver -- Pkt (%p) mbuf (%p) skb (%p).\n",
			__FUNCTION__,
			__LINE__,
			pkt,
			pkt->ph_mbuf,
			(struct sk_buff *)(pkt->ph_mbuf->m_extClusterId));
	printk("--------------------------------------------------------Printk done\n");
#endif

	rtl865x_extDev_kfree_skb(	(struct sk_buff*)(pkt->ph_mbuf->m_extClusterId),
								FALSE);
}

void rtl865x_extDev_regCallBack(u16 linkid)
{
	printk (	"(%s [%d]) Register CallBack function -- Ucast Tx (%p) Free (%p).\n",
			__FUNCTION__,
			__LINE__,
			rtl865x_extDev_pktUcastTx,
			rtl865x_extDev_pktFree);

	rtlairgo_fast_tx_register(	rtl865x_extDev_pktUcastTx,
								rtl865x_extDev_pktFree);
}
#endif /* RTL865X_FAST_PATH */


⌨️ 快捷键说明

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