+/*\r
+ * Copyright (c) 2005 SilverStorm Technologies. All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer.\r
+ *\r
+ * - Redistributions in binary form must reproduce the above\r
+ * copyright notice, this list of conditions and the following\r
+ * disclaimer in the documentation and/or other materials\r
+ * provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id$\r
+ */\r
+\r
+#include "vnic_adapter.h"\r
+\r
+static void\r
+control_recv( Control_t *pControl, RecvIo_t *pRecvIo );\r
+\r
+static void\r
+control_recvComplete(\r
+ IN Io_t *pIo );\r
+\r
+static ib_api_status_t\r
+control_send( Control_t *pControl );\r
+\r
+static void\r
+control_sendComplete( Io_t *pIo );\r
+static void\r
+control_timeout( void * context );\r
+\r
+static void\r
+control_timer( Control_t *pControl, int timeout );\r
+\r
+static void\r
+control_timerStop( Control_t *pControl );\r
+\r
+static void\r
+control_initHdr( Control_t *pControl, uint8_t cmd );\r
+\r
+static RecvIo_t *\r
+control_getRsp( Control_t *pControl );\r
+\r
+static void\r
+copyRecvPoolConfig( Inic_RecvPoolConfig_t *pSrc,\r
+ Inic_RecvPoolConfig_t *pDst );\r
+\r
+static BOOLEAN\r
+checkRecvPoolConfigValue(\r
+ IN void *pSrc,\r
+ IN void *pDst,\r
+ IN void *pMax,\r
+ IN void *pMin,\r
+ IN char *name );\r
+\r
+static BOOLEAN checkRecvPoolConfig(\r
+ Inic_RecvPoolConfig_t *pSrc,\r
+ Inic_RecvPoolConfig_t *pDst,\r
+ Inic_RecvPoolConfig_t *pMax,\r
+ Inic_RecvPoolConfig_t *pMin);\r
+\r
+static void\r
+__control_logControlPacket(\r
+ Inic_ControlPacket_t *pPkt );\r
+\r
+static inline char*\r
+control_ifcfg_name( Control_t *pControl )\r
+{\r
+ if (! pControl)\r
+ return "NCtl";\r
+ return (pControl->p_viport->p_adapter->name );\r
+}\r
+\r
+\r
+void\r
+control_construct(\r
+ IN Control_t *pControl,\r
+ IN viport_t *pViport )\r
+{\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ cl_memclr(pControl, sizeof(Control_t));\r
+\r
+ pControl->p_viport = pViport;\r
+\r
+ pControl->reqOutstanding = FALSE;\r
+ pControl->seqNum = 0;\r
+\r
+ pControl->pResponse = NULL;\r
+ pControl->pInfo = NULL;\r
+\r
+ pControl->p_viport->addrs_query_done = TRUE;\r
+\r
+ InitializeListHead(&pControl->failureList);\r
+ KeInitializeSpinLock(&pControl->ioLock);\r
+\r
+ cl_timer_construct( &pControl->timer );\r
+\r
+ ibqp_construct( &pControl->qp, pViport );\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+}\r
+\r
+\r
+ib_api_status_t\r
+control_init(\r
+ IN Control_t *pControl,\r
+ IN viport_t *pViport,\r
+ IN ControlConfig_t *pConfig,\r
+ IN uint64_t guid )\r
+{\r
+ ib_api_status_t ib_status;\r
+ ib_pd_handle_t hPd;\r
+ Inic_ControlPacket_t *pkt;\r
+ Io_t *pIo;\r
+ int sz;\r
+ unsigned int i;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ pControl->p_conf = pConfig;\r
+\r
+ hPd = pViport->p_adapter->ca.hPd;\r
+\r
+ cl_timer_init( &pControl->timer, control_timeout, pControl );\r
+\r
+ ib_status = ibqp_init(\r
+ &pControl->qp, guid, &pConfig->ibConfig );\r
+ if( ib_status != IB_SUCCESS )\r
+ {\r
+ VNIC_TRACE_EXIT( VNIC_DBG_ERROR, ("%s: ibqp_init returned %s\n",\r
+ pViport->p_adapter->ifc.get_err_str( ib_status )) );\r
+ goto failure;\r
+ }\r
+\r
+ sz = (sizeof(RecvIo_t) * pConfig->numRecvs ) +\r
+ (sizeof(Inic_ControlPacket_t) * (pConfig->numRecvs + 1));\r
+\r
+ pControl->pLocalStorage = cl_zalloc( sz );\r
+\r
+ if ( pControl->pLocalStorage == NULL )\r
+ {\r
+ VNIC_TRACE_EXIT( VNIC_DBG_ERROR,\r
+ ("%s: Failed allocating space for local storage\n",\r
+ control_ifcfg_name(pControl)) );\r
+\r
+ ibqp_cleanup(&pControl->qp);\r
+ ib_status = IB_INSUFFICIENT_MEMORY;\r
+ goto failure;\r
+ }\r
+\r
+ pControl->pRecvIos = (RecvIo_t *)pControl->pLocalStorage;\r
+\r
+ pkt = (Inic_ControlPacket_t *)(pControl->pLocalStorage +\r
+ sizeof(SendIo_t) * pConfig->numRecvs);\r
+\r
+ sz = sizeof(Inic_ControlPacket_t) * (pConfig->numRecvs + 1);\r
+\r
+ ib_status = ibregion_init( pViport, &pControl->region, hPd,\r
+ pkt, sz, IB_AC_LOCAL_WRITE );\r
+ if ( ib_status != IB_SUCCESS )\r
+ {\r
+ /* NOTE: I'm allowing recvs into the send buffer as well\r
+ * as the receive buffers. I'm doing this to combine them\r
+ * into a single region, and conserve a region.\r
+ */\r
+ VNIC_TRACE_EXIT( VNIC_DBG_ERROR|VNIC_DBG_CTRL,\r
+ ("%s: Failed setting up control space region\n",\r
+ control_ifcfg_name(pControl)) );\r
+ ibqp_cleanup( &pControl->qp );\r
+ cl_free( pControl->pLocalStorage );\r
+ goto failure;\r
+ }\r
+ pIo = &pControl->sendIo.io;\r
+ pIo->pViport = pViport;\r
+ pIo->pRoutine = control_sendComplete;\r
+\r
+ pIo->wrq.p_next = NULL;\r
+ pIo->wrq.wr_type = WR_SEND;\r
+ pIo->wrq.send_opt = IB_SEND_OPT_SIGNALED;\r
+ pIo->wrq.wr_id = (uint64_t)(pIo);\r
+ pIo->wrq.num_ds = 1;\r
+ pIo->wrq.ds_array = &pControl->sendIo.dsList;\r
+ pIo->wrq.ds_array[0].length = sizeof(Inic_ControlPacket_t);\r
+ pIo->wrq.ds_array[0].lkey = pControl->region.lkey;\r
+ pIo->wrq.ds_array[0].vaddr = (uint64_t)(pkt++);\r
+\r
+ for (i = 0; i < pConfig->numRecvs; i++ )\r
+ {\r
+ pIo = &pControl->pRecvIos[i].io;\r
+ pIo->pViport = pViport;\r
+ pIo->pRoutine = control_recvComplete;\r
+\r
+ pIo->r_wrq.wr_id = (uint64_t)(pIo);\r
+ pIo->r_wrq.p_next = NULL;\r
+ pIo->r_wrq.num_ds = 1;\r
+ pIo->r_wrq.ds_array = &pControl->pRecvIos[i].dsList;\r
+ pIo->r_wrq.ds_array[0].length = sizeof(Inic_ControlPacket_t);\r
+ pIo->r_wrq.ds_array[0].vaddr = (uint64_t)(pkt++);\r
+ pIo->r_wrq.ds_array[0].lkey = pControl->region.lkey;\r
+ \r
+ if ( ibqp_postRecv( &pControl->qp, pIo ) != IB_SUCCESS )\r
+ {\r
+ control_cleanup( pControl );\r
+ ib_status = IB_ERROR;\r
+ goto failure;\r
+ }\r
+ }\r
+\r
+failure:\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return ib_status;\r
+}\r
+\r
+\r
+void\r
+control_cleanup(\r
+ IN Control_t *pControl )\r
+{\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ control_timerStop( pControl );\r
+ ibqp_detach( &pControl->qp );\r
+ ibqp_cleanup( &pControl->qp );\r
+ ibregion_cleanup( pControl->p_viport, &pControl->region );\r
+\r
+ if ( pControl->pLocalStorage )\r
+ {\r
+ cl_free( pControl->pLocalStorage );\r
+ pControl->pLocalStorage = NULL;\r
+ }\r
+\r
+ cl_timer_destroy( &pControl->timer );\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return;\r
+}\r
+\r
+void\r
+control_processAsync(\r
+ IN Control_t *pControl )\r
+{\r
+ RecvIo_t *pRecvIo;\r
+ Inic_ControlPacket_t *pPkt;\r
+ LIST_ENTRY *p_list_entry;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ pRecvIo = InterlockedExchangePointer( &pControl->pInfo, NULL );\r
+\r
+ if ( pRecvIo != NULL )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_CTRL | VNIC_DBG_INFO,\r
+ ("%s: processing info packet\n",\r
+ control_ifcfg_name(pControl)) );\r
+ \r
+ pPkt = control_packet( pRecvIo );\r
+\r
+ if ( pPkt->hdr.pktCmd == CMD_REPORT_STATUS )\r
+ {\r
+ switch( ntoh32(pPkt->cmd.reportStatus.statusNumber) )\r
+ {\r
+ case INIC_STATUS_LINK_UP:\r
+ VNIC_TRACE( VNIC_DBG_CTRL | VNIC_DBG_INFO,\r
+ ("%s: Link Up\n",\r
+ control_ifcfg_name(pControl)) );\r
+\r
+ viport_linkUp( pControl->p_viport );\r
+ break;\r
+\r
+ case INIC_STATUS_LINK_DOWN:\r
+ VNIC_TRACE( VNIC_DBG_CTRL | VNIC_DBG_INFO,\r
+ ("%s: Link Down\n",\r
+ control_ifcfg_name(pControl)) );\r
+\r
+ viport_linkDown( pControl->p_viport );\r
+ break;\r
+\r
+ default:\r
+ VNIC_TRACE( VNIC_DBG_CTRL | VNIC_DBG_ERROR,\r
+ ("%s: Asynchronous status received from EIOC\n",\r
+ control_ifcfg_name(pControl)) );\r
+ __control_logControlPacket( pPkt );\r
+ break;\r
+ }\r
+ }\r
+\r
+ if ( pPkt->hdr.pktCmd != CMD_REPORT_STATUS ||\r
+ pPkt->cmd.reportStatus.isFatal )\r
+ {\r
+ viport_failure( pControl->p_viport );\r
+ }\r
+\r
+ control_recv( pControl, pRecvIo );\r
+ }\r
+\r
+ while ( !IsListEmpty( &pControl->failureList ) )\r
+ {\r
+\r
+ VNIC_TRACE( VNIC_DBG_CTRL | VNIC_DBG_INFO,\r
+ ("%s: processing error packet\n",\r
+ control_ifcfg_name(pControl)) );\r
+\r
+ p_list_entry = ExInterlockedRemoveHeadList( &pControl->failureList, &pControl->ioLock );\r
+ pRecvIo = (RecvIo_t *)p_list_entry;\r
+ pPkt = control_packet( pRecvIo );\r
+\r
+ VNIC_TRACE( VNIC_DBG_CTRL | VNIC_DBG_INFO,\r
+ ("%s: Asynchronous error received from EIOC\n",\r
+ control_ifcfg_name(pControl)) );\r
+ \r
+ __control_logControlPacket( pPkt );\r
+\r
+ if ( ( pPkt->hdr.pktType != TYPE_ERR ) ||\r
+ ( pPkt->hdr.pktCmd != CMD_REPORT_STATUS ) ||\r
+ ( pPkt->cmd.reportStatus.isFatal ) )\r
+ {\r
+ viport_failure( pControl->p_viport );\r
+ }\r
+\r
+ control_recv( pControl, pRecvIo );\r
+ }\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+}\r
+\r
+\r
+ib_api_status_t\r
+control_initInicReq(\r
+ IN Control_t *pControl )\r
+{\r
+ ControlConfig_t *p_conf = pControl->p_conf;\r
+ Inic_ControlPacket_t *pPkt;\r
+ Inic_CmdInitInicReq_t *pInitInicReq;\r
+ ib_api_status_t ib_status;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ control_initHdr( pControl, CMD_INIT_INIC );\r
+\r
+ pPkt = control_packet( &pControl->sendIo );\r
+ pInitInicReq = &pPkt->cmd.initInicReq;\r
+ pInitInicReq->inicMajorVersion = hton16( INIC_MAJORVERSION );\r
+ pInitInicReq->inicMinorVersion = hton16( INIC_MINORVERSION );\r
+ pInitInicReq->inicInstance = p_conf->inicInstance;\r
+ pInitInicReq->numDataPaths = 1;\r
+ pInitInicReq->numAddressEntries = hton16( p_conf->maxAddressEntries );\r
+\r
+ ib_status = control_send( pControl );\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return ib_status;\r
+}\r
+\r
+\r
+BOOLEAN\r
+control_initInicRsp(\r
+ IN Control_t *pControl,\r
+ IN uint32_t *pFeatures,\r
+ IN uint8_t *pMacAddress,\r
+ IN uint16_t *pNumAddrs,\r
+ IN uint16_t *pVlan )\r
+{\r
+ RecvIo_t *pRecvIo;\r
+ ControlConfig_t *p_conf = pControl->p_conf;\r
+ Inic_ControlPacket_t *pPkt;\r
+ Inic_CmdInitInicRsp_t *pInitInicRsp;\r
+ uint8_t numDataPaths,\r
+ numLanSwitches;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ pRecvIo = control_getRsp( pControl );\r
+ if (!pRecvIo)\r
+ return FALSE;\r
+\r
+ pPkt = control_packet( pRecvIo );\r
+\r
+ if ( pPkt->hdr.pktCmd != CMD_INIT_INIC )\r
+ {\r
+ \r
+ VNIC_TRACE( VNIC_DBG_CTRL | VNIC_DBG_ERROR,\r
+ ("%s: Sent control request:\n",\r
+ control_ifcfg_name(pControl)) );\r
+\r
+ __control_logControlPacket( control_lastReq( pControl ) );\r
+\r
+ VNIC_TRACE_EXIT( VNIC_DBG_CTRL | VNIC_DBG_ERROR,\r
+ ("%s: Received control response:\n",\r
+ control_ifcfg_name(pControl)) );\r
+ \r
+ __control_logControlPacket( pPkt );\r
+ goto failure;\r
+ }\r
+ pInitInicRsp = &pPkt->cmd.initInicRsp;\r
+ pControl->majVer = ntoh16( pInitInicRsp->inicMajorVersion );\r
+ pControl->minVer = ntoh16( pInitInicRsp->inicMinorVersion );\r
+ numDataPaths = pInitInicRsp->numDataPaths;\r
+ numLanSwitches = pInitInicRsp->numLanSwitches;\r
+ *pFeatures = ntoh32( pInitInicRsp->featuresSupported );\r
+ *pNumAddrs = ntoh16( pInitInicRsp->numAddressEntries );\r
+\r
+ if ( ( pControl->majVer > INIC_MAJORVERSION ) ||\r
+ (( pControl->majVer == INIC_MAJORVERSION ) &&\r
+ ( pControl->minVer > INIC_MINORVERSION )) )\r
+ {\r
+ VNIC_TRACE_EXIT( VNIC_DBG_CTRL | VNIC_DBG_ERROR,\r
+ ("%s: Unsupported version\n",\r
+ control_ifcfg_name(pControl)) );\r
+ goto failure;\r
+ }\r
+\r
+ if ( numDataPaths != 1 )\r
+ {\r
+ VNIC_TRACE_EXIT( VNIC_DBG_CTRL | VNIC_DBG_ERROR,\r
+ ("%s: EIOC returned too many datapaths\n",\r
+ control_ifcfg_name(pControl)) );\r
+ goto failure;\r
+ }\r
+\r
+ if ( *pNumAddrs > p_conf->maxAddressEntries )\r
+ {\r
+ VNIC_TRACE_EXIT( VNIC_DBG_CTRL | VNIC_DBG_ERROR,\r
+ ("%s: EIOC returned more Address entries than requested\n",\r
+ control_ifcfg_name(pControl)) );\r
+ goto failure;\r
+ }\r
+ if ( *pNumAddrs < p_conf->minAddressEntries )\r
+ {\r
+ VNIC_TRACE_EXIT( VNIC_DBG_CTRL | VNIC_DBG_ERROR,\r
+ ("%s: Not enough address entries\n",\r
+ control_ifcfg_name(pControl)) );\r
+ goto failure;\r
+ }\r
+ if ( numLanSwitches < 1 )\r
+ {\r
+ VNIC_TRACE_EXIT( VNIC_DBG_CTRL | VNIC_DBG_ERROR,\r
+ ("%s: EIOC returned no lan switches\n",\r
+ control_ifcfg_name(pControl)) );\r
+ goto failure;\r
+ }\r
+ if ( numLanSwitches > 1 )\r
+ {\r
+ VNIC_TRACE_EXIT( VNIC_DBG_CTRL | VNIC_DBG_ERROR,\r
+ ("%s: EIOC returned multiple lan switches\n",\r
+ control_ifcfg_name(pControl)) );\r
+ goto failure;\r
+ }\r
+\r
+ pControl->lanSwitch.lanSwitchNum =\r
+ pInitInicRsp->lanSwitch[0].lanSwitchNum ;\r
+ pControl->lanSwitch.numEnetPorts =\r
+ pInitInicRsp->lanSwitch[0].numEnetPorts ;\r
+ pControl->lanSwitch.defaultVlan =\r
+ ntoh16( pInitInicRsp->lanSwitch[0].defaultVlan );\r
+ *pVlan = pControl->lanSwitch.defaultVlan;\r
+ cl_memcpy( pControl->lanSwitch.hwMacAddress,\r
+ pInitInicRsp->lanSwitch[0].hwMacAddress, MAC_ADDR_LEN );\r
+ cl_memcpy( pMacAddress,\r
+ pInitInicRsp->lanSwitch[0].hwMacAddress, MAC_ADDR_LEN);\r
+\r
+ control_recv( pControl, pRecvIo );\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return TRUE;\r
+failure:\r
+ viport_failure( pControl->p_viport );\r
+ return FALSE;\r
+}\r
+\r
+\r
+ib_api_status_t\r
+control_configDataPathReq(\r
+ IN Control_t *pControl,\r
+ IN uint64_t pathId,\r
+ IN Inic_RecvPoolConfig_t *pHost,\r
+ IN Inic_RecvPoolConfig_t *pEioc )\r
+{\r
+ Inic_ControlPacket_t *pPkt;\r
+ Inic_CmdConfigDataPath_t *pConfigDataPath;\r
+ ib_api_status_t ib_status;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ control_initHdr( pControl, CMD_CONFIG_DATA_PATH );\r
+\r
+ pPkt = control_packet( &pControl->sendIo );\r
+ pConfigDataPath = &pPkt->cmd.configDataPathReq;\r
+ NdisZeroMemory( pConfigDataPath, sizeof( Inic_CmdConfigDataPath_t ) );\r
+ pConfigDataPath->dataPath = 0;\r
+ pConfigDataPath->pathIdentifier = pathId;\r
+ copyRecvPoolConfig( pHost, &pConfigDataPath->hostRecvPoolConfig );\r
+ copyRecvPoolConfig( pEioc, &pConfigDataPath->eiocRecvPoolConfig );\r
+\r
+ ib_status = control_send( pControl );\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return ib_status;\r
+}\r
+\r
+\r
+BOOLEAN\r
+control_configDataPathRsp(\r
+ IN Control_t *pControl,\r
+ IN Inic_RecvPoolConfig_t *pHost,\r
+ IN Inic_RecvPoolConfig_t *pEioc,\r
+ IN Inic_RecvPoolConfig_t *pMaxHost,\r
+ IN Inic_RecvPoolConfig_t *pMaxEioc,\r
+ IN Inic_RecvPoolConfig_t *pMinHost,\r
+ IN Inic_RecvPoolConfig_t *pMinEioc )\r
+{\r
+ RecvIo_t *pRecvIo;\r
+ Inic_ControlPacket_t *pPkt;\r
+ Inic_CmdConfigDataPath_t *pConfigDataPath;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ pRecvIo = control_getRsp( pControl );\r
+ if ( !pRecvIo )\r
+ return FALSE;\r
+\r
+ pPkt = control_packet( pRecvIo );\r
+\r
+ if ( pPkt->hdr.pktCmd != CMD_CONFIG_DATA_PATH )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_ERROR,\r
+ ("%s: Sent control request:\n",\r
+ control_ifcfg_name(pControl)) );\r
+\r
+ __control_logControlPacket( control_lastReq( pControl ) );\r
+\r
+ VNIC_TRACE( VNIC_DBG_ERROR,\r
+ ("%s: Received control response:\n",\r
+ control_ifcfg_name( pControl )) );\r
+ \r
+ __control_logControlPacket( pPkt );\r
+ goto failure;\r
+ }\r
+\r
+ pConfigDataPath = &pPkt->cmd.configDataPathRsp;\r
+\r
+ if ( pConfigDataPath->dataPath != 0 )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_ERROR,\r
+ ("%s: Received CMD_CONFIG_DATA_PATH response for wrong data path: %u\n",\r
+ control_ifcfg_name( pControl ), pConfigDataPath->dataPath) );\r
+ goto failure;\r
+ }\r
+\r
+ if ( !checkRecvPoolConfig(&pConfigDataPath->hostRecvPoolConfig,\r
+ pHost, pMaxHost, pMinHost )\r
+ || !checkRecvPoolConfig(&pConfigDataPath->eiocRecvPoolConfig,\r
+ pEioc, pMaxEioc, pMinEioc))\r
+ {\r
+ goto failure;\r
+ }\r
+\r
+ control_recv( pControl, pRecvIo );\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return TRUE;\r
+failure:\r
+ viport_failure( pControl->p_viport );\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return FALSE;\r
+}\r
+\r
+\r
+ib_api_status_t\r
+control_exchangePoolsReq(\r
+ IN Control_t *pControl,\r
+ IN uint64_t addr,\r
+ IN uint32_t rkey )\r
+{\r
+ Inic_CmdExchangePools_t *pExchangePools;\r
+ Inic_ControlPacket_t *pPkt;\r
+ ib_api_status_t ib_status;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ control_initHdr(pControl, CMD_EXCHANGE_POOLS );\r
+\r
+ pPkt = control_packet( &pControl->sendIo );\r
+ pExchangePools = &pPkt->cmd.exchangePoolsReq;\r
+ NdisZeroMemory( pExchangePools, sizeof( Inic_CmdExchangePools_t ) );\r
+ pExchangePools->dataPath = 0;\r
+ pExchangePools->poolRKey = rkey;\r
+ pExchangePools->poolAddr = hton64( addr );\r
+\r
+ ib_status = control_send( pControl );\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return ib_status;\r
+}\r
+\r
+\r
+BOOLEAN\r
+control_exchangePoolsRsp(\r
+ IN Control_t *pControl,\r
+ IN OUT uint64_t *pAddr,\r
+ IN OUT uint32_t *pRkey )\r
+{\r
+ RecvIo_t *pRecvIo;\r
+ Inic_ControlPacket_t *pPkt;\r
+ Inic_CmdExchangePools_t *pExchangePools;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ pRecvIo = control_getRsp( pControl );\r
+ if ( !pRecvIo )\r
+ return FALSE;\r
+\r
+ pPkt = control_packet( pRecvIo );\r
+\r
+ if ( pPkt->hdr.pktCmd != CMD_EXCHANGE_POOLS )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_ERROR,\r
+ ("%s: Sent control request:\n",\r
+ control_ifcfg_name(pControl)) );\r
+\r
+ __control_logControlPacket( control_lastReq(pControl ) );\r
+\r
+ VNIC_TRACE( VNIC_DBG_ERROR,\r
+ ("%s: Received control response:\n",\r
+ control_ifcfg_name(pControl)) );\r
+ \r
+ __control_logControlPacket( pPkt );\r
+ goto failure;\r
+ }\r
+\r
+ pExchangePools = &pPkt->cmd.exchangePoolsRsp;\r
+ *pRkey = pExchangePools->poolRKey;\r
+ *pAddr = ntoh64( pExchangePools->poolAddr );\r
+\r
+ if ( hton32( pExchangePools->dataPath ) != 0 )\r
+ {\r
+ VNIC_TRACE_EXIT( VNIC_DBG_ERROR,\r
+ ("%s: Received CMD_EXCHANGE_POOLS response for wrong data path: %u\n",\r
+ control_ifcfg_name(pControl), pExchangePools->dataPath ) );\r
+ goto failure;\r
+ }\r
+\r
+ control_recv( pControl, pRecvIo );\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return TRUE;\r
+\r
+failure:\r
+ viport_failure( pControl->p_viport );\r
+ return FALSE;\r
+}\r
+\r
+\r
+ib_api_status_t\r
+control_configLinkReq(\r
+ IN Control_t *pControl,\r
+ IN uint8_t flags,\r
+ IN uint16_t mtu )\r
+{\r
+ Inic_CmdConfigLink_t *pConfigLinkReq;\r
+ Inic_ControlPacket_t *pPkt;\r
+ ib_api_status_t ib_status;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ control_initHdr( pControl, CMD_CONFIG_LINK );\r
+\r
+ pPkt = control_packet( &pControl->sendIo );\r
+ pConfigLinkReq = &pPkt->cmd.configLinkReq;\r
+ NdisZeroMemory( pConfigLinkReq, sizeof( Inic_CmdConfigLink_t ) );\r
+ pConfigLinkReq->lanSwitchNum = pControl->lanSwitch.lanSwitchNum;\r
+ pConfigLinkReq->cmdFlags = INIC_FLAG_SET_MTU;\r
+\r
+ if ( flags & INIC_FLAG_ENABLE_NIC )\r
+ {\r
+ pConfigLinkReq->cmdFlags |= INIC_FLAG_ENABLE_NIC;\r
+ }\r
+ else\r
+ {\r
+ pConfigLinkReq->cmdFlags |= INIC_FLAG_DISABLE_NIC;\r
+ }\r
+\r
+ if (flags & INIC_FLAG_ENABLE_MCAST_ALL )\r
+ {\r
+ pConfigLinkReq->cmdFlags |= INIC_FLAG_ENABLE_MCAST_ALL;\r
+ }\r
+ else\r
+ {\r
+ pConfigLinkReq->cmdFlags |= INIC_FLAG_DISABLE_MCAST_ALL;\r
+ }\r
+ if (flags & INIC_FLAG_ENABLE_PROMISC )\r
+ {\r
+ pConfigLinkReq->cmdFlags |= INIC_FLAG_ENABLE_PROMISC;\r
+ /* The EIOU doesn't really do PROMISC mode.\r
+ * If PROMISC is set, it only receives unicast packets\r
+ * I also have to set MCAST_ALL if I want real\r
+ * PROMISC mode.\r
+ */\r
+ pConfigLinkReq->cmdFlags &= ~INIC_FLAG_DISABLE_MCAST_ALL;\r
+ pConfigLinkReq->cmdFlags |= INIC_FLAG_ENABLE_MCAST_ALL;\r
+ }\r
+ else\r
+ {\r
+ pConfigLinkReq->cmdFlags |= INIC_FLAG_DISABLE_PROMISC;\r
+ }\r
+ pConfigLinkReq->mtuSize = hton16( mtu );\r
+\r
+ ib_status = control_send( pControl );\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return ib_status;\r
+}\r
+\r
+\r
+BOOLEAN\r
+control_configLinkRsp(\r
+ IN Control_t *pControl,\r
+ IN OUT uint8_t *pFlags,\r
+ IN OUT uint16_t *pMtu )\r
+{\r
+ RecvIo_t *pRecvIo;\r
+ Inic_ControlPacket_t *pPkt;\r
+ Inic_CmdConfigLink_t *pConfigLinkRsp;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ pRecvIo = control_getRsp( pControl );\r
+ if ( !pRecvIo )\r
+ return FALSE;\r
+\r
+ pPkt = control_packet( pRecvIo );\r
+ if ( pPkt->hdr.pktCmd != CMD_CONFIG_LINK )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_ERROR,\r
+ ("%s: Sent control request:\n",\r
+ control_ifcfg_name( pControl )) );\r
+\r
+ __control_logControlPacket( control_lastReq( pControl ) );\r
+\r
+ VNIC_TRACE( VNIC_DBG_ERROR,\r
+ ("%s: Received control response:\n",\r
+ control_ifcfg_name( pControl )) );\r
+ \r
+ __control_logControlPacket( pPkt );\r
+ goto failure;\r
+ }\r
+\r
+ pConfigLinkRsp = &pPkt->cmd.configLinkRsp;\r
+\r
+ *pFlags = pConfigLinkRsp->cmdFlags;\r
+ *pMtu = ntoh16( pConfigLinkRsp->mtuSize );\r
+\r
+ control_recv( pControl, pRecvIo );\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return TRUE;\r
+\r
+failure:\r
+ viport_failure( pControl->p_viport );\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return FALSE;\r
+}\r
+\r
+/* control_configAddrsReq:\r
+ * Return values:\r
+ * -1: failure\r
+ * 0: incomplete (successful operation, but more address\r
+ * table entries to be updated)\r
+ * 1: complete\r
+ */\r
+ib_api_status_t\r
+control_configAddrsReq(\r
+ IN Control_t *pControl,\r
+ IN Inic_AddressOp_t *pAddrs,\r
+ IN uint16_t num,\r
+ OUT int32_t *pAddrQueryDone )\r
+{\r
+ Inic_CmdConfigAddresses_t *pConfigAddrsReq;\r
+ Inic_ControlPacket_t *pPkt;\r
+ uint16_t i;\r
+ uint8_t j;\r
+ ib_api_status_t ib_status;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ control_initHdr( pControl, CMD_CONFIG_ADDRESSES );\r
+\r
+ pPkt = control_packet( &pControl->sendIo );\r
+ pConfigAddrsReq = &pPkt->cmd.configAddressesReq;\r
+ NdisZeroMemory( pConfigAddrsReq, sizeof( Inic_CmdConfigAddresses_t ) );\r
+ pConfigAddrsReq->lanSwitchNum = pControl->lanSwitch.lanSwitchNum;\r
+\r
+ for ( i=0, j = 0; ( i < num ) && ( j < 16 ); i++ )\r
+ {\r
+ if ( !pAddrs[i].operation )\r
+ continue;\r
+\r
+ pConfigAddrsReq->listAddressOps[j].index = hton16(i);\r
+ pConfigAddrsReq->listAddressOps[j].operation = INIC_OP_SET_ENTRY;\r
+ pConfigAddrsReq->listAddressOps[j].valid = pAddrs[i].valid;\r
+ \r
+ cl_memcpy( pConfigAddrsReq->listAddressOps[j].address,\r
+ pAddrs[i].address, MAC_ADDR_LEN );\r
+ pConfigAddrsReq->listAddressOps[j].vlan = hton16( pAddrs[i].vlan );\r
+ pAddrs[i].operation = 0;\r
+ j++;\r
+ }\r
+ pConfigAddrsReq->numAddressOps = j;\r
+\r
+ for ( ; i < num; i++ )\r
+ {\r
+ if ( pAddrs[i].operation )\r
+ break;\r
+ }\r
+ *pAddrQueryDone = (i == num);\r
+\r
+ ib_status = control_send( pControl );\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return ib_status;\r
+}\r
+\r
+\r
+BOOLEAN\r
+control_configAddrsRsp(\r
+ IN Control_t *pControl )\r
+{\r
+ RecvIo_t *pRecvIo;\r
+ Inic_ControlPacket_t *pPkt;\r
+ Inic_CmdConfigAddresses_t *pConfigAddrsRsp;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ pRecvIo = control_getRsp( pControl );\r
+ if ( !pRecvIo )\r
+ return FALSE;\r
+\r
+ pPkt = control_packet( pRecvIo );\r
+ if ( pPkt->hdr.pktCmd != CMD_CONFIG_ADDRESSES )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_ERROR,\r
+ ("%s: Sent control request:\n",\r
+ control_ifcfg_name( pControl )) );\r
+\r
+ __control_logControlPacket( control_lastReq( pControl ) );\r
+\r
+ VNIC_TRACE_EXIT(VNIC_DBG_ERROR,\r
+ ("%s: Received control response:\n",\r
+ control_ifcfg_name( pControl )) );\r
+\r
+ __control_logControlPacket( pPkt );\r
+ \r
+ goto failure;\r
+ }\r
+\r
+ pConfigAddrsRsp = &pPkt->cmd.configAddressesRsp;\r
+\r
+ control_recv( pControl, pRecvIo );\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return TRUE;\r
+\r
+failure:\r
+ viport_failure( pControl->p_viport );\r
+ return FALSE;\r
+}\r
+\r
+\r
+ib_api_status_t\r
+control_reportStatisticsReq(\r
+ IN Control_t *pControl )\r
+{\r
+ Inic_ControlPacket_t *pPkt;\r
+ Inic_CmdReportStatisticsReq_t *pReportStatisticsReq;\r
+ ib_api_status_t ib_status;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ control_initHdr( pControl, CMD_REPORT_STATISTICS );\r
+\r
+ pPkt = control_packet( &pControl->sendIo );\r
+ pReportStatisticsReq = &pPkt->cmd.reportStatisticsReq;\r
+ pReportStatisticsReq->lanSwitchNum = pControl->lanSwitch.lanSwitchNum;\r
+\r
+ ib_status = control_send( pControl );\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return ib_status;\r
+}\r
+\r
+\r
+BOOLEAN\r
+control_reportStatisticsRsp(\r
+ IN Control_t *pControl,\r
+ IN Inic_CmdReportStatisticsRsp_t *pStats )\r
+{\r
+ RecvIo_t *pRecvIo;\r
+ Inic_ControlPacket_t *pPkt;\r
+ Inic_CmdReportStatisticsRsp_t *pRepStatRsp;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ pRecvIo = control_getRsp( pControl );\r
+ if (!pRecvIo)\r
+ return FALSE;\r
+\r
+ pPkt = control_packet( pRecvIo );\r
+ if ( pPkt->hdr.pktCmd != CMD_REPORT_STATISTICS )\r
+ {\r
+ VNIC_TRACE(VNIC_DBG_ERROR,\r
+ ("%s: Sent control request:\n",\r
+ control_ifcfg_name( pControl )) );\r
+\r
+ __control_logControlPacket( control_lastReq( pControl ) );\r
+\r
+ VNIC_TRACE_EXIT(VNIC_DBG_ERROR,\r
+ ("%s: Received control response:\n",\r
+ control_ifcfg_name( pControl ) ) );\r
+\r
+ __control_logControlPacket( pPkt );\r
+ \r
+ goto failure;\r
+ }\r
+\r
+ pRepStatRsp = &pPkt->cmd.reportStatisticsRsp;\r
+ pStats->ifInBroadcastPkts = ntoh64(pRepStatRsp->ifInBroadcastPkts);\r
+ pStats->ifInMulticastPkts = ntoh64(pRepStatRsp->ifInMulticastPkts);\r
+ pStats->ifInOctets = ntoh64(pRepStatRsp->ifInOctets);\r
+ pStats->ifInUcastPkts = ntoh64(pRepStatRsp->ifInUcastPkts);\r
+ pStats->ifInNUcastPkts = ntoh64(pRepStatRsp->ifInNUcastPkts);\r
+ pStats->ifInUnderrun = ntoh64(pRepStatRsp->ifInUnderrun);\r
+ pStats->ifInErrors = ntoh64(pRepStatRsp->ifInErrors);\r
+ pStats->ifOutErrors = ntoh64(pRepStatRsp->ifOutErrors);\r
+ pStats->ifOutOctets = ntoh64(pRepStatRsp->ifOutOctets);\r
+ pStats->ifOutUcastPkts = ntoh64(pRepStatRsp->ifOutUcastPkts);\r
+ pStats->ifOutMulticastPkts = ntoh64(pRepStatRsp->ifOutMulticastPkts);\r
+ pStats->ifOutBroadcastPkts = ntoh64(pRepStatRsp->ifOutBroadcastPkts);\r
+ pStats->ifOutNUcastPkts = ntoh64(pRepStatRsp->ifOutNUcastPkts);\r
+ pStats->ifOutOk = ntoh64(pRepStatRsp->ifOutOk);\r
+ pStats->ifInOk = ntoh64(pRepStatRsp->ifInOk);\r
+ pStats->ifOutUcastBytes = ntoh64(pRepStatRsp->ifOutUcastBytes);\r
+ pStats->ifOutMulticastBytes = ntoh64(pRepStatRsp->ifOutMulticastBytes);\r
+ pStats->ifOutBroadcastBytes = ntoh64(pRepStatRsp->ifOutBroadcastBytes);\r
+ pStats->ifInUcastBytes = ntoh64(pRepStatRsp->ifInUcastBytes);\r
+ pStats->ifInMulticastBytes = ntoh64(pRepStatRsp->ifInMulticastBytes);\r
+ pStats->ifInBroadcastBytes = ntoh64(pRepStatRsp->ifInBroadcastBytes);\r
+ pStats->ethernetStatus = ntoh64(pRepStatRsp->ethernetStatus);\r
+\r
+ control_recv(pControl, pRecvIo);\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return TRUE;\r
+failure:\r
+ viport_failure( pControl->p_viport );\r
+ return FALSE;\r
+}\r
+\r
+\r
+ib_api_status_t\r
+control_resetReq(\r
+ IN Control_t *pControl )\r
+{\r
+ ib_api_status_t ib_status;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ control_initHdr( pControl, CMD_RESET );\r
+ ib_status = control_send( pControl );\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return ib_status;\r
+}\r
+\r
+BOOLEAN\r
+control_resetRsp(\r
+ IN Control_t *pControl )\r
+{\r
+ RecvIo_t *pRecvIo;\r
+ Inic_ControlPacket_t *pPkt;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ pRecvIo = control_getRsp( pControl );\r
+ if ( !pRecvIo ) return FALSE;\r
+\r
+ pPkt = control_packet( pRecvIo );\r
+\r
+ if ( pPkt->hdr.pktCmd != CMD_RESET )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_ERROR,\r
+ ("%s: Sent control request:\n",\r
+ control_ifcfg_name( pControl )) );\r
+\r
+ __control_logControlPacket( control_lastReq( pControl ) );\r
+ \r
+ VNIC_TRACE( VNIC_DBG_ERROR,\r
+ ("%s: Received control response:\n",\r
+ control_ifcfg_name( pControl )) );\r
+\r
+ __control_logControlPacket( pPkt );\r
+\r
+ goto failure;\r
+ }\r
+\r
+ control_recv( pControl, pRecvIo );\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return TRUE;\r
+failure:\r
+ viport_failure( pControl->p_viport );\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return FALSE;\r
+}\r
+\r
+\r
+ib_api_status_t\r
+control_heartbeatReq(\r
+ IN Control_t *pControl,\r
+ IN uint32_t hbInterval )\r
+{\r
+ Inic_ControlPacket_t *pPkt;\r
+ Inic_CmdHeartbeat_t *pHeartbeatReq;\r
+ ib_api_status_t ib_status;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ control_initHdr(pControl, CMD_HEARTBEAT);\r
+\r
+ pPkt = control_packet(&pControl->sendIo);\r
+ pHeartbeatReq = &pPkt->cmd.heartbeatReq;\r
+\r
+ /* pass timeout for the target in microseconds */\r
+ pHeartbeatReq->hbInterval = hton32( hbInterval*1000 );\r
+\r
+ ib_status = control_send( pControl );\r
+ ASSERT( ib_status == IB_SUCCESS );\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return ib_status;\r
+}\r
+\r
+BOOLEAN\r
+control_heartbeatRsp(\r
+ IN Control_t *pControl )\r
+{\r
+ RecvIo_t *pRecvIo;\r
+ Inic_ControlPacket_t *pPkt;\r
+ Inic_CmdHeartbeat_t *pHeartbeatRsp;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ pRecvIo = control_getRsp( pControl );\r
+\r
+ if (!pRecvIo)\r
+ return FALSE;\r
+\r
+ pPkt = control_packet(pRecvIo);\r
+\r
+ if ( pPkt->hdr.pktCmd != CMD_HEARTBEAT )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_ERROR,\r
+ ("%s: Sent control request:\n",\r
+ control_ifcfg_name(pControl)) );\r
+ \r
+ __control_logControlPacket( control_lastReq(pControl) );\r
+ \r
+ VNIC_TRACE( VNIC_DBG_ERROR,\r
+ ("%s: Received control response:\n",\r
+ control_ifcfg_name(pControl)) );\r
+ \r
+ __control_logControlPacket( pPkt );\r
+ goto failure;\r
+ }\r
+\r
+ pHeartbeatRsp = &pPkt->cmd.heartbeatRsp;\r
+\r
+ control_recv( pControl, pRecvIo );\r
+ VNIC_EXIT ( VNIC_DBG_CTRL );\r
+ return TRUE;\r
+\r
+failure:\r
+ viport_failure( pControl->p_viport );\r
+ VNIC_EXIT ( VNIC_DBG_CTRL );\r
+ return FALSE;\r
+}\r
+\r
+static void\r
+control_recv(\r
+ IN Control_t *pControl,\r
+ IN RecvIo_t *pRecvIo )\r
+{\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ if ( ibqp_postRecv( &pControl->qp, &pRecvIo->io ) != IB_SUCCESS )\r
+ viport_failure( pControl->p_viport );\r
+\r
+ VNIC_EXIT ( VNIC_DBG_CTRL );\r
+}\r
+\r
+\r
+static void\r
+control_recvComplete(\r
+ IN Io_t *pIo )\r
+{\r
+ RecvIo_t *pRecvIo = (RecvIo_t *)pIo;\r
+ RecvIo_t *pLastRecvIo;\r
+ BOOLEAN status = FALSE;\r
+ Control_t *pControl = &pIo->pViport->control;\r
+ viport_t *p_viport = pIo->pViport;\r
+ Inic_ControlPacket_t *pPkt = control_packet(pRecvIo);\r
+ Inic_ControlHeader_t *pCHdr = &pPkt->hdr;\r
+\r
+ switch ( pCHdr->pktType )\r
+ {\r
+ case TYPE_INFO:\r
+ pLastRecvIo = InterlockedExchangePointer( &pControl->pInfo, pRecvIo );\r
+\r
+ control_processAsync( pControl );\r
+\r
+ if ( pLastRecvIo )\r
+ {\r
+ control_recv( pControl, pLastRecvIo );\r
+ }\r
+ return;\r
+\r
+ case TYPE_RSP:\r
+ break;\r
+\r
+ default:\r
+ //TODO: Should we ever reach this? Who processes the list entries?\r
+ ASSERT( pCHdr->pktType == TYPE_INFO || pCHdr->pktType == TYPE_RSP );\r
+ ExInterlockedInsertTailList( &pRecvIo->io.listPtrs,\r
+ &pControl->failureList,\r
+ &pControl->ioLock );\r
+ return;\r
+ }\r
+\r
+ if( (pCHdr->pktSeqNum != pControl->seqNum) ||\r
+ !InterlockedExchange( (volatile LONG*)&pControl->rspExpected, FALSE ) )\r
+ {\r
+ return;\r
+ }\r
+\r
+ InterlockedExchangePointer( &pControl->pResponse, pRecvIo );\r
+\r
+ switch ( pCHdr->pktCmd )\r
+ {\r
+ case CMD_INIT_INIC:\r
+ status = control_initInicRsp( pControl,\r
+ &p_viport->featuresSupported,\r
+ p_viport->hwMacAddress,\r
+ &p_viport->numMacAddresses,\r
+ &p_viport->defaultVlan );\r
+ if( status )\r
+ {\r
+ InterlockedExchange(\r
+ (volatile LONG*)&p_viport->linkState,\r
+ (LONG)LINK_INITINICRSP );\r
+ }\r
+ InterlockedOr( &p_viport->updates, SYNC_QUERY );\r
+ break;\r
+\r
+ case CMD_CONFIG_DATA_PATH:\r
+ status = control_configDataPathRsp( &p_viport->control,\r
+ data_hostPool( &p_viport->data ),\r
+ data_eiocPool( &p_viport->data ),\r
+ data_hostPoolMax( &p_viport->data ),\r
+ data_eiocPoolMax( &p_viport->data ),\r
+ data_hostPoolMin( &p_viport->data ),\r
+ data_eiocPoolMin( &p_viport->data ));\r
+ if( status )\r
+ {\r
+ InterlockedExchange(\r
+ (volatile LONG*)&p_viport->linkState,\r
+ (LONG)LINK_CONFIGDATAPATHRSP );\r
+ }\r
+ InterlockedOr( &p_viport->updates, SYNC_QUERY );\r
+ break;\r
+\r
+ case CMD_EXCHANGE_POOLS:\r
+ status = control_exchangePoolsRsp( &p_viport->control,\r
+ data_remotePoolAddr( &p_viport->data ),\r
+ data_remotePoolRkey( &p_viport->data ) );\r
+ if( status )\r
+ {\r
+ InterlockedExchange(\r
+ (volatile LONG*)&p_viport->linkState,\r
+ (LONG)LINK_XCHGPOOLRSP );\r
+ }\r
+ InterlockedOr( &p_viport->updates, SYNC_QUERY );\r
+ break;\r
+\r
+ /* process other responses */\r
+ case CMD_CONFIG_LINK:\r
+ status = control_configLinkRsp( &p_viport->control,\r
+ &p_viport->flags,\r
+ &p_viport->mtu );\r
+ if( status )\r
+ {\r
+ InterlockedExchange(\r
+ (volatile LONG*)&p_viport->linkState,\r
+ (LONG)LINK_CONFIGLINKRSP );\r
+\r
+ if( p_viport->flags & INIC_FLAG_ENABLE_NIC )\r
+ {\r
+ InterlockedExchange( &p_viport->p_netpath->carrier, TRUE );\r
+ }\r
+ else\r
+ {\r
+ InterlockedExchange( &p_viport->p_netpath->carrier, FALSE );\r
+ }\r
+ InterlockedAnd( &p_viport->updates, ~NEED_LINK_CONFIG );\r
+ }\r
+ break;\r
+\r
+ case CMD_HEARTBEAT:\r
+ status = control_heartbeatRsp( pControl );\r
+ if( status &&\r
+ !p_viport->errored &&\r
+ !p_viport->disconnect )\r
+ {\r
+ status = FALSE;\r
+ viport_timer( p_viport, p_viport->port_config.hbInterval );\r
+ }\r
+ // Don't signal any waiting thread or start processing other updates.\r
+ return;\r
+\r
+ case CMD_CONFIG_ADDRESSES:\r
+ status = control_configAddrsRsp( pControl );\r
+ if( status == TRUE )\r
+ {\r
+ if( pControl->p_viport->addrs_query_done == 0 )\r
+ {\r
+ // need more entries to send\r
+ // TODO: Handle a send failure.\r
+ control_configAddrsReq( pControl,\r
+ pControl->p_viport->macAddresses,\r
+ pControl->p_viport->numMacAddresses,\r
+ &pControl->p_viport->addrs_query_done );\r
+ // Don't signal any waiting thread or start processing other updates.\r
+ return;\r
+ }\r
+\r
+ InterlockedAnd( &p_viport->updates, ~NEED_ADDRESS_CONFIG );\r
+ InterlockedExchange( (volatile LONG*)&p_viport->linkState,\r
+ (LONG)LINK_CONFIGADDRSRSP );\r
+ }\r
+ break;\r
+\r
+ case CMD_REPORT_STATISTICS:\r
+ status = control_reportStatisticsRsp( pControl, &p_viport->stats );\r
+ if ( status )\r
+ {\r
+ if( p_viport->stats.ethernetStatus > 0 )\r
+ {\r
+ viport_linkUp( p_viport );\r
+ }\r
+ else\r
+ {\r
+ viport_linkDown( p_viport );\r
+ }\r
+ }\r
+ InterlockedAnd( &p_viport->updates, ~NEED_STATS );\r
+ break;\r
+\r
+ case CMD_RESET:\r
+ status = control_resetRsp( pControl );\r
+ if( status )\r
+ {\r
+ status = FALSE;\r
+ InterlockedExchange(\r
+ (volatile LONG*)&p_viport->linkState,\r
+ (LONG)LINK_RESETRSP );\r
+ }\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ if( _viport_process_query( p_viport, FALSE ) == STATUS_SUCCESS )\r
+ {\r
+ /* Complete any pending set OID. */\r
+ vnic_resume_set_oids( p_viport->p_adapter );\r
+ }\r
+\r
+ if( InterlockedAnd( &p_viport->updates, ~SYNC_QUERY ) & SYNC_QUERY )\r
+ cl_event_signal( &p_viport->conn_event );\r
+}\r
+\r
+\r
+static ib_api_status_t\r
+control_send(\r
+ IN Control_t *pControl )\r
+{\r
+ ib_api_status_t ib_status;\r
+ Inic_ControlPacket_t *pPkt = control_packet(&pControl->sendIo);\r
+\r
+ VNIC_ENTER ( VNIC_DBG_CTRL );\r
+\r
+ ASSERT( !pControl->reqOutstanding );\r
+ if ( InterlockedCompareExchange( (volatile LONG*)&pControl->reqOutstanding,\r
+ TRUE, FALSE ) == TRUE )\r
+ {\r
+ /* IF WE HIT THIS WE ARE HOSED!!!\r
+ * by the time we detect this error, the send buffer has been\r
+ * overwritten, and if we retry we will send garbage data.\r
+ */\r
+ VNIC_TRACE_EXIT( VNIC_DBG_ERROR,\r
+ ("IB Send never completed\n" ) );\r
+ viport_failure( pControl->p_viport );\r
+ return IB_ERROR;\r
+ }\r
+\r
+#ifdef _DEBUG_\r
+ __control_logControlPacket( pPkt );\r
+#endif\r
+\r
+ InterlockedExchange( (volatile LONG*)&pControl->rspExpected,\r
+ (LONG)pPkt->hdr.pktCmd );\r
+\r
+ control_timer( pControl, pControl->p_conf->rspTimeout );\r
+\r
+#ifdef VNIC_STATISTIC\r
+ pControl->statistics.requestTime = cl_get_time_stamp();\r
+#endif /* VNIC_STATISTIC */\r
+\r
+ ib_status = ibqp_postSend( &pControl->qp, &pControl->sendIo.io );\r
+ if( ib_status != IB_SUCCESS )\r
+ {\r
+ InterlockedExchange((volatile LONG*)&pControl->reqOutstanding, FALSE );\r
+\r
+ VNIC_TRACE( VNIC_DBG_ERROR,\r
+ ("%s: Failed to post send\n", control_ifcfg_name(pControl)) );\r
+ viport_failure( pControl->p_viport );\r
+ }\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return ib_status;\r
+}\r
+\r
+\r
+static void\r
+control_sendComplete(\r
+ IN Io_t *pIo )\r
+{\r
+ Control_t *pControl = &pIo->pViport->control;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ InterlockedExchange((volatile LONG*)&pControl->reqOutstanding, FALSE );\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return;\r
+}\r
+\r
+static void\r
+control_timeout(\r
+ IN void *p_context )\r
+{\r
+ Control_t *pControl;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ pControl = (Control_t *)p_context;\r
+\r
+ InterlockedExchange( (LONG *)&pControl->timerstate, (LONG)TIMER_EXPIRED );\r
+\r
+ InterlockedExchange( (volatile LONG*)&pControl->rspExpected, FALSE );\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return;\r
+}\r
+\r
+static void\r
+control_timer(\r
+ IN Control_t *pControl,\r
+ IN int timeout )\r
+{\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ InterlockedExchange( (LONG *)&pControl->timerstate, (LONG)TIMER_ACTIVE );\r
+\r
+ cl_timer_start(&pControl->timer, timeout);\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return;\r
+}\r
+\r
+static void\r
+control_timerStop(\r
+ IN Control_t *pControl )\r
+{\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+\r
+ if ( ( InterlockedExchange( (LONG *)&pControl->timerstate,\r
+ (LONG)TIMER_IDLE )) == TIMER_ACTIVE )\r
+ {\r
+ cl_timer_stop( &pControl->timer );\r
+ }\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+ return;\r
+}\r
+\r
+static void\r
+control_initHdr(\r
+ IN Control_t * pControl,\r
+ IN uint8_t cmd )\r
+{\r
+ ControlConfig_t *p_conf;\r
+ Inic_ControlPacket_t *pPkt;\r
+ Inic_ControlHeader_t *pHdr;\r
+\r
+ VNIC_ENTER( VNIC_DBG_CTRL );\r
+\r
+ p_conf = pControl->p_conf;\r
+\r
+ pPkt = control_packet( &pControl->sendIo );\r
+ pHdr = &pPkt->hdr;\r
+\r
+ pHdr->pktType = TYPE_REQ;\r
+ pHdr->pktCmd = cmd;\r
+ pHdr->pktSeqNum = ++pControl->seqNum;\r
+ pControl->reqRetryCounter = 0;\r
+ pHdr->pktRetryCount = 0;\r
+\r
+ VNIC_EXIT( VNIC_DBG_CTRL );\r
+}\r
+\r
+static RecvIo_t*\r
+control_getRsp(\r
+ IN Control_t *pControl )\r
+{\r
+ RecvIo_t *pRecvIo;\r
+\r
+ VNIC_ENTER ( VNIC_DBG_CTRL );\r
+\r
+ pRecvIo = InterlockedExchangePointer( &pControl->pResponse, NULL );\r
+\r
+ if ( pRecvIo != NULL )\r
+ {\r
+ control_timerStop(pControl);\r
+ return pRecvIo;\r
+ }\r
+\r
+ if ( ( pControl->timerstate =\r
+ InterlockedCompareExchange( (LONG *)&pControl->timerstate,\r
+ (LONG)TIMER_IDLE, (LONG)TIMER_EXPIRED )) == TIMER_EXPIRED )\r
+ {\r
+ Inic_ControlPacket_t *pPkt = control_packet( &pControl->sendIo );\r
+ Inic_ControlHeader_t *pHdr = &pPkt->hdr;\r
+\r
+ VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+ ("%s: No response received from EIOC\n",\r
+ control_ifcfg_name(pControl)) );\r
+#ifdef VNIC_STATISTIC\r
+ pControl->statistics.timeoutNum++;\r
+#endif /* VNIC_STATISTIC */\r
+\r
+ pControl->reqRetryCounter++;\r
+\r
+ if ( pControl->reqRetryCounter >= pControl->p_conf->reqRetryCount )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+ ("%s: Control packet retry exceeded\n",\r
+ control_ifcfg_name(pControl)) );\r
+ viport_failure(pControl->p_viport );\r
+ }\r
+ else\r
+ {\r
+ pHdr->pktRetryCount = pControl->reqRetryCounter;\r
+ control_send( pControl );\r
+ }\r
+ }\r
+ return NULL;\r
+}\r
+\r
+static void\r
+copyRecvPoolConfig(\r
+ IN Inic_RecvPoolConfig_t *pSrc,\r
+ IN OUT Inic_RecvPoolConfig_t *pDst )\r
+{\r
+\r
+ pDst->sizeRecvPoolEntry = hton32(pSrc->sizeRecvPoolEntry);\r
+ pDst->numRecvPoolEntries = hton32(pSrc->numRecvPoolEntries);\r
+ pDst->timeoutBeforeKick = hton32(pSrc->timeoutBeforeKick);\r
+ pDst->numRecvPoolEntriesBeforeKick = hton32(pSrc->numRecvPoolEntriesBeforeKick);\r
+ pDst->numRecvPoolBytesBeforeKick = hton32(pSrc->numRecvPoolBytesBeforeKick);\r
+ pDst->freeRecvPoolEntriesPerUpdate = hton32(pSrc->freeRecvPoolEntriesPerUpdate);\r
+ return;\r
+}\r
+\r
+static BOOLEAN\r
+checkRecvPoolConfigValue(\r
+ IN void *pSrc,\r
+ IN void *pDst,\r
+ IN void *pMax,\r
+ IN void *pMin,\r
+ IN char *name )\r
+{\r
+ uint32_t value;\r
+ uint32_t *p_src = (uint32_t *)pSrc;\r
+ uint32_t *p_dst = (uint32_t *)pDst;\r
+ uint32_t *p_min = (uint32_t *)pMin;\r
+ uint32_t *p_max = (uint32_t *)pMax;\r
+\r
+ UNREFERENCED_PARAMETER( name );\r
+\r
+ value = ntoh32( *p_src );\r
+\r
+ if (value > *p_max )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+ ("Value %s too large\n", name) );\r
+ return FALSE;\r
+ }\r
+ else if (value < *p_min )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+ ("Value %s too small\n", name) );\r
+ return FALSE;\r
+ }\r
+\r
+ *p_dst = value;\r
+ return TRUE;\r
+}\r
+\r
+static BOOLEAN\r
+checkRecvPoolConfig(\r
+ IN Inic_RecvPoolConfig_t *pSrc,\r
+ IN Inic_RecvPoolConfig_t *pDst,\r
+ IN Inic_RecvPoolConfig_t *pMax,\r
+ IN Inic_RecvPoolConfig_t *pMin )\r
+{\r
+ if (!checkRecvPoolConfigValue(&pSrc->sizeRecvPoolEntry, &pDst->sizeRecvPoolEntry,\r
+ &pMax->sizeRecvPoolEntry, &pMin->sizeRecvPoolEntry, "sizeRecvPoolEntry")\r
+ || !checkRecvPoolConfigValue(&pSrc->numRecvPoolEntries, &pDst->numRecvPoolEntries,\r
+ &pMax->numRecvPoolEntries, &pMin->numRecvPoolEntries, "numRecvPoolEntries")\r
+ || !checkRecvPoolConfigValue(&pSrc->timeoutBeforeKick, &pDst->timeoutBeforeKick,\r
+ &pMax->timeoutBeforeKick, &pMin->timeoutBeforeKick, "timeoutBeforeKick")\r
+ || !checkRecvPoolConfigValue(&pSrc->numRecvPoolEntriesBeforeKick,\r
+ &pDst->numRecvPoolEntriesBeforeKick, &pMax->numRecvPoolEntriesBeforeKick,\r
+ &pMin->numRecvPoolEntriesBeforeKick, "numRecvPoolEntriesBeforeKick")\r
+ || !checkRecvPoolConfigValue(&pSrc->numRecvPoolBytesBeforeKick,\r
+ &pDst->numRecvPoolBytesBeforeKick, &pMax->numRecvPoolBytesBeforeKick,\r
+ &pMin->numRecvPoolBytesBeforeKick, "numRecvPoolBytesBeforeKick")\r
+ || !checkRecvPoolConfigValue(&pSrc->freeRecvPoolEntriesPerUpdate,\r
+ &pDst->freeRecvPoolEntriesPerUpdate, &pMax->freeRecvPoolEntriesPerUpdate,\r
+ &pMin->freeRecvPoolEntriesPerUpdate, "freeRecvPoolEntriesPerUpdate"))\r
+ return FALSE;\r
+\r
+ if ( !IsPowerOf2( pDst->numRecvPoolEntries ) )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+ ("numRecvPoolEntries (%d) must be power of 2\n",\r
+ pDst->numRecvPoolEntries) );\r
+ return FALSE;\r
+ }\r
+ if ( !IsPowerOf2( pDst->freeRecvPoolEntriesPerUpdate ) )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+ ("freeRecvPoolEntriesPerUpdate (%d) must be power of 2\n",\r
+ pDst->freeRecvPoolEntriesPerUpdate) );\r
+ return FALSE;\r
+ }\r
+ if ( pDst->freeRecvPoolEntriesPerUpdate >= pDst->numRecvPoolEntries )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+ ("freeRecvPoolEntriesPerUpdate (%d) must be less than numRecvPoolEntries (%d)\n",\r
+ pDst->freeRecvPoolEntriesPerUpdate, pDst->numRecvPoolEntries) );\r
+ return FALSE;\r
+ }\r
+ if ( pDst->numRecvPoolEntriesBeforeKick >= pDst->numRecvPoolEntries )\r
+ {\r
+ VNIC_TRACE( VNIC_DBG_CTRL| VNIC_DBG_ERROR,\r
+ ("numRecvPoolEntriesBeforeKick (%d) must be less than numRecvPoolEntries (%d)\n",\r
+ pDst->numRecvPoolEntriesBeforeKick, pDst->numRecvPoolEntries) );\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+static void\r
+__control_logControlPacket(\r
+ IN Inic_ControlPacket_t *pPkt )\r
+{\r
+ char *type;\r
+ int i;\r
+\r
+ switch( pPkt->hdr.pktType )\r
+ {\r
+ case TYPE_INFO:\r
+ type = "TYPE_INFO";\r
+ break;\r
+ case TYPE_REQ:\r
+ type = "TYPE_REQ";\r
+ break;\r
+ case TYPE_RSP:\r
+ type = "TYPE_RSP";\r
+ break;\r
+ case TYPE_ERR:\r
+ type = "TYPE_ERR";\r
+ break;\r
+ default:\r
+ type = "UNKNOWN";\r
+ }\r
+ switch( pPkt->hdr.pktCmd )\r
+ {\r
+ case CMD_INIT_INIC:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ("ControlPacket: pktType = %s, pktCmd = CMD_INIT_INIC\n", type ) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL| VNIC_DBG_INFO,\r
+ (" pktSeqNum = %u, pktRetryCount = %u\n",\r
+ pPkt->hdr.pktSeqNum,\r
+ pPkt->hdr.pktRetryCount) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" inicMajorVersion = %u, inicMinorVersion = %u\n",\r
+ ntoh16(pPkt->cmd.initInicReq.inicMajorVersion),\r
+ ntoh16(pPkt->cmd.initInicReq.inicMinorVersion)) );\r
+ if (pPkt->hdr.pktType == TYPE_REQ)\r
+ {\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" inicInstance = %u, numDataPaths = %u\n",\r
+ pPkt->cmd.initInicReq.inicInstance,\r
+ pPkt->cmd.initInicReq.numDataPaths) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT| VNIC_DBG_INFO,\r
+ (" numAddressEntries = %u\n",\r
+ ntoh16(pPkt->cmd.initInicReq.numAddressEntries)) );\r
+ }\r
+ else\r
+ {\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" numLanSwitches = %u, numDataPaths = %u\n",\r
+ pPkt->cmd.initInicRsp.numLanSwitches,\r
+ pPkt->cmd.initInicRsp.numDataPaths) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" numAddressEntries = %u, featuresSupported = %08x\n",\r
+ ntoh16(pPkt->cmd.initInicRsp.numAddressEntries),\r
+ ntoh32(pPkt->cmd.initInicRsp.featuresSupported)) );\r
+ if (pPkt->cmd.initInicRsp.numLanSwitches != 0)\r
+ {\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ("lanSwitch[0] lanSwitchNum = %u, numEnetPorts = %08x\n",\r
+ pPkt->cmd.initInicRsp.lanSwitch[0].lanSwitchNum,\r
+ pPkt->cmd.initInicRsp.lanSwitch[0].numEnetPorts) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" defaultVlan = %u, hwMacAddress = %02x:%02x:%02x:%02x:%02x:%02x\n",\r
+ ntoh16(pPkt->cmd.initInicRsp.lanSwitch[0].defaultVlan),\r
+ pPkt->cmd.initInicRsp.lanSwitch[0].hwMacAddress[0],\r
+ pPkt->cmd.initInicRsp.lanSwitch[0].hwMacAddress[1],\r
+ pPkt->cmd.initInicRsp.lanSwitch[0].hwMacAddress[2],\r
+ pPkt->cmd.initInicRsp.lanSwitch[0].hwMacAddress[3],\r
+ pPkt->cmd.initInicRsp.lanSwitch[0].hwMacAddress[4],\r
+ pPkt->cmd.initInicRsp.lanSwitch[0].hwMacAddress[5]) );\r
+ }\r
+ }\r
+ break;\r
+ case CMD_CONFIG_DATA_PATH:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ( "ControlPacket: pktType = %s, pktCmd = CMD_CONFIG_DATA_PATH\n", type) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" pktSeqNum = %u, pktRetryCount = %u\n",\r
+ pPkt->hdr.pktSeqNum,\r
+ pPkt->hdr.pktRetryCount) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" pathIdentifier = %"PRIx64", dataPath = %u\n",\r
+ pPkt->cmd.configDataPathReq.pathIdentifier,\r
+ pPkt->cmd.configDataPathReq.dataPath) );\r
+ \r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ("Host Config sizeRecvPoolEntry = %u, numRecvPoolEntries = %u\n",\r
+ ntoh32(pPkt->cmd.configDataPathReq.hostRecvPoolConfig.sizeRecvPoolEntry),\r
+ ntoh32(pPkt->cmd.configDataPathReq.hostRecvPoolConfig.numRecvPoolEntries)) );\r
+ \r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" timeoutBeforeKick = %u, numRecvPoolEntriesBeforeKick = %u\n",\r
+ ntoh32(pPkt->cmd.configDataPathReq.hostRecvPoolConfig.timeoutBeforeKick),\r
+ ntoh32(pPkt->cmd.configDataPathReq.hostRecvPoolConfig.numRecvPoolEntriesBeforeKick)) );\r
+ \r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" numRecvPoolBytesBeforeKick = %u, freeRecvPoolEntriesPerUpdate = %u\n",\r
+ ntoh32(pPkt->cmd.configDataPathReq.hostRecvPoolConfig.numRecvPoolBytesBeforeKick),\r
+ ntoh32(pPkt->cmd.configDataPathReq.hostRecvPoolConfig.freeRecvPoolEntriesPerUpdate)) );\r
+\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ("Eioc Config sizeRecvPoolEntry = %u, numRecvPoolEntries = %u\n",\r
+ ntoh32(pPkt->cmd.configDataPathReq.eiocRecvPoolConfig.sizeRecvPoolEntry),\r
+ ntoh32(pPkt->cmd.configDataPathReq.eiocRecvPoolConfig.numRecvPoolEntries)) );\r
+\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" timeoutBeforeKick = %u, numRecvPoolEntriesBeforeKick = %u\n",\r
+ ntoh32(pPkt->cmd.configDataPathReq.eiocRecvPoolConfig.timeoutBeforeKick),\r
+ ntoh32(pPkt->cmd.configDataPathReq.eiocRecvPoolConfig.numRecvPoolEntriesBeforeKick)) );\r
+\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" numRecvPoolBytesBeforeKick = %u, freeRecvPoolEntriesPerUpdate = %u\n",\r
+ ntoh32(pPkt->cmd.configDataPathReq.eiocRecvPoolConfig.numRecvPoolBytesBeforeKick),\r
+ ntoh32(pPkt->cmd.configDataPathReq.eiocRecvPoolConfig.freeRecvPoolEntriesPerUpdate)) );\r
+ break;\r
+ case CMD_EXCHANGE_POOLS:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ("ControlPacket: pktType = %s, pktCmd = CMD_EXCHANGE_POOLS\n", type ) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" pktSeqNum = %u, pktRetryCount = %u\n",\r
+ pPkt->hdr.pktSeqNum,\r
+ pPkt->hdr.pktRetryCount) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" datapath = %u\n",\r
+ pPkt->cmd.exchangePoolsReq.dataPath) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" poolRKey = %08x poolAddr = %"PRIx64"\n",\r
+ ntoh32(pPkt->cmd.exchangePoolsReq.poolRKey),\r
+ ntoh64(pPkt->cmd.exchangePoolsReq.poolAddr)) );\r
+ break;\r
+ case CMD_CONFIG_ADDRESSES:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ( "ControlPacket: pktType = %s, pktCmd = CMD_CONFIG_ADDRESSES\n", type ) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" pktSeqNum = %u, pktRetryCount = %u\n",\r
+ pPkt->hdr.pktSeqNum,\r
+ pPkt->hdr.pktRetryCount) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" numAddressOps = %x, lanSwitchNum = %d\n",\r
+ pPkt->cmd.configAddressesReq.numAddressOps,\r
+ pPkt->cmd.configAddressesReq.lanSwitchNum) );\r
+ for (i = 0; ( i < pPkt->cmd.configAddressesReq.numAddressOps) && (i < 16); i++)\r
+ {\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" listAddressOps[%u].index = %u\n",\r
+ i, ntoh16(pPkt->cmd.configAddressesReq.listAddressOps[i].index)) );\r
+ \r
+ switch(pPkt->cmd.configAddressesReq.listAddressOps[i].operation)\r
+ {\r
+ case INIC_OP_GET_ENTRY:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" listAddressOps[%u].operation = INIC_OP_GET_ENTRY\n", i) );\r
+ break;\r
+ case INIC_OP_SET_ENTRY:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" listAddressOps[%u].operation = INIC_OP_SET_ENTRY\n", i) );\r
+ break;\r
+ default:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" listAddressOps[%u].operation = UNKNOWN(%d)\n",\r
+ i, pPkt->cmd.configAddressesReq.listAddressOps[i].operation) );\r
+ break;\r
+ }\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" listAddressOps[%u].valid = %u\n",\r
+ i, pPkt->cmd.configAddressesReq.listAddressOps[i].valid) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" listAddressOps[%u].address = %02x:%02x:%02x:%02x:%02x:%02x\n", i,\r
+ pPkt->cmd.configAddressesReq.listAddressOps[i].address[0],\r
+ pPkt->cmd.configAddressesReq.listAddressOps[i].address[1],\r
+ pPkt->cmd.configAddressesReq.listAddressOps[i].address[2],\r
+ pPkt->cmd.configAddressesReq.listAddressOps[i].address[3],\r
+ pPkt->cmd.configAddressesReq.listAddressOps[i].address[4],\r
+ pPkt->cmd.configAddressesReq.listAddressOps[i].address[5]) );\r
+\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" listAddressOps[%u].vlan = %u\n",\r
+ i, ntoh16(pPkt->cmd.configAddressesReq.listAddressOps[i].vlan)) );\r
+ }\r
+ break;\r
+ case CMD_CONFIG_LINK:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ("ControlPacket: pktType = %s, pktCmd = CMD_CONFIG_LINK\n", type) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" pktSeqNum = %u, pktRetryCount = %u\n",\r
+ pPkt->hdr.pktSeqNum,\r
+ pPkt->hdr.pktRetryCount) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" cmdFlags = %x\n",\r
+ pPkt->cmd.configLinkReq.cmdFlags) );\r
+\r
+ if ( pPkt->cmd.configLinkReq.cmdFlags & INIC_FLAG_ENABLE_NIC )\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" INIC_FLAG_ENABLE_NIC\n") );\r
+\r
+ if ( pPkt->cmd.configLinkReq.cmdFlags & INIC_FLAG_DISABLE_NIC )\r
+ \r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" INIC_FLAG_DISABLE_NIC\n") );\r
+\r
+ if ( pPkt->cmd.configLinkReq.cmdFlags & INIC_FLAG_ENABLE_MCAST_ALL )\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" INIC_FLAG_ENABLE_MCAST_ALL\n") );\r
+\r
+ if ( pPkt->cmd.configLinkReq.cmdFlags & INIC_FLAG_DISABLE_MCAST_ALL )\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" INIC_FLAG_DISABLE_MCAST_ALL\n") );\r
+\r
+ if ( pPkt->cmd.configLinkReq.cmdFlags & INIC_FLAG_ENABLE_PROMISC )\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" INIC_FLAG_ENABLE_PROMISC\n") );\r
+ \r
+ if ( pPkt->cmd.configLinkReq.cmdFlags & INIC_FLAG_DISABLE_PROMISC )\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" INIC_FLAG_DISABLE_PROMISC\n") );\r
+ if ( pPkt->cmd.configLinkReq.cmdFlags & INIC_FLAG_SET_MTU )\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" INIC_FLAG_SET_MTU\n") );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" lanSwitchNum = %x, mtuSize = %d\n",\r
+ pPkt->cmd.configLinkReq.lanSwitchNum,\r
+ ntoh16(pPkt->cmd.configLinkReq.mtuSize)) );\r
+ if ( pPkt->hdr.pktType == TYPE_RSP )\r
+ {\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" defaultVlan = %u, hwMacAddress = %02x:%02x:%02x:%02x:%02x:%02x\n",\r
+ ntoh16(pPkt->cmd.configLinkReq.defaultVlan),\r
+ pPkt->cmd.configLinkReq.hwMacAddress[0],\r
+ pPkt->cmd.configLinkReq.hwMacAddress[1],\r
+ pPkt->cmd.configLinkReq.hwMacAddress[2],\r
+ pPkt->cmd.configLinkReq.hwMacAddress[3],\r
+ pPkt->cmd.configLinkReq.hwMacAddress[4],\r
+ pPkt->cmd.configLinkReq.hwMacAddress[5]) );\r
+ }\r
+ break;\r
+ case CMD_REPORT_STATISTICS:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ("ControlPacket: pktType = %s, pktCmd = CMD_REPORT_STATISTICS\n", type ) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" pktSeqNum = %u, pktRetryCount = %u\n",\r
+ pPkt->hdr.pktSeqNum,\r
+ pPkt->hdr.pktRetryCount) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" lanSwitchNum = %u\n",\r
+ pPkt->cmd.reportStatisticsReq.lanSwitchNum) );\r
+\r
+ if (pPkt->hdr.pktType == TYPE_REQ)\r
+ break;\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifInBroadcastPkts = %"PRIu64,\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifInBroadcastPkts)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifInMulticastPkts = %"PRIu64"\n",\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifInMulticastPkts)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifInOctets = %"PRIu64,\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifInOctets)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifInUcastPkts = %"PRIu64"\n",\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifInUcastPkts)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifInNUcastPkts = %"PRIu64,\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifInNUcastPkts)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifInUnderrun = %"PRIu64"\n",\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifInUnderrun)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifInErrors = %"PRIu64,\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifInErrors)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifOutErrors = %"PRIu64"\n",\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifOutErrors)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifOutOctets = %"PRIu64,\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifOutOctets)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifOutUcastPkts = %"PRIu64"\n",\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifOutUcastPkts)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifOutMulticastPkts = %"PRIu64,\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifOutMulticastPkts)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifOutBroadcastPkts = %"PRIu64"\n",\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifOutBroadcastPkts)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifOutNUcastPkts = %"PRIu64,\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifOutNUcastPkts)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifOutOk = %"PRIu64"\n",\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifOutOk)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifInOk = %"PRIu64,\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifInOk)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifOutUcastBytes = %"PRIu64"\n",\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifOutUcastBytes)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifOutMulticastBytes = %"PRIu64,\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifOutMulticastBytes)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifOutBroadcastBytes = %"PRIu64"\n",\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifOutBroadcastBytes)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifInUcastBytes = %"PRIu64,\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifInUcastBytes)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifInMulticastBytes = %"PRIu64"\n",\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifInMulticastBytes)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ifInBroadcastBytes = %"PRIu64,\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ifInBroadcastBytes)) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" ethernetStatus = %"PRIu64"\n",\r
+ ntoh64(pPkt->cmd.reportStatisticsRsp.ethernetStatus)) );\r
+ break;\r
+ case CMD_CLEAR_STATISTICS:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ("ControlPacket: pktType = %s, pktCmd = CMD_CLEAR_STATISTICS\n", type ) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" pktSeqNum = %u, pktRetryCount = %u\n",\r
+ pPkt->hdr.pktSeqNum,\r
+ pPkt->hdr.pktRetryCount) );\r
+ break;\r
+ case CMD_REPORT_STATUS:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ("ControlPacket: pktType = %s, pktCmd = CMD_REPORT_STATUS\n",\r
+ type) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" pktSeqNum = %u, pktRetryCount = %u\n",\r
+ pPkt->hdr.pktSeqNum,\r
+ pPkt->hdr.pktRetryCount) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" lanSwitchNum = %u, isFatal = %u\n",\r
+ pPkt->cmd.reportStatus.lanSwitchNum,\r
+ pPkt->cmd.reportStatus.isFatal) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" statusNumber = %u, statusInfo = %u\n",\r
+ ntoh32(pPkt->cmd.reportStatus.statusNumber),\r
+ ntoh32(pPkt->cmd.reportStatus.statusInfo)) );\r
+ pPkt->cmd.reportStatus.fileName[31] = '\0';\r
+ pPkt->cmd.reportStatus.routine[31] = '\0';\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" filename = %s, routine = %s\n",\r
+ pPkt->cmd.reportStatus.fileName,\r
+ pPkt->cmd.reportStatus.routine) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" lineNum = %u, errorParameter = %u\n",\r
+ ntoh32(pPkt->cmd.reportStatus.lineNum),\r
+ ntoh32(pPkt->cmd.reportStatus.errorParameter)) );\r
+ pPkt->cmd.reportStatus.descText[127] = '\0';\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" descText = %s\n",\r
+ pPkt->cmd.reportStatus.descText) );\r
+ break;\r
+ case CMD_RESET:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ("ControlPacket: pktType = %s, pktCmd = CMD_RESET\n", type ) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" pktSeqNum = %u, pktRetryCount = %u\n",\r
+ pPkt->hdr.pktSeqNum,\r
+ pPkt->hdr.pktRetryCount) );\r
+ break;\r
+ case CMD_HEARTBEAT:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ("ControlPacket: pktType = %s, pktCmd = CMD_HEARTBEAT\n", type ) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" pktSeqNum = %u, pktRetryCount = %u\n",\r
+ pPkt->hdr.pktSeqNum,\r
+ pPkt->hdr.pktRetryCount) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" hbInterval = %d\n",\r
+ ntoh32(pPkt->cmd.heartbeatReq.hbInterval)) );\r
+ break;\r
+ default:\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ ("ControlPacket: pktType = %s, pktCmd = UNKNOWN (%u)\n",\r
+ type,pPkt->hdr.pktCmd) );\r
+ VNIC_PRINT( VNIC_DBG_CTRL_PKT | VNIC_DBG_INFO,\r
+ (" pktSeqNum = %u, pktRetryCount = %u\n",\r
+ pPkt->hdr.pktSeqNum,\r
+ pPkt->hdr.pktRetryCount) );\r
+ break;\r
+ }\r
+ return;\r
+}\r