22 #include <linux/kernel.h>
28 static const char ID_sccs[] =
"@(#)smt.c 2.43 98/11/23 (C) SK " ;
34 #define m_fc(mb) ((mb)->sm_data[0])
36 #define SMT_TID_MAGIC 0x1f0a7b3c
39 static const char *
const smt_type_name[] = {
40 "SMT_00??",
"SMT_INFO",
"SMT_02??",
"SMT_03??",
41 "SMT_04??",
"SMT_05??",
"SMT_06??",
"SMT_07??",
42 "SMT_08??",
"SMT_09??",
"SMT_0A??",
"SMT_0B??",
43 "SMT_0C??",
"SMT_0D??",
"SMT_0E??",
"SMT_NSA"
46 static const char *
const smt_class_name[] = {
47 "UNKNOWN",
"NIF",
"SIF_CONFIG",
"SIF_OPER",
"ECF",
"RAF",
"RDF",
48 "SRF",
"PMF_GET",
"PMF_SET",
"ESF"
51 #define LAST_CLASS (SMT_PMF_SET)
53 static const struct fddi_addr SMT_Unknown = {
61 static int smt_swap_short(
u_short s);
65 static int mac_con_resource_index(
struct s_smc *
smc,
int mac);
66 static int phy_con_resource_index(
struct s_smc *
smc,
int phy);
73 static void smt_echo_test(
struct s_smc *
smc,
int dna);
79 static void smt_string_swap(
char *
data,
const char *
format,
int len);
81 static void smt_add_frame_len(
SMbuf *
mb,
int len);
96 static void smt_fill_manufacturer(
struct s_smc *
smc,
103 static void smt_clear_una_dna(
struct s_smc *
smc);
104 static void smt_clear_old_una_dna(
struct s_smc *
smc);
106 static int entity_to_index(
void);
113 #define hwm_conv_can(smc,data,len)
117 static inline int is_my_addr(
const struct s_smc *
smc,
120 return(*(
short *)(&addr->
a[0]) ==
121 *(
short *)(&smc->
mib.m[
MAC0].fddiMACSMTAddress.a[0])
122 && *(
short *)(&addr->
a[2]) ==
123 *(
short *)(&smc->
mib.m[
MAC0].fddiMACSMTAddress.a[2])
124 && *(
short *)(&addr->
a[4]) ==
125 *(
short *)(&smc->
mib.m[
MAC0].fddiMACSMTAddress.a[4])) ;
130 return *(
u_short *)(&addr->
a[0]) == 0xffff &&
131 *(
u_short *)(&addr->
a[2]) == 0xffff &&
132 *(
u_short *)(&addr->
a[4]) == 0xffff;
135 static inline int is_individual(
const struct fddi_addr *addr)
163 smc->
mib.m[
MAC0].fddiMACSMTAddress = smc->
hw.fddi_home_addr ;
168 smc->
mib.fddiSMTStationId.sid_oem[0] = 0 ;
169 smc->
mib.fddiSMTStationId.sid_oem[1] = 0 ;
171 for (i = 0 ; i < 6 ; i ++) {
172 smc->
mib.fddiSMTStationId.sid_node.a[
i] =
173 bitrev8(smc->
mib.fddiSMTStationId.sid_node.a[i]);
175 smc->
mib.fddiSMTManufacturerData[0] =
176 smc->
mib.fddiSMTStationId.sid_node.a[0] ;
177 smc->
mib.fddiSMTManufacturerData[1] =
178 smc->
mib.fddiSMTStationId.sid_node.a[1] ;
179 smc->
mib.fddiSMTManufacturerData[2] =
180 smc->
mib.fddiSMTStationId.sid_node.a[2] ;
181 smc->
sm.smt_tid = 0 ;
185 smt_clear_una_dna(smc) ;
186 smt_clear_old_una_dna(smc) ;
189 smc->
sm.pend[i] = 0 ;
190 smc->
sm.please_reconnect = 0 ;
191 smc->
sm.uniq_ticks = 0 ;
206 DB_SMT(
"SMT agent task\n",0,0) ;
209 #ifndef SMT_REAL_TOKEN_CT
217 count = ((time - smc->
sm.last_tok_time[mac_index]) *
226 if (smc->
hw.mac_ring_is_up){
227 smc->
mib.m[mac_index].fddiMACToken_Ct +=
count;
231 smc->
sm.last_tok_time[mac_index] =
time;
240 #ifndef SMT_REAL_TOKEN_CT
245 if (smc->
sm.please_reconnect) {
246 smc->
sm.please_reconnect -- ;
247 if (smc->
sm.please_reconnect == 0) {
267 ess_timer_poll(smc) ;
271 sba_timer_poll(smc) ;
285 struct fddi_mib_m *mib ;
295 smc->
sm.smt_last_lem =
time ;
304 (mib->fddiMACLost_Ct - mib->fddiMACOld_Lost_Ct) +
305 (mib->fddiMACError_Ct - mib->fddiMACOld_Error_Ct) ;
307 (mib->fddiMACFrame_Ct - mib->fddiMACOld_Frame_Ct) +
308 (mib->fddiMACLost_Ct - mib->fddiMACOld_Lost_Ct) ;
309 mib->fddiMACFrameErrorRatio = div_ratio(upper,lower) ;
312 ((!mib->fddiMACFrameErrorThreshold &&
313 mib->fddiMACError_Ct != mib->fddiMACOld_Error_Ct) ||
314 (mib->fddiMACFrameErrorRatio >
315 mib->fddiMACFrameErrorThreshold)) ;
317 if (cond != mib->fddiMACFrameErrorFlag)
322 (mib->fddiMACNotCopied_Ct - mib->fddiMACOld_NotCopied_Ct) ;
325 (mib->fddiMACCopied_Ct - mib->fddiMACOld_Copied_Ct) ;
326 mib->fddiMACNotCopiedRatio = div_ratio(upper,lower) ;
329 ((!mib->fddiMACNotCopiedThreshold &&
330 mib->fddiMACNotCopied_Ct !=
331 mib->fddiMACOld_NotCopied_Ct)||
332 (mib->fddiMACNotCopiedRatio >
333 mib->fddiMACNotCopiedThreshold)) ;
335 if (cond != mib->fddiMACNotCopiedFlag)
342 mib->fddiMACOld_Frame_Ct = mib->fddiMACFrame_Ct ;
343 mib->fddiMACOld_Copied_Ct = mib->fddiMACCopied_Ct ;
344 mib->fddiMACOld_Error_Ct = mib->fddiMACError_Ct ;
345 mib->fddiMACOld_Lost_Ct = mib->fddiMACLost_Ct ;
346 mib->fddiMACOld_NotCopied_Ct = mib->fddiMACNotCopied_Ct ;
351 for (port = 0; port <
NUMPHYS; port ++) {
352 phy = &smc->
y[
port] ;
354 if (!phy->
mib->fddiPORTHardwarePresent) {
358 cond = (phy->
mib->fddiPORTEBError_Ct -
359 phy->
mib->fddiPORTOldEBError_Ct > 5) ;
370 phy->
mib->fddiPORTOldEBError_Ct =
371 phy->
mib->fddiPORTEBError_Ct ;
379 if (time - smc->
sm.smt_last_notify >= (
u_long)
391 smc->
sm.smt_last_notify =
time ;
397 if (smc->
sm.smt_tvu &&
399 DB_SMT(
"SMT : UNA expired\n",0,0) ;
400 smc->
sm.smt_tvu = 0 ;
402 if (!is_equal(&smc->
mib.m[
MAC0].fddiMACUpstreamNbr,
405 smc->
mib.m[
MAC0].fddiMACOldUpstreamNbr=
406 smc->
mib.m[
MAC0].fddiMACUpstreamNbr ;
408 smc->
mib.m[
MAC0].fddiMACUpstreamNbr = SMT_Unknown ;
420 if (smc->
sm.smt_tvd &&
422 DB_SMT(
"SMT : DNA expired\n",0,0) ;
423 smc->
sm.smt_tvd = 0 ;
424 if (!is_equal(&smc->
mib.m[
MAC0].fddiMACDownstreamNbr,
427 smc->
mib.m[
MAC0].fddiMACOldDownstreamNbr=
428 smc->
mib.m[
MAC0].fddiMACDownstreamNbr ;
430 smc->
mib.m[
MAC0].fddiMACDownstreamNbr = SMT_Unknown ;
437 #ifndef SMT_REAL_TOKEN_CT
455 if ((upper<<16L) < upper)
456 upper = 0xffff0000
L ;
461 return (
int)(upper/lower) ;
488 smc->
mib.m[
MAC0].fddiMACSMTCopied_Ct++ ;
500 if (is_my_addr(smc,&sm->
smt_source) && !local) {
507 DB_SMT(
"SMT : received packet [%s] at 0x%x\n",
508 smt_type_name[
m_fc(mb) & 0xf],sm) ;
527 DB_SMT(
"SMT : ignoring NSA with A-indicator set from %s\n",
559 DB_SMT(
"SMT : version = %d, dest = %s\n",
575 DB_SMT(
"SMT: NIF with para problem, ignoring\n",0,0) ;
587 &smc->
mib.m[
MAC0].fddiMACUpstreamNbr,
589 DB_SMT(
"SMT : updated my UNA = %s\n",
591 if (!is_equal(&smc->
mib.m[
MAC0].
592 fddiMACUpstreamNbr,&SMT_Unknown)){
594 smc->
mib.m[
MAC0].fddiMACOldUpstreamNbr=
595 smc->
mib.m[
MAC0].fddiMACUpstreamNbr ;
598 smc->
mib.m[
MAC0].fddiMACUpstreamNbr =
603 smt_echo_test(smc,0) ;
609 smc->
mib.m[
MAC0].fddiMACUNDA_Flag =
619 DB_SMT(
"SMT : replying to NIF request %s\n",
628 DB_SMT(
"SMT : received NIF response from %s\n",
630 if (fs & A_INDICATOR) {
632 DB_SMT(
"SMT : duplicate address\n",0,0) ;
633 smc->
mib.m[
MAC0].fddiMACDupAddressTest =
645 &smc->
mib.m[
MAC0].fddiMACDownstreamNbr,
647 DB_SMT(
"SMT : updated my DNA\n",0,0) ;
648 if (!is_equal(&smc->
mib.m[
MAC0].
649 fddiMACDownstreamNbr, &SMT_Unknown)){
651 smc->
mib.m[
MAC0].fddiMACOldDownstreamNbr =
652 smc->
mib.m[
MAC0].fddiMACDownstreamNbr ;
655 smc->
mib.m[
MAC0].fddiMACDownstreamNbr =
660 smt_echo_test(smc,1) ;
665 smc->
mib.m[
MAC0].fddiMACDupAddressTest =
674 DB_SMT(
"SMT : NIF test TID ok\n",0,0) ;
677 DB_SMT(
"SMT : expected TID %lx, got %lx\n",
689 DB_SMT(
"SMT : replying to SIF Config request from %s\n",
696 DB_SMT(
"SMT : replying to SIF Operation request from %s\n",
703 smc->
mib.priv.fddiPRIVECF_Reply_Rx++ ;
704 DB_SMT(
"SMT: received ECF reply from %s\n",
707 DB_SMT(
"SMT: ECHODATA missing\n",0,0) ;
711 DB_SMT(
"SMT : ECF test TID ok\n",0,0) ;
714 DB_SMT(
"SMT : ECF test UNA ok\n",0,0) ;
717 DB_SMT(
"SMT : ECF test DNA ok\n",0,0) ;
720 DB_SMT(
"SMT : expected TID %lx, got %lx\n",
726 smc->
mib.priv.fddiPRIVECF_Req_Rx++ ;
729 DB_SMT(
"SMT: ECF with para problem,sending RDF\n",0,0) ;
734 DB_SMT(
"SMT - sending ECF reply to %s\n",
741 smc->
mib.priv.fddiPRIVECF_Reply_Tx++ ;
753 DB_ESSN(2,
"ESS: RAF frame received\n",0,0) ;
754 fs = ess_raf_received_pack(smc,mb,sm,fs) ;
758 DB_SBAN(2,
"SBA: RAF frame received\n",0,0) ;
759 sba_raf_received_pack(smc,sm,fs) ;
763 smc->
mib.priv.fddiPRIVRDF_Rx++ ;
767 DB_SMT(
"SMT - received ESF, sending RDF\n",0,0) ;
777 smc->
mib.priv.fddiPRIVPMF_Get_Rx++ ;
779 smc->
mib.priv.fddiPRIVPMF_Set_Rx++ ;
785 DB_SMT(
"SMT: ignoring PMF-SET with I/G set\n",0,0) ;
801 DB_SMT(
"SMT : class = %d, send RDF to %s\n",
809 DB_SMT(
"SMT: discarding invalid frame, reason = %d\n",
819 cond = ( smc->
mib.m[
MAC0].fddiMACUNDA_Flag |
820 smc->
mib.m[
MAC0].fddiMACDA_Flag) != 0 ;
821 if (report && (cond != smc->
mib.m[
MAC0].fddiMACDuplicateAddressCond))
824 smc->
mib.m[
MAC0].fddiMACDuplicateAddressCond =
cond ;
839 if (!smc->
r.sm_ma_avail && !local) {
849 smc->
mib.m[
MAC0].fddiMACSMTTransmit_Ct++ ;
872 DB_SMT(
"SMT: sending RDF to %s,reason = 0x%x\n",
913 rdf->
refused.para.p_len = len + 4 ;
923 rdf->
smt.smt_len += len ;
926 smc->
mib.priv.fddiPRIVRDF_Tx++ ;
946 smt_fill_una(smc,&nif->
una) ;
947 smt_fill_sde(smc,&nif->
sde) ;
948 smt_fill_state(smc,&nif->
state) ;
950 smt_fill_fsc(smc,&nif->
fsc) ;
953 nif->
smt.smt_tid = tid ;
962 static void smt_send_nif_request(
struct s_smc *smc,
struct fddi_addr *dest)
972 static void smt_send_ecf_request(
struct s_smc *smc,
struct fddi_addr *dest,
984 static void smt_echo_test(
struct s_smc *smc,
int dna)
990 smt_send_ecf(smc, dna ?
991 &smc->
mib.m[
MAC0].fddiMACDownstreamNbr :
992 &smc->
mib.m[
MAC0].fddiMACUpstreamNbr,
999 static void smt_send_ecf(
struct s_smc *smc,
struct fddi_addr *dest,
int fc,
1000 u_long tid,
int type,
int len)
1014 smt_fill_echo(smc,&ecf->
ec_echo,tid,len) ;
1016 ecf->
smt.smt_tid = tid ;
1017 smc->
mib.priv.fddiPRIVECF_Req_Tx++ ;
1025 static void smt_send_sif_config(
struct s_smc *smc,
struct fddi_addr *dest,
1038 smt_fill_timestamp(smc,&sif->
ts) ;
1039 smt_fill_sde(smc,&sif->
sde) ;
1040 smt_fill_version(smc,&sif->
version) ;
1041 smt_fill_state(smc,&sif->
state) ;
1042 smt_fill_policy(smc,&sif->
policy) ;
1043 smt_fill_latency(smc,&sif->
latency);
1044 smt_fill_neighbor(smc,&sif->
neighbor);
1045 smt_fill_setcount(smc,&sif->
setcount) ;
1046 len = smt_fill_path(smc,&sif->
path);
1048 sif->
smt.smt_tid = tid ;
1049 smt_add_frame_len(mb,len) ;
1058 static void smt_send_sif_operation(
struct s_smc *smc,
struct fddi_addr *dest,
1069 #ifndef CONCENTRATOR
1078 smt_fill_timestamp(smc,&sif->
ts) ;
1079 smt_fill_mac_status(smc,&sif->
status) ;
1080 smt_fill_mac_counter(smc,&sif->
mc) ;
1081 smt_fill_mac_fnc(smc,&sif->
fnc) ;
1082 smt_fill_manufacturer(smc,&sif->
man) ;
1083 smt_fill_user(smc,&sif->
user) ;
1084 smt_fill_setcount(smc,&sif->
setcount) ;
1089 smt_fill_lem(smc,sif->
lem,
PS) ;
1092 for (i = 0 ; i < ports ; i++) {
1093 smt_fill_lem(smc,&sif->
lem[i],i) ;
1098 sif->
smt.smt_tid = tid ;
1113 if (!smc->
r.sm_ma_avail) {
1142 static void smt_add_frame_len(
SMbuf *mb,
int len)
1156 static void smt_fill_una(
struct s_smc *smc,
struct smt_p_una *una)
1166 static void smt_fill_sde(
struct s_smc *smc,
struct smt_p_sde *sde)
1192 if (smc->
mib.fddiSMTPeerWrapFlag) {
1196 if (cfm_status_unattached(smc)) {
1211 if (smc->
mib.a[0].fddiPATHSbaPayload != 0)
1240 time = utime * 100 ;
1243 p[1] = (
u_char)((time>>(8+8+8+8-1)) & 1) ;
1244 p[2] = (
u_char)(time>>(8+8+8-1)) ;
1245 p[3] = (
u_char)(time>>(8+8-1)) ;
1246 p[4] = (
u_char)(time>>(8-1)) ;
1247 p[5] = (
u_char)(time<<1) ;
1248 p[6] = (
u_char)(smc->
sm.uniq_ticks>>8) ;
1249 p[7] = (
u_char)smc->
sm.uniq_ticks ;
1253 if (utime != smc->
sm.uniq_time) {
1254 smc->
sm.uniq_ticks = 0 ;
1256 smc->
sm.uniq_ticks++ ;
1274 static const u_char ansi_weirdness[16] = {
1275 0,7,5,3,8,1,6,4,9,10,2,11,12,13,14,15
1280 in = smc->
mib.fddiSMTConnectionPolicy ;
1281 for (i = 0, map = ansi_weirdness ; i < 16 ; i++) {
1331 #define ALLPHYS NUMPHYS
1333 #define ALLPHYS ((smc->s.sas == SMT_SAS) ? 1 : 2)
1355 for (p = 0,phy = path->
pd_phy ; p < ALLPHYS ; p++, phy++) {
1357 #ifndef CONCENTRATOR
1362 #ifdef LITTLE_ENDIAN
1413 struct fddi_mib_p *mib ;
1415 mib = smc->
y[
phy].mib ;
1422 lem->
lem_alarm = mib->fddiPORTLer_Alarm ;
1427 lem->
lem_ct = mib->fddiPORTLem_Ct ;
1452 static void smt_fill_fsc(
struct s_smc *smc,
struct smt_p_fsc *fsc)
1462 #ifdef LITTLE_ENDIAN
1496 static void smt_fill_manufacturer(
struct s_smc *smc,
1501 (
char *) smc->
mib.fddiSMTManufacturerData,
1512 (
char *) smc->
mib.fddiSMTUserData,
1523 setcount->
count = smc->
mib.fddiSMTSetCount.count ;
1525 (
char *)smc->
mib.fddiSMTSetCount.timestamp,8) ;
1538 echo->
para.p_len = len ;
1539 for (p = echo->
ec_data ; len ; len--) {
1549 static void smt_clear_una_dna(
struct s_smc *smc)
1551 smc->
mib.m[
MAC0].fddiMACUpstreamNbr = SMT_Unknown ;
1552 smc->
mib.m[
MAC0].fddiMACDownstreamNbr = SMT_Unknown ;
1555 static void smt_clear_old_una_dna(
struct s_smc *smc)
1557 smc->
mib.m[
MAC0].fddiMACOldUpstreamNbr = SMT_Unknown ;
1558 smc->
mib.m[
MAC0].fddiMACOldDownstreamNbr = SMT_Unknown ;
1566 return tid & 0x3fffffff
L;
1573 static const struct smt_pdef {
1648 #define N_SMT_PLEN ARRAY_SIZE(smt_pdef)
1656 DB_SMT(
"SMT: smt_check_para - missing para %x\n",*p,0);
1674 p = (
char *)(sm+1) ;
1677 found = (
void *)
p ;
1682 DB_SMT(
"SMT : sm_to_para - length error %d\n",plen,0) ;
1686 DB_SMT(
"SMT : sm_to_para - odd length %d\n",plen,0) ;
1711 p =
smtod(mb,
char *) + 12 ;
1712 for (i = 0 ; i < 3000 ; i++)
1724 char *addr_to_string(
struct fddi_addr *addr)
1727 static char string[6*3] =
"****" ;
1729 for (i = 0 ; i < 6 ; i++) {
1732 string[i * 3 + 2] =
':';
1734 string[5 * 3 + 2] = 0;
1740 int smt_ifconfig(
int argc,
char *argv[])
1742 if (argc >= 2 && !
strcmp(argv[0],
"opt_bypass") &&
1743 !
strcmp(argv[1],
"yes")) {
1744 smc->
mib.fddiSMTBypassPresent = 1 ;
1747 return amdfddi_config(0, argc, argv);
1754 static int mac_index(
struct s_smc *smc,
int mac)
1761 return (smc->
s.sas ==
SMT_SAS) ? 2 : 3;
1768 static int phy_index(
struct s_smc *smc,
int phy)
1777 static int mac_con_resource_index(
struct s_smc *smc,
int mac)
1782 return entity_to_index(smc, cem_get_downstream(smc,
ENTITY_MAC));
1785 switch (smc->
mib.fddiSMTCF_State) {
1794 return smc->
s.sas ==
SMT_SAS ? 2 : 3;
1801 static int phy_con_resource_index(
struct s_smc *smc,
int phy)
1804 return entity_to_index(smc, cem_get_downstream(smc,
ENTITY_PHY(phy))) ;
1806 switch (smc->
mib.fddiSMTCF_State) {
1808 return phy ==
PA ? 3 : 2;
1810 return phy ==
PA ? 1 : 3;
1812 return phy ==
PA ? 3 : 1;
1814 return phy ==
PA ? 2 : 3;
1823 static int entity_to_index(
struct s_smc *smc,
int e)
1826 return mac_index(smc, 1);
1832 #ifdef LITTLE_ENDIAN
1833 static int smt_swap_short(
u_short s)
1835 return ((s>>8)&0xff) | ((s&0xff)<<8);
1842 const struct smt_pdef *
pd ;
1856 p = (
char *) (sm + 1) ;
1873 for (i =
N_SMT_PLEN, pd = smt_pdef;
i ; i--,pd++) {
1874 if (pd->ptype == type)
1877 if (i && pd->pswap) {
1878 smt_string_swap(p+
PARA_LEN,pd->pswap,len) ;
1885 static void smt_string_swap(
char *
data,
const char *
format,
int len)
1887 const char *open_paren =
NULL ;
1890 while (len > 0 && *format) {
1896 format = open_paren ;
1907 data += *format -
'0' ;
1908 len -= *format -
'0' ;
1952 DB_SMT(
"SMT: action %d code %d\n",
class,code) ;
1957 smc->
mib.fddiSMTRemoteDisconnectFlag =
FALSE ;
1962 smc->
mib.fddiSMTRemoteDisconnectFlag =
TRUE ;
1965 FDDI_SMT_EVENT, (
u_long) FDDI_REMOTE_DISCONNECT,
1966 smt_get_event_word(smc));
1970 FDDI_SMT_EVENT, (
u_long) FDDI_PATH_TEST,
1971 smt_get_event_word(smc));
1975 FDDI_SMT_EVENT, (
u_long) FDDI_REMOTE_SELF_TEST,
1976 smt_get_event_word(smc));
1991 for (port = 0 ; port <
NUMPHYS ; port++) {
1992 if (smc->
mib.p[port].fddiPORTMy_Type !=
TM)
2040 for (i = len;
i ; i--, data++)
2041 *data = bitrev8(*data);