Exemple #1
0
/*
 * Open/initialize the SONIC controller.
 *
 * This routine should set everything up anew at each open, even
 *  registers that "should" only need to be set once at boot, so that
 *  there is non-reboot way to recover if something goes wrong.
 */
static int sonic_open(struct net_device *dev)
{
    if (sonic_debug > 2)
      printk("sonic_open: initializing sonic driver.\n");
    
    /*
     * We don't need to deal with auto-irq stuff since we
     * hardwire the sonic interrupt.
     */
/*
 * XXX Horrible work around:  We install sonic_interrupt as fast interrupt.
 * This means that during execution of the handler interrupt are disabled
 * covering another bug otherwise corrupting data.  This doesn't mean
 * this glue works ok under all situations.
 */
//    if (sonic_request_irq(dev->irq, &sonic_interrupt, 0, "sonic", dev)) {
    if (sonic_request_irq(dev->irq, &sonic_interrupt, SA_INTERRUPT, "sonic", dev)) {
	printk ("\n%s: unable to get IRQ %d .\n", dev->name, dev->irq);
	return -EAGAIN;
    }

    /*
     * Initialize the SONIC
     */
    sonic_init(dev);

    dev->tbusy = 0;
    dev->interrupt = 0;
    dev->start = 1;

    if (sonic_debug > 2)
      printk("sonic_open: Initialization done.\n");
	
    return 0;
}
Exemple #2
0
static void sonic_tx_timeout(struct net_device *dev)
{
    struct sonic_local *lp = netdev_priv(dev);
    int i;
    /*
     * put the Sonic into software-reset mode and
     * disable all interrupts before releasing DMA buffers
     */
    SONIC_WRITE(SONIC_IMR, 0);
    SONIC_WRITE(SONIC_ISR, 0x7fff);
    SONIC_WRITE(SONIC_CMD, SONIC_CR_RST);
    /* We could resend the original skbs. Easier to re-initialise. */
    for (i = 0; i < SONIC_NUM_TDS; i++) {
        if(lp->tx_laddr[i]) {
            dma_unmap_single(lp->device, lp->tx_laddr[i], lp->tx_len[i], DMA_TO_DEVICE);
            lp->tx_laddr[i] = (dma_addr_t)0;
        }
        if(lp->tx_skb[i]) {
            dev_kfree_skb(lp->tx_skb[i]);
            lp->tx_skb[i] = NULL;
        }
    }
    /* Try to restart the adaptor. */
    sonic_init(dev);
    lp->stats.tx_errors++;
    dev->trans_start = jiffies; /* prevent tx timeout */
    netif_wake_queue(dev);
}
Exemple #3
0
/*
 * Open/initialize the SONIC controller.
 *
 * This routine should set everything up anew at each open, even
 *  registers that "should" only need to be set once at boot, so that
 *  there is non-reboot way to recover if something goes wrong.
 */
static int sonic_open(struct net_device *dev)
{
    struct sonic_local *lp = netdev_priv(dev);
    int i;

    if (sonic_debug > 2)
        printk("sonic_open: initializing sonic driver.\n");

    for (i = 0; i < SONIC_NUM_RRS; i++) {
        struct sk_buff *skb = dev_alloc_skb(SONIC_RBSIZE + 2);
        if (skb == NULL) {
            while(i > 0) { /* free any that were allocated successfully */
                i--;
                dev_kfree_skb(lp->rx_skb[i]);
                lp->rx_skb[i] = NULL;
            }
            printk(KERN_ERR "%s: couldn't allocate receive buffers\n",
                   dev->name);
            return -ENOMEM;
        }
        /* align IP header unless DMA requires otherwise */
        if (SONIC_BUS_SCALE(lp->dma_bitmode) == 2)
            skb_reserve(skb, 2);
        lp->rx_skb[i] = skb;
    }

    for (i = 0; i < SONIC_NUM_RRS; i++) {
        dma_addr_t laddr = dma_map_single(lp->device, skb_put(lp->rx_skb[i], SONIC_RBSIZE),
                                          SONIC_RBSIZE, DMA_FROM_DEVICE);
        if (!laddr) {
            while(i > 0) { /* free any that were mapped successfully */
                i--;
                dma_unmap_single(lp->device, lp->rx_laddr[i], SONIC_RBSIZE, DMA_FROM_DEVICE);
                lp->rx_laddr[i] = (dma_addr_t)0;
            }
            for (i = 0; i < SONIC_NUM_RRS; i++) {
                dev_kfree_skb(lp->rx_skb[i]);
                lp->rx_skb[i] = NULL;
            }
            printk(KERN_ERR "%s: couldn't map rx DMA buffers\n",
                   dev->name);
            return -ENOMEM;
        }
        lp->rx_laddr[i] = laddr;
    }

    /*
     * Initialize the SONIC
     */
    sonic_init(dev);

    netif_start_queue(dev);

    if (sonic_debug > 2)
        printk("sonic_open: Initialization done.\n");

    return 0;
}
Exemple #4
0
void ritual()
{
    myusbInit();

    myBT_Init();
    line_init();
    distance_init();
    sonic_init();
    motor_init();
    motor_left_duty(10);
    motor_right_duty(10);
    color_init();
    myCmdLineInit();

}
Exemple #5
0
/*
 * transmit packet
 */
static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
{
    struct sonic_local *lp = (struct sonic_local *)dev->priv;
    unsigned int base_addr = dev->base_addr;
    unsigned int laddr;
    int entry,length;
    
    if (sonic_debug > 2)
      printk("sonic_send_packet: skb=%p, dev=%p\n",skb,dev);
  
    if (dev->tbusy) {
	int tickssofar = jiffies - dev->trans_start;

	/* If we get here, some higher level has decided we are broken.
	 There should really be a "kick me" function call instead. */
      
	if (sonic_debug > 1)
	  printk("sonic_send_packet: called with dev->tbusy = 1 !\n");
	
	if (tickssofar < 5)
	  return 1;
	
	printk("%s: transmit timed out.\n", dev->name);
	
	/* Try to restart the adaptor. */
	sonic_init(dev);
	dev->tbusy=0;
	dev->trans_start = jiffies;
    }

    /* 
     * Block a timer-based transmit from overlapping.  This could better be
     * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
     */
    if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
	printk("%s: Transmitter access conflict.\n", dev->name);
	return 1;
    }
    
    /*
     * Map the packet data into the logical DMA address space
     */
    if ((laddr = vdma_alloc(PHYSADDR(skb->data),skb->len)) == ~0UL) {
	printk("%s: no VDMA entry for transmit available.\n",dev->name);
	dev_kfree_skb(skb);
	dev->tbusy = 0;
	return 1;
    }
    entry = lp->cur_tx & SONIC_TDS_MASK;    
    lp->tx_laddr[entry] = laddr;
    lp->tx_skb[entry] = skb;
    
    length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
    flush_cache_all();
    
    /*
     * Setup the transmit descriptor and issue the transmit command.
     */
    lp->tda[entry].tx_status = 0;		/* clear status */
    lp->tda[entry].tx_frag_count = 1;		/* single fragment */
    lp->tda[entry].tx_pktsize = length;		/* length of packet */    
    lp->tda[entry].tx_frag_ptr_l = laddr & 0xffff;
    lp->tda[entry].tx_frag_ptr_h = laddr >> 16;
    lp->tda[entry].tx_frag_size  = length;
    lp->cur_tx++;
    lp->stats.tx_bytes += length;
    
    if (sonic_debug > 2)
      printk("sonic_send_packet: issueing Tx command\n");

    SONIC_WRITE(SONIC_CMD,SONIC_CR_TXP);

    dev->trans_start = jiffies;

    if (lp->cur_tx < lp->dirty_tx + SONIC_NUM_TDS)
      dev->tbusy = 0;
    else
      lp->tx_full = 1;
    
    return 0;
}