Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  eeprom.c   Sprache: C

 
/*
 * Copyright (c) 2008-2011 Atheros Communications Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */


#include "hw.h"

void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
{
        REG_WRITE(ah, reg, val);

        if (ah->config.analog_shiftreg)
  udelay(100);
}

void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
          u32 shift, u32 val)
{
 REG_RMW(ah, reg, ((val << shift) & mask), mask);

 if (ah->config.analog_shiftreg)
  udelay(100);
}

int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
        int16_t targetLeft, int16_t targetRight)
{
 int16_t rv;

 if (srcRight == srcLeft) {
  rv = targetLeft;
 } else {
  rv = (int16_t) (((target - srcLeft) * targetRight +
     (srcRight - target) * targetLeft) /
    (srcRight - srcLeft));
 }
 return rv;
}

bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
        u16 *indexL, u16 *indexR)
{
 u16 i;

 if (target <= pList[0]) {
  *indexL = *indexR = 0;
  return true;
 }
 if (target >= pList[listSize - 1]) {
  *indexL = *indexR = (u16) (listSize - 1);
  return true;
 }

 for (i = 0; i < listSize - 1; i++) {
  if (pList[i] == target) {
   *indexL = *indexR = i;
   return true;
  }
  if (target < pList[i + 1]) {
   *indexL = i;
   *indexR = (u16) (i + 1);
   return false;
  }
 }
 return false;
}

void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data,
      int eep_start_loc, int size)
{
 int i = 0, j, addr;
 u32 addrdata[8];
 u32 data[8];

 for (addr = 0; addr < size; addr++) {
  addrdata[i] = AR5416_EEPROM_OFFSET +
   ((addr + eep_start_loc) << AR5416_EEPROM_S);
  i++;
  if (i == 8) {
   REG_READ_MULTI(ah, addrdata, data, i);

   for (j = 0; j < i; j++) {
    *eep_data = data[j];
    eep_data++;
   }
   i = 0;
  }
 }

 if (i != 0) {
  REG_READ_MULTI(ah, addrdata, data, i);

  for (j = 0; j < i; j++) {
   *eep_data = data[j];
   eep_data++;
  }
 }
}

static bool ath9k_hw_nvram_read_array(u16 *blob, size_t blob_size,
          off_t offset, u16 *data)
{
 if (offset >= blob_size)
  return false;

 *data =  blob[offset];
 return true;
}

static bool ath9k_hw_nvram_read_firmware(const struct firmware *eeprom_blob,
      off_t offset, u16 *data)
{
 return ath9k_hw_nvram_read_array((u16 *) eeprom_blob->data,
      eeprom_blob->size / sizeof(u16),
      offset, data);
}

static bool ath9k_hw_nvram_read_nvmem(struct ath_hw *ah, off_t offset,
          u16 *data)
{
 return ath9k_hw_nvram_read_array(ah->nvmem_blob,
      ah->nvmem_blob_len / sizeof(u16),
      offset, data);
}

bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
{
 struct ath_common *common = ath9k_hw_common(ah);
 bool ret;

 if (ah->nvmem_blob)
  ret = ath9k_hw_nvram_read_nvmem(ah, off, data);
 else if (ah->eeprom_blob)
  ret = ath9k_hw_nvram_read_firmware(ah->eeprom_blob, off, data);
 else
  ret = common->bus_ops->eeprom_read(common, off, data);

 if (!ret)
  ath_dbg(common, EEPROM,
   "unable to read eeprom region at offset %u\n", off);

 return ret;
}

int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size)
{
 u16 magic;
 u16 *eepdata;
 int i;
 bool needs_byteswap = false;
 struct ath_common *common = ath9k_hw_common(ah);

 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
  ath_err(common, "Reading Magic # failed\n");
  return -EIO;
 }

 if (swab16(magic) == AR5416_EEPROM_MAGIC) {
  needs_byteswap = true;
  ath_dbg(common, EEPROM,
   "EEPROM needs byte-swapping to correct endianness.\n");
 } else if (magic != AR5416_EEPROM_MAGIC) {
  if (ath9k_hw_use_flash(ah)) {
   ath_dbg(common, EEPROM,
    "Ignoring invalid EEPROM magic (0x%04x).\n",
    magic);
  } else {
   ath_err(common,
    "Invalid EEPROM magic (0x%04x).\n", magic);
   return -EINVAL;
  }
 }

 if (needs_byteswap) {
  if (ah->ah_flags & AH_NO_EEP_SWAP) {
   ath_info(common,
     "Ignoring endianness difference in EEPROM magic bytes.\n");
  } else {
   eepdata = (u16 *)(&ah->eeprom);

   for (i = 0; i < size; i++)
    eepdata[i] = swab16(eepdata[i]);
  }
 }

 if (ah->eep_ops->get_eepmisc(ah) & AR5416_EEPMISC_BIG_ENDIAN) {
  *swap_needed = true;
  ath_dbg(common, EEPROM,
   "Big Endian EEPROM detected according to EEPMISC register.\n");
 } else {
  *swap_needed = false;
 }

 return 0;
}

bool ath9k_hw_nvram_validate_checksum(struct ath_hw *ah, int size)
{
 u32 i, sum = 0;
 u16 *eepdata = (u16 *)(&ah->eeprom);
 struct ath_common *common = ath9k_hw_common(ah);

 for (i = 0; i < size; i++)
  sum ^= eepdata[i];

 if (sum != 0xffff) {
  ath_err(common, "Bad EEPROM checksum 0x%x\n", sum);
  return false;
 }

 return true;
}

bool ath9k_hw_nvram_check_version(struct ath_hw *ah, int version, int minrev)
{
 struct ath_common *common = ath9k_hw_common(ah);

 if (ah->eep_ops->get_eeprom_ver(ah) != version ||
     ah->eep_ops->get_eeprom_rev(ah) < minrev) {
  ath_err(common, "Bad EEPROM VER 0x%04x or REV 0x%04x\n",
   ah->eep_ops->get_eeprom_ver(ah),
   ah->eep_ops->get_eeprom_rev(ah));
  return false;
 }

 return true;
}

void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
        u8 *pVpdList, u16 numIntercepts,
        u8 *pRetVpdList)
{
 u16 i, k;
 u8 currPwr = pwrMin;
 u16 idxL = 0, idxR = 0;

 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
  ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
            numIntercepts, &(idxL),
            &(idxR));
  if (idxR < 1)
   idxR = 1;
  if (idxL == numIntercepts - 1)
   idxL = (u16) (numIntercepts - 2);
  if (pPwrList[idxL] == pPwrList[idxR])
   k = pVpdList[idxL];
  else
   k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
       (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
      (pPwrList[idxR] - pPwrList[idxL]));
  pRetVpdList[i] = (u8) k;
  currPwr += 2;
 }
}

void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
           struct ath9k_channel *chan,
           struct cal_target_power_leg *powInfo,
           u16 numChannels,
           struct cal_target_power_leg *pNewPower,
           u16 numRates, bool isExtTarget)
{
 struct chan_centers centers;
 u16 clo, chi;
 int i;
 int matchIndex = -1, lowIndex = -1;
 u16 freq;

 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;

 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
           IS_CHAN_2GHZ(chan))) {
  matchIndex = 0;
 } else {
  for (i = 0; (i < numChannels) &&
        (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
   if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
             IS_CHAN_2GHZ(chan))) {
    matchIndex = i;
    break;
   } else if (freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
      IS_CHAN_2GHZ(chan)) && i > 0 &&
       freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
      IS_CHAN_2GHZ(chan))) {
    lowIndex = i - 1;
    break;
   }
  }
  if ((matchIndex == -1) && (lowIndex == -1))
   matchIndex = i - 1;
 }

 if (matchIndex != -1) {
  *pNewPower = powInfo[matchIndex];
 } else {
  clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
      IS_CHAN_2GHZ(chan));
  chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
      IS_CHAN_2GHZ(chan));

  for (i = 0; i < numRates; i++) {
   pNewPower->tPow2x[i] =
    (u8)ath9k_hw_interpolate(freq, clo, chi,
      powInfo[lowIndex].tPow2x[i],
      powInfo[lowIndex + 1].tPow2x[i]);
  }
 }
}

void ath9k_hw_get_target_powers(struct ath_hw *ah,
    struct ath9k_channel *chan,
    struct cal_target_power_ht *powInfo,
    u16 numChannels,
    struct cal_target_power_ht *pNewPower,
    u16 numRates, bool isHt40Target)
{
 struct chan_centers centers;
 u16 clo, chi;
 int i;
 int matchIndex = -1, lowIndex = -1;
 u16 freq;

 ath9k_hw_get_channel_centers(ah, chan, ¢ers);
 freq = isHt40Target ? centers.synth_center : centers.ctl_center;

 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
  matchIndex = 0;
 } else {
  for (i = 0; (i < numChannels) &&
        (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
   if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
             IS_CHAN_2GHZ(chan))) {
    matchIndex = i;
    break;
   } else
    if (freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
      IS_CHAN_2GHZ(chan)) && i > 0 &&
        freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
      IS_CHAN_2GHZ(chan))) {
     lowIndex = i - 1;
     break;
    }
  }
  if ((matchIndex == -1) && (lowIndex == -1))
   matchIndex = i - 1;
 }

 if (matchIndex != -1) {
  *pNewPower = powInfo[matchIndex];
 } else {
  clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
      IS_CHAN_2GHZ(chan));
  chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
      IS_CHAN_2GHZ(chan));

  for (i = 0; i < numRates; i++) {
   pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
      clo, chi,
      powInfo[lowIndex].tPow2x[i],
      powInfo[lowIndex + 1].tPow2x[i]);
  }
 }
}

u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
    bool is2GHz, int num_band_edges)
{
 u16 twiceMaxEdgePower = MAX_RATE_POWER;
 int i;

 for (i = 0; (i < num_band_edges) &&
       (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
  if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
   twiceMaxEdgePower = CTL_EDGE_TPOWER(pRdEdgesPower[i].ctl);
   break;
  } else if ((i > 0) &&
      (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
            is2GHz))) {
   if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
            is2GHz) < freq &&
       CTL_EDGE_FLAGS(pRdEdgesPower[i - 1].ctl)) {
    twiceMaxEdgePower =
     CTL_EDGE_TPOWER(pRdEdgesPower[i - 1].ctl);
   }
   break;
  }
 }

 return twiceMaxEdgePower;
}

u16 ath9k_hw_get_scaled_power(struct ath_hw *ah, u16 power_limit,
         u8 antenna_reduction)
{
 u16 reduction = antenna_reduction;

 /*
 * Reduce scaled Power by number of chains active
 * to get the per chain tx power level.
 */

 switch (ar5416_get_ntxchains(ah->txchainmask)) {
 case 1:
  break;
 case 2:
  reduction += POWER_CORRECTION_FOR_TWO_CHAIN;
  break;
 case 3:
  reduction += POWER_CORRECTION_FOR_THREE_CHAIN;
  break;
 }

 if (power_limit > reduction)
  power_limit -= reduction;
 else
  power_limit = 0;

 return min_t(u16, power_limit, MAX_RATE_POWER);
}

void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
{
 struct ath_common *common = ath9k_hw_common(ah);
 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);

 switch (ar5416_get_ntxchains(ah->txchainmask)) {
 case 1:
  break;
 case 2:
  regulatory->max_power_level += POWER_CORRECTION_FOR_TWO_CHAIN;
  break;
 case 3:
  regulatory->max_power_level += POWER_CORRECTION_FOR_THREE_CHAIN;
  break;
 default:
  ath_dbg(common, EEPROM, "Invalid chainmask configuration\n");
  break;
 }
}

void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
    struct ath9k_channel *chan,
    void *pRawDataSet,
    u8 *bChans, u16 availPiers,
    u16 tPdGainOverlap,
    u16 *pPdGainBoundaries, u8 *pPDADCValues,
    u16 numXpdGains)
{
 int i, j, k;
 int16_t ss;
 u16 idxL = 0, idxR = 0, numPiers;
 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
  [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
  [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
  [AR5416_MAX_PWR_RANGE_IN_HALF_DB];

 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
 u8 minPwrT4[AR5416_NUM_PD_GAINS];
 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
 int16_t vpdStep;
 int16_t tmpVal;
 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
 bool match;
 int16_t minDelta = 0;
 struct chan_centers centers;
 int pdgain_boundary_default;
 struct cal_data_per_freq *data_def = pRawDataSet;
 struct cal_data_per_freq_4k *data_4k = pRawDataSet;
 struct cal_data_per_freq_ar9287 *data_9287 = pRawDataSet;
 bool eeprom_4k = AR_SREV_9285(ah) || AR_SREV_9271(ah);
 int intercepts;

 if (AR_SREV_9287(ah))
  intercepts = AR9287_PD_GAIN_ICEPTS;
 else
  intercepts = AR5416_PD_GAIN_ICEPTS;

 memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS);
 ath9k_hw_get_channel_centers(ah, chan, ¢ers);

 for (numPiers = 0; numPiers < availPiers; numPiers++) {
  if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
   break;
 }

 match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
            IS_CHAN_2GHZ(chan)),
            bChans, numPiers, &idxL, &idxR);

 if (match) {
  if (AR_SREV_9287(ah)) {
   for (i = 0; i < numXpdGains; i++) {
    minPwrT4[i] = data_9287[idxL].pwrPdg[i][0];
    maxPwrT4[i] = data_9287[idxL].pwrPdg[i][intercepts - 1];
    ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
      data_9287[idxL].pwrPdg[i],
      data_9287[idxL].vpdPdg[i],
      intercepts,
      vpdTableI[i]);
   }
  } else if (eeprom_4k) {
   for (i = 0; i < numXpdGains; i++) {
    minPwrT4[i] = data_4k[idxL].pwrPdg[i][0];
    maxPwrT4[i] = data_4k[idxL].pwrPdg[i][intercepts - 1];
    ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
      data_4k[idxL].pwrPdg[i],
      data_4k[idxL].vpdPdg[i],
      intercepts,
      vpdTableI[i]);
   }
  } else {
   for (i = 0; i < numXpdGains; i++) {
    minPwrT4[i] = data_def[idxL].pwrPdg[i][0];
    maxPwrT4[i] = data_def[idxL].pwrPdg[i][intercepts - 1];
    ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
      data_def[idxL].pwrPdg[i],
      data_def[idxL].vpdPdg[i],
      intercepts,
      vpdTableI[i]);
   }
  }
 } else {
  for (i = 0; i < numXpdGains; i++) {
   if (AR_SREV_9287(ah)) {
    pVpdL = data_9287[idxL].vpdPdg[i];
    pPwrL = data_9287[idxL].pwrPdg[i];
    pVpdR = data_9287[idxR].vpdPdg[i];
    pPwrR = data_9287[idxR].pwrPdg[i];
   } else if (eeprom_4k) {
    pVpdL = data_4k[idxL].vpdPdg[i];
    pPwrL = data_4k[idxL].pwrPdg[i];
    pVpdR = data_4k[idxR].vpdPdg[i];
    pPwrR = data_4k[idxR].pwrPdg[i];
   } else {
    pVpdL = data_def[idxL].vpdPdg[i];
    pPwrL = data_def[idxL].pwrPdg[i];
    pVpdR = data_def[idxR].vpdPdg[i];
    pPwrR = data_def[idxR].pwrPdg[i];
   }

   minPwrT4[i] = max(pPwrL[0], pPwrR[0]);

   maxPwrT4[i] =
    min(pPwrL[intercepts - 1],
        pPwrR[intercepts - 1]);


   ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
      pPwrL, pVpdL,
      intercepts,
      vpdTableL[i]);
   ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
      pPwrR, pVpdR,
      intercepts,
      vpdTableR[i]);

   for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
    vpdTableI[i][j] =
     (u8)(ath9k_hw_interpolate((u16)
          FREQ2FBIN(centers.
             synth_center,
             IS_CHAN_2GHZ
             (chan)),
          bChans[idxL], bChans[idxR],
          vpdTableL[i][j], vpdTableR[i][j]));
   }
  }
 }

 k = 0;

 for (i = 0; i < numXpdGains; i++) {
  if (i == (numXpdGains - 1))
   pPdGainBoundaries[i] =
    (u16)(maxPwrT4[i] / 2);
  else
   pPdGainBoundaries[i] =
    (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);

  pPdGainBoundaries[i] =
   min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]);

  minDelta = 0;

  if (i == 0) {
   if (AR_SREV_9280_20_OR_LATER(ah))
    ss = (int16_t)(0 - (minPwrT4[i] / 2));
   else
    ss = 0;
  } else {
   ss = (int16_t)((pPdGainBoundaries[i - 1] -
     (minPwrT4[i] / 2)) -
           tPdGainOverlap + 1 + minDelta);
  }
  vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
  vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);

  while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
   tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
   pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
   ss++;
  }

  sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
  tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
    (minPwrT4[i] / 2));
  maxIndex = (tgtIndex < sizeCurrVpdTable) ?
   tgtIndex : sizeCurrVpdTable;

  while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
   pPDADCValues[k++] = vpdTableI[i][ss++];
  }

  vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
        vpdTableI[i][sizeCurrVpdTable - 2]);
  vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);

  if (tgtIndex >= maxIndex) {
   while ((ss <= tgtIndex) &&
          (k < (AR5416_NUM_PDADC_VALUES - 1))) {
    tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
          (ss - maxIndex + 1) * vpdStep));
    pPDADCValues[k++] = (u8)((tmpVal > 255) ?
        255 : tmpVal);
    ss++;
   }
  }
 }

 if (eeprom_4k)
  pdgain_boundary_default = 58;
 else
  pdgain_boundary_default = pPdGainBoundaries[i - 1];

 while (i < AR5416_PD_GAINS_IN_MASK) {
  pPdGainBoundaries[i] = pdgain_boundary_default;
  i++;
 }

 while (k < AR5416_NUM_PDADC_VALUES) {
  pPDADCValues[k] = pPDADCValues[k - 1];
  k++;
 }
}

int ath9k_hw_eeprom_init(struct ath_hw *ah)
{
 if (AR_SREV_9300_20_OR_LATER(ah))
  ah->eep_ops = &eep_ar9300_ops;
 else if (AR_SREV_9287(ah)) {
  ah->eep_ops = &eep_ar9287_ops;
 } else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
  ah->eep_ops = &eep_4k_ops;
 } else {
  ah->eep_ops = &eep_def_ops;
 }

 if (!ah->eep_ops->fill_eeprom(ah))
  return -EIO;

 return ah->eep_ops->check_eeprom(ah);
}

Messung V0.5
C=100 H=82 G=91

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge