📄 if_cs.c
字号:
printf ("\ncs%d - Can not connect interrupt\n", unit); return (ERROR); } /* Enable interrupt at the 8259 PIC */ CS_INT_ENABLE(pCs->intLevel, &result); if (result == ERROR) { printf ("\ncs%d - Can not enable interrupt\n", unit); return (ERROR); } /* Reset the chip */ if (csChipReset (pCs) == ERROR) { printf ("\ncs%d - Can not reset the chip\n", unit); return (ERROR); } /* Attach this network interface driver to the system */#ifdef BSD43_DRIVER ether_attach (&pCs->arpCom.ac_if, unit, "cs", csInit, csIoctl, csOutput, (FUNCPTR)csReset);#else ether_attach ( &pCs->arpCom.ac_if, unit, "cs", (FUNCPTR) csInit, (FUNCPTR) csIoctl, (FUNCPTR) ether_output, /* generic ether_output */ (FUNCPTR) csReset ); pCs->arpCom.ac_if.if_start = (FUNCPTR) csStartOutput; #endif return (OK); }/********************************************************************************* csChipVerify - verifies that the chip is present and correct** This routine verifies that the Ethernet chip is present and correct.** RETURNS: OK or ERROR*/LOCAL STATUS csChipVerify ( CS_SOFTC *pCs ) { USHORT eisaNumber = csPacketPageR (pCs, CS_PKTPG_EISA_NUM); /* Verify that we can read from the chip */ if (eisaNumber == 0xFFFF) { printf ("\ncs0 - Can't read from chip (I/O address correct?)\n"); return (ERROR); } /* Verify that the chip is a Crystal Semiconductor chip */ if (eisaNumber != CS_EISA_NUM_CRYSTAL) { printf ("\ncs0 - Chip is not a Crystal Semiconductor chip\n"); return (ERROR); } /* Verify that the chip is a CS8900 */ if ((csPacketPageR (pCs, CS_PKTPG_PRODUCT_ID) & CS_PROD_ID_MASK) != CS_PROD_ID_CS8900) { printf ("\ncs0 - Chip is not a CS8900\n"); return (ERROR); } return (OK); }/********************************************************************************* csParmsGet - gets parameters that were not specifed to csAttach()** This routine gets parameters, that were not specifed to csAttach(),* from the EEPROM and puts them in the cs_softc structure. If all the* parameters were specified to csAttach(), then this routine does* not attempt to read the EEPROM.** RETURNS: N/A*/LOCAL STATUS csParmsGet ( CS_SOFTC *pCs ) { USHORT selfStatus; USHORT isaConfig; USHORT memBase; USHORT adapterConfig; USHORT xmitCtl; /* If all of these parameters were specified */ if ((pCs->configFlags != 0) && (pCs->pPacketPage != NULL) && (pCs->intLevel != 0) && (pCs->mediaType != 0)) return (OK); /* Don't need to get anything from the EEPROM */ /* Verify that the EEPROM is present and OK */ selfStatus = csPacketPageR (pCs, CS_PKTPG_SELF_ST); if (!((selfStatus & CS_SELF_ST_EEP_PRES) && (selfStatus & CS_SELF_ST_EEP_OK))) { printf ("\ncs0 - EEPROM is missing or bad\n"); return (ERROR); } /* Get ISA configuration from the EEPROM */ if (csEepromRead (pCs, CS_EEPROM_ISA_CFG, &isaConfig) == ERROR) return (ERROR); /* Get adapter configuration from the EEPROM */ if (csEepromRead (pCs, CS_EEPROM_ADPTR_CFG, &adapterConfig) == ERROR) return (ERROR); /* Get transmission control from the EEPROM */ if (csEepromRead (pCs, CS_EEPROM_XMIT_CTL, &xmitCtl) == ERROR) return (ERROR); /* If the configuration flags were not specified */ if (pCs->configFlags == 0) { /* Copy the memory mode flag */ if (isaConfig & CS_ISA_CFG_MEM_MODE) pCs->configFlags |= CS_CFGFLG_MEM_MODE; /* Copy the USE_SA flag */ if (isaConfig & CS_ISA_CFG_USE_SA) pCs->configFlags |= CS_CFGFLG_USE_SA; /* Copy the IO Channel Ready flag */ if (isaConfig & CS_ISA_CFG_IOCHRDY) pCs->configFlags |= CS_CFGFLG_IOCHRDY; /* Copy the DC/DC Polarity flag */ if (adapterConfig & CS_ADPTR_CFG_DCDC_POL) pCs->configFlags |= CS_CFGFLG_DCDC_POL; /* Copy the Full Duplex flag */ if (xmitCtl & CS_XMIT_CTL_FDX) pCs->configFlags |= CS_CFGFLG_FDX; } /* If the PacketPage pointer was not specified */ if (pCs->pPacketPage == NULL) { /* If memory mode is enabled * Get the memory base address from EEPROM * Setup the PacketPage pointer */ if (pCs->configFlags & CS_CFGFLG_MEM_MODE) { if (csEepromRead (pCs, CS_EEPROM_MEM_BASE, &memBase) == ERROR) return (ERROR); memBase &= CS_MEM_BASE_MASK; /* Clear unused bits */ pCs->pPacketPage = (USHORT *)(((ULONG)memBase) << 8); } } /* If the interrupt level was not specified * Get the interrupt level from the IsaConfig */ if (pCs->intLevel == 0) { pCs->intLevel = isaConfig & CS_ISA_CFG_IRQ_MASK; if (pCs->intLevel == 3) pCs->intLevel = 5; else pCs->intLevel += 10; } /* If the media type was not specified * Get the media type from the adapterConfig */ if (pCs->mediaType == 0) { switch (adapterConfig & CS_ADPTR_CFG_MEDIA) { case CS_ADPTR_CFG_AUI: pCs->mediaType = CS_MEDIA_AUI; break; case CS_ADPTR_CFG_10BASE2: pCs->mediaType = CS_MEDIA_10BASE2; break; case CS_ADPTR_CFG_10BASET: default: pCs->mediaType = CS_MEDIA_10BASET; break; } } return (OK); }/********************************************************************************* csParmsValidate - validate the memory address, interrupt level and media type** This routine verifies that the memory address, interrupt level and media* type are valid. If any of these parameters are invalid, then and error* message is printed and ERROR is returned.** RETURNS: OK or ERROR*/LOCAL STATUS csParmsValidate ( CS_SOFTC *pCs ) { int memAddr = (int)(pCs->pPacketPage); if ((memAddr & 0x000FFF) != 0) { printf ("\ncs0 - Memory address (0x%X) must start on a 4K boundry\n", memAddr); return (ERROR); } if (memAddr > 0xFFF000) { printf ("\ncs0 - Memory address (0x%X) is too large\n", memAddr); return (ERROR); } if (!(pCs->intLevel==5 || pCs->intLevel==10 || pCs->intLevel==11 || pCs->intLevel==12)) { printf ("\ncs0 - Interrupt level (%d) is invalid\n", pCs->intLevel); return (ERROR); } if (!(pCs->mediaType==CS_MEDIA_AUI || pCs->mediaType==CS_MEDIA_10BASE2 || pCs->mediaType==CS_MEDIA_10BASET)) { printf ("\ncs0 - Media type (%d) is invalid\n", pCs->mediaType); return (ERROR); } return (OK); }/********************************************************************************* csEnetAddrGet - get the ethernet address from arguments or EEPROM** If a pointer to an Ethernet address string was passed-in to the csAttach()* routine, then this routine coverts the address string to an Ethernet address* and saves it in the arpcom structure. If an Ethernet address string was* not passed-in, then the Ethernet address is read from the EEPROM and saved* in the arpcom structure.** RETURNS: OK or ERROR*/LOCAL STATUS csEnetAddrGet ( CS_SOFTC *pCs, char *pEthernetAddr ) { USHORT selfStatus; CS_IA *pIA = (CS_IA *)pCs->arpCom.ac_enaddr; /* If the Ethernet address was not specified */ if (pEthernetAddr == NULL) { /* Verify that the EEPROM is present and OK */ selfStatus = csPacketPageR (pCs, CS_PKTPG_SELF_ST); if (!((selfStatus & CS_SELF_ST_EEP_PRES) && (selfStatus & CS_SELF_ST_EEP_OK))) { printf ("\ncs0 - EEPROM is missing or bad\n"); return (ERROR); } /* Get Ethernet address from the EEPROM */ if (csEepromRead (pCs, CS_EEPROM_IND_ADDR_H, &pIA->word[0]) == ERROR) return (ERROR); if (csEepromRead (pCs, CS_EEPROM_IND_ADDR_M, &pIA->word[1]) == ERROR) return (ERROR); if (csEepromRead (pCs, CS_EEPROM_IND_ADDR_L, &pIA->word[2]) == ERROR) return (ERROR); } else /* The Ethernet address was specified */ { /* Convert and save the Ethernet address string */ pEthernetAddr = csHexWord (pEthernetAddr, &pIA->word[0]); if (pEthernetAddr == NULL) return (ERROR); pEthernetAddr = csHexWord (pEthernetAddr, &pIA->word[1]); if (pEthernetAddr == NULL) return (ERROR); pEthernetAddr = csHexWord (pEthernetAddr, &pIA->word[2]); if (pEthernetAddr == NULL) return (ERROR); } return (OK); }/********************************************************************************* csHexWord - converts a sequence of hex characters to the 16-bit value** This routine converts a sequence of hex characters to the 16-bit value* that they represent. The address of the first hex character is passed* in the pChar parameter and the address just beyond the last hex* character is returned. The 16-bit variable pointed to by the pWord* parameter is updated with the converted 16-bit value. If an error* occurred then NULL is returned.** RETURNS: address of next character*/LOCAL char *csHexWord ( char *pChar, USHORT *pWord ) { union { USHORT word; UCHAR byte[2]; } value; /* Get the value of the first hex byte */ pChar = csHexByte (pChar, &value.byte[0]); if ((pChar != NULL) && (*pChar == 0)) printf ("\ncs0 - Ethernet address string too short\n"); if ((pChar == NULL) || (*pChar == 0)) return (NULL); /* Get the value of the second hex byte */ pChar = csHexByte (pChar, &value.byte[1]); if (pChar == NULL) return (NULL); /* Save value of the hex word */ *pWord = value.word; return (pChar); }/********************************************************************************* csHexByte - converts a sequence of hex characters to the 8-bit value** This routine converts a sequence of hex characters to the 8-bit value* that they represent. There may be zero, one or two hex characters and* they may be optionally terminated with a colon or a zero byte.* The address of the first hex character is passed in the pChar parameter* and the address just beyond the last hex character is returned.* The 8-bit variable pointed to by the pByte parameter is updated with* the converted 8-bit value. If an error occurred then NULL is returned.** RETURNS: address of next character*/LOCAL char *csHexByte ( char *pChar, UCHAR *pByte ) { int ix; /* Inititalize the byte value to zero */ *pByte = 0; /* Process two hex characters */ for (ix=0; ix<2; ix++, pChar++) { /* Stop early if find a colon or end of string */ if ((*pChar == ':') || (*pChar == 0)) break; /* Convert the hex character to a value */ if ((*pChar >= '0') && (*pChar <= '9')) *pByte = (*pByte * 16) + *pChar - '0'; else if ((*pChar >= 'a') && (*pChar <= 'f')) *pByte = (*pByte * 16) + *pChar - 'a' + 10; else if ((*pChar >= 'A') && (*pChar <= 'F')) *pByte = (*pByte * 16) + *pChar - 'A' + 10; else { printf ("\ncs0 - Illegal character '%c' in Enet address string\n", *pChar); return (NULL); /* Illegal character */ } } /* Skip past terminating colon */ if (*pChar == ':') pChar++; return (pChar); }/********************************************************************************* csEepromRead - reads a word from the EEPROM** This routine reads a word from the EEPROM at the specified offset.** RETURNS: OK or ERROR*/LOCAL STATUS csEepromRead ( CS_SOFTC *pCs, USHORT offset, USHORT *pValue ) { int ix; /* Ensure that the EEPROM is not busy */ for (ix=0; ix<CS_MAXLOOP; ix++) if (!(csPacketPageR (pCs, CS_PKTPG_SELF_ST) & CS_SELF_ST_SI_BUSY)) break; if (ix == CS_MAXLOOP) { printf ("\ncs0 - Can not read from EEPROM\n"); return (ERROR); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -