Path: blob/main/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c
39566 views
/*-1* SPDX-License-Identifier: ISC2*3* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting4* Copyright (c) 2002-2006 Atheros Communications, Inc.5*6* Permission to use, copy, modify, and/or distribute this software for any7* purpose with or without fee is hereby granted, provided that the above8* copyright notice and this permission notice appear in all copies.9*10* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES11* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF12* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR13* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES14* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN15* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF16* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.17*/18#include "opt_ah.h"1920#include "ah.h"21#include "ah_internal.h"22#include "ah_devid.h"2324#include "ar5211/ar5211.h"25#include "ar5211/ar5211reg.h"26#include "ar5211/ar5211phy.h"2728#include "ah_eeprom_v3.h"2930static HAL_BOOL ar5211GetChannelEdges(struct ath_hal *ah,31uint16_t flags, uint16_t *low, uint16_t *high);32static HAL_BOOL ar5211GetChipPowerLimits(struct ath_hal *ah,33struct ieee80211_channel *chan);3435static void ar5211ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore,36HAL_BOOL power_off);37static void ar5211DisablePCIE(struct ath_hal *ah);3839static const struct ath_hal_private ar5211hal = {{40.ah_magic = AR5211_MAGIC,4142.ah_getRateTable = ar5211GetRateTable,43.ah_detach = ar5211Detach,4445/* Reset Functions */46.ah_reset = ar5211Reset,47.ah_phyDisable = ar5211PhyDisable,48.ah_disable = ar5211Disable,49.ah_configPCIE = ar5211ConfigPCIE,50.ah_disablePCIE = ar5211DisablePCIE,51.ah_setPCUConfig = ar5211SetPCUConfig,52.ah_perCalibration = ar5211PerCalibration,53.ah_perCalibrationN = ar5211PerCalibrationN,54.ah_resetCalValid = ar5211ResetCalValid,55.ah_setTxPowerLimit = ar5211SetTxPowerLimit,56.ah_getChanNoise = ath_hal_getChanNoise,5758/* Transmit functions */59.ah_updateTxTrigLevel = ar5211UpdateTxTrigLevel,60.ah_setupTxQueue = ar5211SetupTxQueue,61.ah_setTxQueueProps = ar5211SetTxQueueProps,62.ah_getTxQueueProps = ar5211GetTxQueueProps,63.ah_releaseTxQueue = ar5211ReleaseTxQueue,64.ah_resetTxQueue = ar5211ResetTxQueue,65.ah_getTxDP = ar5211GetTxDP,66.ah_setTxDP = ar5211SetTxDP,67.ah_numTxPending = ar5211NumTxPending,68.ah_startTxDma = ar5211StartTxDma,69.ah_stopTxDma = ar5211StopTxDma,70.ah_setupTxDesc = ar5211SetupTxDesc,71.ah_setupXTxDesc = ar5211SetupXTxDesc,72.ah_fillTxDesc = ar5211FillTxDesc,73.ah_procTxDesc = ar5211ProcTxDesc,74.ah_getTxIntrQueue = ar5211GetTxIntrQueue,75.ah_reqTxIntrDesc = ar5211IntrReqTxDesc,76.ah_getTxCompletionRates = ar5211GetTxCompletionRates,77.ah_setTxDescLink = ar5211SetTxDescLink,78.ah_getTxDescLink = ar5211GetTxDescLink,79.ah_getTxDescLinkPtr = ar5211GetTxDescLinkPtr,8081/* RX Functions */82.ah_getRxDP = ar5211GetRxDP,83.ah_setRxDP = ar5211SetRxDP,84.ah_enableReceive = ar5211EnableReceive,85.ah_stopDmaReceive = ar5211StopDmaReceive,86.ah_startPcuReceive = ar5211StartPcuReceive,87.ah_stopPcuReceive = ar5211StopPcuReceive,88.ah_setMulticastFilter = ar5211SetMulticastFilter,89.ah_setMulticastFilterIndex = ar5211SetMulticastFilterIndex,90.ah_clrMulticastFilterIndex = ar5211ClrMulticastFilterIndex,91.ah_getRxFilter = ar5211GetRxFilter,92.ah_setRxFilter = ar5211SetRxFilter,93.ah_setupRxDesc = ar5211SetupRxDesc,94.ah_procRxDesc = ar5211ProcRxDesc,95.ah_rxMonitor = ar5211RxMonitor,96.ah_aniPoll = ar5211AniPoll,97.ah_procMibEvent = ar5211MibEvent,9899/* Misc Functions */100.ah_getCapability = ar5211GetCapability,101.ah_setCapability = ar5211SetCapability,102.ah_getDiagState = ar5211GetDiagState,103.ah_getMacAddress = ar5211GetMacAddress,104.ah_setMacAddress = ar5211SetMacAddress,105.ah_getBssIdMask = ar5211GetBssIdMask,106.ah_setBssIdMask = ar5211SetBssIdMask,107.ah_setRegulatoryDomain = ar5211SetRegulatoryDomain,108.ah_setLedState = ar5211SetLedState,109.ah_writeAssocid = ar5211WriteAssocid,110.ah_gpioCfgInput = ar5211GpioCfgInput,111.ah_gpioCfgOutput = ar5211GpioCfgOutput,112.ah_gpioGet = ar5211GpioGet,113.ah_gpioSet = ar5211GpioSet,114.ah_gpioSetIntr = ar5211GpioSetIntr,115.ah_getTsf32 = ar5211GetTsf32,116.ah_getTsf64 = ar5211GetTsf64,117.ah_resetTsf = ar5211ResetTsf,118.ah_detectCardPresent = ar5211DetectCardPresent,119.ah_updateMibCounters = ar5211UpdateMibCounters,120.ah_getRfGain = ar5211GetRfgain,121.ah_getDefAntenna = ar5211GetDefAntenna,122.ah_setDefAntenna = ar5211SetDefAntenna,123.ah_getAntennaSwitch = ar5211GetAntennaSwitch,124.ah_setAntennaSwitch = ar5211SetAntennaSwitch,125.ah_setSifsTime = ar5211SetSifsTime,126.ah_getSifsTime = ar5211GetSifsTime,127.ah_setSlotTime = ar5211SetSlotTime,128.ah_getSlotTime = ar5211GetSlotTime,129.ah_setAckTimeout = ar5211SetAckTimeout,130.ah_getAckTimeout = ar5211GetAckTimeout,131.ah_setAckCTSRate = ar5211SetAckCTSRate,132.ah_getAckCTSRate = ar5211GetAckCTSRate,133.ah_setCTSTimeout = ar5211SetCTSTimeout,134.ah_getCTSTimeout = ar5211GetCTSTimeout,135.ah_setDecompMask = ar5211SetDecompMask,136.ah_setCoverageClass = ar5211SetCoverageClass,137.ah_setQuiet = ar5211SetQuiet,138.ah_get11nExtBusy = ar5211Get11nExtBusy,139.ah_getMibCycleCounts = ar5211GetMibCycleCounts,140.ah_setChainMasks = ar5211SetChainMasks,141.ah_enableDfs = ar5211EnableDfs,142.ah_getDfsThresh = ar5211GetDfsThresh,143/* XXX procRadarEvent */144/* XXX isFastClockEnabled */145.ah_setNav = ar5211SetNav,146.ah_getNav = ar5211GetNav,147148/* Key Cache Functions */149.ah_getKeyCacheSize = ar5211GetKeyCacheSize,150.ah_resetKeyCacheEntry = ar5211ResetKeyCacheEntry,151.ah_isKeyCacheEntryValid = ar5211IsKeyCacheEntryValid,152.ah_setKeyCacheEntry = ar5211SetKeyCacheEntry,153.ah_setKeyCacheEntryMac = ar5211SetKeyCacheEntryMac,154155/* Power Management Functions */156.ah_setPowerMode = ar5211SetPowerMode,157.ah_getPowerMode = ar5211GetPowerMode,158159/* Beacon Functions */160.ah_setBeaconTimers = ar5211SetBeaconTimers,161.ah_beaconInit = ar5211BeaconInit,162.ah_setStationBeaconTimers = ar5211SetStaBeaconTimers,163.ah_resetStationBeaconTimers = ar5211ResetStaBeaconTimers,164.ah_getNextTBTT = ar5211GetNextTBTT,165166/* Interrupt Functions */167.ah_isInterruptPending = ar5211IsInterruptPending,168.ah_getPendingInterrupts = ar5211GetPendingInterrupts,169.ah_getInterrupts = ar5211GetInterrupts,170.ah_setInterrupts = ar5211SetInterrupts },171172.ah_getChannelEdges = ar5211GetChannelEdges,173.ah_getWirelessModes = ar5211GetWirelessModes,174.ah_eepromRead = ar5211EepromRead,175#ifdef AH_SUPPORT_WRITE_EEPROM176.ah_eepromWrite = ar5211EepromWrite,177#endif178.ah_getChipPowerLimits = ar5211GetChipPowerLimits,179};180181static HAL_BOOL ar5211ChipTest(struct ath_hal *);182static HAL_BOOL ar5211FillCapabilityInfo(struct ath_hal *ah);183184/*185* Return the revsion id for the radio chip. This186* fetched via the PHY.187*/188static uint32_t189ar5211GetRadioRev(struct ath_hal *ah)190{191uint32_t val;192int i;193194OS_REG_WRITE(ah, (AR_PHY_BASE + (0x34 << 2)), 0x00001c16);195for (i = 0; i < 8; i++)196OS_REG_WRITE(ah, (AR_PHY_BASE + (0x20 << 2)), 0x00010000);197val = (OS_REG_READ(ah, AR_PHY_BASE + (256 << 2)) >> 24) & 0xff;198val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);199return ath_hal_reverseBits(val, 8);200}201202/*203* Attach for an AR5211 part.204*/205static struct ath_hal *206ar5211Attach(uint16_t devid, HAL_SOFTC sc,207HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,208HAL_OPS_CONFIG *ah_config, HAL_STATUS *status)209{210#define N(a) (sizeof(a)/sizeof(a[0]))211struct ath_hal_5211 *ahp;212struct ath_hal *ah;213uint32_t val;214uint16_t eeval;215HAL_STATUS ecode;216217HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH, "%s: sc %p st %p sh %p\n",218__func__, sc, (void*) st, (void*) sh);219220/* NB: memory is returned zero'd */221ahp = ath_hal_malloc(sizeof (struct ath_hal_5211));222if (ahp == AH_NULL) {223HALDEBUG(AH_NULL, HAL_DEBUG_ANY,224"%s: cannot allocate memory for state block\n", __func__);225ecode = HAL_ENOMEM;226goto bad;227}228ah = &ahp->ah_priv.h;229/* set initial values */230OS_MEMCPY(&ahp->ah_priv, &ar5211hal, sizeof(struct ath_hal_private));231ah->ah_sc = sc;232ah->ah_st = st;233ah->ah_sh = sh;234235ah->ah_devid = devid; /* NB: for AH_DEBUG_ALQ */236AH_PRIVATE(ah)->ah_devid = devid;237AH_PRIVATE(ah)->ah_subvendorid = 0; /* XXX */238239AH_PRIVATE(ah)->ah_powerLimit = MAX_RATE_POWER;240AH_PRIVATE(ah)->ah_tpScale = HAL_TP_SCALE_MAX; /* no scaling */241242ahp->ah_diversityControl = HAL_ANT_VARIABLE;243ahp->ah_staId1Defaults = 0;244ahp->ah_rssiThr = INIT_RSSI_THR;245ahp->ah_sifstime = (u_int) -1;246ahp->ah_slottime = (u_int) -1;247ahp->ah_acktimeout = (u_int) -1;248ahp->ah_ctstimeout = (u_int) -1;249250if (!ar5211ChipReset(ah, AH_NULL)) { /* reset chip */251HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n", __func__);252ecode = HAL_EIO;253goto bad;254}255if (AH_PRIVATE(ah)->ah_devid == AR5211_FPGA11B) {256/* set it back to OFDM mode to be able to read analog rev id */257OS_REG_WRITE(ah, AR5211_PHY_MODE, AR5211_PHY_MODE_OFDM);258OS_REG_WRITE(ah, AR_PHY_PLL_CTL, AR_PHY_PLL_CTL_44);259OS_DELAY(1000);260}261262/* Read Revisions from Chips */263val = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID_M;264AH_PRIVATE(ah)->ah_macVersion = val >> AR_SREV_ID_S;265AH_PRIVATE(ah)->ah_macRev = val & AR_SREV_REVISION_M;266267if (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_MAUI_2 ||268AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_OAHU) {269HALDEBUG(ah, HAL_DEBUG_ANY,270"%s: Mac Chip Rev 0x%x is not supported by this driver\n",271__func__, AH_PRIVATE(ah)->ah_macVersion);272ecode = HAL_ENOTSUPP;273goto bad;274}275276AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIP_ID);277278if (!ar5211ChipTest(ah)) {279HALDEBUG(ah, HAL_DEBUG_ANY, "%s: hardware self-test failed\n",280__func__);281ecode = HAL_ESELFTEST;282goto bad;283}284285/* Set correct Baseband to analog shift setting to access analog chips. */286if (AH_PRIVATE(ah)->ah_macVersion >= AR_SREV_VERSION_OAHU) {287OS_REG_WRITE(ah, AR_PHY_BASE, 0x00000007);288} else {289OS_REG_WRITE(ah, AR_PHY_BASE, 0x00000047);290}291OS_DELAY(2000);292293/* Read Radio Chip Rev Extract */294AH_PRIVATE(ah)->ah_analog5GhzRev = ar5211GetRadioRev(ah);295if ((AH_PRIVATE(ah)->ah_analog5GhzRev & 0xf0) != RAD5_SREV_MAJOR) {296HALDEBUG(ah, HAL_DEBUG_ANY,297"%s: 5G Radio Chip Rev 0x%02X is not supported by this "298"driver\n", __func__, AH_PRIVATE(ah)->ah_analog5GhzRev);299ecode = HAL_ENOTSUPP;300goto bad;301}302303val = (OS_REG_READ(ah, AR_PCICFG) & AR_PCICFG_EEPROM_SIZE_M) >>304AR_PCICFG_EEPROM_SIZE_S;305if (val != AR_PCICFG_EEPROM_SIZE_16K) {306HALDEBUG(ah, HAL_DEBUG_ANY, "%s: unsupported EEPROM size "307"%u (0x%x) found\n", __func__, val, val);308ecode = HAL_EESIZE;309goto bad;310}311ecode = ath_hal_legacyEepromAttach(ah);312if (ecode != HAL_OK) {313goto bad;314}315316/* If Bmode and AR5211, verify 2.4 analog exists */317if (AH_PRIVATE(ah)->ah_macVersion >= AR_SREV_VERSION_OAHU &&318ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) {319/* Set correct Baseband to analog shift setting to access analog chips. */320OS_REG_WRITE(ah, AR_PHY_BASE, 0x00004007);321OS_DELAY(2000);322AH_PRIVATE(ah)->ah_analog2GhzRev = ar5211GetRadioRev(ah);323324/* Set baseband for 5GHz chip */325OS_REG_WRITE(ah, AR_PHY_BASE, 0x00000007);326OS_DELAY(2000);327if ((AH_PRIVATE(ah)->ah_analog2GhzRev & 0xF0) != RAD2_SREV_MAJOR) {328HALDEBUG(ah, HAL_DEBUG_ANY,329"%s: 2G Radio Chip Rev 0x%x is not supported by "330"this driver\n", __func__,331AH_PRIVATE(ah)->ah_analog2GhzRev);332ecode = HAL_ENOTSUPP;333goto bad;334}335} else {336ath_hal_eepromSet(ah, AR_EEP_BMODE, AH_FALSE);337}338339ecode = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, &eeval);340if (ecode != HAL_OK) {341HALDEBUG(ah, HAL_DEBUG_ANY,342"%s: cannot read regulatory domain from EEPROM\n",343__func__);344goto bad;345}346AH_PRIVATE(ah)->ah_currentRD = eeval;347AH_PRIVATE(ah)->ah_getNfAdjust = ar5211GetNfAdjust;348349/*350* Got everything we need now to setup the capabilities.351*/352(void) ar5211FillCapabilityInfo(ah);353354/* Initialize gain ladder thermal calibration structure */355ar5211InitializeGainValues(ah);356357ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);358if (ecode != HAL_OK) {359HALDEBUG(ah, HAL_DEBUG_ANY,360"%s: error getting mac address from EEPROM\n", __func__);361goto bad;362}363364HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);365366return ah;367bad:368if (ahp)369ar5211Detach((struct ath_hal *) ahp);370if (status)371*status = ecode;372return AH_NULL;373#undef N374}375376void377ar5211Detach(struct ath_hal *ah)378{379HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s:\n", __func__);380381HALASSERT(ah != AH_NULL);382HALASSERT(ah->ah_magic == AR5211_MAGIC);383384ath_hal_eepromDetach(ah);385ath_hal_free(ah);386}387388static HAL_BOOL389ar5211ChipTest(struct ath_hal *ah)390{391uint32_t regAddr[2] = { AR_STA_ID0, AR_PHY_BASE+(8 << 2) };392uint32_t regHold[2];393uint32_t patternData[4] =394{ 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999 };395int i, j;396397/* Test PHY & MAC registers */398for (i = 0; i < 2; i++) {399uint32_t addr = regAddr[i];400uint32_t wrData, rdData;401402regHold[i] = OS_REG_READ(ah, addr);403for (j = 0; j < 0x100; j++) {404wrData = (j << 16) | j;405OS_REG_WRITE(ah, addr, wrData);406rdData = OS_REG_READ(ah, addr);407if (rdData != wrData) {408HALDEBUG(ah, HAL_DEBUG_ANY,409"%s: address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",410__func__, addr, wrData, rdData);411return AH_FALSE;412}413}414for (j = 0; j < 4; j++) {415wrData = patternData[j];416OS_REG_WRITE(ah, addr, wrData);417rdData = OS_REG_READ(ah, addr);418if (wrData != rdData) {419HALDEBUG(ah, HAL_DEBUG_ANY,420"%s: address test failed addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",421__func__, addr, wrData, rdData);422return AH_FALSE;423}424}425OS_REG_WRITE(ah, regAddr[i], regHold[i]);426}427OS_DELAY(100);428return AH_TRUE;429}430431/*432* Store the channel edges for the requested operational mode433*/434static HAL_BOOL435ar5211GetChannelEdges(struct ath_hal *ah,436uint16_t flags, uint16_t *low, uint16_t *high)437{438if (flags & IEEE80211_CHAN_5GHZ) {439*low = 4920;440*high = 6100;441return AH_TRUE;442}443if (flags & IEEE80211_CHAN_2GHZ &&444ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) {445*low = 2312;446*high = 2732;447return AH_TRUE;448}449return AH_FALSE;450}451452static HAL_BOOL453ar5211GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan)454{455/* XXX fill in, this is just a placeholder */456HALDEBUG(ah, HAL_DEBUG_ATTACH,457"%s: no min/max power for %u/0x%x\n",458__func__, chan->ic_freq, chan->ic_flags);459chan->ic_maxpower = MAX_RATE_POWER;460chan->ic_minpower = 0;461return AH_TRUE;462}463464static void465ar5211ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore, HAL_BOOL power_off)466{467}468469static void470ar5211DisablePCIE(struct ath_hal *ah)471{472}473474/*475* Fill all software cached or static hardware state information.476*/477static HAL_BOOL478ar5211FillCapabilityInfo(struct ath_hal *ah)479{480struct ath_hal_private *ahpriv = AH_PRIVATE(ah);481HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;482483/* Construct wireless mode from EEPROM */484pCap->halWirelessModes = 0;485if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) {486pCap->halWirelessModes |= HAL_MODE_11A;487if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO5DISABLE))488pCap->halWirelessModes |= HAL_MODE_TURBO;489}490if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE))491pCap->halWirelessModes |= HAL_MODE_11B;492493pCap->halLow2GhzChan = 2312;494pCap->halHigh2GhzChan = 2732;495pCap->halLow5GhzChan = 4920;496pCap->halHigh5GhzChan = 6100;497498pCap->halChanSpreadSupport = AH_TRUE;499pCap->halSleepAfterBeaconBroken = AH_TRUE;500pCap->halPSPollBroken = AH_TRUE;501pCap->halVEOLSupport = AH_TRUE;502pCap->halNumMRRetries = 1; /* No hardware MRR support */503pCap->halNumTxMaps = 1; /* Single TX ptr per descr */504505pCap->halTotalQueues = HAL_NUM_TX_QUEUES;506pCap->halKeyCacheSize = 128;507508/* XXX not needed */509pCap->halChanHalfRate = AH_FALSE;510pCap->halChanQuarterRate = AH_FALSE;511512/*513* RSSI uses the combined field; some 11n NICs may use514* the control chain RSSI.515*/516pCap->halUseCombinedRadarRssi = AH_TRUE;517518if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL) &&519ath_hal_eepromGet(ah, AR_EEP_RFSILENT, &ahpriv->ah_rfsilent) == HAL_OK) {520/* NB: enabled by default */521ahpriv->ah_rfkillEnabled = AH_TRUE;522pCap->halRfSilentSupport = AH_TRUE;523}524525pCap->halRxTstampPrecision = 13;526pCap->halTxTstampPrecision = 16;527pCap->halIntrMask = HAL_INT_COMMON528| HAL_INT_RX529| HAL_INT_TX530| HAL_INT_FATAL531| HAL_INT_BNR532| HAL_INT_TIM533;534535pCap->hal4kbSplitTransSupport = AH_TRUE;536pCap->halHasRxSelfLinkedTail = AH_TRUE;537538/* XXX might be ok w/ some chip revs */539ahpriv->ah_rxornIsFatal = AH_TRUE;540return AH_TRUE;541}542543static const char*544ar5211Probe(uint16_t vendorid, uint16_t devid)545{546if (vendorid == ATHEROS_VENDOR_ID) {547if (devid == AR5211_DEVID || devid == AR5311_DEVID ||548devid == AR5211_DEFAULT)549return "Atheros 5211";550if (devid == AR5211_FPGA11B)551return "Atheros 5211 (FPGA)";552}553return AH_NULL;554}555AH_CHIP(AR5211, ar5211Probe, ar5211Attach);556557558