本文整理汇总了C++中NEXT_TX函数的典型用法代码示例。如果您正苦于以下问题:C++ NEXT_TX函数的具体用法?C++ NEXT_TX怎么用?C++ NEXT_TX使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了NEXT_TX函数的17个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: greth_start_xmit
static netdev_tx_t
greth_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct greth_private *greth = netdev_priv(dev);
struct greth_bd *bdp;
int err = NETDEV_TX_OK;
u32 status, dma_addr, ctrl;
unsigned long flags;
/* Clean TX Ring */
greth_clean_tx(greth->netdev);
if (unlikely(greth->tx_free <= 0)) {
spin_lock_irqsave(&greth->devlock, flags);/*save from poll/irq*/
ctrl = GRETH_REGLOAD(greth->regs->control);
/* Enable TX IRQ only if not already in poll() routine */
if (ctrl & GRETH_RXI)
GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI);
netif_stop_queue(dev);
spin_unlock_irqrestore(&greth->devlock, flags);
return NETDEV_TX_BUSY;
}
if (netif_msg_pktdata(greth))
greth_print_tx_packet(skb);
if (unlikely(skb->len > MAX_FRAME_SIZE)) {
dev->stats.tx_errors++;
goto out;
}
bdp = greth->tx_bd_base + greth->tx_next;
dma_addr = greth_read_bd(&bdp->addr);
memcpy((unsigned char *) phys_to_virt(dma_addr), skb->data, skb->len);
dma_sync_single_for_device(greth->dev, dma_addr, skb->len, DMA_TO_DEVICE);
status = GRETH_BD_EN | GRETH_BD_IE | (skb->len & GRETH_BD_LEN);
greth->tx_bufs_length[greth->tx_next] = skb->len & GRETH_BD_LEN;
/* Wrap around descriptor ring */
if (greth->tx_next == GRETH_TXBD_NUM_MASK) {
status |= GRETH_BD_WR;
}
greth->tx_next = NEXT_TX(greth->tx_next);
greth->tx_free--;
/* Write descriptor control word and enable transmission */
greth_write_bd(&bdp->stat, status);
spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
greth_enable_tx(greth);
spin_unlock_irqrestore(&greth->devlock, flags);
out:
dev_kfree_skb(skb);
return err;
}
开发者ID:CSCLOG,项目名称:beaglebone,代码行数:60,代码来源:greth.c
示例2: kick_tx
static inline void kick_tx(struct net_device *dev,
struct sgiseeq_private *sp,
struct hpc3_ethregs *hregs)
{
struct sgiseeq_tx_desc *td;
int i = sp->tx_old;
/* If the HPC aint doin nothin, and there are more packets
* with ETXD cleared and XIU set we must make very certain
* that we restart the HPC else we risk locking up the
* adapter. The following code is only safe iff the HPCDMA
* is not active!
*/
td = &sp->tx_desc[i];
dma_sync_desc_cpu(dev, td);
while ((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) ==
(HPCDMA_XIU | HPCDMA_ETXD)) {
i = NEXT_TX(i);
td = &sp->tx_desc[i];
dma_sync_desc_cpu(dev, td);
}
if (td->tdma.cntinfo & HPCDMA_XIU) {
hregs->tx_ndptr = VIRT_TO_DMA(sp, td);
hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
}
}
开发者ID:Medvedroid,项目名称:OT_903D-kernel-2.6.35.7,代码行数:26,代码来源:sgiseeq.c
示例3: sgiseeq_tx
static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp,
struct hpc3_ethregs *hregs,
struct sgiseeq_regs *sregs)
{
struct sgiseeq_tx_desc *td;
unsigned long status = hregs->tx_ctrl;
int j;
tx_maybe_reset_collisions(sp, sregs);
if (!(status & (HPC3_ETXCTRL_ACTIVE | SEEQ_TSTAT_PTRANS))) {
/* Oops, HPC detected some sort of error. */
if (status & SEEQ_TSTAT_R16)
dev->stats.tx_aborted_errors++;
if (status & SEEQ_TSTAT_UFLOW)
dev->stats.tx_fifo_errors++;
if (status & SEEQ_TSTAT_LCLS)
dev->stats.collisions++;
}
/* Ack 'em... */
for (j = sp->tx_old; j != sp->tx_new; j = NEXT_TX(j)) {
td = &sp->tx_desc[j];
dma_sync_desc_cpu(dev, td);
if (!(td->tdma.cntinfo & (HPCDMA_XIU)))
break;
if (!(td->tdma.cntinfo & (HPCDMA_ETXD))) {
if (!(status & HPC3_ETXCTRL_ACTIVE)) {
hregs->tx_ndptr = VIRT_TO_DMA(sp, td);
hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
}
break;
}
dev->stats.tx_packets++;
sp->tx_old = NEXT_TX(sp->tx_old);
td->tdma.cntinfo &= ~(HPCDMA_XIU | HPCDMA_XIE);
td->tdma.cntinfo |= HPCDMA_EOX;
if (td->skb) {
dev_kfree_skb_any(td->skb);
td->skb = NULL;
}
dma_sync_desc_dev(dev, td);
}
}
开发者ID:KaZoom,项目名称:buildroot-linux-kernel-m3,代码行数:45,代码来源:sgiseeq.c
示例4: cp_tx
static void cp_tx (struct cp_private *cp)
{
unsigned tx_head = cp->tx_head;
unsigned tx_tail = cp->tx_tail;
while (tx_tail != tx_head) {
struct sk_buff *skb;
u32 status;
rmb();
status = le32_to_cpu(cp->tx_ring[tx_tail].opts1);
if (status & DescOwn)
break;
skb = cp->tx_skb[tx_tail].skb;
if (!skb)
BUG();
pci_unmap_single(cp->pdev, cp->tx_skb[tx_tail].mapping,
skb->len, PCI_DMA_TODEVICE);
if (status & LastFrag) {
if (status & (TxError | TxFIFOUnder)) {
if (netif_msg_tx_err(cp))
printk(KERN_DEBUG "%s: tx err, status 0x%x\n",
cp->dev->name, status);
cp->net_stats.tx_errors++;
if (status & TxOWC)
cp->net_stats.tx_window_errors++;
if (status & TxMaxCol)
cp->net_stats.tx_aborted_errors++;
if (status & TxLinkFail)
cp->net_stats.tx_carrier_errors++;
if (status & TxFIFOUnder)
cp->net_stats.tx_fifo_errors++;
} else {
cp->net_stats.collisions +=
((status >> TxColCntShift) & TxColCntMask);
cp->net_stats.tx_packets++;
cp->net_stats.tx_bytes += skb->len;
if (netif_msg_tx_done(cp))
printk(KERN_DEBUG "%s: tx done, slot %d\n", cp->dev->name, tx_tail);
}
dev_kfree_skb_irq(skb);
}
cp->tx_skb[tx_tail].skb = NULL;
tx_tail = NEXT_TX(tx_tail);
}
cp->tx_tail = tx_tail;
if (TX_BUFFS_AVAIL(cp) > (MAX_SKB_FRAGS + 1))
netif_wake_queue(cp->dev);
}
开发者ID:OpenHMR,项目名称:Open-HMR600,代码行数:56,代码来源:8139cp.c
示例5: qe_start_xmit
/* Get a packet queued to go onto the wire. */
static int qe_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct sunqe *qep = netdev_priv(dev);
struct sunqe_buffers *qbufs = qep->buffers;
__u32 txbuf_dvma, qbufs_dvma = qep->buffers_dvma;
unsigned char *txbuf;
int len, entry;
spin_lock_irq(&qep->lock);
qe_tx_reclaim(qep);
len = skb->len;
entry = qep->tx_new;
txbuf = &qbufs->tx_buf[entry & (TX_RING_SIZE - 1)][0];
txbuf_dvma = qbufs_dvma +
qebuf_offset(tx_buf, (entry & (TX_RING_SIZE - 1)));
/* Avoid a race... */
qep->qe_block->qe_txd[entry].tx_flags = TXD_UPDATE;
skb_copy_from_linear_data(skb, txbuf, len);
qep->qe_block->qe_txd[entry].tx_addr = txbuf_dvma;
qep->qe_block->qe_txd[entry].tx_flags =
(TXD_OWN | TXD_SOP | TXD_EOP | (len & TXD_LENGTH));
qep->tx_new = NEXT_TX(entry);
/* Get it going. */
dev->trans_start = jiffies;
sbus_writel(CREG_CTRL_TWAKEUP, qep->qcregs + CREG_CTRL);
dev->stats.tx_packets++;
dev->stats.tx_bytes += len;
if (TX_BUFFS_AVAIL(qep) <= 0) {
/* Halt the net queue and enable tx interrupts.
* When the tx queue empties the tx irq handler
* will wake up the queue and return us back to
* the lazy tx reclaim scheme.
*/
netif_stop_queue(dev);
sbus_writel(0, qep->qcregs + CREG_TIMASK);
}
spin_unlock_irq(&qep->lock);
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
开发者ID:A2109devs,项目名称:lenovo_a2109a_kernel,代码行数:52,代码来源:sunqe.c
示例6: qe_tx_reclaim
/* Reclaim TX'd frames from the ring. This must always run under
* the IRQ protected qep->lock.
*/
static void qe_tx_reclaim(struct sunqe *qep)
{
struct qe_txd *txbase = &qep->qe_block->qe_txd[0];
int elem = qep->tx_old;
while (elem != qep->tx_new) {
u32 flags = txbase[elem].tx_flags;
if (flags & TXD_OWN)
break;
elem = NEXT_TX(elem);
}
qep->tx_old = elem;
}
开发者ID:Lyude,项目名称:linux,代码行数:17,代码来源:sunqe.c
示例7: greth_clean_tx
static void greth_clean_tx(struct net_device *dev)
{
struct greth_private *greth;
struct greth_bd *bdp;
u32 stat;
greth = netdev_priv(dev);
while (1) {
bdp = greth->tx_bd_base + greth->tx_last;
GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX);
mb();
stat = greth_read_bd(&bdp->stat);
if (unlikely(stat & GRETH_BD_EN))
break;
if (greth->tx_free == GRETH_TXBD_NUM)
break;
/* Check status for errors */
if (unlikely(stat & GRETH_TXBD_STATUS)) {
dev->stats.tx_errors++;
if (stat & GRETH_TXBD_ERR_AL)
dev->stats.tx_aborted_errors++;
if (stat & GRETH_TXBD_ERR_UE)
dev->stats.tx_fifo_errors++;
}
dev->stats.tx_packets++;
dev->stats.tx_bytes += greth->tx_bufs_length[greth->tx_last];
greth->tx_last = NEXT_TX(greth->tx_last);
greth->tx_free++;
}
if (greth->tx_free > 0) {
netif_wake_queue(dev);
}
}
开发者ID:CSCLOG,项目名称:beaglebone,代码行数:39,代码来源:greth.c
示例8: myri_tx
static void myri_tx(struct myri_eth *mp, struct net_device *dev)
{
struct sendq *sq = mp->sq;
int entry = mp->tx_old;
int limit = sbus_readl(&sq->head);
DTX(("entry[%d] limit[%d] ", entry, limit));
if (entry == limit)
return;
while (entry != limit) {
struct sk_buff *skb = mp->tx_skbs[entry];
u32 dma_addr;
DTX(("SKB[%d] ", entry));
dma_addr = sbus_readl(&sq->myri_txd[entry].myri_gathers[0].addr);
sbus_unmap_single(mp->myri_sdev, dma_addr, skb->len, SBUS_DMA_TODEVICE);
dev_kfree_skb(skb);
mp->tx_skbs[entry] = NULL;
mp->enet_stats.tx_packets++;
entry = NEXT_TX(entry);
}
mp->tx_old = entry;
}
开发者ID:dmgerman,项目名称:original,代码行数:23,代码来源:myri_sbus.c
示例9: myri_start_xmit
static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct myri_eth *mp = netdev_priv(dev);
struct sendq __iomem *sq = mp->sq;
struct myri_txd __iomem *txd;
unsigned long flags;
unsigned int head, tail;
int len, entry;
u32 dma_addr;
DTX(("myri_start_xmit: "));
myri_tx(mp, dev);
netif_stop_queue(dev);
/* This is just to prevent multiple PIO reads for TX_BUFFS_AVAIL. */
head = sbus_readl(&sq->head);
tail = sbus_readl(&sq->tail);
if (!TX_BUFFS_AVAIL(head, tail)) {
DTX(("no buffs available, returning 1\n"));
return NETDEV_TX_BUSY;
}
spin_lock_irqsave(&mp->irq_lock, flags);
DHDR(("xmit[skbdata(%p)]\n", skb->data));
#ifdef DEBUG_HEADER
dump_ehdr_and_myripad(((unsigned char *) skb->data));
#endif
/* XXX Maybe this can go as well. */
len = skb->len;
if (len & 3) {
DTX(("len&3 "));
len = (len + 4) & (~3);
}
entry = sbus_readl(&sq->tail);
txd = &sq->myri_txd[entry];
mp->tx_skbs[entry] = skb;
/* Must do this before we sbus map it. */
if (skb->data[MYRI_PAD_LEN] & 0x1) {
sbus_writew(0xffff, &txd->addr[0]);
sbus_writew(0xffff, &txd->addr[1]);
sbus_writew(0xffff, &txd->addr[2]);
sbus_writew(0xffff, &txd->addr[3]);
} else {
sbus_writew(0xffff, &txd->addr[0]);
sbus_writew((skb->data[0] << 8) | skb->data[1], &txd->addr[1]);
sbus_writew((skb->data[2] << 8) | skb->data[3], &txd->addr[2]);
sbus_writew((skb->data[4] << 8) | skb->data[5], &txd->addr[3]);
}
dma_addr = dma_map_single(&mp->myri_op->dev, skb->data,
len, DMA_TO_DEVICE);
sbus_writel(dma_addr, &txd->myri_gathers[0].addr);
sbus_writel(len, &txd->myri_gathers[0].len);
sbus_writel(1, &txd->num_sg);
sbus_writel(KERNEL_CHANNEL, &txd->chan);
sbus_writel(len, &txd->len);
sbus_writel((u32)-1, &txd->csum_off);
sbus_writel(0, &txd->csum_field);
sbus_writel(NEXT_TX(entry), &sq->tail);
DTX(("BangTheChip "));
bang_the_chip(mp);
DTX(("tbusy=0, returning 0\n"));
netif_start_queue(dev);
spin_unlock_irqrestore(&mp->irq_lock, flags);
return NETDEV_TX_OK;
}
开发者ID:nos1609,项目名称:Chrono_Kernel-1,代码行数:76,代码来源:myri_sbus.c
示例10: greth_clean_tx_gbit
static void greth_clean_tx_gbit(struct net_device *dev)
{
struct greth_private *greth;
struct greth_bd *bdp, *bdp_last_frag;
struct sk_buff *skb = NULL;
u32 stat;
int nr_frags, i;
u16 tx_last;
greth = netdev_priv(dev);
tx_last = greth->tx_last;
while (tx_last != greth->tx_next) {
skb = greth->tx_skbuff[tx_last];
nr_frags = skb_shinfo(skb)->nr_frags;
/* We only clean fully completed SKBs */
bdp_last_frag = greth->tx_bd_base + SKIP_TX(tx_last, nr_frags);
GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX);
mb();
stat = greth_read_bd(&bdp_last_frag->stat);
if (stat & GRETH_BD_EN)
break;
greth->tx_skbuff[tx_last] = NULL;
greth_update_tx_stats(dev, stat);
dev->stats.tx_bytes += skb->len;
bdp = greth->tx_bd_base + tx_last;
tx_last = NEXT_TX(tx_last);
dma_unmap_single(greth->dev,
greth_read_bd(&bdp->addr),
skb_headlen(skb),
DMA_TO_DEVICE);
for (i = 0; i < nr_frags; i++) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
bdp = greth->tx_bd_base + tx_last;
dma_unmap_page(greth->dev,
greth_read_bd(&bdp->addr),
skb_frag_size(frag),
DMA_TO_DEVICE);
tx_last = NEXT_TX(tx_last);
}
dev_kfree_skb(skb);
}
if (skb) { /* skb is set only if the above while loop was entered */
wmb();
greth->tx_last = tx_last;
if (netif_queue_stopped(dev) &&
(greth_num_free_bds(tx_last, greth->tx_next) >
(MAX_SKB_FRAGS+1)))
netif_wake_queue(dev);
}
}
开发者ID:513855417,项目名称:linux,代码行数:65,代码来源:greth.c
示例11: greth_clean_rings
static void greth_clean_rings(struct greth_private *greth)
{
int i;
struct greth_bd *rx_bdp = greth->rx_bd_base;
struct greth_bd *tx_bdp = greth->tx_bd_base;
if (greth->gbit_mac) {
/* Free and unmap RX buffers */
for (i = 0; i < GRETH_RXBD_NUM; i++, rx_bdp++) {
if (greth->rx_skbuff[i] != NULL) {
dev_kfree_skb(greth->rx_skbuff[i]);
dma_unmap_single(greth->dev,
greth_read_bd(&rx_bdp->addr),
MAX_FRAME_SIZE+NET_IP_ALIGN,
DMA_FROM_DEVICE);
}
}
/* TX buffers */
while (greth->tx_free < GRETH_TXBD_NUM) {
struct sk_buff *skb = greth->tx_skbuff[greth->tx_last];
int nr_frags = skb_shinfo(skb)->nr_frags;
tx_bdp = greth->tx_bd_base + greth->tx_last;
greth->tx_last = NEXT_TX(greth->tx_last);
dma_unmap_single(greth->dev,
greth_read_bd(&tx_bdp->addr),
skb_headlen(skb),
DMA_TO_DEVICE);
for (i = 0; i < nr_frags; i++) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
tx_bdp = greth->tx_bd_base + greth->tx_last;
dma_unmap_page(greth->dev,
greth_read_bd(&tx_bdp->addr),
skb_frag_size(frag),
DMA_TO_DEVICE);
greth->tx_last = NEXT_TX(greth->tx_last);
}
greth->tx_free += nr_frags+1;
dev_kfree_skb(skb);
}
} else { /* 10/100 Mbps MAC */
for (i = 0; i < GRETH_RXBD_NUM; i++, rx_bdp++) {
kfree(greth->rx_bufs[i]);
dma_unmap_single(greth->dev,
greth_read_bd(&rx_bdp->addr),
MAX_FRAME_SIZE,
DMA_FROM_DEVICE);
}
for (i = 0; i < GRETH_TXBD_NUM; i++, tx_bdp++) {
kfree(greth->tx_bufs[i]);
dma_unmap_single(greth->dev,
greth_read_bd(&tx_bdp->addr),
MAX_FRAME_SIZE,
DMA_TO_DEVICE);
}
}
}
开发者ID:513855417,项目名称:linux,代码行数:66,代码来源:greth.c
示例12: greth_start_xmit_gbit
static netdev_tx_t
greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev)
{
struct greth_private *greth = netdev_priv(dev);
struct greth_bd *bdp;
u32 status, dma_addr;
int curr_tx, nr_frags, i, err = NETDEV_TX_OK;
unsigned long flags;
u16 tx_last;
nr_frags = skb_shinfo(skb)->nr_frags;
tx_last = greth->tx_last;
rmb(); /* tx_last is updated by the poll task */
if (greth_num_free_bds(tx_last, greth->tx_next) < nr_frags + 1) {
netif_stop_queue(dev);
err = NETDEV_TX_BUSY;
goto out;
}
if (netif_msg_pktdata(greth))
greth_print_tx_packet(skb);
if (unlikely(skb->len > MAX_FRAME_SIZE)) {
dev->stats.tx_errors++;
goto out;
}
/* Save skb pointer. */
greth->tx_skbuff[greth->tx_next] = skb;
/* Linear buf */
if (nr_frags != 0)
status = GRETH_TXBD_MORE;
else
status = GRETH_BD_IE;
if (skb->ip_summed == CHECKSUM_PARTIAL)
status |= GRETH_TXBD_CSALL;
status |= skb_headlen(skb) & GRETH_BD_LEN;
if (greth->tx_next == GRETH_TXBD_NUM_MASK)
status |= GRETH_BD_WR;
bdp = greth->tx_bd_base + greth->tx_next;
greth_write_bd(&bdp->stat, status);
dma_addr = dma_map_single(greth->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(greth->dev, dma_addr)))
goto map_error;
greth_write_bd(&bdp->addr, dma_addr);
curr_tx = NEXT_TX(greth->tx_next);
/* Frags */
for (i = 0; i < nr_frags; i++) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
greth->tx_skbuff[curr_tx] = NULL;
bdp = greth->tx_bd_base + curr_tx;
status = GRETH_BD_EN;
if (skb->ip_summed == CHECKSUM_PARTIAL)
status |= GRETH_TXBD_CSALL;
status |= skb_frag_size(frag) & GRETH_BD_LEN;
/* Wrap around descriptor ring */
if (curr_tx == GRETH_TXBD_NUM_MASK)
status |= GRETH_BD_WR;
/* More fragments left */
if (i < nr_frags - 1)
status |= GRETH_TXBD_MORE;
else
status |= GRETH_BD_IE; /* enable IRQ on last fragment */
greth_write_bd(&bdp->stat, status);
dma_addr = skb_frag_dma_map(greth->dev, frag, 0, skb_frag_size(frag),
DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(greth->dev, dma_addr)))
goto frag_map_error;
greth_write_bd(&bdp->addr, dma_addr);
curr_tx = NEXT_TX(curr_tx);
}
wmb();
/* Enable the descriptor chain by enabling the first descriptor */
bdp = greth->tx_bd_base + greth->tx_next;
greth_write_bd(&bdp->stat,
greth_read_bd(&bdp->stat) | GRETH_BD_EN);
spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
greth->tx_next = curr_tx;
greth_enable_tx_and_irq(greth);
spin_unlock_irqrestore(&greth->devlock, flags);
//.........这里部分代码省略.........
开发者ID:513855417,项目名称:linux,代码行数:101,代码来源:greth.c
示例13: cp_start_xmit
static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
{
struct cp_private *cp = netdev_priv(dev);
unsigned entry;
u32 eor;
#if CP_VLAN_TAG_USED
u32 vlan_tag = 0;
#endif
spin_lock_irq(&cp->lock);
/* This is a hard error, log it. */
if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) {
netif_stop_queue(dev);
spin_unlock_irq(&cp->lock);
printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
dev->name);
return 1;
}
#if CP_VLAN_TAG_USED
if (cp->vlgrp && vlan_tx_tag_present(skb))
vlan_tag = TxVlanTag | cpu_to_be16(vlan_tx_tag_get(skb));
#endif
entry = cp->tx_head;
eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
if (skb_shinfo(skb)->nr_frags == 0) {
struct cp_desc *txd = &cp->tx_ring[entry];
u32 len;
dma_addr_t mapping;
len = skb->len;
mapping = pci_map_single(cp->pdev, skb->data, len, PCI_DMA_TODEVICE);
CP_VLAN_TX_TAG(txd, vlan_tag);
txd->addr = cpu_to_le64(mapping);
wmb();
if (skb->ip_summed == CHECKSUM_HW) {
const struct iphdr *ip = skb->nh.iph;
if (ip->protocol == IPPROTO_TCP)
txd->opts1 = cpu_to_le32(eor | len | DescOwn |
FirstFrag | LastFrag |
IPCS | TCPCS);
else if (ip->protocol == IPPROTO_UDP)
txd->opts1 = cpu_to_le32(eor | len | DescOwn |
FirstFrag | LastFrag |
IPCS | UDPCS);
else
BUG();
} else
txd->opts1 = cpu_to_le32(eor | len | DescOwn |
FirstFrag | LastFrag);
wmb();
cp->tx_skb[entry].skb = skb;
cp->tx_skb[entry].mapping = mapping;
cp->tx_skb[entry].frag = 0;
entry = NEXT_TX(entry);
} else {
struct cp_desc *txd;
u32 first_len, first_eor;
dma_addr_t first_mapping;
int frag, first_entry = entry;
const struct iphdr *ip = skb->nh.iph;
/* We must give this initial chunk to the device last.
* Otherwise we could race with the device.
*/
first_eor = eor;
first_len = skb_headlen(skb);
first_mapping = pci_map_single(cp->pdev, skb->data,
first_len, PCI_DMA_TODEVICE);
cp->tx_skb[entry].skb = skb;
cp->tx_skb[entry].mapping = first_mapping;
cp->tx_skb[entry].frag = 1;
entry = NEXT_TX(entry);
for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag];
u32 len;
u32 ctrl;
dma_addr_t mapping;
len = this_frag->size;
mapping = pci_map_single(cp->pdev,
((void *) page_address(this_frag->page) +
this_frag->page_offset),
len, PCI_DMA_TODEVICE);
eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
if (skb->ip_summed == CHECKSUM_HW) {
ctrl = eor | len | DescOwn | IPCS;
if (ip->protocol == IPPROTO_TCP)
ctrl |= TCPCS;
else if (ip->protocol == IPPROTO_UDP)
ctrl |= UDPCS;
else
BUG();
} else
//.........这里部分代码省略.........
开发者ID:OpenHMR,项目名称:Open-HMR600,代码行数:101,代码来源:8139cp.c
示例14: sgiseeq_start_xmit
static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct sgiseeq_private *sp = netdev_priv(dev);
struct hpc3_ethregs *hregs = sp->hregs;
unsigned long flags;
struct sgiseeq_tx_desc *td;
int len, entry;
spin_lock_irqsave(&sp->tx_lock, flags);
/* Setup... */
len = skb->len;
if (len < ETH_ZLEN) {
if (skb_padto(skb, ETH_ZLEN)) {
spin_unlock_irqrestore(&sp->tx_lock, flags);
return NETDEV_TX_OK;
}
len = ETH_ZLEN;
}
dev->stats.tx_bytes += len;
entry = sp->tx_new;
td = &sp->tx_desc[entry];
dma_sync_desc_cpu(dev, td);
/* Create entry. There are so many races with adding a new
* descriptor to the chain:
* 1) Assume that the HPC is off processing a DMA chain while
* we are changing all of the following.
* 2) Do no allow the HPC to look at a new descriptor until
* we have completely set up it's state. This means, do
* not clear HPCDMA_EOX in the current last descritptor
* until the one we are adding looks consistent and could
* be processes right now.
* 3) The tx interrupt code must notice when we've added a new
* entry and the HPC got to the end of the chain before we
* added this new entry and restarted it.
*/
td->skb = skb;
td->tdma.pbuf = dma_map_single(dev->dev.parent, skb->data,
len, DMA_TO_DEVICE);
td->tdma.cntinfo = (len & HPCDMA_BCNT) |
HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX;
dma_sync_desc_dev(dev, td);
if (sp->tx_old != sp->tx_new) {
struct sgiseeq_tx_desc *backend;
backend = &sp->tx_desc[PREV_TX(sp->tx_new)];
dma_sync_desc_cpu(dev, backend);
backend->tdma.cntinfo &= ~HPCDMA_EOX;
dma_sync_desc_dev(dev, backend);
}
sp->tx_new = NEXT_TX(sp->tx_new); /* Advance. */
/* Maybe kick the HPC back into motion. */
if (!(hregs->tx_ctrl & HPC3_ETXCTRL_ACTIVE))
kick_tx(dev, sp, hregs);
dev->trans_start = jiffies;
if (!TX_BUFFS_AVAIL(sp))
netif_stop_queue(dev);
spin_unlock_irqrestore(&sp->tx_lock, flags);
return NETDEV_TX_OK;
}
开发者ID:KaZoom,项目名称:buildroot-linux-kernel-m3,代码行数:66,代码来源:sgiseeq.c
示例15: greth_start_xmit
static netdev_tx_t
greth_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct greth_private *greth = netdev_priv(dev);
struct greth_bd *bdp;
int err = NETDEV_TX_OK;
u32 status, dma_addr;
bdp = greth->tx_bd_base + greth->tx_next;
if (unlikely(greth->tx_free <= 0)) {
netif_stop_queue(dev);
return NETDEV_TX_BUSY;
}
if (netif_msg_pktdata(greth))
greth_print_tx_packet(skb);
if (unlikely(skb->len > MAX_FRAME_SIZE)) {
dev->stats.tx_errors++;
goto out;
}
dma_addr = greth_read_bd(&bdp->addr);
memcpy((unsigned char *) phys_to_virt(dma_addr), skb->data, skb->len);
dma_sync_single_for_device(greth->dev, dma_addr, skb->len, DMA_TO_DEVICE);
status = GRETH_BD_EN | (skb->len & GRETH_BD_LEN);
/* Wrap around descriptor ring */
if (greth->tx_next == GRETH_TXBD_NUM_MASK) {
status |= GRETH_BD_WR;
}
greth->tx_next = NEXT_TX(greth->tx_next);
greth->tx_free--;
/* No more descriptors */
if (unlikely(greth->tx_free == 0)) {
/* Free transmitted descriptors */
greth_clean_tx(dev);
/* If nothing was cleaned, stop queue & wait for irq */
if (unlikely(greth->tx_free == 0)) {
status |= GRETH_BD_IE;
netif_stop_queue(dev);
}
}
/* Write descriptor control word and enable transmission */
greth_write_bd(&bdp->stat, status);
greth_enable_tx(greth);
out:
dev_kfree_skb(skb);
return err;
}
开发者ID:kronenpj,项目名称:samsung-s3c6410-android.2.0,代码行数:61,代码来源:greth.c
示例16: greth_start_xmit_gbit
static netdev_tx_t
greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev)
{
struct greth_private *greth = netdev_priv(dev);
struct greth_bd *bdp;
u32 status = 0, dma_addr;
int curr_tx, nr_frags, i, err = NETDEV_TX_OK;
nr_frags = skb_shinfo(skb)->nr_frags;
if (greth->tx_free < nr_frags + 1) {
netif_stop_queue(dev);
err = NETDEV_TX_BUSY;
goto out;
}
if (netif_msg_pktdata(greth))
greth_print_tx_packet(skb);
if (unlikely(skb->len > MAX_FRAME_SIZE)) {
dev->stats.tx_errors++;
goto out;
}
/* Save skb pointer. */
greth->tx_skbuff[greth->tx_next] = skb;
/* Linear buf */
if (nr_frags != 0)
status = GRETH_TXBD_MORE;
status |= GRETH_TXBD_CSALL;
status |= skb_headlen(skb) & GRETH_BD_LEN;
if (greth->tx_next == GRETH_TXBD_NUM_MASK)
status |= GRETH_BD_WR;
bdp = greth->tx_bd_base + greth->tx_next;
greth_write_bd(&bdp->stat, status);
dma_addr = dma_map_single(greth->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(greth->dev, dma_addr)))
goto map_error;
greth_write_bd(&bdp->addr, dma_addr);
curr_tx = NEXT_TX(greth->tx_next);
/* Frags */
for (i = 0; i < nr_frags; i++) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
greth->tx_skbuff[curr_tx] = NULL;
bdp = greth->tx_bd_base + curr_tx;
status = GRETH_TXBD_CSALL;
status |= frag->size & GRETH_BD_LEN;
/* Wrap around descriptor ring */
if (curr_tx == GRETH_TXBD_NUM_MASK)
status |= GRETH_BD_WR;
/* More fragments left */
if (i < nr_frags - 1)
status |= GRETH_TXBD_MORE;
/* ... last fragment, check if out of descriptors */
else if (greth->tx_free - nr_frags - 1 < (MAX_SKB_FRAGS + 1)) {
/* Enable interrupts and stop queue */
status |= GRETH_BD_IE;
netif_stop_queue(dev);
}
greth_write_bd(&bdp->stat, status);
dma_addr = dma_map_page(greth->dev,
frag->page,
frag->page_offset,
frag->size,
DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(greth->dev, dma_addr)))
goto frag_map_error;
greth_write_bd(&bdp->addr, dma_addr);
curr_tx = NEXT_TX(curr_tx);
}
wmb();
/* Enable the descriptors that we configured ... */
for (i = 0; i < nr_frags + 1; i++) {
bdp = greth->tx_bd_base + greth->tx_next;
greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN);
greth->tx_next = NEXT_TX(greth->tx_next);
greth->tx_free--;
}
greth_enable_tx(greth);
//.........这里部分代码省略.........
开发者ID:kronenpj,项目名称:samsung-s3c6410-android.2.0,代码行数:101,代码来源:greth.c
示例17: greth_start_xmit_gbit
static netdev_tx_t
greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev)
{
struct greth_private *greth = netdev_priv(dev);
struct greth_bd *bdp;
u32 status = 0, dma_addr, ctrl;
int curr_tx, nr_frags, i, err = NETDEV_TX_OK;
unsigned long flags;
nr_frags = skb_shinfo(skb)->nr_frags;
/* Clean TX Ring */
greth_clean_tx_gbit(dev);
if (greth->tx_free < nr_frags + 1) {
spin_lock_irqsave(&greth->devlock, flags);/*save from poll/irq*/
ctrl = GRETH_REGLOAD(greth->regs->control);
/* Enable TX IRQ only if not already in poll() routine */
if (ctrl & GRETH_RXI)
GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI);
netif_stop_queue(dev);
spin_unlock_irqrestore(&greth->devlock, flags);
err = NETDEV_TX_BUSY;
goto out;
}
if (netif_msg_pktdata(greth))
greth_print_tx_packet(skb);
if (unlikely(skb->len > MAX_FRAME_SIZE)) {
dev->stats.tx_errors++;
goto out;
}
/* Save skb pointer. */
greth->tx_skbuff[greth->tx_next] = skb;
/* Linear buf */
if (nr_frags != 0)
status = GRETH_TXBD_MORE;
status |= GRETH_TXBD_CSALL;
status |= skb_headlen(skb) & GRETH_BD_LEN;
if (greth->tx_next == GRETH_TXBD_NUM_MASK)
status |= GRETH_BD_WR;
bdp = greth->tx_bd_base + greth->tx_next;
greth_write_bd(&bdp->stat, status);
dma_addr = dma_map_single(greth->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(greth->dev, dma_addr)))
goto map_error;
greth_write_bd(&bdp->addr, dma_addr);
curr_tx = NEXT_TX(greth->tx_next);
/* Frags */
for (i = 0; i < nr_frags; i++) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
greth->tx_skbuff[curr_tx] = NULL;
bdp = greth->tx_bd_base + curr_tx;
status = GRETH_TXBD_CSALL | GRETH_BD_EN;
status |= frag->size & GRETH_BD_LEN;
/* Wrap around descriptor ring */
if (curr_tx == GRETH_TXBD_NUM_MASK)
status |= GRETH_BD_WR;
/* More fragments left */
if (i < nr_frags - 1)
status |= GRETH_TXBD_MORE;
else
status |= GRETH_BD_IE; /* enable IRQ on last fragment */
greth_write_bd(&bdp->stat, status);
dma_addr = dma_map_page(greth->dev,
frag->page,
frag->page_offset,
frag->size,
DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(greth->dev, dma_addr)))
goto frag_map_error;
greth_write_bd(&bdp->addr, dma_addr);
curr_tx = NEXT_TX(curr_tx);
}
wmb();
/* Enable the descriptor chain by enabling the first descriptor */
bdp = greth->tx_bd_base + greth->tx_next;
greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN);
greth->tx_next = curr_tx;
greth->tx_free -= nr_frags + 1;
//.........这里部分代码省略.........
开发者ID:119-org,项目名称:hi3518-osdrv,代码行数:101,代码来源:greth.c
注:本文中的NEXT_TX函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论