Ejemplo n.º 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)
{
    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;
}
Ejemplo n.º 2
0
/*
 * We have a good packet(s), pass it/them up the network stack.
 */
static void sonic_rx(struct net_device *dev)
{
    struct sonic_local *lp = netdev_priv(dev);
    int status;
    int entry = lp->cur_rx;

    while (sonic_rda_get(dev, entry, SONIC_RD_IN_USE) == 0) {
        struct sk_buff *used_skb;
        struct sk_buff *new_skb;
        dma_addr_t new_laddr;
        u16 bufadr_l;
        u16 bufadr_h;
        int pkt_len;

        status = sonic_rda_get(dev, entry, SONIC_RD_STATUS);
        if (status & SONIC_RCR_PRX) {
            /* Malloc up new buffer. */
            new_skb = dev_alloc_skb(SONIC_RBSIZE + 2);
            if (new_skb == NULL) {
                printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name);
                lp->stats.rx_dropped++;
                break;
            }
            /* provide 16 byte IP header alignment unless DMA requires otherwise */
            if(SONIC_BUS_SCALE(lp->dma_bitmode) == 2)
                skb_reserve(new_skb, 2);

            new_laddr = dma_map_single(lp->device, skb_put(new_skb, SONIC_RBSIZE),
                                       SONIC_RBSIZE, DMA_FROM_DEVICE);
            if (!new_laddr) {
                dev_kfree_skb(new_skb);
                printk(KERN_ERR "%s: Failed to map rx buffer, dropping packet.\n", dev->name);
                lp->stats.rx_dropped++;
                break;
            }

            /* now we have a new skb to replace it, pass the used one up the stack */
            dma_unmap_single(lp->device, lp->rx_laddr[entry], SONIC_RBSIZE, DMA_FROM_DEVICE);
            used_skb = lp->rx_skb[entry];
            pkt_len = sonic_rda_get(dev, entry, SONIC_RD_PKTLEN);
            skb_trim(used_skb, pkt_len);
            used_skb->protocol = eth_type_trans(used_skb, dev);
            netif_rx(used_skb);
            lp->stats.rx_packets++;
            lp->stats.rx_bytes += pkt_len;

            /* and insert the new skb */
            lp->rx_laddr[entry] = new_laddr;
            lp->rx_skb[entry] = new_skb;

            bufadr_l = (unsigned long)new_laddr & 0xffff;
            bufadr_h = (unsigned long)new_laddr >> 16;
            sonic_rra_put(dev, entry, SONIC_RR_BUFADR_L, bufadr_l);
            sonic_rra_put(dev, entry, SONIC_RR_BUFADR_H, bufadr_h);
        } else {
Ejemplo n.º 3
0
static int __devexit mac_sonic_device_remove (struct platform_device *pdev)
{
	struct net_device *dev = platform_get_drvdata(pdev);
	struct sonic_local* lp = netdev_priv(dev);

	unregister_netdev(dev);
	dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
	                  lp->descriptors, lp->descriptors_laddr);
	free_netdev(dev);

	return 0;
}
Ejemplo n.º 4
0
static int __init macsonic_init(struct net_device *dev)
{
	struct sonic_local* lp = netdev_priv(dev);

	/* Allocate the entire chunk of memory for the descriptors.
           Note that this cannot cross a 64K boundary. */
	if ((lp->descriptors = dma_alloc_coherent(lp->device,
	            SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
	            &lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
		printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id);
		return -ENOMEM;
	}

	/* Now set up the pointers to point to the appropriate places */
	lp->cda = lp->descriptors;
	lp->tda = lp->cda + (SIZEOF_SONIC_CDA
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));

	lp->cda_laddr = lp->descriptors_laddr;
	lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));

	dev->open = macsonic_open;
	dev->stop = macsonic_close;
	dev->hard_start_xmit = sonic_send_packet;
	dev->get_stats = sonic_get_stats;
	dev->set_multicast_list = &sonic_multicast_list;
	dev->tx_timeout = sonic_tx_timeout;
	dev->watchdog_timeo = TX_TIMEOUT;

	/*
	 * clear tally counter
	 */
	SONIC_WRITE(SONIC_CRCT, 0xffff);
	SONIC_WRITE(SONIC_FAET, 0xffff);
	SONIC_WRITE(SONIC_MPT, 0xffff);

	return 0;
}
Ejemplo n.º 5
0
static int __devinit macsonic_init(struct net_device *dev)
{
	struct sonic_local* lp = netdev_priv(dev);

	/* Allocate the entire chunk of memory for the descriptors.
           Note that this cannot cross a 64K boundary. */
	if ((lp->descriptors = dma_alloc_coherent(lp->device,
	            SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
	            &lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
		printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n",
		       dev_name(lp->device));
		return -ENOMEM;
	}

	/* Now set up the pointers to point to the appropriate places */
	lp->cda = lp->descriptors;
	lp->tda = lp->cda + (SIZEOF_SONIC_CDA
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));

	lp->cda_laddr = lp->descriptors_laddr;
	lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));

	dev->netdev_ops = &macsonic_netdev_ops;
	dev->watchdog_timeo = TX_TIMEOUT;

	/*
	 * clear tally counter
	 */
	SONIC_WRITE(SONIC_CRCT, 0xffff);
	SONIC_WRITE(SONIC_FAET, 0xffff);
	SONIC_WRITE(SONIC_MPT, 0xffff);

	return 0;
}
Ejemplo n.º 6
0
static int __devinit macsonic_init(struct net_device *dev)
{
	struct sonic_local* lp = netdev_priv(dev);

	
	if ((lp->descriptors = dma_alloc_coherent(lp->device,
	            SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
	            &lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
		printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n",
		       dev_name(lp->device));
		return -ENOMEM;
	}

	
	lp->cda = lp->descriptors;
	lp->tda = lp->cda + (SIZEOF_SONIC_CDA
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));

	lp->cda_laddr = lp->descriptors_laddr;
	lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));

	dev->netdev_ops = &macsonic_netdev_ops;
	dev->watchdog_timeo = TX_TIMEOUT;

	
	SONIC_WRITE(SONIC_CRCT, 0xffff);
	SONIC_WRITE(SONIC_FAET, 0xffff);
	SONIC_WRITE(SONIC_MPT, 0xffff);

	return 0;
}
Ejemplo n.º 7
0
static int __init sonic_probe1(struct net_device *dev)
{
	static unsigned version_printed = 0;
	unsigned int silicon_revision;
	struct sonic_local *lp = netdev_priv(dev);
	unsigned int base_addr = dev->base_addr;
	int i;
	int err = 0;

	if (!request_mem_region(base_addr, 0x100, xtsonic_string))
		return -EBUSY;

	
	silicon_revision = SONIC_READ(SONIC_SR);
	if (sonic_debug > 1)
		printk("SONIC Silicon Revision = 0x%04x\n",silicon_revision);

	i = 0;
	while ((known_revisions[i] != 0xffff) &&
			(known_revisions[i] != silicon_revision))
		i++;

	if (known_revisions[i] == 0xffff) {
		printk("SONIC ethernet controller not found (0x%4x)\n",
				silicon_revision);
		return -ENODEV;
	}

	if (sonic_debug  &&  version_printed++ == 0)
		printk(version);

	
	SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
	SONIC_WRITE(SONIC_DCR,
		    SONIC_DCR_WC0|SONIC_DCR_DW|SONIC_DCR_LBR|SONIC_DCR_SBUS);
	SONIC_WRITE(SONIC_CEP,0);
	SONIC_WRITE(SONIC_IMR,0);

	SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
	SONIC_WRITE(SONIC_CEP,0);

	for (i=0; i<3; i++) {
		unsigned int val = SONIC_READ(SONIC_CAP0-i);
		dev->dev_addr[i*2] = val;
		dev->dev_addr[i*2+1] = val >> 8;
	}

	

	lp->dma_bitmode = SONIC_BITMODE32;

	
	lp->descriptors =
		dma_alloc_coherent(lp->device,
			SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
			&lp->descriptors_laddr, GFP_KERNEL);

	if (lp->descriptors == NULL) {
		printk(KERN_ERR "%s: couldn't alloc DMA memory for "
				" descriptors.\n", dev_name(lp->device));
		goto out;
	}

	lp->cda = lp->descriptors;
	lp->tda = lp->cda + (SIZEOF_SONIC_CDA
			     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
			     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
			     * SONIC_BUS_SCALE(lp->dma_bitmode));

	

	lp->cda_laddr = lp->descriptors_laddr;
	lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA
				         * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
					 * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
					 * SONIC_BUS_SCALE(lp->dma_bitmode));

	dev->netdev_ops		= &xtsonic_netdev_ops;
	dev->watchdog_timeo	= TX_TIMEOUT;

	
	SONIC_WRITE(SONIC_CRCT,0xffff);
	SONIC_WRITE(SONIC_FAET,0xffff);
	SONIC_WRITE(SONIC_MPT,0xffff);

	return 0;
out:
	release_region(dev->base_addr, SONIC_MEM_SIZE);
	return err;
}
Ejemplo n.º 8
0
static int __init sonic_probe1(struct net_device *dev)
{
    static unsigned version_printed = 0;
    unsigned int silicon_revision;
    struct sonic_local *lp = netdev_priv(dev);
    unsigned int base_addr = dev->base_addr;
    int i;
    int err = 0;

    if (!request_mem_region(base_addr, 0x100, xtsonic_string))
        return -EBUSY;

    /*
     * get the Silicon Revision ID. If this is one of the known
     * one assume that we found a SONIC ethernet controller at
     * the expected location.
     */
    silicon_revision = SONIC_READ(SONIC_SR);
    if (sonic_debug > 1)
        printk("SONIC Silicon Revision = 0x%04x\n",silicon_revision);

    i = 0;
    while ((known_revisions[i] != 0xffff) &&
            (known_revisions[i] != silicon_revision))
        i++;

    if (known_revisions[i] == 0xffff) {
        printk("SONIC ethernet controller not found (0x%4x)\n",
               silicon_revision);
        return -ENODEV;
    }

    if (sonic_debug  &&  version_printed++ == 0)
        printk(version);

    /*
     * Put the sonic into software reset, then retrieve ethernet address.
     * Note: we are assuming that the boot-loader has initialized the cam.
     */
    SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
    SONIC_WRITE(SONIC_DCR,
                SONIC_DCR_WC0|SONIC_DCR_DW|SONIC_DCR_LBR|SONIC_DCR_SBUS);
    SONIC_WRITE(SONIC_CEP,0);
    SONIC_WRITE(SONIC_IMR,0);

    SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
    SONIC_WRITE(SONIC_CEP,0);

    for (i=0; i<3; i++) {
        unsigned int val = SONIC_READ(SONIC_CAP0-i);
        dev->dev_addr[i*2] = val;
        dev->dev_addr[i*2+1] = val >> 8;
    }

    /* Initialize the device structure. */

    lp->dma_bitmode = SONIC_BITMODE32;

    /*
     *  Allocate local private descriptor areas in uncached space.
     *  The entire structure must be located within the same 64kb segment.
     *  A simple way to ensure this is to allocate twice the
     *  size of the structure -- given that the structure is
     *  much less than 64 kB, at least one of the halves of
     *  the allocated area will be contained entirely in 64 kB.
     *  We also allocate extra space for a pointer to allow freeing
     *  this structure later on (in xtsonic_cleanup_module()).
     */
    lp->descriptors =
        dma_alloc_coherent(lp->device,
                           SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
                           &lp->descriptors_laddr, GFP_KERNEL);

    if (lp->descriptors == NULL) {
        printk(KERN_ERR "%s: couldn't alloc DMA memory for "
               " descriptors.\n", lp->device->bus_id);
        goto out;
    }

    lp->cda = lp->descriptors;
    lp->tda = lp->cda + (SIZEOF_SONIC_CDA
                         * SONIC_BUS_SCALE(lp->dma_bitmode));
    lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
                         * SONIC_BUS_SCALE(lp->dma_bitmode));
    lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
                         * SONIC_BUS_SCALE(lp->dma_bitmode));

    /* get the virtual dma address */

    lp->cda_laddr = lp->descriptors_laddr;
    lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA
                                     * SONIC_BUS_SCALE(lp->dma_bitmode));
    lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
                                     * SONIC_BUS_SCALE(lp->dma_bitmode));
    lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
                                     * SONIC_BUS_SCALE(lp->dma_bitmode));

    dev->open = xtsonic_open;
    dev->stop = xtsonic_close;
    dev->hard_start_xmit	= sonic_send_packet;
    dev->get_stats		= sonic_get_stats;
    dev->set_multicast_list	= &sonic_multicast_list;
    dev->tx_timeout		= sonic_tx_timeout;
    dev->watchdog_timeo	= TX_TIMEOUT;

    /*
     * clear tally counter
     */
    SONIC_WRITE(SONIC_CRCT,0xffff);
    SONIC_WRITE(SONIC_FAET,0xffff);
    SONIC_WRITE(SONIC_MPT,0xffff);

    return 0;
out:
    release_region(dev->base_addr, SONIC_MEM_SIZE);
    return err;
}
Ejemplo n.º 9
0
static int __init sonic_probe1(struct net_device *dev)
{
	static unsigned version_printed;
	unsigned int silicon_revision;
	unsigned int val;
	struct sonic_local *lp = netdev_priv(dev);
	int err = -ENODEV;
	int i;

	if (!request_mem_region(dev->base_addr, SONIC_MEM_SIZE, jazz_sonic_string))
		return -EBUSY;

	/*
	 * get the Silicon Revision ID. If this is one of the known
	 * one assume that we found a SONIC ethernet controller at
	 * the expected location.
	 */
	silicon_revision = SONIC_READ(SONIC_SR);
	if (sonic_debug > 1)
		printk("SONIC Silicon Revision = 0x%04x\n",silicon_revision);

	i = 0;
	while (known_revisions[i] != 0xffff
	       && known_revisions[i] != silicon_revision)
		i++;

	if (known_revisions[i] == 0xffff) {
		printk("SONIC ethernet controller not found (0x%4x)\n",
		       silicon_revision);
		goto out;
	}

	if (sonic_debug  &&  version_printed++ == 0)
		printk(version);

	printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ",
	       dev_name(lp->device), dev->base_addr);

	/*
	 * Put the sonic into software reset, then
	 * retrieve and print the ethernet address.
	 */
	SONIC_WRITE(SONIC_CMD,SONIC_CR_RST);
	SONIC_WRITE(SONIC_CEP,0);
	for (i=0; i<3; i++) {
		val = SONIC_READ(SONIC_CAP0-i);
		dev->dev_addr[i*2] = val;
		dev->dev_addr[i*2+1] = val >> 8;
	}

	err = -ENOMEM;

	/* Initialize the device structure. */

	lp->dma_bitmode = SONIC_BITMODE32;

	/* Allocate the entire chunk of memory for the descriptors.
           Note that this cannot cross a 64K boundary. */
	if ((lp->descriptors = dma_alloc_coherent(lp->device,
				SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode),
				&lp->descriptors_laddr, GFP_KERNEL)) == NULL) {
		printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n",
		       dev_name(lp->device));
		goto out;
	}

	/* Now set up the pointers to point to the appropriate places */
	lp->cda = lp->descriptors;
	lp->tda = lp->cda + (SIZEOF_SONIC_CDA
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));

	lp->cda_laddr = lp->descriptors_laddr;
	lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));
	lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
	                     * SONIC_BUS_SCALE(lp->dma_bitmode));

	dev->netdev_ops = &sonic_netdev_ops;
	dev->watchdog_timeo = TX_TIMEOUT;

	/*
	 * clear tally counter
	 */
	SONIC_WRITE(SONIC_CRCT,0xffff);
	SONIC_WRITE(SONIC_FAET,0xffff);
	SONIC_WRITE(SONIC_MPT,0xffff);

	return 0;
out:
	release_region(dev->base_addr, SONIC_MEM_SIZE);
	return err;
}