Пример #1
0
/* ************************************************************************
 * ************************************************************************
 *   I N I T
 * ************************************************************************
 * ************************************************************************ */
static int __init rtnetproxy_init_module(void)
{
    int err;

    /* Initialize the proxy's rtskb pool (JK) */
    if (rtskb_pool_init(&rtskb_pool, proxy_rtskbs) < proxy_rtskbs) {
        rtskb_pool_release(&rtskb_pool);
        return -ENOMEM;
    }

    dev_rtnetproxy.init = rtnetproxy_init;
    SET_MODULE_OWNER(&dev_rtnetproxy);

    /* Define the name for this unit */
    err=dev_alloc_name(&dev_rtnetproxy,"rtproxy");

    if(err<0) {
        rtskb_pool_release(&rtskb_pool);
        return err;
    }
    err = register_netdev(&dev_rtnetproxy);
    if (err<0) {
        rtskb_pool_release(&rtskb_pool);
        return err;
    }

    /* Initialize the ringbuffers: */
    memset(&ring_rtskb_kernel_rtnet, 0, sizeof(ring_rtskb_kernel_rtnet));
    memset(&ring_rtskb_rtnet_kernel, 0, sizeof(ring_rtskb_rtnet_kernel));
    memset(&ring_skb_kernel_rtnet, 0, sizeof(ring_skb_kernel_rtnet));
    memset(&ring_skb_rtnet_kernel, 0, sizeof(ring_skb_rtnet_kernel));

    /* Init the task for transmission */
    rtdm_sem_init(&rtnetproxy_sem, 0);
    rtdm_task_init(&rtnetproxy_thread, "rtnetproxy",
                   rtnetproxy_transmit_thread, 0,
                   RTDM_TASK_LOWEST_PRIORITY, 0);

    /* Register srq */
    rtdm_nrtsig_init(&rtnetproxy_signal, rtnetproxy_signal_handler);

    /* rtNet stuff: */
    rt_ip_register_fallback(rtnetproxy_recv);

    printk("rtnetproxy installed as \"%s\"\n", dev_rtnetproxy.name);

    return 0;
}
Пример #2
0
/***
 *  rt_socket_cleanup - releases resources allocated for the socket
 */
int rt_socket_cleanup(struct rtdm_dev_context *context)
{
    struct rtsocket *sock  = (struct rtsocket *)&context->dev_private;
    unsigned int    rtskbs;
    unsigned long   flags;


    rtos_event_sem_delete(&sock->wakeup_event);

    rtos_spin_lock_irqsave(&sock->param_lock, flags);

    set_bit(SKB_POOL_CLOSED, &context->context_flags);
    rtskbs = atomic_read(&sock->pool_size);

    rtos_spin_unlock_irqrestore(&sock->param_lock, flags);

    if (rtskbs > 0) {
        if (test_bit(RTDM_CREATED_IN_NRT, &context->context_flags)) {
            rtskbs = rtskb_pool_shrink(&sock->skb_pool, rtskbs);
            atomic_sub(rtskbs, &sock->pool_size);
            if (atomic_read(&sock->pool_size) > 0)
                return -EAGAIN;
            rtskb_pool_release(&sock->skb_pool);
        } else {
            rtskbs = rtskb_pool_shrink_rt(&sock->skb_pool, rtskbs);
            atomic_sub(rtskbs, &sock->pool_size);
            if (atomic_read(&sock->pool_size) > 0)
                return -EAGAIN;
            rtskb_pool_release_rt(&sock->skb_pool);
        }
    }

    return 0;
}
Пример #3
0
int __init rtcfg_init_frames(void)
{
    int ret;


    rtskb_queue_init(&rx_queue);
    rtos_event_sem_init(&rx_event);

    if (rtskb_pool_init(&rtcfg_pool, num_rtskbs) < num_rtskbs) {
        ret = -ENOMEM;
        goto error1;
    }

    ret = rtos_task_init(&rx_task, rtcfg_rx_task, 0,
                         RTOS_LOWEST_RT_PRIORITY);
    if (ret < 0)
        goto error1;

    ret = rtdev_add_pack(&rtcfg_packet_type);
    if (ret < 0)
        goto error2;

    return 0;

  error2:
    rtos_task_delete(&rx_task);

  error1:
    rtos_event_sem_delete(&rx_event);
    rtskb_pool_release(&rtcfg_pool);

    return ret;
}
Пример #4
0
static void __exit scc_enet_cleanup(void)
{
	struct rtnet_device *rtdev = rtdev_root;
	struct scc_enet_private *cep = (struct scc_enet_private *)rtdev->priv;
	volatile cpm8xx_t *cp = cpmp;
	volatile scc_enet_t *ep;

	if (rtdev) {
		rtdm_irq_disable(&cep->irq_handle);
		rtdm_irq_free(&cep->irq_handle);

		ep = (scc_enet_t *)(&cp->cp_dparam[PROFF_ENET]);
		m8xx_cpm_dpfree(ep->sen_genscc.scc_rbase);
		m8xx_cpm_dpfree(ep->sen_genscc.scc_tbase);

		rt_stack_disconnect(rtdev);
		rt_unregister_rtnetdev(rtdev);
		rt_rtdev_disconnect(rtdev);

		printk("%s: unloaded\n", rtdev->name);
		rtskb_pool_release(&cep->skb_pool);
		rtdev_free(rtdev);
		rtdev_root = NULL;
	}
}
Пример #5
0
int __init rtcfg_init_frames(void)
{
    int ret;


    if (rtskb_pool_init(&rtcfg_pool, num_rtskbs) < num_rtskbs)
        return -ENOMEM;

    rtskb_queue_init(&rx_queue);
    rtdm_event_init(&rx_event, 0);

    ret = rtdm_task_init(&rx_task, "rtcfg-rx", rtcfg_rx_task, 0,
                         RTDM_TASK_LOWEST_PRIORITY, 0);
    if (ret < 0) {
        rtdm_event_destroy(&rx_event);
        goto error1;
    }

    ret = rtdev_add_pack(&rtcfg_packet_type);
    if (ret < 0)
        goto error2;

    return 0;

  error2:
    rtdm_event_destroy(&rx_event);
    rtdm_task_join_nrt(&rx_task, 100);

  error1:
    rtskb_pool_release(&rtcfg_pool);

    return ret;
}
Пример #6
0
/***
 *  rt_socket_cleanup - releases resources allocated for the socket
 */
int rt_socket_cleanup(struct rtdm_dev_context *sockctx)
{
    struct rtsocket *sock  = (struct rtsocket *)&sockctx->dev_private;
    int ret = 0;


    rtdm_sem_destroy(&sock->pending_sem);

    mutex_lock(&sock->pool_nrt_lock);

    set_bit(SKB_POOL_CLOSED, &sockctx->context_flags);

    if (sock->pool_size > 0) {
        sock->pool_size -= rtskb_pool_shrink(&sock->skb_pool, sock->pool_size);

        if (sock->pool_size > 0)
            ret = -EAGAIN;
        else
            rtskb_pool_release(&sock->skb_pool);
    }

    mutex_unlock(&sock->pool_nrt_lock);

    return ret;
}
Пример #7
0
void rtcap_cleanup(void)
{
    unsigned long flags;


#if defined(CONFIG_RTAI_24) || defined(CONFIG_RTAI_30) || defined(CONFIG_RTAI_31)
    if (start_timer)
        stop_rt_timer();
#endif

    rtos_nrt_signal_delete(&cap_signal);

    /* unregister capturing handlers */
    rtos_spin_lock_irqsave(&rtcap_lock, flags);
    rtcap_handler = NULL;
    rtos_spin_unlock_irqrestore(&rtcap_lock, flags);

    /* empty queue (should be already empty) */
    rtcap_signal_handler();

    cleanup_tap_devices();

    rtskb_pool_release(&cap_pool);

    printk("RTcap: unloaded\n");
}
Пример #8
0
void rt2x00_core_remove(struct rtnet_device * rtnet_dev) {

    struct rtwlan_device * rtwlan_dev = rtnetdev_priv(rtnet_dev);

    rtskb_pool_release(&rtwlan_dev->skb_pool);
    rt_unregister_rtnetdev(rtnet_dev);
    rt_rtdev_disconnect(rtnet_dev);

    rtdev_free(rtnet_dev);
  
}
Пример #9
0
/**
 *      rtnet_mgr_release():    release the RTnet-Manager
 *
 */
void rtnet_release(void)
{
        rt_printk("RTnet: End real-time networking\n");
	rt_stack_mgr_delete(&STACK_manager);
	rt_rtdev_mgr_delete(&RTDEV_manager);

#ifdef CONFIG_PROC_FS
        rtnet_mgr_proc_unregister ();
#endif
        rtnet_chrdev_release();
        rt_inet_proto_release();
        rtnet_dev_release();
        rtsockets_release();
        rtskb_pool_release();

        cleanup_crc32();
}
Пример #10
0
static void __exit rtnetproxy_cleanup_module(void)
{

    /* Unregister the fallback at rtnet */
    rt_ip_register_fallback(0);

    /* free the rtai srq */
    rtdm_nrtsig_destroy(&rtnetproxy_signal);

    rtdm_task_destroy(&rtnetproxy_thread);
    rtdm_sem_destroy(&rtnetproxy_sem);

    /* Free the ringbuffers... */
    {
        struct sk_buff *del_skb;  /* standard skb */
        while ((del_skb = read_from_ringbuffer(&ring_skb_rtnet_kernel)) != 0)
        {
            dev_kfree_skb(del_skb);
        }
        while ((del_skb = read_from_ringbuffer(&ring_skb_kernel_rtnet)) != 0)
        {
            dev_kfree_skb(del_skb);
        }
    }
    {
        struct rtskb *del; /* rtnet skb */
        while ((del=read_from_ringbuffer(&ring_rtskb_kernel_rtnet))!=0)
        {
            kfree_rtskb(del); // Although this is kernel mode, freeing should work...
        }
        while ((del=read_from_ringbuffer(&ring_rtskb_rtnet_kernel))!=0)
        {
            kfree_rtskb(del); // Although this is kernel mode, freeing should work...
        }
    }

    /* Unregister the net device: */
    unregister_netdev(&dev_rtnetproxy);
    kfree(dev_rtnetproxy.priv);

    memset(&dev_rtnetproxy, 0, sizeof(dev_rtnetproxy));
    dev_rtnetproxy.init = rtnetproxy_init;

    rtskb_pool_release(&rtskb_pool);
}
Пример #11
0
/***
 *  rt_socket_cleanup - releases resources allocated for the socket
 */
void rt_socket_cleanup(struct rtdm_fd *fd)
{
    struct rtsocket *sock  = rtdm_fd_to_private(fd);


    rtdm_sem_destroy(&sock->pending_sem);

    mutex_lock(&sock->pool_nrt_lock);

    set_bit(SKB_POOL_CLOSED, &sock->flags);

    if (sock->pool_size > 0)
	rtskb_pool_release(&sock->skb_pool);

    mutex_unlock(&sock->pool_nrt_lock);

    module_put(sock->owner);
}
Пример #12
0
void rtcfg_cleanup_frames(void)
{
    struct rtskb *rtskb;


    while (rtdev_remove_pack(&rtcfg_packet_type) == -EAGAIN) {
        RTCFG_DEBUG(3, "RTcfg: waiting for protocol unregistration\n");
        set_current_state(TASK_UNINTERRUPTIBLE);
        schedule_timeout(1*HZ); /* wait a second */
    }

    rtos_event_sem_delete(&rx_event);
    rtos_task_delete(&rx_task);

    while ((rtskb = rtskb_dequeue(&rx_queue)) != NULL) {
        rtdev_dereference(rtskb->rtdev);
        kfree_rtskb(rtskb);
    }

    rtskb_pool_release(&rtcfg_pool);
}
Пример #13
0
/* Initialize the CPM Ethernet on SCC.  If EPPC-Bug loaded us, or performed
 * some other network I/O, a whole bunch of this has already been set up.
 * It is no big deal if we do it again, we just have to disable the
 * transmit and receive to make sure we don't catch the CPM with some
 * inconsistent control information.
 */
int __init scc_enet_init(void)
{
	struct rtnet_device *rtdev = NULL;
	struct scc_enet_private *cep;
	int i, j, k;
	unsigned char	*eap, *ba;
	dma_addr_t	mem_addr;
	bd_t		*bd;
	volatile	cbd_t		*bdp;
	volatile	cpm8xx_t	*cp;
	volatile	scc_t		*sccp;
	volatile	scc_enet_t	*ep;
	volatile	immap_t		*immap;

	cp = cpmp;	/* Get pointer to Communication Processor */

	immap = (immap_t *)(mfspr(IMMR) & 0xFFFF0000);	/* and to internal registers */

	bd = (bd_t *)__res;

	/* Configure the SCC parameters (this has formerly be done 
	 * by macro definitions).
	 */
	switch (rtnet_scc) {
	case 3:
		CPM_CR_ENET = CPM_CR_CH_SCC3;
		PROFF_ENET  = PROFF_SCC3;
		SCC_ENET    = 2;		/* Index, not number! */
		CPMVEC_ENET = CPMVEC_SCC3;
		break;
	case 2:
		CPM_CR_ENET = CPM_CR_CH_SCC2;
		PROFF_ENET  = PROFF_SCC2;
		SCC_ENET    = 1;		/* Index, not number! */
		CPMVEC_ENET = CPMVEC_SCC2;
		break;
	case 1:
		CPM_CR_ENET = CPM_CR_CH_SCC1;
		PROFF_ENET  = PROFF_SCC1;
		SCC_ENET    = 0;		/* Index, not number! */
		CPMVEC_ENET = CPMVEC_SCC1;
		break;
	default:
		printk(KERN_ERR "enet: SCC%d doesn't exit (check rtnet_scc)\n", rtnet_scc);
		return -1;
	}

	/* Allocate some private information and create an Ethernet device instance.
	*/
	rtdev = rtdev_root = rt_alloc_etherdev(sizeof(struct scc_enet_private));
	if (rtdev == NULL) {
		printk(KERN_ERR "enet: Could not allocate ethernet device.\n");
		return -1;
	}
	rtdev_alloc_name(rtdev, "rteth%d");
	rt_rtdev_connect(rtdev, &RTDEV_manager);
	RTNET_SET_MODULE_OWNER(rtdev);
	rtdev->vers = RTDEV_VERS_2_0;

	cep = (struct scc_enet_private *)rtdev->priv;
	rtdm_lock_init(&cep->lock);

	/* Get pointer to SCC area in parameter RAM.
	*/
	ep = (scc_enet_t *)(&cp->cp_dparam[PROFF_ENET]);

	/* And another to the SCC register area.
	*/
	sccp = (volatile scc_t *)(&cp->cp_scc[SCC_ENET]);
	cep->sccp = (scc_t *)sccp;		/* Keep the pointer handy */

	/* Disable receive and transmit in case EPPC-Bug started it.
	*/
	sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	/* Cookbook style from the MPC860 manual.....
	 * Not all of this is necessary if EPPC-Bug has initialized
	 * the network.
	 * So far we are lucky, all board configurations use the same
	 * pins, or at least the same I/O Port for these functions.....
	 * It can't last though......
	 */

#if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD))
	/* Configure port A pins for Txd and Rxd.
	*/
	immap->im_ioport.iop_papar |=  (PA_ENET_RXD | PA_ENET_TXD);
	immap->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD);
	immap->im_ioport.iop_paodr &=                ~PA_ENET_TXD;
#elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD))
	/* Configure port B pins for Txd and Rxd.
	*/
	immap->im_cpm.cp_pbpar |=  (PB_ENET_RXD | PB_ENET_TXD);
	immap->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD);
	immap->im_cpm.cp_pbodr &=		 ~PB_ENET_TXD;
#else
#error Exactly ONE pair of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined
#endif

#if defined(PC_ENET_LBK)
	/* Configure port C pins to disable External Loopback
	 */
	immap->im_ioport.iop_pcpar &= ~PC_ENET_LBK;
	immap->im_ioport.iop_pcdir |=  PC_ENET_LBK;
	immap->im_ioport.iop_pcso  &= ~PC_ENET_LBK;
	immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK;	/* Disable Loopback */
#endif	/* PC_ENET_LBK */

	/* Configure port C pins to enable CLSN and RENA.
	*/
	immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA);
	immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA);
	immap->im_ioport.iop_pcso  |=  (PC_ENET_CLSN | PC_ENET_RENA);

	/* Configure port A for TCLK and RCLK.
	*/
	immap->im_ioport.iop_papar |=  (PA_ENET_TCLK | PA_ENET_RCLK);
	immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK);

	/* Configure Serial Interface clock routing.
	 * First, clear all SCC bits to zero, then set the ones we want.
	 */
	cp->cp_sicr &= ~SICR_ENET_MASK;
	cp->cp_sicr |=  SICR_ENET_CLKRT;

	/* Manual says set SDDR, but I can't find anything with that
	 * name.  I think it is a misprint, and should be SDCR.  This
	 * has already been set by the communication processor initialization.
	 */

	/* Allocate space for the buffer descriptors in the DP ram.
	 * These are relative offsets in the DP ram address space.
	 * Initialize base addresses for the buffer descriptors.
	 */
	i = m8xx_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE);
	ep->sen_genscc.scc_rbase = i;
	cep->rx_bd_base = (cbd_t *)&cp->cp_dpmem[i];

	i = m8xx_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE);
	ep->sen_genscc.scc_tbase = i;
	cep->tx_bd_base = (cbd_t *)&cp->cp_dpmem[i];

	cep->dirty_tx = cep->cur_tx = cep->tx_bd_base;
	cep->cur_rx = cep->rx_bd_base;

	/* Issue init Rx BD command for SCC.
	 * Manual says to perform an Init Rx parameters here.  We have
	 * to perform both Rx and Tx because the SCC may have been
	 * already running.
	 * In addition, we have to do it later because we don't yet have
	 * all of the BD control/status set properly.
	cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_RX) | CPM_CR_FLG;
	while (cp->cp_cpcr & CPM_CR_FLG);
	 */

	/* Initialize function code registers for big-endian.
	*/
	ep->sen_genscc.scc_rfcr = SCC_EB;
	ep->sen_genscc.scc_tfcr = SCC_EB;

	/* Set maximum bytes per receive buffer.
	 * This appears to be an Ethernet frame size, not the buffer
	 * fragment size.  It must be a multiple of four.
	 */
	ep->sen_genscc.scc_mrblr = PKT_MAXBLR_SIZE;

	/* Set CRC preset and mask.
	*/
	ep->sen_cpres = 0xffffffff;
	ep->sen_cmask = 0xdebb20e3;

	ep->sen_crcec = 0;	/* CRC Error counter */
	ep->sen_alec = 0;	/* alignment error counter */
	ep->sen_disfc = 0;	/* discard frame counter */

	ep->sen_pads = 0x8888;	/* Tx short frame pad character */
	ep->sen_retlim = 15;	/* Retry limit threshold */

	ep->sen_maxflr = PKT_MAXBUF_SIZE;   /* maximum frame length register */
	ep->sen_minflr = PKT_MINBUF_SIZE;  /* minimum frame length register */

	ep->sen_maxd1 = PKT_MAXBLR_SIZE;	/* maximum DMA1 length */
	ep->sen_maxd2 = PKT_MAXBLR_SIZE;	/* maximum DMA2 length */

	/* Clear hash tables.
	*/
	ep->sen_gaddr1 = 0;
	ep->sen_gaddr2 = 0;
	ep->sen_gaddr3 = 0;
	ep->sen_gaddr4 = 0;
	ep->sen_iaddr1 = 0;
	ep->sen_iaddr2 = 0;
	ep->sen_iaddr3 = 0;
	ep->sen_iaddr4 = 0;

	/* Set Ethernet station address.
	 */
	eap = (unsigned char *)&(ep->sen_paddrh);
#ifdef CONFIG_FEC_ENET
	/* We need a second MAC address if FEC is used by Linux */
	for (i=5; i>=0; i--)
		*eap++ = rtdev->dev_addr[i] = (bd->bi_enetaddr[i] | 
					     (i==3 ? 0x80 : 0));
#else
	for (i=5; i>=0; i--)
		*eap++ = rtdev->dev_addr[i] = bd->bi_enetaddr[i];
#endif

	ep->sen_pper = 0;	/* 'cause the book says so */
	ep->sen_taddrl = 0;	/* temp address (LSB) */
	ep->sen_taddrm = 0;
	ep->sen_taddrh = 0;	/* temp address (MSB) */

	/* Now allocate the host memory pages and initialize the
	 * buffer descriptors.
	 */
	bdp = cep->tx_bd_base;
	for (i=0; i<TX_RING_SIZE; i++) {

		/* Initialize the BD for every fragment in the page.
		*/
		bdp->cbd_sc = 0;
		bdp->cbd_bufaddr = 0;
		bdp++;
	}

	/* Set the last buffer to wrap.
	*/
	bdp--;
	bdp->cbd_sc |= BD_SC_WRAP;

	bdp = cep->rx_bd_base;
	k = 0;
	for (i=0; i<CPM_ENET_RX_PAGES; i++) {

		/* Allocate a page.
		*/
		ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);

		/* Initialize the BD for every fragment in the page.
		*/
		for (j=0; j<CPM_ENET_RX_FRPPG; j++) {
			bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR;
			bdp->cbd_bufaddr = mem_addr;
			cep->rx_vaddr[k++] = ba;
			mem_addr += CPM_ENET_RX_FRSIZE;
			ba += CPM_ENET_RX_FRSIZE;
			bdp++;
		}
	}

	/* Set the last buffer to wrap.
	*/
	bdp--;
	bdp->cbd_sc |= BD_SC_WRAP;

	/* Let's re-initialize the channel now.  We have to do it later
	 * than the manual describes because we have just now finished
	 * the BD initialization.
	 */
	cp->cp_cpcr = mk_cr_cmd(CPM_CR_ENET, CPM_CR_INIT_TRX) | CPM_CR_FLG;
	while (cp->cp_cpcr & CPM_CR_FLG);

	cep->skb_cur = cep->skb_dirty = 0;

	sccp->scc_scce = 0xffff;	/* Clear any pending events */

	/* Enable interrupts for transmit error, complete frame
	 * received, and any transmit buffer we have also set the
	 * interrupt flag.
	 */
	sccp->scc_sccm = (SCCE_ENET_TXE | SCCE_ENET_RXF | SCCE_ENET_TXB);

	/* Install our interrupt handler.
	*/
	rtdev->irq = CPM_IRQ_OFFSET + CPMVEC_ENET;
	rt_stack_connect(rtdev, &STACK_manager);
	if ((i = rtdm_irq_request(&cep->irq_handle, rtdev->irq,
				  scc_enet_interrupt, 0, "rt_mpc8xx_enet", rtdev))) {
		printk(KERN_ERR "Couldn't request IRQ %d\n", rtdev->irq);
		rtdev_free(rtdev);
		return i;
	}
	

	/* Set GSMR_H to enable all normal operating modes.
	 * Set GSMR_L to enable Ethernet to MC68160.
	 */
	sccp->scc_gsmrh = 0;
	sccp->scc_gsmrl = (SCC_GSMRL_TCI | SCC_GSMRL_TPL_48 | SCC_GSMRL_TPP_10 | SCC_GSMRL_MODE_ENET);

	/* Set sync/delimiters.
	*/
	sccp->scc_dsr = 0xd555;

	/* Set processing mode.  Use Ethernet CRC, catch broadcast, and
	 * start frame search 22 bit times after RENA.
	 */
	sccp->scc_pmsr = (SCC_PMSR_ENCRC | SCC_PMSR_NIB22);

	/* It is now OK to enable the Ethernet transmitter.
	 * Unfortunately, there are board implementation differences here.
	 */
#if   (!defined (PB_ENET_TENA) &&  defined (PC_ENET_TENA))
	immap->im_ioport.iop_pcpar |=  PC_ENET_TENA;
	immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA;
#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA))
	cp->cp_pbpar |= PB_ENET_TENA;
	cp->cp_pbdir |= PB_ENET_TENA;
#else
#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA
#endif

#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
	/* And while we are here, set the configuration to enable ethernet.
	*/
	*((volatile uint *)RPX_CSR_ADDR) &= ~BCSR0_ETHLPBK;
	*((volatile uint *)RPX_CSR_ADDR) |=
			(BCSR0_ETHEN | BCSR0_COLTESTDIS | BCSR0_FULLDPLXDIS);
#endif

#ifdef CONFIG_BSEIP
	/* BSE uses port B and C for PHY control.
	*/
	cp->cp_pbpar &= ~(PB_BSE_POWERUP | PB_BSE_FDXDIS);
	cp->cp_pbdir |= (PB_BSE_POWERUP | PB_BSE_FDXDIS);
	cp->cp_pbdat |= (PB_BSE_POWERUP | PB_BSE_FDXDIS);

	immap->im_ioport.iop_pcpar &= ~PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcdir |= PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcso &= ~PC_BSE_LOOPBACK;
	immap->im_ioport.iop_pcdat &= ~PC_BSE_LOOPBACK;
#endif

#ifdef CONFIG_FADS
	cp->cp_pbpar |= PB_ENET_TENA;
	cp->cp_pbdir |= PB_ENET_TENA;

	/* Enable the EEST PHY.
	*/
	*((volatile uint *)BCSR1) &= ~BCSR1_ETHEN;
#endif

	rtdev->base_addr = (unsigned long)ep;

	/* The CPM Ethernet specific entries in the device structure. */
	rtdev->open = scc_enet_open;
	rtdev->hard_start_xmit = scc_enet_start_xmit;
	rtdev->stop = scc_enet_close;
	rtdev->hard_header = &rt_eth_header;
	rtdev->get_stats = scc_enet_get_stats;

	if (!rx_pool_size)
		rx_pool_size = RX_RING_SIZE * 2;
	if (rtskb_pool_init(&cep->skb_pool, rx_pool_size) < rx_pool_size) {
		rtdm_irq_disable(&cep->irq_handle);
		rtdm_irq_free(&cep->irq_handle);
		rtskb_pool_release(&cep->skb_pool);
		rtdev_free(rtdev);
		return -ENOMEM;
	}

	if ((i = rt_register_rtnetdev(rtdev))) {
		printk(KERN_ERR "Couldn't register rtdev\n");
		rtdm_irq_disable(&cep->irq_handle);
		rtdm_irq_free(&cep->irq_handle);
		rtskb_pool_release(&cep->skb_pool);
		rtdev_free(rtdev);
		return i;
	}

	/* And last, enable the transmit and receive processing.
	*/
	sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);

	printk("%s: CPM ENET Version 0.2 on SCC%d, irq %d, addr %02x:%02x:%02x:%02x:%02x:%02x\n", 
	       rtdev->name, SCC_ENET+1, rtdev->irq,
	       rtdev->dev_addr[0], rtdev->dev_addr[1], rtdev->dev_addr[2],
	       rtdev->dev_addr[3], rtdev->dev_addr[4], rtdev->dev_addr[5]);
	
	return 0;
}
Пример #14
0
int __init rtcap_init(void)
{
    struct rtnet_device *rtdev;
    struct net_device   *dev;
    int                 ret;
    int                 devices = 0;
    int                 i;
    unsigned long       flags;


    printk("RTcap: real-time capturing interface\n");

#if defined(CONFIG_RTAI_24) || defined(CONFIG_RTAI_30) || defined(CONFIG_RTAI_31)
    if (start_timer) {
        rt_set_oneshot_mode();
        start_rt_timer(0);
    }
#endif

    rtskb_queue_init(&cap_queue);

    ret = rtos_nrt_signal_init(&cap_signal, rtcap_signal_handler);
    if (ret < 0)
        goto error1;

    for (i = 0; i < MAX_RT_DEVICES; i++) {
        tap_device[i].present = 0;

        rtdev = rtdev_get_by_index(i);
        if (rtdev != NULL) {
            down(&rtdev->nrt_sem);

            if (test_bit(PRIV_FLAG_UP, &rtdev->priv_flags)) {
                up(&rtdev->nrt_sem);
                printk("RTcap: %s busy, skipping device!\n", rtdev->name);
                rtdev_dereference(rtdev);
                continue;
            }

            if (rtdev->mac_priv != NULL) {
                up(&rtdev->nrt_sem);

                printk("RTcap: RTmac discipline already active on device %s. "
                       "Load RTcap before RTmac!\n", rtdev->name);

                rtdev_dereference(rtdev);
                continue;
            }

            memset(&tap_device[i].tap_dev_stats, 0,
                   sizeof(struct net_device_stats));

            dev = &tap_device[i].tap_dev;
            memset(dev, 0, sizeof(struct net_device));
            dev->init = tap_dev_init;
            dev->priv = rtdev;
            strncpy(dev->name, rtdev->name, IFNAMSIZ-1);
            dev->name[IFNAMSIZ-1] = 0;

            ret = register_netdev(dev);
            if (ret < 0) {
                up(&rtdev->nrt_sem);
                rtdev_dereference(rtdev);

                printk("RTcap: unable to register %s!\n", dev->name);
                goto error2;
            }
            tap_device[i].present = TAP_DEV;

            tap_device[i].orig_xmit = rtdev->hard_start_xmit;

            if ((rtdev->flags & IFF_LOOPBACK) == 0) {
                dev = &tap_device[i].rtmac_tap_dev;
                memset(dev, 0, sizeof(struct net_device));
                dev->init = tap_dev_init;
                dev->priv = rtdev;
                strncpy(dev->name, rtdev->name, IFNAMSIZ-1);
                dev->name[IFNAMSIZ-1] = 0;
                strncat(dev->name, "-mac", IFNAMSIZ-strlen(dev->name));

                ret = register_netdev(dev);
                if (ret < 0) {
                    up(&rtdev->nrt_sem);
                    rtdev_dereference(rtdev);

                    printk("RTcap: unable to register %s!\n", dev->name);
                    goto error2;
                }
                tap_device[i].present |= RTMAC_TAP_DEV;

                rtdev->hard_start_xmit = rtcap_xmit_hook;
            } else
                rtdev->hard_start_xmit = rtcap_loopback_xmit_hook;

            /* If the device requires no xmit_lock, start_xmit points equals
             * hard_start_xmit => we have to update this as well
             */
            if (rtdev->features & RTNETIF_F_NON_EXCLUSIVE_XMIT)
                rtdev->start_xmit = rtdev->hard_start_xmit;
                
            tap_device[i].present |= XMIT_HOOK;
            __MOD_INC_USE_COUNT(rtdev->owner);

            up(&rtdev->nrt_sem);

            devices++;
        }
    }

    if (devices == 0) {
        printk("RTcap: no real-time devices found!\n");
        ret = -ENODEV;
        goto error2;
    }

    if (rtskb_pool_init(&cap_pool, rtcap_rtskbs * devices) <
            rtcap_rtskbs * devices) {
        rtskb_pool_release(&cap_pool);
        ret = -ENOMEM;
        goto error2;
    }

    /* register capturing handlers with RTnet core */
    rtos_spin_lock_irqsave(&rtcap_lock, flags);
    rtcap_handler = rtcap_rx_hook;
    rtos_spin_unlock_irqrestore(&rtcap_lock, flags);

    return 0;

  error2:
    cleanup_tap_devices();
    rtos_nrt_signal_delete(&cap_signal);

  error1:
#if defined(CONFIG_RTAI_24) || defined(CONFIG_RTAI_30) || defined(CONFIG_RTAI_31)
    if (start_timer)
        stop_rt_timer();
#endif

    return ret;
}
Пример #15
0
struct rtnet_device * rt2x00_core_probe(struct _rt2x00_dev_handler * handler, 
					void * priv, 
					u32 sizeof_dev) {

    struct rtnet_device	 * rtnet_dev  = NULL;
    struct _rt2x00_core	 * core       = NULL;
    struct rtwlan_device * rtwlan_dev = NULL;
    static int cards_found = -1;
    int err;

    DEBUG("Start.\n");

    cards_found++;
    if (cards[cards_found] == 0)
        goto exit;

    rtnet_dev = rtwlan_alloc_dev(sizeof_dev + sizeof(*core));
    if(!rtnet_dev)
        goto exit;

    rt_rtdev_connect(rtnet_dev, &RTDEV_manager);
    RTNET_SET_MODULE_OWNER(rtnet_dev);
    rtnet_dev->vers = RTDEV_VERS_2_0;

    rtwlan_dev = rtnetdev_priv(rtnet_dev);
    memset(rtwlan_dev, 0x00, sizeof(*rtwlan_dev));

    core = rtwlan_priv(rtwlan_dev);
    memset(core, 0x00, sizeof(*core));

    core->rtwlan_dev = rtwlan_dev;
    core->handler = handler;
    core->priv = (void*)core + sizeof(*core);
    core->rtnet_dev = rtnet_dev;  

    if (rtskb_pool_init(&core->rtwlan_dev->skb_pool, RX_ENTRIES*2) < RX_ENTRIES*2) {
        rtskb_pool_release(&core->rtwlan_dev->skb_pool);
        ERROR("rtskb_pool_init failed.\n");
        goto exit;
    }

    /* Set configuration default values. */
    rt2x00_init_config(core);

    if(core->handler->dev_probe
       && core->handler->dev_probe(core, priv)){
        ERROR("device probe failed.\n");
        goto exit;
    }
    INFO("Device " MAC_FMT " detected.\n", MAC_ARG(rtnet_dev->dev_addr));

    rtwlan_dev->hard_start_xmit = rt2x00_start_xmit;

    rtnet_dev->open = &rt2x00_open;
    rtnet_dev->stop = &rt2x00_close;
    rtnet_dev->do_ioctl = &rt2x00_ioctl;
    rtnet_dev->hard_header = &rt_eth_header;

    if ((err = rt_register_rtnetdev(rtnet_dev)) != 0) {
        rtdev_free(rtnet_dev);
        ERROR("rtnet_device registration failed.\n");
        printk("err=%d\n", err);
        goto exit_dev_remove;
    }
    
    set_bit(DEVICE_AWAKE, &core->flags);

    return rtnet_dev;

  exit_dev_remove:
    if(core->handler->dev_remove)
        core->handler->dev_remove(core);

  exit:
    return NULL; 
}