📄 hllcputils.c
字号:
/* * goto_hlcp - sends goto hlcp command to exit llcp. * Returns either LLCP_SUCC or LLCP_FAIL. */#ifndef PROMCODEgoto_hlcp(llcptr)llcp_info_t *llcptr;{ register llcp_reg_t *regptr = llcptr->regp; void cmd_wait(); if ( pre_err_chk(llcptr, LLCP_RDY) == LLCP_FAIL ) return(LLCP_FAIL); /* issue llcp command - (length, address, command) */ LLCP_SEND_CMD(regptr, 0L, (u_char *)0, LLCP_GOTO_HLCP); #ifndef UNIXDVR cmd_wait(llcptr, LLCP_HLCP); /* wait up to timeout */ if ( post_err_chk(llcptr, LLCP_HLCP) == LLCP_FAIL ) return(LLCP_FAIL);#endif return(LLCP_SUCC);} /* goto_hlcp */#endif/* * gen_cmd - sends any generic command to the controller * The caller must fully set up the treg contents * before calling this routine, so because of * this extra knowledge needed, it should only be used * with controller specific commands. Note that this * command does not transfer any data. * Returns either LLCP_SUCC or LLCP_FAIL. */#ifndef PROMCODEgen_cmd(llcptr,treg)llcp_info_t *llcptr;llcp_reg_t *treg;{ register llcp_reg_t *regptr = llcptr->regp; void cmd_wait(); if ( pre_err_chk(llcptr, LLCP_RDY) == LLCP_FAIL ) return(LLCP_FAIL); /* issue llcp command - (length, address, command) */ LLCP_SEND_CMD(regptr, treg->len, treg->addr, treg->cmd); #ifndef UNIXDVR cmd_wait(llcptr, LLCP_HLCP); /* wait up to timeout */ if ( post_err_chk(llcptr, LLCP_RDY) == LLCP_FAIL ) return(LLCP_FAIL);#endif return(LLCP_SUCC);} /* gen_cmd */#endif/* * llcp_error() - performs the llcp handshake to retrieve the error string, * if one exists, and prints the message out. Checks on error * state and command complete. Returns LLCP_SUCC if an error * string is found, and LLCP_FAIL otherwise */llcp_error(llcptr)llcp_info_t *llcptr;{ int length; llcp_reg_t treg; register llcp_reg_t *regptr = llcptr->regp; void cmd_wait(); /* issue llcp command - (length, address, command) */ LLCP_SEND_CMD(regptr, 0L, (u_char *)0, LLCP_ERROR); #ifndef UNIXDVR cmd_wait(llcptr, LLCP_ERR); /* wait up to timeout */ /* * Since some of the llcp registers could be broken, do not even * check on command complete. As long as the length is non-zero * we will attempt to print out the contents of the info buffer. */ llcp_get_status(llcptr, &treg); /* get register values */ if ( (length = (int) treg.len) != 0 ) { *(llcptr->cinfop->buf + length) = '\0'; /* terminate str */ /* XXX what if shared memory has not been setup at this point!*/ printf(llcp_msgs[E_LLCP_EST], llcptr->cinfop->buf); return(LLCP_SUCC); } return(LLCP_FAIL);#else return(LLCP_SUCC);#endif} /* llcp_error *//* * llcp_reset - software resets network board. * Determines if the controller is in an undetermined state from * power on reset. If so, does not write any of the shared memory * registers until a timeout or valid combination of values is * found. If a valid combination of values is found in the llcp * register set, simply issues the reset command. * This isn't very robust to hardware errors during runtime, but * then again, the reset command doesn't do a whole hell of a lot! * If there is an error, a message will be displayed through the * post_err_chk routine. */llcp_reset(llcptr)llcp_info_t *llcptr;{#ifdef PROMCODE int retval; /* check if first time through the code on system power-up */ if ( first_time != 0 ) return( reset_cmd(llcptr) ); else { retval = power_on_rst(llcptr); first_time = 1; /* not the first time thru code anymore */ return(retval); }#else /* * can only have a power on reset from prom code */ return( reset_cmd(llcptr) );#endif} /* llcp_reset *//* * reset_cmd - software resets the controller board by writing * the reset command to the llcp registers. * Returns LLCP_SUCC on successful completion and * LLCP_FAIL on failure. */reset_cmd(llcptr)llcp_info_t *llcptr;{ register llcp_reg_t *regptr = llcptr->regp; void cmd_wait(); llcptr->cinfop->timeout = LLCP_T_RESET; /* set 4s timeout for reset */ /* issue llcp command - (length, address, command) */ LLCP_SEND_CMD(regptr, 0L, (u_char *)0, LLCP_RESET); #ifdef DEBUG printf("rst_cmd: ®=0x%x \n", llcptr->regp);#endif#ifndef UNIXDVR cmd_wait(llcptr, LLCP_INIT1); /* wait up to timeout */ if ( post_err_chk(llcptr, LLCP_INIT1) == LLCP_FAIL ) return(LLCP_FAIL);#endif return(LLCP_SUCC);} /* reset_cmd *//* * pre_err_chk - checks all the registers and prints out the appropriate * message if there is an error. This routine is called before * a command to the controller has been issued. If the * controller has gone into the error state, the error * routine is invoked. Returns either LLCP_SUCC or LLCP_FAIL */#ifndef PROMCODEpre_err_chk(llcptr, expected_state)llcp_info_t *llcptr;state_t expected_state;{ llcp_reg_t treg; llcp_get_status(llcptr, &treg); /* get controller status */ /* check if in proper state and command complete */ if ( (treg.state != expected_state) || (treg.cmd != LLCP_CMD_COM) ) { printf(llcp_msgs[E_LLCP_RDY]); return(LLCP_FAIL); } return(LLCP_SUCC);} /* pre_err_chk */#endif/* * post_err_chk - checks all the registers and prints out the appropriate * message if there is an error. This routine is called after * a command to the controller has been issued. If the * controller has gone into the error state, the error routine * is invoked. Returns either LLCP_SUCC or LLCP_FAIL */post_err_chk(llcptr, expected_state)llcp_info_t *llcptr;state_t expected_state;{ llcp_reg_t treg; llcp_get_status(llcptr, &treg); /* get controller status */ /* command did not complete, not in proper state, or bad fault code */ if ( (treg.cmd != LLCP_CMD_COM) || (treg.state != expected_state) ) { printf(llcp_msgs[E_LLCP_RDY]); return(LLCP_FAIL); } else if ( treg.fault != LLCP_FC_OK ) { if ( treg.fault == LLCP_FC_INV_CMD ) printf(llcp_msgs[E_LLCP_INV]); else if ( (treg.state != LLCP_RDY) && (treg.state != LLCP_INIT2) && (treg.state != LLCP_INIT3) ) /* cannot use common memory */ printf(llcp_msgs[E_LLCP_RDY]); else {#ifndef UNIXDVR (void) llcp_error(llcptr); /* print out error string */#endif } return(LLCP_FAIL); } return(LLCP_SUCC);} /* post_err_chk *//* * add_llc_hdr - adds an llc header to our frames. * * The packet received by this routine originally looks like * the following: * * ------------------------------------S------------ * | DA | SA | TYPE | DATA | * ------------------------------------S------------ * * It is converted to adhere to ISO standards, and subsequently * looks like this: * * -------------------------------------------S------------ * | DA | SA | LLC_SNAP_HDR* | DATA | * -------------------------------------------S------------ * * *note that the end of the llc_snap_hdr contains the type * field from the original packet * */voidadd_llc_hdr(buf,tbufp,len)char *buf, *tbufp;int *len;{ int addrlen, etherhdrlen; struct llc_snap_hdr *snap_hdr; short *intp; /* * copy over DA and SA */ addrlen = sizeof(struct ether_addr) * 2; etherhdrlen = addrlen + sizeof(short); bcopy(buf, (char *)tbufp, addrlen); /* DA,SA */ /* * copy over ISO lsap_snap header * for ISO compatibility */ tbufp += addrlen; snap_hdr = (struct llc_snap_hdr *)(tbufp); snap_hdr->d_lsap = 0xaa; snap_hdr->s_lsap = 0xaa; snap_hdr->control = CNTL_LLC_UI; /* un-numbered information packet */ snap_hdr->org[0] = 0x0; snap_hdr->org[1] = 0x0; snap_hdr->org[2] = 0x0; intp = (short *)(buf + addrlen); snap_hdr->type = (u_short)*intp; /* stuff in type of packet */ tbufp += LLC_SNAP_HDR_LEN; /* * copy over rest of data and adjust len */ bcopy(buf+etherhdrlen, tbufp, *len - etherhdrlen); /* Data */ *len += LLC_SNAP_HDR_LEN;} /* add_llc_hdr *//* * strip_llc_hdr - strips an llc header from frames received. * see above diagram for packet formats. */voidstrip_llc_hdr(tbufp,buf,len)char *tbufp, *buf;int *len;{ int addrlen; addrlen = sizeof(struct ether_addr) * 2; bcopy((char *)tbufp, buf, addrlen); /* DA SA */ tbufp += addrlen; /* * note that this second bcopy skews over the llcp_snap_hdr saving * the type field at the end of the llc header */ *len = *len - LLC_SNAP_HDR_LEN + sizeof(short); bcopy((char *)tbufp+(LLC_SNAP_HDR_LEN - sizeof(short)), buf+addrlen, *len - addrlen); /* Data&type */} /* strip_llc_hdr */llcp_get_status(llcptr, treg) /* get controller status */llcp_info_t *llcptr;llcp_reg_t *treg;{ *treg = *llcptr->regp;} /* llcp_get_status */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -