?? rtl865x_fast.c
字號(hào):
}
/* 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 */
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -