Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/net/ethernet/pensando/ionic/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 5 kB image not shown  

Quelle  ionic_fw.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2020 Pensando Systems, Inc */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/firmware.h>

#include "ionic.h"
#include "ionic_dev.h"
#include "ionic_lif.h"
#include "ionic_devlink.h"

/* The worst case wait for the install activity is about 25 minutes when
 * installing a new CPLD, which is very seldom.  Normal is about 30-35
 * seconds.  Since the driver can't tell if a CPLD update will happen we
 * set the timeout for the ugly case.
 */

#define IONIC_FW_INSTALL_TIMEOUT (25 * 60)
#define IONIC_FW_SELECT_TIMEOUT  30

/* Number of periodic log updates during fw file download */
#define IONIC_FW_INTERVAL_FRACTION 32

static void ionic_dev_cmd_firmware_download(struct ionic_dev *idev, u64 addr,
         u32 offset, u32 length)
{
 union ionic_dev_cmd cmd = {
  .fw_download.opcode = IONIC_CMD_FW_DOWNLOAD,
  .fw_download.offset = cpu_to_le32(offset),
  .fw_download.addr = cpu_to_le64(addr),
  .fw_download.length = cpu_to_le32(length),
 };

 ionic_dev_cmd_go(idev, &cmd);
}

static void ionic_dev_cmd_firmware_install(struct ionic_dev *idev)
{
 union ionic_dev_cmd cmd = {
  .fw_control.opcode = IONIC_CMD_FW_CONTROL,
  .fw_control.oper = IONIC_FW_INSTALL_ASYNC
 };

 ionic_dev_cmd_go(idev, &cmd);
}

static void ionic_dev_cmd_firmware_activate(struct ionic_dev *idev, u8 slot)
{
 union ionic_dev_cmd cmd = {
  .fw_control.opcode = IONIC_CMD_FW_CONTROL,
  .fw_control.oper = IONIC_FW_ACTIVATE_ASYNC,
  .fw_control.slot = slot
 };

 ionic_dev_cmd_go(idev, &cmd);
}

static int ionic_fw_status_long_wait(struct ionic *ionic,
         const char *label,
         unsigned long timeout,
         u8 fw_cmd,
         struct netlink_ext_ack *extack)
{
 union ionic_dev_cmd cmd = {
  .fw_control.opcode = IONIC_CMD_FW_CONTROL,
  .fw_control.oper = fw_cmd,
 };
 unsigned long start_time;
 unsigned long end_time;
 int err;

 start_time = jiffies;
 end_time = start_time + (timeout * HZ);
 do {
  mutex_lock(&ionic->dev_cmd_lock);
  ionic_dev_cmd_go(&ionic->idev, &cmd);
  err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
  mutex_unlock(&ionic->dev_cmd_lock);

  msleep(20);
 } while (time_before(jiffies, end_time) && (err == -EAGAIN || err == -ETIMEDOUT));

 if (err == -EAGAIN || err == -ETIMEDOUT) {
  NL_SET_ERR_MSG_MOD(extack, "Firmware wait timed out");
  dev_err(ionic->dev, "DEV_CMD firmware wait %s timed out\n", label);
 } else if (err) {
  NL_SET_ERR_MSG_MOD(extack, "Firmware wait failed");
 }

 return err;
}

int ionic_firmware_update(struct ionic_lif *lif, const struct firmware *fw,
     struct netlink_ext_ack *extack)
{
 struct ionic_dev *idev = &lif->ionic->idev;
 struct net_device *netdev = lif->netdev;
 struct ionic *ionic = lif->ionic;
 union ionic_dev_cmd_comp comp;
 u32 buf_sz, copy_sz, offset;
 struct devlink *dl;
 int next_interval;
 int err = 0;
 u8 fw_slot;

 netdev_info(netdev, "Installing firmware\n");

 dl = priv_to_devlink(ionic);
 devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0);

 if (!idev->dev_cmd_regs) {
  err = -ENXIO;
  goto err_out;
 }

 buf_sz = sizeof(idev->dev_cmd_regs->data);

 netdev_dbg(netdev,
     "downloading firmware - size %d part_sz %d nparts %lu\n",
     (int)fw->size, buf_sz, DIV_ROUND_UP(fw->size, buf_sz));

 offset = 0;
 next_interval = 0;
 while (offset < fw->size) {
  if (offset >= next_interval) {
   devlink_flash_update_status_notify(dl, "Downloading", NULL,
          offset, fw->size);
   next_interval = offset + (fw->size / IONIC_FW_INTERVAL_FRACTION);
  }

  copy_sz = min_t(unsigned int, buf_sz, fw->size - offset);
  mutex_lock(&ionic->dev_cmd_lock);
  memcpy_toio(&idev->dev_cmd_regs->data, fw->data + offset, copy_sz);
  ionic_dev_cmd_firmware_download(idev,
      offsetof(union ionic_dev_cmd_regs, data),
      offset, copy_sz);
  err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
  mutex_unlock(&ionic->dev_cmd_lock);
  if (err) {
   netdev_err(netdev,
       "download failed offset 0x%x addr 0x%lx len 0x%x\n",
       offset, offsetof(union ionic_dev_cmd_regs, data),
       copy_sz);
   NL_SET_ERR_MSG_MOD(extack, "Segment download failed");
   goto err_out;
  }
  offset += copy_sz;
 }
 devlink_flash_update_status_notify(dl, "Downloading", NULL,
        fw->size, fw->size);

 devlink_flash_update_timeout_notify(dl, "Installing", NULL,
         IONIC_FW_INSTALL_TIMEOUT);

 mutex_lock(&ionic->dev_cmd_lock);
 ionic_dev_cmd_firmware_install(idev);
 err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 ionic_dev_cmd_comp(idev, (union ionic_dev_cmd_comp *)&comp);
 fw_slot = comp.fw_control.slot;
 mutex_unlock(&ionic->dev_cmd_lock);
 if (err) {
  NL_SET_ERR_MSG_MOD(extack, "Failed to start firmware install");
  goto err_out;
 }

 err = ionic_fw_status_long_wait(ionic, "Installing",
     IONIC_FW_INSTALL_TIMEOUT,
     IONIC_FW_INSTALL_STATUS,
     extack);
 if (err)
  goto err_out;

 devlink_flash_update_timeout_notify(dl, "Selecting", NULL,
         IONIC_FW_SELECT_TIMEOUT);

 mutex_lock(&ionic->dev_cmd_lock);
 ionic_dev_cmd_firmware_activate(idev, fw_slot);
 err = ionic_dev_cmd_wait(ionic, DEVCMD_TIMEOUT);
 mutex_unlock(&ionic->dev_cmd_lock);
 if (err) {
  NL_SET_ERR_MSG_MOD(extack, "Failed to start firmware select");
  goto err_out;
 }

 err = ionic_fw_status_long_wait(ionic, "Selecting",
     IONIC_FW_SELECT_TIMEOUT,
     IONIC_FW_ACTIVATE_STATUS,
     extack);
 if (err)
  goto err_out;

 netdev_info(netdev, "Firmware update completed\n");

err_out:
 if (err)
  devlink_flash_update_status_notify(dl, "Flash failed", NULL, 0, 0);
 else
  devlink_flash_update_status_notify(dl, "Flash done", NULL, 0, 0);
 return err;
}

Messung V0.5
C=96 H=80 G=88

¤ Dauer der Verarbeitung: 0.2 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.