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

Quelle  enetc_msg.c   Sprache: C

 
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/* Copyright 2017-2019 NXP */

#include "enetc_pf.h"

static void enetc_msg_disable_mr_int(struct enetc_hw *hw)
{
 u32 psiier = enetc_rd(hw, ENETC_PSIIER);
 /* disable MR int source(s) */
 enetc_wr(hw, ENETC_PSIIER, psiier & ~ENETC_PSIIER_MR_MASK);
}

static void enetc_msg_enable_mr_int(struct enetc_hw *hw)
{
 u32 psiier = enetc_rd(hw, ENETC_PSIIER);

 enetc_wr(hw, ENETC_PSIIER, psiier | ENETC_PSIIER_MR_MASK);
}

static irqreturn_t enetc_msg_psi_msix(int irq, void *data)
{
 struct enetc_si *si = (struct enetc_si *)data;
 struct enetc_pf *pf = enetc_si_priv(si);

 enetc_msg_disable_mr_int(&si->hw);
 schedule_work(&pf->msg_task);

 return IRQ_HANDLED;
}

static void enetc_msg_task(struct work_struct *work)
{
 struct enetc_pf *pf = container_of(work, struct enetc_pf, msg_task);
 struct enetc_hw *hw = &pf->si->hw;
 unsigned long mr_mask;
 int i;

 for (;;) {
  mr_mask = enetc_rd(hw, ENETC_PSIMSGRR) & ENETC_PSIMSGRR_MR_MASK;
  if (!mr_mask) {
   /* re-arm MR interrupts, w1c the IDR reg */
   enetc_wr(hw, ENETC_PSIIDR, ENETC_PSIIER_MR_MASK);
   enetc_msg_enable_mr_int(hw);
   return;
  }

  for (i = 0; i < pf->num_vfs; i++) {
   u32 psimsgrr;
   u16 msg_code;

   if (!(ENETC_PSIMSGRR_MR(i) & mr_mask))
    continue;

   enetc_msg_handle_rxmsg(pf, i, &msg_code);

   psimsgrr = ENETC_SIMSGSR_SET_MC(msg_code);
   psimsgrr |= ENETC_PSIMSGRR_MR(i); /* w1c */
   enetc_wr(hw, ENETC_PSIMSGRR, psimsgrr);
  }
 }
}

/* Init */
static int enetc_msg_alloc_mbx(struct enetc_si *si, int idx)
{
 struct enetc_pf *pf = enetc_si_priv(si);
 struct device *dev = &si->pdev->dev;
 struct enetc_hw *hw = &si->hw;
 struct enetc_msg_swbd *msg;
 u32 val;

 msg = &pf->rxmsg[idx];
 /* allocate and set receive buffer */
 msg->size = ENETC_DEFAULT_MSG_SIZE;

 msg->vaddr = dma_alloc_coherent(dev, msg->size, &msg->dma,
     GFP_KERNEL);
 if (!msg->vaddr) {
  dev_err(dev, "msg: fail to alloc dma buffer of size: %d\n",
   msg->size);
  return -ENOMEM;
 }

 /* set multiple of 32 bytes */
 val = lower_32_bits(msg->dma);
 enetc_wr(hw, ENETC_PSIVMSGRCVAR0(idx), val);
 val = upper_32_bits(msg->dma);
 enetc_wr(hw, ENETC_PSIVMSGRCVAR1(idx), val);

 return 0;
}

static void enetc_msg_free_mbx(struct enetc_si *si, int idx)
{
 struct enetc_pf *pf = enetc_si_priv(si);
 struct enetc_hw *hw = &si->hw;
 struct enetc_msg_swbd *msg;

 msg = &pf->rxmsg[idx];
 dma_free_coherent(&si->pdev->dev, msg->size, msg->vaddr, msg->dma);
 memset(msg, 0, sizeof(*msg));

 enetc_wr(hw, ENETC_PSIVMSGRCVAR0(idx), 0);
 enetc_wr(hw, ENETC_PSIVMSGRCVAR1(idx), 0);
}

int enetc_msg_psi_init(struct enetc_pf *pf)
{
 struct enetc_si *si = pf->si;
 int vector, i, err;

 /* register message passing interrupt handler */
 snprintf(pf->msg_int_name, sizeof(pf->msg_int_name), "%s-vfmsg",
   si->ndev->name);
 vector = pci_irq_vector(si->pdev, ENETC_SI_INT_IDX);
 err = request_irq(vector, enetc_msg_psi_msix, 0, pf->msg_int_name, si);
 if (err) {
  dev_err(&si->pdev->dev,
   "PSI messaging: request_irq() failed!\n");
  return err;
 }

 /* set one IRQ entry for PSI message receive notification (SI int) */
 enetc_wr(&si->hw, ENETC_SIMSIVR, ENETC_SI_INT_IDX);

 /* initialize PSI mailbox */
 INIT_WORK(&pf->msg_task, enetc_msg_task);

 for (i = 0; i < pf->num_vfs; i++) {
  err = enetc_msg_alloc_mbx(si, i);
  if (err)
   goto err_init_mbx;
 }

 /* enable MR interrupts */
 enetc_msg_enable_mr_int(&si->hw);

 return 0;

err_init_mbx:
 for (i--; i >= 0; i--)
  enetc_msg_free_mbx(si, i);

 free_irq(vector, si);

 return err;
}

void enetc_msg_psi_free(struct enetc_pf *pf)
{
 struct enetc_si *si = pf->si;
 int i;

 cancel_work_sync(&pf->msg_task);

 /* disable MR interrupts */
 enetc_msg_disable_mr_int(&si->hw);

 for (i = 0; i < pf->num_vfs; i++)
  enetc_msg_free_mbx(si, i);

 /* de-register message passing interrupt handler */
 free_irq(pci_irq_vector(si->pdev, ENETC_SI_INT_IDX), si);
}

Messung V0.5
C=93 H=91 G=91

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ¤

*© 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.