smt.c 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097
  1. /******************************************************************************
  2. *
  3. * (C)Copyright 1998,1999 SysKonnect,
  4. * a business unit of Schneider & Koch & Co. Datensysteme GmbH.
  5. *
  6. * See the file "skfddi.c" for further information.
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * The information in this file is provided "AS IS" without warranty.
  14. *
  15. ******************************************************************************/
  16. #include "h/types.h"
  17. #include "h/fddi.h"
  18. #include "h/smc.h"
  19. #include "h/smt_p.h"
  20. #define KERNEL
  21. #include "h/smtstate.h"
  22. #ifndef lint
  23. static const char ID_sccs[] = "@(#)smt.c 2.43 98/11/23 (C) SK " ;
  24. #endif
  25. extern const u_char canonical[256] ;
  26. /*
  27. * FC in SMbuf
  28. */
  29. #define m_fc(mb) ((mb)->sm_data[0])
  30. #define SMT_TID_MAGIC 0x1f0a7b3c
  31. #ifdef DEBUG
  32. static const char *const smt_type_name[] = {
  33. "SMT_00??", "SMT_INFO", "SMT_02??", "SMT_03??",
  34. "SMT_04??", "SMT_05??", "SMT_06??", "SMT_07??",
  35. "SMT_08??", "SMT_09??", "SMT_0A??", "SMT_0B??",
  36. "SMT_0C??", "SMT_0D??", "SMT_0E??", "SMT_NSA"
  37. } ;
  38. static const char *const smt_class_name[] = {
  39. "UNKNOWN","NIF","SIF_CONFIG","SIF_OPER","ECF","RAF","RDF",
  40. "SRF","PMF_GET","PMF_SET","ESF"
  41. } ;
  42. #endif
  43. #define LAST_CLASS (SMT_PMF_SET)
  44. static const struct fddi_addr SMT_Unknown = {
  45. { 0,0,0x1f,0,0,0 }
  46. } ;
  47. /*
  48. * external variables
  49. */
  50. extern const struct fddi_addr fddi_broadcast ;
  51. /*
  52. * external functions
  53. */
  54. int pcm_status_twisted(struct s_smc *smc);
  55. /*
  56. * function prototypes
  57. */
  58. #ifdef LITTLE_ENDIAN
  59. static int smt_swap_short(u_short s);
  60. #endif
  61. static int mac_index(struct s_smc *smc, int mac);
  62. static int phy_index(struct s_smc *smc, int phy);
  63. static int mac_con_resource_index(struct s_smc *smc, int mac);
  64. static int phy_con_resource_index(struct s_smc *smc, int phy);
  65. static void smt_send_rdf(struct s_smc *smc, SMbuf *rej, int fc, int reason,
  66. int local);
  67. static void smt_send_nif(struct s_smc *smc, const struct fddi_addr *dest,
  68. int fc, u_long tid, int type, int local);
  69. static void smt_send_ecf(struct s_smc *smc, struct fddi_addr *dest, int fc,
  70. u_long tid, int type, int len);
  71. static void smt_echo_test(struct s_smc *smc, int dna);
  72. static void smt_send_sif_config(struct s_smc *smc, struct fddi_addr *dest,
  73. u_long tid, int local);
  74. static void smt_send_sif_operation(struct s_smc *smc, struct fddi_addr *dest,
  75. u_long tid, int local);
  76. #ifdef LITTLE_ENDIAN
  77. static void smt_string_swap(void);
  78. #endif
  79. static void smt_add_frame_len(SMbuf *mb, int len);
  80. static void smt_fill_una(struct s_smc *smc, struct smt_p_una *una);
  81. static void smt_fill_sde(struct s_smc *smc, struct smt_p_sde *sde);
  82. static void smt_fill_state(struct s_smc *smc, struct smt_p_state *state);
  83. static void smt_fill_timestamp(struct s_smc *smc, struct smt_p_timestamp *ts);
  84. static void smt_fill_policy(struct s_smc *smc, struct smt_p_policy *policy);
  85. static void smt_fill_latency(struct s_smc *smc, struct smt_p_latency *latency);
  86. static void smt_fill_neighbor(struct s_smc *smc, struct smt_p_neighbor *neighbor);
  87. static int smt_fill_path(struct s_smc *smc, struct smt_p_path *path);
  88. static void smt_fill_mac_status(struct s_smc *smc, struct smt_p_mac_status *st);
  89. static void smt_fill_lem(struct s_smc *smc, struct smt_p_lem *lem, int phy);
  90. static void smt_fill_version(struct s_smc *smc, struct smt_p_version *vers);
  91. static void smt_fill_fsc(struct s_smc *smc, struct smt_p_fsc *fsc);
  92. static void smt_fill_mac_counter(struct s_smc *smc, struct smt_p_mac_counter *mc);
  93. static void smt_fill_mac_fnc(struct s_smc *smc, struct smt_p_mac_fnc *fnc);
  94. static void smt_fill_manufacturer(struct s_smc *smc,
  95. struct smp_p_manufacturer *man);
  96. static void smt_fill_user(struct s_smc *smc, struct smp_p_user *user);
  97. static void smt_fill_setcount(struct s_smc *smc, struct smt_p_setcount *setcount);
  98. static void smt_fill_echo(struct s_smc *smc, struct smt_p_echo *echo, u_long seed,
  99. int len);
  100. void smt_clear_una_dna(struct s_smc *smc);
  101. static void smt_clear_old_una_dna(struct s_smc *smc);
  102. #ifdef CONCENTRATOR
  103. static int entity_to_index(void);
  104. #endif
  105. static void update_dac(struct s_smc *smc, int report);
  106. static int div_ratio(u_long upper, u_long lower);
  107. #ifdef USE_CAN_ADDR
  108. void hwm_conv_can(struct s_smc *smc, char *data, int len);
  109. #else
  110. #define hwm_conv_can(smc,data,len)
  111. #endif
  112. static inline int is_my_addr(const struct s_smc *smc,
  113. const struct fddi_addr *addr)
  114. {
  115. return(*(short *)(&addr->a[0]) ==
  116. *(short *)(&smc->mib.m[MAC0].fddiMACSMTAddress.a[0])
  117. && *(short *)(&addr->a[2]) ==
  118. *(short *)(&smc->mib.m[MAC0].fddiMACSMTAddress.a[2])
  119. && *(short *)(&addr->a[4]) ==
  120. *(short *)(&smc->mib.m[MAC0].fddiMACSMTAddress.a[4])) ;
  121. }
  122. static inline int is_broadcast(const struct fddi_addr *addr)
  123. {
  124. return(*(u_short *)(&addr->a[0]) == 0xffff &&
  125. *(u_short *)(&addr->a[2]) == 0xffff &&
  126. *(u_short *)(&addr->a[4]) == 0xffff ) ;
  127. }
  128. static inline int is_individual(const struct fddi_addr *addr)
  129. {
  130. return(!(addr->a[0] & GROUP_ADDR)) ;
  131. }
  132. static inline int is_equal(const struct fddi_addr *addr1,
  133. const struct fddi_addr *addr2)
  134. {
  135. return(*(u_short *)(&addr1->a[0]) == *(u_short *)(&addr2->a[0]) &&
  136. *(u_short *)(&addr1->a[2]) == *(u_short *)(&addr2->a[2]) &&
  137. *(u_short *)(&addr1->a[4]) == *(u_short *)(&addr2->a[4]) ) ;
  138. }
  139. /*
  140. * list of mandatory paras in frames
  141. */
  142. static const u_short plist_nif[] = { SMT_P_UNA,SMT_P_SDE,SMT_P_STATE,0 } ;
  143. /*
  144. * init SMT agent
  145. */
  146. void smt_agent_init(struct s_smc *smc)
  147. {
  148. int i ;
  149. /*
  150. * get MAC address
  151. */
  152. smc->mib.m[MAC0].fddiMACSMTAddress = smc->hw.fddi_home_addr ;
  153. /*
  154. * get OUI address from driver (bia == built-in-address)
  155. */
  156. smc->mib.fddiSMTStationId.sid_oem[0] = 0 ;
  157. smc->mib.fddiSMTStationId.sid_oem[1] = 0 ;
  158. driver_get_bia(smc,&smc->mib.fddiSMTStationId.sid_node) ;
  159. for (i = 0 ; i < 6 ; i ++) {
  160. smc->mib.fddiSMTStationId.sid_node.a[i] =
  161. canonical[smc->mib.fddiSMTStationId.sid_node.a[i]] ;
  162. }
  163. smc->mib.fddiSMTManufacturerData[0] =
  164. smc->mib.fddiSMTStationId.sid_node.a[0] ;
  165. smc->mib.fddiSMTManufacturerData[1] =
  166. smc->mib.fddiSMTStationId.sid_node.a[1] ;
  167. smc->mib.fddiSMTManufacturerData[2] =
  168. smc->mib.fddiSMTStationId.sid_node.a[2] ;
  169. smc->sm.smt_tid = 0 ;
  170. smc->mib.m[MAC0].fddiMACDupAddressTest = DA_NONE ;
  171. smc->mib.m[MAC0].fddiMACUNDA_Flag = FALSE ;
  172. #ifndef SLIM_SMT
  173. smt_clear_una_dna(smc) ;
  174. smt_clear_old_una_dna(smc) ;
  175. #endif
  176. for (i = 0 ; i < SMT_MAX_TEST ; i++)
  177. smc->sm.pend[i] = 0 ;
  178. smc->sm.please_reconnect = 0 ;
  179. smc->sm.uniq_ticks = 0 ;
  180. }
  181. /*
  182. * SMT task
  183. * forever
  184. * delay 30 seconds
  185. * send NIF
  186. * check tvu & tvd
  187. * end
  188. */
  189. void smt_agent_task(struct s_smc *smc)
  190. {
  191. smt_timer_start(smc,&smc->sm.smt_timer, (u_long)1000000L,
  192. EV_TOKEN(EVENT_SMT,SM_TIMER)) ;
  193. DB_SMT("SMT agent task\n",0,0) ;
  194. }
  195. void smt_please_reconnect(struct s_smc *smc, int reconn_time)
  196. /* struct s_smc *smc; Pointer to SMT context */
  197. /* int reconn_time; Wait for reconnect time in seconds */
  198. {
  199. /*
  200. * The please reconnect variable is used as a timer.
  201. * It is decremented each time smt_event is called.
  202. * This happens every second or when smt_force_irq is called.
  203. * Note: smt_force_irq () is called on some packet receives and
  204. * when a multicast address is changed. Since nothing
  205. * is received during the disconnect and the multicast
  206. * address changes can be viewed as not very often and
  207. * the timer runs out close to its given value
  208. * (reconn_time).
  209. */
  210. smc->sm.please_reconnect = reconn_time ;
  211. }
  212. #ifndef SMT_REAL_TOKEN_CT
  213. void smt_emulate_token_ct(struct s_smc *smc, int mac_index)
  214. {
  215. u_long count;
  216. u_long time;
  217. time = smt_get_time();
  218. count = ((time - smc->sm.last_tok_time[mac_index]) *
  219. 100)/TICKS_PER_SECOND;
  220. /*
  221. * Only when ring is up we will have a token count. The
  222. * flag is unfortunatly a single instance value. This
  223. * doesn't matter now, because we currently have only
  224. * one MAC instance.
  225. */
  226. if (smc->hw.mac_ring_is_up){
  227. smc->mib.m[mac_index].fddiMACToken_Ct += count;
  228. }
  229. /* Remember current time */
  230. smc->sm.last_tok_time[mac_index] = time;
  231. }
  232. #endif
  233. /*ARGSUSED1*/
  234. void smt_event(struct s_smc *smc, int event)
  235. {
  236. u_long time ;
  237. #ifndef SMT_REAL_TOKEN_CT
  238. int i ;
  239. #endif
  240. if (smc->sm.please_reconnect) {
  241. smc->sm.please_reconnect -- ;
  242. if (smc->sm.please_reconnect == 0) {
  243. /* Counted down */
  244. queue_event(smc,EVENT_ECM,EC_CONNECT) ;
  245. }
  246. }
  247. if (event == SM_FAST)
  248. return ;
  249. /*
  250. * timer for periodic cleanup in driver
  251. * reset and start the watchdog (FM2)
  252. * ESS timer
  253. * SBA timer
  254. */
  255. smt_timer_poll(smc) ;
  256. smt_start_watchdog(smc) ;
  257. #ifndef SLIM_SMT
  258. #ifndef BOOT
  259. #ifdef ESS
  260. ess_timer_poll(smc) ;
  261. #endif
  262. #endif
  263. #ifdef SBA
  264. sba_timer_poll(smc) ;
  265. #endif
  266. smt_srf_event(smc,0,0,0) ;
  267. #endif /* no SLIM_SMT */
  268. time = smt_get_time() ;
  269. if (time - smc->sm.smt_last_lem >= TICKS_PER_SECOND*8) {
  270. /*
  271. * Use 8 sec. for the time intervall, it simplifies the
  272. * LER estimation.
  273. */
  274. struct fddi_mib_m *mib ;
  275. u_long upper ;
  276. u_long lower ;
  277. int cond ;
  278. int port;
  279. struct s_phy *phy ;
  280. /*
  281. * calculate LEM bit error rate
  282. */
  283. sm_lem_evaluate(smc) ;
  284. smc->sm.smt_last_lem = time ;
  285. /*
  286. * check conditions
  287. */
  288. #ifndef SLIM_SMT
  289. mac_update_counter(smc) ;
  290. mib = smc->mib.m ;
  291. upper =
  292. (mib->fddiMACLost_Ct - mib->fddiMACOld_Lost_Ct) +
  293. (mib->fddiMACError_Ct - mib->fddiMACOld_Error_Ct) ;
  294. lower =
  295. (mib->fddiMACFrame_Ct - mib->fddiMACOld_Frame_Ct) +
  296. (mib->fddiMACLost_Ct - mib->fddiMACOld_Lost_Ct) ;
  297. mib->fddiMACFrameErrorRatio = div_ratio(upper,lower) ;
  298. cond =
  299. ((!mib->fddiMACFrameErrorThreshold &&
  300. mib->fddiMACError_Ct != mib->fddiMACOld_Error_Ct) ||
  301. (mib->fddiMACFrameErrorRatio >
  302. mib->fddiMACFrameErrorThreshold)) ;
  303. if (cond != mib->fddiMACFrameErrorFlag)
  304. smt_srf_event(smc,SMT_COND_MAC_FRAME_ERROR,
  305. INDEX_MAC,cond) ;
  306. upper =
  307. (mib->fddiMACNotCopied_Ct - mib->fddiMACOld_NotCopied_Ct) ;
  308. lower =
  309. upper +
  310. (mib->fddiMACCopied_Ct - mib->fddiMACOld_Copied_Ct) ;
  311. mib->fddiMACNotCopiedRatio = div_ratio(upper,lower) ;
  312. cond =
  313. ((!mib->fddiMACNotCopiedThreshold &&
  314. mib->fddiMACNotCopied_Ct !=
  315. mib->fddiMACOld_NotCopied_Ct)||
  316. (mib->fddiMACNotCopiedRatio >
  317. mib->fddiMACNotCopiedThreshold)) ;
  318. if (cond != mib->fddiMACNotCopiedFlag)
  319. smt_srf_event(smc,SMT_COND_MAC_NOT_COPIED,
  320. INDEX_MAC,cond) ;
  321. /*
  322. * set old values
  323. */
  324. mib->fddiMACOld_Frame_Ct = mib->fddiMACFrame_Ct ;
  325. mib->fddiMACOld_Copied_Ct = mib->fddiMACCopied_Ct ;
  326. mib->fddiMACOld_Error_Ct = mib->fddiMACError_Ct ;
  327. mib->fddiMACOld_Lost_Ct = mib->fddiMACLost_Ct ;
  328. mib->fddiMACOld_NotCopied_Ct = mib->fddiMACNotCopied_Ct ;
  329. /*
  330. * Check port EBError Condition
  331. */
  332. for (port = 0; port < NUMPHYS; port ++) {
  333. phy = &smc->y[port] ;
  334. if (!phy->mib->fddiPORTHardwarePresent) {
  335. continue;
  336. }
  337. cond = (phy->mib->fddiPORTEBError_Ct -
  338. phy->mib->fddiPORTOldEBError_Ct > 5) ;
  339. /* If ratio is more than 5 in 8 seconds
  340. * Set the condition.
  341. */
  342. smt_srf_event(smc,SMT_COND_PORT_EB_ERROR,
  343. (int) (INDEX_PORT+ phy->np) ,cond) ;
  344. /*
  345. * set old values
  346. */
  347. phy->mib->fddiPORTOldEBError_Ct =
  348. phy->mib->fddiPORTEBError_Ct ;
  349. }
  350. #endif /* no SLIM_SMT */
  351. }
  352. #ifndef SLIM_SMT
  353. if (time - smc->sm.smt_last_notify >= (u_long)
  354. (smc->mib.fddiSMTTT_Notify * TICKS_PER_SECOND) ) {
  355. /*
  356. * we can either send an announcement or a request
  357. * a request will trigger a reply so that we can update
  358. * our dna
  359. * note: same tid must be used until reply is received
  360. */
  361. if (!smc->sm.pend[SMT_TID_NIF])
  362. smc->sm.pend[SMT_TID_NIF] = smt_get_tid(smc) ;
  363. smt_send_nif(smc,&fddi_broadcast, FC_SMT_NSA,
  364. smc->sm.pend[SMT_TID_NIF], SMT_REQUEST,0) ;
  365. smc->sm.smt_last_notify = time ;
  366. }
  367. /*
  368. * check timer
  369. */
  370. if (smc->sm.smt_tvu &&
  371. time - smc->sm.smt_tvu > 228*TICKS_PER_SECOND) {
  372. DB_SMT("SMT : UNA expired\n",0,0) ;
  373. smc->sm.smt_tvu = 0 ;
  374. if (!is_equal(&smc->mib.m[MAC0].fddiMACUpstreamNbr,
  375. &SMT_Unknown)){
  376. /* Do not update unknown address */
  377. smc->mib.m[MAC0].fddiMACOldUpstreamNbr=
  378. smc->mib.m[MAC0].fddiMACUpstreamNbr ;
  379. }
  380. smc->mib.m[MAC0].fddiMACUpstreamNbr = SMT_Unknown ;
  381. smc->mib.m[MAC0].fddiMACUNDA_Flag = FALSE ;
  382. /*
  383. * Make sure the fddiMACUNDA_Flag = FALSE is
  384. * included in the SRF so we don't generate
  385. * a separate SRF for the deassertion of this
  386. * condition
  387. */
  388. update_dac(smc,0) ;
  389. smt_srf_event(smc, SMT_EVENT_MAC_NEIGHBOR_CHANGE,
  390. INDEX_MAC,0) ;
  391. }
  392. if (smc->sm.smt_tvd &&
  393. time - smc->sm.smt_tvd > 228*TICKS_PER_SECOND) {
  394. DB_SMT("SMT : DNA expired\n",0,0) ;
  395. smc->sm.smt_tvd = 0 ;
  396. if (!is_equal(&smc->mib.m[MAC0].fddiMACDownstreamNbr,
  397. &SMT_Unknown)){
  398. /* Do not update unknown address */
  399. smc->mib.m[MAC0].fddiMACOldDownstreamNbr=
  400. smc->mib.m[MAC0].fddiMACDownstreamNbr ;
  401. }
  402. smc->mib.m[MAC0].fddiMACDownstreamNbr = SMT_Unknown ;
  403. smt_srf_event(smc, SMT_EVENT_MAC_NEIGHBOR_CHANGE,
  404. INDEX_MAC,0) ;
  405. }
  406. #endif /* no SLIM_SMT */
  407. #ifndef SMT_REAL_TOKEN_CT
  408. /*
  409. * Token counter emulation section. If hardware supports the token
  410. * count, the token counter will be updated in mac_update_counter.
  411. */
  412. for (i = MAC0; i < NUMMACS; i++ ){
  413. if (time - smc->sm.last_tok_time[i] > 2*TICKS_PER_SECOND ){
  414. smt_emulate_token_ct( smc, i );
  415. }
  416. }
  417. #endif
  418. smt_timer_start(smc,&smc->sm.smt_timer, (u_long)1000000L,
  419. EV_TOKEN(EVENT_SMT,SM_TIMER)) ;
  420. }
  421. static int div_ratio(u_long upper, u_long lower)
  422. {
  423. if ((upper<<16L) < upper)
  424. upper = 0xffff0000L ;
  425. else
  426. upper <<= 16L ;
  427. if (!lower)
  428. return(0) ;
  429. return((int)(upper/lower)) ;
  430. }
  431. #ifndef SLIM_SMT
  432. /*
  433. * receive packet handler
  434. */
  435. void smt_received_pack(struct s_smc *smc, SMbuf *mb, int fs)
  436. /* int fs; frame status */
  437. {
  438. struct smt_header *sm ;
  439. int local ;
  440. int illegal = 0 ;
  441. switch (m_fc(mb)) {
  442. case FC_SMT_INFO :
  443. case FC_SMT_LAN_LOC :
  444. case FC_SMT_LOC :
  445. case FC_SMT_NSA :
  446. break ;
  447. default :
  448. smt_free_mbuf(smc,mb) ;
  449. return ;
  450. }
  451. smc->mib.m[MAC0].fddiMACSMTCopied_Ct++ ;
  452. sm = smtod(mb,struct smt_header *) ;
  453. local = ((fs & L_INDICATOR) != 0) ;
  454. hwm_conv_can(smc,(char *)sm,12) ;
  455. /* check destination address */
  456. if (is_individual(&sm->smt_dest) && !is_my_addr(smc,&sm->smt_dest)) {
  457. smt_free_mbuf(smc,mb) ;
  458. return ;
  459. }
  460. #if 0 /* for DUP recognition, do NOT filter them */
  461. /* ignore loop back packets */
  462. if (is_my_addr(smc,&sm->smt_source) && !local) {
  463. smt_free_mbuf(smc,mb) ;
  464. return ;
  465. }
  466. #endif
  467. smt_swap_para(sm,(int) mb->sm_len,1) ;
  468. DB_SMT("SMT : received packet [%s] at 0x%x\n",
  469. smt_type_name[m_fc(mb) & 0xf],sm) ;
  470. DB_SMT("SMT : version %d, class %s\n",sm->smt_version,
  471. smt_class_name[(sm->smt_class>LAST_CLASS)?0 : sm->smt_class]) ;
  472. #ifdef SBA
  473. /*
  474. * check if NSA frame
  475. */
  476. if (m_fc(mb) == FC_SMT_NSA && sm->smt_class == SMT_NIF &&
  477. (sm->smt_type == SMT_ANNOUNCE || sm->smt_type == SMT_REQUEST)) {
  478. smc->sba.sm = sm ;
  479. sba(smc,NIF) ;
  480. }
  481. #endif
  482. /*
  483. * ignore any packet with NSA and A-indicator set
  484. */
  485. if ( (fs & A_INDICATOR) && m_fc(mb) == FC_SMT_NSA) {
  486. DB_SMT("SMT : ignoring NSA with A-indicator set from %s\n",
  487. addr_to_string(&sm->smt_source),0) ;
  488. smt_free_mbuf(smc,mb) ;
  489. return ;
  490. }
  491. /*
  492. * ignore frames with illegal length
  493. */
  494. if (((sm->smt_class == SMT_ECF) && (sm->smt_len > SMT_MAX_ECHO_LEN)) ||
  495. ((sm->smt_class != SMT_ECF) && (sm->smt_len > SMT_MAX_INFO_LEN))) {
  496. smt_free_mbuf(smc,mb) ;
  497. return ;
  498. }
  499. /*
  500. * check SMT version
  501. */
  502. switch (sm->smt_class) {
  503. case SMT_NIF :
  504. case SMT_SIF_CONFIG :
  505. case SMT_SIF_OPER :
  506. case SMT_ECF :
  507. if (sm->smt_version != SMT_VID)
  508. illegal = 1;
  509. break ;
  510. default :
  511. if (sm->smt_version != SMT_VID_2)
  512. illegal = 1;
  513. break ;
  514. }
  515. if (illegal) {
  516. DB_SMT("SMT : version = %d, dest = %s\n",
  517. sm->smt_version,addr_to_string(&sm->smt_source)) ;
  518. smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_VERSION,local) ;
  519. smt_free_mbuf(smc,mb) ;
  520. return ;
  521. }
  522. if ((sm->smt_len > mb->sm_len - sizeof(struct smt_header)) ||
  523. ((sm->smt_len & 3) && (sm->smt_class != SMT_ECF))) {
  524. DB_SMT("SMT: info length error, len = %d\n",sm->smt_len,0) ;
  525. smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_LENGTH,local) ;
  526. smt_free_mbuf(smc,mb) ;
  527. return ;
  528. }
  529. switch (sm->smt_class) {
  530. case SMT_NIF :
  531. if (smt_check_para(smc,sm,plist_nif)) {
  532. DB_SMT("SMT: NIF with para problem, ignoring\n",0,0) ;
  533. break ;
  534. } ;
  535. switch (sm->smt_type) {
  536. case SMT_ANNOUNCE :
  537. case SMT_REQUEST :
  538. if (!(fs & C_INDICATOR) && m_fc(mb) == FC_SMT_NSA
  539. && is_broadcast(&sm->smt_dest)) {
  540. struct smt_p_state *st ;
  541. /* set my UNA */
  542. if (!is_equal(
  543. &smc->mib.m[MAC0].fddiMACUpstreamNbr,
  544. &sm->smt_source)) {
  545. DB_SMT("SMT : updated my UNA = %s\n",
  546. addr_to_string(&sm->smt_source),0) ;
  547. if (!is_equal(&smc->mib.m[MAC0].
  548. fddiMACUpstreamNbr,&SMT_Unknown)){
  549. /* Do not update unknown address */
  550. smc->mib.m[MAC0].fddiMACOldUpstreamNbr=
  551. smc->mib.m[MAC0].fddiMACUpstreamNbr ;
  552. }
  553. smc->mib.m[MAC0].fddiMACUpstreamNbr =
  554. sm->smt_source ;
  555. smt_srf_event(smc,
  556. SMT_EVENT_MAC_NEIGHBOR_CHANGE,
  557. INDEX_MAC,0) ;
  558. smt_echo_test(smc,0) ;
  559. }
  560. smc->sm.smt_tvu = smt_get_time() ;
  561. st = (struct smt_p_state *)
  562. sm_to_para(smc,sm,SMT_P_STATE) ;
  563. if (st) {
  564. smc->mib.m[MAC0].fddiMACUNDA_Flag =
  565. (st->st_dupl_addr & SMT_ST_MY_DUPA) ?
  566. TRUE : FALSE ;
  567. update_dac(smc,1) ;
  568. }
  569. }
  570. if ((sm->smt_type == SMT_REQUEST) &&
  571. is_individual(&sm->smt_source) &&
  572. ((!(fs & A_INDICATOR) && m_fc(mb) == FC_SMT_NSA) ||
  573. (m_fc(mb) != FC_SMT_NSA))) {
  574. DB_SMT("SMT : replying to NIF request %s\n",
  575. addr_to_string(&sm->smt_source),0) ;
  576. smt_send_nif(smc,&sm->smt_source,
  577. FC_SMT_INFO,
  578. sm->smt_tid,
  579. SMT_REPLY,local) ;
  580. }
  581. break ;
  582. case SMT_REPLY :
  583. DB_SMT("SMT : received NIF response from %s\n",
  584. addr_to_string(&sm->smt_source),0) ;
  585. if (fs & A_INDICATOR) {
  586. smc->sm.pend[SMT_TID_NIF] = 0 ;
  587. DB_SMT("SMT : duplicate address\n",0,0) ;
  588. smc->mib.m[MAC0].fddiMACDupAddressTest =
  589. DA_FAILED ;
  590. smc->r.dup_addr_test = DA_FAILED ;
  591. queue_event(smc,EVENT_RMT,RM_DUP_ADDR) ;
  592. smc->mib.m[MAC0].fddiMACDA_Flag = TRUE ;
  593. update_dac(smc,1) ;
  594. break ;
  595. }
  596. if (sm->smt_tid == smc->sm.pend[SMT_TID_NIF]) {
  597. smc->sm.pend[SMT_TID_NIF] = 0 ;
  598. /* set my DNA */
  599. if (!is_equal(
  600. &smc->mib.m[MAC0].fddiMACDownstreamNbr,
  601. &sm->smt_source)) {
  602. DB_SMT("SMT : updated my DNA\n",0,0) ;
  603. if (!is_equal(&smc->mib.m[MAC0].
  604. fddiMACDownstreamNbr, &SMT_Unknown)){
  605. /* Do not update unknown address */
  606. smc->mib.m[MAC0].fddiMACOldDownstreamNbr =
  607. smc->mib.m[MAC0].fddiMACDownstreamNbr ;
  608. }
  609. smc->mib.m[MAC0].fddiMACDownstreamNbr =
  610. sm->smt_source ;
  611. smt_srf_event(smc,
  612. SMT_EVENT_MAC_NEIGHBOR_CHANGE,
  613. INDEX_MAC,0) ;
  614. smt_echo_test(smc,1) ;
  615. }
  616. smc->mib.m[MAC0].fddiMACDA_Flag = FALSE ;
  617. update_dac(smc,1) ;
  618. smc->sm.smt_tvd = smt_get_time() ;
  619. smc->mib.m[MAC0].fddiMACDupAddressTest =
  620. DA_PASSED ;
  621. if (smc->r.dup_addr_test != DA_PASSED) {
  622. smc->r.dup_addr_test = DA_PASSED ;
  623. queue_event(smc,EVENT_RMT,RM_DUP_ADDR) ;
  624. }
  625. }
  626. else if (sm->smt_tid ==
  627. smc->sm.pend[SMT_TID_NIF_TEST]) {
  628. DB_SMT("SMT : NIF test TID ok\n",0,0) ;
  629. }
  630. else {
  631. DB_SMT("SMT : expected TID %lx, got %lx\n",
  632. smc->sm.pend[SMT_TID_NIF],sm->smt_tid) ;
  633. }
  634. break ;
  635. default :
  636. illegal = 2 ;
  637. break ;
  638. }
  639. break ;
  640. case SMT_SIF_CONFIG : /* station information */
  641. if (sm->smt_type != SMT_REQUEST)
  642. break ;
  643. DB_SMT("SMT : replying to SIF Config request from %s\n",
  644. addr_to_string(&sm->smt_source),0) ;
  645. smt_send_sif_config(smc,&sm->smt_source,sm->smt_tid,local) ;
  646. break ;
  647. case SMT_SIF_OPER : /* station information */
  648. if (sm->smt_type != SMT_REQUEST)
  649. break ;
  650. DB_SMT("SMT : replying to SIF Operation request from %s\n",
  651. addr_to_string(&sm->smt_source),0) ;
  652. smt_send_sif_operation(smc,&sm->smt_source,sm->smt_tid,local) ;
  653. break ;
  654. case SMT_ECF : /* echo frame */
  655. switch (sm->smt_type) {
  656. case SMT_REPLY :
  657. smc->mib.priv.fddiPRIVECF_Reply_Rx++ ;
  658. DB_SMT("SMT: received ECF reply from %s\n",
  659. addr_to_string(&sm->smt_source),0) ;
  660. if (sm_to_para(smc,sm,SMT_P_ECHODATA) == 0) {
  661. DB_SMT("SMT: ECHODATA missing\n",0,0) ;
  662. break ;
  663. }
  664. if (sm->smt_tid == smc->sm.pend[SMT_TID_ECF]) {
  665. DB_SMT("SMT : ECF test TID ok\n",0,0) ;
  666. }
  667. else if (sm->smt_tid == smc->sm.pend[SMT_TID_ECF_UNA]) {
  668. DB_SMT("SMT : ECF test UNA ok\n",0,0) ;
  669. }
  670. else if (sm->smt_tid == smc->sm.pend[SMT_TID_ECF_DNA]) {
  671. DB_SMT("SMT : ECF test DNA ok\n",0,0) ;
  672. }
  673. else {
  674. DB_SMT("SMT : expected TID %lx, got %lx\n",
  675. smc->sm.pend[SMT_TID_ECF],
  676. sm->smt_tid) ;
  677. }
  678. break ;
  679. case SMT_REQUEST :
  680. smc->mib.priv.fddiPRIVECF_Req_Rx++ ;
  681. {
  682. if (sm->smt_len && !sm_to_para(smc,sm,SMT_P_ECHODATA)) {
  683. DB_SMT("SMT: ECF with para problem,sending RDF\n",0,0) ;
  684. smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_LENGTH,
  685. local) ;
  686. break ;
  687. }
  688. DB_SMT("SMT - sending ECF reply to %s\n",
  689. addr_to_string(&sm->smt_source),0) ;
  690. /* set destination addr. & reply */
  691. sm->smt_dest = sm->smt_source ;
  692. sm->smt_type = SMT_REPLY ;
  693. dump_smt(smc,sm,"ECF REPLY") ;
  694. smc->mib.priv.fddiPRIVECF_Reply_Tx++ ;
  695. smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
  696. return ; /* DON'T free mbuf */
  697. }
  698. default :
  699. illegal = 1 ;
  700. break ;
  701. }
  702. break ;
  703. #ifndef BOOT
  704. case SMT_RAF : /* resource allocation */
  705. #ifdef ESS
  706. DB_ESSN(2,"ESS: RAF frame received\n",0,0) ;
  707. fs = ess_raf_received_pack(smc,mb,sm,fs) ;
  708. #endif
  709. #ifdef SBA
  710. DB_SBAN(2,"SBA: RAF frame received\n",0,0) ;
  711. sba_raf_received_pack(smc,sm,fs) ;
  712. #endif
  713. break ;
  714. case SMT_RDF : /* request denied */
  715. smc->mib.priv.fddiPRIVRDF_Rx++ ;
  716. break ;
  717. case SMT_ESF : /* extended service - not supported */
  718. if (sm->smt_type == SMT_REQUEST) {
  719. DB_SMT("SMT - received ESF, sending RDF\n",0,0) ;
  720. smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_CLASS,local) ;
  721. }
  722. break ;
  723. case SMT_PMF_GET :
  724. case SMT_PMF_SET :
  725. if (sm->smt_type != SMT_REQUEST)
  726. break ;
  727. /* update statistics */
  728. if (sm->smt_class == SMT_PMF_GET)
  729. smc->mib.priv.fddiPRIVPMF_Get_Rx++ ;
  730. else
  731. smc->mib.priv.fddiPRIVPMF_Set_Rx++ ;
  732. /*
  733. * ignore PMF SET with I/G set
  734. */
  735. if ((sm->smt_class == SMT_PMF_SET) &&
  736. !is_individual(&sm->smt_dest)) {
  737. DB_SMT("SMT: ignoring PMF-SET with I/G set\n",0,0) ;
  738. break ;
  739. }
  740. smt_pmf_received_pack(smc,mb, local) ;
  741. break ;
  742. case SMT_SRF :
  743. dump_smt(smc,sm,"SRF received") ;
  744. break ;
  745. default :
  746. if (sm->smt_type != SMT_REQUEST)
  747. break ;
  748. /*
  749. * For frames with unknown class:
  750. * we need to send a RDF frame according to 8.1.3.1.1,
  751. * only if it is a REQUEST.
  752. */
  753. DB_SMT("SMT : class = %d, send RDF to %s\n",
  754. sm->smt_class, addr_to_string(&sm->smt_source)) ;
  755. smt_send_rdf(smc,mb,m_fc(mb),SMT_RDF_CLASS,local) ;
  756. break ;
  757. #endif
  758. }
  759. if (illegal) {
  760. DB_SMT("SMT: discarding invalid frame, reason = %d\n",
  761. illegal,0) ;
  762. }
  763. smt_free_mbuf(smc,mb) ;
  764. }
  765. static void update_dac(struct s_smc *smc, int report)
  766. {
  767. int cond ;
  768. cond = ( smc->mib.m[MAC0].fddiMACUNDA_Flag |
  769. smc->mib.m[MAC0].fddiMACDA_Flag) != 0 ;
  770. if (report && (cond != smc->mib.m[MAC0].fddiMACDuplicateAddressCond))
  771. smt_srf_event(smc, SMT_COND_MAC_DUP_ADDR,INDEX_MAC,cond) ;
  772. else
  773. smc->mib.m[MAC0].fddiMACDuplicateAddressCond = cond ;
  774. }
  775. /*
  776. * send SMT frame
  777. * set source address
  778. * set station ID
  779. * send frame
  780. */
  781. void smt_send_frame(struct s_smc *smc, SMbuf *mb, int fc, int local)
  782. /* SMbuf *mb; buffer to send */
  783. /* int fc; FC value */
  784. {
  785. struct smt_header *sm ;
  786. if (!smc->r.sm_ma_avail && !local) {
  787. smt_free_mbuf(smc,mb) ;
  788. return ;
  789. }
  790. sm = smtod(mb,struct smt_header *) ;
  791. sm->smt_source = smc->mib.m[MAC0].fddiMACSMTAddress ;
  792. sm->smt_sid = smc->mib.fddiSMTStationId ;
  793. smt_swap_para(sm,(int) mb->sm_len,0) ; /* swap para & header */
  794. hwm_conv_can(smc,(char *)sm,12) ; /* convert SA and DA */
  795. smc->mib.m[MAC0].fddiMACSMTTransmit_Ct++ ;
  796. smt_send_mbuf(smc,mb,local ? FC_SMT_LOC : fc) ;
  797. }
  798. /*
  799. * generate and send RDF
  800. */
  801. static void smt_send_rdf(struct s_smc *smc, SMbuf *rej, int fc, int reason,
  802. int local)
  803. /* SMbuf *rej; mbuf of offending frame */
  804. /* int fc; FC of denied frame */
  805. /* int reason; reason code */
  806. {
  807. SMbuf *mb ;
  808. struct smt_header *sm ; /* header of offending frame */
  809. struct smt_rdf *rdf ;
  810. int len ;
  811. int frame_len ;
  812. sm = smtod(rej,struct smt_header *) ;
  813. if (sm->smt_type != SMT_REQUEST)
  814. return ;
  815. DB_SMT("SMT: sending RDF to %s,reason = 0x%x\n",
  816. addr_to_string(&sm->smt_source),reason) ;
  817. /*
  818. * note: get framelength from MAC length, NOT from SMT header
  819. * smt header length is included in sm_len
  820. */
  821. frame_len = rej->sm_len ;
  822. if (!(mb=smt_build_frame(smc,SMT_RDF,SMT_REPLY,sizeof(struct smt_rdf))))
  823. return ;
  824. rdf = smtod(mb,struct smt_rdf *) ;
  825. rdf->smt.smt_tid = sm->smt_tid ; /* use TID from sm */
  826. rdf->smt.smt_dest = sm->smt_source ; /* set dest = source */
  827. /* set P12 */
  828. rdf->reason.para.p_type = SMT_P_REASON ;
  829. rdf->reason.para.p_len = sizeof(struct smt_p_reason) - PARA_LEN ;
  830. rdf->reason.rdf_reason = reason ;
  831. /* set P14 */
  832. rdf->version.para.p_type = SMT_P_VERSION ;
  833. rdf->version.para.p_len = sizeof(struct smt_p_version) - PARA_LEN ;
  834. rdf->version.v_pad = 0 ;
  835. rdf->version.v_n = 1 ;
  836. rdf->version.v_index = 1 ;
  837. rdf->version.v_version[0] = SMT_VID_2 ;
  838. rdf->version.v_pad2 = 0 ;
  839. /* set P13 */
  840. if ((unsigned) frame_len <= SMT_MAX_INFO_LEN - sizeof(*rdf) +
  841. 2*sizeof(struct smt_header))
  842. len = frame_len ;
  843. else
  844. len = SMT_MAX_INFO_LEN - sizeof(*rdf) +
  845. 2*sizeof(struct smt_header) ;
  846. /* make length multiple of 4 */
  847. len &= ~3 ;
  848. rdf->refused.para.p_type = SMT_P_REFUSED ;
  849. /* length of para is smt_frame + ref_fc */
  850. rdf->refused.para.p_len = len + 4 ;
  851. rdf->refused.ref_fc = fc ;
  852. /* swap it back */
  853. smt_swap_para(sm,frame_len,0) ;
  854. memcpy((char *) &rdf->refused.ref_header,(char *) sm,len) ;
  855. len -= sizeof(struct smt_header) ;
  856. mb->sm_len += len ;
  857. rdf->smt.smt_len += len ;
  858. dump_smt(smc,(struct smt_header *)rdf,"RDF") ;
  859. smc->mib.priv.fddiPRIVRDF_Tx++ ;
  860. smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
  861. }
  862. /*
  863. * generate and send NIF
  864. */
  865. static void smt_send_nif(struct s_smc *smc, const struct fddi_addr *dest,
  866. int fc, u_long tid, int type, int local)
  867. /* struct fddi_addr *dest; dest address */
  868. /* int fc; frame control */
  869. /* u_long tid; transaction id */
  870. /* int type; frame type */
  871. {
  872. struct smt_nif *nif ;
  873. SMbuf *mb ;
  874. if (!(mb = smt_build_frame(smc,SMT_NIF,type,sizeof(struct smt_nif))))
  875. return ;
  876. nif = smtod(mb, struct smt_nif *) ;
  877. smt_fill_una(smc,&nif->una) ; /* set UNA */
  878. smt_fill_sde(smc,&nif->sde) ; /* set station descriptor */
  879. smt_fill_state(smc,&nif->state) ; /* set state information */
  880. #ifdef SMT6_10
  881. smt_fill_fsc(smc,&nif->fsc) ; /* set frame status cap. */
  882. #endif
  883. nif->smt.smt_dest = *dest ; /* destination address */
  884. nif->smt.smt_tid = tid ; /* transaction ID */
  885. dump_smt(smc,(struct smt_header *)nif,"NIF") ;
  886. smt_send_frame(smc,mb,fc,local) ;
  887. }
  888. #ifdef DEBUG
  889. /*
  890. * send NIF request (test purpose)
  891. */
  892. static void smt_send_nif_request(struct s_smc *smc, struct fddi_addr *dest)
  893. {
  894. smc->sm.pend[SMT_TID_NIF_TEST] = smt_get_tid(smc) ;
  895. smt_send_nif(smc,dest, FC_SMT_INFO, smc->sm.pend[SMT_TID_NIF_TEST],
  896. SMT_REQUEST,0) ;
  897. }
  898. /*
  899. * send ECF request (test purpose)
  900. */
  901. static void smt_send_ecf_request(struct s_smc *smc, struct fddi_addr *dest,
  902. int len)
  903. {
  904. smc->sm.pend[SMT_TID_ECF] = smt_get_tid(smc) ;
  905. smt_send_ecf(smc,dest, FC_SMT_INFO, smc->sm.pend[SMT_TID_ECF],
  906. SMT_REQUEST,len) ;
  907. }
  908. #endif
  909. /*
  910. * echo test
  911. */
  912. static void smt_echo_test(struct s_smc *smc, int dna)
  913. {
  914. u_long tid ;
  915. smc->sm.pend[dna ? SMT_TID_ECF_DNA : SMT_TID_ECF_UNA] =
  916. tid = smt_get_tid(smc) ;
  917. smt_send_ecf(smc, dna ?
  918. &smc->mib.m[MAC0].fddiMACDownstreamNbr :
  919. &smc->mib.m[MAC0].fddiMACUpstreamNbr,
  920. FC_SMT_INFO,tid, SMT_REQUEST, (SMT_TEST_ECHO_LEN & ~3)-8) ;
  921. }
  922. /*
  923. * generate and send ECF
  924. */
  925. static void smt_send_ecf(struct s_smc *smc, struct fddi_addr *dest, int fc,
  926. u_long tid, int type, int len)
  927. /* struct fddi_addr *dest; dest address */
  928. /* int fc; frame control */
  929. /* u_long tid; transaction id */
  930. /* int type; frame type */
  931. /* int len; frame length */
  932. {
  933. struct smt_ecf *ecf ;
  934. SMbuf *mb ;
  935. if (!(mb = smt_build_frame(smc,SMT_ECF,type,SMT_ECF_LEN + len)))
  936. return ;
  937. ecf = smtod(mb, struct smt_ecf *) ;
  938. smt_fill_echo(smc,&ecf->ec_echo,tid,len) ; /* set ECHO */
  939. ecf->smt.smt_dest = *dest ; /* destination address */
  940. ecf->smt.smt_tid = tid ; /* transaction ID */
  941. smc->mib.priv.fddiPRIVECF_Req_Tx++ ;
  942. smt_send_frame(smc,mb,fc,0) ;
  943. }
  944. /*
  945. * generate and send SIF config response
  946. */
  947. static void smt_send_sif_config(struct s_smc *smc, struct fddi_addr *dest,
  948. u_long tid, int local)
  949. /* struct fddi_addr *dest; dest address */
  950. /* u_long tid; transaction id */
  951. {
  952. struct smt_sif_config *sif ;
  953. SMbuf *mb ;
  954. int len ;
  955. if (!(mb = smt_build_frame(smc,SMT_SIF_CONFIG,SMT_REPLY,
  956. SIZEOF_SMT_SIF_CONFIG)))
  957. return ;
  958. sif = smtod(mb, struct smt_sif_config *) ;
  959. smt_fill_timestamp(smc,&sif->ts) ; /* set time stamp */
  960. smt_fill_sde(smc,&sif->sde) ; /* set station descriptor */
  961. smt_fill_version(smc,&sif->version) ; /* set version information */
  962. smt_fill_state(smc,&sif->state) ; /* set state information */
  963. smt_fill_policy(smc,&sif->policy) ; /* set station policy */
  964. smt_fill_latency(smc,&sif->latency); /* set station latency */
  965. smt_fill_neighbor(smc,&sif->neighbor); /* set station neighbor */
  966. smt_fill_setcount(smc,&sif->setcount) ; /* set count */
  967. len = smt_fill_path(smc,&sif->path); /* set station path descriptor*/
  968. sif->smt.smt_dest = *dest ; /* destination address */
  969. sif->smt.smt_tid = tid ; /* transaction ID */
  970. smt_add_frame_len(mb,len) ; /* adjust length fields */
  971. dump_smt(smc,(struct smt_header *)sif,"SIF Configuration Reply") ;
  972. smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
  973. }
  974. /*
  975. * generate and send SIF operation response
  976. */
  977. static void smt_send_sif_operation(struct s_smc *smc, struct fddi_addr *dest,
  978. u_long tid, int local)
  979. /* struct fddi_addr *dest; dest address */
  980. /* u_long tid; transaction id */
  981. {
  982. struct smt_sif_operation *sif ;
  983. SMbuf *mb ;
  984. int ports ;
  985. int i ;
  986. ports = NUMPHYS ;
  987. #ifndef CONCENTRATOR
  988. if (smc->s.sas == SMT_SAS)
  989. ports = 1 ;
  990. #endif
  991. if (!(mb = smt_build_frame(smc,SMT_SIF_OPER,SMT_REPLY,
  992. SIZEOF_SMT_SIF_OPERATION+ports*sizeof(struct smt_p_lem))))
  993. return ;
  994. sif = smtod(mb, struct smt_sif_operation *) ;
  995. smt_fill_timestamp(smc,&sif->ts) ; /* set time stamp */
  996. smt_fill_mac_status(smc,&sif->status) ; /* set mac status */
  997. smt_fill_mac_counter(smc,&sif->mc) ; /* set mac counter field */
  998. smt_fill_mac_fnc(smc,&sif->fnc) ; /* set frame not copied counter */
  999. smt_fill_manufacturer(smc,&sif->man) ; /* set manufacturer field */
  1000. smt_fill_user(smc,&sif->user) ; /* set user field */
  1001. smt_fill_setcount(smc,&sif->setcount) ; /* set count */
  1002. /*
  1003. * set link error mon information
  1004. */
  1005. if (ports == 1) {
  1006. smt_fill_lem(smc,sif->lem,PS) ;
  1007. }
  1008. else {
  1009. for (i = 0 ; i < ports ; i++) {
  1010. smt_fill_lem(smc,&sif->lem[i],i) ;
  1011. }
  1012. }
  1013. sif->smt.smt_dest = *dest ; /* destination address */
  1014. sif->smt.smt_tid = tid ; /* transaction ID */
  1015. dump_smt(smc,(struct smt_header *)sif,"SIF Operation Reply") ;
  1016. smt_send_frame(smc,mb,FC_SMT_INFO,local) ;
  1017. }
  1018. /*
  1019. * get and initialize SMT frame
  1020. */
  1021. SMbuf *smt_build_frame(struct s_smc *smc, int class, int type,
  1022. int length)
  1023. {
  1024. SMbuf *mb ;
  1025. struct smt_header *smt ;
  1026. #if 0
  1027. if (!smc->r.sm_ma_avail) {
  1028. return(0) ;
  1029. }
  1030. #endif
  1031. if (!(mb = smt_get_mbuf(smc)))
  1032. return(mb) ;
  1033. mb->sm_len = length ;
  1034. smt = smtod(mb, struct smt_header *) ;
  1035. smt->smt_dest = fddi_broadcast ; /* set dest = broadcast */
  1036. smt->smt_class = class ;
  1037. smt->smt_type = type ;
  1038. switch (class) {
  1039. case SMT_NIF :
  1040. case SMT_SIF_CONFIG :
  1041. case SMT_SIF_OPER :
  1042. case SMT_ECF :
  1043. smt->smt_version = SMT_VID ;
  1044. break ;
  1045. default :
  1046. smt->smt_version = SMT_VID_2 ;
  1047. break ;
  1048. }
  1049. smt->smt_tid = smt_get_tid(smc) ; /* set transaction ID */
  1050. smt->smt_pad = 0 ;
  1051. smt->smt_len = length - sizeof(struct smt_header) ;
  1052. return(mb) ;
  1053. }
  1054. static void smt_add_frame_len(SMbuf *mb, int len)
  1055. {
  1056. struct smt_header *smt ;
  1057. smt = smtod(mb, struct smt_header *) ;
  1058. smt->smt_len += len ;
  1059. mb->sm_len += len ;
  1060. }
  1061. /*
  1062. * fill values in UNA parameter
  1063. */
  1064. static void smt_fill_una(struct s_smc *smc, struct smt_p_una *una)
  1065. {
  1066. SMTSETPARA(una,SMT_P_UNA) ;
  1067. una->una_pad = 0 ;
  1068. una->una_node = smc->mib.m[MAC0].fddiMACUpstreamNbr ;
  1069. }
  1070. /*
  1071. * fill values in SDE parameter
  1072. */
  1073. static void smt_fill_sde(struct s_smc *smc, struct smt_p_sde *sde)
  1074. {
  1075. SMTSETPARA(sde,SMT_P_SDE) ;
  1076. sde->sde_non_master = smc->mib.fddiSMTNonMaster_Ct ;
  1077. sde->sde_master = smc->mib.fddiSMTMaster_Ct ;
  1078. sde->sde_mac_count = NUMMACS ; /* only 1 MAC */
  1079. #ifdef CONCENTRATOR
  1080. sde->sde_type = SMT_SDE_CONCENTRATOR ;
  1081. #else
  1082. sde->sde_type = SMT_SDE_STATION ;
  1083. #endif
  1084. }
  1085. /*
  1086. * fill in values in station state parameter
  1087. */
  1088. static void smt_fill_state(struct s_smc *smc, struct smt_p_state *state)
  1089. {
  1090. int top ;
  1091. int twist ;
  1092. SMTSETPARA(state,SMT_P_STATE) ;
  1093. state->st_pad = 0 ;
  1094. /* determine topology */
  1095. top = 0 ;
  1096. if (smc->mib.fddiSMTPeerWrapFlag) {
  1097. top |= SMT_ST_WRAPPED ; /* state wrapped */
  1098. }
  1099. #ifdef CONCENTRATOR
  1100. if (cfm_status_unattached(smc)) {
  1101. top |= SMT_ST_UNATTACHED ; /* unattached concentrator */
  1102. }
  1103. #endif
  1104. if ((twist = pcm_status_twisted(smc)) & 1) {
  1105. top |= SMT_ST_TWISTED_A ; /* twisted cable */
  1106. }
  1107. if (twist & 2) {
  1108. top |= SMT_ST_TWISTED_B ; /* twisted cable */
  1109. }
  1110. #ifdef OPT_SRF
  1111. top |= SMT_ST_SRF ;
  1112. #endif
  1113. if (pcm_rooted_station(smc))
  1114. top |= SMT_ST_ROOTED_S ;
  1115. if (smc->mib.a[0].fddiPATHSbaPayload != 0)
  1116. top |= SMT_ST_SYNC_SERVICE ;
  1117. state->st_topology = top ;
  1118. state->st_dupl_addr =
  1119. ((smc->mib.m[MAC0].fddiMACDA_Flag ? SMT_ST_MY_DUPA : 0 ) |
  1120. (smc->mib.m[MAC0].fddiMACUNDA_Flag ? SMT_ST_UNA_DUPA : 0)) ;
  1121. }
  1122. /*
  1123. * fill values in timestamp parameter
  1124. */
  1125. static void smt_fill_timestamp(struct s_smc *smc, struct smt_p_timestamp *ts)
  1126. {
  1127. SMTSETPARA(ts,SMT_P_TIMESTAMP) ;
  1128. smt_set_timestamp(smc,ts->ts_time) ;
  1129. }
  1130. void smt_set_timestamp(struct s_smc *smc, u_char *p)
  1131. {
  1132. u_long time ;
  1133. u_long utime ;
  1134. /*
  1135. * timestamp is 64 bits long ; resolution is 80 nS
  1136. * our clock resolution is 10mS
  1137. * 10mS/80ns = 125000 ~ 2^17 = 131072
  1138. */
  1139. utime = smt_get_time() ;
  1140. time = utime * 100 ;
  1141. time /= TICKS_PER_SECOND ;
  1142. p[0] = 0 ;
  1143. p[1] = (u_char)((time>>(8+8+8+8-1)) & 1) ;
  1144. p[2] = (u_char)(time>>(8+8+8-1)) ;
  1145. p[3] = (u_char)(time>>(8+8-1)) ;
  1146. p[4] = (u_char)(time>>(8-1)) ;
  1147. p[5] = (u_char)(time<<1) ;
  1148. p[6] = (u_char)(smc->sm.uniq_ticks>>8) ;
  1149. p[7] = (u_char)smc->sm.uniq_ticks ;
  1150. /*
  1151. * make sure we don't wrap: restart whenever the upper digits change
  1152. */
  1153. if (utime != smc->sm.uniq_time) {
  1154. smc->sm.uniq_ticks = 0 ;
  1155. }
  1156. smc->sm.uniq_ticks++ ;
  1157. smc->sm.uniq_time = utime ;
  1158. }
  1159. /*
  1160. * fill values in station policy parameter
  1161. */
  1162. static void smt_fill_policy(struct s_smc *smc, struct smt_p_policy *policy)
  1163. {
  1164. int i ;
  1165. u_char *map ;
  1166. u_short in ;
  1167. u_short out ;
  1168. /*
  1169. * MIB para 101b (fddiSMTConnectionPolicy) coding
  1170. * is different from 0005 coding
  1171. */
  1172. static u_char ansi_weirdness[16] = {
  1173. 0,7,5,3,8,1,6,4,9,10,2,11,12,13,14,15
  1174. } ;
  1175. SMTSETPARA(policy,SMT_P_POLICY) ;
  1176. out = 0 ;
  1177. in = smc->mib.fddiSMTConnectionPolicy ;
  1178. for (i = 0, map = ansi_weirdness ; i < 16 ; i++) {
  1179. if (in & 1)
  1180. out |= (1<<*map) ;
  1181. in >>= 1 ;
  1182. map++ ;
  1183. }
  1184. policy->pl_config = smc->mib.fddiSMTConfigPolicy ;
  1185. policy->pl_connect = out ;
  1186. }
  1187. /*
  1188. * fill values in latency equivalent parameter
  1189. */
  1190. static void smt_fill_latency(struct s_smc *smc, struct smt_p_latency *latency)
  1191. {
  1192. SMTSETPARA(latency,SMT_P_LATENCY) ;
  1193. latency->lt_phyout_idx1 = phy_index(smc,0) ;
  1194. latency->lt_latency1 = 10 ; /* in octets (byte clock) */
  1195. /*
  1196. * note: latency has two phy entries by definition
  1197. * for a SAS, the 2nd one is null
  1198. */
  1199. if (smc->s.sas == SMT_DAS) {
  1200. latency->lt_phyout_idx2 = phy_index(smc,1) ;
  1201. latency->lt_latency2 = 10 ; /* in octets (byte clock) */
  1202. }
  1203. else {
  1204. latency->lt_phyout_idx2 = 0 ;
  1205. latency->lt_latency2 = 0 ;
  1206. }
  1207. }
  1208. /*
  1209. * fill values in MAC neighbors parameter
  1210. */
  1211. static void smt_fill_neighbor(struct s_smc *smc, struct smt_p_neighbor *neighbor)
  1212. {
  1213. SMTSETPARA(neighbor,SMT_P_NEIGHBORS) ;
  1214. neighbor->nb_mib_index = INDEX_MAC ;
  1215. neighbor->nb_mac_index = mac_index(smc,1) ;
  1216. neighbor->nb_una = smc->mib.m[MAC0].fddiMACUpstreamNbr ;
  1217. neighbor->nb_dna = smc->mib.m[MAC0].fddiMACDownstreamNbr ;
  1218. }
  1219. /*
  1220. * fill values in path descriptor
  1221. */
  1222. #ifdef CONCENTRATOR
  1223. #define ALLPHYS NUMPHYS
  1224. #else
  1225. #define ALLPHYS ((smc->s.sas == SMT_SAS) ? 1 : 2)
  1226. #endif
  1227. static int smt_fill_path(struct s_smc *smc, struct smt_p_path *path)
  1228. {
  1229. SK_LOC_DECL(int,type) ;
  1230. SK_LOC_DECL(int,state) ;
  1231. SK_LOC_DECL(int,remote) ;
  1232. SK_LOC_DECL(int,mac) ;
  1233. int len ;
  1234. int p ;
  1235. int physp ;
  1236. struct smt_phy_rec *phy ;
  1237. struct smt_mac_rec *pd_mac ;
  1238. len = PARA_LEN +
  1239. sizeof(struct smt_mac_rec) * NUMMACS +
  1240. sizeof(struct smt_phy_rec) * ALLPHYS ;
  1241. path->para.p_type = SMT_P_PATH ;
  1242. path->para.p_len = len - PARA_LEN ;
  1243. /* PHYs */
  1244. for (p = 0,phy = path->pd_phy ; p < ALLPHYS ; p++, phy++) {
  1245. physp = p ;
  1246. #ifndef CONCENTRATOR
  1247. if (smc->s.sas == SMT_SAS)
  1248. physp = PS ;
  1249. #endif
  1250. pcm_status_state(smc,physp,&type,&state,&remote,&mac) ;
  1251. #ifdef LITTLE_ENDIAN
  1252. phy->phy_mib_index = smt_swap_short((u_short)p+INDEX_PORT) ;
  1253. #else
  1254. phy->phy_mib_index = p+INDEX_PORT ;
  1255. #endif
  1256. phy->phy_type = type ;
  1257. phy->phy_connect_state = state ;
  1258. phy->phy_remote_type = remote ;
  1259. phy->phy_remote_mac = mac ;
  1260. phy->phy_resource_idx = phy_con_resource_index(smc,p) ;
  1261. }
  1262. /* MAC */
  1263. pd_mac = (struct smt_mac_rec *) phy ;
  1264. pd_mac->mac_addr = smc->mib.m[MAC0].fddiMACSMTAddress ;
  1265. pd_mac->mac_resource_idx = mac_con_resource_index(smc,1) ;
  1266. return(len) ;
  1267. }
  1268. /*
  1269. * fill values in mac status
  1270. */
  1271. static void smt_fill_mac_status(struct s_smc *smc, struct smt_p_mac_status *st)
  1272. {
  1273. SMTSETPARA(st,SMT_P_MAC_STATUS) ;
  1274. st->st_mib_index = INDEX_MAC ;
  1275. st->st_mac_index = mac_index(smc,1) ;
  1276. mac_update_counter(smc) ;
  1277. /*
  1278. * timer values are represented in SMT as 2's complement numbers
  1279. * units : internal : 2's complement BCLK
  1280. */
  1281. st->st_t_req = smc->mib.m[MAC0].fddiMACT_Req ;
  1282. st->st_t_neg = smc->mib.m[MAC0].fddiMACT_Neg ;
  1283. st->st_t_max = smc->mib.m[MAC0].fddiMACT_Max ;
  1284. st->st_tvx_value = smc->mib.m[MAC0].fddiMACTvxValue ;
  1285. st->st_t_min = smc->mib.m[MAC0].fddiMACT_Min ;
  1286. st->st_sba = smc->mib.a[PATH0].fddiPATHSbaPayload ;
  1287. st->st_frame_ct = smc->mib.m[MAC0].fddiMACFrame_Ct ;
  1288. st->st_error_ct = smc->mib.m[MAC0].fddiMACError_Ct ;
  1289. st->st_lost_ct = smc->mib.m[MAC0].fddiMACLost_Ct ;
  1290. }
  1291. /*
  1292. * fill values in LEM status
  1293. */
  1294. static void smt_fill_lem(struct s_smc *smc, struct smt_p_lem *lem, int phy)
  1295. {
  1296. struct fddi_mib_p *mib ;
  1297. mib = smc->y[phy].mib ;
  1298. SMTSETPARA(lem,SMT_P_LEM) ;
  1299. lem->lem_mib_index = phy+INDEX_PORT ;
  1300. lem->lem_phy_index = phy_index(smc,phy) ;
  1301. lem->lem_pad2 = 0 ;
  1302. lem->lem_cutoff = mib->fddiPORTLer_Cutoff ;
  1303. lem->lem_alarm = mib->fddiPORTLer_Alarm ;
  1304. /* long term bit error rate */
  1305. lem->lem_estimate = mib->fddiPORTLer_Estimate ;
  1306. /* # of rejected connections */
  1307. lem->lem_reject_ct = mib->fddiPORTLem_Reject_Ct ;
  1308. lem->lem_ct = mib->fddiPORTLem_Ct ; /* total number of errors */
  1309. }
  1310. /*
  1311. * fill version parameter
  1312. */
  1313. static void smt_fill_version(struct s_smc *smc, struct smt_p_version *vers)
  1314. {
  1315. SK_UNUSED(smc) ;
  1316. SMTSETPARA(vers,SMT_P_VERSION) ;
  1317. vers->v_pad = 0 ;
  1318. vers->v_n = 1 ; /* one version is enough .. */
  1319. vers->v_index = 1 ;
  1320. vers->v_version[0] = SMT_VID_2 ;
  1321. vers->v_pad2 = 0 ;
  1322. }
  1323. #ifdef SMT6_10
  1324. /*
  1325. * fill frame status capabilities
  1326. */
  1327. /*
  1328. * note: this para 200B is NOT in swap table, because it's also set in
  1329. * PMF add_para
  1330. */
  1331. static void smt_fill_fsc(struct s_smc *smc, struct smt_p_fsc *fsc)
  1332. {
  1333. SK_UNUSED(smc) ;
  1334. SMTSETPARA(fsc,SMT_P_FSC) ;
  1335. fsc->fsc_pad0 = 0 ;
  1336. fsc->fsc_mac_index = INDEX_MAC ; /* this is MIB ; MIB is NOT
  1337. * mac_index ()i !
  1338. */
  1339. fsc->fsc_pad1 = 0 ;
  1340. fsc->fsc_value = FSC_TYPE0 ; /* "normal" node */
  1341. #ifdef LITTLE_ENDIAN
  1342. fsc->fsc_mac_index = smt_swap_short(INDEX_MAC) ;
  1343. fsc->fsc_value = smt_swap_short(FSC_TYPE0) ;
  1344. #endif
  1345. }
  1346. #endif
  1347. /*
  1348. * fill mac counter field
  1349. */
  1350. static void smt_fill_mac_counter(struct s_smc *smc, struct smt_p_mac_counter *mc)
  1351. {
  1352. SMTSETPARA(mc,SMT_P_MAC_COUNTER) ;
  1353. mc->mc_mib_index = INDEX_MAC ;
  1354. mc->mc_index = mac_index(smc,1) ;
  1355. mc->mc_receive_ct = smc->mib.m[MAC0].fddiMACCopied_Ct ;
  1356. mc->mc_transmit_ct = smc->mib.m[MAC0].fddiMACTransmit_Ct ;
  1357. }
  1358. /*
  1359. * fill mac frame not copied counter
  1360. */
  1361. static void smt_fill_mac_fnc(struct s_smc *smc, struct smt_p_mac_fnc *fnc)
  1362. {
  1363. SMTSETPARA(fnc,SMT_P_MAC_FNC) ;
  1364. fnc->nc_mib_index = INDEX_MAC ;
  1365. fnc->nc_index = mac_index(smc,1) ;
  1366. fnc->nc_counter = smc->mib.m[MAC0].fddiMACNotCopied_Ct ;
  1367. }
  1368. /*
  1369. * fill manufacturer field
  1370. */
  1371. static void smt_fill_manufacturer(struct s_smc *smc,
  1372. struct smp_p_manufacturer *man)
  1373. {
  1374. SMTSETPARA(man,SMT_P_MANUFACTURER) ;
  1375. memcpy((char *) man->mf_data,
  1376. (char *) smc->mib.fddiSMTManufacturerData,
  1377. sizeof(man->mf_data)) ;
  1378. }
  1379. /*
  1380. * fill user field
  1381. */
  1382. static void smt_fill_user(struct s_smc *smc, struct smp_p_user *user)
  1383. {
  1384. SMTSETPARA(user,SMT_P_USER) ;
  1385. memcpy((char *) user->us_data,
  1386. (char *) smc->mib.fddiSMTUserData,
  1387. sizeof(user->us_data)) ;
  1388. }
  1389. /*
  1390. * fill set count
  1391. */
  1392. static void smt_fill_setcount(struct s_smc *smc, struct smt_p_setcount *setcount)
  1393. {
  1394. SK_UNUSED(smc) ;
  1395. SMTSETPARA(setcount,SMT_P_SETCOUNT) ;
  1396. setcount->count = smc->mib.fddiSMTSetCount.count ;
  1397. memcpy((char *)setcount->timestamp,
  1398. (char *)smc->mib.fddiSMTSetCount.timestamp,8) ;
  1399. }
  1400. /*
  1401. * fill echo data
  1402. */
  1403. static void smt_fill_echo(struct s_smc *smc, struct smt_p_echo *echo, u_long seed,
  1404. int len)
  1405. {
  1406. u_char *p ;
  1407. SK_UNUSED(smc) ;
  1408. SMTSETPARA(echo,SMT_P_ECHODATA) ;
  1409. echo->para.p_len = len ;
  1410. for (p = echo->ec_data ; len ; len--) {
  1411. *p++ = (u_char) seed ;
  1412. seed += 13 ;
  1413. }
  1414. }
  1415. /*
  1416. * clear DNA and UNA
  1417. * called from CFM if configuration changes
  1418. */
  1419. void smt_clear_una_dna(struct s_smc *smc)
  1420. {
  1421. smc->mib.m[MAC0].fddiMACUpstreamNbr = SMT_Unknown ;
  1422. smc->mib.m[MAC0].fddiMACDownstreamNbr = SMT_Unknown ;
  1423. }
  1424. static void smt_clear_old_una_dna(struct s_smc *smc)
  1425. {
  1426. smc->mib.m[MAC0].fddiMACOldUpstreamNbr = SMT_Unknown ;
  1427. smc->mib.m[MAC0].fddiMACOldDownstreamNbr = SMT_Unknown ;
  1428. }
  1429. u_long smt_get_tid(struct s_smc *smc)
  1430. {
  1431. u_long tid ;
  1432. while ((tid = ++(smc->sm.smt_tid) ^ SMT_TID_MAGIC) == 0)
  1433. ;
  1434. return(tid & 0x3fffffffL) ;
  1435. }
  1436. /*
  1437. * table of parameter lengths
  1438. */
  1439. static const struct smt_pdef {
  1440. int ptype ;
  1441. int plen ;
  1442. const char *pswap ;
  1443. } smt_pdef[] = {
  1444. { SMT_P_UNA, sizeof(struct smt_p_una) ,
  1445. SWAP_SMT_P_UNA } ,
  1446. { SMT_P_SDE, sizeof(struct smt_p_sde) ,
  1447. SWAP_SMT_P_SDE } ,
  1448. { SMT_P_STATE, sizeof(struct smt_p_state) ,
  1449. SWAP_SMT_P_STATE } ,
  1450. { SMT_P_TIMESTAMP,sizeof(struct smt_p_timestamp) ,
  1451. SWAP_SMT_P_TIMESTAMP } ,
  1452. { SMT_P_POLICY, sizeof(struct smt_p_policy) ,
  1453. SWAP_SMT_P_POLICY } ,
  1454. { SMT_P_LATENCY, sizeof(struct smt_p_latency) ,
  1455. SWAP_SMT_P_LATENCY } ,
  1456. { SMT_P_NEIGHBORS,sizeof(struct smt_p_neighbor) ,
  1457. SWAP_SMT_P_NEIGHBORS } ,
  1458. { SMT_P_PATH, sizeof(struct smt_p_path) ,
  1459. SWAP_SMT_P_PATH } ,
  1460. { SMT_P_MAC_STATUS,sizeof(struct smt_p_mac_status) ,
  1461. SWAP_SMT_P_MAC_STATUS } ,
  1462. { SMT_P_LEM, sizeof(struct smt_p_lem) ,
  1463. SWAP_SMT_P_LEM } ,
  1464. { SMT_P_MAC_COUNTER,sizeof(struct smt_p_mac_counter) ,
  1465. SWAP_SMT_P_MAC_COUNTER } ,
  1466. { SMT_P_MAC_FNC,sizeof(struct smt_p_mac_fnc) ,
  1467. SWAP_SMT_P_MAC_FNC } ,
  1468. { SMT_P_PRIORITY,sizeof(struct smt_p_priority) ,
  1469. SWAP_SMT_P_PRIORITY } ,
  1470. { SMT_P_EB,sizeof(struct smt_p_eb) ,
  1471. SWAP_SMT_P_EB } ,
  1472. { SMT_P_MANUFACTURER,sizeof(struct smp_p_manufacturer) ,
  1473. SWAP_SMT_P_MANUFACTURER } ,
  1474. { SMT_P_REASON, sizeof(struct smt_p_reason) ,
  1475. SWAP_SMT_P_REASON } ,
  1476. { SMT_P_REFUSED, sizeof(struct smt_p_refused) ,
  1477. SWAP_SMT_P_REFUSED } ,
  1478. { SMT_P_VERSION, sizeof(struct smt_p_version) ,
  1479. SWAP_SMT_P_VERSION } ,
  1480. #ifdef ESS
  1481. { SMT_P0015, sizeof(struct smt_p_0015) , SWAP_SMT_P0015 } ,
  1482. { SMT_P0016, sizeof(struct smt_p_0016) , SWAP_SMT_P0016 } ,
  1483. { SMT_P0017, sizeof(struct smt_p_0017) , SWAP_SMT_P0017 } ,
  1484. { SMT_P0018, sizeof(struct smt_p_0018) , SWAP_SMT_P0018 } ,
  1485. { SMT_P0019, sizeof(struct smt_p_0019) , SWAP_SMT_P0019 } ,
  1486. { SMT_P001A, sizeof(struct smt_p_001a) , SWAP_SMT_P001A } ,
  1487. { SMT_P001B, sizeof(struct smt_p_001b) , SWAP_SMT_P001B } ,
  1488. { SMT_P001C, sizeof(struct smt_p_001c) , SWAP_SMT_P001C } ,
  1489. { SMT_P001D, sizeof(struct smt_p_001d) , SWAP_SMT_P001D } ,
  1490. #endif
  1491. #if 0
  1492. { SMT_P_FSC, sizeof(struct smt_p_fsc) ,
  1493. SWAP_SMT_P_FSC } ,
  1494. #endif
  1495. { SMT_P_SETCOUNT,0, SWAP_SMT_P_SETCOUNT } ,
  1496. { SMT_P1048, 0, SWAP_SMT_P1048 } ,
  1497. { SMT_P208C, 0, SWAP_SMT_P208C } ,
  1498. { SMT_P208D, 0, SWAP_SMT_P208D } ,
  1499. { SMT_P208E, 0, SWAP_SMT_P208E } ,
  1500. { SMT_P208F, 0, SWAP_SMT_P208F } ,
  1501. { SMT_P2090, 0, SWAP_SMT_P2090 } ,
  1502. #ifdef ESS
  1503. { SMT_P320B, sizeof(struct smt_p_320b) , SWAP_SMT_P320B } ,
  1504. { SMT_P320F, sizeof(struct smt_p_320f) , SWAP_SMT_P320F } ,
  1505. { SMT_P3210, sizeof(struct smt_p_3210) , SWAP_SMT_P3210 } ,
  1506. #endif
  1507. { SMT_P4050, 0, SWAP_SMT_P4050 } ,
  1508. { SMT_P4051, 0, SWAP_SMT_P4051 } ,
  1509. { SMT_P4052, 0, SWAP_SMT_P4052 } ,
  1510. { SMT_P4053, 0, SWAP_SMT_P4053 } ,
  1511. } ;
  1512. #define N_SMT_PLEN (sizeof(smt_pdef)/sizeof(smt_pdef[0]))
  1513. int smt_check_para(struct s_smc *smc, struct smt_header *sm,
  1514. const u_short list[])
  1515. {
  1516. const u_short *p = list ;
  1517. while (*p) {
  1518. if (!sm_to_para(smc,sm,(int) *p)) {
  1519. DB_SMT("SMT: smt_check_para - missing para %x\n",*p,0);
  1520. return(-1) ;
  1521. }
  1522. p++ ;
  1523. }
  1524. return(0) ;
  1525. }
  1526. void *sm_to_para(struct s_smc *smc, struct smt_header *sm, int para)
  1527. {
  1528. char *p ;
  1529. int len ;
  1530. int plen ;
  1531. void *found = NULL;
  1532. SK_UNUSED(smc) ;
  1533. len = sm->smt_len ;
  1534. p = (char *)(sm+1) ; /* pointer to info */
  1535. while (len > 0 ) {
  1536. if (((struct smt_para *)p)->p_type == para)
  1537. found = (void *) p ;
  1538. plen = ((struct smt_para *)p)->p_len + PARA_LEN ;
  1539. p += plen ;
  1540. len -= plen ;
  1541. if (len < 0) {
  1542. DB_SMT("SMT : sm_to_para - length error %d\n",plen,0) ;
  1543. return NULL;
  1544. }
  1545. if ((plen & 3) && (para != SMT_P_ECHODATA)) {
  1546. DB_SMT("SMT : sm_to_para - odd length %d\n",plen,0) ;
  1547. return NULL;
  1548. }
  1549. if (found)
  1550. return(found) ;
  1551. }
  1552. return NULL;
  1553. }
  1554. #if 0
  1555. /*
  1556. * send ANTC data test frame
  1557. */
  1558. void fddi_send_antc(struct s_smc *smc, struct fddi_addr *dest)
  1559. {
  1560. SK_UNUSED(smc) ;
  1561. SK_UNUSED(dest) ;
  1562. #if 0
  1563. SMbuf *mb ;
  1564. struct smt_header *smt ;
  1565. int i ;
  1566. char *p ;
  1567. mb = smt_get_mbuf() ;
  1568. mb->sm_len = 3000+12 ;
  1569. p = smtod(mb, char *) + 12 ;
  1570. for (i = 0 ; i < 3000 ; i++)
  1571. *p++ = 1 << (i&7) ;
  1572. smt = smtod(mb, struct smt_header *) ;
  1573. smt->smt_dest = *dest ;
  1574. smt->smt_source = smc->mib.m[MAC0].fddiMACSMTAddress ;
  1575. smt_send_mbuf(smc,mb,FC_ASYNC_LLC) ;
  1576. #endif
  1577. }
  1578. #endif
  1579. #ifdef DEBUG
  1580. #define hextoasc(x) "0123456789abcdef"[x]
  1581. char *addr_to_string(struct fddi_addr *addr)
  1582. {
  1583. int i ;
  1584. static char string[6*3] = "****" ;
  1585. for (i = 0 ; i < 6 ; i++) {
  1586. string[i*3] = hextoasc((addr->a[i]>>4)&0xf) ;
  1587. string[i*3+1] = hextoasc((addr->a[i])&0xf) ;
  1588. string[i*3+2] = ':' ;
  1589. }
  1590. string[5*3+2] = 0 ;
  1591. return(string) ;
  1592. }
  1593. #endif
  1594. #ifdef AM29K
  1595. smt_ifconfig(int argc, char *argv[])
  1596. {
  1597. if (argc >= 2 && !strcmp(argv[0],"opt_bypass") &&
  1598. !strcmp(argv[1],"yes")) {
  1599. smc->mib.fddiSMTBypassPresent = 1 ;
  1600. return(0) ;
  1601. }
  1602. return(amdfddi_config(0,argc,argv)) ;
  1603. }
  1604. #endif
  1605. /*
  1606. * return static mac index
  1607. */
  1608. static int mac_index(struct s_smc *smc, int mac)
  1609. {
  1610. SK_UNUSED(mac) ;
  1611. #ifdef CONCENTRATOR
  1612. SK_UNUSED(smc) ;
  1613. return(NUMPHYS+1) ;
  1614. #else
  1615. return((smc->s.sas == SMT_SAS) ? 2 : 3) ;
  1616. #endif
  1617. }
  1618. /*
  1619. * return static phy index
  1620. */
  1621. static int phy_index(struct s_smc *smc, int phy)
  1622. {
  1623. SK_UNUSED(smc) ;
  1624. return(phy+1);
  1625. }
  1626. /*
  1627. * return dynamic mac connection resource index
  1628. */
  1629. static int mac_con_resource_index(struct s_smc *smc, int mac)
  1630. {
  1631. #ifdef CONCENTRATOR
  1632. SK_UNUSED(smc) ;
  1633. SK_UNUSED(mac) ;
  1634. return(entity_to_index(smc,cem_get_downstream(smc,ENTITY_MAC))) ;
  1635. #else
  1636. SK_UNUSED(mac) ;
  1637. switch (smc->mib.fddiSMTCF_State) {
  1638. case SC9_C_WRAP_A :
  1639. case SC5_THRU_B :
  1640. case SC11_C_WRAP_S :
  1641. return(1) ;
  1642. case SC10_C_WRAP_B :
  1643. case SC4_THRU_A :
  1644. return(2) ;
  1645. }
  1646. return(smc->s.sas == SMT_SAS ? 2 : 3) ;
  1647. #endif
  1648. }
  1649. /*
  1650. * return dynamic phy connection resource index
  1651. */
  1652. static int phy_con_resource_index(struct s_smc *smc, int phy)
  1653. {
  1654. #ifdef CONCENTRATOR
  1655. return(entity_to_index(smc,cem_get_downstream(smc,ENTITY_PHY(phy)))) ;
  1656. #else
  1657. switch (smc->mib.fddiSMTCF_State) {
  1658. case SC9_C_WRAP_A :
  1659. return(phy == PA ? 3 : 2) ;
  1660. case SC10_C_WRAP_B :
  1661. return(phy == PA ? 1 : 3) ;
  1662. case SC4_THRU_A :
  1663. return(phy == PA ? 3 : 1) ;
  1664. case SC5_THRU_B :
  1665. return(phy == PA ? 2 : 3) ;
  1666. case SC11_C_WRAP_S :
  1667. return(2) ;
  1668. }
  1669. return(phy) ;
  1670. #endif
  1671. }
  1672. #ifdef CONCENTRATOR
  1673. static int entity_to_index(struct s_smc *smc, int e)
  1674. {
  1675. if (e == ENTITY_MAC)
  1676. return(mac_index(smc,1)) ;
  1677. else
  1678. return(phy_index(smc,e - ENTITY_PHY(0))) ;
  1679. }
  1680. #endif
  1681. #ifdef LITTLE_ENDIAN
  1682. static int smt_swap_short(u_short s)
  1683. {
  1684. return(((s>>8)&0xff)|((s&0xff)<<8)) ;
  1685. }
  1686. void smt_swap_para(struct smt_header *sm, int len, int direction)
  1687. /* int direction; 0 encode 1 decode */
  1688. {
  1689. struct smt_para *pa ;
  1690. const struct smt_pdef *pd ;
  1691. char *p ;
  1692. int plen ;
  1693. int type ;
  1694. int i ;
  1695. /* printf("smt_swap_para sm %x len %d dir %d\n",
  1696. sm,len,direction) ;
  1697. */
  1698. smt_string_swap((char *)sm,SWAP_SMTHEADER,len) ;
  1699. /* swap args */
  1700. len -= sizeof(struct smt_header) ;
  1701. p = (char *) (sm + 1) ;
  1702. while (len > 0) {
  1703. pa = (struct smt_para *) p ;
  1704. plen = pa->p_len ;
  1705. type = pa->p_type ;
  1706. pa->p_type = smt_swap_short(pa->p_type) ;
  1707. pa->p_len = smt_swap_short(pa->p_len) ;
  1708. if (direction) {
  1709. plen = pa->p_len ;
  1710. type = pa->p_type ;
  1711. }
  1712. /*
  1713. * note: paras can have 0 length !
  1714. */
  1715. if (plen < 0)
  1716. break ;
  1717. plen += PARA_LEN ;
  1718. for (i = N_SMT_PLEN, pd = smt_pdef; i ; i--,pd++) {
  1719. if (pd->ptype == type)
  1720. break ;
  1721. }
  1722. if (i && pd->pswap) {
  1723. smt_string_swap(p+PARA_LEN,pd->pswap,len) ;
  1724. }
  1725. len -= plen ;
  1726. p += plen ;
  1727. }
  1728. }
  1729. static void smt_string_swap(char *data, const char *format, int len)
  1730. {
  1731. const char *open_paren = 0 ;
  1732. int x ;
  1733. while (len > 0 && *format) {
  1734. switch (*format) {
  1735. case '[' :
  1736. open_paren = format ;
  1737. break ;
  1738. case ']' :
  1739. format = open_paren ;
  1740. break ;
  1741. case '1' :
  1742. case '2' :
  1743. case '3' :
  1744. case '4' :
  1745. case '5' :
  1746. case '6' :
  1747. case '7' :
  1748. case '8' :
  1749. case '9' :
  1750. data += *format - '0' ;
  1751. len -= *format - '0' ;
  1752. break ;
  1753. case 'c':
  1754. data++ ;
  1755. len-- ;
  1756. break ;
  1757. case 's' :
  1758. x = data[0] ;
  1759. data[0] = data[1] ;
  1760. data[1] = x ;
  1761. data += 2 ;
  1762. len -= 2 ;
  1763. break ;
  1764. case 'l' :
  1765. x = data[0] ;
  1766. data[0] = data[3] ;
  1767. data[3] = x ;
  1768. x = data[1] ;
  1769. data[1] = data[2] ;
  1770. data[2] = x ;
  1771. data += 4 ;
  1772. len -= 4 ;
  1773. break ;
  1774. }
  1775. format++ ;
  1776. }
  1777. }
  1778. #else
  1779. void smt_swap_para(struct smt_header *sm, int len, int direction)
  1780. /* int direction; 0 encode 1 decode */
  1781. {
  1782. SK_UNUSED(sm) ;
  1783. SK_UNUSED(len) ;
  1784. SK_UNUSED(direction) ;
  1785. }
  1786. #endif
  1787. /*
  1788. * PMF actions
  1789. */
  1790. int smt_action(struct s_smc *smc, int class, int code, int index)
  1791. {
  1792. int event ;
  1793. int port ;
  1794. DB_SMT("SMT: action %d code %d\n",class,code) ;
  1795. switch(class) {
  1796. case SMT_STATION_ACTION :
  1797. switch(code) {
  1798. case SMT_STATION_ACTION_CONNECT :
  1799. smc->mib.fddiSMTRemoteDisconnectFlag = FALSE ;
  1800. queue_event(smc,EVENT_ECM,EC_CONNECT) ;
  1801. break ;
  1802. case SMT_STATION_ACTION_DISCONNECT :
  1803. queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
  1804. smc->mib.fddiSMTRemoteDisconnectFlag = TRUE ;
  1805. RS_SET(smc,RS_DISCONNECT) ;
  1806. AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long)
  1807. FDDI_SMT_EVENT, (u_long) FDDI_REMOTE_DISCONNECT,
  1808. smt_get_event_word(smc));
  1809. break ;
  1810. case SMT_STATION_ACTION_PATHTEST :
  1811. AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long)
  1812. FDDI_SMT_EVENT, (u_long) FDDI_PATH_TEST,
  1813. smt_get_event_word(smc));
  1814. break ;
  1815. case SMT_STATION_ACTION_SELFTEST :
  1816. AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long)
  1817. FDDI_SMT_EVENT, (u_long) FDDI_REMOTE_SELF_TEST,
  1818. smt_get_event_word(smc));
  1819. break ;
  1820. case SMT_STATION_ACTION_DISABLE_A :
  1821. if (smc->y[PA].pc_mode == PM_PEER) {
  1822. RS_SET(smc,RS_EVENT) ;
  1823. queue_event(smc,EVENT_PCM+PA,PC_DISABLE) ;
  1824. }
  1825. break ;
  1826. case SMT_STATION_ACTION_DISABLE_B :
  1827. if (smc->y[PB].pc_mode == PM_PEER) {
  1828. RS_SET(smc,RS_EVENT) ;
  1829. queue_event(smc,EVENT_PCM+PB,PC_DISABLE) ;
  1830. }
  1831. break ;
  1832. case SMT_STATION_ACTION_DISABLE_M :
  1833. for (port = 0 ; port < NUMPHYS ; port++) {
  1834. if (smc->mib.p[port].fddiPORTMy_Type != TM)
  1835. continue ;
  1836. RS_SET(smc,RS_EVENT) ;
  1837. queue_event(smc,EVENT_PCM+port,PC_DISABLE) ;
  1838. }
  1839. break ;
  1840. default :
  1841. return(1) ;
  1842. }
  1843. break ;
  1844. case SMT_PORT_ACTION :
  1845. switch(code) {
  1846. case SMT_PORT_ACTION_ENABLE :
  1847. event = PC_ENABLE ;
  1848. break ;
  1849. case SMT_PORT_ACTION_DISABLE :
  1850. event = PC_DISABLE ;
  1851. break ;
  1852. case SMT_PORT_ACTION_MAINT :
  1853. event = PC_MAINT ;
  1854. break ;
  1855. case SMT_PORT_ACTION_START :
  1856. event = PC_START ;
  1857. break ;
  1858. case SMT_PORT_ACTION_STOP :
  1859. event = PC_STOP ;
  1860. break ;
  1861. default :
  1862. return(1) ;
  1863. }
  1864. queue_event(smc,EVENT_PCM+index,event) ;
  1865. break ;
  1866. default :
  1867. return(1) ;
  1868. }
  1869. return(0) ;
  1870. }
  1871. /*
  1872. * change tneg
  1873. * set T_Req in MIB (Path Attribute)
  1874. * calculate new values for MAC
  1875. * if change required
  1876. * disconnect
  1877. * set reconnect
  1878. * end
  1879. */
  1880. void smt_change_t_neg(struct s_smc *smc, u_long tneg)
  1881. {
  1882. smc->mib.a[PATH0].fddiPATHMaxT_Req = tneg ;
  1883. if (smt_set_mac_opvalues(smc)) {
  1884. RS_SET(smc,RS_EVENT) ;
  1885. smc->sm.please_reconnect = 1 ;
  1886. queue_event(smc,EVENT_ECM,EC_DISCONNECT) ;
  1887. }
  1888. }
  1889. /*
  1890. * canonical conversion of <len> bytes beginning form *data
  1891. */
  1892. #ifdef USE_CAN_ADDR
  1893. void hwm_conv_can(struct s_smc *smc, char *data, int len)
  1894. {
  1895. int i ;
  1896. SK_UNUSED(smc) ;
  1897. for (i = len; i ; i--, data++) {
  1898. *data = canonical[*(u_char *)data] ;
  1899. }
  1900. }
  1901. #endif
  1902. #endif /* no SLIM_SMT */