static void ibmlana_set_multicast_list(struct net_device *dev) { /* first stop the SONIC... */ StopSONIC(dev); /* ...then reinit it with the new flags */ InitBoard(dev); }
static int ibmlana_tx(struct sk_buff *skb, struct IBMLANA_NETDEV *dev) { ibmlana_priv *priv = (ibmlana_priv *) dev->priv; int retval = 0, tmplen, addr; unsigned long flags; tda_t tda; int baddr; /* if we get called with a NULL descriptor, the Ethernet layer thinks our card is stuck an we should reset it. We'll do this completely: */ if (skb == NULL) { printk("%s: Resetting SONIC\n", dev->name); StopSONIC(dev); InitBoard(dev); return 0; /* don't try to free the block here ;-) */ } /* find out if there are free slots for a frame to transmit. If not, the upper layer is in deep desperation and we simply ignore the frame. */ if (priv->txusedcnt >= TXBUFCNT) { retval = -EIO; priv->stat.tx_dropped++; goto tx_done; } /* copy the frame data into the next free transmit buffer - fillup missing */ tmplen = skb->len; if (tmplen < 60) tmplen = 60; baddr = priv->txbufstart + (priv->nexttxdescr * PKTSIZE); IBMLANA_TOIO(dev->mem_start + baddr, skb->data, skb->len); /* copy filler into RAM - in case we're filling up... we're filling a bit more than necessary, but that doesn't harm since the buffer is far larger... Sorry Linus for the filler string but I couldn't resist ;-) */ if (tmplen > skb->len) { char *fill = "NetBSD is a nice OS too! "; unsigned int destoffs = skb->len, l = strlen(fill); while (destoffs < tmplen) { IBMLANA_TOIO(dev->mem_start + baddr + destoffs, fill, l); destoffs += l; } } /* set up the new frame descriptor */ addr = priv->tdastart + (priv->nexttxdescr * sizeof(tda_t)); IBMLANA_FROMIO(&tda, dev->mem_start + addr, sizeof(tda_t)); tda.length = tda.fraglength = tmplen; IBMLANA_TOIO(dev->mem_start + addr, &tda, sizeof(tda_t)); /* if there were no active descriptors, trigger the SONIC */ save_flags(flags); cli(); priv->txusedcnt++; priv->txused[priv->nexttxdescr] = 1; /* are all transmission slots used up ? */ if (priv->txusedcnt >= TXBUFCNT) #if (LINUX_VERSION_CODE >= 0x02032a) netif_stop_queue(dev); #else dev->tbusy = 1; #endif if (priv->txusedcnt == 1) StartTx(dev, priv->nexttxdescr); priv->nexttxdescr = (priv->nexttxdescr + 1) % TXBUFCNT; restore_flags(flags); tx_done: /* When did that change exactly ? */ #if (LINUX_VERSION_CODE >= 0x20200) dev_kfree_skb(skb); #else dev_kfree_skb(skb, FREE_WRITE); #endif return retval; }