Sie sind auf Seite 1von 23

ZeroCopyEthernetMUXUserGuide

TableofContents
GuideChangeList......................................................................................................................................3 Introduction................................................................................................................................................4 ZCMUXRequirements.............................................................................................................................4 AddingTheEthernetZCMUXtotheBSP...............................................................................................4 ZCMUXConfiguration............................................................................................................................5 CreatingMUXes....................................................................................................................................5 VirtualPortConfiguration....................................................................................................................6 SampleMUXConfiguration.................................................................................................................6 1:1MUXconfiguration.........................................................................................................................8 EthernetMUXFilters.................................................................................................................................9 TransmitFilters......................................................................................................................................9 ReceiveFilters.....................................................................................................................................10 CompleteMUXConfigurationExample.............................................................................................11 AdvancedFeaturesoftheZCMUX.........................................................................................................11 GlobalMUXConfiguration.................................................................................................................11 ghnetv1TCPIPstackandtheZCMUX...................................................................................................12 ghnetv2TCPIPstackandtheZCMUX...................................................................................................12 LinktimememoryforMUX(optional)...................................................................................................13 ZCMUXvportAPI.................................................................................................................................14 Datatypes............................................................................................................................................14 Methods...............................................................................................................................................14 StackPortingGuide..................................................................................................................................17 HighLevelDifferencesbetweenZCMUXandOMUX....................................................................17 VportInitialization..............................................................................................................................17 TransmittingandReceivingFrames....................................................................................................19 BufferandFrameIndexes...............................................................................................................19 TransmittingFrames.......................................................................................................................20 ReceivingFrames(Preparation)......................................................................................................21 EventHandling...............................................................................................................................21

Copyright(c)2010byGreenHillsSoftware,Inc.Allrightsreserved.Nopartofthispublicationmaybereproduced,storedinaretrievalsystem,or transmitted,inanyformorbyanymeans,electronic,mechanical,photocopying,recording,orotherwise,withoutpriorwrittenpermissionfromGreenHills Software,Inc.

02052010.MUXdocversion1.10

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

GuideChangeList
(Thispageisintentionallyleftblank)

02052010.MUXdocversion1.10

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

Introduction
TheZeroCopyEthernetMUX(ZCMUX)isasoftwaresimulatedOSIlayer2Ethernetswitch.It attachestoaphysicalEthernetdeviceandprovidesmultiplevirtualEthernetdevices/ports(vports). Eachvporthasit'sownMACaddress,andisformostpurposesindistinguishablefromahardware Ethernetdevice.TheZCMUXperformsthesamejobastheOriginalEthernetMUX(OMUX), howeverusesadifferentAPItotransmitandreceiveEthernetframestoachievebetterperformance. Anystack1usingtheEthernetIODeviceAPIcanbeportedtousetheZCMUXvportAPI.

ZCMUXRequirements

TheGHSEthernetdevicedrivermustsupportpromiscuousmode.

AddingTheEthernetZCMUXtotheBSP
TheZCMUXrequirestheBSPreserveaportionofphysicalmemoryforMUXuse.Theamountof memoryrequireddependsonthenumberofvports.Theminimumamountofmemoryrequiredis: (NUM_TX_BUFS*<numberofvports>)+NUM_UPLINK_RX_BUFS Itisrecommendedthatatleast32Pagesareallocatedpervportand32Pagesallocatedforthephysical port.Therearemanywaysofreservingphysicalmemory(seeReservingMemoryRegionsinthe INTEGRITYBSPUser'sGuide.)Thefollowingisanexampleofhowtoreservespaceunderthename __ghs_MUX1_buffersintheinitialmemorymapusingMemoryReservations:
MemoryReservation __ghsentry_reservedmem_bspMUXbuffers = /* 512K for MUX buffers, page-aligned start, end */ { MEMORY_RWE, 0, 0, 1 * 512 * 1024 - 1, RAM_MemoryType, false, 0xfffff000, 0xfffff000, "__ghs_MUX1_buffers" };

Note:EachMUXrequiresitsownreservationofmemory(asopposedtotheOMUXwhichuses buffersfrom__ghsentry_reservedmem_bsptcpipbuffers.) TheMUXusestheconfigurationIODevice.EnsuretheconfiguraitonIODeviceisinyourBSPelseadd theconfigurationIODevicebyaddingconfiguration_iodevice.ctolibbsp.gpj. TheZCMUXservercanrunineitherKernelSpaceorVirtualAddressSpace.ToaddaZCMUX servertoKernelSpace,compilethelibmuxlibrarybyaddingthefollowingtothekernelprojectfile:


-lmux

ToruntheZCMUXinavirtualAddressSpacelinkthevirtualAddressSpacewiththelibvmuxlibrary, declareavariable__ghs_tcpip_is_virtualoftypecharandsetitto1,andinvokeSM_MUXEntry().I.e. createaProgramwiththefollowingintheprojectfile:


1 Forsimplicity,stackreferstoanysoftwarethatinterfacesdirectlywithanEthernetport(physicalorvirtual).

02052010.MUXdocversion1.10

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

-lvmux

ThefollowingshouldbesufficienttostartaVirtualZCMUXinthatAddressSpace:
char __ghs_tcpip_is_virtual = 1; int main() { SM_MUXEntry(); }

ZCMUXConfiguration
SpecialsymbolslinkedintotheZCMUXAddresSpacecontrolthecreationandconfigurationof EthernetMUXes.Thefollowingsectiondescribeshowtodeclaresuchsymbolsandconfigurethe MUXes.

CreatingMUXes
MUXconfigurationisdonewithglobalvariableslinkedintotheAddressSpacewheretheZCMUXis located(KernelSpaceforakernelresidentMUXortheVirtualAddressSpaceofthevirtualZCMUX application.)ToaddanEthernetMUXtothesystem,createaglobalvariablenamed _ghsentry_smmux_XXXwhereXXXisanarbitrarynamethatisuniquetotheMUXbeingcreated. Thevariablemustbeoftypestruct muxconfig,andmustcontaintheconfigurationinformationfor theMUX.Thestructurecanbefoundinmux/mux_config.handisdefinedasfollows:
struct muxconfig{ int id; char *uplink_name; EtherDevEntry *dentry; int nports; char *buffer_name; };

// // // // //

Mux's ID stack name in BSPEthernetIODeviceNames ghs_ethernet driver Number of Virtual ports name of physical memory allocated for this MUX

TheidfieldshouldcontainauniqueidthatstackscanusetoidentifyaMUX.Itisalsousedto identifyaMUXwhenaddingfilterstoit. Theuplink_namefieldcontainstheuplink'sphysicalportname.ThisistheEtherDevnameassigned inBSPEthernetIODeviceNames1asisrelevantforlegacyEthernetIODevices.ThisfieldcanbeNULL ifonlyavirtualMUXbetweenvirtualportsandnouplinkdesired. Thedentryfieldisapointertotheghs_ethernetdriverforthephysicalport.Ifthephysicalportisa legacyEthernetIODevicethendentryshouldbe&mux_ethernet_driver_iod. ThenportsfieldcontainsthenumberofvirtualportsonthisMUX.Thisnumbermustbeatleast1,


1 SeeRenaminganEthernetIODeviceintheINTEGRITYBSPUser'sGuideforinformationonsettingup BSPEthernetIODeviceNames.

02052010.MUXdocversion1.10

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

andcanbearbitrarilylarge,assumingthetotalnumberofvportsonthesystemdoesnotexceed MAX_ENET_MUX_VDEVS. Thebuffer_nameisthenameofthebufferreservedbytheBSP.IntheMemoryReservationexample fromabove,buffer_namewouldcontain__ghs_MUX1_buffers.

VirtualPortConfiguration
TheNetDevs1arraymustbeproperlysetuptoassignMACaddressesandIPaddressestovports.Vport configurationsshouldbeginafterallphysicalportconfigurationsintheNetDevsarrayandshouldbe orderedaccordingtotheMUX'sidandthenvportnumber.Bydefault,theZCMUXassumesthat therearetwophysicalportsandwillskipthefirsttwophysicalportswhenassigningNetDeventries. Thiscanbeoptionallyoverriddenbydeclaringthenum_bsp_physical_interfacesvariableinthe AddressSpaceoftheZCMUX.
/* This BSP has 4 physical interfaces. * Tell the MUX to skip 4 NetDev entries instead of the default 2 */ const int num_bsp_physical_interfaces = 4;

SampleMUXConfiguration
ThefollowingisasampleMUXconfigurationincludingsampleBSPEthernetIODeviceNamesand NetDevsdefinitions.Therearetwophysicalethernetdevices,bothassignedtoaMUX.EachMUX has2virtualports.

/******** MUXes configuration *********/ struct muxconfig __ghsentry_smmux_mux0 = { 0, "MUXEtherDev0", &mux_ethernet_driver_iod, 2, "__ghs_MUX0_buffers" }; struct muxconfig __ghsentry_smmux_mux1 = { 1, "MUXEtherDev1", &mux_ethernet_driver_iod, 2, "__ghs_MUX1_buffers" }; /******** MUXes configuration END *********/

/******** BSPEthernetIODeviceNames configuration *********/ char *BSPEthernetIODeviceNames[] = { "MUXEtherDev0", // PHYSICAL Device 0 "MUXEtherDev1", // PHYSICAL Device 1 // VIRTUAL port MUX_0_VPORT_0 , MUX_0_VPORT_1 ,

1FormoreinformationonsettinguptheNetDevsarrayrefertotheINTEGRITYNetworkingGuide 02052010.MUXdocversion1.10
Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

MUX_1_VPORT_0 , MUX_1_VPORT_1 , }; /******** BSPEthernetIODeviceNames configuration END *********/

/******** NetDevs configuration (usually found in global_tables.c) *********/ #define IPAddress(a,b,c,d) ((a)<<24 | (b)<<16 | (c)<<8 | (d)) struct NetInfo NetDevs[6] = { /* PHYSICAL Devices start first in NetDevs */ { // PHYSICAL Device 0 (MUXEtherDev0) 0x00,0xe0,0x0c,0x0,0x00,0x01, /* EthernetAddress */ IPAddress(192, 168, 102, 1), /* IPAddress */ 0, /* Gateway */ 0, /* NetMask */ 0, /* should be zero */ 0, /* NameServer */ "hostname1.ghs.com" /* hostname */ }, { // PHYSICAL Device 2 (MUXEtherDev1) 0x00,0xe0,0x0c,0x0,0x00,0x2, /* EthernetAddress */ IPAddress(10, 0, 0, 1), /* IPAddress */ 0, /* Gateway */ 0, /* NetMask */ 0, /* should be zero */ 0, /* NameServer */ "hostname2.ghs.com" /* hostname */ }, /* VIRTUAL ports follow after... */ { // MUX0's first MUX Vport (MUX_0_VPORT_0) 0x00,0xe0,0xbb,0xbb,0xbb,0x01,/* EthernetAddress */ IPAddress(192, 168, 102, 2), /* IPAddress */ 0, /* Gateway */ 0, /* NetMask */ 0, /* should be zero */ 0, /* NameServer */ "hostname3.ghs.com" /* hostname */ }, { // MUX0's second Vport (MUX_0_VPORT_1) 0x00,0xe0,0xbb,0xbb,0xbb,0x02,/* EthernetAddress */ IPAddress(192, 168, 102, 3), /* IPAddress */ 0, /* Gateway */ 0, /* NetMask */ 0, /* should be zero */ 0, /* NameServer */ "hostname4.ghs.com" /* hostname */ }, { // MUX1's first Vport (MUX_1_VPORT_0) 0x00,0xe0,0xbb,0xbb,0xbb,0x03,/* EthernetAddress */ IPAddress(10, 0, 0, 2), /* IPAddress */ 0, /* Gateway */ 0, /* NetMask */ 0, /* should be zero */ 0, /* NameServer */ "hostname5.ghs.com" /* hostname */

02052010.MUXdocversion1.10

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

}, { // MUX1's second MUX Vport (MUX_1_VPORT_1) 0x00,0xe0,0xbb,0xbb,0xbb,0x04, /* EthernetAddress */ IPAddress(10, 0, 0, 3), /* IPAddress */ 0, /* Gateway */ 0, /* NetMask */ 0, /* should be zero */ 0, /* NameServer */ "hostname6.ghs.com" /* hostname */ }, } /******** NetDevs configuration END *********/

1:1MUXconfiguration
A1:1MUX,isaMUXconfiguredwithonlyonevirtualport.A1:1MUXcanbeusediftheuser wishestousetheZCMUXAPIinsteadoftheunderlyingAPIsuchastheEnetIODeviceAPI.When configuringa1:1MUX,theNetDevsentryforthephysicaluplinkandthevirtualportSHOULDbethe same.WhileisNOTarequirement,certainoptimizationscanbeperformediftheentriessharethe samesettings.Thefollowingisasampleconfigurationfora1:1MUX:

/******** MUXes configuration *********/ struct muxconfig __ghsentry_smmux_mux1 = { 0, "MUXEtherDev0", &mux_ethernet_driver_iod, 1, "__ghs_MUX1_buffers" }; /******** MUXes configuration END *********/

/******** BSPEthernetIODeviceNames configuration *********/ char *BSPEthernetIODeviceNames[] = { "MUXEtherDev0", // PHYSICAL Device 0 MUX_0_VPORT_0 , // VIRTUAL port } /******** BSPEthernetIODeviceNames configuration END *********/

/******** NetDevs configuration *********/ struct NetInfo NetDevs[2] = { /* PHYSICAL Devices (Uplink) */ { // PHYSICAL Device 0 (MUXEtherDev0) 0x00,0xe0,0x0c,0x0,0x00,0x01, /* IPAddress(192, 168, 102, 1), /* 0, /* 0, /* 0, /* 0, /* "hostname1.ghs.com" /* }, { // Virtual Port (copy of above)

EthernetAddress */ IPAddress */ Gateway */ NetMask */ should be zero */ NameServer */ hostname */

02052010.MUXdocversion1.10

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

0x00,0xe0,0x0c,0x0,0x00,0x01, IPAddress(192, 168, 102, 1), 0, 0, 0, 0, "hostname1.ghs.com" }, }

/* /* /* /* /* /* /*

EthernetAddress */ IPAddress */ Gateway */ NetMask */ should be zero */ NameServer */ hostname */

/* This BSP has 1 physical interfaces. * Tell the MUX to skip 1 NetDev entries instead of the default 2 */ const int num_bsp_physical_interfaces = 1; /******** NetDevs configuration END *********/

EthernetMUXFilters
EthernetMUXfiltersallowthesystemdesignertomonitor,filterandmodifyallEthernettraffic passingthroughtheMUX.Thisisparticularlyusefulforimposingextrasecurityonanuntrustedstack. AfilterisafunctionthatiscalledbytheMUXeverytimeaparticularvirtualportattemptstotransmit orreceiveanEthernetframe.Thefiltermaypassivelymonitortheframe,oritmaymodifytheframe headerordata.IfthefilterdoesnotreturnSuccess,thentheMUXdiscardstheframewithout deliveringit.Tocreateafilter,defineaglobalvariableoftypestruct muxfilterasdescribedbelow. ThesevariablesmustbelinkedintotheMUX'saddressspace.
struct muxfilter{ int mux_id; // int port; // Error (*filter)(char *, int *); // Boolean modifies; // };

Which Mux Which Virtual Port filter Does this filter modify data?

Themux_ididentifiestheMUXcontainingthevirtualporttowhichthefilterattaches. Theportidentifiesthevirtualportnumber,whichisanintegerfrom0to(nports1). Thefilterisapointertothefilterfunctionitself.Theargumentspassedtothefilterareapointerto theEthernetframedataandapointertothelengthoftheframe,inbytes.Thefiltermaymodifythe framedataandlengththroughthesepointers. Themodifiesfieldshouldbesettotrue(nonzero)ifthefilterpotentiallymodifiestheEthernetframe data.

TransmitFilters
TransmitfiltersaffectEthernetframestransmittedfromanapplicationorstackattachedtoaparticular vport.Thefilteriscalledaftertheframeleavesthestackorapplication,butbeforeitenterstheMUX 02052010.MUXdocversion1.10
Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

switchinglogic(sotransmitfilterscanaffectthedestinationoftheframe.)Ifthefilterdoesnotreturn Success,theoutgoingframeissilentlydiscarded,andisneversenttoothervportsorthenetwork. ToaddatransmitfiltertoavirtualportonaMUX,addaglobalvariablelinkedintotheMUX'saddress spacenamed__ghsentry_smmuxtxfilter_XXXwhereXXXisanarbitrarynamethatisuniqueto thefilterbeingcreated.Thesymbolmustbeoftypestruct muxfilter,andmustcontain configurationinformationforthefilter. Forexample,thefollowingcodecreatesafilteronvport1oftheMUXwithid1thatrewritesthe destinationMACaddressonalloutgoingframesfromtheport.Thisrestrictsthestackattachedtothat virtualportfrombeingabletocommunicatewithnetworkpeersusingthatanyotherdestinationMAC address.
static Error myfilter(char *buf, int *len) { static char destaddr[] = { 0x00,0x01,0x03,0xD6,0x18,0xD7 }; memcpy(buf, destaddr, 6); return Success; } struct muxfilter __ghsentry_smmuxtxfilter_a = { 1, 1, myfilter, true };

ReceiveFilters
ReceivefiltersaffectEthernetframessenttoanapplicationorstackattachedtoaparticularvirtualport. Thefilteriscalledjustbeforetheframeispassedtothestackorapplication.Ifthefilterdoesnot returnSuccess,theincomingframeissilentlydiscarded. ToaddareceivefiltertoavirtualportonaMUX,addaglobalvariablelinkedintotheMUX'saddress spacenamed__ghsentry_smmuxrxfilter_XXXwhereXXXisanarbitrarynamethatisuniqueto thefilterbeingcreated.Thesymbolmustbeoftypestruct muxfilter,andmustcontain configurationinformationforthefilter.Itisimportantthatthemodifiesfieldissetproperly.Ifitis not,itmayleadtounintendedmodificationofshareddata,orwasteofCPUcycles.Thefollowingcode createsafilteronport0oftheMUXwithid10thatfiltersoutallframesfromaparticularMAC address.Sinceitdoesnotmodifythedatathemodifiesissettofalse.
static Error myfilter2(char *buf, int *len) { static char badaddr[] = { 0x00,0x01,0x03,0xD6,0x18,0xD7 }; if(memcmp(buf+6, badaddr, 6) == 0) { /* Frame came from disallowed sender. Destroy! */ return Failure; } return Success; } struct muxfilter __ghsentry_smmuxrxfilter_a = { 10, 0, myfilter2, false };

02052010.MUXdocversion1.10

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

10

CompleteMUXConfigurationExample
ThefollowingmustbeplacedinalocationwhereitcanbelinkedintotheMUX'saddressspace.
#include mux/mux_config.h

struct muxfilter{ int mux_id; int port; Error (*filter)(char *, int *); Boolean modifies; }; struct muxconfig __ghsentry_smmux_mux1 = { 1, "MUXEtherDev1", &mux_ethernet_driver_iod, 2, "__ghs_MUX1_buffers" static Error demo_tx_filter(char *data, int *length){ static char destaddr[] = { 0x00,0x01,0x03,0xD6,0x18,0xD7 }; memcpy(data, destaddr, 6); return Success; } struct muxfilter __ghsentry_smmuxtxfilter_a = {MUX1, 0, demo_tx_filter, true};

AdvancedFeaturesoftheZCMUX
TheZCMUXcanbecompiledwithvariousmacrostoenablecertainadvancedfeatures.Changeof anyofthesemacrosrequiresZCMUXsourcetorecompiletheMUXlibraries.Thedefaultvaluesof thesesymbolsaredefinedinsm_mux.h.Thedefaultvaluesmaybeoverriddenbydefiningthemin default.gpjwiththeDoptionorinsm_mux.h.Thesemacrosaredescribedinthefollowingsection.

GlobalMUXConfiguration

MAX_ENET_MUXESthemaximumnumberofEthernetMUXesallowedonthesystem.If thisnumberistoolarge,somephysicalmemorywillbewasted.Thisnumbershouldbeequalto thenumberofphysicalportsusedforMUXes. MAX_ENET_MUX_VDEVSthecumulativemaximumnumberofvportsonallMUXes systemwide.Forexample,fortwoMUXes,onewith3vportsandonewith6vports, MAX_ENET_MUX_VDEVSmustbeatleast9.Ifthenumberistoolarge,somephysical memorywillbewasted.

ENET_MUX_NUM_MAC_ADDRthecumulativenumberofuniqueandmulticastMAC addressesthatcanbeassignedtoavport.NOTE:Avportneedstoalwayshaveatleastone uniqueMACaddress;itcannotbeassignedonlyamulticastMACaddress.MACaddressescan beassignedwiththeMUXVport_clear_MAC(),MUXVport_add_MAC()and MUXVport_set_MAC()methodsdescribedbelow.Bydefault ENET_MUX_NUM_MAC_ADDRis2. 02052010.MUXdocversion1.10 11

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

MUX_GLOBAL_ACCESSthisgreatlyincreasesMUXperformancebyallowingallstacks unrestrictedreadaccesstoMUXframebuffers. MUX_DISABLE_CLEARthisincreasesMUXperformancebynotclearingMUXframe buffersbetweenuses,whichisapotentialsecurityrisk. ENET_MUX_USE_MEMCPYifdefined,theMUXwillusememcpy()forframessmaller thanENET_MUX_INIT_MEMCPY_LIMIT.ThismayimproveperformanceonCPUswith slowmemorymappingoperations.ENET_MUX_INIT_MEMCPY_LIMITmaybetunedfor optimalperformance.IfMUX_GLOBAL_ACCESSisdefined,thisoptionisdisabled. ENET_MUX_BROADCAST_SHAREDifdefined,improvesMUXperformancewith broadcastframes,particularlywithlargenumbersofvports.However,thisoptionusesalarger amountoffixedmemoryandmaybeslowerforMUXeswithonlyoneortwovports.If MUX_GLOBAL_ACCESSisdefined,thisoptionisdisabled.

ghnetv1TCPIPstackandtheZCMUX
ghnetv1ZCMUXsupporthasbeendeprecatedinfavorofghnetv2

ghnetv2TCPIPstackandtheZCMUX
Toattachaghnetv2TCP/IPstacktoavport,linkthestackwiththelibmux_ethdriverandlibvport librariesbyaddingthefollowingtothestack'sproject(i.e.ip4server_modules.gpj): lvport lmux_ethdriver Thestackshouldbealsolinkedwiththeappropriatestacklibrarysuchaslibip4. Useofthelibmux_ethdriverrequiresthedefinitionofthe__ghs_mux_vport_IDsstructwhichisused bythemuxvportdrivertoattachTCP/IPstackstovariousvirtualports.AvportIDconsistofaMUX IDandavportnumber.Thepair{1,2}signifiesvport2ontheMUX1.the__ghs_mux_vport_IDs sturctmustendwith{1,1}andshouldbeplacedintheaddressspaceoftheTCPIPstack.The followingisanexampleofhowtodeclare__ghs_mux_vport_IDs:

typedef struct _vportID{ int mux_id; int vport_num; } vportID; __ghs_mux_vport_IDs = {{1, 2},{-1,-1}}

Anexampleofaghnetv2usingtheZCMUXcanbefoundunder: default.gpj>examples.gpj>networkexamples.gpj>ip4servermux_example.gpj 02052010.MUXdocversion1.10


Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

12

LinktimememoryforMUX(optional)
StaticmemoryneedstobesetasidefortheMUXanditsvports.Bydefaulttheamountofmemory reserveddependsonmacrostheMAX_ENET_MUXES,andMAX_ENET_MUX_VDEVS(seeGlobal MUXConfiguration),whichcanonlybesetbeforecompiletime.Becausecompiletimemaybetoo earlytodeterminethesevalues,theMUXallowsmemorytoprovidedforitatlinktime.Toprovidethe MUXwithlinktimememory,declareavariablenamedmux_alloc_linkedoftypestruct mux_allocation.Atlinktimeifavariablenamedmux_alloc_linkedisdeclared,theMUXwilluse memoryallocatedbythatvariable,elseitwilldefaulttomemoryreservedatcompiletimebythe MAX_ENET_MUXES,andMAX_ENET_MUX_VDEVSmacros.
struct mux_allocationcanbefoundinmux_config.handisdefinedasfollows. struct mux_allocation{ int num_muxes; mux_t *muxes; int num_vports; mux_vport_t *vports; };

Thenum_muxesfieldshouldcontainthemaxnumberofMUXesallocatedfortheMUX.Thisis equivalenttosettingaMAX_ENET_MUXESatcompiletime.Thisshouldbethelengthofthemuxes field. ThemuxesfieldshouldcontainapointertothememoryallocatedforfortheMUXes. Thenum_vportsfieldshouldcontainthemaxnumberofvportsallocatedfortheMUX.Thisis equivalenttoMAX_ENET_MUX_VDEVS.Thisshouldbethelengthofthevportsfield. Thevportsfieldshouldcontainapointertothememoryallocatedforforthevports. Thefollowingisanexampleconfiguration:


#include "mux/mux_config.h" #define LINKED_NUM_MUX 2 #define LINKED_NUM_VPORT NUM_VPORTS 10 mux_t lmuxes[LINKED_NUM_MUX]; mux_vport_t lvports[LINKED_NUM_VPORT]; struct mux_allocation mux_alloc_linked = { LINKED_NUM_MUX, lmuxes, LINKED_NUM_VPORT, lvports };

02052010.MUXdocversion1.10

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

13

ZCMUXvportAPI
ThefollowingsectiondescribestheZCMUXvportAPIthatenablesstacksorsuitableapplicationsto directlycommunicatewiththeMUX.TheZCMUXvportAPIisalsodescribedinthecommentsin mux_vport.h. AstackusingtheZCMUXvportAPIshouldincludethemux_vport.hheaderfilebyadding:
#include <mux/mux_vport.h>

andbecompiledwiththelibrarylibvportbyadding:
-lvport

tothestack'sprojectfile.

Datatypes
MUXVportDev

ThisdatatypestoresconnectioninformationassociatedwithaparticularvportonaparticularMUX. ItispassedasaargumentinallmethodsintheZCMUXvportAPI.Itisdefinedinmux/mux_vport.h andinitializedviathemethodMUXVport_connect().

Methods
Error MUXVport_connect(MUXVportDev *vportDev, int mux_id, int vportNum);

ThismethodinitializestheMUXVportDevpointedtobyvportDev.Thismethodassociatesthestack withvportvportNumontheMUXmux_id.Thismethodshouldbecalledpriortoanyothermethods onthevport.


Error MUXVport_get_info(MUXVportDev *vportDev, Value *requiredMemory, Value *maxRxBufs, Value *maxTxBufs);

Thismethodretrievesinformationaboutthevportnecessarytocompletestackinitialization. requiredMemoryreturnstheamountofVirtualAddressSpacememory(inbytes)requiredbythe vportfortransmitandreceiveframes.maxTxBufsandmaxRxBufsreturnsthemaximumnumberof transmitandreceiveframesastackcanhaveoutstandingbeforeframesaredropped.Ifaparticular parameterisnotneededbythestack,passaNULLpointer.


Error MUXVport_map_memory_buffers(MUXVportDev *vportDev, MemoryRegion bufsMR Address *stackFirst);

ThismethodgivestheMemoryRegionbufsMRtotheMUXtomanage. ForVirtualAddressSpacestacksthebufsMRmustbeavirtualMemoryRegionandmustbeatleast requiredMemory(asreturnedfromMUXVport_get_info())bytesinlength.requiredMemory byteswillbesplitofffrombufsMRandgiventotheMUXtomanage.BecausetheMUXtakes controlofthisvirtualMemoryRegion,anyinformationabouttheMemoryRegionneededbythe 02052010.MUXdocversion1.10


Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

14

stack(e.g.,MemoryRegion'sfirstandlastAddresses)shouldberetrievedpriortotheinvocationof thismethod. ForKernelSpacestacksthebufsMRshouldbesettoNULLMemoryRegion(nomappingisdone becausethestackshouldhavedirectaccesstothephysicalmemory).


stackFirstwillreturntheAddresslocationofthefirstframeinthestack'sAddressSpace.For VirtualAddressSpacestacks,thisisgenerallythefirstAddressoftheofbufsMRMemoryRegion.

ForKernelSpacestacks,thisisactuallocationofthefirstframeinphysicalmemory.

Error MUXVport_get_semaphore(MUXVportDev *vportDev, Semaphore *notifySem);

Thismethodreturnsthevportnotificationeventsemaphore.Whenaneventoccurs, MUXVport_get_status()shouldbecalledtoretrievetheevent(s).Multipleeventscanbemerged intoonesemaphorerelease.EventsaredescribedinMUXVport_get_status().


Error MUXVport_get_status(MUXVportDev *vportDev, Value *cause, Value *arg0, Value *arg1);

Thismethodretrievesapendingnotificationeventtobehandledbythestack.Thismethodshould becalleduponasuccessfulwaitonthesemaphorereturnedfromMUXVport_get_semaphore(). Becausemultipleeventscanbemergedintoonesemaphorerelease,thismethodshouldbecalled repeatedlyuntilacauseofVPORT_STATUS_NONEisreturned.causewillreturnthetypeofeventthat hasoccurred.arg0andarg1containinformationdependentonthetypeofevent.Thefollowingare eventstypes:


VPORT_STATUS_NONEtherearenopendingevents.arg0andarg1willreturn0. VPORT_STATUS_READ_DONEAreceiveframehascompletedsuccessfully.arg0willcontain theframeindexofwherethereceiveframe.arg1willcontainthelengthofvaliddata. VPORT_STATUS_WRITE_DONEAtransmitframehascompletedsuccessfully.arg0will containtheframeindexofthetransmittedframe.arg1willcontaintheuser_data transmittedwiththeframe(viaMUXVport_tx()).

Error MUXVport_get_tx(MUXVportDev *vportDev, Value *frame_index);

Thismethodrequestsatransmitframe.UponreturnofSuccess,theframeindexedby frame_indexcanbewrittento.TheframeistransmittedviaMUXVport_tx().
Error MUXVport_tx(MUXVportDev *vportDev, Value frame_index, Value length, Value user_data);

Thismethodtransmitstheframeindexedbyframe_index.Avalidframe_indexisbeobtainedvia MUXVport_get_tx().lengthisthenumberofvalidbytestotransmit.user_dataisreturnedwith theVPORT_STATUS_WRITE_DONEnotificationevent.Theuser_dataparameterisprovidedforthe 02052010.MUXdocversion1.10


Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

15

stack'sconvenienceandisnotusedbytheMUX(SeeMUXVport_get_status().)
Error MUXVport_rx_done(MUXVportDev *vportDev, Value frame_index);

Thismethodreturnsanoutstandingreceiveframe(obtainedfromVPORT_STATUS_READ_DONE notificationevent)totheMUX.Thestackneedstoreturnreceiveframeinordertoreceive additionalframes.


Error MUXVport_set_promiscuous(MUXVportDev *vportDev, Boolean mode);

Thismethodsetsthevport'spromiscuousmode.Inpromiscuousmode,avportwillreceiveall framessentbyanyotherport(physicalorvirtual).Changesareimmediate.
Error MUXVport_set_multicast(MUXVportDev *vportDev, Boolean capture);

Thismethodsetsthevport'smulticastcapturemode.Ifcaptureissetthenthevportwillcaptureall multicastframes.Thisissimilartopromiscuousmodebutformulticastframesonly.Changesare immediate.


Error MUXVport_get_MAC(MUXVportDev *vportDev, unsigned char const **mac_addr);

Thismethodreturnsthevport'sMACaddress.
Error MUXVport_clear_MAC(MUXVportDev *vportDev);

Thismethodclearsthevport'sMACaddressbuffer.Thismethodshouldbeusedinpreparationto setthevport'sMACaddresses.ChangesarenotperformeduntilMUXVport_set_MAC()iscalled.
Error MUXVport_add_MAC(MUXVportDev *vportDev, unsigned char *mac_addr);

ThismethodaddsaMACaddresstothevport'srecipientaddressbuffer.ThenumberofMAC addressesthatcanbeaddedislimitedbytheENET_MUX_NUM_MAC_ADDR(seeGlobalMUX Configuration).Ifthebufferisfull,thismethodwillreturnanError.Changeswillnotbeperformed untilMUXVport_set_MAC()iscalled.


Error MUXVport_set_MAC(MUXVportDev *vportDev);

ThismethodsetsthevporttolistenforanyMACaddressesaddedviatheMUXVport_add_MAC() method.Changingofavport'sMACaddressrequirestrioofMUXVport_clear_MAC(), MUXVport_add_MAC(),andMUXVport_set_MAC().s 02052010.MUXdocversion1.10 16

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

Error MUXVport_shutdown(MUXVportDev *vportDev);

Thismethodwillshutdownavport;freeingresources.
Address MUXVport_frame_start(MUXVportDev *vportDev, frame_index);

Thisinlinemethodwillreturnthestartaddressofaframegivenaframe_index.Frameindexshould havebeenobtainedviaMUXVport_get_tx()orMUXVport_get_status().

StackPortingGuide
ThefollowingsectionshighlightdifferencesbetweentheEthernetIODeviceAPIandtheZCMUX vportAPIandoffershintsonstackporting.Providedsamplecodemaybeusefulforbuildingnew stacks,aswellasstackporting.Theformatofthissectionwillprovideanexampleimplementation usingtheEthernetIODeviceAPIandacorrespondingimplementationusingtheZCMUXvportAPI.

HighLevelDifferencesbetweenZCMUXandOMUX
WithoutahighlevelunderstandingofthedifferencesbetweentheZCMUXandOMUX,theporting mayleadtonoperformancegainorworseperformance. AstackusingtheOMUXusestheEthernetIODeviceAPI.TheEthernetIODeviceAPIallowstwo methodsoftransmittingandreceivingofframes:BuffersandBlocks.WiththeBuffermethod,astack providesvalidBuffersinitsVirtualAddressSpacetotheEthernetIODevicetotransmitfromorreceive to.WiththeBlockmethod,astackmapsbuffersintoitsVirtualAddressSpaceandEthernetIODevice providesbufferindexesfortransmittingandreceivingindividualbuffers.Duetotheimplementation theOMUX,bothmethodsrequireanexpensivememcpy()operationtotransferdatatothebetween buffers. TheZCMUXavoidsthisexpensivememcpy()operationbymappingbuffersintoastack'sAddress Space.ThetransmittingandreceivingframesusingtheZCMUXvportAPIissimilartotheEthernet IODeviceBlockmethod.Inbothcases,memoryismapped1directlyintothestack'svirtualaddress spaceandindexesareusedtotransmitorreceiveindividualframebuffers.Thedifferenceliesinthe theindexuse.TheOMUXusesbufferindexestoindexintoabufferrangededicatedtoaparticular EthernetIODevice.TheZCMUXusesframeindexestoindexintoaframerangesharedbyallports. Becauseofthesimilaritiesbetweenthetwo,thisportingguidewilldemonstratehowtoportastack fromtheEthernetIODeviceBlockmethodtotheZCMUXvportAPI.

VportInitialization
AstackusingtheEthernetIODeviceAPI(Blockmethod)wouldberequiredtopreparetransmitand receivebuffersbeforetransmittingandreceivingbuffers.Thestackwouldberequiredtoobtainthe EthernetIODeviceObjectfromtheResourceManager,mapthe__ghs_tcpip_buffersphysical
1 MappingisdonebytheMUX(asopposedtothestack)intheZCMUXforsecurityreasons.

02052010.MUXdocversion1.10

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

17

MemoryRegionobtainedfromtheResourceManager,andcalculatewherethefirstbuffertheEthernet IODevicemanagesstarts.ThestackrequiresthenameoftheoftheEthernetIODevice.Thefollowing issamplecodeofhowastackmayaccomplishthis:


/* This will store the address of the tcpip buffers block in this VAS */ Address Buffers_First_Phy, Address Buffers_First_Virt; /* These will store the first address of rx and tx buffers managed by this * device */ Address Device_rx_Buffer_First_Phy, Address Device_tx_Buffer_First_Phy; Address Device_rx_Buffer_First_Virt, Address Device_tx_Buffer_First_Virt; char *devName = "EtherDev2"; MemoryRegion PhyMemReg; static void Init(void){ MemoryRegion VirtMemReg; Value offset; RequestResource((Object *)&ethiod, devName, "!systempassword")); /* Obtain the physical MemoryRegion for the tcpip buffers from the ResourceManager */ RequestResource((Object *)&PhyMemReg, "__ghs_tcpip_buffers", "!systempassword"); GetMemoryRegionAddresses(PhyMemReg, &Buffers_First_Phy, NULL); /* Map tcpip buffers MemoryRegion into this VAS */ MapMemory(__ghs_VirtualMemoryRegionPool, PhyMemReg, &VirtMemReg, &Buffers_First, NULL); /* Calculate where the first rx buffer that this device manages */ ReadIODeviceRegister(ethiod->iod, IODEV_ETHERBUF_OFFSET, &offset); Device_rx_Buffer_First_Phy = Buffer_First_Phy + offset; Device_rx_Buffer_First_Virt = Buffer_First_Virt + offset; /* Calculate where the first tx buffer that this device manages */ ReadIODeviceRegister(ethiod->iod, IODEV_ETHER_RXBUF, &num_rx_buffers); Device_tx_Buffer_First_Phy = Buffer_First_Phy + offset + (INTEGRITY_ETH_BUF_SIZE * num_rx_buffers); Device_tx_Buffer_First_Virt = Buffer_First_Virt + offset + (INTEGRITY_ETH_BUF_SIZE * num_rx_buffers); }

Likewise,astackusingtheZCMUXvportAPImustpreparetransmitandreceivebuffersbefore transmittingandreceivingframes.Astackisrequiredtoinitializethevportconnection,obtain informationonmemoryrequirements,andprovideaMemoryRegioninitsVASforframestobe mappedto.TheseareaccomplishedwiththemethodsMUXVport_connect(),MUXVport_get_info(), MUXVport_map_memory_buffers().ThestackrequirestheidoftheMUXandthevportnumberto connectto.Thefollowingissamplecodeofhowastackwishingtoconnecttovport0onMUX1may accomplishthis: 02052010.MUXdocversion1.10 18


Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

MUXVportDev vportDevice; int muxID = 1; int vportNum = 0; /* This will store the address of the first frame. */ Address Frames_First; static Error Init(void){ MUXVportDev *vportDev = &vportDevice; Value reqMemSize; /* Connect to Vport */ MUXVport_connect(vportDev, muxID, vportNum); /* Get information on vport requirements */ MUXVport_get_info(vportDev, &reqMemSize, NULL, NULL); /* Make virtual MemoryRegion allocation of required size and give to vport/MUX */ AllocateAlignedMemoryRegion(__ghs_VirtualMemoryRegionPool, reqMemSize, 12, &framesMR); MUXVport_map_memory_buffers(vportDev, framesMR, &Frames_First); /* Cleanup and Close framesMR, control has been given to Vport/MUX */ CloseMemoryRegion(framesMR); }

TransmittingandReceivingFrames BufferandFrameIndexes
AstackusingtheBlockmethodusesbufferindexestoreferenceamemorylocationusedfor transmittingandreceivingdata.EachbufferisofsizeINTEGRITY_ETH_BUF_SIZEandisindexed startingattheEthernetIODevice'sfirstreceiveandtransmitbuffers(inthepreviousexamplethese wouldbeDevice_rx_Buffer_First_VirtandDevice_tx_Buffer_First_Virtrespectively).A bufferwithbufferindexbuffer_indexwouldbememorystartingat:
Device_rx_Buffer_First_Virt + (buffer_index * INTEGRITY_ETH_BUF_SIZE);

forrxbuffersand:
Device_tx_Buffer_First_Virt + (buffer_index * INTEGRITY_ETH_BUF_SIZE);

fortxbuffers. TransmittingandreceivingofframesusingtheZCMUXvportAPIisaccomplishedbyuseofframe indexes.Aframeisaportionofmemoryindexedbyaframe_index.Theapplicationshoulddetermine thememoryaddressreferencedbytheframe_indexwithMUXVport_frame_start(). 02052010.MUXdocversion1.10 19

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

TransmittingFrames
Totransmitabuffer,astackusingtheBlockmethodisrequiredtoobtainatransmitbufferindexvia ReadStatusFromIODevice(),writetothecorrespondingbuffer,andmakearequesttotransmitthat bufferviaWriteSubBlockToIODevice().Thefollowingsamplecodeshowsthismaybe accomplished:
/* Assume mac_addr points to this devices MAC address */ char *mac_addr; void writeEmptyBroadCast(IODevice iod, int length) { Address phy_buffer; char *buffer; /* obtain a buffer */ ReadIODeviceStatus(iod, IODEV_STAT_GENERIC, &buffer_index, 4); phy_buffer = (Device_tx_Buffer_First_Phy + (buffer_index * INTEGRITY_ETH_BUF_SIZE)); buffer = (char *) (Device_tx_Buffer_First_Virt + (buffer_index * INTEGRITY_ETH_BUF_SIZE)); /* Use the buffer */ memset(buffer, 0xff, 6); memcpy(buffer + 6, mac_addr, 6); memset(buffer + 12, 0, length - 12); WriteSubBlockToIODevice(iod, length, buffer_index, PhyMemReg, phy_buffer, length); }

Totransmitaframe,astackusingtheZCMUXvportAPIisrequiredtoobtainatransmitframeindex viaMUXVport_get_tx(),writetothecorrespondingframe,andmakearequesttotransmitthatframe viaMUXVport_tx().Thefollowingsamplecodeshowshowthismaybeaccomplished:


/* Assume mac_addr points to this devices MAC address */ char *mac_addr; void writeEmptyBroadCast(MUXVportDev *vportDev, int length) { Value tx_index; unsigned char *frame; /* obtain a buffer */ MUXVport_get_tx(vportDev, &tx_index); /* Use the buffer */ frame = (unsigned char *)MUXVport_frame_start(vportDev, tx_index); memset(&frame[0], 0xff, 6); memcpy(&frame[6], mac_addr, 6); memset(&frame[12], 0, length - 12);

02052010.MUXdocversion1.10

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

20

MUXVport_tx(vportDev, tx_index, length, 0); }

ReceivingFrames(Preparation)
Toreceiveaframe,astackusingtheEthernetIODeviceAPI(Blockmethod)isrequiredtonotifythe EthernetIODevicethattheBSP'sEthernetbufferringshouldbepostedtothedeviceforreadingvia ReadSubBlockFromIODevice().Thefollowingsamplecodeshowshowthismaybeaccomplished:
static void start_rx(IODevice iod) { int i; Value num_rx_bufs; /* Figure out how many buffers to receive */ ReadIODeviceRegister(iod, IODEV_ETHER_RXBUF, &num_rx_bufs); /* Do the initial receives on the device */ for (i=0; i < num_rx_bufs; i++) { Address rxBufAddr = (Device_tx_Buffer_First_Phy + (i * INTEGRITY_ETH_BUF_SIZE)); ReadSubBlockFromIODevice(ethiod->iod, 0, i, PhyMemReg, rxBufAddr, INTEGRITY_ETH_BUF_SIZE); } }

AstackusingtheZCMUXvportAPIdoesnotneedtoprepthevportforreceivingframes.Frames willbegintocomeinassoonasthevportisinitialized.

EventHandling
EventhandlingbetweentheEthernetIODeviceAPIandtheZCMUXvportAPIisverysimilar.Inthe caseoftheEthernetIODevice,thestackwaitsontheEthernetIODeviceObjectandobtainsthestatus viaReadIODeviceStatus().ThestackshouldreadthestatusuntilastatusofNoPendingInterruptis received.IftheeventwasaReadBlockComplete,thestackneedstorereceiveonthebufferviaacall toReadSubBlockFromIODevice()whenitisfinishedwiththebuffer.Thefollowingisanexample eventhandlerfortheEthernetIODeviceAPI(Blockmethod):
buffer_index = status.Id; switch(status.Cause){ case ReadBlockCompleted: /* Code for receive of buffer */ ... /* Re-receive on buffer */ ReadBuffersFromIODevice(ethiod, 0, id, &rxBuffer[id]); break;

02052010.MUXdocversion1.10

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

21

case WriteBlockCompleted: /* Code for transmit complete. */ ... break; case NoPendingInterrupt: break; } }while(status.Cause != NoPendingInterrupt); } }

ThestructureoftheeventhandlerusingtheZCMUXvportAPIisnearlyidentical.Thedifferences arethatthestackusesaSemaphore,MUXVport_get_status()isusedtoobtainthestatusand MUXVport_rx_done()shouldbecalledwhenthestackisfinishedwiththeframe.Thefollowingisan exampleeventhandlerfortheZCMUXvportAPI.


static void event_handler(MUXVportDev *vportDev) { int buffer_index; Semaphore notifySem; Value cause, arg0, arg1; MUXVport_get_semaphore(vportDev, &notifySem); while(1){ /* Wait for Event */ WaitForSemaphore(notifySem); do{ MUXVport_get_status(vportDev, &cause, &arg0, &arg1); buffer_index = status.Id; switch(cause){ case VPORT_STATUS_READ_DONE: /* Code for handling receive of frame */ ... /* Re-receive on frame */ MUXVport_rx_done(vportDev, arg0); break; case VPORT_STATUS_WRITE_DONE: /* Code for handling transmit complete. */ ... break; case VPORT_STATUS_NONE: break; } }while(cause != VPORT_STATUS_NONE); }

02052010.MUXdocversion1.10

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

22

02052010.MUXdocversion1.10

Copyright(c)2010,GreenHillsSoftware,Inc.,allrightsreserved. GreenHillsProprietaryInformation

23