/* VA device start handler. */ static STATUS vxworks_va_start(END_OBJ *end) { VxWorksVa *va = (void *)end; SSH_DEBUG(SSH_D_HIGHOK, ("starting %s", va->name)); /* A normal ethernet driver would set IFF_UP here; we leave it off for ssh_virtual_adapter_configure() to set. */ END_FLAGS_SET(&va->end, IFF_RUNNING); return OK; }
int NetdrvStart(END_DEVICE * pDrvCtrl) { #ifdef POLLING_MODE unsigned int unit; if (started == 1) { return OK; } #endif /** start RX Tasks */ PRINTF_DEBUG(("BCM NetDriver is starting .......\n")); #ifdef POLLING_MODE if (_n_devices > MAX_DEVICES) { printf("\r\nCannot support switch chips over 4\r\n"); return ERROR; } #endif /* POLLING_MODE */ __netDriver = pDrvCtrl; if (GetMacFromFlash(pDrvCtrl->enetAddr) == ERROR) { printf("Error: unable to start netdrv (Invalid MAC Address)\n"); return ERROR; } bcopy ((char *)pDrvCtrl->enetAddr, (char *)END_HADDR(&pDrvCtrl->end), END_HADDR_LEN(&pDrvCtrl->end)); { extern void bcmSystemInit(); bcmSystemInit(); taskDelay(100); } END_FLAGS_SET (&pDrvCtrl->end, IFF_UP | IFF_RUNNING); #ifdef POLLING_MODE gPollRecvTaskId = taskSpawn("RxPollTask", 100, 0, 16384, (FUNCPTR)DrvPollRcvPktTask, (int)pDrvCtrl, 0, 0, 0, 0, 0, 0, 0, 0, 0); if (gPollRecvTaskId == ERROR) { return ERROR; } started = 1; #endif /* POLLING_MODE */ return (OK); }
LOCAL STATUS mirrorEndStart ( END_CTRL* pDrvCtrl ) { /* initialize flag(s) */ pDrvCtrl->polling = FALSE; pDrvCtrl->promiscuous = FALSE; /* mark the channel state as "UP" */ channelState[pDrvCtrl->unit] = CHANNEL_UP; /* raise the interface flags - mark the device as up */ END_FLAGS_SET (&pDrvCtrl->endObject, IP_IFF_UP | IP_IFF_RUNNING); /* update the interface flags */ mirrorEndRunningState(); return OK; }
LOCAL int NetdrvIoctl(END_DEVICE * pDrvCtrl, /* device receiving command */ int cmd, /* ioctl command code */ caddr_t data /* command argument */) { int error = 0; long value; switch (cmd) { case EIOCSADDR: if (data == NULL) { return (EINVAL); } bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end), END_HADDR_LEN(&pDrvCtrl->end)); break; case EIOCGADDR: if (data == NULL) { return (EINVAL); } bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data, END_HADDR_LEN(&pDrvCtrl->end)); break; case EIOCSFLAGS: value = (long)data; if (value < 0) { value = -(--value); END_FLAGS_CLR (&pDrvCtrl->end, value); } else { END_FLAGS_SET (&pDrvCtrl->end, value); } NetdrvConfig(pDrvCtrl); break; case EIOCGFLAGS: *(int *)data = END_FLAGS_GET(&pDrvCtrl->end); break; case EIOCPOLLSTART: /* Begin polled operation */ NetdrvPollStart (pDrvCtrl); break; case EIOCPOLLSTOP: /* End polled operation */ NetdrvPollStop (pDrvCtrl); break; case EIOCGMIB2: /* return MIB information */ if(data == NULL) { return (EINVAL); } bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data, sizeof(pDrvCtrl->end.mib2Tbl)); break; case EIOCGFBUF: /* return minimum First Buffer for chaining */ if(data == NULL) { return (EINVAL); } *(int *)data = NETDRV_MIN_FBUF; break; default: error = EINVAL; } return (error); }
/* VA device unload handler. */ static int vxworks_va_ioctl(END_OBJ *end, int cmd, caddr_t data) { VxWorksVa *va = (void *)end; /* This function can be called from outside tNetTask. No SSH_DEBUG() here. */ switch (cmd) { case EIOCSADDR: return EINVAL; case EIOCGADDR: if (data == NULL) return EINVAL; #ifdef ETHER_ADDR_LEN memcpy(data, va->enet_addr, ETHER_ADDR_LEN); #else /* ETHER_ADDR_LEN */ memcpy(data, va->enet_addr, 6); #endif /* ETHER_ADDR_LEN */ return 0; case EIOCSFLAGS: if ((long)data < 0) END_FLAGS_CLR(&va->end, ~(long)data); else END_FLAGS_SET (&va->end, (long)data); return 0; case EIOCGFLAGS: if (data == NULL) return EINVAL; *(long *)data = END_FLAGS_GET(end); return 0; #if VXWORKS_NETVER < 55122 case EIOCGMIB2: if (data == NULL) return EINVAL; bcopy(&va->end.mib2Tbl, data, sizeof va->end.mib2Tbl); return 0; #ifdef INCLUDE_RFC_2233 case EIOCGMIB2233: if (data == NULL || va->end.pMib2Tbl == NULL) return EINVAL; *((M2_ID **)data) = va->end.pMib2Tbl; return 0; #endif /* INCLUDE_RFC_2233 */ #else /* VXWORKS_NETVER < 55122 */ case EIOCGMIB2: case EIOCGMIB2233: if (data == NULL) return EINVAL; return endM2Ioctl(&va->end, cmd, data); #endif /* VXWORKS_NETVER < 55122 */ default: return EINVAL; } }
STATUS mirrorEndRunningState(void) { BRIDGE_PORT_INFO* pPortInfo; END_OBJ *pEnd0, *pEnd1; END_MEDIA media; int error; long flags; pEnd1 = endFindByName (MIRROR_DEV_NAME,MIRROR_STACK_UNIT_NUM); pEnd0 = endFindByName (MIRROR_DEV_NAME,MIRROR_BRIDGE_UNIT_NUM); if (pEnd1) flags = END_FLAGS_GET(pEnd1); else return OK; for (pPortInfo = (BRIDGE_PORT_INFO*)lstFirst(&bridgePortList); (pPortInfo != NULL) && (strcmp(pPortInfo->name, MIRROR_DEV_NAME)!=0); pPortInfo = (BRIDGE_PORT_INFO*)lstNext((NODE*)pPortInfo)) { muxIoctl(pPortInfo->pMuxBindCookie,EIOCGIFMEDIA,(char *)&media); LOG_MSG("mirrorEndRunningState: port %s, unit %d, status 0x%x\n", pPortInfo->name, pPortInfo->unitNum, media.endMediaStatus, 4, 5, 6); if ((media.endMediaStatus & (IFM_AVALID|IFM_ACTIVE)) == (IFM_AVALID|IFM_ACTIVE)) { if ((flags & IP_IFF_RUNNING) == 0) { LOG_MSG("mirrorEndRunningState: state changed to RUNNING\n", 1, 2, 3, 4, 5, 6); /* raise both interface flags - mark the devices as RUNNING */ if (pEnd0) END_FLAGS_SET (pEnd0, IP_IFF_RUNNING); END_FLAGS_SET (pEnd1, IP_IFF_RUNNING); /* inform the stack about the interface UP state change */ jobQueueStdPost (netJobQueueId, NET_TASK_QJOB_PRI, muxLinkUpNotify, pEnd1, NULL, NULL, NULL, NULL); } return OK; } } if (flags & IP_IFF_RUNNING) { LOG_MSG("mirrorEndRunningState: state changed to NOT RUNNING\n", 1, 2, 3, 4, 5, 6); /* mark both drivers as NOT RUNNING */ if (pEnd0) END_FLAGS_CLR (pEnd0, IP_IFF_RUNNING); END_FLAGS_CLR (pEnd1, IP_IFF_RUNNING); /* inform the stack about the interface UP state change */ jobQueueStdPost (netJobQueueId, NET_TASK_QJOB_PRI, muxLinkDownNotify, pEnd1, NULL, NULL, NULL, NULL); } return OK; }
LOCAL int mirrorEndIoctl ( END_CTRL* pDrvCtrl, int cmd, caddr_t data ) { int error = 0; long value; END_OBJ* pEndObj = &pDrvCtrl->endObject; END_MEDIA * pMedia; switch ((UINT)cmd) { case EIOCSADDR: if (data == NULL) { error = EINVAL; } else { bcopy((char*)data, (char*)END_HADDR(pEndObj), END_HADDR_LEN(pEndObj)); } break; case EIOCGADDR: if (data == NULL) { error = EINVAL; } else { bcopy((char*)END_HADDR(pEndObj), (char*)data, END_HADDR_LEN(pEndObj)); } break; case EIOCSFLAGS: value = (long)data; if (value < 0) { value = -value; value--; END_FLAGS_CLR(pEndObj, value); } else { END_FLAGS_SET(pEndObj, value); } if (END_FLAGS_GET(pEndObj) & IP_IFF_PROMISC) { pDrvCtrl->promiscuous = TRUE; } else { pDrvCtrl->promiscuous = FALSE; } break; case EIOCGFLAGS: if (data == NULL) { error = EINVAL; } else { *(int*)data = END_FLAGS_GET(pEndObj); } break; case EIOCGIFMEDIA: if (data == NULL) error = EINVAL; else { value = END_FLAGS_GET(pEndObj); pMedia = (END_MEDIA *)data; pMedia->endMediaActive = IFM_AVALID; pMedia->endMediaStatus = IFM_AVALID; if (value & IP_IFF_RUNNING) { LOG_MSG("ioctl with EIOCGIFMEDIA, set active bit \n", 1, 2, 3, 4, 5, 6); pMedia->endMediaStatus |= IFM_ACTIVE; } else { LOG_MSG("ioctl with EIOCGIFMEDIA, clear active bit \n", 1, 2, 3, 4, 5, 6); pMedia->endMediaStatus &= ~IFM_ACTIVE; } } break; case EIOCPOLLSTART: error = mirrorEndPollStart(pDrvCtrl); break; case EIOCPOLLSTOP: error = mirrorEndPollStop(pDrvCtrl); break; case EIOCGMIB2: if (data == NULL) { error = EINVAL; } else { bcopy((char*)&pDrvCtrl->endObject.mib2Tbl, (char*)data, sizeof(pDrvCtrl->endObject.mib2Tbl)); } break; case EIOCGFBUF: if (data == NULL) { error = EINVAL; } else { *(int*)data = LENGTH_MIN_FBUF; } break; default: error = EINVAL; break; } return error; }
STATUS socend_start(_END_OBJ_PAR *p) /* * Function: socend_start * Purpose: SENS interface to activate a SOC interface. * Parameters: p - pointer to VxWorks end_obj structure for device * Returns: OK/ERROR * * Notes: */ { int rv; struct end_object *eo = (struct end_object *)p; socend_t *se = (socend_t *)eo->devObject.pDevice; bcm_l2_addr_t l2addr; int i; int my_modid; LOG_INFO(BSL_LS_SYS_END, (BSL_META("socend_start: Device(%s), unit %d\n"), eo->devObject.name, se->se_unit)); if (!ENET_CMP_MACADDR(se->se_mac, mac_zero)) { LOG_CLI((BSL_META("socend_start: No valid mac address assigned: " "Network Device %s%d\n"), eo->devObject.name, eo->devObject.unit)); } bcopy((char *)se->se_mac, (char *)eo->mib2Tbl.ifPhysAddress.phyAddress, eo->mib2Tbl.ifPhysAddress.addrLength); LOG_INFO(BSL_LS_SYS_END, (BSL_META("socend_start: Starting bcm_rx\n"))); if (!bcm_rx_active(se->se_unit)) { bcm_rx_cfg_t rx_cfg; bcm_rx_cfg_get(se->se_unit, &rx_cfg); rx_cfg.pkt_size = SOC_END_PK_SZ; rx_cfg.rx_alloc = socend_packet_alloc; rx_cfg.rx_free = socend_packet_free; if ((rv= bcm_rx_start(se->se_unit, &rx_cfg)) < 0) { LOG_CLI((BSL_META("rxmon: Error: Cannot start RX: %s.\n"), bcm_errmsg(rv))); return(ERROR); } }else { LOG_CLI((BSL_META("RX Thread is already running\n"))); } LOG_INFO(BSL_LS_SYS_END, (BSL_META("socend_start: adding l2 addr\n"))); bcm_l2_addr_t_init(&l2addr, se->se_mac, se->se_vlan); l2addr.port = CMIC_PORT(se->se_unit); l2addr.flags = BCM_L2_STATIC; bcm_stk_my_modid_get(se->se_unit, &my_modid); l2addr.modid = my_modid; rv = bcm_l2_addr_add(se->se_unit, &l2addr); if (rv < 0) { LOG_CLI((BSL_META("socend_start: %s%d bcm_l2_addr_add failed: %s\n"), eo->devObject.name, eo->devObject.unit, bcm_errmsg(rv))); return(ERROR); } LOG_INFO(BSL_LS_SYS_END, (BSL_META("socend_start: registering with bcm_rx\n"))); for (i = 0; i < SOC_END_HANDLER_PRIO_COUNT; i++) { if (socend_prio_map[i].valid != TRUE){ socend_prio_map[i].valid = TRUE; socend_prio_map[i].socend = se; break; } } if(i == SOC_END_HANDLER_PRIO_COUNT){ LOG_CLI((BSL_META("socend_start: socend count is larger %d\n"), SOC_END_HANDLER_PRIO_COUNT)); return(ERROR); } /* Register call back */ if (SOC_IS_ESW(se->se_unit)) { rv = bcm_rx_register(se->se_unit, "SOCEND", socend_receive, (i + SOC_END_HANDLER_PRIO_BASE), (void *)se, BCM_RCO_F_ALL_COS); } else { rv = bcm_rx_register(se->se_unit, "SOCEND", socend_receive, (i + SOC_END_HANDLER_PRIO_BASE), (void *)se, BCM_RCO_F_ALL_COS | BCM_RCO_F_INTR); } if (rv < 0) { LOG_CLI((BSL_META("Warning: Could not register socend_receive from RX\n"))); return(ERROR); } END_FLAGS_SET(eo, IFF_UP | IFF_RUNNING | IFF_BROADCAST); LOG_INFO(BSL_LS_SYS_END, (BSL_META("socend_start: Started Network Interface: %s%d\n"), eo->devObject.name, eo->devObject.unit)); return(OK); }
STATUS socend_ioctl(_END_OBJ_PAR *p, int cmd, caddr_t data) /* * Function: socend_ioctl * Purpose: SENS IOCTL function for SOC devices. * Parameters: p - pointer to VxWorks end_obj structure for device * cmd - command to execute * data - data or address of data for CMD. * Returns: Status */ { struct end_object *eo = (struct end_object *)p; socend_t *se = (socend_t *)eo->devObject.pDevice; STATUS error = OK; int unit = se->se_unit; LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: unit %d\n"), se->se_unit)); switch((unsigned int)cmd) { case EIOCSFLAGS: LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: %s%d: EIOCSFLAGS(0x%x)\n"), eo->devObject.name, eo->devObject.unit, (unsigned int)data)); if ((long)data < 0) { /* Clearing flags? */ END_FLAGS_CLR(eo, -(long)data); } else { END_FLAGS_SET(eo, (long)data); } break; case EIOCGFLAGS: LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: %s%d: EIOCGFLAGS\n"), eo->devObject.name, eo->devObject.unit)); if (NULL == data) { error = EINVAL; } else { *(int *)data = eo->flags; } break; case EIOCSADDR: /* Set interface address */ LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: %s%d: EIOCSADDR\n"), eo->devObject.name, eo->devObject.unit)); if (NULL == data) { error = EINVAL; } else { bcm_l2_addr_t l2addr; int my_modid; if (ENET_CMP_MACADDR(se->se_mac, mac_zero)) { LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: Deleting old mac address\n"))); (void)bcm_l2_addr_delete(se->se_unit, se->se_mac, se->se_vlan); } ENET_COPY_MACADDR(data, se->se_mac); LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: Setting new mac address\n"))); bcm_l2_addr_t_init(&l2addr, se->se_mac, se->se_vlan); l2addr.port = CMIC_PORT(unit); l2addr.flags = BCM_L2_STATIC; bcm_stk_my_modid_get(se->se_unit, &my_modid); l2addr.modid = my_modid; if (0 > bcm_l2_addr_add(se->se_unit, &l2addr)) { LOG_CLI((BSL_META_U(unit, "socend_ioctl: mac_configure_address failed: " "Network Device %s%d\n"), eo->devObject.name, eo->devObject.unit)); ENET_COPY_MACADDR(mac_zero, se->se_mac); error = EIO; break; } END_MIB_INIT(eo, M2_ifType_ethernet_csmacd, (uint8 *)data, 6, ETHERMTU, SOC_END_SPEED); } break; case EIOCGADDR: /* Get Interface address */ LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: %s%d: EIOCGADDR\n"), eo->devObject.name, eo->devObject.unit)); if (NULL == data) { error = EINVAL; } else { bcopy((char *)eo->mib2Tbl.ifPhysAddress.phyAddress, (char *)data, eo->mib2Tbl.ifPhysAddress.addrLength); } break; case EIOCGFBUF: /* Get min 1st buf for chain */ LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: %s%d: EIOCGFBUF\n"), eo->devObject.name, eo->devObject.unit)); if (data == NULL) { error = EINVAL; } else { *(int *)data = 32; } break; case EIOCGMWIDTH: /* Get device memory witdh */ LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: %s%d: EIOCGMWIDTH\n"), eo->devObject.name, eo->devObject.unit)); if (NULL == data) { error = EINVAL; } else { *(int *)data = 32; } break; case EIOCMULTIADD: case EIOCMULTIDEL: case EIOCMULTIGET: case EIOCPOLLSTART: case EIOCPOLLSTOP: LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: %s%d: MULTI/POLL\n"), eo->devObject.name, eo->devObject.unit)); error = ENOSYS; break; case EIOCGMIB2: /* Get MIB2 Table */ LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: %s%d: EIOCGMIB2\n"), eo->devObject.name, eo->devObject.unit)); if (data == NULL) { error = EINVAL; } else { bcopy ((char *)&eo->mib2Tbl, (char *)data, sizeof(eo->mib2Tbl)); } break; case EIOCGNAME: /* Get device Name */ LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: %s%d: EIOCGNAME\n"), eo->devObject.name, eo->devObject.unit)); if (NULL == data) { error = EINVAL; } else { bcopy(eo->devObject.name, (char *)data, sizeof(eo->devObject.name)); } break; case EIOCGHDRLEN: if (NULL == data) { error = EINVAL; } else { *(int *)data = ENET_TAGGED_HDR_LEN; } break; #if VX_VERSION == 62 || VX_VERSION == 64 || VX_VERSION == 66 || VX_VERSION == 68 case EIOCGRCVJOBQ: LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: %s%d: EIOCGRCVJOBQ\n"), eo->devObject.name, eo->devObject.unit)); if (NULL == data) { error = EINVAL; } else { END_RCVJOBQ_INFO *qinfo = (END_RCVJOBQ_INFO *)data; LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: %s%d: numRcvJobQs input#: %d\n"), eo->devObject.name, eo->devObject.unit, qinfo->numRcvJobQs)); if (qinfo->numRcvJobQs < 1) { error = ENOSPC; } else { qinfo->qIds[0] = netJobQueueId; } qinfo->numRcvJobQs = 1; } break; #endif /* VX_VERSION */ default: LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: %s%d: Unknown IOCTL\n"), eo->devObject.name, eo->devObject.unit)); error = EINVAL; break; } LOG_INFO(BSL_LS_SYS_END, (BSL_META_U(unit, "socend_ioctl: %s%d: cmd=0x%x Return(%d)\n"), eo->devObject.name, eo->devObject.unit, cmd, error)); return(error); }