/* ************************************************************************ * ************************************************************************ * 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; }
/*** * 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; }
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; }
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; } }
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; }
/*** * 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; }
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"); }
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); }
/** * 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(); }
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); }
/*** * 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); }
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); }
/* 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; }
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; }
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; }