aboutsummaryrefslogtreecommitdiffstats
BranchCommit messageAuthorAge
archive/unc-master-3.0P-FP: fix BUG_ON releated to priority inheritanceBjoern Brandenburg13 years
archived-2013.1uncachedev: mmap memory that is not cached by CPUsGlenn Elliott12 years
archived-private-masterMerge branch 'wip-2.6.34' into old-private-masterAndrea Bastoni15 years
archived-semi-partMerge branch 'wip-semi-part' of ssh://cvs/cvs/proj/litmus/repo/litmus2010 int...Andrea Bastoni15 years
demoFurther refinementsJonathan Herman14 years
ecrts-pgm-finalMerge branch 'wip-ecrts14-pgm' of ssh://rtsrv.cs.unc.edu/home/litmus/litmus-r...Glenn Elliott12 years
ecrts14-pgm-finalMerge branch 'wip-ecrts14-pgm' of ssh://rtsrv.cs.unc.edu/home/litmus/litmus-r...Glenn Elliott12 years
gpusync-rtss12Final GPUSync implementation.Glenn Elliott12 years
gpusync/stagingRename IKGLP R2DGLP.Glenn Elliott12 years
linux-tipMerge branch 'slab/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/p...Linus Torvalds15 years
litmus2008-patch-seriesadd i386 feather-trace implementationBjoern B. Brandenburg16 years
masterPSN-EDF: use inferred_sporadic_job_release_atBjoern Brandenburg9 years
pgmmake it compileGlenn Elliott12 years
prop/litmus-signalsInfrastructure for Litmus signals.Glenn Elliott13 years
prop/robust-tie-breakFixed bug in edf_higher_prio().Glenn Elliott13 years
stagingFix tracepoint compilation errorFelipe Cerqueira13 years
test9/23/2016Namhoon Kim9 years
tracing-develTest kernel tracing events capabilitiesAndrea Bastoni16 years
v2.6.34-with-arm-patchessmsc911x: Add spinlocks around registers accessCatalin Marinas15 years
v2015.1Add ARM syscall def for get_current_budgetBjoern Brandenburg10 years
wip-2011.2-bbbLitmus core: simplify np-section protocolBjoern B. Brandenburg14 years
wip-2011.2-bbb-traceRefactor sched_trace_log_message() -> debug_trace_log_message()Andrea Bastoni14 years
wip-2012.3-gpuSOBLIV draining support for C-EDF.Glenn Elliott12 years
wip-2012.3-gpu-preportpick up last C-RM fileGlenn Elliott12 years
wip-2012.3-gpu-rtss13Fix critical bug in GPU tracker.Glenn Elliott12 years
wip-2012.3-gpu-sobliv-budget-w-ksharkProper sobliv draining and many bug fixes.Glenn Elliott12 years
wip-aedzl-finalMake it easier to compile AEDZL interfaces in liblitmus.Glenn Elliott15 years
wip-aedzl-revisedAdd sched_trace data for Apative EDZLGlenn Elliott15 years
wip-arbit-deadlineFix compilation bug.Glenn Elliott13 years
wip-aux-tasksDescription of refined aux task inheritance.Glenn Elliott13 years
wip-bbbGSN-EDF & Core: improve debug TRACE'ing for NP sectionsBjoern B. Brandenburg14 years
wip-bbb-prio-donuse correct timestampBjoern B. Brandenburg14 years
wip-better-breakImplement hash-based EDF tie-breaking.Glenn Elliott13 years
wip-binary-heapMake C-EDF work with simplified binheap_deleteGlenn Elliott13 years
wip-budgetAdded support for choices in budget policy enforcement.Glenn Elliott15 years
wip-colorSummarize schedulability with final recordJonathan Herman13 years
wip-color-jlhsched_color: Fixed two bugs causing crashing on experiment restart and a rare...Jonathan Herman13 years
wip-d10-hz1000Enable HZ=1000 on District 10Bjoern B. Brandenburg15 years
wip-default-clusteringFeature: Make default C-EDF clustering compile-time configurable.Glenn Elliott15 years
wip-dissipation-jericksoUpdate from 2.6.36 to 2.6.36.4Jeremy Erickson11 years
wip-dissipation2-jericksoUpdate 2.6.36 to 2.6.36.4Jeremy Erickson11 years
wip-ecrts14-pgmMerge branch 'wip-ecrts14-pgm' of ssh://rtsrv.cs.unc.edu/home/litmus/litmus-r...Glenn Elliott12 years
wip-edf-hsblast tested versionJonathan Herman14 years
wip-edf-osLookup table EDF-osJeremy Erickson12 years
wip-edf-tie-breakMerge branch 'wip-edf-tie-break' of ssh://rtsrv.cs.unc.edu/home/litmus/litmus...Glenn Elliott13 years
wip-edzl-critiqueUse hr_timer's active checks instead of having own flag.Glenn Elliott15 years
wip-edzl-finalImplementation of the EDZL scheduler.Glenn Elliott15 years
wip-edzl-revisedClean up comments.Glenn Elliott15 years
wip-eventsAdded support for tracing arbitrary actions.Jonathan Herman15 years
wip-extra-debugDBG: add additional tracingBjoern B. Brandenburg15 years
wip-fix-switch-jericksoAttempt to fix race condition with plugin switchingJeremy Erickson15 years
wip-fix3sched: show length of runqueue clock deactivation in /proc/sched_debugBjoern B. Brandenburg15 years
wip-fmlp-dequeueImprove FMLP queue management.Glenn Elliott14 years
wip-ft-irq-flagFeather-Trace: keep track of interrupt-related interference.Bjoern B. Brandenburg14 years
wip-gpu-cleanupEnable sched_trace log injection from userspaceGlenn Elliott13 years
wip-gpu-interruptsRemove option for threading of all softirqs.Glenn Elliott14 years
wip-gpu-rtas12Generalized GPU cost predictors + EWMA. (untested)Glenn Elliott13 years
wip-gpu-rtss12Final GPUSync implementation.Glenn Elliott13 years
wip-gpu-rtss12-srpexperimental changes to support GPUs under SRPGlenn Elliott13 years
wip-gpusync-mergeCleanup priority tracking for budget enforcement.Glenn Elliott11 years
wip-ikglpMove RSM and IKGLP imp. to own .c filesGlenn Elliott13 years
wip-k-fmlpMerge branch 'mpi-master' into wip-k-fmlpGlenn Elliott14 years
wip-kernel-coloringAdded recolor syscallNamhoon Kim7 years
wip-kernthreadsKludge work-queue processing into klitirqd.Glenn Elliott15 years
wip-klmirqd-to-auxAllow klmirqd threads to be given names.Glenn Elliott13 years
wip-ksharkMerge branch 'mpi-staging' into wip-ksharkJonathan Herman13 years
wip-litmus-3.2Merge commit 'v3.2' into litmus-stagingAndrea Bastoni13 years
wip-litmus2011.2Cleanup: Coding conformance for affinity stuff.Glenn Elliott14 years
wip-litmus3.0-2011.2Feather-Trace: keep track of interrupt-related interference.Bjoern B. Brandenburg14 years
wip-master-2.6.33-rtAvoid deadlock when switching task policy to BACKGROUND (ugly)Andrea Bastoni15 years
wip-mcRemoved ARM-specific hacks which disabled less common mixed-criticality featu...Jonathan Herman12 years
wip-mc-bipasaMC-EDF addedbipasa chattopadhyay13 years
wip-mc-jericksoSplit C/D queuesJeremy Erickson15 years
wip-mc2-cache-slackManually patched mc^2 related codeMing Yang10 years
wip-mcrit-maccosmeticMac Mollison15 years
wip-merge-3.0Prevent Linux to send IPI and queue tasks on remote CPUs.Andrea Bastoni14 years
wip-merge-v3.0Prevent Linux to send IPI and queue tasks on remote CPUs.Andrea Bastoni14 years
wip-migration-affinityNULL affinity dereference in C-EDF.Glenn Elliott14 years
wip-mmap-uncacheshare branch with othersGlenn Elliott13 years
wip-modechangeRTSS 2017 submissionNamhoon Kim8 years
wip-nested-lockingAppears to be working.Bryan Ward12 years
wip-omlp-gedfFirst implementation of G-OMLP.Glenn Elliott15 years
wip-paiSome cleanup of PAIGlenn Elliott14 years
wip-percore-lib9/21/2016Namhoon Kim9 years
wip-performanceCONFIG_DONT_PREEMPT_ON_TIE: Don't preeempt a scheduled task on priority tie.Glenn Elliott14 years
wip-pgmAdd PGM support to C-FLGlenn Elliott12 years
wip-pgm-splitFirst draft of C-FL-splitNamhoon Kim12 years
wip-pm-ovdAdd preemption-and-migration overhead tracing supportAndrea Bastoni15 years
wip-prio-inhP-EDF updated to use the generic pi framework.Glenn Elliott15 years
wip-prioq-dglBUG FIX: Support DGLs with PRIOQ_MUTEXGlenn Elliott13 years
wip-refactored-gedfGeneralizd architecture for GEDF-style scheduelrs to reduce code redundancy.Glenn Elliott15 years
wip-release-master-fixbugfix: release master CPU must signal task was pickedBjoern B. Brandenburg14 years
wip-robust-tie-breakEDF priority tie-breaks.Glenn Elliott13 years
wip-rt-ksharkMove task time accounting into the complete_job method.Jonathan Herman13 years
wip-rtas12-pgmScheduling of PGM jobs.Glenn Elliott13 years
wip-semi-partFix compile error with newer GCCJeremy Erickson12 years
wip-semi-part-edfos-jericksoUse initial CPU set by clientJeremy Erickson12 years
wip-shared-libTODO: Fix condition checks in replicate_page_move_mapping()Namhoon Kim9 years
wip-shared-lib2RTAS 2017 Submission ver.Namhoon Kim9 years
wip-shared-memInitial commit for shared libraryNamhoon Kim9 years
wip-splitting-jericksoFix release behaviorJeremy Erickson13 years
wip-splitting-omlp-jericksoBjoern's Dissertation Code with Priority DonationJeremy Erickson13 years
wip-stage-binheapAn efficient binary heap implementation.Glenn Elliott13 years
wip-sun-portDynamic memory allocation and clean exit for FeatherTraceChristopher Kenna15 years
wip-timer-tracebugfix: C-EDF, clear scheduled field of the correct CPU upon task_exitAndrea Bastoni15 years
wip-tracepointsAdd kernel-style events for sched_trace_XXX() functionsAndrea Bastoni14 years
 
TagDownloadAuthorAge
2015.1commit 8e51b37822...Bjoern Brandenburg10 years
2013.1commit bcaacec1ca...Glenn Elliott12 years
2012.3commit c158b5fbe4...Jonathan Herman13 years
2012.2commit b53c479a0f...Glenn Elliott13 years
2012.1commit 83b11ea1c6...Bjoern B. Brandenburg14 years
rtas12-mc-beta-expcommit 8e236ee20f...Christopher Kenna14 years
2011.1commit d11808b5c6...Christopher Kenna15 years
v2.6.37-rc4commit e8a7e48bb2...Linus Torvalds15 years
v2.6.37-rc3commit 3561d43fd2...Linus Torvalds15 years
v2.6.37-rc2commit e53beacd23...Linus Torvalds15 years
v2.6.37-rc1commit c8ddb2713c...Linus Torvalds15 years
v2.6.36commit f6f94e2ab1...Linus Torvalds15 years
2010.2commit 5c5456402d...Bjoern B. Brandenburg15 years
v2.6.36-rc8commit cd07202cc8...Linus Torvalds15 years
v2.6.36-rc7commit cb655d0f3d...Linus Torvalds15 years
v2.6.36-rc6commit 899611ee7d...Linus Torvalds15 years
v2.6.36-rc5commit b30a3f6257...Linus Torvalds15 years
v2.6.36-rc4commit 49553c2ef8...Linus Torvalds15 years
v2.6.36-rc3commit 2bfc96a127...Linus Torvalds15 years
v2.6.36-rc2commit 76be97c1fc...Linus Torvalds15 years
v2.6.36-rc1commit da5cabf80e...Linus Torvalds15 years
v2.6.35commit 9fe6206f40...Linus Torvalds15 years
v2.6.35-rc6commit b37fa16e78...Linus Torvalds15 years
v2.6.35-rc5commit 1c5474a65b...Linus Torvalds15 years
v2.6.35-rc4commit 815c4163b6...Linus Torvalds15 years
v2.6.35-rc3commit 7e27d6e778...Linus Torvalds15 years
v2.6.35-rc2commit e44a21b726...Linus Torvalds15 years
v2.6.35-rc1commit 67a3e12b05...Linus Torvalds15 years
2010.1commit 7c1ff4c544...Andrea Bastoni15 years
v2.6.34commit e40152ee1e...Linus Torvalds15 years
v2.6.33.4commit 4640b4e7d9...Greg Kroah-Hartman15 years
v2.6.34-rc7commit b57f95a382...Linus Torvalds15 years
v2.6.34-rc6commit 66f41d4c5c...Linus Torvalds15 years
v2.6.33.3commit 3e7ad8ed97...Greg Kroah-Hartman15 years
v2.6.34-rc5commit 01bf0b6457...Linus Torvalds15 years
v2.6.34-rc4commit 0d0fb0f9c5...Linus Torvalds15 years
v2.6.33.2commit 19f00f070c...Greg Kroah-Hartman15 years
v2.6.34-rc3commit 2eaa9cfdf3...Linus Torvalds15 years
v2.6.34-rc2commit 220bf991b0...Linus Torvalds15 years
v2.6.33.1commit dbdafe5ccf...Greg Kroah-Hartman16 years
v2.6.34-rc1commit 57d54889cd...Linus Torvalds16 years
v2.6.33commit 60b341b778...Linus Torvalds16 years
v2.6.33-rc8commit 724e6d3fe8...Linus Torvalds16 years
v2.6.33-rc7commit 29275254ca...Linus Torvalds16 years
v2.6.33-rc6commit abe94c756c...Linus Torvalds16 years
v2.6.33-rc5commit 92dcffb916...Linus Torvalds16 years
v2.6.33-rc4commit 7284ce6c9f...Linus Torvalds16 years
v2.6.33-rc3commit 74d2e4f8d7...Linus Torvalds16 years
v2.6.33-rc2commit 6b7b284958...Linus Torvalds16 years
v2.6.33-rc1commit 55639353a0...Linus Torvalds16 years
v2.6.32commit 22763c5cf3...Linus Torvalds16 years
v2.6.32-rc8commit 648f4e3e50...Linus Torvalds16 years
v2.6.32-rc7commit 156171c71a...Linus Torvalds16 years
v2.6.32-rc6commit b419148e56...Linus Torvalds16 years
v2.6.32-rc5commit 012abeea66...Linus Torvalds16 years
v2.6.32-rc4commit 161291396e...Linus Torvalds16 years
v2.6.32-rc3commit 374576a8b6...Linus Torvalds16 years
v2.6.32-rc1commit 17d857be64...Linus Torvalds16 years
v2.6.32-rc2commit 17d857be64...Linus Torvalds16 years
v2.6.31commit 74fca6a428...Linus Torvalds16 years
v2.6.31-rc9commit e07cccf404...Linus Torvalds16 years
v2.6.31-rc8commit 326ba5010a...Linus Torvalds16 years
v2.6.31-rc7commit 422bef879e...Linus Torvalds16 years
v2.6.31-rc6commit 64f1607ffb...Linus Torvalds16 years
v2.6.31-rc5commit ed680c4ad4...Linus Torvalds16 years
v2.6.31-rc4commit 4be3bd7849...Linus Torvalds16 years
v2.6.31-rc3commit 6847e154e3...Linus Torvalds16 years
v2.6.31-rc2commit 8e4a718ff3...Linus Torvalds16 years
v2.6.31-rc1commit 28d0325ce6...Linus Torvalds16 years
v2.6.30commit 07a2039b8e...Linus Torvalds16 years
v2.6.30-rc8commit 9fa7eb283c...Linus Torvalds16 years
v2.6.30-rc7commit 59a3759d0f...Linus Torvalds16 years
v2.6.30-rc6commit 1406de8e11...Linus Torvalds16 years
v2.6.30-rc5commit 091bf7624d...Linus Torvalds16 years
v2.6.30-rc4commit 091438dd56...Linus Torvalds16 years
v2.6.30-rc3commit 0910697403...Linus Torvalds16 years
v2.6.30-rc2commit 0882e8dd3a...Linus Torvalds16 years
v2.6.30-rc1commit 577c9c456f...Linus Torvalds16 years
v2.6.29commit 8e0ee43bc2...Linus Torvalds16 years
v2.6.29-rc8commit 041b62374c...Linus Torvalds17 years
v2.6.29-rc7commit fec6c6fec3...Linus Torvalds17 years
v2.6.29-rc6commit 20f4d6c3a2...Linus Torvalds17 years
v2.6.29-rc5commit d2f8d7ee1a...Linus Torvalds17 years
v2.6.29-rc4commit 8e4921515c...Linus Torvalds17 years
v2.6.29-rc3commit 18e352e4a7...Linus Torvalds17 years
v2.6.29-rc2commit 1de9e8e70f...Linus Torvalds17 years
v2.6.29-rc1commit c59765042f...Linus Torvalds17 years
v2.6.28commit 4a6908a3a0...Linus Torvalds17 years
v2.6.28-rc9commit 929096fe9f...Linus Torvalds17 years
v2.6.28-rc8commit 8b1fae4e42...Linus Torvalds17 years
v2.6.28-rc7commit 061e41fdb5...Linus Torvalds17 years
v2.6.28-rc6commit 13d428afc0...Linus Torvalds17 years
v2.6.28-rc5commit 9bf1a2445f...Linus Torvalds17 years
v2.6.28-rc4commit f7160c7573...Linus Torvalds17 years
v2.6.28-rc3commit 45beca08dd...Linus Torvalds17 years
v2.6.28-rc2commit 0173a3265b...Linus Torvalds17 years
v2.6.28-rc1commit 57f8f7b60d...Linus Torvalds17 years
v2.6.27commit 3fa8749e58...Linus Torvalds17 years
v2.6.27-rc9commit 4330ed8ed4...Linus Torvalds17 years
v2.6.27-rc8commit 94aca1dac6...Linus Torvalds17 years
v2.6.27-rc7commit 72d31053f6...Linus Torvalds17 years
v2.6.27-rc6commit adee14b2e1...Linus Torvalds17 years
v2.6.27-rc5commit 24342c34a0...Linus Torvalds17 years
v2.6.27-rc4commit 6a55617ed5...Linus Torvalds17 years
v2.6.27-rc3commit 30a2f3c60a...Linus Torvalds17 years
v2.6.27-rc2commit 0967d61ea0...Linus Torvalds17 years
v2.6.27-rc1commit 6e86841d05...Linus Torvalds17 years
v2.6.26commit bce7f793da...Linus Torvalds17 years
v2.6.26-rc9commit b7279469d6...Linus Torvalds17 years
v2.6.26-rc8commit 543cf4cb3f...Linus Torvalds17 years
v2.6.26-rc7commit d70ac829b7...Linus Torvalds17 years
v2.6.26-rc6commit 5dd34572ad...Linus Torvalds17 years
v2.6.26-rc5commit 53c8ba9540...Linus Torvalds17 years
v2.6.26-rc4commit e490517a03...Linus Torvalds17 years
v2.6.26-rc3commit b8291ad07a...Linus Torvalds17 years
v2.6.26-rc2commit 492c2e476e...Linus Torvalds17 years
v2.6.26-rc1commit 2ddcca36c8...Linus Torvalds17 years
v2.6.25commit 4b119e21d0...Linus Torvalds17 years
v2.6.25-rc9commit 120dd64cac...Linus Torvalds17 years
v2.6.25-rc8commit 0e81a8ae37...Linus Torvalds17 years
v2.6.25-rc7commit 05dda977f2...Linus Torvalds17 years
v2.6.25-rc6commit a978b30af3...Linus Torvalds18 years
v2.6.25-rc5commit cdeeeae056...Linus Torvalds18 years
v2.6.25-rc4commit 29e8c3c304...Linus Torvalds18 years
v2.6.25-rc3commit bfa274e243...Linus Torvalds18 years
v2.6.25-rc2commit 101142c37b...Linus Torvalds18 years
v2.6.25-rc1commit 19af35546d...Linus Torvalds18 years
v2.6.24commit 49914084e7...Linus Torvalds18 years
v2.6.24-rc8commit cbd9c88369...Linus Torvalds18 years
v2.6.24-rc7commit 3ce5445046...Linus Torvalds18 years
v2.6.24-rc6commit ea67db4cdb...Linus Torvalds18 years
v2.6.24-rc5commit 82d29bf6dc...Linus Torvalds18 years
v2.6.24-rc4commit 09b56adc98...Linus Torvalds18 years
v2.6.24-rc3commit d9f8bcbf67...Linus Torvalds18 years
v2.6.24-rc2commit dbeeb816e8...Linus Torvalds18 years
v2.6.24-rc1commit c9927c2bf4...Linus Torvalds18 years
v2.6.23commit bbf25010f1...Linus Torvalds18 years
v2.6.23-rc9commit 3146b39c18...Linus Torvalds18 years
v2.6.23-rc8commit 4942de4a0e...Linus Torvalds18 years
v2.6.23-rc7commit 81cfe79b9c...Linus Torvalds18 years
v2.6.23-rc6commit 0d4cbb5e7f...Linus Torvalds18 years
v2.6.23-rc5commit 40ffbfad6b...Linus Torvalds18 years
v2.6.23-rc4commit b07d68b5ca...Linus Torvalds18 years
v2.6.23-rc3commit 39d3520c92...Linus Torvalds18 years
v2.6.23-rc2commit d4ac2477fa...Linus Torvalds18 years
v2.6.23-rc1commit f695baf2df...Linus Torvalds18 years
v2.6.22commit 7dcca30a32...Linus Torvalds18 years
v2.6.22-rc7commit a38d6181ff...Linus Torvalds18 years
v2.6.22-rc6commit 189548642c...Linus Torvalds18 years
v2.6.22-rc5commit 188e1f81ba...Linus Torvalds18 years
v2.6.22-rc4commit 5ecd3100e6...Linus Torvalds18 years
v2.6.22-rc3commit c420bc9f09...Linus Torvalds18 years
v2.6.22-rc2commit 55b637c6a0...Linus Torvalds18 years
v2.6.22-rc1commit 39403865d2...Linus Torvalds18 years
v2.6.21commit de46c33745...Linus Torvalds18 years
v2.6.21-rc7commit 94a05509a9...Linus Torvalds18 years
v2.6.21-rc6commit a21bd69e15...Linus Torvalds18 years
v2.6.21-rc5commit e0f2e3a06b...Linus Torvalds18 years
v2.6.21-rc4commit db98e0b434...Linus Torvalds19 years
v2.6.21-rc3commit 08e15e81a4...Linus Torvalds19 years
v2.6.21-rc2commit 606135a308...Linus Torvalds19 years
v2.6.21-rc1commit c8f71b01a5...Linus Torvalds19 years
v2.6.20commit 62d0cfcb27...Linus Torvalds19 years
v2.6.20-rc7commit f56df2f4db...Linus Torvalds19 years
v2.6.20-rc6commit 99abfeafb5...Linus Torvalds19 years
v2.6.20-rc5commit a8b3485287...Linus Torvalds19 years
v2.6.20-rc4commit bf81b46482...Linus Torvalds19 years
v2.6.20-rc3commit 669df1b478...Linus Torvalds19 years
v2.6.20-rc2commit 3bf8ba38f3...Linus Torvalds19 years
v2.6.20-rc1commit cc016448b0...Linus Torvalds19 years
v2.6.19commit 0215ffb08c...Linus Torvalds19 years
v2.6.19-rc6commit 44597f65f6...Linus Torvalds19 years
v2.6.19-rc5commit 80c2188127...Linus Torvalds19 years
v2.6.19-rc4commit ae99a78af3...Linus Torvalds19 years
v2.6.19-rc3commit 7059abedd2...Linus Torvalds19 years
v2.6.19-rc2commit b4bd8c6643...Linus Torvalds19 years
v2.6.19-rc1commit d223a60106...Linus Torvalds19 years
v2.6.18commit e478bec0ba...Linus Torvalds19 years
v2.6.18-rc7commit 95064a75eb...Linus Torvalds19 years
v2.6.18-rc6commit c336923b66...Linus Torvalds19 years
v2.6.18-rc5commit 60d4684068...Linus Torvalds19 years
v2.6.18-rc4commit 9f737633e6...Linus Torvalds19 years
v2.6.18-rc3commit b6ff50833a...Linus Torvalds19 years
v2.6.18-rc2commit 82d6897fef...Linus Torvalds19 years
v2.6.18-rc1commit 120bda20c6...Linus Torvalds19 years
v2.6.17commit 427abfa28a...Linus Torvalds19 years
v2.6.17-rc6commit 1def630a6a...Linus Torvalds19 years
v2.6.17-rc5commit a8bd60705a...Linus Torvalds19 years
v2.6.17-rc4commit d8c3291c73...Linus Torvalds19 years
v2.6.17-rc3commit 2be4d50295...Linus Torvalds19 years
v2.6.17-rc2commit 8bbde0e6d5...Linus Torvalds19 years
v2.6.17-rc1commit 6246b6128b...Linus Torvalds19 years
v2.6.16commit 7705a8792b...Linus Torvalds19 years
v2.6.16-rc6commit 535744878e...Linus Torvalds20 years
v2.6.16-rc5commit b9a33cebac...Linus Torvalds20 years
v2.6.16-rc4commit bd71c2b174...Linus Torvalds20 years
v2.6.16-rc3commit e9bb4c9929...Linus Torvalds20 years
v2.6.16-rc2commit 826eeb53a6...Linus Torvalds20 years
v2.6.16-rc1commit 2664b25051...Linus Torvalds20 years
v2.6.15commit 88026842b0...Linus Torvalds20 years
v2.6.15-rc7commit f89f5948fc...Linus Torvalds20 years
v2.6.15-rc6commit df7addbb45...Linus Torvalds20 years
v2.6.15-rc5commit 436b0f76f2...Linus Torvalds20 years
v2.6.15-rc4commit 5666c0947e...Linus Torvalds20 years
v2.6.15-rc3commit 624f54be20...Linus Torvalds20 years
v2.6.15-rc2commit 3bedff1d73...Linus Torvalds20 years
v2.6.15-rc1commit cd52d1ee9a...Linus Torvalds20 years
v2.6.14commit 741b2252a5...Linus Torvalds20 years
v2.6.14-rc5commit 93918e9afc...Linus Torvalds20 years
v2.6.14-rc4commit 907a426179...Linus Torvalds20 years
v2.6.14-rc3commit 1c9426e8a5...Linus Torvalds20 years
v2.6.14-rc2commit 676d55ae30...Linus Torvalds20 years
v2.6.14-rc1commit 2f4ba45a75...Linus Torvalds20 years
v2.6.13commit 02b3e4e2d7...Linus Torvalds20 years
v2.6.13-rc7commit 0572e3da3f...Linus Torvalds20 years
v2.6.13-rc6commit 6fc32179de...Linus Torvalds20 years
v2.6.13-rc5commit 9a351e30d7...Linus Torvalds20 years
v2.6.13-rc4commit 6395352334...Linus Torvalds20 years
v2.6.11tree c39ae07f39...
v2.6.11-treetree c39ae07f39...
v2.6.12commit 9ee1c939d1...
v2.6.12-rc2commit 1da177e4c3...
v2.6.12-rc3commit a2755a80f4...
v2.6.12-rc4commit 88d7bd8cb9...
v2.6.12-rc5commit 2a24ab628a...
v2.6.12-rc6commit 7cef5677ef...
v2.6.13-rc1commit 4c91aedb75...
v2.6.13-rc2commit a18bcb7450...
v2.6.13-rc3commit c32511e271...
span class="hl ppc"> #define RLMT_STATIC #ifndef SK_LITTLE_ENDIAN /* First 32 bits */ #define OFFS_LO32 1 /* Second 32 bits */ #define OFFS_HI32 0 #else /* SK_LITTLE_ENDIAN */ /* First 32 bits */ #define OFFS_LO32 0 /* Second 32 bits */ #define OFFS_HI32 1 #endif /* SK_LITTLE_ENDIAN */ #endif /* DEBUG */ /* ----- Private timeout values ----- */ #define SK_RLMT_MIN_TO_VAL 125000 /* 1/8 sec. */ #define SK_RLMT_DEF_TO_VAL 1000000 /* 1 sec. */ #define SK_RLMT_PORTDOWN_TIM_VAL 900000 /* another 0.9 sec. */ #define SK_RLMT_PORTSTART_TIM_VAL 100000 /* 0.1 sec. */ #define SK_RLMT_PORTUP_TIM_VAL 2500000 /* 2.5 sec. */ #define SK_RLMT_SEG_TO_VAL 900000000 /* 15 min. */ /* Assume tick counter increment is 1 - may be set OS-dependent. */ #ifndef SK_TICK_INCR #define SK_TICK_INCR SK_CONSTU64(1) #endif /* !defined(SK_TICK_INCR) */ /* * Amount that a time stamp must be later to be recognized as "substantially * later". This is about 1/128 sec, but above 1 tick counter increment. */ #define SK_RLMT_BC_DELTA (1 + ((SK_TICKS_PER_SEC >> 7) > SK_TICK_INCR ? \ (SK_TICKS_PER_SEC >> 7) : SK_TICK_INCR)) /* ----- Private RLMT defaults ----- */ #define SK_RLMT_DEF_PREF_PORT 0 /* "Lower" port. */ #define SK_RLMT_DEF_MODE SK_RLMT_CHECK_LINK /* Default RLMT Mode. */ /* ----- Private RLMT checking states ----- */ #define SK_RLMT_RCS_SEG 1 /* RLMT Check State: check seg. */ #define SK_RLMT_RCS_START_SEG 2 /* RLMT Check State: start check seg. */ #define SK_RLMT_RCS_SEND_SEG 4 /* RLMT Check State: send BPDU packet */ #define SK_RLMT_RCS_REPORT_SEG 8 /* RLMT Check State: report seg. */ /* ----- Private PORT checking states ----- */ #define SK_RLMT_PCS_TX 1 /* Port Check State: check tx. */ #define SK_RLMT_PCS_RX 2 /* Port Check State: check rx. */ /* ----- Private PORT events ----- */ /* Note: Update simulation when changing these. */ #define SK_RLMT_PORTSTART_TIM 1100 /* Port start timeout. */ #define SK_RLMT_PORTUP_TIM 1101 /* Port can now go up. */ #define SK_RLMT_PORTDOWN_RX_TIM 1102 /* Port did not receive once ... */ #define SK_RLMT_PORTDOWN 1103 /* Port went down. */ #define SK_RLMT_PORTDOWN_TX_TIM 1104 /* Partner did not receive ... */ /* ----- Private RLMT events ----- */ /* Note: Update simulation when changing these. */ #define SK_RLMT_TIM 2100 /* RLMT timeout. */ #define SK_RLMT_SEG_TIM 2101 /* RLMT segmentation check timeout. */ #define TO_SHORTEN(tim) ((tim) / 2) /* Error numbers and messages. */ #define SKERR_RLMT_E001 (SK_ERRBASE_RLMT + 0) #define SKERR_RLMT_E001_MSG "No Packet." #define SKERR_RLMT_E002 (SKERR_RLMT_E001 + 1) #define SKERR_RLMT_E002_MSG "Short Packet." #define SKERR_RLMT_E003 (SKERR_RLMT_E002 + 1) #define SKERR_RLMT_E003_MSG "Unknown RLMT event." #define SKERR_RLMT_E004 (SKERR_RLMT_E003 + 1) #define SKERR_RLMT_E004_MSG "PortsUp incorrect." #define SKERR_RLMT_E005 (SKERR_RLMT_E004 + 1) #define SKERR_RLMT_E005_MSG \ "Net seems to be segmented (different root bridges are reported on the ports)." #define SKERR_RLMT_E006 (SKERR_RLMT_E005 + 1) #define SKERR_RLMT_E006_MSG "Duplicate MAC Address detected." #define SKERR_RLMT_E007 (SKERR_RLMT_E006 + 1) #define SKERR_RLMT_E007_MSG "LinksUp incorrect." #define SKERR_RLMT_E008 (SKERR_RLMT_E007 + 1) #define SKERR_RLMT_E008_MSG "Port not started but link came up." #define SKERR_RLMT_E009 (SKERR_RLMT_E008 + 1) #define SKERR_RLMT_E009_MSG "Corrected illegal setting of Preferred Port." #define SKERR_RLMT_E010 (SKERR_RLMT_E009 + 1) #define SKERR_RLMT_E010_MSG "Ignored illegal Preferred Port." /* LLC field values. */ #define LLC_COMMAND_RESPONSE_BIT 1 #define LLC_TEST_COMMAND 0xE3 #define LLC_UI 0x03 /* RLMT Packet fields. */ #define SK_RLMT_DSAP 0 #define SK_RLMT_SSAP 0 #define SK_RLMT_CTRL (LLC_TEST_COMMAND) #define SK_RLMT_INDICATOR0 0x53 /* S */ #define SK_RLMT_INDICATOR1 0x4B /* K */ #define SK_RLMT_INDICATOR2 0x2D /* - */ #define SK_RLMT_INDICATOR3 0x52 /* R */ #define SK_RLMT_INDICATOR4 0x4C /* L */ #define SK_RLMT_INDICATOR5 0x4D /* M */ #define SK_RLMT_INDICATOR6 0x54 /* T */ #define SK_RLMT_PACKET_VERSION 0 /* RLMT SPT Flag values. */ #define SK_RLMT_SPT_FLAG_CHANGE 0x01 #define SK_RLMT_SPT_FLAG_CHANGE_ACK 0x80 /* RLMT SPT Packet fields. */ #define SK_RLMT_SPT_DSAP 0x42 #define SK_RLMT_SPT_SSAP 0x42 #define SK_RLMT_SPT_CTRL (LLC_UI) #define SK_RLMT_SPT_PROTOCOL_ID0 0x00 #define SK_RLMT_SPT_PROTOCOL_ID1 0x00 #define SK_RLMT_SPT_PROTOCOL_VERSION_ID 0x00 #define SK_RLMT_SPT_BPDU_TYPE 0x00 #define SK_RLMT_SPT_FLAGS 0x00 /* ?? */ #define SK_RLMT_SPT_ROOT_ID0 0xFF /* Lowest possible priority. */ #define SK_RLMT_SPT_ROOT_ID1 0xFF /* Lowest possible priority. */ /* Remaining 6 bytes will be the current port address. */ #define SK_RLMT_SPT_ROOT_PATH_COST0 0x00 #define SK_RLMT_SPT_ROOT_PATH_COST1 0x00 #define SK_RLMT_SPT_ROOT_PATH_COST2 0x00 #define SK_RLMT_SPT_ROOT_PATH_COST3 0x00 #define SK_RLMT_SPT_BRIDGE_ID0 0xFF /* Lowest possible priority. */ #define SK_RLMT_SPT_BRIDGE_ID1 0xFF /* Lowest possible priority. */ /* Remaining 6 bytes will be the current port address. */ #define SK_RLMT_SPT_PORT_ID0 0xFF /* Lowest possible priority. */ #define SK_RLMT_SPT_PORT_ID1 0xFF /* Lowest possible priority. */ #define SK_RLMT_SPT_MSG_AGE0 0x00 #define SK_RLMT_SPT_MSG_AGE1 0x00 #define SK_RLMT_SPT_MAX_AGE0 0x00 #define SK_RLMT_SPT_MAX_AGE1 0xFF #define SK_RLMT_SPT_HELLO_TIME0 0x00 #define SK_RLMT_SPT_HELLO_TIME1 0xFF #define SK_RLMT_SPT_FWD_DELAY0 0x00 #define SK_RLMT_SPT_FWD_DELAY1 0x40 /* Size defines. */ #define SK_RLMT_MIN_PACKET_SIZE 34 #define SK_RLMT_MAX_PACKET_SIZE (SK_RLMT_MAX_TX_BUF_SIZE) #define SK_PACKET_DATA_LEN (SK_RLMT_MAX_PACKET_SIZE - \ SK_RLMT_MIN_PACKET_SIZE) /* ----- RLMT packet types ----- */ #define SK_PACKET_ANNOUNCE 1 /* Port announcement. */ #define SK_PACKET_ALIVE 2 /* Alive packet to port. */ #define SK_PACKET_ADDR_CHANGED 3 /* Port address changed. */ #define SK_PACKET_CHECK_TX 4 /* Check your tx line. */ #ifdef SK_LITTLE_ENDIAN #define SK_U16_TO_NETWORK_ORDER(Val,Addr) { \ SK_U8 *_Addr = (SK_U8*)(Addr); \ SK_U16 _Val = (SK_U16)(Val); \ *_Addr++ = (SK_U8)(_Val >> 8); \ *_Addr = (SK_U8)(_Val & 0xFF); \ } #endif /* SK_LITTLE_ENDIAN */ #ifdef SK_BIG_ENDIAN #define SK_U16_TO_NETWORK_ORDER(Val,Addr) (*(SK_U16*)(Addr) = (SK_U16)(Val)) #endif /* SK_BIG_ENDIAN */ #define AUTONEG_FAILED SK_FALSE #define AUTONEG_SUCCESS SK_TRUE /* typedefs *******************************************************************/ /* RLMT packet. Length: SK_RLMT_MAX_PACKET_SIZE (60) bytes. */ typedef struct s_RlmtPacket { SK_U8 DstAddr[SK_MAC_ADDR_LEN]; SK_U8 SrcAddr[SK_MAC_ADDR_LEN]; SK_U8 TypeLen[2]; SK_U8 DSap; SK_U8 SSap; SK_U8 Ctrl; SK_U8 Indicator[7]; SK_U8 RlmtPacketType[2]; SK_U8 Align1[2]; SK_U8 Random[4]; /* Random value of requesting(!) station. */ SK_U8 RlmtPacketVersion[2]; /* RLMT Packet version. */ SK_U8 Data[SK_PACKET_DATA_LEN]; } SK_RLMT_PACKET; typedef struct s_SpTreeRlmtPacket { SK_U8 DstAddr[SK_MAC_ADDR_LEN]; SK_U8 SrcAddr[SK_MAC_ADDR_LEN]; SK_U8 TypeLen[2]; SK_U8 DSap; SK_U8 SSap; SK_U8 Ctrl; SK_U8 ProtocolId[2]; SK_U8 ProtocolVersionId; SK_U8 BpduType; SK_U8 Flags; SK_U8 RootId[8]; SK_U8 RootPathCost[4]; SK_U8 BridgeId[8]; SK_U8 PortId[2]; SK_U8 MessageAge[2]; SK_U8 MaxAge[2]; SK_U8 HelloTime[2]; SK_U8 ForwardDelay[2]; } SK_SPTREE_PACKET; /* global variables ***********************************************************/ SK_MAC_ADDR SkRlmtMcAddr = {{0x01, 0x00, 0x5A, 0x52, 0x4C, 0x4D}}; SK_MAC_ADDR BridgeMcAddr = {{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}}; /* local variables ************************************************************/ /* None. */ /* functions ******************************************************************/ RLMT_STATIC void SkRlmtCheckSwitch( SK_AC *pAC, SK_IOC IoC, SK_U32 NetIdx); RLMT_STATIC void SkRlmtCheckSeg( SK_AC *pAC, SK_IOC IoC, SK_U32 NetIdx); RLMT_STATIC void SkRlmtEvtSetNets( SK_AC *pAC, SK_IOC IoC, SK_EVPARA Para); /****************************************************************************** * * SkRlmtInit - initialize data, set state to init * * Description: * * SK_INIT_DATA * ============ * * This routine initializes all RLMT-related variables to a known state. * The initial state is SK_RLMT_RS_INIT. * All ports are initialized to SK_RLMT_PS_INIT. * * * SK_INIT_IO * ========== * * Nothing. * * * SK_INIT_RUN * =========== * * Determine the adapter's random value. * Set the hw registers, the "logical MAC address", the * RLMT multicast address, and eventually the BPDU multicast address. * * Context: * init, pageable * * Returns: * Nothing. */ void SkRlmtInit( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ int Level) /* Initialization Level */ { SK_U32 i, j; SK_U64 Random; SK_EVPARA Para; SK_MAC_ADDR VirtualMacAddress; SK_MAC_ADDR PhysicalAMacAddress; SK_BOOL VirtualMacAddressSet; SK_BOOL PhysicalAMacAddressSet; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT, ("RLMT Init level %d.\n", Level)) switch (Level) { case SK_INIT_DATA: /* Initialize data structures. */ SK_MEMSET((char *)&pAC->Rlmt, 0, sizeof(SK_RLMT)); for (i = 0; i < SK_MAX_MACS; i++) { pAC->Rlmt.Port[i].PortState = SK_RLMT_PS_INIT; pAC->Rlmt.Port[i].LinkDown = SK_TRUE; pAC->Rlmt.Port[i].PortDown = SK_TRUE; pAC->Rlmt.Port[i].PortStarted = SK_FALSE; pAC->Rlmt.Port[i].PortNoRx = SK_FALSE; pAC->Rlmt.Port[i].RootIdSet = SK_FALSE; pAC->Rlmt.Port[i].PortNumber = i; pAC->Rlmt.Port[i].Net = &pAC->Rlmt.Net[0]; pAC->Rlmt.Port[i].AddrPort = &pAC->Addr.Port[i]; } pAC->Rlmt.NumNets = 1; for (i = 0; i < SK_MAX_NETS; i++) { pAC->Rlmt.Net[i].RlmtState = SK_RLMT_RS_INIT; pAC->Rlmt.Net[i].RootIdSet = SK_FALSE; pAC->Rlmt.Net[i].PrefPort = SK_RLMT_DEF_PREF_PORT; pAC->Rlmt.Net[i].Preference = 0xFFFFFFFF; /* Automatic. */ /* Just assuming. */ pAC->Rlmt.Net[i].ActivePort = pAC->Rlmt.Net[i].PrefPort; pAC->Rlmt.Net[i].RlmtMode = SK_RLMT_DEF_MODE; pAC->Rlmt.Net[i].TimeoutValue = SK_RLMT_DEF_TO_VAL; pAC->Rlmt.Net[i].NetNumber = i; } pAC->Rlmt.Net[0].Port[0] = &pAC->Rlmt.Port[0]; pAC->Rlmt.Net[0].Port[1] = &pAC->Rlmt.Port[1]; #if SK_MAX_NETS > 1 pAC->Rlmt.Net[1].Port[0] = &pAC->Rlmt.Port[1]; #endif /* SK_MAX_NETS > 1 */ break; case SK_INIT_IO: /* GIMacsFound first available here. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT, ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound)) pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound; /* Initialize HW registers? */ if (pAC->GIni.GIMacsFound == 1) { Para.Para32[0] = SK_RLMT_MODE_CLS; Para.Para32[1] = 0; (void)SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, Para); } break; case SK_INIT_RUN: /* Ensure RLMT is set to one net. */ if (pAC->Rlmt.NumNets > 1) { Para.Para32[0] = 1; Para.Para32[1] = -1; SkRlmtEvtSetNets(pAC, IoC, Para); } for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { Random = SkOsGetTime(pAC); *(SK_U32*)&pAC->Rlmt.Port[i].Random = *(SK_U32*)&Random; for (j = 0; j < 4; j++) { pAC->Rlmt.Port[i].Random[j] ^= pAC->Rlmt.Port[i].AddrPort-> CurrentMacAddress.a[SK_MAC_ADDR_LEN - 1 - j]; } (void)SkAddrMcClear(pAC, IoC, i, SK_ADDR_PERMANENT | SK_MC_SW_ONLY); /* Add RLMT MC address. */ (void)SkAddrMcAdd(pAC, IoC, i, &SkRlmtMcAddr, SK_ADDR_PERMANENT); if (pAC->Rlmt.Net[0].RlmtMode & SK_RLMT_CHECK_SEG) { /* Add BPDU MC address. */ (void)SkAddrMcAdd(pAC, IoC, i, &BridgeMcAddr, SK_ADDR_PERMANENT); } (void)SkAddrMcUpdate(pAC, IoC, i); } VirtualMacAddressSet = SK_FALSE; /* Read virtual MAC address from Control Register File. */ for (j = 0; j < SK_MAC_ADDR_LEN; j++) { SK_IN8(IoC, B2_MAC_1 + j, &VirtualMacAddress.a[j]); VirtualMacAddressSet |= VirtualMacAddress.a[j]; } PhysicalAMacAddressSet = SK_FALSE; /* Read physical MAC address for MAC A from Control Register File. */ for (j = 0; j < SK_MAC_ADDR_LEN; j++) { SK_IN8(IoC, B2_MAC_2 + j, &PhysicalAMacAddress.a[j]); PhysicalAMacAddressSet |= PhysicalAMacAddress.a[j]; } /* check if the two mac addresses contain reasonable values */ if (!VirtualMacAddressSet || !PhysicalAMacAddressSet) { pAC->Rlmt.RlmtOff = SK_TRUE; } /* if the two mac addresses are equal switch off the RLMT_PRE_LOOKAHEAD and the RLMT_LOOKAHEAD macros */ else if (SK_ADDR_EQUAL(PhysicalAMacAddress.a, VirtualMacAddress.a)) { pAC->Rlmt.RlmtOff = SK_TRUE; } else { pAC->Rlmt.RlmtOff = SK_FALSE; } break; default: /* error */ break; } return; } /* SkRlmtInit */ /****************************************************************************** * * SkRlmtBuildCheckChain - build the check chain * * Description: * This routine builds the local check chain: * - Each port that is up checks the next port. * - The last port that is up checks the first port that is up. * * Notes: * - Currently only local ports are considered when building the chain. * - Currently the SuspectState is just reset; * it would be better to save it ... * * Context: * runtime, pageable? * * Returns: * Nothing */ RLMT_STATIC void SkRlmtBuildCheckChain( SK_AC *pAC, /* Adapter Context */ SK_U32 NetIdx) /* Net Number */ { SK_U32 i; SK_U32 NumMacsUp; SK_RLMT_PORT * FirstMacUp; SK_RLMT_PORT * PrevMacUp; FirstMacUp = NULL; PrevMacUp = NULL; if (!(pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_CHECK_LOC_LINK)) { for (i = 0; i < pAC->Rlmt.Net[i].NumPorts; i++) { pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0; } return; /* Done. */ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SkRlmtBuildCheckChain.\n")) NumMacsUp = 0; for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) { pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked = 0; pAC->Rlmt.Net[NetIdx].Port[i]->PortsSuspect = 0; pAC->Rlmt.Net[NetIdx].Port[i]->CheckingState &= ~(SK_RLMT_PCS_RX | SK_RLMT_PCS_TX); /* * If more than two links are detected we should consider * checking at least two other ports: * 1. the next port that is not LinkDown and * 2. the next port that is not PortDown. */ if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) { if (NumMacsUp == 0) { FirstMacUp = pAC->Rlmt.Net[NetIdx].Port[i]; } else { PrevMacUp->PortCheck[ pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked].CheckAddr = pAC->Rlmt.Net[NetIdx].Port[i]->AddrPort->CurrentMacAddress; PrevMacUp->PortCheck[ PrevMacUp->PortsChecked].SuspectTx = SK_FALSE; PrevMacUp->PortsChecked++; } PrevMacUp = pAC->Rlmt.Net[NetIdx].Port[i]; NumMacsUp++; } } if (NumMacsUp > 1) { PrevMacUp->PortCheck[PrevMacUp->PortsChecked].CheckAddr = FirstMacUp->AddrPort->CurrentMacAddress; PrevMacUp->PortCheck[PrevMacUp->PortsChecked].SuspectTx = SK_FALSE; PrevMacUp->PortsChecked++; } #ifdef DEBUG for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Port %d checks %d other ports: %2X.\n", i, pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked, pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5])) } #endif /* DEBUG */ return; } /* SkRlmtBuildCheckChain */ /****************************************************************************** * * SkRlmtBuildPacket - build an RLMT packet * * Description: * This routine sets up an RLMT packet. * * Context: * runtime, pageable? * * Returns: * NULL or pointer to RLMT mbuf */ RLMT_STATIC SK_MBUF *SkRlmtBuildPacket( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 PortNumber, /* Sending port */ SK_U16 PacketType, /* RLMT packet type */ SK_MAC_ADDR *SrcAddr, /* Source address */ SK_MAC_ADDR *DestAddr) /* Destination address */ { int i; SK_U16 Length; SK_MBUF *pMb; SK_RLMT_PACKET *pPacket; #ifdef DEBUG SK_U8 CheckSrc = 0; SK_U8 CheckDest = 0; for (i = 0; i < SK_MAC_ADDR_LEN; ++i) { CheckSrc |= SrcAddr->a[i]; CheckDest |= DestAddr->a[i]; } if ((CheckSrc == 0) || (CheckDest == 0)) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR, ("SkRlmtBuildPacket: Invalid %s%saddr.\n", (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : ""))) } #endif if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) { pPacket = (SK_RLMT_PACKET*)pMb->pData; for (i = 0; i < SK_MAC_ADDR_LEN; i++) { pPacket->DstAddr[i] = DestAddr->a[i]; pPacket->SrcAddr[i] = SrcAddr->a[i]; } pPacket->DSap = SK_RLMT_DSAP; pPacket->SSap = SK_RLMT_SSAP; pPacket->Ctrl = SK_RLMT_CTRL; pPacket->Indicator[0] = SK_RLMT_INDICATOR0; pPacket->Indicator[1] = SK_RLMT_INDICATOR1; pPacket->Indicator[2] = SK_RLMT_INDICATOR2; pPacket->Indicator[3] = SK_RLMT_INDICATOR3; pPacket->Indicator[4] = SK_RLMT_INDICATOR4; pPacket->Indicator[5] = SK_RLMT_INDICATOR5; pPacket->Indicator[6] = SK_RLMT_INDICATOR6; SK_U16_TO_NETWORK_ORDER(PacketType, &pPacket->RlmtPacketType[0]); for (i = 0; i < 4; i++) { pPacket->Random[i] = pAC->Rlmt.Port[PortNumber].Random[i]; } SK_U16_TO_NETWORK_ORDER( SK_RLMT_PACKET_VERSION, &pPacket->RlmtPacketVersion[0]); for (i = 0; i < SK_PACKET_DATA_LEN; i++) { pPacket->Data[i] = 0x00; } Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */ pMb->Length = Length; pMb->PortIdx = PortNumber; Length -= 14; SK_U16_TO_NETWORK_ORDER(Length, &pPacket->TypeLen[0]); if (PacketType == SK_PACKET_ALIVE) { pAC->Rlmt.Port[PortNumber].TxHelloCts++; } } return (pMb); } /* SkRlmtBuildPacket */ /****************************************************************************** * * SkRlmtBuildSpanningTreePacket - build spanning tree check packet * * Description: * This routine sets up a BPDU packet for spanning tree check. * * Context: * runtime, pageable? * * Returns: * NULL or pointer to RLMT mbuf */ RLMT_STATIC SK_MBUF *SkRlmtBuildSpanningTreePacket( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 PortNumber) /* Sending port */ { unsigned i; SK_U16 Length; SK_MBUF *pMb; SK_SPTREE_PACKET *pSPacket; if ((pMb = SkDrvAllocRlmtMbuf(pAC, IoC, SK_RLMT_MAX_PACKET_SIZE)) != NULL) { pSPacket = (SK_SPTREE_PACKET*)pMb->pData; for (i = 0; i < SK_MAC_ADDR_LEN; i++) { pSPacket->DstAddr[i] = BridgeMcAddr.a[i]; pSPacket->SrcAddr[i] = pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i]; } pSPacket->DSap = SK_RLMT_SPT_DSAP; pSPacket->SSap = SK_RLMT_SPT_SSAP; pSPacket->Ctrl = SK_RLMT_SPT_CTRL; pSPacket->ProtocolId[0] = SK_RLMT_SPT_PROTOCOL_ID0; pSPacket->ProtocolId[1] = SK_RLMT_SPT_PROTOCOL_ID1; pSPacket->ProtocolVersionId = SK_RLMT_SPT_PROTOCOL_VERSION_ID; pSPacket->BpduType = SK_RLMT_SPT_BPDU_TYPE; pSPacket->Flags = SK_RLMT_SPT_FLAGS; pSPacket->RootId[0] = SK_RLMT_SPT_ROOT_ID0; pSPacket->RootId[1] = SK_RLMT_SPT_ROOT_ID1; pSPacket->RootPathCost[0] = SK_RLMT_SPT_ROOT_PATH_COST0; pSPacket->RootPathCost[1] = SK_RLMT_SPT_ROOT_PATH_COST1; pSPacket->RootPathCost[2] = SK_RLMT_SPT_ROOT_PATH_COST2; pSPacket->RootPathCost[3] = SK_RLMT_SPT_ROOT_PATH_COST3; pSPacket->BridgeId[0] = SK_RLMT_SPT_BRIDGE_ID0; pSPacket->BridgeId[1] = SK_RLMT_SPT_BRIDGE_ID1; /* * Use logical MAC address as bridge ID and filter these packets * on receive. */ for (i = 0; i < SK_MAC_ADDR_LEN; i++) { pSPacket->BridgeId[i + 2] = pSPacket->RootId[i + 2] = pAC->Addr.Net[pAC->Rlmt.Port[PortNumber].Net->NetNumber]. CurrentMacAddress.a[i]; } pSPacket->PortId[0] = SK_RLMT_SPT_PORT_ID0; pSPacket->PortId[1] = SK_RLMT_SPT_PORT_ID1; pSPacket->MessageAge[0] = SK_RLMT_SPT_MSG_AGE0; pSPacket->MessageAge[1] = SK_RLMT_SPT_MSG_AGE1; pSPacket->MaxAge[0] = SK_RLMT_SPT_MAX_AGE0; pSPacket->MaxAge[1] = SK_RLMT_SPT_MAX_AGE1; pSPacket->HelloTime[0] = SK_RLMT_SPT_HELLO_TIME0; pSPacket->HelloTime[1] = SK_RLMT_SPT_HELLO_TIME1; pSPacket->ForwardDelay[0] = SK_RLMT_SPT_FWD_DELAY0; pSPacket->ForwardDelay[1] = SK_RLMT_SPT_FWD_DELAY1; Length = SK_RLMT_MAX_PACKET_SIZE; /* Or smaller. */ pMb->Length = Length; pMb->PortIdx = PortNumber; Length -= 14; SK_U16_TO_NETWORK_ORDER(Length, &pSPacket->TypeLen[0]); pAC->Rlmt.Port[PortNumber].TxSpHelloReqCts++; } return (pMb); } /* SkRlmtBuildSpanningTreePacket */ /****************************************************************************** * * SkRlmtSend - build and send check packets * * Description: * Depending on the RLMT state and the checking state, several packets * are sent through the indicated port. * * Context: * runtime, pageable? * * Returns: * Nothing. */ RLMT_STATIC void SkRlmtSend( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 PortNumber) /* Sending port */ { unsigned j; SK_EVPARA Para; SK_RLMT_PORT *pRPort; pRPort = &pAC->Rlmt.Port[PortNumber]; if (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) { if (pRPort->CheckingState & (SK_RLMT_PCS_TX | SK_RLMT_PCS_RX)) { /* Port is suspicious. Send the RLMT packet to the RLMT mc addr. */ if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress, &SkRlmtMcAddr)) != NULL) { SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); } } else { /* * Send a directed RLMT packet to all ports that are * checked by the indicated port. */ for (j = 0; j < pRPort->PortsChecked; j++) { if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress, &pRPort->PortCheck[j].CheckAddr)) != NULL) { SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); } } } } if ((pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) && (pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEND_SEG)) { /* * Send a BPDU packet to make a connected switch tell us * the correct root bridge. */ if ((Para.pParaPtr = SkRlmtBuildSpanningTreePacket(pAC, IoC, PortNumber)) != NULL) { pAC->Rlmt.Port[PortNumber].Net->CheckingState &= ~SK_RLMT_RCS_SEND_SEG; pRPort->RootIdSet = SK_FALSE; SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX, ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber)) } } return; } /* SkRlmtSend */ /****************************************************************************** * * SkRlmtPortReceives - check if port is (going) down and bring it up * * Description: * This routine checks if a port who received a non-BPDU packet * needs to go up or needs to be stopped going down. * * Context: * runtime, pageable? * * Returns: * Nothing. */ RLMT_STATIC void SkRlmtPortReceives( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 PortNumber) /* Port to check */ { SK_RLMT_PORT *pRPort; SK_EVPARA Para; pRPort = &pAC->Rlmt.Port[PortNumber]; pRPort->PortNoRx = SK_FALSE; if ((pRPort->PortState == SK_RLMT_PS_DOWN) && !(pRPort->CheckingState & SK_RLMT_PCS_TX)) { /* * Port is marked down (rx), but received a non-BPDU packet. * Bring it up. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: Received on PortDown.\n")) pRPort->PortState = SK_RLMT_PS_GOING_UP; pRPort->GuTimeStamp = SkOsGetTime(pAC); Para.Para32[0] = PortNumber; Para.Para32[1] = (SK_U32)-1; SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para); pRPort->CheckingState &= ~SK_RLMT_PCS_RX; /* pAC->Rlmt.CheckSwitch = SK_TRUE; */ SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); } /* PortDown && !SuspectTx */ else if (pRPort->CheckingState & SK_RLMT_PCS_RX) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: Stop bringing port down.\n")) SkTimerStop(pAC, IoC, &pRPort->DownRxTimer); pRPort->CheckingState &= ~SK_RLMT_PCS_RX; /* pAC->Rlmt.CheckSwitch = SK_TRUE; */ SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); } /* PortGoingDown */ return; } /* SkRlmtPortReceives */ /****************************************************************************** * * SkRlmtPacketReceive - receive a packet for closer examination * * Description: * This routine examines a packet more closely than SK_RLMT_LOOKAHEAD. * * Context: * runtime, pageable? * * Returns: * Nothing. */ RLMT_STATIC void SkRlmtPacketReceive( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_MBUF *pMb) /* Received packet */ { #ifdef xDEBUG extern void DumpData(char *p, int size); #endif /* DEBUG */ int i; unsigned j; SK_U16 PacketType; SK_U32 PortNumber; SK_ADDR_PORT *pAPort; SK_RLMT_PORT *pRPort; SK_RLMT_PACKET *pRPacket; SK_SPTREE_PACKET *pSPacket; SK_EVPARA Para; PortNumber = pMb->PortIdx; pAPort = &pAC->Addr.Port[PortNumber]; pRPort = &pAC->Rlmt.Port[PortNumber]; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber)) pRPacket = (SK_RLMT_PACKET*)pMb->pData; pSPacket = (SK_SPTREE_PACKET*)pRPacket; #ifdef xDEBUG DumpData((char *)pRPacket, 32); #endif /* DEBUG */ if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) != 0) { SkRlmtPortReceives(pAC, IoC, PortNumber); } /* Check destination address. */ if (!SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->DstAddr) && !SK_ADDR_EQUAL(SkRlmtMcAddr.a, pRPacket->DstAddr) && !SK_ADDR_EQUAL(BridgeMcAddr.a, pRPacket->DstAddr)) { /* Not sent to current MAC or registered MC address => Trash it. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: Not for me.\n")) SkDrvFreeRlmtMbuf(pAC, IoC, pMb); return; } else if (SK_ADDR_EQUAL(pAPort->CurrentMacAddress.a, pRPacket->SrcAddr)) { /* * Was sent by same port (may happen during port switching * or in case of duplicate MAC addresses). */ /* * Check for duplicate address here: * If Packet.Random != My.Random => DupAddr. */ for (i = 3; i >= 0; i--) { if (pRPort->Random[i] != pRPacket->Random[i]) { break; } } /* * CAUTION: Do not check for duplicate MAC address in RLMT Alive Reply * packets (they have the LLC_COMMAND_RESPONSE_BIT set in * pRPacket->SSap). */ if (i >= 0 && pRPacket->DSap == SK_RLMT_DSAP && pRPacket->Ctrl == SK_RLMT_CTRL && pRPacket->SSap == SK_RLMT_SSAP && pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 && pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 && pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 && pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 && pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 && pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 && pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: Duplicate MAC Address.\n")) /* Error Log entry. */ SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG); } else { /* Simply trash it. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: Sent by me.\n")) } SkDrvFreeRlmtMbuf(pAC, IoC, pMb); return; } /* Check SuspectTx entries. */ if (pRPort->PortsSuspect > 0) { for (j = 0; j < pRPort->PortsChecked; j++) { if (pRPort->PortCheck[j].SuspectTx && SK_ADDR_EQUAL( pRPacket->SrcAddr, pRPort->PortCheck[j].CheckAddr.a)) { pRPort->PortCheck[j].SuspectTx = SK_FALSE; pRPort->PortsSuspect--; break; } } } /* Determine type of packet. */ if (pRPacket->DSap == SK_RLMT_DSAP && pRPacket->Ctrl == SK_RLMT_CTRL && (pRPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SSAP && pRPacket->Indicator[0] == SK_RLMT_INDICATOR0 && pRPacket->Indicator[1] == SK_RLMT_INDICATOR1 && pRPacket->Indicator[2] == SK_RLMT_INDICATOR2 && pRPacket->Indicator[3] == SK_RLMT_INDICATOR3 && pRPacket->Indicator[4] == SK_RLMT_INDICATOR4 && pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 && pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) { /* It's an RLMT packet. */ PacketType = (SK_U16)((pRPacket->RlmtPacketType[0] << 8) | pRPacket->RlmtPacketType[1]); switch (PacketType) { case SK_PACKET_ANNOUNCE: /* Not yet used. */ #if 0 /* Build the check chain. */ SkRlmtBuildCheckChain(pAC); #endif /* 0 */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: Announce.\n")) SkDrvFreeRlmtMbuf(pAC, IoC, pMb); break; case SK_PACKET_ALIVE: if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: Alive Reply.\n")) if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) || SK_ADDR_EQUAL( pRPacket->DstAddr, pAPort->CurrentMacAddress.a)) { /* Obviously we could send something. */ if (pRPort->CheckingState & SK_RLMT_PCS_TX) { pRPort->CheckingState &= ~SK_RLMT_PCS_TX; SkTimerStop(pAC, IoC, &pRPort->DownTxTimer); } if ((pRPort->PortState == SK_RLMT_PS_DOWN) && !(pRPort->CheckingState & SK_RLMT_PCS_RX)) { pRPort->PortState = SK_RLMT_PS_GOING_UP; pRPort->GuTimeStamp = SkOsGetTime(pAC); SkTimerStop(pAC, IoC, &pRPort->DownTxTimer); Para.Para32[0] = PortNumber; Para.Para32[1] = (SK_U32)-1; SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para); } } /* Mark sending port as alive? */ SkDrvFreeRlmtMbuf(pAC, IoC, pMb); } else { /* Alive Request Packet. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: Alive Request.\n")) pRPort->RxHelloCts++; /* Answer. */ for (i = 0; i < SK_MAC_ADDR_LEN; i++) { pRPacket->DstAddr[i] = pRPacket->SrcAddr[i]; pRPacket->SrcAddr[i] = pAC->Addr.Port[PortNumber].CurrentMacAddress.a[i]; } pRPacket->SSap |= LLC_COMMAND_RESPONSE_BIT; Para.pParaPtr = pMb; SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); } break; case SK_PACKET_CHECK_TX: SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: Check your tx line.\n")) /* A port checking us requests us to check our tx line. */ pRPort->CheckingState |= SK_RLMT_PCS_TX; /* Start PortDownTx timer. */ Para.Para32[0] = PortNumber; Para.Para32[1] = (SK_U32)-1; SkTimerStart(pAC, IoC, &pRPort->DownTxTimer, SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTDOWN_TX_TIM, Para); SkDrvFreeRlmtMbuf(pAC, IoC, pMb); if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_ALIVE, &pAC->Addr.Port[PortNumber].CurrentMacAddress, &SkRlmtMcAddr)) != NULL) { SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); } break; case SK_PACKET_ADDR_CHANGED: SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: Address Change.\n")) /* Build the check chain. */ SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber); SkDrvFreeRlmtMbuf(pAC, IoC, pMb); break; default: SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: Unknown RLMT packet.\n")) /* RA;:;: ??? */ SkDrvFreeRlmtMbuf(pAC, IoC, pMb); } } else if (pSPacket->DSap == SK_RLMT_SPT_DSAP && pSPacket->Ctrl == SK_RLMT_SPT_CTRL && (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: BPDU Packet.\n")) /* Spanning Tree packet. */ pRPort->RxSpHelloCts++; if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pAC->Addr.Net[pAC->Rlmt. Port[PortNumber].Net->NetNumber].CurrentMacAddress.a[0])) { /* * Check segmentation if a new root bridge is set and * the segmentation check is not currently running. */ if (!SK_ADDR_EQUAL(&pSPacket->RootId[2], &pRPort->Root.Id[2]) && (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) && (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) != 0 && (pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG) == 0) { pAC->Rlmt.Port[PortNumber].Net->CheckingState |= SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG; } /* Store tree view of this port. */ for (i = 0; i < 8; i++) { pRPort->Root.Id[i] = pSPacket->RootId[i]; } pRPort->RootIdSet = SK_TRUE; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP, ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", PortNumber, pRPort->Root.Id[0], pRPort->Root.Id[1], pRPort->Root.Id[2], pRPort->Root.Id[3], pRPort->Root.Id[4], pRPort->Root.Id[5], pRPort->Root.Id[6], pRPort->Root.Id[7])) } SkDrvFreeRlmtMbuf(pAC, IoC, pMb); if ((pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_REPORT_SEG) != 0) { SkRlmtCheckSeg(pAC, IoC, pAC->Rlmt.Port[PortNumber].Net->NetNumber); } } else { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, ("SkRlmtPacketReceive: Unknown Packet Type.\n")) /* Unknown packet. */ SkDrvFreeRlmtMbuf(pAC, IoC, pMb); } return; } /* SkRlmtPacketReceive */ /****************************************************************************** * * SkRlmtCheckPort - check if a port works * * Description: * This routine checks if a port whose link is up received something * and if it seems to transmit successfully. * * # PortState: PsInit, PsLinkDown, PsDown, PsGoingUp, PsUp * # PortCheckingState (Bitfield): ChkTx, ChkRx, ChkSeg * # RlmtCheckingState (Bitfield): ChkSeg, StartChkSeg, ReportSeg * * if (Rx - RxBpdu == 0) { # No rx. * if (state == PsUp) { * PortCheckingState |= ChkRx * } * if (ModeCheckSeg && (Timeout == * TO_SHORTEN(RLMT_DEFAULT_TIMEOUT))) { * RlmtCheckingState |= ChkSeg) * PortCheckingState |= ChkSeg * } * NewTimeout = TO_SHORTEN(Timeout) * if (NewTimeout < RLMT_MIN_TIMEOUT) { * NewTimeout = RLMT_MIN_TIMEOUT * PortState = PsDown * ... * } * } * else { # something was received * # Set counter to 0 at LinkDown? * # No - rx may be reported after LinkDown ??? * PortCheckingState &= ~ChkRx * NewTimeout = RLMT_DEFAULT_TIMEOUT * if (RxAck == 0) { * possible reasons: * is my tx line bad? -- * send RLMT multicast and report * back internally? (only possible * between ports on same adapter) * } * if (RxChk == 0) { * possible reasons: * - tx line of port set to check me * maybe bad * - no other port/adapter available or set * to check me * - adapter checking me has a longer * timeout * ??? anything that can be done here? * } * } * * Context: * runtime, pageable? * * Returns: * New timeout value. */ RLMT_STATIC SK_U32 SkRlmtCheckPort( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 PortNumber) /* Port to check */ { unsigned i; SK_U32 NewTimeout; SK_RLMT_PORT *pRPort; SK_EVPARA Para; pRPort = &pAC->Rlmt.Port[PortNumber]; if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n", PortNumber, pRPort->PacketsPerTimeSlot)) /* * Check segmentation if there was no receive at least twice * in a row (PortNoRx is already set) and the segmentation * check is not currently running. */ if (pRPort->PortNoRx && (pAC->Rlmt.Port[PortNumber].Net->LinksUp > 1) && (pAC->Rlmt.Port[PortNumber].Net->RlmtMode & SK_RLMT_CHECK_SEG) && !(pAC->Rlmt.Port[PortNumber].Net->CheckingState & SK_RLMT_RCS_SEG)) { pAC->Rlmt.Port[PortNumber].Net->CheckingState |= SK_RLMT_RCS_START_SEG | SK_RLMT_RCS_SEND_SEG; } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n", pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX)) if (pRPort->PortState != SK_RLMT_PS_DOWN) { NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue); if (NewTimeout < SK_RLMT_MIN_TO_VAL) { NewTimeout = SK_RLMT_MIN_TO_VAL; } if (!(pRPort->CheckingState & SK_RLMT_PCS_RX)) { Para.Para32[0] = PortNumber; pRPort->CheckingState |= SK_RLMT_PCS_RX; /* * What shall we do if the port checked by this one receives * our request frames? What's bad - our rx line or his tx line? */ Para.Para32[1] = (SK_U32)-1; SkTimerStart(pAC, IoC, &pRPort->DownRxTimer, SK_RLMT_PORTDOWN_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTDOWN_RX_TIM, Para); for (i = 0; i < pRPort->PortsChecked; i++) { if (pRPort->PortCheck[i].SuspectTx) { continue; } pRPort->PortCheck[i].SuspectTx = SK_TRUE; pRPort->PortsSuspect++; if ((Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, PortNumber, SK_PACKET_CHECK_TX, &pAC->Addr.Port[PortNumber].CurrentMacAddress, &pRPort->PortCheck[i].CheckAddr)) != NULL) { SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); } } } } else { /* PortDown -- or all partners suspect. */ NewTimeout = SK_RLMT_DEF_TO_VAL; } pRPort->PortNoRx = SK_TRUE; } else { /* A non-BPDU packet was received. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n", PortNumber, pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot, pRPort->PacketsPerTimeSlot)) SkRlmtPortReceives(pAC, IoC, PortNumber); if (pAC->Rlmt.CheckSwitch) { SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); } NewTimeout = SK_RLMT_DEF_TO_VAL; } return (NewTimeout); } /* SkRlmtCheckPort */ /****************************************************************************** * * SkRlmtSelectBcRx - select new active port, criteria 1 (CLP) * * Description: * This routine selects the port that received a broadcast frame * substantially later than all other ports. * * Context: * runtime, pageable? * * Returns: * SK_BOOL */ RLMT_STATIC SK_BOOL SkRlmtSelectBcRx( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 Active, /* Active port */ SK_U32 PrefPort, /* Preferred port */ SK_U32 *pSelect) /* New active port */ { SK_U64 BcTimeStamp; SK_U32 i; SK_BOOL PortFound; BcTimeStamp = 0; /* Not totally necessary, but feeling better. */ PortFound = SK_FALSE; /* Select port with the latest TimeStamp. */ for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("TimeStamp Port %d (Down: %d, NoRx: %d): %08x %08x.\n", i, pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx, *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32), *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32))) if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) { if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) { BcTimeStamp = pAC->Rlmt.Port[i].BcTimeStamp; *pSelect = i; PortFound = SK_TRUE; } } } if (PortFound) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Port %d received the last broadcast.\n", *pSelect)) /* Look if another port's time stamp is similar. */ for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { if (i == *pSelect) { continue; } if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx && (pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp - SK_RLMT_BC_DELTA || pAC->Rlmt.Port[i].BcTimeStamp + SK_RLMT_BC_DELTA > BcTimeStamp)) { PortFound = SK_FALSE; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Port %d received a broadcast at a similar time.\n", i)) break; } } } #ifdef DEBUG if (PortFound) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially " "latest broadcast (%u).\n", *pSelect, BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp)) } #endif /* DEBUG */ return (PortFound); } /* SkRlmtSelectBcRx */ /****************************************************************************** * * SkRlmtSelectNotSuspect - select new active port, criteria 2 (CLP) * * Description: * This routine selects a good port (it is PortUp && !SuspectRx). * * Context: * runtime, pageable? * * Returns: * SK_BOOL */ RLMT_STATIC SK_BOOL SkRlmtSelectNotSuspect( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 Active, /* Active port */ SK_U32 PrefPort, /* Preferred port */ SK_U32 *pSelect) /* New active port */ { SK_U32 i; SK_BOOL PortFound; PortFound = SK_FALSE; /* Select first port that is PortUp && !SuspectRx. */ for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { if (!pAC->Rlmt.Port[i].PortDown && !(pAC->Rlmt.Port[i].CheckingState & SK_RLMT_PCS_RX)) { *pSelect = i; if (!pAC->Rlmt.Port[Active].PortDown && !(pAC->Rlmt.Port[Active].CheckingState & SK_RLMT_PCS_RX)) { *pSelect = Active; } if (!pAC->Rlmt.Port[PrefPort].PortDown && !(pAC->Rlmt.Port[PrefPort].CheckingState & SK_RLMT_PCS_RX)) { *pSelect = PrefPort; } PortFound = SK_TRUE; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n", *pSelect)) break; } } return (PortFound); } /* SkRlmtSelectNotSuspect */ /****************************************************************************** * * SkRlmtSelectUp - select new active port, criteria 3, 4 (CLP) * * Description: * This routine selects a port that is up. * * Context: * runtime, pageable? * * Returns: * SK_BOOL */ RLMT_STATIC SK_BOOL SkRlmtSelectUp( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 Active, /* Active port */ SK_U32 PrefPort, /* Preferred port */ SK_U32 *pSelect, /* New active port */ SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */ { SK_U32 i; SK_BOOL PortFound; PortFound = SK_FALSE; /* Select first port that is PortUp. */ for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_UP && pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) { *pSelect = i; if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_UP && pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) { *pSelect = Active; } if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_UP && pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) { *pSelect = PrefPort; } PortFound = SK_TRUE; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect)) break; } } return (PortFound); } /* SkRlmtSelectUp */ /****************************************************************************** * * SkRlmtSelectGoingUp - select new active port, criteria 5, 6 (CLP) * * Description: * This routine selects the port that is going up for the longest time. * * Context: * runtime, pageable? * * Returns: * SK_BOOL */ RLMT_STATIC SK_BOOL SkRlmtSelectGoingUp( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 Active, /* Active port */ SK_U32 PrefPort, /* Preferred port */ SK_U32 *pSelect, /* New active port */ SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */ { SK_U64 GuTimeStamp; SK_U32 i; SK_BOOL PortFound; GuTimeStamp = 0; PortFound = SK_FALSE; /* Select port that is PortGoingUp for the longest time. */ for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP && pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) { GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp; *pSelect = i; PortFound = SK_TRUE; break; } } if (!PortFound) { return (SK_FALSE); } for (i = *pSelect + 1; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_GOING_UP && pAC->Rlmt.Port[i].GuTimeStamp < GuTimeStamp && pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) { GuTimeStamp = pAC->Rlmt.Port[i].GuTimeStamp; *pSelect = i; } } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect)) return (SK_TRUE); } /* SkRlmtSelectGoingUp */ /****************************************************************************** * * SkRlmtSelectDown - select new active port, criteria 7, 8 (CLP) * * Description: * This routine selects a port that is down. * * Context: * runtime, pageable? * * Returns: * SK_BOOL */ RLMT_STATIC SK_BOOL SkRlmtSelectDown( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 Active, /* Active port */ SK_U32 PrefPort, /* Preferred port */ SK_U32 *pSelect, /* New active port */ SK_BOOL AutoNegDone) /* Successfully auto-negotiated? */ { SK_U32 i; SK_BOOL PortFound; PortFound = SK_FALSE; /* Select first port that is PortDown. */ for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { if (pAC->Rlmt.Port[i].PortState == SK_RLMT_PS_DOWN && pAC->GIni.GP[i].PAutoNegFail != AutoNegDone) { *pSelect = i; if (pAC->Rlmt.Port[Active].PortState == SK_RLMT_PS_DOWN && pAC->GIni.GP[Active].PAutoNegFail != AutoNegDone) { *pSelect = Active; } if (pAC->Rlmt.Port[PrefPort].PortState == SK_RLMT_PS_DOWN && pAC->GIni.GP[PrefPort].PAutoNegFail != AutoNegDone) { *pSelect = PrefPort; } PortFound = SK_TRUE; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect)) break; } } return (PortFound); } /* SkRlmtSelectDown */ /****************************************************************************** * * SkRlmtCheckSwitch - select new active port and switch to it * * Description: * This routine decides which port should be the active one and queues * port switching if necessary. * * Context: * runtime, pageable? * * Returns: * Nothing. */ RLMT_STATIC void SkRlmtCheckSwitch( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 NetIdx) /* Net index */ { SK_EVPARA Para; SK_U32 Active; SK_U32 PrefPort; SK_U32 i; SK_BOOL PortFound; Active = pAC->Rlmt.Net[NetIdx].ActivePort; /* Index of active port. */ PrefPort = pAC->Rlmt.Net[NetIdx].PrefPort; /* Index of preferred port. */ PortFound = SK_FALSE; pAC->Rlmt.CheckSwitch = SK_FALSE; #if 0 /* RW 2001/10/18 - active port becomes always prefered one */ if (pAC->Rlmt.Net[NetIdx].Preference == 0xFFFFFFFF) { /* Automatic */ /* disable auto-fail back */ PrefPort = Active; } #endif if (pAC->Rlmt.Net[NetIdx].LinksUp == 0) { /* Last link went down - shut down the net. */ pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_DOWN; Para.Para32[0] = SK_RLMT_NET_DOWN_TEMP; Para.Para32[1] = NetIdx; SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_DOWN, Para); Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber; Para.Para32[1] = NetIdx; SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para); return; } /* pAC->Rlmt.LinksUp == 0 */ else if (pAC->Rlmt.Net[NetIdx].LinksUp == 1 && pAC->Rlmt.Net[NetIdx].RlmtState == SK_RLMT_RS_NET_DOWN) { /* First link came up - get the net up. */ pAC->Rlmt.Net[NetIdx].RlmtState = SK_RLMT_RS_NET_UP; /* * If pAC->Rlmt.ActivePort != Para.Para32[0], * the DRV switches to the port that came up. */ for (i = 0; i < pAC->Rlmt.Net[NetIdx].NumPorts; i++) { if (!pAC->Rlmt.Net[NetIdx].Port[i]->LinkDown) { if (!pAC->Rlmt.Net[NetIdx].Port[Active]->LinkDown) { i = Active; } if (!pAC->Rlmt.Net[NetIdx].Port[PrefPort]->LinkDown) { i = PrefPort; } PortFound = SK_TRUE; break; } } if (PortFound) { Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber; Para.Para32[1] = NetIdx; SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para); pAC->Rlmt.Net[NetIdx].ActivePort = i; Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber; Para.Para32[1] = NetIdx; SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para); if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 && (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber, SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx]. CurrentMacAddress, &SkRlmtMcAddr)) != NULL) { /* * Send announce packet to RLMT multicast address to force * switches to learn the new location of the logical MAC address. */ SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); } } else { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E007, SKERR_RLMT_E007_MSG); } return; } /* LinksUp == 1 && RlmtState == SK_RLMT_RS_NET_DOWN */ else { /* Cannot be reached in dual-net mode. */ Para.Para32[0] = Active; /* * Preselection: * If RLMT Mode != CheckLinkState * select port that received a broadcast frame substantially later * than all other ports * else select first port that is not SuspectRx * else select first port that is PortUp * else select port that is PortGoingUp for the longest time * else select first port that is PortDown * else stop. * * For the preselected port: * If ActivePort is equal in quality, select ActivePort. * * If PrefPort is equal in quality, select PrefPort. * * If ActivePort != SelectedPort, * If old ActivePort is LinkDown, * SwitchHard * else * SwitchSoft */ /* check of ChgBcPrio flag added */ if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) && (!pAC->Rlmt.Net[0].ChgBcPrio)) { if (!PortFound) { PortFound = SkRlmtSelectBcRx( pAC, IoC, Active, PrefPort, &Para.Para32[1]); } if (!PortFound) { PortFound = SkRlmtSelectNotSuspect( pAC, IoC, Active, PrefPort, &Para.Para32[1]); } } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ /* with changed priority for last broadcast received */ if ((pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) && (pAC->Rlmt.Net[0].ChgBcPrio)) { if (!PortFound) { PortFound = SkRlmtSelectNotSuspect( pAC, IoC, Active, PrefPort, &Para.Para32[1]); } if (!PortFound) { PortFound = SkRlmtSelectBcRx( pAC, IoC, Active, PrefPort, &Para.Para32[1]); } } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ if (!PortFound) { PortFound = SkRlmtSelectUp( pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS); } if (!PortFound) { PortFound = SkRlmtSelectUp( pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED); } if (!PortFound) { PortFound = SkRlmtSelectGoingUp( pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS); } if (!PortFound) { PortFound = SkRlmtSelectGoingUp( pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED); } if (pAC->Rlmt.Net[0].RlmtMode != SK_RLMT_MODE_CLS) { if (!PortFound) { PortFound = SkRlmtSelectDown(pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_SUCCESS); } if (!PortFound) { PortFound = SkRlmtSelectDown(pAC, IoC, Active, PrefPort, &Para.Para32[1], AUTONEG_FAILED); } } /* pAC->Rlmt.RlmtMode != SK_RLMT_MODE_CLS */ if (PortFound) { if (Para.Para32[1] != Active) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Active: %d, Para1: %d.\n", Active, Para.Para32[1])) pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1]; Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. Port[Para.Para32[0]]->PortNumber; Para.Para32[1] = pAC->Rlmt.Net[NetIdx]. Port[Para.Para32[1]]->PortNumber; SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[1], SK_LED_ACTIVE); if (pAC->Rlmt.Port[Active].LinkDown) { SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_HARD, Para); } else { SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY); SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_SOFT, Para); } Para.Para32[1] = NetIdx; Para.Para32[0] = pAC->Rlmt.Net[NetIdx].Port[Para.Para32[0]]->PortNumber; SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_DOWN, Para); Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. Port[pAC->Rlmt.Net[NetIdx].ActivePort]->PortNumber; SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_ACTIVE_UP, Para); if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 && (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx].CurrentMacAddress, &SkRlmtMcAddr)) != NULL) { /* * Send announce packet to RLMT multicast address to force * switches to learn the new location of the logical * MAC address. */ SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); } /* (Para.pParaPtr = SkRlmtBuildPacket(...)) != NULL */ } /* Para.Para32[1] != Active */ } /* PortFound */ else { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E004, SKERR_RLMT_E004_MSG); } } /* LinksUp > 1 || LinksUp == 1 && RlmtState != SK_RLMT_RS_NET_DOWN */ return; } /* SkRlmtCheckSwitch */ /****************************************************************************** * * SkRlmtCheckSeg - Report if segmentation is detected * * Description: * This routine checks if the ports see different root bridges and reports * segmentation in such a case. * * Context: * runtime, pageable? * * Returns: * Nothing. */ RLMT_STATIC void SkRlmtCheckSeg( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 NetIdx) /* Net number */ { SK_EVPARA Para; SK_RLMT_NET *pNet; SK_U32 i, j; SK_BOOL Equal; pNet = &pAC->Rlmt.Net[NetIdx]; pNet->RootIdSet = SK_FALSE; Equal = SK_TRUE; for (i = 0; i < pNet->NumPorts; i++) { if (pNet->Port[i]->LinkDown || !pNet->Port[i]->RootIdSet) { continue; } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_DUMP, ("Root ID %d: %02x %02x %02x %02x %02x %02x %02x %02x.\n", i, pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1], pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3], pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5], pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7])) if (!pNet->RootIdSet) { pNet->Root = pNet->Port[i]->Root; pNet->RootIdSet = SK_TRUE; continue; } for (j = 0; j < 8; j ++) { Equal &= pNet->Port[i]->Root.Id[j] == pNet->Root.Id[j]; if (!Equal) { break; } } if (!Equal) { SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E005, SKERR_RLMT_E005_MSG); Para.Para32[0] = NetIdx; Para.Para32[1] = (SK_U32)-1; SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SEGMENTATION, Para); pNet->CheckingState &= ~SK_RLMT_RCS_REPORT_SEG; /* 2000-03-06 RA: New. */ Para.Para32[0] = NetIdx; Para.Para32[1] = (SK_U32)-1; SkTimerStart(pAC, IoC, &pNet->SegTimer, SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para); break; } } /* for (i = 0; i < pNet->NumPorts; i++) */ /* 2000-03-06 RA: Moved here. */ /* Segmentation check not running anymore. */ pNet->CheckingState &= ~SK_RLMT_RCS_SEG; } /* SkRlmtCheckSeg */ /****************************************************************************** * * SkRlmtPortStart - initialize port variables and start port * * Description: * This routine initializes a port's variables and issues a PORT_START * to the HWAC module. This handles retries if the start fails or the * link eventually goes down. * * Context: * runtime, pageable? * * Returns: * Nothing */ RLMT_STATIC void SkRlmtPortStart( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 PortNumber) /* Port number */ { SK_EVPARA Para; pAC->Rlmt.Port[PortNumber].PortState = SK_RLMT_PS_LINK_DOWN; pAC->Rlmt.Port[PortNumber].PortStarted = SK_TRUE; pAC->Rlmt.Port[PortNumber].LinkDown = SK_TRUE; pAC->Rlmt.Port[PortNumber].PortDown = SK_TRUE; pAC->Rlmt.Port[PortNumber].CheckingState = 0; pAC->Rlmt.Port[PortNumber].RootIdSet = SK_FALSE; Para.Para32[0] = PortNumber; Para.Para32[1] = (SK_U32)-1; SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para); } /* SkRlmtPortStart */ /****************************************************************************** * * SkRlmtEvtPortStartTim - PORT_START_TIM * * Description: * This routine handles PORT_START_TIM events. * * Context: * runtime, pageable? * may be called after SK_INIT_IO * * Returns: * Nothing */ RLMT_STATIC void SkRlmtEvtPortStartTim( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */ { SK_U32 i; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0])) if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Bad Parameter.\n")) SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n")) return; } /* * Used to start non-preferred ports if the preferred one * does not come up. * This timeout needs only be set when starting the first * (preferred) port. */ if (pAC->Rlmt.Port[Para.Para32[0]].LinkDown) { /* PORT_START failed. */ for (i = 0; i < pAC->Rlmt.Port[Para.Para32[0]].Net->NumPorts; i++) { if (!pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortStarted) { SkRlmtPortStart(pAC, IoC, pAC->Rlmt.Port[Para.Para32[0]].Net->Port[i]->PortNumber); } } } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n")) } /* SkRlmtEvtPortStartTim */ /****************************************************************************** * * SkRlmtEvtLinkUp - LINK_UP * * Description: * This routine handles LLINK_UP events. * * Context: * runtime, pageable? * may be called after SK_INIT_IO * * Returns: * Nothing */ RLMT_STATIC void SkRlmtEvtLinkUp( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */ { SK_U32 i; SK_RLMT_PORT *pRPort; SK_EVPARA Para2; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0])) pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; if (!pRPort->PortStarted) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_LINK_UP Event EMPTY.\n")) return; } if (!pRPort->LinkDown) { /* RA;:;: Any better solution? */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_LINK_UP Event EMPTY.\n")) return; } SkTimerStop(pAC, IoC, &pRPort->UpTimer); SkTimerStop(pAC, IoC, &pRPort->DownRxTimer); SkTimerStop(pAC, IoC, &pRPort->DownTxTimer); /* Do something if timer already fired? */ pRPort->LinkDown = SK_FALSE; pRPort->PortState = SK_RLMT_PS_GOING_UP; pRPort->GuTimeStamp = SkOsGetTime(pAC); pRPort->BcTimeStamp = 0; pRPort->Net->LinksUp++; if (pRPort->Net->LinksUp == 1) { SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_ACTIVE); } else { SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_STANDBY); } for (i = 0; i < pRPort->Net->NumPorts; i++) { if (!pRPort->Net->Port[i]->PortStarted) { SkRlmtPortStart(pAC, IoC, pRPort->Net->Port[i]->PortNumber); } } SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); if (pRPort->Net->LinksUp >= 2) { if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) { /* Build the check chain. */ SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber); } } /* If the first link comes up, start the periodical RLMT timeout. */ if (pRPort->Net->NumPorts > 1 && pRPort->Net->LinksUp == 1 && (pRPort->Net->RlmtMode & SK_RLMT_CHECK_OTHERS) != 0) { Para2.Para32[0] = pRPort->Net->NetNumber; Para2.Para32[1] = (SK_U32)-1; SkTimerStart(pAC, IoC, &pRPort->Net->LocTimer, pRPort->Net->TimeoutValue, SKGE_RLMT, SK_RLMT_TIM, Para2); } Para2 = Para; Para2.Para32[1] = (SK_U32)-1; SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2); /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */ if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 && (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 && (Para2.pParaPtr = SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE, &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr) ) != NULL) { /* Send "new" packet to RLMT multicast address. */ SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); } if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) { if ((Para2.pParaPtr = SkRlmtBuildSpanningTreePacket(pAC, IoC, Para.Para32[0])) != NULL) { pAC->Rlmt.Port[Para.Para32[0]].RootIdSet = SK_FALSE; pRPort->Net->CheckingState |= SK_RLMT_RCS_SEG | SK_RLMT_RCS_REPORT_SEG; SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); Para.Para32[1] = (SK_U32)-1; SkTimerStart(pAC, IoC, &pRPort->Net->SegTimer, SK_RLMT_SEG_TO_VAL, SKGE_RLMT, SK_RLMT_SEG_TIM, Para); } } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_LINK_UP Event END.\n")) } /* SkRlmtEvtLinkUp */ /****************************************************************************** * * SkRlmtEvtPortUpTim - PORT_UP_TIM * * Description: * This routine handles PORT_UP_TIM events. * * Context: * runtime, pageable? * may be called after SK_INIT_IO * * Returns: * Nothing */ RLMT_STATIC void SkRlmtEvtPortUpTim( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */ { SK_RLMT_PORT *pRPort; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0])) if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Bad Parameter.\n")) SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTUP_TIM Event EMPTY.\n")) return; } pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0])) return; } pRPort->PortDown = SK_FALSE; pRPort->PortState = SK_RLMT_PS_UP; pRPort->Net->PortsUp++; if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) { if (pAC->Rlmt.NumNets <= 1) { SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); } SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_UP, Para); } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTUP_TIM Event END.\n")) } /* SkRlmtEvtPortUpTim */ /****************************************************************************** * * SkRlmtEvtPortDownTim - PORT_DOWN_* * * Description: * This routine handles PORT_DOWN_* events. * * Context: * runtime, pageable? * may be called after SK_INIT_IO * * Returns: * Nothing */ RLMT_STATIC void SkRlmtEvtPortDownX( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 Event, /* Event code */ SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */ { SK_RLMT_PORT *pRPort; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n", Para.Para32[0], Event)) if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Bad Parameter.\n")) SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTDOWN* Event EMPTY.\n")) return; } pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM && !(pRPort->CheckingState & SK_RLMT_PCS_TX))) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event)) return; } /* Stop port's timers. */ SkTimerStop(pAC, IoC, &pRPort->UpTimer); SkTimerStop(pAC, IoC, &pRPort->DownRxTimer); SkTimerStop(pAC, IoC, &pRPort->DownTxTimer); if (pRPort->PortState != SK_RLMT_PS_LINK_DOWN) { pRPort->PortState = SK_RLMT_PS_DOWN; } if (!pRPort->PortDown) { pRPort->Net->PortsUp--; pRPort->PortDown = SK_TRUE; SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_PORT_DOWN, Para); } pRPort->PacketsPerTimeSlot = 0; /* pRPort->DataPacketsPerTimeSlot = 0; */ pRPort->BpduPacketsPerTimeSlot = 0; pRPort->BcTimeStamp = 0; /* * RA;:;: To be checked: * - actions at RLMT_STOP: We should not switch anymore. */ if (pRPort->Net->RlmtState != SK_RLMT_RS_INIT) { if (Para.Para32[0] == pRPort->Net->Port[pRPort->Net->ActivePort]->PortNumber) { /* Active Port went down. */ SkRlmtCheckSwitch(pAC, IoC, pRPort->Net->NetNumber); } } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event)) } /* SkRlmtEvtPortDownX */ /****************************************************************************** * * SkRlmtEvtLinkDown - LINK_DOWN * * Description: * This routine handles LINK_DOWN events. * * Context: * runtime, pageable? * may be called after SK_INIT_IO * * Returns: * Nothing */ RLMT_STATIC void SkRlmtEvtLinkDown( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 Undefined */ { SK_RLMT_PORT *pRPort; pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0])) if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) { pRPort->Net->LinksUp--; pRPort->LinkDown = SK_TRUE; pRPort->PortState = SK_RLMT_PS_LINK_DOWN; SK_HWAC_LINK_LED(pAC, IoC, Para.Para32[0], SK_LED_OFF); if ((pRPort->Net->RlmtMode & SK_RLMT_CHECK_LOC_LINK) != 0) { /* Build the check chain. */ SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber); } /* Ensure that port is marked down. */ Para.Para32[1] = -1; (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PORTDOWN, Para); } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_LINK_DOWN Event END.\n")) } /* SkRlmtEvtLinkDown */ /****************************************************************************** * * SkRlmtEvtPortAddr - PORT_ADDR * * Description: * This routine handles PORT_ADDR events. * * Context: * runtime, pageable? * may be called after SK_INIT_IO * * Returns: * Nothing */ RLMT_STATIC void SkRlmtEvtPortAddr( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_EVPARA Para) /* SK_U32 PortNumber; SK_U32 -1 */ { SK_U32 i, j; SK_RLMT_PORT *pRPort; SK_MAC_ADDR *pOldMacAddr; SK_MAC_ADDR *pNewMacAddr; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0])) if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Bad Parameter.\n")) SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORT_ADDR Event EMPTY.\n")) return; } /* Port's physical MAC address changed. */ pOldMacAddr = &pAC->Addr.Port[Para.Para32[0]].PreviousMacAddress; pNewMacAddr = &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress; /* * NOTE: This is not scalable for solutions where ports are * checked remotely. There, we need to send an RLMT * address change packet - and how do we ensure delivery? */ for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { pRPort = &pAC->Rlmt.Port[i]; for (j = 0; j < pRPort->PortsChecked; j++) { if (SK_ADDR_EQUAL( pRPort->PortCheck[j].CheckAddr.a, pOldMacAddr->a)) { pRPort->PortCheck[j].CheckAddr = *pNewMacAddr; } } } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORT_ADDR Event END.\n")) } /* SkRlmtEvtPortAddr */ /****************************************************************************** * * SkRlmtEvtStart - START * * Description: * This routine handles START events. * * Context: * runtime, pageable? * may be called after SK_INIT_IO * * Returns: * Nothing */ RLMT_STATIC void SkRlmtEvtStart( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ { SK_EVPARA Para2; SK_U32 PortIdx; SK_U32 PortNumber; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0])) if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Bad Parameter.\n")) SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_START Event EMPTY.\n")) return; } if (Para.Para32[0] >= pAC->Rlmt.NumNets) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Bad NetNumber %d.\n", Para.Para32[0])) SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_START Event EMPTY.\n")) return; } if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_START Event EMPTY.\n")) return; } if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("All nets should have been started.\n")) SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_START Event EMPTY.\n")) return; } if (pAC->Rlmt.Net[Para.Para32[0]].PrefPort >= pAC->Rlmt.Net[Para.Para32[0]].NumPorts) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E009, SKERR_RLMT_E009_MSG); /* Change PrefPort to internal default. */ Para2.Para32[0] = 0xFFFFFFFF; Para2.Para32[1] = Para.Para32[0]; (void)SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, Para2); } PortIdx = pAC->Rlmt.Net[Para.Para32[0]].PrefPort; PortNumber = pAC->Rlmt.Net[Para.Para32[0]].Port[PortIdx]->PortNumber;