/* * Function: * soc_robo_dos_monitor_init (internal) * Purpose: * dos monitor init * Parameters: * unit - unit number. * interval - time between resynchronization passes * Returns: * SOC_E_INTERNAL if can't create threads. */ int soc_robo_dos_monitor_init(int unit) { drv_robo_dos_monitor_t *dm; if (drv_dm_control[unit] != NULL){ SOC_IF_ERROR_RETURN(soc_robo_dos_monitor_deinit(unit)); } if ((dm = sal_alloc(sizeof(drv_robo_dos_monitor_t), "dos_monitor")) == NULL){ return SOC_E_MEMORY; } /* allocate dm and set init value */ sal_memset(dm, 0, sizeof (drv_robo_dos_monitor_t)); dm->dm_lock = sal_mutex_create("soc_dos_monitor_lock"); if (dm->dm_lock == NULL){ sal_free(dm); return SOC_E_MEMORY; } dm->dm_sema = sal_sem_create("robo_HWDOS_MONITOR_SLEEP", sal_sem_BINARY, 0); if (dm->dm_sema == NULL) { sal_mutex_destroy(dm->dm_lock); sal_free(dm); return SOC_E_MEMORY; } dm->dm_thread = NULL; drv_dm_control[unit] = dm; return SOC_E_NONE; }
int dmac_init(verinet_t *v) { if (v->dmacInited) { return 0; } v->dmacListening = sal_sem_create("dmac listener", sal_sem_BINARY, 0); printk("Starting DMA service...\n"); v->dmacListener = sal_thread_create("DMA-listener", SAL_THREAD_STKSZ, 100, dmac_listener, v); if (SAL_THREAD_ERROR == v->dmacListener) { printk("ERROR: could not create DMAC task: %s!\n", strerror(errno)); return -2; } sal_sem_take(v->dmacListening, sal_sem_FOREVER); /* Wait for listen() */ sal_sem_destroy(v->dmacListening); v->dmacInited = 1; return 0; }
/* * Function: _ioctl * * Purpose: * Handle IOCTL commands from user mode. * Parameters: * cmd - IOCTL cmd * arg - IOCTL parameters * Returns: * 0 on success, <0 on error */ static int _ioctl(unsigned int cmd, unsigned long arg) { lubde_ioctl_t io; uint32 pbase, size; const ibde_dev_t *bde_dev; int inst_id; bde_inst_resource_t *res; if (copy_from_user(&io, (void *)arg, sizeof(io))) { return -EFAULT; } io.rc = LUBDE_SUCCESS; switch(cmd) { case LUBDE_VERSION: io.d0 = 0; break; case LUBDE_GET_NUM_DEVICES: io.d0 = user_bde->num_devices(io.dev); break; case LUBDE_GET_DEVICE: bde_dev = user_bde->get_dev(io.dev); if (bde_dev) { io.d0 = bde_dev->device; io.d1 = bde_dev->rev; if (BDE_DEV_MEM_MAPPED(_devices[io.dev].dev_type)) { /* Get physical address to map */ io.d2 = lkbde_get_dev_phys(io.dev); io.d3 = lkbde_get_dev_phys_hi(io.dev); } } else { io.rc = LUBDE_FAIL; } break; case LUBDE_GET_DEVICE_TYPE: io.d0 = _devices[io.dev].dev_type; break; case LUBDE_GET_BUS_FEATURES: user_bde->pci_bus_features(io.dev, (int *) &io.d0, (int *) &io.d1, (int *) &io.d2); break; case LUBDE_PCI_CONFIG_PUT32: if (_devices[io.dev].dev_type & BDE_PCI_DEV_TYPE) { user_bde->pci_conf_write(io.dev, io.d0, io.d1); } else { io.rc = LUBDE_FAIL; } break; case LUBDE_PCI_CONFIG_GET32: if (_devices[io.dev].dev_type & BDE_PCI_DEV_TYPE) { io.d0 = user_bde->pci_conf_read(io.dev, io.d0); } else { io.rc = LUBDE_FAIL; } break; case LUBDE_GET_DMA_INFO: inst_id = io.dev; if (_bde_multi_inst){ _dma_resource_get(inst_id, &pbase, &size); } else { lkbde_get_dma_info(&pbase, &size); } io.d0 = pbase; io.d1 = size; /* Optionally enable DMA mmap via /dev/linux-kernel-bde */ io.d2 = USE_LINUX_BDE_MMAP; break; case LUBDE_ENABLE_INTERRUPTS: if (_devices[io.dev].dev_type & BDE_SWITCH_DEV_TYPE) { if (_devices[io.dev].isr && !_devices[io.dev].enabled) { user_bde->interrupt_connect(io.dev, _devices[io.dev].isr, _devices+io.dev); _devices[io.dev].enabled = 1; } } else { /* Process ethernet device interrupt */ /* FIXME: for multiple chips */ if (!_devices[io.dev].enabled) { user_bde->interrupt_connect(io.dev, (void(*)(void *))_ether_interrupt, _devices+io.dev); _devices[io.dev].enabled = 1; } } break; case LUBDE_DISABLE_INTERRUPTS: if (_devices[io.dev].enabled) { user_bde->interrupt_disconnect(io.dev); _devices[io.dev].enabled = 0; } break; case LUBDE_WAIT_FOR_INTERRUPT: if (_devices[io.dev].dev_type & BDE_SWITCH_DEV_TYPE) { res = &_bde_inst_resource[_devices[io.dev].inst]; #ifdef BDE_LINUX_NON_INTERRUPTIBLE wait_event_timeout(res->intr_wq, atomic_read(&res->intr) != 0, 100); #else wait_event_interruptible(res->intr_wq, atomic_read(&res->intr) != 0); #endif /* * Even if we get multiple interrupts, we * only run the interrupt handler once. */ atomic_set(&res->intr, 0); } else { #ifdef BDE_LINUX_NON_INTERRUPTIBLE wait_event_timeout(_ether_interrupt_wq, atomic_read(&_ether_interrupt_has_taken_place) != 0, 100); #else wait_event_interruptible(_ether_interrupt_wq, atomic_read(&_ether_interrupt_has_taken_place) != 0); #endif /* * Even if we get multiple interrupts, we * only run the interrupt handler once. */ atomic_set(&_ether_interrupt_has_taken_place, 0); } break; case LUBDE_USLEEP: sal_usleep(io.d0); break; case LUBDE_UDELAY: sal_udelay(io.d0); break; case LUBDE_SEM_OP: switch (io.d0) { case LUBDE_SEM_OP_CREATE: io.p0 = (bde_kernel_addr_t)sal_sem_create("", io.d1, io.d2); break; case LUBDE_SEM_OP_DESTROY: sal_sem_destroy((sal_sem_t)io.p0); break; case LUBDE_SEM_OP_TAKE: io.rc = sal_sem_take((sal_sem_t)io.p0, io.d2); break; case LUBDE_SEM_OP_GIVE: io.rc = sal_sem_give((sal_sem_t)io.p0); break; default: io.rc = LUBDE_FAIL; break; } break; case LUBDE_WRITE_IRQ_MASK: io.rc = lkbde_irq_mask_set(io.dev, io.d0, io.d1, 0); break; case LUBDE_SPI_READ_REG: if (user_bde->spi_read(io.dev, io.d0, io.dx.buf, io.d1) == -1) { io.rc = LUBDE_FAIL; } break; case LUBDE_SPI_WRITE_REG: if (user_bde->spi_write(io.dev, io.d0, io.dx.buf, io.d1) == -1) { io.rc = LUBDE_FAIL; } break; case LUBDE_READ_REG_16BIT_BUS: io.d1 = user_bde->read(io.dev, io.d0); break; case LUBDE_WRITE_REG_16BIT_BUS: io.rc = user_bde->write(io.dev, io.d0, io.d1); break; #if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)) case LUBDE_CPU_WRITE_REG: { if (lkbde_cpu_write(io.dev, io.d0, (uint32*)io.dx.buf) == -1) { io.rc = LUBDE_FAIL; } break; } case LUBDE_CPU_READ_REG: { if (lkbde_cpu_read(io.dev, io.d0, (uint32*)io.dx.buf) == -1) { io.rc = LUBDE_FAIL; } break; } case LUBDE_CPU_PCI_REGISTER: { if (lkbde_cpu_pci_register(io.dev) == -1) { io.rc = LUBDE_FAIL; } break; } #endif case LUBDE_DEV_RESOURCE: bde_dev = user_bde->get_dev(io.dev); if (bde_dev) { if (BDE_DEV_MEM_MAPPED(_devices[io.dev].dev_type)) { /* Get physical address to map */ io.rc = lkbde_get_dev_resource(io.dev, io.d0, &io.d1, &io.d2, &io.d3); } } else { io.rc = LUBDE_FAIL; } break; case LUBDE_IPROC_READ_REG: io.d1 = user_bde->iproc_read(io.dev, io.d0); if (io.d1 == -1) { io.rc = LUBDE_FAIL; } break; case LUBDE_IPROC_WRITE_REG: if (user_bde->iproc_write(io.dev, io.d0, io.d1) == -1) { io.rc = LUBDE_FAIL; } break; case LUBDE_ATTACH_INSTANCE: io.rc = _instance_attach(io.d0, io.d1); break; default: gprintk("Error: Invalid ioctl (%08x)\n", cmd); io.rc = LUBDE_FAIL; break; } if (copy_to_user((void *)arg, &io, sizeof(io))) { return -EFAULT; } return 0; }
cmd_result_t cmd_esw_rx_mon(int unit, args_t *args) /* * Function: rx * Purpose: Perform simple RX test * Parameters: unit - unit number * args - arguments * Returns: CMD_XX */ { char *c; uint32 active; int r; int rv = CMD_OK; if (!sh_check_attached(ARG_CMD(args), unit)) { return(CMD_FAIL); } bcm_rx_channels_running(unit, &active); c = ARG_GET(args); if (c == NULL) { printk("Active bitmap for RX is %x.\n", active); return CMD_OK; } if (sal_strcasecmp(c, "init") == 0) { if (_init_rx_api(unit) < 0) { return CMD_FAIL; } else { return CMD_OK; } } else if (sal_strcasecmp(c, "enqueue") == 0) { if (pkt_queue_lock[unit] == NULL) { /* Init free pkt stuff */ pkt_queue_lock[unit] = sal_mutex_create("rxmon"); pkts_are_ready[unit] = sal_sem_create("rxmon", sal_sem_BINARY, 0); if (sal_thread_create("rxmon", SAL_THREAD_STKSZ, 80, rx_free_pkts, INT_TO_PTR(unit)) == SAL_THREAD_ERROR) { printk("FAILED to start rxmon packet free thread\n"); sal_mutex_destroy(pkt_queue_lock[unit]); pkt_queue_lock[unit] = NULL; sal_sem_destroy(pkts_are_ready[unit]); pkts_are_ready[unit] = NULL; return CMD_FAIL; } } enqueue_pkts[unit] = 1; if ((c = ARG_GET(args)) != NULL) { enqueue_pkts[unit] = strtoul(c, NULL, 0); } } else if (sal_strcasecmp(c, "-enqueue") == 0) { enqueue_pkts[unit] = 0; } else if (sal_strcasecmp(c, "start") == 0) { rx_cb_count = 0; if (!bcm_rx_active(unit)) { /* Try to initialize */ if (_init_rx_api(unit) < 0) { printk("Warning: init failed. Will attempt register\n"); } } /* Register to accept all cos */ if ((r = bcm_rx_register(unit, "RX CMD", rx_cb_handler, BASIC_PRIO, NULL, BCM_RCO_F_ALL_COS)) < 0) { printk("%s: bcm_rx_register failed: %s\n", ARG_CMD(args), bcm_errmsg(r)); return CMD_FAIL; } printk("NOTE: 'debugmod diag rx' required for rxmon output\n"); } else if (sal_strcasecmp(c, "stop") == 0) { if ((r = bcm_rx_stop(unit, &rx_cfg)) < 0) { printk("%s: Error: Cannot stop RX: %s. Is it running?\n", ARG_CMD(args), bcm_errmsg(r)); return CMD_FAIL; } /* Unregister handler */ if ((r = bcm_rx_unregister(unit, rx_cb_handler, BASIC_PRIO)) < 0) { printk("%s: bcm_rx_unregister failed: %s\n", ARG_CMD(args), bcm_errmsg(r)); return CMD_FAIL; } } else if (sal_strcasecmp(c, "show") == 0) { #ifdef BROADCOM_DEBUG bcm_rx_show(unit); #else printk("%s: ERROR: cannot show in non-BROADCOM_DEBUG compilation\n", ARG_CMD(args)); return CMD_FAIL; #endif /* BROADCOM_DEBUG */ } else { return CMD_USAGE; } return rv; }
int _bcm_mbox_comm_init(int unit, int appl_type) { #if defined(BCM_CMICM_SUPPORT) int rv = BCM_E_NONE; int timeout_usec = 1900000; int max_num_cores = 2; int result; int c; int i; /* Init the system if this is the first time in */ if (mbox_info.unit_state == NULL) { mbox_info.unit_state = soc_cm_salloc(unit, sizeof(_bcm_bs_internal_stack_state_t) * BCM_MAX_NUM_UNITS, "mbox_info_unit_state"); sal_memset(mbox_info.unit_state, 0, sizeof(_bcm_bs_internal_stack_state_t) * BCM_MAX_NUM_UNITS); } /* Init the unit if this is the first time for the unit */ if (mbox_info.unit_state[unit].mboxes == NULL) { /* allocate space for mboxes */ mbox_info.unit_state[unit].mboxes = soc_cm_salloc(unit, sizeof(_bcm_bs_internal_stack_mboxes_t), "bs msg"); if (!mbox_info.unit_state[unit].mboxes) { return BCM_E_MEMORY; } /* clear state of message mboxes */ mbox_info.unit_state[unit].mboxes->num_buffers = soc_ntohl(_BCM_MBOX_MAX_BUFFERS); for (i = 0; i < _BCM_MBOX_MAX_BUFFERS; ++i) { mbox_info.unit_state[unit].mboxes->status[i] = _BCM_MBOX_MS_EMPTY; } mbox_info.comm_available = sal_sem_create("BCM BS comms", sal_sem_BINARY, 0); rv = sal_sem_give(mbox_info.comm_available); mbox_info.unit_state[unit].response_ready = sal_sem_create("CMICM_resp", sal_sem_BINARY, 0); sal_thread_create("CMICM Rx", SAL_THREAD_STKSZ, soc_property_get(unit, spn_UC_MSG_THREAD_PRI, 50) + 1, _bcm_mbox_rx_thread, INT_TO_PTR(unit)); /* allocate space for debug log */ /* size is the size of the structure without the placeholder space for debug->buf, plus the real space for it */ mbox_info.unit_state[unit].log = soc_cm_salloc(unit, sizeof(_bcm_bs_internal_stack_log_t) - sizeof(mbox_info.unit_state[unit].log->buf) + _BCM_MBOX_MAX_LOG, "bs log"); if (!mbox_info.unit_state[unit].log) { soc_cm_sfree(unit, mbox_info.unit_state[unit].mboxes); return BCM_E_MEMORY; } /* initialize debug */ mbox_info.unit_state[unit].log->size = soc_htonl(_BCM_MBOX_MAX_LOG); mbox_info.unit_state[unit].log->head = 0; mbox_info.unit_state[unit].log->tail = 0; /* set up the network-byte-order pointers so that CMICm can access the shared memory */ mbox_info.unit_state[unit].mbox_ptr = soc_htonl(soc_cm_l2p(unit, (void*)mbox_info.unit_state[unit].mboxes)); mbox_info.unit_state[unit].log_ptr = soc_htonl(soc_cm_l2p(unit, (void*)mbox_info.unit_state[unit].log)); /* soc_cm_print("DEBUG SPACE: %p\n", (void *)mbox_info.unit_state[unit].log->buf); */ rv = BCM_E_UNAVAIL; for (c = max_num_cores - 1; c >= 0; c--) { /* soc_cm_print("Trying BS on core %d\n", c); */ result = soc_cmic_uc_appl_init(unit, c, MOS_MSG_CLASS_BS, timeout_usec, _BCM_MBOX_SDK_VERSION, _BCM_MBOX_UC_MIN_VERSION); if (SOC_E_NONE == result){ /* uKernel communcations started successfully, so run the init */ /* Note: the length of this message is unused, and can be overloaded */ mos_msg_data_t start_msg; start_msg.s.mclass = MOS_MSG_CLASS_BS; start_msg.s.subclass = MOS_MSG_SUBCLASS_MBOX_CONFIG; _shr_uint16_write((uint8*)(&(start_msg.s.len)), (uint16) appl_type); start_msg.s.data = bcm_htonl(soc_cm_l2p(unit, (void*)&mbox_info.unit_state[unit])); if (BCM_FAILURE(rv = soc_cmic_uc_msg_send(unit, c, &start_msg, timeout_usec))) { _MBOX_ERROR_FUNC("soc_cmic_uc_msg_send()"); } mbox_info.unit_state[unit].core_num = c; break; } /* soc_cm_print("No response on core %d\n", c); */ } if (BCM_FAILURE(rv)) { soc_cm_print("No response from CMICm core(s)\n"); return rv; } _bcm_mbox_debug_poll(INT_TO_PTR(&_bcm_mbox_debug_poll), INT_TO_PTR(1000), INT_TO_PTR(unit), 0, 0); } return rv; #else /* BCM_CMICM_SUPPORT */ return BCM_E_UNAVAIL; #endif /* BCM_CMICM_SUPPORT */ }
_bcm_ptp_sem_t _bcm_ptp_sem_create(char *desc, int binary, int initial_count) { return sal_sem_create(desc, binary, initial_count); }