static void smc_hardware_send_pkt(unsigned long data) { struct net_device *dev = (struct net_device *)data; struct smc_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; struct sk_buff *skb; unsigned int packet_no, len; unsigned char *buf; unsigned long flags; DBG(3, "%s: %s\n", dev->name, __func__); if (!smc_special_trylock(&lp->lock, flags)) { netif_stop_queue(dev); tasklet_schedule(&lp->tx_task); return; } skb = lp->pending_tx_skb; if (unlikely(!skb)) { smc_special_unlock(&lp->lock, flags); return; } lp->pending_tx_skb = NULL; packet_no = SMC_GET_AR(lp); if (unlikely(packet_no & AR_FAILED)) { printk("%s: Memory allocation failed.\n", dev->name); dev->stats.tx_errors++; dev->stats.tx_fifo_errors++; smc_special_unlock(&lp->lock, flags); goto done; } SMC_SET_PN(lp, packet_no); SMC_SET_PTR(lp, PTR_AUTOINC); buf = skb->data; len = skb->len; DBG(2, "%s: TX PNR 0x%x LENGTH 0x%04x (%d) BUF 0x%p\n", dev->name, packet_no, len, len, buf); PRINT_PKT(buf, len); SMC_PUT_PKT_HDR(lp, 0, len + 6); SMC_PUSH_DATA(lp, buf, len & ~1); SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG(lp)); if (THROTTLE_TX_PKTS) netif_stop_queue(dev); SMC_SET_MMU_CMD(lp, MC_ENQUEUE); smc_special_unlock(&lp->lock, flags); dev->trans_start = jiffies; dev->stats.tx_packets++; dev->stats.tx_bytes += len; SMC_ENABLE_INT(lp, IM_TX_INT | IM_TX_EMPTY_INT); done: if (!THROTTLE_TX_PKTS) netif_wake_queue(dev); dev_kfree_skb(skb); }
/* * This is called to actually send a packet to the chip. */ static void smc_hardware_send_pkt(unsigned long data) { struct net_device *dev = (struct net_device *)data; struct smc_local *lp = netdev_priv(dev); void __iomem *ioaddr = lp->base; struct sk_buff *skb; unsigned int packet_no, len; unsigned char *buf; unsigned long flags; DBG(3, "%s: %s\n", dev->name, __func__); if (!smc_special_trylock(&lp->lock, flags)) { netif_stop_queue(dev); tasklet_schedule(&lp->tx_task); return; } skb = lp->pending_tx_skb; if (unlikely(!skb)) { smc_special_unlock(&lp->lock, flags); return; } lp->pending_tx_skb = NULL; packet_no = SMC_GET_AR(lp); if (unlikely(packet_no & AR_FAILED)) { printk("%s: Memory allocation failed.\n", dev->name); dev->stats.tx_errors++; dev->stats.tx_fifo_errors++; smc_special_unlock(&lp->lock, flags); goto done; } /* point to the beginning of the packet */ SMC_SET_PN(lp, packet_no); SMC_SET_PTR(lp, PTR_AUTOINC); buf = skb->data; len = skb->len; DBG(2, "%s: TX PNR 0x%x LENGTH 0x%04x (%d) BUF 0x%p\n", dev->name, packet_no, len, len, buf); PRINT_PKT(buf, len); /* * Send the packet length (+6 for status words, length, and ctl. * The card will pad to 64 bytes with zeroes if packet is too small. */ SMC_PUT_PKT_HDR(lp, 0, len + 6); /* send the actual data */ SMC_PUSH_DATA(lp, buf, len & ~1); /* Send final ctl word with the last byte if there is one */ SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG(lp)); /* * If THROTTLE_TX_PKTS is set, we stop the queue here. This will * have the effect of having at most one packet queued for TX * in the chip's memory at all time. * * If THROTTLE_TX_PKTS is not set then the queue is stopped only * when memory allocation (MC_ALLOC) does not succeed right away. */ if (THROTTLE_TX_PKTS) netif_stop_queue(dev); /* queue the packet for TX */ SMC_SET_MMU_CMD(lp, MC_ENQUEUE); smc_special_unlock(&lp->lock, flags); dev->trans_start = jiffies; dev->stats.tx_packets++; dev->stats.tx_bytes += len; SMC_ENABLE_INT(lp, IM_TX_INT | IM_TX_EMPTY_INT); done: if (!THROTTLE_TX_PKTS) netif_wake_queue(dev); dev_kfree_skb(skb); }