diff options
Diffstat (limited to 'drivers/misc')
158 files changed, 18733 insertions, 24449 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index d5ce8082b0a0..fafa8b0d8099 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -474,7 +474,6 @@ source "drivers/misc/lis3lv02d/Kconfig" source "drivers/misc/altera-stapl/Kconfig" source "drivers/misc/mei/Kconfig" source "drivers/misc/vmw_vmci/Kconfig" -source "drivers/misc/mic/Kconfig" source "drivers/misc/genwqe/Kconfig" source "drivers/misc/echo/Kconfig" source "drivers/misc/cxl/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 2521359e8ef7..d23231e73330 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -46,7 +46,6 @@ obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/ obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o obj-$(CONFIG_SRAM) += sram.o obj-$(CONFIG_SRAM_EXEC) += sram-exec.o -obj-y += mic/ obj-$(CONFIG_GENWQE) += genwqe/ obj-$(CONFIG_ECHO) += echo/ obj-$(CONFIG_CXL_BASE) += cxl/ diff --git a/drivers/misc/altera-stapl/altera.c b/drivers/misc/altera-stapl/altera.c index 5bdf57472314..92c0611034b0 100644 --- a/drivers/misc/altera-stapl/altera.c +++ b/drivers/misc/altera-stapl/altera.c @@ -2265,11 +2265,6 @@ static int altera_check_crc(u8 *p, s32 program_size) "actual %04x\n", __func__, local_expected, local_actual); break; - case -ENODATA: - printk(KERN_ERR "%s: expected CRC not found, " - "actual CRC = %04x\n", __func__, - local_actual); - break; case -EIO: printk(KERN_ERR "%s: error: format isn't " "recognized.\n", __func__); diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c index 80d87e8a0bea..fb9a1b49ff6d 100644 --- a/drivers/misc/c2port/core.c +++ b/drivers/misc/c2port/core.c @@ -899,7 +899,7 @@ struct c2port_device *c2port_device_register(char *name, unlikely(!ops->c2d_get) || unlikely(!ops->c2d_set)) return ERR_PTR(-EINVAL); - c2dev = kmalloc(sizeof(struct c2port_device), GFP_KERNEL); + c2dev = kzalloc(sizeof(struct c2port_device), GFP_KERNEL); if (unlikely(!c2dev)) return ERR_PTR(-ENOMEM); diff --git a/drivers/misc/cardreader/rts5249.c b/drivers/misc/cardreader/rts5249.c index b85279f1fc5e..b2676e7f5027 100644 --- a/drivers/misc/cardreader/rts5249.c +++ b/drivers/misc/cardreader/rts5249.c @@ -73,6 +73,9 @@ static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr) pci_read_config_dword(pdev, PCR_SETTING_REG2, ®); pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg); + + pcr->rtd3_en = rtsx_reg_to_rtd3_uhsii(reg); + if (rtsx_check_mmc_support(reg)) pcr->extra_caps |= EXTRA_CAPS_NO_MMC; pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg); @@ -278,15 +281,28 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr) rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF); - if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) { + if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) rtsx_pci_write_register(pcr, REG_VREF, PWD_SUSPND_EN, PWD_SUSPND_EN); - rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3, 0x01, 0x00); - rtsx_pci_write_register(pcr, RTS524A_PME_FORCE_CTL, 0x30, 0x20); + + if (pcr->rtd3_en) { + if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) { + rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3, 0x01, 0x01); + rtsx_pci_write_register(pcr, RTS524A_PME_FORCE_CTL, 0x30, 0x30); + } else { + rtsx_pci_write_register(pcr, PM_CTRL3, 0x01, 0x01); + rtsx_pci_write_register(pcr, PME_FORCE_CTL, 0xFF, 0x33); + } } else { - rtsx_pci_write_register(pcr, PME_FORCE_CTL, 0xFF, 0x30); - rtsx_pci_write_register(pcr, PM_CTRL3, 0x01, 0x00); + if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) { + rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3, 0x01, 0x00); + rtsx_pci_write_register(pcr, RTS524A_PME_FORCE_CTL, 0x30, 0x20); + } else { + rtsx_pci_write_register(pcr, PME_FORCE_CTL, 0xFF, 0x30); + rtsx_pci_write_register(pcr, PM_CTRL3, 0x01, 0x00); + } } + /* * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced * to drive low, and we forcibly request clock. diff --git a/drivers/misc/cardreader/rts5261.c b/drivers/misc/cardreader/rts5261.c index 471961487ff8..6c64dade8e1a 100644 --- a/drivers/misc/cardreader/rts5261.c +++ b/drivers/misc/cardreader/rts5261.c @@ -26,16 +26,16 @@ static u8 rts5261_get_ic_version(struct rtsx_pcr *pcr) static void rts5261_fill_driving(struct rtsx_pcr *pcr, u8 voltage) { u8 driving_3v3[4][3] = { - {0x13, 0x13, 0x13}, {0x96, 0x96, 0x96}, - {0x7F, 0x7F, 0x7F}, {0x96, 0x96, 0x96}, + {0x7F, 0x7F, 0x7F}, + {0x13, 0x13, 0x13}, }; u8 driving_1v8[4][3] = { - {0x99, 0x99, 0x99}, + {0xB3, 0xB3, 0xB3}, {0x3A, 0x3A, 0x3A}, {0xE6, 0xE6, 0xE6}, - {0xB3, 0xB3, 0xB3}, + {0x99, 0x99, 0x99}, }; u8 (*driving)[3], drive_sel; @@ -67,12 +67,17 @@ static void rtsx5261_fetch_vendor_settings(struct rtsx_pcr *pcr) pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg); if (!rts5261_vendor_setting_valid(reg)) { + /* Not support MMC default */ + pcr->extra_caps |= EXTRA_CAPS_NO_MMC; pcr_dbg(pcr, "skip fetch vendor setting\n"); return; } - pcr->card_drive_sel &= 0x3F; - pcr->card_drive_sel |= rts5261_reg_to_card_drive_sel(reg); + if (!rts5261_reg_check_mmc_support(reg)) + pcr->extra_caps |= EXTRA_CAPS_NO_MMC; + + /* TO do: need to add rtd3 function */ + pcr->rtd3_en = rts5261_reg_to_rtd3(reg); if (rts5261_reg_check_reverse_socket(reg)) pcr->flags |= PCR_REVERSE_SOCKET; @@ -171,6 +176,8 @@ static int rts5261_card_power_on(struct rtsx_pcr *pcr, int card) if (option->ocp_en) rtsx_pci_enable_ocp(pcr); + rtsx_pci_write_register(pcr, REG_CRC_DUMMY_0, + CFG_SD_POW_AUTO_PD, CFG_SD_POW_AUTO_PD); rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG1, RTS5261_LDO1_TUNE_MASK, RTS5261_LDO1_33); @@ -272,6 +279,9 @@ static void rts5261_enable_ocp(struct rtsx_pcr *pcr) u8 val = 0; val = SD_OCP_INT_EN | SD_DETECT_EN; + rtsx_pci_write_register(pcr, RTS5261_LDO1_CFG0, + RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN, + RTS5261_LDO1_OCP_EN | RTS5261_LDO1_OCP_LMT_EN); rtsx_pci_write_register(pcr, REG_OCPCTL, 0xFF, val); } @@ -295,6 +305,8 @@ static int rts5261_card_power_off(struct rtsx_pcr *pcr, int card) err = rtsx_pci_write_register(pcr, RTS5261_LDO1233318_POW_CTL, RTS5261_LDO_POWERON_MASK, 0); + rtsx_pci_write_register(pcr, REG_CRC_DUMMY_0, + CFG_SD_POW_AUTO_PD, 0); if (pcr->option.ocp_en) rtsx_pci_disable_ocp(pcr); @@ -340,7 +352,7 @@ static void rts5261_clear_ocpstat(struct rtsx_pcr *pcr) rtsx_pci_write_register(pcr, REG_OCPCTL, mask, val); - udelay(10); + udelay(1000); rtsx_pci_write_register(pcr, REG_OCPCTL, mask, 0); } @@ -353,9 +365,9 @@ static void rts5261_process_ocp(struct rtsx_pcr *pcr) rtsx_pci_get_ocpstat(pcr, &pcr->ocp_stat); if (pcr->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { + rts5261_clear_ocpstat(pcr); rts5261_card_power_off(pcr, RTSX_SD_CARD); rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, 0); - rts5261_clear_ocpstat(pcr); pcr->ocp_stat = 0; } @@ -467,6 +479,7 @@ static void rts5261_init_from_cfg(struct rtsx_pcr *pcr) static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) { struct rtsx_cr_option *option = &pcr->option; + u32 val; rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1, CD_RESUME_EN_MASK, CD_RESUME_EN_MASK); @@ -481,6 +494,10 @@ static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) AUX_CLK_ACTIVE_SEL_MASK, MAC_CKSW_DONE); rtsx_pci_write_register(pcr, L1SUB_CONFIG3, 0xFF, 0); + if (is_version_higher_than(pcr, PID_5261, IC_VER_B)) { + val = rtsx_pci_readl(pcr, RTSX_DUM_REG); + rtsx_pci_writel(pcr, RTSX_DUM_REG, val | 0x1); + } rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG4, RTS5261_AUX_CLK_16M_EN, 0); @@ -502,6 +519,11 @@ static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) /* Configure driving */ rts5261_fill_driving(pcr, OUTPUT_3V3); + if (pcr->flags & PCR_REVERSE_SOCKET) + rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x30); + else + rtsx_pci_write_register(pcr, PETXCFG, 0x30, 0x00); + /* * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced * to drive low, and we forcibly request clock. @@ -513,6 +535,7 @@ static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) rtsx_pci_write_register(pcr, PETXCFG, FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_HIGH); + rtsx_pci_write_register(pcr, PWD_SUSPEND_EN, 0xFF, 0xFB); rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x00); rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL, FORCE_PM_CONTROL | FORCE_PM_VALUE, FORCE_PM_CONTROL); @@ -526,22 +549,30 @@ static int rts5261_extra_init_hw(struct rtsx_pcr *pcr) static void rts5261_enable_aspm(struct rtsx_pcr *pcr, bool enable) { + u8 val = FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1; + u8 mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1; + if (pcr->aspm_enabled == enable) return; + val |= (pcr->aspm_en & 0x02); + rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val); pcie_capability_clear_and_set_word(pcr->pci, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_ASPMC, pcr->aspm_en); pcr->aspm_enabled = enable; - } static void rts5261_disable_aspm(struct rtsx_pcr *pcr, bool enable) { + u8 val = FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1; + u8 mask = FORCE_ASPM_VAL_MASK | FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1; + if (pcr->aspm_enabled == enable) return; pcie_capability_clear_and_set_word(pcr->pci, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_ASPMC, 0); + rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, mask, val); rtsx_pci_write_register(pcr, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); udelay(10); pcr->aspm_enabled = enable; @@ -618,7 +649,7 @@ int rts5261_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, if (initial_mode) { /* We use 250k(around) here, in initial stage */ - if (is_version(pcr, PID_5261, IC_VER_D)) { + if (is_version_higher_than(pcr, PID_5261, IC_VER_C)) { clk_divider = SD_CLK_DIVIDE_256; card_clock = 60000000; } else { @@ -669,7 +700,7 @@ int rts5261_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock, div++; } - n = (n / 2); + n = (n / 2) - 1; pcr_dbg(pcr, "n = %d, div = %d\n", n, div); ssc_depth = depth[ssc_depth]; @@ -738,15 +769,19 @@ void rts5261_init_params(struct rtsx_pcr *pcr) { struct rtsx_cr_option *option = &pcr->option; struct rtsx_hw_param *hw_param = &pcr->hw_param; + u8 val; pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104; + rtsx_pci_read_register(pcr, RTS5261_FW_STATUS, &val); + if (!(val & RTS5261_EXPRESS_LINK_FAIL_MASK)) + pcr->extra_caps |= EXTRA_CAPS_SD_EXPRESS; pcr->num_slots = 1; pcr->ops = &rts5261_pcr_ops; pcr->flags = 0; pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT; - pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; - pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; + pcr->sd30_drive_sel_1v8 = 0x00; + pcr->sd30_drive_sel_3v3 = 0x00; pcr->aspm_en = ASPM_L1_EN; pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 11); pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); diff --git a/drivers/misc/cardreader/rts5261.h b/drivers/misc/cardreader/rts5261.h index ebfdd236a553..2344c560a637 100644 --- a/drivers/misc/cardreader/rts5261.h +++ b/drivers/misc/cardreader/rts5261.h @@ -12,12 +12,13 @@ /*New add*/ #define rts5261_vendor_setting_valid(reg) ((reg) & 0x010000) -#define rts5261_reg_to_aspm(reg) (((reg) >> 28) ^ 0x03) +#define rts5261_reg_to_aspm(reg) \ + (((~(reg) >> 28) & 0x02) | (((reg) >> 28) & 0x01)) #define rts5261_reg_check_reverse_socket(reg) ((reg) & 0x04) -#define rts5261_reg_to_card_drive_sel(reg) ((((reg) >> 6) & 0x01) << 6) -#define rts5261_reg_to_sd30_drive_sel_1v8(reg) (((reg) >> 22) ^ 0x03) -#define rts5261_reg_to_sd30_drive_sel_3v3(reg) (((reg) >> 16) ^ 0x03) - +#define rts5261_reg_to_sd30_drive_sel_1v8(reg) (((reg) >> 22) & 0x03) +#define rts5261_reg_to_sd30_drive_sel_3v3(reg) (((reg) >> 16) & 0x03) +#define rts5261_reg_to_rtd3(reg) ((reg) & 0x08) +#define rts5261_reg_check_mmc_support(reg) ((reg) & 0x10) #define RTS5261_AUTOLOAD_CFG0 0xFF7B #define RTS5261_AUTOLOAD_CFG1 0xFF7C @@ -60,28 +61,6 @@ /* DMACTL 0xFE2C */ #define RTS5261_DMA_PACK_SIZE_MASK 0xF0 -/* FW config info register */ -#define RTS5261_FW_CFG_INFO0 0xFF50 -#define RTS5261_FW_EXPRESS_TEST_MASK (0x01<<0) -#define RTS5261_FW_EA_MODE_MASK (0x01<<5) - -/* FW config register */ -#define RTS5261_FW_CFG0 0xFF54 -#define RTS5261_FW_ENTER_EXPRESS (0x01<<0) - -#define RTS5261_FW_CFG1 0xFF55 -#define RTS5261_SYS_CLK_SEL_MCU_CLK (0x01<<7) -#define RTS5261_CRC_CLK_SEL_MCU_CLK (0x01<<6) -#define RTS5261_FAKE_MCU_CLOCK_GATING (0x01<<5) -/*MCU_bus_mode_sel: 0=real 8051 1=fake mcu*/ -#define RTS5261_MCU_BUS_SEL_MASK (0x01<<4) -/*MCU_clock_sel:VerA 00=aux16M 01=aux400K 1x=REFCLK100M*/ -/*MCU_clock_sel:VerB 00=aux400K 01=aux16M 10=REFCLK100M*/ -#define RTS5261_MCU_CLOCK_SEL_MASK (0x03<<2) -#define RTS5261_MCU_CLOCK_SEL_16M (0x01<<2) -#define RTS5261_MCU_CLOCK_GATING (0x01<<1) -#define RTS5261_DRIVER_ENABLE_FW (0x01<<0) - /* FW status register */ #define RTS5261_FW_STATUS 0xFF56 #define RTS5261_EXPRESS_LINK_FAIL_MASK (0x01<<7) @@ -121,12 +100,6 @@ #define RTS5261_DV3318_19 (0x04<<4) #define RTS5261_DV3318_33 (0x07<<4) -#define RTS5261_LDO1_CFG0 0xFF72 -#define RTS5261_LDO1_OCP_THD_MASK (0x07<<5) -#define RTS5261_LDO1_OCP_EN (0x01<<4) -#define RTS5261_LDO1_OCP_LMT_THD_MASK (0x03<<2) -#define RTS5261_LDO1_OCP_LMT_EN (0x01<<1) - /* CRD6603-433 190319 request changed */ #define RTS5261_LDO1_OCP_THD_740 (0x00<<5) #define RTS5261_LDO1_OCP_THD_800 (0x01<<5) diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c index 5d15607027e9..2aa6648fa41f 100644 --- a/drivers/misc/cardreader/rtsx_pcr.c +++ b/drivers/misc/cardreader/rtsx_pcr.c @@ -20,6 +20,8 @@ #include <linux/rtsx_pci.h> #include <linux/mmc/card.h> #include <asm/unaligned.h> +#include <linux/pm.h> +#include <linux/pm_runtime.h> #include "rtsx_pcr.h" #include "rts5261.h" @@ -89,9 +91,15 @@ static void rtsx_comm_set_aspm(struct rtsx_pcr *pcr, bool enable) if (pcr->aspm_enabled == enable) return; - pcie_capability_clear_and_set_word(pcr->pci, PCI_EXP_LNKCTL, - PCI_EXP_LNKCTL_ASPMC, - enable ? pcr->aspm_en : 0); + if (pcr->aspm_en & 0x02) + rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, FORCE_ASPM_CTL0 | + FORCE_ASPM_CTL1, enable ? 0 : FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1); + else + rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, FORCE_ASPM_CTL0 | + FORCE_ASPM_CTL1, FORCE_ASPM_CTL0 | FORCE_ASPM_CTL1); + + if (!enable && (pcr->aspm_en & 0x02)) + mdelay(10); pcr->aspm_enabled = enable; } @@ -144,6 +152,12 @@ void rtsx_pci_start_run(struct rtsx_pcr *pcr) if (pcr->remove_pci) return; + if (pcr->rtd3_en) + if (pcr->is_runtime_suspended) { + pm_runtime_get(&(pcr->pci->dev)); + pcr->is_runtime_suspended = false; + } + if (pcr->state != PDEV_STAT_RUN) { pcr->state = PDEV_STAT_RUN; if (pcr->ops->enable_auto_blink) @@ -990,6 +1004,11 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) } else { pcr->card_removed |= SD_EXIST; pcr->card_inserted &= ~SD_EXIST; + if (PCI_PID(pcr) == PID_5261) { + rtsx_pci_write_register(pcr, RTS5261_FW_STATUS, + RTS5261_EXPRESS_LINK_FAIL_MASK, 0); + pcr->extra_caps |= EXTRA_CAPS_SD_EXPRESS; + } } pcr->dma_error_count = 0; } @@ -1075,6 +1094,16 @@ static void rtsx_pm_power_saving(struct rtsx_pcr *pcr) rtsx_comm_pm_power_saving(pcr); } +static void rtsx_pci_rtd3_work(struct work_struct *work) +{ + struct delayed_work *dwork = to_delayed_work(work); + struct rtsx_pcr *pcr = container_of(dwork, struct rtsx_pcr, rtd3_work); + + pcr_dbg(pcr, "--> %s\n", __func__); + if (!pcr->is_runtime_suspended) + pm_runtime_put(&(pcr->pci->dev)); +} + static void rtsx_pci_idle_work(struct work_struct *work) { struct delayed_work *dwork = to_delayed_work(work); @@ -1094,6 +1123,9 @@ static void rtsx_pci_idle_work(struct work_struct *work) rtsx_pm_power_saving(pcr); mutex_unlock(&pcr->pcr_mutex); + + if (pcr->rtd3_en) + mod_delayed_work(system_wq, &pcr->rtd3_work, msecs_to_jiffies(10000)); } static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, u8 pm_state) @@ -1283,7 +1315,7 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) /* Wait SSC power stable */ udelay(200); - rtsx_pci_disable_aspm(pcr); + rtsx_disable_aspm(pcr); if (pcr->ops->optimize_phy) { err = pcr->ops->optimize_phy(pcr); if (err < 0) @@ -1357,8 +1389,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) rtsx_pci_init_ocp(pcr); /* Enable clk_request_n to enable clock power management */ - pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, - PCI_EXP_LNKCTL_CLKREQ_EN); + pcie_capability_clear_and_set_word(pcr->pci, PCI_EXP_LNKCTL, + 0, PCI_EXP_LNKCTL_CLKREQ_EN); /* Enter L1 when host tx idle */ pci_write_config_byte(pdev, 0x70F, 0x5B); @@ -1368,6 +1400,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr) return err; } + rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0x30, 0x30); + /* No CD interrupt if probing driver with card inserted. * So we need to initialize pcr->card_exist here. */ @@ -1571,6 +1605,15 @@ static int rtsx_pci_probe(struct pci_dev *pcidev, rtsx_pcr_cells[i].platform_data = handle; rtsx_pcr_cells[i].pdata_size = sizeof(*handle); } + + if (pcr->rtd3_en) { + INIT_DELAYED_WORK(&pcr->rtd3_work, rtsx_pci_rtd3_work); + pm_runtime_allow(&pcidev->dev); + pm_runtime_enable(&pcidev->dev); + pcr->is_runtime_suspended = false; + } + + ret = mfd_add_devices(&pcidev->dev, pcr->id, rtsx_pcr_cells, ARRAY_SIZE(rtsx_pcr_cells), NULL, 0, NULL); if (ret < 0) @@ -1608,6 +1651,9 @@ static void rtsx_pci_remove(struct pci_dev *pcidev) struct pcr_handle *handle = pci_get_drvdata(pcidev); struct rtsx_pcr *pcr = handle->pcr; + if (pcr->rtd3_en) + pm_runtime_get_noresume(&pcr->pci->dev); + pcr->remove_pci = true; /* Disable interrupts at the pcr level */ @@ -1618,6 +1664,8 @@ static void rtsx_pci_remove(struct pci_dev *pcidev) cancel_delayed_work_sync(&pcr->carddet_work); cancel_delayed_work_sync(&pcr->idle_work); + if (pcr->rtd3_en) + cancel_delayed_work_sync(&pcr->rtd3_work); mfd_remove_devices(&pcidev->dev); @@ -1635,6 +1683,11 @@ static void rtsx_pci_remove(struct pci_dev *pcidev) idr_remove(&rtsx_pci_idr, pcr->id); spin_unlock(&rtsx_pci_lock); + if (pcr->rtd3_en) { + pm_runtime_disable(&pcr->pci->dev); + pm_runtime_put_noidle(&pcr->pci->dev); + } + kfree(pcr->slots); kfree(pcr); kfree(handle); @@ -1716,13 +1769,77 @@ static void rtsx_pci_shutdown(struct pci_dev *pcidev) pci_disable_msi(pcr->pci); } +static int rtsx_pci_runtime_suspend(struct device *device) +{ + struct pci_dev *pcidev = to_pci_dev(device); + struct pcr_handle *handle; + struct rtsx_pcr *pcr; + + handle = pci_get_drvdata(pcidev); + pcr = handle->pcr; + dev_dbg(&(pcidev->dev), "--> %s\n", __func__); + + cancel_delayed_work(&pcr->carddet_work); + cancel_delayed_work(&pcr->rtd3_work); + cancel_delayed_work(&pcr->idle_work); + + mutex_lock(&pcr->pcr_mutex); + rtsx_pci_power_off(pcr, HOST_ENTER_S3); + + free_irq(pcr->irq, (void *)pcr); + + mutex_unlock(&pcr->pcr_mutex); + + pcr->is_runtime_suspended = true; + + return 0; +} + +static int rtsx_pci_runtime_resume(struct device *device) +{ + struct pci_dev *pcidev = to_pci_dev(device); + struct pcr_handle *handle; + struct rtsx_pcr *pcr; + int ret = 0; + + handle = pci_get_drvdata(pcidev); + pcr = handle->pcr; + dev_dbg(&(pcidev->dev), "--> %s\n", __func__); + + mutex_lock(&pcr->pcr_mutex); + + rtsx_pci_write_register(pcr, HOST_SLEEP_STATE, 0x03, 0x00); + rtsx_pci_acquire_irq(pcr); + synchronize_irq(pcr->irq); + + if (pcr->ops->fetch_vendor_settings) + pcr->ops->fetch_vendor_settings(pcr); + + rtsx_pci_init_hw(pcr); + + if (pcr->slots[RTSX_SD_CARD].p_dev != NULL) { + pcr->slots[RTSX_SD_CARD].card_event( + pcr->slots[RTSX_SD_CARD].p_dev); + } + + schedule_delayed_work(&pcr->idle_work, msecs_to_jiffies(200)); + + mutex_unlock(&pcr->pcr_mutex); + return ret; +} + #else /* CONFIG_PM */ #define rtsx_pci_shutdown NULL +#define rtsx_pci_runtime_suspend NULL +#define rtsx_pic_runtime_resume NULL #endif /* CONFIG_PM */ -static SIMPLE_DEV_PM_OPS(rtsx_pci_pm_ops, rtsx_pci_suspend, rtsx_pci_resume); +static const struct dev_pm_ops rtsx_pci_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(rtsx_pci_suspend, rtsx_pci_resume) + SET_RUNTIME_PM_OPS(rtsx_pci_runtime_suspend, rtsx_pci_runtime_resume, NULL) +}; static struct pci_driver rtsx_pci_driver = { .name = DRV_NAME_RTSX_PCI, diff --git a/drivers/misc/cardreader/rtsx_pcr.h b/drivers/misc/cardreader/rtsx_pcr.h index fe5f4ca0f937..daf057c4eea6 100644 --- a/drivers/misc/cardreader/rtsx_pcr.h +++ b/drivers/misc/cardreader/rtsx_pcr.h @@ -90,6 +90,7 @@ static inline u8 map_sd_drive(int idx) #define rtsx_check_mmc_support(reg) ((reg) & 0x10) #define rtsx_reg_to_rtd3(reg) ((reg) & 0x02) +#define rtsx_reg_to_rtd3_uhsii(reg) ((reg) & 0x04) #define rtsx_reg_to_aspm(reg) (((reg) >> 28) & 0x03) #define rtsx_reg_to_sd30_drive_sel_1v8(reg) (((reg) >> 26) & 0x03) #define rtsx_reg_to_sd30_drive_sel_3v3(reg) (((reg) >> 5) & 0x03) diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 1c0a41803bb6..926408b41270 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -736,7 +736,6 @@ static int at24_probe(struct i2c_client *client) nvmem_config.type = NVMEM_TYPE_EEPROM; nvmem_config.dev = dev; - nvmem_config.id = NVMEM_DEVID_AUTO; nvmem_config.read_only = !writable; nvmem_config.root_only = !(flags & AT24_FLAG_IRUGO); nvmem_config.owner = THIS_MODULE; diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 3b7d8b7584f4..b76e4901b4a4 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -22,6 +22,9 @@ * mean that some AT25 products are EEPROMs, and others are FLASH. * Handle FLASH chips with the drivers/mtd/devices/m25p80.c driver, * not this one! + * + * EEPROMs that can be used with this driver include, for example: + * AT25M02, AT25128B */ struct at25_data { diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 994ab67bc2dc..70eb5ed942d0 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -586,11 +586,13 @@ static void fastrpc_dma_buf_detatch(struct dma_buf *dmabuf, kfree(a); } -static void *fastrpc_vmap(struct dma_buf *dmabuf) +static int fastrpc_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map) { struct fastrpc_buf *buf = dmabuf->priv; - return buf->virt; + dma_buf_map_set_vaddr(map, buf->virt); + + return 0; } static int fastrpc_mmap(struct dma_buf *dmabuf, diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index c9b886618071..2e1befbd1ad9 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -1089,24 +1089,9 @@ static int genwqe_pci_setup(struct genwqe_dev *cd) } /* check for 64-bit DMA address supported (DAC) */ - if (!pci_set_dma_mask(pci_dev, DMA_BIT_MASK(64))) { - err = pci_set_consistent_dma_mask(pci_dev, DMA_BIT_MASK(64)); - if (err) { - dev_err(&pci_dev->dev, - "err: DMA64 consistent mask error\n"); - err = -EIO; - goto out_release_resources; - } /* check for 32-bit DMA address supported (SAC) */ - } else if (!pci_set_dma_mask(pci_dev, DMA_BIT_MASK(32))) { - err = pci_set_consistent_dma_mask(pci_dev, DMA_BIT_MASK(32)); - if (err) { - dev_err(&pci_dev->dev, - "err: DMA32 consistent mask error\n"); - err = -EIO; - goto out_release_resources; - } - } else { + if (dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(64)) || + dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32))) { dev_err(&pci_dev->dev, "err: neither DMA32 nor DMA64 supported\n"); err = -EIO; diff --git a/drivers/misc/habanalabs/common/command_buffer.c b/drivers/misc/habanalabs/common/command_buffer.c index 901e213daf40..6f6a904ab6ca 100644 --- a/drivers/misc/habanalabs/common/command_buffer.c +++ b/drivers/misc/habanalabs/common/command_buffer.c @@ -11,7 +11,6 @@ #include <linux/mm.h> #include <linux/slab.h> #include <linux/uaccess.h> -#include <linux/genalloc.h> static int cb_map_mem(struct hl_ctx *ctx, struct hl_cb *cb) { @@ -68,9 +67,9 @@ static int cb_map_mem(struct hl_ctx *ctx, struct hl_cb *cb) bus_addr = cb->bus_address; offset = 0; list_for_each_entry(va_block, &cb->va_block_list, node) { - rc = hl_mmu_map(ctx, va_block->start, bus_addr, va_block->size, - list_is_last(&va_block->node, - &cb->va_block_list)); + rc = hl_mmu_map_page(ctx, va_block->start, bus_addr, + va_block->size, list_is_last(&va_block->node, + &cb->va_block_list)); if (rc) { dev_err(hdev->dev, "Failed to map VA %#llx to CB\n", va_block->start); @@ -93,7 +92,7 @@ err_va_umap: list_for_each_entry(va_block, &cb->va_block_list, node) { if (offset <= 0) break; - hl_mmu_unmap(ctx, va_block->start, va_block->size, + hl_mmu_unmap_page(ctx, va_block->start, va_block->size, offset <= va_block->size); offset -= va_block->size; } @@ -120,7 +119,7 @@ static void cb_unmap_mem(struct hl_ctx *ctx, struct hl_cb *cb) mutex_lock(&ctx->mmu_lock); list_for_each_entry(va_block, &cb->va_block_list, node) - if (hl_mmu_unmap(ctx, va_block->start, va_block->size, + if (hl_mmu_unmap_page(ctx, va_block->start, va_block->size, list_is_last(&va_block->node, &cb->va_block_list))) dev_warn_ratelimited(hdev->dev, @@ -142,11 +141,10 @@ static void cb_fini(struct hl_device *hdev, struct hl_cb *cb) { if (cb->is_internal) gen_pool_free(hdev->internal_cb_pool, - cb->kernel_address, cb->size); + (uintptr_t)cb->kernel_address, cb->size); else hdev->asic_funcs->asic_dma_free_coherent(hdev, cb->size, - (void *) (uintptr_t) cb->kernel_address, - cb->bus_address); + cb->kernel_address, cb->bus_address); kfree(cb); } @@ -230,7 +228,7 @@ static struct hl_cb *hl_cb_alloc(struct hl_device *hdev, u32 cb_size, return NULL; } - cb->kernel_address = (u64) (uintptr_t) p; + cb->kernel_address = p; cb->size = cb_size; return cb; @@ -377,17 +375,49 @@ int hl_cb_destroy(struct hl_device *hdev, struct hl_cb_mgr *mgr, u64 cb_handle) return rc; } +static int hl_cb_info(struct hl_device *hdev, struct hl_cb_mgr *mgr, + u64 cb_handle, u32 *usage_cnt) +{ + struct hl_cb *cb; + u32 handle; + int rc = 0; + + /* The CB handle was given to user to do mmap, so need to shift it back + * to the value which was allocated by the IDR module. + */ + cb_handle >>= PAGE_SHIFT; + handle = (u32) cb_handle; + + spin_lock(&mgr->cb_lock); + + cb = idr_find(&mgr->cb_handles, handle); + if (!cb) { + dev_err(hdev->dev, + "CB info failed, no match to handle 0x%x\n", handle); + rc = -EINVAL; + goto out; + } + + *usage_cnt = atomic_read(&cb->cs_cnt); + +out: + spin_unlock(&mgr->cb_lock); + return rc; +} + int hl_cb_ioctl(struct hl_fpriv *hpriv, void *data) { union hl_cb_args *args = data; struct hl_device *hdev = hpriv->hdev; + enum hl_device_status status; u64 handle = 0; + u32 usage_cnt = 0; int rc; - if (hl_device_disabled_or_in_reset(hdev)) { + if (!hl_device_operational(hdev, &status)) { dev_warn_ratelimited(hdev->dev, "Device is %s. Can't execute CB IOCTL\n", - atomic_read(&hdev->in_reset) ? "in_reset" : "disabled"); + hdev->status[status]); return -EBUSY; } @@ -414,6 +444,13 @@ int hl_cb_ioctl(struct hl_fpriv *hpriv, void *data) args->in.cb_handle); break; + case HL_CB_OP_INFO: + rc = hl_cb_info(hdev, &hpriv->cb_mgr, args->in.cb_handle, + &usage_cnt); + memset(args, 0, sizeof(*args)); + args->out.usage_cnt = usage_cnt; + break; + default: rc = -ENOTTY; break; @@ -509,7 +546,7 @@ int hl_cb_mmap(struct hl_fpriv *hpriv, struct vm_area_struct *vma) vma->vm_private_data = cb; - rc = hdev->asic_funcs->cb_mmap(hdev, vma, (void *) cb->kernel_address, + rc = hdev->asic_funcs->cb_mmap(hdev, vma, cb->kernel_address, cb->bus_address, cb->size); if (rc) { spin_lock(&cb->lock); @@ -518,6 +555,7 @@ int hl_cb_mmap(struct hl_fpriv *hpriv, struct vm_area_struct *vma) } cb->mmap_size = cb->size; + vma->vm_pgoff = handle; return 0; diff --git a/drivers/misc/habanalabs/common/command_submission.c b/drivers/misc/habanalabs/common/command_submission.c index b2b974ecc431..beb482310a58 100644 --- a/drivers/misc/habanalabs/common/command_submission.c +++ b/drivers/misc/habanalabs/common/command_submission.c @@ -11,11 +11,25 @@ #include <linux/uaccess.h> #include <linux/slab.h> -#define HL_CS_FLAGS_SIG_WAIT (HL_CS_FLAGS_SIGNAL | HL_CS_FLAGS_WAIT) +#define HL_CS_FLAGS_TYPE_MASK (HL_CS_FLAGS_SIGNAL | HL_CS_FLAGS_WAIT | \ + HL_CS_FLAGS_COLLECTIVE_WAIT) + +/** + * enum hl_cs_wait_status - cs wait status + * @CS_WAIT_STATUS_BUSY: cs was not completed yet + * @CS_WAIT_STATUS_COMPLETED: cs completed + * @CS_WAIT_STATUS_GONE: cs completed but fence is already gone + */ +enum hl_cs_wait_status { + CS_WAIT_STATUS_BUSY, + CS_WAIT_STATUS_COMPLETED, + CS_WAIT_STATUS_GONE +}; static void job_wq_completion(struct work_struct *work); -static long _hl_cs_wait_ioctl(struct hl_device *hdev, - struct hl_ctx *ctx, u64 timeout_us, u64 seq); +static int _hl_cs_wait_ioctl(struct hl_device *hdev, struct hl_ctx *ctx, + u64 timeout_us, u64 seq, + enum hl_cs_wait_status *status, s64 *timestamp); static void cs_do_release(struct kref *ref); static void hl_sob_reset(struct kref *ref) @@ -38,6 +52,38 @@ void hl_sob_reset_error(struct kref *ref) hw_sob->q_idx, hw_sob->sob_id); } +/** + * hl_gen_sob_mask() - Generates a sob mask to be used in a monitor arm packet + * @sob_base: sob base id + * @sob_mask: sob user mask, each bit represents a sob offset from sob base + * @mask: generated mask + * + * Return: 0 if given parameters are valid + */ +int hl_gen_sob_mask(u16 sob_base, u8 sob_mask, u8 *mask) +{ + int i; + + if (sob_mask == 0) + return -EINVAL; + + if (sob_mask == 0x1) { + *mask = ~(1 << (sob_base & 0x7)); + } else { + /* find msb in order to verify sob range is valid */ + for (i = BITS_PER_BYTE - 1 ; i >= 0 ; i--) + if (BIT(i) & sob_mask) + break; + + if (i > (HL_MAX_SOBS_PER_MONITOR - (sob_base & 0x7) - 1)) + return -EINVAL; + + *mask = ~sob_mask; + } + + return 0; +} + static void hl_fence_release(struct kref *kref) { struct hl_fence *fence = @@ -53,7 +99,8 @@ static void hl_fence_release(struct kref *kref) goto free; if ((hl_cs_cmpl->type == CS_TYPE_SIGNAL) || - (hl_cs_cmpl->type == CS_TYPE_WAIT)) { + (hl_cs_cmpl->type == CS_TYPE_WAIT) || + (hl_cs_cmpl->type == CS_TYPE_COLLECTIVE_WAIT)) { dev_dbg(hdev->dev, "CS 0x%llx type %d finished, sob_id: %d, sob_val: 0x%x\n", @@ -80,6 +127,10 @@ static void hl_fence_release(struct kref *kref) * hence the above scenario is avoided. */ kref_put(&hl_cs_cmpl->hw_sob->kref, hl_sob_reset); + + if (hl_cs_cmpl->type == CS_TYPE_COLLECTIVE_WAIT) + hdev->asic_funcs->reset_sob_group(hdev, + hl_cs_cmpl->sob_group); } free: @@ -102,10 +153,11 @@ static void hl_fence_init(struct hl_fence *fence) { kref_init(&fence->refcount); fence->error = 0; + fence->timestamp = ktime_set(0, 0); init_completion(&fence->completion); } -static void cs_get(struct hl_cs *cs) +void cs_get(struct hl_cs *cs) { kref_get(&cs->refcount); } @@ -120,6 +172,18 @@ static void cs_put(struct hl_cs *cs) kref_put(&cs->refcount, cs_do_release); } +static void cs_job_do_release(struct kref *ref) +{ + struct hl_cs_job *job = container_of(ref, struct hl_cs_job, refcount); + + kfree(job); +} + +static void cs_job_put(struct hl_cs_job *job) +{ + kref_put(&job->refcount, cs_job_do_release); +} + static bool is_cb_patched(struct hl_device *hdev, struct hl_cs_job *job) { /* @@ -169,10 +233,7 @@ static int cs_parser(struct hl_fpriv *hpriv, struct hl_cs_job *job) job->patched_cb = parser.patched_cb; job->job_cb_size = parser.patched_cb_size; job->contains_dma_pkt = parser.contains_dma_pkt; - - spin_lock(&job->patched_cb->lock); - job->patched_cb->cs_cnt++; - spin_unlock(&job->patched_cb->lock); + atomic_inc(&job->patched_cb->cs_cnt); } /* @@ -180,9 +241,7 @@ static int cs_parser(struct hl_fpriv *hpriv, struct hl_cs_job *job) * original CB anymore because it was already parsed and * won't be accessed again for this CS */ - spin_lock(&job->user_cb->lock); - job->user_cb->cs_cnt--; - spin_unlock(&job->user_cb->lock); + atomic_dec(&job->user_cb->cs_cnt); hl_cb_put(job->user_cb); job->user_cb = NULL; } else if (!rc) { @@ -192,7 +251,7 @@ static int cs_parser(struct hl_fpriv *hpriv, struct hl_cs_job *job) return rc; } -static void free_job(struct hl_device *hdev, struct hl_cs_job *job) +static void complete_job(struct hl_device *hdev, struct hl_cs_job *job) { struct hl_cs *cs = job->cs; @@ -204,10 +263,7 @@ static void free_job(struct hl_device *hdev, struct hl_cs_job *job) * created, so we need to check it's not NULL */ if (job->patched_cb) { - spin_lock(&job->patched_cb->lock); - job->patched_cb->cs_cnt--; - spin_unlock(&job->patched_cb->lock); - + atomic_dec(&job->patched_cb->cs_cnt); hl_cb_put(job->patched_cb); } } @@ -215,13 +271,12 @@ static void free_job(struct hl_device *hdev, struct hl_cs_job *job) /* For H/W queue jobs, if a user CB was allocated by driver and MMU is * enabled, the user CB isn't released in cs_parser() and thus should be * released here. + * This is also true for INT queues jobs which were allocated by driver */ - if (job->queue_type == QUEUE_TYPE_HW && - job->is_kernel_allocated_cb && hdev->mmu_enable) { - spin_lock(&job->user_cb->lock); - job->user_cb->cs_cnt--; - spin_unlock(&job->user_cb->lock); - + if (job->is_kernel_allocated_cb && + ((job->queue_type == QUEUE_TYPE_HW && hdev->mmu_enable) || + job->queue_type == QUEUE_TYPE_INT)) { + atomic_dec(&job->user_cb->cs_cnt); hl_cb_put(job->user_cb); } @@ -239,27 +294,12 @@ static void free_job(struct hl_device *hdev, struct hl_cs_job *job) job->queue_type == QUEUE_TYPE_HW) cs_put(cs); - kfree(job); -} - -static void cs_counters_aggregate(struct hl_device *hdev, struct hl_ctx *ctx) -{ - hdev->aggregated_cs_counters.device_in_reset_drop_cnt += - ctx->cs_counters.device_in_reset_drop_cnt; - hdev->aggregated_cs_counters.out_of_mem_drop_cnt += - ctx->cs_counters.out_of_mem_drop_cnt; - hdev->aggregated_cs_counters.parsing_drop_cnt += - ctx->cs_counters.parsing_drop_cnt; - hdev->aggregated_cs_counters.queue_full_drop_cnt += - ctx->cs_counters.queue_full_drop_cnt; - hdev->aggregated_cs_counters.max_cs_in_flight_drop_cnt += - ctx->cs_counters.max_cs_in_flight_drop_cnt; + cs_job_put(job); } static void cs_do_release(struct kref *ref) { - struct hl_cs *cs = container_of(ref, struct hl_cs, - refcount); + struct hl_cs *cs = container_of(ref, struct hl_cs, refcount); struct hl_device *hdev = cs->ctx->hdev; struct hl_cs_job *job, *tmp; @@ -268,77 +308,78 @@ static void cs_do_release(struct kref *ref) /* * Although if we reached here it means that all external jobs have * finished, because each one of them took refcnt to CS, we still - * need to go over the internal jobs and free them. Otherwise, we + * need to go over the internal jobs and complete them. Otherwise, we * will have leaked memory and what's worse, the CS object (and * potentially the CTX object) could be released, while the JOB * still holds a pointer to them (but no reference). */ list_for_each_entry_safe(job, tmp, &cs->job_list, cs_node) - free_job(hdev, job); + complete_job(hdev, job); - /* We also need to update CI for internal queues */ - if (cs->submitted) { - hdev->asic_funcs->hw_queues_lock(hdev); + if (!cs->submitted) { + /* In case the wait for signal CS was submitted, the put occurs + * in init_signal_wait_cs() or collective_wait_init_cs() + * right before hanging on the PQ. + */ + if (cs->type == CS_TYPE_WAIT || + cs->type == CS_TYPE_COLLECTIVE_WAIT) + hl_fence_put(cs->signal_fence); - hdev->cs_active_cnt--; - if (!hdev->cs_active_cnt) { - struct hl_device_idle_busy_ts *ts; + goto out; + } - ts = &hdev->idle_busy_ts_arr[hdev->idle_busy_ts_idx++]; - ts->busy_to_idle_ts = ktime_get(); + hdev->asic_funcs->hw_queues_lock(hdev); - if (hdev->idle_busy_ts_idx == HL_IDLE_BUSY_TS_ARR_SIZE) - hdev->idle_busy_ts_idx = 0; - } else if (hdev->cs_active_cnt < 0) { - dev_crit(hdev->dev, "CS active cnt %d is negative\n", - hdev->cs_active_cnt); - } + hdev->cs_active_cnt--; + if (!hdev->cs_active_cnt) { + struct hl_device_idle_busy_ts *ts; - hdev->asic_funcs->hw_queues_unlock(hdev); + ts = &hdev->idle_busy_ts_arr[hdev->idle_busy_ts_idx++]; + ts->busy_to_idle_ts = ktime_get(); - hl_int_hw_queue_update_ci(cs); + if (hdev->idle_busy_ts_idx == HL_IDLE_BUSY_TS_ARR_SIZE) + hdev->idle_busy_ts_idx = 0; + } else if (hdev->cs_active_cnt < 0) { + dev_crit(hdev->dev, "CS active cnt %d is negative\n", + hdev->cs_active_cnt); + } - spin_lock(&hdev->hw_queues_mirror_lock); - /* remove CS from hw_queues mirror list */ - list_del_init(&cs->mirror_node); - spin_unlock(&hdev->hw_queues_mirror_lock); + hdev->asic_funcs->hw_queues_unlock(hdev); - /* - * Don't cancel TDR in case this CS was timedout because we - * might be running from the TDR context - */ - if ((!cs->timedout) && - (hdev->timeout_jiffies != MAX_SCHEDULE_TIMEOUT)) { - struct hl_cs *next; + /* Need to update CI for internal queues */ + hl_int_hw_queue_update_ci(cs); - if (cs->tdr_active) - cancel_delayed_work_sync(&cs->work_tdr); + /* remove CS from CS mirror list */ + spin_lock(&hdev->cs_mirror_lock); + list_del_init(&cs->mirror_node); + spin_unlock(&hdev->cs_mirror_lock); - spin_lock(&hdev->hw_queues_mirror_lock); + /* Don't cancel TDR in case this CS was timedout because we might be + * running from the TDR context + */ + if (!cs->timedout && hdev->timeout_jiffies != MAX_SCHEDULE_TIMEOUT) { + struct hl_cs *next; - /* queue TDR for next CS */ - next = list_first_entry_or_null( - &hdev->hw_queues_mirror_list, - struct hl_cs, mirror_node); + if (cs->tdr_active) + cancel_delayed_work_sync(&cs->work_tdr); - if ((next) && (!next->tdr_active)) { - next->tdr_active = true; - schedule_delayed_work(&next->work_tdr, - hdev->timeout_jiffies); - } + spin_lock(&hdev->cs_mirror_lock); - spin_unlock(&hdev->hw_queues_mirror_lock); + /* queue TDR for next CS */ + next = list_first_entry_or_null(&hdev->cs_mirror_list, + struct hl_cs, mirror_node); + + if (next && !next->tdr_active) { + next->tdr_active = true; + schedule_delayed_work(&next->work_tdr, + hdev->timeout_jiffies); } - } else if (cs->type == CS_TYPE_WAIT) { - /* - * In case the wait for signal CS was submitted, the put occurs - * in init_signal_wait_cs() right before hanging on the PQ. - */ - hl_fence_put(cs->signal_fence); + + spin_unlock(&hdev->cs_mirror_lock); } - /* - * Must be called before hl_ctx_put because inside we use ctx to get +out: + /* Must be called before hl_ctx_put because inside we use ctx to get * the device */ hl_debugfs_remove_cs(cs); @@ -356,9 +397,10 @@ static void cs_do_release(struct kref *ref) else if (!cs->submitted) cs->fence->error = -EBUSY; + if (cs->timestamp) + cs->fence->timestamp = ktime_get(); complete_all(&cs->fence->completion); hl_fence_put(cs->fence); - cs_counters_aggregate(hdev, cs->ctx); kfree(cs->jobs_in_queue_cnt); kfree(cs); @@ -384,24 +426,51 @@ static void cs_timedout(struct work_struct *work) hdev = cs->ctx->hdev; - dev_err(hdev->dev, - "Command submission %llu has not finished in time!\n", - cs->sequence); + switch (cs->type) { + case CS_TYPE_SIGNAL: + dev_err(hdev->dev, + "Signal command submission %llu has not finished in time!\n", + cs->sequence); + break; + + case CS_TYPE_WAIT: + dev_err(hdev->dev, + "Wait command submission %llu has not finished in time!\n", + cs->sequence); + break; + + case CS_TYPE_COLLECTIVE_WAIT: + dev_err(hdev->dev, + "Collective Wait command submission %llu has not finished in time!\n", + cs->sequence); + break; + + default: + dev_err(hdev->dev, + "Command submission %llu has not finished in time!\n", + cs->sequence); + break; + } cs_put(cs); if (hdev->reset_on_lockup) hl_device_reset(hdev, false, false); + else + hdev->needs_reset = true; } static int allocate_cs(struct hl_device *hdev, struct hl_ctx *ctx, enum hl_cs_type cs_type, struct hl_cs **cs_new) { - struct hl_cs_compl *cs_cmpl; + struct hl_cs_counters_atomic *cntr; struct hl_fence *other = NULL; + struct hl_cs_compl *cs_cmpl; struct hl_cs *cs; int rc; + cntr = &hdev->aggregated_cs_counters; + cs = kzalloc(sizeof(*cs), GFP_ATOMIC); if (!cs) return -ENOMEM; @@ -435,7 +504,8 @@ static int allocate_cs(struct hl_device *hdev, struct hl_ctx *ctx, if (other && !completion_done(&other->completion)) { dev_dbg_ratelimited(hdev->dev, "Rejecting CS because of too many in-flights CS\n"); - ctx->cs_counters.max_cs_in_flight_drop_cnt++; + atomic64_inc(&ctx->cs_counters.max_cs_in_flight_drop_cnt); + atomic64_inc(&cntr->max_cs_in_flight_drop_cnt); rc = -EAGAIN; goto free_fence; } @@ -480,7 +550,7 @@ static void cs_rollback(struct hl_device *hdev, struct hl_cs *cs) struct hl_cs_job *job, *tmp; list_for_each_entry_safe(job, tmp, &cs->job_list, cs_node) - free_job(hdev, job); + complete_job(hdev, job); } void hl_cs_rollback_all(struct hl_device *hdev) @@ -493,8 +563,7 @@ void hl_cs_rollback_all(struct hl_device *hdev) flush_workqueue(hdev->cq_wq[i]); /* Make sure we don't have leftovers in the H/W queues mirror list */ - list_for_each_entry_safe(cs, tmp, &hdev->hw_queues_mirror_list, - mirror_node) { + list_for_each_entry_safe(cs, tmp, &hdev->cs_mirror_list, mirror_node) { cs_get(cs); cs->aborted = true; dev_warn_ratelimited(hdev->dev, "Killing CS %d.%llu\n", @@ -512,7 +581,7 @@ static void job_wq_completion(struct work_struct *work) struct hl_device *hdev = cs->ctx->hdev; /* job is no longer needed */ - free_job(hdev, job); + complete_job(hdev, job); } static int validate_queue_index(struct hl_device *hdev, @@ -547,9 +616,36 @@ static int validate_queue_index(struct hl_device *hdev, return -EINVAL; } - *queue_type = hw_queue_prop->type; - *is_kernel_allocated_cb = !!hw_queue_prop->requires_kernel_cb; + /* When hw queue type isn't QUEUE_TYPE_HW, + * USER_ALLOC_CB flag shall be referred as "don't care". + */ + if (hw_queue_prop->type == QUEUE_TYPE_HW) { + if (chunk->cs_chunk_flags & HL_CS_CHUNK_FLAGS_USER_ALLOC_CB) { + if (!(hw_queue_prop->cb_alloc_flags & CB_ALLOC_USER)) { + dev_err(hdev->dev, + "Queue index %d doesn't support user CB\n", + chunk->queue_index); + return -EINVAL; + } + + *is_kernel_allocated_cb = false; + } else { + if (!(hw_queue_prop->cb_alloc_flags & + CB_ALLOC_KERNEL)) { + dev_err(hdev->dev, + "Queue index %d doesn't support kernel CB\n", + chunk->queue_index); + return -EINVAL; + } + + *is_kernel_allocated_cb = true; + } + } else { + *is_kernel_allocated_cb = !!(hw_queue_prop->cb_alloc_flags + & CB_ALLOC_KERNEL); + } + *queue_type = hw_queue_prop->type; return 0; } @@ -573,9 +669,7 @@ static struct hl_cb *get_cb_from_cs_chunk(struct hl_device *hdev, goto release_cb; } - spin_lock(&cb->lock); - cb->cs_cnt++; - spin_unlock(&cb->lock); + atomic_inc(&cb->cs_cnt); return cb; @@ -593,6 +687,7 @@ struct hl_cs_job *hl_cs_allocate_job(struct hl_device *hdev, if (!job) return NULL; + kref_init(&job->refcount); job->queue_type = queue_type; job->is_kernel_allocated_cb = is_kernel_allocated_cb; @@ -605,42 +700,115 @@ struct hl_cs_job *hl_cs_allocate_job(struct hl_device *hdev, return job; } -static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, - u32 num_chunks, u64 *cs_seq) +static enum hl_cs_type hl_cs_get_cs_type(u32 cs_type_flags) +{ + if (cs_type_flags & HL_CS_FLAGS_SIGNAL) + return CS_TYPE_SIGNAL; + else if (cs_type_flags & HL_CS_FLAGS_WAIT) + return CS_TYPE_WAIT; + else if (cs_type_flags & HL_CS_FLAGS_COLLECTIVE_WAIT) + return CS_TYPE_COLLECTIVE_WAIT; + else + return CS_TYPE_DEFAULT; +} + +static int hl_cs_sanity_checks(struct hl_fpriv *hpriv, union hl_cs_args *args) { struct hl_device *hdev = hpriv->hdev; - struct hl_cs_chunk *cs_chunk_array; - struct hl_cs_job *job; - struct hl_cs *cs; - struct hl_cb *cb; - bool int_queues_only = true; - u32 size_to_copy; - int rc, i; + struct hl_ctx *ctx = hpriv->ctx; + u32 cs_type_flags, num_chunks; + enum hl_device_status status; + enum hl_cs_type cs_type; - *cs_seq = ULLONG_MAX; + if (!hl_device_operational(hdev, &status)) { + dev_warn_ratelimited(hdev->dev, + "Device is %s. Can't submit new CS\n", + hdev->status[status]); + return -EBUSY; + } + + cs_type_flags = args->in.cs_flags & HL_CS_FLAGS_TYPE_MASK; + + if (unlikely(cs_type_flags && !is_power_of_2(cs_type_flags))) { + dev_err(hdev->dev, + "CS type flags are mutually exclusive, context %d\n", + ctx->asid); + return -EINVAL; + } + + cs_type = hl_cs_get_cs_type(cs_type_flags); + num_chunks = args->in.num_chunks_execute; + + if (unlikely((cs_type != CS_TYPE_DEFAULT) && + !hdev->supports_sync_stream)) { + dev_err(hdev->dev, "Sync stream CS is not supported\n"); + return -EINVAL; + } + + if (cs_type == CS_TYPE_DEFAULT) { + if (!num_chunks) { + dev_err(hdev->dev, + "Got execute CS with 0 chunks, context %d\n", + ctx->asid); + return -EINVAL; + } + } else if (num_chunks != 1) { + dev_err(hdev->dev, + "Sync stream CS mandates one chunk only, context %d\n", + ctx->asid); + return -EINVAL; + } + + return 0; +} + +static int hl_cs_copy_chunk_array(struct hl_device *hdev, + struct hl_cs_chunk **cs_chunk_array, + void __user *chunks, u32 num_chunks) +{ + u32 size_to_copy; if (num_chunks > HL_MAX_JOBS_PER_CS) { dev_err(hdev->dev, "Number of chunks can NOT be larger than %d\n", HL_MAX_JOBS_PER_CS); - rc = -EINVAL; - goto out; + return -EINVAL; } - cs_chunk_array = kmalloc_array(num_chunks, sizeof(*cs_chunk_array), + *cs_chunk_array = kmalloc_array(num_chunks, sizeof(**cs_chunk_array), GFP_ATOMIC); - if (!cs_chunk_array) { - rc = -ENOMEM; - goto out; - } + if (!*cs_chunk_array) + return -ENOMEM; size_to_copy = num_chunks * sizeof(struct hl_cs_chunk); - if (copy_from_user(cs_chunk_array, chunks, size_to_copy)) { + if (copy_from_user(*cs_chunk_array, chunks, size_to_copy)) { dev_err(hdev->dev, "Failed to copy cs chunk array from user\n"); - rc = -EFAULT; - goto free_cs_chunk_array; + kfree(*cs_chunk_array); + return -EFAULT; } + return 0; +} + +static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, + u32 num_chunks, u64 *cs_seq, bool timestamp) +{ + bool int_queues_only = true; + struct hl_device *hdev = hpriv->hdev; + struct hl_cs_chunk *cs_chunk_array; + struct hl_cs_counters_atomic *cntr; + struct hl_cs_job *job; + struct hl_cs *cs; + struct hl_cb *cb; + int rc, i; + + cntr = &hdev->aggregated_cs_counters; + *cs_seq = ULLONG_MAX; + + rc = hl_cs_copy_chunk_array(hdev, &cs_chunk_array, chunks, num_chunks); + if (rc) + goto out; + /* increment refcnt for context */ hl_ctx_get(hdev, hpriv->ctx); @@ -650,6 +818,7 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, goto free_cs_chunk_array; } + cs->timestamp = !!timestamp; *cs_seq = cs->sequence; hl_debugfs_add_cs(cs); @@ -663,14 +832,17 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, rc = validate_queue_index(hdev, chunk, &queue_type, &is_kernel_allocated_cb); if (rc) { - hpriv->ctx->cs_counters.parsing_drop_cnt++; + atomic64_inc(&hpriv->ctx->cs_counters.parsing_drop_cnt); + atomic64_inc(&cntr->parsing_drop_cnt); goto free_cs_object; } if (is_kernel_allocated_cb) { cb = get_cb_from_cs_chunk(hdev, &hpriv->cb_mgr, chunk); if (!cb) { - hpriv->ctx->cs_counters.parsing_drop_cnt++; + atomic64_inc( + &hpriv->ctx->cs_counters.parsing_drop_cnt); + atomic64_inc(&cntr->parsing_drop_cnt); rc = -EINVAL; goto free_cs_object; } @@ -684,7 +856,9 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, job = hl_cs_allocate_job(hdev, queue_type, is_kernel_allocated_cb); if (!job) { - hpriv->ctx->cs_counters.out_of_mem_drop_cnt++; + atomic64_inc( + &hpriv->ctx->cs_counters.out_of_mem_drop_cnt); + atomic64_inc(&cntr->out_of_mem_drop_cnt); dev_err(hdev->dev, "Failed to allocate a new job\n"); rc = -ENOMEM; if (is_kernel_allocated_cb) @@ -717,7 +891,8 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, rc = cs_parser(hpriv, job); if (rc) { - hpriv->ctx->cs_counters.parsing_drop_cnt++; + atomic64_inc(&hpriv->ctx->cs_counters.parsing_drop_cnt); + atomic64_inc(&cntr->parsing_drop_cnt); dev_err(hdev->dev, "Failed to parse JOB %d.%llu.%d, err %d, rejecting the CS\n", cs->ctx->asid, cs->sequence, job->id, rc); @@ -726,7 +901,8 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, } if (int_queues_only) { - hpriv->ctx->cs_counters.parsing_drop_cnt++; + atomic64_inc(&hpriv->ctx->cs_counters.parsing_drop_cnt); + atomic64_inc(&cntr->parsing_drop_cnt); dev_err(hdev->dev, "Reject CS %d.%llu because only internal queues jobs are present\n", cs->ctx->asid, cs->sequence); @@ -747,9 +923,7 @@ static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks, goto put_cs; release_cb: - spin_lock(&cb->lock); - cb->cs_cnt--; - spin_unlock(&cb->lock); + atomic_dec(&cb->cs_cnt); hl_cb_put(cb); free_cs_object: cs_rollback(hdev, cs); @@ -764,47 +938,234 @@ out: return rc; } -static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type, - void __user *chunks, u32 num_chunks, +static int hl_cs_ctx_switch(struct hl_fpriv *hpriv, union hl_cs_args *args, u64 *cs_seq) { struct hl_device *hdev = hpriv->hdev; struct hl_ctx *ctx = hpriv->ctx; - struct hl_cs_chunk *cs_chunk_array, *chunk; - struct hw_queue_properties *hw_queue_prop; - struct hl_fence *sig_fence = NULL; - struct hl_cs_job *job; - struct hl_cs *cs; - struct hl_cb *cb; - enum hl_queue_type q_type; - u64 *signal_seq_arr = NULL, signal_seq; - u32 size_to_copy, q_idx, signal_seq_arr_len, cb_size; - int rc; + bool need_soft_reset = false; + int rc = 0, do_ctx_switch; + void __user *chunks; + u32 num_chunks, tmp; + int ret; - *cs_seq = ULLONG_MAX; + do_ctx_switch = atomic_cmpxchg(&ctx->thread_ctx_switch_token, 1, 0); - if (num_chunks > HL_MAX_JOBS_PER_CS) { + if (do_ctx_switch || (args->in.cs_flags & HL_CS_FLAGS_FORCE_RESTORE)) { + mutex_lock(&hpriv->restore_phase_mutex); + + if (do_ctx_switch) { + rc = hdev->asic_funcs->context_switch(hdev, ctx->asid); + if (rc) { + dev_err_ratelimited(hdev->dev, + "Failed to switch to context %d, rejecting CS! %d\n", + ctx->asid, rc); + /* + * If we timedout, or if the device is not IDLE + * while we want to do context-switch (-EBUSY), + * we need to soft-reset because QMAN is + * probably stuck. However, we can't call to + * reset here directly because of deadlock, so + * need to do it at the very end of this + * function + */ + if ((rc == -ETIMEDOUT) || (rc == -EBUSY)) + need_soft_reset = true; + mutex_unlock(&hpriv->restore_phase_mutex); + goto out; + } + } + + hdev->asic_funcs->restore_phase_topology(hdev); + + chunks = (void __user *) (uintptr_t) args->in.chunks_restore; + num_chunks = args->in.num_chunks_restore; + + if (!num_chunks) { + dev_dbg(hdev->dev, + "Need to run restore phase but restore CS is empty\n"); + rc = 0; + } else { + rc = cs_ioctl_default(hpriv, chunks, num_chunks, + cs_seq, false); + } + + mutex_unlock(&hpriv->restore_phase_mutex); + + if (rc) { + dev_err(hdev->dev, + "Failed to submit restore CS for context %d (%d)\n", + ctx->asid, rc); + goto out; + } + + /* Need to wait for restore completion before execution phase */ + if (num_chunks) { + enum hl_cs_wait_status status; +wait_again: + ret = _hl_cs_wait_ioctl(hdev, ctx, + jiffies_to_usecs(hdev->timeout_jiffies), + *cs_seq, &status, NULL); + if (ret) { + if (ret == -ERESTARTSYS) { + usleep_range(100, 200); + goto wait_again; + } + + dev_err(hdev->dev, + "Restore CS for context %d failed to complete %d\n", + ctx->asid, ret); + rc = -ENOEXEC; + goto out; + } + } + + ctx->thread_ctx_switch_wait_token = 1; + + } else if (!ctx->thread_ctx_switch_wait_token) { + rc = hl_poll_timeout_memory(hdev, + &ctx->thread_ctx_switch_wait_token, tmp, (tmp == 1), + 100, jiffies_to_usecs(hdev->timeout_jiffies), false); + + if (rc == -ETIMEDOUT) { + dev_err(hdev->dev, + "context switch phase timeout (%d)\n", tmp); + goto out; + } + } + +out: + if ((rc == -ETIMEDOUT || rc == -EBUSY) && (need_soft_reset)) + hl_device_reset(hdev, false, false); + + return rc; +} + +static int cs_ioctl_extract_signal_seq(struct hl_device *hdev, + struct hl_cs_chunk *chunk, u64 *signal_seq) +{ + u64 *signal_seq_arr = NULL; + u32 size_to_copy, signal_seq_arr_len; + int rc = 0; + + signal_seq_arr_len = chunk->num_signal_seq_arr; + + /* currently only one signal seq is supported */ + if (signal_seq_arr_len != 1) { dev_err(hdev->dev, - "Number of chunks can NOT be larger than %d\n", - HL_MAX_JOBS_PER_CS); - rc = -EINVAL; - goto out; + "Wait for signal CS supports only one signal CS seq\n"); + return -EINVAL; } - cs_chunk_array = kmalloc_array(num_chunks, sizeof(*cs_chunk_array), + signal_seq_arr = kmalloc_array(signal_seq_arr_len, + sizeof(*signal_seq_arr), GFP_ATOMIC); - if (!cs_chunk_array) { - rc = -ENOMEM; + if (!signal_seq_arr) + return -ENOMEM; + + size_to_copy = chunk->num_signal_seq_arr * sizeof(*signal_seq_arr); + if (copy_from_user(signal_seq_arr, + u64_to_user_ptr(chunk->signal_seq_arr), + size_to_copy)) { + dev_err(hdev->dev, + "Failed to copy signal seq array from user\n"); + rc = -EFAULT; goto out; } - size_to_copy = num_chunks * sizeof(struct hl_cs_chunk); - if (copy_from_user(cs_chunk_array, chunks, size_to_copy)) { - dev_err(hdev->dev, "Failed to copy cs chunk array from user\n"); - rc = -EFAULT; - goto free_cs_chunk_array; + /* currently it is guaranteed to have only one signal seq */ + *signal_seq = signal_seq_arr[0]; + +out: + kfree(signal_seq_arr); + + return rc; +} + +static int cs_ioctl_signal_wait_create_jobs(struct hl_device *hdev, + struct hl_ctx *ctx, struct hl_cs *cs, enum hl_queue_type q_type, + u32 q_idx) +{ + struct hl_cs_counters_atomic *cntr; + struct hl_cs_job *job; + struct hl_cb *cb; + u32 cb_size; + + cntr = &hdev->aggregated_cs_counters; + + job = hl_cs_allocate_job(hdev, q_type, true); + if (!job) { + atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); + atomic64_inc(&cntr->out_of_mem_drop_cnt); + dev_err(hdev->dev, "Failed to allocate a new job\n"); + return -ENOMEM; } + if (cs->type == CS_TYPE_WAIT) + cb_size = hdev->asic_funcs->get_wait_cb_size(hdev); + else + cb_size = hdev->asic_funcs->get_signal_cb_size(hdev); + + cb = hl_cb_kernel_create(hdev, cb_size, + q_type == QUEUE_TYPE_HW && hdev->mmu_enable); + if (!cb) { + atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); + atomic64_inc(&cntr->out_of_mem_drop_cnt); + kfree(job); + return -EFAULT; + } + + job->id = 0; + job->cs = cs; + job->user_cb = cb; + atomic_inc(&job->user_cb->cs_cnt); + job->user_cb_size = cb_size; + job->hw_queue_id = q_idx; + + /* + * No need in parsing, user CB is the patched CB. + * We call hl_cb_destroy() out of two reasons - we don't need the CB in + * the CB idr anymore and to decrement its refcount as it was + * incremented inside hl_cb_kernel_create(). + */ + job->patched_cb = job->user_cb; + job->job_cb_size = job->user_cb_size; + hl_cb_destroy(hdev, &hdev->kernel_cb_mgr, cb->id << PAGE_SHIFT); + + /* increment refcount as for external queues we get completion */ + cs_get(cs); + + cs->jobs_in_queue_cnt[job->hw_queue_id]++; + + list_add_tail(&job->cs_node, &cs->job_list); + + hl_debugfs_add_job(hdev, job); + + return 0; +} + +static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type, + void __user *chunks, u32 num_chunks, + u64 *cs_seq, bool timestamp) +{ + struct hl_cs_chunk *cs_chunk_array, *chunk; + struct hw_queue_properties *hw_queue_prop; + struct hl_device *hdev = hpriv->hdev; + struct hl_cs_compl *sig_waitcs_cmpl; + u32 q_idx, collective_engine_id = 0; + struct hl_fence *sig_fence = NULL; + struct hl_ctx *ctx = hpriv->ctx; + enum hl_queue_type q_type; + struct hl_cs *cs; + u64 signal_seq; + int rc; + + *cs_seq = ULLONG_MAX; + + rc = hl_cs_copy_chunk_array(hdev, &cs_chunk_array, chunks, num_chunks); + if (rc) + goto out; + /* currently it is guaranteed to have only one chunk */ chunk = &cs_chunk_array[0]; @@ -819,60 +1180,43 @@ static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type, hw_queue_prop = &hdev->asic_prop.hw_queues_props[q_idx]; q_type = hw_queue_prop->type; - if ((q_idx >= hdev->asic_prop.max_queues) || - (!hw_queue_prop->supports_sync_stream)) { - dev_err(hdev->dev, "Queue index %d is invalid\n", q_idx); + if (!hw_queue_prop->supports_sync_stream) { + dev_err(hdev->dev, + "Queue index %d does not support sync stream operations\n", + q_idx); rc = -EINVAL; goto free_cs_chunk_array; } - if (cs_type == CS_TYPE_WAIT) { - struct hl_cs_compl *sig_waitcs_cmpl; - - signal_seq_arr_len = chunk->num_signal_seq_arr; - - /* currently only one signal seq is supported */ - if (signal_seq_arr_len != 1) { + if (cs_type == CS_TYPE_COLLECTIVE_WAIT) { + if (!(hw_queue_prop->collective_mode == HL_COLLECTIVE_MASTER)) { dev_err(hdev->dev, - "Wait for signal CS supports only one signal CS seq\n"); + "Queue index %d is invalid\n", q_idx); rc = -EINVAL; goto free_cs_chunk_array; } - signal_seq_arr = kmalloc_array(signal_seq_arr_len, - sizeof(*signal_seq_arr), - GFP_ATOMIC); - if (!signal_seq_arr) { - rc = -ENOMEM; - goto free_cs_chunk_array; - } + collective_engine_id = chunk->collective_engine_id; + } - size_to_copy = chunk->num_signal_seq_arr * - sizeof(*signal_seq_arr); - if (copy_from_user(signal_seq_arr, - u64_to_user_ptr(chunk->signal_seq_arr), - size_to_copy)) { - dev_err(hdev->dev, - "Failed to copy signal seq array from user\n"); - rc = -EFAULT; - goto free_signal_seq_array; - } + if (cs_type == CS_TYPE_WAIT || cs_type == CS_TYPE_COLLECTIVE_WAIT) { + rc = cs_ioctl_extract_signal_seq(hdev, chunk, &signal_seq); + if (rc) + goto free_cs_chunk_array; - /* currently it is guaranteed to have only one signal seq */ - signal_seq = signal_seq_arr[0]; sig_fence = hl_ctx_get_fence(ctx, signal_seq); if (IS_ERR(sig_fence)) { dev_err(hdev->dev, "Failed to get signal CS with seq 0x%llx\n", signal_seq); rc = PTR_ERR(sig_fence); - goto free_signal_seq_array; + goto free_cs_chunk_array; } if (!sig_fence) { /* signal CS already finished */ rc = 0; - goto free_signal_seq_array; + goto free_cs_chunk_array; } sig_waitcs_cmpl = @@ -884,14 +1228,14 @@ static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type, signal_seq); hl_fence_put(sig_fence); rc = -EINVAL; - goto free_signal_seq_array; + goto free_cs_chunk_array; } if (completion_done(&sig_fence->completion)) { /* signal CS already finished */ hl_fence_put(sig_fence); rc = 0; - goto free_signal_seq_array; + goto free_cs_chunk_array; } } @@ -900,70 +1244,37 @@ static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type, rc = allocate_cs(hdev, ctx, cs_type, &cs); if (rc) { - if (cs_type == CS_TYPE_WAIT) + if (cs_type == CS_TYPE_WAIT || + cs_type == CS_TYPE_COLLECTIVE_WAIT) hl_fence_put(sig_fence); hl_ctx_put(ctx); - goto free_signal_seq_array; + goto free_cs_chunk_array; } + cs->timestamp = !!timestamp; + /* * Save the signal CS fence for later initialization right before * hanging the wait CS on the queue. */ - if (cs->type == CS_TYPE_WAIT) + if (cs_type == CS_TYPE_WAIT || cs_type == CS_TYPE_COLLECTIVE_WAIT) cs->signal_fence = sig_fence; hl_debugfs_add_cs(cs); *cs_seq = cs->sequence; - job = hl_cs_allocate_job(hdev, q_type, true); - if (!job) { - ctx->cs_counters.out_of_mem_drop_cnt++; - dev_err(hdev->dev, "Failed to allocate a new job\n"); - rc = -ENOMEM; - goto put_cs; - } - - if (cs->type == CS_TYPE_WAIT) - cb_size = hdev->asic_funcs->get_wait_cb_size(hdev); + if (cs_type == CS_TYPE_WAIT || cs_type == CS_TYPE_SIGNAL) + rc = cs_ioctl_signal_wait_create_jobs(hdev, ctx, cs, q_type, + q_idx); + else if (cs_type == CS_TYPE_COLLECTIVE_WAIT) + rc = hdev->asic_funcs->collective_wait_create_jobs(hdev, ctx, + cs, q_idx, collective_engine_id); else - cb_size = hdev->asic_funcs->get_signal_cb_size(hdev); - - cb = hl_cb_kernel_create(hdev, cb_size, - q_type == QUEUE_TYPE_HW && hdev->mmu_enable); - if (!cb) { - ctx->cs_counters.out_of_mem_drop_cnt++; - kfree(job); - rc = -EFAULT; - goto put_cs; - } - - job->id = 0; - job->cs = cs; - job->user_cb = cb; - job->user_cb->cs_cnt++; - job->user_cb_size = cb_size; - job->hw_queue_id = q_idx; - - /* - * No need in parsing, user CB is the patched CB. - * We call hl_cb_destroy() out of two reasons - we don't need the CB in - * the CB idr anymore and to decrement its refcount as it was - * incremented inside hl_cb_kernel_create(). - */ - job->patched_cb = job->user_cb; - job->job_cb_size = job->user_cb_size; - hl_cb_destroy(hdev, &hdev->kernel_cb_mgr, cb->id << PAGE_SHIFT); - - cs->jobs_in_queue_cnt[job->hw_queue_id]++; - - list_add_tail(&job->cs_node, &cs->job_list); - - /* increment refcount as for external queues we get completion */ - cs_get(cs); + rc = -EINVAL; - hl_debugfs_add_job(hdev, job); + if (rc) + goto free_cs_object; rc = hl_hw_queue_schedule_cs(cs); if (rc) { @@ -984,9 +1295,6 @@ free_cs_object: put_cs: /* We finished with the CS in this function, so put the ref */ cs_put(cs); -free_signal_seq_array: - if (cs_type == CS_TYPE_WAIT) - kfree(signal_seq_arr); free_cs_chunk_array: kfree(cs_chunk_array); out: @@ -995,156 +1303,39 @@ out: int hl_cs_ioctl(struct hl_fpriv *hpriv, void *data) { - struct hl_device *hdev = hpriv->hdev; union hl_cs_args *args = data; - struct hl_ctx *ctx = hpriv->ctx; - void __user *chunks_execute, *chunks_restore; enum hl_cs_type cs_type; - u32 num_chunks_execute, num_chunks_restore, sig_wait_flags; u64 cs_seq = ULONG_MAX; - int rc, do_ctx_switch; - bool need_soft_reset = false; - - if (hl_device_disabled_or_in_reset(hdev)) { - dev_warn_ratelimited(hdev->dev, - "Device is %s. Can't submit new CS\n", - atomic_read(&hdev->in_reset) ? "in_reset" : "disabled"); - rc = -EBUSY; - goto out; - } - - sig_wait_flags = args->in.cs_flags & HL_CS_FLAGS_SIG_WAIT; + void __user *chunks; + u32 num_chunks; + int rc; - if (unlikely(sig_wait_flags == HL_CS_FLAGS_SIG_WAIT)) { - dev_err(hdev->dev, - "Signal and wait CS flags are mutually exclusive, context %d\n", - ctx->asid); - rc = -EINVAL; + rc = hl_cs_sanity_checks(hpriv, args); + if (rc) goto out; - } - if (unlikely((sig_wait_flags & HL_CS_FLAGS_SIG_WAIT) && - (!hdev->supports_sync_stream))) { - dev_err(hdev->dev, "Sync stream CS is not supported\n"); - rc = -EINVAL; + rc = hl_cs_ctx_switch(hpriv, args, &cs_seq); + if (rc) goto out; - } - if (args->in.cs_flags & HL_CS_FLAGS_SIGNAL) - cs_type = CS_TYPE_SIGNAL; - else if (args->in.cs_flags & HL_CS_FLAGS_WAIT) - cs_type = CS_TYPE_WAIT; - else - cs_type = CS_TYPE_DEFAULT; - - chunks_execute = (void __user *) (uintptr_t) args->in.chunks_execute; - num_chunks_execute = args->in.num_chunks_execute; - - if (cs_type == CS_TYPE_DEFAULT) { - if (!num_chunks_execute) { - dev_err(hdev->dev, - "Got execute CS with 0 chunks, context %d\n", - ctx->asid); - rc = -EINVAL; - goto out; - } - } else if (num_chunks_execute != 1) { - dev_err(hdev->dev, - "Sync stream CS mandates one chunk only, context %d\n", - ctx->asid); - rc = -EINVAL; - goto out; + cs_type = hl_cs_get_cs_type(args->in.cs_flags & + ~HL_CS_FLAGS_FORCE_RESTORE); + chunks = (void __user *) (uintptr_t) args->in.chunks_execute; + num_chunks = args->in.num_chunks_execute; + + switch (cs_type) { + case CS_TYPE_SIGNAL: + case CS_TYPE_WAIT: + case CS_TYPE_COLLECTIVE_WAIT: + rc = cs_ioctl_signal_wait(hpriv, cs_type, chunks, num_chunks, + &cs_seq, args->in.cs_flags & HL_CS_FLAGS_TIMESTAMP); + break; + default: + rc = cs_ioctl_default(hpriv, chunks, num_chunks, &cs_seq, + args->in.cs_flags & HL_CS_FLAGS_TIMESTAMP); + break; } - do_ctx_switch = atomic_cmpxchg(&ctx->thread_ctx_switch_token, 1, 0); - - if (do_ctx_switch || (args->in.cs_flags & HL_CS_FLAGS_FORCE_RESTORE)) { - long ret; - - chunks_restore = - (void __user *) (uintptr_t) args->in.chunks_restore; - num_chunks_restore = args->in.num_chunks_restore; - - mutex_lock(&hpriv->restore_phase_mutex); - - if (do_ctx_switch) { - rc = hdev->asic_funcs->context_switch(hdev, ctx->asid); - if (rc) { - dev_err_ratelimited(hdev->dev, - "Failed to switch to context %d, rejecting CS! %d\n", - ctx->asid, rc); - /* - * If we timedout, or if the device is not IDLE - * while we want to do context-switch (-EBUSY), - * we need to soft-reset because QMAN is - * probably stuck. However, we can't call to - * reset here directly because of deadlock, so - * need to do it at the very end of this - * function - */ - if ((rc == -ETIMEDOUT) || (rc == -EBUSY)) - need_soft_reset = true; - mutex_unlock(&hpriv->restore_phase_mutex); - goto out; - } - } - - hdev->asic_funcs->restore_phase_topology(hdev); - - if (!num_chunks_restore) { - dev_dbg(hdev->dev, - "Need to run restore phase but restore CS is empty\n"); - rc = 0; - } else { - rc = cs_ioctl_default(hpriv, chunks_restore, - num_chunks_restore, &cs_seq); - } - - mutex_unlock(&hpriv->restore_phase_mutex); - - if (rc) { - dev_err(hdev->dev, - "Failed to submit restore CS for context %d (%d)\n", - ctx->asid, rc); - goto out; - } - - /* Need to wait for restore completion before execution phase */ - if (num_chunks_restore) { - ret = _hl_cs_wait_ioctl(hdev, ctx, - jiffies_to_usecs(hdev->timeout_jiffies), - cs_seq); - if (ret <= 0) { - dev_err(hdev->dev, - "Restore CS for context %d failed to complete %ld\n", - ctx->asid, ret); - rc = -ENOEXEC; - goto out; - } - } - - ctx->thread_ctx_switch_wait_token = 1; - } else if (!ctx->thread_ctx_switch_wait_token) { - u32 tmp; - - rc = hl_poll_timeout_memory(hdev, - &ctx->thread_ctx_switch_wait_token, tmp, (tmp == 1), - 100, jiffies_to_usecs(hdev->timeout_jiffies), false); - - if (rc == -ETIMEDOUT) { - dev_err(hdev->dev, - "context switch phase timeout (%d)\n", tmp); - goto out; - } - } - - if (cs_type == CS_TYPE_DEFAULT) - rc = cs_ioctl_default(hpriv, chunks_execute, num_chunks_execute, - &cs_seq); - else - rc = cs_ioctl_signal_wait(hpriv, cs_type, chunks_execute, - num_chunks_execute, &cs_seq); - out: if (rc != -EAGAIN) { memset(args, 0, sizeof(*args)); @@ -1152,18 +1343,20 @@ out: args->out.seq = cs_seq; } - if (((rc == -ETIMEDOUT) || (rc == -EBUSY)) && (need_soft_reset)) - hl_device_reset(hdev, false, false); - return rc; } -static long _hl_cs_wait_ioctl(struct hl_device *hdev, - struct hl_ctx *ctx, u64 timeout_us, u64 seq) +static int _hl_cs_wait_ioctl(struct hl_device *hdev, struct hl_ctx *ctx, + u64 timeout_us, u64 seq, + enum hl_cs_wait_status *status, s64 *timestamp) { struct hl_fence *fence; unsigned long timeout; - long rc; + int rc = 0; + long completion_rc; + + if (timestamp) + *timestamp = 0; if (timeout_us == MAX_SCHEDULE_TIMEOUT) timeout = timeout_us; @@ -1181,11 +1374,20 @@ static long _hl_cs_wait_ioctl(struct hl_device *hdev, seq, ctx->cs_sequence); } else if (fence) { if (!timeout_us) - rc = completion_done(&fence->completion); + completion_rc = completion_done(&fence->completion); else - rc = wait_for_completion_interruptible_timeout( + completion_rc = + wait_for_completion_interruptible_timeout( &fence->completion, timeout); + if (completion_rc > 0) { + *status = CS_WAIT_STATUS_COMPLETED; + if (timestamp) + *timestamp = ktime_to_ns(fence->timestamp); + } else { + *status = CS_WAIT_STATUS_BUSY; + } + if (fence->error == -ETIMEDOUT) rc = -ETIMEDOUT; else if (fence->error == -EIO) @@ -1196,7 +1398,7 @@ static long _hl_cs_wait_ioctl(struct hl_device *hdev, dev_dbg(hdev->dev, "Can't wait on seq %llu because current CS is at seq %llu (Fence is gone)\n", seq, ctx->cs_sequence); - rc = 1; + *status = CS_WAIT_STATUS_GONE; } hl_ctx_put(ctx); @@ -1208,14 +1410,17 @@ int hl_cs_wait_ioctl(struct hl_fpriv *hpriv, void *data) { struct hl_device *hdev = hpriv->hdev; union hl_wait_cs_args *args = data; + enum hl_cs_wait_status status; u64 seq = args->in.seq; - long rc; + s64 timestamp; + int rc; - rc = _hl_cs_wait_ioctl(hdev, hpriv->ctx, args->in.timeout_us, seq); + rc = _hl_cs_wait_ioctl(hdev, hpriv->ctx, args->in.timeout_us, seq, + &status, ×tamp); memset(args, 0, sizeof(*args)); - if (rc < 0) { + if (rc) { if (rc == -ERESTARTSYS) { dev_err_ratelimited(hdev->dev, "user process got signal while waiting for CS handle %llu\n", @@ -1236,10 +1441,23 @@ int hl_cs_wait_ioctl(struct hl_fpriv *hpriv, void *data) return rc; } - if (rc == 0) - args->out.status = HL_WAIT_CS_STATUS_BUSY; - else + if (timestamp) { + args->out.flags |= HL_WAIT_CS_STATUS_FLAG_TIMESTAMP_VLD; + args->out.timestamp_nsec = timestamp; + } + + switch (status) { + case CS_WAIT_STATUS_GONE: + args->out.flags |= HL_WAIT_CS_STATUS_FLAG_GONE; + fallthrough; + case CS_WAIT_STATUS_COMPLETED: args->out.status = HL_WAIT_CS_STATUS_COMPLETED; + break; + case CS_WAIT_STATUS_BUSY: + default: + args->out.status = HL_WAIT_CS_STATUS_BUSY; + break; + } return 0; } diff --git a/drivers/misc/habanalabs/common/context.c b/drivers/misc/habanalabs/common/context.c index 7a59dd7c6450..f65e6559149b 100644 --- a/drivers/misc/habanalabs/common/context.c +++ b/drivers/misc/habanalabs/common/context.c @@ -40,10 +40,14 @@ static void hl_ctx_fini(struct hl_ctx *ctx) if ((hdev->in_debug) && (hdev->compute_ctx == ctx)) hl_device_set_debug_mode(hdev, false); + hdev->asic_funcs->ctx_fini(ctx); hl_cb_va_pool_fini(ctx); hl_vm_ctx_fini(ctx); hl_asid_free(hdev, ctx->asid); + /* Scrub both SRAM and DRAM */ + hdev->asic_funcs->scrub_device_mem(hdev, 0, 0); + if ((!hdev->pldm) && (hdev->pdev) && (!hdev->asic_funcs->is_device_idle(hdev, &idle_mask, NULL))) diff --git a/drivers/misc/habanalabs/common/debugfs.c b/drivers/misc/habanalabs/common/debugfs.c index 912ddfa360b1..cef716643979 100644 --- a/drivers/misc/habanalabs/common/debugfs.c +++ b/drivers/misc/habanalabs/common/debugfs.c @@ -22,9 +22,10 @@ static int hl_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr, u8 i2c_reg, long *val) { struct cpucp_packet pkt; + u64 result; int rc; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -EBUSY; memset(&pkt, 0, sizeof(pkt)); @@ -36,7 +37,9 @@ static int hl_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr, pkt.i2c_reg = i2c_reg; rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), - 0, val); + 0, &result); + + *val = (long) result; if (rc) dev_err(hdev->dev, "Failed to read from I2C, error %d\n", rc); @@ -50,7 +53,7 @@ static int hl_debugfs_i2c_write(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr, struct cpucp_packet pkt; int rc; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -EBUSY; memset(&pkt, 0, sizeof(pkt)); @@ -76,7 +79,7 @@ static void hl_debugfs_led_set(struct hl_device *hdev, u8 led, u8 state) struct cpucp_packet pkt; int rc; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return; memset(&pkt, 0, sizeof(pkt)); @@ -113,7 +116,7 @@ static int command_buffers_show(struct seq_file *s, void *data) " %03llu %d 0x%08x %d %d %d\n", cb->id, cb->ctx->asid, cb->size, kref_read(&cb->refcount), - cb->mmap, cb->cs_cnt); + cb->mmap, atomic_read(&cb->cs_cnt)); } spin_unlock(&dev_entry->cb_spinlock); @@ -168,18 +171,19 @@ static int command_submission_jobs_show(struct seq_file *s, void *data) if (first) { first = false; seq_puts(s, "\n"); - seq_puts(s, " JOB ID CS ID CTX ASID H/W Queue\n"); - seq_puts(s, "---------------------------------------\n"); + seq_puts(s, " JOB ID CS ID CTX ASID JOB RefCnt H/W Queue\n"); + seq_puts(s, "----------------------------------------------------\n"); } if (job->cs) seq_printf(s, - " %02d %llu %d %d\n", + " %02d %llu %d %d %d\n", job->id, job->cs->sequence, job->cs->ctx->asid, - job->hw_queue_id); + kref_read(&job->refcount), job->hw_queue_id); else seq_printf(s, - " %02d 0 %d %d\n", - job->id, HL_KERNEL_ASID_ID, job->hw_queue_id); + " %02d 0 %d %d %d\n", + job->id, HL_KERNEL_ASID_ID, + kref_read(&job->refcount), job->hw_queue_id); } spin_unlock(&dev_entry->cs_job_spinlock); @@ -300,93 +304,15 @@ static int vm_show(struct seq_file *s, void *data) return 0; } -/* these inline functions are copied from mmu.c */ -static inline u64 get_hop0_addr(struct hl_ctx *ctx) -{ - return ctx->hdev->asic_prop.mmu_pgt_addr + - (ctx->asid * ctx->hdev->asic_prop.mmu_hop_table_size); -} - -static inline u64 get_hopN_pte_addr(struct hl_ctx *ctx, u64 hop_addr, - u64 virt_addr, u64 mask, u64 shift) -{ - return hop_addr + ctx->hdev->asic_prop.mmu_pte_size * - ((virt_addr & mask) >> shift); -} - -static inline u64 get_hop0_pte_addr(struct hl_ctx *ctx, - struct hl_mmu_properties *mmu_specs, - u64 hop_addr, u64 vaddr) -{ - return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop0_mask, - mmu_specs->hop0_shift); -} - -static inline u64 get_hop1_pte_addr(struct hl_ctx *ctx, - struct hl_mmu_properties *mmu_specs, - u64 hop_addr, u64 vaddr) -{ - return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop1_mask, - mmu_specs->hop1_shift); -} - -static inline u64 get_hop2_pte_addr(struct hl_ctx *ctx, - struct hl_mmu_properties *mmu_specs, - u64 hop_addr, u64 vaddr) -{ - return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop2_mask, - mmu_specs->hop2_shift); -} - -static inline u64 get_hop3_pte_addr(struct hl_ctx *ctx, - struct hl_mmu_properties *mmu_specs, - u64 hop_addr, u64 vaddr) -{ - return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop3_mask, - mmu_specs->hop3_shift); -} - -static inline u64 get_hop4_pte_addr(struct hl_ctx *ctx, - struct hl_mmu_properties *mmu_specs, - u64 hop_addr, u64 vaddr) -{ - return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop4_mask, - mmu_specs->hop4_shift); -} - -static inline u64 get_hop5_pte_addr(struct hl_ctx *ctx, - struct hl_mmu_properties *mmu_specs, - u64 hop_addr, u64 vaddr) -{ - return get_hopN_pte_addr(ctx, hop_addr, vaddr, mmu_specs->hop5_mask, - mmu_specs->hop5_shift); -} - -static inline u64 get_next_hop_addr(u64 curr_pte) -{ - if (curr_pte & PAGE_PRESENT_MASK) - return curr_pte & HOP_PHYS_ADDR_MASK; - else - return ULLONG_MAX; -} - static int mmu_show(struct seq_file *s, void *data) { struct hl_debugfs_entry *entry = s->private; struct hl_dbg_device_entry *dev_entry = entry->dev_entry; struct hl_device *hdev = dev_entry->hdev; - struct asic_fixed_properties *prop = &hdev->asic_prop; - struct hl_mmu_properties *mmu_prop; struct hl_ctx *ctx; - bool is_dram_addr; - - u64 hop0_addr = 0, hop0_pte_addr = 0, hop0_pte = 0, - hop1_addr = 0, hop1_pte_addr = 0, hop1_pte = 0, - hop2_addr = 0, hop2_pte_addr = 0, hop2_pte = 0, - hop3_addr = 0, hop3_pte_addr = 0, hop3_pte = 0, - hop4_addr = 0, hop4_pte_addr = 0, hop4_pte = 0, - hop5_addr = 0, hop5_pte_addr = 0, hop5_pte = 0, - virt_addr = dev_entry->mmu_addr; + struct hl_mmu_hop_info hops_info; + u64 virt_addr = dev_entry->mmu_addr; + int i; if (!hdev->mmu_enable) return 0; @@ -401,132 +327,24 @@ static int mmu_show(struct seq_file *s, void *data) return 0; } - is_dram_addr = hl_mem_area_inside_range(virt_addr, prop->dmmu.page_size, - prop->dmmu.start_addr, - prop->dmmu.end_addr); - - /* shifts and masks are the same in PMMU and HPMMU, use one of them */ - mmu_prop = is_dram_addr ? &prop->dmmu : &prop->pmmu; - - mutex_lock(&ctx->mmu_lock); - - /* the following lookup is copied from unmap() in mmu.c */ - - hop0_addr = get_hop0_addr(ctx); - hop0_pte_addr = get_hop0_pte_addr(ctx, mmu_prop, hop0_addr, virt_addr); - hop0_pte = hdev->asic_funcs->read_pte(hdev, hop0_pte_addr); - hop1_addr = get_next_hop_addr(hop0_pte); - - if (hop1_addr == ULLONG_MAX) - goto not_mapped; - - hop1_pte_addr = get_hop1_pte_addr(ctx, mmu_prop, hop1_addr, virt_addr); - hop1_pte = hdev->asic_funcs->read_pte(hdev, hop1_pte_addr); - hop2_addr = get_next_hop_addr(hop1_pte); - - if (hop2_addr == ULLONG_MAX) - goto not_mapped; - - hop2_pte_addr = get_hop2_pte_addr(ctx, mmu_prop, hop2_addr, virt_addr); - hop2_pte = hdev->asic_funcs->read_pte(hdev, hop2_pte_addr); - hop3_addr = get_next_hop_addr(hop2_pte); - - if (hop3_addr == ULLONG_MAX) - goto not_mapped; - - hop3_pte_addr = get_hop3_pte_addr(ctx, mmu_prop, hop3_addr, virt_addr); - hop3_pte = hdev->asic_funcs->read_pte(hdev, hop3_pte_addr); - - if (mmu_prop->num_hops == MMU_ARCH_5_HOPS) { - if (!(hop3_pte & LAST_MASK)) { - hop4_addr = get_next_hop_addr(hop3_pte); - - if (hop4_addr == ULLONG_MAX) - goto not_mapped; - - hop4_pte_addr = get_hop4_pte_addr(ctx, mmu_prop, - hop4_addr, virt_addr); - hop4_pte = hdev->asic_funcs->read_pte(hdev, - hop4_pte_addr); - if (!(hop4_pte & PAGE_PRESENT_MASK)) - goto not_mapped; - } else { - if (!(hop3_pte & PAGE_PRESENT_MASK)) - goto not_mapped; - } - } else { - hop4_addr = get_next_hop_addr(hop3_pte); - - if (hop4_addr == ULLONG_MAX) - goto not_mapped; - - hop4_pte_addr = get_hop4_pte_addr(ctx, mmu_prop, - hop4_addr, virt_addr); - hop4_pte = hdev->asic_funcs->read_pte(hdev, - hop4_pte_addr); - if (!(hop4_pte & LAST_MASK)) { - hop5_addr = get_next_hop_addr(hop4_pte); - - if (hop5_addr == ULLONG_MAX) - goto not_mapped; - - hop5_pte_addr = get_hop5_pte_addr(ctx, mmu_prop, - hop5_addr, virt_addr); - hop5_pte = hdev->asic_funcs->read_pte(hdev, - hop5_pte_addr); - if (!(hop5_pte & PAGE_PRESENT_MASK)) - goto not_mapped; - } else { - if (!(hop4_pte & PAGE_PRESENT_MASK)) - goto not_mapped; - } + if (hl_mmu_get_tlb_info(ctx, virt_addr, &hops_info)) { + dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n", + virt_addr); + return 0; } seq_printf(s, "asid: %u, virt_addr: 0x%llx\n", dev_entry->mmu_asid, dev_entry->mmu_addr); - seq_printf(s, "hop0_addr: 0x%llx\n", hop0_addr); - seq_printf(s, "hop0_pte_addr: 0x%llx\n", hop0_pte_addr); - seq_printf(s, "hop0_pte: 0x%llx\n", hop0_pte); - - seq_printf(s, "hop1_addr: 0x%llx\n", hop1_addr); - seq_printf(s, "hop1_pte_addr: 0x%llx\n", hop1_pte_addr); - seq_printf(s, "hop1_pte: 0x%llx\n", hop1_pte); - - seq_printf(s, "hop2_addr: 0x%llx\n", hop2_addr); - seq_printf(s, "hop2_pte_addr: 0x%llx\n", hop2_pte_addr); - seq_printf(s, "hop2_pte: 0x%llx\n", hop2_pte); - - seq_printf(s, "hop3_addr: 0x%llx\n", hop3_addr); - seq_printf(s, "hop3_pte_addr: 0x%llx\n", hop3_pte_addr); - seq_printf(s, "hop3_pte: 0x%llx\n", hop3_pte); - - if (mmu_prop->num_hops == MMU_ARCH_5_HOPS) { - if (!(hop3_pte & LAST_MASK)) { - seq_printf(s, "hop4_addr: 0x%llx\n", hop4_addr); - seq_printf(s, "hop4_pte_addr: 0x%llx\n", hop4_pte_addr); - seq_printf(s, "hop4_pte: 0x%llx\n", hop4_pte); - } - } else { - seq_printf(s, "hop4_addr: 0x%llx\n", hop4_addr); - seq_printf(s, "hop4_pte_addr: 0x%llx\n", hop4_pte_addr); - seq_printf(s, "hop4_pte: 0x%llx\n", hop4_pte); - - if (!(hop4_pte & LAST_MASK)) { - seq_printf(s, "hop5_addr: 0x%llx\n", hop5_addr); - seq_printf(s, "hop5_pte_addr: 0x%llx\n", hop5_pte_addr); - seq_printf(s, "hop5_pte: 0x%llx\n", hop5_pte); - } + for (i = 0 ; i < hops_info.used_hops ; i++) { + seq_printf(s, "hop%d_addr: 0x%llx\n", + i, hops_info.hop_info[i].hop_addr); + seq_printf(s, "hop%d_pte_addr: 0x%llx\n", + i, hops_info.hop_info[i].hop_pte_addr); + seq_printf(s, "hop%d_pte: 0x%llx\n", + i, hops_info.hop_info[i].hop_pte_val); } - goto out; - -not_mapped: - dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n", - virt_addr); -out: - mutex_unlock(&ctx->mmu_lock); - return 0; } @@ -597,7 +415,7 @@ static bool hl_is_device_va(struct hl_device *hdev, u64 addr) if (!hdev->mmu_enable) goto out; - if (hdev->dram_supports_virtual_memory && + if (prop->dram_supports_virtual_memory && (addr >= prop->dmmu.start_addr && addr < prop->dmmu.end_addr)) return true; @@ -616,78 +434,20 @@ static int device_va_to_pa(struct hl_device *hdev, u64 virt_addr, u64 *phys_addr) { struct hl_ctx *ctx = hdev->compute_ctx; - struct asic_fixed_properties *prop = &hdev->asic_prop; - struct hl_mmu_properties *mmu_prop; - u64 hop_addr, hop_pte_addr, hop_pte; - u64 offset_mask = HOP4_MASK | FLAGS_MASK; int rc = 0; - bool is_dram_addr; if (!ctx) { dev_err(hdev->dev, "no ctx available\n"); return -EINVAL; } - is_dram_addr = hl_mem_area_inside_range(virt_addr, prop->dmmu.page_size, - prop->dmmu.start_addr, - prop->dmmu.end_addr); - - /* shifts and masks are the same in PMMU and HPMMU, use one of them */ - mmu_prop = is_dram_addr ? &prop->dmmu : &prop->pmmu; - - mutex_lock(&ctx->mmu_lock); - - /* hop 0 */ - hop_addr = get_hop0_addr(ctx); - hop_pte_addr = get_hop0_pte_addr(ctx, mmu_prop, hop_addr, virt_addr); - hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr); - - /* hop 1 */ - hop_addr = get_next_hop_addr(hop_pte); - if (hop_addr == ULLONG_MAX) - goto not_mapped; - hop_pte_addr = get_hop1_pte_addr(ctx, mmu_prop, hop_addr, virt_addr); - hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr); - - /* hop 2 */ - hop_addr = get_next_hop_addr(hop_pte); - if (hop_addr == ULLONG_MAX) - goto not_mapped; - hop_pte_addr = get_hop2_pte_addr(ctx, mmu_prop, hop_addr, virt_addr); - hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr); - - /* hop 3 */ - hop_addr = get_next_hop_addr(hop_pte); - if (hop_addr == ULLONG_MAX) - goto not_mapped; - hop_pte_addr = get_hop3_pte_addr(ctx, mmu_prop, hop_addr, virt_addr); - hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr); - - if (!(hop_pte & LAST_MASK)) { - /* hop 4 */ - hop_addr = get_next_hop_addr(hop_pte); - if (hop_addr == ULLONG_MAX) - goto not_mapped; - hop_pte_addr = get_hop4_pte_addr(ctx, mmu_prop, hop_addr, - virt_addr); - hop_pte = hdev->asic_funcs->read_pte(hdev, hop_pte_addr); - - offset_mask = FLAGS_MASK; + rc = hl_mmu_va_to_pa(ctx, virt_addr, phys_addr); + if (rc) { + dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n", + virt_addr); + rc = -EINVAL; } - if (!(hop_pte & PAGE_PRESENT_MASK)) - goto not_mapped; - - *phys_addr = (hop_pte & ~offset_mask) | (virt_addr & offset_mask); - - goto out; - -not_mapped: - dev_err(hdev->dev, "virt addr 0x%llx is not mapped to phys addr\n", - virt_addr); - rc = -EINVAL; -out: - mutex_unlock(&ctx->mmu_lock); return rc; } diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c index 20572224099a..5871162a8442 100644 --- a/drivers/misc/habanalabs/common/device.c +++ b/drivers/misc/habanalabs/common/device.c @@ -10,20 +10,9 @@ #include "habanalabs.h" #include <linux/pci.h> -#include <linux/sched/signal.h> #include <linux/hwmon.h> #include <uapi/misc/habanalabs.h> -#define HL_PLDM_PENDING_RESET_PER_SEC (HL_PENDING_RESET_PER_SEC * 10) - -bool hl_device_disabled_or_in_reset(struct hl_device *hdev) -{ - if ((hdev->disabled) || (atomic_read(&hdev->in_reset))) - return true; - else - return false; -} - enum hl_device_status hl_device_status(struct hl_device *hdev) { enum hl_device_status status; @@ -32,12 +21,34 @@ enum hl_device_status hl_device_status(struct hl_device *hdev) status = HL_DEVICE_STATUS_MALFUNCTION; else if (atomic_read(&hdev->in_reset)) status = HL_DEVICE_STATUS_IN_RESET; + else if (hdev->needs_reset) + status = HL_DEVICE_STATUS_NEEDS_RESET; else status = HL_DEVICE_STATUS_OPERATIONAL; return status; } +bool hl_device_operational(struct hl_device *hdev, + enum hl_device_status *status) +{ + enum hl_device_status current_status; + + current_status = hl_device_status(hdev); + if (status) + *status = current_status; + + switch (current_status) { + case HL_DEVICE_STATUS_IN_RESET: + case HL_DEVICE_STATUS_MALFUNCTION: + case HL_DEVICE_STATUS_NEEDS_RESET: + return false; + case HL_DEVICE_STATUS_OPERATIONAL: + default: + return true; + } +} + static void hpriv_release(struct kref *ref) { struct hl_fpriv *hpriv; @@ -231,16 +242,36 @@ delete_cdev_device: static void device_cdev_sysfs_del(struct hl_device *hdev) { - /* device_release() won't be called so must free devices explicitly */ - if (!hdev->cdev_sysfs_created) { - kfree(hdev->dev_ctrl); - kfree(hdev->dev); - return; - } + if (!hdev->cdev_sysfs_created) + goto put_devices; hl_sysfs_fini(hdev); cdev_device_del(&hdev->cdev_ctrl, hdev->dev_ctrl); cdev_device_del(&hdev->cdev, hdev->dev); + +put_devices: + put_device(hdev->dev); + put_device(hdev->dev_ctrl); +} + +static void device_hard_reset_pending(struct work_struct *work) +{ + struct hl_device_reset_work *device_reset_work = + container_of(work, struct hl_device_reset_work, + reset_work.work); + struct hl_device *hdev = device_reset_work->hdev; + int rc; + + rc = hl_device_reset(hdev, true, true); + if ((rc == -EBUSY) && !hdev->device_fini_pending) { + dev_info(hdev->dev, + "Could not reset device. will try again in %u seconds", + HL_PENDING_RESET_PER_SEC); + + queue_delayed_work(device_reset_work->wq, + &device_reset_work->reset_work, + msecs_to_jiffies(HL_PENDING_RESET_PER_SEC * 1000)); + } } /* @@ -327,17 +358,32 @@ static int device_early_init(struct hl_device *hdev) hl_cb_mgr_init(&hdev->kernel_cb_mgr); + hdev->device_reset_work.wq = + create_singlethread_workqueue("hl_device_reset"); + if (!hdev->device_reset_work.wq) { + rc = -ENOMEM; + dev_err(hdev->dev, "Failed to create device reset WQ\n"); + goto free_cb_mgr; + } + + INIT_DELAYED_WORK(&hdev->device_reset_work.reset_work, + device_hard_reset_pending); + hdev->device_reset_work.hdev = hdev; + hdev->device_fini_pending = 0; + mutex_init(&hdev->send_cpu_message_lock); mutex_init(&hdev->debug_lock); mutex_init(&hdev->mmu_cache_lock); - INIT_LIST_HEAD(&hdev->hw_queues_mirror_list); - spin_lock_init(&hdev->hw_queues_mirror_lock); + INIT_LIST_HEAD(&hdev->cs_mirror_list); + spin_lock_init(&hdev->cs_mirror_lock); INIT_LIST_HEAD(&hdev->fpriv_list); mutex_init(&hdev->fpriv_list_lock); atomic_set(&hdev->in_reset, 0); return 0; +free_cb_mgr: + hl_cb_mgr_fini(hdev, &hdev->kernel_cb_mgr); free_idle_busy_ts_arr: kfree(hdev->idle_busy_ts_arr); free_chip_info: @@ -380,6 +426,7 @@ static void device_early_fini(struct hl_device *hdev) kfree(hdev->hl_chip_info); destroy_workqueue(hdev->eq_wq); + destroy_workqueue(hdev->device_reset_work.wq); for (i = 0 ; i < hdev->asic_prop.completion_queues_count ; i++) destroy_workqueue(hdev->cq_wq[i]); @@ -412,7 +459,7 @@ static void hl_device_heartbeat(struct work_struct *work) struct hl_device *hdev = container_of(work, struct hl_device, work_heartbeat.work); - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) goto reschedule; if (!hdev->asic_funcs->send_heartbeat(hdev)) @@ -758,16 +805,12 @@ disable_device: return rc; } -static int device_kill_open_processes(struct hl_device *hdev) +static int device_kill_open_processes(struct hl_device *hdev, u32 timeout) { - u16 pending_total, pending_cnt; struct hl_fpriv *hpriv; struct task_struct *task = NULL; + u32 pending_cnt; - if (hdev->pldm) - pending_total = HL_PLDM_PENDING_RESET_PER_SEC; - else - pending_total = HL_PENDING_RESET_PER_SEC; /* Giving time for user to close FD, and for processes that are inside * hl_device_open to finish @@ -775,6 +818,19 @@ static int device_kill_open_processes(struct hl_device *hdev) if (!list_empty(&hdev->fpriv_list)) ssleep(1); + if (timeout) { + pending_cnt = timeout; + } else { + if (hdev->process_kill_trial_cnt) { + /* Processes have been already killed */ + pending_cnt = 1; + goto wait_for_processes; + } else { + /* Wait a small period after process kill */ + pending_cnt = HL_PENDING_RESET_PER_SEC; + } + } + mutex_lock(&hdev->fpriv_list_lock); /* This section must be protected because we are dereferencing @@ -794,16 +850,18 @@ static int device_kill_open_processes(struct hl_device *hdev) mutex_unlock(&hdev->fpriv_list_lock); - /* We killed the open users, but because the driver cleans up after the - * user contexts are closed (e.g. mmu mappings), we need to wait again - * to make sure the cleaning phase is finished before continuing with - * the reset + /* + * We killed the open users, but that doesn't mean they are closed. + * It could be that they are running a long cleanup phase in the driver + * e.g. MMU unmappings, or running other long teardown flow even before + * our cleanup. + * Therefore we need to wait again to make sure they are closed before + * continuing with the reset. */ - pending_cnt = pending_total; - +wait_for_processes: while ((!list_empty(&hdev->fpriv_list)) && (pending_cnt)) { - dev_info(hdev->dev, + dev_dbg(hdev->dev, "Waiting for all unmap operations to finish before hard reset\n"); pending_cnt--; @@ -811,18 +869,17 @@ static int device_kill_open_processes(struct hl_device *hdev) ssleep(1); } - return list_empty(&hdev->fpriv_list) ? 0 : -EBUSY; -} + /* All processes exited successfully */ + if (list_empty(&hdev->fpriv_list)) + return 0; -static void device_hard_reset_pending(struct work_struct *work) -{ - struct hl_device_reset_work *device_reset_work = - container_of(work, struct hl_device_reset_work, reset_work); - struct hl_device *hdev = device_reset_work->hdev; + /* Give up waiting for processes to exit */ + if (hdev->process_kill_trial_cnt == HL_PENDING_RESET_MAX_TRIALS) + return -ETIME; - hl_device_reset(hdev, true, true); + hdev->process_kill_trial_cnt++; - kfree(device_reset_work); + return -EBUSY; } /* @@ -859,6 +916,10 @@ int hl_device_reset(struct hl_device *hdev, bool hard_reset, hard_reset = true; } + /* Re-entry of reset thread */ + if (from_hard_reset_thread && hdev->process_kill_trial_cnt) + goto kill_processes; + /* * Prevent concurrency in this function - only one reset should be * done at any given time. Only need to perform this if we didn't @@ -904,26 +965,17 @@ int hl_device_reset(struct hl_device *hdev, bool hard_reset, again: if ((hard_reset) && (!from_hard_reset_thread)) { - struct hl_device_reset_work *device_reset_work; - hdev->hard_reset_pending = true; - device_reset_work = kzalloc(sizeof(*device_reset_work), - GFP_ATOMIC); - if (!device_reset_work) { - rc = -ENOMEM; - goto out_err; - } + hdev->process_kill_trial_cnt = 0; /* * Because the reset function can't run from interrupt or * from heartbeat work, we need to call the reset function * from a dedicated work */ - INIT_WORK(&device_reset_work->reset_work, - device_hard_reset_pending); - device_reset_work->hdev = hdev; - schedule_work(&device_reset_work->reset_work); + queue_delayed_work(hdev->device_reset_work.wq, + &hdev->device_reset_work.reset_work, 0); return 0; } @@ -949,12 +1001,25 @@ again: /* Go over all the queues, release all CS and their jobs */ hl_cs_rollback_all(hdev); +kill_processes: if (hard_reset) { /* Kill processes here after CS rollback. This is because the * process can't really exit until all its CSs are done, which * is what we do in cs rollback */ - rc = device_kill_open_processes(hdev); + rc = device_kill_open_processes(hdev, 0); + + if (rc == -EBUSY) { + if (hdev->device_fini_pending) { + dev_crit(hdev->dev, + "Failed to kill all open processes, stopping hard reset\n"); + goto out_err; + } + + /* signal reset thread to reschedule */ + return rc; + } + if (rc) { dev_crit(hdev->dev, "Failed to kill all open processes, stopping hard reset\n"); @@ -1089,6 +1154,7 @@ again: } atomic_set(&hdev->in_reset, 0); + hdev->needs_reset = false; if (hard_reset) hdev->hard_reset_cnt++; @@ -1261,13 +1327,6 @@ int hl_device_init(struct hl_device *hdev, struct class *hclass) hl_debugfs_add_device(hdev); - if (hdev->asic_funcs->get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) { - dev_info(hdev->dev, - "H/W state is dirty, must reset before initializing\n"); - hdev->asic_funcs->halt_engines(hdev, true); - hdev->asic_funcs->hw_fini(hdev, true); - } - /* * From this point, in case of an error, add char devices and create * sysfs nodes as part of the error flow, to allow debugging. @@ -1371,9 +1430,9 @@ sw_fini: early_fini: device_early_fini(hdev); free_dev_ctrl: - kfree(hdev->dev_ctrl); + put_device(hdev->dev_ctrl); free_dev: - kfree(hdev->dev); + put_device(hdev->dev); out_disabled: hdev->disabled = true; if (add_cdev_sysfs_on_err) @@ -1398,11 +1457,14 @@ out_disabled: */ void hl_device_fini(struct hl_device *hdev) { - int i, rc; ktime_t timeout; + int i, rc; dev_info(hdev->dev, "Removing device\n"); + hdev->device_fini_pending = 1; + flush_delayed_work(&hdev->device_reset_work.reset_work); + /* * This function is competing with the reset function, so try to * take the reset atomic and if we are already in middle of reset, @@ -1458,7 +1520,11 @@ void hl_device_fini(struct hl_device *hdev) * can't really exit until all its CSs are done, which is what we * do in cs rollback */ - rc = device_kill_open_processes(hdev); + dev_info(hdev->dev, + "Waiting for all processes to exit (timeout of %u seconds)", + HL_PENDING_RESET_LONG_SEC); + + rc = device_kill_open_processes(hdev, HL_PENDING_RESET_LONG_SEC); if (rc) dev_crit(hdev->dev, "Failed to kill all open processes\n"); diff --git a/drivers/misc/habanalabs/common/firmware_if.c b/drivers/misc/habanalabs/common/firmware_if.c index cd41c7ceb0e7..0e1c629e9800 100644 --- a/drivers/misc/habanalabs/common/firmware_if.c +++ b/drivers/misc/habanalabs/common/firmware_if.c @@ -9,8 +9,6 @@ #include "../include/common/hl_boot_if.h" #include <linux/firmware.h> -#include <linux/genalloc.h> -#include <linux/io-64-nonatomic-lo-hi.h> #include <linux/slab.h> #define FW_FILE_MAX_SIZE 0x1400000 /* maximum size of 20MB */ @@ -20,16 +18,18 @@ * @hdev: pointer to hl_device structure. * @fw_name: the firmware image name * @dst: IO memory mapped address space to copy firmware to + * @src_offset: offset in src FW to copy from + * @size: amount of bytes to copy (0 to copy the whole binary) * * Copy fw code from firmware file to device memory. * * Return: 0 on success, non-zero for failure. */ int hl_fw_load_fw_to_device(struct hl_device *hdev, const char *fw_name, - void __iomem *dst) + void __iomem *dst, u32 src_offset, u32 size) { const struct firmware *fw; - const u64 *fw_data; + const void *fw_data; size_t fw_size; int rc; @@ -57,9 +57,20 @@ int hl_fw_load_fw_to_device(struct hl_device *hdev, const char *fw_name, goto out; } - fw_data = (const u64 *) fw->data; + if (size - src_offset > fw_size) { + dev_err(hdev->dev, + "size to copy(%u) and offset(%u) are invalid\n", + size, src_offset); + rc = -EINVAL; + goto out; + } + + if (size) + fw_size = size; + + fw_data = (const void *) fw->data; - memcpy_toio(dst, fw_data, fw_size); + memcpy_toio(dst, fw_data + src_offset, fw_size); out: release_firmware(fw); @@ -77,7 +88,7 @@ int hl_fw_send_pci_access_msg(struct hl_device *hdev, u32 opcode) } int hl_fw_send_cpu_message(struct hl_device *hdev, u32 hw_queue_id, u32 *msg, - u16 len, u32 timeout, long *result) + u16 len, u32 timeout, u64 *result) { struct cpucp_packet *pkt; dma_addr_t pkt_dma_addr; @@ -132,7 +143,7 @@ int hl_fw_send_cpu_message(struct hl_device *hdev, u32 hw_queue_id, u32 *msg, >> CPUCP_PKT_CTL_OPCODE_SHIFT); rc = -EIO; } else if (result) { - *result = (long) le64_to_cpu(pkt->result); + *result = le64_to_cpu(pkt->result); } out: @@ -146,7 +157,7 @@ out: int hl_fw_unmask_irq(struct hl_device *hdev, u16 event_type) { struct cpucp_packet pkt; - long result; + u64 result; int rc; memset(&pkt, 0, sizeof(pkt)); @@ -169,7 +180,7 @@ int hl_fw_unmask_irq_arr(struct hl_device *hdev, const u32 *irq_arr, { struct cpucp_unmask_irq_arr_packet *pkt; size_t total_pkt_size; - long result; + u64 result; int rc; total_pkt_size = sizeof(struct cpucp_unmask_irq_arr_packet) + @@ -208,7 +219,7 @@ int hl_fw_unmask_irq_arr(struct hl_device *hdev, const u32 *irq_arr, int hl_fw_test_cpu_queue(struct hl_device *hdev) { struct cpucp_packet test_pkt = {}; - long result; + u64 result; int rc; test_pkt.ctl = cpu_to_le32(CPUCP_PACKET_TEST << @@ -221,7 +232,7 @@ int hl_fw_test_cpu_queue(struct hl_device *hdev) if (!rc) { if (result != CPUCP_PACKET_FENCE_VAL) dev_err(hdev->dev, - "CPU queue test failed (0x%08lX)\n", result); + "CPU queue test failed (%#08llx)\n", result); } else { dev_err(hdev->dev, "CPU queue test failed, error %d\n", rc); } @@ -252,7 +263,7 @@ void hl_fw_cpu_accessible_dma_pool_free(struct hl_device *hdev, size_t size, int hl_fw_send_heartbeat(struct hl_device *hdev) { struct cpucp_packet hb_pkt = {}; - long result; + u64 result; int rc; hb_pkt.ctl = cpu_to_le32(CPUCP_PACKET_TEST << @@ -268,13 +279,14 @@ int hl_fw_send_heartbeat(struct hl_device *hdev) return rc; } -int hl_fw_cpucp_info_get(struct hl_device *hdev) +int hl_fw_cpucp_info_get(struct hl_device *hdev, + u32 cpu_security_boot_status_reg) { struct asic_fixed_properties *prop = &hdev->asic_prop; struct cpucp_packet pkt = {}; void *cpucp_info_cpu_addr; dma_addr_t cpucp_info_dma_addr; - long result; + u64 result; int rc; cpucp_info_cpu_addr = @@ -313,6 +325,11 @@ int hl_fw_cpucp_info_get(struct hl_device *hdev) goto out; } + /* Read FW application security bits again */ + if (hdev->asic_prop.fw_security_status_valid) + hdev->asic_prop.fw_app_security_map = + RREG32(cpu_security_boot_status_reg); + out: hdev->asic_funcs->cpu_accessible_dma_pool_free(hdev, sizeof(struct cpucp_info), cpucp_info_cpu_addr); @@ -325,7 +342,7 @@ int hl_fw_get_eeprom_data(struct hl_device *hdev, void *data, size_t max_size) struct cpucp_packet pkt = {}; void *eeprom_info_cpu_addr; dma_addr_t eeprom_info_dma_addr; - long result; + u64 result; int rc; eeprom_info_cpu_addr = @@ -368,7 +385,7 @@ int hl_fw_cpucp_pci_counters_get(struct hl_device *hdev, struct hl_info_pci_counters *counters) { struct cpucp_packet pkt = {}; - long result; + u64 result; int rc; pkt.ctl = cpu_to_le32(CPUCP_PACKET_PCIE_THROUGHPUT_GET << @@ -415,7 +432,7 @@ int hl_fw_cpucp_pci_counters_get(struct hl_device *hdev, int hl_fw_cpucp_total_energy_get(struct hl_device *hdev, u64 *total_energy) { struct cpucp_packet pkt = {}; - long result; + u64 result; int rc; pkt.ctl = cpu_to_le32(CPUCP_PACKET_TOTAL_ENERGY_GET << @@ -435,9 +452,36 @@ int hl_fw_cpucp_total_energy_get(struct hl_device *hdev, u64 *total_energy) return rc; } -static void fw_read_errors(struct hl_device *hdev, u32 boot_err0_reg) +int hl_fw_cpucp_pll_info_get(struct hl_device *hdev, u16 pll_index, + u16 *pll_freq_arr) { - u32 err_val; + struct cpucp_packet pkt; + u64 result; + int rc; + + memset(&pkt, 0, sizeof(pkt)); + + pkt.ctl = cpu_to_le32(CPUCP_PACKET_PLL_INFO_GET << + CPUCP_PKT_CTL_OPCODE_SHIFT); + pkt.pll_type = __cpu_to_le16(pll_index); + + rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), + HL_CPUCP_INFO_TIMEOUT_USEC, &result); + if (rc) + dev_err(hdev->dev, "Failed to read PLL info, error %d\n", rc); + + pll_freq_arr[0] = FIELD_GET(CPUCP_PKT_RES_PLL_OUT0_MASK, result); + pll_freq_arr[1] = FIELD_GET(CPUCP_PKT_RES_PLL_OUT1_MASK, result); + pll_freq_arr[2] = FIELD_GET(CPUCP_PKT_RES_PLL_OUT2_MASK, result); + pll_freq_arr[3] = FIELD_GET(CPUCP_PKT_RES_PLL_OUT3_MASK, result); + + return rc; +} + +static void fw_read_errors(struct hl_device *hdev, u32 boot_err0_reg, + u32 cpu_security_boot_status_reg) +{ + u32 err_val, security_val; /* Some of the firmware status codes are deprecated in newer f/w * versions. In those versions, the errors are reported @@ -472,6 +516,18 @@ static void fw_read_errors(struct hl_device *hdev, u32 boot_err0_reg) if (err_val & CPU_BOOT_ERR0_NIC_FW_FAIL) dev_err(hdev->dev, "Device boot error - NIC F/W initialization failed\n"); + if (err_val & CPU_BOOT_ERR0_SECURITY_NOT_RDY) + dev_warn(hdev->dev, + "Device boot warning - security not ready\n"); + if (err_val & CPU_BOOT_ERR0_SECURITY_FAIL) + dev_err(hdev->dev, "Device boot error - security failure\n"); + if (err_val & CPU_BOOT_ERR0_EFUSE_FAIL) + dev_err(hdev->dev, "Device boot error - eFuse failure\n"); + + security_val = RREG32(cpu_security_boot_status_reg); + if (security_val & CPU_BOOT_DEV_STS0_ENABLED) + dev_dbg(hdev->dev, "Device security status %#x\n", + security_val); } static void detect_cpu_boot_status(struct hl_device *hdev, u32 status) @@ -524,10 +580,12 @@ static void detect_cpu_boot_status(struct hl_device *hdev, u32 status) } } -int hl_fw_read_preboot_ver(struct hl_device *hdev, u32 cpu_boot_status_reg, - u32 boot_err0_reg, u32 timeout) +int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg, + u32 cpu_security_boot_status_reg, u32 boot_err0_reg, + u32 timeout) { - u32 status; + struct asic_fixed_properties *prop = &hdev->asic_prop; + u32 status, security_status; int rc; if (!hdev->cpu_enable) @@ -557,23 +615,52 @@ int hl_fw_read_preboot_ver(struct hl_device *hdev, u32 cpu_boot_status_reg, if (rc) { dev_err(hdev->dev, "Failed to read preboot version\n"); detect_cpu_boot_status(hdev, status); - fw_read_errors(hdev, boot_err0_reg); + fw_read_errors(hdev, boot_err0_reg, + cpu_security_boot_status_reg); return -EIO; } - hdev->asic_funcs->read_device_fw_version(hdev, FW_COMP_PREBOOT); + rc = hdev->asic_funcs->read_device_fw_version(hdev, FW_COMP_PREBOOT); + if (rc) + return rc; + + security_status = RREG32(cpu_security_boot_status_reg); + + /* We read security status multiple times during boot: + * 1. preboot - we check if fw security feature is supported + * 2. boot cpu - we get boot cpu security status + * 3. FW application - we get FW application security status + * + * Preboot: + * Check security status bit (CPU_BOOT_DEV_STS0_ENABLED), if it is set + * check security enabled bit (CPU_BOOT_DEV_STS0_SECURITY_EN) + */ + if (security_status & CPU_BOOT_DEV_STS0_ENABLED) { + hdev->asic_prop.fw_security_status_valid = 1; + prop->fw_security_disabled = + !(security_status & CPU_BOOT_DEV_STS0_SECURITY_EN); + } else { + hdev->asic_prop.fw_security_status_valid = 0; + prop->fw_security_disabled = true; + } + + dev_info(hdev->dev, "firmware-level security is %s\n", + prop->fw_security_disabled ? "disabled" : "enabled"); return 0; } int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg, u32 msg_to_cpu_reg, u32 cpu_msg_status_reg, - u32 boot_err0_reg, bool skip_bmc, - u32 cpu_timeout, u32 boot_fit_timeout) + u32 cpu_security_boot_status_reg, u32 boot_err0_reg, + bool skip_bmc, u32 cpu_timeout, u32 boot_fit_timeout) { u32 status; int rc; + if (!(hdev->fw_loading & FW_TYPE_BOOT_CPU)) + return 0; + dev_info(hdev->dev, "Going to wait for device boot (up to %lds)\n", cpu_timeout / USEC_PER_SEC); @@ -631,17 +718,24 @@ int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg, 10000, cpu_timeout); + dev_dbg(hdev->dev, "uboot status = %d\n", status); + /* Read U-Boot version now in case we will later fail */ hdev->asic_funcs->read_device_fw_version(hdev, FW_COMP_UBOOT); + /* Read boot_cpu security bits */ + if (hdev->asic_prop.fw_security_status_valid) + hdev->asic_prop.fw_boot_cpu_security_map = + RREG32(cpu_security_boot_status_reg); + if (rc) { detect_cpu_boot_status(hdev, status); rc = -EIO; goto out; } - if (!hdev->fw_loading) { - dev_info(hdev->dev, "Skip loading FW\n"); + if (!(hdev->fw_loading & FW_TYPE_LINUX)) { + dev_info(hdev->dev, "Skip loading Linux F/W\n"); goto out; } @@ -702,10 +796,23 @@ int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg, goto out; } + /* Read FW application security bits */ + if (hdev->asic_prop.fw_security_status_valid) { + hdev->asic_prop.fw_app_security_map = + RREG32(cpu_security_boot_status_reg); + + if (hdev->asic_prop.fw_app_security_map & + CPU_BOOT_DEV_STS0_FW_HARD_RST_EN) + hdev->asic_prop.hard_reset_done_by_fw = true; + } + + dev_dbg(hdev->dev, "Firmware hard-reset is %s\n", + hdev->asic_prop.hard_reset_done_by_fw ? "enabled" : "disabled"); + dev_info(hdev->dev, "Successfully loaded firmware to device\n"); out: - fw_read_errors(hdev, boot_err0_reg); + fw_read_errors(hdev, boot_err0_reg, cpu_security_boot_status_reg); return rc; } diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 80d4d7385ffe..571eda6ef5ab 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -10,6 +10,7 @@ #include "../include/common/cpucp_if.h" #include "../include/common/qman_if.h" +#include "../include/hw_ip/mmu/mmu_general.h" #include <uapi/misc/habanalabs.h> #include <linux/cdev.h> @@ -19,6 +20,10 @@ #include <linux/scatterlist.h> #include <linux/hashtable.h> #include <linux/bitfield.h> +#include <linux/genalloc.h> +#include <linux/sched/signal.h> +#include <linux/io-64-nonatomic-lo-hi.h> +#include <linux/coresight.h> #define HL_NAME "habanalabs" @@ -36,7 +41,9 @@ #define HL_MMAP_OFFSET_VALUE_MASK (0x3FFFFFFFFFFFull >> PAGE_SHIFT) #define HL_MMAP_OFFSET_VALUE_GET(off) (off & HL_MMAP_OFFSET_VALUE_MASK) -#define HL_PENDING_RESET_PER_SEC 30 +#define HL_PENDING_RESET_PER_SEC 10 +#define HL_PENDING_RESET_MAX_TRIALS 60 /* 10 minutes */ +#define HL_PENDING_RESET_LONG_SEC 60 #define HL_HARD_RESET_MAX_TIMEOUT 120 @@ -61,15 +68,29 @@ /* MMU */ #define MMU_HASH_TABLE_BITS 7 /* 1 << 7 buckets */ +/** + * enum hl_mmu_page_table_locaion - mmu page table location + * @MMU_DR_PGT: page-table is located on device DRAM. + * @MMU_HR_PGT: page-table is located on host memory. + * @MMU_NUM_PGT_LOCATIONS: number of page-table locations currently supported. + */ +enum hl_mmu_page_table_location { + MMU_DR_PGT = 0, /* device-dram-resident MMU PGT */ + MMU_HR_PGT, /* host resident MMU PGT */ + MMU_NUM_PGT_LOCATIONS /* num of PGT locations */ +}; + /* * HL_RSVD_SOBS 'sync stream' reserved sync objects per QMAN stream * HL_RSVD_MONS 'sync stream' reserved monitors per QMAN stream */ -#define HL_RSVD_SOBS 4 -#define HL_RSVD_MONS 2 +#define HL_RSVD_SOBS 2 +#define HL_RSVD_MONS 1 -#define HL_RSVD_SOBS_IN_USE 2 -#define HL_RSVD_MONS_IN_USE 1 +/* + * HL_COLLECTIVE_RSVD_MSTR_MONS 'collective' reserved monitors per QMAN stream + */ +#define HL_COLLECTIVE_RSVD_MSTR_MONS 2 #define HL_MAX_SOB_VAL (1 << 15) @@ -80,6 +101,28 @@ #define HL_MAX_DCORES 4 +#define HL_MAX_SOBS_PER_MONITOR 8 + +/** + * struct hl_gen_wait_properties - properties for generating a wait CB + * @data: command buffer + * @q_idx: queue id is used to extract fence register address + * @size: offset in command buffer + * @sob_base: SOB base to use in this wait CB + * @sob_val: SOB value to wait for + * @mon_id: monitor to use in this wait CB + * @sob_mask: each bit represents a SOB offset from sob_base to be used + */ +struct hl_gen_wait_properties { + void *data; + u32 q_idx; + u32 size; + u16 sob_base; + u16 sob_val; + u16 mon_id; + u8 sob_mask; +}; + /** * struct pgt_info - MMU hop page info. * @node: hash linked-list node for the pgts shadow hash of pgts. @@ -125,6 +168,18 @@ enum hl_fw_component { }; /** + * enum hl_fw_types - F/W types to load + * @FW_TYPE_LINUX: Linux image for device CPU + * @FW_TYPE_BOOT_CPU: Boot image for device CPU + * @FW_TYPE_ALL_TYPES: Mask for all types + */ +enum hl_fw_types { + FW_TYPE_LINUX = 0x1, + FW_TYPE_BOOT_CPU = 0x2, + FW_TYPE_ALL_TYPES = (FW_TYPE_LINUX | FW_TYPE_BOOT_CPU) +}; + +/** * enum hl_queue_type - Supported QUEUE types. * @QUEUE_TYPE_NA: queue is not available. * @QUEUE_TYPE_EXT: external queue which is a DMA channel that may access the @@ -146,7 +201,8 @@ enum hl_queue_type { enum hl_cs_type { CS_TYPE_DEFAULT, CS_TYPE_SIGNAL, - CS_TYPE_WAIT + CS_TYPE_WAIT, + CS_TYPE_COLLECTIVE_WAIT }; /* @@ -176,6 +232,17 @@ struct hl_outbound_pci_region { }; /* + * enum queue_cb_alloc_flags - Indicates queue support for CBs that + * allocated by Kernel or by User + * @CB_ALLOC_KERNEL: support only CBs that allocated by Kernel + * @CB_ALLOC_USER: support only CBs that allocated by User + */ +enum queue_cb_alloc_flags { + CB_ALLOC_KERNEL = 0x1, + CB_ALLOC_USER = 0x2 +}; + +/* * struct hl_hw_sob - H/W SOB info. * @hdev: habanalabs device structure. * @kref: refcount of this SOB. The SOB will reset once the refcount is zero. @@ -189,19 +256,29 @@ struct hl_hw_sob { u32 q_idx; }; +enum hl_collective_mode { + HL_COLLECTIVE_NOT_SUPPORTED = 0x0, + HL_COLLECTIVE_MASTER = 0x1, + HL_COLLECTIVE_SLAVE = 0x2 +}; + /** * struct hw_queue_properties - queue information. * @type: queue type. + * @queue_cb_alloc_flags: bitmap which indicates if the hw queue supports CB + * that allocated by the Kernel driver and therefore, + * a CB handle can be provided for jobs on this queue. + * Otherwise, a CB address must be provided. + * @collective_mode: collective mode of current queue * @driver_only: true if only the driver is allowed to send a job to this queue, * false otherwise. - * @requires_kernel_cb: true if a CB handle must be provided for jobs on this - * queue, false otherwise (a CB address must be provided). * @supports_sync_stream: True if queue supports sync stream */ struct hw_queue_properties { enum hl_queue_type type; + enum queue_cb_alloc_flags cb_alloc_flags; + enum hl_collective_mode collective_mode; u8 driver_only; - u8 requires_kernel_cb; u8 supports_sync_stream; }; @@ -227,6 +304,8 @@ enum hl_device_hw_state { HL_DEVICE_HW_STATE_DIRTY }; +#define HL_MMU_VA_ALIGNMENT_NOT_NEEDED 0 + /** * struct hl_mmu_properties - ASIC specific MMU address translation properties. * @start_addr: virtual start address of the memory region. @@ -245,6 +324,8 @@ enum hl_device_hw_state { * @hop5_mask: mask to get the PTE address in hop 5. * @page_size: default page size used to allocate memory. * @num_hops: The amount of hops supported by the translation table. + * @host_resident: Should the MMU page table reside in host memory or in the + * device DRAM. */ struct hl_mmu_properties { u64 start_addr; @@ -263,6 +344,7 @@ struct hl_mmu_properties { u64 hop5_mask; u32 page_size; u32 num_hops; + u8 host_resident; }; /** @@ -314,6 +396,14 @@ struct hl_mmu_properties { * @cb_pool_cb_size: size of each CB in the CB pool. * @max_pending_cs: maximum of concurrent pending command submissions * @max_queues: maximum amount of queues in the system + * @fw_boot_cpu_security_map: bitmap representation of boot cpu security status + * reported by FW, bit description can be found in + * CPU_BOOT_DEV_STS* + * @fw_app_security_map: bitmap representation of application security status + * reported by FW, bit description can be found in + * CPU_BOOT_DEV_STS* + * @collective_first_sob: first sync object available for collective use + * @collective_first_mon: first monitor available for collective use * @sync_stream_first_sob: first sync object available for sync stream use * @sync_stream_first_mon: first monitor available for sync stream use * @first_available_user_sob: first sob available for the user @@ -322,6 +412,10 @@ struct hl_mmu_properties { * @completion_queues_count: number of completion queues. * @fw_security_disabled: true if security measures are disabled in firmware, * false otherwise + * @fw_security_status_valid: security status bits are valid and can be fetched + * from BOOT_DEV_STS0 + * @dram_supports_virtual_memory: is there an MMU towards the DRAM + * @hard_reset_done_by_fw: true if firmware is handling hard reset flow */ struct asic_fixed_properties { struct hw_queue_properties *hw_queues_props; @@ -366,6 +460,10 @@ struct asic_fixed_properties { u32 cb_pool_cb_size; u32 max_pending_cs; u32 max_queues; + u32 fw_boot_cpu_security_map; + u32 fw_app_security_map; + u16 collective_first_sob; + u16 collective_first_mon; u16 sync_stream_first_sob; u16 sync_stream_first_mon; u16 first_available_user_sob[HL_MAX_DCORES]; @@ -373,6 +471,9 @@ struct asic_fixed_properties { u8 tpc_enabled_mask; u8 completion_queues_count; u8 fw_security_disabled; + u8 fw_security_status_valid; + u8 dram_supports_virtual_memory; + u8 hard_reset_done_by_fw; }; /** @@ -380,12 +481,14 @@ struct asic_fixed_properties { * @completion: fence is implemented using completion * @refcount: refcount for this fence * @error: mark this fence with error + * @timestamp: timestamp upon completion * */ struct hl_fence { struct completion completion; struct kref refcount; int error; + ktime_t timestamp; }; /** @@ -397,6 +500,7 @@ struct hl_fence { * @cs_seq: command submission sequence number. * @type: type of the CS - signal/wait. * @sob_val: the SOB value that is used in this signal/wait CS. + * @sob_group: the SOB group that is used in this collective wait CS. */ struct hl_cs_compl { struct hl_fence base_fence; @@ -406,6 +510,7 @@ struct hl_cs_compl { u64 cs_seq; enum hl_cs_type type; u16 sob_val; + u16 sob_group; }; /* @@ -427,7 +532,7 @@ struct hl_cb_mgr { * @refcount: reference counter for usage of the CB. * @hdev: pointer to device this CB belongs to. * @ctx: pointer to the CB owner's context. - * @lock: spinlock to protect mmap/cs flows. + * @lock: spinlock to protect mmap flows. * @debugfs_list: node in debugfs list of command buffers. * @pool_list: node in pool list of command buffers. * @va_block_list: list of virtual addresses blocks of the CB if it is mapped to @@ -452,11 +557,11 @@ struct hl_cb { struct list_head pool_list; struct list_head va_block_list; u64 id; - u64 kernel_address; + void *kernel_address; dma_addr_t bus_address; u32 mmap_size; u32 size; - u32 cs_cnt; + atomic_t cs_cnt; u8 mmap; u8 is_pool; u8 is_internal; @@ -468,6 +573,7 @@ struct hl_cb { * QUEUES */ +struct hl_cs; struct hl_cs_job; /* Queue length of external and HW queues */ @@ -490,10 +596,38 @@ struct hl_cs_job; #define HL_CPU_ACCESSIBLE_MEM_SIZE SZ_2M /** - * struct hl_hw_queue - describes a H/W transport queue. + * struct hl_sync_stream_properties - + * describes a H/W queue sync stream properties * @hw_sob: array of the used H/W SOBs by this H/W queue. + * @next_sob_val: the next value to use for the currently used SOB. + * @base_sob_id: the base SOB id of the SOBs used by this queue. + * @base_mon_id: the base MON id of the MONs used by this queue. + * @collective_mstr_mon_id: the MON ids of the MONs used by this master queue + * in order to sync with all slave queues. + * @collective_slave_mon_id: the MON id used by this slave queue in order to + * sync with its master queue. + * @collective_sob_id: current SOB id used by this collective slave queue + * to signal its collective master queue upon completion. + * @curr_sob_offset: the id offset to the currently used SOB from the + * HL_RSVD_SOBS that are being used by this queue. + */ +struct hl_sync_stream_properties { + struct hl_hw_sob hw_sob[HL_RSVD_SOBS]; + u16 next_sob_val; + u16 base_sob_id; + u16 base_mon_id; + u16 collective_mstr_mon_id[HL_COLLECTIVE_RSVD_MSTR_MONS]; + u16 collective_slave_mon_id; + u16 collective_sob_id; + u8 curr_sob_offset; +}; + +/** + * struct hl_hw_queue - describes a H/W transport queue. * @shadow_queue: pointer to a shadow queue that holds pointers to jobs. + * @sync_stream_prop: sync stream queue properties * @queue_type: type of queue. + * @collective_mode: collective mode of current queue * @kernel_address: holds the queue's kernel virtual address. * @bus_address: holds the queue's DMA address. * @pi: holds the queue's pi value. @@ -502,33 +636,25 @@ struct hl_cs_job; * @cq_id: the id for the corresponding CQ for this H/W queue. * @msi_vec: the IRQ number of the H/W queue. * @int_queue_len: length of internal queue (number of entries). - * @next_sob_val: the next value to use for the currently used SOB. - * @base_sob_id: the base SOB id of the SOBs used by this queue. - * @base_mon_id: the base MON id of the MONs used by this queue. * @valid: is the queue valid (we have array of 32 queues, not all of them * exist). - * @curr_sob_offset: the id offset to the currently used SOB from the - * HL_RSVD_SOBS that are being used by this queue. * @supports_sync_stream: True if queue supports sync stream */ struct hl_hw_queue { - struct hl_hw_sob hw_sob[HL_RSVD_SOBS]; - struct hl_cs_job **shadow_queue; - enum hl_queue_type queue_type; - u64 kernel_address; - dma_addr_t bus_address; - u32 pi; - atomic_t ci; - u32 hw_queue_id; - u32 cq_id; - u32 msi_vec; - u16 int_queue_len; - u16 next_sob_val; - u16 base_sob_id; - u16 base_mon_id; - u8 valid; - u8 curr_sob_offset; - u8 supports_sync_stream; + struct hl_cs_job **shadow_queue; + struct hl_sync_stream_properties sync_stream_prop; + enum hl_queue_type queue_type; + enum hl_collective_mode collective_mode; + void *kernel_address; + dma_addr_t bus_address; + u32 pi; + atomic_t ci; + u32 hw_queue_id; + u32 cq_id; + u32 msi_vec; + u16 int_queue_len; + u8 valid; + u8 supports_sync_stream; }; /** @@ -544,7 +670,7 @@ struct hl_hw_queue { */ struct hl_cq { struct hl_device *hdev; - u64 kernel_address; + void *kernel_address; dma_addr_t bus_address; u32 cq_idx; u32 hw_queue_id; @@ -562,7 +688,7 @@ struct hl_cq { */ struct hl_eq { struct hl_device *hdev; - u64 kernel_address; + void *kernel_address; dma_addr_t bus_address; u32 ci; }; @@ -650,6 +776,7 @@ enum div_select_defs { * dma_free_coherent(). This is ASIC function because * its implementation is not trivial when the driver * is loaded in simulation mode (not upstreamed). + * @scrub_device_mem: Scrub device memory given an address and size * @get_int_queue_base: get the internal queue base address. * @test_queues: run simple test on all queues for sanity check. * @asic_dma_pool_zalloc: small DMA allocation of coherent memory from DMA pool. @@ -700,6 +827,7 @@ enum div_select_defs { * @wreg: Write a register. Needed for simulator support. * @halt_coresight: stop the ETF and ETR traces. * @ctx_init: context dependent initialization. + * @ctx_fini: context dependent cleanup. * @get_clk_rate: Retrieve the ASIC current and maximum clock rate in MHz * @get_queue_id_for_cq: Get the H/W queue id related to the given CQ index. * @read_device_fw_version: read the device's firmware versions that are @@ -711,9 +839,13 @@ enum div_select_defs { * @gen_signal_cb: Generate a signal CB. * @gen_wait_cb: Generate a wait CB. * @reset_sob: Reset a SOB. + * @reset_sob_group: Reset SOB group * @set_dma_mask_from_fw: set the DMA mask in the driver according to the * firmware configuration * @get_device_time: Get the device time. + * @collective_wait_init_cs: Generate collective master/slave packets + * and place them in the relevant cs jobs + * @collective_wait_create_jobs: allocate collective wait cs jobs */ struct hl_asic_funcs { int (*early_init)(struct hl_device *hdev); @@ -736,6 +868,7 @@ struct hl_asic_funcs { dma_addr_t *dma_handle, gfp_t flag); void (*asic_dma_free_coherent)(struct hl_device *hdev, size_t size, void *cpu_addr, dma_addr_t dma_handle); + int (*scrub_device_mem)(struct hl_device *hdev, u64 addr, u64 size); void* (*get_int_queue_base)(struct hl_device *hdev, u32 queue_id, dma_addr_t *dma_handle, u16 *queue_len); int (*test_queues)(struct hl_device *hdev); @@ -757,7 +890,7 @@ struct hl_asic_funcs { u32 (*get_dma_desc_list_size)(struct hl_device *hdev, struct sg_table *sgt); void (*add_end_of_cb_packets)(struct hl_device *hdev, - u64 kernel_address, u32 len, + void *kernel_address, u32 len, u64 cq_addr, u32 cq_val, u32 msix_num, bool eb); void (*update_eq_ci)(struct hl_device *hdev, u32 val); @@ -794,28 +927,34 @@ struct hl_asic_funcs { int (*get_eeprom_data)(struct hl_device *hdev, void *data, size_t max_size); int (*send_cpu_message)(struct hl_device *hdev, u32 *msg, - u16 len, u32 timeout, long *result); - enum hl_device_hw_state (*get_hw_state)(struct hl_device *hdev); + u16 len, u32 timeout, u64 *result); int (*pci_bars_map)(struct hl_device *hdev); int (*init_iatu)(struct hl_device *hdev); u32 (*rreg)(struct hl_device *hdev, u32 reg); void (*wreg)(struct hl_device *hdev, u32 reg, u32 val); void (*halt_coresight)(struct hl_device *hdev); int (*ctx_init)(struct hl_ctx *ctx); + void (*ctx_fini)(struct hl_ctx *ctx); int (*get_clk_rate)(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk); u32 (*get_queue_id_for_cq)(struct hl_device *hdev, u32 cq_idx); - void (*read_device_fw_version)(struct hl_device *hdev, + int (*read_device_fw_version)(struct hl_device *hdev, enum hl_fw_component fwc); int (*load_firmware_to_device)(struct hl_device *hdev); int (*load_boot_fit_to_device)(struct hl_device *hdev); u32 (*get_signal_cb_size)(struct hl_device *hdev); u32 (*get_wait_cb_size)(struct hl_device *hdev); - void (*gen_signal_cb)(struct hl_device *hdev, void *data, u16 sob_id); - void (*gen_wait_cb)(struct hl_device *hdev, void *data, u16 sob_id, - u16 sob_val, u16 mon_id, u32 q_idx); + u32 (*gen_signal_cb)(struct hl_device *hdev, void *data, u16 sob_id, + u32 size); + u32 (*gen_wait_cb)(struct hl_device *hdev, + struct hl_gen_wait_properties *prop); void (*reset_sob)(struct hl_device *hdev, void *data); + void (*reset_sob_group)(struct hl_device *hdev, u16 sob_group); void (*set_dma_mask_from_fw)(struct hl_device *hdev); u64 (*get_device_time)(struct hl_device *hdev); + void (*collective_wait_init_cs)(struct hl_cs *cs); + int (*collective_wait_create_jobs)(struct hl_device *hdev, + struct hl_ctx *ctx, struct hl_cs *cs, u32 wait_queue_id, + u32 collective_engine_id); }; @@ -826,17 +965,48 @@ struct hl_asic_funcs { #define HL_KERNEL_ASID_ID 0 /** + * enum hl_va_range_type - virtual address range type. + * @HL_VA_RANGE_TYPE_HOST: range type of host pages + * @HL_VA_RANGE_TYPE_HOST_HUGE: range type of host huge pages + * @HL_VA_RANGE_TYPE_DRAM: range type of dram pages + */ +enum hl_va_range_type { + HL_VA_RANGE_TYPE_HOST, + HL_VA_RANGE_TYPE_HOST_HUGE, + HL_VA_RANGE_TYPE_DRAM, + HL_VA_RANGE_TYPE_MAX +}; + +/** * struct hl_va_range - virtual addresses range. * @lock: protects the virtual addresses list. * @list: list of virtual addresses blocks available for mappings. * @start_addr: range start address. * @end_addr: range end address. + * @page_size: page size of this va range. */ struct hl_va_range { struct mutex lock; struct list_head list; u64 start_addr; u64 end_addr; + u32 page_size; +}; + +/** + * struct hl_cs_counters_atomic - command submission counters + * @out_of_mem_drop_cnt: dropped due to memory allocation issue + * @parsing_drop_cnt: dropped due to error in packet parsing + * @queue_full_drop_cnt: dropped due to queue full + * @device_in_reset_drop_cnt: dropped due to device in reset + * @max_cs_in_flight_drop_cnt: dropped due to maximum CS in-flight + */ +struct hl_cs_counters_atomic { + atomic64_t out_of_mem_drop_cnt; + atomic64_t parsing_drop_cnt; + atomic64_t queue_full_drop_cnt; + atomic64_t device_in_reset_drop_cnt; + atomic64_t max_cs_in_flight_drop_cnt; }; /** @@ -849,14 +1019,12 @@ struct hl_va_range { * @refcount: reference counter for the context. Context is released only when * this hits 0l. It is incremented on CS and CS_WAIT. * @cs_pending: array of hl fence objects representing pending CS. - * @host_va_range: holds available virtual addresses for host mappings. - * @host_huge_va_range: holds available virtual addresses for host mappings - * with huge pages. - * @dram_va_range: holds available virtual addresses for DRAM mappings. + * @va_range: holds available virtual addresses for host and dram mappings. * @mem_hash_lock: protects the mem_hash. * @mmu_lock: protects the MMU page tables. Any change to the PGT, modifying the * MMU hash or walking the PGT requires talking this lock. * @debugfs_list: node in debugfs list of contexts. + * @cs_counters: context command submission counters. * @cb_va_pool: device VA pool for command buffers which are mapped to the * device's MMU. * @cs_sequence: sequence number for CS. Value is assigned to a CS and passed @@ -879,26 +1047,24 @@ struct hl_va_range { struct hl_ctx { DECLARE_HASHTABLE(mem_hash, MEM_HASH_TABLE_BITS); DECLARE_HASHTABLE(mmu_shadow_hash, MMU_HASH_TABLE_BITS); - struct hl_fpriv *hpriv; - struct hl_device *hdev; - struct kref refcount; - struct hl_fence **cs_pending; - struct hl_va_range *host_va_range; - struct hl_va_range *host_huge_va_range; - struct hl_va_range *dram_va_range; - struct mutex mem_hash_lock; - struct mutex mmu_lock; - struct list_head debugfs_list; - struct hl_cs_counters cs_counters; - struct gen_pool *cb_va_pool; - u64 cs_sequence; - u64 *dram_default_hops; - spinlock_t cs_lock; - atomic64_t dram_phys_mem; - atomic_t thread_ctx_switch_token; - u32 thread_ctx_switch_wait_token; - u32 asid; - u32 handle; + struct hl_fpriv *hpriv; + struct hl_device *hdev; + struct kref refcount; + struct hl_fence **cs_pending; + struct hl_va_range *va_range[HL_VA_RANGE_TYPE_MAX]; + struct mutex mem_hash_lock; + struct mutex mmu_lock; + struct list_head debugfs_list; + struct hl_cs_counters_atomic cs_counters; + struct gen_pool *cb_va_pool; + u64 cs_sequence; + u64 *dram_default_hops; + spinlock_t cs_lock; + atomic64_t dram_phys_mem; + atomic_t thread_ctx_switch_token; + u32 thread_ctx_switch_wait_token; + u32 asid; + u32 handle; }; /** @@ -963,6 +1129,7 @@ struct hl_userptr { * @tdr_active: true if TDR was activated for this CS (to prevent * double TDR activation). * @aborted: true if CS was aborted due to some device error. + * @timestamp: true if a timestmap must be captured upon completion */ struct hl_cs { u16 *jobs_in_queue_cnt; @@ -983,6 +1150,7 @@ struct hl_cs { u8 timedout; u8 tdr_active; u8 aborted; + u8 timestamp; }; /** @@ -996,6 +1164,7 @@ struct hl_cs { * @userptr_list: linked-list of userptr mappings that belong to this job and * wait for completion. * @debugfs_list: node in debugfs list of command submission jobs. + * @refcount: reference counter for usage of the CS job. * @queue_type: the type of the H/W queue this job is submitted to. * @id: the id of this job inside a CS. * @hw_queue_id: the id of the H/W queue this job is submitted to. @@ -1019,6 +1188,7 @@ struct hl_cs_job { struct work_struct finish_work; struct list_head userptr_list; struct list_head debugfs_list; + struct kref refcount; enum hl_queue_type queue_type; u32 id; u32 hw_queue_id; @@ -1067,7 +1237,6 @@ struct hl_cs_parser { u8 contains_dma_pkt; }; - /* * MEMORY STRUCTURE */ @@ -1285,6 +1454,10 @@ struct hl_dbg_device_entry { * DEVICES */ +#define HL_STR_MAX 32 + +#define HL_DEV_STS_MAX (HL_DEVICE_STATUS_NEEDS_RESET + 1) + /* Theoretical limit only. A single host can only contain up to 4 or 8 PCIe * x16 cards. In extreme cases, there are hosts that can accommodate 16 cards. */ @@ -1382,13 +1555,13 @@ void hl_wreg(struct hl_device *hdev, u32 reg, u32 val); for (;;) { \ /* Verify we read updates done by other cores or by device */ \ mb(); \ - (val) = *((u32 *) (uintptr_t) (addr)); \ + (val) = *((u32 *)(addr)); \ if (mem_written_by_device) \ (val) = le32_to_cpu(*(__le32 *) &(val)); \ if (cond) \ break; \ if (timeout_us && ktime_compare(ktime_get(), __timeout) > 0) { \ - (val) = *((u32 *) (uintptr_t) (addr)); \ + (val) = *((u32 *)(addr)); \ if (mem_written_by_device) \ (val) = le32_to_cpu(*(__le32 *) &(val)); \ break; \ @@ -1428,11 +1601,13 @@ struct hwmon_chip_info; /** * struct hl_device_reset_work - reset workqueue task wrapper. + * @wq: work queue for device reset procedure. * @reset_work: reset work to be done. * @hdev: habanalabs device structure. */ struct hl_device_reset_work { - struct work_struct reset_work; + struct workqueue_struct *wq; + struct delayed_work reset_work; struct hl_device *hdev; }; @@ -1446,18 +1621,78 @@ struct hl_device_idle_busy_ts { ktime_t busy_to_idle_ts; }; +/** + * struct hr_mmu_hop_addrs - used for holding per-device host-resident mmu hop + * information. + * @virt_addr: the virtual address of the hop. + * @phys-addr: the physical address of the hop (used by the device-mmu). + * @shadow_addr: The shadow of the hop used by the driver for walking the hops. + */ +struct hr_mmu_hop_addrs { + u64 virt_addr; + u64 phys_addr; + u64 shadow_addr; +}; /** - * struct hl_mmu_priv - used for holding per-device mmu internal information. + * struct hl_mmu_hr_pgt_priv - used for holding per-device mmu host-resident + * page-table internal information. * @mmu_pgt_pool: pool of page tables used by MMU for allocating hops. * @mmu_shadow_hop0: shadow array of hop0 tables. */ -struct hl_mmu_priv { +struct hl_mmu_hr_priv { + struct gen_pool *mmu_pgt_pool; + struct hr_mmu_hop_addrs *mmu_shadow_hop0; +}; + +/** + * struct hl_mmu_dr_pgt_priv - used for holding per-device mmu device-resident + * page-table internal information. + * @mmu_pgt_pool: pool of page tables used by MMU for allocating hops. + * @mmu_shadow_hop0: shadow array of hop0 tables. + */ +struct hl_mmu_dr_priv { struct gen_pool *mmu_pgt_pool; void *mmu_shadow_hop0; }; /** + * struct hl_mmu_priv - used for holding per-device mmu internal information. + * @dr: information on the device-resident MMU, when exists. + * @hr: information on the host-resident MMU, when exists. + */ +struct hl_mmu_priv { + struct hl_mmu_dr_priv dr; + struct hl_mmu_hr_priv hr; +}; + +/** + * struct hl_mmu_per_hop_info - A structure describing one TLB HOP and its entry + * that was created in order to translate a virtual address to a + * physical one. + * @hop_addr: The address of the hop. + * @hop_pte_addr: The address of the hop entry. + * @hop_pte_val: The value in the hop entry. + */ +struct hl_mmu_per_hop_info { + u64 hop_addr; + u64 hop_pte_addr; + u64 hop_pte_val; +}; + +/** + * struct hl_mmu_hop_info - A structure describing the TLB hops and their + * hop-entries that were created in order to translate a virtual address to a + * physical one. + * @hop_info: Array holding the per-hop information used for the translation. + * @used_hops: The number of hops used for the translation. + */ +struct hl_mmu_hop_info { + struct hl_mmu_per_hop_info hop_info[MMU_ARCH_5_HOPS]; + u32 used_hops; +}; + +/** * struct hl_mmu_funcs - Device related MMU functions. * @init: initialize the MMU module. * @fini: release the MMU module. @@ -1468,6 +1703,9 @@ struct hl_mmu_priv { * @flush: flush all writes from all cores to reach device MMU. * @swap_out: marks all mapping of the given context as swapped out. * @swap_in: marks all mapping of the given context as swapped in. + * @get_tlb_info: returns the list of hops and hop-entries used that were + * created in order to translate the giver virtual address to a + * physical one. */ struct hl_mmu_funcs { int (*init)(struct hl_device *hdev); @@ -1482,6 +1720,8 @@ struct hl_mmu_funcs { void (*flush)(struct hl_ctx *ctx); void (*swap_out)(struct hl_ctx *ctx); void (*swap_in)(struct hl_ctx *ctx); + int (*get_tlb_info)(struct hl_ctx *ctx, + u64 virt_addr, struct hl_mmu_hop_info *hops); }; /** @@ -1497,6 +1737,7 @@ struct hl_mmu_funcs { * @dev_ctrl: related kernel device structure for the control device * @work_freq: delayed work to lower device frequency if possible. * @work_heartbeat: delayed work for CPU-CP is-alive check. + * @device_reset_work: delayed work which performs hard reset * @asic_name: ASIC specific name. * @asic_type: ASIC specific type. * @completion_queue: array of hl_cq. @@ -1505,8 +1746,8 @@ struct hl_mmu_funcs { * @eq_wq: work queue of event queue for executing work in process context. * @kernel_ctx: Kernel driver context structure. * @kernel_queues: array of hl_hw_queue. - * @hw_queues_mirror_list: CS mirror list for TDR. - * @hw_queues_mirror_lock: protects hw_queues_mirror_list. + * @cs_mirror_list: CS mirror list for TDR. + * @cs_mirror_lock: protects cs_mirror_list. * @kernel_cb_mgr: command buffer manager for creating/destroying/handling CGs. * @event_queue: event queue for IRQ from CPU-CP. * @dma_pool: DMA pool for small allocations. @@ -1525,6 +1766,7 @@ struct hl_mmu_funcs { * @hwmon_dev: H/W monitor device. * @pm_mng_profile: current power management profile. * @hl_chip_info: ASIC's sensors information. + * @device_status_description: device status description. * @hl_debugfs: device's debugfs manager. * @cb_pool: list of preallocated CBs. * @cb_pool_lock: protects the CB pool. @@ -1572,13 +1814,12 @@ struct hl_mmu_funcs { * @heartbeat: is heartbeat sanity check towards CPU-CP enabled. * @reset_on_lockup: true if a reset should be done in case of stuck CS, false * otherwise. - * @dram_supports_virtual_memory: is MMU enabled towards DRAM. * @dram_default_page_mapping: is DRAM default page mapping enabled. + * @memory_scrub: true to perform device memory scrub in various locations, + * such as context-switch, context close, page free, etc. * @pmmu_huge_range: is a different virtual addresses range used for PMMU with * huge pages. * @init_done: is the initialization of the device done. - * @mmu_enable: is MMU enabled. - * @mmu_huge_page_opt: is MMU huge pages optimization enabled. * @device_cpu_disabled: is the device CPU disabled (due to timeouts) * @dma_mask: the dma mask that was set for this device * @in_debug: is device under debug. This, together with fpriv_list, enforces @@ -1589,9 +1830,16 @@ struct hl_mmu_funcs { * @stop_on_err: true if engines should stop on error. * @supports_sync_stream: is sync stream supported. * @sync_stream_queue_idx: helper index for sync stream queues initialization. + * @collective_mon_idx: helper index for collective initialization * @supports_coresight: is CoreSight supported. * @supports_soft_reset: is soft reset supported. * @supports_cb_mapping: is mapping a CB to the device's MMU supported. + * @needs_reset: true if reset_on_lockup is false and device should be reset + * due to lockup. + * @process_kill_trial_cnt: number of trials reset thread tried killing + * user processes + * @device_fini_pending: true if device_fini was called and might be + * waiting for the reset thread to finish */ struct hl_device { struct pci_dev *pdev; @@ -1604,15 +1852,17 @@ struct hl_device { struct device *dev_ctrl; struct delayed_work work_freq; struct delayed_work work_heartbeat; - char asic_name[32]; + struct hl_device_reset_work device_reset_work; + char asic_name[HL_STR_MAX]; + char status[HL_DEV_STS_MAX][HL_STR_MAX]; enum hl_asic_type asic_type; struct hl_cq *completion_queue; struct workqueue_struct **cq_wq; struct workqueue_struct *eq_wq; struct hl_ctx *kernel_ctx; struct hl_hw_queue *kernel_queues; - struct list_head hw_queues_mirror_list; - spinlock_t hw_queues_mirror_lock; + struct list_head cs_mirror_list; + spinlock_t cs_mirror_lock; struct hl_cb_mgr kernel_cb_mgr; struct hl_eq event_queue; struct dma_pool *dma_pool; @@ -1649,10 +1899,10 @@ struct hl_device { struct hl_device_idle_busy_ts *idle_busy_ts_arr; - struct hl_cs_counters aggregated_cs_counters; + struct hl_cs_counters_atomic aggregated_cs_counters; struct hl_mmu_priv mmu_priv; - struct hl_mmu_funcs mmu_func; + struct hl_mmu_funcs mmu_func[MMU_NUM_PGT_LOCATIONS]; atomic64_t dram_used_mem; u64 timeout_jiffies; @@ -1677,8 +1927,8 @@ struct hl_device { u8 hard_reset_pending; u8 heartbeat; u8 reset_on_lockup; - u8 dram_supports_virtual_memory; u8 dram_default_page_mapping; + u8 memory_scrub; u8 pmmu_huge_range; u8 init_done; u8 device_cpu_disabled; @@ -1689,17 +1939,22 @@ struct hl_device { u8 stop_on_err; u8 supports_sync_stream; u8 sync_stream_queue_idx; + u8 collective_mon_idx; u8 supports_coresight; u8 supports_soft_reset; u8 supports_cb_mapping; + u8 needs_reset; + u8 process_kill_trial_cnt; + u8 device_fini_pending; /* Parameters for bring-up */ + u64 nic_ports_mask; + u64 fw_loading; u8 mmu_enable; u8 mmu_huge_page_opt; u8 cpu_enable; u8 reset_pcilink; u8 cpu_queues_enable; - u8 fw_loading; u8 pldm; u8 axi_drain; u8 sram_scrambler_enable; @@ -1707,6 +1962,7 @@ struct hl_device { u8 hard_reset_on_fw_events; u8 bmc_enable; u8 rl_enable; + u8 reset_on_preboot_fail; }; @@ -1793,7 +2049,8 @@ static inline bool hl_mem_area_crosses_range(u64 address, u32 size, int hl_device_open(struct inode *inode, struct file *filp); int hl_device_open_ctrl(struct inode *inode, struct file *filp); -bool hl_device_disabled_or_in_reset(struct hl_device *hdev); +bool hl_device_operational(struct hl_device *hdev, + enum hl_device_status *status); enum hl_device_status hl_device_status(struct hl_device *hdev); int hl_device_set_debug_mode(struct hl_device *hdev, bool enable); int create_hdev(struct hl_device **dev, struct pci_dev *pdev, @@ -1878,8 +2135,10 @@ void hl_cs_rollback_all(struct hl_device *hdev); struct hl_cs_job *hl_cs_allocate_job(struct hl_device *hdev, enum hl_queue_type queue_type, bool is_kernel_allocated_cb); void hl_sob_reset_error(struct kref *ref); +int hl_gen_sob_mask(u16 sob_base, u8 sob_mask, u8 *mask); void hl_fence_put(struct hl_fence *fence); void hl_fence_get(struct hl_fence *fence); +void cs_get(struct hl_cs *cs); void goya_set_asic_funcs(struct hl_device *hdev); void gaudi_set_asic_funcs(struct hl_device *hdev); @@ -1890,6 +2149,10 @@ void hl_vm_ctx_fini(struct hl_ctx *ctx); int hl_vm_init(struct hl_device *hdev); void hl_vm_fini(struct hl_device *hdev); +u64 hl_reserve_va_block(struct hl_device *hdev, struct hl_ctx *ctx, + enum hl_va_range_type type, u32 size, u32 alignment); +int hl_unreserve_va_block(struct hl_device *hdev, struct hl_ctx *ctx, + u64 start_addr, u64 size); int hl_pin_host_memory(struct hl_device *hdev, u64 addr, u64 size, struct hl_userptr *userptr); void hl_unpin_host_memory(struct hl_device *hdev, struct hl_userptr *userptr); @@ -1903,20 +2166,26 @@ int hl_mmu_init(struct hl_device *hdev); void hl_mmu_fini(struct hl_device *hdev); int hl_mmu_ctx_init(struct hl_ctx *ctx); void hl_mmu_ctx_fini(struct hl_ctx *ctx); -int hl_mmu_map(struct hl_ctx *ctx, u64 virt_addr, u64 phys_addr, +int hl_mmu_map_page(struct hl_ctx *ctx, u64 virt_addr, u64 phys_addr, u32 page_size, bool flush_pte); -int hl_mmu_unmap(struct hl_ctx *ctx, u64 virt_addr, u32 page_size, +int hl_mmu_unmap_page(struct hl_ctx *ctx, u64 virt_addr, u32 page_size, bool flush_pte); +int hl_mmu_map_contiguous(struct hl_ctx *ctx, u64 virt_addr, + u64 phys_addr, u32 size); +int hl_mmu_unmap_contiguous(struct hl_ctx *ctx, u64 virt_addr, u32 size); void hl_mmu_swap_out(struct hl_ctx *ctx); void hl_mmu_swap_in(struct hl_ctx *ctx); int hl_mmu_if_set_funcs(struct hl_device *hdev); -void hl_mmu_v1_set_funcs(struct hl_device *hdev); +void hl_mmu_v1_set_funcs(struct hl_device *hdev, struct hl_mmu_funcs *mmu); +int hl_mmu_va_to_pa(struct hl_ctx *ctx, u64 virt_addr, u64 *phys_addr); +int hl_mmu_get_tlb_info(struct hl_ctx *ctx, u64 virt_addr, + struct hl_mmu_hop_info *hops); int hl_fw_load_fw_to_device(struct hl_device *hdev, const char *fw_name, - void __iomem *dst); + void __iomem *dst, u32 src_offset, u32 size); int hl_fw_send_pci_access_msg(struct hl_device *hdev, u32 opcode); int hl_fw_send_cpu_message(struct hl_device *hdev, u32 hw_queue_id, u32 *msg, - u16 len, u32 timeout, long *result); + u16 len, u32 timeout, u64 *result); int hl_fw_unmask_irq(struct hl_device *hdev, u16 event_type); int hl_fw_unmask_irq_arr(struct hl_device *hdev, const u32 *irq_arr, size_t irq_arr_size); @@ -1926,18 +2195,22 @@ void *hl_fw_cpu_accessible_dma_pool_alloc(struct hl_device *hdev, size_t size, void hl_fw_cpu_accessible_dma_pool_free(struct hl_device *hdev, size_t size, void *vaddr); int hl_fw_send_heartbeat(struct hl_device *hdev); -int hl_fw_cpucp_info_get(struct hl_device *hdev); +int hl_fw_cpucp_info_get(struct hl_device *hdev, + u32 cpu_security_boot_status_reg); int hl_fw_get_eeprom_data(struct hl_device *hdev, void *data, size_t max_size); int hl_fw_cpucp_pci_counters_get(struct hl_device *hdev, struct hl_info_pci_counters *counters); int hl_fw_cpucp_total_energy_get(struct hl_device *hdev, u64 *total_energy); +int hl_fw_cpucp_pll_info_get(struct hl_device *hdev, u16 pll_index, + u16 *pll_freq_arr); int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg, u32 msg_to_cpu_reg, u32 cpu_msg_status_reg, - u32 boot_err0_reg, bool skip_bmc, - u32 cpu_timeout, u32 boot_fit_timeout); -int hl_fw_read_preboot_ver(struct hl_device *hdev, u32 cpu_boot_status_reg, - u32 boot_err0_reg, u32 timeout); + u32 cpu_security_boot_status_reg, u32 boot_err0_reg, + bool skip_bmc, u32 cpu_timeout, u32 boot_fit_timeout); +int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg, + u32 cpu_security_boot_status_reg, u32 boot_err0_reg, + u32 timeout); int hl_pci_bars_map(struct hl_device *hdev, const char * const name[3], bool is_wc[3]); @@ -1946,8 +2219,7 @@ int hl_pci_set_inbound_region(struct hl_device *hdev, u8 region, struct hl_inbound_pci_region *pci_region); int hl_pci_set_outbound_region(struct hl_device *hdev, struct hl_outbound_pci_region *pci_region); -int hl_pci_init(struct hl_device *hdev, u32 cpu_boot_status_reg, - u32 boot_err0_reg, u32 preboot_ver_timeout); +int hl_pci_init(struct hl_device *hdev); void hl_pci_fini(struct hl_device *hdev); long hl_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr); diff --git a/drivers/misc/habanalabs/common/habanalabs_drv.c b/drivers/misc/habanalabs/common/habanalabs_drv.c index f9067d3ef437..6bbb6bca6860 100644 --- a/drivers/misc/habanalabs/common/habanalabs_drv.c +++ b/drivers/misc/habanalabs/common/habanalabs_drv.c @@ -29,6 +29,7 @@ static DEFINE_MUTEX(hl_devs_idr_lock); static int timeout_locked = 5; static int reset_on_lockup = 1; +static int memory_scrub = 1; module_param(timeout_locked, int, 0444); MODULE_PARM_DESC(timeout_locked, @@ -38,6 +39,10 @@ module_param(reset_on_lockup, int, 0444); MODULE_PARM_DESC(reset_on_lockup, "Do device reset on lockup (0 = no, 1 = yes, default yes)"); +module_param(memory_scrub, int, 0444); +MODULE_PARM_DESC(memory_scrub, + "Scrub device memory in various states (0 = no, 1 = yes, default yes)"); + #define PCI_VENDOR_ID_HABANALABS 0x1da3 #define PCI_IDS_GOYA 0x0001 @@ -87,6 +92,7 @@ static enum hl_asic_type get_asic_type(u16 device) */ int hl_device_open(struct inode *inode, struct file *filp) { + enum hl_device_status status; struct hl_device *hdev; struct hl_fpriv *hpriv; int rc; @@ -119,10 +125,10 @@ int hl_device_open(struct inode *inode, struct file *filp) mutex_lock(&hdev->fpriv_list_lock); - if (hl_device_disabled_or_in_reset(hdev)) { + if (!hl_device_operational(hdev, &status)) { dev_err_ratelimited(hdev->dev, - "Can't open %s because it is disabled or in reset\n", - dev_name(hdev->dev)); + "Can't open %s because it is %s\n", + dev_name(hdev->dev), hdev->status[status]); rc = -EPERM; goto out_err; } @@ -199,7 +205,7 @@ int hl_device_open_ctrl(struct inode *inode, struct file *filp) mutex_lock(&hdev->fpriv_list_lock); - if (hl_device_disabled_or_in_reset(hdev)) { + if (!hl_device_operational(hdev, NULL)) { dev_err_ratelimited(hdev->dev_ctrl, "Can't open %s because it is disabled or in reset\n", dev_name(hdev->dev_ctrl)); @@ -228,19 +234,20 @@ out_err: static void set_driver_behavior_per_device(struct hl_device *hdev) { - hdev->mmu_enable = 1; hdev->cpu_enable = 1; - hdev->fw_loading = 1; + hdev->fw_loading = FW_TYPE_ALL_TYPES; hdev->cpu_queues_enable = 1; hdev->heartbeat = 1; + hdev->mmu_enable = 1; hdev->clock_gating_mask = ULONG_MAX; - - hdev->reset_pcilink = 0; - hdev->axi_drain = 0; hdev->sram_scrambler_enable = 1; hdev->dram_scrambler_enable = 1; hdev->bmc_enable = 1; hdev->hard_reset_on_fw_events = 1; + hdev->reset_on_preboot_fail = 1; + + hdev->reset_pcilink = 0; + hdev->axi_drain = 0; } /* @@ -281,8 +288,17 @@ int create_hdev(struct hl_device **dev, struct pci_dev *pdev, hdev->asic_type = asic_type; } + /* Assign status description string */ + strncpy(hdev->status[HL_DEVICE_STATUS_MALFUNCTION], + "disabled", HL_STR_MAX); + strncpy(hdev->status[HL_DEVICE_STATUS_IN_RESET], + "in reset", HL_STR_MAX); + strncpy(hdev->status[HL_DEVICE_STATUS_NEEDS_RESET], + "needs reset", HL_STR_MAX); + hdev->major = hl_major; hdev->reset_on_lockup = reset_on_lockup; + hdev->memory_scrub = memory_scrub; hdev->pldm = 0; set_driver_behavior_per_device(hdev); diff --git a/drivers/misc/habanalabs/common/habanalabs_ioctl.c b/drivers/misc/habanalabs/common/habanalabs_ioctl.c index 07317ea49129..32e6af1db4e3 100644 --- a/drivers/misc/habanalabs/common/habanalabs_ioctl.c +++ b/drivers/misc/habanalabs/common/habanalabs_ioctl.c @@ -314,20 +314,45 @@ static int clk_throttle_info(struct hl_fpriv *hpriv, struct hl_info_args *args) static int cs_counters_info(struct hl_fpriv *hpriv, struct hl_info_args *args) { + void __user *out = (void __user *) (uintptr_t) args->return_pointer; + struct hl_info_cs_counters cs_counters = {0}; struct hl_device *hdev = hpriv->hdev; - struct hl_info_cs_counters cs_counters = { {0} }; + struct hl_cs_counters_atomic *cntr; u32 max_size = args->return_size; - void __user *out = (void __user *) (uintptr_t) args->return_pointer; + + cntr = &hdev->aggregated_cs_counters; if ((!max_size) || (!out)) return -EINVAL; - memcpy(&cs_counters.cs_counters, &hdev->aggregated_cs_counters, - sizeof(struct hl_cs_counters)); - - if (hpriv->ctx) - memcpy(&cs_counters.ctx_cs_counters, &hpriv->ctx->cs_counters, - sizeof(struct hl_cs_counters)); + cs_counters.total_out_of_mem_drop_cnt = + atomic64_read(&cntr->out_of_mem_drop_cnt); + cs_counters.total_parsing_drop_cnt = + atomic64_read(&cntr->parsing_drop_cnt); + cs_counters.total_queue_full_drop_cnt = + atomic64_read(&cntr->queue_full_drop_cnt); + cs_counters.total_device_in_reset_drop_cnt = + atomic64_read(&cntr->device_in_reset_drop_cnt); + cs_counters.total_max_cs_in_flight_drop_cnt = + atomic64_read(&cntr->max_cs_in_flight_drop_cnt); + + if (hpriv->ctx) { + cs_counters.ctx_out_of_mem_drop_cnt = + atomic64_read( + &hpriv->ctx->cs_counters.out_of_mem_drop_cnt); + cs_counters.ctx_parsing_drop_cnt = + atomic64_read( + &hpriv->ctx->cs_counters.parsing_drop_cnt); + cs_counters.ctx_queue_full_drop_cnt = + atomic64_read( + &hpriv->ctx->cs_counters.queue_full_drop_cnt); + cs_counters.ctx_device_in_reset_drop_cnt = + atomic64_read( + &hpriv->ctx->cs_counters.device_in_reset_drop_cnt); + cs_counters.ctx_max_cs_in_flight_drop_cnt = + atomic64_read( + &hpriv->ctx->cs_counters.max_cs_in_flight_drop_cnt); + } return copy_to_user(out, &cs_counters, min((size_t) max_size, sizeof(cs_counters))) ? -EFAULT : 0; @@ -378,11 +403,32 @@ static int total_energy_consumption_info(struct hl_fpriv *hpriv, min((size_t) max_size, sizeof(total_energy))) ? -EFAULT : 0; } +static int pll_frequency_info(struct hl_fpriv *hpriv, struct hl_info_args *args) +{ + struct hl_device *hdev = hpriv->hdev; + struct hl_pll_frequency_info freq_info = {0}; + u32 max_size = args->return_size; + void __user *out = (void __user *) (uintptr_t) args->return_pointer; + int rc; + + if ((!max_size) || (!out)) + return -EINVAL; + + rc = hl_fw_cpucp_pll_info_get(hdev, args->pll_index, freq_info.output); + if (rc) + return rc; + + return copy_to_user(out, &freq_info, + min((size_t) max_size, sizeof(freq_info))) ? -EFAULT : 0; +} + static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data, struct device *dev) { + enum hl_device_status status; struct hl_info_args *args = data; struct hl_device *hdev = hpriv->hdev; + int rc; /* @@ -403,10 +449,10 @@ static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data, break; } - if (hl_device_disabled_or_in_reset(hdev)) { + if (!hl_device_operational(hdev, &status)) { dev_warn_ratelimited(dev, "Device is %s. Can't execute INFO IOCTL\n", - atomic_read(&hdev->in_reset) ? "in_reset" : "disabled"); + hdev->status[status]); return -EBUSY; } @@ -453,6 +499,9 @@ static int _hl_info_ioctl(struct hl_fpriv *hpriv, void *data, case HL_INFO_TOTAL_ENERGY: return total_energy_consumption_info(hpriv, args); + case HL_INFO_PLL_FREQUENCY: + return pll_frequency_info(hpriv, args); + default: dev_err(dev, "Invalid request %d\n", args->op); rc = -ENOTTY; @@ -476,12 +525,14 @@ static int hl_debug_ioctl(struct hl_fpriv *hpriv, void *data) { struct hl_debug_args *args = data; struct hl_device *hdev = hpriv->hdev; + enum hl_device_status status; + int rc = 0; - if (hl_device_disabled_or_in_reset(hdev)) { + if (!hl_device_operational(hdev, &status)) { dev_warn_ratelimited(hdev->dev, "Device is %s. Can't execute DEBUG IOCTL\n", - atomic_read(&hdev->in_reset) ? "in_reset" : "disabled"); + hdev->status[status]); return -EBUSY; } @@ -544,7 +595,7 @@ static long _hl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg, int retcode; if (hdev->hard_reset_pending) { - dev_crit_ratelimited(hdev->dev_ctrl, + dev_crit_ratelimited(dev, "Device HARD reset pending! Please close FD\n"); return -ENODEV; } diff --git a/drivers/misc/habanalabs/common/hw_queue.c b/drivers/misc/habanalabs/common/hw_queue.c index 5e66c98fb0d3..7caf868d1585 100644 --- a/drivers/misc/habanalabs/common/hw_queue.c +++ b/drivers/misc/habanalabs/common/hw_queue.c @@ -48,6 +48,11 @@ void hl_int_hw_queue_update_ci(struct hl_cs *cs) return; q = &hdev->kernel_queues[0]; + + /* There are no internal queues if H/W queues are being used */ + if (!hdev->asic_prop.max_queues || q->queue_type == QUEUE_TYPE_HW) + return; + for (i = 0 ; i < hdev->asic_prop.max_queues ; i++, q++) { if (q->queue_type == QUEUE_TYPE_INT) atomic_add(cs->jobs_in_queue_cnt[i], &q->ci); @@ -75,7 +80,7 @@ static void ext_and_hw_queue_submit_bd(struct hl_device *hdev, { struct hl_bd *bd; - bd = (struct hl_bd *) (uintptr_t) q->kernel_address; + bd = q->kernel_address; bd += hl_pi_2_offset(q->pi); bd->ctl = cpu_to_le32(ctl); bd->len = cpu_to_le32(len); @@ -333,10 +338,16 @@ static void int_queue_schedule_job(struct hl_cs_job *job) bd.ctl = 0; bd.len = cpu_to_le32(job->job_cb_size); - bd.ptr = cpu_to_le64((u64) (uintptr_t) job->user_cb); - pi = (__le64 *) (uintptr_t) (q->kernel_address + - ((q->pi & (q->int_queue_len - 1)) * sizeof(bd))); + if (job->is_kernel_allocated_cb) + /* bus_address is actually a mmu mapped address + * allocated from an internal pool + */ + bd.ptr = cpu_to_le64(job->user_cb->bus_address); + else + bd.ptr = cpu_to_le64((u64) (uintptr_t) job->user_cb); + + pi = q->kernel_address + (q->pi & (q->int_queue_len - 1)) * sizeof(bd); q->pi++; q->pi &= ((q->int_queue_len << 1) - 1); @@ -389,6 +400,91 @@ static void hw_queue_schedule_job(struct hl_cs_job *job) ext_and_hw_queue_submit_bd(hdev, q, ctl, len, ptr); } +static void init_signal_cs(struct hl_device *hdev, + struct hl_cs_job *job, struct hl_cs_compl *cs_cmpl) +{ + struct hl_sync_stream_properties *prop; + struct hl_hw_sob *hw_sob; + u32 q_idx; + + q_idx = job->hw_queue_id; + prop = &hdev->kernel_queues[q_idx].sync_stream_prop; + hw_sob = &prop->hw_sob[prop->curr_sob_offset]; + + cs_cmpl->hw_sob = hw_sob; + cs_cmpl->sob_val = prop->next_sob_val++; + + dev_dbg(hdev->dev, + "generate signal CB, sob_id: %d, sob val: 0x%x, q_idx: %d\n", + cs_cmpl->hw_sob->sob_id, cs_cmpl->sob_val, q_idx); + + hdev->asic_funcs->gen_signal_cb(hdev, job->patched_cb, + cs_cmpl->hw_sob->sob_id, 0); + + kref_get(&hw_sob->kref); + + /* check for wraparound */ + if (prop->next_sob_val == HL_MAX_SOB_VAL) { + /* + * Decrement as we reached the max value. + * The release function won't be called here as we've + * just incremented the refcount. + */ + kref_put(&hw_sob->kref, hl_sob_reset_error); + prop->next_sob_val = 1; + /* only two SOBs are currently in use */ + prop->curr_sob_offset = + (prop->curr_sob_offset + 1) % HL_RSVD_SOBS; + + dev_dbg(hdev->dev, "switched to SOB %d, q_idx: %d\n", + prop->curr_sob_offset, q_idx); + } +} + +static void init_wait_cs(struct hl_device *hdev, struct hl_cs *cs, + struct hl_cs_job *job, struct hl_cs_compl *cs_cmpl) +{ + struct hl_cs_compl *signal_cs_cmpl; + struct hl_sync_stream_properties *prop; + struct hl_gen_wait_properties wait_prop; + u32 q_idx; + + q_idx = job->hw_queue_id; + prop = &hdev->kernel_queues[q_idx].sync_stream_prop; + + signal_cs_cmpl = container_of(cs->signal_fence, + struct hl_cs_compl, + base_fence); + + /* copy the SOB id and value of the signal CS */ + cs_cmpl->hw_sob = signal_cs_cmpl->hw_sob; + cs_cmpl->sob_val = signal_cs_cmpl->sob_val; + + dev_dbg(hdev->dev, + "generate wait CB, sob_id: %d, sob_val: 0x%x, mon_id: %d, q_idx: %d\n", + cs_cmpl->hw_sob->sob_id, cs_cmpl->sob_val, + prop->base_mon_id, q_idx); + + wait_prop.data = (void *) job->patched_cb; + wait_prop.sob_base = cs_cmpl->hw_sob->sob_id; + wait_prop.sob_mask = 0x1; + wait_prop.sob_val = cs_cmpl->sob_val; + wait_prop.mon_id = prop->base_mon_id; + wait_prop.q_idx = q_idx; + wait_prop.size = 0; + hdev->asic_funcs->gen_wait_cb(hdev, &wait_prop); + + kref_get(&cs_cmpl->hw_sob->kref); + /* + * Must put the signal fence after the SOB refcnt increment so + * the SOB refcnt won't turn 0 and reset the SOB before the + * wait CS was submitted. + */ + mb(); + hl_fence_put(cs->signal_fence); + cs->signal_fence = NULL; +} + /* * init_signal_wait_cs - initialize a signal/wait CS * @cs: pointer to the signal/wait CS @@ -399,84 +495,18 @@ static void init_signal_wait_cs(struct hl_cs *cs) { struct hl_ctx *ctx = cs->ctx; struct hl_device *hdev = ctx->hdev; - struct hl_hw_queue *hw_queue; + struct hl_cs_job *job; struct hl_cs_compl *cs_cmpl = container_of(cs->fence, struct hl_cs_compl, base_fence); - struct hl_hw_sob *hw_sob; - struct hl_cs_job *job; - u32 q_idx; - /* There is only one job in a signal/wait CS */ job = list_first_entry(&cs->job_list, struct hl_cs_job, cs_node); - q_idx = job->hw_queue_id; - hw_queue = &hdev->kernel_queues[q_idx]; - - if (cs->type & CS_TYPE_SIGNAL) { - hw_sob = &hw_queue->hw_sob[hw_queue->curr_sob_offset]; - - cs_cmpl->hw_sob = hw_sob; - cs_cmpl->sob_val = hw_queue->next_sob_val++; - - dev_dbg(hdev->dev, - "generate signal CB, sob_id: %d, sob val: 0x%x, q_idx: %d\n", - cs_cmpl->hw_sob->sob_id, cs_cmpl->sob_val, q_idx); - - hdev->asic_funcs->gen_signal_cb(hdev, job->patched_cb, - cs_cmpl->hw_sob->sob_id); - - kref_get(&hw_sob->kref); - - /* check for wraparound */ - if (hw_queue->next_sob_val == HL_MAX_SOB_VAL) { - /* - * Decrement as we reached the max value. - * The release function won't be called here as we've - * just incremented the refcount. - */ - kref_put(&hw_sob->kref, hl_sob_reset_error); - hw_queue->next_sob_val = 1; - /* only two SOBs are currently in use */ - hw_queue->curr_sob_offset = - (hw_queue->curr_sob_offset + 1) % - HL_RSVD_SOBS_IN_USE; - - dev_dbg(hdev->dev, "switched to SOB %d, q_idx: %d\n", - hw_queue->curr_sob_offset, q_idx); - } - } else if (cs->type & CS_TYPE_WAIT) { - struct hl_cs_compl *signal_cs_cmpl; - - signal_cs_cmpl = container_of(cs->signal_fence, - struct hl_cs_compl, - base_fence); - - /* copy the the SOB id and value of the signal CS */ - cs_cmpl->hw_sob = signal_cs_cmpl->hw_sob; - cs_cmpl->sob_val = signal_cs_cmpl->sob_val; - - dev_dbg(hdev->dev, - "generate wait CB, sob_id: %d, sob_val: 0x%x, mon_id: %d, q_idx: %d\n", - cs_cmpl->hw_sob->sob_id, cs_cmpl->sob_val, - hw_queue->base_mon_id, q_idx); - hdev->asic_funcs->gen_wait_cb(hdev, job->patched_cb, - cs_cmpl->hw_sob->sob_id, - cs_cmpl->sob_val, - hw_queue->base_mon_id, - q_idx); - - kref_get(&cs_cmpl->hw_sob->kref); - /* - * Must put the signal fence after the SOB refcnt increment so - * the SOB refcnt won't turn 0 and reset the SOB before the - * wait CS was submitted. - */ - mb(); - hl_fence_put(cs->signal_fence); - cs->signal_fence = NULL; - } + if (cs->type & CS_TYPE_SIGNAL) + init_signal_cs(hdev, job, cs_cmpl); + else if (cs->type & CS_TYPE_WAIT) + init_wait_cs(hdev, cs, job, cs_cmpl); } /* @@ -485,19 +515,24 @@ static void init_signal_wait_cs(struct hl_cs *cs) */ int hl_hw_queue_schedule_cs(struct hl_cs *cs) { + enum hl_device_status status; + struct hl_cs_counters_atomic *cntr; struct hl_ctx *ctx = cs->ctx; struct hl_device *hdev = ctx->hdev; struct hl_cs_job *job, *tmp; struct hl_hw_queue *q; - u32 max_queues; int rc = 0, i, cq_cnt; + u32 max_queues; + + cntr = &hdev->aggregated_cs_counters; hdev->asic_funcs->hw_queues_lock(hdev); - if (hl_device_disabled_or_in_reset(hdev)) { - ctx->cs_counters.device_in_reset_drop_cnt++; + if (!hl_device_operational(hdev, &status)) { + atomic64_inc(&cntr->device_in_reset_drop_cnt); + atomic64_inc(&ctx->cs_counters.device_in_reset_drop_cnt); dev_err(hdev->dev, - "device is disabled or in reset, CS rejected!\n"); + "device is %s, CS rejected!\n", hdev->status[status]); rc = -EPERM; goto out; } @@ -528,7 +563,9 @@ int hl_hw_queue_schedule_cs(struct hl_cs *cs) } if (rc) { - ctx->cs_counters.queue_full_drop_cnt++; + atomic64_inc( + &ctx->cs_counters.queue_full_drop_cnt); + atomic64_inc(&cntr->queue_full_drop_cnt); goto unroll_cq_resv; } @@ -539,21 +576,23 @@ int hl_hw_queue_schedule_cs(struct hl_cs *cs) if ((cs->type == CS_TYPE_SIGNAL) || (cs->type == CS_TYPE_WAIT)) init_signal_wait_cs(cs); + else if (cs->type == CS_TYPE_COLLECTIVE_WAIT) + hdev->asic_funcs->collective_wait_init_cs(cs); - spin_lock(&hdev->hw_queues_mirror_lock); - list_add_tail(&cs->mirror_node, &hdev->hw_queues_mirror_list); + spin_lock(&hdev->cs_mirror_lock); + list_add_tail(&cs->mirror_node, &hdev->cs_mirror_list); /* Queue TDR if the CS is the first entry and if timeout is wanted */ if ((hdev->timeout_jiffies != MAX_SCHEDULE_TIMEOUT) && - (list_first_entry(&hdev->hw_queues_mirror_list, + (list_first_entry(&hdev->cs_mirror_list, struct hl_cs, mirror_node) == cs)) { cs->tdr_active = true; schedule_delayed_work(&cs->work_tdr, hdev->timeout_jiffies); - spin_unlock(&hdev->hw_queues_mirror_lock); - } else { - spin_unlock(&hdev->hw_queues_mirror_lock); + } + spin_unlock(&hdev->cs_mirror_lock); + if (!hdev->cs_active_cnt++) { struct hl_device_idle_busy_ts *ts; @@ -630,7 +669,7 @@ static int ext_and_cpu_queue_init(struct hl_device *hdev, struct hl_hw_queue *q, if (!p) return -ENOMEM; - q->kernel_address = (u64) (uintptr_t) p; + q->kernel_address = p; q->shadow_queue = kmalloc_array(HL_QUEUE_LENGTH, sizeof(*q->shadow_queue), @@ -653,11 +692,11 @@ free_queue: if (is_cpu_queue) hdev->asic_funcs->cpu_accessible_dma_pool_free(hdev, HL_QUEUE_SIZE_IN_BYTES, - (void *) (uintptr_t) q->kernel_address); + q->kernel_address); else hdev->asic_funcs->asic_dma_free_coherent(hdev, HL_QUEUE_SIZE_IN_BYTES, - (void *) (uintptr_t) q->kernel_address, + q->kernel_address, q->bus_address); return rc; @@ -676,7 +715,7 @@ static int int_queue_init(struct hl_device *hdev, struct hl_hw_queue *q) return -EFAULT; } - q->kernel_address = (u64) (uintptr_t) p; + q->kernel_address = p; q->pi = 0; atomic_set(&q->ci, 0); @@ -704,7 +743,7 @@ static int hw_queue_init(struct hl_device *hdev, struct hl_hw_queue *q) if (!p) return -ENOMEM; - q->kernel_address = (u64) (uintptr_t) p; + q->kernel_address = p; /* Make sure read/write pointers are initialized to start of queue */ atomic_set(&q->ci, 0); @@ -715,22 +754,56 @@ static int hw_queue_init(struct hl_device *hdev, struct hl_hw_queue *q) static void sync_stream_queue_init(struct hl_device *hdev, u32 q_idx) { - struct hl_hw_queue *hw_queue = &hdev->kernel_queues[q_idx]; + struct hl_sync_stream_properties *sync_stream_prop; struct asic_fixed_properties *prop = &hdev->asic_prop; struct hl_hw_sob *hw_sob; - int sob, queue_idx = hdev->sync_stream_queue_idx++; + int sob, reserved_mon_idx, queue_idx; + + sync_stream_prop = &hdev->kernel_queues[q_idx].sync_stream_prop; + + /* We use 'collective_mon_idx' as a running index in order to reserve + * monitors for collective master/slave queues. + * collective master queue gets 2 reserved monitors + * collective slave queue gets 1 reserved monitor + */ + if (hdev->kernel_queues[q_idx].collective_mode == + HL_COLLECTIVE_MASTER) { + reserved_mon_idx = hdev->collective_mon_idx; + + /* reserve the first monitor for collective master queue */ + sync_stream_prop->collective_mstr_mon_id[0] = + prop->collective_first_mon + reserved_mon_idx; + + /* reserve the second monitor for collective master queue */ + sync_stream_prop->collective_mstr_mon_id[1] = + prop->collective_first_mon + reserved_mon_idx + 1; + + hdev->collective_mon_idx += HL_COLLECTIVE_RSVD_MSTR_MONS; + } else if (hdev->kernel_queues[q_idx].collective_mode == + HL_COLLECTIVE_SLAVE) { + reserved_mon_idx = hdev->collective_mon_idx++; + + /* reserve a monitor for collective slave queue */ + sync_stream_prop->collective_slave_mon_id = + prop->collective_first_mon + reserved_mon_idx; + } + + if (!hdev->kernel_queues[q_idx].supports_sync_stream) + return; + + queue_idx = hdev->sync_stream_queue_idx++; - hw_queue->base_sob_id = - prop->sync_stream_first_sob + queue_idx * HL_RSVD_SOBS; - hw_queue->base_mon_id = - prop->sync_stream_first_mon + queue_idx * HL_RSVD_MONS; - hw_queue->next_sob_val = 1; - hw_queue->curr_sob_offset = 0; + sync_stream_prop->base_sob_id = prop->sync_stream_first_sob + + (queue_idx * HL_RSVD_SOBS); + sync_stream_prop->base_mon_id = prop->sync_stream_first_mon + + (queue_idx * HL_RSVD_MONS); + sync_stream_prop->next_sob_val = 1; + sync_stream_prop->curr_sob_offset = 0; for (sob = 0 ; sob < HL_RSVD_SOBS ; sob++) { - hw_sob = &hw_queue->hw_sob[sob]; + hw_sob = &sync_stream_prop->hw_sob[sob]; hw_sob->hdev = hdev; - hw_sob->sob_id = hw_queue->base_sob_id + sob; + hw_sob->sob_id = sync_stream_prop->base_sob_id + sob; hw_sob->q_idx = q_idx; kref_init(&hw_sob->kref); } @@ -738,15 +811,16 @@ static void sync_stream_queue_init(struct hl_device *hdev, u32 q_idx) static void sync_stream_queue_reset(struct hl_device *hdev, u32 q_idx) { - struct hl_hw_queue *hw_queue = &hdev->kernel_queues[q_idx]; + struct hl_sync_stream_properties *prop = + &hdev->kernel_queues[q_idx].sync_stream_prop; /* * In case we got here due to a stuck CS, the refcnt might be bigger * than 1 and therefore we reset it. */ - kref_init(&hw_queue->hw_sob[hw_queue->curr_sob_offset].kref); - hw_queue->curr_sob_offset = 0; - hw_queue->next_sob_val = 1; + kref_init(&prop->hw_sob[prop->curr_sob_offset].kref); + prop->curr_sob_offset = 0; + prop->next_sob_val = 1; } /* @@ -789,8 +863,7 @@ static int queue_init(struct hl_device *hdev, struct hl_hw_queue *q, break; } - if (q->supports_sync_stream) - sync_stream_queue_init(hdev, q->hw_queue_id); + sync_stream_queue_init(hdev, q->hw_queue_id); if (rc) return rc; @@ -839,11 +912,11 @@ static void queue_fini(struct hl_device *hdev, struct hl_hw_queue *q) if (q->queue_type == QUEUE_TYPE_CPU) hdev->asic_funcs->cpu_accessible_dma_pool_free(hdev, HL_QUEUE_SIZE_IN_BYTES, - (void *) (uintptr_t) q->kernel_address); + q->kernel_address); else hdev->asic_funcs->asic_dma_free_coherent(hdev, HL_QUEUE_SIZE_IN_BYTES, - (void *) (uintptr_t) q->kernel_address, + q->kernel_address, q->bus_address); } @@ -868,6 +941,7 @@ int hl_hw_queues_create(struct hl_device *hdev) q->queue_type = asic->hw_queues_props[i].type; q->supports_sync_stream = asic->hw_queues_props[i].supports_sync_stream; + q->collective_mode = asic->hw_queues_props[i].collective_mode; rc = queue_init(hdev, q, i); if (rc) { dev_err(hdev->dev, diff --git a/drivers/misc/habanalabs/common/hwmon.c b/drivers/misc/habanalabs/common/hwmon.c index 2ac29cb2fe61..6b421d76b311 100644 --- a/drivers/misc/habanalabs/common/hwmon.c +++ b/drivers/misc/habanalabs/common/hwmon.c @@ -114,7 +114,7 @@ static int hl_read(struct device *dev, enum hwmon_sensor_types type, struct hl_device *hdev = dev_get_drvdata(dev); int rc; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; switch (type) { @@ -192,7 +192,7 @@ static int hl_write(struct device *dev, enum hwmon_sensor_types type, { struct hl_device *hdev = dev_get_drvdata(dev); - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; switch (type) { @@ -312,6 +312,7 @@ int hl_get_temperature(struct hl_device *hdev, int sensor_index, u32 attr, long *value) { struct cpucp_packet pkt; + u64 result; int rc; memset(&pkt, 0, sizeof(pkt)); @@ -322,7 +323,9 @@ int hl_get_temperature(struct hl_device *hdev, pkt.type = __cpu_to_le16(attr); rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), - 0, value); + 0, &result); + + *value = (long) result; if (rc) { dev_err(hdev->dev, @@ -363,6 +366,7 @@ int hl_get_voltage(struct hl_device *hdev, int sensor_index, u32 attr, long *value) { struct cpucp_packet pkt; + u64 result; int rc; memset(&pkt, 0, sizeof(pkt)); @@ -373,7 +377,9 @@ int hl_get_voltage(struct hl_device *hdev, pkt.type = __cpu_to_le16(attr); rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), - 0, value); + 0, &result); + + *value = (long) result; if (rc) { dev_err(hdev->dev, @@ -389,6 +395,7 @@ int hl_get_current(struct hl_device *hdev, int sensor_index, u32 attr, long *value) { struct cpucp_packet pkt; + u64 result; int rc; memset(&pkt, 0, sizeof(pkt)); @@ -399,7 +406,9 @@ int hl_get_current(struct hl_device *hdev, pkt.type = __cpu_to_le16(attr); rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), - 0, value); + 0, &result); + + *value = (long) result; if (rc) { dev_err(hdev->dev, @@ -415,6 +424,7 @@ int hl_get_fan_speed(struct hl_device *hdev, int sensor_index, u32 attr, long *value) { struct cpucp_packet pkt; + u64 result; int rc; memset(&pkt, 0, sizeof(pkt)); @@ -425,7 +435,9 @@ int hl_get_fan_speed(struct hl_device *hdev, pkt.type = __cpu_to_le16(attr); rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), - 0, value); + 0, &result); + + *value = (long) result; if (rc) { dev_err(hdev->dev, @@ -441,6 +453,7 @@ int hl_get_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr, long *value) { struct cpucp_packet pkt; + u64 result; int rc; memset(&pkt, 0, sizeof(pkt)); @@ -451,7 +464,9 @@ int hl_get_pwm_info(struct hl_device *hdev, pkt.type = __cpu_to_le16(attr); rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt), - 0, value); + 0, &result); + + *value = (long) result; if (rc) { dev_err(hdev->dev, @@ -542,7 +557,7 @@ int hl_hwmon_init(struct hl_device *hdev) struct asic_fixed_properties *prop = &hdev->asic_prop; int rc; - if ((hdev->hwmon_initialized) || !(hdev->fw_loading)) + if ((hdev->hwmon_initialized) || !(hdev->cpu_queues_enable)) return 0; if (hdev->hl_chip_info->info) { diff --git a/drivers/misc/habanalabs/common/irq.c b/drivers/misc/habanalabs/common/irq.c index d20e40a53d70..de53fb5f978a 100644 --- a/drivers/misc/habanalabs/common/irq.c +++ b/drivers/misc/habanalabs/common/irq.c @@ -90,7 +90,7 @@ irqreturn_t hl_irq_handler_cq(int irq, void *arg) return IRQ_HANDLED; } - cq_base = (struct hl_cq_entry *) (uintptr_t) cq->kernel_address; + cq_base = cq->kernel_address; while (1) { bool entry_ready = ((le32_to_cpu(cq_base[cq->ci].data) & @@ -152,7 +152,7 @@ irqreturn_t hl_irq_handler_eq(int irq, void *arg) struct hl_eq_entry *eq_base; struct hl_eqe_work *handle_eqe_work; - eq_base = (struct hl_eq_entry *) (uintptr_t) eq->kernel_address; + eq_base = eq->kernel_address; while (1) { bool entry_ready = @@ -221,7 +221,7 @@ int hl_cq_init(struct hl_device *hdev, struct hl_cq *q, u32 hw_queue_id) return -ENOMEM; q->hdev = hdev; - q->kernel_address = (u64) (uintptr_t) p; + q->kernel_address = p; q->hw_queue_id = hw_queue_id; q->ci = 0; q->pi = 0; @@ -242,7 +242,8 @@ int hl_cq_init(struct hl_device *hdev, struct hl_cq *q, u32 hw_queue_id) void hl_cq_fini(struct hl_device *hdev, struct hl_cq *q) { hdev->asic_funcs->asic_dma_free_coherent(hdev, HL_CQ_SIZE_IN_BYTES, - (void *) (uintptr_t) q->kernel_address, q->bus_address); + q->kernel_address, + q->bus_address); } void hl_cq_reset(struct hl_device *hdev, struct hl_cq *q) @@ -259,7 +260,7 @@ void hl_cq_reset(struct hl_device *hdev, struct hl_cq *q) * when the device is operational again */ - memset((void *) (uintptr_t) q->kernel_address, 0, HL_CQ_SIZE_IN_BYTES); + memset(q->kernel_address, 0, HL_CQ_SIZE_IN_BYTES); } /** @@ -282,7 +283,7 @@ int hl_eq_init(struct hl_device *hdev, struct hl_eq *q) return -ENOMEM; q->hdev = hdev; - q->kernel_address = (u64) (uintptr_t) p; + q->kernel_address = p; q->ci = 0; return 0; @@ -302,7 +303,7 @@ void hl_eq_fini(struct hl_device *hdev, struct hl_eq *q) hdev->asic_funcs->cpu_accessible_dma_pool_free(hdev, HL_EQ_SIZE_IN_BYTES, - (void *) (uintptr_t) q->kernel_address); + q->kernel_address); } void hl_eq_reset(struct hl_device *hdev, struct hl_eq *q) @@ -316,5 +317,5 @@ void hl_eq_reset(struct hl_device *hdev, struct hl_eq *q) * when the device is operational again */ - memset((void *) (uintptr_t) q->kernel_address, 0, HL_EQ_SIZE_IN_BYTES); + memset(q->kernel_address, 0, HL_EQ_SIZE_IN_BYTES); } diff --git a/drivers/misc/habanalabs/common/memory.c b/drivers/misc/habanalabs/common/memory.c index 84227819e4d1..cbe9da4e0211 100644 --- a/drivers/misc/habanalabs/common/memory.c +++ b/drivers/misc/habanalabs/common/memory.c @@ -11,7 +11,6 @@ #include <linux/uaccess.h> #include <linux/slab.h> -#include <linux/genalloc.h> #define HL_MMU_DEBUG 0 @@ -46,7 +45,7 @@ * @ret_handle : result handle * * This function does the following: - * - Allocate the requested size rounded up to 2MB pages + * - Allocate the requested size rounded up to 'dram_page_size' pages * - Return unique handle */ static int alloc_device_memory(struct hl_ctx *ctx, struct hl_mem_in *args, @@ -81,6 +80,16 @@ static int alloc_device_memory(struct hl_ctx *ctx, struct hl_mem_in *args, num_pgs, total_size); return -ENOMEM; } + + if (hdev->memory_scrub) { + rc = hdev->asic_funcs->scrub_device_mem(hdev, paddr, + total_size); + if (rc) { + dev_err(hdev->dev, + "Failed to scrub contiguous device memory\n"); + goto pages_pack_err; + } + } } phys_pg_pack = kzalloc(sizeof(*phys_pg_pack), GFP_KERNEL); @@ -118,6 +127,17 @@ static int alloc_device_memory(struct hl_ctx *ctx, struct hl_mem_in *args, goto page_err; } + if (hdev->memory_scrub) { + rc = hdev->asic_funcs->scrub_device_mem(hdev, + phys_pg_pack->pages[i], + page_size); + if (rc) { + dev_err(hdev->dev, + "Failed to scrub device memory\n"); + goto page_err; + } + } + num_curr_pgs++; } } @@ -601,6 +621,87 @@ out: } /* + * hl_reserve_va_block() - reserve a virtual block of a given size. + * @hdev: pointer to the habanalabs device structure. + * @ctx: current context + * @type: virtual addresses range type. + * @size: requested block size. + * @alignment: required alignment in bytes of the virtual block start address, + * 0 means no alignment. + * + * This function does the following: + * - Iterate on the virtual block list to find a suitable virtual block for the + * given size and alignment. + * - Reserve the requested block and update the list. + * - Return the start address of the virtual block. + */ +u64 hl_reserve_va_block(struct hl_device *hdev, struct hl_ctx *ctx, + enum hl_va_range_type type, u32 size, u32 alignment) +{ + return get_va_block(hdev, ctx->va_range[type], size, 0, + max(alignment, ctx->va_range[type]->page_size)); +} + +/** + * hl_get_va_range_type() - get va_range type for the given address and size. + * @address: The start address of the area we want to validate. + * @size: The size in bytes of the area we want to validate. + * @type: returned va_range type + * + * Return: true if the area is inside a valid range, false otherwise. + */ +static int hl_get_va_range_type(struct hl_ctx *ctx, u64 address, u64 size, + enum hl_va_range_type *type) +{ + int i; + + for (i = 0 ; i < HL_VA_RANGE_TYPE_MAX; i++) { + if (hl_mem_area_inside_range(address, size, + ctx->va_range[i]->start_addr, + ctx->va_range[i]->end_addr)) { + *type = i; + return 0; + } + } + + return -EINVAL; +} + +/* + * hl_unreserve_va_block - wrapper for add_va_block for unreserving a va block + * + * @hdev: pointer to the habanalabs device structure + * @ctx: current context + * @start: start virtual address + * @end: end virtual address + * + * This function does the following: + * - Takes the list lock and calls add_va_block_locked + */ +int hl_unreserve_va_block(struct hl_device *hdev, struct hl_ctx *ctx, + u64 start_addr, u64 size) +{ + enum hl_va_range_type type; + int rc; + + rc = hl_get_va_range_type(ctx, start_addr, size, &type); + if (rc) { + dev_err(hdev->dev, + "cannot find va_range for va %#llx size %llu", + start_addr, size); + return rc; + } + + rc = add_va_block(hdev, ctx->va_range[type], start_addr, + start_addr + size - 1); + if (rc) + dev_warn(hdev->dev, + "add va block failed for vaddr: 0x%llx\n", start_addr); + + return rc; +} + +/* * get_sg_info - get number of pages and the DMA address from SG list * * @sg : the SG list @@ -742,7 +843,7 @@ static int map_phys_pg_pack(struct hl_ctx *ctx, u64 vaddr, for (i = 0 ; i < phys_pg_pack->npages ; i++) { paddr = phys_pg_pack->pages[i]; - rc = hl_mmu_map(ctx, next_vaddr, paddr, page_size, + rc = hl_mmu_map_page(ctx, next_vaddr, paddr, page_size, (i + 1) == phys_pg_pack->npages); if (rc) { dev_err(hdev->dev, @@ -761,7 +862,7 @@ static int map_phys_pg_pack(struct hl_ctx *ctx, u64 vaddr, err: next_vaddr = vaddr; for (i = 0 ; i < mapped_pg_cnt ; i++) { - if (hl_mmu_unmap(ctx, next_vaddr, page_size, + if (hl_mmu_unmap_page(ctx, next_vaddr, page_size, (i + 1) == mapped_pg_cnt)) dev_warn_ratelimited(hdev->dev, "failed to unmap handle %u, va: 0x%llx, pa: 0x%llx, page size: %u\n", @@ -791,7 +892,7 @@ static void unmap_phys_pg_pack(struct hl_ctx *ctx, u64 vaddr, next_vaddr = vaddr; for (i = 0 ; i < phys_pg_pack->npages ; i++, next_vaddr += page_size) { - if (hl_mmu_unmap(ctx, next_vaddr, page_size, + if (hl_mmu_unmap_page(ctx, next_vaddr, page_size, (i + 1) == phys_pg_pack->npages)) dev_warn_ratelimited(hdev->dev, "unmap failed for vaddr: 0x%llx\n", next_vaddr); @@ -888,7 +989,7 @@ static int map_device_va(struct hl_ctx *ctx, struct hl_mem_in *args, /* get required alignment */ if (phys_pg_pack->page_size == page_size) { - va_range = ctx->host_va_range; + va_range = ctx->va_range[HL_VA_RANGE_TYPE_HOST]; /* * huge page alignment may be needed in case of regular @@ -903,7 +1004,7 @@ static int map_device_va(struct hl_ctx *ctx, struct hl_mem_in *args, * huge page alignment is needed in case of huge page * mapping */ - va_range = ctx->host_huge_va_range; + va_range = ctx->va_range[HL_VA_RANGE_TYPE_HOST_HUGE]; va_block_align = huge_page_size; } } else { @@ -928,7 +1029,7 @@ static int map_device_va(struct hl_ctx *ctx, struct hl_mem_in *args, hint_addr = args->map_device.hint_addr; /* DRAM VA alignment is the same as the DRAM page size */ - va_range = ctx->dram_va_range; + va_range = ctx->va_range[HL_VA_RANGE_TYPE_DRAM]; va_block_align = hdev->asic_prop.dmmu.page_size; } @@ -1073,12 +1174,12 @@ static int unmap_device_va(struct hl_ctx *ctx, u64 vaddr, bool ctx_free) if (phys_pg_pack->page_size == hdev->asic_prop.pmmu.page_size) - va_range = ctx->host_va_range; + va_range = ctx->va_range[HL_VA_RANGE_TYPE_HOST]; else - va_range = ctx->host_huge_va_range; + va_range = ctx->va_range[HL_VA_RANGE_TYPE_HOST_HUGE]; } else if (*vm_type == VM_TYPE_PHYS_PACK) { is_userptr = false; - va_range = ctx->dram_va_range; + va_range = ctx->va_range[HL_VA_RANGE_TYPE_DRAM]; phys_pg_pack = hnode->ptr; } else { dev_warn(hdev->dev, @@ -1217,6 +1318,7 @@ out: int hl_mem_ioctl(struct hl_fpriv *hpriv, void *data) { + enum hl_device_status status; union hl_mem_args *args = data; struct hl_device *hdev = hpriv->hdev; struct hl_ctx *ctx = hpriv->ctx; @@ -1224,10 +1326,10 @@ int hl_mem_ioctl(struct hl_fpriv *hpriv, void *data) u32 handle = 0; int rc; - if (hl_device_disabled_or_in_reset(hdev)) { + if (!hl_device_operational(hdev, &status)) { dev_warn_ratelimited(hdev->dev, "Device is %s. Can't execute MEMORY IOCTL\n", - atomic_read(&hdev->in_reset) ? "in_reset" : "disabled"); + hdev->status[status]); return -EBUSY; } @@ -1236,18 +1338,35 @@ int hl_mem_ioctl(struct hl_fpriv *hpriv, void *data) switch (args->in.op) { case HL_MEM_OP_ALLOC: - if (!hdev->dram_supports_virtual_memory) { - dev_err(hdev->dev, "DRAM alloc is not supported\n"); - rc = -EINVAL; - goto out; - } - if (args->in.alloc.mem_size == 0) { dev_err(hdev->dev, "alloc size must be larger than 0\n"); rc = -EINVAL; goto out; } + + /* If DRAM does not support virtual memory the driver won't + * handle the allocation/freeing of that memory. However, for + * system administration/monitoring purposes, the driver will + * keep track of the amount of DRAM memory that is allocated + * and freed by the user. Because this code totally relies on + * the user's input, the driver can't ensure the validity + * of this accounting. + */ + if (!hdev->asic_prop.dram_supports_virtual_memory) { + atomic64_add(args->in.alloc.mem_size, + &ctx->dram_phys_mem); + atomic64_add(args->in.alloc.mem_size, + &hdev->dram_used_mem); + + dev_dbg(hdev->dev, "DRAM alloc is not supported\n"); + rc = 0; + + memset(args, 0, sizeof(*args)); + args->out.handle = 0; + goto out; + } + rc = alloc_device_memory(ctx, &args->in, &handle); memset(args, 0, sizeof(*args)); @@ -1255,6 +1374,26 @@ int hl_mem_ioctl(struct hl_fpriv *hpriv, void *data) break; case HL_MEM_OP_FREE: + /* If DRAM does not support virtual memory the driver won't + * handle the allocation/freeing of that memory. However, for + * system administration/monitoring purposes, the driver will + * keep track of the amount of DRAM memory that is allocated + * and freed by the user. Because this code totally relies on + * the user's input, the driver can't ensure the validity + * of this accounting. + */ + if (!hdev->asic_prop.dram_supports_virtual_memory) { + atomic64_sub(args->in.alloc.mem_size, + &ctx->dram_phys_mem); + atomic64_sub(args->in.alloc.mem_size, + &hdev->dram_used_mem); + + dev_dbg(hdev->dev, "DRAM alloc is not supported\n"); + rc = 0; + + goto out; + } + rc = free_device_memory(ctx, args->in.free.handle); break; @@ -1498,7 +1637,7 @@ bool hl_userptr_is_pinned(struct hl_device *hdev, u64 addr, * addresses. */ static int va_range_init(struct hl_device *hdev, struct hl_va_range *va_range, - u64 start, u64 end) + u64 start, u64 end, u32 page_size) { int rc; @@ -1528,6 +1667,7 @@ static int va_range_init(struct hl_device *hdev, struct hl_va_range *va_range, va_range->start_addr = start; va_range->end_addr = end; + va_range->page_size = page_size; return 0; } @@ -1540,8 +1680,7 @@ static int va_range_init(struct hl_device *hdev, struct hl_va_range *va_range, * This function does the following: * - Frees the virtual addresses block list and its lock */ -static void va_range_fini(struct hl_device *hdev, - struct hl_va_range *va_range) +static void va_range_fini(struct hl_device *hdev, struct hl_va_range *va_range) { mutex_lock(&va_range->lock); clear_va_list_locked(hdev, &va_range->list); @@ -1571,101 +1710,97 @@ static void va_range_fini(struct hl_device *hdev, static int vm_ctx_init_with_ranges(struct hl_ctx *ctx, u64 host_range_start, u64 host_range_end, + u32 host_page_size, u64 host_huge_range_start, u64 host_huge_range_end, + u32 host_huge_page_size, u64 dram_range_start, - u64 dram_range_end) + u64 dram_range_end, + u32 dram_page_size) { struct hl_device *hdev = ctx->hdev; - int rc; - - ctx->host_va_range = kzalloc(sizeof(*ctx->host_va_range), GFP_KERNEL); - if (!ctx->host_va_range) - return -ENOMEM; - - ctx->host_huge_va_range = kzalloc(sizeof(*ctx->host_huge_va_range), - GFP_KERNEL); - if (!ctx->host_huge_va_range) { - rc = -ENOMEM; - goto host_huge_va_range_err; - } - - ctx->dram_va_range = kzalloc(sizeof(*ctx->dram_va_range), GFP_KERNEL); - if (!ctx->dram_va_range) { - rc = -ENOMEM; - goto dram_va_range_err; + int i, rc; + + for (i = 0 ; i < HL_VA_RANGE_TYPE_MAX ; i++) { + ctx->va_range[i] = + kzalloc(sizeof(struct hl_va_range), GFP_KERNEL); + if (!ctx->va_range[i]) { + rc = -ENOMEM; + goto free_va_range; + } } rc = hl_mmu_ctx_init(ctx); if (rc) { dev_err(hdev->dev, "failed to init context %d\n", ctx->asid); - goto mmu_ctx_err; + goto free_va_range; } mutex_init(&ctx->mem_hash_lock); hash_init(ctx->mem_hash); - mutex_init(&ctx->host_va_range->lock); + mutex_init(&ctx->va_range[HL_VA_RANGE_TYPE_HOST]->lock); - rc = va_range_init(hdev, ctx->host_va_range, host_range_start, - host_range_end); + rc = va_range_init(hdev, ctx->va_range[HL_VA_RANGE_TYPE_HOST], + host_range_start, host_range_end, host_page_size); if (rc) { dev_err(hdev->dev, "failed to init host vm range\n"); - goto host_page_range_err; + goto mmu_ctx_fini; } if (hdev->pmmu_huge_range) { - mutex_init(&ctx->host_huge_va_range->lock); + mutex_init(&ctx->va_range[HL_VA_RANGE_TYPE_HOST_HUGE]->lock); - rc = va_range_init(hdev, ctx->host_huge_va_range, - host_huge_range_start, - host_huge_range_end); + rc = va_range_init(hdev, + ctx->va_range[HL_VA_RANGE_TYPE_HOST_HUGE], + host_huge_range_start, host_huge_range_end, + host_huge_page_size); if (rc) { dev_err(hdev->dev, "failed to init host huge vm range\n"); - goto host_hpage_range_err; + goto clear_host_va_range; } } else { - ctx->host_huge_va_range = ctx->host_va_range; + kfree(ctx->va_range[HL_VA_RANGE_TYPE_HOST_HUGE]); + ctx->va_range[HL_VA_RANGE_TYPE_HOST_HUGE] = + ctx->va_range[HL_VA_RANGE_TYPE_HOST]; } - mutex_init(&ctx->dram_va_range->lock); + mutex_init(&ctx->va_range[HL_VA_RANGE_TYPE_DRAM]->lock); - rc = va_range_init(hdev, ctx->dram_va_range, dram_range_start, - dram_range_end); + rc = va_range_init(hdev, ctx->va_range[HL_VA_RANGE_TYPE_DRAM], + dram_range_start, dram_range_end, dram_page_size); if (rc) { dev_err(hdev->dev, "failed to init dram vm range\n"); - goto dram_vm_err; + goto clear_host_huge_va_range; } hl_debugfs_add_ctx_mem_hash(hdev, ctx); return 0; -dram_vm_err: - mutex_destroy(&ctx->dram_va_range->lock); +clear_host_huge_va_range: + mutex_destroy(&ctx->va_range[HL_VA_RANGE_TYPE_DRAM]->lock); if (hdev->pmmu_huge_range) { - mutex_lock(&ctx->host_huge_va_range->lock); - clear_va_list_locked(hdev, &ctx->host_huge_va_range->list); - mutex_unlock(&ctx->host_huge_va_range->lock); + mutex_lock(&ctx->va_range[HL_VA_RANGE_TYPE_HOST_HUGE]->lock); + clear_va_list_locked(hdev, + &ctx->va_range[HL_VA_RANGE_TYPE_HOST_HUGE]->list); + mutex_unlock(&ctx->va_range[HL_VA_RANGE_TYPE_HOST_HUGE]->lock); } -host_hpage_range_err: +clear_host_va_range: if (hdev->pmmu_huge_range) - mutex_destroy(&ctx->host_huge_va_range->lock); - mutex_lock(&ctx->host_va_range->lock); - clear_va_list_locked(hdev, &ctx->host_va_range->list); - mutex_unlock(&ctx->host_va_range->lock); -host_page_range_err: - mutex_destroy(&ctx->host_va_range->lock); + mutex_destroy(&ctx->va_range[HL_VA_RANGE_TYPE_HOST_HUGE]->lock); + mutex_lock(&ctx->va_range[HL_VA_RANGE_TYPE_HOST]->lock); + clear_va_list_locked(hdev, &ctx->va_range[HL_VA_RANGE_TYPE_HOST]->list); + mutex_unlock(&ctx->va_range[HL_VA_RANGE_TYPE_HOST]->lock); +mmu_ctx_fini: + mutex_destroy(&ctx->va_range[HL_VA_RANGE_TYPE_HOST]->lock); mutex_destroy(&ctx->mem_hash_lock); hl_mmu_ctx_fini(ctx); -mmu_ctx_err: - kfree(ctx->dram_va_range); -dram_va_range_err: - kfree(ctx->host_huge_va_range); -host_huge_va_range_err: - kfree(ctx->host_va_range); +free_va_range: + for (i = 0 ; i < HL_VA_RANGE_TYPE_MAX ; i++) + kfree(ctx->va_range[i]); return rc; } @@ -1675,6 +1810,7 @@ int hl_vm_ctx_init(struct hl_ctx *ctx) struct asic_fixed_properties *prop = &ctx->hdev->asic_prop; u64 host_range_start, host_range_end, host_huge_range_start, host_huge_range_end, dram_range_start, dram_range_end; + u32 host_page_size, host_huge_page_size, dram_page_size; atomic64_set(&ctx->dram_phys_mem, 0); @@ -1685,27 +1821,23 @@ int hl_vm_ctx_init(struct hl_ctx *ctx) * In case of DRAM mapping, the returned address is the physical * address of the memory related to the given handle. */ - if (ctx->hdev->mmu_enable) { - dram_range_start = prop->dmmu.start_addr; - dram_range_end = prop->dmmu.end_addr; - host_range_start = prop->pmmu.start_addr; - host_range_end = prop->pmmu.end_addr; - host_huge_range_start = prop->pmmu_huge.start_addr; - host_huge_range_end = prop->pmmu_huge.end_addr; - } else { - dram_range_start = prop->dram_user_base_address; - dram_range_end = prop->dram_end_address; - host_range_start = prop->dram_user_base_address; - host_range_end = prop->dram_end_address; - host_huge_range_start = prop->dram_user_base_address; - host_huge_range_end = prop->dram_end_address; - } + if (!ctx->hdev->mmu_enable) + return 0; + + dram_range_start = prop->dmmu.start_addr; + dram_range_end = prop->dmmu.end_addr; + dram_page_size = prop->dmmu.page_size; + host_range_start = prop->pmmu.start_addr; + host_range_end = prop->pmmu.end_addr; + host_page_size = prop->pmmu.page_size; + host_huge_range_start = prop->pmmu_huge.start_addr; + host_huge_range_end = prop->pmmu_huge.end_addr; + host_huge_page_size = prop->pmmu_huge.page_size; return vm_ctx_init_with_ranges(ctx, host_range_start, host_range_end, - host_huge_range_start, - host_huge_range_end, - dram_range_start, - dram_range_end); + host_page_size, host_huge_range_start, + host_huge_range_end, host_huge_page_size, + dram_range_start, dram_range_end, dram_page_size); } /* @@ -1737,6 +1869,9 @@ void hl_vm_ctx_fini(struct hl_ctx *ctx) struct hlist_node *tmp_node; int i; + if (!ctx->hdev->mmu_enable) + return; + hl_debugfs_remove_ctx_mem_hash(hdev, ctx); /* @@ -1771,13 +1906,21 @@ void hl_vm_ctx_fini(struct hl_ctx *ctx) } spin_unlock(&vm->idr_lock); - va_range_fini(hdev, ctx->dram_va_range); + va_range_fini(hdev, ctx->va_range[HL_VA_RANGE_TYPE_DRAM]); + va_range_fini(hdev, ctx->va_range[HL_VA_RANGE_TYPE_HOST]); + if (hdev->pmmu_huge_range) - va_range_fini(hdev, ctx->host_huge_va_range); - va_range_fini(hdev, ctx->host_va_range); + va_range_fini(hdev, ctx->va_range[HL_VA_RANGE_TYPE_HOST_HUGE]); mutex_destroy(&ctx->mem_hash_lock); hl_mmu_ctx_fini(ctx); + + /* In this case we need to clear the global accounting of DRAM usage + * because the user notifies us on allocations. If the user is no more, + * all DRAM is available + */ + if (!ctx->hdev->asic_prop.dram_supports_virtual_memory) + atomic64_set(&ctx->hdev->dram_used_mem, 0); } /* diff --git a/drivers/misc/habanalabs/common/mmu.c b/drivers/misc/habanalabs/common/mmu.c index b5058798aeb9..33ae953d3a36 100644 --- a/drivers/misc/habanalabs/common/mmu.c +++ b/drivers/misc/habanalabs/common/mmu.c @@ -22,18 +22,25 @@ static bool is_dram_va(struct hl_device *hdev, u64 virt_addr) * hl_mmu_init() - initialize the MMU module. * @hdev: habanalabs device structure. * - * This function does the following: - * - Create a pool of pages for pgt_infos. - * - Create a shadow table for pgt - * * Return: 0 for success, non-zero for failure. */ int hl_mmu_init(struct hl_device *hdev) { - if (hdev->mmu_enable) - return hdev->mmu_func.init(hdev); + int rc = -EOPNOTSUPP; - return 0; + if (!hdev->mmu_enable) + return 0; + + if (hdev->mmu_func[MMU_DR_PGT].init != NULL) { + rc = hdev->mmu_func[MMU_DR_PGT].init(hdev); + if (rc) + return rc; + } + + if (hdev->mmu_func[MMU_HR_PGT].init != NULL) + rc = hdev->mmu_func[MMU_HR_PGT].init(hdev); + + return rc; } /** @@ -48,8 +55,14 @@ int hl_mmu_init(struct hl_device *hdev) */ void hl_mmu_fini(struct hl_device *hdev) { - if (hdev->mmu_enable) - hdev->mmu_func.fini(hdev); + if (!hdev->mmu_enable) + return; + + if (hdev->mmu_func[MMU_DR_PGT].fini != NULL) + hdev->mmu_func[MMU_DR_PGT].fini(hdev); + + if (hdev->mmu_func[MMU_HR_PGT].fini != NULL) + hdev->mmu_func[MMU_HR_PGT].fini(hdev); } /** @@ -63,11 +76,23 @@ void hl_mmu_fini(struct hl_device *hdev) int hl_mmu_ctx_init(struct hl_ctx *ctx) { struct hl_device *hdev = ctx->hdev; + int rc = -EOPNOTSUPP; - if (hdev->mmu_enable) - return hdev->mmu_func.ctx_init(ctx); + if (!hdev->mmu_enable) + return 0; - return 0; + mutex_init(&ctx->mmu_lock); + + if (hdev->mmu_func[MMU_DR_PGT].ctx_init != NULL) { + rc = hdev->mmu_func[MMU_DR_PGT].ctx_init(ctx); + if (rc) + return rc; + } + + if (hdev->mmu_func[MMU_HR_PGT].ctx_init != NULL) + rc = hdev->mmu_func[MMU_HR_PGT].ctx_init(ctx); + + return rc; } /* @@ -84,12 +109,20 @@ void hl_mmu_ctx_fini(struct hl_ctx *ctx) { struct hl_device *hdev = ctx->hdev; - if (hdev->mmu_enable) - hdev->mmu_func.ctx_fini(ctx); + if (!hdev->mmu_enable) + return; + + if (hdev->mmu_func[MMU_DR_PGT].ctx_fini != NULL) + hdev->mmu_func[MMU_DR_PGT].ctx_fini(ctx); + + if (hdev->mmu_func[MMU_HR_PGT].ctx_fini != NULL) + hdev->mmu_func[MMU_HR_PGT].ctx_fini(ctx); + + mutex_destroy(&ctx->mmu_lock); } /* - * hl_mmu_unmap - unmaps a virtual addr + * hl_mmu_unmap_page - unmaps a virtual addr * * @ctx: pointer to the context structure * @virt_addr: virt addr to map from @@ -109,7 +142,7 @@ void hl_mmu_ctx_fini(struct hl_ctx *ctx) * For optimization reasons PCI flush may be requested once after unmapping of * large area. */ -int hl_mmu_unmap(struct hl_ctx *ctx, u64 virt_addr, u32 page_size, +int hl_mmu_unmap_page(struct hl_ctx *ctx, u64 virt_addr, u32 page_size, bool flush_pte) { struct hl_device *hdev = ctx->hdev; @@ -117,7 +150,7 @@ int hl_mmu_unmap(struct hl_ctx *ctx, u64 virt_addr, u32 page_size, struct hl_mmu_properties *mmu_prop; u64 real_virt_addr; u32 real_page_size, npages; - int i, rc = 0; + int i, rc = 0, pgt_residency; bool is_dram_addr; if (!hdev->mmu_enable) @@ -132,6 +165,8 @@ int hl_mmu_unmap(struct hl_ctx *ctx, u64 virt_addr, u32 page_size, else mmu_prop = &prop->pmmu; + pgt_residency = mmu_prop->host_resident ? MMU_HR_PGT : MMU_DR_PGT; + /* * The H/W handles mapping of specific page sizes. Hence if the page * size is bigger, we break it to sub-pages and unmap them separately. @@ -150,7 +185,8 @@ int hl_mmu_unmap(struct hl_ctx *ctx, u64 virt_addr, u32 page_size, real_virt_addr = virt_addr; for (i = 0 ; i < npages ; i++) { - rc = hdev->mmu_func.unmap(ctx, real_virt_addr, is_dram_addr); + rc = hdev->mmu_func[pgt_residency].unmap(ctx, + real_virt_addr, is_dram_addr); if (rc) break; @@ -158,13 +194,13 @@ int hl_mmu_unmap(struct hl_ctx *ctx, u64 virt_addr, u32 page_size, } if (flush_pte) - hdev->mmu_func.flush(ctx); + hdev->mmu_func[pgt_residency].flush(ctx); return rc; } /* - * hl_mmu_map - maps a virtual addr to physical addr + * hl_mmu_map_page - maps a virtual addr to physical addr * * @ctx: pointer to the context structure * @virt_addr: virt addr to map from @@ -185,17 +221,18 @@ int hl_mmu_unmap(struct hl_ctx *ctx, u64 virt_addr, u32 page_size, * For optimization reasons PCI flush may be requested once after mapping of * large area. */ -int hl_mmu_map(struct hl_ctx *ctx, u64 virt_addr, u64 phys_addr, u32 page_size, - bool flush_pte) +int hl_mmu_map_page(struct hl_ctx *ctx, u64 virt_addr, u64 phys_addr, + u32 page_size, bool flush_pte) { struct hl_device *hdev = ctx->hdev; struct asic_fixed_properties *prop = &hdev->asic_prop; struct hl_mmu_properties *mmu_prop; u64 real_virt_addr, real_phys_addr; u32 real_page_size, npages; - int i, rc, mapped_cnt = 0; + int i, rc, pgt_residency, mapped_cnt = 0; bool is_dram_addr; + if (!hdev->mmu_enable) return 0; @@ -208,6 +245,8 @@ int hl_mmu_map(struct hl_ctx *ctx, u64 virt_addr, u64 phys_addr, u32 page_size, else mmu_prop = &prop->pmmu; + pgt_residency = mmu_prop->host_resident ? MMU_HR_PGT : MMU_DR_PGT; + /* * The H/W handles mapping of specific page sizes. Hence if the page * size is bigger, we break it to sub-pages and map them separately. @@ -216,7 +255,7 @@ int hl_mmu_map(struct hl_ctx *ctx, u64 virt_addr, u64 phys_addr, u32 page_size, real_page_size = mmu_prop->page_size; } else { dev_err(hdev->dev, - "page size of %u is not %uKB aligned, can't unmap\n", + "page size of %u is not %uKB aligned, can't map\n", page_size, mmu_prop->page_size >> 10); return -EFAULT; @@ -231,8 +270,9 @@ int hl_mmu_map(struct hl_ctx *ctx, u64 virt_addr, u64 phys_addr, u32 page_size, real_phys_addr = phys_addr; for (i = 0 ; i < npages ; i++) { - rc = hdev->mmu_func.map(ctx, real_virt_addr, real_phys_addr, - real_page_size, is_dram_addr); + rc = hdev->mmu_func[pgt_residency].map(ctx, + real_virt_addr, real_phys_addr, + real_page_size, is_dram_addr); if (rc) goto err; @@ -242,21 +282,124 @@ int hl_mmu_map(struct hl_ctx *ctx, u64 virt_addr, u64 phys_addr, u32 page_size, } if (flush_pte) - hdev->mmu_func.flush(ctx); + hdev->mmu_func[pgt_residency].flush(ctx); return 0; err: real_virt_addr = virt_addr; for (i = 0 ; i < mapped_cnt ; i++) { - if (hdev->mmu_func.unmap(ctx, real_virt_addr, is_dram_addr)) + if (hdev->mmu_func[pgt_residency].unmap(ctx, + real_virt_addr, is_dram_addr)) dev_warn_ratelimited(hdev->dev, "failed to unmap va: 0x%llx\n", real_virt_addr); real_virt_addr += real_page_size; } - hdev->mmu_func.flush(ctx); + hdev->mmu_func[pgt_residency].flush(ctx); + + return rc; +} + +/* + * hl_mmu_map_contiguous - implements a wrapper for hl_mmu_map_page + * for mapping contiguous physical memory + * + * @ctx: pointer to the context structure + * @virt_addr: virt addr to map from + * @phys_addr: phys addr to map to + * @size: size to map + * + */ +int hl_mmu_map_contiguous(struct hl_ctx *ctx, u64 virt_addr, + u64 phys_addr, u32 size) +{ + struct hl_device *hdev = ctx->hdev; + struct asic_fixed_properties *prop = &hdev->asic_prop; + u64 curr_va, curr_pa; + u32 page_size; + bool flush_pte; + int rc = 0, off; + + if (hl_mem_area_inside_range(virt_addr, size, + prop->dmmu.start_addr, prop->dmmu.end_addr)) + page_size = prop->dmmu.page_size; + else if (hl_mem_area_inside_range(virt_addr, size, + prop->pmmu.start_addr, prop->pmmu.end_addr)) + page_size = prop->pmmu.page_size; + else if (hl_mem_area_inside_range(virt_addr, size, + prop->pmmu_huge.start_addr, prop->pmmu_huge.end_addr)) + page_size = prop->pmmu_huge.page_size; + else + return -EINVAL; + + for (off = 0 ; off < size ; off += page_size) { + curr_va = virt_addr + off; + curr_pa = phys_addr + off; + flush_pte = (off + page_size) >= size; + rc = hl_mmu_map_page(ctx, curr_va, curr_pa, page_size, + flush_pte); + if (rc) { + dev_err(hdev->dev, + "Map failed for va 0x%llx to pa 0x%llx\n", + curr_va, curr_pa); + goto unmap; + } + } + + return rc; + +unmap: + for (; off >= 0 ; off -= page_size) { + curr_va = virt_addr + off; + flush_pte = (off - (s32) page_size) < 0; + if (hl_mmu_unmap_page(ctx, curr_va, page_size, flush_pte)) + dev_warn_ratelimited(hdev->dev, + "failed to unmap va 0x%llx\n", curr_va); + } + + return rc; +} + +/* + * hl_mmu_unmap_contiguous - implements a wrapper for hl_mmu_unmap_page + * for unmapping contiguous physical memory + * + * @ctx: pointer to the context structure + * @virt_addr: virt addr to unmap + * @size: size to unmap + * + */ +int hl_mmu_unmap_contiguous(struct hl_ctx *ctx, u64 virt_addr, u32 size) +{ + struct hl_device *hdev = ctx->hdev; + struct asic_fixed_properties *prop = &hdev->asic_prop; + u64 curr_va; + u32 page_size; + bool flush_pte; + int rc = 0, off; + + if (hl_mem_area_inside_range(virt_addr, size, + prop->dmmu.start_addr, prop->dmmu.end_addr)) + page_size = prop->dmmu.page_size; + else if (hl_mem_area_inside_range(virt_addr, size, + prop->pmmu.start_addr, prop->pmmu.end_addr)) + page_size = prop->pmmu.page_size; + else if (hl_mem_area_inside_range(virt_addr, size, + prop->pmmu_huge.start_addr, prop->pmmu_huge.end_addr)) + page_size = prop->pmmu_huge.page_size; + else + return -EINVAL; + + for (off = 0 ; off < size ; off += page_size) { + curr_va = virt_addr + off; + flush_pte = (off + page_size) >= size; + rc = hl_mmu_unmap_page(ctx, curr_va, page_size, flush_pte); + if (rc) + dev_warn_ratelimited(hdev->dev, + "Unmap failed for va 0x%llx\n", curr_va); + } return rc; } @@ -271,8 +414,14 @@ void hl_mmu_swap_out(struct hl_ctx *ctx) { struct hl_device *hdev = ctx->hdev; - if (hdev->mmu_enable) - hdev->mmu_func.swap_out(ctx); + if (!hdev->mmu_enable) + return; + + if (hdev->mmu_func[MMU_DR_PGT].swap_out != NULL) + hdev->mmu_func[MMU_DR_PGT].swap_out(ctx); + + if (hdev->mmu_func[MMU_HR_PGT].swap_out != NULL) + hdev->mmu_func[MMU_HR_PGT].swap_out(ctx); } /* @@ -285,8 +434,64 @@ void hl_mmu_swap_in(struct hl_ctx *ctx) { struct hl_device *hdev = ctx->hdev; - if (hdev->mmu_enable) - hdev->mmu_func.swap_in(ctx); + if (!hdev->mmu_enable) + return; + + if (hdev->mmu_func[MMU_DR_PGT].swap_in != NULL) + hdev->mmu_func[MMU_DR_PGT].swap_in(ctx); + + if (hdev->mmu_func[MMU_HR_PGT].swap_in != NULL) + hdev->mmu_func[MMU_HR_PGT].swap_in(ctx); +} + +int hl_mmu_va_to_pa(struct hl_ctx *ctx, u64 virt_addr, u64 *phys_addr) +{ + struct hl_mmu_hop_info hops; + u64 tmp_addr; + int rc; + + rc = hl_mmu_get_tlb_info(ctx, virt_addr, &hops); + if (rc) + return rc; + + /* last hop holds the phys address and flags */ + tmp_addr = hops.hop_info[hops.used_hops - 1].hop_pte_val; + *phys_addr = (tmp_addr & HOP_PHYS_ADDR_MASK) | (virt_addr & FLAGS_MASK); + + return 0; +} + +int hl_mmu_get_tlb_info(struct hl_ctx *ctx, u64 virt_addr, + struct hl_mmu_hop_info *hops) +{ + struct hl_device *hdev = ctx->hdev; + struct asic_fixed_properties *prop = &hdev->asic_prop; + struct hl_mmu_properties *mmu_prop; + int rc; + bool is_dram_addr; + + if (!hdev->mmu_enable) + return -EOPNOTSUPP; + + is_dram_addr = hl_mem_area_inside_range(virt_addr, prop->dmmu.page_size, + prop->dmmu.start_addr, + prop->dmmu.end_addr); + + /* host-residency is the same in PMMU and HPMMU, use one of them */ + mmu_prop = is_dram_addr ? &prop->dmmu : &prop->pmmu; + + mutex_lock(&ctx->mmu_lock); + + if (mmu_prop->host_resident) + rc = hdev->mmu_func[MMU_HR_PGT].get_tlb_info(ctx, + virt_addr, hops); + else + rc = hdev->mmu_func[MMU_DR_PGT].get_tlb_info(ctx, + virt_addr, hops); + + mutex_unlock(&ctx->mmu_lock); + + return rc; } int hl_mmu_if_set_funcs(struct hl_device *hdev) @@ -297,7 +502,7 @@ int hl_mmu_if_set_funcs(struct hl_device *hdev) switch (hdev->asic_type) { case ASIC_GOYA: case ASIC_GAUDI: - hl_mmu_v1_set_funcs(hdev); + hl_mmu_v1_set_funcs(hdev, &hdev->mmu_func[MMU_DR_PGT]); break; default: dev_err(hdev->dev, "Unrecognized ASIC type %d\n", diff --git a/drivers/misc/habanalabs/common/mmu_v1.c b/drivers/misc/habanalabs/common/mmu_v1.c index 8d1eb5265419..2ce6ea89d4fa 100644 --- a/drivers/misc/habanalabs/common/mmu_v1.c +++ b/drivers/misc/habanalabs/common/mmu_v1.c @@ -8,7 +8,6 @@ #include "habanalabs.h" #include "../include/hw_ip/mmu/mmu_general.h" -#include <linux/genalloc.h> #include <linux/slab.h> static inline u64 get_phys_addr(struct hl_ctx *ctx, u64 shadow_addr); @@ -29,7 +28,7 @@ static void _free_hop(struct hl_ctx *ctx, struct pgt_info *pgt_info) { struct hl_device *hdev = ctx->hdev; - gen_pool_free(hdev->mmu_priv.mmu_pgt_pool, pgt_info->phys_addr, + gen_pool_free(hdev->mmu_priv.dr.mmu_pgt_pool, pgt_info->phys_addr, hdev->asic_prop.mmu_hop_table_size); hash_del(&pgt_info->node); kfree((u64 *) (uintptr_t) pgt_info->shadow_addr); @@ -54,7 +53,7 @@ static u64 alloc_hop(struct hl_ctx *ctx) if (!pgt_info) return ULLONG_MAX; - phys_addr = (u64) gen_pool_alloc(hdev->mmu_priv.mmu_pgt_pool, + phys_addr = (u64) gen_pool_alloc(hdev->mmu_priv.dr.mmu_pgt_pool, prop->mmu_hop_table_size); if (!phys_addr) { dev_err(hdev->dev, "failed to allocate page\n"); @@ -75,7 +74,7 @@ static u64 alloc_hop(struct hl_ctx *ctx) return shadow_addr; shadow_err: - gen_pool_free(hdev->mmu_priv.mmu_pgt_pool, phys_addr, + gen_pool_free(hdev->mmu_priv.dr.mmu_pgt_pool, phys_addr, prop->mmu_hop_table_size); pool_add_err: kfree(pgt_info); @@ -91,7 +90,7 @@ static inline u64 get_phys_hop0_addr(struct hl_ctx *ctx) static inline u64 get_hop0_addr(struct hl_ctx *ctx) { - return (u64) (uintptr_t) ctx->hdev->mmu_priv.mmu_shadow_hop0 + + return (u64) (uintptr_t) ctx->hdev->mmu_priv.dr.mmu_shadow_hop0 + (ctx->asid * ctx->hdev->asic_prop.mmu_hop_table_size); } @@ -263,7 +262,7 @@ static int dram_default_mapping_init(struct hl_ctx *ctx) hop2_pte_addr, hop3_pte_addr, pte_val; int rc, i, j, hop3_allocated = 0; - if ((!hdev->dram_supports_virtual_memory) || + if ((!prop->dram_supports_virtual_memory) || (!hdev->dram_default_page_mapping) || (ctx->asid == HL_KERNEL_ASID_ID)) return 0; @@ -363,7 +362,7 @@ static void dram_default_mapping_fini(struct hl_ctx *ctx) hop2_pte_addr, hop3_pte_addr; int i, j; - if ((!hdev->dram_supports_virtual_memory) || + if ((!prop->dram_supports_virtual_memory) || (!hdev->dram_default_page_mapping) || (ctx->asid == HL_KERNEL_ASID_ID)) return; @@ -419,15 +418,15 @@ static int hl_mmu_v1_init(struct hl_device *hdev) struct asic_fixed_properties *prop = &hdev->asic_prop; int rc; - hdev->mmu_priv.mmu_pgt_pool = + hdev->mmu_priv.dr.mmu_pgt_pool = gen_pool_create(__ffs(prop->mmu_hop_table_size), -1); - if (!hdev->mmu_priv.mmu_pgt_pool) { + if (!hdev->mmu_priv.dr.mmu_pgt_pool) { dev_err(hdev->dev, "Failed to create page gen pool\n"); return -ENOMEM; } - rc = gen_pool_add(hdev->mmu_priv.mmu_pgt_pool, prop->mmu_pgt_addr + + rc = gen_pool_add(hdev->mmu_priv.dr.mmu_pgt_pool, prop->mmu_pgt_addr + prop->mmu_hop0_tables_total_size, prop->mmu_pgt_size - prop->mmu_hop0_tables_total_size, -1); @@ -436,10 +435,10 @@ static int hl_mmu_v1_init(struct hl_device *hdev) goto err_pool_add; } - hdev->mmu_priv.mmu_shadow_hop0 = kvmalloc_array(prop->max_asid, + hdev->mmu_priv.dr.mmu_shadow_hop0 = kvmalloc_array(prop->max_asid, prop->mmu_hop_table_size, GFP_KERNEL | __GFP_ZERO); - if (ZERO_OR_NULL_PTR(hdev->mmu_priv.mmu_shadow_hop0)) { + if (ZERO_OR_NULL_PTR(hdev->mmu_priv.dr.mmu_shadow_hop0)) { rc = -ENOMEM; goto err_pool_add; } @@ -449,7 +448,7 @@ static int hl_mmu_v1_init(struct hl_device *hdev) return 0; err_pool_add: - gen_pool_destroy(hdev->mmu_priv.mmu_pgt_pool); + gen_pool_destroy(hdev->mmu_priv.dr.mmu_pgt_pool); return rc; } @@ -468,8 +467,8 @@ static void hl_mmu_v1_fini(struct hl_device *hdev) { /* MMU H/W fini was already done in device hw_fini() */ - kvfree(hdev->mmu_priv.mmu_shadow_hop0); - gen_pool_destroy(hdev->mmu_priv.mmu_pgt_pool); + kvfree(hdev->mmu_priv.dr.mmu_shadow_hop0); + gen_pool_destroy(hdev->mmu_priv.dr.mmu_pgt_pool); } /** @@ -482,9 +481,7 @@ static void hl_mmu_v1_fini(struct hl_device *hdev) */ static int hl_mmu_v1_ctx_init(struct hl_ctx *ctx) { - mutex_init(&ctx->mmu_lock); hash_init(ctx->mmu_shadow_hash); - return dram_default_mapping_init(ctx); } @@ -517,8 +514,6 @@ static void hl_mmu_v1_ctx_fini(struct hl_ctx *ctx) pgt_info->phys_addr, ctx->asid, pgt_info->num_of_ptes); _free_hop(ctx, pgt_info); } - - mutex_destroy(&ctx->mmu_lock); } static int _hl_mmu_v1_unmap(struct hl_ctx *ctx, @@ -842,15 +837,114 @@ static void hl_mmu_v1_swap_in(struct hl_ctx *ctx) } +static inline u64 get_hop_pte_addr(struct hl_ctx *ctx, + struct hl_mmu_properties *mmu_prop, + int hop_num, u64 hop_addr, u64 virt_addr) +{ + switch (hop_num) { + case 0: + return get_hop0_pte_addr(ctx, mmu_prop, hop_addr, virt_addr); + case 1: + return get_hop1_pte_addr(ctx, mmu_prop, hop_addr, virt_addr); + case 2: + return get_hop2_pte_addr(ctx, mmu_prop, hop_addr, virt_addr); + case 3: + return get_hop3_pte_addr(ctx, mmu_prop, hop_addr, virt_addr); + case 4: + return get_hop4_pte_addr(ctx, mmu_prop, hop_addr, virt_addr); + default: + break; + } + return U64_MAX; +} + +static int hl_mmu_v1_get_tlb_info(struct hl_ctx *ctx, u64 virt_addr, + struct hl_mmu_hop_info *hops) +{ + struct hl_device *hdev = ctx->hdev; + struct asic_fixed_properties *prop = &hdev->asic_prop; + struct hl_mmu_properties *mmu_prop; + bool is_dram_addr, is_pmmu_addr, is_pmmu_h_addr, is_huge; + int i, used_hops; + + is_dram_addr = hl_mem_area_inside_range(virt_addr, prop->dmmu.page_size, + prop->dmmu.start_addr, + prop->dmmu.end_addr); + is_pmmu_addr = hl_mem_area_inside_range(virt_addr, prop->pmmu.page_size, + prop->pmmu.start_addr, + prop->pmmu.end_addr); + is_pmmu_h_addr = hl_mem_area_inside_range(virt_addr, + prop->pmmu_huge.page_size, + prop->pmmu_huge.start_addr, + prop->pmmu_huge.end_addr); + if (is_dram_addr) { + mmu_prop = &prop->dmmu; + is_huge = true; + } else if (is_pmmu_addr) { + mmu_prop = &prop->pmmu; + is_huge = false; + } else if (is_pmmu_h_addr) { + mmu_prop = &prop->pmmu_huge; + is_huge = true; + } else { + return -EINVAL; + } + + used_hops = mmu_prop->num_hops; + + /* huge pages use lesser hops */ + if (is_huge) + used_hops--; + + hops->hop_info[0].hop_addr = get_phys_hop0_addr(ctx); + hops->hop_info[0].hop_pte_addr = + get_hop_pte_addr(ctx, mmu_prop, 0, + hops->hop_info[0].hop_addr, virt_addr); + hops->hop_info[0].hop_pte_val = + hdev->asic_funcs->read_pte(hdev, + hops->hop_info[0].hop_pte_addr); + + for (i = 1 ; i < used_hops ; i++) { + hops->hop_info[i].hop_addr = + get_next_hop_addr(ctx, + hops->hop_info[i - 1].hop_pte_val); + if (hops->hop_info[i].hop_addr == ULLONG_MAX) + return -EFAULT; + + hops->hop_info[i].hop_pte_addr = + get_hop_pte_addr(ctx, mmu_prop, i, + hops->hop_info[i].hop_addr, + virt_addr); + hops->hop_info[i].hop_pte_val = + hdev->asic_funcs->read_pte(hdev, + hops->hop_info[i].hop_pte_addr); + + if (!(hops->hop_info[i].hop_pte_val & PAGE_PRESENT_MASK)) + return -EFAULT; + + if (hops->hop_info[i].hop_pte_val & LAST_MASK) + break; + } + + /* if passed over all hops then no last hop was found */ + if (i == mmu_prop->num_hops) + return -EFAULT; + + if (!(hops->hop_info[i].hop_pte_val & PAGE_PRESENT_MASK)) + return -EFAULT; + + hops->used_hops = i + 1; + + return 0; +} + /* * hl_mmu_v1_prepare - prepare mmu for working with mmu v1 * * @hdev: pointer to the device structure */ -void hl_mmu_v1_set_funcs(struct hl_device *hdev) +void hl_mmu_v1_set_funcs(struct hl_device *hdev, struct hl_mmu_funcs *mmu) { - struct hl_mmu_funcs *mmu = &hdev->mmu_func; - mmu->init = hl_mmu_v1_init; mmu->fini = hl_mmu_v1_fini; mmu->ctx_init = hl_mmu_v1_ctx_init; @@ -860,4 +954,5 @@ void hl_mmu_v1_set_funcs(struct hl_device *hdev) mmu->flush = flush; mmu->swap_out = hl_mmu_v1_swap_out; mmu->swap_in = hl_mmu_v1_swap_in; + mmu->get_tlb_info = hl_mmu_v1_get_tlb_info; } diff --git a/drivers/misc/habanalabs/common/pci.c b/drivers/misc/habanalabs/common/pci.c index 4327e5704ebb..923b2606e29f 100644 --- a/drivers/misc/habanalabs/common/pci.c +++ b/drivers/misc/habanalabs/common/pci.c @@ -338,17 +338,12 @@ static int hl_pci_set_dma_mask(struct hl_device *hdev) /** * hl_pci_init() - PCI initialization code. * @hdev: Pointer to hl_device structure. - * @cpu_boot_status_reg: status register of the device's CPU - * @boot_err0_reg: boot error register of the device's CPU - * @preboot_ver_timeout: how much to wait before bailing out on reading - * the preboot version * * Set DMA masks, initialize the PCI controller and map the PCI BARs. * * Return: 0 on success, non-zero for failure. */ -int hl_pci_init(struct hl_device *hdev, u32 cpu_boot_status_reg, - u32 boot_err0_reg, u32 preboot_ver_timeout) +int hl_pci_init(struct hl_device *hdev) { struct pci_dev *pdev = hdev->pdev; int rc; @@ -380,15 +375,6 @@ int hl_pci_init(struct hl_device *hdev, u32 cpu_boot_status_reg, if (rc) goto unmap_pci_bars; - /* Before continuing in the initialization, we need to read the preboot - * version to determine whether we run with a security-enabled firmware - * The check will be done in each ASIC's specific code - */ - rc = hl_fw_read_preboot_ver(hdev, cpu_boot_status_reg, boot_err0_reg, - preboot_ver_timeout); - if (rc) - goto unmap_pci_bars; - return 0; unmap_pci_bars: diff --git a/drivers/misc/habanalabs/common/sysfs.c b/drivers/misc/habanalabs/common/sysfs.c index 3ceae87016b1..4366d8f93842 100644 --- a/drivers/misc/habanalabs/common/sysfs.c +++ b/drivers/misc/habanalabs/common/sysfs.c @@ -12,7 +12,7 @@ long hl_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr) { struct cpucp_packet pkt; - long result; + u64 result; int rc; memset(&pkt, 0, sizeof(pkt)); @@ -32,10 +32,10 @@ long hl_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr) dev_err(hdev->dev, "Failed to get frequency of PLL %d, error %d\n", pll_index, rc); - result = rc; + return rc; } - return result; + return (long) result; } void hl_set_frequency(struct hl_device *hdev, u32 pll_index, u64 freq) @@ -62,7 +62,7 @@ void hl_set_frequency(struct hl_device *hdev, u32 pll_index, u64 freq) u64 hl_get_max_power(struct hl_device *hdev) { struct cpucp_packet pkt; - long result; + u64 result; int rc; memset(&pkt, 0, sizeof(pkt)); @@ -75,7 +75,7 @@ u64 hl_get_max_power(struct hl_device *hdev) if (rc) { dev_err(hdev->dev, "Failed to get max power, error %d\n", rc); - result = rc; + return (u64) rc; } return result; @@ -276,6 +276,8 @@ static ssize_t status_show(struct device *dev, struct device_attribute *attr, str = "In reset"; else if (hdev->disabled) str = "Malfunction"; + else if (hdev->needs_reset) + str = "Needs Reset"; else str = "Operational"; @@ -304,7 +306,7 @@ static ssize_t max_power_show(struct device *dev, struct device_attribute *attr, struct hl_device *hdev = dev_get_drvdata(dev); long val; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; val = hl_get_max_power(hdev); @@ -319,7 +321,7 @@ static ssize_t max_power_store(struct device *dev, unsigned long value; int rc; - if (hl_device_disabled_or_in_reset(hdev)) { + if (!hl_device_operational(hdev, NULL)) { count = -ENODEV; goto out; } @@ -347,7 +349,7 @@ static ssize_t eeprom_read_handler(struct file *filp, struct kobject *kobj, char *data; int rc; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; if (!max_size) diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c index 5f65a1691551..1f1926607c5e 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi.c +++ b/drivers/misc/habanalabs/gaudi/gaudi.c @@ -17,8 +17,6 @@ #include <linux/pci.h> #include <linux/firmware.h> #include <linux/hwmon.h> -#include <linux/genalloc.h> -#include <linux/io-64-nonatomic-lo-hi.h> #include <linux/iommu.h> #include <linux/seq_file.h> @@ -38,7 +36,7 @@ * * MMU is always enabled. * - * QMAN DMA channels 0,1,5 (PCI DMAN): + * QMAN DMA channels 0,1 (PCI DMAN): * - DMA is not secured. * - PQ and CQ are secured. * - CP is secured: The driver needs to parse CB but WREG should be allowed @@ -55,7 +53,7 @@ * idle) * - MMU page tables area clear (happens on init) * - * QMAN DMA 2-4,6,7, TPC, MME, NIC: + * QMAN DMA 2-7, TPC, MME, NIC: * PQ is secured and is located on the Host (HBM CON TPC3 bug) * CQ, CP and the engine are not secured * @@ -67,7 +65,7 @@ #define GAUDI_DMA_POOL_BLK_SIZE 0x100 /* 256 bytes */ -#define GAUDI_RESET_TIMEOUT_MSEC 1000 /* 1000ms */ +#define GAUDI_RESET_TIMEOUT_MSEC 2000 /* 2000ms */ #define GAUDI_RESET_WAIT_MSEC 1 /* 1ms */ #define GAUDI_CPU_RESET_WAIT_MSEC 200 /* 200ms */ #define GAUDI_TEST_QUEUE_WAIT_USEC 100000 /* 100ms */ @@ -103,6 +101,10 @@ BIT(GAUDI_ENGINE_ID_MME_2) |\ GENMASK_ULL(GAUDI_ENGINE_ID_TPC_7, GAUDI_ENGINE_ID_TPC_0)) +#define HBM_SCRUBBING_TIMEOUT_US 1000000 /* 1s */ + +#define GAUDI_PLL_MAX 10 + static const char gaudi_irq_name[GAUDI_MSI_ENTRIES][GAUDI_MAX_STRING_LEN] = { "gaudi cq 0_0", "gaudi cq 0_1", "gaudi cq 0_2", "gaudi cq 0_3", "gaudi cq 1_0", "gaudi cq 1_1", "gaudi cq 1_2", "gaudi cq 1_3", @@ -113,12 +115,12 @@ static const char gaudi_irq_name[GAUDI_MSI_ENTRIES][GAUDI_MAX_STRING_LEN] = { static const u8 gaudi_dma_assignment[GAUDI_DMA_MAX] = { [GAUDI_PCI_DMA_1] = GAUDI_ENGINE_ID_DMA_0, [GAUDI_PCI_DMA_2] = GAUDI_ENGINE_ID_DMA_1, - [GAUDI_PCI_DMA_3] = GAUDI_ENGINE_ID_DMA_5, [GAUDI_HBM_DMA_1] = GAUDI_ENGINE_ID_DMA_2, [GAUDI_HBM_DMA_2] = GAUDI_ENGINE_ID_DMA_3, [GAUDI_HBM_DMA_3] = GAUDI_ENGINE_ID_DMA_4, - [GAUDI_HBM_DMA_4] = GAUDI_ENGINE_ID_DMA_6, - [GAUDI_HBM_DMA_5] = GAUDI_ENGINE_ID_DMA_7 + [GAUDI_HBM_DMA_4] = GAUDI_ENGINE_ID_DMA_5, + [GAUDI_HBM_DMA_5] = GAUDI_ENGINE_ID_DMA_6, + [GAUDI_HBM_DMA_6] = GAUDI_ENGINE_ID_DMA_7 }; static const u8 gaudi_cq_assignment[NUMBER_OF_CMPLT_QUEUES] = { @@ -130,10 +132,6 @@ static const u8 gaudi_cq_assignment[NUMBER_OF_CMPLT_QUEUES] = { [5] = GAUDI_QUEUE_ID_DMA_1_1, [6] = GAUDI_QUEUE_ID_DMA_1_2, [7] = GAUDI_QUEUE_ID_DMA_1_3, - [8] = GAUDI_QUEUE_ID_DMA_5_0, - [9] = GAUDI_QUEUE_ID_DMA_5_1, - [10] = GAUDI_QUEUE_ID_DMA_5_2, - [11] = GAUDI_QUEUE_ID_DMA_5_3 }; static const u16 gaudi_packet_sizes[MAX_PACKET_ID] = { @@ -153,6 +151,19 @@ static const u16 gaudi_packet_sizes[MAX_PACKET_ID] = { [PACKET_LOAD_AND_EXE] = sizeof(struct packet_load_and_exe) }; +static const u32 gaudi_pll_base_addresses[GAUDI_PLL_MAX] = { + [CPU_PLL] = mmPSOC_CPU_PLL_NR, + [PCI_PLL] = mmPSOC_PCI_PLL_NR, + [SRAM_PLL] = mmSRAM_W_PLL_NR, + [HBM_PLL] = mmPSOC_HBM_PLL_NR, + [NIC_PLL] = mmNIC0_PLL_NR, + [DMA_PLL] = mmDMA_W_PLL_NR, + [MESH_PLL] = mmMESH_W_PLL_NR, + [MME_PLL] = mmPSOC_MME_PLL_NR, + [TPC_PLL] = mmPSOC_TPC_PLL_NR, + [IF_PLL] = mmIF_W_PLL_NR +}; + static inline bool validate_packet_id(enum packet_id id) { switch (id) { @@ -249,10 +260,10 @@ static enum hl_queue_type gaudi_queue_type[GAUDI_QUEUE_ID_SIZE] = { QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_4_1 */ QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_4_2 */ QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_4_3 */ - QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_5_0 */ - QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_5_1 */ - QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_5_2 */ - QUEUE_TYPE_EXT, /* GAUDI_QUEUE_ID_DMA_5_3 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_5_0 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_5_1 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_5_2 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_5_3 */ QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_6_0 */ QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_6_1 */ QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_DMA_6_2 */ @@ -301,46 +312,46 @@ static enum hl_queue_type gaudi_queue_type[GAUDI_QUEUE_ID_SIZE] = { QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_7_1 */ QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_7_2 */ QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_TPC_7_3 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_0_0 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_0_1 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_0_2 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_0_3 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_1_0 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_1_1 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_1_2 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_1_3 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_2_0 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_2_1 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_2_2 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_2_3 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_3_0 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_3_1 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_3_2 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_3_3 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_4_0 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_4_1 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_4_2 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_4_3 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_5_0 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_5_1 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_5_2 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_5_3 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_6_0 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_6_1 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_6_2 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_6_3 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_7_0 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_7_1 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_7_2 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_7_3 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_8_0 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_8_1 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_8_2 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_8_3 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_9_0 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_9_1 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_9_2 */ - QUEUE_TYPE_NA, /* GAUDI_QUEUE_ID_NIC_9_3 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_0_0 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_0_1 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_0_2 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_0_3 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_1_0 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_1_1 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_1_2 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_1_3 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_2_0 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_2_1 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_2_2 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_2_3 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_3_0 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_3_1 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_3_2 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_3_3 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_4_0 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_4_1 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_4_2 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_4_3 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_5_0 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_5_1 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_5_2 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_5_3 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_6_0 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_6_1 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_6_2 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_6_3 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_7_0 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_7_1 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_7_2 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_7_3 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_8_0 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_8_1 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_8_2 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_8_3 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_9_0 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_9_1 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_9_2 */ + QUEUE_TYPE_INT, /* GAUDI_QUEUE_ID_NIC_9_3 */ }; struct ecc_info_extract_params { @@ -362,6 +373,31 @@ static int gaudi_mmu_clear_pgt_range(struct hl_device *hdev); static int gaudi_cpucp_info_get(struct hl_device *hdev); static void gaudi_disable_clock_gating(struct hl_device *hdev); static void gaudi_mmu_prepare(struct hl_device *hdev, u32 asid); +static u32 gaudi_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id, + u32 size); +static u32 gaudi_gen_wait_cb(struct hl_device *hdev, + struct hl_gen_wait_properties *prop); + +static inline enum hl_collective_mode +get_collective_mode(struct hl_device *hdev, u32 queue_id) +{ + if (gaudi_queue_type[queue_id] == QUEUE_TYPE_EXT) + return HL_COLLECTIVE_MASTER; + + if (queue_id >= GAUDI_QUEUE_ID_DMA_5_0 && + queue_id <= GAUDI_QUEUE_ID_DMA_5_3) + return HL_COLLECTIVE_SLAVE; + + if (queue_id >= GAUDI_QUEUE_ID_TPC_7_0 && + queue_id <= GAUDI_QUEUE_ID_TPC_7_3) + return HL_COLLECTIVE_SLAVE; + + if (queue_id >= GAUDI_QUEUE_ID_NIC_0_0 && + queue_id <= GAUDI_QUEUE_ID_NIC_9_3) + return HL_COLLECTIVE_SLAVE; + + return HL_COLLECTIVE_NOT_SUPPORTED; +} static int gaudi_get_fixed_properties(struct hl_device *hdev) { @@ -381,29 +417,44 @@ static int gaudi_get_fixed_properties(struct hl_device *hdev) if (gaudi_queue_type[i] == QUEUE_TYPE_EXT) { prop->hw_queues_props[i].type = QUEUE_TYPE_EXT; prop->hw_queues_props[i].driver_only = 0; - prop->hw_queues_props[i].requires_kernel_cb = 1; prop->hw_queues_props[i].supports_sync_stream = 1; + prop->hw_queues_props[i].cb_alloc_flags = + CB_ALLOC_KERNEL; num_sync_stream_queues++; } else if (gaudi_queue_type[i] == QUEUE_TYPE_CPU) { prop->hw_queues_props[i].type = QUEUE_TYPE_CPU; prop->hw_queues_props[i].driver_only = 1; - prop->hw_queues_props[i].requires_kernel_cb = 0; prop->hw_queues_props[i].supports_sync_stream = 0; + prop->hw_queues_props[i].cb_alloc_flags = + CB_ALLOC_KERNEL; } else if (gaudi_queue_type[i] == QUEUE_TYPE_INT) { prop->hw_queues_props[i].type = QUEUE_TYPE_INT; prop->hw_queues_props[i].driver_only = 0; - prop->hw_queues_props[i].requires_kernel_cb = 0; - } else if (gaudi_queue_type[i] == QUEUE_TYPE_NA) { - prop->hw_queues_props[i].type = QUEUE_TYPE_NA; - prop->hw_queues_props[i].driver_only = 0; - prop->hw_queues_props[i].requires_kernel_cb = 0; prop->hw_queues_props[i].supports_sync_stream = 0; + prop->hw_queues_props[i].cb_alloc_flags = + CB_ALLOC_USER; + } + prop->hw_queues_props[i].collective_mode = + get_collective_mode(hdev, i); } prop->completion_queues_count = NUMBER_OF_CMPLT_QUEUES; - prop->sync_stream_first_sob = 0; - prop->sync_stream_first_mon = 0; + prop->collective_first_sob = 0; + prop->collective_first_mon = 0; + + /* 2 SOBs per internal queue stream are reserved for collective */ + prop->sync_stream_first_sob = + ALIGN(NUMBER_OF_SOBS_IN_GRP, HL_MAX_SOBS_PER_MONITOR) + * QMAN_STREAMS * HL_RSVD_SOBS; + + /* 1 monitor per internal queue stream are reserved for collective + * 2 monitors per external queue stream are reserved for collective + */ + prop->sync_stream_first_mon = + (NUMBER_OF_COLLECTIVE_QUEUES * QMAN_STREAMS) + + (NUMBER_OF_EXT_HW_QUEUES * 2); + prop->dram_base_address = DRAM_PHYS_BASE; prop->dram_size = GAUDI_HBM_SIZE_32GB; prop->dram_end_address = prop->dram_base_address + @@ -426,6 +477,7 @@ static int gaudi_get_fixed_properties(struct hl_device *hdev) prop->mmu_hop_table_size = HOP_TABLE_SIZE; prop->mmu_hop0_tables_total_size = HOP0_TABLES_TOTAL_SIZE; prop->dram_page_size = PAGE_SIZE_2MB; + prop->dram_supports_virtual_memory = false; prop->pmmu.hop0_shift = HOP0_SHIFT; prop->pmmu.hop1_shift = HOP1_SHIFT; @@ -472,9 +524,16 @@ static int gaudi_get_fixed_properties(struct hl_device *hdev) prop->max_pending_cs = GAUDI_MAX_PENDING_CS; prop->first_available_user_sob[HL_GAUDI_WS_DCORE] = - num_sync_stream_queues * HL_RSVD_SOBS; + prop->sync_stream_first_sob + + (num_sync_stream_queues * HL_RSVD_SOBS); prop->first_available_user_mon[HL_GAUDI_WS_DCORE] = - num_sync_stream_queues * HL_RSVD_MONS; + prop->sync_stream_first_mon + + (num_sync_stream_queues * HL_RSVD_MONS); + + /* disable fw security for now, set it in a later stage */ + prop->fw_security_disabled = true; + prop->fw_security_status_valid = false; + prop->hard_reset_done_by_fw = false; return 0; } @@ -562,6 +621,11 @@ done: return rc; } +static enum hl_device_hw_state gaudi_get_hw_state(struct hl_device *hdev) +{ + return RREG32(mmHW_STATE); +} + static int gaudi_early_init(struct hl_device *hdev) { struct asic_fixed_properties *prop = &hdev->asic_prop; @@ -599,17 +663,32 @@ static int gaudi_early_init(struct hl_device *hdev) prop->dram_pci_bar_size = pci_resource_len(pdev, HBM_BAR_ID); - rc = hl_pci_init(hdev, mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS, - mmCPU_BOOT_ERR0, GAUDI_BOOT_FIT_REQ_TIMEOUT_USEC); + rc = hl_pci_init(hdev); if (rc) goto free_queue_props; - /* GAUDI Firmware does not yet support security */ - prop->fw_security_disabled = true; - dev_info(hdev->dev, "firmware-level security is disabled\n"); + if (gaudi_get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) { + dev_info(hdev->dev, + "H/W state is dirty, must reset before initializing\n"); + hdev->asic_funcs->hw_fini(hdev, true); + } + + /* Before continuing in the initialization, we need to read the preboot + * version to determine whether we run with a security-enabled firmware + */ + rc = hl_fw_read_preboot_status(hdev, mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS, + mmCPU_BOOT_DEV_STS0, mmCPU_BOOT_ERR0, + GAUDI_BOOT_FIT_REQ_TIMEOUT_USEC); + if (rc) { + if (hdev->reset_on_preboot_fail) + hdev->asic_funcs->hw_fini(hdev, true); + goto pci_fini; + } return 0; +pci_fini: + hl_pci_fini(hdev); free_queue_props: kfree(hdev->asic_prop.hw_queues_props); return rc; @@ -624,44 +703,95 @@ static int gaudi_early_fini(struct hl_device *hdev) } /** - * gaudi_fetch_psoc_frequency - Fetch PSOC frequency values + * gaudi_fetch_pll_frequency - Fetch PLL frequency values * * @hdev: pointer to hl_device structure + * @pll_index: index of the pll to fetch frequency from + * @pll_freq: pointer to store the pll frequency in MHz in each of the available + * outputs. if a certain output is not available a 0 will be set * */ -static void gaudi_fetch_psoc_frequency(struct hl_device *hdev) +static int gaudi_fetch_pll_frequency(struct hl_device *hdev, + enum gaudi_pll_index pll_index, + u16 *pll_freq_arr) { - struct asic_fixed_properties *prop = &hdev->asic_prop; - u32 trace_freq = 0; - u32 pll_clk = 0; - u32 div_fctr = RREG32(mmPSOC_CPU_PLL_DIV_FACTOR_2); - u32 div_sel = RREG32(mmPSOC_CPU_PLL_DIV_SEL_2); - u32 nr = RREG32(mmPSOC_CPU_PLL_NR); - u32 nf = RREG32(mmPSOC_CPU_PLL_NF); - u32 od = RREG32(mmPSOC_CPU_PLL_OD); - - if (div_sel == DIV_SEL_REF_CLK || div_sel == DIV_SEL_DIVIDED_REF) { - if (div_sel == DIV_SEL_REF_CLK) - trace_freq = PLL_REF_CLK; - else - trace_freq = PLL_REF_CLK / (div_fctr + 1); - } else if (div_sel == DIV_SEL_PLL_CLK || + u32 nr = 0, nf = 0, od = 0, pll_clk = 0, div_fctr, div_sel, + pll_base_addr = gaudi_pll_base_addresses[pll_index]; + u16 freq = 0; + int i, rc; + + if (hdev->asic_prop.fw_security_status_valid && + (hdev->asic_prop.fw_app_security_map & + CPU_BOOT_DEV_STS0_PLL_INFO_EN)) { + rc = hl_fw_cpucp_pll_info_get(hdev, pll_index, pll_freq_arr); + + if (rc) + return rc; + } else if (hdev->asic_prop.fw_security_disabled) { + /* Backward compatibility */ + nr = RREG32(pll_base_addr + PLL_NR_OFFSET); + nf = RREG32(pll_base_addr + PLL_NF_OFFSET); + od = RREG32(pll_base_addr + PLL_OD_OFFSET); + + for (i = 0; i < HL_PLL_NUM_OUTPUTS; i++) { + div_fctr = RREG32(pll_base_addr + + PLL_DIV_FACTOR_0_OFFSET + i * 4); + div_sel = RREG32(pll_base_addr + + PLL_DIV_SEL_0_OFFSET + i * 4); + + if (div_sel == DIV_SEL_REF_CLK || + div_sel == DIV_SEL_DIVIDED_REF) { + if (div_sel == DIV_SEL_REF_CLK) + freq = PLL_REF_CLK; + else + freq = PLL_REF_CLK / (div_fctr + 1); + } else if (div_sel == DIV_SEL_PLL_CLK || div_sel == DIV_SEL_DIVIDED_PLL) { - pll_clk = PLL_REF_CLK * (nf + 1) / ((nr + 1) * (od + 1)); - if (div_sel == DIV_SEL_PLL_CLK) - trace_freq = pll_clk; - else - trace_freq = pll_clk / (div_fctr + 1); + pll_clk = PLL_REF_CLK * (nf + 1) / + ((nr + 1) * (od + 1)); + if (div_sel == DIV_SEL_PLL_CLK) + freq = pll_clk; + else + freq = pll_clk / (div_fctr + 1); + } else { + dev_warn(hdev->dev, + "Received invalid div select value: %d", + div_sel); + } + + pll_freq_arr[i] = freq; + } } else { - dev_warn(hdev->dev, - "Received invalid div select value: %d", div_sel); + dev_err(hdev->dev, "Failed to fetch PLL frequency values\n"); + return -EIO; } - prop->psoc_timestamp_frequency = trace_freq; - prop->psoc_pci_pll_nr = nr; - prop->psoc_pci_pll_nf = nf; - prop->psoc_pci_pll_od = od; - prop->psoc_pci_pll_div_factor = div_fctr; + return 0; +} + +/** + * gaudi_fetch_psoc_frequency - Fetch PSOC frequency values + * + * @hdev: pointer to hl_device structure + * + */ +static int gaudi_fetch_psoc_frequency(struct hl_device *hdev) +{ + struct asic_fixed_properties *prop = &hdev->asic_prop; + u16 pll_freq[HL_PLL_NUM_OUTPUTS]; + int rc; + + rc = gaudi_fetch_pll_frequency(hdev, CPU_PLL, pll_freq); + if (rc) + return rc; + + prop->psoc_timestamp_frequency = pll_freq[2]; + prop->psoc_pci_pll_nr = 0; + prop->psoc_pci_pll_nf = 0; + prop->psoc_pci_pll_od = 0; + prop->psoc_pci_pll_div_factor = 0; + + return 0; } static int _gaudi_init_tpc_mem(struct hl_device *hdev, @@ -680,8 +810,7 @@ static int _gaudi_init_tpc_mem(struct hl_device *hdev, if (!cb) return -EFAULT; - init_tpc_mem_pkt = (struct packet_lin_dma *) (uintptr_t) - cb->kernel_address; + init_tpc_mem_pkt = cb->kernel_address; cb_size = sizeof(*init_tpc_mem_pkt); memset(init_tpc_mem_pkt, 0, cb_size); @@ -709,7 +838,7 @@ static int _gaudi_init_tpc_mem(struct hl_device *hdev, job->id = 0; job->user_cb = cb; - job->user_cb->cs_cnt++; + atomic_inc(&job->user_cb->cs_cnt); job->user_cb_size = cb_size; job->hw_queue_id = GAUDI_QUEUE_ID_DMA_0_0; job->patched_cb = job->user_cb; @@ -732,7 +861,7 @@ free_job: hl_userptr_delete_list(hdev, &job->userptr_list); hl_debugfs_remove_job(hdev, job); kfree(job); - cb->cs_cnt--; + atomic_dec(&cb->cs_cnt); release_cb: hl_cb_put(cb); @@ -787,6 +916,451 @@ out: return rc; } +static void gaudi_collective_map_sobs(struct hl_device *hdev, u32 stream) +{ + struct gaudi_device *gaudi = hdev->asic_specific; + struct gaudi_collective_properties *prop = &gaudi->collective_props; + struct hl_hw_queue *q; + u32 i, sob_id, sob_group_id, queue_id; + + /* Iterate through SOB groups and assign a SOB for each slave queue */ + sob_group_id = + stream * HL_RSVD_SOBS + prop->curr_sob_group_idx[stream]; + sob_id = prop->hw_sob_group[sob_group_id].base_sob_id; + + queue_id = GAUDI_QUEUE_ID_NIC_0_0 + stream; + for (i = 0 ; i < NIC_NUMBER_OF_ENGINES ; i++) { + q = &hdev->kernel_queues[queue_id + (4 * i)]; + q->sync_stream_prop.collective_sob_id = sob_id + i; + } + + /* Both DMA5 and TPC7 use the same resources since only a single + * engine need to participate in the reduction process + */ + queue_id = GAUDI_QUEUE_ID_DMA_5_0 + stream; + q = &hdev->kernel_queues[queue_id]; + q->sync_stream_prop.collective_sob_id = + sob_id + NIC_NUMBER_OF_ENGINES; + + queue_id = GAUDI_QUEUE_ID_TPC_7_0 + stream; + q = &hdev->kernel_queues[queue_id]; + q->sync_stream_prop.collective_sob_id = + sob_id + NIC_NUMBER_OF_ENGINES; +} + +static void gaudi_sob_group_hw_reset(struct kref *ref) +{ + struct gaudi_hw_sob_group *hw_sob_group = + container_of(ref, struct gaudi_hw_sob_group, kref); + struct hl_device *hdev = hw_sob_group->hdev; + int i; + + for (i = 0 ; i < NUMBER_OF_SOBS_IN_GRP ; i++) + WREG32(mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_SOB_OBJ_0 + + (hw_sob_group->base_sob_id + i) * 4, 0); + + kref_init(&hw_sob_group->kref); +} + +static void gaudi_sob_group_reset_error(struct kref *ref) +{ + struct gaudi_hw_sob_group *hw_sob_group = + container_of(ref, struct gaudi_hw_sob_group, kref); + struct hl_device *hdev = hw_sob_group->hdev; + + dev_crit(hdev->dev, + "SOB release shouldn't be called here, base_sob_id: %d\n", + hw_sob_group->base_sob_id); +} + +static int gaudi_collective_init(struct hl_device *hdev) +{ + u32 i, master_monitor_sobs, sob_id, reserved_sobs_per_group; + struct gaudi_collective_properties *prop; + struct gaudi_device *gaudi; + + gaudi = hdev->asic_specific; + prop = &gaudi->collective_props; + sob_id = hdev->asic_prop.collective_first_sob; + + /* First sob in group must be aligned to HL_MAX_SOBS_PER_MONITOR */ + reserved_sobs_per_group = + ALIGN(NUMBER_OF_SOBS_IN_GRP, HL_MAX_SOBS_PER_MONITOR); + + /* Init SOB groups */ + for (i = 0 ; i < NUM_SOB_GROUPS; i++) { + prop->hw_sob_group[i].hdev = hdev; + prop->hw_sob_group[i].base_sob_id = sob_id; + sob_id += reserved_sobs_per_group; + gaudi_sob_group_hw_reset(&prop->hw_sob_group[i].kref); + } + + for (i = 0 ; i < QMAN_STREAMS; i++) { + prop->next_sob_group_val[i] = 1; + prop->curr_sob_group_idx[i] = 0; + gaudi_collective_map_sobs(hdev, i); + } + + prop->mstr_sob_mask[0] = 0; + master_monitor_sobs = HL_MAX_SOBS_PER_MONITOR; + for (i = 0 ; i < master_monitor_sobs ; i++) + if (gaudi->hw_cap_initialized & BIT(HW_CAP_NIC_SHIFT + i)) + prop->mstr_sob_mask[0] |= BIT(i); + + prop->mstr_sob_mask[1] = 0; + master_monitor_sobs = + NIC_NUMBER_OF_ENGINES - HL_MAX_SOBS_PER_MONITOR; + for (i = 0 ; i < master_monitor_sobs; i++) { + if (gaudi->hw_cap_initialized & BIT(HW_CAP_NIC_SHIFT + i)) + prop->mstr_sob_mask[1] |= BIT(i); + } + + /* Set collective engine bit */ + prop->mstr_sob_mask[1] |= BIT(i); + + return 0; +} + +static void gaudi_reset_sob_group(struct hl_device *hdev, u16 sob_group) +{ + struct gaudi_device *gaudi = hdev->asic_specific; + struct gaudi_collective_properties *cprop = &gaudi->collective_props; + + kref_put(&cprop->hw_sob_group[sob_group].kref, + gaudi_sob_group_hw_reset); +} + +static void gaudi_collective_master_init_job(struct hl_device *hdev, + struct hl_cs_job *job, u32 stream, u32 sob_group_offset) +{ + u32 master_sob_base, master_monitor, queue_id, cb_size = 0; + struct gaudi_collective_properties *cprop; + struct hl_gen_wait_properties wait_prop; + struct hl_sync_stream_properties *prop; + struct gaudi_device *gaudi; + + gaudi = hdev->asic_specific; + cprop = &gaudi->collective_props; + queue_id = job->hw_queue_id; + prop = &hdev->kernel_queues[queue_id].sync_stream_prop; + + master_sob_base = + cprop->hw_sob_group[sob_group_offset].base_sob_id; + master_monitor = prop->collective_mstr_mon_id[0]; + + dev_dbg(hdev->dev, + "Generate master wait CBs, sob %d (mask %#x), val:0x%x, mon %u, q %d\n", + master_sob_base, cprop->mstr_sob_mask[0], + cprop->next_sob_group_val[stream], + master_monitor, queue_id); + + wait_prop.data = (void *) job->patched_cb; + wait_prop.sob_base = master_sob_base; + wait_prop.sob_mask = cprop->mstr_sob_mask[0]; + wait_prop.sob_val = cprop->next_sob_group_val[stream]; + wait_prop.mon_id = master_monitor; + wait_prop.q_idx = queue_id; + wait_prop.size = cb_size; + cb_size += gaudi_gen_wait_cb(hdev, &wait_prop); + + master_sob_base += HL_MAX_SOBS_PER_MONITOR; + master_monitor = prop->collective_mstr_mon_id[1]; + + dev_dbg(hdev->dev, + "Generate master wait CBs, sob %d (mask %#x), val:0x%x, mon %u, q %d\n", + master_sob_base, cprop->mstr_sob_mask[1], + cprop->next_sob_group_val[stream], + master_monitor, queue_id); + + wait_prop.sob_base = master_sob_base; + wait_prop.sob_mask = cprop->mstr_sob_mask[1]; + wait_prop.mon_id = master_monitor; + wait_prop.size = cb_size; + cb_size += gaudi_gen_wait_cb(hdev, &wait_prop); +} + +static void gaudi_collective_slave_init_job(struct hl_device *hdev, + struct hl_cs_job *job, struct hl_cs_compl *cs_cmpl) +{ + struct hl_gen_wait_properties wait_prop; + struct hl_sync_stream_properties *prop; + u32 queue_id, cb_size = 0; + + queue_id = job->hw_queue_id; + prop = &hdev->kernel_queues[queue_id].sync_stream_prop; + + /* Add to wait CBs using slave monitor */ + wait_prop.data = (void *) job->user_cb; + wait_prop.sob_base = cs_cmpl->hw_sob->sob_id; + wait_prop.sob_mask = 0x1; + wait_prop.sob_val = cs_cmpl->sob_val; + wait_prop.mon_id = prop->collective_slave_mon_id; + wait_prop.q_idx = queue_id; + wait_prop.size = cb_size; + + dev_dbg(hdev->dev, + "Generate slave wait CB, sob %d, val:0x%x, mon %d, q %d\n", + cs_cmpl->hw_sob->sob_id, cs_cmpl->sob_val, + prop->collective_slave_mon_id, queue_id); + + cb_size += gaudi_gen_wait_cb(hdev, &wait_prop); + + dev_dbg(hdev->dev, + "generate signal CB, sob_id: %d, sob val: 1, q_idx: %d\n", + prop->collective_sob_id, queue_id); + + cb_size += gaudi_gen_signal_cb(hdev, job->user_cb, + prop->collective_sob_id, cb_size); +} + +static void gaudi_collective_wait_init_cs(struct hl_cs *cs) +{ + struct hl_cs_compl *signal_cs_cmpl = + container_of(cs->signal_fence, struct hl_cs_compl, base_fence); + struct hl_cs_compl *cs_cmpl = + container_of(cs->fence, struct hl_cs_compl, base_fence); + struct gaudi_collective_properties *cprop; + u32 stream, queue_id, sob_group_offset; + struct gaudi_device *gaudi; + struct hl_device *hdev; + struct hl_cs_job *job; + struct hl_ctx *ctx; + + ctx = cs->ctx; + hdev = ctx->hdev; + gaudi = hdev->asic_specific; + cprop = &gaudi->collective_props; + + /* copy the SOB id and value of the signal CS */ + cs_cmpl->hw_sob = signal_cs_cmpl->hw_sob; + cs_cmpl->sob_val = signal_cs_cmpl->sob_val; + + /* Calculate the stream from collective master queue (1st job) */ + job = list_first_entry(&cs->job_list, struct hl_cs_job, cs_node); + stream = job->hw_queue_id % 4; + sob_group_offset = + stream * HL_RSVD_SOBS + cprop->curr_sob_group_idx[stream]; + + list_for_each_entry(job, &cs->job_list, cs_node) { + queue_id = job->hw_queue_id; + + if (hdev->kernel_queues[queue_id].collective_mode == + HL_COLLECTIVE_MASTER) + gaudi_collective_master_init_job(hdev, job, stream, + sob_group_offset); + else + gaudi_collective_slave_init_job(hdev, job, cs_cmpl); + } + + cs_cmpl->sob_group = sob_group_offset; + + /* Handle sob group kref and wraparound */ + kref_get(&cprop->hw_sob_group[sob_group_offset].kref); + cprop->next_sob_group_val[stream]++; + + if (cprop->next_sob_group_val[stream] == HL_MAX_SOB_VAL) { + /* + * Decrement as we reached the max value. + * The release function won't be called here as we've + * just incremented the refcount. + */ + kref_put(&cprop->hw_sob_group[sob_group_offset].kref, + gaudi_sob_group_reset_error); + cprop->next_sob_group_val[stream] = 1; + /* only two SOBs are currently in use */ + cprop->curr_sob_group_idx[stream] = + (cprop->curr_sob_group_idx[stream] + 1) & + (HL_RSVD_SOBS - 1); + + gaudi_collective_map_sobs(hdev, stream); + + dev_dbg(hdev->dev, "switched to SOB group %d, stream: %d\n", + cprop->curr_sob_group_idx[stream], stream); + } + + /* Increment kref since all slave queues are now waiting on it */ + kref_get(&cs_cmpl->hw_sob->kref); + /* + * Must put the signal fence after the SOB refcnt increment so + * the SOB refcnt won't turn 0 and reset the SOB before the + * wait CS was submitted. + */ + mb(); + hl_fence_put(cs->signal_fence); + cs->signal_fence = NULL; +} + +static int gaudi_collective_wait_create_job(struct hl_device *hdev, + struct hl_ctx *ctx, struct hl_cs *cs, + enum hl_collective_mode mode, u32 queue_id, u32 wait_queue_id) +{ + struct hw_queue_properties *hw_queue_prop; + struct hl_cs_counters_atomic *cntr; + struct hl_cs_job *job; + struct hl_cb *cb; + u32 cb_size; + bool patched_cb; + + cntr = &hdev->aggregated_cs_counters; + + if (mode == HL_COLLECTIVE_MASTER) { + /* CB size of collective master queue contains + * 4 msg short packets for monitor 1 configuration + * 1 fence packet + * 4 msg short packets for monitor 2 configuration + * 1 fence packet + * 2 msg prot packets for completion and MSI-X + */ + cb_size = sizeof(struct packet_msg_short) * 8 + + sizeof(struct packet_fence) * 2 + + sizeof(struct packet_msg_prot) * 2; + patched_cb = true; + } else { + /* CB size of collective slave queues contains + * 4 msg short packets for monitor configuration + * 1 fence packet + * 1 additional msg short packet for sob signal + */ + cb_size = sizeof(struct packet_msg_short) * 5 + + sizeof(struct packet_fence); + patched_cb = false; + } + + hw_queue_prop = &hdev->asic_prop.hw_queues_props[queue_id]; + job = hl_cs_allocate_job(hdev, hw_queue_prop->type, true); + if (!job) { + atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); + atomic64_inc(&cntr->out_of_mem_drop_cnt); + dev_err(hdev->dev, "Failed to allocate a new job\n"); + return -ENOMEM; + } + + /* Allocate internal mapped CB for non patched CBs */ + cb = hl_cb_kernel_create(hdev, cb_size, + hdev->mmu_enable && !patched_cb); + if (!cb) { + atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); + atomic64_inc(&cntr->out_of_mem_drop_cnt); + kfree(job); + return -EFAULT; + } + + job->id = 0; + job->cs = cs; + job->user_cb = cb; + atomic_inc(&job->user_cb->cs_cnt); + job->user_cb_size = cb_size; + job->hw_queue_id = queue_id; + + /* + * No need in parsing, user CB is the patched CB. + * We call hl_cb_destroy() out of two reasons - we don't need + * the CB in the CB idr anymore and to decrement its refcount as + * it was incremented inside hl_cb_kernel_create(). + */ + if (patched_cb) + job->patched_cb = job->user_cb; + else + job->patched_cb = NULL; + + job->job_cb_size = job->user_cb_size; + hl_cb_destroy(hdev, &hdev->kernel_cb_mgr, cb->id << PAGE_SHIFT); + + /* increment refcount as for external queues we get completion */ + if (hw_queue_prop->type == QUEUE_TYPE_EXT) + cs_get(cs); + + cs->jobs_in_queue_cnt[job->hw_queue_id]++; + + list_add_tail(&job->cs_node, &cs->job_list); + + hl_debugfs_add_job(hdev, job); + + return 0; +} + +static int gaudi_collective_wait_create_jobs(struct hl_device *hdev, + struct hl_ctx *ctx, struct hl_cs *cs, u32 wait_queue_id, + u32 collective_engine_id) +{ + struct gaudi_device *gaudi = hdev->asic_specific; + struct hw_queue_properties *hw_queue_prop; + u32 queue_id, collective_queue, num_jobs; + u32 stream, nic_queue, nic_idx = 0; + bool skip; + int i, rc; + + /* Verify wait queue id is configured as master */ + hw_queue_prop = &hdev->asic_prop.hw_queues_props[wait_queue_id]; + if (!(hw_queue_prop->collective_mode == HL_COLLECTIVE_MASTER)) { + dev_err(hdev->dev, + "Queue %d is not configured as collective master\n", + wait_queue_id); + return -EINVAL; + } + + /* Verify engine id is supported */ + if (collective_engine_id != GAUDI_ENGINE_ID_DMA_5 && + collective_engine_id != GAUDI_ENGINE_ID_TPC_7) { + dev_err(hdev->dev, + "Collective wait does not support engine %u\n", + collective_engine_id); + return -EINVAL; + } + + stream = wait_queue_id % 4; + + if (collective_engine_id == GAUDI_ENGINE_ID_DMA_5) + collective_queue = GAUDI_QUEUE_ID_DMA_5_0 + stream; + else + collective_queue = GAUDI_QUEUE_ID_TPC_7_0 + stream; + + num_jobs = NUMBER_OF_SOBS_IN_GRP + 1; + nic_queue = GAUDI_QUEUE_ID_NIC_0_0 + stream; + + /* First job goes to the collective master queue, it will wait for + * the collective slave queues to finish execution. + * The synchronization is done using two monitors: + * First monitor for NICs 0-7, second monitor for NICs 8-9 and the + * reduction engine (DMA5/TPC7). + * + * Rest of the jobs goes to the collective slave queues which will + * all wait for the user to signal sob 'cs_cmpl->sob_val'. + */ + for (i = 0 ; i < num_jobs ; i++) { + if (i == 0) { + queue_id = wait_queue_id; + rc = gaudi_collective_wait_create_job(hdev, ctx, cs, + HL_COLLECTIVE_MASTER, queue_id, wait_queue_id); + } else { + if (nic_idx < NIC_NUMBER_OF_ENGINES) { + if (gaudi->hw_cap_initialized & + BIT(HW_CAP_NIC_SHIFT + nic_idx)) + skip = false; + else + skip = true; + + queue_id = nic_queue; + nic_queue += 4; + nic_idx++; + + if (skip) + continue; + } else { + queue_id = collective_queue; + } + + rc = gaudi_collective_wait_create_job(hdev, ctx, cs, + HL_COLLECTIVE_SLAVE, queue_id, wait_queue_id); + } + + if (rc) + return rc; + } + + return rc; +} + static int gaudi_late_init(struct hl_device *hdev) { struct gaudi_device *gaudi = hdev->asic_specific; @@ -798,6 +1372,27 @@ static int gaudi_late_init(struct hl_device *hdev) return rc; } + if ((hdev->card_type == cpucp_card_type_pci) && + (hdev->nic_ports_mask & 0x3)) { + dev_info(hdev->dev, + "PCI card detected, only 8 ports are enabled\n"); + hdev->nic_ports_mask &= ~0x3; + + /* Stop and disable unused NIC QMANs */ + WREG32(mmNIC0_QM0_GLBL_CFG1, NIC0_QM0_GLBL_CFG1_PQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CP_STOP_MASK); + + WREG32(mmNIC0_QM1_GLBL_CFG1, NIC0_QM0_GLBL_CFG1_PQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CP_STOP_MASK); + + WREG32(mmNIC0_QM0_GLBL_CFG0, 0); + WREG32(mmNIC0_QM1_GLBL_CFG0, 0); + + gaudi->hw_cap_initialized &= ~(HW_CAP_NIC0 | HW_CAP_NIC1); + } + rc = hl_fw_send_pci_access_msg(hdev, CPUCP_PACKET_ENABLE_PCI_ACCESS); if (rc) { dev_err(hdev->dev, "Failed to enable PCI access from CPU\n"); @@ -806,7 +1401,11 @@ static int gaudi_late_init(struct hl_device *hdev) WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, GAUDI_EVENT_INTS_REGISTER); - gaudi_fetch_psoc_frequency(hdev); + rc = gaudi_fetch_psoc_frequency(hdev); + if (rc) { + dev_err(hdev->dev, "Failed to fetch psoc frequency\n"); + goto disable_pci_access; + } rc = gaudi_mmu_clear_pgt_range(hdev); if (rc) { @@ -820,6 +1419,12 @@ static int gaudi_late_init(struct hl_device *hdev) goto disable_pci_access; } + rc = gaudi_collective_init(hdev); + if (rc) { + dev_err(hdev->dev, "Failed to init collective\n"); + goto disable_pci_access; + } + return 0; disable_pci_access: @@ -893,7 +1498,8 @@ static int gaudi_alloc_cpu_accessible_dma_mem(struct hl_device *hdev) hdev->cpu_pci_msb_addr = GAUDI_CPU_PCI_MSB_ADDR(hdev->cpu_accessible_dma_address); - GAUDI_PCI_TO_CPU_ADDR(hdev->cpu_accessible_dma_address); + if (hdev->asic_prop.fw_security_disabled) + GAUDI_PCI_TO_CPU_ADDR(hdev->cpu_accessible_dma_address); free_dma_mem_arr: for (j = 0 ; j < i ; j++) @@ -934,8 +1540,7 @@ static int gaudi_alloc_internal_qmans_pq_mem(struct hl_device *hdev) q = &gaudi->internal_qmans[i]; switch (i) { - case GAUDI_QUEUE_ID_DMA_2_0 ... GAUDI_QUEUE_ID_DMA_4_3: - case GAUDI_QUEUE_ID_DMA_6_0 ... GAUDI_QUEUE_ID_DMA_7_3: + case GAUDI_QUEUE_ID_DMA_2_0 ... GAUDI_QUEUE_ID_DMA_7_3: q->pq_size = HBM_DMA_QMAN_SIZE_IN_BYTES; break; case GAUDI_QUEUE_ID_MME_0_0 ... GAUDI_QUEUE_ID_MME_1_3: @@ -944,6 +1549,9 @@ static int gaudi_alloc_internal_qmans_pq_mem(struct hl_device *hdev) case GAUDI_QUEUE_ID_TPC_0_0 ... GAUDI_QUEUE_ID_TPC_7_3: q->pq_size = TPC_QMAN_SIZE_IN_BYTES; break; + case GAUDI_QUEUE_ID_NIC_0_0 ... GAUDI_QUEUE_ID_NIC_9_3: + q->pq_size = NIC_QMAN_SIZE_IN_BYTES; + break; default: dev_err(hdev->dev, "Bad internal queue index %d", i); rc = -EINVAL; @@ -1045,8 +1653,9 @@ static int gaudi_sw_init(struct hl_device *hdev) free_cpu_accessible_dma_pool: gen_pool_destroy(hdev->cpu_accessible_dma_pool); free_cpu_dma_mem: - GAUDI_CPU_TO_PCI_ADDR(hdev->cpu_accessible_dma_address, - hdev->cpu_pci_msb_addr); + if (hdev->asic_prop.fw_security_disabled) + GAUDI_CPU_TO_PCI_ADDR(hdev->cpu_accessible_dma_address, + hdev->cpu_pci_msb_addr); hdev->asic_funcs->asic_dma_free_coherent(hdev, HL_CPU_ACCESSIBLE_MEM_SIZE, hdev->cpu_accessible_dma_mem, @@ -1066,8 +1675,10 @@ static int gaudi_sw_fini(struct hl_device *hdev) gen_pool_destroy(hdev->cpu_accessible_dma_pool); - GAUDI_CPU_TO_PCI_ADDR(hdev->cpu_accessible_dma_address, + if (hdev->asic_prop.fw_security_disabled) + GAUDI_CPU_TO_PCI_ADDR(hdev->cpu_accessible_dma_address, hdev->cpu_pci_msb_addr); + hdev->asic_funcs->asic_dma_free_coherent(hdev, HL_CPU_ACCESSIBLE_MEM_SIZE, hdev->cpu_accessible_dma_mem, @@ -1121,7 +1732,7 @@ static int gaudi_enable_msi_single(struct hl_device *hdev) { int rc, irq; - dev_info(hdev->dev, "Working in single MSI IRQ mode\n"); + dev_dbg(hdev->dev, "Working in single MSI IRQ mode\n"); irq = gaudi_pci_irq_vector(hdev, 0, false); rc = request_irq(irq, gaudi_irq_handler_single, 0, @@ -1253,6 +1864,14 @@ static void gaudi_init_scrambler_sram(struct hl_device *hdev) { struct gaudi_device *gaudi = hdev->asic_specific; + if (!hdev->asic_prop.fw_security_disabled) + return; + + if (hdev->asic_prop.fw_security_status_valid && + (hdev->asic_prop.fw_app_security_map & + CPU_BOOT_DEV_STS0_SRAM_SCR_EN)) + return; + if (gaudi->hw_cap_initialized & HW_CAP_SRAM_SCRAMBLER) return; @@ -1317,6 +1936,14 @@ static void gaudi_init_scrambler_hbm(struct hl_device *hdev) { struct gaudi_device *gaudi = hdev->asic_specific; + if (!hdev->asic_prop.fw_security_disabled) + return; + + if (hdev->asic_prop.fw_security_status_valid && + (hdev->asic_prop.fw_boot_cpu_security_map & + CPU_BOOT_DEV_STS0_DRAM_SCR_EN)) + return; + if (gaudi->hw_cap_initialized & HW_CAP_HBM_SCRAMBLER) return; @@ -1379,6 +2006,14 @@ static void gaudi_init_scrambler_hbm(struct hl_device *hdev) static void gaudi_init_e2e(struct hl_device *hdev) { + if (!hdev->asic_prop.fw_security_disabled) + return; + + if (hdev->asic_prop.fw_security_status_valid && + (hdev->asic_prop.fw_boot_cpu_security_map & + CPU_BOOT_DEV_STS0_E2E_CRED_EN)) + return; + WREG32(mmSIF_RTR_CTRL_0_E2E_HBM_WR_SIZE, 247 >> 3); WREG32(mmSIF_RTR_CTRL_0_E2E_HBM_RD_SIZE, 785 >> 3); WREG32(mmSIF_RTR_CTRL_0_E2E_PCI_WR_SIZE, 49); @@ -1746,6 +2381,14 @@ static void gaudi_init_hbm_cred(struct hl_device *hdev) { uint32_t hbm0_wr, hbm1_wr, hbm0_rd, hbm1_rd; + if (!hdev->asic_prop.fw_security_disabled) + return; + + if (hdev->asic_prop.fw_security_status_valid && + (hdev->asic_prop.fw_boot_cpu_security_map & + CPU_BOOT_DEV_STS0_HBM_CRED_EN)) + return; + hbm0_wr = 0x33333333; hbm0_rd = 0x77777777; hbm1_wr = 0x55555555; @@ -1804,7 +2447,6 @@ static void gaudi_init_golden_registers(struct hl_device *hdev) int tpc_id, i; gaudi_init_e2e(hdev); - gaudi_init_hbm_cred(hdev); hdev->asic_funcs->disable_clock_gating(hdev); @@ -1999,21 +2641,29 @@ static void gaudi_init_pci_dma_qmans(struct hl_device *hdev) static void gaudi_init_hbm_dma_qman(struct hl_device *hdev, int dma_id, int qman_id, u64 qman_base_addr) { - u32 mtr_base_lo, mtr_base_hi; - u32 so_base_lo, so_base_hi; + u32 mtr_base_en_lo, mtr_base_en_hi, mtr_base_ws_lo, mtr_base_ws_hi; + u32 so_base_en_lo, so_base_en_hi, so_base_ws_lo, so_base_ws_hi; u32 q_off, dma_qm_offset; u32 dma_qm_err_cfg; dma_qm_offset = dma_id * DMA_QMAN_OFFSET; - mtr_base_lo = lower_32_bits(CFG_BASE + - mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); - mtr_base_hi = upper_32_bits(CFG_BASE + + mtr_base_en_lo = lower_32_bits(CFG_BASE + + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); + mtr_base_en_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); - so_base_lo = lower_32_bits(CFG_BASE + + so_base_en_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0); - so_base_hi = upper_32_bits(CFG_BASE + + so_base_en_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0); + mtr_base_ws_lo = lower_32_bits(CFG_BASE + + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); + mtr_base_ws_hi = upper_32_bits(CFG_BASE + + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); + so_base_ws_lo = lower_32_bits(CFG_BASE + + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_SOB_OBJ_0); + so_base_ws_hi = upper_32_bits(CFG_BASE + + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_SOB_OBJ_0); q_off = dma_qm_offset + qman_id * 4; @@ -2071,10 +2721,22 @@ static void gaudi_init_hbm_dma_qman(struct hl_device *hdev, int dma_id, QMAN_INTERNAL_MAKE_TRUSTED); } - WREG32(mmDMA0_QM_CP_MSG_BASE0_ADDR_LO_0 + q_off, mtr_base_lo); - WREG32(mmDMA0_QM_CP_MSG_BASE0_ADDR_HI_0 + q_off, mtr_base_hi); - WREG32(mmDMA0_QM_CP_MSG_BASE1_ADDR_LO_0 + q_off, so_base_lo); - WREG32(mmDMA0_QM_CP_MSG_BASE1_ADDR_HI_0 + q_off, so_base_hi); + WREG32(mmDMA0_QM_CP_MSG_BASE0_ADDR_LO_0 + q_off, mtr_base_en_lo); + WREG32(mmDMA0_QM_CP_MSG_BASE0_ADDR_HI_0 + q_off, mtr_base_en_hi); + WREG32(mmDMA0_QM_CP_MSG_BASE1_ADDR_LO_0 + q_off, so_base_en_lo); + WREG32(mmDMA0_QM_CP_MSG_BASE1_ADDR_HI_0 + q_off, so_base_en_hi); + + /* Configure DMA5 CP_MSG_BASE 2/3 for sync stream collective */ + if (gaudi_dma_assignment[dma_id] == GAUDI_ENGINE_ID_DMA_5) { + WREG32(mmDMA0_QM_CP_MSG_BASE2_ADDR_LO_0 + q_off, + mtr_base_ws_lo); + WREG32(mmDMA0_QM_CP_MSG_BASE2_ADDR_HI_0 + q_off, + mtr_base_ws_hi); + WREG32(mmDMA0_QM_CP_MSG_BASE3_ADDR_LO_0 + q_off, + so_base_ws_lo); + WREG32(mmDMA0_QM_CP_MSG_BASE3_ADDR_HI_0 + q_off, + so_base_ws_hi); + } } static void gaudi_init_hbm_dma_qmans(struct hl_device *hdev) @@ -2237,22 +2899,33 @@ static void gaudi_init_mme_qmans(struct hl_device *hdev) static void gaudi_init_tpc_qman(struct hl_device *hdev, u32 tpc_offset, int qman_id, u64 qman_base_addr) { - u32 mtr_base_lo, mtr_base_hi; - u32 so_base_lo, so_base_hi; + u32 mtr_base_en_lo, mtr_base_en_hi, mtr_base_ws_lo, mtr_base_ws_hi; + u32 so_base_en_lo, so_base_en_hi, so_base_ws_lo, so_base_ws_hi; u32 q_off, tpc_id; u32 tpc_qm_err_cfg; - mtr_base_lo = lower_32_bits(CFG_BASE + - mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); - mtr_base_hi = upper_32_bits(CFG_BASE + + mtr_base_en_lo = lower_32_bits(CFG_BASE + + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); + mtr_base_en_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); - so_base_lo = lower_32_bits(CFG_BASE + + so_base_en_lo = lower_32_bits(CFG_BASE + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0); - so_base_hi = upper_32_bits(CFG_BASE + + so_base_en_hi = upper_32_bits(CFG_BASE + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0); + mtr_base_ws_lo = lower_32_bits(CFG_BASE + + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); + mtr_base_ws_hi = upper_32_bits(CFG_BASE + + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); + so_base_ws_lo = lower_32_bits(CFG_BASE + + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_SOB_OBJ_0); + so_base_ws_hi = upper_32_bits(CFG_BASE + + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_SOB_OBJ_0); q_off = tpc_offset + qman_id * 4; + tpc_id = tpc_offset / + (mmTPC1_QM_GLBL_CFG0 - mmTPC0_QM_GLBL_CFG0); + if (qman_id < 4) { WREG32(mmTPC0_QM_PQ_BASE_LO_0 + q_off, lower_32_bits(qman_base_addr)); @@ -2278,9 +2951,6 @@ static void gaudi_init_tpc_qman(struct hl_device *hdev, u32 tpc_offset, QMAN_LDMA_DST_OFFSET); /* Configure RAZWI IRQ */ - tpc_id = tpc_offset / - (mmTPC1_QM_GLBL_CFG0 - mmTPC0_QM_GLBL_CFG0); - tpc_qm_err_cfg = TPC_QMAN_GLBL_ERR_CFG_MSG_EN_MASK; if (hdev->stop_on_err) { tpc_qm_err_cfg |= @@ -2310,10 +2980,22 @@ static void gaudi_init_tpc_qman(struct hl_device *hdev, u32 tpc_offset, QMAN_INTERNAL_MAKE_TRUSTED); } - WREG32(mmTPC0_QM_CP_MSG_BASE0_ADDR_LO_0 + q_off, mtr_base_lo); - WREG32(mmTPC0_QM_CP_MSG_BASE0_ADDR_HI_0 + q_off, mtr_base_hi); - WREG32(mmTPC0_QM_CP_MSG_BASE1_ADDR_LO_0 + q_off, so_base_lo); - WREG32(mmTPC0_QM_CP_MSG_BASE1_ADDR_HI_0 + q_off, so_base_hi); + WREG32(mmTPC0_QM_CP_MSG_BASE0_ADDR_LO_0 + q_off, mtr_base_en_lo); + WREG32(mmTPC0_QM_CP_MSG_BASE0_ADDR_HI_0 + q_off, mtr_base_en_hi); + WREG32(mmTPC0_QM_CP_MSG_BASE1_ADDR_LO_0 + q_off, so_base_en_lo); + WREG32(mmTPC0_QM_CP_MSG_BASE1_ADDR_HI_0 + q_off, so_base_en_hi); + + /* Configure TPC7 CP_MSG_BASE 2/3 for sync stream collective */ + if (tpc_id == 6) { + WREG32(mmTPC0_QM_CP_MSG_BASE2_ADDR_LO_0 + q_off, + mtr_base_ws_lo); + WREG32(mmTPC0_QM_CP_MSG_BASE2_ADDR_HI_0 + q_off, + mtr_base_ws_hi); + WREG32(mmTPC0_QM_CP_MSG_BASE3_ADDR_LO_0 + q_off, + so_base_ws_lo); + WREG32(mmTPC0_QM_CP_MSG_BASE3_ADDR_HI_0 + q_off, + so_base_ws_hi); + } } static void gaudi_init_tpc_qmans(struct hl_device *hdev) @@ -2361,6 +3043,142 @@ static void gaudi_init_tpc_qmans(struct hl_device *hdev) } } +static void gaudi_init_nic_qman(struct hl_device *hdev, u32 nic_offset, + int qman_id, u64 qman_base_addr, int nic_id) +{ + u32 mtr_base_en_lo, mtr_base_en_hi, mtr_base_ws_lo, mtr_base_ws_hi; + u32 so_base_en_lo, so_base_en_hi, so_base_ws_lo, so_base_ws_hi; + u32 q_off; + u32 nic_qm_err_cfg; + + mtr_base_en_lo = lower_32_bits(CFG_BASE + + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); + mtr_base_en_hi = upper_32_bits(CFG_BASE + + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); + so_base_en_lo = lower_32_bits(CFG_BASE + + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0); + so_base_en_hi = upper_32_bits(CFG_BASE + + mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0); + mtr_base_ws_lo = lower_32_bits(CFG_BASE + + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); + mtr_base_ws_hi = upper_32_bits(CFG_BASE + + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0); + so_base_ws_lo = lower_32_bits(CFG_BASE + + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_SOB_OBJ_0); + so_base_ws_hi = upper_32_bits(CFG_BASE + + mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_SOB_OBJ_0); + + q_off = nic_offset + qman_id * 4; + + WREG32(mmNIC0_QM0_PQ_BASE_LO_0 + q_off, lower_32_bits(qman_base_addr)); + WREG32(mmNIC0_QM0_PQ_BASE_HI_0 + q_off, upper_32_bits(qman_base_addr)); + + WREG32(mmNIC0_QM0_PQ_SIZE_0 + q_off, ilog2(NIC_QMAN_LENGTH)); + WREG32(mmNIC0_QM0_PQ_PI_0 + q_off, 0); + WREG32(mmNIC0_QM0_PQ_CI_0 + q_off, 0); + + WREG32(mmNIC0_QM0_CP_LDMA_TSIZE_OFFSET_0 + q_off, + QMAN_LDMA_SIZE_OFFSET); + WREG32(mmNIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_0 + q_off, + QMAN_LDMA_SRC_OFFSET); + WREG32(mmNIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_0 + q_off, + QMAN_LDMA_DST_OFFSET); + + WREG32(mmNIC0_QM0_CP_MSG_BASE0_ADDR_LO_0 + q_off, mtr_base_en_lo); + WREG32(mmNIC0_QM0_CP_MSG_BASE0_ADDR_HI_0 + q_off, mtr_base_en_hi); + WREG32(mmNIC0_QM0_CP_MSG_BASE1_ADDR_LO_0 + q_off, so_base_en_lo); + WREG32(mmNIC0_QM0_CP_MSG_BASE1_ADDR_HI_0 + q_off, so_base_en_hi); + + /* Configure NIC CP_MSG_BASE 2/3 for sync stream collective */ + WREG32(mmNIC0_QM0_CP_MSG_BASE2_ADDR_LO_0 + q_off, mtr_base_ws_lo); + WREG32(mmNIC0_QM0_CP_MSG_BASE2_ADDR_HI_0 + q_off, mtr_base_ws_hi); + WREG32(mmNIC0_QM0_CP_MSG_BASE3_ADDR_LO_0 + q_off, so_base_ws_lo); + WREG32(mmNIC0_QM0_CP_MSG_BASE3_ADDR_HI_0 + q_off, so_base_ws_hi); + + if (qman_id == 0) { + /* Configure RAZWI IRQ */ + nic_qm_err_cfg = NIC_QMAN_GLBL_ERR_CFG_MSG_EN_MASK; + if (hdev->stop_on_err) { + nic_qm_err_cfg |= + NIC_QMAN_GLBL_ERR_CFG_STOP_ON_ERR_EN_MASK; + } + + WREG32(mmNIC0_QM0_GLBL_ERR_CFG + nic_offset, nic_qm_err_cfg); + WREG32(mmNIC0_QM0_GLBL_ERR_ADDR_LO + nic_offset, + lower_32_bits(CFG_BASE + + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR)); + WREG32(mmNIC0_QM0_GLBL_ERR_ADDR_HI + nic_offset, + upper_32_bits(CFG_BASE + + mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR)); + WREG32(mmNIC0_QM0_GLBL_ERR_WDATA + nic_offset, + gaudi_irq_map_table[GAUDI_EVENT_NIC0_QM0].cpu_id + + nic_id); + + WREG32(mmNIC0_QM0_ARB_ERR_MSG_EN + nic_offset, + QM_ARB_ERR_MSG_EN_MASK); + + /* Increase ARB WDT to support streams architecture */ + WREG32(mmNIC0_QM0_ARB_SLV_CHOISE_WDT + nic_offset, + GAUDI_ARB_WDT_TIMEOUT); + + WREG32(mmNIC0_QM0_GLBL_CFG1 + nic_offset, 0); + WREG32(mmNIC0_QM0_GLBL_PROT + nic_offset, + QMAN_INTERNAL_MAKE_TRUSTED); + } +} + +static void gaudi_init_nic_qmans(struct hl_device *hdev) +{ + struct gaudi_device *gaudi = hdev->asic_specific; + struct gaudi_internal_qman_info *q; + u64 qman_base_addr; + u32 nic_offset = 0; + u32 nic_delta_between_qmans = + mmNIC0_QM1_GLBL_CFG0 - mmNIC0_QM0_GLBL_CFG0; + u32 nic_delta_between_nics = + mmNIC1_QM0_GLBL_CFG0 - mmNIC0_QM0_GLBL_CFG0; + int i, nic_id, internal_q_index; + + if (!hdev->nic_ports_mask) + return; + + if (gaudi->hw_cap_initialized & HW_CAP_NIC_MASK) + return; + + dev_dbg(hdev->dev, "Initializing NIC QMANs\n"); + + for (nic_id = 0 ; nic_id < NIC_NUMBER_OF_ENGINES ; nic_id++) { + if (!(hdev->nic_ports_mask & (1 << nic_id))) { + nic_offset += nic_delta_between_qmans; + if (nic_id & 1) { + nic_offset -= (nic_delta_between_qmans * 2); + nic_offset += nic_delta_between_nics; + } + continue; + } + + for (i = 0 ; i < QMAN_STREAMS ; i++) { + internal_q_index = GAUDI_QUEUE_ID_NIC_0_0 + + nic_id * QMAN_STREAMS + i; + q = &gaudi->internal_qmans[internal_q_index]; + qman_base_addr = (u64) q->pq_dma_addr; + gaudi_init_nic_qman(hdev, nic_offset, (i & 0x3), + qman_base_addr, nic_id); + } + + /* Enable the QMAN */ + WREG32(mmNIC0_QM0_GLBL_CFG0 + nic_offset, NIC_QMAN_ENABLE); + + nic_offset += nic_delta_between_qmans; + if (nic_id & 1) { + nic_offset -= (nic_delta_between_qmans * 2); + nic_offset += nic_delta_between_nics; + } + + gaudi->hw_cap_initialized |= 1 << (HW_CAP_NIC_SHIFT + nic_id); + } +} + static void gaudi_disable_pci_dma_qmans(struct hl_device *hdev) { struct gaudi_device *gaudi = hdev->asic_specific; @@ -2413,6 +3231,30 @@ static void gaudi_disable_tpc_qmans(struct hl_device *hdev) } } +static void gaudi_disable_nic_qmans(struct hl_device *hdev) +{ + struct gaudi_device *gaudi = hdev->asic_specific; + u32 nic_mask, nic_offset = 0; + u32 nic_delta_between_qmans = + mmNIC0_QM1_GLBL_CFG0 - mmNIC0_QM0_GLBL_CFG0; + u32 nic_delta_between_nics = + mmNIC1_QM0_GLBL_CFG0 - mmNIC0_QM0_GLBL_CFG0; + int nic_id; + + for (nic_id = 0 ; nic_id < NIC_NUMBER_OF_ENGINES ; nic_id++) { + nic_mask = 1 << (HW_CAP_NIC_SHIFT + nic_id); + + if (gaudi->hw_cap_initialized & nic_mask) + WREG32(mmNIC0_QM0_GLBL_CFG0 + nic_offset, 0); + + nic_offset += nic_delta_between_qmans; + if (nic_id & 1) { + nic_offset -= (nic_delta_between_qmans * 2); + nic_offset += nic_delta_between_nics; + } + } +} + static void gaudi_stop_pci_dma_qmans(struct hl_device *hdev) { struct gaudi_device *gaudi = hdev->asic_specific; @@ -2471,6 +3313,73 @@ static void gaudi_stop_tpc_qmans(struct hl_device *hdev) WREG32(mmTPC7_QM_GLBL_CFG1, 0x1F << TPC0_QM_GLBL_CFG1_CP_STOP_SHIFT); } +static void gaudi_stop_nic_qmans(struct hl_device *hdev) +{ + struct gaudi_device *gaudi = hdev->asic_specific; + + /* Stop upper CPs of QMANs */ + + if (gaudi->hw_cap_initialized & HW_CAP_NIC0) + WREG32(mmNIC0_QM0_GLBL_CFG1, + NIC0_QM0_GLBL_CFG1_PQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CP_STOP_MASK); + + if (gaudi->hw_cap_initialized & HW_CAP_NIC1) + WREG32(mmNIC0_QM1_GLBL_CFG1, + NIC0_QM0_GLBL_CFG1_PQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CP_STOP_MASK); + + if (gaudi->hw_cap_initialized & HW_CAP_NIC2) + WREG32(mmNIC1_QM0_GLBL_CFG1, + NIC0_QM0_GLBL_CFG1_PQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CP_STOP_MASK); + + if (gaudi->hw_cap_initialized & HW_CAP_NIC3) + WREG32(mmNIC1_QM1_GLBL_CFG1, + NIC0_QM0_GLBL_CFG1_PQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CP_STOP_MASK); + + if (gaudi->hw_cap_initialized & HW_CAP_NIC4) + WREG32(mmNIC2_QM0_GLBL_CFG1, + NIC0_QM0_GLBL_CFG1_PQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CP_STOP_MASK); + + if (gaudi->hw_cap_initialized & HW_CAP_NIC5) + WREG32(mmNIC2_QM1_GLBL_CFG1, + NIC0_QM0_GLBL_CFG1_PQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CP_STOP_MASK); + + if (gaudi->hw_cap_initialized & HW_CAP_NIC6) + WREG32(mmNIC3_QM0_GLBL_CFG1, + NIC0_QM0_GLBL_CFG1_PQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CP_STOP_MASK); + + if (gaudi->hw_cap_initialized & HW_CAP_NIC7) + WREG32(mmNIC3_QM1_GLBL_CFG1, + NIC0_QM0_GLBL_CFG1_PQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CP_STOP_MASK); + + if (gaudi->hw_cap_initialized & HW_CAP_NIC8) + WREG32(mmNIC4_QM0_GLBL_CFG1, + NIC0_QM0_GLBL_CFG1_PQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CP_STOP_MASK); + + if (gaudi->hw_cap_initialized & HW_CAP_NIC9) + WREG32(mmNIC4_QM1_GLBL_CFG1, + NIC0_QM0_GLBL_CFG1_PQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CQF_STOP_MASK | + NIC0_QM0_GLBL_CFG1_CP_STOP_MASK); +} + static void gaudi_pci_dma_stall(struct hl_device *hdev) { struct gaudi_device *gaudi = hdev->asic_specific; @@ -2660,7 +3569,7 @@ static void gaudi_halt_engines(struct hl_device *hdev, bool hard_reset) else wait_timeout_ms = GAUDI_RESET_WAIT_MSEC; - + gaudi_stop_nic_qmans(hdev); gaudi_stop_mme_qmans(hdev); gaudi_stop_tpc_qmans(hdev); gaudi_stop_hbm_dma_qmans(hdev); @@ -2677,6 +3586,7 @@ static void gaudi_halt_engines(struct hl_device *hdev, bool hard_reset) msleep(wait_timeout_ms); + gaudi_disable_nic_qmans(hdev); gaudi_disable_mme_qmans(hdev); gaudi_disable_tpc_qmans(hdev); gaudi_disable_hbm_dma_qmans(hdev); @@ -2700,8 +3610,6 @@ static int gaudi_mmu_init(struct hl_device *hdev) if (gaudi->hw_cap_initialized & HW_CAP_MMU) return 0; - hdev->dram_supports_virtual_memory = false; - for (i = 0 ; i < prop->max_asid ; i++) { hop0_addr = prop->mmu_pgt_addr + (i * prop->mmu_hop_table_size); @@ -2749,7 +3657,7 @@ static int gaudi_load_firmware_to_device(struct hl_device *hdev) dst = hdev->pcie_bar[HBM_BAR_ID] + LINUX_FW_OFFSET; - return hl_fw_load_fw_to_device(hdev, GAUDI_LINUX_FW_FILE, dst); + return hl_fw_load_fw_to_device(hdev, GAUDI_LINUX_FW_FILE, dst, 0, 0); } static int gaudi_load_boot_fit_to_device(struct hl_device *hdev) @@ -2758,10 +3666,10 @@ static int gaudi_load_boot_fit_to_device(struct hl_device *hdev) dst = hdev->pcie_bar[SRAM_BAR_ID] + BOOT_FIT_SRAM_OFFSET; - return hl_fw_load_fw_to_device(hdev, GAUDI_BOOT_FIT_FILE, dst); + return hl_fw_load_fw_to_device(hdev, GAUDI_BOOT_FIT_FILE, dst, 0, 0); } -static void gaudi_read_device_fw_version(struct hl_device *hdev, +static int gaudi_read_device_fw_version(struct hl_device *hdev, enum hl_fw_component fwc) { const char *name; @@ -2781,7 +3689,7 @@ static void gaudi_read_device_fw_version(struct hl_device *hdev, break; default: dev_warn(hdev->dev, "Undefined FW component: %d\n", fwc); - return; + return -EIO; } ver_off &= ~((u32)SRAM_BASE_ADDR); @@ -2793,7 +3701,10 @@ static void gaudi_read_device_fw_version(struct hl_device *hdev, dev_err(hdev->dev, "%s version offset (0x%x) is above SRAM\n", name, ver_off); strcpy(dest, "unavailable"); + return -EIO; } + + return 0; } static int gaudi_init_cpu(struct hl_device *hdev) @@ -2811,12 +3722,13 @@ static int gaudi_init_cpu(struct hl_device *hdev) * The device CPU works with 40 bits addresses. * This register sets the extension to 50 bits. */ - WREG32(mmCPU_IF_CPU_MSB_ADDR, hdev->cpu_pci_msb_addr); + if (hdev->asic_prop.fw_security_disabled) + WREG32(mmCPU_IF_CPU_MSB_ADDR, hdev->cpu_pci_msb_addr); rc = hl_fw_init_cpu(hdev, mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS, mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU, mmCPU_CMD_STATUS_TO_HOST, - mmCPU_BOOT_ERR0, + mmCPU_BOOT_DEV_STS0, mmCPU_BOOT_ERR0, !hdev->bmc_enable, GAUDI_CPU_TIMEOUT_USEC, GAUDI_BOOT_FIT_REQ_TIMEOUT_USEC); @@ -2896,17 +3808,19 @@ static void gaudi_pre_hw_init(struct hl_device *hdev) /* Perform read from the device to make sure device is up */ RREG32(mmPCIE_DBI_DEVICE_ID_VENDOR_ID_REG); - /* Set the access through PCI bars (Linux driver only) as - * secured - */ - WREG32(mmPCIE_WRAP_LBW_PROT_OVR, - (PCIE_WRAP_LBW_PROT_OVR_RD_EN_MASK | - PCIE_WRAP_LBW_PROT_OVR_WR_EN_MASK)); + if (hdev->asic_prop.fw_security_disabled) { + /* Set the access through PCI bars (Linux driver only) as + * secured + */ + WREG32(mmPCIE_WRAP_LBW_PROT_OVR, + (PCIE_WRAP_LBW_PROT_OVR_RD_EN_MASK | + PCIE_WRAP_LBW_PROT_OVR_WR_EN_MASK)); - /* Perform read to flush the waiting writes to ensure - * configuration was set in the device - */ - RREG32(mmPCIE_WRAP_LBW_PROT_OVR); + /* Perform read to flush the waiting writes to ensure + * configuration was set in the device + */ + RREG32(mmPCIE_WRAP_LBW_PROT_OVR); + } /* * Let's mark in the H/W that we have reached this point. We check @@ -2915,40 +3829,12 @@ static void gaudi_pre_hw_init(struct hl_device *hdev) * cleared by the H/W upon H/W reset */ WREG32(mmHW_STATE, HL_DEVICE_HW_STATE_DIRTY); - - /* Configure the reset registers. Must be done as early as possible - * in case we fail during H/W initialization - */ - WREG32(mmPSOC_GLOBAL_CONF_SOFT_RST_CFG_H, - (CFG_RST_H_DMA_MASK | - CFG_RST_H_MME_MASK | - CFG_RST_H_SM_MASK | - CFG_RST_H_TPC_7_MASK)); - - WREG32(mmPSOC_GLOBAL_CONF_SOFT_RST_CFG_L, CFG_RST_L_TPC_MASK); - - WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST_CFG_H, - (CFG_RST_H_HBM_MASK | - CFG_RST_H_TPC_7_MASK | - CFG_RST_H_NIC_MASK | - CFG_RST_H_SM_MASK | - CFG_RST_H_DMA_MASK | - CFG_RST_H_MME_MASK | - CFG_RST_H_CPU_MASK | - CFG_RST_H_MMU_MASK)); - - WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST_CFG_L, - (CFG_RST_L_IF_MASK | - CFG_RST_L_PSOC_MASK | - CFG_RST_L_TPC_MASK)); } static int gaudi_hw_init(struct hl_device *hdev) { int rc; - dev_info(hdev->dev, "Starting initialization of H/W\n"); - gaudi_pre_hw_init(hdev); gaudi_init_pci_dma_qmans(hdev); @@ -2979,11 +3865,13 @@ static int gaudi_hw_init(struct hl_device *hdev) gaudi_init_tpc_qmans(hdev); + gaudi_init_nic_qmans(hdev); + hdev->asic_funcs->set_clock_gating(hdev); gaudi_enable_timestamp(hdev); - /* MSI must be enabled before CPU queues are initialized */ + /* MSI must be enabled before CPU queues and NIC are initialized */ rc = gaudi_enable_msi(hdev); if (rc) goto disable_queues; @@ -3013,7 +3901,7 @@ disable_queues: static void gaudi_hw_fini(struct hl_device *hdev, bool hard_reset) { struct gaudi_device *gaudi = hdev->asic_specific; - u32 status, reset_timeout_ms, cpu_timeout_ms, boot_strap = 0; + u32 status, reset_timeout_ms, cpu_timeout_ms; if (!hard_reset) { dev_err(hdev->dev, "GAUDI doesn't support soft-reset\n"); @@ -3031,35 +3919,60 @@ static void gaudi_hw_fini(struct hl_device *hdev, bool hard_reset) /* Set device to handle FLR by H/W as we will put the device CPU to * halt mode */ - WREG32(mmPCIE_AUX_FLR_CTRL, (PCIE_AUX_FLR_CTRL_HW_CTRL_MASK | + if (hdev->asic_prop.fw_security_disabled && + !hdev->asic_prop.hard_reset_done_by_fw) + WREG32(mmPCIE_AUX_FLR_CTRL, (PCIE_AUX_FLR_CTRL_HW_CTRL_MASK | PCIE_AUX_FLR_CTRL_INT_MASK_MASK)); /* I don't know what is the state of the CPU so make sure it is * stopped in any means necessary */ WREG32(mmPSOC_GLOBAL_CONF_KMD_MSG_TO_CPU, KMD_MSG_GOTO_WFE); - WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, GAUDI_EVENT_HALT_MACHINE); - - msleep(cpu_timeout_ms); - - /* Tell ASIC not to re-initialize PCIe */ - WREG32(mmPREBOOT_PCIE_EN, LKD_HARD_RESET_MAGIC); - - boot_strap = RREG32(mmPSOC_GLOBAL_CONF_BOOT_STRAP_PINS); - /* H/W bug WA: - * rdata[31:0] = strap_read_val; - * wdata[31:0] = rdata[30:21],1'b0,rdata[20:0] - */ - boot_strap = (((boot_strap & 0x7FE00000) << 1) | - (boot_strap & 0x001FFFFF)); - WREG32(mmPSOC_GLOBAL_CONF_BOOT_STRAP_PINS, boot_strap & ~0x2); + WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, GAUDI_EVENT_HALT_MACHINE); - /* Restart BTL/BLR upon hard-reset */ - WREG32(mmPSOC_GLOBAL_CONF_BOOT_SEQ_RE_START, 1); + if (hdev->asic_prop.fw_security_disabled && + !hdev->asic_prop.hard_reset_done_by_fw) { - WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST, + /* Configure the reset registers. Must be done as early as + * possible in case we fail during H/W initialization + */ + WREG32(mmPSOC_GLOBAL_CONF_SOFT_RST_CFG_H, + (CFG_RST_H_DMA_MASK | + CFG_RST_H_MME_MASK | + CFG_RST_H_SM_MASK | + CFG_RST_H_TPC_7_MASK)); + + WREG32(mmPSOC_GLOBAL_CONF_SOFT_RST_CFG_L, CFG_RST_L_TPC_MASK); + + WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST_CFG_H, + (CFG_RST_H_HBM_MASK | + CFG_RST_H_TPC_7_MASK | + CFG_RST_H_NIC_MASK | + CFG_RST_H_SM_MASK | + CFG_RST_H_DMA_MASK | + CFG_RST_H_MME_MASK | + CFG_RST_H_CPU_MASK | + CFG_RST_H_MMU_MASK)); + + WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST_CFG_L, + (CFG_RST_L_IF_MASK | + CFG_RST_L_PSOC_MASK | + CFG_RST_L_TPC_MASK)); + + msleep(cpu_timeout_ms); + + /* Tell ASIC not to re-initialize PCIe */ + WREG32(mmPREBOOT_PCIE_EN, LKD_HARD_RESET_MAGIC); + + /* Restart BTL/BLR upon hard-reset */ + if (hdev->asic_prop.fw_security_disabled) + WREG32(mmPSOC_GLOBAL_CONF_BOOT_SEQ_RE_START, 1); + + WREG32(mmPSOC_GLOBAL_CONF_SW_ALL_RST, 1 << PSOC_GLOBAL_CONF_SW_ALL_RST_IND_SHIFT); + } + dev_info(hdev->dev, "Issued HARD reset command, going to wait %dms\n", reset_timeout_ms); @@ -3076,18 +3989,18 @@ static void gaudi_hw_fini(struct hl_device *hdev, bool hard_reset) "Timeout while waiting for device to reset 0x%x\n", status); - WREG32(mmPSOC_GLOBAL_CONF_BOOT_STRAP_PINS, boot_strap); - - gaudi->hw_cap_initialized &= ~(HW_CAP_CPU | HW_CAP_CPU_Q | - HW_CAP_HBM | HW_CAP_PCI_DMA | - HW_CAP_MME | HW_CAP_TPC_MASK | - HW_CAP_HBM_DMA | HW_CAP_PLL | - HW_CAP_MMU | - HW_CAP_SRAM_SCRAMBLER | - HW_CAP_HBM_SCRAMBLER | - HW_CAP_CLK_GATE); + if (gaudi) { + gaudi->hw_cap_initialized &= ~(HW_CAP_CPU | HW_CAP_CPU_Q | + HW_CAP_HBM | HW_CAP_PCI_DMA | + HW_CAP_MME | HW_CAP_TPC_MASK | + HW_CAP_HBM_DMA | HW_CAP_PLL | + HW_CAP_NIC_MASK | HW_CAP_MMU | + HW_CAP_SRAM_SCRAMBLER | + HW_CAP_HBM_SCRAMBLER | + HW_CAP_CLK_GATE); - memset(gaudi->events_stat, 0, sizeof(gaudi->events_stat)); + memset(gaudi->events_stat, 0, sizeof(gaudi->events_stat)); + } } static int gaudi_suspend(struct hl_device *hdev) @@ -3165,21 +4078,21 @@ static void gaudi_ring_doorbell(struct hl_device *hdev, u32 hw_queue_id, u32 pi) break; case GAUDI_QUEUE_ID_DMA_5_0...GAUDI_QUEUE_ID_DMA_5_3: - dma_id = gaudi_dma_assignment[GAUDI_PCI_DMA_3]; + dma_id = gaudi_dma_assignment[GAUDI_HBM_DMA_4]; dma_qm_offset = dma_id * DMA_QMAN_OFFSET; q_off = dma_qm_offset + ((hw_queue_id - 1) & 0x3) * 4; db_reg_offset = mmDMA0_QM_PQ_PI_0 + q_off; break; case GAUDI_QUEUE_ID_DMA_6_0...GAUDI_QUEUE_ID_DMA_6_3: - dma_id = gaudi_dma_assignment[GAUDI_HBM_DMA_4]; + dma_id = gaudi_dma_assignment[GAUDI_HBM_DMA_5]; dma_qm_offset = dma_id * DMA_QMAN_OFFSET; q_off = dma_qm_offset + ((hw_queue_id - 1) & 0x3) * 4; db_reg_offset = mmDMA0_QM_PQ_PI_0 + q_off; break; case GAUDI_QUEUE_ID_DMA_7_0...GAUDI_QUEUE_ID_DMA_7_3: - dma_id = gaudi_dma_assignment[GAUDI_HBM_DMA_5]; + dma_id = gaudi_dma_assignment[GAUDI_HBM_DMA_6]; dma_qm_offset = dma_id * DMA_QMAN_OFFSET; q_off = dma_qm_offset + ((hw_queue_id - 1) & 0x3) * 4; db_reg_offset = mmDMA0_QM_PQ_PI_0 + q_off; @@ -3352,6 +4265,166 @@ static void gaudi_ring_doorbell(struct hl_device *hdev, u32 hw_queue_id, u32 pi) db_reg_offset = mmTPC7_QM_PQ_PI_3; break; + case GAUDI_QUEUE_ID_NIC_0_0: + db_reg_offset = mmNIC0_QM0_PQ_PI_0; + break; + + case GAUDI_QUEUE_ID_NIC_0_1: + db_reg_offset = mmNIC0_QM0_PQ_PI_1; + break; + + case GAUDI_QUEUE_ID_NIC_0_2: + db_reg_offset = mmNIC0_QM0_PQ_PI_2; + break; + + case GAUDI_QUEUE_ID_NIC_0_3: + db_reg_offset = mmNIC0_QM0_PQ_PI_3; + break; + + case GAUDI_QUEUE_ID_NIC_1_0: + db_reg_offset = mmNIC0_QM1_PQ_PI_0; + break; + + case GAUDI_QUEUE_ID_NIC_1_1: + db_reg_offset = mmNIC0_QM1_PQ_PI_1; + break; + + case GAUDI_QUEUE_ID_NIC_1_2: + db_reg_offset = mmNIC0_QM1_PQ_PI_2; + break; + + case GAUDI_QUEUE_ID_NIC_1_3: + db_reg_offset = mmNIC0_QM1_PQ_PI_3; + break; + + case GAUDI_QUEUE_ID_NIC_2_0: + db_reg_offset = mmNIC1_QM0_PQ_PI_0; + break; + + case GAUDI_QUEUE_ID_NIC_2_1: + db_reg_offset = mmNIC1_QM0_PQ_PI_1; + break; + + case GAUDI_QUEUE_ID_NIC_2_2: + db_reg_offset = mmNIC1_QM0_PQ_PI_2; + break; + + case GAUDI_QUEUE_ID_NIC_2_3: + db_reg_offset = mmNIC1_QM0_PQ_PI_3; + break; + + case GAUDI_QUEUE_ID_NIC_3_0: + db_reg_offset = mmNIC1_QM1_PQ_PI_0; + break; + + case GAUDI_QUEUE_ID_NIC_3_1: + db_reg_offset = mmNIC1_QM1_PQ_PI_1; + break; + + case GAUDI_QUEUE_ID_NIC_3_2: + db_reg_offset = mmNIC1_QM1_PQ_PI_2; + break; + + case GAUDI_QUEUE_ID_NIC_3_3: + db_reg_offset = mmNIC1_QM1_PQ_PI_3; + break; + + case GAUDI_QUEUE_ID_NIC_4_0: + db_reg_offset = mmNIC2_QM0_PQ_PI_0; + break; + + case GAUDI_QUEUE_ID_NIC_4_1: + db_reg_offset = mmNIC2_QM0_PQ_PI_1; + break; + + case GAUDI_QUEUE_ID_NIC_4_2: + db_reg_offset = mmNIC2_QM0_PQ_PI_2; + break; + + case GAUDI_QUEUE_ID_NIC_4_3: + db_reg_offset = mmNIC2_QM0_PQ_PI_3; + break; + + case GAUDI_QUEUE_ID_NIC_5_0: + db_reg_offset = mmNIC2_QM1_PQ_PI_0; + break; + + case GAUDI_QUEUE_ID_NIC_5_1: + db_reg_offset = mmNIC2_QM1_PQ_PI_1; + break; + + case GAUDI_QUEUE_ID_NIC_5_2: + db_reg_offset = mmNIC2_QM1_PQ_PI_2; + break; + + case GAUDI_QUEUE_ID_NIC_5_3: + db_reg_offset = mmNIC2_QM1_PQ_PI_3; + break; + + case GAUDI_QUEUE_ID_NIC_6_0: + db_reg_offset = mmNIC3_QM0_PQ_PI_0; + break; + + case GAUDI_QUEUE_ID_NIC_6_1: + db_reg_offset = mmNIC3_QM0_PQ_PI_1; + break; + + case GAUDI_QUEUE_ID_NIC_6_2: + db_reg_offset = mmNIC3_QM0_PQ_PI_2; + break; + + case GAUDI_QUEUE_ID_NIC_6_3: + db_reg_offset = mmNIC3_QM0_PQ_PI_3; + break; + + case GAUDI_QUEUE_ID_NIC_7_0: + db_reg_offset = mmNIC3_QM1_PQ_PI_0; + break; + + case GAUDI_QUEUE_ID_NIC_7_1: + db_reg_offset = mmNIC3_QM1_PQ_PI_1; + break; + + case GAUDI_QUEUE_ID_NIC_7_2: + db_reg_offset = mmNIC3_QM1_PQ_PI_2; + break; + + case GAUDI_QUEUE_ID_NIC_7_3: + db_reg_offset = mmNIC3_QM1_PQ_PI_3; + break; + + case GAUDI_QUEUE_ID_NIC_8_0: + db_reg_offset = mmNIC4_QM0_PQ_PI_0; + break; + + case GAUDI_QUEUE_ID_NIC_8_1: + db_reg_offset = mmNIC4_QM0_PQ_PI_1; + break; + + case GAUDI_QUEUE_ID_NIC_8_2: + db_reg_offset = mmNIC4_QM0_PQ_PI_2; + break; + + case GAUDI_QUEUE_ID_NIC_8_3: + db_reg_offset = mmNIC4_QM0_PQ_PI_3; + break; + + case GAUDI_QUEUE_ID_NIC_9_0: + db_reg_offset = mmNIC4_QM1_PQ_PI_0; + break; + + case GAUDI_QUEUE_ID_NIC_9_1: + db_reg_offset = mmNIC4_QM1_PQ_PI_1; + break; + + case GAUDI_QUEUE_ID_NIC_9_2: + db_reg_offset = mmNIC4_QM1_PQ_PI_2; + break; + + case GAUDI_QUEUE_ID_NIC_9_3: + db_reg_offset = mmNIC4_QM1_PQ_PI_3; + break; + default: invalid_queue = true; } @@ -3405,6 +4478,121 @@ static void gaudi_dma_free_coherent(struct hl_device *hdev, size_t size, dma_free_coherent(&hdev->pdev->dev, size, cpu_addr, fixed_dma_handle); } +static int gaudi_hbm_scrubbing(struct hl_device *hdev) +{ + struct asic_fixed_properties *prop = &hdev->asic_prop; + u64 cur_addr = DRAM_BASE_ADDR_USER; + u32 val; + u32 chunk_size; + int rc, dma_id; + + while (cur_addr < prop->dram_end_address) { + for (dma_id = 0 ; dma_id < DMA_NUMBER_OF_CHANNELS ; dma_id++) { + u32 dma_offset = dma_id * DMA_CORE_OFFSET; + + chunk_size = + min((u64)SZ_2G, prop->dram_end_address - cur_addr); + + dev_dbg(hdev->dev, + "Doing HBM scrubbing for 0x%09llx - 0x%09llx\n", + cur_addr, cur_addr + chunk_size); + + WREG32(mmDMA0_CORE_SRC_BASE_LO + dma_offset, 0); + WREG32(mmDMA0_CORE_SRC_BASE_HI + dma_offset, 0); + WREG32(mmDMA0_CORE_DST_BASE_LO + dma_offset, + lower_32_bits(cur_addr)); + WREG32(mmDMA0_CORE_DST_BASE_HI + dma_offset, + upper_32_bits(cur_addr)); + WREG32(mmDMA0_CORE_DST_TSIZE_0 + dma_offset, + chunk_size); + WREG32(mmDMA0_CORE_COMMIT + dma_offset, + ((1 << DMA0_CORE_COMMIT_LIN_SHIFT) | + (1 << DMA0_CORE_COMMIT_MEM_SET_SHIFT))); + + cur_addr += chunk_size; + + if (cur_addr == prop->dram_end_address) + break; + } + + for (dma_id = 0 ; dma_id < DMA_NUMBER_OF_CHANNELS ; dma_id++) { + u32 dma_offset = dma_id * DMA_CORE_OFFSET; + + rc = hl_poll_timeout( + hdev, + mmDMA0_CORE_STS0 + dma_offset, + val, + ((val & DMA0_CORE_STS0_BUSY_MASK) == 0), + 1000, + HBM_SCRUBBING_TIMEOUT_US); + + if (rc) { + dev_err(hdev->dev, + "DMA Timeout during HBM scrubbing of DMA #%d\n", + dma_id); + return -EIO; + } + } + } + + return 0; +} + +static int gaudi_scrub_device_mem(struct hl_device *hdev, u64 addr, u64 size) +{ + struct asic_fixed_properties *prop = &hdev->asic_prop; + struct gaudi_device *gaudi = hdev->asic_specific; + u64 idle_mask = 0; + int rc = 0; + u64 val = 0; + + if (!hdev->memory_scrub) + return 0; + + if (!addr && !size) { + /* Wait till device is idle */ + rc = hl_poll_timeout( + hdev, + mmDMA0_CORE_STS0/* dummy */, + val/* dummy */, + (hdev->asic_funcs->is_device_idle(hdev, + &idle_mask, NULL)), + 1000, + HBM_SCRUBBING_TIMEOUT_US); + if (rc) { + dev_err(hdev->dev, "waiting for idle timeout\n"); + return -EIO; + } + + /* Scrub SRAM */ + addr = prop->sram_user_base_address; + size = hdev->pldm ? 0x10000 : + (prop->sram_size - SRAM_USER_BASE_OFFSET); + val = 0x7777777777777777ull; + + rc = gaudi_memset_device_memory(hdev, addr, size, val); + if (rc) { + dev_err(hdev->dev, + "Failed to clear SRAM in mem scrub all\n"); + return rc; + } + + mutex_lock(&gaudi->clk_gate_mutex); + hdev->asic_funcs->disable_clock_gating(hdev); + + /* Scrub HBM using all DMA channels in parallel */ + rc = gaudi_hbm_scrubbing(hdev); + if (rc) + dev_err(hdev->dev, + "Failed to clear HBM in mem scrub all\n"); + + hdev->asic_funcs->set_clock_gating(hdev); + mutex_unlock(&gaudi->clk_gate_mutex); + } + + return rc; +} + static void *gaudi_get_int_queue_base(struct hl_device *hdev, u32 queue_id, dma_addr_t *dma_handle, u16 *queue_len) @@ -3426,7 +4614,7 @@ static void *gaudi_get_int_queue_base(struct hl_device *hdev, } static int gaudi_send_cpu_message(struct hl_device *hdev, u32 *msg, - u16 len, u32 timeout, long *result) + u16 len, u32 timeout, u64 *result) { struct gaudi_device *gaudi = hdev->asic_specific; @@ -3811,8 +4999,7 @@ static int gaudi_validate_cb(struct hl_device *hdev, u16 pkt_size; struct gaudi_packet *user_pkt; - user_pkt = (struct gaudi_packet *) (uintptr_t) - (parser->user_cb->kernel_address + cb_parsed_length); + user_pkt = parser->user_cb->kernel_address + cb_parsed_length; pkt_id = (enum packet_id) ( (le64_to_cpu(user_pkt->header) & @@ -4035,11 +5222,9 @@ static int gaudi_patch_cb(struct hl_device *hdev, u32 new_pkt_size = 0; struct gaudi_packet *user_pkt, *kernel_pkt; - user_pkt = (struct gaudi_packet *) (uintptr_t) - (parser->user_cb->kernel_address + cb_parsed_length); - kernel_pkt = (struct gaudi_packet *) (uintptr_t) - (parser->patched_cb->kernel_address + - cb_patched_cur_length); + user_pkt = parser->user_cb->kernel_address + cb_parsed_length; + kernel_pkt = parser->patched_cb->kernel_address + + cb_patched_cur_length; pkt_id = (enum packet_id) ( (le64_to_cpu(user_pkt->header) & @@ -4155,8 +5340,8 @@ static int gaudi_parse_cb_mmu(struct hl_device *hdev, * The check that parser->user_cb_size <= parser->user_cb->size was done * in validate_queue_index(). */ - memcpy((void *) (uintptr_t) parser->patched_cb->kernel_address, - (void *) (uintptr_t) parser->user_cb->kernel_address, + memcpy(parser->patched_cb->kernel_address, + parser->user_cb->kernel_address, parser->user_cb_size); patched_cb_size = parser->patched_cb_size; @@ -4248,6 +5433,17 @@ static int gaudi_parse_cb_no_ext_queue(struct hl_device *hdev, struct hl_cs_parser *parser) { struct asic_fixed_properties *asic_prop = &hdev->asic_prop; + struct gaudi_device *gaudi = hdev->asic_specific; + u32 nic_mask_q_id = 1 << (HW_CAP_NIC_SHIFT + + ((parser->hw_queue_id - GAUDI_QUEUE_ID_NIC_0_0) >> 2)); + + if ((parser->hw_queue_id >= GAUDI_QUEUE_ID_NIC_0_0) && + (parser->hw_queue_id <= GAUDI_QUEUE_ID_NIC_9_3) && + (!(gaudi->hw_cap_initialized & nic_mask_q_id))) { + dev_err(hdev->dev, "h/w queue %d is disabled\n", + parser->hw_queue_id); + return -EINVAL; + } /* For internal queue jobs just check if CB address is valid */ if (hl_mem_area_inside_range((u64) (uintptr_t) parser->user_cb, @@ -4290,7 +5486,7 @@ static int gaudi_cs_parser(struct hl_device *hdev, struct hl_cs_parser *parser) } static void gaudi_add_end_of_cb_packets(struct hl_device *hdev, - u64 kernel_address, u32 len, + void *kernel_address, u32 len, u64 cq_addr, u32 cq_val, u32 msi_vec, bool eb) { @@ -4298,8 +5494,7 @@ static void gaudi_add_end_of_cb_packets(struct hl_device *hdev, struct packet_msg_prot *cq_pkt; u32 tmp; - cq_pkt = (struct packet_msg_prot *) (uintptr_t) - (kernel_address + len - (sizeof(struct packet_msg_prot) * 2)); + cq_pkt = kernel_address + len - (sizeof(struct packet_msg_prot) * 2); tmp = FIELD_PREP(GAUDI_PKT_CTL_OPCODE_MASK, PACKET_MSG_PROT); tmp |= FIELD_PREP(GAUDI_PKT_CTL_MB_MASK, 1); @@ -4342,7 +5537,7 @@ static int gaudi_memset_device_memory(struct hl_device *hdev, u64 addr, if (!cb) return -EFAULT; - lin_dma_pkt = (struct packet_lin_dma *) (uintptr_t) cb->kernel_address; + lin_dma_pkt = cb->kernel_address; memset(lin_dma_pkt, 0, sizeof(*lin_dma_pkt)); cb_size = sizeof(*lin_dma_pkt); @@ -4375,7 +5570,7 @@ static int gaudi_memset_device_memory(struct hl_device *hdev, u64 addr, job->id = 0; job->user_cb = cb; - job->user_cb->cs_cnt++; + atomic_inc(&job->user_cb->cs_cnt); job->user_cb_size = cb_size; job->hw_queue_id = GAUDI_QUEUE_ID_DMA_0_0; job->patched_cb = job->user_cb; @@ -4386,7 +5581,7 @@ static int gaudi_memset_device_memory(struct hl_device *hdev, u64 addr, rc = gaudi_send_job_on_qman0(hdev, job); hl_debugfs_remove_job(hdev, job); kfree(job); - cb->cs_cnt--; + atomic_dec(&cb->cs_cnt); /* Verify DMA is OK */ err_cause = RREG32(mmDMA0_CORE_ERR_CAUSE); @@ -4481,6 +5676,12 @@ static void gaudi_restore_qm_registers(struct hl_device *hdev) qman_offset = i * TPC_QMAN_OFFSET; WREG32(mmTPC0_QM_ARB_CFG_0 + qman_offset, 0); } + + for (i = 0 ; i < NIC_NUMBER_OF_ENGINES ; i++) { + qman_offset = (i >> 1) * NIC_MACRO_QMAN_OFFSET + + (i & 0x1) * NIC_ENGINE_QMAN_OFFSET; + WREG32(mmNIC0_QM0_ARB_CFG_0 + qman_offset, 0); + } } static void gaudi_restore_user_registers(struct hl_device *hdev) @@ -4492,21 +5693,6 @@ static void gaudi_restore_user_registers(struct hl_device *hdev) static int gaudi_context_switch(struct hl_device *hdev, u32 asid) { - struct asic_fixed_properties *prop = &hdev->asic_prop; - u64 addr = prop->sram_user_base_address; - u32 size = hdev->pldm ? 0x10000 : - (prop->sram_size - SRAM_USER_BASE_OFFSET); - u64 val = 0x7777777777777777ull; - int rc; - - rc = gaudi_memset_device_memory(hdev, addr, size, val); - if (rc) { - dev_err(hdev->dev, "Failed to clear SRAM in context switch\n"); - return rc; - } - - gaudi_mmu_prepare(hdev, asid); - gaudi_restore_user_registers(hdev); return 0; @@ -4747,7 +5933,7 @@ static void gaudi_write_pte(struct hl_device *hdev, u64 addr, u64 val) (addr - gaudi->hbm_bar_cur_addr)); } -static void gaudi_mmu_prepare_reg(struct hl_device *hdev, u64 reg, u32 asid) +void gaudi_mmu_prepare_reg(struct hl_device *hdev, u64 reg, u32 asid) { /* mask to zero the MMBP and ASID bits */ WREG32_AND(reg, ~0x7FF); @@ -4915,8 +6101,135 @@ static void gaudi_mmu_prepare(struct hl_device *hdev, u32 asid) gaudi_mmu_prepare_reg(hdev, mmMME2_ACC_WBC, asid); gaudi_mmu_prepare_reg(hdev, mmMME3_ACC_WBC, asid); - gaudi_mmu_prepare_reg(hdev, mmPSOC_GLOBAL_CONF_TRACE_ARUSER, asid); - gaudi_mmu_prepare_reg(hdev, mmPSOC_GLOBAL_CONF_TRACE_AWUSER, asid); + if (hdev->nic_ports_mask & GAUDI_NIC_MASK_NIC0) { + gaudi_mmu_prepare_reg(hdev, mmNIC0_QM0_GLBL_NON_SECURE_PROPS_0, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC0_QM0_GLBL_NON_SECURE_PROPS_1, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC0_QM0_GLBL_NON_SECURE_PROPS_2, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC0_QM0_GLBL_NON_SECURE_PROPS_3, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC0_QM0_GLBL_NON_SECURE_PROPS_4, + asid); + } + + if (hdev->nic_ports_mask & GAUDI_NIC_MASK_NIC1) { + gaudi_mmu_prepare_reg(hdev, mmNIC0_QM1_GLBL_NON_SECURE_PROPS_0, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC0_QM1_GLBL_NON_SECURE_PROPS_1, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC0_QM1_GLBL_NON_SECURE_PROPS_2, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC0_QM1_GLBL_NON_SECURE_PROPS_3, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC0_QM1_GLBL_NON_SECURE_PROPS_4, + asid); + } + + if (hdev->nic_ports_mask & GAUDI_NIC_MASK_NIC2) { + gaudi_mmu_prepare_reg(hdev, mmNIC1_QM0_GLBL_NON_SECURE_PROPS_0, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC1_QM0_GLBL_NON_SECURE_PROPS_1, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC1_QM0_GLBL_NON_SECURE_PROPS_2, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC1_QM0_GLBL_NON_SECURE_PROPS_3, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC1_QM0_GLBL_NON_SECURE_PROPS_4, + asid); + } + + if (hdev->nic_ports_mask & GAUDI_NIC_MASK_NIC3) { + gaudi_mmu_prepare_reg(hdev, mmNIC1_QM1_GLBL_NON_SECURE_PROPS_0, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC1_QM1_GLBL_NON_SECURE_PROPS_1, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC1_QM1_GLBL_NON_SECURE_PROPS_2, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC1_QM1_GLBL_NON_SECURE_PROPS_3, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC1_QM1_GLBL_NON_SECURE_PROPS_4, + asid); + } + + if (hdev->nic_ports_mask & GAUDI_NIC_MASK_NIC4) { + gaudi_mmu_prepare_reg(hdev, mmNIC2_QM0_GLBL_NON_SECURE_PROPS_0, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC2_QM0_GLBL_NON_SECURE_PROPS_1, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC2_QM0_GLBL_NON_SECURE_PROPS_2, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC2_QM0_GLBL_NON_SECURE_PROPS_3, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC2_QM0_GLBL_NON_SECURE_PROPS_4, + asid); + } + + if (hdev->nic_ports_mask & GAUDI_NIC_MASK_NIC5) { + gaudi_mmu_prepare_reg(hdev, mmNIC2_QM1_GLBL_NON_SECURE_PROPS_0, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC2_QM1_GLBL_NON_SECURE_PROPS_1, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC2_QM1_GLBL_NON_SECURE_PROPS_2, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC2_QM1_GLBL_NON_SECURE_PROPS_3, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC2_QM1_GLBL_NON_SECURE_PROPS_4, + asid); + } + + if (hdev->nic_ports_mask & GAUDI_NIC_MASK_NIC6) { + gaudi_mmu_prepare_reg(hdev, mmNIC3_QM0_GLBL_NON_SECURE_PROPS_0, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC3_QM0_GLBL_NON_SECURE_PROPS_1, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC3_QM0_GLBL_NON_SECURE_PROPS_2, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC3_QM0_GLBL_NON_SECURE_PROPS_3, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC3_QM0_GLBL_NON_SECURE_PROPS_4, + asid); + } + + if (hdev->nic_ports_mask & GAUDI_NIC_MASK_NIC7) { + gaudi_mmu_prepare_reg(hdev, mmNIC3_QM1_GLBL_NON_SECURE_PROPS_0, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC3_QM1_GLBL_NON_SECURE_PROPS_1, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC3_QM1_GLBL_NON_SECURE_PROPS_2, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC3_QM1_GLBL_NON_SECURE_PROPS_3, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC3_QM1_GLBL_NON_SECURE_PROPS_4, + asid); + } + + if (hdev->nic_ports_mask & GAUDI_NIC_MASK_NIC8) { + gaudi_mmu_prepare_reg(hdev, mmNIC4_QM0_GLBL_NON_SECURE_PROPS_0, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC4_QM0_GLBL_NON_SECURE_PROPS_1, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC4_QM0_GLBL_NON_SECURE_PROPS_2, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC4_QM0_GLBL_NON_SECURE_PROPS_3, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC4_QM0_GLBL_NON_SECURE_PROPS_4, + asid); + } + + if (hdev->nic_ports_mask & GAUDI_NIC_MASK_NIC9) { + gaudi_mmu_prepare_reg(hdev, mmNIC4_QM1_GLBL_NON_SECURE_PROPS_0, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC4_QM1_GLBL_NON_SECURE_PROPS_1, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC4_QM1_GLBL_NON_SECURE_PROPS_2, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC4_QM1_GLBL_NON_SECURE_PROPS_3, + asid); + gaudi_mmu_prepare_reg(hdev, mmNIC4_QM1_GLBL_NON_SECURE_PROPS_4, + asid); + } hdev->asic_funcs->set_clock_gating(hdev); @@ -4954,8 +6267,8 @@ static int gaudi_send_job_on_qman0(struct hl_device *hdev, cb = job->patched_cb; - fence_pkt = (struct packet_msg_prot *) (uintptr_t) (cb->kernel_address + - job->job_cb_size - sizeof(struct packet_msg_prot)); + fence_pkt = cb->kernel_address + + job->job_cb_size - sizeof(struct packet_msg_prot); tmp = FIELD_PREP(GAUDI_PKT_CTL_OPCODE_MASK, PACKET_MSG_PROT); tmp |= FIELD_PREP(GAUDI_PKT_CTL_EB_MASK, 1); @@ -5444,6 +6757,8 @@ static void gaudi_handle_ecc_event(struct hl_device *hdev, u16 event_type, params.num_memories = 33; params.derr = true; params.disable_clock_gating = true; + extract_info_from_fw = false; + break; default: return; } @@ -5495,6 +6810,56 @@ static void gaudi_handle_qman_err(struct hl_device *hdev, u16 event_type) mmDMA0_QM_ARB_ERR_CAUSE + index * DMA_QMAN_OFFSET; snprintf(desc, ARRAY_SIZE(desc), "%s%d", "DMA_QM", index); break; + case GAUDI_EVENT_NIC0_QM0: + glbl_sts_addr = mmNIC0_QM0_GLBL_STS1_0; + arb_err_addr = mmNIC0_QM0_ARB_ERR_CAUSE; + snprintf(desc, ARRAY_SIZE(desc), "NIC0_QM0"); + break; + case GAUDI_EVENT_NIC0_QM1: + glbl_sts_addr = mmNIC0_QM1_GLBL_STS1_0; + arb_err_addr = mmNIC0_QM1_ARB_ERR_CAUSE; + snprintf(desc, ARRAY_SIZE(desc), "NIC0_QM1"); + break; + case GAUDI_EVENT_NIC1_QM0: + glbl_sts_addr = mmNIC1_QM0_GLBL_STS1_0; + arb_err_addr = mmNIC1_QM0_ARB_ERR_CAUSE; + snprintf(desc, ARRAY_SIZE(desc), "NIC1_QM0"); + break; + case GAUDI_EVENT_NIC1_QM1: + glbl_sts_addr = mmNIC1_QM1_GLBL_STS1_0; + arb_err_addr = mmNIC1_QM1_ARB_ERR_CAUSE; + snprintf(desc, ARRAY_SIZE(desc), "NIC1_QM1"); + break; + case GAUDI_EVENT_NIC2_QM0: + glbl_sts_addr = mmNIC2_QM0_GLBL_STS1_0; + arb_err_addr = mmNIC2_QM0_ARB_ERR_CAUSE; + snprintf(desc, ARRAY_SIZE(desc), "NIC2_QM0"); + break; + case GAUDI_EVENT_NIC2_QM1: + glbl_sts_addr = mmNIC2_QM1_GLBL_STS1_0; + arb_err_addr = mmNIC2_QM1_ARB_ERR_CAUSE; + snprintf(desc, ARRAY_SIZE(desc), "NIC2_QM1"); + break; + case GAUDI_EVENT_NIC3_QM0: + glbl_sts_addr = mmNIC3_QM0_GLBL_STS1_0; + arb_err_addr = mmNIC3_QM0_ARB_ERR_CAUSE; + snprintf(desc, ARRAY_SIZE(desc), "NIC3_QM0"); + break; + case GAUDI_EVENT_NIC3_QM1: + glbl_sts_addr = mmNIC3_QM1_GLBL_STS1_0; + arb_err_addr = mmNIC3_QM1_ARB_ERR_CAUSE; + snprintf(desc, ARRAY_SIZE(desc), "NIC3_QM1"); + break; + case GAUDI_EVENT_NIC4_QM0: + glbl_sts_addr = mmNIC4_QM0_GLBL_STS1_0; + arb_err_addr = mmNIC4_QM0_ARB_ERR_CAUSE; + snprintf(desc, ARRAY_SIZE(desc), "NIC4_QM0"); + break; + case GAUDI_EVENT_NIC4_QM1: + glbl_sts_addr = mmNIC4_QM1_GLBL_STS1_0; + arb_err_addr = mmNIC4_QM1_ARB_ERR_CAUSE; + snprintf(desc, ARRAY_SIZE(desc), "NIC4_QM1"); + break; default: return; } @@ -5527,10 +6892,41 @@ static int gaudi_soft_reset_late_init(struct hl_device *hdev) return hl_fw_unmask_irq_arr(hdev, gaudi->events, sizeof(gaudi->events)); } -static int gaudi_hbm_read_interrupts(struct hl_device *hdev, int device) +static int gaudi_hbm_read_interrupts(struct hl_device *hdev, int device, + struct hl_eq_hbm_ecc_data *hbm_ecc_data) { - int ch, err = 0; - u32 base, val, val2; + u32 base, val, val2, wr_par, rd_par, ca_par, derr, serr, type, ch; + int err = 0; + + if (!hdev->asic_prop.fw_security_disabled) { + if (!hbm_ecc_data) { + dev_err(hdev->dev, "No FW ECC data"); + return 0; + } + + wr_par = FIELD_GET(CPUCP_PKT_HBM_ECC_INFO_WR_PAR_MASK, + le32_to_cpu(hbm_ecc_data->hbm_ecc_info)); + rd_par = FIELD_GET(CPUCP_PKT_HBM_ECC_INFO_RD_PAR_MASK, + le32_to_cpu(hbm_ecc_data->hbm_ecc_info)); + ca_par = FIELD_GET(CPUCP_PKT_HBM_ECC_INFO_CA_PAR_MASK, + le32_to_cpu(hbm_ecc_data->hbm_ecc_info)); + derr = FIELD_GET(CPUCP_PKT_HBM_ECC_INFO_DERR_MASK, + le32_to_cpu(hbm_ecc_data->hbm_ecc_info)); + serr = FIELD_GET(CPUCP_PKT_HBM_ECC_INFO_SERR_MASK, + le32_to_cpu(hbm_ecc_data->hbm_ecc_info)); + type = FIELD_GET(CPUCP_PKT_HBM_ECC_INFO_TYPE_MASK, + le32_to_cpu(hbm_ecc_data->hbm_ecc_info)); + ch = FIELD_GET(CPUCP_PKT_HBM_ECC_INFO_HBM_CH_MASK, + le32_to_cpu(hbm_ecc_data->hbm_ecc_info)); + + dev_err(hdev->dev, + "HBM%d pc%d ECC: TYPE=%d, WR_PAR=%d, RD_PAR=%d, CA_PAR=%d, SERR=%d, DERR=%d\n", + device, ch, type, wr_par, rd_par, ca_par, serr, derr); + + err = 1; + + return 0; + } base = GAUDI_HBM_CFG_BASE + device * GAUDI_HBM_CFG_OFFSET; for (ch = 0 ; ch < GAUDI_HBM_CHANNELS ; ch++) { @@ -5546,7 +6942,7 @@ static int gaudi_hbm_read_interrupts(struct hl_device *hdev, int device) val2 = RREG32(base + ch * 0x1000 + 0x060); dev_err(hdev->dev, - "HBM%d pc%d ECC info: 1ST_ERR_ADDR=0x%x, 1ST_ERR_TYPE=%d, SEC_CONT_CNT=%d, SEC_CNT=%d, DED_CNT=%d\n", + "HBM%d pc%d ECC info: 1ST_ERR_ADDR=0x%x, 1ST_ERR_TYPE=%d, SEC_CONT_CNT=%d, SEC_CNT=%d, DEC_CNT=%d\n", device, ch * 2, RREG32(base + ch * 0x1000 + 0x064), (val2 & 0x200) >> 9, (val2 & 0xFC00) >> 10, @@ -5566,7 +6962,7 @@ static int gaudi_hbm_read_interrupts(struct hl_device *hdev, int device) val2 = RREG32(base + ch * 0x1000 + 0x070); dev_err(hdev->dev, - "HBM%d pc%d ECC info: 1ST_ERR_ADDR=0x%x, 1ST_ERR_TYPE=%d, SEC_CONT_CNT=%d, SEC_CNT=%d, DED_CNT=%d\n", + "HBM%d pc%d ECC info: 1ST_ERR_ADDR=0x%x, 1ST_ERR_TYPE=%d, SEC_CONT_CNT=%d, SEC_CNT=%d, DEC_CNT=%d\n", device, ch * 2 + 1, RREG32(base + ch * 0x1000 + 0x074), (val2 & 0x200) >> 9, (val2 & 0xFC00) >> 10, @@ -5767,7 +7163,8 @@ static void gaudi_handle_eqe(struct hl_device *hdev, case GAUDI_EVENT_HBM3_SPI_0: gaudi_print_irq_info(hdev, event_type, false); gaudi_hbm_read_interrupts(hdev, - gaudi_hbm_event_to_dev(event_type)); + gaudi_hbm_event_to_dev(event_type), + &eq_entry->hbm_ecc_data); if (hdev->hard_reset_on_fw_events) hl_device_reset(hdev, true, false); break; @@ -5778,7 +7175,8 @@ static void gaudi_handle_eqe(struct hl_device *hdev, case GAUDI_EVENT_HBM3_SPI_1: gaudi_print_irq_info(hdev, event_type, false); gaudi_hbm_read_interrupts(hdev, - gaudi_hbm_event_to_dev(event_type)); + gaudi_hbm_event_to_dev(event_type), + &eq_entry->hbm_ecc_data); break; case GAUDI_EVENT_TPC0_DEC: @@ -5872,6 +7270,16 @@ static void gaudi_handle_eqe(struct hl_device *hdev, case GAUDI_EVENT_MME0_QM ... GAUDI_EVENT_MME2_QM: case GAUDI_EVENT_DMA0_QM ... GAUDI_EVENT_DMA7_QM: fallthrough; + case GAUDI_EVENT_NIC0_QM0: + case GAUDI_EVENT_NIC0_QM1: + case GAUDI_EVENT_NIC1_QM0: + case GAUDI_EVENT_NIC1_QM1: + case GAUDI_EVENT_NIC2_QM0: + case GAUDI_EVENT_NIC2_QM1: + case GAUDI_EVENT_NIC3_QM0: + case GAUDI_EVENT_NIC3_QM1: + case GAUDI_EVENT_NIC4_QM0: + case GAUDI_EVENT_NIC4_QM1: case GAUDI_EVENT_DMA0_CORE ... GAUDI_EVENT_DMA7_CORE: gaudi_print_irq_info(hdev, event_type, true); gaudi_handle_qman_err(hdev, event_type); @@ -6079,7 +7487,7 @@ static int gaudi_cpucp_info_get(struct hl_device *hdev) if (!(gaudi->hw_cap_initialized & HW_CAP_CPU_Q)) return 0; - rc = hl_fw_cpucp_info_get(hdev); + rc = hl_fw_cpucp_info_get(hdev, mmCPU_BOOT_DEV_STS0); if (rc) return rc; @@ -6105,10 +7513,11 @@ static bool gaudi_is_device_idle(struct hl_device *hdev, u64 *mask, struct gaudi_device *gaudi = hdev->asic_specific; const char *fmt = "%-5d%-9s%#-14x%#-12x%#x\n"; const char *mme_slave_fmt = "%-5d%-9s%-14s%-12s%#x\n"; + const char *nic_fmt = "%-5d%-9s%#-14x%#x\n"; u32 qm_glbl_sts0, qm_cgm_sts, dma_core_sts0, tpc_cfg_sts, mme_arch_sts; bool is_idle = true, is_eng_idle, is_slave; u64 offset; - int i, dma_id; + int i, dma_id, port; mutex_lock(&gaudi->clk_gate_mutex); @@ -6198,6 +7607,45 @@ static bool gaudi_is_device_idle(struct hl_device *hdev, u64 *mask, } if (s) + seq_puts(s, "\nNIC is_idle QM_GLBL_STS0 QM_CGM_STS\n" + "--- ------- ------------ ----------\n"); + + for (i = 0 ; i < (NIC_NUMBER_OF_ENGINES / 2) ; i++) { + offset = i * NIC_MACRO_QMAN_OFFSET; + port = 2 * i; + if (hdev->nic_ports_mask & BIT(port)) { + qm_glbl_sts0 = RREG32(mmNIC0_QM0_GLBL_STS0 + offset); + qm_cgm_sts = RREG32(mmNIC0_QM0_CGM_STS + offset); + is_eng_idle = IS_QM_IDLE(qm_glbl_sts0, qm_cgm_sts); + is_idle &= is_eng_idle; + + if (mask) + *mask |= ((u64) !is_eng_idle) << + (GAUDI_ENGINE_ID_NIC_0 + port); + if (s) + seq_printf(s, nic_fmt, port, + is_eng_idle ? "Y" : "N", + qm_glbl_sts0, qm_cgm_sts); + } + + port = 2 * i + 1; + if (hdev->nic_ports_mask & BIT(port)) { + qm_glbl_sts0 = RREG32(mmNIC0_QM1_GLBL_STS0 + offset); + qm_cgm_sts = RREG32(mmNIC0_QM1_CGM_STS + offset); + is_eng_idle = IS_QM_IDLE(qm_glbl_sts0, qm_cgm_sts); + is_idle &= is_eng_idle; + + if (mask) + *mask |= ((u64) !is_eng_idle) << + (GAUDI_ENGINE_ID_NIC_0 + port); + if (s) + seq_printf(s, nic_fmt, port, + is_eng_idle ? "Y" : "N", + qm_glbl_sts0, qm_cgm_sts); + } + } + + if (s) seq_puts(s, "\n"); hdev->asic_funcs->set_clock_gating(hdev); @@ -6352,14 +7800,121 @@ static int gaudi_run_tpc_kernel(struct hl_device *hdev, u64 tpc_kernel, return 0; } -static enum hl_device_hw_state gaudi_get_hw_state(struct hl_device *hdev) +static int gaudi_internal_cb_pool_init(struct hl_device *hdev, + struct hl_ctx *ctx) { - return RREG32(mmHW_STATE); + struct gaudi_device *gaudi = hdev->asic_specific; + int min_alloc_order, rc, collective_cb_size; + + if (!(gaudi->hw_cap_initialized & HW_CAP_MMU)) + return 0; + + hdev->internal_cb_pool_virt_addr = + hdev->asic_funcs->asic_dma_alloc_coherent(hdev, + HOST_SPACE_INTERNAL_CB_SZ, + &hdev->internal_cb_pool_dma_addr, + GFP_KERNEL | __GFP_ZERO); + + if (!hdev->internal_cb_pool_virt_addr) + return -ENOMEM; + + collective_cb_size = sizeof(struct packet_msg_short) * 5 + + sizeof(struct packet_fence); + min_alloc_order = ilog2(collective_cb_size); + + hdev->internal_cb_pool = gen_pool_create(min_alloc_order, -1); + if (!hdev->internal_cb_pool) { + dev_err(hdev->dev, + "Failed to create internal CB pool\n"); + rc = -ENOMEM; + goto free_internal_cb_pool; + } + + rc = gen_pool_add(hdev->internal_cb_pool, + (uintptr_t) hdev->internal_cb_pool_virt_addr, + HOST_SPACE_INTERNAL_CB_SZ, -1); + if (rc) { + dev_err(hdev->dev, + "Failed to add memory to internal CB pool\n"); + rc = -EFAULT; + goto destroy_internal_cb_pool; + } + + hdev->internal_cb_va_base = hl_reserve_va_block(hdev, ctx, + HL_VA_RANGE_TYPE_HOST, HOST_SPACE_INTERNAL_CB_SZ, + HL_MMU_VA_ALIGNMENT_NOT_NEEDED); + + if (!hdev->internal_cb_va_base) + goto destroy_internal_cb_pool; + + mutex_lock(&ctx->mmu_lock); + rc = hl_mmu_map_contiguous(ctx, hdev->internal_cb_va_base, + hdev->internal_cb_pool_dma_addr, + HOST_SPACE_INTERNAL_CB_SZ); + + hdev->asic_funcs->mmu_invalidate_cache(hdev, false, VM_TYPE_USERPTR); + mutex_unlock(&ctx->mmu_lock); + + if (rc) + goto unreserve_internal_cb_pool; + + return 0; + +unreserve_internal_cb_pool: + hl_unreserve_va_block(hdev, ctx, hdev->internal_cb_va_base, + HOST_SPACE_INTERNAL_CB_SZ); +destroy_internal_cb_pool: + gen_pool_destroy(hdev->internal_cb_pool); +free_internal_cb_pool: + hdev->asic_funcs->asic_dma_free_coherent(hdev, + HOST_SPACE_INTERNAL_CB_SZ, + hdev->internal_cb_pool_virt_addr, + hdev->internal_cb_pool_dma_addr); + + return rc; +} + +static void gaudi_internal_cb_pool_fini(struct hl_device *hdev, + struct hl_ctx *ctx) +{ + struct gaudi_device *gaudi = hdev->asic_specific; + + if (!(gaudi->hw_cap_initialized & HW_CAP_MMU)) + return; + + mutex_lock(&ctx->mmu_lock); + hl_mmu_unmap_contiguous(ctx, hdev->internal_cb_va_base, + HOST_SPACE_INTERNAL_CB_SZ); + hl_unreserve_va_block(hdev, ctx, hdev->internal_cb_va_base, + HOST_SPACE_INTERNAL_CB_SZ); + hdev->asic_funcs->mmu_invalidate_cache(hdev, true, VM_TYPE_USERPTR); + mutex_unlock(&ctx->mmu_lock); + + gen_pool_destroy(hdev->internal_cb_pool); + + hdev->asic_funcs->asic_dma_free_coherent(hdev, + HOST_SPACE_INTERNAL_CB_SZ, + hdev->internal_cb_pool_virt_addr, + hdev->internal_cb_pool_dma_addr); } static int gaudi_ctx_init(struct hl_ctx *ctx) { - return 0; + gaudi_mmu_prepare(ctx->hdev, ctx->asid); + return gaudi_internal_cb_pool_init(ctx->hdev, ctx); +} + +static void gaudi_ctx_fini(struct hl_ctx *ctx) +{ + struct hl_device *hdev = ctx->hdev; + + /* Gaudi will NEVER support more then a single compute context. + * Therefore, don't clear anything unless it is the compute context + */ + if (hdev->compute_ctx != ctx) + return; + + gaudi_internal_cb_pool_fini(ctx->hdev, ctx); } static u32 gaudi_get_queue_id_for_cq(struct hl_device *hdev, u32 cq_idx) @@ -6380,14 +7935,15 @@ static u32 gaudi_get_wait_cb_size(struct hl_device *hdev) sizeof(struct packet_msg_prot) * 2; } -static void gaudi_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id) +static u32 gaudi_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id, + u32 size) { struct hl_cb *cb = (struct hl_cb *) data; struct packet_msg_short *pkt; - u32 value, ctl; + u32 value, ctl, pkt_size = sizeof(*pkt); - pkt = (struct packet_msg_short *) (uintptr_t) cb->kernel_address; - memset(pkt, 0, sizeof(*pkt)); + pkt = cb->kernel_address + size; + memset(pkt, 0, pkt_size); /* Inc by 1, Mode ADD */ value = FIELD_PREP(GAUDI_PKT_SHORT_VAL_SOB_SYNC_VAL_MASK, 1); @@ -6403,6 +7959,8 @@ static void gaudi_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id) pkt->value = cpu_to_le32(value); pkt->ctl = cpu_to_le32(ctl); + + return size + pkt_size; } static u32 gaudi_add_mon_msg_short(struct packet_msg_short *pkt, u32 value, @@ -6425,21 +7983,42 @@ static u32 gaudi_add_mon_msg_short(struct packet_msg_short *pkt, u32 value, return pkt_size; } -static u32 gaudi_add_arm_monitor_pkt(struct packet_msg_short *pkt, u16 sob_id, - u16 sob_val, u16 addr) +static u32 gaudi_add_arm_monitor_pkt(struct hl_device *hdev, + struct packet_msg_short *pkt, u16 sob_base, u8 sob_mask, + u16 sob_val, u16 mon_id) { + u64 monitor_base; u32 ctl, value, pkt_size = sizeof(*pkt); - u8 mask = ~(1 << (sob_id & 0x7)); + u16 msg_addr_offset; + u8 mask; + + if (hl_gen_sob_mask(sob_base, sob_mask, &mask)) { + dev_err(hdev->dev, + "sob_base %u (mask %#x) is not valid\n", + sob_base, sob_mask); + return 0; + } + + /* + * monitor_base should be the content of the base0 address registers, + * so it will be added to the msg short offsets + */ + monitor_base = mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_PAY_ADDRL_0; + + msg_addr_offset = + (mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_ARM_0 + mon_id * 4) - + monitor_base; memset(pkt, 0, pkt_size); - value = FIELD_PREP(GAUDI_PKT_SHORT_VAL_MON_SYNC_GID_MASK, sob_id / 8); + /* Monitor config packet: bind the monitor to a sync object */ + value = FIELD_PREP(GAUDI_PKT_SHORT_VAL_MON_SYNC_GID_MASK, sob_base / 8); value |= FIELD_PREP(GAUDI_PKT_SHORT_VAL_MON_SYNC_VAL_MASK, sob_val); value |= FIELD_PREP(GAUDI_PKT_SHORT_VAL_MON_MODE_MASK, 0); /* GREATER OR EQUAL*/ value |= FIELD_PREP(GAUDI_PKT_SHORT_VAL_MON_MASK_MASK, mask); - ctl = FIELD_PREP(GAUDI_PKT_SHORT_CTL_ADDR_MASK, addr); + ctl = FIELD_PREP(GAUDI_PKT_SHORT_CTL_ADDR_MASK, msg_addr_offset); ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_OP_MASK, 0); /* write the value */ ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_BASE_MASK, 2); /* W_S MON base */ ctl |= FIELD_PREP(GAUDI_PKT_SHORT_CTL_OPCODE_MASK, PACKET_MSG_SHORT); @@ -6474,60 +8053,133 @@ static u32 gaudi_add_fence_pkt(struct packet_fence *pkt) return pkt_size; } -static void gaudi_gen_wait_cb(struct hl_device *hdev, void *data, u16 sob_id, - u16 sob_val, u16 mon_id, u32 q_idx) +static int gaudi_get_fence_addr(struct hl_device *hdev, u32 queue_id, u64 *addr) { - struct hl_cb *cb = (struct hl_cb *) data; - void *buf = (void *) (uintptr_t) cb->kernel_address; - u64 monitor_base, fence_addr = 0; - u32 size = 0; - u16 msg_addr_offset; + u32 offset, nic_index; - switch (q_idx) { + switch (queue_id) { case GAUDI_QUEUE_ID_DMA_0_0: - fence_addr = mmDMA0_QM_CP_FENCE2_RDATA_0; + offset = mmDMA0_QM_CP_FENCE2_RDATA_0; break; case GAUDI_QUEUE_ID_DMA_0_1: - fence_addr = mmDMA0_QM_CP_FENCE2_RDATA_1; + offset = mmDMA0_QM_CP_FENCE2_RDATA_1; break; case GAUDI_QUEUE_ID_DMA_0_2: - fence_addr = mmDMA0_QM_CP_FENCE2_RDATA_2; + offset = mmDMA0_QM_CP_FENCE2_RDATA_2; break; case GAUDI_QUEUE_ID_DMA_0_3: - fence_addr = mmDMA0_QM_CP_FENCE2_RDATA_3; + offset = mmDMA0_QM_CP_FENCE2_RDATA_3; break; case GAUDI_QUEUE_ID_DMA_1_0: - fence_addr = mmDMA1_QM_CP_FENCE2_RDATA_0; + offset = mmDMA1_QM_CP_FENCE2_RDATA_0; break; case GAUDI_QUEUE_ID_DMA_1_1: - fence_addr = mmDMA1_QM_CP_FENCE2_RDATA_1; + offset = mmDMA1_QM_CP_FENCE2_RDATA_1; break; case GAUDI_QUEUE_ID_DMA_1_2: - fence_addr = mmDMA1_QM_CP_FENCE2_RDATA_2; + offset = mmDMA1_QM_CP_FENCE2_RDATA_2; break; case GAUDI_QUEUE_ID_DMA_1_3: - fence_addr = mmDMA1_QM_CP_FENCE2_RDATA_3; + offset = mmDMA1_QM_CP_FENCE2_RDATA_3; break; case GAUDI_QUEUE_ID_DMA_5_0: - fence_addr = mmDMA5_QM_CP_FENCE2_RDATA_0; + offset = mmDMA5_QM_CP_FENCE2_RDATA_0; break; case GAUDI_QUEUE_ID_DMA_5_1: - fence_addr = mmDMA5_QM_CP_FENCE2_RDATA_1; + offset = mmDMA5_QM_CP_FENCE2_RDATA_1; break; case GAUDI_QUEUE_ID_DMA_5_2: - fence_addr = mmDMA5_QM_CP_FENCE2_RDATA_2; + offset = mmDMA5_QM_CP_FENCE2_RDATA_2; break; case GAUDI_QUEUE_ID_DMA_5_3: - fence_addr = mmDMA5_QM_CP_FENCE2_RDATA_3; + offset = mmDMA5_QM_CP_FENCE2_RDATA_3; + break; + case GAUDI_QUEUE_ID_TPC_7_0: + offset = mmTPC7_QM_CP_FENCE2_RDATA_0; + break; + case GAUDI_QUEUE_ID_TPC_7_1: + offset = mmTPC7_QM_CP_FENCE2_RDATA_1; + break; + case GAUDI_QUEUE_ID_TPC_7_2: + offset = mmTPC7_QM_CP_FENCE2_RDATA_2; + break; + case GAUDI_QUEUE_ID_TPC_7_3: + offset = mmTPC7_QM_CP_FENCE2_RDATA_3; + break; + case GAUDI_QUEUE_ID_NIC_0_0: + case GAUDI_QUEUE_ID_NIC_1_0: + case GAUDI_QUEUE_ID_NIC_2_0: + case GAUDI_QUEUE_ID_NIC_3_0: + case GAUDI_QUEUE_ID_NIC_4_0: + case GAUDI_QUEUE_ID_NIC_5_0: + case GAUDI_QUEUE_ID_NIC_6_0: + case GAUDI_QUEUE_ID_NIC_7_0: + case GAUDI_QUEUE_ID_NIC_8_0: + case GAUDI_QUEUE_ID_NIC_9_0: + nic_index = (queue_id - GAUDI_QUEUE_ID_NIC_0_0) >> 2; + offset = mmNIC0_QM0_CP_FENCE2_RDATA_0 + + (nic_index >> 1) * NIC_MACRO_QMAN_OFFSET + + (nic_index & 0x1) * NIC_ENGINE_QMAN_OFFSET; + break; + case GAUDI_QUEUE_ID_NIC_0_1: + case GAUDI_QUEUE_ID_NIC_1_1: + case GAUDI_QUEUE_ID_NIC_2_1: + case GAUDI_QUEUE_ID_NIC_3_1: + case GAUDI_QUEUE_ID_NIC_4_1: + case GAUDI_QUEUE_ID_NIC_5_1: + case GAUDI_QUEUE_ID_NIC_6_1: + case GAUDI_QUEUE_ID_NIC_7_1: + case GAUDI_QUEUE_ID_NIC_8_1: + case GAUDI_QUEUE_ID_NIC_9_1: + nic_index = (queue_id - GAUDI_QUEUE_ID_NIC_0_1) >> 2; + offset = mmNIC0_QM0_CP_FENCE2_RDATA_1 + + (nic_index >> 1) * NIC_MACRO_QMAN_OFFSET + + (nic_index & 0x1) * NIC_ENGINE_QMAN_OFFSET; + break; + case GAUDI_QUEUE_ID_NIC_0_2: + case GAUDI_QUEUE_ID_NIC_1_2: + case GAUDI_QUEUE_ID_NIC_2_2: + case GAUDI_QUEUE_ID_NIC_3_2: + case GAUDI_QUEUE_ID_NIC_4_2: + case GAUDI_QUEUE_ID_NIC_5_2: + case GAUDI_QUEUE_ID_NIC_6_2: + case GAUDI_QUEUE_ID_NIC_7_2: + case GAUDI_QUEUE_ID_NIC_8_2: + case GAUDI_QUEUE_ID_NIC_9_2: + nic_index = (queue_id - GAUDI_QUEUE_ID_NIC_0_2) >> 2; + offset = mmNIC0_QM0_CP_FENCE2_RDATA_2 + + (nic_index >> 1) * NIC_MACRO_QMAN_OFFSET + + (nic_index & 0x1) * NIC_ENGINE_QMAN_OFFSET; + break; + case GAUDI_QUEUE_ID_NIC_0_3: + case GAUDI_QUEUE_ID_NIC_1_3: + case GAUDI_QUEUE_ID_NIC_2_3: + case GAUDI_QUEUE_ID_NIC_3_3: + case GAUDI_QUEUE_ID_NIC_4_3: + case GAUDI_QUEUE_ID_NIC_5_3: + case GAUDI_QUEUE_ID_NIC_6_3: + case GAUDI_QUEUE_ID_NIC_7_3: + case GAUDI_QUEUE_ID_NIC_8_3: + case GAUDI_QUEUE_ID_NIC_9_3: + nic_index = (queue_id - GAUDI_QUEUE_ID_NIC_0_3) >> 2; + offset = mmNIC0_QM0_CP_FENCE2_RDATA_3 + + (nic_index >> 1) * NIC_MACRO_QMAN_OFFSET + + (nic_index & 0x1) * NIC_ENGINE_QMAN_OFFSET; break; default: - /* queue index should be valid here */ - dev_crit(hdev->dev, "wrong queue id %d for wait packet\n", - q_idx); - return; + return -EINVAL; } - fence_addr += CFG_BASE; + *addr = CFG_BASE + offset; + + return 0; +} + +static u32 gaudi_add_mon_pkts(void *buf, u16 mon_id, u64 fence_addr) +{ + u64 monitor_base; + u32 size = 0; + u16 msg_addr_offset; /* * monitor_base should be the content of the base0 address registers, @@ -6561,15 +8213,29 @@ static void gaudi_gen_wait_cb(struct hl_device *hdev, void *data, u16 sob_id, size += gaudi_add_mon_msg_short(buf + size, 1, msg_addr_offset); - /* Fourth monitor config packet: bind the monitor to a sync object */ - msg_addr_offset = - (mmSYNC_MNGR_W_S_SYNC_MNGR_OBJS_MON_ARM_0 + mon_id * 4) - - monitor_base; - size += gaudi_add_arm_monitor_pkt(buf + size, sob_id, sob_val, - msg_addr_offset); + return size; +} + +static u32 gaudi_gen_wait_cb(struct hl_device *hdev, + struct hl_gen_wait_properties *prop) +{ + struct hl_cb *cb = (struct hl_cb *) prop->data; + void *buf = cb->kernel_address; + u64 fence_addr = 0; + u32 size = prop->size; - /* Fence packet */ + if (gaudi_get_fence_addr(hdev, prop->q_idx, &fence_addr)) { + dev_crit(hdev->dev, "wrong queue id %d for wait packet\n", + prop->q_idx); + return 0; + } + + size += gaudi_add_mon_pkts(buf + size, prop->mon_id, fence_addr); + size += gaudi_add_arm_monitor_pkt(hdev, buf + size, prop->sob_base, + prop->sob_mask, prop->sob_val, prop->mon_id); size += gaudi_add_fence_pkt(buf + size); + + return size; } static void gaudi_reset_sob(struct hl_device *hdev, void *data) @@ -6621,6 +8287,7 @@ static const struct hl_asic_funcs gaudi_funcs = { .pqe_write = gaudi_pqe_write, .asic_dma_alloc_coherent = gaudi_dma_alloc_coherent, .asic_dma_free_coherent = gaudi_dma_free_coherent, + .scrub_device_mem = gaudi_scrub_device_mem, .get_int_queue_base = gaudi_get_int_queue_base, .test_queues = gaudi_test_queues, .asic_dma_pool_zalloc = gaudi_dma_pool_zalloc, @@ -6658,13 +8325,13 @@ static const struct hl_asic_funcs gaudi_funcs = { .get_pci_id = gaudi_get_pci_id, .get_eeprom_data = gaudi_get_eeprom_data, .send_cpu_message = gaudi_send_cpu_message, - .get_hw_state = gaudi_get_hw_state, .pci_bars_map = gaudi_pci_bars_map, .init_iatu = gaudi_init_iatu, .rreg = hl_rreg, .wreg = hl_wreg, .halt_coresight = gaudi_halt_coresight, .ctx_init = gaudi_ctx_init, + .ctx_fini = gaudi_ctx_fini, .get_clk_rate = gaudi_get_clk_rate, .get_queue_id_for_cq = gaudi_get_queue_id_for_cq, .read_device_fw_version = gaudi_read_device_fw_version, @@ -6675,8 +8342,11 @@ static const struct hl_asic_funcs gaudi_funcs = { .gen_signal_cb = gaudi_gen_signal_cb, .gen_wait_cb = gaudi_gen_wait_cb, .reset_sob = gaudi_reset_sob, + .reset_sob_group = gaudi_reset_sob_group, .set_dma_mask_from_fw = gaudi_set_dma_mask_from_fw, - .get_device_time = gaudi_get_device_time + .get_device_time = gaudi_get_device_time, + .collective_wait_init_cs = gaudi_collective_wait_init_cs, + .collective_wait_create_jobs = gaudi_collective_wait_create_jobs }; /** diff --git a/drivers/misc/habanalabs/gaudi/gaudiP.h b/drivers/misc/habanalabs/gaudi/gaudiP.h index 83ad2b0a3a61..f2d91f4fcffe 100644 --- a/drivers/misc/habanalabs/gaudi/gaudiP.h +++ b/drivers/misc/habanalabs/gaudi/gaudiP.h @@ -14,8 +14,9 @@ #include "../include/gaudi/gaudi_packets.h" #include "../include/gaudi/gaudi.h" #include "../include/gaudi/gaudi_async_events.h" +#include "../include/gaudi/gaudi_fw_if.h" -#define NUMBER_OF_EXT_HW_QUEUES 12 +#define NUMBER_OF_EXT_HW_QUEUES 8 #define NUMBER_OF_CMPLT_QUEUES NUMBER_OF_EXT_HW_QUEUES #define NUMBER_OF_CPU_HW_QUEUES 1 #define NUMBER_OF_INT_HW_QUEUES 100 @@ -23,6 +24,10 @@ NUMBER_OF_CPU_HW_QUEUES + \ NUMBER_OF_INT_HW_QUEUES) +/* 10 NIC QMANs, DMA5 QMAN, TPC7 QMAN */ +#define NUMBER_OF_COLLECTIVE_QUEUES 12 +#define NUMBER_OF_SOBS_IN_GRP 11 + /* * Number of MSI interrupts IDS: * Each completion queue has 1 ID @@ -56,14 +61,14 @@ #define GAUDI_DEFAULT_CARD_NAME "HL2000" -#define GAUDI_MAX_PENDING_CS 1024 +#define GAUDI_MAX_PENDING_CS SZ_16K #if !IS_MAX_PENDING_CS_VALID(GAUDI_MAX_PENDING_CS) #error "GAUDI_MAX_PENDING_CS must be power of 2 and greater than 1" #endif -#define PCI_DMA_NUMBER_OF_CHNLS 3 -#define HBM_DMA_NUMBER_OF_CHNLS 5 +#define PCI_DMA_NUMBER_OF_CHNLS 2 +#define HBM_DMA_NUMBER_OF_CHNLS 6 #define DMA_NUMBER_OF_CHNLS (PCI_DMA_NUMBER_OF_CHNLS + \ HBM_DMA_NUMBER_OF_CHNLS) @@ -79,6 +84,7 @@ #define TPC_QMAN_OFFSET (mmTPC1_QM_BASE - mmTPC0_QM_BASE) #define MME_QMAN_OFFSET (mmMME1_QM_BASE - mmMME0_QM_BASE) #define NIC_MACRO_QMAN_OFFSET (mmNIC1_QM0_BASE - mmNIC0_QM0_BASE) +#define NIC_ENGINE_QMAN_OFFSET (mmNIC0_QM1_BASE - mmNIC0_QM0_BASE) #define TPC_CFG_OFFSET (mmTPC1_CFG_BASE - mmTPC0_CFG_BASE) @@ -99,6 +105,13 @@ #define MME_ACC_OFFSET (mmMME1_ACC_BASE - mmMME0_ACC_BASE) #define SRAM_BANK_OFFSET (mmSRAM_Y0_X1_RTR_BASE - mmSRAM_Y0_X0_RTR_BASE) +#define PLL_NR_OFFSET 0 +#define PLL_NF_OFFSET (mmPSOC_CPU_PLL_NF - mmPSOC_CPU_PLL_NR) +#define PLL_OD_OFFSET (mmPSOC_CPU_PLL_OD - mmPSOC_CPU_PLL_NR) +#define PLL_DIV_FACTOR_0_OFFSET (mmPSOC_CPU_PLL_DIV_FACTOR_0 - \ + mmPSOC_CPU_PLL_NR) +#define PLL_DIV_SEL_0_OFFSET (mmPSOC_CPU_PLL_DIV_SEL_0 - mmPSOC_CPU_PLL_NR) + #define NUM_OF_SOB_IN_BLOCK \ (((mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_2047 - \ mmSYNC_MNGR_E_N_SYNC_MNGR_OBJS_SOB_OBJ_0) + 4) >> 2) @@ -140,13 +153,18 @@ #define TPC_QMAN_LENGTH 1024 #define TPC_QMAN_SIZE_IN_BYTES (TPC_QMAN_LENGTH * QMAN_PQ_ENTRY_SIZE) +#define NIC_QMAN_LENGTH 1024 +#define NIC_QMAN_SIZE_IN_BYTES (NIC_QMAN_LENGTH * QMAN_PQ_ENTRY_SIZE) + + #define SRAM_USER_BASE_OFFSET GAUDI_DRIVER_SRAM_RESERVED_SIZE_FROM_START /* Virtual address space */ #define VA_HOST_SPACE_START 0x1000000000000ull /* 256TB */ -#define VA_HOST_SPACE_END 0x3FF8000000000ull /* 1PB - 1TB */ +#define VA_HOST_SPACE_END 0x3FF8000000000ull /* 1PB - 512GB */ #define VA_HOST_SPACE_SIZE (VA_HOST_SPACE_END - \ VA_HOST_SPACE_START) /* 767TB */ +#define HOST_SPACE_INTERNAL_CB_SZ SZ_2M #define HW_CAP_PLL BIT(0) #define HW_CAP_HBM BIT(1) @@ -161,6 +179,19 @@ #define HW_CAP_SRAM_SCRAMBLER BIT(10) #define HW_CAP_HBM_SCRAMBLER BIT(11) +#define HW_CAP_NIC0 BIT(14) +#define HW_CAP_NIC1 BIT(15) +#define HW_CAP_NIC2 BIT(16) +#define HW_CAP_NIC3 BIT(17) +#define HW_CAP_NIC4 BIT(18) +#define HW_CAP_NIC5 BIT(19) +#define HW_CAP_NIC6 BIT(20) +#define HW_CAP_NIC7 BIT(21) +#define HW_CAP_NIC8 BIT(22) +#define HW_CAP_NIC9 BIT(23) +#define HW_CAP_NIC_MASK GENMASK(23, 14) +#define HW_CAP_NIC_SHIFT 14 + #define HW_CAP_TPC0 BIT(24) #define HW_CAP_TPC1 BIT(25) #define HW_CAP_TPC2 BIT(26) @@ -187,12 +218,12 @@ enum gaudi_dma_channels { GAUDI_PCI_DMA_1, GAUDI_PCI_DMA_2, - GAUDI_PCI_DMA_3, GAUDI_HBM_DMA_1, GAUDI_HBM_DMA_2, GAUDI_HBM_DMA_3, GAUDI_HBM_DMA_4, GAUDI_HBM_DMA_5, + GAUDI_HBM_DMA_6, GAUDI_DMA_MAX }; @@ -208,6 +239,48 @@ enum gaudi_tpc_mask { GAUDI_TPC_MASK_ALL = 0xFF }; +enum gaudi_nic_mask { + GAUDI_NIC_MASK_NIC0 = 0x01, + GAUDI_NIC_MASK_NIC1 = 0x02, + GAUDI_NIC_MASK_NIC2 = 0x04, + GAUDI_NIC_MASK_NIC3 = 0x08, + GAUDI_NIC_MASK_NIC4 = 0x10, + GAUDI_NIC_MASK_NIC5 = 0x20, + GAUDI_NIC_MASK_NIC6 = 0x40, + GAUDI_NIC_MASK_NIC7 = 0x80, + GAUDI_NIC_MASK_NIC8 = 0x100, + GAUDI_NIC_MASK_NIC9 = 0x200, + GAUDI_NIC_MASK_ALL = 0x3FF +}; + +/* + * struct gaudi_hw_sob_group - H/W SOB group info. + * @hdev: habanalabs device structure. + * @kref: refcount of this SOB group. group will reset once refcount is zero. + * @base_sob_id: base sob id of this SOB group. + */ +struct gaudi_hw_sob_group { + struct hl_device *hdev; + struct kref kref; + u32 base_sob_id; +}; + +#define NUM_SOB_GROUPS (HL_RSVD_SOBS * QMAN_STREAMS) +/** + * struct gaudi_collective_properties - + * holds all SOB groups and queues info reserved for the collective + * @hw_sob_group: H/W SOB groups. + * @next_sob_group_val: the next value to use for the currently used SOB group. + * @curr_sob_group_idx: the index of the currently used SOB group. + * @mstr_sob_mask: pre-defined masks for collective master monitors + */ +struct gaudi_collective_properties { + struct gaudi_hw_sob_group hw_sob_group[NUM_SOB_GROUPS]; + u16 next_sob_group_val[QMAN_STREAMS]; + u8 curr_sob_group_idx[QMAN_STREAMS]; + u8 mstr_sob_mask[HL_COLLECTIVE_RSVD_MSTR_MONS]; +}; + /** * struct gaudi_internal_qman_info - Internal QMAN information. * @pq_kernel_addr: Kernel address of the PQ memory area in the host. @@ -253,6 +326,8 @@ struct gaudi_device { struct gaudi_internal_qman_info internal_qmans[GAUDI_QUEUE_ID_SIZE]; + struct gaudi_collective_properties collective_props; + u64 hbm_bar_cur_addr; u64 max_freq_value; @@ -271,5 +346,6 @@ void gaudi_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq); int gaudi_debug_coresight(struct hl_device *hdev, void *data); void gaudi_halt_coresight(struct hl_device *hdev); int gaudi_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk); +void gaudi_mmu_prepare_reg(struct hl_device *hdev, u64 reg, u32 asid); #endif /* GAUDIP_H_ */ diff --git a/drivers/misc/habanalabs/gaudi/gaudi_coresight.c b/drivers/misc/habanalabs/gaudi/gaudi_coresight.c index 881531d4d9da..2e3612e1ee28 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi_coresight.c +++ b/drivers/misc/habanalabs/gaudi/gaudi_coresight.c @@ -11,8 +11,6 @@ #include "../include/gaudi/gaudi_masks.h" #include <uapi/misc/habanalabs.h> -#include <linux/coresight.h> - #define SPMU_SECTION_SIZE MME0_ACC_SPMU_MAX_OFFSET #define SPMU_EVENT_TYPES_OFFSET 0x400 #define SPMU_MAX_COUNTERS 6 @@ -623,6 +621,11 @@ static int gaudi_config_etr(struct hl_device *hdev, return -EINVAL; } + gaudi_mmu_prepare_reg(hdev, mmPSOC_GLOBAL_CONF_TRACE_ARUSER, + hdev->compute_ctx->asid); + gaudi_mmu_prepare_reg(hdev, mmPSOC_GLOBAL_CONF_TRACE_AWUSER, + hdev->compute_ctx->asid); + msb = upper_32_bits(input->buffer_address) >> 8; msb &= PSOC_GLOBAL_CONF_TRACE_ADDR_MSB_MASK; WREG32(mmPSOC_GLOBAL_CONF_TRACE_ADDR, msb); diff --git a/drivers/misc/habanalabs/gaudi/gaudi_hwmgr.c b/drivers/misc/habanalabs/gaudi/gaudi_hwmgr.c index 1076b4932ce2..8c49da4bcbd5 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi_hwmgr.c +++ b/drivers/misc/habanalabs/gaudi/gaudi_hwmgr.c @@ -20,7 +20,7 @@ int gaudi_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk) { long value; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_get_frequency(hdev, MME_PLL, false); @@ -54,7 +54,7 @@ static ssize_t clk_max_freq_mhz_show(struct device *dev, struct gaudi_device *gaudi = hdev->asic_specific; long value; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_get_frequency(hdev, MME_PLL, false); @@ -72,7 +72,7 @@ static ssize_t clk_max_freq_mhz_store(struct device *dev, int rc; u64 value; - if (hl_device_disabled_or_in_reset(hdev)) { + if (!hl_device_operational(hdev, NULL)) { count = -ENODEV; goto fail; } @@ -97,7 +97,7 @@ static ssize_t clk_cur_freq_mhz_show(struct device *dev, struct hl_device *hdev = dev_get_drvdata(dev); long value; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_get_frequency(hdev, MME_PLL, true); diff --git a/drivers/misc/habanalabs/gaudi/gaudi_security.c b/drivers/misc/habanalabs/gaudi/gaudi_security.c index 2d7add0e5bcc..e10181692d0b 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi_security.c +++ b/drivers/misc/habanalabs/gaudi/gaudi_security.c @@ -1448,21 +1448,23 @@ static void gaudi_init_dma_protection_bits(struct hl_device *hdev) u32 pb_addr, mask; u8 word_offset; - gaudi_pb_set_block(hdev, mmDMA_IF_E_S_BASE); - gaudi_pb_set_block(hdev, mmDMA_IF_E_S_DOWN_CH0_BASE); - gaudi_pb_set_block(hdev, mmDMA_IF_E_S_DOWN_CH1_BASE); - gaudi_pb_set_block(hdev, mmDMA_E_PLL_BASE); - gaudi_pb_set_block(hdev, mmDMA_IF_E_S_DOWN_BASE); - - gaudi_pb_set_block(hdev, mmDMA_IF_W_N_BASE); - gaudi_pb_set_block(hdev, mmDMA_IF_W_N_DOWN_CH0_BASE); - gaudi_pb_set_block(hdev, mmDMA_IF_W_N_DOWN_CH1_BASE); - gaudi_pb_set_block(hdev, mmDMA_IF_W_N_DOWN_BASE); - - gaudi_pb_set_block(hdev, mmDMA_IF_E_N_BASE); - gaudi_pb_set_block(hdev, mmDMA_IF_E_N_DOWN_CH0_BASE); - gaudi_pb_set_block(hdev, mmDMA_IF_E_N_DOWN_CH1_BASE); - gaudi_pb_set_block(hdev, mmDMA_IF_E_N_DOWN_BASE); + if (hdev->asic_prop.fw_security_disabled) { + gaudi_pb_set_block(hdev, mmDMA_IF_E_S_BASE); + gaudi_pb_set_block(hdev, mmDMA_IF_E_S_DOWN_CH0_BASE); + gaudi_pb_set_block(hdev, mmDMA_IF_E_S_DOWN_CH1_BASE); + gaudi_pb_set_block(hdev, mmDMA_E_PLL_BASE); + gaudi_pb_set_block(hdev, mmDMA_IF_E_S_DOWN_BASE); + + gaudi_pb_set_block(hdev, mmDMA_IF_W_N_BASE); + gaudi_pb_set_block(hdev, mmDMA_IF_W_N_DOWN_CH0_BASE); + gaudi_pb_set_block(hdev, mmDMA_IF_W_N_DOWN_CH1_BASE); + gaudi_pb_set_block(hdev, mmDMA_IF_W_N_DOWN_BASE); + + gaudi_pb_set_block(hdev, mmDMA_IF_E_N_BASE); + gaudi_pb_set_block(hdev, mmDMA_IF_E_N_DOWN_CH0_BASE); + gaudi_pb_set_block(hdev, mmDMA_IF_E_N_DOWN_CH1_BASE); + gaudi_pb_set_block(hdev, mmDMA_IF_E_N_DOWN_BASE); + } WREG32(mmDMA0_QM_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); WREG32(mmDMA1_QM_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); @@ -5157,19 +5159,3992 @@ static void gaudi_init_dma_protection_bits(struct hl_device *hdev) WREG32(pb_addr + word_offset, ~mask); } +static void gaudi_init_nic_protection_bits(struct hl_device *hdev) +{ + u32 pb_addr, mask; + u8 word_offset; + + WREG32(mmNIC0_QM0_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); + WREG32(mmNIC0_QM1_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); + + pb_addr = (mmNIC0_QM0_GLBL_CFG0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_GLBL_CFG0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_GLBL_CFG0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_CFG1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_PROT & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_ERR_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_NON_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_NON_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_NON_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_NON_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_NON_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_STS0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_STS1_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_MSG_EN_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_MSG_EN_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_MSG_EN_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_MSG_EN_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_MSG_EN_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_BASE_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_BASE_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_BASE_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_BASE_LO_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_PQ_BASE_HI_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_PQ_BASE_HI_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_PQ_BASE_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_BASE_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_BASE_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_BASE_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_SIZE_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_SIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_SIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_SIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_PI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_PI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_PI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_PI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_CI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_CI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_CI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_CI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_CFG0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_CFG0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_CFG0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_CFG0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_CFG1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_CFG1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_CFG1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_CFG1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_STS0_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_PQ_STS1_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_PQ_STS1_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_PQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_PQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_STS0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_TSIZE_0 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_CQ_CTL_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_CQ_CTL_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_CQ_CTL_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_TSIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_CTL_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_TSIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_CTL_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_TSIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_CTL_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_LO_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_LO_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_LO_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_LO_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_LO_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_HI_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_HI_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_HI_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_HI_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_PTR_HI_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_TSIZE_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_TSIZE_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_TSIZE_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_TSIZE_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_TSIZE_STS_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_CQ_CTL_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_CQ_CTL_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_CQ_CTL_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_CTL_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_CTL_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_CTL_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_CTL_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_IFIFO_CNT_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_IFIFO_CNT_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_IFIFO_CNT_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_IFIFO_CNT_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CQ_IFIFO_CNT_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE0_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE0_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE0_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE0_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE0_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE0_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE0_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE0_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE0_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE0_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE1_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE1_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE1_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE1_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE1_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE1_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE1_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE1_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE1_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE1_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE2_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE2_ADDR_LO_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_CP_MSG_BASE2_ADDR_LO_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_CP_MSG_BASE2_ADDR_LO_2 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_CP_MSG_BASE2_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE2_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE2_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE2_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE2_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE2_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE2_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE2_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE3_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE3_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE3_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE3_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE3_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE3_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE3_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE3_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE3_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_MSG_BASE3_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_TSIZE_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_TSIZE_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_TSIZE_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_TSIZE_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_TSIZE_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_CP_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_CP_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_CP_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_CURRENT_INST_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_CURRENT_INST_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_CURRENT_INST_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_CURRENT_INST_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_CURRENT_INST_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_CURRENT_INST_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_CURRENT_INST_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_CURRENT_INST_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_CURRENT_INST_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_CURRENT_INST_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_BARRIER_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_BARRIER_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_BARRIER_CFG_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_CP_BARRIER_CFG_3 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_CP_BARRIER_CFG_3 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_CP_BARRIER_CFG_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_BARRIER_CFG_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_DBG_0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_DBG_0_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_CP_DBG_0_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_CP_DBG_0_2 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_CP_DBG_0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_DBG_0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_DBG_0_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_ARUSER_31_11_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_AWUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_AWUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_AWUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_AWUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CP_AWUSER_31_11_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_ARB_CFG_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_ARB_CFG_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_ARB_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_19 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_23 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_ARB_MST_AVAIL_CRED_24 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_24 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_AVAIL_CRED_31 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_23 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_23 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_ARB_SLV_CHOISE_WDT & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MSG_MAX_INFLIGHT & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MSG_AWUSER_31_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MSG_AWUSER_SEC_PROP & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MSG_AWUSER_NON_SEC_PROP & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_ARB_STATE_STS & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_ARB_STATE_STS & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_ARB_STATE_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_CHOISE_FULLNESS_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MSG_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_SLV_CHOISE_Q_HEAD & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_ERR_CAUSE & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_ERR_MSG_EN & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_ERR_STS_DRP & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_19 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_ARB_MST_CRED_STS_20 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_ARB_MST_CRED_STS_20 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_23 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_ARB_MST_CRED_STS_31 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CGM_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CGM_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CGM_CFG1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_LOCAL_RANGE_BASE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_LOCAL_RANGE_BASE & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_LOCAL_RANGE_BASE & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_LOCAL_RANGE_SIZE & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_CSMR_STRICT_PRIO_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_HBW_RD_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_LBW_WR_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_LBW_WR_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_HBW_RD_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_AXCACHE & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_IND_GW_APB_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_IND_GW_APB_WDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_IND_GW_APB_RDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_IND_GW_APB_STATUS & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_ERR_ADDR_LO & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_ERR_ADDR_HI & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM0_GLBL_ERR_WDATA & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM0_GLBL_MEM_INIT_BUSY & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM0_GLBL_MEM_INIT_BUSY & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC0_QM0_GLBL_MEM_INIT_BUSY & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_GLBL_CFG0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_GLBL_CFG0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_GLBL_CFG0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_CFG1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_PROT & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_ERR_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_NON_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_NON_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_NON_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_NON_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_NON_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_STS0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_STS1_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_MSG_EN_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_MSG_EN_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_MSG_EN_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_MSG_EN_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_MSG_EN_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_BASE_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_BASE_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_BASE_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_BASE_LO_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_PQ_BASE_HI_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_PQ_BASE_HI_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_PQ_BASE_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_BASE_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_BASE_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_BASE_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_SIZE_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_SIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_SIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_SIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_PI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_PI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_PI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_PI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_CI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_CI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_CI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_CI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_CFG0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_CFG0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_CFG0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_CFG0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_CFG1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_CFG1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_CFG1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_CFG1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_STS0_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_PQ_STS1_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_PQ_STS1_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_PQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_PQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_STS0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_TSIZE_0 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_CQ_CTL_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_CQ_CTL_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_CQ_CTL_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_TSIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_CTL_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_TSIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_CTL_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_TSIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_CTL_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_LO_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_LO_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_LO_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_LO_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_LO_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_HI_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_HI_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_HI_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_HI_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_PTR_HI_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_TSIZE_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_TSIZE_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_TSIZE_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_TSIZE_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_TSIZE_STS_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_CQ_CTL_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_CQ_CTL_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_CQ_CTL_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_CTL_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_CTL_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_CTL_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_CTL_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_IFIFO_CNT_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_IFIFO_CNT_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_IFIFO_CNT_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_IFIFO_CNT_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CQ_IFIFO_CNT_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE0_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE0_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE0_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE0_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE0_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE0_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE0_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE0_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE0_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE0_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE1_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE1_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE1_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE1_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE1_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE1_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE1_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE1_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE1_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE1_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE2_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE2_ADDR_LO_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_CP_MSG_BASE2_ADDR_LO_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_CP_MSG_BASE2_ADDR_LO_2 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_CP_MSG_BASE2_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE2_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE2_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE2_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE2_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE2_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE2_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE2_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE3_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE3_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE3_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE3_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE3_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE3_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE3_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE3_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE3_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_MSG_BASE3_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_TSIZE_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_TSIZE_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_TSIZE_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_TSIZE_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_TSIZE_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_DST_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_DST_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_DST_BASE_LO_OFFSET_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_LDMA_DST_BASE_LO_OFFSET_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_CP_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_CP_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_CP_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_CURRENT_INST_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_CURRENT_INST_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_CURRENT_INST_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_CURRENT_INST_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_CURRENT_INST_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_CURRENT_INST_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_CURRENT_INST_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_CURRENT_INST_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_CURRENT_INST_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_CURRENT_INST_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_BARRIER_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_BARRIER_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_BARRIER_CFG_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_CP_BARRIER_CFG_3 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_CP_BARRIER_CFG_3 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_CP_BARRIER_CFG_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_BARRIER_CFG_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_DBG_0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_DBG_0_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_CP_DBG_0_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_CP_DBG_0_2 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_CP_DBG_0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_DBG_0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_DBG_0_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_ARUSER_31_11_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_AWUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_AWUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_AWUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_AWUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CP_AWUSER_31_11_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_ARB_CFG_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_ARB_CFG_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_ARB_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_19 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_23 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_ARB_MST_AVAIL_CRED_24 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_24 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_AVAIL_CRED_31 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_23 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_23 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_ARB_SLV_CHOISE_WDT & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MSG_MAX_INFLIGHT & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MSG_AWUSER_31_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MSG_AWUSER_SEC_PROP & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MSG_AWUSER_NON_SEC_PROP & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_ARB_STATE_STS & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_ARB_STATE_STS & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_ARB_STATE_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_CHOISE_FULLNESS_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MSG_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_SLV_CHOISE_Q_HEAD & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_ERR_CAUSE & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_ERR_MSG_EN & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_ERR_STS_DRP & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_19 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_ARB_MST_CRED_STS_20 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_ARB_MST_CRED_STS_20 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_23 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_ARB_MST_CRED_STS_31 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CGM_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CGM_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CGM_CFG1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_LOCAL_RANGE_BASE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_LOCAL_RANGE_BASE & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_LOCAL_RANGE_BASE & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_LOCAL_RANGE_SIZE & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_CSMR_STRICT_PRIO_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_HBW_RD_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_LBW_WR_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_LBW_WR_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_HBW_RD_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_AXCACHE & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_IND_GW_APB_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_IND_GW_APB_WDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_IND_GW_APB_RDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_IND_GW_APB_STATUS & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_ERR_ADDR_LO & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_ERR_ADDR_HI & 0x7F) >> 2); + mask |= 1U << ((mmNIC0_QM1_GLBL_ERR_WDATA & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC0_QM1_GLBL_MEM_INIT_BUSY & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC0_QM1_GLBL_MEM_INIT_BUSY & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC0_QM1_GLBL_MEM_INIT_BUSY & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + WREG32(mmNIC1_QM0_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); + WREG32(mmNIC1_QM1_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); + + pb_addr = (mmNIC1_QM0_GLBL_CFG0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_GLBL_CFG0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_GLBL_CFG0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_CFG1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_PROT & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_ERR_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_NON_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_NON_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_NON_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_NON_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_NON_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_STS0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_STS1_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_MSG_EN_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_MSG_EN_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_MSG_EN_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_MSG_EN_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_MSG_EN_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_BASE_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_BASE_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_BASE_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_BASE_LO_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_PQ_BASE_HI_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_PQ_BASE_HI_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_PQ_BASE_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_BASE_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_BASE_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_BASE_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_SIZE_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_SIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_SIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_SIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_PI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_PI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_PI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_PI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_CI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_CI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_CI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_CI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_CFG0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_CFG0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_CFG0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_CFG0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_CFG1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_CFG1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_CFG1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_CFG1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_STS0_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_PQ_STS1_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_PQ_STS1_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_PQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_PQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_STS0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_TSIZE_0 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_CQ_CTL_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_CQ_CTL_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_CQ_CTL_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_TSIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_CTL_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_TSIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_CTL_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_TSIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_CTL_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_LO_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_LO_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_LO_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_LO_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_LO_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_HI_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_HI_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_HI_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_HI_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_PTR_HI_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_TSIZE_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_TSIZE_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_TSIZE_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_TSIZE_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_TSIZE_STS_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_CQ_CTL_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_CQ_CTL_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_CQ_CTL_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_CTL_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_CTL_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_CTL_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_CTL_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_IFIFO_CNT_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_IFIFO_CNT_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_IFIFO_CNT_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_IFIFO_CNT_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CQ_IFIFO_CNT_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE0_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE0_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE0_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE0_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE0_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE0_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE0_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE0_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE0_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE0_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE1_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE1_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE1_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE1_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE1_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE1_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE1_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE1_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE1_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE1_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE2_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE2_ADDR_LO_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_CP_MSG_BASE2_ADDR_LO_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_CP_MSG_BASE2_ADDR_LO_2 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_CP_MSG_BASE2_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE2_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE2_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE2_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE2_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE2_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE2_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE2_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE3_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE3_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE3_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE3_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE3_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE3_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE3_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE3_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE3_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_MSG_BASE3_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_TSIZE_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_TSIZE_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_TSIZE_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_TSIZE_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_TSIZE_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_DST_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_DST_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_DST_BASE_LO_OFFSET_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_LDMA_DST_BASE_LO_OFFSET_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_CP_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_CP_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_CP_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_CURRENT_INST_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_CURRENT_INST_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_CURRENT_INST_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_CURRENT_INST_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_CURRENT_INST_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_CURRENT_INST_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_CURRENT_INST_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_CURRENT_INST_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_CURRENT_INST_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_CURRENT_INST_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_BARRIER_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_BARRIER_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_BARRIER_CFG_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_CP_BARRIER_CFG_3 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_CP_BARRIER_CFG_3 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_CP_BARRIER_CFG_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_BARRIER_CFG_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_DBG_0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_DBG_0_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_CP_DBG_0_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_CP_DBG_0_2 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_CP_DBG_0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_DBG_0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_DBG_0_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_ARUSER_31_11_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_AWUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_AWUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_AWUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_AWUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CP_AWUSER_31_11_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_ARB_CFG_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_ARB_CFG_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_ARB_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_19 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_23 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_ARB_MST_AVAIL_CRED_24 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_24 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_AVAIL_CRED_31 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_23 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_23 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_ARB_SLV_CHOISE_WDT & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MSG_MAX_INFLIGHT & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MSG_AWUSER_31_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MSG_AWUSER_SEC_PROP & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MSG_AWUSER_NON_SEC_PROP & 0x7F) >> 2); + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_ARB_STATE_STS & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_ARB_STATE_STS & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_ARB_STATE_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_CHOISE_FULLNESS_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MSG_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_SLV_CHOISE_Q_HEAD & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_ERR_CAUSE & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_ERR_MSG_EN & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_ERR_STS_DRP & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_19 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_ARB_MST_CRED_STS_20 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_ARB_MST_CRED_STS_20 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_23 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_ARB_MST_CRED_STS_31 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CGM_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CGM_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CGM_CFG1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_LOCAL_RANGE_BASE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_LOCAL_RANGE_BASE & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_LOCAL_RANGE_BASE & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_LOCAL_RANGE_SIZE & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_CSMR_STRICT_PRIO_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_HBW_RD_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_LBW_WR_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_LBW_WR_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_HBW_RD_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_AXCACHE & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_IND_GW_APB_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_IND_GW_APB_WDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_IND_GW_APB_RDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_IND_GW_APB_STATUS & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_ERR_ADDR_LO & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_ERR_ADDR_HI & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM0_GLBL_ERR_WDATA & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM0_GLBL_MEM_INIT_BUSY & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM0_GLBL_MEM_INIT_BUSY & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC1_QM0_GLBL_MEM_INIT_BUSY & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_GLBL_CFG0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_GLBL_CFG0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_GLBL_CFG0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_CFG1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_PROT & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_ERR_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_NON_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_NON_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_NON_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_NON_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_NON_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_STS0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_STS1_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_MSG_EN_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_MSG_EN_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_MSG_EN_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_MSG_EN_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_MSG_EN_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_BASE_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_BASE_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_BASE_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_BASE_LO_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_PQ_BASE_HI_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_PQ_BASE_HI_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_PQ_BASE_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_BASE_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_BASE_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_BASE_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_SIZE_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_SIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_SIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_SIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_PI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_PI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_PI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_PI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_CI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_CI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_CI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_CI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_CFG0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_CFG0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_CFG0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_CFG0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_CFG1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_CFG1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_CFG1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_CFG1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_STS0_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_PQ_STS1_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_PQ_STS1_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_PQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_PQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_STS0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_TSIZE_0 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_CQ_CTL_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_CQ_CTL_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_CQ_CTL_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_TSIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_CTL_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_TSIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_CTL_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_TSIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_CTL_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_LO_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_LO_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_LO_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_LO_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_LO_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_HI_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_HI_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_HI_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_HI_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_PTR_HI_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_TSIZE_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_TSIZE_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_TSIZE_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_TSIZE_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_TSIZE_STS_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_CQ_CTL_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_CQ_CTL_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_CQ_CTL_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_CTL_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_CTL_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_CTL_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_CTL_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_IFIFO_CNT_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_IFIFO_CNT_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_IFIFO_CNT_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_IFIFO_CNT_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CQ_IFIFO_CNT_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE0_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE0_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE0_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE0_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE0_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE0_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE0_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE0_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE0_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE0_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE1_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE1_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE1_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE1_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE1_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE1_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE1_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE1_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE1_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE1_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE2_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE2_ADDR_LO_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_CP_MSG_BASE2_ADDR_LO_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_CP_MSG_BASE2_ADDR_LO_2 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_CP_MSG_BASE2_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE2_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE2_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE2_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE2_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE2_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE2_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE2_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE3_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE3_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE3_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE3_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE3_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE3_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE3_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE3_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE3_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_MSG_BASE3_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_TSIZE_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_TSIZE_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_TSIZE_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_TSIZE_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_TSIZE_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_DST_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_DST_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_DST_BASE_LO_OFFSET_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_LDMA_DST_BASE_LO_OFFSET_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_CP_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_CP_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_CP_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_CURRENT_INST_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_CURRENT_INST_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_CURRENT_INST_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_CURRENT_INST_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_CURRENT_INST_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_CURRENT_INST_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_CURRENT_INST_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_CURRENT_INST_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_CURRENT_INST_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_CURRENT_INST_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_BARRIER_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_BARRIER_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_BARRIER_CFG_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_CP_BARRIER_CFG_3 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_CP_BARRIER_CFG_3 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_CP_BARRIER_CFG_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_BARRIER_CFG_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_DBG_0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_DBG_0_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_CP_DBG_0_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_CP_DBG_0_2 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_CP_DBG_0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_DBG_0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_DBG_0_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_ARUSER_31_11_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_AWUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_AWUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_AWUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_AWUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CP_AWUSER_31_11_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_ARB_CFG_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_ARB_CFG_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_ARB_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_19 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_23 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_ARB_MST_AVAIL_CRED_24 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_24 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_AVAIL_CRED_31 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_23 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_23 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_ARB_SLV_CHOISE_WDT & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MSG_MAX_INFLIGHT & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MSG_AWUSER_31_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MSG_AWUSER_SEC_PROP & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MSG_AWUSER_NON_SEC_PROP & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_ARB_STATE_STS & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_ARB_STATE_STS & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_ARB_STATE_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_CHOISE_FULLNESS_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MSG_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_SLV_CHOISE_Q_HEAD & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_ERR_CAUSE & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_ERR_MSG_EN & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_ERR_STS_DRP & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_19 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_ARB_MST_CRED_STS_20 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_ARB_MST_CRED_STS_20 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_23 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_ARB_MST_CRED_STS_31 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CGM_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CGM_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CGM_CFG1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_LOCAL_RANGE_BASE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_LOCAL_RANGE_BASE & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_LOCAL_RANGE_BASE & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_LOCAL_RANGE_SIZE & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_CSMR_STRICT_PRIO_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_HBW_RD_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_LBW_WR_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_LBW_WR_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_HBW_RD_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_AXCACHE & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_IND_GW_APB_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_IND_GW_APB_WDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_IND_GW_APB_RDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_IND_GW_APB_STATUS & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_ERR_ADDR_LO & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_ERR_ADDR_HI & 0x7F) >> 2); + mask |= 1U << ((mmNIC1_QM1_GLBL_ERR_WDATA & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC1_QM1_GLBL_MEM_INIT_BUSY & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC1_QM1_GLBL_MEM_INIT_BUSY & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC1_QM1_GLBL_MEM_INIT_BUSY & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + WREG32(mmNIC2_QM0_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); + WREG32(mmNIC2_QM1_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); + + pb_addr = (mmNIC2_QM0_GLBL_CFG0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_GLBL_CFG0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_GLBL_CFG0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_CFG1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_PROT & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_ERR_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_NON_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_NON_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_NON_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_NON_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_NON_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_STS0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_STS1_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_MSG_EN_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_MSG_EN_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_MSG_EN_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_MSG_EN_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_MSG_EN_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_BASE_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_BASE_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_BASE_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_BASE_LO_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_PQ_BASE_HI_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_PQ_BASE_HI_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_PQ_BASE_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_BASE_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_BASE_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_BASE_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_SIZE_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_SIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_SIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_SIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_PI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_PI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_PI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_PI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_CI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_CI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_CI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_CI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_CFG0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_CFG0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_CFG0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_CFG0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_CFG1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_CFG1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_CFG1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_CFG1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_STS0_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_PQ_STS1_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_PQ_STS1_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_PQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_PQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_STS0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_TSIZE_0 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_CQ_CTL_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_CQ_CTL_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_CQ_CTL_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_TSIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_CTL_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_TSIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_CTL_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_TSIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_CTL_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_LO_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_LO_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_LO_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_LO_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_LO_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_HI_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_HI_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_HI_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_HI_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_PTR_HI_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_TSIZE_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_TSIZE_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_TSIZE_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_TSIZE_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_TSIZE_STS_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_CQ_CTL_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_CQ_CTL_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_CQ_CTL_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_CTL_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_CTL_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_CTL_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_CTL_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_IFIFO_CNT_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_IFIFO_CNT_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_IFIFO_CNT_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_IFIFO_CNT_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CQ_IFIFO_CNT_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE0_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE0_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE0_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE0_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE0_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE0_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE0_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE0_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE0_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE0_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE1_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE1_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE1_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE1_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE1_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE1_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE1_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE1_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE1_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE1_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE2_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE2_ADDR_LO_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_CP_MSG_BASE2_ADDR_LO_2 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_CP_MSG_BASE2_ADDR_LO_2 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_CP_MSG_BASE2_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE2_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE2_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE2_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE2_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE2_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE2_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE2_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE3_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE3_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE3_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE3_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE3_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE3_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE3_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE3_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE3_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_MSG_BASE3_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_TSIZE_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_TSIZE_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_TSIZE_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_TSIZE_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_TSIZE_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_DST_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_DST_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_DST_BASE_LO_OFFSET_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_LDMA_DST_BASE_LO_OFFSET_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_CP_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_CP_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_CP_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_CURRENT_INST_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_CURRENT_INST_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_CURRENT_INST_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_CURRENT_INST_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_CURRENT_INST_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_CURRENT_INST_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_CURRENT_INST_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_CURRENT_INST_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_CURRENT_INST_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_CURRENT_INST_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_BARRIER_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_BARRIER_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_BARRIER_CFG_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_CP_BARRIER_CFG_3 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_CP_BARRIER_CFG_3 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_CP_BARRIER_CFG_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_BARRIER_CFG_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_DBG_0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_DBG_0_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_CP_DBG_0_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_CP_DBG_0_2 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_CP_DBG_0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_DBG_0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_DBG_0_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_ARUSER_31_11_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_AWUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_AWUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_AWUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_AWUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CP_AWUSER_31_11_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_ARB_CFG_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_ARB_CFG_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_ARB_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_19 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_23 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_ARB_MST_AVAIL_CRED_24 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_24 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_AVAIL_CRED_31 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_23 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_23 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_ARB_SLV_CHOISE_WDT & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MSG_MAX_INFLIGHT & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MSG_AWUSER_31_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MSG_AWUSER_SEC_PROP & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MSG_AWUSER_NON_SEC_PROP & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_ARB_STATE_STS & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_ARB_STATE_STS & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_ARB_STATE_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_CHOISE_FULLNESS_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MSG_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_SLV_CHOISE_Q_HEAD & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_ERR_CAUSE & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_ERR_MSG_EN & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_ERR_STS_DRP & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_19 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_ARB_MST_CRED_STS_20 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_ARB_MST_CRED_STS_20 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_23 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_ARB_MST_CRED_STS_31 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CGM_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CGM_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CGM_CFG1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_LOCAL_RANGE_BASE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_LOCAL_RANGE_BASE & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_LOCAL_RANGE_BASE & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_LOCAL_RANGE_SIZE & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_CSMR_STRICT_PRIO_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_HBW_RD_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_LBW_WR_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_LBW_WR_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_HBW_RD_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_AXCACHE & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_IND_GW_APB_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_IND_GW_APB_WDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_IND_GW_APB_RDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_IND_GW_APB_STATUS & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_ERR_ADDR_LO & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_ERR_ADDR_HI & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM0_GLBL_ERR_WDATA & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM0_GLBL_MEM_INIT_BUSY & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM0_GLBL_MEM_INIT_BUSY & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC2_QM0_GLBL_MEM_INIT_BUSY & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_GLBL_CFG0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_GLBL_CFG0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_GLBL_CFG0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_CFG1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_PROT & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_ERR_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_NON_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_NON_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_NON_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_NON_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_NON_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_STS0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_STS1_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_MSG_EN_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_MSG_EN_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_MSG_EN_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_MSG_EN_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_MSG_EN_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_BASE_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_BASE_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_BASE_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_BASE_LO_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_PQ_BASE_HI_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_PQ_BASE_HI_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_PQ_BASE_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_BASE_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_BASE_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_BASE_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_SIZE_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_SIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_SIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_SIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_PI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_PI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_PI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_PI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_CI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_CI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_CI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_CI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_CFG0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_CFG0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_CFG0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_CFG0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_CFG1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_CFG1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_CFG1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_CFG1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_STS0_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_PQ_STS1_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_PQ_STS1_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_PQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_PQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_STS0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_TSIZE_0 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_CQ_CTL_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_CQ_CTL_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_CQ_CTL_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_TSIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_CTL_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_TSIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_CTL_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_TSIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_CTL_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_LO_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_LO_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_LO_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_LO_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_LO_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_HI_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_HI_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_HI_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_HI_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_PTR_HI_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_TSIZE_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_TSIZE_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_TSIZE_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_TSIZE_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_TSIZE_STS_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_CQ_CTL_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_CQ_CTL_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_CQ_CTL_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_CTL_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_CTL_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_CTL_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_CTL_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_IFIFO_CNT_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_IFIFO_CNT_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_IFIFO_CNT_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_IFIFO_CNT_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CQ_IFIFO_CNT_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE0_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE0_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE0_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE0_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE0_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE0_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE0_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE0_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE0_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE0_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE1_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE1_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE1_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE1_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE1_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE1_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE1_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE1_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE1_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE1_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE2_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE2_ADDR_LO_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_CP_MSG_BASE2_ADDR_LO_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_CP_MSG_BASE2_ADDR_LO_2 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_CP_MSG_BASE2_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE2_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE2_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE2_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE2_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE2_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE2_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE2_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE3_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE3_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE3_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE3_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE3_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE3_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE3_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE3_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE3_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_MSG_BASE3_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_TSIZE_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_TSIZE_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_TSIZE_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_TSIZE_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_TSIZE_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_DST_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_DST_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_DST_BASE_LO_OFFSET_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_LDMA_DST_BASE_LO_OFFSET_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_CP_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_CP_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_CP_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_CURRENT_INST_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_CURRENT_INST_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_CURRENT_INST_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_CURRENT_INST_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_CURRENT_INST_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_CURRENT_INST_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_CURRENT_INST_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_CURRENT_INST_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_CURRENT_INST_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_CURRENT_INST_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_BARRIER_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_BARRIER_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_BARRIER_CFG_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_CP_BARRIER_CFG_3 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_CP_BARRIER_CFG_3 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_CP_BARRIER_CFG_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_BARRIER_CFG_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_DBG_0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_DBG_0_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_CP_DBG_0_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_CP_DBG_0_2 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_CP_DBG_0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_DBG_0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_DBG_0_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_ARUSER_31_11_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_AWUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_AWUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_AWUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_AWUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CP_AWUSER_31_11_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_ARB_CFG_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_ARB_CFG_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_ARB_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_19 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_23 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_ARB_MST_AVAIL_CRED_24 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_24 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_AVAIL_CRED_31 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_23 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_23 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_ARB_SLV_CHOISE_WDT & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MSG_MAX_INFLIGHT & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MSG_AWUSER_31_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MSG_AWUSER_SEC_PROP & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MSG_AWUSER_NON_SEC_PROP & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_ARB_STATE_STS & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_ARB_STATE_STS & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_ARB_STATE_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_CHOISE_FULLNESS_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MSG_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_SLV_CHOISE_Q_HEAD & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_ERR_CAUSE & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_ERR_MSG_EN & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_ERR_STS_DRP & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_19 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_ARB_MST_CRED_STS_20 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_ARB_MST_CRED_STS_20 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_23 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_ARB_MST_CRED_STS_31 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CGM_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CGM_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CGM_CFG1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_LOCAL_RANGE_BASE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_LOCAL_RANGE_BASE & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_LOCAL_RANGE_BASE & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_LOCAL_RANGE_SIZE & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_CSMR_STRICT_PRIO_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_HBW_RD_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_LBW_WR_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_LBW_WR_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_HBW_RD_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_AXCACHE & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_IND_GW_APB_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_IND_GW_APB_WDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_IND_GW_APB_RDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_IND_GW_APB_STATUS & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_ERR_ADDR_LO & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_ERR_ADDR_HI & 0x7F) >> 2); + mask |= 1U << ((mmNIC2_QM1_GLBL_ERR_WDATA & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC2_QM1_GLBL_MEM_INIT_BUSY & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC2_QM1_GLBL_MEM_INIT_BUSY & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC2_QM1_GLBL_MEM_INIT_BUSY & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + WREG32(mmNIC3_QM0_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); + WREG32(mmNIC3_QM1_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); + + pb_addr = (mmNIC3_QM0_GLBL_CFG0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_GLBL_CFG0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_GLBL_CFG0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_CFG1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_PROT & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_ERR_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_NON_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_NON_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_NON_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_NON_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_NON_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_STS0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_STS1_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_MSG_EN_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_MSG_EN_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_MSG_EN_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_MSG_EN_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_MSG_EN_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_BASE_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_BASE_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_BASE_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_BASE_LO_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_PQ_BASE_HI_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_PQ_BASE_HI_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_PQ_BASE_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_BASE_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_BASE_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_BASE_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_SIZE_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_SIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_SIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_SIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_PI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_PI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_PI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_PI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_CI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_CI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_CI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_CI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_CFG0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_CFG0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_CFG0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_CFG0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_CFG1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_CFG1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_CFG1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_CFG1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_STS0_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_PQ_STS1_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_PQ_STS1_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_PQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_PQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_STS0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_TSIZE_0 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_CQ_CTL_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_CQ_CTL_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_CQ_CTL_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_TSIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_CTL_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_TSIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_CTL_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_TSIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_CTL_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_LO_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_LO_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_LO_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_LO_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_LO_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_HI_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_HI_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_HI_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_HI_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_PTR_HI_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_TSIZE_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_TSIZE_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_TSIZE_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_TSIZE_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_TSIZE_STS_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_CQ_CTL_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_CQ_CTL_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_CQ_CTL_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_CTL_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_CTL_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_CTL_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_CTL_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_IFIFO_CNT_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_IFIFO_CNT_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_IFIFO_CNT_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_IFIFO_CNT_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CQ_IFIFO_CNT_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE0_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE0_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE0_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE0_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE0_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE0_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE0_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE0_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE0_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE0_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE1_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE1_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE1_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE1_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE1_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE1_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE1_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE1_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE1_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE1_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE2_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE2_ADDR_LO_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_CP_MSG_BASE2_ADDR_LO_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_CP_MSG_BASE2_ADDR_LO_2 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_CP_MSG_BASE2_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE2_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE2_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE2_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE2_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE2_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE2_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE2_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE3_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE3_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE3_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE3_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE3_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE3_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE3_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE3_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE3_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_MSG_BASE3_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_TSIZE_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_TSIZE_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_TSIZE_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_TSIZE_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_TSIZE_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_DST_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_DST_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_DST_BASE_LO_OFFSET_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_LDMA_DST_BASE_LO_OFFSET_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_CP_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_CP_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_CP_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_CURRENT_INST_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_CURRENT_INST_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_CURRENT_INST_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_CURRENT_INST_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_CURRENT_INST_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_CURRENT_INST_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_CURRENT_INST_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_CURRENT_INST_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_CURRENT_INST_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_CURRENT_INST_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_BARRIER_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_BARRIER_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_BARRIER_CFG_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_CP_BARRIER_CFG_3 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_CP_BARRIER_CFG_3 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_CP_BARRIER_CFG_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_BARRIER_CFG_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_DBG_0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_DBG_0_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_CP_DBG_0_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_CP_DBG_0_2 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_CP_DBG_0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_DBG_0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_DBG_0_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_ARUSER_31_11_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_AWUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_AWUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_AWUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_AWUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CP_AWUSER_31_11_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_ARB_CFG_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_ARB_CFG_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_ARB_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_19 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_23 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_ARB_MST_AVAIL_CRED_24 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_24 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_AVAIL_CRED_31 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_23 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_23 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_ARB_SLV_CHOISE_WDT & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MSG_MAX_INFLIGHT & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MSG_AWUSER_31_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MSG_AWUSER_SEC_PROP & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MSG_AWUSER_NON_SEC_PROP & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_ARB_STATE_STS & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_ARB_STATE_STS & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_ARB_STATE_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_CHOISE_FULLNESS_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MSG_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_SLV_CHOISE_Q_HEAD & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_ERR_CAUSE & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_ERR_MSG_EN & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_ERR_STS_DRP & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_19 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_ARB_MST_CRED_STS_20 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_ARB_MST_CRED_STS_20 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_23 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_ARB_MST_CRED_STS_31 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CGM_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CGM_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CGM_CFG1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_LOCAL_RANGE_BASE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_LOCAL_RANGE_BASE & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_LOCAL_RANGE_BASE & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_LOCAL_RANGE_SIZE & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_CSMR_STRICT_PRIO_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_HBW_RD_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_LBW_WR_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_LBW_WR_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_HBW_RD_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_AXCACHE & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_IND_GW_APB_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_IND_GW_APB_WDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_IND_GW_APB_RDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_IND_GW_APB_STATUS & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_ERR_ADDR_LO & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_ERR_ADDR_HI & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM0_GLBL_ERR_WDATA & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM0_GLBL_MEM_INIT_BUSY & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM0_GLBL_MEM_INIT_BUSY & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC3_QM0_GLBL_MEM_INIT_BUSY & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_GLBL_CFG0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_GLBL_CFG0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_GLBL_CFG0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_CFG1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_PROT & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_ERR_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_NON_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_NON_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_NON_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_NON_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_NON_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_STS0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_STS1_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_MSG_EN_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_MSG_EN_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_MSG_EN_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_MSG_EN_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_MSG_EN_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_BASE_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_BASE_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_BASE_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_BASE_LO_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_PQ_BASE_HI_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_PQ_BASE_HI_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_PQ_BASE_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_BASE_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_BASE_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_BASE_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_SIZE_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_SIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_SIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_SIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_PI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_PI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_PI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_PI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_CI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_CI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_CI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_CI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_CFG0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_CFG0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_CFG0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_CFG0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_CFG1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_CFG1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_CFG1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_CFG1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_STS0_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_PQ_STS1_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_PQ_STS1_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_PQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_PQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_STS0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_TSIZE_0 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_CQ_CTL_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_CQ_CTL_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_CQ_CTL_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_TSIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_CTL_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_TSIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_CTL_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_TSIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_CTL_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_LO_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_LO_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_LO_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_LO_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_LO_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_HI_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_HI_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_HI_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_HI_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_PTR_HI_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_TSIZE_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_TSIZE_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_TSIZE_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_TSIZE_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_TSIZE_STS_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_CQ_CTL_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_CQ_CTL_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_CQ_CTL_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_CTL_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_CTL_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_CTL_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_CTL_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_IFIFO_CNT_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_IFIFO_CNT_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_IFIFO_CNT_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_IFIFO_CNT_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CQ_IFIFO_CNT_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE0_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE0_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE0_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE0_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE0_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE0_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE0_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE0_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE0_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE0_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE1_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE1_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE1_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE1_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE1_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE1_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE1_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE1_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE1_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE1_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE2_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE2_ADDR_LO_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_CP_MSG_BASE2_ADDR_LO_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_CP_MSG_BASE2_ADDR_LO_2 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_CP_MSG_BASE2_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE2_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE2_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE2_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE2_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE2_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE2_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE2_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE3_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE3_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE3_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE3_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE3_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE3_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE3_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE3_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE3_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_MSG_BASE3_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_TSIZE_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_TSIZE_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_TSIZE_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_TSIZE_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_TSIZE_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_DST_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_DST_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_DST_BASE_LO_OFFSET_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_LDMA_DST_BASE_LO_OFFSET_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_CP_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_CP_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_CP_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_CURRENT_INST_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_CURRENT_INST_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_CURRENT_INST_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_CURRENT_INST_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_CURRENT_INST_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_CURRENT_INST_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_CURRENT_INST_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_CURRENT_INST_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_CURRENT_INST_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_CURRENT_INST_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_BARRIER_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_BARRIER_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_BARRIER_CFG_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_CP_BARRIER_CFG_3 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_CP_BARRIER_CFG_3 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_CP_BARRIER_CFG_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_BARRIER_CFG_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_DBG_0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_DBG_0_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_CP_DBG_0_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_CP_DBG_0_2 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_CP_DBG_0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_DBG_0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_DBG_0_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_ARUSER_31_11_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_AWUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_AWUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_AWUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_AWUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CP_AWUSER_31_11_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_ARB_CFG_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_ARB_CFG_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_ARB_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_19 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_23 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_ARB_MST_AVAIL_CRED_24 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_24 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_AVAIL_CRED_31 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_23 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_23 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_ARB_SLV_CHOISE_WDT & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MSG_MAX_INFLIGHT & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MSG_AWUSER_31_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MSG_AWUSER_SEC_PROP & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MSG_AWUSER_NON_SEC_PROP & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_ARB_STATE_STS & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_ARB_STATE_STS & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_ARB_STATE_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_CHOISE_FULLNESS_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MSG_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_SLV_CHOISE_Q_HEAD & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_ERR_CAUSE & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_ERR_MSG_EN & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_ERR_STS_DRP & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_19 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_ARB_MST_CRED_STS_20 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_ARB_MST_CRED_STS_20 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_23 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_ARB_MST_CRED_STS_31 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CGM_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CGM_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CGM_CFG1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_LOCAL_RANGE_BASE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_LOCAL_RANGE_BASE & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_LOCAL_RANGE_BASE & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_LOCAL_RANGE_SIZE & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_CSMR_STRICT_PRIO_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_HBW_RD_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_LBW_WR_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_LBW_WR_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_HBW_RD_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_AXCACHE & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_IND_GW_APB_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_IND_GW_APB_WDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_IND_GW_APB_RDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_IND_GW_APB_STATUS & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_ERR_ADDR_LO & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_ERR_ADDR_HI & 0x7F) >> 2); + mask |= 1U << ((mmNIC3_QM1_GLBL_ERR_WDATA & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC3_QM1_GLBL_MEM_INIT_BUSY & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC3_QM1_GLBL_MEM_INIT_BUSY & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC3_QM1_GLBL_MEM_INIT_BUSY & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + WREG32(mmNIC4_QM0_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); + WREG32(mmNIC4_QM1_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); + + pb_addr = (mmNIC4_QM0_GLBL_CFG0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_GLBL_CFG0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_GLBL_CFG0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_CFG1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_PROT & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_ERR_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_NON_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_NON_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_NON_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_NON_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_NON_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_STS0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_STS1_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_MSG_EN_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_MSG_EN_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_MSG_EN_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_MSG_EN_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_MSG_EN_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_BASE_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_BASE_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_BASE_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_BASE_LO_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_PQ_BASE_HI_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_PQ_BASE_HI_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_PQ_BASE_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_BASE_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_BASE_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_BASE_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_SIZE_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_SIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_SIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_SIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_PI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_PI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_PI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_PI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_CI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_CI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_CI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_CI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_CFG0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_CFG0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_CFG0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_CFG0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_CFG1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_CFG1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_CFG1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_CFG1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_STS0_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_PQ_STS1_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_PQ_STS1_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_PQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_PQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_STS0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_TSIZE_0 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_CQ_CTL_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_CQ_CTL_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_CQ_CTL_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_TSIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_CTL_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_TSIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_CTL_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_TSIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_CTL_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_LO_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_LO_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_LO_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_LO_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_LO_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_HI_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_HI_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_HI_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_HI_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_PTR_HI_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_TSIZE_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_TSIZE_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_TSIZE_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_TSIZE_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_TSIZE_STS_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_CQ_CTL_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_CQ_CTL_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_CQ_CTL_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_CTL_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_CTL_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_CTL_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_CTL_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_IFIFO_CNT_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_IFIFO_CNT_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_IFIFO_CNT_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_IFIFO_CNT_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CQ_IFIFO_CNT_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE0_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE0_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE0_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE0_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE0_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE0_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE0_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE0_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE0_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE0_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE1_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE1_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE1_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE1_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE1_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE1_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE1_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE1_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE1_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE1_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE2_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE2_ADDR_LO_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_CP_MSG_BASE2_ADDR_LO_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_CP_MSG_BASE2_ADDR_LO_2 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_CP_MSG_BASE2_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE2_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE2_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE2_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE2_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE2_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE2_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE2_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE3_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE3_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE3_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE3_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE3_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE3_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE3_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE3_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE3_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_MSG_BASE3_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_TSIZE_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_TSIZE_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_TSIZE_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_TSIZE_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_TSIZE_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_DST_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_DST_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_DST_BASE_LO_OFFSET_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_LDMA_DST_BASE_LO_OFFSET_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_CP_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_CP_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_CP_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_CURRENT_INST_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_CURRENT_INST_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_CURRENT_INST_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_CURRENT_INST_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_CURRENT_INST_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_CURRENT_INST_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_CURRENT_INST_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_CURRENT_INST_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_CURRENT_INST_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_CURRENT_INST_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_BARRIER_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_BARRIER_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_BARRIER_CFG_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_CP_BARRIER_CFG_3 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_CP_BARRIER_CFG_3 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_CP_BARRIER_CFG_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_BARRIER_CFG_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_DBG_0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_DBG_0_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_CP_DBG_0_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_CP_DBG_0_2 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_CP_DBG_0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_DBG_0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_DBG_0_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_ARUSER_31_11_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_AWUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_AWUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_AWUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_AWUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CP_AWUSER_31_11_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_ARB_CFG_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_ARB_CFG_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_ARB_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_19 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_23 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_ARB_MST_AVAIL_CRED_24 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_24 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_AVAIL_CRED_31 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_23 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_23 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_ARB_SLV_CHOISE_WDT & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MSG_MAX_INFLIGHT & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MSG_AWUSER_31_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MSG_AWUSER_SEC_PROP & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MSG_AWUSER_NON_SEC_PROP & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_ARB_STATE_STS & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_ARB_STATE_STS & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_ARB_STATE_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_CHOISE_FULLNESS_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MSG_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_SLV_CHOISE_Q_HEAD & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_ERR_CAUSE & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_ERR_MSG_EN & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_ERR_STS_DRP & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_19 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_ARB_MST_CRED_STS_20 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_ARB_MST_CRED_STS_20 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_23 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_ARB_MST_CRED_STS_31 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CGM_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CGM_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CGM_CFG1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_LOCAL_RANGE_BASE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_LOCAL_RANGE_BASE & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_LOCAL_RANGE_BASE & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_LOCAL_RANGE_SIZE & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_CSMR_STRICT_PRIO_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_HBW_RD_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_LBW_WR_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_LBW_WR_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_HBW_RD_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_AXCACHE & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_IND_GW_APB_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_IND_GW_APB_WDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_IND_GW_APB_RDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_IND_GW_APB_STATUS & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_ERR_ADDR_LO & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_ERR_ADDR_HI & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM0_GLBL_ERR_WDATA & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM0_GLBL_MEM_INIT_BUSY & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM0_GLBL_MEM_INIT_BUSY & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC4_QM0_GLBL_MEM_INIT_BUSY & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_GLBL_CFG0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_GLBL_CFG0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_GLBL_CFG0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_CFG1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_PROT & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_ERR_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_NON_SECURE_PROPS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_NON_SECURE_PROPS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_NON_SECURE_PROPS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_NON_SECURE_PROPS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_NON_SECURE_PROPS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_STS0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_STS1_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_MSG_EN_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_MSG_EN_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_MSG_EN_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_MSG_EN_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_MSG_EN_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_BASE_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_BASE_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_BASE_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_BASE_LO_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_PQ_BASE_HI_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_PQ_BASE_HI_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_PQ_BASE_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_BASE_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_BASE_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_BASE_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_SIZE_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_SIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_SIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_SIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_PI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_PI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_PI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_PI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_CI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_CI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_CI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_CI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_CFG0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_CFG0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_CFG0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_CFG0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_CFG1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_CFG1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_CFG1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_CFG1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_STS0_3 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_PQ_STS1_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_PQ_STS1_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_PQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_PQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_STS0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_STS0_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_STS0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_STS0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_STS1_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_STS1_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_STS1_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_STS1_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_TSIZE_0 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_CQ_CTL_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_CQ_CTL_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_CQ_CTL_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_TSIZE_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_CTL_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_TSIZE_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_CTL_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_TSIZE_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_CTL_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_LO_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_LO_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_LO_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_LO_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_LO_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_HI_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_HI_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_HI_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_HI_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_PTR_HI_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_TSIZE_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_TSIZE_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_TSIZE_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_TSIZE_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_TSIZE_STS_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_CQ_CTL_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_CQ_CTL_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_CQ_CTL_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_CTL_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_CTL_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_CTL_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_CTL_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_IFIFO_CNT_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_IFIFO_CNT_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_IFIFO_CNT_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_IFIFO_CNT_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CQ_IFIFO_CNT_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE0_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE0_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE0_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE0_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE0_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE0_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE0_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE0_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE0_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE0_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE1_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE1_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE1_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE1_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE1_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE1_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE1_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE1_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE1_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE1_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE2_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE2_ADDR_LO_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_CP_MSG_BASE2_ADDR_LO_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_CP_MSG_BASE2_ADDR_LO_2 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_CP_MSG_BASE2_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE2_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE2_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE2_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE2_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE2_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE2_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE2_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE3_ADDR_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE3_ADDR_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE3_ADDR_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE3_ADDR_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE3_ADDR_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE3_ADDR_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE3_ADDR_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE3_ADDR_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE3_ADDR_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_MSG_BASE3_ADDR_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_TSIZE_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_TSIZE_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_TSIZE_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_TSIZE_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_TSIZE_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_DST_BASE_LO_OFFSET_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_DST_BASE_LO_OFFSET_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_DST_BASE_LO_OFFSET_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_LDMA_DST_BASE_LO_OFFSET_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_CP_STS_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_CP_STS_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_CP_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_CURRENT_INST_LO_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_CURRENT_INST_LO_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_CURRENT_INST_LO_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_CURRENT_INST_LO_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_CURRENT_INST_LO_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_CURRENT_INST_HI_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_CURRENT_INST_HI_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_CURRENT_INST_HI_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_CURRENT_INST_HI_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_CURRENT_INST_HI_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_BARRIER_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_BARRIER_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_BARRIER_CFG_2 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_CP_BARRIER_CFG_3 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_CP_BARRIER_CFG_3 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_CP_BARRIER_CFG_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_BARRIER_CFG_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_DBG_0_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_DBG_0_1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_CP_DBG_0_2 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_CP_DBG_0_2 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_CP_DBG_0_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_DBG_0_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_DBG_0_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_ARUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_ARUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_ARUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_ARUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_ARUSER_31_11_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_AWUSER_31_11_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_AWUSER_31_11_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_AWUSER_31_11_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_AWUSER_31_11_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CP_AWUSER_31_11_4 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_ARB_CFG_0 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_ARB_CFG_0 & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_ARB_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_19 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_23 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_ARB_MST_AVAIL_CRED_24 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_24 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_AVAIL_CRED_31 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_23 & ~0xFFF) + + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_23 & + PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_ARB_SLV_CHOISE_WDT & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MSG_MAX_INFLIGHT & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MSG_AWUSER_31_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MSG_AWUSER_SEC_PROP & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MSG_AWUSER_NON_SEC_PROP & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_ARB_STATE_STS & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_ARB_STATE_STS & PROT_BITS_OFFS) >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_ARB_STATE_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_CHOISE_FULLNESS_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MSG_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_SLV_CHOISE_Q_HEAD & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_ERR_CAUSE & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_ERR_MSG_EN & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_ERR_STS_DRP & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_2 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_3 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_4 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_5 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_6 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_7 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_8 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_9 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_10 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_11 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_12 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_13 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_14 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_15 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_16 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_17 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_18 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_19 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_ARB_MST_CRED_STS_20 & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_ARB_MST_CRED_STS_20 & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_20 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_21 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_22 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_23 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_24 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_25 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_26 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_27 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_28 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_29 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_30 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_ARB_MST_CRED_STS_31 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CGM_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CGM_STS & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CGM_CFG1 & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_LOCAL_RANGE_BASE & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_LOCAL_RANGE_BASE & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_LOCAL_RANGE_BASE & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_LOCAL_RANGE_SIZE & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_CSMR_STRICT_PRIO_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_HBW_RD_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_LBW_WR_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_LBW_WR_RATE_LIM_CFG_1 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_HBW_RD_RATE_LIM_CFG_0 & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_AXCACHE & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_IND_GW_APB_CFG & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_IND_GW_APB_WDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_IND_GW_APB_RDATA & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_IND_GW_APB_STATUS & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_ERR_ADDR_LO & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_ERR_ADDR_HI & 0x7F) >> 2); + mask |= 1U << ((mmNIC4_QM1_GLBL_ERR_WDATA & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); + + pb_addr = (mmNIC4_QM1_GLBL_MEM_INIT_BUSY & ~0xFFF) + PROT_BITS_OFFS; + word_offset = ((mmNIC4_QM1_GLBL_MEM_INIT_BUSY & PROT_BITS_OFFS) + >> 7) << 2; + mask = 1U << ((mmNIC4_QM1_GLBL_MEM_INIT_BUSY & 0x7F) >> 2); + + WREG32(pb_addr + word_offset, ~mask); +} + static void gaudi_init_tpc_protection_bits(struct hl_device *hdev) { u32 pb_addr, mask; u8 word_offset; - gaudi_pb_set_block(hdev, mmTPC0_E2E_CRED_BASE); - gaudi_pb_set_block(hdev, mmTPC1_E2E_CRED_BASE); - gaudi_pb_set_block(hdev, mmTPC2_E2E_CRED_BASE); - gaudi_pb_set_block(hdev, mmTPC3_E2E_CRED_BASE); - gaudi_pb_set_block(hdev, mmTPC4_E2E_CRED_BASE); - gaudi_pb_set_block(hdev, mmTPC5_E2E_CRED_BASE); - gaudi_pb_set_block(hdev, mmTPC6_E2E_CRED_BASE); - gaudi_pb_set_block(hdev, mmTPC7_E2E_CRED_BASE); + if (hdev->asic_prop.fw_security_disabled) { + gaudi_pb_set_block(hdev, mmTPC0_E2E_CRED_BASE); + gaudi_pb_set_block(hdev, mmTPC1_E2E_CRED_BASE); + gaudi_pb_set_block(hdev, mmTPC2_E2E_CRED_BASE); + gaudi_pb_set_block(hdev, mmTPC3_E2E_CRED_BASE); + gaudi_pb_set_block(hdev, mmTPC4_E2E_CRED_BASE); + gaudi_pb_set_block(hdev, mmTPC5_E2E_CRED_BASE); + gaudi_pb_set_block(hdev, mmTPC6_E2E_CRED_BASE); + gaudi_pb_set_block(hdev, mmTPC7_E2E_CRED_BASE); + } WREG32(mmTPC0_QM_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); WREG32(mmTPC0_CFG_BASE - CFG_BASE + PROT_BITS_OFFS + 0x7C, 0); @@ -8851,16 +12826,20 @@ static void gaudi_init_protection_bits(struct hl_device *hdev) * secured */ - gaudi_pb_set_block(hdev, mmIF_E_PLL_BASE); - gaudi_pb_set_block(hdev, mmMESH_W_PLL_BASE); - gaudi_pb_set_block(hdev, mmSRAM_W_PLL_BASE); - gaudi_pb_set_block(hdev, mmMESH_E_PLL_BASE); - gaudi_pb_set_block(hdev, mmSRAM_E_PLL_BASE); + if (hdev->asic_prop.fw_security_disabled) { + gaudi_pb_set_block(hdev, mmIF_E_PLL_BASE); + gaudi_pb_set_block(hdev, mmMESH_W_PLL_BASE); + gaudi_pb_set_block(hdev, mmSRAM_W_PLL_BASE); + gaudi_pb_set_block(hdev, mmMESH_E_PLL_BASE); + gaudi_pb_set_block(hdev, mmSRAM_E_PLL_BASE); + } gaudi_init_dma_protection_bits(hdev); gaudi_init_mme_protection_bits(hdev); + gaudi_init_nic_protection_bits(hdev); + gaudi_init_tpc_protection_bits(hdev); } @@ -9052,17 +13031,20 @@ void gaudi_init_security(struct hl_device *hdev) * property configuration of MME SBAB and ACC to be non-privileged and * non-secured */ - WREG32(mmMME0_SBAB_PROT, 0x2); - WREG32(mmMME0_ACC_PROT, 0x2); - WREG32(mmMME1_SBAB_PROT, 0x2); - WREG32(mmMME1_ACC_PROT, 0x2); - WREG32(mmMME2_SBAB_PROT, 0x2); - WREG32(mmMME2_ACC_PROT, 0x2); - WREG32(mmMME3_SBAB_PROT, 0x2); - WREG32(mmMME3_ACC_PROT, 0x2); + if (hdev->asic_prop.fw_security_disabled) { + WREG32(mmMME0_SBAB_PROT, 0x2); + WREG32(mmMME0_ACC_PROT, 0x2); + WREG32(mmMME1_SBAB_PROT, 0x2); + WREG32(mmMME1_ACC_PROT, 0x2); + WREG32(mmMME2_SBAB_PROT, 0x2); + WREG32(mmMME2_ACC_PROT, 0x2); + WREG32(mmMME3_SBAB_PROT, 0x2); + WREG32(mmMME3_ACC_PROT, 0x2); + } /* On RAZWI, 0 will be returned from RR and 0xBABA0BAD from PB */ - WREG32(0xC01B28, 0x1); + if (hdev->asic_prop.fw_security_disabled) + WREG32(0xC01B28, 0x1); gaudi_init_range_registers_lbw(hdev); diff --git a/drivers/misc/habanalabs/goya/goya.c b/drivers/misc/habanalabs/goya/goya.c index 5db52064ed9e..3e5eb9e3d7bd 100644 --- a/drivers/misc/habanalabs/goya/goya.c +++ b/drivers/misc/habanalabs/goya/goya.c @@ -12,9 +12,7 @@ #include "../include/goya/goya_reg_map.h" #include <linux/pci.h> -#include <linux/genalloc.h> #include <linux/hwmon.h> -#include <linux/io-64-nonatomic-lo-hi.h> #include <linux/iommu.h> #include <linux/seq_file.h> @@ -373,20 +371,20 @@ int goya_get_fixed_properties(struct hl_device *hdev) for (i = 0 ; i < NUMBER_OF_EXT_HW_QUEUES ; i++) { prop->hw_queues_props[i].type = QUEUE_TYPE_EXT; prop->hw_queues_props[i].driver_only = 0; - prop->hw_queues_props[i].requires_kernel_cb = 1; + prop->hw_queues_props[i].cb_alloc_flags = CB_ALLOC_KERNEL; } for (; i < NUMBER_OF_EXT_HW_QUEUES + NUMBER_OF_CPU_HW_QUEUES ; i++) { prop->hw_queues_props[i].type = QUEUE_TYPE_CPU; prop->hw_queues_props[i].driver_only = 1; - prop->hw_queues_props[i].requires_kernel_cb = 0; + prop->hw_queues_props[i].cb_alloc_flags = CB_ALLOC_KERNEL; } for (; i < NUMBER_OF_EXT_HW_QUEUES + NUMBER_OF_CPU_HW_QUEUES + NUMBER_OF_INT_HW_QUEUES; i++) { prop->hw_queues_props[i].type = QUEUE_TYPE_INT; prop->hw_queues_props[i].driver_only = 0; - prop->hw_queues_props[i].requires_kernel_cb = 0; + prop->hw_queues_props[i].cb_alloc_flags = CB_ALLOC_USER; } prop->completion_queues_count = NUMBER_OF_CMPLT_QUEUES; @@ -412,6 +410,7 @@ int goya_get_fixed_properties(struct hl_device *hdev) prop->mmu_hop_table_size = HOP_TABLE_SIZE; prop->mmu_hop0_tables_total_size = HOP0_TABLES_TOTAL_SIZE; prop->dram_page_size = PAGE_SIZE_2MB; + prop->dram_supports_virtual_memory = true; prop->dmmu.hop0_shift = HOP0_SHIFT; prop->dmmu.hop1_shift = HOP1_SHIFT; @@ -456,6 +455,11 @@ int goya_get_fixed_properties(struct hl_device *hdev) prop->max_pending_cs = GOYA_MAX_PENDING_CS; + /* disable fw security for now, set it in a later stage */ + prop->fw_security_disabled = true; + prop->fw_security_status_valid = false; + prop->hard_reset_done_by_fw = false; + return 0; } @@ -551,6 +555,11 @@ done: return rc; } +static enum hl_device_hw_state goya_get_hw_state(struct hl_device *hdev) +{ + return RREG32(mmHW_STATE); +} + /* * goya_early_init - GOYA early initialization code * @@ -600,14 +609,27 @@ static int goya_early_init(struct hl_device *hdev) prop->dram_pci_bar_size = pci_resource_len(pdev, DDR_BAR_ID); - rc = hl_pci_init(hdev, mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS, - mmCPU_BOOT_ERR0, GOYA_BOOT_FIT_REQ_TIMEOUT_USEC); + rc = hl_pci_init(hdev); if (rc) goto free_queue_props; - /* Goya Firmware does not support security */ - prop->fw_security_disabled = true; - dev_info(hdev->dev, "firmware-level security is disabled\n"); + if (goya_get_hw_state(hdev) == HL_DEVICE_HW_STATE_DIRTY) { + dev_info(hdev->dev, + "H/W state is dirty, must reset before initializing\n"); + hdev->asic_funcs->hw_fini(hdev, true); + } + + /* Before continuing in the initialization, we need to read the preboot + * version to determine whether we run with a security-enabled firmware + */ + rc = hl_fw_read_preboot_status(hdev, mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS, + mmCPU_BOOT_DEV_STS0, mmCPU_BOOT_ERR0, + GOYA_BOOT_FIT_REQ_TIMEOUT_USEC); + if (rc) { + if (hdev->reset_on_preboot_fail) + hdev->asic_funcs->hw_fini(hdev, true); + goto pci_fini; + } if (!hdev->pldm) { val = RREG32(mmPSOC_GLOBAL_CONF_BOOT_STRAP_PINS); @@ -618,6 +640,8 @@ static int goya_early_init(struct hl_device *hdev) return 0; +pci_fini: + hl_pci_fini(hdev); free_queue_props: kfree(hdev->asic_prop.hw_queues_props); return rc; @@ -2315,7 +2339,7 @@ static int goya_load_firmware_to_device(struct hl_device *hdev) dst = hdev->pcie_bar[DDR_BAR_ID] + LINUX_FW_OFFSET; - return hl_fw_load_fw_to_device(hdev, GOYA_LINUX_FW_FILE, dst); + return hl_fw_load_fw_to_device(hdev, GOYA_LINUX_FW_FILE, dst, 0, 0); } /* @@ -2332,14 +2356,14 @@ static int goya_load_boot_fit_to_device(struct hl_device *hdev) dst = hdev->pcie_bar[SRAM_CFG_BAR_ID] + BOOT_FIT_SRAM_OFFSET; - return hl_fw_load_fw_to_device(hdev, GOYA_BOOT_FIT_FILE, dst); + return hl_fw_load_fw_to_device(hdev, GOYA_BOOT_FIT_FILE, dst, 0, 0); } /* * FW component passes an offset from SRAM_BASE_ADDR in SCRATCHPAD_xx. * The version string should be located by that offset. */ -static void goya_read_device_fw_version(struct hl_device *hdev, +static int goya_read_device_fw_version(struct hl_device *hdev, enum hl_fw_component fwc) { const char *name; @@ -2359,7 +2383,7 @@ static void goya_read_device_fw_version(struct hl_device *hdev, break; default: dev_warn(hdev->dev, "Undefined FW component: %d\n", fwc); - return; + return -EIO; } ver_off &= ~((u32)SRAM_BASE_ADDR); @@ -2371,7 +2395,11 @@ static void goya_read_device_fw_version(struct hl_device *hdev, dev_err(hdev->dev, "%s version offset (0x%x) is above SRAM\n", name, ver_off); strcpy(dest, "unavailable"); + + return -EIO; } + + return 0; } static int goya_init_cpu(struct hl_device *hdev) @@ -2397,7 +2425,8 @@ static int goya_init_cpu(struct hl_device *hdev) rc = hl_fw_init_cpu(hdev, mmPSOC_GLOBAL_CONF_CPU_BOOT_STATUS, mmPSOC_GLOBAL_CONF_UBOOT_MAGIC, - mmCPU_CMD_STATUS_TO_HOST, mmCPU_BOOT_ERR0, + mmCPU_CMD_STATUS_TO_HOST, + mmCPU_BOOT_DEV_STS0, mmCPU_BOOT_ERR0, false, GOYA_CPU_TIMEOUT_USEC, GOYA_BOOT_FIT_REQ_TIMEOUT_USEC); @@ -2454,7 +2483,6 @@ int goya_mmu_init(struct hl_device *hdev) if (goya->hw_cap_initialized & HW_CAP_MMU) return 0; - hdev->dram_supports_virtual_memory = true; hdev->dram_default_page_mapping = true; for (i = 0 ; i < prop->max_asid ; i++) { @@ -2505,8 +2533,6 @@ static int goya_hw_init(struct hl_device *hdev) struct asic_fixed_properties *prop = &hdev->asic_prop; int rc; - dev_info(hdev->dev, "Starting initialization of H/W\n"); - /* Perform read from the device to make sure device is up */ RREG32(mmPCIE_DBI_DEVICE_ID_VENDOR_ID_REG); @@ -2628,7 +2654,7 @@ static void goya_hw_fini(struct hl_device *hdev, bool hard_reset) "Timeout while waiting for device to reset 0x%x\n", status); - if (!hard_reset) { + if (!hard_reset && goya) { goya->hw_cap_initialized &= ~(HW_CAP_DMA | HW_CAP_MME | HW_CAP_GOLDEN | HW_CAP_TPC); WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, @@ -2643,12 +2669,15 @@ static void goya_hw_fini(struct hl_device *hdev, bool hard_reset) WREG32(mmPSOC_GLOBAL_CONF_SW_BTM_FSM, 0xA << PSOC_GLOBAL_CONF_SW_BTM_FSM_CTRL_SHIFT); - goya->hw_cap_initialized &= ~(HW_CAP_CPU | HW_CAP_CPU_Q | - HW_CAP_DDR_0 | HW_CAP_DDR_1 | - HW_CAP_DMA | HW_CAP_MME | - HW_CAP_MMU | HW_CAP_TPC_MBIST | - HW_CAP_GOLDEN | HW_CAP_TPC); - memset(goya->events_stat, 0, sizeof(goya->events_stat)); + if (goya) { + goya->hw_cap_initialized &= ~(HW_CAP_CPU | HW_CAP_CPU_Q | + HW_CAP_DDR_0 | HW_CAP_DDR_1 | + HW_CAP_DMA | HW_CAP_MME | + HW_CAP_MMU | HW_CAP_TPC_MBIST | + HW_CAP_GOLDEN | HW_CAP_TPC); + + memset(goya->events_stat, 0, sizeof(goya->events_stat)); + } } int goya_suspend(struct hl_device *hdev) @@ -2792,6 +2821,11 @@ static void goya_dma_free_coherent(struct hl_device *hdev, size_t size, dma_free_coherent(&hdev->pdev->dev, size, cpu_addr, fixed_dma_handle); } +int goya_scrub_device_mem(struct hl_device *hdev, u64 addr, u64 size) +{ + return 0; +} + void *goya_get_int_queue_base(struct hl_device *hdev, u32 queue_id, dma_addr_t *dma_handle, u16 *queue_len) { @@ -2882,8 +2916,8 @@ static int goya_send_job_on_qman0(struct hl_device *hdev, struct hl_cs_job *job) cb = job->patched_cb; - fence_pkt = (struct packet_msg_prot *) (uintptr_t) (cb->kernel_address + - job->job_cb_size - sizeof(struct packet_msg_prot)); + fence_pkt = cb->kernel_address + + job->job_cb_size - sizeof(struct packet_msg_prot); tmp = (PACKET_MSG_PROT << GOYA_PKT_CTL_OPCODE_SHIFT) | (1 << GOYA_PKT_CTL_EB_SHIFT) | @@ -2920,7 +2954,7 @@ free_fence_ptr: } int goya_send_cpu_message(struct hl_device *hdev, u32 *msg, u16 len, - u32 timeout, long *result) + u32 timeout, u64 *result) { struct goya_device *goya = hdev->asic_specific; @@ -3475,8 +3509,7 @@ static int goya_validate_cb(struct hl_device *hdev, u16 pkt_size; struct goya_packet *user_pkt; - user_pkt = (struct goya_packet *) (uintptr_t) - (parser->user_cb->kernel_address + cb_parsed_length); + user_pkt = parser->user_cb->kernel_address + cb_parsed_length; pkt_id = (enum packet_id) ( (le64_to_cpu(user_pkt->header) & @@ -3713,11 +3746,9 @@ static int goya_patch_cb(struct hl_device *hdev, u32 new_pkt_size = 0; struct goya_packet *user_pkt, *kernel_pkt; - user_pkt = (struct goya_packet *) (uintptr_t) - (parser->user_cb->kernel_address + cb_parsed_length); - kernel_pkt = (struct goya_packet *) (uintptr_t) - (parser->patched_cb->kernel_address + - cb_patched_cur_length); + user_pkt = parser->user_cb->kernel_address + cb_parsed_length; + kernel_pkt = parser->patched_cb->kernel_address + + cb_patched_cur_length; pkt_id = (enum packet_id) ( (le64_to_cpu(user_pkt->header) & @@ -3841,8 +3872,8 @@ static int goya_parse_cb_mmu(struct hl_device *hdev, * The check that parser->user_cb_size <= parser->user_cb->size was done * in validate_queue_index(). */ - memcpy((void *) (uintptr_t) parser->patched_cb->kernel_address, - (void *) (uintptr_t) parser->user_cb->kernel_address, + memcpy(parser->patched_cb->kernel_address, + parser->user_cb->kernel_address, parser->user_cb_size); patched_cb_size = parser->patched_cb_size; @@ -3974,15 +4005,14 @@ int goya_cs_parser(struct hl_device *hdev, struct hl_cs_parser *parser) return goya_parse_cb_no_mmu(hdev, parser); } -void goya_add_end_of_cb_packets(struct hl_device *hdev, u64 kernel_address, +void goya_add_end_of_cb_packets(struct hl_device *hdev, void *kernel_address, u32 len, u64 cq_addr, u32 cq_val, u32 msix_vec, bool eb) { struct packet_msg_prot *cq_pkt; u32 tmp; - cq_pkt = (struct packet_msg_prot *) (uintptr_t) - (kernel_address + len - (sizeof(struct packet_msg_prot) * 2)); + cq_pkt = kernel_address + len - (sizeof(struct packet_msg_prot) * 2); tmp = (PACKET_MSG_PROT << GOYA_PKT_CTL_OPCODE_SHIFT) | (1 << GOYA_PKT_CTL_EB_SHIFT) | @@ -4510,7 +4540,7 @@ static int goya_unmask_irq_arr(struct hl_device *hdev, u32 *irq_arr, { struct cpucp_unmask_irq_arr_packet *pkt; size_t total_pkt_size; - long result; + u64 result; int rc; int irq_num_entries, irq_arr_index; __le32 *goya_irq_arr; @@ -4569,7 +4599,7 @@ static int goya_soft_reset_late_init(struct hl_device *hdev) static int goya_unmask_irq(struct hl_device *hdev, u16 event_type) { struct cpucp_packet pkt; - long result; + u64 result; int rc; memset(&pkt, 0, sizeof(pkt)); @@ -4746,7 +4776,7 @@ static int goya_memset_device_memory(struct hl_device *hdev, u64 addr, u64 size, if (!cb) return -ENOMEM; - lin_dma_pkt = (struct packet_lin_dma *) (uintptr_t) cb->kernel_address; + lin_dma_pkt = cb->kernel_address; do { memset(lin_dma_pkt, 0, sizeof(*lin_dma_pkt)); @@ -4781,7 +4811,7 @@ static int goya_memset_device_memory(struct hl_device *hdev, u64 addr, u64 size, job->id = 0; job->user_cb = cb; - job->user_cb->cs_cnt++; + atomic_inc(&job->user_cb->cs_cnt); job->user_cb_size = cb_size; job->hw_queue_id = GOYA_QUEUE_ID_DMA_0; job->patched_cb = job->user_cb; @@ -4793,7 +4823,7 @@ static int goya_memset_device_memory(struct hl_device *hdev, u64 addr, u64 size, hl_debugfs_remove_job(hdev, job); kfree(job); - cb->cs_cnt--; + atomic_dec(&cb->cs_cnt); release_cb: hl_cb_put(cb); @@ -4876,9 +4906,10 @@ static int goya_mmu_add_mappings_for_device_cpu(struct hl_device *hdev) return 0; for (off = 0 ; off < CPU_FW_IMAGE_SIZE ; off += PAGE_SIZE_2MB) { - rc = hl_mmu_map(hdev->kernel_ctx, prop->dram_base_address + off, - prop->dram_base_address + off, PAGE_SIZE_2MB, - (off + PAGE_SIZE_2MB) == CPU_FW_IMAGE_SIZE); + rc = hl_mmu_map_page(hdev->kernel_ctx, + prop->dram_base_address + off, + prop->dram_base_address + off, PAGE_SIZE_2MB, + (off + PAGE_SIZE_2MB) == CPU_FW_IMAGE_SIZE); if (rc) { dev_err(hdev->dev, "Map failed for address 0x%llx\n", prop->dram_base_address + off); @@ -4887,8 +4918,10 @@ static int goya_mmu_add_mappings_for_device_cpu(struct hl_device *hdev) } if (!(hdev->cpu_accessible_dma_address & (PAGE_SIZE_2MB - 1))) { - rc = hl_mmu_map(hdev->kernel_ctx, VA_CPU_ACCESSIBLE_MEM_ADDR, - hdev->cpu_accessible_dma_address, PAGE_SIZE_2MB, true); + rc = hl_mmu_map_page(hdev->kernel_ctx, + VA_CPU_ACCESSIBLE_MEM_ADDR, + hdev->cpu_accessible_dma_address, + PAGE_SIZE_2MB, true); if (rc) { dev_err(hdev->dev, @@ -4898,7 +4931,7 @@ static int goya_mmu_add_mappings_for_device_cpu(struct hl_device *hdev) } } else { for (cpu_off = 0 ; cpu_off < SZ_2M ; cpu_off += PAGE_SIZE_4KB) { - rc = hl_mmu_map(hdev->kernel_ctx, + rc = hl_mmu_map_page(hdev->kernel_ctx, VA_CPU_ACCESSIBLE_MEM_ADDR + cpu_off, hdev->cpu_accessible_dma_address + cpu_off, PAGE_SIZE_4KB, true); @@ -4925,7 +4958,7 @@ static int goya_mmu_add_mappings_for_device_cpu(struct hl_device *hdev) unmap_cpu: for (; cpu_off >= 0 ; cpu_off -= PAGE_SIZE_4KB) - if (hl_mmu_unmap(hdev->kernel_ctx, + if (hl_mmu_unmap_page(hdev->kernel_ctx, VA_CPU_ACCESSIBLE_MEM_ADDR + cpu_off, PAGE_SIZE_4KB, true)) dev_warn_ratelimited(hdev->dev, @@ -4933,7 +4966,7 @@ unmap_cpu: VA_CPU_ACCESSIBLE_MEM_ADDR + cpu_off); unmap: for (; off >= 0 ; off -= PAGE_SIZE_2MB) - if (hl_mmu_unmap(hdev->kernel_ctx, + if (hl_mmu_unmap_page(hdev->kernel_ctx, prop->dram_base_address + off, PAGE_SIZE_2MB, true)) dev_warn_ratelimited(hdev->dev, @@ -4959,13 +4992,14 @@ void goya_mmu_remove_device_cpu_mappings(struct hl_device *hdev) WREG32(mmCPU_IF_AWUSER_OVR_EN, 0); if (!(hdev->cpu_accessible_dma_address & (PAGE_SIZE_2MB - 1))) { - if (hl_mmu_unmap(hdev->kernel_ctx, VA_CPU_ACCESSIBLE_MEM_ADDR, + if (hl_mmu_unmap_page(hdev->kernel_ctx, + VA_CPU_ACCESSIBLE_MEM_ADDR, PAGE_SIZE_2MB, true)) dev_warn(hdev->dev, "Failed to unmap CPU accessible memory\n"); } else { for (cpu_off = 0 ; cpu_off < SZ_2M ; cpu_off += PAGE_SIZE_4KB) - if (hl_mmu_unmap(hdev->kernel_ctx, + if (hl_mmu_unmap_page(hdev->kernel_ctx, VA_CPU_ACCESSIBLE_MEM_ADDR + cpu_off, PAGE_SIZE_4KB, (cpu_off + PAGE_SIZE_4KB) >= SZ_2M)) @@ -4975,7 +5009,7 @@ void goya_mmu_remove_device_cpu_mappings(struct hl_device *hdev) } for (off = 0 ; off < CPU_FW_IMAGE_SIZE ; off += PAGE_SIZE_2MB) - if (hl_mmu_unmap(hdev->kernel_ctx, + if (hl_mmu_unmap_page(hdev->kernel_ctx, prop->dram_base_address + off, PAGE_SIZE_2MB, (off + PAGE_SIZE_2MB) >= CPU_FW_IMAGE_SIZE)) dev_warn_ratelimited(hdev->dev, @@ -5122,7 +5156,7 @@ int goya_cpucp_info_get(struct hl_device *hdev) if (!(goya->hw_cap_initialized & HW_CAP_CPU_Q)) return 0; - rc = hl_fw_cpucp_info_get(hdev); + rc = hl_fw_cpucp_info_get(hdev, mmCPU_BOOT_DEV_STS0); if (rc) return rc; @@ -5269,11 +5303,6 @@ static int goya_get_eeprom_data(struct hl_device *hdev, void *data, return hl_fw_get_eeprom_data(hdev, data, max_size); } -static enum hl_device_hw_state goya_get_hw_state(struct hl_device *hdev) -{ - return RREG32(mmHW_STATE); -} - static int goya_ctx_init(struct hl_ctx *ctx) { return 0; @@ -5294,18 +5323,24 @@ static u32 goya_get_wait_cb_size(struct hl_device *hdev) return 0; } -static void goya_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id) +static u32 goya_gen_signal_cb(struct hl_device *hdev, void *data, u16 sob_id, + u32 size) { + return 0; +} +static u32 goya_gen_wait_cb(struct hl_device *hdev, + struct hl_gen_wait_properties *prop) +{ + return 0; } -static void goya_gen_wait_cb(struct hl_device *hdev, void *data, u16 sob_id, - u16 sob_val, u16 mon_id, u32 q_idx) +static void goya_reset_sob(struct hl_device *hdev, void *data) { } -static void goya_reset_sob(struct hl_device *hdev, void *data) +static void goya_reset_sob_group(struct hl_device *hdev, u16 sob_group) { } @@ -5331,6 +5366,23 @@ u64 goya_get_device_time(struct hl_device *hdev) return device_time | RREG32(mmPSOC_TIMESTAMP_CNTCVL); } +static void goya_collective_wait_init_cs(struct hl_cs *cs) +{ + +} + +static int goya_collective_wait_create_jobs(struct hl_device *hdev, + struct hl_ctx *ctx, struct hl_cs *cs, u32 wait_queue_id, + u32 collective_engine_id) +{ + return -EINVAL; +} + +static void goya_ctx_fini(struct hl_ctx *ctx) +{ + +} + static const struct hl_asic_funcs goya_funcs = { .early_init = goya_early_init, .early_fini = goya_early_fini, @@ -5348,6 +5400,7 @@ static const struct hl_asic_funcs goya_funcs = { .pqe_write = goya_pqe_write, .asic_dma_alloc_coherent = goya_dma_alloc_coherent, .asic_dma_free_coherent = goya_dma_free_coherent, + .scrub_device_mem = goya_scrub_device_mem, .get_int_queue_base = goya_get_int_queue_base, .test_queues = goya_test_queues, .asic_dma_pool_zalloc = goya_dma_pool_zalloc, @@ -5385,13 +5438,13 @@ static const struct hl_asic_funcs goya_funcs = { .get_pci_id = goya_get_pci_id, .get_eeprom_data = goya_get_eeprom_data, .send_cpu_message = goya_send_cpu_message, - .get_hw_state = goya_get_hw_state, .pci_bars_map = goya_pci_bars_map, .init_iatu = goya_init_iatu, .rreg = hl_rreg, .wreg = hl_wreg, .halt_coresight = goya_halt_coresight, .ctx_init = goya_ctx_init, + .ctx_fini = goya_ctx_fini, .get_clk_rate = goya_get_clk_rate, .get_queue_id_for_cq = goya_get_queue_id_for_cq, .read_device_fw_version = goya_read_device_fw_version, @@ -5402,8 +5455,11 @@ static const struct hl_asic_funcs goya_funcs = { .gen_signal_cb = goya_gen_signal_cb, .gen_wait_cb = goya_gen_wait_cb, .reset_sob = goya_reset_sob, + .reset_sob_group = goya_reset_sob_group, .set_dma_mask_from_fw = goya_set_dma_mask_from_fw, - .get_device_time = goya_get_device_time + .get_device_time = goya_get_device_time, + .collective_wait_init_cs = goya_collective_wait_init_cs, + .collective_wait_create_jobs = goya_collective_wait_create_jobs }; /* diff --git a/drivers/misc/habanalabs/goya/goyaP.h b/drivers/misc/habanalabs/goya/goyaP.h index 09b4006d4dc3..8b3408211af6 100644 --- a/drivers/misc/habanalabs/goya/goyaP.h +++ b/drivers/misc/habanalabs/goya/goyaP.h @@ -192,7 +192,7 @@ int goya_test_queue(struct hl_device *hdev, u32 hw_queue_id); int goya_test_queues(struct hl_device *hdev); int goya_test_cpu_queue(struct hl_device *hdev); int goya_send_cpu_message(struct hl_device *hdev, u32 *msg, u16 len, - u32 timeout, long *result); + u32 timeout, u64 *result); long goya_get_temperature(struct hl_device *hdev, int sensor_index, u32 attr); long goya_get_voltage(struct hl_device *hdev, int sensor_index, u32 attr); @@ -217,10 +217,11 @@ int goya_resume(struct hl_device *hdev); void goya_handle_eqe(struct hl_device *hdev, struct hl_eq_entry *eq_entry); void *goya_get_events_stat(struct hl_device *hdev, bool aggregate, u32 *size); -void goya_add_end_of_cb_packets(struct hl_device *hdev, u64 kernel_address, +void goya_add_end_of_cb_packets(struct hl_device *hdev, void *kernel_address, u32 len, u64 cq_addr, u32 cq_val, u32 msix_vec, bool eb); int goya_cs_parser(struct hl_device *hdev, struct hl_cs_parser *parser); +int goya_scrub_device_mem(struct hl_device *hdev, u64 addr, u64 size); void *goya_get_int_queue_base(struct hl_device *hdev, u32 queue_id, dma_addr_t *dma_handle, u16 *queue_len); u32 goya_get_dma_desc_list_size(struct hl_device *hdev, struct sg_table *sgt); diff --git a/drivers/misc/habanalabs/goya/goya_coresight.c b/drivers/misc/habanalabs/goya/goya_coresight.c index 4027a6a334d7..6fa03933b438 100644 --- a/drivers/misc/habanalabs/goya/goya_coresight.c +++ b/drivers/misc/habanalabs/goya/goya_coresight.c @@ -12,8 +12,6 @@ #include <uapi/misc/habanalabs.h> -#include <linux/coresight.h> - #define GOYA_PLDM_CORESIGHT_TIMEOUT_USEC (CORESIGHT_TIMEOUT_USEC * 100) #define SPMU_SECTION_SIZE DMA_CH_0_CS_SPMU_MAX_OFFSET diff --git a/drivers/misc/habanalabs/goya/goya_hwmgr.c b/drivers/misc/habanalabs/goya/goya_hwmgr.c index cdd4903e48fa..3acb36a1a902 100644 --- a/drivers/misc/habanalabs/goya/goya_hwmgr.c +++ b/drivers/misc/habanalabs/goya/goya_hwmgr.c @@ -36,7 +36,7 @@ int goya_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk) { long value; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_get_frequency(hdev, MME_PLL, false); @@ -69,7 +69,7 @@ static ssize_t mme_clk_show(struct device *dev, struct device_attribute *attr, struct hl_device *hdev = dev_get_drvdata(dev); long value; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_get_frequency(hdev, MME_PLL, false); @@ -88,7 +88,7 @@ static ssize_t mme_clk_store(struct device *dev, struct device_attribute *attr, int rc; long value; - if (hl_device_disabled_or_in_reset(hdev)) { + if (!hl_device_operational(hdev, NULL)) { count = -ENODEV; goto fail; } @@ -118,7 +118,7 @@ static ssize_t tpc_clk_show(struct device *dev, struct device_attribute *attr, struct hl_device *hdev = dev_get_drvdata(dev); long value; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_get_frequency(hdev, TPC_PLL, false); @@ -137,7 +137,7 @@ static ssize_t tpc_clk_store(struct device *dev, struct device_attribute *attr, int rc; long value; - if (hl_device_disabled_or_in_reset(hdev)) { + if (!hl_device_operational(hdev, NULL)) { count = -ENODEV; goto fail; } @@ -167,7 +167,7 @@ static ssize_t ic_clk_show(struct device *dev, struct device_attribute *attr, struct hl_device *hdev = dev_get_drvdata(dev); long value; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_get_frequency(hdev, IC_PLL, false); @@ -186,7 +186,7 @@ static ssize_t ic_clk_store(struct device *dev, struct device_attribute *attr, int rc; long value; - if (hl_device_disabled_or_in_reset(hdev)) { + if (!hl_device_operational(hdev, NULL)) { count = -ENODEV; goto fail; } @@ -216,7 +216,7 @@ static ssize_t mme_clk_curr_show(struct device *dev, struct hl_device *hdev = dev_get_drvdata(dev); long value; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_get_frequency(hdev, MME_PLL, true); @@ -233,7 +233,7 @@ static ssize_t tpc_clk_curr_show(struct device *dev, struct hl_device *hdev = dev_get_drvdata(dev); long value; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_get_frequency(hdev, TPC_PLL, true); @@ -250,7 +250,7 @@ static ssize_t ic_clk_curr_show(struct device *dev, struct hl_device *hdev = dev_get_drvdata(dev); long value; - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; value = hl_get_frequency(hdev, IC_PLL, true); @@ -266,7 +266,7 @@ static ssize_t pm_mng_profile_show(struct device *dev, { struct hl_device *hdev = dev_get_drvdata(dev); - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; return sprintf(buf, "%s\n", @@ -280,7 +280,7 @@ static ssize_t pm_mng_profile_store(struct device *dev, { struct hl_device *hdev = dev_get_drvdata(dev); - if (hl_device_disabled_or_in_reset(hdev)) { + if (!hl_device_operational(hdev, NULL)) { count = -ENODEV; goto out; } @@ -335,7 +335,7 @@ static ssize_t high_pll_show(struct device *dev, struct device_attribute *attr, { struct hl_device *hdev = dev_get_drvdata(dev); - if (hl_device_disabled_or_in_reset(hdev)) + if (!hl_device_operational(hdev, NULL)) return -ENODEV; return sprintf(buf, "%u\n", hdev->high_pll); @@ -348,7 +348,7 @@ static ssize_t high_pll_store(struct device *dev, struct device_attribute *attr, long value; int rc; - if (hl_device_disabled_or_in_reset(hdev)) { + if (!hl_device_operational(hdev, NULL)) { count = -ENODEV; goto out; } diff --git a/drivers/misc/habanalabs/include/common/cpucp_if.h b/drivers/misc/habanalabs/include/common/cpucp_if.h index 2a5c9cb3d505..00bd9b392f93 100644 --- a/drivers/misc/habanalabs/include/common/cpucp_if.h +++ b/drivers/misc/habanalabs/include/common/cpucp_if.h @@ -9,6 +9,38 @@ #define CPUCP_IF_H #include <linux/types.h> +#include <linux/if_ether.h> + +#define NUM_HBM_PSEUDO_CH 2 +#define NUM_HBM_CH_PER_DEV 8 +#define CPUCP_PKT_HBM_ECC_INFO_WR_PAR_SHIFT 0 +#define CPUCP_PKT_HBM_ECC_INFO_WR_PAR_MASK 0x00000001 +#define CPUCP_PKT_HBM_ECC_INFO_RD_PAR_SHIFT 1 +#define CPUCP_PKT_HBM_ECC_INFO_RD_PAR_MASK 0x00000002 +#define CPUCP_PKT_HBM_ECC_INFO_CA_PAR_SHIFT 2 +#define CPUCP_PKT_HBM_ECC_INFO_CA_PAR_MASK 0x00000004 +#define CPUCP_PKT_HBM_ECC_INFO_DERR_SHIFT 3 +#define CPUCP_PKT_HBM_ECC_INFO_DERR_MASK 0x00000008 +#define CPUCP_PKT_HBM_ECC_INFO_SERR_SHIFT 4 +#define CPUCP_PKT_HBM_ECC_INFO_SERR_MASK 0x00000010 +#define CPUCP_PKT_HBM_ECC_INFO_TYPE_SHIFT 5 +#define CPUCP_PKT_HBM_ECC_INFO_TYPE_MASK 0x00000020 +#define CPUCP_PKT_HBM_ECC_INFO_HBM_CH_SHIFT 6 +#define CPUCP_PKT_HBM_ECC_INFO_HBM_CH_MASK 0x000007C0 + +struct hl_eq_hbm_ecc_data { + /* SERR counter */ + __le32 sec_cnt; + /* DERR counter */ + __le32 dec_cnt; + /* Supplemental Information according to the mask bits */ + __le32 hbm_ecc_info; + /* Address in hbm where the ecc happened */ + __le32 first_addr; + /* SERR continuous address counter */ + __le32 sec_cont_cnt; + __le32 pad; +}; /* * EVENT QUEUE @@ -30,6 +62,7 @@ struct hl_eq_entry { struct hl_eq_header hdr; union { struct hl_eq_ecc_data ecc_data; + struct hl_eq_hbm_ecc_data hbm_ecc_data; __le64 data[7]; }; }; @@ -199,6 +232,11 @@ enum pq_init_status { * CpuCP to write to the structure, to prevent data corruption in case of * mismatched driver/FW versions. * + * CPUCP_PACKET_NIC_INFO_GET - + * Fetch information from the device regarding the NIC. the host's driver + * passes the max size it allows the CpuCP to write to the structure, to + * prevent data corruption in case of mismatched driver/FW versions. + * * CPUCP_PACKET_TEMPERATURE_SET - * Set the value of the offset property of a specified thermal sensor. * The packet's arguments specify the desired sensor and the field to @@ -214,10 +252,26 @@ enum pq_init_status { * The packet's arguments specify the desired sensor and the field to * set. * - * CPUCP_PACKET_PLL_REG_GET - * Fetch register of PLL from the required PLL IP. - * The packet's arguments specify the PLL IP and the register to get. - * Each register is 32-bit value which is returned in result field. + * CPUCP_PACKET_PCIE_THROUGHPUT_GET + * Get throughput of PCIe. + * The packet's arguments specify the transaction direction (TX/RX). + * The window measurement is 10[msec], and the return value is in KB/sec. + * + * CPUCP_PACKET_PCIE_REPLAY_CNT_GET + * Replay count measures number of "replay" events, which is basicly + * number of retries done by PCIe. + * + * CPUCP_PACKET_TOTAL_ENERGY_GET + * Total Energy is measurement of energy from the time FW Linux + * is loaded. It is calculated by multiplying the average power + * by time (passed from armcp start). The units are in MilliJouls. + * + * CPUCP_PACKET_PLL_INFO_GET + * Fetch frequencies of PLL from the required PLL IP. + * The packet's arguments specify the device PLL type + * Pll type is the PLL from device pll_index enum. + * The result is composed of 4 outputs, each is 16-bit + * frequency in MHz. * */ @@ -244,14 +298,14 @@ enum cpucp_packet_id { CPUCP_PACKET_MAX_POWER_GET, /* sysfs */ CPUCP_PACKET_MAX_POWER_SET, /* sysfs */ CPUCP_PACKET_EEPROM_DATA_GET, /* sysfs */ - CPUCP_RESERVED, + CPUCP_PACKET_NIC_INFO_GET, /* internal */ CPUCP_PACKET_TEMPERATURE_SET, /* sysfs */ CPUCP_PACKET_VOLTAGE_SET, /* sysfs */ CPUCP_PACKET_CURRENT_SET, /* sysfs */ - CPUCP_PACKET_PCIE_THROUGHPUT_GET, /* internal */ - CPUCP_PACKET_PCIE_REPLAY_CNT_GET, /* internal */ + CPUCP_PACKET_PCIE_THROUGHPUT_GET, /* internal */ + CPUCP_PACKET_PCIE_REPLAY_CNT_GET, /* internal */ CPUCP_PACKET_TOTAL_ENERGY_GET, /* internal */ - CPUCP_PACKET_PLL_REG_GET, /* internal */ + CPUCP_PACKET_PLL_INFO_GET, /* internal */ }; #define CPUCP_PACKET_FENCE_VAL 0xFE8CE7A5 @@ -262,6 +316,15 @@ enum cpucp_packet_id { #define CPUCP_PKT_CTL_OPCODE_SHIFT 16 #define CPUCP_PKT_CTL_OPCODE_MASK 0x1FFF0000 +#define CPUCP_PKT_RES_PLL_OUT0_SHIFT 0 +#define CPUCP_PKT_RES_PLL_OUT0_MASK 0x000000000000FFFFull +#define CPUCP_PKT_RES_PLL_OUT1_SHIFT 16 +#define CPUCP_PKT_RES_PLL_OUT1_MASK 0x00000000FFFF0000ull +#define CPUCP_PKT_RES_PLL_OUT2_SHIFT 32 +#define CPUCP_PKT_RES_PLL_OUT2_MASK 0x0000FFFF00000000ull +#define CPUCP_PKT_RES_PLL_OUT3_SHIFT 48 +#define CPUCP_PKT_RES_PLL_OUT3_MASK 0xFFFF000000000000ull + struct cpucp_packet { union { __le64 value; /* For SET packets */ @@ -286,8 +349,9 @@ struct cpucp_packet { __u8 pad; /* unused */ }; - struct {/* For PLL register fetch */ + struct {/* For PLL info fetch */ __le16 pll_type; + /* TODO pll_reg is kept temporary before removal */ __le16 pll_reg; }; @@ -300,7 +364,7 @@ struct cpucp_packet { /* For led set */ __le32 led_index; - /* For get CpuCP info/EEPROM data */ + /* For get CpuCP info/EEPROM data/NIC info */ __le32 data_max_size; }; @@ -366,6 +430,7 @@ enum cpucp_pcie_throughput_attributes { cpucp_pcie_throughput_rx }; +/* TODO temporary kept before removal */ enum cpucp_pll_reg_attributes { cpucp_pll_nr_reg, cpucp_pll_nf_reg, @@ -374,6 +439,7 @@ enum cpucp_pll_reg_attributes { cpucp_pll_div_sel_reg }; +/* TODO temporary kept before removal */ enum cpucp_pll_type_attributes { cpucp_pll_cpu, cpucp_pll_pci, @@ -392,6 +458,12 @@ struct eq_generic_event { #define CARD_NAME_MAX_LEN 16 #define VERSION_MAX_LEN 128 #define CPUCP_MAX_SENSORS 128 +#define CPUCP_MAX_NICS 128 +#define CPUCP_LANES_PER_NIC 4 +#define CPUCP_NIC_QSFP_EEPROM_MAX_LEN 1024 +#define CPUCP_MAX_NIC_LANES (CPUCP_MAX_NICS * CPUCP_LANES_PER_NIC) +#define CPUCP_NIC_MASK_ARR_LEN ((CPUCP_MAX_NICS + 63) / 64) +#define CPUCP_NIC_POLARITY_ARR_LEN ((CPUCP_MAX_NIC_LANES + 63) / 64) struct cpucp_sensor { __le32 type; @@ -408,6 +480,29 @@ enum cpucp_card_types { cpucp_card_type_pmc }; +#define CPUCP_SEC_CONF_ENABLED_SHIFT 0 +#define CPUCP_SEC_CONF_ENABLED_MASK 0x00000001 + +#define CPUCP_SEC_CONF_FLASH_WP_SHIFT 1 +#define CPUCP_SEC_CONF_FLASH_WP_MASK 0x00000002 + +#define CPUCP_SEC_CONF_EEPROM_WP_SHIFT 2 +#define CPUCP_SEC_CONF_EEPROM_WP_MASK 0x00000004 + +/** + * struct cpucp_security_info - Security information. + * @config: configuration bit field + * @keys_num: number of stored keys + * @revoked_keys: revoked keys bit field + * @min_svn: minimal security version + */ +struct cpucp_security_info { + __u8 config; + __u8 keys_num; + __u8 revoked_keys; + __u8 min_svn; +}; + /** * struct cpucp_info - Info from CpuCP that is necessary to the host's driver * @sensors: available sensors description. @@ -423,6 +518,7 @@ enum cpucp_card_types { * @cpucp_version: CpuCP S/W version. * @dram_size: available DRAM size. * @card_name: card name that will be displayed in HWMON subsystem on the host + * @sec_info: security information */ struct cpucp_info { struct cpucp_sensor sensors[CPUCP_MAX_SENSORS]; @@ -438,6 +534,26 @@ struct cpucp_info { __le32 reserved2; __le64 dram_size; char card_name[CARD_NAME_MAX_LEN]; + __le64 reserved3; + __le64 reserved4; + __u8 reserved5; + __u8 pad[7]; + struct cpucp_security_info sec_info; + __le32 reserved6; +}; + +struct cpucp_mac_addr { + __u8 mac_addr[ETH_ALEN]; +}; + +struct cpucp_nic_info { + struct cpucp_mac_addr mac_addrs[CPUCP_MAX_NICS]; + __le64 link_mask[CPUCP_NIC_MASK_ARR_LEN]; + __le64 pol_tx_mask[CPUCP_NIC_POLARITY_ARR_LEN]; + __le64 pol_rx_mask[CPUCP_NIC_POLARITY_ARR_LEN]; + __le64 link_ext_mask[CPUCP_NIC_MASK_ARR_LEN]; + __u8 qsfp_eeprom[CPUCP_NIC_QSFP_EEPROM_MAX_LEN]; + __le64 auto_neg_mask[CPUCP_NIC_MASK_ARR_LEN]; }; #endif /* CPUCP_IF_H */ diff --git a/drivers/misc/habanalabs/include/common/hl_boot_if.h b/drivers/misc/habanalabs/include/common/hl_boot_if.h index bb67cafc6e00..e5801ecf0cb2 100644 --- a/drivers/misc/habanalabs/include/common/hl_boot_if.h +++ b/drivers/misc/habanalabs/include/common/hl_boot_if.h @@ -53,6 +53,23 @@ * trust), boot authentication (chain of * trust), data packets authentication. * + * CPU_BOOT_ERR0_EFUSE_FAIL Reading from eFuse failed. + * The PCI device ID might be wrong. + * + * CPU_BOOT_ERR0_PRI_IMG_VER_FAIL Verification of primary image failed. + * It mean that ppboot checksum + * verification for the preboot primary + * image has failed to match expected + * checksum. Trying to program image again + * might solve this. + * + * CPU_BOOT_ERR0_SEC_IMG_VER_FAIL Verification of secondary image failed. + * It mean that ppboot checksum + * verification for the preboot secondary + * image has failed to match expected + * checksum. Trying to program image again + * might solve this. + * * CPU_BOOT_ERR0_ENABLED Error registers enabled. * This is a main indication that the * running FW populates the error @@ -68,8 +85,94 @@ #define CPU_BOOT_ERR0_NIC_FW_FAIL (1 << 6) #define CPU_BOOT_ERR0_SECURITY_NOT_RDY (1 << 7) #define CPU_BOOT_ERR0_SECURITY_FAIL (1 << 8) +#define CPU_BOOT_ERR0_EFUSE_FAIL (1 << 9) +#define CPU_BOOT_ERR0_PRI_IMG_VER_FAIL (1 << 10) +#define CPU_BOOT_ERR0_SEC_IMG_VER_FAIL (1 << 11) #define CPU_BOOT_ERR0_ENABLED (1 << 31) +/* + * BOOT DEVICE STATUS bits in BOOT_DEVICE_STS registers + * + * CPU_BOOT_DEV_STS0_SECURITY_EN Security is Enabled. + * This is an indication for security + * enabled in FW, which means that + * all conditions for security are met: + * device is indicated as security enabled, + * registers are protected, and device + * uses keys for image verification. + * Initialized in: preboot + * + * CPU_BOOT_DEV_STS0_DEBUG_EN Debug is enabled. + * Enabled when JTAG or DEBUG is enabled + * in FW. + * Initialized in: preboot + * + * CPU_BOOT_DEV_STS0_WATCHDOG_EN Watchdog is enabled. + * Watchdog is enabled in FW. + * Initialized in: preboot + * + * CPU_BOOT_DEV_STS0_DRAM_INIT_EN DRAM initialization is enabled. + * DRAM initialization has been done in FW. + * Initialized in: u-boot + * + * CPU_BOOT_DEV_STS0_BMC_WAIT_EN Waiting for BMC data enabled. + * If set, it means that during boot, + * FW waited for BMC data. + * Initialized in: u-boot + * + * CPU_BOOT_DEV_STS0_E2E_CRED_EN E2E credits initialized. + * FW initialized E2E credits. + * Initialized in: u-boot + * + * CPU_BOOT_DEV_STS0_HBM_CRED_EN HBM credits initialized. + * FW initialized HBM credits. + * Initialized in: u-boot + * + * CPU_BOOT_DEV_STS0_RL_EN Rate limiter initialized. + * FW initialized rate limiter. + * Initialized in: u-boot + * + * CPU_BOOT_DEV_STS0_SRAM_SCR_EN SRAM scrambler enabled. + * FW initialized SRAM scrambler. + * Initialized in: linux + * + * CPU_BOOT_DEV_STS0_DRAM_SCR_EN DRAM scrambler enabled. + * FW initialized DRAM scrambler. + * Initialized in: u-boot + * + * CPU_BOOT_DEV_STS0_FW_HARD_RST_EN FW hard reset procedure is enabled. + * FW has the hard reset procedure + * implemented. This means that FW will + * perform hard reset procedure on + * receiving the halt-machine event. + * Initialized in: linux + * + * CPU_BOOT_DEV_STS0_PLL_INFO_EN FW retrieval of PLL info is enabled. + * Initialized in: linux + * + * CPU_BOOT_DEV_STS0_ENABLED Device status register enabled. + * This is a main indication that the + * running FW populates the device status + * register. Meaning the device status + * bits are not garbage, but actual + * statuses. + * Initialized in: preboot + * + */ +#define CPU_BOOT_DEV_STS0_SECURITY_EN (1 << 0) +#define CPU_BOOT_DEV_STS0_DEBUG_EN (1 << 1) +#define CPU_BOOT_DEV_STS0_WATCHDOG_EN (1 << 2) +#define CPU_BOOT_DEV_STS0_DRAM_INIT_EN (1 << 3) +#define CPU_BOOT_DEV_STS0_BMC_WAIT_EN (1 << 4) +#define CPU_BOOT_DEV_STS0_E2E_CRED_EN (1 << 5) +#define CPU_BOOT_DEV_STS0_HBM_CRED_EN (1 << 6) +#define CPU_BOOT_DEV_STS0_RL_EN (1 << 7) +#define CPU_BOOT_DEV_STS0_SRAM_SCR_EN (1 << 8) +#define CPU_BOOT_DEV_STS0_DRAM_SCR_EN (1 << 9) +#define CPU_BOOT_DEV_STS0_FW_HARD_RST_EN (1 << 10) +#define CPU_BOOT_DEV_STS0_PLL_INFO_EN (1 << 11) +#define CPU_BOOT_DEV_STS0_ENABLED (1 << 31) + enum cpu_boot_status { CPU_BOOT_STATUS_NA = 0, /* Default value after reset of chip */ CPU_BOOT_STATUS_IN_WFE = 1, diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/gaudi_regs.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/gaudi_regs.h index f92dc53af074..5bb54b34a8ae 100644 --- a/drivers/misc/habanalabs/include/gaudi/asic_reg/gaudi_regs.h +++ b/drivers/misc/habanalabs/include/gaudi/asic_reg/gaudi_regs.h @@ -81,6 +81,7 @@ #include "sif_rtr_ctrl_6_regs.h" #include "sif_rtr_ctrl_7_regs.h" #include "psoc_etr_regs.h" +#include "psoc_cpu_pll_regs.h" #include "dma0_qm_masks.h" #include "mme0_qm_masks.h" @@ -89,9 +90,18 @@ #include "tpc0_cfg_masks.h" #include "psoc_global_conf_masks.h" -#include "psoc_pci_pll_regs.h" -#include "psoc_hbm_pll_regs.h" -#include "psoc_cpu_pll_regs.h" +#include "nic0_qm0_regs.h" +#include "nic1_qm0_regs.h" +#include "nic2_qm0_regs.h" +#include "nic3_qm0_regs.h" +#include "nic4_qm0_regs.h" +#include "nic0_qm1_regs.h" +#include "nic1_qm1_regs.h" +#include "nic2_qm1_regs.h" +#include "nic3_qm1_regs.h" +#include "nic4_qm1_regs.h" + +#include "nic0_qm0_masks.h" #define GAUDI_ECC_MEM_SEL_OFFSET 0xF18 #define GAUDI_ECC_ADDRESS_OFFSET 0xF1C @@ -295,4 +305,14 @@ #define mmPCIE_AUX_FLR_CTRL 0xC07394 #define mmPCIE_AUX_DBI 0xC07490 +#define mmPSOC_PCI_PLL_NR 0xC72100 +#define mmSRAM_W_PLL_NR 0x4C8100 +#define mmPSOC_HBM_PLL_NR 0xC74100 +#define mmNIC0_PLL_NR 0xCF9100 +#define mmDMA_W_PLL_NR 0x487100 +#define mmMESH_W_PLL_NR 0x4C7100 +#define mmPSOC_MME_PLL_NR 0xC71100 +#define mmPSOC_TPC_PLL_NR 0xC73100 +#define mmIF_W_PLL_NR 0x488100 + #endif /* ASIC_REG_GAUDI_REGS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/nic0_qm0_masks.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic0_qm0_masks.h new file mode 100644 index 000000000000..bd37b6452133 --- /dev/null +++ b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic0_qm0_masks.h @@ -0,0 +1,800 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright 2016-2018 HabanaLabs, Ltd. + * All Rights Reserved. + * + */ + +/************************************ + ** This is an auto-generated file ** + ** DO NOT EDIT BELOW ** + ************************************/ + +#ifndef ASIC_REG_NIC0_QM0_MASKS_H_ +#define ASIC_REG_NIC0_QM0_MASKS_H_ + +/* + ***************************************** + * NIC0_QM0 (Prototype: QMAN) + ***************************************** + */ + +/* NIC0_QM0_GLBL_CFG0 */ +#define NIC0_QM0_GLBL_CFG0_PQF_EN_SHIFT 0 +#define NIC0_QM0_GLBL_CFG0_PQF_EN_MASK 0xF +#define NIC0_QM0_GLBL_CFG0_CQF_EN_SHIFT 4 +#define NIC0_QM0_GLBL_CFG0_CQF_EN_MASK 0x1F0 +#define NIC0_QM0_GLBL_CFG0_CP_EN_SHIFT 9 +#define NIC0_QM0_GLBL_CFG0_CP_EN_MASK 0x3E00 + +/* NIC0_QM0_GLBL_CFG1 */ +#define NIC0_QM0_GLBL_CFG1_PQF_STOP_SHIFT 0 +#define NIC0_QM0_GLBL_CFG1_PQF_STOP_MASK 0xF +#define NIC0_QM0_GLBL_CFG1_CQF_STOP_SHIFT 4 +#define NIC0_QM0_GLBL_CFG1_CQF_STOP_MASK 0x1F0 +#define NIC0_QM0_GLBL_CFG1_CP_STOP_SHIFT 9 +#define NIC0_QM0_GLBL_CFG1_CP_STOP_MASK 0x3E00 +#define NIC0_QM0_GLBL_CFG1_PQF_FLUSH_SHIFT 16 +#define NIC0_QM0_GLBL_CFG1_PQF_FLUSH_MASK 0xF0000 +#define NIC0_QM0_GLBL_CFG1_CQF_FLUSH_SHIFT 20 +#define NIC0_QM0_GLBL_CFG1_CQF_FLUSH_MASK 0x1F00000 +#define NIC0_QM0_GLBL_CFG1_CP_FLUSH_SHIFT 25 +#define NIC0_QM0_GLBL_CFG1_CP_FLUSH_MASK 0x3E000000 + +/* NIC0_QM0_GLBL_PROT */ +#define NIC0_QM0_GLBL_PROT_PQF_SHIFT 0 +#define NIC0_QM0_GLBL_PROT_PQF_MASK 0xF +#define NIC0_QM0_GLBL_PROT_CQF_SHIFT 4 +#define NIC0_QM0_GLBL_PROT_CQF_MASK 0x1F0 +#define NIC0_QM0_GLBL_PROT_CP_SHIFT 9 +#define NIC0_QM0_GLBL_PROT_CP_MASK 0x3E00 +#define NIC0_QM0_GLBL_PROT_ERR_SHIFT 14 +#define NIC0_QM0_GLBL_PROT_ERR_MASK 0x4000 +#define NIC0_QM0_GLBL_PROT_ARB_SHIFT 15 +#define NIC0_QM0_GLBL_PROT_ARB_MASK 0x8000 + +/* NIC0_QM0_GLBL_ERR_CFG */ +#define NIC0_QM0_GLBL_ERR_CFG_PQF_ERR_MSG_EN_SHIFT 0 +#define NIC0_QM0_GLBL_ERR_CFG_PQF_ERR_MSG_EN_MASK 0xF +#define NIC0_QM0_GLBL_ERR_CFG_CQF_ERR_MSG_EN_SHIFT 4 +#define NIC0_QM0_GLBL_ERR_CFG_CQF_ERR_MSG_EN_MASK 0x1F0 +#define NIC0_QM0_GLBL_ERR_CFG_CP_ERR_MSG_EN_SHIFT 9 +#define NIC0_QM0_GLBL_ERR_CFG_CP_ERR_MSG_EN_MASK 0x3E00 +#define NIC0_QM0_GLBL_ERR_CFG_PQF_STOP_ON_ERR_SHIFT 16 +#define NIC0_QM0_GLBL_ERR_CFG_PQF_STOP_ON_ERR_MASK 0xF0000 +#define NIC0_QM0_GLBL_ERR_CFG_CQF_STOP_ON_ERR_SHIFT 20 +#define NIC0_QM0_GLBL_ERR_CFG_CQF_STOP_ON_ERR_MASK 0x1F00000 +#define NIC0_QM0_GLBL_ERR_CFG_CP_STOP_ON_ERR_SHIFT 25 +#define NIC0_QM0_GLBL_ERR_CFG_CP_STOP_ON_ERR_MASK 0x3E000000 +#define NIC0_QM0_GLBL_ERR_CFG_ARB_STOP_ON_ERR_SHIFT 31 +#define NIC0_QM0_GLBL_ERR_CFG_ARB_STOP_ON_ERR_MASK 0x80000000 + +/* NIC0_QM0_GLBL_SECURE_PROPS */ +#define NIC0_QM0_GLBL_SECURE_PROPS_0_ASID_SHIFT 0 +#define NIC0_QM0_GLBL_SECURE_PROPS_0_ASID_MASK 0x3FF +#define NIC0_QM0_GLBL_SECURE_PROPS_1_ASID_SHIFT 0 +#define NIC0_QM0_GLBL_SECURE_PROPS_1_ASID_MASK 0x3FF +#define NIC0_QM0_GLBL_SECURE_PROPS_2_ASID_SHIFT 0 +#define NIC0_QM0_GLBL_SECURE_PROPS_2_ASID_MASK 0x3FF +#define NIC0_QM0_GLBL_SECURE_PROPS_3_ASID_SHIFT 0 +#define NIC0_QM0_GLBL_SECURE_PROPS_3_ASID_MASK 0x3FF +#define NIC0_QM0_GLBL_SECURE_PROPS_4_ASID_SHIFT 0 +#define NIC0_QM0_GLBL_SECURE_PROPS_4_ASID_MASK 0x3FF +#define NIC0_QM0_GLBL_SECURE_PROPS_0_MMBP_SHIFT 10 +#define NIC0_QM0_GLBL_SECURE_PROPS_0_MMBP_MASK 0x400 +#define NIC0_QM0_GLBL_SECURE_PROPS_1_MMBP_SHIFT 10 +#define NIC0_QM0_GLBL_SECURE_PROPS_1_MMBP_MASK 0x400 +#define NIC0_QM0_GLBL_SECURE_PROPS_2_MMBP_SHIFT 10 +#define NIC0_QM0_GLBL_SECURE_PROPS_2_MMBP_MASK 0x400 +#define NIC0_QM0_GLBL_SECURE_PROPS_3_MMBP_SHIFT 10 +#define NIC0_QM0_GLBL_SECURE_PROPS_3_MMBP_MASK 0x400 +#define NIC0_QM0_GLBL_SECURE_PROPS_4_MMBP_SHIFT 10 +#define NIC0_QM0_GLBL_SECURE_PROPS_4_MMBP_MASK 0x400 + +/* NIC0_QM0_GLBL_NON_SECURE_PROPS */ +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_0_ASID_SHIFT 0 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_0_ASID_MASK 0x3FF +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_1_ASID_SHIFT 0 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_1_ASID_MASK 0x3FF +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_2_ASID_SHIFT 0 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_2_ASID_MASK 0x3FF +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_3_ASID_SHIFT 0 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_3_ASID_MASK 0x3FF +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_4_ASID_SHIFT 0 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_4_ASID_MASK 0x3FF +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_0_MMBP_SHIFT 10 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_0_MMBP_MASK 0x400 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_1_MMBP_SHIFT 10 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_1_MMBP_MASK 0x400 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_2_MMBP_SHIFT 10 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_2_MMBP_MASK 0x400 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_3_MMBP_SHIFT 10 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_3_MMBP_MASK 0x400 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_4_MMBP_SHIFT 10 +#define NIC0_QM0_GLBL_NON_SECURE_PROPS_4_MMBP_MASK 0x400 + +/* NIC0_QM0_GLBL_STS0 */ +#define NIC0_QM0_GLBL_STS0_PQF_IDLE_SHIFT 0 +#define NIC0_QM0_GLBL_STS0_PQF_IDLE_MASK 0xF +#define NIC0_QM0_GLBL_STS0_CQF_IDLE_SHIFT 4 +#define NIC0_QM0_GLBL_STS0_CQF_IDLE_MASK 0x1F0 +#define NIC0_QM0_GLBL_STS0_CP_IDLE_SHIFT 9 +#define NIC0_QM0_GLBL_STS0_CP_IDLE_MASK 0x3E00 +#define NIC0_QM0_GLBL_STS0_PQF_IS_STOP_SHIFT 16 +#define NIC0_QM0_GLBL_STS0_PQF_IS_STOP_MASK 0xF0000 +#define NIC0_QM0_GLBL_STS0_CQF_IS_STOP_SHIFT 20 +#define NIC0_QM0_GLBL_STS0_CQF_IS_STOP_MASK 0x1F00000 +#define NIC0_QM0_GLBL_STS0_CP_IS_STOP_SHIFT 25 +#define NIC0_QM0_GLBL_STS0_CP_IS_STOP_MASK 0x3E000000 +#define NIC0_QM0_GLBL_STS0_ARB_IS_STOP_SHIFT 31 +#define NIC0_QM0_GLBL_STS0_ARB_IS_STOP_MASK 0x80000000 + +/* NIC0_QM0_GLBL_STS1 */ +#define NIC0_QM0_GLBL_STS1_PQF_RD_ERR_SHIFT 0 +#define NIC0_QM0_GLBL_STS1_PQF_RD_ERR_MASK 0x1 +#define NIC0_QM0_GLBL_STS1_CQF_RD_ERR_SHIFT 1 +#define NIC0_QM0_GLBL_STS1_CQF_RD_ERR_MASK 0x2 +#define NIC0_QM0_GLBL_STS1_CP_RD_ERR_SHIFT 2 +#define NIC0_QM0_GLBL_STS1_CP_RD_ERR_MASK 0x4 +#define NIC0_QM0_GLBL_STS1_CP_UNDEF_CMD_ERR_SHIFT 3 +#define NIC0_QM0_GLBL_STS1_CP_UNDEF_CMD_ERR_MASK 0x8 +#define NIC0_QM0_GLBL_STS1_CP_STOP_OP_SHIFT 4 +#define NIC0_QM0_GLBL_STS1_CP_STOP_OP_MASK 0x10 +#define NIC0_QM0_GLBL_STS1_CP_MSG_WR_ERR_SHIFT 5 +#define NIC0_QM0_GLBL_STS1_CP_MSG_WR_ERR_MASK 0x20 +#define NIC0_QM0_GLBL_STS1_CP_WREG_ERR_SHIFT 6 +#define NIC0_QM0_GLBL_STS1_CP_WREG_ERR_MASK 0x40 +#define NIC0_QM0_GLBL_STS1_CP_FENCE0_OVF_ERR_SHIFT 8 +#define NIC0_QM0_GLBL_STS1_CP_FENCE0_OVF_ERR_MASK 0x100 +#define NIC0_QM0_GLBL_STS1_CP_FENCE1_OVF_ERR_SHIFT 9 +#define NIC0_QM0_GLBL_STS1_CP_FENCE1_OVF_ERR_MASK 0x200 +#define NIC0_QM0_GLBL_STS1_CP_FENCE2_OVF_ERR_SHIFT 10 +#define NIC0_QM0_GLBL_STS1_CP_FENCE2_OVF_ERR_MASK 0x400 +#define NIC0_QM0_GLBL_STS1_CP_FENCE3_OVF_ERR_SHIFT 11 +#define NIC0_QM0_GLBL_STS1_CP_FENCE3_OVF_ERR_MASK 0x800 +#define NIC0_QM0_GLBL_STS1_CP_FENCE0_UDF_ERR_SHIFT 12 +#define NIC0_QM0_GLBL_STS1_CP_FENCE0_UDF_ERR_MASK 0x1000 +#define NIC0_QM0_GLBL_STS1_CP_FENCE1_UDF_ERR_SHIFT 13 +#define NIC0_QM0_GLBL_STS1_CP_FENCE1_UDF_ERR_MASK 0x2000 +#define NIC0_QM0_GLBL_STS1_CP_FENCE2_UDF_ERR_SHIFT 14 +#define NIC0_QM0_GLBL_STS1_CP_FENCE2_UDF_ERR_MASK 0x4000 +#define NIC0_QM0_GLBL_STS1_CP_FENCE3_UDF_ERR_SHIFT 15 +#define NIC0_QM0_GLBL_STS1_CP_FENCE3_UDF_ERR_MASK 0x8000 + +/* NIC0_QM0_GLBL_STS1_4 */ +#define NIC0_QM0_GLBL_STS1_4_CQF_RD_ERR_SHIFT 1 +#define NIC0_QM0_GLBL_STS1_4_CQF_RD_ERR_MASK 0x2 +#define NIC0_QM0_GLBL_STS1_4_CP_RD_ERR_SHIFT 2 +#define NIC0_QM0_GLBL_STS1_4_CP_RD_ERR_MASK 0x4 +#define NIC0_QM0_GLBL_STS1_4_CP_UNDEF_CMD_ERR_SHIFT 3 +#define NIC0_QM0_GLBL_STS1_4_CP_UNDEF_CMD_ERR_MASK 0x8 +#define NIC0_QM0_GLBL_STS1_4_CP_STOP_OP_SHIFT 4 +#define NIC0_QM0_GLBL_STS1_4_CP_STOP_OP_MASK 0x10 +#define NIC0_QM0_GLBL_STS1_4_CP_MSG_WR_ERR_SHIFT 5 +#define NIC0_QM0_GLBL_STS1_4_CP_MSG_WR_ERR_MASK 0x20 +#define NIC0_QM0_GLBL_STS1_4_CP_WREG_ERR_SHIFT 6 +#define NIC0_QM0_GLBL_STS1_4_CP_WREG_ERR_MASK 0x40 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE0_OVF_ERR_SHIFT 8 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE0_OVF_ERR_MASK 0x100 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE1_OVF_ERR_SHIFT 9 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE1_OVF_ERR_MASK 0x200 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE2_OVF_ERR_SHIFT 10 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE2_OVF_ERR_MASK 0x400 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE3_OVF_ERR_SHIFT 11 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE3_OVF_ERR_MASK 0x800 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE0_UDF_ERR_SHIFT 12 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE0_UDF_ERR_MASK 0x1000 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE1_UDF_ERR_SHIFT 13 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE1_UDF_ERR_MASK 0x2000 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE2_UDF_ERR_SHIFT 14 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE2_UDF_ERR_MASK 0x4000 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE3_UDF_ERR_SHIFT 15 +#define NIC0_QM0_GLBL_STS1_4_CP_FENCE3_UDF_ERR_MASK 0x8000 + +/* NIC0_QM0_GLBL_MSG_EN */ +#define NIC0_QM0_GLBL_MSG_EN_PQF_RD_ERR_SHIFT 0 +#define NIC0_QM0_GLBL_MSG_EN_PQF_RD_ERR_MASK 0x1 +#define NIC0_QM0_GLBL_MSG_EN_CQF_RD_ERR_SHIFT 1 +#define NIC0_QM0_GLBL_MSG_EN_CQF_RD_ERR_MASK 0x2 +#define NIC0_QM0_GLBL_MSG_EN_CP_RD_ERR_SHIFT 2 +#define NIC0_QM0_GLBL_MSG_EN_CP_RD_ERR_MASK 0x4 +#define NIC0_QM0_GLBL_MSG_EN_CP_UNDEF_CMD_ERR_SHIFT 3 +#define NIC0_QM0_GLBL_MSG_EN_CP_UNDEF_CMD_ERR_MASK 0x8 +#define NIC0_QM0_GLBL_MSG_EN_CP_STOP_OP_SHIFT 4 +#define NIC0_QM0_GLBL_MSG_EN_CP_STOP_OP_MASK 0x10 +#define NIC0_QM0_GLBL_MSG_EN_CP_MSG_WR_ERR_SHIFT 5 +#define NIC0_QM0_GLBL_MSG_EN_CP_MSG_WR_ERR_MASK 0x20 +#define NIC0_QM0_GLBL_MSG_EN_CP_WREG_ERR_SHIFT 6 +#define NIC0_QM0_GLBL_MSG_EN_CP_WREG_ERR_MASK 0x40 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE0_OVF_ERR_SHIFT 8 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE0_OVF_ERR_MASK 0x100 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE1_OVF_ERR_SHIFT 9 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE1_OVF_ERR_MASK 0x200 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE2_OVF_ERR_SHIFT 10 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE2_OVF_ERR_MASK 0x400 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE3_OVF_ERR_SHIFT 11 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE3_OVF_ERR_MASK 0x800 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE0_UDF_ERR_SHIFT 12 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE0_UDF_ERR_MASK 0x1000 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE1_UDF_ERR_SHIFT 13 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE1_UDF_ERR_MASK 0x2000 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE2_UDF_ERR_SHIFT 14 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE2_UDF_ERR_MASK 0x4000 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE3_UDF_ERR_SHIFT 15 +#define NIC0_QM0_GLBL_MSG_EN_CP_FENCE3_UDF_ERR_MASK 0x8000 + +/* NIC0_QM0_GLBL_MSG_EN_4 */ +#define NIC0_QM0_GLBL_MSG_EN_4_CQF_RD_ERR_SHIFT 1 +#define NIC0_QM0_GLBL_MSG_EN_4_CQF_RD_ERR_MASK 0x2 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_RD_ERR_SHIFT 2 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_RD_ERR_MASK 0x4 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_UNDEF_CMD_ERR_SHIFT 3 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_UNDEF_CMD_ERR_MASK 0x8 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_STOP_OP_SHIFT 4 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_STOP_OP_MASK 0x10 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_MSG_WR_ERR_SHIFT 5 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_MSG_WR_ERR_MASK 0x20 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_WREG_ERR_SHIFT 6 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_WREG_ERR_MASK 0x40 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE0_OVF_ERR_SHIFT 8 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE0_OVF_ERR_MASK 0x100 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE1_OVF_ERR_SHIFT 9 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE1_OVF_ERR_MASK 0x200 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE2_OVF_ERR_SHIFT 10 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE2_OVF_ERR_MASK 0x400 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE3_OVF_ERR_SHIFT 11 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE3_OVF_ERR_MASK 0x800 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE0_UDF_ERR_SHIFT 12 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE0_UDF_ERR_MASK 0x1000 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE1_UDF_ERR_SHIFT 13 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE1_UDF_ERR_MASK 0x2000 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE2_UDF_ERR_SHIFT 14 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE2_UDF_ERR_MASK 0x4000 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE3_UDF_ERR_SHIFT 15 +#define NIC0_QM0_GLBL_MSG_EN_4_CP_FENCE3_UDF_ERR_MASK 0x8000 + +/* NIC0_QM0_PQ_BASE_LO */ +#define NIC0_QM0_PQ_BASE_LO_VAL_SHIFT 0 +#define NIC0_QM0_PQ_BASE_LO_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_PQ_BASE_HI */ +#define NIC0_QM0_PQ_BASE_HI_VAL_SHIFT 0 +#define NIC0_QM0_PQ_BASE_HI_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_PQ_SIZE */ +#define NIC0_QM0_PQ_SIZE_VAL_SHIFT 0 +#define NIC0_QM0_PQ_SIZE_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_PQ_PI */ +#define NIC0_QM0_PQ_PI_VAL_SHIFT 0 +#define NIC0_QM0_PQ_PI_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_PQ_CI */ +#define NIC0_QM0_PQ_CI_VAL_SHIFT 0 +#define NIC0_QM0_PQ_CI_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_PQ_CFG0 */ +#define NIC0_QM0_PQ_CFG0_RESERVED_SHIFT 0 +#define NIC0_QM0_PQ_CFG0_RESERVED_MASK 0x1 + +/* NIC0_QM0_PQ_CFG1 */ +#define NIC0_QM0_PQ_CFG1_CREDIT_LIM_SHIFT 0 +#define NIC0_QM0_PQ_CFG1_CREDIT_LIM_MASK 0xFFFF +#define NIC0_QM0_PQ_CFG1_MAX_INFLIGHT_SHIFT 16 +#define NIC0_QM0_PQ_CFG1_MAX_INFLIGHT_MASK 0xFFFF0000 + +/* NIC0_QM0_PQ_ARUSER_31_11 */ +#define NIC0_QM0_PQ_ARUSER_31_11_VAL_SHIFT 0 +#define NIC0_QM0_PQ_ARUSER_31_11_VAL_MASK 0x1FFFFF + +/* NIC0_QM0_PQ_STS0 */ +#define NIC0_QM0_PQ_STS0_PQ_CREDIT_CNT_SHIFT 0 +#define NIC0_QM0_PQ_STS0_PQ_CREDIT_CNT_MASK 0xFFFF +#define NIC0_QM0_PQ_STS0_PQ_FREE_CNT_SHIFT 16 +#define NIC0_QM0_PQ_STS0_PQ_FREE_CNT_MASK 0xFFFF0000 + +/* NIC0_QM0_PQ_STS1 */ +#define NIC0_QM0_PQ_STS1_PQ_INFLIGHT_CNT_SHIFT 0 +#define NIC0_QM0_PQ_STS1_PQ_INFLIGHT_CNT_MASK 0xFFFF +#define NIC0_QM0_PQ_STS1_PQ_BUF_EMPTY_SHIFT 30 +#define NIC0_QM0_PQ_STS1_PQ_BUF_EMPTY_MASK 0x40000000 +#define NIC0_QM0_PQ_STS1_PQ_BUSY_SHIFT 31 +#define NIC0_QM0_PQ_STS1_PQ_BUSY_MASK 0x80000000 + +/* NIC0_QM0_CQ_CFG0 */ +#define NIC0_QM0_CQ_CFG0_RESERVED_SHIFT 0 +#define NIC0_QM0_CQ_CFG0_RESERVED_MASK 0x1 + +/* NIC0_QM0_CQ_CFG1 */ +#define NIC0_QM0_CQ_CFG1_CREDIT_LIM_SHIFT 0 +#define NIC0_QM0_CQ_CFG1_CREDIT_LIM_MASK 0xFFFF +#define NIC0_QM0_CQ_CFG1_MAX_INFLIGHT_SHIFT 16 +#define NIC0_QM0_CQ_CFG1_MAX_INFLIGHT_MASK 0xFFFF0000 + +/* NIC0_QM0_CQ_ARUSER_31_11 */ +#define NIC0_QM0_CQ_ARUSER_31_11_VAL_SHIFT 0 +#define NIC0_QM0_CQ_ARUSER_31_11_VAL_MASK 0x1FFFFF + +/* NIC0_QM0_CQ_STS0 */ +#define NIC0_QM0_CQ_STS0_CQ_CREDIT_CNT_SHIFT 0 +#define NIC0_QM0_CQ_STS0_CQ_CREDIT_CNT_MASK 0xFFFF +#define NIC0_QM0_CQ_STS0_CQ_FREE_CNT_SHIFT 16 +#define NIC0_QM0_CQ_STS0_CQ_FREE_CNT_MASK 0xFFFF0000 + +/* NIC0_QM0_CQ_STS1 */ +#define NIC0_QM0_CQ_STS1_CQ_INFLIGHT_CNT_SHIFT 0 +#define NIC0_QM0_CQ_STS1_CQ_INFLIGHT_CNT_MASK 0xFFFF +#define NIC0_QM0_CQ_STS1_CQ_BUF_EMPTY_SHIFT 30 +#define NIC0_QM0_CQ_STS1_CQ_BUF_EMPTY_MASK 0x40000000 +#define NIC0_QM0_CQ_STS1_CQ_BUSY_SHIFT 31 +#define NIC0_QM0_CQ_STS1_CQ_BUSY_MASK 0x80000000 + +/* NIC0_QM0_CQ_PTR_LO_0 */ +#define NIC0_QM0_CQ_PTR_LO_0_VAL_SHIFT 0 +#define NIC0_QM0_CQ_PTR_LO_0_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_PTR_HI_0 */ +#define NIC0_QM0_CQ_PTR_HI_0_VAL_SHIFT 0 +#define NIC0_QM0_CQ_PTR_HI_0_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_TSIZE_0 */ +#define NIC0_QM0_CQ_TSIZE_0_VAL_SHIFT 0 +#define NIC0_QM0_CQ_TSIZE_0_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_CTL_0 */ +#define NIC0_QM0_CQ_CTL_0_RPT_SHIFT 0 +#define NIC0_QM0_CQ_CTL_0_RPT_MASK 0xFFFF +#define NIC0_QM0_CQ_CTL_0_CTL_SHIFT 16 +#define NIC0_QM0_CQ_CTL_0_CTL_MASK 0xFFFF0000 + +/* NIC0_QM0_CQ_PTR_LO_1 */ +#define NIC0_QM0_CQ_PTR_LO_1_VAL_SHIFT 0 +#define NIC0_QM0_CQ_PTR_LO_1_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_PTR_HI_1 */ +#define NIC0_QM0_CQ_PTR_HI_1_VAL_SHIFT 0 +#define NIC0_QM0_CQ_PTR_HI_1_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_TSIZE_1 */ +#define NIC0_QM0_CQ_TSIZE_1_VAL_SHIFT 0 +#define NIC0_QM0_CQ_TSIZE_1_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_CTL_1 */ +#define NIC0_QM0_CQ_CTL_1_RPT_SHIFT 0 +#define NIC0_QM0_CQ_CTL_1_RPT_MASK 0xFFFF +#define NIC0_QM0_CQ_CTL_1_CTL_SHIFT 16 +#define NIC0_QM0_CQ_CTL_1_CTL_MASK 0xFFFF0000 + +/* NIC0_QM0_CQ_PTR_LO_2 */ +#define NIC0_QM0_CQ_PTR_LO_2_VAL_SHIFT 0 +#define NIC0_QM0_CQ_PTR_LO_2_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_PTR_HI_2 */ +#define NIC0_QM0_CQ_PTR_HI_2_VAL_SHIFT 0 +#define NIC0_QM0_CQ_PTR_HI_2_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_TSIZE_2 */ +#define NIC0_QM0_CQ_TSIZE_2_VAL_SHIFT 0 +#define NIC0_QM0_CQ_TSIZE_2_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_CTL_2 */ +#define NIC0_QM0_CQ_CTL_2_RPT_SHIFT 0 +#define NIC0_QM0_CQ_CTL_2_RPT_MASK 0xFFFF +#define NIC0_QM0_CQ_CTL_2_CTL_SHIFT 16 +#define NIC0_QM0_CQ_CTL_2_CTL_MASK 0xFFFF0000 + +/* NIC0_QM0_CQ_PTR_LO_3 */ +#define NIC0_QM0_CQ_PTR_LO_3_VAL_SHIFT 0 +#define NIC0_QM0_CQ_PTR_LO_3_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_PTR_HI_3 */ +#define NIC0_QM0_CQ_PTR_HI_3_VAL_SHIFT 0 +#define NIC0_QM0_CQ_PTR_HI_3_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_TSIZE_3 */ +#define NIC0_QM0_CQ_TSIZE_3_VAL_SHIFT 0 +#define NIC0_QM0_CQ_TSIZE_3_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_CTL_3 */ +#define NIC0_QM0_CQ_CTL_3_RPT_SHIFT 0 +#define NIC0_QM0_CQ_CTL_3_RPT_MASK 0xFFFF +#define NIC0_QM0_CQ_CTL_3_CTL_SHIFT 16 +#define NIC0_QM0_CQ_CTL_3_CTL_MASK 0xFFFF0000 + +/* NIC0_QM0_CQ_PTR_LO_4 */ +#define NIC0_QM0_CQ_PTR_LO_4_VAL_SHIFT 0 +#define NIC0_QM0_CQ_PTR_LO_4_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_PTR_HI_4 */ +#define NIC0_QM0_CQ_PTR_HI_4_VAL_SHIFT 0 +#define NIC0_QM0_CQ_PTR_HI_4_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_TSIZE_4 */ +#define NIC0_QM0_CQ_TSIZE_4_VAL_SHIFT 0 +#define NIC0_QM0_CQ_TSIZE_4_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_CTL_4 */ +#define NIC0_QM0_CQ_CTL_4_RPT_SHIFT 0 +#define NIC0_QM0_CQ_CTL_4_RPT_MASK 0xFFFF +#define NIC0_QM0_CQ_CTL_4_CTL_SHIFT 16 +#define NIC0_QM0_CQ_CTL_4_CTL_MASK 0xFFFF0000 + +/* NIC0_QM0_CQ_PTR_LO_STS */ +#define NIC0_QM0_CQ_PTR_LO_STS_VAL_SHIFT 0 +#define NIC0_QM0_CQ_PTR_LO_STS_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_PTR_HI_STS */ +#define NIC0_QM0_CQ_PTR_HI_STS_VAL_SHIFT 0 +#define NIC0_QM0_CQ_PTR_HI_STS_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_TSIZE_STS */ +#define NIC0_QM0_CQ_TSIZE_STS_VAL_SHIFT 0 +#define NIC0_QM0_CQ_TSIZE_STS_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CQ_CTL_STS */ +#define NIC0_QM0_CQ_CTL_STS_RPT_SHIFT 0 +#define NIC0_QM0_CQ_CTL_STS_RPT_MASK 0xFFFF +#define NIC0_QM0_CQ_CTL_STS_CTL_SHIFT 16 +#define NIC0_QM0_CQ_CTL_STS_CTL_MASK 0xFFFF0000 + +/* NIC0_QM0_CQ_IFIFO_CNT */ +#define NIC0_QM0_CQ_IFIFO_CNT_VAL_SHIFT 0 +#define NIC0_QM0_CQ_IFIFO_CNT_VAL_MASK 0x3 + +/* NIC0_QM0_CP_MSG_BASE0_ADDR_LO */ +#define NIC0_QM0_CP_MSG_BASE0_ADDR_LO_VAL_SHIFT 0 +#define NIC0_QM0_CP_MSG_BASE0_ADDR_LO_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CP_MSG_BASE0_ADDR_HI */ +#define NIC0_QM0_CP_MSG_BASE0_ADDR_HI_VAL_SHIFT 0 +#define NIC0_QM0_CP_MSG_BASE0_ADDR_HI_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CP_MSG_BASE1_ADDR_LO */ +#define NIC0_QM0_CP_MSG_BASE1_ADDR_LO_VAL_SHIFT 0 +#define NIC0_QM0_CP_MSG_BASE1_ADDR_LO_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CP_MSG_BASE1_ADDR_HI */ +#define NIC0_QM0_CP_MSG_BASE1_ADDR_HI_VAL_SHIFT 0 +#define NIC0_QM0_CP_MSG_BASE1_ADDR_HI_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CP_MSG_BASE2_ADDR_LO */ +#define NIC0_QM0_CP_MSG_BASE2_ADDR_LO_VAL_SHIFT 0 +#define NIC0_QM0_CP_MSG_BASE2_ADDR_LO_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CP_MSG_BASE2_ADDR_HI */ +#define NIC0_QM0_CP_MSG_BASE2_ADDR_HI_VAL_SHIFT 0 +#define NIC0_QM0_CP_MSG_BASE2_ADDR_HI_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CP_MSG_BASE3_ADDR_LO */ +#define NIC0_QM0_CP_MSG_BASE3_ADDR_LO_VAL_SHIFT 0 +#define NIC0_QM0_CP_MSG_BASE3_ADDR_LO_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CP_MSG_BASE3_ADDR_HI */ +#define NIC0_QM0_CP_MSG_BASE3_ADDR_HI_VAL_SHIFT 0 +#define NIC0_QM0_CP_MSG_BASE3_ADDR_HI_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CP_LDMA_TSIZE_OFFSET */ +#define NIC0_QM0_CP_LDMA_TSIZE_OFFSET_VAL_SHIFT 0 +#define NIC0_QM0_CP_LDMA_TSIZE_OFFSET_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET */ +#define NIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_VAL_SHIFT 0 +#define NIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET */ +#define NIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_VAL_SHIFT 0 +#define NIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CP_FENCE0_RDATA */ +#define NIC0_QM0_CP_FENCE0_RDATA_INC_VAL_SHIFT 0 +#define NIC0_QM0_CP_FENCE0_RDATA_INC_VAL_MASK 0xF + +/* NIC0_QM0_CP_FENCE1_RDATA */ +#define NIC0_QM0_CP_FENCE1_RDATA_INC_VAL_SHIFT 0 +#define NIC0_QM0_CP_FENCE1_RDATA_INC_VAL_MASK 0xF + +/* NIC0_QM0_CP_FENCE2_RDATA */ +#define NIC0_QM0_CP_FENCE2_RDATA_INC_VAL_SHIFT 0 +#define NIC0_QM0_CP_FENCE2_RDATA_INC_VAL_MASK 0xF + +/* NIC0_QM0_CP_FENCE3_RDATA */ +#define NIC0_QM0_CP_FENCE3_RDATA_INC_VAL_SHIFT 0 +#define NIC0_QM0_CP_FENCE3_RDATA_INC_VAL_MASK 0xF + +/* NIC0_QM0_CP_FENCE0_CNT */ +#define NIC0_QM0_CP_FENCE0_CNT_VAL_SHIFT 0 +#define NIC0_QM0_CP_FENCE0_CNT_VAL_MASK 0x3FFF + +/* NIC0_QM0_CP_FENCE1_CNT */ +#define NIC0_QM0_CP_FENCE1_CNT_VAL_SHIFT 0 +#define NIC0_QM0_CP_FENCE1_CNT_VAL_MASK 0x3FFF + +/* NIC0_QM0_CP_FENCE2_CNT */ +#define NIC0_QM0_CP_FENCE2_CNT_VAL_SHIFT 0 +#define NIC0_QM0_CP_FENCE2_CNT_VAL_MASK 0x3FFF + +/* NIC0_QM0_CP_FENCE3_CNT */ +#define NIC0_QM0_CP_FENCE3_CNT_VAL_SHIFT 0 +#define NIC0_QM0_CP_FENCE3_CNT_VAL_MASK 0x3FFF + +/* NIC0_QM0_CP_STS */ +#define NIC0_QM0_CP_STS_MSG_INFLIGHT_CNT_SHIFT 0 +#define NIC0_QM0_CP_STS_MSG_INFLIGHT_CNT_MASK 0xFFFF +#define NIC0_QM0_CP_STS_ERDY_SHIFT 16 +#define NIC0_QM0_CP_STS_ERDY_MASK 0x10000 +#define NIC0_QM0_CP_STS_RRDY_SHIFT 17 +#define NIC0_QM0_CP_STS_RRDY_MASK 0x20000 +#define NIC0_QM0_CP_STS_MRDY_SHIFT 18 +#define NIC0_QM0_CP_STS_MRDY_MASK 0x40000 +#define NIC0_QM0_CP_STS_SW_STOP_SHIFT 19 +#define NIC0_QM0_CP_STS_SW_STOP_MASK 0x80000 +#define NIC0_QM0_CP_STS_FENCE_ID_SHIFT 20 +#define NIC0_QM0_CP_STS_FENCE_ID_MASK 0x300000 +#define NIC0_QM0_CP_STS_FENCE_IN_PROGRESS_SHIFT 22 +#define NIC0_QM0_CP_STS_FENCE_IN_PROGRESS_MASK 0x400000 + +/* NIC0_QM0_CP_CURRENT_INST_LO */ +#define NIC0_QM0_CP_CURRENT_INST_LO_VAL_SHIFT 0 +#define NIC0_QM0_CP_CURRENT_INST_LO_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CP_CURRENT_INST_HI */ +#define NIC0_QM0_CP_CURRENT_INST_HI_VAL_SHIFT 0 +#define NIC0_QM0_CP_CURRENT_INST_HI_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_CP_BARRIER_CFG */ +#define NIC0_QM0_CP_BARRIER_CFG_EBGUARD_SHIFT 0 +#define NIC0_QM0_CP_BARRIER_CFG_EBGUARD_MASK 0xFFF +#define NIC0_QM0_CP_BARRIER_CFG_RBGUARD_SHIFT 16 +#define NIC0_QM0_CP_BARRIER_CFG_RBGUARD_MASK 0xF0000 + +/* NIC0_QM0_CP_DBG_0 */ +#define NIC0_QM0_CP_DBG_0_CS_SHIFT 0 +#define NIC0_QM0_CP_DBG_0_CS_MASK 0xF +#define NIC0_QM0_CP_DBG_0_EB_CNT_NOT_ZERO_SHIFT 4 +#define NIC0_QM0_CP_DBG_0_EB_CNT_NOT_ZERO_MASK 0x10 +#define NIC0_QM0_CP_DBG_0_BULK_CNT_NOT_ZERO_SHIFT 5 +#define NIC0_QM0_CP_DBG_0_BULK_CNT_NOT_ZERO_MASK 0x20 +#define NIC0_QM0_CP_DBG_0_MREB_STALL_SHIFT 6 +#define NIC0_QM0_CP_DBG_0_MREB_STALL_MASK 0x40 +#define NIC0_QM0_CP_DBG_0_STALL_SHIFT 7 +#define NIC0_QM0_CP_DBG_0_STALL_MASK 0x80 + +/* NIC0_QM0_CP_ARUSER_31_11 */ +#define NIC0_QM0_CP_ARUSER_31_11_VAL_SHIFT 0 +#define NIC0_QM0_CP_ARUSER_31_11_VAL_MASK 0x1FFFFF + +/* NIC0_QM0_CP_AWUSER_31_11 */ +#define NIC0_QM0_CP_AWUSER_31_11_VAL_SHIFT 0 +#define NIC0_QM0_CP_AWUSER_31_11_VAL_MASK 0x1FFFFF + +/* NIC0_QM0_ARB_CFG_0 */ +#define NIC0_QM0_ARB_CFG_0_TYPE_SHIFT 0 +#define NIC0_QM0_ARB_CFG_0_TYPE_MASK 0x1 +#define NIC0_QM0_ARB_CFG_0_IS_MASTER_SHIFT 4 +#define NIC0_QM0_ARB_CFG_0_IS_MASTER_MASK 0x10 +#define NIC0_QM0_ARB_CFG_0_EN_SHIFT 8 +#define NIC0_QM0_ARB_CFG_0_EN_MASK 0x100 +#define NIC0_QM0_ARB_CFG_0_MASK_SHIFT 12 +#define NIC0_QM0_ARB_CFG_0_MASK_MASK 0xF000 +#define NIC0_QM0_ARB_CFG_0_MST_MSG_NOSTALL_SHIFT 16 +#define NIC0_QM0_ARB_CFG_0_MST_MSG_NOSTALL_MASK 0x10000 + +/* NIC0_QM0_ARB_CHOISE_Q_PUSH */ +#define NIC0_QM0_ARB_CHOISE_Q_PUSH_VAL_SHIFT 0 +#define NIC0_QM0_ARB_CHOISE_Q_PUSH_VAL_MASK 0x3 + +/* NIC0_QM0_ARB_WRR_WEIGHT */ +#define NIC0_QM0_ARB_WRR_WEIGHT_VAL_SHIFT 0 +#define NIC0_QM0_ARB_WRR_WEIGHT_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_ARB_CFG_1 */ +#define NIC0_QM0_ARB_CFG_1_CLR_SHIFT 0 +#define NIC0_QM0_ARB_CFG_1_CLR_MASK 0x1 + +/* NIC0_QM0_ARB_MST_AVAIL_CRED */ +#define NIC0_QM0_ARB_MST_AVAIL_CRED_VAL_SHIFT 0 +#define NIC0_QM0_ARB_MST_AVAIL_CRED_VAL_MASK 0x7F + +/* NIC0_QM0_ARB_MST_CRED_INC */ +#define NIC0_QM0_ARB_MST_CRED_INC_VAL_SHIFT 0 +#define NIC0_QM0_ARB_MST_CRED_INC_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_ARB_MST_CHOISE_PUSH_OFST */ +#define NIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_VAL_SHIFT 0 +#define NIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_ARB_SLV_MASTER_INC_CRED_OFST */ +#define NIC0_QM0_ARB_SLV_MASTER_INC_CRED_OFST_VAL_SHIFT 0 +#define NIC0_QM0_ARB_SLV_MASTER_INC_CRED_OFST_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_ARB_MST_SLAVE_EN */ +#define NIC0_QM0_ARB_MST_SLAVE_EN_VAL_SHIFT 0 +#define NIC0_QM0_ARB_MST_SLAVE_EN_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_ARB_MST_QUIET_PER */ +#define NIC0_QM0_ARB_MST_QUIET_PER_VAL_SHIFT 0 +#define NIC0_QM0_ARB_MST_QUIET_PER_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_ARB_SLV_CHOISE_WDT */ +#define NIC0_QM0_ARB_SLV_CHOISE_WDT_VAL_SHIFT 0 +#define NIC0_QM0_ARB_SLV_CHOISE_WDT_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_ARB_SLV_ID */ +#define NIC0_QM0_ARB_SLV_ID_VAL_SHIFT 0 +#define NIC0_QM0_ARB_SLV_ID_VAL_MASK 0x1F + +/* NIC0_QM0_ARB_MSG_MAX_INFLIGHT */ +#define NIC0_QM0_ARB_MSG_MAX_INFLIGHT_VAL_SHIFT 0 +#define NIC0_QM0_ARB_MSG_MAX_INFLIGHT_VAL_MASK 0x3F + +/* NIC0_QM0_ARB_MSG_AWUSER_31_11 */ +#define NIC0_QM0_ARB_MSG_AWUSER_31_11_VAL_SHIFT 0 +#define NIC0_QM0_ARB_MSG_AWUSER_31_11_VAL_MASK 0x1FFFFF + +/* NIC0_QM0_ARB_MSG_AWUSER_SEC_PROP */ +#define NIC0_QM0_ARB_MSG_AWUSER_SEC_PROP_ASID_SHIFT 0 +#define NIC0_QM0_ARB_MSG_AWUSER_SEC_PROP_ASID_MASK 0x3FF +#define NIC0_QM0_ARB_MSG_AWUSER_SEC_PROP_MMBP_SHIFT 10 +#define NIC0_QM0_ARB_MSG_AWUSER_SEC_PROP_MMBP_MASK 0x400 + +/* NIC0_QM0_ARB_MSG_AWUSER_NON_SEC_PROP */ +#define NIC0_QM0_ARB_MSG_AWUSER_NON_SEC_PROP_ASID_SHIFT 0 +#define NIC0_QM0_ARB_MSG_AWUSER_NON_SEC_PROP_ASID_MASK 0x3FF +#define NIC0_QM0_ARB_MSG_AWUSER_NON_SEC_PROP_MMBP_SHIFT 10 +#define NIC0_QM0_ARB_MSG_AWUSER_NON_SEC_PROP_MMBP_MASK 0x400 + +/* NIC0_QM0_ARB_BASE_LO */ +#define NIC0_QM0_ARB_BASE_LO_VAL_SHIFT 0 +#define NIC0_QM0_ARB_BASE_LO_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_ARB_BASE_HI */ +#define NIC0_QM0_ARB_BASE_HI_VAL_SHIFT 0 +#define NIC0_QM0_ARB_BASE_HI_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_ARB_STATE_STS */ +#define NIC0_QM0_ARB_STATE_STS_VAL_SHIFT 0 +#define NIC0_QM0_ARB_STATE_STS_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_ARB_CHOISE_FULLNESS_STS */ +#define NIC0_QM0_ARB_CHOISE_FULLNESS_STS_VAL_SHIFT 0 +#define NIC0_QM0_ARB_CHOISE_FULLNESS_STS_VAL_MASK 0x7F + +/* NIC0_QM0_ARB_MSG_STS */ +#define NIC0_QM0_ARB_MSG_STS_FULL_SHIFT 0 +#define NIC0_QM0_ARB_MSG_STS_FULL_MASK 0x1 +#define NIC0_QM0_ARB_MSG_STS_NO_INFLIGHT_SHIFT 1 +#define NIC0_QM0_ARB_MSG_STS_NO_INFLIGHT_MASK 0x2 + +/* NIC0_QM0_ARB_SLV_CHOISE_Q_HEAD */ +#define NIC0_QM0_ARB_SLV_CHOISE_Q_HEAD_VAL_SHIFT 0 +#define NIC0_QM0_ARB_SLV_CHOISE_Q_HEAD_VAL_MASK 0x3 + +/* NIC0_QM0_ARB_ERR_CAUSE */ +#define NIC0_QM0_ARB_ERR_CAUSE_CHOISE_OVF_SHIFT 0 +#define NIC0_QM0_ARB_ERR_CAUSE_CHOISE_OVF_MASK 0x1 +#define NIC0_QM0_ARB_ERR_CAUSE_CHOISE_WDT_SHIFT 1 +#define NIC0_QM0_ARB_ERR_CAUSE_CHOISE_WDT_MASK 0x2 +#define NIC0_QM0_ARB_ERR_CAUSE_AXI_LBW_ERR_SHIFT 2 +#define NIC0_QM0_ARB_ERR_CAUSE_AXI_LBW_ERR_MASK 0x4 + +/* NIC0_QM0_ARB_ERR_MSG_EN */ +#define NIC0_QM0_ARB_ERR_MSG_EN_CHOISE_OVF_SHIFT 0 +#define NIC0_QM0_ARB_ERR_MSG_EN_CHOISE_OVF_MASK 0x1 +#define NIC0_QM0_ARB_ERR_MSG_EN_CHOISE_WDT_SHIFT 1 +#define NIC0_QM0_ARB_ERR_MSG_EN_CHOISE_WDT_MASK 0x2 +#define NIC0_QM0_ARB_ERR_MSG_EN_AXI_LBW_ERR_SHIFT 2 +#define NIC0_QM0_ARB_ERR_MSG_EN_AXI_LBW_ERR_MASK 0x4 + +/* NIC0_QM0_ARB_ERR_STS_DRP */ +#define NIC0_QM0_ARB_ERR_STS_DRP_VAL_SHIFT 0 +#define NIC0_QM0_ARB_ERR_STS_DRP_VAL_MASK 0x3 + +/* NIC0_QM0_ARB_MST_CRED_STS */ +#define NIC0_QM0_ARB_MST_CRED_STS_VAL_SHIFT 0 +#define NIC0_QM0_ARB_MST_CRED_STS_VAL_MASK 0x7F + +/* NIC0_QM0_CGM_CFG */ +#define NIC0_QM0_CGM_CFG_IDLE_TH_SHIFT 0 +#define NIC0_QM0_CGM_CFG_IDLE_TH_MASK 0xFFF +#define NIC0_QM0_CGM_CFG_G2F_TH_SHIFT 16 +#define NIC0_QM0_CGM_CFG_G2F_TH_MASK 0xFF0000 +#define NIC0_QM0_CGM_CFG_CP_IDLE_MASK_SHIFT 24 +#define NIC0_QM0_CGM_CFG_CP_IDLE_MASK_MASK 0x1F000000 +#define NIC0_QM0_CGM_CFG_EN_SHIFT 31 +#define NIC0_QM0_CGM_CFG_EN_MASK 0x80000000 + +/* NIC0_QM0_CGM_STS */ +#define NIC0_QM0_CGM_STS_ST_SHIFT 0 +#define NIC0_QM0_CGM_STS_ST_MASK 0x3 +#define NIC0_QM0_CGM_STS_CG_SHIFT 4 +#define NIC0_QM0_CGM_STS_CG_MASK 0x10 +#define NIC0_QM0_CGM_STS_AGENT_IDLE_SHIFT 8 +#define NIC0_QM0_CGM_STS_AGENT_IDLE_MASK 0x100 +#define NIC0_QM0_CGM_STS_AXI_IDLE_SHIFT 9 +#define NIC0_QM0_CGM_STS_AXI_IDLE_MASK 0x200 +#define NIC0_QM0_CGM_STS_CP_IDLE_SHIFT 10 +#define NIC0_QM0_CGM_STS_CP_IDLE_MASK 0x400 + +/* NIC0_QM0_CGM_CFG1 */ +#define NIC0_QM0_CGM_CFG1_MASK_TH_SHIFT 0 +#define NIC0_QM0_CGM_CFG1_MASK_TH_MASK 0xFF + +/* NIC0_QM0_LOCAL_RANGE_BASE */ +#define NIC0_QM0_LOCAL_RANGE_BASE_VAL_SHIFT 0 +#define NIC0_QM0_LOCAL_RANGE_BASE_VAL_MASK 0xFFFF + +/* NIC0_QM0_LOCAL_RANGE_SIZE */ +#define NIC0_QM0_LOCAL_RANGE_SIZE_VAL_SHIFT 0 +#define NIC0_QM0_LOCAL_RANGE_SIZE_VAL_MASK 0xFFFF + +/* NIC0_QM0_CSMR_STRICT_PRIO_CFG */ +#define NIC0_QM0_CSMR_STRICT_PRIO_CFG_TYPE_SHIFT 0 +#define NIC0_QM0_CSMR_STRICT_PRIO_CFG_TYPE_MASK 0x1 + +/* NIC0_QM0_HBW_RD_RATE_LIM_CFG_1 */ +#define NIC0_QM0_HBW_RD_RATE_LIM_CFG_1_TOUT_SHIFT 0 +#define NIC0_QM0_HBW_RD_RATE_LIM_CFG_1_TOUT_MASK 0xFF +#define NIC0_QM0_HBW_RD_RATE_LIM_CFG_1_EN_SHIFT 31 +#define NIC0_QM0_HBW_RD_RATE_LIM_CFG_1_EN_MASK 0x80000000 + +/* NIC0_QM0_LBW_WR_RATE_LIM_CFG_0 */ +#define NIC0_QM0_LBW_WR_RATE_LIM_CFG_0_RST_TOKEN_SHIFT 0 +#define NIC0_QM0_LBW_WR_RATE_LIM_CFG_0_RST_TOKEN_MASK 0xFF +#define NIC0_QM0_LBW_WR_RATE_LIM_CFG_0_SAT_SHIFT 16 +#define NIC0_QM0_LBW_WR_RATE_LIM_CFG_0_SAT_MASK 0xFF0000 + +/* NIC0_QM0_LBW_WR_RATE_LIM_CFG_1 */ +#define NIC0_QM0_LBW_WR_RATE_LIM_CFG_1_TOUT_SHIFT 0 +#define NIC0_QM0_LBW_WR_RATE_LIM_CFG_1_TOUT_MASK 0xFF +#define NIC0_QM0_LBW_WR_RATE_LIM_CFG_1_EN_SHIFT 31 +#define NIC0_QM0_LBW_WR_RATE_LIM_CFG_1_EN_MASK 0x80000000 + +/* NIC0_QM0_HBW_RD_RATE_LIM_CFG_0 */ +#define NIC0_QM0_HBW_RD_RATE_LIM_CFG_0_RST_TOKEN_SHIFT 0 +#define NIC0_QM0_HBW_RD_RATE_LIM_CFG_0_RST_TOKEN_MASK 0xFF +#define NIC0_QM0_HBW_RD_RATE_LIM_CFG_0_SAT_SHIFT 16 +#define NIC0_QM0_HBW_RD_RATE_LIM_CFG_0_SAT_MASK 0xFF0000 + +/* NIC0_QM0_GLBL_AXCACHE */ +#define NIC0_QM0_GLBL_AXCACHE_AR_SHIFT 0 +#define NIC0_QM0_GLBL_AXCACHE_AR_MASK 0xF +#define NIC0_QM0_GLBL_AXCACHE_AW_SHIFT 16 +#define NIC0_QM0_GLBL_AXCACHE_AW_MASK 0xF0000 + +/* NIC0_QM0_IND_GW_APB_CFG */ +#define NIC0_QM0_IND_GW_APB_CFG_ADDR_SHIFT 0 +#define NIC0_QM0_IND_GW_APB_CFG_ADDR_MASK 0x7FFFFFFF +#define NIC0_QM0_IND_GW_APB_CFG_CMD_SHIFT 31 +#define NIC0_QM0_IND_GW_APB_CFG_CMD_MASK 0x80000000 + +/* NIC0_QM0_IND_GW_APB_WDATA */ +#define NIC0_QM0_IND_GW_APB_WDATA_VAL_SHIFT 0 +#define NIC0_QM0_IND_GW_APB_WDATA_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_IND_GW_APB_RDATA */ +#define NIC0_QM0_IND_GW_APB_RDATA_VAL_SHIFT 0 +#define NIC0_QM0_IND_GW_APB_RDATA_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_IND_GW_APB_STATUS */ +#define NIC0_QM0_IND_GW_APB_STATUS_RDY_SHIFT 0 +#define NIC0_QM0_IND_GW_APB_STATUS_RDY_MASK 0x1 +#define NIC0_QM0_IND_GW_APB_STATUS_ERR_SHIFT 1 +#define NIC0_QM0_IND_GW_APB_STATUS_ERR_MASK 0x2 + +/* NIC0_QM0_GLBL_ERR_ADDR_LO */ +#define NIC0_QM0_GLBL_ERR_ADDR_LO_VAL_SHIFT 0 +#define NIC0_QM0_GLBL_ERR_ADDR_LO_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_GLBL_ERR_ADDR_HI */ +#define NIC0_QM0_GLBL_ERR_ADDR_HI_VAL_SHIFT 0 +#define NIC0_QM0_GLBL_ERR_ADDR_HI_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_GLBL_ERR_WDATA */ +#define NIC0_QM0_GLBL_ERR_WDATA_VAL_SHIFT 0 +#define NIC0_QM0_GLBL_ERR_WDATA_VAL_MASK 0xFFFFFFFF + +/* NIC0_QM0_GLBL_MEM_INIT_BUSY */ +#define NIC0_QM0_GLBL_MEM_INIT_BUSY_RBUF_SHIFT 0 +#define NIC0_QM0_GLBL_MEM_INIT_BUSY_RBUF_MASK 0xF + +#endif /* ASIC_REG_NIC0_QM0_MASKS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/nic0_qm0_regs.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic0_qm0_regs.h new file mode 100644 index 000000000000..7c97f4041b8e --- /dev/null +++ b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic0_qm0_regs.h @@ -0,0 +1,834 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright 2016-2018 HabanaLabs, Ltd. + * All Rights Reserved. + * + */ + +/************************************ + ** This is an auto-generated file ** + ** DO NOT EDIT BELOW ** + ************************************/ + +#ifndef ASIC_REG_NIC0_QM0_REGS_H_ +#define ASIC_REG_NIC0_QM0_REGS_H_ + +/* + ***************************************** + * NIC0_QM0 (Prototype: QMAN) + ***************************************** + */ + +#define mmNIC0_QM0_GLBL_CFG0 0xCE0000 + +#define mmNIC0_QM0_GLBL_CFG1 0xCE0004 + +#define mmNIC0_QM0_GLBL_PROT 0xCE0008 + +#define mmNIC0_QM0_GLBL_ERR_CFG 0xCE000C + +#define mmNIC0_QM0_GLBL_SECURE_PROPS_0 0xCE0010 + +#define mmNIC0_QM0_GLBL_SECURE_PROPS_1 0xCE0014 + +#define mmNIC0_QM0_GLBL_SECURE_PROPS_2 0xCE0018 + +#define mmNIC0_QM0_GLBL_SECURE_PROPS_3 0xCE001C + +#define mmNIC0_QM0_GLBL_SECURE_PROPS_4 0xCE0020 + +#define mmNIC0_QM0_GLBL_NON_SECURE_PROPS_0 0xCE0024 + +#define mmNIC0_QM0_GLBL_NON_SECURE_PROPS_1 0xCE0028 + +#define mmNIC0_QM0_GLBL_NON_SECURE_PROPS_2 0xCE002C + +#define mmNIC0_QM0_GLBL_NON_SECURE_PROPS_3 0xCE0030 + +#define mmNIC0_QM0_GLBL_NON_SECURE_PROPS_4 0xCE0034 + +#define mmNIC0_QM0_GLBL_STS0 0xCE0038 + +#define mmNIC0_QM0_GLBL_STS1_0 0xCE0040 + +#define mmNIC0_QM0_GLBL_STS1_1 0xCE0044 + +#define mmNIC0_QM0_GLBL_STS1_2 0xCE0048 + +#define mmNIC0_QM0_GLBL_STS1_3 0xCE004C + +#define mmNIC0_QM0_GLBL_STS1_4 0xCE0050 + +#define mmNIC0_QM0_GLBL_MSG_EN_0 0xCE0054 + +#define mmNIC0_QM0_GLBL_MSG_EN_1 0xCE0058 + +#define mmNIC0_QM0_GLBL_MSG_EN_2 0xCE005C + +#define mmNIC0_QM0_GLBL_MSG_EN_3 0xCE0060 + +#define mmNIC0_QM0_GLBL_MSG_EN_4 0xCE0068 + +#define mmNIC0_QM0_PQ_BASE_LO_0 0xCE0070 + +#define mmNIC0_QM0_PQ_BASE_LO_1 0xCE0074 + +#define mmNIC0_QM0_PQ_BASE_LO_2 0xCE0078 + +#define mmNIC0_QM0_PQ_BASE_LO_3 0xCE007C + +#define mmNIC0_QM0_PQ_BASE_HI_0 0xCE0080 + +#define mmNIC0_QM0_PQ_BASE_HI_1 0xCE0084 + +#define mmNIC0_QM0_PQ_BASE_HI_2 0xCE0088 + +#define mmNIC0_QM0_PQ_BASE_HI_3 0xCE008C + +#define mmNIC0_QM0_PQ_SIZE_0 0xCE0090 + +#define mmNIC0_QM0_PQ_SIZE_1 0xCE0094 + +#define mmNIC0_QM0_PQ_SIZE_2 0xCE0098 + +#define mmNIC0_QM0_PQ_SIZE_3 0xCE009C + +#define mmNIC0_QM0_PQ_PI_0 0xCE00A0 + +#define mmNIC0_QM0_PQ_PI_1 0xCE00A4 + +#define mmNIC0_QM0_PQ_PI_2 0xCE00A8 + +#define mmNIC0_QM0_PQ_PI_3 0xCE00AC + +#define mmNIC0_QM0_PQ_CI_0 0xCE00B0 + +#define mmNIC0_QM0_PQ_CI_1 0xCE00B4 + +#define mmNIC0_QM0_PQ_CI_2 0xCE00B8 + +#define mmNIC0_QM0_PQ_CI_3 0xCE00BC + +#define mmNIC0_QM0_PQ_CFG0_0 0xCE00C0 + +#define mmNIC0_QM0_PQ_CFG0_1 0xCE00C4 + +#define mmNIC0_QM0_PQ_CFG0_2 0xCE00C8 + +#define mmNIC0_QM0_PQ_CFG0_3 0xCE00CC + +#define mmNIC0_QM0_PQ_CFG1_0 0xCE00D0 + +#define mmNIC0_QM0_PQ_CFG1_1 0xCE00D4 + +#define mmNIC0_QM0_PQ_CFG1_2 0xCE00D8 + +#define mmNIC0_QM0_PQ_CFG1_3 0xCE00DC + +#define mmNIC0_QM0_PQ_ARUSER_31_11_0 0xCE00E0 + +#define mmNIC0_QM0_PQ_ARUSER_31_11_1 0xCE00E4 + +#define mmNIC0_QM0_PQ_ARUSER_31_11_2 0xCE00E8 + +#define mmNIC0_QM0_PQ_ARUSER_31_11_3 0xCE00EC + +#define mmNIC0_QM0_PQ_STS0_0 0xCE00F0 + +#define mmNIC0_QM0_PQ_STS0_1 0xCE00F4 + +#define mmNIC0_QM0_PQ_STS0_2 0xCE00F8 + +#define mmNIC0_QM0_PQ_STS0_3 0xCE00FC + +#define mmNIC0_QM0_PQ_STS1_0 0xCE0100 + +#define mmNIC0_QM0_PQ_STS1_1 0xCE0104 + +#define mmNIC0_QM0_PQ_STS1_2 0xCE0108 + +#define mmNIC0_QM0_PQ_STS1_3 0xCE010C + +#define mmNIC0_QM0_CQ_CFG0_0 0xCE0110 + +#define mmNIC0_QM0_CQ_CFG0_1 0xCE0114 + +#define mmNIC0_QM0_CQ_CFG0_2 0xCE0118 + +#define mmNIC0_QM0_CQ_CFG0_3 0xCE011C + +#define mmNIC0_QM0_CQ_CFG0_4 0xCE0120 + +#define mmNIC0_QM0_CQ_CFG1_0 0xCE0124 + +#define mmNIC0_QM0_CQ_CFG1_1 0xCE0128 + +#define mmNIC0_QM0_CQ_CFG1_2 0xCE012C + +#define mmNIC0_QM0_CQ_CFG1_3 0xCE0130 + +#define mmNIC0_QM0_CQ_CFG1_4 0xCE0134 + +#define mmNIC0_QM0_CQ_ARUSER_31_11_0 0xCE0138 + +#define mmNIC0_QM0_CQ_ARUSER_31_11_1 0xCE013C + +#define mmNIC0_QM0_CQ_ARUSER_31_11_2 0xCE0140 + +#define mmNIC0_QM0_CQ_ARUSER_31_11_3 0xCE0144 + +#define mmNIC0_QM0_CQ_ARUSER_31_11_4 0xCE0148 + +#define mmNIC0_QM0_CQ_STS0_0 0xCE014C + +#define mmNIC0_QM0_CQ_STS0_1 0xCE0150 + +#define mmNIC0_QM0_CQ_STS0_2 0xCE0154 + +#define mmNIC0_QM0_CQ_STS0_3 0xCE0158 + +#define mmNIC0_QM0_CQ_STS0_4 0xCE015C + +#define mmNIC0_QM0_CQ_STS1_0 0xCE0160 + +#define mmNIC0_QM0_CQ_STS1_1 0xCE0164 + +#define mmNIC0_QM0_CQ_STS1_2 0xCE0168 + +#define mmNIC0_QM0_CQ_STS1_3 0xCE016C + +#define mmNIC0_QM0_CQ_STS1_4 0xCE0170 + +#define mmNIC0_QM0_CQ_PTR_LO_0 0xCE0174 + +#define mmNIC0_QM0_CQ_PTR_HI_0 0xCE0178 + +#define mmNIC0_QM0_CQ_TSIZE_0 0xCE017C + +#define mmNIC0_QM0_CQ_CTL_0 0xCE0180 + +#define mmNIC0_QM0_CQ_PTR_LO_1 0xCE0184 + +#define mmNIC0_QM0_CQ_PTR_HI_1 0xCE0188 + +#define mmNIC0_QM0_CQ_TSIZE_1 0xCE018C + +#define mmNIC0_QM0_CQ_CTL_1 0xCE0190 + +#define mmNIC0_QM0_CQ_PTR_LO_2 0xCE0194 + +#define mmNIC0_QM0_CQ_PTR_HI_2 0xCE0198 + +#define mmNIC0_QM0_CQ_TSIZE_2 0xCE019C + +#define mmNIC0_QM0_CQ_CTL_2 0xCE01A0 + +#define mmNIC0_QM0_CQ_PTR_LO_3 0xCE01A4 + +#define mmNIC0_QM0_CQ_PTR_HI_3 0xCE01A8 + +#define mmNIC0_QM0_CQ_TSIZE_3 0xCE01AC + +#define mmNIC0_QM0_CQ_CTL_3 0xCE01B0 + +#define mmNIC0_QM0_CQ_PTR_LO_4 0xCE01B4 + +#define mmNIC0_QM0_CQ_PTR_HI_4 0xCE01B8 + +#define mmNIC0_QM0_CQ_TSIZE_4 0xCE01BC + +#define mmNIC0_QM0_CQ_CTL_4 0xCE01C0 + +#define mmNIC0_QM0_CQ_PTR_LO_STS_0 0xCE01C4 + +#define mmNIC0_QM0_CQ_PTR_LO_STS_1 0xCE01C8 + +#define mmNIC0_QM0_CQ_PTR_LO_STS_2 0xCE01CC + +#define mmNIC0_QM0_CQ_PTR_LO_STS_3 0xCE01D0 + +#define mmNIC0_QM0_CQ_PTR_LO_STS_4 0xCE01D4 + +#define mmNIC0_QM0_CQ_PTR_HI_STS_0 0xCE01D8 + +#define mmNIC0_QM0_CQ_PTR_HI_STS_1 0xCE01DC + +#define mmNIC0_QM0_CQ_PTR_HI_STS_2 0xCE01E0 + +#define mmNIC0_QM0_CQ_PTR_HI_STS_3 0xCE01E4 + +#define mmNIC0_QM0_CQ_PTR_HI_STS_4 0xCE01E8 + +#define mmNIC0_QM0_CQ_TSIZE_STS_0 0xCE01EC + +#define mmNIC0_QM0_CQ_TSIZE_STS_1 0xCE01F0 + +#define mmNIC0_QM0_CQ_TSIZE_STS_2 0xCE01F4 + +#define mmNIC0_QM0_CQ_TSIZE_STS_3 0xCE01F8 + +#define mmNIC0_QM0_CQ_TSIZE_STS_4 0xCE01FC + +#define mmNIC0_QM0_CQ_CTL_STS_0 0xCE0200 + +#define mmNIC0_QM0_CQ_CTL_STS_1 0xCE0204 + +#define mmNIC0_QM0_CQ_CTL_STS_2 0xCE0208 + +#define mmNIC0_QM0_CQ_CTL_STS_3 0xCE020C + +#define mmNIC0_QM0_CQ_CTL_STS_4 0xCE0210 + +#define mmNIC0_QM0_CQ_IFIFO_CNT_0 0xCE0214 + +#define mmNIC0_QM0_CQ_IFIFO_CNT_1 0xCE0218 + +#define mmNIC0_QM0_CQ_IFIFO_CNT_2 0xCE021C + +#define mmNIC0_QM0_CQ_IFIFO_CNT_3 0xCE0220 + +#define mmNIC0_QM0_CQ_IFIFO_CNT_4 0xCE0224 + +#define mmNIC0_QM0_CP_MSG_BASE0_ADDR_LO_0 0xCE0228 + +#define mmNIC0_QM0_CP_MSG_BASE0_ADDR_LO_1 0xCE022C + +#define mmNIC0_QM0_CP_MSG_BASE0_ADDR_LO_2 0xCE0230 + +#define mmNIC0_QM0_CP_MSG_BASE0_ADDR_LO_3 0xCE0234 + +#define mmNIC0_QM0_CP_MSG_BASE0_ADDR_LO_4 0xCE0238 + +#define mmNIC0_QM0_CP_MSG_BASE0_ADDR_HI_0 0xCE023C + +#define mmNIC0_QM0_CP_MSG_BASE0_ADDR_HI_1 0xCE0240 + +#define mmNIC0_QM0_CP_MSG_BASE0_ADDR_HI_2 0xCE0244 + +#define mmNIC0_QM0_CP_MSG_BASE0_ADDR_HI_3 0xCE0248 + +#define mmNIC0_QM0_CP_MSG_BASE0_ADDR_HI_4 0xCE024C + +#define mmNIC0_QM0_CP_MSG_BASE1_ADDR_LO_0 0xCE0250 + +#define mmNIC0_QM0_CP_MSG_BASE1_ADDR_LO_1 0xCE0254 + +#define mmNIC0_QM0_CP_MSG_BASE1_ADDR_LO_2 0xCE0258 + +#define mmNIC0_QM0_CP_MSG_BASE1_ADDR_LO_3 0xCE025C + +#define mmNIC0_QM0_CP_MSG_BASE1_ADDR_LO_4 0xCE0260 + +#define mmNIC0_QM0_CP_MSG_BASE1_ADDR_HI_0 0xCE0264 + +#define mmNIC0_QM0_CP_MSG_BASE1_ADDR_HI_1 0xCE0268 + +#define mmNIC0_QM0_CP_MSG_BASE1_ADDR_HI_2 0xCE026C + +#define mmNIC0_QM0_CP_MSG_BASE1_ADDR_HI_3 0xCE0270 + +#define mmNIC0_QM0_CP_MSG_BASE1_ADDR_HI_4 0xCE0274 + +#define mmNIC0_QM0_CP_MSG_BASE2_ADDR_LO_0 0xCE0278 + +#define mmNIC0_QM0_CP_MSG_BASE2_ADDR_LO_1 0xCE027C + +#define mmNIC0_QM0_CP_MSG_BASE2_ADDR_LO_2 0xCE0280 + +#define mmNIC0_QM0_CP_MSG_BASE2_ADDR_LO_3 0xCE0284 + +#define mmNIC0_QM0_CP_MSG_BASE2_ADDR_LO_4 0xCE0288 + +#define mmNIC0_QM0_CP_MSG_BASE2_ADDR_HI_0 0xCE028C + +#define mmNIC0_QM0_CP_MSG_BASE2_ADDR_HI_1 0xCE0290 + +#define mmNIC0_QM0_CP_MSG_BASE2_ADDR_HI_2 0xCE0294 + +#define mmNIC0_QM0_CP_MSG_BASE2_ADDR_HI_3 0xCE0298 + +#define mmNIC0_QM0_CP_MSG_BASE2_ADDR_HI_4 0xCE029C + +#define mmNIC0_QM0_CP_MSG_BASE3_ADDR_LO_0 0xCE02A0 + +#define mmNIC0_QM0_CP_MSG_BASE3_ADDR_LO_1 0xCE02A4 + +#define mmNIC0_QM0_CP_MSG_BASE3_ADDR_LO_2 0xCE02A8 + +#define mmNIC0_QM0_CP_MSG_BASE3_ADDR_LO_3 0xCE02AC + +#define mmNIC0_QM0_CP_MSG_BASE3_ADDR_LO_4 0xCE02B0 + +#define mmNIC0_QM0_CP_MSG_BASE3_ADDR_HI_0 0xCE02B4 + +#define mmNIC0_QM0_CP_MSG_BASE3_ADDR_HI_1 0xCE02B8 + +#define mmNIC0_QM0_CP_MSG_BASE3_ADDR_HI_2 0xCE02BC + +#define mmNIC0_QM0_CP_MSG_BASE3_ADDR_HI_3 0xCE02C0 + +#define mmNIC0_QM0_CP_MSG_BASE3_ADDR_HI_4 0xCE02C4 + +#define mmNIC0_QM0_CP_LDMA_TSIZE_OFFSET_0 0xCE02C8 + +#define mmNIC0_QM0_CP_LDMA_TSIZE_OFFSET_1 0xCE02CC + +#define mmNIC0_QM0_CP_LDMA_TSIZE_OFFSET_2 0xCE02D0 + +#define mmNIC0_QM0_CP_LDMA_TSIZE_OFFSET_3 0xCE02D4 + +#define mmNIC0_QM0_CP_LDMA_TSIZE_OFFSET_4 0xCE02D8 + +#define mmNIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_0 0xCE02E0 + +#define mmNIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_1 0xCE02E4 + +#define mmNIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_2 0xCE02E8 + +#define mmNIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_3 0xCE02EC + +#define mmNIC0_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_4 0xCE02F0 + +#define mmNIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_0 0xCE02F4 + +#define mmNIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_1 0xCE02F8 + +#define mmNIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_2 0xCE02FC + +#define mmNIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 0xCE0300 + +#define mmNIC0_QM0_CP_LDMA_DST_BASE_LO_OFFSET_4 0xCE0304 + +#define mmNIC0_QM0_CP_FENCE0_RDATA_0 0xCE0308 + +#define mmNIC0_QM0_CP_FENCE0_RDATA_1 0xCE030C + +#define mmNIC0_QM0_CP_FENCE0_RDATA_2 0xCE0310 + +#define mmNIC0_QM0_CP_FENCE0_RDATA_3 0xCE0314 + +#define mmNIC0_QM0_CP_FENCE0_RDATA_4 0xCE0318 + +#define mmNIC0_QM0_CP_FENCE1_RDATA_0 0xCE031C + +#define mmNIC0_QM0_CP_FENCE1_RDATA_1 0xCE0320 + +#define mmNIC0_QM0_CP_FENCE1_RDATA_2 0xCE0324 + +#define mmNIC0_QM0_CP_FENCE1_RDATA_3 0xCE0328 + +#define mmNIC0_QM0_CP_FENCE1_RDATA_4 0xCE032C + +#define mmNIC0_QM0_CP_FENCE2_RDATA_0 0xCE0330 + +#define mmNIC0_QM0_CP_FENCE2_RDATA_1 0xCE0334 + +#define mmNIC0_QM0_CP_FENCE2_RDATA_2 0xCE0338 + +#define mmNIC0_QM0_CP_FENCE2_RDATA_3 0xCE033C + +#define mmNIC0_QM0_CP_FENCE2_RDATA_4 0xCE0340 + +#define mmNIC0_QM0_CP_FENCE3_RDATA_0 0xCE0344 + +#define mmNIC0_QM0_CP_FENCE3_RDATA_1 0xCE0348 + +#define mmNIC0_QM0_CP_FENCE3_RDATA_2 0xCE034C + +#define mmNIC0_QM0_CP_FENCE3_RDATA_3 0xCE0350 + +#define mmNIC0_QM0_CP_FENCE3_RDATA_4 0xCE0354 + +#define mmNIC0_QM0_CP_FENCE0_CNT_0 0xCE0358 + +#define mmNIC0_QM0_CP_FENCE0_CNT_1 0xCE035C + +#define mmNIC0_QM0_CP_FENCE0_CNT_2 0xCE0360 + +#define mmNIC0_QM0_CP_FENCE0_CNT_3 0xCE0364 + +#define mmNIC0_QM0_CP_FENCE0_CNT_4 0xCE0368 + +#define mmNIC0_QM0_CP_FENCE1_CNT_0 0xCE036C + +#define mmNIC0_QM0_CP_FENCE1_CNT_1 0xCE0370 + +#define mmNIC0_QM0_CP_FENCE1_CNT_2 0xCE0374 + +#define mmNIC0_QM0_CP_FENCE1_CNT_3 0xCE0378 + +#define mmNIC0_QM0_CP_FENCE1_CNT_4 0xCE037C + +#define mmNIC0_QM0_CP_FENCE2_CNT_0 0xCE0380 + +#define mmNIC0_QM0_CP_FENCE2_CNT_1 0xCE0384 + +#define mmNIC0_QM0_CP_FENCE2_CNT_2 0xCE0388 + +#define mmNIC0_QM0_CP_FENCE2_CNT_3 0xCE038C + +#define mmNIC0_QM0_CP_FENCE2_CNT_4 0xCE0390 + +#define mmNIC0_QM0_CP_FENCE3_CNT_0 0xCE0394 + +#define mmNIC0_QM0_CP_FENCE3_CNT_1 0xCE0398 + +#define mmNIC0_QM0_CP_FENCE3_CNT_2 0xCE039C + +#define mmNIC0_QM0_CP_FENCE3_CNT_3 0xCE03A0 + +#define mmNIC0_QM0_CP_FENCE3_CNT_4 0xCE03A4 + +#define mmNIC0_QM0_CP_STS_0 0xCE03A8 + +#define mmNIC0_QM0_CP_STS_1 0xCE03AC + +#define mmNIC0_QM0_CP_STS_2 0xCE03B0 + +#define mmNIC0_QM0_CP_STS_3 0xCE03B4 + +#define mmNIC0_QM0_CP_STS_4 0xCE03B8 + +#define mmNIC0_QM0_CP_CURRENT_INST_LO_0 0xCE03BC + +#define mmNIC0_QM0_CP_CURRENT_INST_LO_1 0xCE03C0 + +#define mmNIC0_QM0_CP_CURRENT_INST_LO_2 0xCE03C4 + +#define mmNIC0_QM0_CP_CURRENT_INST_LO_3 0xCE03C8 + +#define mmNIC0_QM0_CP_CURRENT_INST_LO_4 0xCE03CC + +#define mmNIC0_QM0_CP_CURRENT_INST_HI_0 0xCE03D0 + +#define mmNIC0_QM0_CP_CURRENT_INST_HI_1 0xCE03D4 + +#define mmNIC0_QM0_CP_CURRENT_INST_HI_2 0xCE03D8 + +#define mmNIC0_QM0_CP_CURRENT_INST_HI_3 0xCE03DC + +#define mmNIC0_QM0_CP_CURRENT_INST_HI_4 0xCE03E0 + +#define mmNIC0_QM0_CP_BARRIER_CFG_0 0xCE03F4 + +#define mmNIC0_QM0_CP_BARRIER_CFG_1 0xCE03F8 + +#define mmNIC0_QM0_CP_BARRIER_CFG_2 0xCE03FC + +#define mmNIC0_QM0_CP_BARRIER_CFG_3 0xCE0400 + +#define mmNIC0_QM0_CP_BARRIER_CFG_4 0xCE0404 + +#define mmNIC0_QM0_CP_DBG_0_0 0xCE0408 + +#define mmNIC0_QM0_CP_DBG_0_1 0xCE040C + +#define mmNIC0_QM0_CP_DBG_0_2 0xCE0410 + +#define mmNIC0_QM0_CP_DBG_0_3 0xCE0414 + +#define mmNIC0_QM0_CP_DBG_0_4 0xCE0418 + +#define mmNIC0_QM0_CP_ARUSER_31_11_0 0xCE041C + +#define mmNIC0_QM0_CP_ARUSER_31_11_1 0xCE0420 + +#define mmNIC0_QM0_CP_ARUSER_31_11_2 0xCE0424 + +#define mmNIC0_QM0_CP_ARUSER_31_11_3 0xCE0428 + +#define mmNIC0_QM0_CP_ARUSER_31_11_4 0xCE042C + +#define mmNIC0_QM0_CP_AWUSER_31_11_0 0xCE0430 + +#define mmNIC0_QM0_CP_AWUSER_31_11_1 0xCE0434 + +#define mmNIC0_QM0_CP_AWUSER_31_11_2 0xCE0438 + +#define mmNIC0_QM0_CP_AWUSER_31_11_3 0xCE043C + +#define mmNIC0_QM0_CP_AWUSER_31_11_4 0xCE0440 + +#define mmNIC0_QM0_ARB_CFG_0 0xCE0A00 + +#define mmNIC0_QM0_ARB_CHOISE_Q_PUSH 0xCE0A04 + +#define mmNIC0_QM0_ARB_WRR_WEIGHT_0 0xCE0A08 + +#define mmNIC0_QM0_ARB_WRR_WEIGHT_1 0xCE0A0C + +#define mmNIC0_QM0_ARB_WRR_WEIGHT_2 0xCE0A10 + +#define mmNIC0_QM0_ARB_WRR_WEIGHT_3 0xCE0A14 + +#define mmNIC0_QM0_ARB_CFG_1 0xCE0A18 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_0 0xCE0A20 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_1 0xCE0A24 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_2 0xCE0A28 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_3 0xCE0A2C + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_4 0xCE0A30 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_5 0xCE0A34 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_6 0xCE0A38 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_7 0xCE0A3C + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_8 0xCE0A40 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_9 0xCE0A44 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_10 0xCE0A48 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_11 0xCE0A4C + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_12 0xCE0A50 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_13 0xCE0A54 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_14 0xCE0A58 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_15 0xCE0A5C + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_16 0xCE0A60 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_17 0xCE0A64 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_18 0xCE0A68 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_19 0xCE0A6C + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_20 0xCE0A70 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_21 0xCE0A74 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_22 0xCE0A78 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_23 0xCE0A7C + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_24 0xCE0A80 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_25 0xCE0A84 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_26 0xCE0A88 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_27 0xCE0A8C + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_28 0xCE0A90 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_29 0xCE0A94 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_30 0xCE0A98 + +#define mmNIC0_QM0_ARB_MST_AVAIL_CRED_31 0xCE0A9C + +#define mmNIC0_QM0_ARB_MST_CRED_INC 0xCE0AA0 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_0 0xCE0AA4 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_1 0xCE0AA8 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_2 0xCE0AAC + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_3 0xCE0AB0 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_4 0xCE0AB4 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_5 0xCE0AB8 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_6 0xCE0ABC + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_7 0xCE0AC0 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_8 0xCE0AC4 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_9 0xCE0AC8 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_10 0xCE0ACC + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_11 0xCE0AD0 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_12 0xCE0AD4 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_13 0xCE0AD8 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_14 0xCE0ADC + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_15 0xCE0AE0 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_16 0xCE0AE4 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_17 0xCE0AE8 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_18 0xCE0AEC + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_19 0xCE0AF0 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_20 0xCE0AF4 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_21 0xCE0AF8 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_22 0xCE0AFC + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_23 0xCE0B00 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_24 0xCE0B04 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_25 0xCE0B08 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_26 0xCE0B0C + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_27 0xCE0B10 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_28 0xCE0B14 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_29 0xCE0B18 + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_30 0xCE0B1C + +#define mmNIC0_QM0_ARB_MST_CHOISE_PUSH_OFST_31 0xCE0B20 + +#define mmNIC0_QM0_ARB_SLV_MASTER_INC_CRED_OFST 0xCE0B28 + +#define mmNIC0_QM0_ARB_MST_SLAVE_EN 0xCE0B2C + +#define mmNIC0_QM0_ARB_MST_QUIET_PER 0xCE0B34 + +#define mmNIC0_QM0_ARB_SLV_CHOISE_WDT 0xCE0B38 + +#define mmNIC0_QM0_ARB_SLV_ID 0xCE0B3C + +#define mmNIC0_QM0_ARB_MSG_MAX_INFLIGHT 0xCE0B44 + +#define mmNIC0_QM0_ARB_MSG_AWUSER_31_11 0xCE0B48 + +#define mmNIC0_QM0_ARB_MSG_AWUSER_SEC_PROP 0xCE0B4C + +#define mmNIC0_QM0_ARB_MSG_AWUSER_NON_SEC_PROP 0xCE0B50 + +#define mmNIC0_QM0_ARB_BASE_LO 0xCE0B54 + +#define mmNIC0_QM0_ARB_BASE_HI 0xCE0B58 + +#define mmNIC0_QM0_ARB_STATE_STS 0xCE0B80 + +#define mmNIC0_QM0_ARB_CHOISE_FULLNESS_STS 0xCE0B84 + +#define mmNIC0_QM0_ARB_MSG_STS 0xCE0B88 + +#define mmNIC0_QM0_ARB_SLV_CHOISE_Q_HEAD 0xCE0B8C + +#define mmNIC0_QM0_ARB_ERR_CAUSE 0xCE0B9C + +#define mmNIC0_QM0_ARB_ERR_MSG_EN 0xCE0BA0 + +#define mmNIC0_QM0_ARB_ERR_STS_DRP 0xCE0BA8 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_0 0xCE0BB0 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_1 0xCE0BB4 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_2 0xCE0BB8 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_3 0xCE0BBC + +#define mmNIC0_QM0_ARB_MST_CRED_STS_4 0xCE0BC0 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_5 0xCE0BC4 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_6 0xCE0BC8 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_7 0xCE0BCC + +#define mmNIC0_QM0_ARB_MST_CRED_STS_8 0xCE0BD0 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_9 0xCE0BD4 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_10 0xCE0BD8 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_11 0xCE0BDC + +#define mmNIC0_QM0_ARB_MST_CRED_STS_12 0xCE0BE0 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_13 0xCE0BE4 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_14 0xCE0BE8 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_15 0xCE0BEC + +#define mmNIC0_QM0_ARB_MST_CRED_STS_16 0xCE0BF0 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_17 0xCE0BF4 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_18 0xCE0BF8 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_19 0xCE0BFC + +#define mmNIC0_QM0_ARB_MST_CRED_STS_20 0xCE0C00 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_21 0xCE0C04 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_22 0xCE0C08 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_23 0xCE0C0C + +#define mmNIC0_QM0_ARB_MST_CRED_STS_24 0xCE0C10 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_25 0xCE0C14 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_26 0xCE0C18 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_27 0xCE0C1C + +#define mmNIC0_QM0_ARB_MST_CRED_STS_28 0xCE0C20 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_29 0xCE0C24 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_30 0xCE0C28 + +#define mmNIC0_QM0_ARB_MST_CRED_STS_31 0xCE0C2C + +#define mmNIC0_QM0_CGM_CFG 0xCE0C70 + +#define mmNIC0_QM0_CGM_STS 0xCE0C74 + +#define mmNIC0_QM0_CGM_CFG1 0xCE0C78 + +#define mmNIC0_QM0_LOCAL_RANGE_BASE 0xCE0C80 + +#define mmNIC0_QM0_LOCAL_RANGE_SIZE 0xCE0C84 + +#define mmNIC0_QM0_CSMR_STRICT_PRIO_CFG 0xCE0C90 + +#define mmNIC0_QM0_HBW_RD_RATE_LIM_CFG_1 0xCE0C94 + +#define mmNIC0_QM0_LBW_WR_RATE_LIM_CFG_0 0xCE0C98 + +#define mmNIC0_QM0_LBW_WR_RATE_LIM_CFG_1 0xCE0C9C + +#define mmNIC0_QM0_HBW_RD_RATE_LIM_CFG_0 0xCE0CA0 + +#define mmNIC0_QM0_GLBL_AXCACHE 0xCE0CA4 + +#define mmNIC0_QM0_IND_GW_APB_CFG 0xCE0CB0 + +#define mmNIC0_QM0_IND_GW_APB_WDATA 0xCE0CB4 + +#define mmNIC0_QM0_IND_GW_APB_RDATA 0xCE0CB8 + +#define mmNIC0_QM0_IND_GW_APB_STATUS 0xCE0CBC + +#define mmNIC0_QM0_GLBL_ERR_ADDR_LO 0xCE0CD0 + +#define mmNIC0_QM0_GLBL_ERR_ADDR_HI 0xCE0CD4 + +#define mmNIC0_QM0_GLBL_ERR_WDATA 0xCE0CD8 + +#define mmNIC0_QM0_GLBL_MEM_INIT_BUSY 0xCE0D00 + +#endif /* ASIC_REG_NIC0_QM0_REGS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/nic0_qm1_regs.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic0_qm1_regs.h new file mode 100644 index 000000000000..fe96c575b5c6 --- /dev/null +++ b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic0_qm1_regs.h @@ -0,0 +1,834 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright 2016-2018 HabanaLabs, Ltd. + * All Rights Reserved. + * + */ + +/************************************ + ** This is an auto-generated file ** + ** DO NOT EDIT BELOW ** + ************************************/ + +#ifndef ASIC_REG_NIC0_QM1_REGS_H_ +#define ASIC_REG_NIC0_QM1_REGS_H_ + +/* + ***************************************** + * NIC0_QM1 (Prototype: QMAN) + ***************************************** + */ + +#define mmNIC0_QM1_GLBL_CFG0 0xCE2000 + +#define mmNIC0_QM1_GLBL_CFG1 0xCE2004 + +#define mmNIC0_QM1_GLBL_PROT 0xCE2008 + +#define mmNIC0_QM1_GLBL_ERR_CFG 0xCE200C + +#define mmNIC0_QM1_GLBL_SECURE_PROPS_0 0xCE2010 + +#define mmNIC0_QM1_GLBL_SECURE_PROPS_1 0xCE2014 + +#define mmNIC0_QM1_GLBL_SECURE_PROPS_2 0xCE2018 + +#define mmNIC0_QM1_GLBL_SECURE_PROPS_3 0xCE201C + +#define mmNIC0_QM1_GLBL_SECURE_PROPS_4 0xCE2020 + +#define mmNIC0_QM1_GLBL_NON_SECURE_PROPS_0 0xCE2024 + +#define mmNIC0_QM1_GLBL_NON_SECURE_PROPS_1 0xCE2028 + +#define mmNIC0_QM1_GLBL_NON_SECURE_PROPS_2 0xCE202C + +#define mmNIC0_QM1_GLBL_NON_SECURE_PROPS_3 0xCE2030 + +#define mmNIC0_QM1_GLBL_NON_SECURE_PROPS_4 0xCE2034 + +#define mmNIC0_QM1_GLBL_STS0 0xCE2038 + +#define mmNIC0_QM1_GLBL_STS1_0 0xCE2040 + +#define mmNIC0_QM1_GLBL_STS1_1 0xCE2044 + +#define mmNIC0_QM1_GLBL_STS1_2 0xCE2048 + +#define mmNIC0_QM1_GLBL_STS1_3 0xCE204C + +#define mmNIC0_QM1_GLBL_STS1_4 0xCE2050 + +#define mmNIC0_QM1_GLBL_MSG_EN_0 0xCE2054 + +#define mmNIC0_QM1_GLBL_MSG_EN_1 0xCE2058 + +#define mmNIC0_QM1_GLBL_MSG_EN_2 0xCE205C + +#define mmNIC0_QM1_GLBL_MSG_EN_3 0xCE2060 + +#define mmNIC0_QM1_GLBL_MSG_EN_4 0xCE2068 + +#define mmNIC0_QM1_PQ_BASE_LO_0 0xCE2070 + +#define mmNIC0_QM1_PQ_BASE_LO_1 0xCE2074 + +#define mmNIC0_QM1_PQ_BASE_LO_2 0xCE2078 + +#define mmNIC0_QM1_PQ_BASE_LO_3 0xCE207C + +#define mmNIC0_QM1_PQ_BASE_HI_0 0xCE2080 + +#define mmNIC0_QM1_PQ_BASE_HI_1 0xCE2084 + +#define mmNIC0_QM1_PQ_BASE_HI_2 0xCE2088 + +#define mmNIC0_QM1_PQ_BASE_HI_3 0xCE208C + +#define mmNIC0_QM1_PQ_SIZE_0 0xCE2090 + +#define mmNIC0_QM1_PQ_SIZE_1 0xCE2094 + +#define mmNIC0_QM1_PQ_SIZE_2 0xCE2098 + +#define mmNIC0_QM1_PQ_SIZE_3 0xCE209C + +#define mmNIC0_QM1_PQ_PI_0 0xCE20A0 + +#define mmNIC0_QM1_PQ_PI_1 0xCE20A4 + +#define mmNIC0_QM1_PQ_PI_2 0xCE20A8 + +#define mmNIC0_QM1_PQ_PI_3 0xCE20AC + +#define mmNIC0_QM1_PQ_CI_0 0xCE20B0 + +#define mmNIC0_QM1_PQ_CI_1 0xCE20B4 + +#define mmNIC0_QM1_PQ_CI_2 0xCE20B8 + +#define mmNIC0_QM1_PQ_CI_3 0xCE20BC + +#define mmNIC0_QM1_PQ_CFG0_0 0xCE20C0 + +#define mmNIC0_QM1_PQ_CFG0_1 0xCE20C4 + +#define mmNIC0_QM1_PQ_CFG0_2 0xCE20C8 + +#define mmNIC0_QM1_PQ_CFG0_3 0xCE20CC + +#define mmNIC0_QM1_PQ_CFG1_0 0xCE20D0 + +#define mmNIC0_QM1_PQ_CFG1_1 0xCE20D4 + +#define mmNIC0_QM1_PQ_CFG1_2 0xCE20D8 + +#define mmNIC0_QM1_PQ_CFG1_3 0xCE20DC + +#define mmNIC0_QM1_PQ_ARUSER_31_11_0 0xCE20E0 + +#define mmNIC0_QM1_PQ_ARUSER_31_11_1 0xCE20E4 + +#define mmNIC0_QM1_PQ_ARUSER_31_11_2 0xCE20E8 + +#define mmNIC0_QM1_PQ_ARUSER_31_11_3 0xCE20EC + +#define mmNIC0_QM1_PQ_STS0_0 0xCE20F0 + +#define mmNIC0_QM1_PQ_STS0_1 0xCE20F4 + +#define mmNIC0_QM1_PQ_STS0_2 0xCE20F8 + +#define mmNIC0_QM1_PQ_STS0_3 0xCE20FC + +#define mmNIC0_QM1_PQ_STS1_0 0xCE2100 + +#define mmNIC0_QM1_PQ_STS1_1 0xCE2104 + +#define mmNIC0_QM1_PQ_STS1_2 0xCE2108 + +#define mmNIC0_QM1_PQ_STS1_3 0xCE210C + +#define mmNIC0_QM1_CQ_CFG0_0 0xCE2110 + +#define mmNIC0_QM1_CQ_CFG0_1 0xCE2114 + +#define mmNIC0_QM1_CQ_CFG0_2 0xCE2118 + +#define mmNIC0_QM1_CQ_CFG0_3 0xCE211C + +#define mmNIC0_QM1_CQ_CFG0_4 0xCE2120 + +#define mmNIC0_QM1_CQ_CFG1_0 0xCE2124 + +#define mmNIC0_QM1_CQ_CFG1_1 0xCE2128 + +#define mmNIC0_QM1_CQ_CFG1_2 0xCE212C + +#define mmNIC0_QM1_CQ_CFG1_3 0xCE2130 + +#define mmNIC0_QM1_CQ_CFG1_4 0xCE2134 + +#define mmNIC0_QM1_CQ_ARUSER_31_11_0 0xCE2138 + +#define mmNIC0_QM1_CQ_ARUSER_31_11_1 0xCE213C + +#define mmNIC0_QM1_CQ_ARUSER_31_11_2 0xCE2140 + +#define mmNIC0_QM1_CQ_ARUSER_31_11_3 0xCE2144 + +#define mmNIC0_QM1_CQ_ARUSER_31_11_4 0xCE2148 + +#define mmNIC0_QM1_CQ_STS0_0 0xCE214C + +#define mmNIC0_QM1_CQ_STS0_1 0xCE2150 + +#define mmNIC0_QM1_CQ_STS0_2 0xCE2154 + +#define mmNIC0_QM1_CQ_STS0_3 0xCE2158 + +#define mmNIC0_QM1_CQ_STS0_4 0xCE215C + +#define mmNIC0_QM1_CQ_STS1_0 0xCE2160 + +#define mmNIC0_QM1_CQ_STS1_1 0xCE2164 + +#define mmNIC0_QM1_CQ_STS1_2 0xCE2168 + +#define mmNIC0_QM1_CQ_STS1_3 0xCE216C + +#define mmNIC0_QM1_CQ_STS1_4 0xCE2170 + +#define mmNIC0_QM1_CQ_PTR_LO_0 0xCE2174 + +#define mmNIC0_QM1_CQ_PTR_HI_0 0xCE2178 + +#define mmNIC0_QM1_CQ_TSIZE_0 0xCE217C + +#define mmNIC0_QM1_CQ_CTL_0 0xCE2180 + +#define mmNIC0_QM1_CQ_PTR_LO_1 0xCE2184 + +#define mmNIC0_QM1_CQ_PTR_HI_1 0xCE2188 + +#define mmNIC0_QM1_CQ_TSIZE_1 0xCE218C + +#define mmNIC0_QM1_CQ_CTL_1 0xCE2190 + +#define mmNIC0_QM1_CQ_PTR_LO_2 0xCE2194 + +#define mmNIC0_QM1_CQ_PTR_HI_2 0xCE2198 + +#define mmNIC0_QM1_CQ_TSIZE_2 0xCE219C + +#define mmNIC0_QM1_CQ_CTL_2 0xCE21A0 + +#define mmNIC0_QM1_CQ_PTR_LO_3 0xCE21A4 + +#define mmNIC0_QM1_CQ_PTR_HI_3 0xCE21A8 + +#define mmNIC0_QM1_CQ_TSIZE_3 0xCE21AC + +#define mmNIC0_QM1_CQ_CTL_3 0xCE21B0 + +#define mmNIC0_QM1_CQ_PTR_LO_4 0xCE21B4 + +#define mmNIC0_QM1_CQ_PTR_HI_4 0xCE21B8 + +#define mmNIC0_QM1_CQ_TSIZE_4 0xCE21BC + +#define mmNIC0_QM1_CQ_CTL_4 0xCE21C0 + +#define mmNIC0_QM1_CQ_PTR_LO_STS_0 0xCE21C4 + +#define mmNIC0_QM1_CQ_PTR_LO_STS_1 0xCE21C8 + +#define mmNIC0_QM1_CQ_PTR_LO_STS_2 0xCE21CC + +#define mmNIC0_QM1_CQ_PTR_LO_STS_3 0xCE21D0 + +#define mmNIC0_QM1_CQ_PTR_LO_STS_4 0xCE21D4 + +#define mmNIC0_QM1_CQ_PTR_HI_STS_0 0xCE21D8 + +#define mmNIC0_QM1_CQ_PTR_HI_STS_1 0xCE21DC + +#define mmNIC0_QM1_CQ_PTR_HI_STS_2 0xCE21E0 + +#define mmNIC0_QM1_CQ_PTR_HI_STS_3 0xCE21E4 + +#define mmNIC0_QM1_CQ_PTR_HI_STS_4 0xCE21E8 + +#define mmNIC0_QM1_CQ_TSIZE_STS_0 0xCE21EC + +#define mmNIC0_QM1_CQ_TSIZE_STS_1 0xCE21F0 + +#define mmNIC0_QM1_CQ_TSIZE_STS_2 0xCE21F4 + +#define mmNIC0_QM1_CQ_TSIZE_STS_3 0xCE21F8 + +#define mmNIC0_QM1_CQ_TSIZE_STS_4 0xCE21FC + +#define mmNIC0_QM1_CQ_CTL_STS_0 0xCE2200 + +#define mmNIC0_QM1_CQ_CTL_STS_1 0xCE2204 + +#define mmNIC0_QM1_CQ_CTL_STS_2 0xCE2208 + +#define mmNIC0_QM1_CQ_CTL_STS_3 0xCE220C + +#define mmNIC0_QM1_CQ_CTL_STS_4 0xCE2210 + +#define mmNIC0_QM1_CQ_IFIFO_CNT_0 0xCE2214 + +#define mmNIC0_QM1_CQ_IFIFO_CNT_1 0xCE2218 + +#define mmNIC0_QM1_CQ_IFIFO_CNT_2 0xCE221C + +#define mmNIC0_QM1_CQ_IFIFO_CNT_3 0xCE2220 + +#define mmNIC0_QM1_CQ_IFIFO_CNT_4 0xCE2224 + +#define mmNIC0_QM1_CP_MSG_BASE0_ADDR_LO_0 0xCE2228 + +#define mmNIC0_QM1_CP_MSG_BASE0_ADDR_LO_1 0xCE222C + +#define mmNIC0_QM1_CP_MSG_BASE0_ADDR_LO_2 0xCE2230 + +#define mmNIC0_QM1_CP_MSG_BASE0_ADDR_LO_3 0xCE2234 + +#define mmNIC0_QM1_CP_MSG_BASE0_ADDR_LO_4 0xCE2238 + +#define mmNIC0_QM1_CP_MSG_BASE0_ADDR_HI_0 0xCE223C + +#define mmNIC0_QM1_CP_MSG_BASE0_ADDR_HI_1 0xCE2240 + +#define mmNIC0_QM1_CP_MSG_BASE0_ADDR_HI_2 0xCE2244 + +#define mmNIC0_QM1_CP_MSG_BASE0_ADDR_HI_3 0xCE2248 + +#define mmNIC0_QM1_CP_MSG_BASE0_ADDR_HI_4 0xCE224C + +#define mmNIC0_QM1_CP_MSG_BASE1_ADDR_LO_0 0xCE2250 + +#define mmNIC0_QM1_CP_MSG_BASE1_ADDR_LO_1 0xCE2254 + +#define mmNIC0_QM1_CP_MSG_BASE1_ADDR_LO_2 0xCE2258 + +#define mmNIC0_QM1_CP_MSG_BASE1_ADDR_LO_3 0xCE225C + +#define mmNIC0_QM1_CP_MSG_BASE1_ADDR_LO_4 0xCE2260 + +#define mmNIC0_QM1_CP_MSG_BASE1_ADDR_HI_0 0xCE2264 + +#define mmNIC0_QM1_CP_MSG_BASE1_ADDR_HI_1 0xCE2268 + +#define mmNIC0_QM1_CP_MSG_BASE1_ADDR_HI_2 0xCE226C + +#define mmNIC0_QM1_CP_MSG_BASE1_ADDR_HI_3 0xCE2270 + +#define mmNIC0_QM1_CP_MSG_BASE1_ADDR_HI_4 0xCE2274 + +#define mmNIC0_QM1_CP_MSG_BASE2_ADDR_LO_0 0xCE2278 + +#define mmNIC0_QM1_CP_MSG_BASE2_ADDR_LO_1 0xCE227C + +#define mmNIC0_QM1_CP_MSG_BASE2_ADDR_LO_2 0xCE2280 + +#define mmNIC0_QM1_CP_MSG_BASE2_ADDR_LO_3 0xCE2284 + +#define mmNIC0_QM1_CP_MSG_BASE2_ADDR_LO_4 0xCE2288 + +#define mmNIC0_QM1_CP_MSG_BASE2_ADDR_HI_0 0xCE228C + +#define mmNIC0_QM1_CP_MSG_BASE2_ADDR_HI_1 0xCE2290 + +#define mmNIC0_QM1_CP_MSG_BASE2_ADDR_HI_2 0xCE2294 + +#define mmNIC0_QM1_CP_MSG_BASE2_ADDR_HI_3 0xCE2298 + +#define mmNIC0_QM1_CP_MSG_BASE2_ADDR_HI_4 0xCE229C + +#define mmNIC0_QM1_CP_MSG_BASE3_ADDR_LO_0 0xCE22A0 + +#define mmNIC0_QM1_CP_MSG_BASE3_ADDR_LO_1 0xCE22A4 + +#define mmNIC0_QM1_CP_MSG_BASE3_ADDR_LO_2 0xCE22A8 + +#define mmNIC0_QM1_CP_MSG_BASE3_ADDR_LO_3 0xCE22AC + +#define mmNIC0_QM1_CP_MSG_BASE3_ADDR_LO_4 0xCE22B0 + +#define mmNIC0_QM1_CP_MSG_BASE3_ADDR_HI_0 0xCE22B4 + +#define mmNIC0_QM1_CP_MSG_BASE3_ADDR_HI_1 0xCE22B8 + +#define mmNIC0_QM1_CP_MSG_BASE3_ADDR_HI_2 0xCE22BC + +#define mmNIC0_QM1_CP_MSG_BASE3_ADDR_HI_3 0xCE22C0 + +#define mmNIC0_QM1_CP_MSG_BASE3_ADDR_HI_4 0xCE22C4 + +#define mmNIC0_QM1_CP_LDMA_TSIZE_OFFSET_0 0xCE22C8 + +#define mmNIC0_QM1_CP_LDMA_TSIZE_OFFSET_1 0xCE22CC + +#define mmNIC0_QM1_CP_LDMA_TSIZE_OFFSET_2 0xCE22D0 + +#define mmNIC0_QM1_CP_LDMA_TSIZE_OFFSET_3 0xCE22D4 + +#define mmNIC0_QM1_CP_LDMA_TSIZE_OFFSET_4 0xCE22D8 + +#define mmNIC0_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_0 0xCE22E0 + +#define mmNIC0_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_1 0xCE22E4 + +#define mmNIC0_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_2 0xCE22E8 + +#define mmNIC0_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_3 0xCE22EC + +#define mmNIC0_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_4 0xCE22F0 + +#define mmNIC0_QM1_CP_LDMA_DST_BASE_LO_OFFSET_0 0xCE22F4 + +#define mmNIC0_QM1_CP_LDMA_DST_BASE_LO_OFFSET_1 0xCE22F8 + +#define mmNIC0_QM1_CP_LDMA_DST_BASE_LO_OFFSET_2 0xCE22FC + +#define mmNIC0_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 0xCE2300 + +#define mmNIC0_QM1_CP_LDMA_DST_BASE_LO_OFFSET_4 0xCE2304 + +#define mmNIC0_QM1_CP_FENCE0_RDATA_0 0xCE2308 + +#define mmNIC0_QM1_CP_FENCE0_RDATA_1 0xCE230C + +#define mmNIC0_QM1_CP_FENCE0_RDATA_2 0xCE2310 + +#define mmNIC0_QM1_CP_FENCE0_RDATA_3 0xCE2314 + +#define mmNIC0_QM1_CP_FENCE0_RDATA_4 0xCE2318 + +#define mmNIC0_QM1_CP_FENCE1_RDATA_0 0xCE231C + +#define mmNIC0_QM1_CP_FENCE1_RDATA_1 0xCE2320 + +#define mmNIC0_QM1_CP_FENCE1_RDATA_2 0xCE2324 + +#define mmNIC0_QM1_CP_FENCE1_RDATA_3 0xCE2328 + +#define mmNIC0_QM1_CP_FENCE1_RDATA_4 0xCE232C + +#define mmNIC0_QM1_CP_FENCE2_RDATA_0 0xCE2330 + +#define mmNIC0_QM1_CP_FENCE2_RDATA_1 0xCE2334 + +#define mmNIC0_QM1_CP_FENCE2_RDATA_2 0xCE2338 + +#define mmNIC0_QM1_CP_FENCE2_RDATA_3 0xCE233C + +#define mmNIC0_QM1_CP_FENCE2_RDATA_4 0xCE2340 + +#define mmNIC0_QM1_CP_FENCE3_RDATA_0 0xCE2344 + +#define mmNIC0_QM1_CP_FENCE3_RDATA_1 0xCE2348 + +#define mmNIC0_QM1_CP_FENCE3_RDATA_2 0xCE234C + +#define mmNIC0_QM1_CP_FENCE3_RDATA_3 0xCE2350 + +#define mmNIC0_QM1_CP_FENCE3_RDATA_4 0xCE2354 + +#define mmNIC0_QM1_CP_FENCE0_CNT_0 0xCE2358 + +#define mmNIC0_QM1_CP_FENCE0_CNT_1 0xCE235C + +#define mmNIC0_QM1_CP_FENCE0_CNT_2 0xCE2360 + +#define mmNIC0_QM1_CP_FENCE0_CNT_3 0xCE2364 + +#define mmNIC0_QM1_CP_FENCE0_CNT_4 0xCE2368 + +#define mmNIC0_QM1_CP_FENCE1_CNT_0 0xCE236C + +#define mmNIC0_QM1_CP_FENCE1_CNT_1 0xCE2370 + +#define mmNIC0_QM1_CP_FENCE1_CNT_2 0xCE2374 + +#define mmNIC0_QM1_CP_FENCE1_CNT_3 0xCE2378 + +#define mmNIC0_QM1_CP_FENCE1_CNT_4 0xCE237C + +#define mmNIC0_QM1_CP_FENCE2_CNT_0 0xCE2380 + +#define mmNIC0_QM1_CP_FENCE2_CNT_1 0xCE2384 + +#define mmNIC0_QM1_CP_FENCE2_CNT_2 0xCE2388 + +#define mmNIC0_QM1_CP_FENCE2_CNT_3 0xCE238C + +#define mmNIC0_QM1_CP_FENCE2_CNT_4 0xCE2390 + +#define mmNIC0_QM1_CP_FENCE3_CNT_0 0xCE2394 + +#define mmNIC0_QM1_CP_FENCE3_CNT_1 0xCE2398 + +#define mmNIC0_QM1_CP_FENCE3_CNT_2 0xCE239C + +#define mmNIC0_QM1_CP_FENCE3_CNT_3 0xCE23A0 + +#define mmNIC0_QM1_CP_FENCE3_CNT_4 0xCE23A4 + +#define mmNIC0_QM1_CP_STS_0 0xCE23A8 + +#define mmNIC0_QM1_CP_STS_1 0xCE23AC + +#define mmNIC0_QM1_CP_STS_2 0xCE23B0 + +#define mmNIC0_QM1_CP_STS_3 0xCE23B4 + +#define mmNIC0_QM1_CP_STS_4 0xCE23B8 + +#define mmNIC0_QM1_CP_CURRENT_INST_LO_0 0xCE23BC + +#define mmNIC0_QM1_CP_CURRENT_INST_LO_1 0xCE23C0 + +#define mmNIC0_QM1_CP_CURRENT_INST_LO_2 0xCE23C4 + +#define mmNIC0_QM1_CP_CURRENT_INST_LO_3 0xCE23C8 + +#define mmNIC0_QM1_CP_CURRENT_INST_LO_4 0xCE23CC + +#define mmNIC0_QM1_CP_CURRENT_INST_HI_0 0xCE23D0 + +#define mmNIC0_QM1_CP_CURRENT_INST_HI_1 0xCE23D4 + +#define mmNIC0_QM1_CP_CURRENT_INST_HI_2 0xCE23D8 + +#define mmNIC0_QM1_CP_CURRENT_INST_HI_3 0xCE23DC + +#define mmNIC0_QM1_CP_CURRENT_INST_HI_4 0xCE23E0 + +#define mmNIC0_QM1_CP_BARRIER_CFG_0 0xCE23F4 + +#define mmNIC0_QM1_CP_BARRIER_CFG_1 0xCE23F8 + +#define mmNIC0_QM1_CP_BARRIER_CFG_2 0xCE23FC + +#define mmNIC0_QM1_CP_BARRIER_CFG_3 0xCE2400 + +#define mmNIC0_QM1_CP_BARRIER_CFG_4 0xCE2404 + +#define mmNIC0_QM1_CP_DBG_0_0 0xCE2408 + +#define mmNIC0_QM1_CP_DBG_0_1 0xCE240C + +#define mmNIC0_QM1_CP_DBG_0_2 0xCE2410 + +#define mmNIC0_QM1_CP_DBG_0_3 0xCE2414 + +#define mmNIC0_QM1_CP_DBG_0_4 0xCE2418 + +#define mmNIC0_QM1_CP_ARUSER_31_11_0 0xCE241C + +#define mmNIC0_QM1_CP_ARUSER_31_11_1 0xCE2420 + +#define mmNIC0_QM1_CP_ARUSER_31_11_2 0xCE2424 + +#define mmNIC0_QM1_CP_ARUSER_31_11_3 0xCE2428 + +#define mmNIC0_QM1_CP_ARUSER_31_11_4 0xCE242C + +#define mmNIC0_QM1_CP_AWUSER_31_11_0 0xCE2430 + +#define mmNIC0_QM1_CP_AWUSER_31_11_1 0xCE2434 + +#define mmNIC0_QM1_CP_AWUSER_31_11_2 0xCE2438 + +#define mmNIC0_QM1_CP_AWUSER_31_11_3 0xCE243C + +#define mmNIC0_QM1_CP_AWUSER_31_11_4 0xCE2440 + +#define mmNIC0_QM1_ARB_CFG_0 0xCE2A00 + +#define mmNIC0_QM1_ARB_CHOISE_Q_PUSH 0xCE2A04 + +#define mmNIC0_QM1_ARB_WRR_WEIGHT_0 0xCE2A08 + +#define mmNIC0_QM1_ARB_WRR_WEIGHT_1 0xCE2A0C + +#define mmNIC0_QM1_ARB_WRR_WEIGHT_2 0xCE2A10 + +#define mmNIC0_QM1_ARB_WRR_WEIGHT_3 0xCE2A14 + +#define mmNIC0_QM1_ARB_CFG_1 0xCE2A18 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_0 0xCE2A20 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_1 0xCE2A24 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_2 0xCE2A28 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_3 0xCE2A2C + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_4 0xCE2A30 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_5 0xCE2A34 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_6 0xCE2A38 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_7 0xCE2A3C + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_8 0xCE2A40 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_9 0xCE2A44 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_10 0xCE2A48 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_11 0xCE2A4C + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_12 0xCE2A50 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_13 0xCE2A54 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_14 0xCE2A58 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_15 0xCE2A5C + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_16 0xCE2A60 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_17 0xCE2A64 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_18 0xCE2A68 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_19 0xCE2A6C + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_20 0xCE2A70 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_21 0xCE2A74 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_22 0xCE2A78 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_23 0xCE2A7C + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_24 0xCE2A80 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_25 0xCE2A84 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_26 0xCE2A88 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_27 0xCE2A8C + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_28 0xCE2A90 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_29 0xCE2A94 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_30 0xCE2A98 + +#define mmNIC0_QM1_ARB_MST_AVAIL_CRED_31 0xCE2A9C + +#define mmNIC0_QM1_ARB_MST_CRED_INC 0xCE2AA0 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_0 0xCE2AA4 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_1 0xCE2AA8 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_2 0xCE2AAC + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_3 0xCE2AB0 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_4 0xCE2AB4 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_5 0xCE2AB8 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_6 0xCE2ABC + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_7 0xCE2AC0 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_8 0xCE2AC4 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_9 0xCE2AC8 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_10 0xCE2ACC + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_11 0xCE2AD0 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_12 0xCE2AD4 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_13 0xCE2AD8 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_14 0xCE2ADC + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_15 0xCE2AE0 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_16 0xCE2AE4 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_17 0xCE2AE8 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_18 0xCE2AEC + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_19 0xCE2AF0 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_20 0xCE2AF4 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_21 0xCE2AF8 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_22 0xCE2AFC + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_23 0xCE2B00 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_24 0xCE2B04 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_25 0xCE2B08 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_26 0xCE2B0C + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_27 0xCE2B10 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_28 0xCE2B14 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_29 0xCE2B18 + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_30 0xCE2B1C + +#define mmNIC0_QM1_ARB_MST_CHOISE_PUSH_OFST_31 0xCE2B20 + +#define mmNIC0_QM1_ARB_SLV_MASTER_INC_CRED_OFST 0xCE2B28 + +#define mmNIC0_QM1_ARB_MST_SLAVE_EN 0xCE2B2C + +#define mmNIC0_QM1_ARB_MST_QUIET_PER 0xCE2B34 + +#define mmNIC0_QM1_ARB_SLV_CHOISE_WDT 0xCE2B38 + +#define mmNIC0_QM1_ARB_SLV_ID 0xCE2B3C + +#define mmNIC0_QM1_ARB_MSG_MAX_INFLIGHT 0xCE2B44 + +#define mmNIC0_QM1_ARB_MSG_AWUSER_31_11 0xCE2B48 + +#define mmNIC0_QM1_ARB_MSG_AWUSER_SEC_PROP 0xCE2B4C + +#define mmNIC0_QM1_ARB_MSG_AWUSER_NON_SEC_PROP 0xCE2B50 + +#define mmNIC0_QM1_ARB_BASE_LO 0xCE2B54 + +#define mmNIC0_QM1_ARB_BASE_HI 0xCE2B58 + +#define mmNIC0_QM1_ARB_STATE_STS 0xCE2B80 + +#define mmNIC0_QM1_ARB_CHOISE_FULLNESS_STS 0xCE2B84 + +#define mmNIC0_QM1_ARB_MSG_STS 0xCE2B88 + +#define mmNIC0_QM1_ARB_SLV_CHOISE_Q_HEAD 0xCE2B8C + +#define mmNIC0_QM1_ARB_ERR_CAUSE 0xCE2B9C + +#define mmNIC0_QM1_ARB_ERR_MSG_EN 0xCE2BA0 + +#define mmNIC0_QM1_ARB_ERR_STS_DRP 0xCE2BA8 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_0 0xCE2BB0 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_1 0xCE2BB4 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_2 0xCE2BB8 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_3 0xCE2BBC + +#define mmNIC0_QM1_ARB_MST_CRED_STS_4 0xCE2BC0 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_5 0xCE2BC4 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_6 0xCE2BC8 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_7 0xCE2BCC + +#define mmNIC0_QM1_ARB_MST_CRED_STS_8 0xCE2BD0 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_9 0xCE2BD4 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_10 0xCE2BD8 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_11 0xCE2BDC + +#define mmNIC0_QM1_ARB_MST_CRED_STS_12 0xCE2BE0 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_13 0xCE2BE4 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_14 0xCE2BE8 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_15 0xCE2BEC + +#define mmNIC0_QM1_ARB_MST_CRED_STS_16 0xCE2BF0 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_17 0xCE2BF4 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_18 0xCE2BF8 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_19 0xCE2BFC + +#define mmNIC0_QM1_ARB_MST_CRED_STS_20 0xCE2C00 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_21 0xCE2C04 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_22 0xCE2C08 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_23 0xCE2C0C + +#define mmNIC0_QM1_ARB_MST_CRED_STS_24 0xCE2C10 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_25 0xCE2C14 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_26 0xCE2C18 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_27 0xCE2C1C + +#define mmNIC0_QM1_ARB_MST_CRED_STS_28 0xCE2C20 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_29 0xCE2C24 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_30 0xCE2C28 + +#define mmNIC0_QM1_ARB_MST_CRED_STS_31 0xCE2C2C + +#define mmNIC0_QM1_CGM_CFG 0xCE2C70 + +#define mmNIC0_QM1_CGM_STS 0xCE2C74 + +#define mmNIC0_QM1_CGM_CFG1 0xCE2C78 + +#define mmNIC0_QM1_LOCAL_RANGE_BASE 0xCE2C80 + +#define mmNIC0_QM1_LOCAL_RANGE_SIZE 0xCE2C84 + +#define mmNIC0_QM1_CSMR_STRICT_PRIO_CFG 0xCE2C90 + +#define mmNIC0_QM1_HBW_RD_RATE_LIM_CFG_1 0xCE2C94 + +#define mmNIC0_QM1_LBW_WR_RATE_LIM_CFG_0 0xCE2C98 + +#define mmNIC0_QM1_LBW_WR_RATE_LIM_CFG_1 0xCE2C9C + +#define mmNIC0_QM1_HBW_RD_RATE_LIM_CFG_0 0xCE2CA0 + +#define mmNIC0_QM1_GLBL_AXCACHE 0xCE2CA4 + +#define mmNIC0_QM1_IND_GW_APB_CFG 0xCE2CB0 + +#define mmNIC0_QM1_IND_GW_APB_WDATA 0xCE2CB4 + +#define mmNIC0_QM1_IND_GW_APB_RDATA 0xCE2CB8 + +#define mmNIC0_QM1_IND_GW_APB_STATUS 0xCE2CBC + +#define mmNIC0_QM1_GLBL_ERR_ADDR_LO 0xCE2CD0 + +#define mmNIC0_QM1_GLBL_ERR_ADDR_HI 0xCE2CD4 + +#define mmNIC0_QM1_GLBL_ERR_WDATA 0xCE2CD8 + +#define mmNIC0_QM1_GLBL_MEM_INIT_BUSY 0xCE2D00 + +#endif /* ASIC_REG_NIC0_QM1_REGS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/nic1_qm0_regs.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic1_qm0_regs.h new file mode 100644 index 000000000000..0d1caf057ad0 --- /dev/null +++ b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic1_qm0_regs.h @@ -0,0 +1,834 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright 2016-2018 HabanaLabs, Ltd. + * All Rights Reserved. + * + */ + +/************************************ + ** This is an auto-generated file ** + ** DO NOT EDIT BELOW ** + ************************************/ + +#ifndef ASIC_REG_NIC1_QM0_REGS_H_ +#define ASIC_REG_NIC1_QM0_REGS_H_ + +/* + ***************************************** + * NIC1_QM0 (Prototype: QMAN) + ***************************************** + */ + +#define mmNIC1_QM0_GLBL_CFG0 0xD20000 + +#define mmNIC1_QM0_GLBL_CFG1 0xD20004 + +#define mmNIC1_QM0_GLBL_PROT 0xD20008 + +#define mmNIC1_QM0_GLBL_ERR_CFG 0xD2000C + +#define mmNIC1_QM0_GLBL_SECURE_PROPS_0 0xD20010 + +#define mmNIC1_QM0_GLBL_SECURE_PROPS_1 0xD20014 + +#define mmNIC1_QM0_GLBL_SECURE_PROPS_2 0xD20018 + +#define mmNIC1_QM0_GLBL_SECURE_PROPS_3 0xD2001C + +#define mmNIC1_QM0_GLBL_SECURE_PROPS_4 0xD20020 + +#define mmNIC1_QM0_GLBL_NON_SECURE_PROPS_0 0xD20024 + +#define mmNIC1_QM0_GLBL_NON_SECURE_PROPS_1 0xD20028 + +#define mmNIC1_QM0_GLBL_NON_SECURE_PROPS_2 0xD2002C + +#define mmNIC1_QM0_GLBL_NON_SECURE_PROPS_3 0xD20030 + +#define mmNIC1_QM0_GLBL_NON_SECURE_PROPS_4 0xD20034 + +#define mmNIC1_QM0_GLBL_STS0 0xD20038 + +#define mmNIC1_QM0_GLBL_STS1_0 0xD20040 + +#define mmNIC1_QM0_GLBL_STS1_1 0xD20044 + +#define mmNIC1_QM0_GLBL_STS1_2 0xD20048 + +#define mmNIC1_QM0_GLBL_STS1_3 0xD2004C + +#define mmNIC1_QM0_GLBL_STS1_4 0xD20050 + +#define mmNIC1_QM0_GLBL_MSG_EN_0 0xD20054 + +#define mmNIC1_QM0_GLBL_MSG_EN_1 0xD20058 + +#define mmNIC1_QM0_GLBL_MSG_EN_2 0xD2005C + +#define mmNIC1_QM0_GLBL_MSG_EN_3 0xD20060 + +#define mmNIC1_QM0_GLBL_MSG_EN_4 0xD20068 + +#define mmNIC1_QM0_PQ_BASE_LO_0 0xD20070 + +#define mmNIC1_QM0_PQ_BASE_LO_1 0xD20074 + +#define mmNIC1_QM0_PQ_BASE_LO_2 0xD20078 + +#define mmNIC1_QM0_PQ_BASE_LO_3 0xD2007C + +#define mmNIC1_QM0_PQ_BASE_HI_0 0xD20080 + +#define mmNIC1_QM0_PQ_BASE_HI_1 0xD20084 + +#define mmNIC1_QM0_PQ_BASE_HI_2 0xD20088 + +#define mmNIC1_QM0_PQ_BASE_HI_3 0xD2008C + +#define mmNIC1_QM0_PQ_SIZE_0 0xD20090 + +#define mmNIC1_QM0_PQ_SIZE_1 0xD20094 + +#define mmNIC1_QM0_PQ_SIZE_2 0xD20098 + +#define mmNIC1_QM0_PQ_SIZE_3 0xD2009C + +#define mmNIC1_QM0_PQ_PI_0 0xD200A0 + +#define mmNIC1_QM0_PQ_PI_1 0xD200A4 + +#define mmNIC1_QM0_PQ_PI_2 0xD200A8 + +#define mmNIC1_QM0_PQ_PI_3 0xD200AC + +#define mmNIC1_QM0_PQ_CI_0 0xD200B0 + +#define mmNIC1_QM0_PQ_CI_1 0xD200B4 + +#define mmNIC1_QM0_PQ_CI_2 0xD200B8 + +#define mmNIC1_QM0_PQ_CI_3 0xD200BC + +#define mmNIC1_QM0_PQ_CFG0_0 0xD200C0 + +#define mmNIC1_QM0_PQ_CFG0_1 0xD200C4 + +#define mmNIC1_QM0_PQ_CFG0_2 0xD200C8 + +#define mmNIC1_QM0_PQ_CFG0_3 0xD200CC + +#define mmNIC1_QM0_PQ_CFG1_0 0xD200D0 + +#define mmNIC1_QM0_PQ_CFG1_1 0xD200D4 + +#define mmNIC1_QM0_PQ_CFG1_2 0xD200D8 + +#define mmNIC1_QM0_PQ_CFG1_3 0xD200DC + +#define mmNIC1_QM0_PQ_ARUSER_31_11_0 0xD200E0 + +#define mmNIC1_QM0_PQ_ARUSER_31_11_1 0xD200E4 + +#define mmNIC1_QM0_PQ_ARUSER_31_11_2 0xD200E8 + +#define mmNIC1_QM0_PQ_ARUSER_31_11_3 0xD200EC + +#define mmNIC1_QM0_PQ_STS0_0 0xD200F0 + +#define mmNIC1_QM0_PQ_STS0_1 0xD200F4 + +#define mmNIC1_QM0_PQ_STS0_2 0xD200F8 + +#define mmNIC1_QM0_PQ_STS0_3 0xD200FC + +#define mmNIC1_QM0_PQ_STS1_0 0xD20100 + +#define mmNIC1_QM0_PQ_STS1_1 0xD20104 + +#define mmNIC1_QM0_PQ_STS1_2 0xD20108 + +#define mmNIC1_QM0_PQ_STS1_3 0xD2010C + +#define mmNIC1_QM0_CQ_CFG0_0 0xD20110 + +#define mmNIC1_QM0_CQ_CFG0_1 0xD20114 + +#define mmNIC1_QM0_CQ_CFG0_2 0xD20118 + +#define mmNIC1_QM0_CQ_CFG0_3 0xD2011C + +#define mmNIC1_QM0_CQ_CFG0_4 0xD20120 + +#define mmNIC1_QM0_CQ_CFG1_0 0xD20124 + +#define mmNIC1_QM0_CQ_CFG1_1 0xD20128 + +#define mmNIC1_QM0_CQ_CFG1_2 0xD2012C + +#define mmNIC1_QM0_CQ_CFG1_3 0xD20130 + +#define mmNIC1_QM0_CQ_CFG1_4 0xD20134 + +#define mmNIC1_QM0_CQ_ARUSER_31_11_0 0xD20138 + +#define mmNIC1_QM0_CQ_ARUSER_31_11_1 0xD2013C + +#define mmNIC1_QM0_CQ_ARUSER_31_11_2 0xD20140 + +#define mmNIC1_QM0_CQ_ARUSER_31_11_3 0xD20144 + +#define mmNIC1_QM0_CQ_ARUSER_31_11_4 0xD20148 + +#define mmNIC1_QM0_CQ_STS0_0 0xD2014C + +#define mmNIC1_QM0_CQ_STS0_1 0xD20150 + +#define mmNIC1_QM0_CQ_STS0_2 0xD20154 + +#define mmNIC1_QM0_CQ_STS0_3 0xD20158 + +#define mmNIC1_QM0_CQ_STS0_4 0xD2015C + +#define mmNIC1_QM0_CQ_STS1_0 0xD20160 + +#define mmNIC1_QM0_CQ_STS1_1 0xD20164 + +#define mmNIC1_QM0_CQ_STS1_2 0xD20168 + +#define mmNIC1_QM0_CQ_STS1_3 0xD2016C + +#define mmNIC1_QM0_CQ_STS1_4 0xD20170 + +#define mmNIC1_QM0_CQ_PTR_LO_0 0xD20174 + +#define mmNIC1_QM0_CQ_PTR_HI_0 0xD20178 + +#define mmNIC1_QM0_CQ_TSIZE_0 0xD2017C + +#define mmNIC1_QM0_CQ_CTL_0 0xD20180 + +#define mmNIC1_QM0_CQ_PTR_LO_1 0xD20184 + +#define mmNIC1_QM0_CQ_PTR_HI_1 0xD20188 + +#define mmNIC1_QM0_CQ_TSIZE_1 0xD2018C + +#define mmNIC1_QM0_CQ_CTL_1 0xD20190 + +#define mmNIC1_QM0_CQ_PTR_LO_2 0xD20194 + +#define mmNIC1_QM0_CQ_PTR_HI_2 0xD20198 + +#define mmNIC1_QM0_CQ_TSIZE_2 0xD2019C + +#define mmNIC1_QM0_CQ_CTL_2 0xD201A0 + +#define mmNIC1_QM0_CQ_PTR_LO_3 0xD201A4 + +#define mmNIC1_QM0_CQ_PTR_HI_3 0xD201A8 + +#define mmNIC1_QM0_CQ_TSIZE_3 0xD201AC + +#define mmNIC1_QM0_CQ_CTL_3 0xD201B0 + +#define mmNIC1_QM0_CQ_PTR_LO_4 0xD201B4 + +#define mmNIC1_QM0_CQ_PTR_HI_4 0xD201B8 + +#define mmNIC1_QM0_CQ_TSIZE_4 0xD201BC + +#define mmNIC1_QM0_CQ_CTL_4 0xD201C0 + +#define mmNIC1_QM0_CQ_PTR_LO_STS_0 0xD201C4 + +#define mmNIC1_QM0_CQ_PTR_LO_STS_1 0xD201C8 + +#define mmNIC1_QM0_CQ_PTR_LO_STS_2 0xD201CC + +#define mmNIC1_QM0_CQ_PTR_LO_STS_3 0xD201D0 + +#define mmNIC1_QM0_CQ_PTR_LO_STS_4 0xD201D4 + +#define mmNIC1_QM0_CQ_PTR_HI_STS_0 0xD201D8 + +#define mmNIC1_QM0_CQ_PTR_HI_STS_1 0xD201DC + +#define mmNIC1_QM0_CQ_PTR_HI_STS_2 0xD201E0 + +#define mmNIC1_QM0_CQ_PTR_HI_STS_3 0xD201E4 + +#define mmNIC1_QM0_CQ_PTR_HI_STS_4 0xD201E8 + +#define mmNIC1_QM0_CQ_TSIZE_STS_0 0xD201EC + +#define mmNIC1_QM0_CQ_TSIZE_STS_1 0xD201F0 + +#define mmNIC1_QM0_CQ_TSIZE_STS_2 0xD201F4 + +#define mmNIC1_QM0_CQ_TSIZE_STS_3 0xD201F8 + +#define mmNIC1_QM0_CQ_TSIZE_STS_4 0xD201FC + +#define mmNIC1_QM0_CQ_CTL_STS_0 0xD20200 + +#define mmNIC1_QM0_CQ_CTL_STS_1 0xD20204 + +#define mmNIC1_QM0_CQ_CTL_STS_2 0xD20208 + +#define mmNIC1_QM0_CQ_CTL_STS_3 0xD2020C + +#define mmNIC1_QM0_CQ_CTL_STS_4 0xD20210 + +#define mmNIC1_QM0_CQ_IFIFO_CNT_0 0xD20214 + +#define mmNIC1_QM0_CQ_IFIFO_CNT_1 0xD20218 + +#define mmNIC1_QM0_CQ_IFIFO_CNT_2 0xD2021C + +#define mmNIC1_QM0_CQ_IFIFO_CNT_3 0xD20220 + +#define mmNIC1_QM0_CQ_IFIFO_CNT_4 0xD20224 + +#define mmNIC1_QM0_CP_MSG_BASE0_ADDR_LO_0 0xD20228 + +#define mmNIC1_QM0_CP_MSG_BASE0_ADDR_LO_1 0xD2022C + +#define mmNIC1_QM0_CP_MSG_BASE0_ADDR_LO_2 0xD20230 + +#define mmNIC1_QM0_CP_MSG_BASE0_ADDR_LO_3 0xD20234 + +#define mmNIC1_QM0_CP_MSG_BASE0_ADDR_LO_4 0xD20238 + +#define mmNIC1_QM0_CP_MSG_BASE0_ADDR_HI_0 0xD2023C + +#define mmNIC1_QM0_CP_MSG_BASE0_ADDR_HI_1 0xD20240 + +#define mmNIC1_QM0_CP_MSG_BASE0_ADDR_HI_2 0xD20244 + +#define mmNIC1_QM0_CP_MSG_BASE0_ADDR_HI_3 0xD20248 + +#define mmNIC1_QM0_CP_MSG_BASE0_ADDR_HI_4 0xD2024C + +#define mmNIC1_QM0_CP_MSG_BASE1_ADDR_LO_0 0xD20250 + +#define mmNIC1_QM0_CP_MSG_BASE1_ADDR_LO_1 0xD20254 + +#define mmNIC1_QM0_CP_MSG_BASE1_ADDR_LO_2 0xD20258 + +#define mmNIC1_QM0_CP_MSG_BASE1_ADDR_LO_3 0xD2025C + +#define mmNIC1_QM0_CP_MSG_BASE1_ADDR_LO_4 0xD20260 + +#define mmNIC1_QM0_CP_MSG_BASE1_ADDR_HI_0 0xD20264 + +#define mmNIC1_QM0_CP_MSG_BASE1_ADDR_HI_1 0xD20268 + +#define mmNIC1_QM0_CP_MSG_BASE1_ADDR_HI_2 0xD2026C + +#define mmNIC1_QM0_CP_MSG_BASE1_ADDR_HI_3 0xD20270 + +#define mmNIC1_QM0_CP_MSG_BASE1_ADDR_HI_4 0xD20274 + +#define mmNIC1_QM0_CP_MSG_BASE2_ADDR_LO_0 0xD20278 + +#define mmNIC1_QM0_CP_MSG_BASE2_ADDR_LO_1 0xD2027C + +#define mmNIC1_QM0_CP_MSG_BASE2_ADDR_LO_2 0xD20280 + +#define mmNIC1_QM0_CP_MSG_BASE2_ADDR_LO_3 0xD20284 + +#define mmNIC1_QM0_CP_MSG_BASE2_ADDR_LO_4 0xD20288 + +#define mmNIC1_QM0_CP_MSG_BASE2_ADDR_HI_0 0xD2028C + +#define mmNIC1_QM0_CP_MSG_BASE2_ADDR_HI_1 0xD20290 + +#define mmNIC1_QM0_CP_MSG_BASE2_ADDR_HI_2 0xD20294 + +#define mmNIC1_QM0_CP_MSG_BASE2_ADDR_HI_3 0xD20298 + +#define mmNIC1_QM0_CP_MSG_BASE2_ADDR_HI_4 0xD2029C + +#define mmNIC1_QM0_CP_MSG_BASE3_ADDR_LO_0 0xD202A0 + +#define mmNIC1_QM0_CP_MSG_BASE3_ADDR_LO_1 0xD202A4 + +#define mmNIC1_QM0_CP_MSG_BASE3_ADDR_LO_2 0xD202A8 + +#define mmNIC1_QM0_CP_MSG_BASE3_ADDR_LO_3 0xD202AC + +#define mmNIC1_QM0_CP_MSG_BASE3_ADDR_LO_4 0xD202B0 + +#define mmNIC1_QM0_CP_MSG_BASE3_ADDR_HI_0 0xD202B4 + +#define mmNIC1_QM0_CP_MSG_BASE3_ADDR_HI_1 0xD202B8 + +#define mmNIC1_QM0_CP_MSG_BASE3_ADDR_HI_2 0xD202BC + +#define mmNIC1_QM0_CP_MSG_BASE3_ADDR_HI_3 0xD202C0 + +#define mmNIC1_QM0_CP_MSG_BASE3_ADDR_HI_4 0xD202C4 + +#define mmNIC1_QM0_CP_LDMA_TSIZE_OFFSET_0 0xD202C8 + +#define mmNIC1_QM0_CP_LDMA_TSIZE_OFFSET_1 0xD202CC + +#define mmNIC1_QM0_CP_LDMA_TSIZE_OFFSET_2 0xD202D0 + +#define mmNIC1_QM0_CP_LDMA_TSIZE_OFFSET_3 0xD202D4 + +#define mmNIC1_QM0_CP_LDMA_TSIZE_OFFSET_4 0xD202D8 + +#define mmNIC1_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_0 0xD202E0 + +#define mmNIC1_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_1 0xD202E4 + +#define mmNIC1_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_2 0xD202E8 + +#define mmNIC1_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_3 0xD202EC + +#define mmNIC1_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_4 0xD202F0 + +#define mmNIC1_QM0_CP_LDMA_DST_BASE_LO_OFFSET_0 0xD202F4 + +#define mmNIC1_QM0_CP_LDMA_DST_BASE_LO_OFFSET_1 0xD202F8 + +#define mmNIC1_QM0_CP_LDMA_DST_BASE_LO_OFFSET_2 0xD202FC + +#define mmNIC1_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 0xD20300 + +#define mmNIC1_QM0_CP_LDMA_DST_BASE_LO_OFFSET_4 0xD20304 + +#define mmNIC1_QM0_CP_FENCE0_RDATA_0 0xD20308 + +#define mmNIC1_QM0_CP_FENCE0_RDATA_1 0xD2030C + +#define mmNIC1_QM0_CP_FENCE0_RDATA_2 0xD20310 + +#define mmNIC1_QM0_CP_FENCE0_RDATA_3 0xD20314 + +#define mmNIC1_QM0_CP_FENCE0_RDATA_4 0xD20318 + +#define mmNIC1_QM0_CP_FENCE1_RDATA_0 0xD2031C + +#define mmNIC1_QM0_CP_FENCE1_RDATA_1 0xD20320 + +#define mmNIC1_QM0_CP_FENCE1_RDATA_2 0xD20324 + +#define mmNIC1_QM0_CP_FENCE1_RDATA_3 0xD20328 + +#define mmNIC1_QM0_CP_FENCE1_RDATA_4 0xD2032C + +#define mmNIC1_QM0_CP_FENCE2_RDATA_0 0xD20330 + +#define mmNIC1_QM0_CP_FENCE2_RDATA_1 0xD20334 + +#define mmNIC1_QM0_CP_FENCE2_RDATA_2 0xD20338 + +#define mmNIC1_QM0_CP_FENCE2_RDATA_3 0xD2033C + +#define mmNIC1_QM0_CP_FENCE2_RDATA_4 0xD20340 + +#define mmNIC1_QM0_CP_FENCE3_RDATA_0 0xD20344 + +#define mmNIC1_QM0_CP_FENCE3_RDATA_1 0xD20348 + +#define mmNIC1_QM0_CP_FENCE3_RDATA_2 0xD2034C + +#define mmNIC1_QM0_CP_FENCE3_RDATA_3 0xD20350 + +#define mmNIC1_QM0_CP_FENCE3_RDATA_4 0xD20354 + +#define mmNIC1_QM0_CP_FENCE0_CNT_0 0xD20358 + +#define mmNIC1_QM0_CP_FENCE0_CNT_1 0xD2035C + +#define mmNIC1_QM0_CP_FENCE0_CNT_2 0xD20360 + +#define mmNIC1_QM0_CP_FENCE0_CNT_3 0xD20364 + +#define mmNIC1_QM0_CP_FENCE0_CNT_4 0xD20368 + +#define mmNIC1_QM0_CP_FENCE1_CNT_0 0xD2036C + +#define mmNIC1_QM0_CP_FENCE1_CNT_1 0xD20370 + +#define mmNIC1_QM0_CP_FENCE1_CNT_2 0xD20374 + +#define mmNIC1_QM0_CP_FENCE1_CNT_3 0xD20378 + +#define mmNIC1_QM0_CP_FENCE1_CNT_4 0xD2037C + +#define mmNIC1_QM0_CP_FENCE2_CNT_0 0xD20380 + +#define mmNIC1_QM0_CP_FENCE2_CNT_1 0xD20384 + +#define mmNIC1_QM0_CP_FENCE2_CNT_2 0xD20388 + +#define mmNIC1_QM0_CP_FENCE2_CNT_3 0xD2038C + +#define mmNIC1_QM0_CP_FENCE2_CNT_4 0xD20390 + +#define mmNIC1_QM0_CP_FENCE3_CNT_0 0xD20394 + +#define mmNIC1_QM0_CP_FENCE3_CNT_1 0xD20398 + +#define mmNIC1_QM0_CP_FENCE3_CNT_2 0xD2039C + +#define mmNIC1_QM0_CP_FENCE3_CNT_3 0xD203A0 + +#define mmNIC1_QM0_CP_FENCE3_CNT_4 0xD203A4 + +#define mmNIC1_QM0_CP_STS_0 0xD203A8 + +#define mmNIC1_QM0_CP_STS_1 0xD203AC + +#define mmNIC1_QM0_CP_STS_2 0xD203B0 + +#define mmNIC1_QM0_CP_STS_3 0xD203B4 + +#define mmNIC1_QM0_CP_STS_4 0xD203B8 + +#define mmNIC1_QM0_CP_CURRENT_INST_LO_0 0xD203BC + +#define mmNIC1_QM0_CP_CURRENT_INST_LO_1 0xD203C0 + +#define mmNIC1_QM0_CP_CURRENT_INST_LO_2 0xD203C4 + +#define mmNIC1_QM0_CP_CURRENT_INST_LO_3 0xD203C8 + +#define mmNIC1_QM0_CP_CURRENT_INST_LO_4 0xD203CC + +#define mmNIC1_QM0_CP_CURRENT_INST_HI_0 0xD203D0 + +#define mmNIC1_QM0_CP_CURRENT_INST_HI_1 0xD203D4 + +#define mmNIC1_QM0_CP_CURRENT_INST_HI_2 0xD203D8 + +#define mmNIC1_QM0_CP_CURRENT_INST_HI_3 0xD203DC + +#define mmNIC1_QM0_CP_CURRENT_INST_HI_4 0xD203E0 + +#define mmNIC1_QM0_CP_BARRIER_CFG_0 0xD203F4 + +#define mmNIC1_QM0_CP_BARRIER_CFG_1 0xD203F8 + +#define mmNIC1_QM0_CP_BARRIER_CFG_2 0xD203FC + +#define mmNIC1_QM0_CP_BARRIER_CFG_3 0xD20400 + +#define mmNIC1_QM0_CP_BARRIER_CFG_4 0xD20404 + +#define mmNIC1_QM0_CP_DBG_0_0 0xD20408 + +#define mmNIC1_QM0_CP_DBG_0_1 0xD2040C + +#define mmNIC1_QM0_CP_DBG_0_2 0xD20410 + +#define mmNIC1_QM0_CP_DBG_0_3 0xD20414 + +#define mmNIC1_QM0_CP_DBG_0_4 0xD20418 + +#define mmNIC1_QM0_CP_ARUSER_31_11_0 0xD2041C + +#define mmNIC1_QM0_CP_ARUSER_31_11_1 0xD20420 + +#define mmNIC1_QM0_CP_ARUSER_31_11_2 0xD20424 + +#define mmNIC1_QM0_CP_ARUSER_31_11_3 0xD20428 + +#define mmNIC1_QM0_CP_ARUSER_31_11_4 0xD2042C + +#define mmNIC1_QM0_CP_AWUSER_31_11_0 0xD20430 + +#define mmNIC1_QM0_CP_AWUSER_31_11_1 0xD20434 + +#define mmNIC1_QM0_CP_AWUSER_31_11_2 0xD20438 + +#define mmNIC1_QM0_CP_AWUSER_31_11_3 0xD2043C + +#define mmNIC1_QM0_CP_AWUSER_31_11_4 0xD20440 + +#define mmNIC1_QM0_ARB_CFG_0 0xD20A00 + +#define mmNIC1_QM0_ARB_CHOISE_Q_PUSH 0xD20A04 + +#define mmNIC1_QM0_ARB_WRR_WEIGHT_0 0xD20A08 + +#define mmNIC1_QM0_ARB_WRR_WEIGHT_1 0xD20A0C + +#define mmNIC1_QM0_ARB_WRR_WEIGHT_2 0xD20A10 + +#define mmNIC1_QM0_ARB_WRR_WEIGHT_3 0xD20A14 + +#define mmNIC1_QM0_ARB_CFG_1 0xD20A18 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_0 0xD20A20 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_1 0xD20A24 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_2 0xD20A28 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_3 0xD20A2C + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_4 0xD20A30 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_5 0xD20A34 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_6 0xD20A38 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_7 0xD20A3C + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_8 0xD20A40 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_9 0xD20A44 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_10 0xD20A48 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_11 0xD20A4C + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_12 0xD20A50 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_13 0xD20A54 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_14 0xD20A58 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_15 0xD20A5C + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_16 0xD20A60 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_17 0xD20A64 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_18 0xD20A68 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_19 0xD20A6C + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_20 0xD20A70 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_21 0xD20A74 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_22 0xD20A78 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_23 0xD20A7C + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_24 0xD20A80 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_25 0xD20A84 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_26 0xD20A88 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_27 0xD20A8C + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_28 0xD20A90 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_29 0xD20A94 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_30 0xD20A98 + +#define mmNIC1_QM0_ARB_MST_AVAIL_CRED_31 0xD20A9C + +#define mmNIC1_QM0_ARB_MST_CRED_INC 0xD20AA0 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_0 0xD20AA4 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_1 0xD20AA8 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_2 0xD20AAC + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_3 0xD20AB0 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_4 0xD20AB4 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_5 0xD20AB8 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_6 0xD20ABC + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_7 0xD20AC0 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_8 0xD20AC4 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_9 0xD20AC8 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_10 0xD20ACC + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_11 0xD20AD0 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_12 0xD20AD4 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_13 0xD20AD8 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_14 0xD20ADC + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_15 0xD20AE0 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_16 0xD20AE4 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_17 0xD20AE8 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_18 0xD20AEC + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_19 0xD20AF0 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_20 0xD20AF4 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_21 0xD20AF8 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_22 0xD20AFC + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_23 0xD20B00 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_24 0xD20B04 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_25 0xD20B08 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_26 0xD20B0C + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_27 0xD20B10 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_28 0xD20B14 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_29 0xD20B18 + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_30 0xD20B1C + +#define mmNIC1_QM0_ARB_MST_CHOISE_PUSH_OFST_31 0xD20B20 + +#define mmNIC1_QM0_ARB_SLV_MASTER_INC_CRED_OFST 0xD20B28 + +#define mmNIC1_QM0_ARB_MST_SLAVE_EN 0xD20B2C + +#define mmNIC1_QM0_ARB_MST_QUIET_PER 0xD20B34 + +#define mmNIC1_QM0_ARB_SLV_CHOISE_WDT 0xD20B38 + +#define mmNIC1_QM0_ARB_SLV_ID 0xD20B3C + +#define mmNIC1_QM0_ARB_MSG_MAX_INFLIGHT 0xD20B44 + +#define mmNIC1_QM0_ARB_MSG_AWUSER_31_11 0xD20B48 + +#define mmNIC1_QM0_ARB_MSG_AWUSER_SEC_PROP 0xD20B4C + +#define mmNIC1_QM0_ARB_MSG_AWUSER_NON_SEC_PROP 0xD20B50 + +#define mmNIC1_QM0_ARB_BASE_LO 0xD20B54 + +#define mmNIC1_QM0_ARB_BASE_HI 0xD20B58 + +#define mmNIC1_QM0_ARB_STATE_STS 0xD20B80 + +#define mmNIC1_QM0_ARB_CHOISE_FULLNESS_STS 0xD20B84 + +#define mmNIC1_QM0_ARB_MSG_STS 0xD20B88 + +#define mmNIC1_QM0_ARB_SLV_CHOISE_Q_HEAD 0xD20B8C + +#define mmNIC1_QM0_ARB_ERR_CAUSE 0xD20B9C + +#define mmNIC1_QM0_ARB_ERR_MSG_EN 0xD20BA0 + +#define mmNIC1_QM0_ARB_ERR_STS_DRP 0xD20BA8 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_0 0xD20BB0 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_1 0xD20BB4 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_2 0xD20BB8 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_3 0xD20BBC + +#define mmNIC1_QM0_ARB_MST_CRED_STS_4 0xD20BC0 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_5 0xD20BC4 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_6 0xD20BC8 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_7 0xD20BCC + +#define mmNIC1_QM0_ARB_MST_CRED_STS_8 0xD20BD0 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_9 0xD20BD4 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_10 0xD20BD8 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_11 0xD20BDC + +#define mmNIC1_QM0_ARB_MST_CRED_STS_12 0xD20BE0 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_13 0xD20BE4 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_14 0xD20BE8 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_15 0xD20BEC + +#define mmNIC1_QM0_ARB_MST_CRED_STS_16 0xD20BF0 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_17 0xD20BF4 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_18 0xD20BF8 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_19 0xD20BFC + +#define mmNIC1_QM0_ARB_MST_CRED_STS_20 0xD20C00 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_21 0xD20C04 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_22 0xD20C08 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_23 0xD20C0C + +#define mmNIC1_QM0_ARB_MST_CRED_STS_24 0xD20C10 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_25 0xD20C14 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_26 0xD20C18 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_27 0xD20C1C + +#define mmNIC1_QM0_ARB_MST_CRED_STS_28 0xD20C20 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_29 0xD20C24 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_30 0xD20C28 + +#define mmNIC1_QM0_ARB_MST_CRED_STS_31 0xD20C2C + +#define mmNIC1_QM0_CGM_CFG 0xD20C70 + +#define mmNIC1_QM0_CGM_STS 0xD20C74 + +#define mmNIC1_QM0_CGM_CFG1 0xD20C78 + +#define mmNIC1_QM0_LOCAL_RANGE_BASE 0xD20C80 + +#define mmNIC1_QM0_LOCAL_RANGE_SIZE 0xD20C84 + +#define mmNIC1_QM0_CSMR_STRICT_PRIO_CFG 0xD20C90 + +#define mmNIC1_QM0_HBW_RD_RATE_LIM_CFG_1 0xD20C94 + +#define mmNIC1_QM0_LBW_WR_RATE_LIM_CFG_0 0xD20C98 + +#define mmNIC1_QM0_LBW_WR_RATE_LIM_CFG_1 0xD20C9C + +#define mmNIC1_QM0_HBW_RD_RATE_LIM_CFG_0 0xD20CA0 + +#define mmNIC1_QM0_GLBL_AXCACHE 0xD20CA4 + +#define mmNIC1_QM0_IND_GW_APB_CFG 0xD20CB0 + +#define mmNIC1_QM0_IND_GW_APB_WDATA 0xD20CB4 + +#define mmNIC1_QM0_IND_GW_APB_RDATA 0xD20CB8 + +#define mmNIC1_QM0_IND_GW_APB_STATUS 0xD20CBC + +#define mmNIC1_QM0_GLBL_ERR_ADDR_LO 0xD20CD0 + +#define mmNIC1_QM0_GLBL_ERR_ADDR_HI 0xD20CD4 + +#define mmNIC1_QM0_GLBL_ERR_WDATA 0xD20CD8 + +#define mmNIC1_QM0_GLBL_MEM_INIT_BUSY 0xD20D00 + +#endif /* ASIC_REG_NIC1_QM0_REGS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/nic1_qm1_regs.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic1_qm1_regs.h new file mode 100644 index 000000000000..1b115ee6d6f0 --- /dev/null +++ b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic1_qm1_regs.h @@ -0,0 +1,834 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright 2016-2018 HabanaLabs, Ltd. + * All Rights Reserved. + * + */ + +/************************************ + ** This is an auto-generated file ** + ** DO NOT EDIT BELOW ** + ************************************/ + +#ifndef ASIC_REG_NIC1_QM1_REGS_H_ +#define ASIC_REG_NIC1_QM1_REGS_H_ + +/* + ***************************************** + * NIC1_QM1 (Prototype: QMAN) + ***************************************** + */ + +#define mmNIC1_QM1_GLBL_CFG0 0xD22000 + +#define mmNIC1_QM1_GLBL_CFG1 0xD22004 + +#define mmNIC1_QM1_GLBL_PROT 0xD22008 + +#define mmNIC1_QM1_GLBL_ERR_CFG 0xD2200C + +#define mmNIC1_QM1_GLBL_SECURE_PROPS_0 0xD22010 + +#define mmNIC1_QM1_GLBL_SECURE_PROPS_1 0xD22014 + +#define mmNIC1_QM1_GLBL_SECURE_PROPS_2 0xD22018 + +#define mmNIC1_QM1_GLBL_SECURE_PROPS_3 0xD2201C + +#define mmNIC1_QM1_GLBL_SECURE_PROPS_4 0xD22020 + +#define mmNIC1_QM1_GLBL_NON_SECURE_PROPS_0 0xD22024 + +#define mmNIC1_QM1_GLBL_NON_SECURE_PROPS_1 0xD22028 + +#define mmNIC1_QM1_GLBL_NON_SECURE_PROPS_2 0xD2202C + +#define mmNIC1_QM1_GLBL_NON_SECURE_PROPS_3 0xD22030 + +#define mmNIC1_QM1_GLBL_NON_SECURE_PROPS_4 0xD22034 + +#define mmNIC1_QM1_GLBL_STS0 0xD22038 + +#define mmNIC1_QM1_GLBL_STS1_0 0xD22040 + +#define mmNIC1_QM1_GLBL_STS1_1 0xD22044 + +#define mmNIC1_QM1_GLBL_STS1_2 0xD22048 + +#define mmNIC1_QM1_GLBL_STS1_3 0xD2204C + +#define mmNIC1_QM1_GLBL_STS1_4 0xD22050 + +#define mmNIC1_QM1_GLBL_MSG_EN_0 0xD22054 + +#define mmNIC1_QM1_GLBL_MSG_EN_1 0xD22058 + +#define mmNIC1_QM1_GLBL_MSG_EN_2 0xD2205C + +#define mmNIC1_QM1_GLBL_MSG_EN_3 0xD22060 + +#define mmNIC1_QM1_GLBL_MSG_EN_4 0xD22068 + +#define mmNIC1_QM1_PQ_BASE_LO_0 0xD22070 + +#define mmNIC1_QM1_PQ_BASE_LO_1 0xD22074 + +#define mmNIC1_QM1_PQ_BASE_LO_2 0xD22078 + +#define mmNIC1_QM1_PQ_BASE_LO_3 0xD2207C + +#define mmNIC1_QM1_PQ_BASE_HI_0 0xD22080 + +#define mmNIC1_QM1_PQ_BASE_HI_1 0xD22084 + +#define mmNIC1_QM1_PQ_BASE_HI_2 0xD22088 + +#define mmNIC1_QM1_PQ_BASE_HI_3 0xD2208C + +#define mmNIC1_QM1_PQ_SIZE_0 0xD22090 + +#define mmNIC1_QM1_PQ_SIZE_1 0xD22094 + +#define mmNIC1_QM1_PQ_SIZE_2 0xD22098 + +#define mmNIC1_QM1_PQ_SIZE_3 0xD2209C + +#define mmNIC1_QM1_PQ_PI_0 0xD220A0 + +#define mmNIC1_QM1_PQ_PI_1 0xD220A4 + +#define mmNIC1_QM1_PQ_PI_2 0xD220A8 + +#define mmNIC1_QM1_PQ_PI_3 0xD220AC + +#define mmNIC1_QM1_PQ_CI_0 0xD220B0 + +#define mmNIC1_QM1_PQ_CI_1 0xD220B4 + +#define mmNIC1_QM1_PQ_CI_2 0xD220B8 + +#define mmNIC1_QM1_PQ_CI_3 0xD220BC + +#define mmNIC1_QM1_PQ_CFG0_0 0xD220C0 + +#define mmNIC1_QM1_PQ_CFG0_1 0xD220C4 + +#define mmNIC1_QM1_PQ_CFG0_2 0xD220C8 + +#define mmNIC1_QM1_PQ_CFG0_3 0xD220CC + +#define mmNIC1_QM1_PQ_CFG1_0 0xD220D0 + +#define mmNIC1_QM1_PQ_CFG1_1 0xD220D4 + +#define mmNIC1_QM1_PQ_CFG1_2 0xD220D8 + +#define mmNIC1_QM1_PQ_CFG1_3 0xD220DC + +#define mmNIC1_QM1_PQ_ARUSER_31_11_0 0xD220E0 + +#define mmNIC1_QM1_PQ_ARUSER_31_11_1 0xD220E4 + +#define mmNIC1_QM1_PQ_ARUSER_31_11_2 0xD220E8 + +#define mmNIC1_QM1_PQ_ARUSER_31_11_3 0xD220EC + +#define mmNIC1_QM1_PQ_STS0_0 0xD220F0 + +#define mmNIC1_QM1_PQ_STS0_1 0xD220F4 + +#define mmNIC1_QM1_PQ_STS0_2 0xD220F8 + +#define mmNIC1_QM1_PQ_STS0_3 0xD220FC + +#define mmNIC1_QM1_PQ_STS1_0 0xD22100 + +#define mmNIC1_QM1_PQ_STS1_1 0xD22104 + +#define mmNIC1_QM1_PQ_STS1_2 0xD22108 + +#define mmNIC1_QM1_PQ_STS1_3 0xD2210C + +#define mmNIC1_QM1_CQ_CFG0_0 0xD22110 + +#define mmNIC1_QM1_CQ_CFG0_1 0xD22114 + +#define mmNIC1_QM1_CQ_CFG0_2 0xD22118 + +#define mmNIC1_QM1_CQ_CFG0_3 0xD2211C + +#define mmNIC1_QM1_CQ_CFG0_4 0xD22120 + +#define mmNIC1_QM1_CQ_CFG1_0 0xD22124 + +#define mmNIC1_QM1_CQ_CFG1_1 0xD22128 + +#define mmNIC1_QM1_CQ_CFG1_2 0xD2212C + +#define mmNIC1_QM1_CQ_CFG1_3 0xD22130 + +#define mmNIC1_QM1_CQ_CFG1_4 0xD22134 + +#define mmNIC1_QM1_CQ_ARUSER_31_11_0 0xD22138 + +#define mmNIC1_QM1_CQ_ARUSER_31_11_1 0xD2213C + +#define mmNIC1_QM1_CQ_ARUSER_31_11_2 0xD22140 + +#define mmNIC1_QM1_CQ_ARUSER_31_11_3 0xD22144 + +#define mmNIC1_QM1_CQ_ARUSER_31_11_4 0xD22148 + +#define mmNIC1_QM1_CQ_STS0_0 0xD2214C + +#define mmNIC1_QM1_CQ_STS0_1 0xD22150 + +#define mmNIC1_QM1_CQ_STS0_2 0xD22154 + +#define mmNIC1_QM1_CQ_STS0_3 0xD22158 + +#define mmNIC1_QM1_CQ_STS0_4 0xD2215C + +#define mmNIC1_QM1_CQ_STS1_0 0xD22160 + +#define mmNIC1_QM1_CQ_STS1_1 0xD22164 + +#define mmNIC1_QM1_CQ_STS1_2 0xD22168 + +#define mmNIC1_QM1_CQ_STS1_3 0xD2216C + +#define mmNIC1_QM1_CQ_STS1_4 0xD22170 + +#define mmNIC1_QM1_CQ_PTR_LO_0 0xD22174 + +#define mmNIC1_QM1_CQ_PTR_HI_0 0xD22178 + +#define mmNIC1_QM1_CQ_TSIZE_0 0xD2217C + +#define mmNIC1_QM1_CQ_CTL_0 0xD22180 + +#define mmNIC1_QM1_CQ_PTR_LO_1 0xD22184 + +#define mmNIC1_QM1_CQ_PTR_HI_1 0xD22188 + +#define mmNIC1_QM1_CQ_TSIZE_1 0xD2218C + +#define mmNIC1_QM1_CQ_CTL_1 0xD22190 + +#define mmNIC1_QM1_CQ_PTR_LO_2 0xD22194 + +#define mmNIC1_QM1_CQ_PTR_HI_2 0xD22198 + +#define mmNIC1_QM1_CQ_TSIZE_2 0xD2219C + +#define mmNIC1_QM1_CQ_CTL_2 0xD221A0 + +#define mmNIC1_QM1_CQ_PTR_LO_3 0xD221A4 + +#define mmNIC1_QM1_CQ_PTR_HI_3 0xD221A8 + +#define mmNIC1_QM1_CQ_TSIZE_3 0xD221AC + +#define mmNIC1_QM1_CQ_CTL_3 0xD221B0 + +#define mmNIC1_QM1_CQ_PTR_LO_4 0xD221B4 + +#define mmNIC1_QM1_CQ_PTR_HI_4 0xD221B8 + +#define mmNIC1_QM1_CQ_TSIZE_4 0xD221BC + +#define mmNIC1_QM1_CQ_CTL_4 0xD221C0 + +#define mmNIC1_QM1_CQ_PTR_LO_STS_0 0xD221C4 + +#define mmNIC1_QM1_CQ_PTR_LO_STS_1 0xD221C8 + +#define mmNIC1_QM1_CQ_PTR_LO_STS_2 0xD221CC + +#define mmNIC1_QM1_CQ_PTR_LO_STS_3 0xD221D0 + +#define mmNIC1_QM1_CQ_PTR_LO_STS_4 0xD221D4 + +#define mmNIC1_QM1_CQ_PTR_HI_STS_0 0xD221D8 + +#define mmNIC1_QM1_CQ_PTR_HI_STS_1 0xD221DC + +#define mmNIC1_QM1_CQ_PTR_HI_STS_2 0xD221E0 + +#define mmNIC1_QM1_CQ_PTR_HI_STS_3 0xD221E4 + +#define mmNIC1_QM1_CQ_PTR_HI_STS_4 0xD221E8 + +#define mmNIC1_QM1_CQ_TSIZE_STS_0 0xD221EC + +#define mmNIC1_QM1_CQ_TSIZE_STS_1 0xD221F0 + +#define mmNIC1_QM1_CQ_TSIZE_STS_2 0xD221F4 + +#define mmNIC1_QM1_CQ_TSIZE_STS_3 0xD221F8 + +#define mmNIC1_QM1_CQ_TSIZE_STS_4 0xD221FC + +#define mmNIC1_QM1_CQ_CTL_STS_0 0xD22200 + +#define mmNIC1_QM1_CQ_CTL_STS_1 0xD22204 + +#define mmNIC1_QM1_CQ_CTL_STS_2 0xD22208 + +#define mmNIC1_QM1_CQ_CTL_STS_3 0xD2220C + +#define mmNIC1_QM1_CQ_CTL_STS_4 0xD22210 + +#define mmNIC1_QM1_CQ_IFIFO_CNT_0 0xD22214 + +#define mmNIC1_QM1_CQ_IFIFO_CNT_1 0xD22218 + +#define mmNIC1_QM1_CQ_IFIFO_CNT_2 0xD2221C + +#define mmNIC1_QM1_CQ_IFIFO_CNT_3 0xD22220 + +#define mmNIC1_QM1_CQ_IFIFO_CNT_4 0xD22224 + +#define mmNIC1_QM1_CP_MSG_BASE0_ADDR_LO_0 0xD22228 + +#define mmNIC1_QM1_CP_MSG_BASE0_ADDR_LO_1 0xD2222C + +#define mmNIC1_QM1_CP_MSG_BASE0_ADDR_LO_2 0xD22230 + +#define mmNIC1_QM1_CP_MSG_BASE0_ADDR_LO_3 0xD22234 + +#define mmNIC1_QM1_CP_MSG_BASE0_ADDR_LO_4 0xD22238 + +#define mmNIC1_QM1_CP_MSG_BASE0_ADDR_HI_0 0xD2223C + +#define mmNIC1_QM1_CP_MSG_BASE0_ADDR_HI_1 0xD22240 + +#define mmNIC1_QM1_CP_MSG_BASE0_ADDR_HI_2 0xD22244 + +#define mmNIC1_QM1_CP_MSG_BASE0_ADDR_HI_3 0xD22248 + +#define mmNIC1_QM1_CP_MSG_BASE0_ADDR_HI_4 0xD2224C + +#define mmNIC1_QM1_CP_MSG_BASE1_ADDR_LO_0 0xD22250 + +#define mmNIC1_QM1_CP_MSG_BASE1_ADDR_LO_1 0xD22254 + +#define mmNIC1_QM1_CP_MSG_BASE1_ADDR_LO_2 0xD22258 + +#define mmNIC1_QM1_CP_MSG_BASE1_ADDR_LO_3 0xD2225C + +#define mmNIC1_QM1_CP_MSG_BASE1_ADDR_LO_4 0xD22260 + +#define mmNIC1_QM1_CP_MSG_BASE1_ADDR_HI_0 0xD22264 + +#define mmNIC1_QM1_CP_MSG_BASE1_ADDR_HI_1 0xD22268 + +#define mmNIC1_QM1_CP_MSG_BASE1_ADDR_HI_2 0xD2226C + +#define mmNIC1_QM1_CP_MSG_BASE1_ADDR_HI_3 0xD22270 + +#define mmNIC1_QM1_CP_MSG_BASE1_ADDR_HI_4 0xD22274 + +#define mmNIC1_QM1_CP_MSG_BASE2_ADDR_LO_0 0xD22278 + +#define mmNIC1_QM1_CP_MSG_BASE2_ADDR_LO_1 0xD2227C + +#define mmNIC1_QM1_CP_MSG_BASE2_ADDR_LO_2 0xD22280 + +#define mmNIC1_QM1_CP_MSG_BASE2_ADDR_LO_3 0xD22284 + +#define mmNIC1_QM1_CP_MSG_BASE2_ADDR_LO_4 0xD22288 + +#define mmNIC1_QM1_CP_MSG_BASE2_ADDR_HI_0 0xD2228C + +#define mmNIC1_QM1_CP_MSG_BASE2_ADDR_HI_1 0xD22290 + +#define mmNIC1_QM1_CP_MSG_BASE2_ADDR_HI_2 0xD22294 + +#define mmNIC1_QM1_CP_MSG_BASE2_ADDR_HI_3 0xD22298 + +#define mmNIC1_QM1_CP_MSG_BASE2_ADDR_HI_4 0xD2229C + +#define mmNIC1_QM1_CP_MSG_BASE3_ADDR_LO_0 0xD222A0 + +#define mmNIC1_QM1_CP_MSG_BASE3_ADDR_LO_1 0xD222A4 + +#define mmNIC1_QM1_CP_MSG_BASE3_ADDR_LO_2 0xD222A8 + +#define mmNIC1_QM1_CP_MSG_BASE3_ADDR_LO_3 0xD222AC + +#define mmNIC1_QM1_CP_MSG_BASE3_ADDR_LO_4 0xD222B0 + +#define mmNIC1_QM1_CP_MSG_BASE3_ADDR_HI_0 0xD222B4 + +#define mmNIC1_QM1_CP_MSG_BASE3_ADDR_HI_1 0xD222B8 + +#define mmNIC1_QM1_CP_MSG_BASE3_ADDR_HI_2 0xD222BC + +#define mmNIC1_QM1_CP_MSG_BASE3_ADDR_HI_3 0xD222C0 + +#define mmNIC1_QM1_CP_MSG_BASE3_ADDR_HI_4 0xD222C4 + +#define mmNIC1_QM1_CP_LDMA_TSIZE_OFFSET_0 0xD222C8 + +#define mmNIC1_QM1_CP_LDMA_TSIZE_OFFSET_1 0xD222CC + +#define mmNIC1_QM1_CP_LDMA_TSIZE_OFFSET_2 0xD222D0 + +#define mmNIC1_QM1_CP_LDMA_TSIZE_OFFSET_3 0xD222D4 + +#define mmNIC1_QM1_CP_LDMA_TSIZE_OFFSET_4 0xD222D8 + +#define mmNIC1_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_0 0xD222E0 + +#define mmNIC1_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_1 0xD222E4 + +#define mmNIC1_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_2 0xD222E8 + +#define mmNIC1_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_3 0xD222EC + +#define mmNIC1_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_4 0xD222F0 + +#define mmNIC1_QM1_CP_LDMA_DST_BASE_LO_OFFSET_0 0xD222F4 + +#define mmNIC1_QM1_CP_LDMA_DST_BASE_LO_OFFSET_1 0xD222F8 + +#define mmNIC1_QM1_CP_LDMA_DST_BASE_LO_OFFSET_2 0xD222FC + +#define mmNIC1_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 0xD22300 + +#define mmNIC1_QM1_CP_LDMA_DST_BASE_LO_OFFSET_4 0xD22304 + +#define mmNIC1_QM1_CP_FENCE0_RDATA_0 0xD22308 + +#define mmNIC1_QM1_CP_FENCE0_RDATA_1 0xD2230C + +#define mmNIC1_QM1_CP_FENCE0_RDATA_2 0xD22310 + +#define mmNIC1_QM1_CP_FENCE0_RDATA_3 0xD22314 + +#define mmNIC1_QM1_CP_FENCE0_RDATA_4 0xD22318 + +#define mmNIC1_QM1_CP_FENCE1_RDATA_0 0xD2231C + +#define mmNIC1_QM1_CP_FENCE1_RDATA_1 0xD22320 + +#define mmNIC1_QM1_CP_FENCE1_RDATA_2 0xD22324 + +#define mmNIC1_QM1_CP_FENCE1_RDATA_3 0xD22328 + +#define mmNIC1_QM1_CP_FENCE1_RDATA_4 0xD2232C + +#define mmNIC1_QM1_CP_FENCE2_RDATA_0 0xD22330 + +#define mmNIC1_QM1_CP_FENCE2_RDATA_1 0xD22334 + +#define mmNIC1_QM1_CP_FENCE2_RDATA_2 0xD22338 + +#define mmNIC1_QM1_CP_FENCE2_RDATA_3 0xD2233C + +#define mmNIC1_QM1_CP_FENCE2_RDATA_4 0xD22340 + +#define mmNIC1_QM1_CP_FENCE3_RDATA_0 0xD22344 + +#define mmNIC1_QM1_CP_FENCE3_RDATA_1 0xD22348 + +#define mmNIC1_QM1_CP_FENCE3_RDATA_2 0xD2234C + +#define mmNIC1_QM1_CP_FENCE3_RDATA_3 0xD22350 + +#define mmNIC1_QM1_CP_FENCE3_RDATA_4 0xD22354 + +#define mmNIC1_QM1_CP_FENCE0_CNT_0 0xD22358 + +#define mmNIC1_QM1_CP_FENCE0_CNT_1 0xD2235C + +#define mmNIC1_QM1_CP_FENCE0_CNT_2 0xD22360 + +#define mmNIC1_QM1_CP_FENCE0_CNT_3 0xD22364 + +#define mmNIC1_QM1_CP_FENCE0_CNT_4 0xD22368 + +#define mmNIC1_QM1_CP_FENCE1_CNT_0 0xD2236C + +#define mmNIC1_QM1_CP_FENCE1_CNT_1 0xD22370 + +#define mmNIC1_QM1_CP_FENCE1_CNT_2 0xD22374 + +#define mmNIC1_QM1_CP_FENCE1_CNT_3 0xD22378 + +#define mmNIC1_QM1_CP_FENCE1_CNT_4 0xD2237C + +#define mmNIC1_QM1_CP_FENCE2_CNT_0 0xD22380 + +#define mmNIC1_QM1_CP_FENCE2_CNT_1 0xD22384 + +#define mmNIC1_QM1_CP_FENCE2_CNT_2 0xD22388 + +#define mmNIC1_QM1_CP_FENCE2_CNT_3 0xD2238C + +#define mmNIC1_QM1_CP_FENCE2_CNT_4 0xD22390 + +#define mmNIC1_QM1_CP_FENCE3_CNT_0 0xD22394 + +#define mmNIC1_QM1_CP_FENCE3_CNT_1 0xD22398 + +#define mmNIC1_QM1_CP_FENCE3_CNT_2 0xD2239C + +#define mmNIC1_QM1_CP_FENCE3_CNT_3 0xD223A0 + +#define mmNIC1_QM1_CP_FENCE3_CNT_4 0xD223A4 + +#define mmNIC1_QM1_CP_STS_0 0xD223A8 + +#define mmNIC1_QM1_CP_STS_1 0xD223AC + +#define mmNIC1_QM1_CP_STS_2 0xD223B0 + +#define mmNIC1_QM1_CP_STS_3 0xD223B4 + +#define mmNIC1_QM1_CP_STS_4 0xD223B8 + +#define mmNIC1_QM1_CP_CURRENT_INST_LO_0 0xD223BC + +#define mmNIC1_QM1_CP_CURRENT_INST_LO_1 0xD223C0 + +#define mmNIC1_QM1_CP_CURRENT_INST_LO_2 0xD223C4 + +#define mmNIC1_QM1_CP_CURRENT_INST_LO_3 0xD223C8 + +#define mmNIC1_QM1_CP_CURRENT_INST_LO_4 0xD223CC + +#define mmNIC1_QM1_CP_CURRENT_INST_HI_0 0xD223D0 + +#define mmNIC1_QM1_CP_CURRENT_INST_HI_1 0xD223D4 + +#define mmNIC1_QM1_CP_CURRENT_INST_HI_2 0xD223D8 + +#define mmNIC1_QM1_CP_CURRENT_INST_HI_3 0xD223DC + +#define mmNIC1_QM1_CP_CURRENT_INST_HI_4 0xD223E0 + +#define mmNIC1_QM1_CP_BARRIER_CFG_0 0xD223F4 + +#define mmNIC1_QM1_CP_BARRIER_CFG_1 0xD223F8 + +#define mmNIC1_QM1_CP_BARRIER_CFG_2 0xD223FC + +#define mmNIC1_QM1_CP_BARRIER_CFG_3 0xD22400 + +#define mmNIC1_QM1_CP_BARRIER_CFG_4 0xD22404 + +#define mmNIC1_QM1_CP_DBG_0_0 0xD22408 + +#define mmNIC1_QM1_CP_DBG_0_1 0xD2240C + +#define mmNIC1_QM1_CP_DBG_0_2 0xD22410 + +#define mmNIC1_QM1_CP_DBG_0_3 0xD22414 + +#define mmNIC1_QM1_CP_DBG_0_4 0xD22418 + +#define mmNIC1_QM1_CP_ARUSER_31_11_0 0xD2241C + +#define mmNIC1_QM1_CP_ARUSER_31_11_1 0xD22420 + +#define mmNIC1_QM1_CP_ARUSER_31_11_2 0xD22424 + +#define mmNIC1_QM1_CP_ARUSER_31_11_3 0xD22428 + +#define mmNIC1_QM1_CP_ARUSER_31_11_4 0xD2242C + +#define mmNIC1_QM1_CP_AWUSER_31_11_0 0xD22430 + +#define mmNIC1_QM1_CP_AWUSER_31_11_1 0xD22434 + +#define mmNIC1_QM1_CP_AWUSER_31_11_2 0xD22438 + +#define mmNIC1_QM1_CP_AWUSER_31_11_3 0xD2243C + +#define mmNIC1_QM1_CP_AWUSER_31_11_4 0xD22440 + +#define mmNIC1_QM1_ARB_CFG_0 0xD22A00 + +#define mmNIC1_QM1_ARB_CHOISE_Q_PUSH 0xD22A04 + +#define mmNIC1_QM1_ARB_WRR_WEIGHT_0 0xD22A08 + +#define mmNIC1_QM1_ARB_WRR_WEIGHT_1 0xD22A0C + +#define mmNIC1_QM1_ARB_WRR_WEIGHT_2 0xD22A10 + +#define mmNIC1_QM1_ARB_WRR_WEIGHT_3 0xD22A14 + +#define mmNIC1_QM1_ARB_CFG_1 0xD22A18 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_0 0xD22A20 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_1 0xD22A24 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_2 0xD22A28 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_3 0xD22A2C + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_4 0xD22A30 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_5 0xD22A34 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_6 0xD22A38 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_7 0xD22A3C + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_8 0xD22A40 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_9 0xD22A44 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_10 0xD22A48 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_11 0xD22A4C + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_12 0xD22A50 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_13 0xD22A54 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_14 0xD22A58 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_15 0xD22A5C + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_16 0xD22A60 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_17 0xD22A64 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_18 0xD22A68 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_19 0xD22A6C + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_20 0xD22A70 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_21 0xD22A74 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_22 0xD22A78 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_23 0xD22A7C + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_24 0xD22A80 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_25 0xD22A84 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_26 0xD22A88 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_27 0xD22A8C + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_28 0xD22A90 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_29 0xD22A94 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_30 0xD22A98 + +#define mmNIC1_QM1_ARB_MST_AVAIL_CRED_31 0xD22A9C + +#define mmNIC1_QM1_ARB_MST_CRED_INC 0xD22AA0 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_0 0xD22AA4 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_1 0xD22AA8 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_2 0xD22AAC + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_3 0xD22AB0 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_4 0xD22AB4 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_5 0xD22AB8 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_6 0xD22ABC + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_7 0xD22AC0 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_8 0xD22AC4 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_9 0xD22AC8 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_10 0xD22ACC + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_11 0xD22AD0 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_12 0xD22AD4 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_13 0xD22AD8 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_14 0xD22ADC + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_15 0xD22AE0 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_16 0xD22AE4 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_17 0xD22AE8 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_18 0xD22AEC + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_19 0xD22AF0 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_20 0xD22AF4 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_21 0xD22AF8 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_22 0xD22AFC + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_23 0xD22B00 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_24 0xD22B04 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_25 0xD22B08 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_26 0xD22B0C + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_27 0xD22B10 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_28 0xD22B14 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_29 0xD22B18 + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_30 0xD22B1C + +#define mmNIC1_QM1_ARB_MST_CHOISE_PUSH_OFST_31 0xD22B20 + +#define mmNIC1_QM1_ARB_SLV_MASTER_INC_CRED_OFST 0xD22B28 + +#define mmNIC1_QM1_ARB_MST_SLAVE_EN 0xD22B2C + +#define mmNIC1_QM1_ARB_MST_QUIET_PER 0xD22B34 + +#define mmNIC1_QM1_ARB_SLV_CHOISE_WDT 0xD22B38 + +#define mmNIC1_QM1_ARB_SLV_ID 0xD22B3C + +#define mmNIC1_QM1_ARB_MSG_MAX_INFLIGHT 0xD22B44 + +#define mmNIC1_QM1_ARB_MSG_AWUSER_31_11 0xD22B48 + +#define mmNIC1_QM1_ARB_MSG_AWUSER_SEC_PROP 0xD22B4C + +#define mmNIC1_QM1_ARB_MSG_AWUSER_NON_SEC_PROP 0xD22B50 + +#define mmNIC1_QM1_ARB_BASE_LO 0xD22B54 + +#define mmNIC1_QM1_ARB_BASE_HI 0xD22B58 + +#define mmNIC1_QM1_ARB_STATE_STS 0xD22B80 + +#define mmNIC1_QM1_ARB_CHOISE_FULLNESS_STS 0xD22B84 + +#define mmNIC1_QM1_ARB_MSG_STS 0xD22B88 + +#define mmNIC1_QM1_ARB_SLV_CHOISE_Q_HEAD 0xD22B8C + +#define mmNIC1_QM1_ARB_ERR_CAUSE 0xD22B9C + +#define mmNIC1_QM1_ARB_ERR_MSG_EN 0xD22BA0 + +#define mmNIC1_QM1_ARB_ERR_STS_DRP 0xD22BA8 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_0 0xD22BB0 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_1 0xD22BB4 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_2 0xD22BB8 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_3 0xD22BBC + +#define mmNIC1_QM1_ARB_MST_CRED_STS_4 0xD22BC0 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_5 0xD22BC4 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_6 0xD22BC8 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_7 0xD22BCC + +#define mmNIC1_QM1_ARB_MST_CRED_STS_8 0xD22BD0 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_9 0xD22BD4 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_10 0xD22BD8 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_11 0xD22BDC + +#define mmNIC1_QM1_ARB_MST_CRED_STS_12 0xD22BE0 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_13 0xD22BE4 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_14 0xD22BE8 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_15 0xD22BEC + +#define mmNIC1_QM1_ARB_MST_CRED_STS_16 0xD22BF0 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_17 0xD22BF4 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_18 0xD22BF8 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_19 0xD22BFC + +#define mmNIC1_QM1_ARB_MST_CRED_STS_20 0xD22C00 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_21 0xD22C04 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_22 0xD22C08 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_23 0xD22C0C + +#define mmNIC1_QM1_ARB_MST_CRED_STS_24 0xD22C10 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_25 0xD22C14 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_26 0xD22C18 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_27 0xD22C1C + +#define mmNIC1_QM1_ARB_MST_CRED_STS_28 0xD22C20 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_29 0xD22C24 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_30 0xD22C28 + +#define mmNIC1_QM1_ARB_MST_CRED_STS_31 0xD22C2C + +#define mmNIC1_QM1_CGM_CFG 0xD22C70 + +#define mmNIC1_QM1_CGM_STS 0xD22C74 + +#define mmNIC1_QM1_CGM_CFG1 0xD22C78 + +#define mmNIC1_QM1_LOCAL_RANGE_BASE 0xD22C80 + +#define mmNIC1_QM1_LOCAL_RANGE_SIZE 0xD22C84 + +#define mmNIC1_QM1_CSMR_STRICT_PRIO_CFG 0xD22C90 + +#define mmNIC1_QM1_HBW_RD_RATE_LIM_CFG_1 0xD22C94 + +#define mmNIC1_QM1_LBW_WR_RATE_LIM_CFG_0 0xD22C98 + +#define mmNIC1_QM1_LBW_WR_RATE_LIM_CFG_1 0xD22C9C + +#define mmNIC1_QM1_HBW_RD_RATE_LIM_CFG_0 0xD22CA0 + +#define mmNIC1_QM1_GLBL_AXCACHE 0xD22CA4 + +#define mmNIC1_QM1_IND_GW_APB_CFG 0xD22CB0 + +#define mmNIC1_QM1_IND_GW_APB_WDATA 0xD22CB4 + +#define mmNIC1_QM1_IND_GW_APB_RDATA 0xD22CB8 + +#define mmNIC1_QM1_IND_GW_APB_STATUS 0xD22CBC + +#define mmNIC1_QM1_GLBL_ERR_ADDR_LO 0xD22CD0 + +#define mmNIC1_QM1_GLBL_ERR_ADDR_HI 0xD22CD4 + +#define mmNIC1_QM1_GLBL_ERR_WDATA 0xD22CD8 + +#define mmNIC1_QM1_GLBL_MEM_INIT_BUSY 0xD22D00 + +#endif /* ASIC_REG_NIC1_QM1_REGS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/nic2_qm0_regs.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic2_qm0_regs.h new file mode 100644 index 000000000000..a89116a4586f --- /dev/null +++ b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic2_qm0_regs.h @@ -0,0 +1,834 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright 2016-2018 HabanaLabs, Ltd. + * All Rights Reserved. + * + */ + +/************************************ + ** This is an auto-generated file ** + ** DO NOT EDIT BELOW ** + ************************************/ + +#ifndef ASIC_REG_NIC2_QM0_REGS_H_ +#define ASIC_REG_NIC2_QM0_REGS_H_ + +/* + ***************************************** + * NIC2_QM0 (Prototype: QMAN) + ***************************************** + */ + +#define mmNIC2_QM0_GLBL_CFG0 0xD60000 + +#define mmNIC2_QM0_GLBL_CFG1 0xD60004 + +#define mmNIC2_QM0_GLBL_PROT 0xD60008 + +#define mmNIC2_QM0_GLBL_ERR_CFG 0xD6000C + +#define mmNIC2_QM0_GLBL_SECURE_PROPS_0 0xD60010 + +#define mmNIC2_QM0_GLBL_SECURE_PROPS_1 0xD60014 + +#define mmNIC2_QM0_GLBL_SECURE_PROPS_2 0xD60018 + +#define mmNIC2_QM0_GLBL_SECURE_PROPS_3 0xD6001C + +#define mmNIC2_QM0_GLBL_SECURE_PROPS_4 0xD60020 + +#define mmNIC2_QM0_GLBL_NON_SECURE_PROPS_0 0xD60024 + +#define mmNIC2_QM0_GLBL_NON_SECURE_PROPS_1 0xD60028 + +#define mmNIC2_QM0_GLBL_NON_SECURE_PROPS_2 0xD6002C + +#define mmNIC2_QM0_GLBL_NON_SECURE_PROPS_3 0xD60030 + +#define mmNIC2_QM0_GLBL_NON_SECURE_PROPS_4 0xD60034 + +#define mmNIC2_QM0_GLBL_STS0 0xD60038 + +#define mmNIC2_QM0_GLBL_STS1_0 0xD60040 + +#define mmNIC2_QM0_GLBL_STS1_1 0xD60044 + +#define mmNIC2_QM0_GLBL_STS1_2 0xD60048 + +#define mmNIC2_QM0_GLBL_STS1_3 0xD6004C + +#define mmNIC2_QM0_GLBL_STS1_4 0xD60050 + +#define mmNIC2_QM0_GLBL_MSG_EN_0 0xD60054 + +#define mmNIC2_QM0_GLBL_MSG_EN_1 0xD60058 + +#define mmNIC2_QM0_GLBL_MSG_EN_2 0xD6005C + +#define mmNIC2_QM0_GLBL_MSG_EN_3 0xD60060 + +#define mmNIC2_QM0_GLBL_MSG_EN_4 0xD60068 + +#define mmNIC2_QM0_PQ_BASE_LO_0 0xD60070 + +#define mmNIC2_QM0_PQ_BASE_LO_1 0xD60074 + +#define mmNIC2_QM0_PQ_BASE_LO_2 0xD60078 + +#define mmNIC2_QM0_PQ_BASE_LO_3 0xD6007C + +#define mmNIC2_QM0_PQ_BASE_HI_0 0xD60080 + +#define mmNIC2_QM0_PQ_BASE_HI_1 0xD60084 + +#define mmNIC2_QM0_PQ_BASE_HI_2 0xD60088 + +#define mmNIC2_QM0_PQ_BASE_HI_3 0xD6008C + +#define mmNIC2_QM0_PQ_SIZE_0 0xD60090 + +#define mmNIC2_QM0_PQ_SIZE_1 0xD60094 + +#define mmNIC2_QM0_PQ_SIZE_2 0xD60098 + +#define mmNIC2_QM0_PQ_SIZE_3 0xD6009C + +#define mmNIC2_QM0_PQ_PI_0 0xD600A0 + +#define mmNIC2_QM0_PQ_PI_1 0xD600A4 + +#define mmNIC2_QM0_PQ_PI_2 0xD600A8 + +#define mmNIC2_QM0_PQ_PI_3 0xD600AC + +#define mmNIC2_QM0_PQ_CI_0 0xD600B0 + +#define mmNIC2_QM0_PQ_CI_1 0xD600B4 + +#define mmNIC2_QM0_PQ_CI_2 0xD600B8 + +#define mmNIC2_QM0_PQ_CI_3 0xD600BC + +#define mmNIC2_QM0_PQ_CFG0_0 0xD600C0 + +#define mmNIC2_QM0_PQ_CFG0_1 0xD600C4 + +#define mmNIC2_QM0_PQ_CFG0_2 0xD600C8 + +#define mmNIC2_QM0_PQ_CFG0_3 0xD600CC + +#define mmNIC2_QM0_PQ_CFG1_0 0xD600D0 + +#define mmNIC2_QM0_PQ_CFG1_1 0xD600D4 + +#define mmNIC2_QM0_PQ_CFG1_2 0xD600D8 + +#define mmNIC2_QM0_PQ_CFG1_3 0xD600DC + +#define mmNIC2_QM0_PQ_ARUSER_31_11_0 0xD600E0 + +#define mmNIC2_QM0_PQ_ARUSER_31_11_1 0xD600E4 + +#define mmNIC2_QM0_PQ_ARUSER_31_11_2 0xD600E8 + +#define mmNIC2_QM0_PQ_ARUSER_31_11_3 0xD600EC + +#define mmNIC2_QM0_PQ_STS0_0 0xD600F0 + +#define mmNIC2_QM0_PQ_STS0_1 0xD600F4 + +#define mmNIC2_QM0_PQ_STS0_2 0xD600F8 + +#define mmNIC2_QM0_PQ_STS0_3 0xD600FC + +#define mmNIC2_QM0_PQ_STS1_0 0xD60100 + +#define mmNIC2_QM0_PQ_STS1_1 0xD60104 + +#define mmNIC2_QM0_PQ_STS1_2 0xD60108 + +#define mmNIC2_QM0_PQ_STS1_3 0xD6010C + +#define mmNIC2_QM0_CQ_CFG0_0 0xD60110 + +#define mmNIC2_QM0_CQ_CFG0_1 0xD60114 + +#define mmNIC2_QM0_CQ_CFG0_2 0xD60118 + +#define mmNIC2_QM0_CQ_CFG0_3 0xD6011C + +#define mmNIC2_QM0_CQ_CFG0_4 0xD60120 + +#define mmNIC2_QM0_CQ_CFG1_0 0xD60124 + +#define mmNIC2_QM0_CQ_CFG1_1 0xD60128 + +#define mmNIC2_QM0_CQ_CFG1_2 0xD6012C + +#define mmNIC2_QM0_CQ_CFG1_3 0xD60130 + +#define mmNIC2_QM0_CQ_CFG1_4 0xD60134 + +#define mmNIC2_QM0_CQ_ARUSER_31_11_0 0xD60138 + +#define mmNIC2_QM0_CQ_ARUSER_31_11_1 0xD6013C + +#define mmNIC2_QM0_CQ_ARUSER_31_11_2 0xD60140 + +#define mmNIC2_QM0_CQ_ARUSER_31_11_3 0xD60144 + +#define mmNIC2_QM0_CQ_ARUSER_31_11_4 0xD60148 + +#define mmNIC2_QM0_CQ_STS0_0 0xD6014C + +#define mmNIC2_QM0_CQ_STS0_1 0xD60150 + +#define mmNIC2_QM0_CQ_STS0_2 0xD60154 + +#define mmNIC2_QM0_CQ_STS0_3 0xD60158 + +#define mmNIC2_QM0_CQ_STS0_4 0xD6015C + +#define mmNIC2_QM0_CQ_STS1_0 0xD60160 + +#define mmNIC2_QM0_CQ_STS1_1 0xD60164 + +#define mmNIC2_QM0_CQ_STS1_2 0xD60168 + +#define mmNIC2_QM0_CQ_STS1_3 0xD6016C + +#define mmNIC2_QM0_CQ_STS1_4 0xD60170 + +#define mmNIC2_QM0_CQ_PTR_LO_0 0xD60174 + +#define mmNIC2_QM0_CQ_PTR_HI_0 0xD60178 + +#define mmNIC2_QM0_CQ_TSIZE_0 0xD6017C + +#define mmNIC2_QM0_CQ_CTL_0 0xD60180 + +#define mmNIC2_QM0_CQ_PTR_LO_1 0xD60184 + +#define mmNIC2_QM0_CQ_PTR_HI_1 0xD60188 + +#define mmNIC2_QM0_CQ_TSIZE_1 0xD6018C + +#define mmNIC2_QM0_CQ_CTL_1 0xD60190 + +#define mmNIC2_QM0_CQ_PTR_LO_2 0xD60194 + +#define mmNIC2_QM0_CQ_PTR_HI_2 0xD60198 + +#define mmNIC2_QM0_CQ_TSIZE_2 0xD6019C + +#define mmNIC2_QM0_CQ_CTL_2 0xD601A0 + +#define mmNIC2_QM0_CQ_PTR_LO_3 0xD601A4 + +#define mmNIC2_QM0_CQ_PTR_HI_3 0xD601A8 + +#define mmNIC2_QM0_CQ_TSIZE_3 0xD601AC + +#define mmNIC2_QM0_CQ_CTL_3 0xD601B0 + +#define mmNIC2_QM0_CQ_PTR_LO_4 0xD601B4 + +#define mmNIC2_QM0_CQ_PTR_HI_4 0xD601B8 + +#define mmNIC2_QM0_CQ_TSIZE_4 0xD601BC + +#define mmNIC2_QM0_CQ_CTL_4 0xD601C0 + +#define mmNIC2_QM0_CQ_PTR_LO_STS_0 0xD601C4 + +#define mmNIC2_QM0_CQ_PTR_LO_STS_1 0xD601C8 + +#define mmNIC2_QM0_CQ_PTR_LO_STS_2 0xD601CC + +#define mmNIC2_QM0_CQ_PTR_LO_STS_3 0xD601D0 + +#define mmNIC2_QM0_CQ_PTR_LO_STS_4 0xD601D4 + +#define mmNIC2_QM0_CQ_PTR_HI_STS_0 0xD601D8 + +#define mmNIC2_QM0_CQ_PTR_HI_STS_1 0xD601DC + +#define mmNIC2_QM0_CQ_PTR_HI_STS_2 0xD601E0 + +#define mmNIC2_QM0_CQ_PTR_HI_STS_3 0xD601E4 + +#define mmNIC2_QM0_CQ_PTR_HI_STS_4 0xD601E8 + +#define mmNIC2_QM0_CQ_TSIZE_STS_0 0xD601EC + +#define mmNIC2_QM0_CQ_TSIZE_STS_1 0xD601F0 + +#define mmNIC2_QM0_CQ_TSIZE_STS_2 0xD601F4 + +#define mmNIC2_QM0_CQ_TSIZE_STS_3 0xD601F8 + +#define mmNIC2_QM0_CQ_TSIZE_STS_4 0xD601FC + +#define mmNIC2_QM0_CQ_CTL_STS_0 0xD60200 + +#define mmNIC2_QM0_CQ_CTL_STS_1 0xD60204 + +#define mmNIC2_QM0_CQ_CTL_STS_2 0xD60208 + +#define mmNIC2_QM0_CQ_CTL_STS_3 0xD6020C + +#define mmNIC2_QM0_CQ_CTL_STS_4 0xD60210 + +#define mmNIC2_QM0_CQ_IFIFO_CNT_0 0xD60214 + +#define mmNIC2_QM0_CQ_IFIFO_CNT_1 0xD60218 + +#define mmNIC2_QM0_CQ_IFIFO_CNT_2 0xD6021C + +#define mmNIC2_QM0_CQ_IFIFO_CNT_3 0xD60220 + +#define mmNIC2_QM0_CQ_IFIFO_CNT_4 0xD60224 + +#define mmNIC2_QM0_CP_MSG_BASE0_ADDR_LO_0 0xD60228 + +#define mmNIC2_QM0_CP_MSG_BASE0_ADDR_LO_1 0xD6022C + +#define mmNIC2_QM0_CP_MSG_BASE0_ADDR_LO_2 0xD60230 + +#define mmNIC2_QM0_CP_MSG_BASE0_ADDR_LO_3 0xD60234 + +#define mmNIC2_QM0_CP_MSG_BASE0_ADDR_LO_4 0xD60238 + +#define mmNIC2_QM0_CP_MSG_BASE0_ADDR_HI_0 0xD6023C + +#define mmNIC2_QM0_CP_MSG_BASE0_ADDR_HI_1 0xD60240 + +#define mmNIC2_QM0_CP_MSG_BASE0_ADDR_HI_2 0xD60244 + +#define mmNIC2_QM0_CP_MSG_BASE0_ADDR_HI_3 0xD60248 + +#define mmNIC2_QM0_CP_MSG_BASE0_ADDR_HI_4 0xD6024C + +#define mmNIC2_QM0_CP_MSG_BASE1_ADDR_LO_0 0xD60250 + +#define mmNIC2_QM0_CP_MSG_BASE1_ADDR_LO_1 0xD60254 + +#define mmNIC2_QM0_CP_MSG_BASE1_ADDR_LO_2 0xD60258 + +#define mmNIC2_QM0_CP_MSG_BASE1_ADDR_LO_3 0xD6025C + +#define mmNIC2_QM0_CP_MSG_BASE1_ADDR_LO_4 0xD60260 + +#define mmNIC2_QM0_CP_MSG_BASE1_ADDR_HI_0 0xD60264 + +#define mmNIC2_QM0_CP_MSG_BASE1_ADDR_HI_1 0xD60268 + +#define mmNIC2_QM0_CP_MSG_BASE1_ADDR_HI_2 0xD6026C + +#define mmNIC2_QM0_CP_MSG_BASE1_ADDR_HI_3 0xD60270 + +#define mmNIC2_QM0_CP_MSG_BASE1_ADDR_HI_4 0xD60274 + +#define mmNIC2_QM0_CP_MSG_BASE2_ADDR_LO_0 0xD60278 + +#define mmNIC2_QM0_CP_MSG_BASE2_ADDR_LO_1 0xD6027C + +#define mmNIC2_QM0_CP_MSG_BASE2_ADDR_LO_2 0xD60280 + +#define mmNIC2_QM0_CP_MSG_BASE2_ADDR_LO_3 0xD60284 + +#define mmNIC2_QM0_CP_MSG_BASE2_ADDR_LO_4 0xD60288 + +#define mmNIC2_QM0_CP_MSG_BASE2_ADDR_HI_0 0xD6028C + +#define mmNIC2_QM0_CP_MSG_BASE2_ADDR_HI_1 0xD60290 + +#define mmNIC2_QM0_CP_MSG_BASE2_ADDR_HI_2 0xD60294 + +#define mmNIC2_QM0_CP_MSG_BASE2_ADDR_HI_3 0xD60298 + +#define mmNIC2_QM0_CP_MSG_BASE2_ADDR_HI_4 0xD6029C + +#define mmNIC2_QM0_CP_MSG_BASE3_ADDR_LO_0 0xD602A0 + +#define mmNIC2_QM0_CP_MSG_BASE3_ADDR_LO_1 0xD602A4 + +#define mmNIC2_QM0_CP_MSG_BASE3_ADDR_LO_2 0xD602A8 + +#define mmNIC2_QM0_CP_MSG_BASE3_ADDR_LO_3 0xD602AC + +#define mmNIC2_QM0_CP_MSG_BASE3_ADDR_LO_4 0xD602B0 + +#define mmNIC2_QM0_CP_MSG_BASE3_ADDR_HI_0 0xD602B4 + +#define mmNIC2_QM0_CP_MSG_BASE3_ADDR_HI_1 0xD602B8 + +#define mmNIC2_QM0_CP_MSG_BASE3_ADDR_HI_2 0xD602BC + +#define mmNIC2_QM0_CP_MSG_BASE3_ADDR_HI_3 0xD602C0 + +#define mmNIC2_QM0_CP_MSG_BASE3_ADDR_HI_4 0xD602C4 + +#define mmNIC2_QM0_CP_LDMA_TSIZE_OFFSET_0 0xD602C8 + +#define mmNIC2_QM0_CP_LDMA_TSIZE_OFFSET_1 0xD602CC + +#define mmNIC2_QM0_CP_LDMA_TSIZE_OFFSET_2 0xD602D0 + +#define mmNIC2_QM0_CP_LDMA_TSIZE_OFFSET_3 0xD602D4 + +#define mmNIC2_QM0_CP_LDMA_TSIZE_OFFSET_4 0xD602D8 + +#define mmNIC2_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_0 0xD602E0 + +#define mmNIC2_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_1 0xD602E4 + +#define mmNIC2_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_2 0xD602E8 + +#define mmNIC2_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_3 0xD602EC + +#define mmNIC2_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_4 0xD602F0 + +#define mmNIC2_QM0_CP_LDMA_DST_BASE_LO_OFFSET_0 0xD602F4 + +#define mmNIC2_QM0_CP_LDMA_DST_BASE_LO_OFFSET_1 0xD602F8 + +#define mmNIC2_QM0_CP_LDMA_DST_BASE_LO_OFFSET_2 0xD602FC + +#define mmNIC2_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 0xD60300 + +#define mmNIC2_QM0_CP_LDMA_DST_BASE_LO_OFFSET_4 0xD60304 + +#define mmNIC2_QM0_CP_FENCE0_RDATA_0 0xD60308 + +#define mmNIC2_QM0_CP_FENCE0_RDATA_1 0xD6030C + +#define mmNIC2_QM0_CP_FENCE0_RDATA_2 0xD60310 + +#define mmNIC2_QM0_CP_FENCE0_RDATA_3 0xD60314 + +#define mmNIC2_QM0_CP_FENCE0_RDATA_4 0xD60318 + +#define mmNIC2_QM0_CP_FENCE1_RDATA_0 0xD6031C + +#define mmNIC2_QM0_CP_FENCE1_RDATA_1 0xD60320 + +#define mmNIC2_QM0_CP_FENCE1_RDATA_2 0xD60324 + +#define mmNIC2_QM0_CP_FENCE1_RDATA_3 0xD60328 + +#define mmNIC2_QM0_CP_FENCE1_RDATA_4 0xD6032C + +#define mmNIC2_QM0_CP_FENCE2_RDATA_0 0xD60330 + +#define mmNIC2_QM0_CP_FENCE2_RDATA_1 0xD60334 + +#define mmNIC2_QM0_CP_FENCE2_RDATA_2 0xD60338 + +#define mmNIC2_QM0_CP_FENCE2_RDATA_3 0xD6033C + +#define mmNIC2_QM0_CP_FENCE2_RDATA_4 0xD60340 + +#define mmNIC2_QM0_CP_FENCE3_RDATA_0 0xD60344 + +#define mmNIC2_QM0_CP_FENCE3_RDATA_1 0xD60348 + +#define mmNIC2_QM0_CP_FENCE3_RDATA_2 0xD6034C + +#define mmNIC2_QM0_CP_FENCE3_RDATA_3 0xD60350 + +#define mmNIC2_QM0_CP_FENCE3_RDATA_4 0xD60354 + +#define mmNIC2_QM0_CP_FENCE0_CNT_0 0xD60358 + +#define mmNIC2_QM0_CP_FENCE0_CNT_1 0xD6035C + +#define mmNIC2_QM0_CP_FENCE0_CNT_2 0xD60360 + +#define mmNIC2_QM0_CP_FENCE0_CNT_3 0xD60364 + +#define mmNIC2_QM0_CP_FENCE0_CNT_4 0xD60368 + +#define mmNIC2_QM0_CP_FENCE1_CNT_0 0xD6036C + +#define mmNIC2_QM0_CP_FENCE1_CNT_1 0xD60370 + +#define mmNIC2_QM0_CP_FENCE1_CNT_2 0xD60374 + +#define mmNIC2_QM0_CP_FENCE1_CNT_3 0xD60378 + +#define mmNIC2_QM0_CP_FENCE1_CNT_4 0xD6037C + +#define mmNIC2_QM0_CP_FENCE2_CNT_0 0xD60380 + +#define mmNIC2_QM0_CP_FENCE2_CNT_1 0xD60384 + +#define mmNIC2_QM0_CP_FENCE2_CNT_2 0xD60388 + +#define mmNIC2_QM0_CP_FENCE2_CNT_3 0xD6038C + +#define mmNIC2_QM0_CP_FENCE2_CNT_4 0xD60390 + +#define mmNIC2_QM0_CP_FENCE3_CNT_0 0xD60394 + +#define mmNIC2_QM0_CP_FENCE3_CNT_1 0xD60398 + +#define mmNIC2_QM0_CP_FENCE3_CNT_2 0xD6039C + +#define mmNIC2_QM0_CP_FENCE3_CNT_3 0xD603A0 + +#define mmNIC2_QM0_CP_FENCE3_CNT_4 0xD603A4 + +#define mmNIC2_QM0_CP_STS_0 0xD603A8 + +#define mmNIC2_QM0_CP_STS_1 0xD603AC + +#define mmNIC2_QM0_CP_STS_2 0xD603B0 + +#define mmNIC2_QM0_CP_STS_3 0xD603B4 + +#define mmNIC2_QM0_CP_STS_4 0xD603B8 + +#define mmNIC2_QM0_CP_CURRENT_INST_LO_0 0xD603BC + +#define mmNIC2_QM0_CP_CURRENT_INST_LO_1 0xD603C0 + +#define mmNIC2_QM0_CP_CURRENT_INST_LO_2 0xD603C4 + +#define mmNIC2_QM0_CP_CURRENT_INST_LO_3 0xD603C8 + +#define mmNIC2_QM0_CP_CURRENT_INST_LO_4 0xD603CC + +#define mmNIC2_QM0_CP_CURRENT_INST_HI_0 0xD603D0 + +#define mmNIC2_QM0_CP_CURRENT_INST_HI_1 0xD603D4 + +#define mmNIC2_QM0_CP_CURRENT_INST_HI_2 0xD603D8 + +#define mmNIC2_QM0_CP_CURRENT_INST_HI_3 0xD603DC + +#define mmNIC2_QM0_CP_CURRENT_INST_HI_4 0xD603E0 + +#define mmNIC2_QM0_CP_BARRIER_CFG_0 0xD603F4 + +#define mmNIC2_QM0_CP_BARRIER_CFG_1 0xD603F8 + +#define mmNIC2_QM0_CP_BARRIER_CFG_2 0xD603FC + +#define mmNIC2_QM0_CP_BARRIER_CFG_3 0xD60400 + +#define mmNIC2_QM0_CP_BARRIER_CFG_4 0xD60404 + +#define mmNIC2_QM0_CP_DBG_0_0 0xD60408 + +#define mmNIC2_QM0_CP_DBG_0_1 0xD6040C + +#define mmNIC2_QM0_CP_DBG_0_2 0xD60410 + +#define mmNIC2_QM0_CP_DBG_0_3 0xD60414 + +#define mmNIC2_QM0_CP_DBG_0_4 0xD60418 + +#define mmNIC2_QM0_CP_ARUSER_31_11_0 0xD6041C + +#define mmNIC2_QM0_CP_ARUSER_31_11_1 0xD60420 + +#define mmNIC2_QM0_CP_ARUSER_31_11_2 0xD60424 + +#define mmNIC2_QM0_CP_ARUSER_31_11_3 0xD60428 + +#define mmNIC2_QM0_CP_ARUSER_31_11_4 0xD6042C + +#define mmNIC2_QM0_CP_AWUSER_31_11_0 0xD60430 + +#define mmNIC2_QM0_CP_AWUSER_31_11_1 0xD60434 + +#define mmNIC2_QM0_CP_AWUSER_31_11_2 0xD60438 + +#define mmNIC2_QM0_CP_AWUSER_31_11_3 0xD6043C + +#define mmNIC2_QM0_CP_AWUSER_31_11_4 0xD60440 + +#define mmNIC2_QM0_ARB_CFG_0 0xD60A00 + +#define mmNIC2_QM0_ARB_CHOISE_Q_PUSH 0xD60A04 + +#define mmNIC2_QM0_ARB_WRR_WEIGHT_0 0xD60A08 + +#define mmNIC2_QM0_ARB_WRR_WEIGHT_1 0xD60A0C + +#define mmNIC2_QM0_ARB_WRR_WEIGHT_2 0xD60A10 + +#define mmNIC2_QM0_ARB_WRR_WEIGHT_3 0xD60A14 + +#define mmNIC2_QM0_ARB_CFG_1 0xD60A18 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_0 0xD60A20 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_1 0xD60A24 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_2 0xD60A28 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_3 0xD60A2C + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_4 0xD60A30 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_5 0xD60A34 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_6 0xD60A38 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_7 0xD60A3C + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_8 0xD60A40 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_9 0xD60A44 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_10 0xD60A48 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_11 0xD60A4C + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_12 0xD60A50 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_13 0xD60A54 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_14 0xD60A58 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_15 0xD60A5C + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_16 0xD60A60 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_17 0xD60A64 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_18 0xD60A68 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_19 0xD60A6C + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_20 0xD60A70 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_21 0xD60A74 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_22 0xD60A78 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_23 0xD60A7C + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_24 0xD60A80 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_25 0xD60A84 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_26 0xD60A88 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_27 0xD60A8C + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_28 0xD60A90 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_29 0xD60A94 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_30 0xD60A98 + +#define mmNIC2_QM0_ARB_MST_AVAIL_CRED_31 0xD60A9C + +#define mmNIC2_QM0_ARB_MST_CRED_INC 0xD60AA0 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_0 0xD60AA4 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_1 0xD60AA8 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_2 0xD60AAC + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_3 0xD60AB0 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_4 0xD60AB4 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_5 0xD60AB8 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_6 0xD60ABC + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_7 0xD60AC0 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_8 0xD60AC4 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_9 0xD60AC8 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_10 0xD60ACC + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_11 0xD60AD0 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_12 0xD60AD4 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_13 0xD60AD8 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_14 0xD60ADC + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_15 0xD60AE0 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_16 0xD60AE4 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_17 0xD60AE8 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_18 0xD60AEC + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_19 0xD60AF0 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_20 0xD60AF4 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_21 0xD60AF8 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_22 0xD60AFC + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_23 0xD60B00 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_24 0xD60B04 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_25 0xD60B08 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_26 0xD60B0C + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_27 0xD60B10 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_28 0xD60B14 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_29 0xD60B18 + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_30 0xD60B1C + +#define mmNIC2_QM0_ARB_MST_CHOISE_PUSH_OFST_31 0xD60B20 + +#define mmNIC2_QM0_ARB_SLV_MASTER_INC_CRED_OFST 0xD60B28 + +#define mmNIC2_QM0_ARB_MST_SLAVE_EN 0xD60B2C + +#define mmNIC2_QM0_ARB_MST_QUIET_PER 0xD60B34 + +#define mmNIC2_QM0_ARB_SLV_CHOISE_WDT 0xD60B38 + +#define mmNIC2_QM0_ARB_SLV_ID 0xD60B3C + +#define mmNIC2_QM0_ARB_MSG_MAX_INFLIGHT 0xD60B44 + +#define mmNIC2_QM0_ARB_MSG_AWUSER_31_11 0xD60B48 + +#define mmNIC2_QM0_ARB_MSG_AWUSER_SEC_PROP 0xD60B4C + +#define mmNIC2_QM0_ARB_MSG_AWUSER_NON_SEC_PROP 0xD60B50 + +#define mmNIC2_QM0_ARB_BASE_LO 0xD60B54 + +#define mmNIC2_QM0_ARB_BASE_HI 0xD60B58 + +#define mmNIC2_QM0_ARB_STATE_STS 0xD60B80 + +#define mmNIC2_QM0_ARB_CHOISE_FULLNESS_STS 0xD60B84 + +#define mmNIC2_QM0_ARB_MSG_STS 0xD60B88 + +#define mmNIC2_QM0_ARB_SLV_CHOISE_Q_HEAD 0xD60B8C + +#define mmNIC2_QM0_ARB_ERR_CAUSE 0xD60B9C + +#define mmNIC2_QM0_ARB_ERR_MSG_EN 0xD60BA0 + +#define mmNIC2_QM0_ARB_ERR_STS_DRP 0xD60BA8 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_0 0xD60BB0 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_1 0xD60BB4 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_2 0xD60BB8 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_3 0xD60BBC + +#define mmNIC2_QM0_ARB_MST_CRED_STS_4 0xD60BC0 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_5 0xD60BC4 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_6 0xD60BC8 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_7 0xD60BCC + +#define mmNIC2_QM0_ARB_MST_CRED_STS_8 0xD60BD0 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_9 0xD60BD4 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_10 0xD60BD8 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_11 0xD60BDC + +#define mmNIC2_QM0_ARB_MST_CRED_STS_12 0xD60BE0 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_13 0xD60BE4 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_14 0xD60BE8 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_15 0xD60BEC + +#define mmNIC2_QM0_ARB_MST_CRED_STS_16 0xD60BF0 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_17 0xD60BF4 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_18 0xD60BF8 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_19 0xD60BFC + +#define mmNIC2_QM0_ARB_MST_CRED_STS_20 0xD60C00 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_21 0xD60C04 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_22 0xD60C08 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_23 0xD60C0C + +#define mmNIC2_QM0_ARB_MST_CRED_STS_24 0xD60C10 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_25 0xD60C14 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_26 0xD60C18 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_27 0xD60C1C + +#define mmNIC2_QM0_ARB_MST_CRED_STS_28 0xD60C20 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_29 0xD60C24 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_30 0xD60C28 + +#define mmNIC2_QM0_ARB_MST_CRED_STS_31 0xD60C2C + +#define mmNIC2_QM0_CGM_CFG 0xD60C70 + +#define mmNIC2_QM0_CGM_STS 0xD60C74 + +#define mmNIC2_QM0_CGM_CFG1 0xD60C78 + +#define mmNIC2_QM0_LOCAL_RANGE_BASE 0xD60C80 + +#define mmNIC2_QM0_LOCAL_RANGE_SIZE 0xD60C84 + +#define mmNIC2_QM0_CSMR_STRICT_PRIO_CFG 0xD60C90 + +#define mmNIC2_QM0_HBW_RD_RATE_LIM_CFG_1 0xD60C94 + +#define mmNIC2_QM0_LBW_WR_RATE_LIM_CFG_0 0xD60C98 + +#define mmNIC2_QM0_LBW_WR_RATE_LIM_CFG_1 0xD60C9C + +#define mmNIC2_QM0_HBW_RD_RATE_LIM_CFG_0 0xD60CA0 + +#define mmNIC2_QM0_GLBL_AXCACHE 0xD60CA4 + +#define mmNIC2_QM0_IND_GW_APB_CFG 0xD60CB0 + +#define mmNIC2_QM0_IND_GW_APB_WDATA 0xD60CB4 + +#define mmNIC2_QM0_IND_GW_APB_RDATA 0xD60CB8 + +#define mmNIC2_QM0_IND_GW_APB_STATUS 0xD60CBC + +#define mmNIC2_QM0_GLBL_ERR_ADDR_LO 0xD60CD0 + +#define mmNIC2_QM0_GLBL_ERR_ADDR_HI 0xD60CD4 + +#define mmNIC2_QM0_GLBL_ERR_WDATA 0xD60CD8 + +#define mmNIC2_QM0_GLBL_MEM_INIT_BUSY 0xD60D00 + +#endif /* ASIC_REG_NIC2_QM0_REGS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/nic2_qm1_regs.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic2_qm1_regs.h new file mode 100644 index 000000000000..b7f091ddc89c --- /dev/null +++ b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic2_qm1_regs.h @@ -0,0 +1,834 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright 2016-2018 HabanaLabs, Ltd. + * All Rights Reserved. + * + */ + +/************************************ + ** This is an auto-generated file ** + ** DO NOT EDIT BELOW ** + ************************************/ + +#ifndef ASIC_REG_NIC2_QM1_REGS_H_ +#define ASIC_REG_NIC2_QM1_REGS_H_ + +/* + ***************************************** + * NIC2_QM1 (Prototype: QMAN) + ***************************************** + */ + +#define mmNIC2_QM1_GLBL_CFG0 0xD62000 + +#define mmNIC2_QM1_GLBL_CFG1 0xD62004 + +#define mmNIC2_QM1_GLBL_PROT 0xD62008 + +#define mmNIC2_QM1_GLBL_ERR_CFG 0xD6200C + +#define mmNIC2_QM1_GLBL_SECURE_PROPS_0 0xD62010 + +#define mmNIC2_QM1_GLBL_SECURE_PROPS_1 0xD62014 + +#define mmNIC2_QM1_GLBL_SECURE_PROPS_2 0xD62018 + +#define mmNIC2_QM1_GLBL_SECURE_PROPS_3 0xD6201C + +#define mmNIC2_QM1_GLBL_SECURE_PROPS_4 0xD62020 + +#define mmNIC2_QM1_GLBL_NON_SECURE_PROPS_0 0xD62024 + +#define mmNIC2_QM1_GLBL_NON_SECURE_PROPS_1 0xD62028 + +#define mmNIC2_QM1_GLBL_NON_SECURE_PROPS_2 0xD6202C + +#define mmNIC2_QM1_GLBL_NON_SECURE_PROPS_3 0xD62030 + +#define mmNIC2_QM1_GLBL_NON_SECURE_PROPS_4 0xD62034 + +#define mmNIC2_QM1_GLBL_STS0 0xD62038 + +#define mmNIC2_QM1_GLBL_STS1_0 0xD62040 + +#define mmNIC2_QM1_GLBL_STS1_1 0xD62044 + +#define mmNIC2_QM1_GLBL_STS1_2 0xD62048 + +#define mmNIC2_QM1_GLBL_STS1_3 0xD6204C + +#define mmNIC2_QM1_GLBL_STS1_4 0xD62050 + +#define mmNIC2_QM1_GLBL_MSG_EN_0 0xD62054 + +#define mmNIC2_QM1_GLBL_MSG_EN_1 0xD62058 + +#define mmNIC2_QM1_GLBL_MSG_EN_2 0xD6205C + +#define mmNIC2_QM1_GLBL_MSG_EN_3 0xD62060 + +#define mmNIC2_QM1_GLBL_MSG_EN_4 0xD62068 + +#define mmNIC2_QM1_PQ_BASE_LO_0 0xD62070 + +#define mmNIC2_QM1_PQ_BASE_LO_1 0xD62074 + +#define mmNIC2_QM1_PQ_BASE_LO_2 0xD62078 + +#define mmNIC2_QM1_PQ_BASE_LO_3 0xD6207C + +#define mmNIC2_QM1_PQ_BASE_HI_0 0xD62080 + +#define mmNIC2_QM1_PQ_BASE_HI_1 0xD62084 + +#define mmNIC2_QM1_PQ_BASE_HI_2 0xD62088 + +#define mmNIC2_QM1_PQ_BASE_HI_3 0xD6208C + +#define mmNIC2_QM1_PQ_SIZE_0 0xD62090 + +#define mmNIC2_QM1_PQ_SIZE_1 0xD62094 + +#define mmNIC2_QM1_PQ_SIZE_2 0xD62098 + +#define mmNIC2_QM1_PQ_SIZE_3 0xD6209C + +#define mmNIC2_QM1_PQ_PI_0 0xD620A0 + +#define mmNIC2_QM1_PQ_PI_1 0xD620A4 + +#define mmNIC2_QM1_PQ_PI_2 0xD620A8 + +#define mmNIC2_QM1_PQ_PI_3 0xD620AC + +#define mmNIC2_QM1_PQ_CI_0 0xD620B0 + +#define mmNIC2_QM1_PQ_CI_1 0xD620B4 + +#define mmNIC2_QM1_PQ_CI_2 0xD620B8 + +#define mmNIC2_QM1_PQ_CI_3 0xD620BC + +#define mmNIC2_QM1_PQ_CFG0_0 0xD620C0 + +#define mmNIC2_QM1_PQ_CFG0_1 0xD620C4 + +#define mmNIC2_QM1_PQ_CFG0_2 0xD620C8 + +#define mmNIC2_QM1_PQ_CFG0_3 0xD620CC + +#define mmNIC2_QM1_PQ_CFG1_0 0xD620D0 + +#define mmNIC2_QM1_PQ_CFG1_1 0xD620D4 + +#define mmNIC2_QM1_PQ_CFG1_2 0xD620D8 + +#define mmNIC2_QM1_PQ_CFG1_3 0xD620DC + +#define mmNIC2_QM1_PQ_ARUSER_31_11_0 0xD620E0 + +#define mmNIC2_QM1_PQ_ARUSER_31_11_1 0xD620E4 + +#define mmNIC2_QM1_PQ_ARUSER_31_11_2 0xD620E8 + +#define mmNIC2_QM1_PQ_ARUSER_31_11_3 0xD620EC + +#define mmNIC2_QM1_PQ_STS0_0 0xD620F0 + +#define mmNIC2_QM1_PQ_STS0_1 0xD620F4 + +#define mmNIC2_QM1_PQ_STS0_2 0xD620F8 + +#define mmNIC2_QM1_PQ_STS0_3 0xD620FC + +#define mmNIC2_QM1_PQ_STS1_0 0xD62100 + +#define mmNIC2_QM1_PQ_STS1_1 0xD62104 + +#define mmNIC2_QM1_PQ_STS1_2 0xD62108 + +#define mmNIC2_QM1_PQ_STS1_3 0xD6210C + +#define mmNIC2_QM1_CQ_CFG0_0 0xD62110 + +#define mmNIC2_QM1_CQ_CFG0_1 0xD62114 + +#define mmNIC2_QM1_CQ_CFG0_2 0xD62118 + +#define mmNIC2_QM1_CQ_CFG0_3 0xD6211C + +#define mmNIC2_QM1_CQ_CFG0_4 0xD62120 + +#define mmNIC2_QM1_CQ_CFG1_0 0xD62124 + +#define mmNIC2_QM1_CQ_CFG1_1 0xD62128 + +#define mmNIC2_QM1_CQ_CFG1_2 0xD6212C + +#define mmNIC2_QM1_CQ_CFG1_3 0xD62130 + +#define mmNIC2_QM1_CQ_CFG1_4 0xD62134 + +#define mmNIC2_QM1_CQ_ARUSER_31_11_0 0xD62138 + +#define mmNIC2_QM1_CQ_ARUSER_31_11_1 0xD6213C + +#define mmNIC2_QM1_CQ_ARUSER_31_11_2 0xD62140 + +#define mmNIC2_QM1_CQ_ARUSER_31_11_3 0xD62144 + +#define mmNIC2_QM1_CQ_ARUSER_31_11_4 0xD62148 + +#define mmNIC2_QM1_CQ_STS0_0 0xD6214C + +#define mmNIC2_QM1_CQ_STS0_1 0xD62150 + +#define mmNIC2_QM1_CQ_STS0_2 0xD62154 + +#define mmNIC2_QM1_CQ_STS0_3 0xD62158 + +#define mmNIC2_QM1_CQ_STS0_4 0xD6215C + +#define mmNIC2_QM1_CQ_STS1_0 0xD62160 + +#define mmNIC2_QM1_CQ_STS1_1 0xD62164 + +#define mmNIC2_QM1_CQ_STS1_2 0xD62168 + +#define mmNIC2_QM1_CQ_STS1_3 0xD6216C + +#define mmNIC2_QM1_CQ_STS1_4 0xD62170 + +#define mmNIC2_QM1_CQ_PTR_LO_0 0xD62174 + +#define mmNIC2_QM1_CQ_PTR_HI_0 0xD62178 + +#define mmNIC2_QM1_CQ_TSIZE_0 0xD6217C + +#define mmNIC2_QM1_CQ_CTL_0 0xD62180 + +#define mmNIC2_QM1_CQ_PTR_LO_1 0xD62184 + +#define mmNIC2_QM1_CQ_PTR_HI_1 0xD62188 + +#define mmNIC2_QM1_CQ_TSIZE_1 0xD6218C + +#define mmNIC2_QM1_CQ_CTL_1 0xD62190 + +#define mmNIC2_QM1_CQ_PTR_LO_2 0xD62194 + +#define mmNIC2_QM1_CQ_PTR_HI_2 0xD62198 + +#define mmNIC2_QM1_CQ_TSIZE_2 0xD6219C + +#define mmNIC2_QM1_CQ_CTL_2 0xD621A0 + +#define mmNIC2_QM1_CQ_PTR_LO_3 0xD621A4 + +#define mmNIC2_QM1_CQ_PTR_HI_3 0xD621A8 + +#define mmNIC2_QM1_CQ_TSIZE_3 0xD621AC + +#define mmNIC2_QM1_CQ_CTL_3 0xD621B0 + +#define mmNIC2_QM1_CQ_PTR_LO_4 0xD621B4 + +#define mmNIC2_QM1_CQ_PTR_HI_4 0xD621B8 + +#define mmNIC2_QM1_CQ_TSIZE_4 0xD621BC + +#define mmNIC2_QM1_CQ_CTL_4 0xD621C0 + +#define mmNIC2_QM1_CQ_PTR_LO_STS_0 0xD621C4 + +#define mmNIC2_QM1_CQ_PTR_LO_STS_1 0xD621C8 + +#define mmNIC2_QM1_CQ_PTR_LO_STS_2 0xD621CC + +#define mmNIC2_QM1_CQ_PTR_LO_STS_3 0xD621D0 + +#define mmNIC2_QM1_CQ_PTR_LO_STS_4 0xD621D4 + +#define mmNIC2_QM1_CQ_PTR_HI_STS_0 0xD621D8 + +#define mmNIC2_QM1_CQ_PTR_HI_STS_1 0xD621DC + +#define mmNIC2_QM1_CQ_PTR_HI_STS_2 0xD621E0 + +#define mmNIC2_QM1_CQ_PTR_HI_STS_3 0xD621E4 + +#define mmNIC2_QM1_CQ_PTR_HI_STS_4 0xD621E8 + +#define mmNIC2_QM1_CQ_TSIZE_STS_0 0xD621EC + +#define mmNIC2_QM1_CQ_TSIZE_STS_1 0xD621F0 + +#define mmNIC2_QM1_CQ_TSIZE_STS_2 0xD621F4 + +#define mmNIC2_QM1_CQ_TSIZE_STS_3 0xD621F8 + +#define mmNIC2_QM1_CQ_TSIZE_STS_4 0xD621FC + +#define mmNIC2_QM1_CQ_CTL_STS_0 0xD62200 + +#define mmNIC2_QM1_CQ_CTL_STS_1 0xD62204 + +#define mmNIC2_QM1_CQ_CTL_STS_2 0xD62208 + +#define mmNIC2_QM1_CQ_CTL_STS_3 0xD6220C + +#define mmNIC2_QM1_CQ_CTL_STS_4 0xD62210 + +#define mmNIC2_QM1_CQ_IFIFO_CNT_0 0xD62214 + +#define mmNIC2_QM1_CQ_IFIFO_CNT_1 0xD62218 + +#define mmNIC2_QM1_CQ_IFIFO_CNT_2 0xD6221C + +#define mmNIC2_QM1_CQ_IFIFO_CNT_3 0xD62220 + +#define mmNIC2_QM1_CQ_IFIFO_CNT_4 0xD62224 + +#define mmNIC2_QM1_CP_MSG_BASE0_ADDR_LO_0 0xD62228 + +#define mmNIC2_QM1_CP_MSG_BASE0_ADDR_LO_1 0xD6222C + +#define mmNIC2_QM1_CP_MSG_BASE0_ADDR_LO_2 0xD62230 + +#define mmNIC2_QM1_CP_MSG_BASE0_ADDR_LO_3 0xD62234 + +#define mmNIC2_QM1_CP_MSG_BASE0_ADDR_LO_4 0xD62238 + +#define mmNIC2_QM1_CP_MSG_BASE0_ADDR_HI_0 0xD6223C + +#define mmNIC2_QM1_CP_MSG_BASE0_ADDR_HI_1 0xD62240 + +#define mmNIC2_QM1_CP_MSG_BASE0_ADDR_HI_2 0xD62244 + +#define mmNIC2_QM1_CP_MSG_BASE0_ADDR_HI_3 0xD62248 + +#define mmNIC2_QM1_CP_MSG_BASE0_ADDR_HI_4 0xD6224C + +#define mmNIC2_QM1_CP_MSG_BASE1_ADDR_LO_0 0xD62250 + +#define mmNIC2_QM1_CP_MSG_BASE1_ADDR_LO_1 0xD62254 + +#define mmNIC2_QM1_CP_MSG_BASE1_ADDR_LO_2 0xD62258 + +#define mmNIC2_QM1_CP_MSG_BASE1_ADDR_LO_3 0xD6225C + +#define mmNIC2_QM1_CP_MSG_BASE1_ADDR_LO_4 0xD62260 + +#define mmNIC2_QM1_CP_MSG_BASE1_ADDR_HI_0 0xD62264 + +#define mmNIC2_QM1_CP_MSG_BASE1_ADDR_HI_1 0xD62268 + +#define mmNIC2_QM1_CP_MSG_BASE1_ADDR_HI_2 0xD6226C + +#define mmNIC2_QM1_CP_MSG_BASE1_ADDR_HI_3 0xD62270 + +#define mmNIC2_QM1_CP_MSG_BASE1_ADDR_HI_4 0xD62274 + +#define mmNIC2_QM1_CP_MSG_BASE2_ADDR_LO_0 0xD62278 + +#define mmNIC2_QM1_CP_MSG_BASE2_ADDR_LO_1 0xD6227C + +#define mmNIC2_QM1_CP_MSG_BASE2_ADDR_LO_2 0xD62280 + +#define mmNIC2_QM1_CP_MSG_BASE2_ADDR_LO_3 0xD62284 + +#define mmNIC2_QM1_CP_MSG_BASE2_ADDR_LO_4 0xD62288 + +#define mmNIC2_QM1_CP_MSG_BASE2_ADDR_HI_0 0xD6228C + +#define mmNIC2_QM1_CP_MSG_BASE2_ADDR_HI_1 0xD62290 + +#define mmNIC2_QM1_CP_MSG_BASE2_ADDR_HI_2 0xD62294 + +#define mmNIC2_QM1_CP_MSG_BASE2_ADDR_HI_3 0xD62298 + +#define mmNIC2_QM1_CP_MSG_BASE2_ADDR_HI_4 0xD6229C + +#define mmNIC2_QM1_CP_MSG_BASE3_ADDR_LO_0 0xD622A0 + +#define mmNIC2_QM1_CP_MSG_BASE3_ADDR_LO_1 0xD622A4 + +#define mmNIC2_QM1_CP_MSG_BASE3_ADDR_LO_2 0xD622A8 + +#define mmNIC2_QM1_CP_MSG_BASE3_ADDR_LO_3 0xD622AC + +#define mmNIC2_QM1_CP_MSG_BASE3_ADDR_LO_4 0xD622B0 + +#define mmNIC2_QM1_CP_MSG_BASE3_ADDR_HI_0 0xD622B4 + +#define mmNIC2_QM1_CP_MSG_BASE3_ADDR_HI_1 0xD622B8 + +#define mmNIC2_QM1_CP_MSG_BASE3_ADDR_HI_2 0xD622BC + +#define mmNIC2_QM1_CP_MSG_BASE3_ADDR_HI_3 0xD622C0 + +#define mmNIC2_QM1_CP_MSG_BASE3_ADDR_HI_4 0xD622C4 + +#define mmNIC2_QM1_CP_LDMA_TSIZE_OFFSET_0 0xD622C8 + +#define mmNIC2_QM1_CP_LDMA_TSIZE_OFFSET_1 0xD622CC + +#define mmNIC2_QM1_CP_LDMA_TSIZE_OFFSET_2 0xD622D0 + +#define mmNIC2_QM1_CP_LDMA_TSIZE_OFFSET_3 0xD622D4 + +#define mmNIC2_QM1_CP_LDMA_TSIZE_OFFSET_4 0xD622D8 + +#define mmNIC2_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_0 0xD622E0 + +#define mmNIC2_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_1 0xD622E4 + +#define mmNIC2_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_2 0xD622E8 + +#define mmNIC2_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_3 0xD622EC + +#define mmNIC2_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_4 0xD622F0 + +#define mmNIC2_QM1_CP_LDMA_DST_BASE_LO_OFFSET_0 0xD622F4 + +#define mmNIC2_QM1_CP_LDMA_DST_BASE_LO_OFFSET_1 0xD622F8 + +#define mmNIC2_QM1_CP_LDMA_DST_BASE_LO_OFFSET_2 0xD622FC + +#define mmNIC2_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 0xD62300 + +#define mmNIC2_QM1_CP_LDMA_DST_BASE_LO_OFFSET_4 0xD62304 + +#define mmNIC2_QM1_CP_FENCE0_RDATA_0 0xD62308 + +#define mmNIC2_QM1_CP_FENCE0_RDATA_1 0xD6230C + +#define mmNIC2_QM1_CP_FENCE0_RDATA_2 0xD62310 + +#define mmNIC2_QM1_CP_FENCE0_RDATA_3 0xD62314 + +#define mmNIC2_QM1_CP_FENCE0_RDATA_4 0xD62318 + +#define mmNIC2_QM1_CP_FENCE1_RDATA_0 0xD6231C + +#define mmNIC2_QM1_CP_FENCE1_RDATA_1 0xD62320 + +#define mmNIC2_QM1_CP_FENCE1_RDATA_2 0xD62324 + +#define mmNIC2_QM1_CP_FENCE1_RDATA_3 0xD62328 + +#define mmNIC2_QM1_CP_FENCE1_RDATA_4 0xD6232C + +#define mmNIC2_QM1_CP_FENCE2_RDATA_0 0xD62330 + +#define mmNIC2_QM1_CP_FENCE2_RDATA_1 0xD62334 + +#define mmNIC2_QM1_CP_FENCE2_RDATA_2 0xD62338 + +#define mmNIC2_QM1_CP_FENCE2_RDATA_3 0xD6233C + +#define mmNIC2_QM1_CP_FENCE2_RDATA_4 0xD62340 + +#define mmNIC2_QM1_CP_FENCE3_RDATA_0 0xD62344 + +#define mmNIC2_QM1_CP_FENCE3_RDATA_1 0xD62348 + +#define mmNIC2_QM1_CP_FENCE3_RDATA_2 0xD6234C + +#define mmNIC2_QM1_CP_FENCE3_RDATA_3 0xD62350 + +#define mmNIC2_QM1_CP_FENCE3_RDATA_4 0xD62354 + +#define mmNIC2_QM1_CP_FENCE0_CNT_0 0xD62358 + +#define mmNIC2_QM1_CP_FENCE0_CNT_1 0xD6235C + +#define mmNIC2_QM1_CP_FENCE0_CNT_2 0xD62360 + +#define mmNIC2_QM1_CP_FENCE0_CNT_3 0xD62364 + +#define mmNIC2_QM1_CP_FENCE0_CNT_4 0xD62368 + +#define mmNIC2_QM1_CP_FENCE1_CNT_0 0xD6236C + +#define mmNIC2_QM1_CP_FENCE1_CNT_1 0xD62370 + +#define mmNIC2_QM1_CP_FENCE1_CNT_2 0xD62374 + +#define mmNIC2_QM1_CP_FENCE1_CNT_3 0xD62378 + +#define mmNIC2_QM1_CP_FENCE1_CNT_4 0xD6237C + +#define mmNIC2_QM1_CP_FENCE2_CNT_0 0xD62380 + +#define mmNIC2_QM1_CP_FENCE2_CNT_1 0xD62384 + +#define mmNIC2_QM1_CP_FENCE2_CNT_2 0xD62388 + +#define mmNIC2_QM1_CP_FENCE2_CNT_3 0xD6238C + +#define mmNIC2_QM1_CP_FENCE2_CNT_4 0xD62390 + +#define mmNIC2_QM1_CP_FENCE3_CNT_0 0xD62394 + +#define mmNIC2_QM1_CP_FENCE3_CNT_1 0xD62398 + +#define mmNIC2_QM1_CP_FENCE3_CNT_2 0xD6239C + +#define mmNIC2_QM1_CP_FENCE3_CNT_3 0xD623A0 + +#define mmNIC2_QM1_CP_FENCE3_CNT_4 0xD623A4 + +#define mmNIC2_QM1_CP_STS_0 0xD623A8 + +#define mmNIC2_QM1_CP_STS_1 0xD623AC + +#define mmNIC2_QM1_CP_STS_2 0xD623B0 + +#define mmNIC2_QM1_CP_STS_3 0xD623B4 + +#define mmNIC2_QM1_CP_STS_4 0xD623B8 + +#define mmNIC2_QM1_CP_CURRENT_INST_LO_0 0xD623BC + +#define mmNIC2_QM1_CP_CURRENT_INST_LO_1 0xD623C0 + +#define mmNIC2_QM1_CP_CURRENT_INST_LO_2 0xD623C4 + +#define mmNIC2_QM1_CP_CURRENT_INST_LO_3 0xD623C8 + +#define mmNIC2_QM1_CP_CURRENT_INST_LO_4 0xD623CC + +#define mmNIC2_QM1_CP_CURRENT_INST_HI_0 0xD623D0 + +#define mmNIC2_QM1_CP_CURRENT_INST_HI_1 0xD623D4 + +#define mmNIC2_QM1_CP_CURRENT_INST_HI_2 0xD623D8 + +#define mmNIC2_QM1_CP_CURRENT_INST_HI_3 0xD623DC + +#define mmNIC2_QM1_CP_CURRENT_INST_HI_4 0xD623E0 + +#define mmNIC2_QM1_CP_BARRIER_CFG_0 0xD623F4 + +#define mmNIC2_QM1_CP_BARRIER_CFG_1 0xD623F8 + +#define mmNIC2_QM1_CP_BARRIER_CFG_2 0xD623FC + +#define mmNIC2_QM1_CP_BARRIER_CFG_3 0xD62400 + +#define mmNIC2_QM1_CP_BARRIER_CFG_4 0xD62404 + +#define mmNIC2_QM1_CP_DBG_0_0 0xD62408 + +#define mmNIC2_QM1_CP_DBG_0_1 0xD6240C + +#define mmNIC2_QM1_CP_DBG_0_2 0xD62410 + +#define mmNIC2_QM1_CP_DBG_0_3 0xD62414 + +#define mmNIC2_QM1_CP_DBG_0_4 0xD62418 + +#define mmNIC2_QM1_CP_ARUSER_31_11_0 0xD6241C + +#define mmNIC2_QM1_CP_ARUSER_31_11_1 0xD62420 + +#define mmNIC2_QM1_CP_ARUSER_31_11_2 0xD62424 + +#define mmNIC2_QM1_CP_ARUSER_31_11_3 0xD62428 + +#define mmNIC2_QM1_CP_ARUSER_31_11_4 0xD6242C + +#define mmNIC2_QM1_CP_AWUSER_31_11_0 0xD62430 + +#define mmNIC2_QM1_CP_AWUSER_31_11_1 0xD62434 + +#define mmNIC2_QM1_CP_AWUSER_31_11_2 0xD62438 + +#define mmNIC2_QM1_CP_AWUSER_31_11_3 0xD6243C + +#define mmNIC2_QM1_CP_AWUSER_31_11_4 0xD62440 + +#define mmNIC2_QM1_ARB_CFG_0 0xD62A00 + +#define mmNIC2_QM1_ARB_CHOISE_Q_PUSH 0xD62A04 + +#define mmNIC2_QM1_ARB_WRR_WEIGHT_0 0xD62A08 + +#define mmNIC2_QM1_ARB_WRR_WEIGHT_1 0xD62A0C + +#define mmNIC2_QM1_ARB_WRR_WEIGHT_2 0xD62A10 + +#define mmNIC2_QM1_ARB_WRR_WEIGHT_3 0xD62A14 + +#define mmNIC2_QM1_ARB_CFG_1 0xD62A18 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_0 0xD62A20 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_1 0xD62A24 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_2 0xD62A28 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_3 0xD62A2C + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_4 0xD62A30 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_5 0xD62A34 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_6 0xD62A38 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_7 0xD62A3C + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_8 0xD62A40 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_9 0xD62A44 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_10 0xD62A48 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_11 0xD62A4C + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_12 0xD62A50 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_13 0xD62A54 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_14 0xD62A58 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_15 0xD62A5C + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_16 0xD62A60 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_17 0xD62A64 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_18 0xD62A68 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_19 0xD62A6C + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_20 0xD62A70 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_21 0xD62A74 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_22 0xD62A78 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_23 0xD62A7C + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_24 0xD62A80 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_25 0xD62A84 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_26 0xD62A88 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_27 0xD62A8C + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_28 0xD62A90 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_29 0xD62A94 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_30 0xD62A98 + +#define mmNIC2_QM1_ARB_MST_AVAIL_CRED_31 0xD62A9C + +#define mmNIC2_QM1_ARB_MST_CRED_INC 0xD62AA0 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_0 0xD62AA4 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_1 0xD62AA8 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_2 0xD62AAC + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_3 0xD62AB0 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_4 0xD62AB4 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_5 0xD62AB8 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_6 0xD62ABC + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_7 0xD62AC0 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_8 0xD62AC4 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_9 0xD62AC8 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_10 0xD62ACC + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_11 0xD62AD0 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_12 0xD62AD4 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_13 0xD62AD8 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_14 0xD62ADC + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_15 0xD62AE0 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_16 0xD62AE4 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_17 0xD62AE8 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_18 0xD62AEC + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_19 0xD62AF0 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_20 0xD62AF4 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_21 0xD62AF8 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_22 0xD62AFC + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_23 0xD62B00 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_24 0xD62B04 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_25 0xD62B08 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_26 0xD62B0C + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_27 0xD62B10 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_28 0xD62B14 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_29 0xD62B18 + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_30 0xD62B1C + +#define mmNIC2_QM1_ARB_MST_CHOISE_PUSH_OFST_31 0xD62B20 + +#define mmNIC2_QM1_ARB_SLV_MASTER_INC_CRED_OFST 0xD62B28 + +#define mmNIC2_QM1_ARB_MST_SLAVE_EN 0xD62B2C + +#define mmNIC2_QM1_ARB_MST_QUIET_PER 0xD62B34 + +#define mmNIC2_QM1_ARB_SLV_CHOISE_WDT 0xD62B38 + +#define mmNIC2_QM1_ARB_SLV_ID 0xD62B3C + +#define mmNIC2_QM1_ARB_MSG_MAX_INFLIGHT 0xD62B44 + +#define mmNIC2_QM1_ARB_MSG_AWUSER_31_11 0xD62B48 + +#define mmNIC2_QM1_ARB_MSG_AWUSER_SEC_PROP 0xD62B4C + +#define mmNIC2_QM1_ARB_MSG_AWUSER_NON_SEC_PROP 0xD62B50 + +#define mmNIC2_QM1_ARB_BASE_LO 0xD62B54 + +#define mmNIC2_QM1_ARB_BASE_HI 0xD62B58 + +#define mmNIC2_QM1_ARB_STATE_STS 0xD62B80 + +#define mmNIC2_QM1_ARB_CHOISE_FULLNESS_STS 0xD62B84 + +#define mmNIC2_QM1_ARB_MSG_STS 0xD62B88 + +#define mmNIC2_QM1_ARB_SLV_CHOISE_Q_HEAD 0xD62B8C + +#define mmNIC2_QM1_ARB_ERR_CAUSE 0xD62B9C + +#define mmNIC2_QM1_ARB_ERR_MSG_EN 0xD62BA0 + +#define mmNIC2_QM1_ARB_ERR_STS_DRP 0xD62BA8 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_0 0xD62BB0 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_1 0xD62BB4 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_2 0xD62BB8 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_3 0xD62BBC + +#define mmNIC2_QM1_ARB_MST_CRED_STS_4 0xD62BC0 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_5 0xD62BC4 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_6 0xD62BC8 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_7 0xD62BCC + +#define mmNIC2_QM1_ARB_MST_CRED_STS_8 0xD62BD0 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_9 0xD62BD4 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_10 0xD62BD8 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_11 0xD62BDC + +#define mmNIC2_QM1_ARB_MST_CRED_STS_12 0xD62BE0 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_13 0xD62BE4 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_14 0xD62BE8 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_15 0xD62BEC + +#define mmNIC2_QM1_ARB_MST_CRED_STS_16 0xD62BF0 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_17 0xD62BF4 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_18 0xD62BF8 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_19 0xD62BFC + +#define mmNIC2_QM1_ARB_MST_CRED_STS_20 0xD62C00 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_21 0xD62C04 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_22 0xD62C08 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_23 0xD62C0C + +#define mmNIC2_QM1_ARB_MST_CRED_STS_24 0xD62C10 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_25 0xD62C14 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_26 0xD62C18 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_27 0xD62C1C + +#define mmNIC2_QM1_ARB_MST_CRED_STS_28 0xD62C20 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_29 0xD62C24 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_30 0xD62C28 + +#define mmNIC2_QM1_ARB_MST_CRED_STS_31 0xD62C2C + +#define mmNIC2_QM1_CGM_CFG 0xD62C70 + +#define mmNIC2_QM1_CGM_STS 0xD62C74 + +#define mmNIC2_QM1_CGM_CFG1 0xD62C78 + +#define mmNIC2_QM1_LOCAL_RANGE_BASE 0xD62C80 + +#define mmNIC2_QM1_LOCAL_RANGE_SIZE 0xD62C84 + +#define mmNIC2_QM1_CSMR_STRICT_PRIO_CFG 0xD62C90 + +#define mmNIC2_QM1_HBW_RD_RATE_LIM_CFG_1 0xD62C94 + +#define mmNIC2_QM1_LBW_WR_RATE_LIM_CFG_0 0xD62C98 + +#define mmNIC2_QM1_LBW_WR_RATE_LIM_CFG_1 0xD62C9C + +#define mmNIC2_QM1_HBW_RD_RATE_LIM_CFG_0 0xD62CA0 + +#define mmNIC2_QM1_GLBL_AXCACHE 0xD62CA4 + +#define mmNIC2_QM1_IND_GW_APB_CFG 0xD62CB0 + +#define mmNIC2_QM1_IND_GW_APB_WDATA 0xD62CB4 + +#define mmNIC2_QM1_IND_GW_APB_RDATA 0xD62CB8 + +#define mmNIC2_QM1_IND_GW_APB_STATUS 0xD62CBC + +#define mmNIC2_QM1_GLBL_ERR_ADDR_LO 0xD62CD0 + +#define mmNIC2_QM1_GLBL_ERR_ADDR_HI 0xD62CD4 + +#define mmNIC2_QM1_GLBL_ERR_WDATA 0xD62CD8 + +#define mmNIC2_QM1_GLBL_MEM_INIT_BUSY 0xD62D00 + +#endif /* ASIC_REG_NIC2_QM1_REGS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/nic3_qm0_regs.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic3_qm0_regs.h new file mode 100644 index 000000000000..4712cc62b009 --- /dev/null +++ b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic3_qm0_regs.h @@ -0,0 +1,834 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright 2016-2018 HabanaLabs, Ltd. + * All Rights Reserved. + * + */ + +/************************************ + ** This is an auto-generated file ** + ** DO NOT EDIT BELOW ** + ************************************/ + +#ifndef ASIC_REG_NIC3_QM0_REGS_H_ +#define ASIC_REG_NIC3_QM0_REGS_H_ + +/* + ***************************************** + * NIC3_QM0 (Prototype: QMAN) + ***************************************** + */ + +#define mmNIC3_QM0_GLBL_CFG0 0xDA0000 + +#define mmNIC3_QM0_GLBL_CFG1 0xDA0004 + +#define mmNIC3_QM0_GLBL_PROT 0xDA0008 + +#define mmNIC3_QM0_GLBL_ERR_CFG 0xDA000C + +#define mmNIC3_QM0_GLBL_SECURE_PROPS_0 0xDA0010 + +#define mmNIC3_QM0_GLBL_SECURE_PROPS_1 0xDA0014 + +#define mmNIC3_QM0_GLBL_SECURE_PROPS_2 0xDA0018 + +#define mmNIC3_QM0_GLBL_SECURE_PROPS_3 0xDA001C + +#define mmNIC3_QM0_GLBL_SECURE_PROPS_4 0xDA0020 + +#define mmNIC3_QM0_GLBL_NON_SECURE_PROPS_0 0xDA0024 + +#define mmNIC3_QM0_GLBL_NON_SECURE_PROPS_1 0xDA0028 + +#define mmNIC3_QM0_GLBL_NON_SECURE_PROPS_2 0xDA002C + +#define mmNIC3_QM0_GLBL_NON_SECURE_PROPS_3 0xDA0030 + +#define mmNIC3_QM0_GLBL_NON_SECURE_PROPS_4 0xDA0034 + +#define mmNIC3_QM0_GLBL_STS0 0xDA0038 + +#define mmNIC3_QM0_GLBL_STS1_0 0xDA0040 + +#define mmNIC3_QM0_GLBL_STS1_1 0xDA0044 + +#define mmNIC3_QM0_GLBL_STS1_2 0xDA0048 + +#define mmNIC3_QM0_GLBL_STS1_3 0xDA004C + +#define mmNIC3_QM0_GLBL_STS1_4 0xDA0050 + +#define mmNIC3_QM0_GLBL_MSG_EN_0 0xDA0054 + +#define mmNIC3_QM0_GLBL_MSG_EN_1 0xDA0058 + +#define mmNIC3_QM0_GLBL_MSG_EN_2 0xDA005C + +#define mmNIC3_QM0_GLBL_MSG_EN_3 0xDA0060 + +#define mmNIC3_QM0_GLBL_MSG_EN_4 0xDA0068 + +#define mmNIC3_QM0_PQ_BASE_LO_0 0xDA0070 + +#define mmNIC3_QM0_PQ_BASE_LO_1 0xDA0074 + +#define mmNIC3_QM0_PQ_BASE_LO_2 0xDA0078 + +#define mmNIC3_QM0_PQ_BASE_LO_3 0xDA007C + +#define mmNIC3_QM0_PQ_BASE_HI_0 0xDA0080 + +#define mmNIC3_QM0_PQ_BASE_HI_1 0xDA0084 + +#define mmNIC3_QM0_PQ_BASE_HI_2 0xDA0088 + +#define mmNIC3_QM0_PQ_BASE_HI_3 0xDA008C + +#define mmNIC3_QM0_PQ_SIZE_0 0xDA0090 + +#define mmNIC3_QM0_PQ_SIZE_1 0xDA0094 + +#define mmNIC3_QM0_PQ_SIZE_2 0xDA0098 + +#define mmNIC3_QM0_PQ_SIZE_3 0xDA009C + +#define mmNIC3_QM0_PQ_PI_0 0xDA00A0 + +#define mmNIC3_QM0_PQ_PI_1 0xDA00A4 + +#define mmNIC3_QM0_PQ_PI_2 0xDA00A8 + +#define mmNIC3_QM0_PQ_PI_3 0xDA00AC + +#define mmNIC3_QM0_PQ_CI_0 0xDA00B0 + +#define mmNIC3_QM0_PQ_CI_1 0xDA00B4 + +#define mmNIC3_QM0_PQ_CI_2 0xDA00B8 + +#define mmNIC3_QM0_PQ_CI_3 0xDA00BC + +#define mmNIC3_QM0_PQ_CFG0_0 0xDA00C0 + +#define mmNIC3_QM0_PQ_CFG0_1 0xDA00C4 + +#define mmNIC3_QM0_PQ_CFG0_2 0xDA00C8 + +#define mmNIC3_QM0_PQ_CFG0_3 0xDA00CC + +#define mmNIC3_QM0_PQ_CFG1_0 0xDA00D0 + +#define mmNIC3_QM0_PQ_CFG1_1 0xDA00D4 + +#define mmNIC3_QM0_PQ_CFG1_2 0xDA00D8 + +#define mmNIC3_QM0_PQ_CFG1_3 0xDA00DC + +#define mmNIC3_QM0_PQ_ARUSER_31_11_0 0xDA00E0 + +#define mmNIC3_QM0_PQ_ARUSER_31_11_1 0xDA00E4 + +#define mmNIC3_QM0_PQ_ARUSER_31_11_2 0xDA00E8 + +#define mmNIC3_QM0_PQ_ARUSER_31_11_3 0xDA00EC + +#define mmNIC3_QM0_PQ_STS0_0 0xDA00F0 + +#define mmNIC3_QM0_PQ_STS0_1 0xDA00F4 + +#define mmNIC3_QM0_PQ_STS0_2 0xDA00F8 + +#define mmNIC3_QM0_PQ_STS0_3 0xDA00FC + +#define mmNIC3_QM0_PQ_STS1_0 0xDA0100 + +#define mmNIC3_QM0_PQ_STS1_1 0xDA0104 + +#define mmNIC3_QM0_PQ_STS1_2 0xDA0108 + +#define mmNIC3_QM0_PQ_STS1_3 0xDA010C + +#define mmNIC3_QM0_CQ_CFG0_0 0xDA0110 + +#define mmNIC3_QM0_CQ_CFG0_1 0xDA0114 + +#define mmNIC3_QM0_CQ_CFG0_2 0xDA0118 + +#define mmNIC3_QM0_CQ_CFG0_3 0xDA011C + +#define mmNIC3_QM0_CQ_CFG0_4 0xDA0120 + +#define mmNIC3_QM0_CQ_CFG1_0 0xDA0124 + +#define mmNIC3_QM0_CQ_CFG1_1 0xDA0128 + +#define mmNIC3_QM0_CQ_CFG1_2 0xDA012C + +#define mmNIC3_QM0_CQ_CFG1_3 0xDA0130 + +#define mmNIC3_QM0_CQ_CFG1_4 0xDA0134 + +#define mmNIC3_QM0_CQ_ARUSER_31_11_0 0xDA0138 + +#define mmNIC3_QM0_CQ_ARUSER_31_11_1 0xDA013C + +#define mmNIC3_QM0_CQ_ARUSER_31_11_2 0xDA0140 + +#define mmNIC3_QM0_CQ_ARUSER_31_11_3 0xDA0144 + +#define mmNIC3_QM0_CQ_ARUSER_31_11_4 0xDA0148 + +#define mmNIC3_QM0_CQ_STS0_0 0xDA014C + +#define mmNIC3_QM0_CQ_STS0_1 0xDA0150 + +#define mmNIC3_QM0_CQ_STS0_2 0xDA0154 + +#define mmNIC3_QM0_CQ_STS0_3 0xDA0158 + +#define mmNIC3_QM0_CQ_STS0_4 0xDA015C + +#define mmNIC3_QM0_CQ_STS1_0 0xDA0160 + +#define mmNIC3_QM0_CQ_STS1_1 0xDA0164 + +#define mmNIC3_QM0_CQ_STS1_2 0xDA0168 + +#define mmNIC3_QM0_CQ_STS1_3 0xDA016C + +#define mmNIC3_QM0_CQ_STS1_4 0xDA0170 + +#define mmNIC3_QM0_CQ_PTR_LO_0 0xDA0174 + +#define mmNIC3_QM0_CQ_PTR_HI_0 0xDA0178 + +#define mmNIC3_QM0_CQ_TSIZE_0 0xDA017C + +#define mmNIC3_QM0_CQ_CTL_0 0xDA0180 + +#define mmNIC3_QM0_CQ_PTR_LO_1 0xDA0184 + +#define mmNIC3_QM0_CQ_PTR_HI_1 0xDA0188 + +#define mmNIC3_QM0_CQ_TSIZE_1 0xDA018C + +#define mmNIC3_QM0_CQ_CTL_1 0xDA0190 + +#define mmNIC3_QM0_CQ_PTR_LO_2 0xDA0194 + +#define mmNIC3_QM0_CQ_PTR_HI_2 0xDA0198 + +#define mmNIC3_QM0_CQ_TSIZE_2 0xDA019C + +#define mmNIC3_QM0_CQ_CTL_2 0xDA01A0 + +#define mmNIC3_QM0_CQ_PTR_LO_3 0xDA01A4 + +#define mmNIC3_QM0_CQ_PTR_HI_3 0xDA01A8 + +#define mmNIC3_QM0_CQ_TSIZE_3 0xDA01AC + +#define mmNIC3_QM0_CQ_CTL_3 0xDA01B0 + +#define mmNIC3_QM0_CQ_PTR_LO_4 0xDA01B4 + +#define mmNIC3_QM0_CQ_PTR_HI_4 0xDA01B8 + +#define mmNIC3_QM0_CQ_TSIZE_4 0xDA01BC + +#define mmNIC3_QM0_CQ_CTL_4 0xDA01C0 + +#define mmNIC3_QM0_CQ_PTR_LO_STS_0 0xDA01C4 + +#define mmNIC3_QM0_CQ_PTR_LO_STS_1 0xDA01C8 + +#define mmNIC3_QM0_CQ_PTR_LO_STS_2 0xDA01CC + +#define mmNIC3_QM0_CQ_PTR_LO_STS_3 0xDA01D0 + +#define mmNIC3_QM0_CQ_PTR_LO_STS_4 0xDA01D4 + +#define mmNIC3_QM0_CQ_PTR_HI_STS_0 0xDA01D8 + +#define mmNIC3_QM0_CQ_PTR_HI_STS_1 0xDA01DC + +#define mmNIC3_QM0_CQ_PTR_HI_STS_2 0xDA01E0 + +#define mmNIC3_QM0_CQ_PTR_HI_STS_3 0xDA01E4 + +#define mmNIC3_QM0_CQ_PTR_HI_STS_4 0xDA01E8 + +#define mmNIC3_QM0_CQ_TSIZE_STS_0 0xDA01EC + +#define mmNIC3_QM0_CQ_TSIZE_STS_1 0xDA01F0 + +#define mmNIC3_QM0_CQ_TSIZE_STS_2 0xDA01F4 + +#define mmNIC3_QM0_CQ_TSIZE_STS_3 0xDA01F8 + +#define mmNIC3_QM0_CQ_TSIZE_STS_4 0xDA01FC + +#define mmNIC3_QM0_CQ_CTL_STS_0 0xDA0200 + +#define mmNIC3_QM0_CQ_CTL_STS_1 0xDA0204 + +#define mmNIC3_QM0_CQ_CTL_STS_2 0xDA0208 + +#define mmNIC3_QM0_CQ_CTL_STS_3 0xDA020C + +#define mmNIC3_QM0_CQ_CTL_STS_4 0xDA0210 + +#define mmNIC3_QM0_CQ_IFIFO_CNT_0 0xDA0214 + +#define mmNIC3_QM0_CQ_IFIFO_CNT_1 0xDA0218 + +#define mmNIC3_QM0_CQ_IFIFO_CNT_2 0xDA021C + +#define mmNIC3_QM0_CQ_IFIFO_CNT_3 0xDA0220 + +#define mmNIC3_QM0_CQ_IFIFO_CNT_4 0xDA0224 + +#define mmNIC3_QM0_CP_MSG_BASE0_ADDR_LO_0 0xDA0228 + +#define mmNIC3_QM0_CP_MSG_BASE0_ADDR_LO_1 0xDA022C + +#define mmNIC3_QM0_CP_MSG_BASE0_ADDR_LO_2 0xDA0230 + +#define mmNIC3_QM0_CP_MSG_BASE0_ADDR_LO_3 0xDA0234 + +#define mmNIC3_QM0_CP_MSG_BASE0_ADDR_LO_4 0xDA0238 + +#define mmNIC3_QM0_CP_MSG_BASE0_ADDR_HI_0 0xDA023C + +#define mmNIC3_QM0_CP_MSG_BASE0_ADDR_HI_1 0xDA0240 + +#define mmNIC3_QM0_CP_MSG_BASE0_ADDR_HI_2 0xDA0244 + +#define mmNIC3_QM0_CP_MSG_BASE0_ADDR_HI_3 0xDA0248 + +#define mmNIC3_QM0_CP_MSG_BASE0_ADDR_HI_4 0xDA024C + +#define mmNIC3_QM0_CP_MSG_BASE1_ADDR_LO_0 0xDA0250 + +#define mmNIC3_QM0_CP_MSG_BASE1_ADDR_LO_1 0xDA0254 + +#define mmNIC3_QM0_CP_MSG_BASE1_ADDR_LO_2 0xDA0258 + +#define mmNIC3_QM0_CP_MSG_BASE1_ADDR_LO_3 0xDA025C + +#define mmNIC3_QM0_CP_MSG_BASE1_ADDR_LO_4 0xDA0260 + +#define mmNIC3_QM0_CP_MSG_BASE1_ADDR_HI_0 0xDA0264 + +#define mmNIC3_QM0_CP_MSG_BASE1_ADDR_HI_1 0xDA0268 + +#define mmNIC3_QM0_CP_MSG_BASE1_ADDR_HI_2 0xDA026C + +#define mmNIC3_QM0_CP_MSG_BASE1_ADDR_HI_3 0xDA0270 + +#define mmNIC3_QM0_CP_MSG_BASE1_ADDR_HI_4 0xDA0274 + +#define mmNIC3_QM0_CP_MSG_BASE2_ADDR_LO_0 0xDA0278 + +#define mmNIC3_QM0_CP_MSG_BASE2_ADDR_LO_1 0xDA027C + +#define mmNIC3_QM0_CP_MSG_BASE2_ADDR_LO_2 0xDA0280 + +#define mmNIC3_QM0_CP_MSG_BASE2_ADDR_LO_3 0xDA0284 + +#define mmNIC3_QM0_CP_MSG_BASE2_ADDR_LO_4 0xDA0288 + +#define mmNIC3_QM0_CP_MSG_BASE2_ADDR_HI_0 0xDA028C + +#define mmNIC3_QM0_CP_MSG_BASE2_ADDR_HI_1 0xDA0290 + +#define mmNIC3_QM0_CP_MSG_BASE2_ADDR_HI_2 0xDA0294 + +#define mmNIC3_QM0_CP_MSG_BASE2_ADDR_HI_3 0xDA0298 + +#define mmNIC3_QM0_CP_MSG_BASE2_ADDR_HI_4 0xDA029C + +#define mmNIC3_QM0_CP_MSG_BASE3_ADDR_LO_0 0xDA02A0 + +#define mmNIC3_QM0_CP_MSG_BASE3_ADDR_LO_1 0xDA02A4 + +#define mmNIC3_QM0_CP_MSG_BASE3_ADDR_LO_2 0xDA02A8 + +#define mmNIC3_QM0_CP_MSG_BASE3_ADDR_LO_3 0xDA02AC + +#define mmNIC3_QM0_CP_MSG_BASE3_ADDR_LO_4 0xDA02B0 + +#define mmNIC3_QM0_CP_MSG_BASE3_ADDR_HI_0 0xDA02B4 + +#define mmNIC3_QM0_CP_MSG_BASE3_ADDR_HI_1 0xDA02B8 + +#define mmNIC3_QM0_CP_MSG_BASE3_ADDR_HI_2 0xDA02BC + +#define mmNIC3_QM0_CP_MSG_BASE3_ADDR_HI_3 0xDA02C0 + +#define mmNIC3_QM0_CP_MSG_BASE3_ADDR_HI_4 0xDA02C4 + +#define mmNIC3_QM0_CP_LDMA_TSIZE_OFFSET_0 0xDA02C8 + +#define mmNIC3_QM0_CP_LDMA_TSIZE_OFFSET_1 0xDA02CC + +#define mmNIC3_QM0_CP_LDMA_TSIZE_OFFSET_2 0xDA02D0 + +#define mmNIC3_QM0_CP_LDMA_TSIZE_OFFSET_3 0xDA02D4 + +#define mmNIC3_QM0_CP_LDMA_TSIZE_OFFSET_4 0xDA02D8 + +#define mmNIC3_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_0 0xDA02E0 + +#define mmNIC3_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_1 0xDA02E4 + +#define mmNIC3_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_2 0xDA02E8 + +#define mmNIC3_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_3 0xDA02EC + +#define mmNIC3_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_4 0xDA02F0 + +#define mmNIC3_QM0_CP_LDMA_DST_BASE_LO_OFFSET_0 0xDA02F4 + +#define mmNIC3_QM0_CP_LDMA_DST_BASE_LO_OFFSET_1 0xDA02F8 + +#define mmNIC3_QM0_CP_LDMA_DST_BASE_LO_OFFSET_2 0xDA02FC + +#define mmNIC3_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 0xDA0300 + +#define mmNIC3_QM0_CP_LDMA_DST_BASE_LO_OFFSET_4 0xDA0304 + +#define mmNIC3_QM0_CP_FENCE0_RDATA_0 0xDA0308 + +#define mmNIC3_QM0_CP_FENCE0_RDATA_1 0xDA030C + +#define mmNIC3_QM0_CP_FENCE0_RDATA_2 0xDA0310 + +#define mmNIC3_QM0_CP_FENCE0_RDATA_3 0xDA0314 + +#define mmNIC3_QM0_CP_FENCE0_RDATA_4 0xDA0318 + +#define mmNIC3_QM0_CP_FENCE1_RDATA_0 0xDA031C + +#define mmNIC3_QM0_CP_FENCE1_RDATA_1 0xDA0320 + +#define mmNIC3_QM0_CP_FENCE1_RDATA_2 0xDA0324 + +#define mmNIC3_QM0_CP_FENCE1_RDATA_3 0xDA0328 + +#define mmNIC3_QM0_CP_FENCE1_RDATA_4 0xDA032C + +#define mmNIC3_QM0_CP_FENCE2_RDATA_0 0xDA0330 + +#define mmNIC3_QM0_CP_FENCE2_RDATA_1 0xDA0334 + +#define mmNIC3_QM0_CP_FENCE2_RDATA_2 0xDA0338 + +#define mmNIC3_QM0_CP_FENCE2_RDATA_3 0xDA033C + +#define mmNIC3_QM0_CP_FENCE2_RDATA_4 0xDA0340 + +#define mmNIC3_QM0_CP_FENCE3_RDATA_0 0xDA0344 + +#define mmNIC3_QM0_CP_FENCE3_RDATA_1 0xDA0348 + +#define mmNIC3_QM0_CP_FENCE3_RDATA_2 0xDA034C + +#define mmNIC3_QM0_CP_FENCE3_RDATA_3 0xDA0350 + +#define mmNIC3_QM0_CP_FENCE3_RDATA_4 0xDA0354 + +#define mmNIC3_QM0_CP_FENCE0_CNT_0 0xDA0358 + +#define mmNIC3_QM0_CP_FENCE0_CNT_1 0xDA035C + +#define mmNIC3_QM0_CP_FENCE0_CNT_2 0xDA0360 + +#define mmNIC3_QM0_CP_FENCE0_CNT_3 0xDA0364 + +#define mmNIC3_QM0_CP_FENCE0_CNT_4 0xDA0368 + +#define mmNIC3_QM0_CP_FENCE1_CNT_0 0xDA036C + +#define mmNIC3_QM0_CP_FENCE1_CNT_1 0xDA0370 + +#define mmNIC3_QM0_CP_FENCE1_CNT_2 0xDA0374 + +#define mmNIC3_QM0_CP_FENCE1_CNT_3 0xDA0378 + +#define mmNIC3_QM0_CP_FENCE1_CNT_4 0xDA037C + +#define mmNIC3_QM0_CP_FENCE2_CNT_0 0xDA0380 + +#define mmNIC3_QM0_CP_FENCE2_CNT_1 0xDA0384 + +#define mmNIC3_QM0_CP_FENCE2_CNT_2 0xDA0388 + +#define mmNIC3_QM0_CP_FENCE2_CNT_3 0xDA038C + +#define mmNIC3_QM0_CP_FENCE2_CNT_4 0xDA0390 + +#define mmNIC3_QM0_CP_FENCE3_CNT_0 0xDA0394 + +#define mmNIC3_QM0_CP_FENCE3_CNT_1 0xDA0398 + +#define mmNIC3_QM0_CP_FENCE3_CNT_2 0xDA039C + +#define mmNIC3_QM0_CP_FENCE3_CNT_3 0xDA03A0 + +#define mmNIC3_QM0_CP_FENCE3_CNT_4 0xDA03A4 + +#define mmNIC3_QM0_CP_STS_0 0xDA03A8 + +#define mmNIC3_QM0_CP_STS_1 0xDA03AC + +#define mmNIC3_QM0_CP_STS_2 0xDA03B0 + +#define mmNIC3_QM0_CP_STS_3 0xDA03B4 + +#define mmNIC3_QM0_CP_STS_4 0xDA03B8 + +#define mmNIC3_QM0_CP_CURRENT_INST_LO_0 0xDA03BC + +#define mmNIC3_QM0_CP_CURRENT_INST_LO_1 0xDA03C0 + +#define mmNIC3_QM0_CP_CURRENT_INST_LO_2 0xDA03C4 + +#define mmNIC3_QM0_CP_CURRENT_INST_LO_3 0xDA03C8 + +#define mmNIC3_QM0_CP_CURRENT_INST_LO_4 0xDA03CC + +#define mmNIC3_QM0_CP_CURRENT_INST_HI_0 0xDA03D0 + +#define mmNIC3_QM0_CP_CURRENT_INST_HI_1 0xDA03D4 + +#define mmNIC3_QM0_CP_CURRENT_INST_HI_2 0xDA03D8 + +#define mmNIC3_QM0_CP_CURRENT_INST_HI_3 0xDA03DC + +#define mmNIC3_QM0_CP_CURRENT_INST_HI_4 0xDA03E0 + +#define mmNIC3_QM0_CP_BARRIER_CFG_0 0xDA03F4 + +#define mmNIC3_QM0_CP_BARRIER_CFG_1 0xDA03F8 + +#define mmNIC3_QM0_CP_BARRIER_CFG_2 0xDA03FC + +#define mmNIC3_QM0_CP_BARRIER_CFG_3 0xDA0400 + +#define mmNIC3_QM0_CP_BARRIER_CFG_4 0xDA0404 + +#define mmNIC3_QM0_CP_DBG_0_0 0xDA0408 + +#define mmNIC3_QM0_CP_DBG_0_1 0xDA040C + +#define mmNIC3_QM0_CP_DBG_0_2 0xDA0410 + +#define mmNIC3_QM0_CP_DBG_0_3 0xDA0414 + +#define mmNIC3_QM0_CP_DBG_0_4 0xDA0418 + +#define mmNIC3_QM0_CP_ARUSER_31_11_0 0xDA041C + +#define mmNIC3_QM0_CP_ARUSER_31_11_1 0xDA0420 + +#define mmNIC3_QM0_CP_ARUSER_31_11_2 0xDA0424 + +#define mmNIC3_QM0_CP_ARUSER_31_11_3 0xDA0428 + +#define mmNIC3_QM0_CP_ARUSER_31_11_4 0xDA042C + +#define mmNIC3_QM0_CP_AWUSER_31_11_0 0xDA0430 + +#define mmNIC3_QM0_CP_AWUSER_31_11_1 0xDA0434 + +#define mmNIC3_QM0_CP_AWUSER_31_11_2 0xDA0438 + +#define mmNIC3_QM0_CP_AWUSER_31_11_3 0xDA043C + +#define mmNIC3_QM0_CP_AWUSER_31_11_4 0xDA0440 + +#define mmNIC3_QM0_ARB_CFG_0 0xDA0A00 + +#define mmNIC3_QM0_ARB_CHOISE_Q_PUSH 0xDA0A04 + +#define mmNIC3_QM0_ARB_WRR_WEIGHT_0 0xDA0A08 + +#define mmNIC3_QM0_ARB_WRR_WEIGHT_1 0xDA0A0C + +#define mmNIC3_QM0_ARB_WRR_WEIGHT_2 0xDA0A10 + +#define mmNIC3_QM0_ARB_WRR_WEIGHT_3 0xDA0A14 + +#define mmNIC3_QM0_ARB_CFG_1 0xDA0A18 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_0 0xDA0A20 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_1 0xDA0A24 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_2 0xDA0A28 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_3 0xDA0A2C + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_4 0xDA0A30 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_5 0xDA0A34 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_6 0xDA0A38 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_7 0xDA0A3C + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_8 0xDA0A40 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_9 0xDA0A44 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_10 0xDA0A48 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_11 0xDA0A4C + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_12 0xDA0A50 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_13 0xDA0A54 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_14 0xDA0A58 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_15 0xDA0A5C + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_16 0xDA0A60 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_17 0xDA0A64 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_18 0xDA0A68 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_19 0xDA0A6C + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_20 0xDA0A70 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_21 0xDA0A74 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_22 0xDA0A78 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_23 0xDA0A7C + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_24 0xDA0A80 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_25 0xDA0A84 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_26 0xDA0A88 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_27 0xDA0A8C + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_28 0xDA0A90 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_29 0xDA0A94 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_30 0xDA0A98 + +#define mmNIC3_QM0_ARB_MST_AVAIL_CRED_31 0xDA0A9C + +#define mmNIC3_QM0_ARB_MST_CRED_INC 0xDA0AA0 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_0 0xDA0AA4 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_1 0xDA0AA8 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_2 0xDA0AAC + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_3 0xDA0AB0 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_4 0xDA0AB4 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_5 0xDA0AB8 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_6 0xDA0ABC + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_7 0xDA0AC0 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_8 0xDA0AC4 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_9 0xDA0AC8 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_10 0xDA0ACC + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_11 0xDA0AD0 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_12 0xDA0AD4 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_13 0xDA0AD8 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_14 0xDA0ADC + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_15 0xDA0AE0 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_16 0xDA0AE4 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_17 0xDA0AE8 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_18 0xDA0AEC + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_19 0xDA0AF0 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_20 0xDA0AF4 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_21 0xDA0AF8 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_22 0xDA0AFC + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_23 0xDA0B00 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_24 0xDA0B04 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_25 0xDA0B08 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_26 0xDA0B0C + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_27 0xDA0B10 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_28 0xDA0B14 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_29 0xDA0B18 + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_30 0xDA0B1C + +#define mmNIC3_QM0_ARB_MST_CHOISE_PUSH_OFST_31 0xDA0B20 + +#define mmNIC3_QM0_ARB_SLV_MASTER_INC_CRED_OFST 0xDA0B28 + +#define mmNIC3_QM0_ARB_MST_SLAVE_EN 0xDA0B2C + +#define mmNIC3_QM0_ARB_MST_QUIET_PER 0xDA0B34 + +#define mmNIC3_QM0_ARB_SLV_CHOISE_WDT 0xDA0B38 + +#define mmNIC3_QM0_ARB_SLV_ID 0xDA0B3C + +#define mmNIC3_QM0_ARB_MSG_MAX_INFLIGHT 0xDA0B44 + +#define mmNIC3_QM0_ARB_MSG_AWUSER_31_11 0xDA0B48 + +#define mmNIC3_QM0_ARB_MSG_AWUSER_SEC_PROP 0xDA0B4C + +#define mmNIC3_QM0_ARB_MSG_AWUSER_NON_SEC_PROP 0xDA0B50 + +#define mmNIC3_QM0_ARB_BASE_LO 0xDA0B54 + +#define mmNIC3_QM0_ARB_BASE_HI 0xDA0B58 + +#define mmNIC3_QM0_ARB_STATE_STS 0xDA0B80 + +#define mmNIC3_QM0_ARB_CHOISE_FULLNESS_STS 0xDA0B84 + +#define mmNIC3_QM0_ARB_MSG_STS 0xDA0B88 + +#define mmNIC3_QM0_ARB_SLV_CHOISE_Q_HEAD 0xDA0B8C + +#define mmNIC3_QM0_ARB_ERR_CAUSE 0xDA0B9C + +#define mmNIC3_QM0_ARB_ERR_MSG_EN 0xDA0BA0 + +#define mmNIC3_QM0_ARB_ERR_STS_DRP 0xDA0BA8 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_0 0xDA0BB0 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_1 0xDA0BB4 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_2 0xDA0BB8 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_3 0xDA0BBC + +#define mmNIC3_QM0_ARB_MST_CRED_STS_4 0xDA0BC0 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_5 0xDA0BC4 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_6 0xDA0BC8 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_7 0xDA0BCC + +#define mmNIC3_QM0_ARB_MST_CRED_STS_8 0xDA0BD0 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_9 0xDA0BD4 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_10 0xDA0BD8 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_11 0xDA0BDC + +#define mmNIC3_QM0_ARB_MST_CRED_STS_12 0xDA0BE0 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_13 0xDA0BE4 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_14 0xDA0BE8 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_15 0xDA0BEC + +#define mmNIC3_QM0_ARB_MST_CRED_STS_16 0xDA0BF0 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_17 0xDA0BF4 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_18 0xDA0BF8 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_19 0xDA0BFC + +#define mmNIC3_QM0_ARB_MST_CRED_STS_20 0xDA0C00 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_21 0xDA0C04 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_22 0xDA0C08 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_23 0xDA0C0C + +#define mmNIC3_QM0_ARB_MST_CRED_STS_24 0xDA0C10 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_25 0xDA0C14 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_26 0xDA0C18 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_27 0xDA0C1C + +#define mmNIC3_QM0_ARB_MST_CRED_STS_28 0xDA0C20 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_29 0xDA0C24 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_30 0xDA0C28 + +#define mmNIC3_QM0_ARB_MST_CRED_STS_31 0xDA0C2C + +#define mmNIC3_QM0_CGM_CFG 0xDA0C70 + +#define mmNIC3_QM0_CGM_STS 0xDA0C74 + +#define mmNIC3_QM0_CGM_CFG1 0xDA0C78 + +#define mmNIC3_QM0_LOCAL_RANGE_BASE 0xDA0C80 + +#define mmNIC3_QM0_LOCAL_RANGE_SIZE 0xDA0C84 + +#define mmNIC3_QM0_CSMR_STRICT_PRIO_CFG 0xDA0C90 + +#define mmNIC3_QM0_HBW_RD_RATE_LIM_CFG_1 0xDA0C94 + +#define mmNIC3_QM0_LBW_WR_RATE_LIM_CFG_0 0xDA0C98 + +#define mmNIC3_QM0_LBW_WR_RATE_LIM_CFG_1 0xDA0C9C + +#define mmNIC3_QM0_HBW_RD_RATE_LIM_CFG_0 0xDA0CA0 + +#define mmNIC3_QM0_GLBL_AXCACHE 0xDA0CA4 + +#define mmNIC3_QM0_IND_GW_APB_CFG 0xDA0CB0 + +#define mmNIC3_QM0_IND_GW_APB_WDATA 0xDA0CB4 + +#define mmNIC3_QM0_IND_GW_APB_RDATA 0xDA0CB8 + +#define mmNIC3_QM0_IND_GW_APB_STATUS 0xDA0CBC + +#define mmNIC3_QM0_GLBL_ERR_ADDR_LO 0xDA0CD0 + +#define mmNIC3_QM0_GLBL_ERR_ADDR_HI 0xDA0CD4 + +#define mmNIC3_QM0_GLBL_ERR_WDATA 0xDA0CD8 + +#define mmNIC3_QM0_GLBL_MEM_INIT_BUSY 0xDA0D00 + +#endif /* ASIC_REG_NIC3_QM0_REGS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/nic3_qm1_regs.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic3_qm1_regs.h new file mode 100644 index 000000000000..7fa040f65004 --- /dev/null +++ b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic3_qm1_regs.h @@ -0,0 +1,834 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright 2016-2018 HabanaLabs, Ltd. + * All Rights Reserved. + * + */ + +/************************************ + ** This is an auto-generated file ** + ** DO NOT EDIT BELOW ** + ************************************/ + +#ifndef ASIC_REG_NIC3_QM1_REGS_H_ +#define ASIC_REG_NIC3_QM1_REGS_H_ + +/* + ***************************************** + * NIC3_QM1 (Prototype: QMAN) + ***************************************** + */ + +#define mmNIC3_QM1_GLBL_CFG0 0xDA2000 + +#define mmNIC3_QM1_GLBL_CFG1 0xDA2004 + +#define mmNIC3_QM1_GLBL_PROT 0xDA2008 + +#define mmNIC3_QM1_GLBL_ERR_CFG 0xDA200C + +#define mmNIC3_QM1_GLBL_SECURE_PROPS_0 0xDA2010 + +#define mmNIC3_QM1_GLBL_SECURE_PROPS_1 0xDA2014 + +#define mmNIC3_QM1_GLBL_SECURE_PROPS_2 0xDA2018 + +#define mmNIC3_QM1_GLBL_SECURE_PROPS_3 0xDA201C + +#define mmNIC3_QM1_GLBL_SECURE_PROPS_4 0xDA2020 + +#define mmNIC3_QM1_GLBL_NON_SECURE_PROPS_0 0xDA2024 + +#define mmNIC3_QM1_GLBL_NON_SECURE_PROPS_1 0xDA2028 + +#define mmNIC3_QM1_GLBL_NON_SECURE_PROPS_2 0xDA202C + +#define mmNIC3_QM1_GLBL_NON_SECURE_PROPS_3 0xDA2030 + +#define mmNIC3_QM1_GLBL_NON_SECURE_PROPS_4 0xDA2034 + +#define mmNIC3_QM1_GLBL_STS0 0xDA2038 + +#define mmNIC3_QM1_GLBL_STS1_0 0xDA2040 + +#define mmNIC3_QM1_GLBL_STS1_1 0xDA2044 + +#define mmNIC3_QM1_GLBL_STS1_2 0xDA2048 + +#define mmNIC3_QM1_GLBL_STS1_3 0xDA204C + +#define mmNIC3_QM1_GLBL_STS1_4 0xDA2050 + +#define mmNIC3_QM1_GLBL_MSG_EN_0 0xDA2054 + +#define mmNIC3_QM1_GLBL_MSG_EN_1 0xDA2058 + +#define mmNIC3_QM1_GLBL_MSG_EN_2 0xDA205C + +#define mmNIC3_QM1_GLBL_MSG_EN_3 0xDA2060 + +#define mmNIC3_QM1_GLBL_MSG_EN_4 0xDA2068 + +#define mmNIC3_QM1_PQ_BASE_LO_0 0xDA2070 + +#define mmNIC3_QM1_PQ_BASE_LO_1 0xDA2074 + +#define mmNIC3_QM1_PQ_BASE_LO_2 0xDA2078 + +#define mmNIC3_QM1_PQ_BASE_LO_3 0xDA207C + +#define mmNIC3_QM1_PQ_BASE_HI_0 0xDA2080 + +#define mmNIC3_QM1_PQ_BASE_HI_1 0xDA2084 + +#define mmNIC3_QM1_PQ_BASE_HI_2 0xDA2088 + +#define mmNIC3_QM1_PQ_BASE_HI_3 0xDA208C + +#define mmNIC3_QM1_PQ_SIZE_0 0xDA2090 + +#define mmNIC3_QM1_PQ_SIZE_1 0xDA2094 + +#define mmNIC3_QM1_PQ_SIZE_2 0xDA2098 + +#define mmNIC3_QM1_PQ_SIZE_3 0xDA209C + +#define mmNIC3_QM1_PQ_PI_0 0xDA20A0 + +#define mmNIC3_QM1_PQ_PI_1 0xDA20A4 + +#define mmNIC3_QM1_PQ_PI_2 0xDA20A8 + +#define mmNIC3_QM1_PQ_PI_3 0xDA20AC + +#define mmNIC3_QM1_PQ_CI_0 0xDA20B0 + +#define mmNIC3_QM1_PQ_CI_1 0xDA20B4 + +#define mmNIC3_QM1_PQ_CI_2 0xDA20B8 + +#define mmNIC3_QM1_PQ_CI_3 0xDA20BC + +#define mmNIC3_QM1_PQ_CFG0_0 0xDA20C0 + +#define mmNIC3_QM1_PQ_CFG0_1 0xDA20C4 + +#define mmNIC3_QM1_PQ_CFG0_2 0xDA20C8 + +#define mmNIC3_QM1_PQ_CFG0_3 0xDA20CC + +#define mmNIC3_QM1_PQ_CFG1_0 0xDA20D0 + +#define mmNIC3_QM1_PQ_CFG1_1 0xDA20D4 + +#define mmNIC3_QM1_PQ_CFG1_2 0xDA20D8 + +#define mmNIC3_QM1_PQ_CFG1_3 0xDA20DC + +#define mmNIC3_QM1_PQ_ARUSER_31_11_0 0xDA20E0 + +#define mmNIC3_QM1_PQ_ARUSER_31_11_1 0xDA20E4 + +#define mmNIC3_QM1_PQ_ARUSER_31_11_2 0xDA20E8 + +#define mmNIC3_QM1_PQ_ARUSER_31_11_3 0xDA20EC + +#define mmNIC3_QM1_PQ_STS0_0 0xDA20F0 + +#define mmNIC3_QM1_PQ_STS0_1 0xDA20F4 + +#define mmNIC3_QM1_PQ_STS0_2 0xDA20F8 + +#define mmNIC3_QM1_PQ_STS0_3 0xDA20FC + +#define mmNIC3_QM1_PQ_STS1_0 0xDA2100 + +#define mmNIC3_QM1_PQ_STS1_1 0xDA2104 + +#define mmNIC3_QM1_PQ_STS1_2 0xDA2108 + +#define mmNIC3_QM1_PQ_STS1_3 0xDA210C + +#define mmNIC3_QM1_CQ_CFG0_0 0xDA2110 + +#define mmNIC3_QM1_CQ_CFG0_1 0xDA2114 + +#define mmNIC3_QM1_CQ_CFG0_2 0xDA2118 + +#define mmNIC3_QM1_CQ_CFG0_3 0xDA211C + +#define mmNIC3_QM1_CQ_CFG0_4 0xDA2120 + +#define mmNIC3_QM1_CQ_CFG1_0 0xDA2124 + +#define mmNIC3_QM1_CQ_CFG1_1 0xDA2128 + +#define mmNIC3_QM1_CQ_CFG1_2 0xDA212C + +#define mmNIC3_QM1_CQ_CFG1_3 0xDA2130 + +#define mmNIC3_QM1_CQ_CFG1_4 0xDA2134 + +#define mmNIC3_QM1_CQ_ARUSER_31_11_0 0xDA2138 + +#define mmNIC3_QM1_CQ_ARUSER_31_11_1 0xDA213C + +#define mmNIC3_QM1_CQ_ARUSER_31_11_2 0xDA2140 + +#define mmNIC3_QM1_CQ_ARUSER_31_11_3 0xDA2144 + +#define mmNIC3_QM1_CQ_ARUSER_31_11_4 0xDA2148 + +#define mmNIC3_QM1_CQ_STS0_0 0xDA214C + +#define mmNIC3_QM1_CQ_STS0_1 0xDA2150 + +#define mmNIC3_QM1_CQ_STS0_2 0xDA2154 + +#define mmNIC3_QM1_CQ_STS0_3 0xDA2158 + +#define mmNIC3_QM1_CQ_STS0_4 0xDA215C + +#define mmNIC3_QM1_CQ_STS1_0 0xDA2160 + +#define mmNIC3_QM1_CQ_STS1_1 0xDA2164 + +#define mmNIC3_QM1_CQ_STS1_2 0xDA2168 + +#define mmNIC3_QM1_CQ_STS1_3 0xDA216C + +#define mmNIC3_QM1_CQ_STS1_4 0xDA2170 + +#define mmNIC3_QM1_CQ_PTR_LO_0 0xDA2174 + +#define mmNIC3_QM1_CQ_PTR_HI_0 0xDA2178 + +#define mmNIC3_QM1_CQ_TSIZE_0 0xDA217C + +#define mmNIC3_QM1_CQ_CTL_0 0xDA2180 + +#define mmNIC3_QM1_CQ_PTR_LO_1 0xDA2184 + +#define mmNIC3_QM1_CQ_PTR_HI_1 0xDA2188 + +#define mmNIC3_QM1_CQ_TSIZE_1 0xDA218C + +#define mmNIC3_QM1_CQ_CTL_1 0xDA2190 + +#define mmNIC3_QM1_CQ_PTR_LO_2 0xDA2194 + +#define mmNIC3_QM1_CQ_PTR_HI_2 0xDA2198 + +#define mmNIC3_QM1_CQ_TSIZE_2 0xDA219C + +#define mmNIC3_QM1_CQ_CTL_2 0xDA21A0 + +#define mmNIC3_QM1_CQ_PTR_LO_3 0xDA21A4 + +#define mmNIC3_QM1_CQ_PTR_HI_3 0xDA21A8 + +#define mmNIC3_QM1_CQ_TSIZE_3 0xDA21AC + +#define mmNIC3_QM1_CQ_CTL_3 0xDA21B0 + +#define mmNIC3_QM1_CQ_PTR_LO_4 0xDA21B4 + +#define mmNIC3_QM1_CQ_PTR_HI_4 0xDA21B8 + +#define mmNIC3_QM1_CQ_TSIZE_4 0xDA21BC + +#define mmNIC3_QM1_CQ_CTL_4 0xDA21C0 + +#define mmNIC3_QM1_CQ_PTR_LO_STS_0 0xDA21C4 + +#define mmNIC3_QM1_CQ_PTR_LO_STS_1 0xDA21C8 + +#define mmNIC3_QM1_CQ_PTR_LO_STS_2 0xDA21CC + +#define mmNIC3_QM1_CQ_PTR_LO_STS_3 0xDA21D0 + +#define mmNIC3_QM1_CQ_PTR_LO_STS_4 0xDA21D4 + +#define mmNIC3_QM1_CQ_PTR_HI_STS_0 0xDA21D8 + +#define mmNIC3_QM1_CQ_PTR_HI_STS_1 0xDA21DC + +#define mmNIC3_QM1_CQ_PTR_HI_STS_2 0xDA21E0 + +#define mmNIC3_QM1_CQ_PTR_HI_STS_3 0xDA21E4 + +#define mmNIC3_QM1_CQ_PTR_HI_STS_4 0xDA21E8 + +#define mmNIC3_QM1_CQ_TSIZE_STS_0 0xDA21EC + +#define mmNIC3_QM1_CQ_TSIZE_STS_1 0xDA21F0 + +#define mmNIC3_QM1_CQ_TSIZE_STS_2 0xDA21F4 + +#define mmNIC3_QM1_CQ_TSIZE_STS_3 0xDA21F8 + +#define mmNIC3_QM1_CQ_TSIZE_STS_4 0xDA21FC + +#define mmNIC3_QM1_CQ_CTL_STS_0 0xDA2200 + +#define mmNIC3_QM1_CQ_CTL_STS_1 0xDA2204 + +#define mmNIC3_QM1_CQ_CTL_STS_2 0xDA2208 + +#define mmNIC3_QM1_CQ_CTL_STS_3 0xDA220C + +#define mmNIC3_QM1_CQ_CTL_STS_4 0xDA2210 + +#define mmNIC3_QM1_CQ_IFIFO_CNT_0 0xDA2214 + +#define mmNIC3_QM1_CQ_IFIFO_CNT_1 0xDA2218 + +#define mmNIC3_QM1_CQ_IFIFO_CNT_2 0xDA221C + +#define mmNIC3_QM1_CQ_IFIFO_CNT_3 0xDA2220 + +#define mmNIC3_QM1_CQ_IFIFO_CNT_4 0xDA2224 + +#define mmNIC3_QM1_CP_MSG_BASE0_ADDR_LO_0 0xDA2228 + +#define mmNIC3_QM1_CP_MSG_BASE0_ADDR_LO_1 0xDA222C + +#define mmNIC3_QM1_CP_MSG_BASE0_ADDR_LO_2 0xDA2230 + +#define mmNIC3_QM1_CP_MSG_BASE0_ADDR_LO_3 0xDA2234 + +#define mmNIC3_QM1_CP_MSG_BASE0_ADDR_LO_4 0xDA2238 + +#define mmNIC3_QM1_CP_MSG_BASE0_ADDR_HI_0 0xDA223C + +#define mmNIC3_QM1_CP_MSG_BASE0_ADDR_HI_1 0xDA2240 + +#define mmNIC3_QM1_CP_MSG_BASE0_ADDR_HI_2 0xDA2244 + +#define mmNIC3_QM1_CP_MSG_BASE0_ADDR_HI_3 0xDA2248 + +#define mmNIC3_QM1_CP_MSG_BASE0_ADDR_HI_4 0xDA224C + +#define mmNIC3_QM1_CP_MSG_BASE1_ADDR_LO_0 0xDA2250 + +#define mmNIC3_QM1_CP_MSG_BASE1_ADDR_LO_1 0xDA2254 + +#define mmNIC3_QM1_CP_MSG_BASE1_ADDR_LO_2 0xDA2258 + +#define mmNIC3_QM1_CP_MSG_BASE1_ADDR_LO_3 0xDA225C + +#define mmNIC3_QM1_CP_MSG_BASE1_ADDR_LO_4 0xDA2260 + +#define mmNIC3_QM1_CP_MSG_BASE1_ADDR_HI_0 0xDA2264 + +#define mmNIC3_QM1_CP_MSG_BASE1_ADDR_HI_1 0xDA2268 + +#define mmNIC3_QM1_CP_MSG_BASE1_ADDR_HI_2 0xDA226C + +#define mmNIC3_QM1_CP_MSG_BASE1_ADDR_HI_3 0xDA2270 + +#define mmNIC3_QM1_CP_MSG_BASE1_ADDR_HI_4 0xDA2274 + +#define mmNIC3_QM1_CP_MSG_BASE2_ADDR_LO_0 0xDA2278 + +#define mmNIC3_QM1_CP_MSG_BASE2_ADDR_LO_1 0xDA227C + +#define mmNIC3_QM1_CP_MSG_BASE2_ADDR_LO_2 0xDA2280 + +#define mmNIC3_QM1_CP_MSG_BASE2_ADDR_LO_3 0xDA2284 + +#define mmNIC3_QM1_CP_MSG_BASE2_ADDR_LO_4 0xDA2288 + +#define mmNIC3_QM1_CP_MSG_BASE2_ADDR_HI_0 0xDA228C + +#define mmNIC3_QM1_CP_MSG_BASE2_ADDR_HI_1 0xDA2290 + +#define mmNIC3_QM1_CP_MSG_BASE2_ADDR_HI_2 0xDA2294 + +#define mmNIC3_QM1_CP_MSG_BASE2_ADDR_HI_3 0xDA2298 + +#define mmNIC3_QM1_CP_MSG_BASE2_ADDR_HI_4 0xDA229C + +#define mmNIC3_QM1_CP_MSG_BASE3_ADDR_LO_0 0xDA22A0 + +#define mmNIC3_QM1_CP_MSG_BASE3_ADDR_LO_1 0xDA22A4 + +#define mmNIC3_QM1_CP_MSG_BASE3_ADDR_LO_2 0xDA22A8 + +#define mmNIC3_QM1_CP_MSG_BASE3_ADDR_LO_3 0xDA22AC + +#define mmNIC3_QM1_CP_MSG_BASE3_ADDR_LO_4 0xDA22B0 + +#define mmNIC3_QM1_CP_MSG_BASE3_ADDR_HI_0 0xDA22B4 + +#define mmNIC3_QM1_CP_MSG_BASE3_ADDR_HI_1 0xDA22B8 + +#define mmNIC3_QM1_CP_MSG_BASE3_ADDR_HI_2 0xDA22BC + +#define mmNIC3_QM1_CP_MSG_BASE3_ADDR_HI_3 0xDA22C0 + +#define mmNIC3_QM1_CP_MSG_BASE3_ADDR_HI_4 0xDA22C4 + +#define mmNIC3_QM1_CP_LDMA_TSIZE_OFFSET_0 0xDA22C8 + +#define mmNIC3_QM1_CP_LDMA_TSIZE_OFFSET_1 0xDA22CC + +#define mmNIC3_QM1_CP_LDMA_TSIZE_OFFSET_2 0xDA22D0 + +#define mmNIC3_QM1_CP_LDMA_TSIZE_OFFSET_3 0xDA22D4 + +#define mmNIC3_QM1_CP_LDMA_TSIZE_OFFSET_4 0xDA22D8 + +#define mmNIC3_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_0 0xDA22E0 + +#define mmNIC3_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_1 0xDA22E4 + +#define mmNIC3_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_2 0xDA22E8 + +#define mmNIC3_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_3 0xDA22EC + +#define mmNIC3_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_4 0xDA22F0 + +#define mmNIC3_QM1_CP_LDMA_DST_BASE_LO_OFFSET_0 0xDA22F4 + +#define mmNIC3_QM1_CP_LDMA_DST_BASE_LO_OFFSET_1 0xDA22F8 + +#define mmNIC3_QM1_CP_LDMA_DST_BASE_LO_OFFSET_2 0xDA22FC + +#define mmNIC3_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 0xDA2300 + +#define mmNIC3_QM1_CP_LDMA_DST_BASE_LO_OFFSET_4 0xDA2304 + +#define mmNIC3_QM1_CP_FENCE0_RDATA_0 0xDA2308 + +#define mmNIC3_QM1_CP_FENCE0_RDATA_1 0xDA230C + +#define mmNIC3_QM1_CP_FENCE0_RDATA_2 0xDA2310 + +#define mmNIC3_QM1_CP_FENCE0_RDATA_3 0xDA2314 + +#define mmNIC3_QM1_CP_FENCE0_RDATA_4 0xDA2318 + +#define mmNIC3_QM1_CP_FENCE1_RDATA_0 0xDA231C + +#define mmNIC3_QM1_CP_FENCE1_RDATA_1 0xDA2320 + +#define mmNIC3_QM1_CP_FENCE1_RDATA_2 0xDA2324 + +#define mmNIC3_QM1_CP_FENCE1_RDATA_3 0xDA2328 + +#define mmNIC3_QM1_CP_FENCE1_RDATA_4 0xDA232C + +#define mmNIC3_QM1_CP_FENCE2_RDATA_0 0xDA2330 + +#define mmNIC3_QM1_CP_FENCE2_RDATA_1 0xDA2334 + +#define mmNIC3_QM1_CP_FENCE2_RDATA_2 0xDA2338 + +#define mmNIC3_QM1_CP_FENCE2_RDATA_3 0xDA233C + +#define mmNIC3_QM1_CP_FENCE2_RDATA_4 0xDA2340 + +#define mmNIC3_QM1_CP_FENCE3_RDATA_0 0xDA2344 + +#define mmNIC3_QM1_CP_FENCE3_RDATA_1 0xDA2348 + +#define mmNIC3_QM1_CP_FENCE3_RDATA_2 0xDA234C + +#define mmNIC3_QM1_CP_FENCE3_RDATA_3 0xDA2350 + +#define mmNIC3_QM1_CP_FENCE3_RDATA_4 0xDA2354 + +#define mmNIC3_QM1_CP_FENCE0_CNT_0 0xDA2358 + +#define mmNIC3_QM1_CP_FENCE0_CNT_1 0xDA235C + +#define mmNIC3_QM1_CP_FENCE0_CNT_2 0xDA2360 + +#define mmNIC3_QM1_CP_FENCE0_CNT_3 0xDA2364 + +#define mmNIC3_QM1_CP_FENCE0_CNT_4 0xDA2368 + +#define mmNIC3_QM1_CP_FENCE1_CNT_0 0xDA236C + +#define mmNIC3_QM1_CP_FENCE1_CNT_1 0xDA2370 + +#define mmNIC3_QM1_CP_FENCE1_CNT_2 0xDA2374 + +#define mmNIC3_QM1_CP_FENCE1_CNT_3 0xDA2378 + +#define mmNIC3_QM1_CP_FENCE1_CNT_4 0xDA237C + +#define mmNIC3_QM1_CP_FENCE2_CNT_0 0xDA2380 + +#define mmNIC3_QM1_CP_FENCE2_CNT_1 0xDA2384 + +#define mmNIC3_QM1_CP_FENCE2_CNT_2 0xDA2388 + +#define mmNIC3_QM1_CP_FENCE2_CNT_3 0xDA238C + +#define mmNIC3_QM1_CP_FENCE2_CNT_4 0xDA2390 + +#define mmNIC3_QM1_CP_FENCE3_CNT_0 0xDA2394 + +#define mmNIC3_QM1_CP_FENCE3_CNT_1 0xDA2398 + +#define mmNIC3_QM1_CP_FENCE3_CNT_2 0xDA239C + +#define mmNIC3_QM1_CP_FENCE3_CNT_3 0xDA23A0 + +#define mmNIC3_QM1_CP_FENCE3_CNT_4 0xDA23A4 + +#define mmNIC3_QM1_CP_STS_0 0xDA23A8 + +#define mmNIC3_QM1_CP_STS_1 0xDA23AC + +#define mmNIC3_QM1_CP_STS_2 0xDA23B0 + +#define mmNIC3_QM1_CP_STS_3 0xDA23B4 + +#define mmNIC3_QM1_CP_STS_4 0xDA23B8 + +#define mmNIC3_QM1_CP_CURRENT_INST_LO_0 0xDA23BC + +#define mmNIC3_QM1_CP_CURRENT_INST_LO_1 0xDA23C0 + +#define mmNIC3_QM1_CP_CURRENT_INST_LO_2 0xDA23C4 + +#define mmNIC3_QM1_CP_CURRENT_INST_LO_3 0xDA23C8 + +#define mmNIC3_QM1_CP_CURRENT_INST_LO_4 0xDA23CC + +#define mmNIC3_QM1_CP_CURRENT_INST_HI_0 0xDA23D0 + +#define mmNIC3_QM1_CP_CURRENT_INST_HI_1 0xDA23D4 + +#define mmNIC3_QM1_CP_CURRENT_INST_HI_2 0xDA23D8 + +#define mmNIC3_QM1_CP_CURRENT_INST_HI_3 0xDA23DC + +#define mmNIC3_QM1_CP_CURRENT_INST_HI_4 0xDA23E0 + +#define mmNIC3_QM1_CP_BARRIER_CFG_0 0xDA23F4 + +#define mmNIC3_QM1_CP_BARRIER_CFG_1 0xDA23F8 + +#define mmNIC3_QM1_CP_BARRIER_CFG_2 0xDA23FC + +#define mmNIC3_QM1_CP_BARRIER_CFG_3 0xDA2400 + +#define mmNIC3_QM1_CP_BARRIER_CFG_4 0xDA2404 + +#define mmNIC3_QM1_CP_DBG_0_0 0xDA2408 + +#define mmNIC3_QM1_CP_DBG_0_1 0xDA240C + +#define mmNIC3_QM1_CP_DBG_0_2 0xDA2410 + +#define mmNIC3_QM1_CP_DBG_0_3 0xDA2414 + +#define mmNIC3_QM1_CP_DBG_0_4 0xDA2418 + +#define mmNIC3_QM1_CP_ARUSER_31_11_0 0xDA241C + +#define mmNIC3_QM1_CP_ARUSER_31_11_1 0xDA2420 + +#define mmNIC3_QM1_CP_ARUSER_31_11_2 0xDA2424 + +#define mmNIC3_QM1_CP_ARUSER_31_11_3 0xDA2428 + +#define mmNIC3_QM1_CP_ARUSER_31_11_4 0xDA242C + +#define mmNIC3_QM1_CP_AWUSER_31_11_0 0xDA2430 + +#define mmNIC3_QM1_CP_AWUSER_31_11_1 0xDA2434 + +#define mmNIC3_QM1_CP_AWUSER_31_11_2 0xDA2438 + +#define mmNIC3_QM1_CP_AWUSER_31_11_3 0xDA243C + +#define mmNIC3_QM1_CP_AWUSER_31_11_4 0xDA2440 + +#define mmNIC3_QM1_ARB_CFG_0 0xDA2A00 + +#define mmNIC3_QM1_ARB_CHOISE_Q_PUSH 0xDA2A04 + +#define mmNIC3_QM1_ARB_WRR_WEIGHT_0 0xDA2A08 + +#define mmNIC3_QM1_ARB_WRR_WEIGHT_1 0xDA2A0C + +#define mmNIC3_QM1_ARB_WRR_WEIGHT_2 0xDA2A10 + +#define mmNIC3_QM1_ARB_WRR_WEIGHT_3 0xDA2A14 + +#define mmNIC3_QM1_ARB_CFG_1 0xDA2A18 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_0 0xDA2A20 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_1 0xDA2A24 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_2 0xDA2A28 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_3 0xDA2A2C + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_4 0xDA2A30 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_5 0xDA2A34 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_6 0xDA2A38 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_7 0xDA2A3C + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_8 0xDA2A40 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_9 0xDA2A44 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_10 0xDA2A48 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_11 0xDA2A4C + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_12 0xDA2A50 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_13 0xDA2A54 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_14 0xDA2A58 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_15 0xDA2A5C + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_16 0xDA2A60 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_17 0xDA2A64 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_18 0xDA2A68 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_19 0xDA2A6C + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_20 0xDA2A70 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_21 0xDA2A74 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_22 0xDA2A78 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_23 0xDA2A7C + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_24 0xDA2A80 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_25 0xDA2A84 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_26 0xDA2A88 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_27 0xDA2A8C + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_28 0xDA2A90 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_29 0xDA2A94 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_30 0xDA2A98 + +#define mmNIC3_QM1_ARB_MST_AVAIL_CRED_31 0xDA2A9C + +#define mmNIC3_QM1_ARB_MST_CRED_INC 0xDA2AA0 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_0 0xDA2AA4 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_1 0xDA2AA8 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_2 0xDA2AAC + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_3 0xDA2AB0 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_4 0xDA2AB4 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_5 0xDA2AB8 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_6 0xDA2ABC + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_7 0xDA2AC0 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_8 0xDA2AC4 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_9 0xDA2AC8 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_10 0xDA2ACC + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_11 0xDA2AD0 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_12 0xDA2AD4 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_13 0xDA2AD8 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_14 0xDA2ADC + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_15 0xDA2AE0 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_16 0xDA2AE4 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_17 0xDA2AE8 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_18 0xDA2AEC + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_19 0xDA2AF0 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_20 0xDA2AF4 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_21 0xDA2AF8 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_22 0xDA2AFC + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_23 0xDA2B00 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_24 0xDA2B04 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_25 0xDA2B08 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_26 0xDA2B0C + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_27 0xDA2B10 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_28 0xDA2B14 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_29 0xDA2B18 + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_30 0xDA2B1C + +#define mmNIC3_QM1_ARB_MST_CHOISE_PUSH_OFST_31 0xDA2B20 + +#define mmNIC3_QM1_ARB_SLV_MASTER_INC_CRED_OFST 0xDA2B28 + +#define mmNIC3_QM1_ARB_MST_SLAVE_EN 0xDA2B2C + +#define mmNIC3_QM1_ARB_MST_QUIET_PER 0xDA2B34 + +#define mmNIC3_QM1_ARB_SLV_CHOISE_WDT 0xDA2B38 + +#define mmNIC3_QM1_ARB_SLV_ID 0xDA2B3C + +#define mmNIC3_QM1_ARB_MSG_MAX_INFLIGHT 0xDA2B44 + +#define mmNIC3_QM1_ARB_MSG_AWUSER_31_11 0xDA2B48 + +#define mmNIC3_QM1_ARB_MSG_AWUSER_SEC_PROP 0xDA2B4C + +#define mmNIC3_QM1_ARB_MSG_AWUSER_NON_SEC_PROP 0xDA2B50 + +#define mmNIC3_QM1_ARB_BASE_LO 0xDA2B54 + +#define mmNIC3_QM1_ARB_BASE_HI 0xDA2B58 + +#define mmNIC3_QM1_ARB_STATE_STS 0xDA2B80 + +#define mmNIC3_QM1_ARB_CHOISE_FULLNESS_STS 0xDA2B84 + +#define mmNIC3_QM1_ARB_MSG_STS 0xDA2B88 + +#define mmNIC3_QM1_ARB_SLV_CHOISE_Q_HEAD 0xDA2B8C + +#define mmNIC3_QM1_ARB_ERR_CAUSE 0xDA2B9C + +#define mmNIC3_QM1_ARB_ERR_MSG_EN 0xDA2BA0 + +#define mmNIC3_QM1_ARB_ERR_STS_DRP 0xDA2BA8 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_0 0xDA2BB0 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_1 0xDA2BB4 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_2 0xDA2BB8 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_3 0xDA2BBC + +#define mmNIC3_QM1_ARB_MST_CRED_STS_4 0xDA2BC0 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_5 0xDA2BC4 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_6 0xDA2BC8 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_7 0xDA2BCC + +#define mmNIC3_QM1_ARB_MST_CRED_STS_8 0xDA2BD0 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_9 0xDA2BD4 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_10 0xDA2BD8 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_11 0xDA2BDC + +#define mmNIC3_QM1_ARB_MST_CRED_STS_12 0xDA2BE0 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_13 0xDA2BE4 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_14 0xDA2BE8 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_15 0xDA2BEC + +#define mmNIC3_QM1_ARB_MST_CRED_STS_16 0xDA2BF0 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_17 0xDA2BF4 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_18 0xDA2BF8 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_19 0xDA2BFC + +#define mmNIC3_QM1_ARB_MST_CRED_STS_20 0xDA2C00 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_21 0xDA2C04 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_22 0xDA2C08 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_23 0xDA2C0C + +#define mmNIC3_QM1_ARB_MST_CRED_STS_24 0xDA2C10 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_25 0xDA2C14 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_26 0xDA2C18 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_27 0xDA2C1C + +#define mmNIC3_QM1_ARB_MST_CRED_STS_28 0xDA2C20 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_29 0xDA2C24 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_30 0xDA2C28 + +#define mmNIC3_QM1_ARB_MST_CRED_STS_31 0xDA2C2C + +#define mmNIC3_QM1_CGM_CFG 0xDA2C70 + +#define mmNIC3_QM1_CGM_STS 0xDA2C74 + +#define mmNIC3_QM1_CGM_CFG1 0xDA2C78 + +#define mmNIC3_QM1_LOCAL_RANGE_BASE 0xDA2C80 + +#define mmNIC3_QM1_LOCAL_RANGE_SIZE 0xDA2C84 + +#define mmNIC3_QM1_CSMR_STRICT_PRIO_CFG 0xDA2C90 + +#define mmNIC3_QM1_HBW_RD_RATE_LIM_CFG_1 0xDA2C94 + +#define mmNIC3_QM1_LBW_WR_RATE_LIM_CFG_0 0xDA2C98 + +#define mmNIC3_QM1_LBW_WR_RATE_LIM_CFG_1 0xDA2C9C + +#define mmNIC3_QM1_HBW_RD_RATE_LIM_CFG_0 0xDA2CA0 + +#define mmNIC3_QM1_GLBL_AXCACHE 0xDA2CA4 + +#define mmNIC3_QM1_IND_GW_APB_CFG 0xDA2CB0 + +#define mmNIC3_QM1_IND_GW_APB_WDATA 0xDA2CB4 + +#define mmNIC3_QM1_IND_GW_APB_RDATA 0xDA2CB8 + +#define mmNIC3_QM1_IND_GW_APB_STATUS 0xDA2CBC + +#define mmNIC3_QM1_GLBL_ERR_ADDR_LO 0xDA2CD0 + +#define mmNIC3_QM1_GLBL_ERR_ADDR_HI 0xDA2CD4 + +#define mmNIC3_QM1_GLBL_ERR_WDATA 0xDA2CD8 + +#define mmNIC3_QM1_GLBL_MEM_INIT_BUSY 0xDA2D00 + +#endif /* ASIC_REG_NIC3_QM1_REGS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/nic4_qm0_regs.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic4_qm0_regs.h new file mode 100644 index 000000000000..99d5319672dd --- /dev/null +++ b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic4_qm0_regs.h @@ -0,0 +1,834 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright 2016-2018 HabanaLabs, Ltd. + * All Rights Reserved. + * + */ + +/************************************ + ** This is an auto-generated file ** + ** DO NOT EDIT BELOW ** + ************************************/ + +#ifndef ASIC_REG_NIC4_QM0_REGS_H_ +#define ASIC_REG_NIC4_QM0_REGS_H_ + +/* + ***************************************** + * NIC4_QM0 (Prototype: QMAN) + ***************************************** + */ + +#define mmNIC4_QM0_GLBL_CFG0 0xDE0000 + +#define mmNIC4_QM0_GLBL_CFG1 0xDE0004 + +#define mmNIC4_QM0_GLBL_PROT 0xDE0008 + +#define mmNIC4_QM0_GLBL_ERR_CFG 0xDE000C + +#define mmNIC4_QM0_GLBL_SECURE_PROPS_0 0xDE0010 + +#define mmNIC4_QM0_GLBL_SECURE_PROPS_1 0xDE0014 + +#define mmNIC4_QM0_GLBL_SECURE_PROPS_2 0xDE0018 + +#define mmNIC4_QM0_GLBL_SECURE_PROPS_3 0xDE001C + +#define mmNIC4_QM0_GLBL_SECURE_PROPS_4 0xDE0020 + +#define mmNIC4_QM0_GLBL_NON_SECURE_PROPS_0 0xDE0024 + +#define mmNIC4_QM0_GLBL_NON_SECURE_PROPS_1 0xDE0028 + +#define mmNIC4_QM0_GLBL_NON_SECURE_PROPS_2 0xDE002C + +#define mmNIC4_QM0_GLBL_NON_SECURE_PROPS_3 0xDE0030 + +#define mmNIC4_QM0_GLBL_NON_SECURE_PROPS_4 0xDE0034 + +#define mmNIC4_QM0_GLBL_STS0 0xDE0038 + +#define mmNIC4_QM0_GLBL_STS1_0 0xDE0040 + +#define mmNIC4_QM0_GLBL_STS1_1 0xDE0044 + +#define mmNIC4_QM0_GLBL_STS1_2 0xDE0048 + +#define mmNIC4_QM0_GLBL_STS1_3 0xDE004C + +#define mmNIC4_QM0_GLBL_STS1_4 0xDE0050 + +#define mmNIC4_QM0_GLBL_MSG_EN_0 0xDE0054 + +#define mmNIC4_QM0_GLBL_MSG_EN_1 0xDE0058 + +#define mmNIC4_QM0_GLBL_MSG_EN_2 0xDE005C + +#define mmNIC4_QM0_GLBL_MSG_EN_3 0xDE0060 + +#define mmNIC4_QM0_GLBL_MSG_EN_4 0xDE0068 + +#define mmNIC4_QM0_PQ_BASE_LO_0 0xDE0070 + +#define mmNIC4_QM0_PQ_BASE_LO_1 0xDE0074 + +#define mmNIC4_QM0_PQ_BASE_LO_2 0xDE0078 + +#define mmNIC4_QM0_PQ_BASE_LO_3 0xDE007C + +#define mmNIC4_QM0_PQ_BASE_HI_0 0xDE0080 + +#define mmNIC4_QM0_PQ_BASE_HI_1 0xDE0084 + +#define mmNIC4_QM0_PQ_BASE_HI_2 0xDE0088 + +#define mmNIC4_QM0_PQ_BASE_HI_3 0xDE008C + +#define mmNIC4_QM0_PQ_SIZE_0 0xDE0090 + +#define mmNIC4_QM0_PQ_SIZE_1 0xDE0094 + +#define mmNIC4_QM0_PQ_SIZE_2 0xDE0098 + +#define mmNIC4_QM0_PQ_SIZE_3 0xDE009C + +#define mmNIC4_QM0_PQ_PI_0 0xDE00A0 + +#define mmNIC4_QM0_PQ_PI_1 0xDE00A4 + +#define mmNIC4_QM0_PQ_PI_2 0xDE00A8 + +#define mmNIC4_QM0_PQ_PI_3 0xDE00AC + +#define mmNIC4_QM0_PQ_CI_0 0xDE00B0 + +#define mmNIC4_QM0_PQ_CI_1 0xDE00B4 + +#define mmNIC4_QM0_PQ_CI_2 0xDE00B8 + +#define mmNIC4_QM0_PQ_CI_3 0xDE00BC + +#define mmNIC4_QM0_PQ_CFG0_0 0xDE00C0 + +#define mmNIC4_QM0_PQ_CFG0_1 0xDE00C4 + +#define mmNIC4_QM0_PQ_CFG0_2 0xDE00C8 + +#define mmNIC4_QM0_PQ_CFG0_3 0xDE00CC + +#define mmNIC4_QM0_PQ_CFG1_0 0xDE00D0 + +#define mmNIC4_QM0_PQ_CFG1_1 0xDE00D4 + +#define mmNIC4_QM0_PQ_CFG1_2 0xDE00D8 + +#define mmNIC4_QM0_PQ_CFG1_3 0xDE00DC + +#define mmNIC4_QM0_PQ_ARUSER_31_11_0 0xDE00E0 + +#define mmNIC4_QM0_PQ_ARUSER_31_11_1 0xDE00E4 + +#define mmNIC4_QM0_PQ_ARUSER_31_11_2 0xDE00E8 + +#define mmNIC4_QM0_PQ_ARUSER_31_11_3 0xDE00EC + +#define mmNIC4_QM0_PQ_STS0_0 0xDE00F0 + +#define mmNIC4_QM0_PQ_STS0_1 0xDE00F4 + +#define mmNIC4_QM0_PQ_STS0_2 0xDE00F8 + +#define mmNIC4_QM0_PQ_STS0_3 0xDE00FC + +#define mmNIC4_QM0_PQ_STS1_0 0xDE0100 + +#define mmNIC4_QM0_PQ_STS1_1 0xDE0104 + +#define mmNIC4_QM0_PQ_STS1_2 0xDE0108 + +#define mmNIC4_QM0_PQ_STS1_3 0xDE010C + +#define mmNIC4_QM0_CQ_CFG0_0 0xDE0110 + +#define mmNIC4_QM0_CQ_CFG0_1 0xDE0114 + +#define mmNIC4_QM0_CQ_CFG0_2 0xDE0118 + +#define mmNIC4_QM0_CQ_CFG0_3 0xDE011C + +#define mmNIC4_QM0_CQ_CFG0_4 0xDE0120 + +#define mmNIC4_QM0_CQ_CFG1_0 0xDE0124 + +#define mmNIC4_QM0_CQ_CFG1_1 0xDE0128 + +#define mmNIC4_QM0_CQ_CFG1_2 0xDE012C + +#define mmNIC4_QM0_CQ_CFG1_3 0xDE0130 + +#define mmNIC4_QM0_CQ_CFG1_4 0xDE0134 + +#define mmNIC4_QM0_CQ_ARUSER_31_11_0 0xDE0138 + +#define mmNIC4_QM0_CQ_ARUSER_31_11_1 0xDE013C + +#define mmNIC4_QM0_CQ_ARUSER_31_11_2 0xDE0140 + +#define mmNIC4_QM0_CQ_ARUSER_31_11_3 0xDE0144 + +#define mmNIC4_QM0_CQ_ARUSER_31_11_4 0xDE0148 + +#define mmNIC4_QM0_CQ_STS0_0 0xDE014C + +#define mmNIC4_QM0_CQ_STS0_1 0xDE0150 + +#define mmNIC4_QM0_CQ_STS0_2 0xDE0154 + +#define mmNIC4_QM0_CQ_STS0_3 0xDE0158 + +#define mmNIC4_QM0_CQ_STS0_4 0xDE015C + +#define mmNIC4_QM0_CQ_STS1_0 0xDE0160 + +#define mmNIC4_QM0_CQ_STS1_1 0xDE0164 + +#define mmNIC4_QM0_CQ_STS1_2 0xDE0168 + +#define mmNIC4_QM0_CQ_STS1_3 0xDE016C + +#define mmNIC4_QM0_CQ_STS1_4 0xDE0170 + +#define mmNIC4_QM0_CQ_PTR_LO_0 0xDE0174 + +#define mmNIC4_QM0_CQ_PTR_HI_0 0xDE0178 + +#define mmNIC4_QM0_CQ_TSIZE_0 0xDE017C + +#define mmNIC4_QM0_CQ_CTL_0 0xDE0180 + +#define mmNIC4_QM0_CQ_PTR_LO_1 0xDE0184 + +#define mmNIC4_QM0_CQ_PTR_HI_1 0xDE0188 + +#define mmNIC4_QM0_CQ_TSIZE_1 0xDE018C + +#define mmNIC4_QM0_CQ_CTL_1 0xDE0190 + +#define mmNIC4_QM0_CQ_PTR_LO_2 0xDE0194 + +#define mmNIC4_QM0_CQ_PTR_HI_2 0xDE0198 + +#define mmNIC4_QM0_CQ_TSIZE_2 0xDE019C + +#define mmNIC4_QM0_CQ_CTL_2 0xDE01A0 + +#define mmNIC4_QM0_CQ_PTR_LO_3 0xDE01A4 + +#define mmNIC4_QM0_CQ_PTR_HI_3 0xDE01A8 + +#define mmNIC4_QM0_CQ_TSIZE_3 0xDE01AC + +#define mmNIC4_QM0_CQ_CTL_3 0xDE01B0 + +#define mmNIC4_QM0_CQ_PTR_LO_4 0xDE01B4 + +#define mmNIC4_QM0_CQ_PTR_HI_4 0xDE01B8 + +#define mmNIC4_QM0_CQ_TSIZE_4 0xDE01BC + +#define mmNIC4_QM0_CQ_CTL_4 0xDE01C0 + +#define mmNIC4_QM0_CQ_PTR_LO_STS_0 0xDE01C4 + +#define mmNIC4_QM0_CQ_PTR_LO_STS_1 0xDE01C8 + +#define mmNIC4_QM0_CQ_PTR_LO_STS_2 0xDE01CC + +#define mmNIC4_QM0_CQ_PTR_LO_STS_3 0xDE01D0 + +#define mmNIC4_QM0_CQ_PTR_LO_STS_4 0xDE01D4 + +#define mmNIC4_QM0_CQ_PTR_HI_STS_0 0xDE01D8 + +#define mmNIC4_QM0_CQ_PTR_HI_STS_1 0xDE01DC + +#define mmNIC4_QM0_CQ_PTR_HI_STS_2 0xDE01E0 + +#define mmNIC4_QM0_CQ_PTR_HI_STS_3 0xDE01E4 + +#define mmNIC4_QM0_CQ_PTR_HI_STS_4 0xDE01E8 + +#define mmNIC4_QM0_CQ_TSIZE_STS_0 0xDE01EC + +#define mmNIC4_QM0_CQ_TSIZE_STS_1 0xDE01F0 + +#define mmNIC4_QM0_CQ_TSIZE_STS_2 0xDE01F4 + +#define mmNIC4_QM0_CQ_TSIZE_STS_3 0xDE01F8 + +#define mmNIC4_QM0_CQ_TSIZE_STS_4 0xDE01FC + +#define mmNIC4_QM0_CQ_CTL_STS_0 0xDE0200 + +#define mmNIC4_QM0_CQ_CTL_STS_1 0xDE0204 + +#define mmNIC4_QM0_CQ_CTL_STS_2 0xDE0208 + +#define mmNIC4_QM0_CQ_CTL_STS_3 0xDE020C + +#define mmNIC4_QM0_CQ_CTL_STS_4 0xDE0210 + +#define mmNIC4_QM0_CQ_IFIFO_CNT_0 0xDE0214 + +#define mmNIC4_QM0_CQ_IFIFO_CNT_1 0xDE0218 + +#define mmNIC4_QM0_CQ_IFIFO_CNT_2 0xDE021C + +#define mmNIC4_QM0_CQ_IFIFO_CNT_3 0xDE0220 + +#define mmNIC4_QM0_CQ_IFIFO_CNT_4 0xDE0224 + +#define mmNIC4_QM0_CP_MSG_BASE0_ADDR_LO_0 0xDE0228 + +#define mmNIC4_QM0_CP_MSG_BASE0_ADDR_LO_1 0xDE022C + +#define mmNIC4_QM0_CP_MSG_BASE0_ADDR_LO_2 0xDE0230 + +#define mmNIC4_QM0_CP_MSG_BASE0_ADDR_LO_3 0xDE0234 + +#define mmNIC4_QM0_CP_MSG_BASE0_ADDR_LO_4 0xDE0238 + +#define mmNIC4_QM0_CP_MSG_BASE0_ADDR_HI_0 0xDE023C + +#define mmNIC4_QM0_CP_MSG_BASE0_ADDR_HI_1 0xDE0240 + +#define mmNIC4_QM0_CP_MSG_BASE0_ADDR_HI_2 0xDE0244 + +#define mmNIC4_QM0_CP_MSG_BASE0_ADDR_HI_3 0xDE0248 + +#define mmNIC4_QM0_CP_MSG_BASE0_ADDR_HI_4 0xDE024C + +#define mmNIC4_QM0_CP_MSG_BASE1_ADDR_LO_0 0xDE0250 + +#define mmNIC4_QM0_CP_MSG_BASE1_ADDR_LO_1 0xDE0254 + +#define mmNIC4_QM0_CP_MSG_BASE1_ADDR_LO_2 0xDE0258 + +#define mmNIC4_QM0_CP_MSG_BASE1_ADDR_LO_3 0xDE025C + +#define mmNIC4_QM0_CP_MSG_BASE1_ADDR_LO_4 0xDE0260 + +#define mmNIC4_QM0_CP_MSG_BASE1_ADDR_HI_0 0xDE0264 + +#define mmNIC4_QM0_CP_MSG_BASE1_ADDR_HI_1 0xDE0268 + +#define mmNIC4_QM0_CP_MSG_BASE1_ADDR_HI_2 0xDE026C + +#define mmNIC4_QM0_CP_MSG_BASE1_ADDR_HI_3 0xDE0270 + +#define mmNIC4_QM0_CP_MSG_BASE1_ADDR_HI_4 0xDE0274 + +#define mmNIC4_QM0_CP_MSG_BASE2_ADDR_LO_0 0xDE0278 + +#define mmNIC4_QM0_CP_MSG_BASE2_ADDR_LO_1 0xDE027C + +#define mmNIC4_QM0_CP_MSG_BASE2_ADDR_LO_2 0xDE0280 + +#define mmNIC4_QM0_CP_MSG_BASE2_ADDR_LO_3 0xDE0284 + +#define mmNIC4_QM0_CP_MSG_BASE2_ADDR_LO_4 0xDE0288 + +#define mmNIC4_QM0_CP_MSG_BASE2_ADDR_HI_0 0xDE028C + +#define mmNIC4_QM0_CP_MSG_BASE2_ADDR_HI_1 0xDE0290 + +#define mmNIC4_QM0_CP_MSG_BASE2_ADDR_HI_2 0xDE0294 + +#define mmNIC4_QM0_CP_MSG_BASE2_ADDR_HI_3 0xDE0298 + +#define mmNIC4_QM0_CP_MSG_BASE2_ADDR_HI_4 0xDE029C + +#define mmNIC4_QM0_CP_MSG_BASE3_ADDR_LO_0 0xDE02A0 + +#define mmNIC4_QM0_CP_MSG_BASE3_ADDR_LO_1 0xDE02A4 + +#define mmNIC4_QM0_CP_MSG_BASE3_ADDR_LO_2 0xDE02A8 + +#define mmNIC4_QM0_CP_MSG_BASE3_ADDR_LO_3 0xDE02AC + +#define mmNIC4_QM0_CP_MSG_BASE3_ADDR_LO_4 0xDE02B0 + +#define mmNIC4_QM0_CP_MSG_BASE3_ADDR_HI_0 0xDE02B4 + +#define mmNIC4_QM0_CP_MSG_BASE3_ADDR_HI_1 0xDE02B8 + +#define mmNIC4_QM0_CP_MSG_BASE3_ADDR_HI_2 0xDE02BC + +#define mmNIC4_QM0_CP_MSG_BASE3_ADDR_HI_3 0xDE02C0 + +#define mmNIC4_QM0_CP_MSG_BASE3_ADDR_HI_4 0xDE02C4 + +#define mmNIC4_QM0_CP_LDMA_TSIZE_OFFSET_0 0xDE02C8 + +#define mmNIC4_QM0_CP_LDMA_TSIZE_OFFSET_1 0xDE02CC + +#define mmNIC4_QM0_CP_LDMA_TSIZE_OFFSET_2 0xDE02D0 + +#define mmNIC4_QM0_CP_LDMA_TSIZE_OFFSET_3 0xDE02D4 + +#define mmNIC4_QM0_CP_LDMA_TSIZE_OFFSET_4 0xDE02D8 + +#define mmNIC4_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_0 0xDE02E0 + +#define mmNIC4_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_1 0xDE02E4 + +#define mmNIC4_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_2 0xDE02E8 + +#define mmNIC4_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_3 0xDE02EC + +#define mmNIC4_QM0_CP_LDMA_SRC_BASE_LO_OFFSET_4 0xDE02F0 + +#define mmNIC4_QM0_CP_LDMA_DST_BASE_LO_OFFSET_0 0xDE02F4 + +#define mmNIC4_QM0_CP_LDMA_DST_BASE_LO_OFFSET_1 0xDE02F8 + +#define mmNIC4_QM0_CP_LDMA_DST_BASE_LO_OFFSET_2 0xDE02FC + +#define mmNIC4_QM0_CP_LDMA_DST_BASE_LO_OFFSET_3 0xDE0300 + +#define mmNIC4_QM0_CP_LDMA_DST_BASE_LO_OFFSET_4 0xDE0304 + +#define mmNIC4_QM0_CP_FENCE0_RDATA_0 0xDE0308 + +#define mmNIC4_QM0_CP_FENCE0_RDATA_1 0xDE030C + +#define mmNIC4_QM0_CP_FENCE0_RDATA_2 0xDE0310 + +#define mmNIC4_QM0_CP_FENCE0_RDATA_3 0xDE0314 + +#define mmNIC4_QM0_CP_FENCE0_RDATA_4 0xDE0318 + +#define mmNIC4_QM0_CP_FENCE1_RDATA_0 0xDE031C + +#define mmNIC4_QM0_CP_FENCE1_RDATA_1 0xDE0320 + +#define mmNIC4_QM0_CP_FENCE1_RDATA_2 0xDE0324 + +#define mmNIC4_QM0_CP_FENCE1_RDATA_3 0xDE0328 + +#define mmNIC4_QM0_CP_FENCE1_RDATA_4 0xDE032C + +#define mmNIC4_QM0_CP_FENCE2_RDATA_0 0xDE0330 + +#define mmNIC4_QM0_CP_FENCE2_RDATA_1 0xDE0334 + +#define mmNIC4_QM0_CP_FENCE2_RDATA_2 0xDE0338 + +#define mmNIC4_QM0_CP_FENCE2_RDATA_3 0xDE033C + +#define mmNIC4_QM0_CP_FENCE2_RDATA_4 0xDE0340 + +#define mmNIC4_QM0_CP_FENCE3_RDATA_0 0xDE0344 + +#define mmNIC4_QM0_CP_FENCE3_RDATA_1 0xDE0348 + +#define mmNIC4_QM0_CP_FENCE3_RDATA_2 0xDE034C + +#define mmNIC4_QM0_CP_FENCE3_RDATA_3 0xDE0350 + +#define mmNIC4_QM0_CP_FENCE3_RDATA_4 0xDE0354 + +#define mmNIC4_QM0_CP_FENCE0_CNT_0 0xDE0358 + +#define mmNIC4_QM0_CP_FENCE0_CNT_1 0xDE035C + +#define mmNIC4_QM0_CP_FENCE0_CNT_2 0xDE0360 + +#define mmNIC4_QM0_CP_FENCE0_CNT_3 0xDE0364 + +#define mmNIC4_QM0_CP_FENCE0_CNT_4 0xDE0368 + +#define mmNIC4_QM0_CP_FENCE1_CNT_0 0xDE036C + +#define mmNIC4_QM0_CP_FENCE1_CNT_1 0xDE0370 + +#define mmNIC4_QM0_CP_FENCE1_CNT_2 0xDE0374 + +#define mmNIC4_QM0_CP_FENCE1_CNT_3 0xDE0378 + +#define mmNIC4_QM0_CP_FENCE1_CNT_4 0xDE037C + +#define mmNIC4_QM0_CP_FENCE2_CNT_0 0xDE0380 + +#define mmNIC4_QM0_CP_FENCE2_CNT_1 0xDE0384 + +#define mmNIC4_QM0_CP_FENCE2_CNT_2 0xDE0388 + +#define mmNIC4_QM0_CP_FENCE2_CNT_3 0xDE038C + +#define mmNIC4_QM0_CP_FENCE2_CNT_4 0xDE0390 + +#define mmNIC4_QM0_CP_FENCE3_CNT_0 0xDE0394 + +#define mmNIC4_QM0_CP_FENCE3_CNT_1 0xDE0398 + +#define mmNIC4_QM0_CP_FENCE3_CNT_2 0xDE039C + +#define mmNIC4_QM0_CP_FENCE3_CNT_3 0xDE03A0 + +#define mmNIC4_QM0_CP_FENCE3_CNT_4 0xDE03A4 + +#define mmNIC4_QM0_CP_STS_0 0xDE03A8 + +#define mmNIC4_QM0_CP_STS_1 0xDE03AC + +#define mmNIC4_QM0_CP_STS_2 0xDE03B0 + +#define mmNIC4_QM0_CP_STS_3 0xDE03B4 + +#define mmNIC4_QM0_CP_STS_4 0xDE03B8 + +#define mmNIC4_QM0_CP_CURRENT_INST_LO_0 0xDE03BC + +#define mmNIC4_QM0_CP_CURRENT_INST_LO_1 0xDE03C0 + +#define mmNIC4_QM0_CP_CURRENT_INST_LO_2 0xDE03C4 + +#define mmNIC4_QM0_CP_CURRENT_INST_LO_3 0xDE03C8 + +#define mmNIC4_QM0_CP_CURRENT_INST_LO_4 0xDE03CC + +#define mmNIC4_QM0_CP_CURRENT_INST_HI_0 0xDE03D0 + +#define mmNIC4_QM0_CP_CURRENT_INST_HI_1 0xDE03D4 + +#define mmNIC4_QM0_CP_CURRENT_INST_HI_2 0xDE03D8 + +#define mmNIC4_QM0_CP_CURRENT_INST_HI_3 0xDE03DC + +#define mmNIC4_QM0_CP_CURRENT_INST_HI_4 0xDE03E0 + +#define mmNIC4_QM0_CP_BARRIER_CFG_0 0xDE03F4 + +#define mmNIC4_QM0_CP_BARRIER_CFG_1 0xDE03F8 + +#define mmNIC4_QM0_CP_BARRIER_CFG_2 0xDE03FC + +#define mmNIC4_QM0_CP_BARRIER_CFG_3 0xDE0400 + +#define mmNIC4_QM0_CP_BARRIER_CFG_4 0xDE0404 + +#define mmNIC4_QM0_CP_DBG_0_0 0xDE0408 + +#define mmNIC4_QM0_CP_DBG_0_1 0xDE040C + +#define mmNIC4_QM0_CP_DBG_0_2 0xDE0410 + +#define mmNIC4_QM0_CP_DBG_0_3 0xDE0414 + +#define mmNIC4_QM0_CP_DBG_0_4 0xDE0418 + +#define mmNIC4_QM0_CP_ARUSER_31_11_0 0xDE041C + +#define mmNIC4_QM0_CP_ARUSER_31_11_1 0xDE0420 + +#define mmNIC4_QM0_CP_ARUSER_31_11_2 0xDE0424 + +#define mmNIC4_QM0_CP_ARUSER_31_11_3 0xDE0428 + +#define mmNIC4_QM0_CP_ARUSER_31_11_4 0xDE042C + +#define mmNIC4_QM0_CP_AWUSER_31_11_0 0xDE0430 + +#define mmNIC4_QM0_CP_AWUSER_31_11_1 0xDE0434 + +#define mmNIC4_QM0_CP_AWUSER_31_11_2 0xDE0438 + +#define mmNIC4_QM0_CP_AWUSER_31_11_3 0xDE043C + +#define mmNIC4_QM0_CP_AWUSER_31_11_4 0xDE0440 + +#define mmNIC4_QM0_ARB_CFG_0 0xDE0A00 + +#define mmNIC4_QM0_ARB_CHOISE_Q_PUSH 0xDE0A04 + +#define mmNIC4_QM0_ARB_WRR_WEIGHT_0 0xDE0A08 + +#define mmNIC4_QM0_ARB_WRR_WEIGHT_1 0xDE0A0C + +#define mmNIC4_QM0_ARB_WRR_WEIGHT_2 0xDE0A10 + +#define mmNIC4_QM0_ARB_WRR_WEIGHT_3 0xDE0A14 + +#define mmNIC4_QM0_ARB_CFG_1 0xDE0A18 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_0 0xDE0A20 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_1 0xDE0A24 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_2 0xDE0A28 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_3 0xDE0A2C + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_4 0xDE0A30 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_5 0xDE0A34 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_6 0xDE0A38 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_7 0xDE0A3C + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_8 0xDE0A40 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_9 0xDE0A44 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_10 0xDE0A48 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_11 0xDE0A4C + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_12 0xDE0A50 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_13 0xDE0A54 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_14 0xDE0A58 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_15 0xDE0A5C + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_16 0xDE0A60 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_17 0xDE0A64 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_18 0xDE0A68 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_19 0xDE0A6C + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_20 0xDE0A70 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_21 0xDE0A74 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_22 0xDE0A78 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_23 0xDE0A7C + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_24 0xDE0A80 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_25 0xDE0A84 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_26 0xDE0A88 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_27 0xDE0A8C + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_28 0xDE0A90 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_29 0xDE0A94 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_30 0xDE0A98 + +#define mmNIC4_QM0_ARB_MST_AVAIL_CRED_31 0xDE0A9C + +#define mmNIC4_QM0_ARB_MST_CRED_INC 0xDE0AA0 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_0 0xDE0AA4 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_1 0xDE0AA8 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_2 0xDE0AAC + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_3 0xDE0AB0 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_4 0xDE0AB4 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_5 0xDE0AB8 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_6 0xDE0ABC + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_7 0xDE0AC0 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_8 0xDE0AC4 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_9 0xDE0AC8 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_10 0xDE0ACC + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_11 0xDE0AD0 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_12 0xDE0AD4 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_13 0xDE0AD8 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_14 0xDE0ADC + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_15 0xDE0AE0 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_16 0xDE0AE4 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_17 0xDE0AE8 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_18 0xDE0AEC + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_19 0xDE0AF0 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_20 0xDE0AF4 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_21 0xDE0AF8 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_22 0xDE0AFC + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_23 0xDE0B00 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_24 0xDE0B04 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_25 0xDE0B08 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_26 0xDE0B0C + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_27 0xDE0B10 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_28 0xDE0B14 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_29 0xDE0B18 + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_30 0xDE0B1C + +#define mmNIC4_QM0_ARB_MST_CHOISE_PUSH_OFST_31 0xDE0B20 + +#define mmNIC4_QM0_ARB_SLV_MASTER_INC_CRED_OFST 0xDE0B28 + +#define mmNIC4_QM0_ARB_MST_SLAVE_EN 0xDE0B2C + +#define mmNIC4_QM0_ARB_MST_QUIET_PER 0xDE0B34 + +#define mmNIC4_QM0_ARB_SLV_CHOISE_WDT 0xDE0B38 + +#define mmNIC4_QM0_ARB_SLV_ID 0xDE0B3C + +#define mmNIC4_QM0_ARB_MSG_MAX_INFLIGHT 0xDE0B44 + +#define mmNIC4_QM0_ARB_MSG_AWUSER_31_11 0xDE0B48 + +#define mmNIC4_QM0_ARB_MSG_AWUSER_SEC_PROP 0xDE0B4C + +#define mmNIC4_QM0_ARB_MSG_AWUSER_NON_SEC_PROP 0xDE0B50 + +#define mmNIC4_QM0_ARB_BASE_LO 0xDE0B54 + +#define mmNIC4_QM0_ARB_BASE_HI 0xDE0B58 + +#define mmNIC4_QM0_ARB_STATE_STS 0xDE0B80 + +#define mmNIC4_QM0_ARB_CHOISE_FULLNESS_STS 0xDE0B84 + +#define mmNIC4_QM0_ARB_MSG_STS 0xDE0B88 + +#define mmNIC4_QM0_ARB_SLV_CHOISE_Q_HEAD 0xDE0B8C + +#define mmNIC4_QM0_ARB_ERR_CAUSE 0xDE0B9C + +#define mmNIC4_QM0_ARB_ERR_MSG_EN 0xDE0BA0 + +#define mmNIC4_QM0_ARB_ERR_STS_DRP 0xDE0BA8 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_0 0xDE0BB0 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_1 0xDE0BB4 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_2 0xDE0BB8 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_3 0xDE0BBC + +#define mmNIC4_QM0_ARB_MST_CRED_STS_4 0xDE0BC0 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_5 0xDE0BC4 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_6 0xDE0BC8 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_7 0xDE0BCC + +#define mmNIC4_QM0_ARB_MST_CRED_STS_8 0xDE0BD0 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_9 0xDE0BD4 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_10 0xDE0BD8 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_11 0xDE0BDC + +#define mmNIC4_QM0_ARB_MST_CRED_STS_12 0xDE0BE0 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_13 0xDE0BE4 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_14 0xDE0BE8 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_15 0xDE0BEC + +#define mmNIC4_QM0_ARB_MST_CRED_STS_16 0xDE0BF0 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_17 0xDE0BF4 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_18 0xDE0BF8 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_19 0xDE0BFC + +#define mmNIC4_QM0_ARB_MST_CRED_STS_20 0xDE0C00 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_21 0xDE0C04 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_22 0xDE0C08 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_23 0xDE0C0C + +#define mmNIC4_QM0_ARB_MST_CRED_STS_24 0xDE0C10 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_25 0xDE0C14 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_26 0xDE0C18 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_27 0xDE0C1C + +#define mmNIC4_QM0_ARB_MST_CRED_STS_28 0xDE0C20 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_29 0xDE0C24 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_30 0xDE0C28 + +#define mmNIC4_QM0_ARB_MST_CRED_STS_31 0xDE0C2C + +#define mmNIC4_QM0_CGM_CFG 0xDE0C70 + +#define mmNIC4_QM0_CGM_STS 0xDE0C74 + +#define mmNIC4_QM0_CGM_CFG1 0xDE0C78 + +#define mmNIC4_QM0_LOCAL_RANGE_BASE 0xDE0C80 + +#define mmNIC4_QM0_LOCAL_RANGE_SIZE 0xDE0C84 + +#define mmNIC4_QM0_CSMR_STRICT_PRIO_CFG 0xDE0C90 + +#define mmNIC4_QM0_HBW_RD_RATE_LIM_CFG_1 0xDE0C94 + +#define mmNIC4_QM0_LBW_WR_RATE_LIM_CFG_0 0xDE0C98 + +#define mmNIC4_QM0_LBW_WR_RATE_LIM_CFG_1 0xDE0C9C + +#define mmNIC4_QM0_HBW_RD_RATE_LIM_CFG_0 0xDE0CA0 + +#define mmNIC4_QM0_GLBL_AXCACHE 0xDE0CA4 + +#define mmNIC4_QM0_IND_GW_APB_CFG 0xDE0CB0 + +#define mmNIC4_QM0_IND_GW_APB_WDATA 0xDE0CB4 + +#define mmNIC4_QM0_IND_GW_APB_RDATA 0xDE0CB8 + +#define mmNIC4_QM0_IND_GW_APB_STATUS 0xDE0CBC + +#define mmNIC4_QM0_GLBL_ERR_ADDR_LO 0xDE0CD0 + +#define mmNIC4_QM0_GLBL_ERR_ADDR_HI 0xDE0CD4 + +#define mmNIC4_QM0_GLBL_ERR_WDATA 0xDE0CD8 + +#define mmNIC4_QM0_GLBL_MEM_INIT_BUSY 0xDE0D00 + +#endif /* ASIC_REG_NIC4_QM0_REGS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/nic4_qm1_regs.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic4_qm1_regs.h new file mode 100644 index 000000000000..34b21b21da52 --- /dev/null +++ b/drivers/misc/habanalabs/include/gaudi/asic_reg/nic4_qm1_regs.h @@ -0,0 +1,834 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright 2016-2018 HabanaLabs, Ltd. + * All Rights Reserved. + * + */ + +/************************************ + ** This is an auto-generated file ** + ** DO NOT EDIT BELOW ** + ************************************/ + +#ifndef ASIC_REG_NIC4_QM1_REGS_H_ +#define ASIC_REG_NIC4_QM1_REGS_H_ + +/* + ***************************************** + * NIC4_QM1 (Prototype: QMAN) + ***************************************** + */ + +#define mmNIC4_QM1_GLBL_CFG0 0xDE2000 + +#define mmNIC4_QM1_GLBL_CFG1 0xDE2004 + +#define mmNIC4_QM1_GLBL_PROT 0xDE2008 + +#define mmNIC4_QM1_GLBL_ERR_CFG 0xDE200C + +#define mmNIC4_QM1_GLBL_SECURE_PROPS_0 0xDE2010 + +#define mmNIC4_QM1_GLBL_SECURE_PROPS_1 0xDE2014 + +#define mmNIC4_QM1_GLBL_SECURE_PROPS_2 0xDE2018 + +#define mmNIC4_QM1_GLBL_SECURE_PROPS_3 0xDE201C + +#define mmNIC4_QM1_GLBL_SECURE_PROPS_4 0xDE2020 + +#define mmNIC4_QM1_GLBL_NON_SECURE_PROPS_0 0xDE2024 + +#define mmNIC4_QM1_GLBL_NON_SECURE_PROPS_1 0xDE2028 + +#define mmNIC4_QM1_GLBL_NON_SECURE_PROPS_2 0xDE202C + +#define mmNIC4_QM1_GLBL_NON_SECURE_PROPS_3 0xDE2030 + +#define mmNIC4_QM1_GLBL_NON_SECURE_PROPS_4 0xDE2034 + +#define mmNIC4_QM1_GLBL_STS0 0xDE2038 + +#define mmNIC4_QM1_GLBL_STS1_0 0xDE2040 + +#define mmNIC4_QM1_GLBL_STS1_1 0xDE2044 + +#define mmNIC4_QM1_GLBL_STS1_2 0xDE2048 + +#define mmNIC4_QM1_GLBL_STS1_3 0xDE204C + +#define mmNIC4_QM1_GLBL_STS1_4 0xDE2050 + +#define mmNIC4_QM1_GLBL_MSG_EN_0 0xDE2054 + +#define mmNIC4_QM1_GLBL_MSG_EN_1 0xDE2058 + +#define mmNIC4_QM1_GLBL_MSG_EN_2 0xDE205C + +#define mmNIC4_QM1_GLBL_MSG_EN_3 0xDE2060 + +#define mmNIC4_QM1_GLBL_MSG_EN_4 0xDE2068 + +#define mmNIC4_QM1_PQ_BASE_LO_0 0xDE2070 + +#define mmNIC4_QM1_PQ_BASE_LO_1 0xDE2074 + +#define mmNIC4_QM1_PQ_BASE_LO_2 0xDE2078 + +#define mmNIC4_QM1_PQ_BASE_LO_3 0xDE207C + +#define mmNIC4_QM1_PQ_BASE_HI_0 0xDE2080 + +#define mmNIC4_QM1_PQ_BASE_HI_1 0xDE2084 + +#define mmNIC4_QM1_PQ_BASE_HI_2 0xDE2088 + +#define mmNIC4_QM1_PQ_BASE_HI_3 0xDE208C + +#define mmNIC4_QM1_PQ_SIZE_0 0xDE2090 + +#define mmNIC4_QM1_PQ_SIZE_1 0xDE2094 + +#define mmNIC4_QM1_PQ_SIZE_2 0xDE2098 + +#define mmNIC4_QM1_PQ_SIZE_3 0xDE209C + +#define mmNIC4_QM1_PQ_PI_0 0xDE20A0 + +#define mmNIC4_QM1_PQ_PI_1 0xDE20A4 + +#define mmNIC4_QM1_PQ_PI_2 0xDE20A8 + +#define mmNIC4_QM1_PQ_PI_3 0xDE20AC + +#define mmNIC4_QM1_PQ_CI_0 0xDE20B0 + +#define mmNIC4_QM1_PQ_CI_1 0xDE20B4 + +#define mmNIC4_QM1_PQ_CI_2 0xDE20B8 + +#define mmNIC4_QM1_PQ_CI_3 0xDE20BC + +#define mmNIC4_QM1_PQ_CFG0_0 0xDE20C0 + +#define mmNIC4_QM1_PQ_CFG0_1 0xDE20C4 + +#define mmNIC4_QM1_PQ_CFG0_2 0xDE20C8 + +#define mmNIC4_QM1_PQ_CFG0_3 0xDE20CC + +#define mmNIC4_QM1_PQ_CFG1_0 0xDE20D0 + +#define mmNIC4_QM1_PQ_CFG1_1 0xDE20D4 + +#define mmNIC4_QM1_PQ_CFG1_2 0xDE20D8 + +#define mmNIC4_QM1_PQ_CFG1_3 0xDE20DC + +#define mmNIC4_QM1_PQ_ARUSER_31_11_0 0xDE20E0 + +#define mmNIC4_QM1_PQ_ARUSER_31_11_1 0xDE20E4 + +#define mmNIC4_QM1_PQ_ARUSER_31_11_2 0xDE20E8 + +#define mmNIC4_QM1_PQ_ARUSER_31_11_3 0xDE20EC + +#define mmNIC4_QM1_PQ_STS0_0 0xDE20F0 + +#define mmNIC4_QM1_PQ_STS0_1 0xDE20F4 + +#define mmNIC4_QM1_PQ_STS0_2 0xDE20F8 + +#define mmNIC4_QM1_PQ_STS0_3 0xDE20FC + +#define mmNIC4_QM1_PQ_STS1_0 0xDE2100 + +#define mmNIC4_QM1_PQ_STS1_1 0xDE2104 + +#define mmNIC4_QM1_PQ_STS1_2 0xDE2108 + +#define mmNIC4_QM1_PQ_STS1_3 0xDE210C + +#define mmNIC4_QM1_CQ_CFG0_0 0xDE2110 + +#define mmNIC4_QM1_CQ_CFG0_1 0xDE2114 + +#define mmNIC4_QM1_CQ_CFG0_2 0xDE2118 + +#define mmNIC4_QM1_CQ_CFG0_3 0xDE211C + +#define mmNIC4_QM1_CQ_CFG0_4 0xDE2120 + +#define mmNIC4_QM1_CQ_CFG1_0 0xDE2124 + +#define mmNIC4_QM1_CQ_CFG1_1 0xDE2128 + +#define mmNIC4_QM1_CQ_CFG1_2 0xDE212C + +#define mmNIC4_QM1_CQ_CFG1_3 0xDE2130 + +#define mmNIC4_QM1_CQ_CFG1_4 0xDE2134 + +#define mmNIC4_QM1_CQ_ARUSER_31_11_0 0xDE2138 + +#define mmNIC4_QM1_CQ_ARUSER_31_11_1 0xDE213C + +#define mmNIC4_QM1_CQ_ARUSER_31_11_2 0xDE2140 + +#define mmNIC4_QM1_CQ_ARUSER_31_11_3 0xDE2144 + +#define mmNIC4_QM1_CQ_ARUSER_31_11_4 0xDE2148 + +#define mmNIC4_QM1_CQ_STS0_0 0xDE214C + +#define mmNIC4_QM1_CQ_STS0_1 0xDE2150 + +#define mmNIC4_QM1_CQ_STS0_2 0xDE2154 + +#define mmNIC4_QM1_CQ_STS0_3 0xDE2158 + +#define mmNIC4_QM1_CQ_STS0_4 0xDE215C + +#define mmNIC4_QM1_CQ_STS1_0 0xDE2160 + +#define mmNIC4_QM1_CQ_STS1_1 0xDE2164 + +#define mmNIC4_QM1_CQ_STS1_2 0xDE2168 + +#define mmNIC4_QM1_CQ_STS1_3 0xDE216C + +#define mmNIC4_QM1_CQ_STS1_4 0xDE2170 + +#define mmNIC4_QM1_CQ_PTR_LO_0 0xDE2174 + +#define mmNIC4_QM1_CQ_PTR_HI_0 0xDE2178 + +#define mmNIC4_QM1_CQ_TSIZE_0 0xDE217C + +#define mmNIC4_QM1_CQ_CTL_0 0xDE2180 + +#define mmNIC4_QM1_CQ_PTR_LO_1 0xDE2184 + +#define mmNIC4_QM1_CQ_PTR_HI_1 0xDE2188 + +#define mmNIC4_QM1_CQ_TSIZE_1 0xDE218C + +#define mmNIC4_QM1_CQ_CTL_1 0xDE2190 + +#define mmNIC4_QM1_CQ_PTR_LO_2 0xDE2194 + +#define mmNIC4_QM1_CQ_PTR_HI_2 0xDE2198 + +#define mmNIC4_QM1_CQ_TSIZE_2 0xDE219C + +#define mmNIC4_QM1_CQ_CTL_2 0xDE21A0 + +#define mmNIC4_QM1_CQ_PTR_LO_3 0xDE21A4 + +#define mmNIC4_QM1_CQ_PTR_HI_3 0xDE21A8 + +#define mmNIC4_QM1_CQ_TSIZE_3 0xDE21AC + +#define mmNIC4_QM1_CQ_CTL_3 0xDE21B0 + +#define mmNIC4_QM1_CQ_PTR_LO_4 0xDE21B4 + +#define mmNIC4_QM1_CQ_PTR_HI_4 0xDE21B8 + +#define mmNIC4_QM1_CQ_TSIZE_4 0xDE21BC + +#define mmNIC4_QM1_CQ_CTL_4 0xDE21C0 + +#define mmNIC4_QM1_CQ_PTR_LO_STS_0 0xDE21C4 + +#define mmNIC4_QM1_CQ_PTR_LO_STS_1 0xDE21C8 + +#define mmNIC4_QM1_CQ_PTR_LO_STS_2 0xDE21CC + +#define mmNIC4_QM1_CQ_PTR_LO_STS_3 0xDE21D0 + +#define mmNIC4_QM1_CQ_PTR_LO_STS_4 0xDE21D4 + +#define mmNIC4_QM1_CQ_PTR_HI_STS_0 0xDE21D8 + +#define mmNIC4_QM1_CQ_PTR_HI_STS_1 0xDE21DC + +#define mmNIC4_QM1_CQ_PTR_HI_STS_2 0xDE21E0 + +#define mmNIC4_QM1_CQ_PTR_HI_STS_3 0xDE21E4 + +#define mmNIC4_QM1_CQ_PTR_HI_STS_4 0xDE21E8 + +#define mmNIC4_QM1_CQ_TSIZE_STS_0 0xDE21EC + +#define mmNIC4_QM1_CQ_TSIZE_STS_1 0xDE21F0 + +#define mmNIC4_QM1_CQ_TSIZE_STS_2 0xDE21F4 + +#define mmNIC4_QM1_CQ_TSIZE_STS_3 0xDE21F8 + +#define mmNIC4_QM1_CQ_TSIZE_STS_4 0xDE21FC + +#define mmNIC4_QM1_CQ_CTL_STS_0 0xDE2200 + +#define mmNIC4_QM1_CQ_CTL_STS_1 0xDE2204 + +#define mmNIC4_QM1_CQ_CTL_STS_2 0xDE2208 + +#define mmNIC4_QM1_CQ_CTL_STS_3 0xDE220C + +#define mmNIC4_QM1_CQ_CTL_STS_4 0xDE2210 + +#define mmNIC4_QM1_CQ_IFIFO_CNT_0 0xDE2214 + +#define mmNIC4_QM1_CQ_IFIFO_CNT_1 0xDE2218 + +#define mmNIC4_QM1_CQ_IFIFO_CNT_2 0xDE221C + +#define mmNIC4_QM1_CQ_IFIFO_CNT_3 0xDE2220 + +#define mmNIC4_QM1_CQ_IFIFO_CNT_4 0xDE2224 + +#define mmNIC4_QM1_CP_MSG_BASE0_ADDR_LO_0 0xDE2228 + +#define mmNIC4_QM1_CP_MSG_BASE0_ADDR_LO_1 0xDE222C + +#define mmNIC4_QM1_CP_MSG_BASE0_ADDR_LO_2 0xDE2230 + +#define mmNIC4_QM1_CP_MSG_BASE0_ADDR_LO_3 0xDE2234 + +#define mmNIC4_QM1_CP_MSG_BASE0_ADDR_LO_4 0xDE2238 + +#define mmNIC4_QM1_CP_MSG_BASE0_ADDR_HI_0 0xDE223C + +#define mmNIC4_QM1_CP_MSG_BASE0_ADDR_HI_1 0xDE2240 + +#define mmNIC4_QM1_CP_MSG_BASE0_ADDR_HI_2 0xDE2244 + +#define mmNIC4_QM1_CP_MSG_BASE0_ADDR_HI_3 0xDE2248 + +#define mmNIC4_QM1_CP_MSG_BASE0_ADDR_HI_4 0xDE224C + +#define mmNIC4_QM1_CP_MSG_BASE1_ADDR_LO_0 0xDE2250 + +#define mmNIC4_QM1_CP_MSG_BASE1_ADDR_LO_1 0xDE2254 + +#define mmNIC4_QM1_CP_MSG_BASE1_ADDR_LO_2 0xDE2258 + +#define mmNIC4_QM1_CP_MSG_BASE1_ADDR_LO_3 0xDE225C + +#define mmNIC4_QM1_CP_MSG_BASE1_ADDR_LO_4 0xDE2260 + +#define mmNIC4_QM1_CP_MSG_BASE1_ADDR_HI_0 0xDE2264 + +#define mmNIC4_QM1_CP_MSG_BASE1_ADDR_HI_1 0xDE2268 + +#define mmNIC4_QM1_CP_MSG_BASE1_ADDR_HI_2 0xDE226C + +#define mmNIC4_QM1_CP_MSG_BASE1_ADDR_HI_3 0xDE2270 + +#define mmNIC4_QM1_CP_MSG_BASE1_ADDR_HI_4 0xDE2274 + +#define mmNIC4_QM1_CP_MSG_BASE2_ADDR_LO_0 0xDE2278 + +#define mmNIC4_QM1_CP_MSG_BASE2_ADDR_LO_1 0xDE227C + +#define mmNIC4_QM1_CP_MSG_BASE2_ADDR_LO_2 0xDE2280 + +#define mmNIC4_QM1_CP_MSG_BASE2_ADDR_LO_3 0xDE2284 + +#define mmNIC4_QM1_CP_MSG_BASE2_ADDR_LO_4 0xDE2288 + +#define mmNIC4_QM1_CP_MSG_BASE2_ADDR_HI_0 0xDE228C + +#define mmNIC4_QM1_CP_MSG_BASE2_ADDR_HI_1 0xDE2290 + +#define mmNIC4_QM1_CP_MSG_BASE2_ADDR_HI_2 0xDE2294 + +#define mmNIC4_QM1_CP_MSG_BASE2_ADDR_HI_3 0xDE2298 + +#define mmNIC4_QM1_CP_MSG_BASE2_ADDR_HI_4 0xDE229C + +#define mmNIC4_QM1_CP_MSG_BASE3_ADDR_LO_0 0xDE22A0 + +#define mmNIC4_QM1_CP_MSG_BASE3_ADDR_LO_1 0xDE22A4 + +#define mmNIC4_QM1_CP_MSG_BASE3_ADDR_LO_2 0xDE22A8 + +#define mmNIC4_QM1_CP_MSG_BASE3_ADDR_LO_3 0xDE22AC + +#define mmNIC4_QM1_CP_MSG_BASE3_ADDR_LO_4 0xDE22B0 + +#define mmNIC4_QM1_CP_MSG_BASE3_ADDR_HI_0 0xDE22B4 + +#define mmNIC4_QM1_CP_MSG_BASE3_ADDR_HI_1 0xDE22B8 + +#define mmNIC4_QM1_CP_MSG_BASE3_ADDR_HI_2 0xDE22BC + +#define mmNIC4_QM1_CP_MSG_BASE3_ADDR_HI_3 0xDE22C0 + +#define mmNIC4_QM1_CP_MSG_BASE3_ADDR_HI_4 0xDE22C4 + +#define mmNIC4_QM1_CP_LDMA_TSIZE_OFFSET_0 0xDE22C8 + +#define mmNIC4_QM1_CP_LDMA_TSIZE_OFFSET_1 0xDE22CC + +#define mmNIC4_QM1_CP_LDMA_TSIZE_OFFSET_2 0xDE22D0 + +#define mmNIC4_QM1_CP_LDMA_TSIZE_OFFSET_3 0xDE22D4 + +#define mmNIC4_QM1_CP_LDMA_TSIZE_OFFSET_4 0xDE22D8 + +#define mmNIC4_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_0 0xDE22E0 + +#define mmNIC4_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_1 0xDE22E4 + +#define mmNIC4_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_2 0xDE22E8 + +#define mmNIC4_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_3 0xDE22EC + +#define mmNIC4_QM1_CP_LDMA_SRC_BASE_LO_OFFSET_4 0xDE22F0 + +#define mmNIC4_QM1_CP_LDMA_DST_BASE_LO_OFFSET_0 0xDE22F4 + +#define mmNIC4_QM1_CP_LDMA_DST_BASE_LO_OFFSET_1 0xDE22F8 + +#define mmNIC4_QM1_CP_LDMA_DST_BASE_LO_OFFSET_2 0xDE22FC + +#define mmNIC4_QM1_CP_LDMA_DST_BASE_LO_OFFSET_3 0xDE2300 + +#define mmNIC4_QM1_CP_LDMA_DST_BASE_LO_OFFSET_4 0xDE2304 + +#define mmNIC4_QM1_CP_FENCE0_RDATA_0 0xDE2308 + +#define mmNIC4_QM1_CP_FENCE0_RDATA_1 0xDE230C + +#define mmNIC4_QM1_CP_FENCE0_RDATA_2 0xDE2310 + +#define mmNIC4_QM1_CP_FENCE0_RDATA_3 0xDE2314 + +#define mmNIC4_QM1_CP_FENCE0_RDATA_4 0xDE2318 + +#define mmNIC4_QM1_CP_FENCE1_RDATA_0 0xDE231C + +#define mmNIC4_QM1_CP_FENCE1_RDATA_1 0xDE2320 + +#define mmNIC4_QM1_CP_FENCE1_RDATA_2 0xDE2324 + +#define mmNIC4_QM1_CP_FENCE1_RDATA_3 0xDE2328 + +#define mmNIC4_QM1_CP_FENCE1_RDATA_4 0xDE232C + +#define mmNIC4_QM1_CP_FENCE2_RDATA_0 0xDE2330 + +#define mmNIC4_QM1_CP_FENCE2_RDATA_1 0xDE2334 + +#define mmNIC4_QM1_CP_FENCE2_RDATA_2 0xDE2338 + +#define mmNIC4_QM1_CP_FENCE2_RDATA_3 0xDE233C + +#define mmNIC4_QM1_CP_FENCE2_RDATA_4 0xDE2340 + +#define mmNIC4_QM1_CP_FENCE3_RDATA_0 0xDE2344 + +#define mmNIC4_QM1_CP_FENCE3_RDATA_1 0xDE2348 + +#define mmNIC4_QM1_CP_FENCE3_RDATA_2 0xDE234C + +#define mmNIC4_QM1_CP_FENCE3_RDATA_3 0xDE2350 + +#define mmNIC4_QM1_CP_FENCE3_RDATA_4 0xDE2354 + +#define mmNIC4_QM1_CP_FENCE0_CNT_0 0xDE2358 + +#define mmNIC4_QM1_CP_FENCE0_CNT_1 0xDE235C + +#define mmNIC4_QM1_CP_FENCE0_CNT_2 0xDE2360 + +#define mmNIC4_QM1_CP_FENCE0_CNT_3 0xDE2364 + +#define mmNIC4_QM1_CP_FENCE0_CNT_4 0xDE2368 + +#define mmNIC4_QM1_CP_FENCE1_CNT_0 0xDE236C + +#define mmNIC4_QM1_CP_FENCE1_CNT_1 0xDE2370 + +#define mmNIC4_QM1_CP_FENCE1_CNT_2 0xDE2374 + +#define mmNIC4_QM1_CP_FENCE1_CNT_3 0xDE2378 + +#define mmNIC4_QM1_CP_FENCE1_CNT_4 0xDE237C + +#define mmNIC4_QM1_CP_FENCE2_CNT_0 0xDE2380 + +#define mmNIC4_QM1_CP_FENCE2_CNT_1 0xDE2384 + +#define mmNIC4_QM1_CP_FENCE2_CNT_2 0xDE2388 + +#define mmNIC4_QM1_CP_FENCE2_CNT_3 0xDE238C + +#define mmNIC4_QM1_CP_FENCE2_CNT_4 0xDE2390 + +#define mmNIC4_QM1_CP_FENCE3_CNT_0 0xDE2394 + +#define mmNIC4_QM1_CP_FENCE3_CNT_1 0xDE2398 + +#define mmNIC4_QM1_CP_FENCE3_CNT_2 0xDE239C + +#define mmNIC4_QM1_CP_FENCE3_CNT_3 0xDE23A0 + +#define mmNIC4_QM1_CP_FENCE3_CNT_4 0xDE23A4 + +#define mmNIC4_QM1_CP_STS_0 0xDE23A8 + +#define mmNIC4_QM1_CP_STS_1 0xDE23AC + +#define mmNIC4_QM1_CP_STS_2 0xDE23B0 + +#define mmNIC4_QM1_CP_STS_3 0xDE23B4 + +#define mmNIC4_QM1_CP_STS_4 0xDE23B8 + +#define mmNIC4_QM1_CP_CURRENT_INST_LO_0 0xDE23BC + +#define mmNIC4_QM1_CP_CURRENT_INST_LO_1 0xDE23C0 + +#define mmNIC4_QM1_CP_CURRENT_INST_LO_2 0xDE23C4 + +#define mmNIC4_QM1_CP_CURRENT_INST_LO_3 0xDE23C8 + +#define mmNIC4_QM1_CP_CURRENT_INST_LO_4 0xDE23CC + +#define mmNIC4_QM1_CP_CURRENT_INST_HI_0 0xDE23D0 + +#define mmNIC4_QM1_CP_CURRENT_INST_HI_1 0xDE23D4 + +#define mmNIC4_QM1_CP_CURRENT_INST_HI_2 0xDE23D8 + +#define mmNIC4_QM1_CP_CURRENT_INST_HI_3 0xDE23DC + +#define mmNIC4_QM1_CP_CURRENT_INST_HI_4 0xDE23E0 + +#define mmNIC4_QM1_CP_BARRIER_CFG_0 0xDE23F4 + +#define mmNIC4_QM1_CP_BARRIER_CFG_1 0xDE23F8 + +#define mmNIC4_QM1_CP_BARRIER_CFG_2 0xDE23FC + +#define mmNIC4_QM1_CP_BARRIER_CFG_3 0xDE2400 + +#define mmNIC4_QM1_CP_BARRIER_CFG_4 0xDE2404 + +#define mmNIC4_QM1_CP_DBG_0_0 0xDE2408 + +#define mmNIC4_QM1_CP_DBG_0_1 0xDE240C + +#define mmNIC4_QM1_CP_DBG_0_2 0xDE2410 + +#define mmNIC4_QM1_CP_DBG_0_3 0xDE2414 + +#define mmNIC4_QM1_CP_DBG_0_4 0xDE2418 + +#define mmNIC4_QM1_CP_ARUSER_31_11_0 0xDE241C + +#define mmNIC4_QM1_CP_ARUSER_31_11_1 0xDE2420 + +#define mmNIC4_QM1_CP_ARUSER_31_11_2 0xDE2424 + +#define mmNIC4_QM1_CP_ARUSER_31_11_3 0xDE2428 + +#define mmNIC4_QM1_CP_ARUSER_31_11_4 0xDE242C + +#define mmNIC4_QM1_CP_AWUSER_31_11_0 0xDE2430 + +#define mmNIC4_QM1_CP_AWUSER_31_11_1 0xDE2434 + +#define mmNIC4_QM1_CP_AWUSER_31_11_2 0xDE2438 + +#define mmNIC4_QM1_CP_AWUSER_31_11_3 0xDE243C + +#define mmNIC4_QM1_CP_AWUSER_31_11_4 0xDE2440 + +#define mmNIC4_QM1_ARB_CFG_0 0xDE2A00 + +#define mmNIC4_QM1_ARB_CHOISE_Q_PUSH 0xDE2A04 + +#define mmNIC4_QM1_ARB_WRR_WEIGHT_0 0xDE2A08 + +#define mmNIC4_QM1_ARB_WRR_WEIGHT_1 0xDE2A0C + +#define mmNIC4_QM1_ARB_WRR_WEIGHT_2 0xDE2A10 + +#define mmNIC4_QM1_ARB_WRR_WEIGHT_3 0xDE2A14 + +#define mmNIC4_QM1_ARB_CFG_1 0xDE2A18 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_0 0xDE2A20 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_1 0xDE2A24 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_2 0xDE2A28 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_3 0xDE2A2C + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_4 0xDE2A30 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_5 0xDE2A34 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_6 0xDE2A38 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_7 0xDE2A3C + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_8 0xDE2A40 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_9 0xDE2A44 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_10 0xDE2A48 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_11 0xDE2A4C + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_12 0xDE2A50 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_13 0xDE2A54 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_14 0xDE2A58 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_15 0xDE2A5C + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_16 0xDE2A60 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_17 0xDE2A64 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_18 0xDE2A68 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_19 0xDE2A6C + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_20 0xDE2A70 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_21 0xDE2A74 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_22 0xDE2A78 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_23 0xDE2A7C + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_24 0xDE2A80 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_25 0xDE2A84 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_26 0xDE2A88 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_27 0xDE2A8C + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_28 0xDE2A90 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_29 0xDE2A94 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_30 0xDE2A98 + +#define mmNIC4_QM1_ARB_MST_AVAIL_CRED_31 0xDE2A9C + +#define mmNIC4_QM1_ARB_MST_CRED_INC 0xDE2AA0 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_0 0xDE2AA4 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_1 0xDE2AA8 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_2 0xDE2AAC + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_3 0xDE2AB0 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_4 0xDE2AB4 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_5 0xDE2AB8 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_6 0xDE2ABC + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_7 0xDE2AC0 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_8 0xDE2AC4 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_9 0xDE2AC8 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_10 0xDE2ACC + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_11 0xDE2AD0 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_12 0xDE2AD4 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_13 0xDE2AD8 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_14 0xDE2ADC + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_15 0xDE2AE0 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_16 0xDE2AE4 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_17 0xDE2AE8 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_18 0xDE2AEC + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_19 0xDE2AF0 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_20 0xDE2AF4 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_21 0xDE2AF8 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_22 0xDE2AFC + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_23 0xDE2B00 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_24 0xDE2B04 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_25 0xDE2B08 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_26 0xDE2B0C + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_27 0xDE2B10 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_28 0xDE2B14 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_29 0xDE2B18 + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_30 0xDE2B1C + +#define mmNIC4_QM1_ARB_MST_CHOISE_PUSH_OFST_31 0xDE2B20 + +#define mmNIC4_QM1_ARB_SLV_MASTER_INC_CRED_OFST 0xDE2B28 + +#define mmNIC4_QM1_ARB_MST_SLAVE_EN 0xDE2B2C + +#define mmNIC4_QM1_ARB_MST_QUIET_PER 0xDE2B34 + +#define mmNIC4_QM1_ARB_SLV_CHOISE_WDT 0xDE2B38 + +#define mmNIC4_QM1_ARB_SLV_ID 0xDE2B3C + +#define mmNIC4_QM1_ARB_MSG_MAX_INFLIGHT 0xDE2B44 + +#define mmNIC4_QM1_ARB_MSG_AWUSER_31_11 0xDE2B48 + +#define mmNIC4_QM1_ARB_MSG_AWUSER_SEC_PROP 0xDE2B4C + +#define mmNIC4_QM1_ARB_MSG_AWUSER_NON_SEC_PROP 0xDE2B50 + +#define mmNIC4_QM1_ARB_BASE_LO 0xDE2B54 + +#define mmNIC4_QM1_ARB_BASE_HI 0xDE2B58 + +#define mmNIC4_QM1_ARB_STATE_STS 0xDE2B80 + +#define mmNIC4_QM1_ARB_CHOISE_FULLNESS_STS 0xDE2B84 + +#define mmNIC4_QM1_ARB_MSG_STS 0xDE2B88 + +#define mmNIC4_QM1_ARB_SLV_CHOISE_Q_HEAD 0xDE2B8C + +#define mmNIC4_QM1_ARB_ERR_CAUSE 0xDE2B9C + +#define mmNIC4_QM1_ARB_ERR_MSG_EN 0xDE2BA0 + +#define mmNIC4_QM1_ARB_ERR_STS_DRP 0xDE2BA8 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_0 0xDE2BB0 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_1 0xDE2BB4 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_2 0xDE2BB8 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_3 0xDE2BBC + +#define mmNIC4_QM1_ARB_MST_CRED_STS_4 0xDE2BC0 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_5 0xDE2BC4 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_6 0xDE2BC8 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_7 0xDE2BCC + +#define mmNIC4_QM1_ARB_MST_CRED_STS_8 0xDE2BD0 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_9 0xDE2BD4 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_10 0xDE2BD8 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_11 0xDE2BDC + +#define mmNIC4_QM1_ARB_MST_CRED_STS_12 0xDE2BE0 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_13 0xDE2BE4 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_14 0xDE2BE8 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_15 0xDE2BEC + +#define mmNIC4_QM1_ARB_MST_CRED_STS_16 0xDE2BF0 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_17 0xDE2BF4 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_18 0xDE2BF8 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_19 0xDE2BFC + +#define mmNIC4_QM1_ARB_MST_CRED_STS_20 0xDE2C00 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_21 0xDE2C04 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_22 0xDE2C08 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_23 0xDE2C0C + +#define mmNIC4_QM1_ARB_MST_CRED_STS_24 0xDE2C10 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_25 0xDE2C14 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_26 0xDE2C18 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_27 0xDE2C1C + +#define mmNIC4_QM1_ARB_MST_CRED_STS_28 0xDE2C20 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_29 0xDE2C24 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_30 0xDE2C28 + +#define mmNIC4_QM1_ARB_MST_CRED_STS_31 0xDE2C2C + +#define mmNIC4_QM1_CGM_CFG 0xDE2C70 + +#define mmNIC4_QM1_CGM_STS 0xDE2C74 + +#define mmNIC4_QM1_CGM_CFG1 0xDE2C78 + +#define mmNIC4_QM1_LOCAL_RANGE_BASE 0xDE2C80 + +#define mmNIC4_QM1_LOCAL_RANGE_SIZE 0xDE2C84 + +#define mmNIC4_QM1_CSMR_STRICT_PRIO_CFG 0xDE2C90 + +#define mmNIC4_QM1_HBW_RD_RATE_LIM_CFG_1 0xDE2C94 + +#define mmNIC4_QM1_LBW_WR_RATE_LIM_CFG_0 0xDE2C98 + +#define mmNIC4_QM1_LBW_WR_RATE_LIM_CFG_1 0xDE2C9C + +#define mmNIC4_QM1_HBW_RD_RATE_LIM_CFG_0 0xDE2CA0 + +#define mmNIC4_QM1_GLBL_AXCACHE 0xDE2CA4 + +#define mmNIC4_QM1_IND_GW_APB_CFG 0xDE2CB0 + +#define mmNIC4_QM1_IND_GW_APB_WDATA 0xDE2CB4 + +#define mmNIC4_QM1_IND_GW_APB_RDATA 0xDE2CB8 + +#define mmNIC4_QM1_IND_GW_APB_STATUS 0xDE2CBC + +#define mmNIC4_QM1_GLBL_ERR_ADDR_LO 0xDE2CD0 + +#define mmNIC4_QM1_GLBL_ERR_ADDR_HI 0xDE2CD4 + +#define mmNIC4_QM1_GLBL_ERR_WDATA 0xDE2CD8 + +#define mmNIC4_QM1_GLBL_MEM_INIT_BUSY 0xDE2D00 + +#endif /* ASIC_REG_NIC4_QM1_REGS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/psoc_hbm_pll_regs.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/psoc_hbm_pll_regs.h deleted file mode 100644 index 687e2255cb19..000000000000 --- a/drivers/misc/habanalabs/include/gaudi/asic_reg/psoc_hbm_pll_regs.h +++ /dev/null @@ -1,114 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright 2016-2018 HabanaLabs, Ltd. - * All Rights Reserved. - * - */ - -/************************************ - ** This is an auto-generated file ** - ** DO NOT EDIT BELOW ** - ************************************/ - -#ifndef ASIC_REG_PSOC_HBM_PLL_REGS_H_ -#define ASIC_REG_PSOC_HBM_PLL_REGS_H_ - -/* - ***************************************** - * PSOC_HBM_PLL (Prototype: PLL) - ***************************************** - */ - -#define mmPSOC_HBM_PLL_NR 0xC74100 - -#define mmPSOC_HBM_PLL_NF 0xC74104 - -#define mmPSOC_HBM_PLL_OD 0xC74108 - -#define mmPSOC_HBM_PLL_NB 0xC7410C - -#define mmPSOC_HBM_PLL_CFG 0xC74110 - -#define mmPSOC_HBM_PLL_LOSE_MASK 0xC74120 - -#define mmPSOC_HBM_PLL_LOCK_INTR 0xC74128 - -#define mmPSOC_HBM_PLL_LOCK_BYPASS 0xC7412C - -#define mmPSOC_HBM_PLL_DATA_CHNG 0xC74130 - -#define mmPSOC_HBM_PLL_RST 0xC74134 - -#define mmPSOC_HBM_PLL_SLIP_WD_CNTR 0xC74150 - -#define mmPSOC_HBM_PLL_DIV_FACTOR_0 0xC74200 - -#define mmPSOC_HBM_PLL_DIV_FACTOR_1 0xC74204 - -#define mmPSOC_HBM_PLL_DIV_FACTOR_2 0xC74208 - -#define mmPSOC_HBM_PLL_DIV_FACTOR_3 0xC7420C - -#define mmPSOC_HBM_PLL_DIV_FACTOR_CMD_0 0xC74220 - -#define mmPSOC_HBM_PLL_DIV_FACTOR_CMD_1 0xC74224 - -#define mmPSOC_HBM_PLL_DIV_FACTOR_CMD_2 0xC74228 - -#define mmPSOC_HBM_PLL_DIV_FACTOR_CMD_3 0xC7422C - -#define mmPSOC_HBM_PLL_DIV_SEL_0 0xC74280 - -#define mmPSOC_HBM_PLL_DIV_SEL_1 0xC74284 - -#define mmPSOC_HBM_PLL_DIV_SEL_2 0xC74288 - -#define mmPSOC_HBM_PLL_DIV_SEL_3 0xC7428C - -#define mmPSOC_HBM_PLL_DIV_EN_0 0xC742A0 - -#define mmPSOC_HBM_PLL_DIV_EN_1 0xC742A4 - -#define mmPSOC_HBM_PLL_DIV_EN_2 0xC742A8 - -#define mmPSOC_HBM_PLL_DIV_EN_3 0xC742AC - -#define mmPSOC_HBM_PLL_DIV_FACTOR_BUSY_0 0xC742C0 - -#define mmPSOC_HBM_PLL_DIV_FACTOR_BUSY_1 0xC742C4 - -#define mmPSOC_HBM_PLL_DIV_FACTOR_BUSY_2 0xC742C8 - -#define mmPSOC_HBM_PLL_DIV_FACTOR_BUSY_3 0xC742CC - -#define mmPSOC_HBM_PLL_CLK_GATER 0xC74300 - -#define mmPSOC_HBM_PLL_CLK_RLX_0 0xC74310 - -#define mmPSOC_HBM_PLL_CLK_RLX_1 0xC74314 - -#define mmPSOC_HBM_PLL_CLK_RLX_2 0xC74318 - -#define mmPSOC_HBM_PLL_CLK_RLX_3 0xC7431C - -#define mmPSOC_HBM_PLL_REF_CNTR_PERIOD 0xC74400 - -#define mmPSOC_HBM_PLL_REF_LOW_THRESHOLD 0xC74410 - -#define mmPSOC_HBM_PLL_REF_HIGH_THRESHOLD 0xC74420 - -#define mmPSOC_HBM_PLL_PLL_NOT_STABLE 0xC74430 - -#define mmPSOC_HBM_PLL_FREQ_CALC_EN 0xC74440 - -#define mmPSOC_HBM_PLL_RLX_BITMAP_CFG 0xC74500 - -#define mmPSOC_HBM_PLL_RLX_BITMAP_0 0xC74510 - -#define mmPSOC_HBM_PLL_RLX_BITMAP_1 0xC74514 - -#define mmPSOC_HBM_PLL_RLX_BITMAP_2 0xC74518 - -#define mmPSOC_HBM_PLL_RLX_BITMAP_3 0xC7451C - -#endif /* ASIC_REG_PSOC_HBM_PLL_REGS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/asic_reg/psoc_pci_pll_regs.h b/drivers/misc/habanalabs/include/gaudi/asic_reg/psoc_pci_pll_regs.h deleted file mode 100644 index 3dc9bb4542dd..000000000000 --- a/drivers/misc/habanalabs/include/gaudi/asic_reg/psoc_pci_pll_regs.h +++ /dev/null @@ -1,114 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright 2016-2018 HabanaLabs, Ltd. - * All Rights Reserved. - * - */ - -/************************************ - ** This is an auto-generated file ** - ** DO NOT EDIT BELOW ** - ************************************/ - -#ifndef ASIC_REG_PSOC_PCI_PLL_REGS_H_ -#define ASIC_REG_PSOC_PCI_PLL_REGS_H_ - -/* - ***************************************** - * PSOC_PCI_PLL (Prototype: PLL) - ***************************************** - */ - -#define mmPSOC_PCI_PLL_NR 0xC72100 - -#define mmPSOC_PCI_PLL_NF 0xC72104 - -#define mmPSOC_PCI_PLL_OD 0xC72108 - -#define mmPSOC_PCI_PLL_NB 0xC7210C - -#define mmPSOC_PCI_PLL_CFG 0xC72110 - -#define mmPSOC_PCI_PLL_LOSE_MASK 0xC72120 - -#define mmPSOC_PCI_PLL_LOCK_INTR 0xC72128 - -#define mmPSOC_PCI_PLL_LOCK_BYPASS 0xC7212C - -#define mmPSOC_PCI_PLL_DATA_CHNG 0xC72130 - -#define mmPSOC_PCI_PLL_RST 0xC72134 - -#define mmPSOC_PCI_PLL_SLIP_WD_CNTR 0xC72150 - -#define mmPSOC_PCI_PLL_DIV_FACTOR_0 0xC72200 - -#define mmPSOC_PCI_PLL_DIV_FACTOR_1 0xC72204 - -#define mmPSOC_PCI_PLL_DIV_FACTOR_2 0xC72208 - -#define mmPSOC_PCI_PLL_DIV_FACTOR_3 0xC7220C - -#define mmPSOC_PCI_PLL_DIV_FACTOR_CMD_0 0xC72220 - -#define mmPSOC_PCI_PLL_DIV_FACTOR_CMD_1 0xC72224 - -#define mmPSOC_PCI_PLL_DIV_FACTOR_CMD_2 0xC72228 - -#define mmPSOC_PCI_PLL_DIV_FACTOR_CMD_3 0xC7222C - -#define mmPSOC_PCI_PLL_DIV_SEL_0 0xC72280 - -#define mmPSOC_PCI_PLL_DIV_SEL_1 0xC72284 - -#define mmPSOC_PCI_PLL_DIV_SEL_2 0xC72288 - -#define mmPSOC_PCI_PLL_DIV_SEL_3 0xC7228C - -#define mmPSOC_PCI_PLL_DIV_EN_0 0xC722A0 - -#define mmPSOC_PCI_PLL_DIV_EN_1 0xC722A4 - -#define mmPSOC_PCI_PLL_DIV_EN_2 0xC722A8 - -#define mmPSOC_PCI_PLL_DIV_EN_3 0xC722AC - -#define mmPSOC_PCI_PLL_DIV_FACTOR_BUSY_0 0xC722C0 - -#define mmPSOC_PCI_PLL_DIV_FACTOR_BUSY_1 0xC722C4 - -#define mmPSOC_PCI_PLL_DIV_FACTOR_BUSY_2 0xC722C8 - -#define mmPSOC_PCI_PLL_DIV_FACTOR_BUSY_3 0xC722CC - -#define mmPSOC_PCI_PLL_CLK_GATER 0xC72300 - -#define mmPSOC_PCI_PLL_CLK_RLX_0 0xC72310 - -#define mmPSOC_PCI_PLL_CLK_RLX_1 0xC72314 - -#define mmPSOC_PCI_PLL_CLK_RLX_2 0xC72318 - -#define mmPSOC_PCI_PLL_CLK_RLX_3 0xC7231C - -#define mmPSOC_PCI_PLL_REF_CNTR_PERIOD 0xC72400 - -#define mmPSOC_PCI_PLL_REF_LOW_THRESHOLD 0xC72410 - -#define mmPSOC_PCI_PLL_REF_HIGH_THRESHOLD 0xC72420 - -#define mmPSOC_PCI_PLL_PLL_NOT_STABLE 0xC72430 - -#define mmPSOC_PCI_PLL_FREQ_CALC_EN 0xC72440 - -#define mmPSOC_PCI_PLL_RLX_BITMAP_CFG 0xC72500 - -#define mmPSOC_PCI_PLL_RLX_BITMAP_0 0xC72510 - -#define mmPSOC_PCI_PLL_RLX_BITMAP_1 0xC72514 - -#define mmPSOC_PCI_PLL_RLX_BITMAP_2 0xC72518 - -#define mmPSOC_PCI_PLL_RLX_BITMAP_3 0xC7251C - -#endif /* ASIC_REG_PSOC_PCI_PLL_REGS_H_ */ diff --git a/drivers/misc/habanalabs/include/gaudi/gaudi_fw_if.h b/drivers/misc/habanalabs/include/gaudi/gaudi_fw_if.h index 8aadc6357da1..25acd9e87e20 100644 --- a/drivers/misc/habanalabs/include/gaudi/gaudi_fw_if.h +++ b/drivers/misc/habanalabs/include/gaudi/gaudi_fw_if.h @@ -8,6 +8,8 @@ #ifndef GAUDI_FW_IF_H #define GAUDI_FW_IF_H +#include <linux/types.h> + #define GAUDI_EVENT_QUEUE_MSI_IDX 8 #define GAUDI_NIC_PORT1_MSI_IDX 10 #define GAUDI_NIC_PORT3_MSI_IDX 12 @@ -28,7 +30,30 @@ enum gaudi_pll_index { MESH_PLL, MME_PLL, TPC_PLL, - IF_PLL + IF_PLL, + PLL_MAX +}; + +enum gaudi_nic_axi_error { + RXB, + RXE, + TXS, + TXE, + QPC_RESP, + NON_AXI_ERR, +}; + +/* + * struct eq_nic_sei_event - describes an AXI error cause. + * @axi_error_cause: one of the events defined in enum gaudi_nic_axi_error. + * @id: can be either 0 or 1, to further describe unit with interrupt cause + * (i.e. TXE0 or TXE1). + * @pad[6]: padding structure to 64bit. + */ +struct eq_nic_sei_event { + __u8 axi_error_cause; + __u8 id; + __u8 pad[6]; }; #define GAUDI_PLL_FREQ_LOW 200000000 /* 200 MHz */ diff --git a/drivers/misc/habanalabs/include/gaudi/gaudi_masks.h b/drivers/misc/habanalabs/include/gaudi/gaudi_masks.h index f395721060bd..b9b90d079e23 100644 --- a/drivers/misc/habanalabs/include/gaudi/gaudi_masks.h +++ b/drivers/misc/habanalabs/include/gaudi/gaudi_masks.h @@ -41,6 +41,11 @@ (FIELD_PREP(TPC0_QM_GLBL_CFG0_CQF_EN_MASK, 0x1F)) | \ (FIELD_PREP(TPC0_QM_GLBL_CFG0_CP_EN_MASK, 0x1F))) +#define NIC_QMAN_ENABLE (\ + (FIELD_PREP(NIC0_QM0_GLBL_CFG0_PQF_EN_MASK, 0xF)) | \ + (FIELD_PREP(NIC0_QM0_GLBL_CFG0_CQF_EN_MASK, 0xF)) | \ + (FIELD_PREP(NIC0_QM0_GLBL_CFG0_CP_EN_MASK, 0xF))) + #define QMAN_UPPER_CP_CGM_PWR_GATE_EN (\ (FIELD_PREP(DMA0_QM_CGM_CFG_IDLE_TH_MASK, 0x20)) | \ (FIELD_PREP(DMA0_QM_CGM_CFG_G2F_TH_MASK, 0xA)) | \ @@ -93,6 +98,16 @@ (FIELD_PREP(MME0_QM_GLBL_ERR_CFG_CQF_STOP_ON_ERR_MASK, 0x1F)) | \ (FIELD_PREP(MME0_QM_GLBL_ERR_CFG_CP_STOP_ON_ERR_MASK, 0x1F))) +#define NIC_QMAN_GLBL_ERR_CFG_MSG_EN_MASK (\ + (FIELD_PREP(NIC0_QM0_GLBL_ERR_CFG_PQF_ERR_MSG_EN_MASK, 0xF)) | \ + (FIELD_PREP(NIC0_QM0_GLBL_ERR_CFG_CQF_ERR_MSG_EN_MASK, 0xF)) | \ + (FIELD_PREP(NIC0_QM0_GLBL_ERR_CFG_CP_ERR_MSG_EN_MASK, 0xF))) + +#define NIC_QMAN_GLBL_ERR_CFG_STOP_ON_ERR_EN_MASK (\ + (FIELD_PREP(NIC0_QM0_GLBL_ERR_CFG_PQF_STOP_ON_ERR_MASK, 0xF)) | \ + (FIELD_PREP(NIC0_QM0_GLBL_ERR_CFG_CQF_STOP_ON_ERR_MASK, 0xF)) | \ + (FIELD_PREP(NIC0_QM0_GLBL_ERR_CFG_CP_STOP_ON_ERR_MASK, 0xF))) + #define QMAN_CGM1_PWR_GATE_EN (FIELD_PREP(DMA0_QM_CGM_CFG1_MASK_TH_MASK, 0xA)) /* RESET registers configuration */ @@ -421,7 +436,6 @@ enum axi_id { #define QM_ARB_ERR_MSG_EN_MASK (\ QM_ARB_ERR_MSG_EN_CHOISE_OVF_MASK |\ - QM_ARB_ERR_MSG_EN_CHOISE_WDT_MASK |\ QM_ARB_ERR_MSG_EN_AXI_LBW_ERR_MASK) #define PCIE_AUX_FLR_CTRL_HW_CTRL_MASK 0x1 diff --git a/drivers/misc/habanalabs/include/gaudi/gaudi_reg_map.h b/drivers/misc/habanalabs/include/gaudi/gaudi_reg_map.h index 977fb341a6e7..137afedf5f15 100644 --- a/drivers/misc/habanalabs/include/gaudi/gaudi_reg_map.h +++ b/drivers/misc/habanalabs/include/gaudi/gaudi_reg_map.h @@ -12,6 +12,8 @@ * PSOC scratch-pad registers */ #define mmHW_STATE mmPSOC_GLOBAL_CONF_SCRATCHPAD_0 +#define mmCPU_BOOT_DEV_STS0 mmPSOC_GLOBAL_CONF_SCRATCHPAD_20 +#define mmCPU_BOOT_DEV_STS1 mmPSOC_GLOBAL_CONF_SCRATCHPAD_21 #define mmFUSE_VER_OFFSET mmPSOC_GLOBAL_CONF_SCRATCHPAD_22 #define mmCPU_CMD_STATUS_TO_HOST mmPSOC_GLOBAL_CONF_SCRATCHPAD_23 #define mmCPU_BOOT_ERR0 mmPSOC_GLOBAL_CONF_SCRATCHPAD_24 diff --git a/drivers/misc/habanalabs/include/goya/goya_fw_if.h b/drivers/misc/habanalabs/include/goya/goya_fw_if.h index 0fa80fe9f6cc..daf8d8cd14be 100644 --- a/drivers/misc/habanalabs/include/goya/goya_fw_if.h +++ b/drivers/misc/habanalabs/include/goya/goya_fw_if.h @@ -22,7 +22,8 @@ enum goya_pll_index { MME_PLL, PCI_PLL, EMMC_PLL, - TPC_PLL + TPC_PLL, + PLL_MAX }; #define GOYA_PLL_FREQ_LOW 50000000 /* 50 MHz */ diff --git a/drivers/misc/habanalabs/include/goya/goya_reg_map.h b/drivers/misc/habanalabs/include/goya/goya_reg_map.h index e56124265a05..f3ab282cafa4 100644 --- a/drivers/misc/habanalabs/include/goya/goya_reg_map.h +++ b/drivers/misc/habanalabs/include/goya/goya_reg_map.h @@ -22,6 +22,8 @@ #define mmCPU_CQ_BASE_ADDR_LOW mmPSOC_GLOBAL_CONF_SCRATCHPAD_8 #define mmCPU_CQ_BASE_ADDR_HIGH mmPSOC_GLOBAL_CONF_SCRATCHPAD_9 #define mmCPU_CQ_LENGTH mmPSOC_GLOBAL_CONF_SCRATCHPAD_10 +#define mmCPU_BOOT_DEV_STS0 mmPSOC_GLOBAL_CONF_SCRATCHPAD_20 +#define mmCPU_BOOT_DEV_STS1 mmPSOC_GLOBAL_CONF_SCRATCHPAD_21 #define mmFUSE_VER_OFFSET mmPSOC_GLOBAL_CONF_SCRATCHPAD_22 #define mmCPU_CMD_STATUS_TO_HOST mmPSOC_GLOBAL_CONF_SCRATCHPAD_23 #define mmCPU_BOOT_ERR0 mmPSOC_GLOBAL_CONF_SCRATCHPAD_24 diff --git a/drivers/misc/hisi_hikey_usb.c b/drivers/misc/hisi_hikey_usb.c index cc93569e601c..989d7d129469 100644 --- a/drivers/misc/hisi_hikey_usb.c +++ b/drivers/misc/hisi_hikey_usb.c @@ -168,10 +168,7 @@ static int hisi_hikey_usb_parse_kirin970(struct platform_device *pdev, hisi_hikey_usb->reset = devm_gpiod_get(&pdev->dev, "hub_reset_en_gpio", GPIOD_OUT_HIGH); - if (IS_ERR(hisi_hikey_usb->reset)) - return PTR_ERR(hisi_hikey_usb->reset); - - return 0; + return PTR_ERR_OR_ZERO(hisi_hikey_usb->reset); } static int hisi_hikey_usb_probe(struct platform_device *pdev) diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c index c12406f610d5..703d20e83ebd 100644 --- a/drivers/misc/isl29003.c +++ b/drivers/misc/isl29003.c @@ -127,13 +127,13 @@ static int isl29003_set_resolution(struct i2c_client *client, int res) static int isl29003_get_mode(struct i2c_client *client) { return __isl29003_read_reg(client, ISL29003_REG_COMMAND, - ISL29003_RES_MASK, ISL29003_RES_SHIFT); + ISL29003_MODE_MASK, ISL29003_MODE_SHIFT); } static int isl29003_set_mode(struct i2c_client *client, int mode) { return __isl29003_write_reg(client, ISL29003_REG_COMMAND, - ISL29003_RES_MASK, ISL29003_RES_SHIFT, mode); + ISL29003_MODE_MASK, ISL29003_MODE_SHIFT, mode); } /* power_state */ diff --git a/drivers/misc/lkdtm/Makefile b/drivers/misc/lkdtm/Makefile index c70b3822013f..6b888d04392d 100644 --- a/drivers/misc/lkdtm/Makefile +++ b/drivers/misc/lkdtm/Makefile @@ -10,13 +10,16 @@ lkdtm-$(CONFIG_LKDTM) += rodata_objcopy.o lkdtm-$(CONFIG_LKDTM) += usercopy.o lkdtm-$(CONFIG_LKDTM) += stackleak.o lkdtm-$(CONFIG_LKDTM) += cfi.o +lkdtm-$(CONFIG_LKDTM) += fortify.o +lkdtm-$(CONFIG_PPC_BOOK3S_64) += powerpc.o +KASAN_SANITIZE_rodata.o := n KASAN_SANITIZE_stackleak.o := n KCOV_INSTRUMENT_rodata.o := n OBJCOPYFLAGS := OBJCOPYFLAGS_rodata_objcopy.o := \ - --rename-section .text=.rodata,alloc,readonly,load + --rename-section .noinstr.text=.rodata,alloc,readonly,load targets += rodata.o rodata_objcopy.o $(obj)/rodata_objcopy.o: $(obj)/rodata.o FORCE $(call if_changed,objcopy) diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c index a0675d4154d2..110f5a8538e9 100644 --- a/drivers/misc/lkdtm/bugs.c +++ b/drivers/misc/lkdtm/bugs.c @@ -482,3 +482,53 @@ noinline void lkdtm_CORRUPT_PAC(void) pr_err("XFAIL: this test is arm64-only\n"); #endif } + +void lkdtm_FORTIFY_OBJECT(void) +{ + struct target { + char a[10]; + } target[2] = {}; + int result; + + /* + * Using volatile prevents the compiler from determining the value of + * 'size' at compile time. Without that, we would get a compile error + * rather than a runtime error. + */ + volatile int size = 11; + + pr_info("trying to read past the end of a struct\n"); + + result = memcmp(&target[0], &target[1], size); + + /* Print result to prevent the code from being eliminated */ + pr_err("FAIL: fortify did not catch an object overread!\n" + "\"%d\" was the memcmp result.\n", result); +} + +void lkdtm_FORTIFY_SUBOBJECT(void) +{ + struct target { + char a[10]; + char b[10]; + } target; + char *src; + + src = kmalloc(20, GFP_KERNEL); + strscpy(src, "over ten bytes", 20); + + pr_info("trying to strcpy past the end of a member of a struct\n"); + + /* + * strncpy(target.a, src, 20); will hit a compile error because the + * compiler knows at build time that target.a < 20 bytes. Use strcpy() + * to force a runtime error. + */ + strcpy(target.a, src); + + /* Use target.a to prevent the code from being eliminated */ + pr_err("FAIL: fortify did not catch an sub-object overrun!\n" + "\"%s\" was copied.\n", target.a); + + kfree(src); +} diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c index 97803f213d9d..b2aff4d87c01 100644 --- a/drivers/misc/lkdtm/core.c +++ b/drivers/misc/lkdtm/core.c @@ -117,6 +117,8 @@ static const struct crashtype crashtypes[] = { CRASHTYPE(UNSET_SMEP), CRASHTYPE(CORRUPT_PAC), CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE), + CRASHTYPE(FORTIFY_OBJECT), + CRASHTYPE(FORTIFY_SUBOBJECT), CRASHTYPE(OVERWRITE_ALLOCATION), CRASHTYPE(WRITE_AFTER_FREE), CRASHTYPE(READ_AFTER_FREE), @@ -173,9 +175,13 @@ static const struct crashtype crashtypes[] = { CRASHTYPE(USERCOPY_KERNEL), CRASHTYPE(STACKLEAK_ERASING), CRASHTYPE(CFI_FORWARD_PROTO), + CRASHTYPE(FORTIFIED_STRSCPY), #ifdef CONFIG_X86_32 CRASHTYPE(DOUBLE_FAULT), #endif +#ifdef CONFIG_PPC_BOOK3S_64 + CRASHTYPE(PPC_SLB_MULTIHIT), +#endif }; diff --git a/drivers/misc/lkdtm/fortify.c b/drivers/misc/lkdtm/fortify.c new file mode 100644 index 000000000000..faf29cf04baa --- /dev/null +++ b/drivers/misc/lkdtm/fortify.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 Francis Laniel <[email protected]> + * + * Add tests related to fortified functions in this file. + */ +#include "lkdtm.h" +#include <linux/string.h> +#include <linux/slab.h> + + +/* + * Calls fortified strscpy to test that it returns the same result as vanilla + * strscpy and generate a panic because there is a write overflow (i.e. src + * length is greater than dst length). + */ +void lkdtm_FORTIFIED_STRSCPY(void) +{ + char *src; + char dst[5]; + + struct { + union { + char big[10]; + char src[5]; + }; + } weird = { .big = "hello!" }; + char weird_dst[sizeof(weird.src) + 1]; + + src = kstrdup("foobar", GFP_KERNEL); + + if (src == NULL) + return; + + /* Vanilla strscpy returns -E2BIG if size is 0. */ + if (strscpy(dst, src, 0) != -E2BIG) + pr_warn("FAIL: strscpy() of 0 length did not return -E2BIG\n"); + + /* Vanilla strscpy returns -E2BIG if src is truncated. */ + if (strscpy(dst, src, sizeof(dst)) != -E2BIG) + pr_warn("FAIL: strscpy() did not return -E2BIG while src is truncated\n"); + + /* After above call, dst must contain "foob" because src was truncated. */ + if (strncmp(dst, "foob", sizeof(dst)) != 0) + pr_warn("FAIL: after strscpy() dst does not contain \"foob\" but \"%s\"\n", + dst); + + /* Shrink src so the strscpy() below succeeds. */ + src[3] = '\0'; + + /* + * Vanilla strscpy returns number of character copied if everything goes + * well. + */ + if (strscpy(dst, src, sizeof(dst)) != 3) + pr_warn("FAIL: strscpy() did not return 3 while src was copied entirely truncated\n"); + + /* After above call, dst must contain "foo" because src was copied. */ + if (strncmp(dst, "foo", sizeof(dst)) != 0) + pr_warn("FAIL: after strscpy() dst does not contain \"foo\" but \"%s\"\n", + dst); + + /* Test when src is embedded inside a union. */ + strscpy(weird_dst, weird.src, sizeof(weird_dst)); + + if (strcmp(weird_dst, "hello") != 0) + pr_warn("FAIL: after strscpy() weird_dst does not contain \"hello\" but \"%s\"\n", + weird_dst); + + /* Restore src to its initial value. */ + src[3] = 'b'; + + /* + * Use strlen here so size cannot be known at compile time and there is + * a runtime write overflow. + */ + strscpy(dst, src, strlen(src)); + + pr_warn("FAIL: No overflow in above strscpy()\n"); + + kfree(src); +} diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h index 6dec4c9b442f..5ae48c64df24 100644 --- a/drivers/misc/lkdtm/lkdtm.h +++ b/drivers/misc/lkdtm/lkdtm.h @@ -6,7 +6,7 @@ #include <linux/kernel.h> -/* lkdtm_bugs.c */ +/* bugs.c */ void __init lkdtm_bugs_init(int *recur_param); void lkdtm_PANIC(void); void lkdtm_BUG(void); @@ -32,8 +32,10 @@ void lkdtm_STACK_GUARD_PAGE_TRAILING(void); void lkdtm_UNSET_SMEP(void); void lkdtm_DOUBLE_FAULT(void); void lkdtm_CORRUPT_PAC(void); +void lkdtm_FORTIFY_OBJECT(void); +void lkdtm_FORTIFY_SUBOBJECT(void); -/* lkdtm_heap.c */ +/* heap.c */ void __init lkdtm_heap_init(void); void __exit lkdtm_heap_exit(void); void lkdtm_OVERWRITE_ALLOCATION(void); @@ -45,7 +47,7 @@ void lkdtm_SLAB_FREE_DOUBLE(void); void lkdtm_SLAB_FREE_CROSS(void); void lkdtm_SLAB_FREE_PAGE(void); -/* lkdtm_perms.c */ +/* perms.c */ void __init lkdtm_perms_init(void); void lkdtm_WRITE_RO(void); void lkdtm_WRITE_RO_AFTER_INIT(void); @@ -60,7 +62,7 @@ void lkdtm_EXEC_NULL(void); void lkdtm_ACCESS_USERSPACE(void); void lkdtm_ACCESS_NULL(void); -/* lkdtm_refcount.c */ +/* refcount.c */ void lkdtm_REFCOUNT_INC_OVERFLOW(void); void lkdtm_REFCOUNT_ADD_OVERFLOW(void); void lkdtm_REFCOUNT_INC_NOT_ZERO_OVERFLOW(void); @@ -81,10 +83,10 @@ void lkdtm_REFCOUNT_SUB_AND_TEST_SATURATED(void); void lkdtm_REFCOUNT_TIMING(void); void lkdtm_ATOMIC_TIMING(void); -/* lkdtm_rodata.c */ +/* rodata.c */ void lkdtm_rodata_do_nothing(void); -/* lkdtm_usercopy.c */ +/* usercopy.c */ void __init lkdtm_usercopy_init(void); void __exit lkdtm_usercopy_exit(void); void lkdtm_USERCOPY_HEAP_SIZE_TO(void); @@ -96,10 +98,16 @@ void lkdtm_USERCOPY_STACK_FRAME_FROM(void); void lkdtm_USERCOPY_STACK_BEYOND(void); void lkdtm_USERCOPY_KERNEL(void); -/* lkdtm_stackleak.c */ +/* stackleak.c */ void lkdtm_STACKLEAK_ERASING(void); /* cfi.c */ void lkdtm_CFI_FORWARD_PROTO(void); +/* fortify.c */ +void lkdtm_FORTIFIED_STRSCPY(void); + +/* powerpc.c */ +void lkdtm_PPC_SLB_MULTIHIT(void); + #endif diff --git a/drivers/misc/lkdtm/powerpc.c b/drivers/misc/lkdtm/powerpc.c new file mode 100644 index 000000000000..077c9f9ed8d0 --- /dev/null +++ b/drivers/misc/lkdtm/powerpc.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "lkdtm.h" +#include <linux/slab.h> +#include <linux/vmalloc.h> +#include <asm/mmu.h> + +/* Inserts new slb entries */ +static void insert_slb_entry(unsigned long p, int ssize, int page_size) +{ + unsigned long flags; + + flags = SLB_VSID_KERNEL | mmu_psize_defs[page_size].sllp; + preempt_disable(); + + asm volatile("slbmte %0,%1" : + : "r" (mk_vsid_data(p, ssize, flags)), + "r" (mk_esid_data(p, ssize, SLB_NUM_BOLTED)) + : "memory"); + + asm volatile("slbmte %0,%1" : + : "r" (mk_vsid_data(p, ssize, flags)), + "r" (mk_esid_data(p, ssize, SLB_NUM_BOLTED + 1)) + : "memory"); + preempt_enable(); +} + +/* Inject slb multihit on vmalloc-ed address i.e 0xD00... */ +static int inject_vmalloc_slb_multihit(void) +{ + char *p; + + p = vmalloc(PAGE_SIZE); + if (!p) + return -ENOMEM; + + insert_slb_entry((unsigned long)p, MMU_SEGSIZE_1T, mmu_vmalloc_psize); + /* + * This triggers exception, If handled correctly we must recover + * from this error. + */ + p[0] = '!'; + vfree(p); + return 0; +} + +/* Inject slb multihit on kmalloc-ed address i.e 0xC00... */ +static int inject_kmalloc_slb_multihit(void) +{ + char *p; + + p = kmalloc(2048, GFP_KERNEL); + if (!p) + return -ENOMEM; + + insert_slb_entry((unsigned long)p, MMU_SEGSIZE_1T, mmu_linear_psize); + /* + * This triggers exception, If handled correctly we must recover + * from this error. + */ + p[0] = '!'; + kfree(p); + return 0; +} + +/* + * Few initial SLB entries are bolted. Add a test to inject + * multihit in bolted entry 0. + */ +static void insert_dup_slb_entry_0(void) +{ + unsigned long test_address = PAGE_OFFSET, *test_ptr; + unsigned long esid, vsid; + unsigned long i = 0; + + test_ptr = (unsigned long *)test_address; + preempt_disable(); + + asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i)); + asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i)); + + /* for i !=0 we would need to mask out the old entry number */ + asm volatile("slbmte %0,%1" : + : "r" (vsid), + "r" (esid | SLB_NUM_BOLTED) + : "memory"); + + asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i)); + asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i)); + + /* for i !=0 we would need to mask out the old entry number */ + asm volatile("slbmte %0,%1" : + : "r" (vsid), + "r" (esid | (SLB_NUM_BOLTED + 1)) + : "memory"); + + pr_info("%s accessing test address 0x%lx: 0x%lx\n", + __func__, test_address, *test_ptr); + + preempt_enable(); +} + +void lkdtm_PPC_SLB_MULTIHIT(void) +{ + if (!radix_enabled()) { + pr_info("Injecting SLB multihit errors\n"); + /* + * These need not be separate tests, And they do pretty + * much same thing. In any case we must recover from the + * errors introduced by these functions, machine would not + * survive these tests in case of failure to handle. + */ + inject_vmalloc_slb_multihit(); + inject_kmalloc_slb_multihit(); + insert_dup_slb_entry_0(); + pr_info("Recovered from SLB multihit errors\n"); + } else { + pr_err("XFAIL: This test is for ppc64 and with hash mode MMU only\n"); + } +} diff --git a/drivers/misc/lkdtm/rodata.c b/drivers/misc/lkdtm/rodata.c index 58d180af72cf..baacb876d1d9 100644 --- a/drivers/misc/lkdtm/rodata.c +++ b/drivers/misc/lkdtm/rodata.c @@ -5,7 +5,7 @@ */ #include "lkdtm.h" -void notrace lkdtm_rodata_do_nothing(void) +void noinstr lkdtm_rodata_do_nothing(void) { /* Does nothing. We just want an architecture agnostic "return". */ } diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig index c06581ffa7bd..f5fd5b786607 100644 --- a/drivers/misc/mei/Kconfig +++ b/drivers/misc/mei/Kconfig @@ -46,14 +46,4 @@ config INTEL_MEI_TXE Supported SoCs: Intel Bay Trail -config INTEL_MEI_VIRTIO - tristate "Intel MEI interface emulation with virtio framework" - select INTEL_MEI - depends on X86 && PCI && VIRTIO_PCI - help - This module implements mei hw emulation over virtio transport. - The module will be called mei_virtio. - Enable this if your virtual machine supports virtual mei - device over virtio. - source "drivers/misc/mei/hdcp/Kconfig" diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile index 52aefaab5c1b..f1c76f7ee804 100644 --- a/drivers/misc/mei/Makefile +++ b/drivers/misc/mei/Makefile @@ -22,9 +22,6 @@ obj-$(CONFIG_INTEL_MEI_TXE) += mei-txe.o mei-txe-objs := pci-txe.o mei-txe-objs += hw-txe.o -obj-$(CONFIG_INTEL_MEI_VIRTIO) += mei-virtio.o -mei-virtio-objs := hw-virtio.o - mei-$(CONFIG_EVENT_TRACING) += mei-trace.o CFLAGS_mei-trace.o = -I$(src) diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c index 4e30fa98fe7d..d8e760b11ae3 100644 --- a/drivers/misc/mei/bus-fixup.c +++ b/drivers/misc/mei/bus-fixup.c @@ -33,6 +33,9 @@ static const uuid_le mei_nfc_info_guid = MEI_UUID_NFC_INFO; #define MEI_UUID_HDCP UUID_LE(0xB638AB7E, 0x94E2, 0x4EA2, \ 0xA5, 0x52, 0xD1, 0xC5, 0x4B, 0x62, 0x7F, 0x04) +#define MEI_UUID_PAVP UUID_LE(0xfbf6fcf1, 0x96cf, 0x4e2e, 0xA6, \ + 0xa6, 0x1b, 0xab, 0x8c, 0xbe, 0x36, 0xb1) + #define MEI_UUID_ANY NULL_UUID_LE /** @@ -148,7 +151,7 @@ static int mei_osver(struct mei_cl_device *cldev) os_ver = (struct mei_os_ver *)fwcaps->data; os_ver->os_type = OSTYPE_LINUX; - return __mei_cl_send(cldev->cl, buf, size, mode); + return __mei_cl_send(cldev->cl, buf, size, 0, mode); } #define MKHI_FWVER_BUF_LEN (sizeof(struct mkhi_msg_hdr) + \ @@ -169,7 +172,7 @@ static int mei_fwver(struct mei_cl_device *cldev) req.hdr.group_id = MKHI_GEN_GROUP_ID; req.hdr.command = MKHI_GEN_GET_FW_VERSION_CMD; - ret = __mei_cl_send(cldev->cl, (u8 *)&req, sizeof(req), + ret = __mei_cl_send(cldev->cl, (u8 *)&req, sizeof(req), 0, MEI_CL_IO_TX_BLOCKING); if (ret < 0) { dev_err(&cldev->dev, "Could not send ReqFWVersion cmd\n"); @@ -177,7 +180,7 @@ static int mei_fwver(struct mei_cl_device *cldev) } ret = 0; - bytes_recv = __mei_cl_recv(cldev->cl, buf, sizeof(buf), 0, + bytes_recv = __mei_cl_recv(cldev->cl, buf, sizeof(buf), NULL, 0, MKHI_RCV_TIMEOUT); if (bytes_recv < 0 || (size_t)bytes_recv < MKHI_FWVER_LEN(1)) { /* @@ -324,13 +327,15 @@ static int mei_nfc_if_version(struct mei_cl *cl, }; struct mei_nfc_reply *reply = NULL; size_t if_version_length; + u8 vtag; int bytes_recv, ret; bus = cl->dev; WARN_ON(mutex_is_locked(&bus->device_lock)); - ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(cmd), MEI_CL_IO_TX_BLOCKING); + ret = __mei_cl_send(cl, (u8 *)&cmd, sizeof(cmd), 0, + MEI_CL_IO_TX_BLOCKING); if (ret < 0) { dev_err(bus->dev, "Could not send IF version cmd\n"); return ret; @@ -344,7 +349,8 @@ static int mei_nfc_if_version(struct mei_cl *cl, return -ENOMEM; ret = 0; - bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, 0, 0); + bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length, &vtag, + 0, 0); if (bytes_recv < 0 || (size_t)bytes_recv < if_version_length) { dev_err(bus->dev, "Could not read IF version\n"); ret = -EIO; @@ -488,6 +494,7 @@ static struct mei_fixup { MEI_FIXUP(MEI_UUID_MKHIF_FIX, mei_mkhi_fix), MEI_FIXUP(MEI_UUID_HDCP, whitelist), MEI_FIXUP(MEI_UUID_ANY, vt_support), + MEI_FIXUP(MEI_UUID_PAVP, whitelist), }; /** diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 9cdaa7f3af23..2907db260fba 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -26,11 +26,12 @@ * @cl: host client * @buf: buffer to send * @length: buffer length + * @vtag: virtual tag * @mode: sending mode * * Return: written size bytes or < 0 on error */ -ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, +ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, u8 vtag, unsigned int mode) { struct mei_device *bus; @@ -86,6 +87,7 @@ ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, rets = -ENOMEM; goto out; } + cb->vtag = vtag; cb->internal = !!(mode & MEI_CL_IO_TX_INTERNAL); cb->blocking = !!(mode & MEI_CL_IO_TX_BLOCKING); @@ -106,11 +108,12 @@ out: * @buf: buffer to receive * @length: buffer length * @mode: io mode + * @vtag: virtual tag * @timeout: recv timeout, 0 for infinite timeout * * Return: read size in bytes of < 0 on error */ -ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, +ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, u8 *vtag, unsigned int mode, unsigned long timeout) { struct mei_device *bus; @@ -196,6 +199,8 @@ copy: r_length = min_t(size_t, length, cb->buf_idx); memcpy(buf, cb->buf.data, r_length); rets = r_length; + if (vtag) + *vtag = cb->vtag; free: mei_cl_del_rd_completed(cl, cb); @@ -206,40 +211,87 @@ out: } /** - * mei_cldev_send - me device send (write) + * mei_cldev_send_vtag - me device send with vtag (write) * * @cldev: me client device * @buf: buffer to send * @length: buffer length + * @vtag: virtual tag * - * Return: written size in bytes or < 0 on error + * Return: + * * written size in bytes + * * < 0 on error */ -ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length) + +ssize_t mei_cldev_send_vtag(struct mei_cl_device *cldev, u8 *buf, size_t length, + u8 vtag) { struct mei_cl *cl = cldev->cl; - return __mei_cl_send(cl, buf, length, MEI_CL_IO_TX_BLOCKING); + return __mei_cl_send(cl, buf, length, vtag, MEI_CL_IO_TX_BLOCKING); } -EXPORT_SYMBOL_GPL(mei_cldev_send); +EXPORT_SYMBOL_GPL(mei_cldev_send_vtag); /** - * mei_cldev_recv_nonblock - non block client receive (read) + * mei_cldev_recv_vtag - client receive with vtag (read) * * @cldev: me client device * @buf: buffer to receive * @length: buffer length + * @vtag: virtual tag * - * Return: read size in bytes of < 0 on error - * -EAGAIN if function will block. + * Return: + * * read size in bytes + * * < 0 on error */ -ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf, - size_t length) + +ssize_t mei_cldev_recv_vtag(struct mei_cl_device *cldev, u8 *buf, size_t length, + u8 *vtag) { struct mei_cl *cl = cldev->cl; - return __mei_cl_recv(cl, buf, length, MEI_CL_IO_RX_NONBLOCK, 0); + return __mei_cl_recv(cl, buf, length, vtag, 0, 0); } -EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock); +EXPORT_SYMBOL_GPL(mei_cldev_recv_vtag); + +/** + * mei_cldev_recv_nonblock_vtag - non block client receive with vtag (read) + * + * @cldev: me client device + * @buf: buffer to receive + * @length: buffer length + * @vtag: virtual tag + * + * Return: + * * read size in bytes + * * -EAGAIN if function will block. + * * < 0 on other error + */ +ssize_t mei_cldev_recv_nonblock_vtag(struct mei_cl_device *cldev, u8 *buf, + size_t length, u8 *vtag) +{ + struct mei_cl *cl = cldev->cl; + + return __mei_cl_recv(cl, buf, length, vtag, MEI_CL_IO_RX_NONBLOCK, 0); +} +EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock_vtag); + +/** + * mei_cldev_send - me device send (write) + * + * @cldev: me client device + * @buf: buffer to send + * @length: buffer length + * + * Return: + * * written size in bytes + * * < 0 on error + */ +ssize_t mei_cldev_send(struct mei_cl_device *cldev, u8 *buf, size_t length) +{ + return mei_cldev_send_vtag(cldev, buf, length, 0); +} +EXPORT_SYMBOL_GPL(mei_cldev_send); /** * mei_cldev_recv - client receive (read) @@ -252,13 +304,28 @@ EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock); */ ssize_t mei_cldev_recv(struct mei_cl_device *cldev, u8 *buf, size_t length) { - struct mei_cl *cl = cldev->cl; - - return __mei_cl_recv(cl, buf, length, 0, 0); + return mei_cldev_recv_vtag(cldev, buf, length, NULL); } EXPORT_SYMBOL_GPL(mei_cldev_recv); /** + * mei_cldev_recv_nonblock - non block client receive (read) + * + * @cldev: me client device + * @buf: buffer to receive + * @length: buffer length + * + * Return: read size in bytes of < 0 on error + * -EAGAIN if function will block. + */ +ssize_t mei_cldev_recv_nonblock(struct mei_cl_device *cldev, u8 *buf, + size_t length) +{ + return mei_cldev_recv_nonblock_vtag(cldev, buf, length, NULL); +} +EXPORT_SYMBOL_GPL(mei_cldev_recv_nonblock); + +/** * mei_cl_bus_rx_work - dispatch rx event for a bus device * * @work: work @@ -276,7 +343,8 @@ static void mei_cl_bus_rx_work(struct work_struct *work) cldev->rx_cb(cldev); mutex_lock(&bus->device_lock); - mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL); + if (mei_cl_is_connected(cldev->cl)) + mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL); mutex_unlock(&bus->device_lock); } @@ -364,10 +432,16 @@ int mei_cldev_register_rx_cb(struct mei_cl_device *cldev, mei_cldev_cb_t rx_cb) INIT_WORK(&cldev->rx_work, mei_cl_bus_rx_work); mutex_lock(&bus->device_lock); - ret = mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL); + if (mei_cl_is_connected(cldev->cl)) + ret = mei_cl_read_start(cldev->cl, mei_cl_mtu(cldev->cl), NULL); + else + ret = -ENODEV; mutex_unlock(&bus->device_lock); - if (ret && ret != -EBUSY) + if (ret && ret != -EBUSY) { + cancel_work_sync(&cldev->rx_work); + cldev->rx_cb = NULL; return ret; + } return 0; } @@ -401,8 +475,11 @@ int mei_cldev_register_notif_cb(struct mei_cl_device *cldev, mutex_lock(&bus->device_lock); ret = mei_cl_notify_request(cldev->cl, NULL, 1); mutex_unlock(&bus->device_lock); - if (ret) + if (ret) { + cancel_work_sync(&cldev->notif_work); + cldev->notif_cb = NULL; return ret; + } return 0; } @@ -1037,7 +1114,7 @@ static struct mei_cl_device *mei_cl_bus_dev_alloc(struct mei_device *bus, } /** - * mei_cl_dev_setup - setup me client device + * mei_cl_bus_dev_setup - setup me client device * run fix up routines and set the device name * * @bus: mei device diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index d5c3f7d54634..a56d41321f32 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -1306,7 +1306,7 @@ struct mei_cl_vtag *mei_cl_vtag_alloc(struct file *fp, u8 vtag) * mei_cl_fp_by_vtag - obtain the file pointer by vtag * * @cl: host client - * @vtag: vm tag + * @vtag: virtual tag * * Return: * * A file pointer - on success @@ -1317,7 +1317,9 @@ const struct file *mei_cl_fp_by_vtag(const struct mei_cl *cl, u8 vtag) struct mei_cl_vtag *vtag_l; list_for_each_entry(vtag_l, &cl->vtag_map, list) - if (vtag_l->vtag == vtag) + /* The client on bus has one fixed fp */ + if ((cl->cldev && mei_cldev_enabled(cl->cldev)) || + vtag_l->vtag == vtag) return vtag_l->fp; return ERR_PTR(-ENOENT); diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index 64143d4ec758..9e08a9843bba 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h @@ -182,11 +182,11 @@ static inline u8 mei_cl_me_id(const struct mei_cl *cl) * * @cl: host client * - * Return: mtu + * Return: mtu or 0 if client is not connected */ static inline size_t mei_cl_mtu(const struct mei_cl *cl) { - return cl->me_cl->props.max_msg_length; + return cl->me_cl ? cl->me_cl->props.max_msg_length : 0; } /** diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index a97eb5d47705..686e8b6a4c55 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -1377,7 +1377,6 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) dev_info(dev->dev, "hbm: stop response: resetting.\n"); /* force the reset */ return -EPROTO; - break; case CLIENT_DISCONNECT_REQ_CMD: dev_dbg(dev->dev, "hbm: disconnect request: message received\n"); diff --git a/drivers/misc/mei/hw-virtio.c b/drivers/misc/mei/hw-virtio.c deleted file mode 100644 index 899dc1c5e7ca..000000000000 --- a/drivers/misc/mei/hw-virtio.c +++ /dev/null @@ -1,874 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Intel Management Engine Interface (Intel MEI) Linux driver - * Copyright (c) 2018-2020, Intel Corporation. - */ -#include <linux/err.h> -#include <linux/module.h> -#include <linux/pm_runtime.h> -#include <linux/scatterlist.h> -#include <linux/spinlock.h> -#include <linux/slab.h> -#include <linux/virtio.h> -#include <linux/virtio_config.h> -#include <linux/virtio_ids.h> -#include <linux/atomic.h> - -#include "mei_dev.h" -#include "hbm.h" -#include "client.h" - -#define MEI_VIRTIO_RPM_TIMEOUT 500 -/* ACRN virtio device types */ -#ifndef VIRTIO_ID_MEI -#define VIRTIO_ID_MEI 0xFFFE /* virtio mei */ -#endif - -/** - * struct mei_virtio_cfg - settings passed from the virtio backend - * @buf_depth: read buffer depth in slots (4bytes) - * @hw_ready: hw is ready for operation - * @host_reset: synchronize reset with virtio backend - * @reserved: reserved for alignment - * @fw_status: FW status - */ -struct mei_virtio_cfg { - u32 buf_depth; - u8 hw_ready; - u8 host_reset; - u8 reserved[2]; - u32 fw_status[MEI_FW_STATUS_MAX]; -} __packed; - -struct mei_virtio_hw { - struct mei_device mdev; - char name[32]; - - struct virtqueue *in; - struct virtqueue *out; - - bool host_ready; - struct work_struct intr_handler; - - u32 *recv_buf; - u8 recv_rdy; - size_t recv_sz; - u32 recv_idx; - u32 recv_len; - - /* send buffer */ - atomic_t hbuf_ready; - const void *send_hdr; - const void *send_buf; - - struct mei_virtio_cfg cfg; -}; - -#define to_virtio_hw(_dev) container_of(_dev, struct mei_virtio_hw, mdev) - -/** - * mei_virtio_fw_status() - read status register of mei - * @dev: mei device - * @fw_status: fw status register values - * - * Return: always 0 - */ -static int mei_virtio_fw_status(struct mei_device *dev, - struct mei_fw_status *fw_status) -{ - struct virtio_device *vdev = dev_to_virtio(dev->dev); - - fw_status->count = MEI_FW_STATUS_MAX; - virtio_cread_bytes(vdev, offsetof(struct mei_virtio_cfg, fw_status), - fw_status->status, sizeof(fw_status->status)); - return 0; -} - -/** - * mei_virtio_pg_state() - translate internal pg state - * to the mei power gating state - * There is no power management in ACRN mode always return OFF - * @dev: mei device - * - * Return: - * * MEI_PG_OFF - if aliveness is on (always) - * * MEI_PG_ON - (never) - */ -static inline enum mei_pg_state mei_virtio_pg_state(struct mei_device *dev) -{ - return MEI_PG_OFF; -} - -/** - * mei_virtio_hw_config() - configure hw dependent settings - * - * @dev: mei device - * - * Return: always 0 - */ -static int mei_virtio_hw_config(struct mei_device *dev) -{ - return 0; -} - -/** - * mei_virtio_hbuf_empty_slots() - counts write empty slots. - * @dev: the device structure - * - * Return: always return frontend buf size if buffer is ready, 0 otherwise - */ -static int mei_virtio_hbuf_empty_slots(struct mei_device *dev) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - - return (atomic_read(&hw->hbuf_ready) == 1) ? hw->cfg.buf_depth : 0; -} - -/** - * mei_virtio_hbuf_is_ready() - checks if write buffer is ready - * @dev: the device structure - * - * Return: true if hbuf is ready - */ -static bool mei_virtio_hbuf_is_ready(struct mei_device *dev) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - - return atomic_read(&hw->hbuf_ready) == 1; -} - -/** - * mei_virtio_hbuf_max_depth() - returns depth of FE write buffer. - * @dev: the device structure - * - * Return: size of frontend write buffer in bytes - */ -static u32 mei_virtio_hbuf_depth(const struct mei_device *dev) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - - return hw->cfg.buf_depth; -} - -/** - * mei_virtio_intr_clear() - clear and stop interrupts - * @dev: the device structure - */ -static void mei_virtio_intr_clear(struct mei_device *dev) -{ - /* - * In our virtio solution, there are two types of interrupts, - * vq interrupt and config change interrupt. - * 1) start/reset rely on virtio config changed interrupt; - * 2) send/recv rely on virtio virtqueue interrupts. - * They are all virtual interrupts. So, we don't have corresponding - * operation to do here. - */ -} - -/** - * mei_virtio_intr_enable() - enables mei BE virtqueues callbacks - * @dev: the device structure - */ -static void mei_virtio_intr_enable(struct mei_device *dev) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - struct virtio_device *vdev = dev_to_virtio(dev->dev); - - virtio_config_enable(vdev); - - virtqueue_enable_cb(hw->in); - virtqueue_enable_cb(hw->out); -} - -/** - * mei_virtio_intr_disable() - disables mei BE virtqueues callbacks - * - * @dev: the device structure - */ -static void mei_virtio_intr_disable(struct mei_device *dev) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - struct virtio_device *vdev = dev_to_virtio(dev->dev); - - virtio_config_disable(vdev); - - virtqueue_disable_cb(hw->in); - virtqueue_disable_cb(hw->out); -} - -/** - * mei_virtio_synchronize_irq() - wait for pending IRQ handlers for all - * virtqueue - * @dev: the device structure - */ -static void mei_virtio_synchronize_irq(struct mei_device *dev) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - - /* - * Now, all IRQ handlers are converted to workqueue. - * Change synchronize irq to flush this work. - */ - flush_work(&hw->intr_handler); -} - -static void mei_virtio_free_outbufs(struct mei_virtio_hw *hw) -{ - kfree(hw->send_hdr); - kfree(hw->send_buf); - hw->send_hdr = NULL; - hw->send_buf = NULL; -} - -/** - * mei_virtio_write_message() - writes a message to mei virtio back-end service. - * @dev: the device structure - * @hdr: mei header of message - * @hdr_len: header length - * @data: message payload will be written - * @data_len: message payload length - * - * Return: - * * 0: on success - * * -EIO: if write has failed - * * -ENOMEM: on memory allocation failure - */ -static int mei_virtio_write_message(struct mei_device *dev, - const void *hdr, size_t hdr_len, - const void *data, size_t data_len) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - struct scatterlist sg[2]; - const void *hbuf, *dbuf; - int ret; - - if (WARN_ON(!atomic_add_unless(&hw->hbuf_ready, -1, 0))) - return -EIO; - - hbuf = kmemdup(hdr, hdr_len, GFP_KERNEL); - hw->send_hdr = hbuf; - - dbuf = kmemdup(data, data_len, GFP_KERNEL); - hw->send_buf = dbuf; - - if (!hbuf || !dbuf) { - ret = -ENOMEM; - goto fail; - } - - sg_init_table(sg, 2); - sg_set_buf(&sg[0], hbuf, hdr_len); - sg_set_buf(&sg[1], dbuf, data_len); - - ret = virtqueue_add_outbuf(hw->out, sg, 2, hw, GFP_KERNEL); - if (ret) { - dev_err(dev->dev, "failed to add outbuf\n"); - goto fail; - } - - virtqueue_kick(hw->out); - return 0; -fail: - - mei_virtio_free_outbufs(hw); - - return ret; -} - -/** - * mei_virtio_count_full_read_slots() - counts read full slots. - * @dev: the device structure - * - * Return: -EOVERFLOW if overflow, otherwise filled slots count - */ -static int mei_virtio_count_full_read_slots(struct mei_device *dev) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - - if (hw->recv_idx > hw->recv_len) - return -EOVERFLOW; - - return hw->recv_len - hw->recv_idx; -} - -/** - * mei_virtio_read_hdr() - Reads 32bit dword from mei virtio receive buffer - * - * @dev: the device structure - * - * Return: 32bit dword of receive buffer (u32) - */ -static inline u32 mei_virtio_read_hdr(const struct mei_device *dev) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - - WARN_ON(hw->cfg.buf_depth < hw->recv_idx + 1); - - return hw->recv_buf[hw->recv_idx++]; -} - -static int mei_virtio_read(struct mei_device *dev, unsigned char *buffer, - unsigned long len) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - u32 slots = mei_data2slots(len); - - if (WARN_ON(hw->cfg.buf_depth < hw->recv_idx + slots)) - return -EOVERFLOW; - - /* - * Assumption: There is only one MEI message in recv_buf each time. - * Backend service need follow this rule too. - */ - memcpy(buffer, hw->recv_buf + hw->recv_idx, len); - hw->recv_idx += slots; - - return 0; -} - -static bool mei_virtio_pg_is_enabled(struct mei_device *dev) -{ - return false; -} - -static bool mei_virtio_pg_in_transition(struct mei_device *dev) -{ - return false; -} - -static void mei_virtio_add_recv_buf(struct mei_virtio_hw *hw) -{ - struct scatterlist sg; - - if (hw->recv_rdy) /* not needed */ - return; - - /* refill the recv_buf to IN virtqueue to get next message */ - sg_init_one(&sg, hw->recv_buf, mei_slots2data(hw->cfg.buf_depth)); - hw->recv_len = 0; - hw->recv_idx = 0; - hw->recv_rdy = 1; - virtqueue_add_inbuf(hw->in, &sg, 1, hw->recv_buf, GFP_KERNEL); - virtqueue_kick(hw->in); -} - -/** - * mei_virtio_hw_is_ready() - check whether the BE(hw) has turned ready - * @dev: mei device - * Return: bool - */ -static bool mei_virtio_hw_is_ready(struct mei_device *dev) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - struct virtio_device *vdev = dev_to_virtio(dev->dev); - - virtio_cread(vdev, struct mei_virtio_cfg, - hw_ready, &hw->cfg.hw_ready); - - dev_dbg(dev->dev, "hw ready %d\n", hw->cfg.hw_ready); - - return hw->cfg.hw_ready; -} - -/** - * mei_virtio_hw_reset - resets virtio hw. - * - * @dev: the device structure - * @intr_enable: virtio use data/config callbacks - * - * Return: 0 on success an error code otherwise - */ -static int mei_virtio_hw_reset(struct mei_device *dev, bool intr_enable) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - struct virtio_device *vdev = dev_to_virtio(dev->dev); - - dev_dbg(dev->dev, "hw reset\n"); - - dev->recvd_hw_ready = false; - hw->host_ready = false; - atomic_set(&hw->hbuf_ready, 0); - hw->recv_len = 0; - hw->recv_idx = 0; - - hw->cfg.host_reset = 1; - virtio_cwrite(vdev, struct mei_virtio_cfg, - host_reset, &hw->cfg.host_reset); - - mei_virtio_hw_is_ready(dev); - - if (intr_enable) - mei_virtio_intr_enable(dev); - - return 0; -} - -/** - * mei_virtio_hw_reset_release() - release device from the reset - * @dev: the device structure - */ -static void mei_virtio_hw_reset_release(struct mei_device *dev) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - struct virtio_device *vdev = dev_to_virtio(dev->dev); - - dev_dbg(dev->dev, "hw reset release\n"); - hw->cfg.host_reset = 0; - virtio_cwrite(vdev, struct mei_virtio_cfg, - host_reset, &hw->cfg.host_reset); -} - -/** - * mei_virtio_hw_ready_wait() - wait until the virtio(hw) has turned ready - * or timeout is reached - * @dev: mei device - * - * Return: 0 on success, error otherwise - */ -static int mei_virtio_hw_ready_wait(struct mei_device *dev) -{ - mutex_unlock(&dev->device_lock); - wait_event_timeout(dev->wait_hw_ready, - dev->recvd_hw_ready, - mei_secs_to_jiffies(MEI_HW_READY_TIMEOUT)); - mutex_lock(&dev->device_lock); - if (!dev->recvd_hw_ready) { - dev_err(dev->dev, "wait hw ready failed\n"); - return -ETIMEDOUT; - } - - dev->recvd_hw_ready = false; - return 0; -} - -/** - * mei_virtio_hw_start() - hw start routine - * @dev: mei device - * - * Return: 0 on success, error otherwise - */ -static int mei_virtio_hw_start(struct mei_device *dev) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - int ret; - - dev_dbg(dev->dev, "hw start\n"); - mei_virtio_hw_reset_release(dev); - - ret = mei_virtio_hw_ready_wait(dev); - if (ret) - return ret; - - mei_virtio_add_recv_buf(hw); - atomic_set(&hw->hbuf_ready, 1); - dev_dbg(dev->dev, "hw is ready\n"); - hw->host_ready = true; - - return 0; -} - -/** - * mei_virtio_host_is_ready() - check whether the FE has turned ready - * @dev: mei device - * - * Return: bool - */ -static bool mei_virtio_host_is_ready(struct mei_device *dev) -{ - struct mei_virtio_hw *hw = to_virtio_hw(dev); - - dev_dbg(dev->dev, "host ready %d\n", hw->host_ready); - - return hw->host_ready; -} - -/** - * mei_virtio_data_in() - The callback of recv virtqueue of virtio mei - * @vq: receiving virtqueue - */ -static void mei_virtio_data_in(struct virtqueue *vq) -{ - struct mei_virtio_hw *hw = vq->vdev->priv; - - /* disable interrupts (enabled again from in the interrupt worker) */ - virtqueue_disable_cb(hw->in); - - schedule_work(&hw->intr_handler); -} - -/** - * mei_virtio_data_out() - The callback of send virtqueue of virtio mei - * @vq: transmitting virtqueue - */ -static void mei_virtio_data_out(struct virtqueue *vq) -{ - struct mei_virtio_hw *hw = vq->vdev->priv; - - schedule_work(&hw->intr_handler); -} - -static void mei_virtio_intr_handler(struct work_struct *work) -{ - struct mei_virtio_hw *hw = - container_of(work, struct mei_virtio_hw, intr_handler); - struct mei_device *dev = &hw->mdev; - LIST_HEAD(complete_list); - s32 slots; - int rets = 0; - void *data; - unsigned int len; - - mutex_lock(&dev->device_lock); - - if (dev->dev_state == MEI_DEV_DISABLED) { - dev_warn(dev->dev, "Interrupt in disabled state.\n"); - mei_virtio_intr_disable(dev); - goto end; - } - - /* check if ME wants a reset */ - if (!mei_hw_is_ready(dev) && dev->dev_state != MEI_DEV_RESETTING) { - dev_warn(dev->dev, "BE service not ready: resetting.\n"); - schedule_work(&dev->reset_work); - goto end; - } - - /* check if we need to start the dev */ - if (!mei_host_is_ready(dev)) { - if (mei_hw_is_ready(dev)) { - dev_dbg(dev->dev, "we need to start the dev.\n"); - dev->recvd_hw_ready = true; - wake_up(&dev->wait_hw_ready); - } else { - dev_warn(dev->dev, "Spurious Interrupt\n"); - } - goto end; - } - - /* read */ - if (hw->recv_rdy) { - data = virtqueue_get_buf(hw->in, &len); - if (!data || !len) { - dev_dbg(dev->dev, "No data %d", len); - } else { - dev_dbg(dev->dev, "data_in %d\n", len); - WARN_ON(data != hw->recv_buf); - hw->recv_len = mei_data2slots(len); - hw->recv_rdy = 0; - } - } - - /* write */ - if (!atomic_read(&hw->hbuf_ready)) { - if (!virtqueue_get_buf(hw->out, &len)) { - dev_warn(dev->dev, "Failed to getbuf\n"); - } else { - mei_virtio_free_outbufs(hw); - atomic_inc(&hw->hbuf_ready); - } - } - - /* check slots available for reading */ - slots = mei_count_full_read_slots(dev); - while (slots > 0) { - dev_dbg(dev->dev, "slots to read = %08x\n", slots); - rets = mei_irq_read_handler(dev, &complete_list, &slots); - - if (rets && - (dev->dev_state != MEI_DEV_RESETTING && - dev->dev_state != MEI_DEV_POWER_DOWN)) { - dev_err(dev->dev, "mei_irq_read_handler ret = %d.\n", - rets); - schedule_work(&dev->reset_work); - goto end; - } - } - - dev->hbuf_is_ready = mei_hbuf_is_ready(dev); - - mei_irq_write_handler(dev, &complete_list); - - dev->hbuf_is_ready = mei_hbuf_is_ready(dev); - - mei_irq_compl_handler(dev, &complete_list); - - mei_virtio_add_recv_buf(hw); - -end: - if (dev->dev_state != MEI_DEV_DISABLED) { - if (!virtqueue_enable_cb(hw->in)) - schedule_work(&hw->intr_handler); - } - - mutex_unlock(&dev->device_lock); -} - -static void mei_virtio_config_changed(struct virtio_device *vdev) -{ - struct mei_virtio_hw *hw = vdev->priv; - struct mei_device *dev = &hw->mdev; - - virtio_cread(vdev, struct mei_virtio_cfg, - hw_ready, &hw->cfg.hw_ready); - - if (dev->dev_state == MEI_DEV_DISABLED) { - dev_dbg(dev->dev, "disabled state don't start\n"); - return; - } - - /* Run intr handler once to handle reset notify */ - schedule_work(&hw->intr_handler); -} - -static void mei_virtio_remove_vqs(struct virtio_device *vdev) -{ - struct mei_virtio_hw *hw = vdev->priv; - - virtqueue_detach_unused_buf(hw->in); - hw->recv_len = 0; - hw->recv_idx = 0; - hw->recv_rdy = 0; - - virtqueue_detach_unused_buf(hw->out); - - mei_virtio_free_outbufs(hw); - - vdev->config->del_vqs(vdev); -} - -/* - * There are two virtqueues, one is for send and another is for recv. - */ -static int mei_virtio_init_vqs(struct mei_virtio_hw *hw, - struct virtio_device *vdev) -{ - struct virtqueue *vqs[2]; - - vq_callback_t *cbs[] = { - mei_virtio_data_in, - mei_virtio_data_out, - }; - static const char * const names[] = { - "in", - "out", - }; - int ret; - - ret = virtio_find_vqs(vdev, 2, vqs, cbs, names, NULL); - if (ret) - return ret; - - hw->in = vqs[0]; - hw->out = vqs[1]; - - return 0; -} - -static const struct mei_hw_ops mei_virtio_ops = { - .fw_status = mei_virtio_fw_status, - .pg_state = mei_virtio_pg_state, - - .host_is_ready = mei_virtio_host_is_ready, - - .hw_is_ready = mei_virtio_hw_is_ready, - .hw_reset = mei_virtio_hw_reset, - .hw_config = mei_virtio_hw_config, - .hw_start = mei_virtio_hw_start, - - .pg_in_transition = mei_virtio_pg_in_transition, - .pg_is_enabled = mei_virtio_pg_is_enabled, - - .intr_clear = mei_virtio_intr_clear, - .intr_enable = mei_virtio_intr_enable, - .intr_disable = mei_virtio_intr_disable, - .synchronize_irq = mei_virtio_synchronize_irq, - - .hbuf_free_slots = mei_virtio_hbuf_empty_slots, - .hbuf_is_ready = mei_virtio_hbuf_is_ready, - .hbuf_depth = mei_virtio_hbuf_depth, - - .write = mei_virtio_write_message, - - .rdbuf_full_slots = mei_virtio_count_full_read_slots, - .read_hdr = mei_virtio_read_hdr, - .read = mei_virtio_read, -}; - -static int mei_virtio_probe(struct virtio_device *vdev) -{ - struct mei_virtio_hw *hw; - int ret; - - hw = devm_kzalloc(&vdev->dev, sizeof(*hw), GFP_KERNEL); - if (!hw) - return -ENOMEM; - - vdev->priv = hw; - - INIT_WORK(&hw->intr_handler, mei_virtio_intr_handler); - - ret = mei_virtio_init_vqs(hw, vdev); - if (ret) - goto vqs_failed; - - virtio_cread(vdev, struct mei_virtio_cfg, - buf_depth, &hw->cfg.buf_depth); - - hw->recv_buf = kzalloc(mei_slots2data(hw->cfg.buf_depth), GFP_KERNEL); - if (!hw->recv_buf) { - ret = -ENOMEM; - goto hbuf_failed; - } - atomic_set(&hw->hbuf_ready, 0); - - virtio_device_ready(vdev); - - mei_device_init(&hw->mdev, &vdev->dev, &mei_virtio_ops); - - pm_runtime_get_noresume(&vdev->dev); - pm_runtime_set_active(&vdev->dev); - pm_runtime_enable(&vdev->dev); - - ret = mei_start(&hw->mdev); - if (ret) - goto mei_start_failed; - - pm_runtime_set_autosuspend_delay(&vdev->dev, MEI_VIRTIO_RPM_TIMEOUT); - pm_runtime_use_autosuspend(&vdev->dev); - - ret = mei_register(&hw->mdev, &vdev->dev); - if (ret) - goto mei_failed; - - pm_runtime_put(&vdev->dev); - - return 0; - -mei_failed: - mei_stop(&hw->mdev); -mei_start_failed: - mei_cancel_work(&hw->mdev); - mei_disable_interrupts(&hw->mdev); - kfree(hw->recv_buf); -hbuf_failed: - vdev->config->del_vqs(vdev); -vqs_failed: - return ret; -} - -static int __maybe_unused mei_virtio_pm_runtime_idle(struct device *device) -{ - struct virtio_device *vdev = dev_to_virtio(device); - struct mei_virtio_hw *hw = vdev->priv; - - dev_dbg(&vdev->dev, "rpm: mei_virtio : runtime_idle\n"); - - if (!hw) - return -ENODEV; - - if (mei_write_is_idle(&hw->mdev)) - pm_runtime_autosuspend(device); - - return -EBUSY; -} - -static int __maybe_unused mei_virtio_pm_runtime_suspend(struct device *device) -{ - return 0; -} - -static int __maybe_unused mei_virtio_pm_runtime_resume(struct device *device) -{ - return 0; -} - -static int __maybe_unused mei_virtio_freeze(struct virtio_device *vdev) -{ - struct mei_virtio_hw *hw = vdev->priv; - - dev_dbg(&vdev->dev, "freeze\n"); - - if (!hw) - return -ENODEV; - - mei_stop(&hw->mdev); - mei_disable_interrupts(&hw->mdev); - cancel_work_sync(&hw->intr_handler); - vdev->config->reset(vdev); - mei_virtio_remove_vqs(vdev); - - return 0; -} - -static int __maybe_unused mei_virtio_restore(struct virtio_device *vdev) -{ - struct mei_virtio_hw *hw = vdev->priv; - int ret; - - dev_dbg(&vdev->dev, "restore\n"); - - if (!hw) - return -ENODEV; - - ret = mei_virtio_init_vqs(hw, vdev); - if (ret) - return ret; - - virtio_device_ready(vdev); - - ret = mei_restart(&hw->mdev); - if (ret) - return ret; - - /* Start timer if stopped in suspend */ - schedule_delayed_work(&hw->mdev.timer_work, HZ); - - return 0; -} - -static const struct dev_pm_ops mei_virtio_pm_ops = { - SET_RUNTIME_PM_OPS(mei_virtio_pm_runtime_suspend, - mei_virtio_pm_runtime_resume, - mei_virtio_pm_runtime_idle) -}; - -static void mei_virtio_remove(struct virtio_device *vdev) -{ - struct mei_virtio_hw *hw = vdev->priv; - - mei_stop(&hw->mdev); - mei_disable_interrupts(&hw->mdev); - cancel_work_sync(&hw->intr_handler); - mei_deregister(&hw->mdev); - vdev->config->reset(vdev); - mei_virtio_remove_vqs(vdev); - kfree(hw->recv_buf); - pm_runtime_disable(&vdev->dev); -} - -static struct virtio_device_id id_table[] = { - { VIRTIO_ID_MEI, VIRTIO_DEV_ANY_ID }, - { } -}; - -static struct virtio_driver mei_virtio_driver = { - .id_table = id_table, - .probe = mei_virtio_probe, - .remove = mei_virtio_remove, - .config_changed = mei_virtio_config_changed, - .driver = { - .name = KBUILD_MODNAME, - .owner = THIS_MODULE, - .pm = &mei_virtio_pm_ops, - }, -#ifdef CONFIG_PM_SLEEP - .freeze = mei_virtio_freeze, - .restore = mei_virtio_restore, -#endif -}; - -module_virtio_driver(mei_virtio_driver); -MODULE_DEVICE_TABLE(virtio, id_table); -MODULE_DESCRIPTION("Virtio MEI frontend driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mei/hw.h b/drivers/misc/mei/hw.h index 8bac86c4d86b..df2fb9520dd8 100644 --- a/drivers/misc/mei/hw.h +++ b/drivers/misc/mei/hw.h @@ -224,7 +224,7 @@ struct mei_ext_hdr { u8 type; u8 length; u8 ext_payload[2]; - u8 hdr[0]; + u8 hdr[]; }; /** @@ -238,7 +238,7 @@ struct mei_ext_meta_hdr { u8 count; u8 size; u8 reserved[2]; - struct mei_ext_hdr hdrs[0]; + struct mei_ext_hdr hdrs[]; }; /* @@ -308,7 +308,7 @@ struct mei_msg_hdr { u32 dma_ring:1; u32 internal:1; u32 msg_complete:1; - u32 extension[0]; + u32 extension[]; } __packed; /* The length is up to 9 bits */ diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 2f4cc1a8aae8..8c395bfdf6f3 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -340,9 +340,9 @@ struct mei_hw_ops { /* MEI bus API*/ void mei_cl_bus_rescan_work(struct work_struct *work); void mei_cl_bus_dev_fixup(struct mei_cl_device *dev); -ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, +ssize_t __mei_cl_send(struct mei_cl *cl, u8 *buf, size_t length, u8 vtag, unsigned int mode); -ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, +ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length, u8 *vtag, unsigned int mode, unsigned long timeout); bool mei_cl_bus_rx_event(struct mei_cl *cl); bool mei_cl_bus_notify_event(struct mei_cl *cl); diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig deleted file mode 100644 index 8a7c2c5711d5..000000000000 --- a/drivers/misc/mic/Kconfig +++ /dev/null @@ -1,141 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -menu "Intel MIC & related support" - -config INTEL_MIC_BUS - tristate "Intel MIC Bus Driver" - depends on 64BIT && PCI && X86 - select DMA_OPS - help - This option is selected by any driver which registers a - device or driver on the MIC Bus, such as CONFIG_INTEL_MIC_HOST, - CONFIG_INTEL_MIC_CARD, CONFIG_INTEL_MIC_X100_DMA etc. - - If you are building a host/card kernel with an Intel MIC device - then say M (recommended) or Y, else say N. If unsure say N. - - More information about the Intel MIC family as well as the Linux - OS and tools for MIC to use with this driver are available from - <http://software.intel.com/en-us/mic-developer>. - -config SCIF_BUS - tristate "SCIF Bus Driver" - depends on 64BIT && PCI && X86 - select DMA_OPS - help - This option is selected by any driver which registers a - device or driver on the SCIF Bus, such as CONFIG_INTEL_MIC_HOST - and CONFIG_INTEL_MIC_CARD. - - If you are building a host/card kernel with an Intel MIC device - then say M (recommended) or Y, else say N. If unsure say N. - - More information about the Intel MIC family as well as the Linux - OS and tools for MIC to use with this driver are available from - <http://software.intel.com/en-us/mic-developer>. - -config VOP_BUS - tristate "VOP Bus Driver" - depends on HAS_DMA - select DMA_OPS - help - This option is selected by any driver which registers a - device or driver on the VOP Bus, such as CONFIG_INTEL_MIC_HOST - and CONFIG_INTEL_MIC_CARD. - - If you are building a host/card kernel with an Intel MIC device - then say M (recommended) or Y, else say N. If unsure say N. - - More information about the Intel MIC family as well as the Linux - OS and tools for MIC to use with this driver are available from - <http://software.intel.com/en-us/mic-developer>. - -config INTEL_MIC_HOST - tristate "Intel MIC Host Driver" - depends on 64BIT && PCI && X86 - depends on INTEL_MIC_BUS && SCIF_BUS && MIC_COSM && VOP_BUS - select DMA_OPS - help - This enables Host Driver support for the Intel Many Integrated - Core (MIC) family of PCIe form factor coprocessor devices that - run a 64 bit Linux OS. The driver manages card OS state and - enables communication between host and card. Intel MIC X100 - devices are currently supported. - - If you are building a host kernel with an Intel MIC device then - say M (recommended) or Y, else say N. If unsure say N. - - More information about the Intel MIC family as well as the Linux - OS and tools for MIC to use with this driver are available from - <http://software.intel.com/en-us/mic-developer>. - -config INTEL_MIC_CARD - tristate "Intel MIC Card Driver" - depends on 64BIT && X86 - depends on INTEL_MIC_BUS && SCIF_BUS && MIC_COSM && VOP_BUS - select VIRTIO - help - This enables card driver support for the Intel Many Integrated - Core (MIC) device family. The card driver communicates shutdown/ - crash events to the host and allows registration/configuration of - virtio devices. Intel MIC X100 devices are currently supported. - - If you are building a card kernel for an Intel MIC device then - say M (recommended) or Y, else say N. If unsure say N. - - For more information see - <http://software.intel.com/en-us/mic-developer>. - -config SCIF - tristate "SCIF Driver" - depends on 64BIT && PCI && X86 && SCIF_BUS && IOMMU_SUPPORT - select IOMMU_IOVA - help - This enables SCIF Driver support for the Intel Many Integrated - Core (MIC) family of PCIe form factor coprocessor devices that - run a 64 bit Linux OS. The Symmetric Communication Interface - (SCIF (pronounced as skiff)) is a low level communications API - across PCIe currently implemented for MIC. - - If you are building a host kernel with an Intel MIC device then - say M (recommended) or Y, else say N. If unsure say N. - - More information about the Intel MIC family as well as the Linux - OS and tools for MIC to use with this driver are available from - <http://software.intel.com/en-us/mic-developer>. - -config MIC_COSM - tristate "Intel MIC Coprocessor State Management (COSM) Drivers" - depends on 64BIT && PCI && X86 && SCIF - help - This enables COSM driver support for the Intel Many - Integrated Core (MIC) family of PCIe form factor coprocessor - devices. COSM drivers implement functions such as boot, - shutdown, reset and reboot of MIC devices. - - If you are building a host kernel with an Intel MIC device then - say M (recommended) or Y, else say N. If unsure say N. - - More information about the Intel MIC family as well as the Linux - OS and tools for MIC to use with this driver are available from - <http://software.intel.com/en-us/mic-developer>. - -config VOP - tristate "VOP Driver" - depends on VOP_BUS - select VHOST_RING - select VIRTIO - help - This enables VOP (Virtio over PCIe) Driver support for the Intel - Many Integrated Core (MIC) family of PCIe form factor coprocessor - devices. The VOP driver allows virtio drivers, e.g. net, console - and block drivers, on the card connect to user space virtio - devices on the host. - - If you are building a host kernel with an Intel MIC device then - say M (recommended) or Y, else say N. If unsure say N. - - More information about the Intel MIC family as well as the Linux - OS and tools for MIC to use with this driver are available from - <http://software.intel.com/en-us/mic-developer>. - -endmenu diff --git a/drivers/misc/mic/Makefile b/drivers/misc/mic/Makefile deleted file mode 100644 index 1a43622b183f..000000000000 --- a/drivers/misc/mic/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile - Intel MIC Linux driver. -# Copyright(c) 2013, Intel Corporation. -# -obj-$(CONFIG_INTEL_MIC_HOST) += host/ -obj-$(CONFIG_INTEL_MIC_CARD) += card/ -obj-y += bus/ -obj-$(CONFIG_SCIF) += scif/ -obj-$(CONFIG_MIC_COSM) += cosm/ -obj-$(CONFIG_MIC_COSM) += cosm_client/ -obj-$(CONFIG_VOP) += vop/ diff --git a/drivers/misc/mic/bus/Makefile b/drivers/misc/mic/bus/Makefile deleted file mode 100644 index 0a6aa21b2f67..000000000000 --- a/drivers/misc/mic/bus/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile - Intel MIC Linux driver. -# Copyright(c) 2014, Intel Corporation. -# -obj-$(CONFIG_INTEL_MIC_BUS) += mic_bus.o -obj-$(CONFIG_SCIF_BUS) += scif_bus.o -obj-$(CONFIG_MIC_COSM) += cosm_bus.o -obj-$(CONFIG_VOP_BUS) += vop_bus.o diff --git a/drivers/misc/mic/bus/cosm_bus.c b/drivers/misc/mic/bus/cosm_bus.c deleted file mode 100644 index 5f2141c71738..000000000000 --- a/drivers/misc/mic/bus/cosm_bus.c +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel MIC COSM Bus Driver - */ -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/idr.h> -#include "cosm_bus.h" - -/* Unique numbering for cosm devices. */ -static DEFINE_IDA(cosm_index_ida); - -static int cosm_dev_probe(struct device *d) -{ - struct cosm_device *dev = dev_to_cosm(d); - struct cosm_driver *drv = drv_to_cosm(dev->dev.driver); - - return drv->probe(dev); -} - -static int cosm_dev_remove(struct device *d) -{ - struct cosm_device *dev = dev_to_cosm(d); - struct cosm_driver *drv = drv_to_cosm(dev->dev.driver); - - drv->remove(dev); - return 0; -} - -static struct bus_type cosm_bus = { - .name = "cosm_bus", - .probe = cosm_dev_probe, - .remove = cosm_dev_remove, -}; - -int cosm_register_driver(struct cosm_driver *driver) -{ - driver->driver.bus = &cosm_bus; - return driver_register(&driver->driver); -} -EXPORT_SYMBOL_GPL(cosm_register_driver); - -void cosm_unregister_driver(struct cosm_driver *driver) -{ - driver_unregister(&driver->driver); -} -EXPORT_SYMBOL_GPL(cosm_unregister_driver); - -static inline void cosm_release_dev(struct device *d) -{ - struct cosm_device *cdev = dev_to_cosm(d); - - kfree(cdev); -} - -struct cosm_device * -cosm_register_device(struct device *pdev, struct cosm_hw_ops *hw_ops) -{ - struct cosm_device *cdev; - int ret; - - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); - if (!cdev) - return ERR_PTR(-ENOMEM); - - cdev->dev.parent = pdev; - cdev->dev.release = cosm_release_dev; - cdev->hw_ops = hw_ops; - dev_set_drvdata(&cdev->dev, cdev); - cdev->dev.bus = &cosm_bus; - - /* Assign a unique device index and hence name */ - ret = ida_simple_get(&cosm_index_ida, 0, 0, GFP_KERNEL); - if (ret < 0) - goto free_cdev; - - cdev->index = ret; - cdev->dev.id = ret; - dev_set_name(&cdev->dev, "cosm-dev%u", cdev->index); - - ret = device_register(&cdev->dev); - if (ret) - goto ida_remove; - return cdev; -ida_remove: - ida_simple_remove(&cosm_index_ida, cdev->index); -free_cdev: - put_device(&cdev->dev); - return ERR_PTR(ret); -} -EXPORT_SYMBOL_GPL(cosm_register_device); - -void cosm_unregister_device(struct cosm_device *dev) -{ - int index = dev->index; /* save for after device release */ - - device_unregister(&dev->dev); - ida_simple_remove(&cosm_index_ida, index); -} -EXPORT_SYMBOL_GPL(cosm_unregister_device); - -struct cosm_device *cosm_find_cdev_by_id(int id) -{ - struct device *dev = subsys_find_device_by_id(&cosm_bus, id, NULL); - - return dev ? container_of(dev, struct cosm_device, dev) : NULL; -} -EXPORT_SYMBOL_GPL(cosm_find_cdev_by_id); - -static int __init cosm_init(void) -{ - return bus_register(&cosm_bus); -} - -static void __exit cosm_exit(void) -{ - bus_unregister(&cosm_bus); - ida_destroy(&cosm_index_ida); -} - -core_initcall(cosm_init); -module_exit(cosm_exit); - -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) MIC card OS state management bus driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mic/bus/cosm_bus.h b/drivers/misc/mic/bus/cosm_bus.h deleted file mode 100644 index d50d7aea168d..000000000000 --- a/drivers/misc/mic/bus/cosm_bus.h +++ /dev/null @@ -1,125 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel MIC COSM Bus Driver - */ -#ifndef _COSM_BUS_H_ -#define _COSM_BUS_H_ - -#include <linux/scif.h> -#include <linux/mic_common.h> -#include "../common/mic_dev.h" - -/** - * cosm_device - representation of a cosm device - * - * @attr_group: Pointer to list of sysfs attribute groups. - * @sdev: Device for sysfs entries. - * @state: MIC state. - * @prev_state: MIC state previous to MIC_RESETTING - * @shutdown_status: MIC status reported by card for shutdown/crashes. - * @shutdown_status_int: Internal shutdown status maintained by the driver - * @cosm_mutex: Mutex for synchronizing access to data structures. - * @reset_trigger_work: Work for triggering reset requests. - * @scif_work: Work for handling per device SCIF connections - * @cmdline: Kernel command line. - * @firmware: Firmware file name. - * @ramdisk: Ramdisk file name. - * @bootmode: Boot mode i.e. "linux" or "elf" for flash updates. - * @log_buf_addr: Log buffer address for MIC. - * @log_buf_len: Log buffer length address for MIC. - * @state_sysfs: Sysfs dirent for notifying ring 3 about MIC state changes. - * @hw_ops: the hardware bus ops for this device. - * @dev: underlying device. - * @index: unique position on the cosm bus - * @dbg_dir: debug fs directory - * @newepd: new endpoint from scif accept to be assigned to this cdev - * @epd: SCIF endpoint for this cdev - * @heartbeat_watchdog_enable: if heartbeat watchdog is enabled for this cdev - * @sysfs_heartbeat_enable: sysfs setting for disabling heartbeat notification - */ -struct cosm_device { - const struct attribute_group **attr_group; - struct device *sdev; - u8 state; - u8 prev_state; - u8 shutdown_status; - u8 shutdown_status_int; - struct mutex cosm_mutex; - struct work_struct reset_trigger_work; - struct work_struct scif_work; - char *cmdline; - char *firmware; - char *ramdisk; - char *bootmode; - void *log_buf_addr; - int *log_buf_len; - struct kernfs_node *state_sysfs; - struct cosm_hw_ops *hw_ops; - struct device dev; - int index; - struct dentry *dbg_dir; - scif_epd_t newepd; - scif_epd_t epd; - bool heartbeat_watchdog_enable; - bool sysfs_heartbeat_enable; -}; - -/** - * cosm_driver - operations for a cosm driver - * - * @driver: underlying device driver (populate name and owner). - * @probe: the function to call when a device is found. Returns 0 or -errno. - * @remove: the function to call when a device is removed. - */ -struct cosm_driver { - struct device_driver driver; - int (*probe)(struct cosm_device *dev); - void (*remove)(struct cosm_device *dev); -}; - -/** - * cosm_hw_ops - cosm bus ops - * - * @reset: trigger MIC reset - * @force_reset: force MIC reset - * @post_reset: inform MIC reset is complete - * @ready: is MIC ready for OS download - * @start: boot MIC - * @stop: prepare MIC for reset - * @family: return MIC HW family string - * @stepping: return MIC HW stepping string - * @aper: return MIC PCIe aperture - */ -struct cosm_hw_ops { - void (*reset)(struct cosm_device *cdev); - void (*force_reset)(struct cosm_device *cdev); - void (*post_reset)(struct cosm_device *cdev, enum mic_states state); - bool (*ready)(struct cosm_device *cdev); - int (*start)(struct cosm_device *cdev, int id); - void (*stop)(struct cosm_device *cdev, bool force); - ssize_t (*family)(struct cosm_device *cdev, char *buf); - ssize_t (*stepping)(struct cosm_device *cdev, char *buf); - struct mic_mw *(*aper)(struct cosm_device *cdev); -}; - -struct cosm_device * -cosm_register_device(struct device *pdev, struct cosm_hw_ops *hw_ops); -void cosm_unregister_device(struct cosm_device *dev); -int cosm_register_driver(struct cosm_driver *drv); -void cosm_unregister_driver(struct cosm_driver *drv); -struct cosm_device *cosm_find_cdev_by_id(int id); - -static inline struct cosm_device *dev_to_cosm(struct device *dev) -{ - return container_of(dev, struct cosm_device, dev); -} - -static inline struct cosm_driver *drv_to_cosm(struct device_driver *drv) -{ - return container_of(drv, struct cosm_driver, driver); -} -#endif /* _COSM_BUS_H */ diff --git a/drivers/misc/mic/bus/mic_bus.c b/drivers/misc/mic/bus/mic_bus.c deleted file mode 100644 index a08cb29692a8..000000000000 --- a/drivers/misc/mic/bus/mic_bus.c +++ /dev/null @@ -1,194 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel MIC Bus driver. - * - * This implementation is very similar to the the virtio bus driver - * implementation @ drivers/virtio/virtio.c - */ -#include <linux/dma-map-ops.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/idr.h> -#include <linux/mic_bus.h> - -static ssize_t device_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct mbus_device *dev = dev_to_mbus(d); - return sprintf(buf, "0x%04x\n", dev->id.device); -} -static DEVICE_ATTR_RO(device); - -static ssize_t vendor_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct mbus_device *dev = dev_to_mbus(d); - return sprintf(buf, "0x%04x\n", dev->id.vendor); -} -static DEVICE_ATTR_RO(vendor); - -static ssize_t modalias_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct mbus_device *dev = dev_to_mbus(d); - return sprintf(buf, "mbus:d%08Xv%08X\n", - dev->id.device, dev->id.vendor); -} -static DEVICE_ATTR_RO(modalias); - -static struct attribute *mbus_dev_attrs[] = { - &dev_attr_device.attr, - &dev_attr_vendor.attr, - &dev_attr_modalias.attr, - NULL, -}; -ATTRIBUTE_GROUPS(mbus_dev); - -static inline int mbus_id_match(const struct mbus_device *dev, - const struct mbus_device_id *id) -{ - if (id->device != dev->id.device && id->device != MBUS_DEV_ANY_ID) - return 0; - - return id->vendor == MBUS_DEV_ANY_ID || id->vendor == dev->id.vendor; -} - -/* - * This looks through all the IDs a driver claims to support. If any of them - * match, we return 1 and the kernel will call mbus_dev_probe(). - */ -static int mbus_dev_match(struct device *dv, struct device_driver *dr) -{ - unsigned int i; - struct mbus_device *dev = dev_to_mbus(dv); - const struct mbus_device_id *ids; - - ids = drv_to_mbus(dr)->id_table; - for (i = 0; ids[i].device; i++) - if (mbus_id_match(dev, &ids[i])) - return 1; - return 0; -} - -static int mbus_uevent(struct device *dv, struct kobj_uevent_env *env) -{ - struct mbus_device *dev = dev_to_mbus(dv); - - return add_uevent_var(env, "MODALIAS=mbus:d%08Xv%08X", - dev->id.device, dev->id.vendor); -} - -static int mbus_dev_probe(struct device *d) -{ - int err; - struct mbus_device *dev = dev_to_mbus(d); - struct mbus_driver *drv = drv_to_mbus(dev->dev.driver); - - err = drv->probe(dev); - if (!err) - if (drv->scan) - drv->scan(dev); - return err; -} - -static int mbus_dev_remove(struct device *d) -{ - struct mbus_device *dev = dev_to_mbus(d); - struct mbus_driver *drv = drv_to_mbus(dev->dev.driver); - - drv->remove(dev); - return 0; -} - -static struct bus_type mic_bus = { - .name = "mic_bus", - .match = mbus_dev_match, - .dev_groups = mbus_dev_groups, - .uevent = mbus_uevent, - .probe = mbus_dev_probe, - .remove = mbus_dev_remove, -}; - -int mbus_register_driver(struct mbus_driver *driver) -{ - driver->driver.bus = &mic_bus; - return driver_register(&driver->driver); -} -EXPORT_SYMBOL_GPL(mbus_register_driver); - -void mbus_unregister_driver(struct mbus_driver *driver) -{ - driver_unregister(&driver->driver); -} -EXPORT_SYMBOL_GPL(mbus_unregister_driver); - -static void mbus_release_dev(struct device *d) -{ - struct mbus_device *mbdev = dev_to_mbus(d); - kfree(mbdev); -} - -struct mbus_device * -mbus_register_device(struct device *pdev, int id, const struct dma_map_ops *dma_ops, - struct mbus_hw_ops *hw_ops, int index, - void __iomem *mmio_va) -{ - int ret; - struct mbus_device *mbdev; - - mbdev = kzalloc(sizeof(*mbdev), GFP_KERNEL); - if (!mbdev) - return ERR_PTR(-ENOMEM); - - mbdev->mmio_va = mmio_va; - mbdev->dev.parent = pdev; - mbdev->id.device = id; - mbdev->id.vendor = MBUS_DEV_ANY_ID; - mbdev->dev.dma_ops = dma_ops; - mbdev->dev.dma_mask = &mbdev->dev.coherent_dma_mask; - dma_set_mask(&mbdev->dev, DMA_BIT_MASK(64)); - mbdev->dev.release = mbus_release_dev; - mbdev->hw_ops = hw_ops; - mbdev->dev.bus = &mic_bus; - mbdev->index = index; - dev_set_name(&mbdev->dev, "mbus-dev%u", mbdev->index); - /* - * device_register() causes the bus infrastructure to look for a - * matching driver. - */ - ret = device_register(&mbdev->dev); - if (ret) - goto free_mbdev; - return mbdev; -free_mbdev: - put_device(&mbdev->dev); - return ERR_PTR(ret); -} -EXPORT_SYMBOL_GPL(mbus_register_device); - -void mbus_unregister_device(struct mbus_device *mbdev) -{ - device_unregister(&mbdev->dev); -} -EXPORT_SYMBOL_GPL(mbus_unregister_device); - -static int __init mbus_init(void) -{ - return bus_register(&mic_bus); -} - -static void __exit mbus_exit(void) -{ - bus_unregister(&mic_bus); -} - -core_initcall(mbus_init); -module_exit(mbus_exit); - -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) MIC Bus driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mic/bus/scif_bus.c b/drivers/misc/mic/bus/scif_bus.c deleted file mode 100644 index ad7c3604f151..000000000000 --- a/drivers/misc/mic/bus/scif_bus.c +++ /dev/null @@ -1,201 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel Symmetric Communications Interface Bus driver. - */ -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/idr.h> -#include <linux/dma-map-ops.h> - -#include "scif_bus.h" - -static ssize_t device_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct scif_hw_dev *dev = dev_to_scif(d); - - return sprintf(buf, "0x%04x\n", dev->id.device); -} -static DEVICE_ATTR_RO(device); - -static ssize_t vendor_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct scif_hw_dev *dev = dev_to_scif(d); - - return sprintf(buf, "0x%04x\n", dev->id.vendor); -} -static DEVICE_ATTR_RO(vendor); - -static ssize_t modalias_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct scif_hw_dev *dev = dev_to_scif(d); - - return sprintf(buf, "scif:d%08Xv%08X\n", - dev->id.device, dev->id.vendor); -} -static DEVICE_ATTR_RO(modalias); - -static struct attribute *scif_dev_attrs[] = { - &dev_attr_device.attr, - &dev_attr_vendor.attr, - &dev_attr_modalias.attr, - NULL, -}; -ATTRIBUTE_GROUPS(scif_dev); - -static inline int scif_id_match(const struct scif_hw_dev *dev, - const struct scif_hw_dev_id *id) -{ - if (id->device != dev->id.device && id->device != SCIF_DEV_ANY_ID) - return 0; - - return id->vendor == SCIF_DEV_ANY_ID || id->vendor == dev->id.vendor; -} - -/* - * This looks through all the IDs a driver claims to support. If any of them - * match, we return 1 and the kernel will call scif_dev_probe(). - */ -static int scif_dev_match(struct device *dv, struct device_driver *dr) -{ - unsigned int i; - struct scif_hw_dev *dev = dev_to_scif(dv); - const struct scif_hw_dev_id *ids; - - ids = drv_to_scif(dr)->id_table; - for (i = 0; ids[i].device; i++) - if (scif_id_match(dev, &ids[i])) - return 1; - return 0; -} - -static int scif_uevent(struct device *dv, struct kobj_uevent_env *env) -{ - struct scif_hw_dev *dev = dev_to_scif(dv); - - return add_uevent_var(env, "MODALIAS=scif:d%08Xv%08X", - dev->id.device, dev->id.vendor); -} - -static int scif_dev_probe(struct device *d) -{ - struct scif_hw_dev *dev = dev_to_scif(d); - struct scif_driver *drv = drv_to_scif(dev->dev.driver); - - return drv->probe(dev); -} - -static int scif_dev_remove(struct device *d) -{ - struct scif_hw_dev *dev = dev_to_scif(d); - struct scif_driver *drv = drv_to_scif(dev->dev.driver); - - drv->remove(dev); - return 0; -} - -static struct bus_type scif_bus = { - .name = "scif_bus", - .match = scif_dev_match, - .dev_groups = scif_dev_groups, - .uevent = scif_uevent, - .probe = scif_dev_probe, - .remove = scif_dev_remove, -}; - -int scif_register_driver(struct scif_driver *driver) -{ - driver->driver.bus = &scif_bus; - return driver_register(&driver->driver); -} -EXPORT_SYMBOL_GPL(scif_register_driver); - -void scif_unregister_driver(struct scif_driver *driver) -{ - driver_unregister(&driver->driver); -} -EXPORT_SYMBOL_GPL(scif_unregister_driver); - -static void scif_release_dev(struct device *d) -{ - struct scif_hw_dev *sdev = dev_to_scif(d); - - kfree(sdev); -} - -struct scif_hw_dev * -scif_register_device(struct device *pdev, int id, const struct dma_map_ops *dma_ops, - struct scif_hw_ops *hw_ops, u8 dnode, u8 snode, - struct mic_mw *mmio, struct mic_mw *aper, void *dp, - void __iomem *rdp, struct dma_chan **chan, int num_chan, - bool card_rel_da) -{ - int ret; - struct scif_hw_dev *sdev; - - sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); - if (!sdev) - return ERR_PTR(-ENOMEM); - - sdev->dev.parent = pdev; - sdev->id.device = id; - sdev->id.vendor = SCIF_DEV_ANY_ID; - sdev->dev.dma_ops = dma_ops; - sdev->dev.release = scif_release_dev; - sdev->hw_ops = hw_ops; - sdev->dnode = dnode; - sdev->snode = snode; - dev_set_drvdata(&sdev->dev, sdev); - sdev->dev.bus = &scif_bus; - sdev->mmio = mmio; - sdev->aper = aper; - sdev->dp = dp; - sdev->rdp = rdp; - sdev->dev.dma_mask = &sdev->dev.coherent_dma_mask; - dma_set_mask(&sdev->dev, DMA_BIT_MASK(64)); - sdev->dma_ch = chan; - sdev->num_dma_ch = num_chan; - sdev->card_rel_da = card_rel_da; - dev_set_name(&sdev->dev, "scif-dev%u", sdev->dnode); - /* - * device_register() causes the bus infrastructure to look for a - * matching driver. - */ - ret = device_register(&sdev->dev); - if (ret) - goto free_sdev; - return sdev; -free_sdev: - put_device(&sdev->dev); - return ERR_PTR(ret); -} -EXPORT_SYMBOL_GPL(scif_register_device); - -void scif_unregister_device(struct scif_hw_dev *sdev) -{ - device_unregister(&sdev->dev); -} -EXPORT_SYMBOL_GPL(scif_unregister_device); - -static int __init scif_init(void) -{ - return bus_register(&scif_bus); -} - -static void __exit scif_exit(void) -{ - bus_unregister(&scif_bus); -} - -core_initcall(scif_init); -module_exit(scif_exit); - -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) SCIF Bus driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mic/bus/scif_bus.h b/drivers/misc/mic/bus/scif_bus.h deleted file mode 100644 index 4981eb56f879..000000000000 --- a/drivers/misc/mic/bus/scif_bus.h +++ /dev/null @@ -1,125 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel Symmetric Communications Interface Bus driver. - */ -#ifndef _SCIF_BUS_H_ -#define _SCIF_BUS_H_ -/* - * Everything a scif driver needs to work with any particular scif - * hardware abstraction layer. - */ -#include <linux/dma-map-ops.h> - -#include <linux/mic_common.h> -#include "../common/mic_dev.h" - -struct scif_hw_dev_id { - u32 device; - u32 vendor; -}; - -#define MIC_SCIF_DEV 1 -#define SCIF_DEV_ANY_ID 0xffffffff - -/** - * scif_hw_dev - representation of a hardware device abstracted for scif - * @hw_ops: the hardware ops supported by this device - * @id: the device type identification (used to match it with a driver) - * @mmio: MMIO memory window - * @aper: Aperture memory window - * @dev: underlying device - * @dnode - The destination node which this device will communicate with. - * @snode - The source node for this device. - * @dp - Self device page - * @rdp - Remote device page - * @dma_ch - Array of DMA channels - * @num_dma_ch - Number of DMA channels available - * @card_rel_da - Set to true if DMA addresses programmed in the DMA engine - * are relative to the card point of view - */ -struct scif_hw_dev { - struct scif_hw_ops *hw_ops; - struct scif_hw_dev_id id; - struct mic_mw *mmio; - struct mic_mw *aper; - struct device dev; - u8 dnode; - u8 snode; - void *dp; - void __iomem *rdp; - struct dma_chan **dma_ch; - int num_dma_ch; - bool card_rel_da; -}; - -/** - * scif_driver - operations for a scif I/O driver - * @driver: underlying device driver (populate name and owner). - * @id_table: the ids serviced by this driver. - * @probe: the function to call when a device is found. Returns 0 or -errno. - * @remove: the function to call when a device is removed. - */ -struct scif_driver { - struct device_driver driver; - const struct scif_hw_dev_id *id_table; - int (*probe)(struct scif_hw_dev *dev); - void (*remove)(struct scif_hw_dev *dev); -}; - -/** - * scif_hw_ops - Hardware operations for accessing a SCIF device on the SCIF bus. - * - * @next_db: Obtain the next available doorbell. - * @request_irq: Request an interrupt on a particular doorbell. - * @free_irq: Free an interrupt requested previously. - * @ack_interrupt: acknowledge an interrupt in the ISR. - * @send_intr: Send an interrupt to the remote node on a specified doorbell. - * @send_p2p_intr: Send an interrupt to the peer node on a specified doorbell - * which is specifically targeted for a peer to peer node. - * @remap: Map a buffer with the specified physical address and length. - * @unmap: Unmap a buffer previously mapped. - */ -struct scif_hw_ops { - int (*next_db)(struct scif_hw_dev *sdev); - struct mic_irq * (*request_irq)(struct scif_hw_dev *sdev, - irqreturn_t (*func)(int irq, - void *data), - const char *name, void *data, - int db); - void (*free_irq)(struct scif_hw_dev *sdev, - struct mic_irq *cookie, void *data); - void (*ack_interrupt)(struct scif_hw_dev *sdev, int num); - void (*send_intr)(struct scif_hw_dev *sdev, int db); - void (*send_p2p_intr)(struct scif_hw_dev *sdev, int db, - struct mic_mw *mw); - void __iomem * (*remap)(struct scif_hw_dev *sdev, - phys_addr_t pa, size_t len); - void (*unmap)(struct scif_hw_dev *sdev, void __iomem *va); -}; - -int scif_register_driver(struct scif_driver *driver); -void scif_unregister_driver(struct scif_driver *driver); -struct scif_hw_dev * -scif_register_device(struct device *pdev, int id, - const struct dma_map_ops *dma_ops, - struct scif_hw_ops *hw_ops, u8 dnode, u8 snode, - struct mic_mw *mmio, struct mic_mw *aper, - void *dp, void __iomem *rdp, - struct dma_chan **chan, int num_chan, - bool card_rel_da); -void scif_unregister_device(struct scif_hw_dev *sdev); - -static inline struct scif_hw_dev *dev_to_scif(struct device *dev) -{ - return container_of(dev, struct scif_hw_dev, dev); -} - -static inline struct scif_driver *drv_to_scif(struct device_driver *drv) -{ - return container_of(drv, struct scif_driver, driver); -} -#endif /* _SCIF_BUS_H */ diff --git a/drivers/misc/mic/bus/vop_bus.c b/drivers/misc/mic/bus/vop_bus.c deleted file mode 100644 index 6935ddca1bd5..000000000000 --- a/drivers/misc/mic/bus/vop_bus.c +++ /dev/null @@ -1,194 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2016 Intel Corporation. - * - * Intel Virtio Over PCIe (VOP) Bus driver. - */ -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/idr.h> -#include <linux/dma-map-ops.h> - -#include "vop_bus.h" - -static ssize_t device_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct vop_device *dev = dev_to_vop(d); - - return sprintf(buf, "0x%04x\n", dev->id.device); -} -static DEVICE_ATTR_RO(device); - -static ssize_t vendor_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct vop_device *dev = dev_to_vop(d); - - return sprintf(buf, "0x%04x\n", dev->id.vendor); -} -static DEVICE_ATTR_RO(vendor); - -static ssize_t modalias_show(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct vop_device *dev = dev_to_vop(d); - - return sprintf(buf, "vop:d%08Xv%08X\n", - dev->id.device, dev->id.vendor); -} -static DEVICE_ATTR_RO(modalias); - -static struct attribute *vop_dev_attrs[] = { - &dev_attr_device.attr, - &dev_attr_vendor.attr, - &dev_attr_modalias.attr, - NULL, -}; -ATTRIBUTE_GROUPS(vop_dev); - -static inline int vop_id_match(const struct vop_device *dev, - const struct vop_device_id *id) -{ - if (id->device != dev->id.device && id->device != VOP_DEV_ANY_ID) - return 0; - - return id->vendor == VOP_DEV_ANY_ID || id->vendor == dev->id.vendor; -} - -/* - * This looks through all the IDs a driver claims to support. If any of them - * match, we return 1 and the kernel will call vop_dev_probe(). - */ -static int vop_dev_match(struct device *dv, struct device_driver *dr) -{ - unsigned int i; - struct vop_device *dev = dev_to_vop(dv); - const struct vop_device_id *ids; - - ids = drv_to_vop(dr)->id_table; - for (i = 0; ids[i].device; i++) - if (vop_id_match(dev, &ids[i])) - return 1; - return 0; -} - -static int vop_uevent(struct device *dv, struct kobj_uevent_env *env) -{ - struct vop_device *dev = dev_to_vop(dv); - - return add_uevent_var(env, "MODALIAS=vop:d%08Xv%08X", - dev->id.device, dev->id.vendor); -} - -static int vop_dev_probe(struct device *d) -{ - struct vop_device *dev = dev_to_vop(d); - struct vop_driver *drv = drv_to_vop(dev->dev.driver); - - return drv->probe(dev); -} - -static int vop_dev_remove(struct device *d) -{ - struct vop_device *dev = dev_to_vop(d); - struct vop_driver *drv = drv_to_vop(dev->dev.driver); - - drv->remove(dev); - return 0; -} - -static struct bus_type vop_bus = { - .name = "vop_bus", - .match = vop_dev_match, - .dev_groups = vop_dev_groups, - .uevent = vop_uevent, - .probe = vop_dev_probe, - .remove = vop_dev_remove, -}; - -int vop_register_driver(struct vop_driver *driver) -{ - driver->driver.bus = &vop_bus; - return driver_register(&driver->driver); -} -EXPORT_SYMBOL_GPL(vop_register_driver); - -void vop_unregister_driver(struct vop_driver *driver) -{ - driver_unregister(&driver->driver); -} -EXPORT_SYMBOL_GPL(vop_unregister_driver); - -static void vop_release_dev(struct device *d) -{ - struct vop_device *dev = dev_to_vop(d); - - kfree(dev); -} - -struct vop_device * -vop_register_device(struct device *pdev, int id, - const struct dma_map_ops *dma_ops, - struct vop_hw_ops *hw_ops, u8 dnode, struct mic_mw *aper, - struct dma_chan *chan) -{ - int ret; - struct vop_device *vdev; - - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); - if (!vdev) - return ERR_PTR(-ENOMEM); - - vdev->dev.parent = pdev; - vdev->id.device = id; - vdev->id.vendor = VOP_DEV_ANY_ID; - vdev->dev.dma_ops = dma_ops; - vdev->dev.dma_mask = &vdev->dev.coherent_dma_mask; - dma_set_mask(&vdev->dev, DMA_BIT_MASK(64)); - vdev->dev.release = vop_release_dev; - vdev->hw_ops = hw_ops; - vdev->dev.bus = &vop_bus; - vdev->dnode = dnode; - vdev->aper = aper; - vdev->dma_ch = chan; - vdev->index = dnode - 1; - dev_set_name(&vdev->dev, "vop-dev%u", vdev->index); - /* - * device_register() causes the bus infrastructure to look for a - * matching driver. - */ - ret = device_register(&vdev->dev); - if (ret) - goto free_vdev; - return vdev; -free_vdev: - put_device(&vdev->dev); - return ERR_PTR(ret); -} -EXPORT_SYMBOL_GPL(vop_register_device); - -void vop_unregister_device(struct vop_device *dev) -{ - device_unregister(&dev->dev); -} -EXPORT_SYMBOL_GPL(vop_unregister_device); - -static int __init vop_init(void) -{ - return bus_register(&vop_bus); -} - -static void __exit vop_exit(void) -{ - bus_unregister(&vop_bus); -} - -core_initcall(vop_init); -module_exit(vop_exit); - -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) VOP Bus driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mic/bus/vop_bus.h b/drivers/misc/mic/bus/vop_bus.h deleted file mode 100644 index 4fa02808c1e2..000000000000 --- a/drivers/misc/mic/bus/vop_bus.h +++ /dev/null @@ -1,129 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2016 Intel Corporation. - * - * Intel Virtio over PCIe Bus driver. - */ -#ifndef _VOP_BUS_H_ -#define _VOP_BUS_H_ -/* - * Everything a vop driver needs to work with any particular vop - * implementation. - */ -#include <linux/dmaengine.h> -#include <linux/interrupt.h> - -#include "../common/mic_dev.h" - -struct vop_device_id { - u32 device; - u32 vendor; -}; - -#define VOP_DEV_TRNSP 1 -#define VOP_DEV_ANY_ID 0xffffffff -/* - * Size of the internal buffer used during DMA's as an intermediate buffer - * for copy to/from user. Must be an integral number of pages. - */ -#define VOP_INT_DMA_BUF_SIZE PAGE_ALIGN(64 * 1024ULL) - -/** - * vop_device - representation of a device using vop - * @hw_ops: the hardware ops supported by this device. - * @id: the device type identification (used to match it with a driver). - * @dev: underlying device. - * @dnode - The destination node which this device will communicate with. - * @aper: Aperture memory window - * @dma_ch - DMA channel - * @index: unique position on the vop bus - */ -struct vop_device { - struct vop_hw_ops *hw_ops; - struct vop_device_id id; - struct device dev; - u8 dnode; - struct mic_mw *aper; - struct dma_chan *dma_ch; - int index; -}; - -/** - * vop_driver - operations for a vop I/O driver - * @driver: underlying device driver (populate name and owner). - * @id_table: the ids serviced by this driver. - * @probe: the function to call when a device is found. Returns 0 or -errno. - * @remove: the function to call when a device is removed. - */ -struct vop_driver { - struct device_driver driver; - const struct vop_device_id *id_table; - int (*probe)(struct vop_device *dev); - void (*remove)(struct vop_device *dev); -}; - -/** - * vop_hw_ops - Hardware operations for accessing a VOP device on the VOP bus. - * - * @next_db: Obtain the next available doorbell. - * @request_irq: Request an interrupt on a particular doorbell. - * @free_irq: Free an interrupt requested previously. - * @ack_interrupt: acknowledge an interrupt in the ISR. - * @get_remote_dp: Get access to the virtio device page used by the remote - * node to add/remove/configure virtio devices. - * @get_dp: Get access to the virtio device page used by the self - * node to add/remove/configure virtio devices. - * @send_intr: Send an interrupt to the peer node on a specified doorbell. - * @remap: Map a buffer with the specified DMA address and length. - * @unmap: Unmap a buffer previously mapped. - * @dma_filter: The DMA filter function to use for obtaining access to - * a DMA channel on the peer node. - */ -struct vop_hw_ops { - int (*next_db)(struct vop_device *vpdev); - struct mic_irq *(*request_irq)(struct vop_device *vpdev, - irqreturn_t (*func)(int irq, void *data), - const char *name, void *data, - int intr_src); - void (*free_irq)(struct vop_device *vpdev, - struct mic_irq *cookie, void *data); - void (*ack_interrupt)(struct vop_device *vpdev, int num); - void __iomem * (*get_remote_dp)(struct vop_device *vpdev); - void * (*get_dp)(struct vop_device *vpdev); - void (*send_intr)(struct vop_device *vpdev, int db); - void __iomem * (*remap)(struct vop_device *vpdev, - dma_addr_t pa, size_t len); - void (*unmap)(struct vop_device *vpdev, void __iomem *va); -}; - -struct vop_device * -vop_register_device(struct device *pdev, int id, - const struct dma_map_ops *dma_ops, - struct vop_hw_ops *hw_ops, u8 dnode, struct mic_mw *aper, - struct dma_chan *chan); -void vop_unregister_device(struct vop_device *dev); -int vop_register_driver(struct vop_driver *drv); -void vop_unregister_driver(struct vop_driver *drv); - -/* - * module_vop_driver() - Helper macro for drivers that don't do - * anything special in module init/exit. This eliminates a lot of - * boilerplate. Each module may only use this macro once, and - * calling it replaces module_init() and module_exit() - */ -#define module_vop_driver(__vop_driver) \ - module_driver(__vop_driver, vop_register_driver, \ - vop_unregister_driver) - -static inline struct vop_device *dev_to_vop(struct device *dev) -{ - return container_of(dev, struct vop_device, dev); -} - -static inline struct vop_driver *drv_to_vop(struct device_driver *drv) -{ - return container_of(drv, struct vop_driver, driver); -} -#endif /* _VOP_BUS_H */ diff --git a/drivers/misc/mic/card/Makefile b/drivers/misc/mic/card/Makefile deleted file mode 100644 index 921a7e7e0fbd..000000000000 --- a/drivers/misc/mic/card/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile - Intel MIC Linux driver. -# Copyright(c) 2013, Intel Corporation. -# -ccflags-y += -DINTEL_MIC_CARD - -obj-$(CONFIG_INTEL_MIC_CARD) += mic_card.o -mic_card-y += mic_x100.o -mic_card-y += mic_device.o -mic_card-y += mic_debugfs.o diff --git a/drivers/misc/mic/card/mic_debugfs.c b/drivers/misc/mic/card/mic_debugfs.c deleted file mode 100644 index 4c326e8f4d99..000000000000 --- a/drivers/misc/mic/card/mic_debugfs.c +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Disclaimer: The codes contained in these modules may be specific to - * the Intel Software Development Platform codenamed: Knights Ferry, and - * the Intel product codenamed: Knights Corner, and are not backward - * compatible with other Intel products. Additionally, Intel will NOT - * support the codes or instruction set in future products. - * - * Intel MIC Card driver. - */ -#include <linux/debugfs.h> -#include <linux/delay.h> -#include <linux/seq_file.h> -#include <linux/interrupt.h> -#include <linux/device.h> - -#include "../common/mic_dev.h" -#include "mic_device.h" - -/* Debugfs parent dir */ -static struct dentry *mic_dbg; - -/* - * mic_intr_show - Send interrupts to host. - */ -static int mic_intr_show(struct seq_file *s, void *unused) -{ - struct mic_driver *mdrv = s->private; - struct mic_device *mdev = &mdrv->mdev; - - mic_send_intr(mdev, 0); - msleep(1000); - mic_send_intr(mdev, 1); - msleep(1000); - mic_send_intr(mdev, 2); - msleep(1000); - mic_send_intr(mdev, 3); - msleep(1000); - - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(mic_intr); - -/* - * mic_create_card_debug_dir - Initialize MIC debugfs entries. - */ -void __init mic_create_card_debug_dir(struct mic_driver *mdrv) -{ - if (!mic_dbg) - return; - - mdrv->dbg_dir = debugfs_create_dir(mdrv->name, mic_dbg); - - debugfs_create_file("intr_test", 0444, mdrv->dbg_dir, mdrv, - &mic_intr_fops); -} - -/* - * mic_delete_card_debug_dir - Uninitialize MIC debugfs entries. - */ -void mic_delete_card_debug_dir(struct mic_driver *mdrv) -{ - debugfs_remove_recursive(mdrv->dbg_dir); -} - -/* - * mic_init_card_debugfs - Initialize global debugfs entry. - */ -void __init mic_init_card_debugfs(void) -{ - mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); -} - -/* - * mic_exit_card_debugfs - Uninitialize global debugfs entry - */ -void mic_exit_card_debugfs(void) -{ - debugfs_remove(mic_dbg); -} diff --git a/drivers/misc/mic/card/mic_device.c b/drivers/misc/mic/card/mic_device.c deleted file mode 100644 index a15606259bdc..000000000000 --- a/drivers/misc/mic/card/mic_device.c +++ /dev/null @@ -1,417 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Disclaimer: The codes contained in these modules may be specific to - * the Intel Software Development Platform codenamed: Knights Ferry, and - * the Intel product codenamed: Knights Corner, and are not backward - * compatible with other Intel products. Additionally, Intel will NOT - * support the codes or instruction set in future products. - * - * Intel MIC Card driver. - */ -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/interrupt.h> -#include <linux/reboot.h> -#include <linux/dmaengine.h> -#include <linux/kmod.h> - -#include <linux/mic_common.h> -#include "../common/mic_dev.h" -#include "mic_device.h" - -static struct mic_driver *g_drv; - -static int __init mic_dp_init(void) -{ - struct mic_driver *mdrv = g_drv; - struct mic_device *mdev = &mdrv->mdev; - struct mic_bootparam __iomem *bootparam; - u64 lo, hi, dp_dma_addr; - u32 magic; - - lo = mic_read_spad(&mdrv->mdev, MIC_DPLO_SPAD); - hi = mic_read_spad(&mdrv->mdev, MIC_DPHI_SPAD); - - dp_dma_addr = lo | (hi << 32); - mdrv->dp = mic_card_map(mdev, dp_dma_addr, MIC_DP_SIZE); - if (!mdrv->dp) { - dev_err(mdrv->dev, "Cannot remap Aperture BAR\n"); - return -ENOMEM; - } - bootparam = mdrv->dp; - magic = ioread32(&bootparam->magic); - if (MIC_MAGIC != magic) { - dev_err(mdrv->dev, "bootparam magic mismatch 0x%x\n", magic); - return -EIO; - } - return 0; -} - -/* Uninitialize the device page */ -static void mic_dp_uninit(void) -{ - mic_card_unmap(&g_drv->mdev, g_drv->dp); -} - -/** - * mic_request_card_irq - request an irq. - * - * @handler: interrupt handler passed to request_threaded_irq. - * @thread_fn: thread fn. passed to request_threaded_irq. - * @name: The ASCII name of the callee requesting the irq. - * @data: private data that is returned back when calling the - * function handler. - * @index: The doorbell index of the requester. - * - * returns: The cookie that is transparent to the caller. Passed - * back when calling mic_free_irq. An appropriate error code - * is returned on failure. Caller needs to use IS_ERR(return_val) - * to check for failure and PTR_ERR(return_val) to obtained the - * error code. - * - */ -struct mic_irq * -mic_request_card_irq(irq_handler_t handler, - irq_handler_t thread_fn, const char *name, - void *data, int index) -{ - int rc = 0; - unsigned long cookie; - struct mic_driver *mdrv = g_drv; - - rc = request_threaded_irq(mic_db_to_irq(mdrv, index), handler, - thread_fn, 0, name, data); - if (rc) { - dev_err(mdrv->dev, "request_threaded_irq failed rc = %d\n", rc); - goto err; - } - mdrv->irq_info.irq_usage_count[index]++; - cookie = index; - return (struct mic_irq *)cookie; -err: - return ERR_PTR(rc); -} - -/** - * mic_free_card_irq - free irq. - * - * @cookie: cookie obtained during a successful call to mic_request_threaded_irq - * @data: private data specified by the calling function during the - * mic_request_threaded_irq - * - * returns: none. - */ -void mic_free_card_irq(struct mic_irq *cookie, void *data) -{ - int index; - struct mic_driver *mdrv = g_drv; - - index = (unsigned long)cookie & 0xFFFFU; - free_irq(mic_db_to_irq(mdrv, index), data); - mdrv->irq_info.irq_usage_count[index]--; -} - -/** - * mic_next_card_db - Get the doorbell with minimum usage count. - * - * Returns the irq index. - */ -int mic_next_card_db(void) -{ - int i; - int index = 0; - struct mic_driver *mdrv = g_drv; - - for (i = 0; i < mdrv->intr_info.num_intr; i++) { - if (mdrv->irq_info.irq_usage_count[i] < - mdrv->irq_info.irq_usage_count[index]) - index = i; - } - - return index; -} - -/** - * mic_init_irq - Initialize irq information. - * - * Returns 0 in success. Appropriate error code on failure. - */ -static int mic_init_irq(void) -{ - struct mic_driver *mdrv = g_drv; - - mdrv->irq_info.irq_usage_count = kzalloc((sizeof(u32) * - mdrv->intr_info.num_intr), - GFP_KERNEL); - if (!mdrv->irq_info.irq_usage_count) - return -ENOMEM; - return 0; -} - -/** - * mic_uninit_irq - Uninitialize irq information. - * - * None. - */ -static void mic_uninit_irq(void) -{ - struct mic_driver *mdrv = g_drv; - - kfree(mdrv->irq_info.irq_usage_count); -} - -static inline struct mic_driver *scdev_to_mdrv(struct scif_hw_dev *scdev) -{ - return dev_get_drvdata(scdev->dev.parent); -} - -static struct mic_irq * -___mic_request_irq(struct scif_hw_dev *scdev, - irqreturn_t (*func)(int irq, void *data), - const char *name, void *data, - int db) -{ - return mic_request_card_irq(func, NULL, name, data, db); -} - -static void -___mic_free_irq(struct scif_hw_dev *scdev, - struct mic_irq *cookie, void *data) -{ - return mic_free_card_irq(cookie, data); -} - -static void ___mic_ack_interrupt(struct scif_hw_dev *scdev, int num) -{ - struct mic_driver *mdrv = scdev_to_mdrv(scdev); - - mic_ack_interrupt(&mdrv->mdev); -} - -static int ___mic_next_db(struct scif_hw_dev *scdev) -{ - return mic_next_card_db(); -} - -static void ___mic_send_intr(struct scif_hw_dev *scdev, int db) -{ - struct mic_driver *mdrv = scdev_to_mdrv(scdev); - - mic_send_intr(&mdrv->mdev, db); -} - -static void ___mic_send_p2p_intr(struct scif_hw_dev *scdev, int db, - struct mic_mw *mw) -{ - mic_send_p2p_intr(db, mw); -} - -static void __iomem * -___mic_ioremap(struct scif_hw_dev *scdev, - phys_addr_t pa, size_t len) -{ - struct mic_driver *mdrv = scdev_to_mdrv(scdev); - - return mic_card_map(&mdrv->mdev, pa, len); -} - -static void ___mic_iounmap(struct scif_hw_dev *scdev, void __iomem *va) -{ - struct mic_driver *mdrv = scdev_to_mdrv(scdev); - - mic_card_unmap(&mdrv->mdev, va); -} - -static struct scif_hw_ops scif_hw_ops = { - .request_irq = ___mic_request_irq, - .free_irq = ___mic_free_irq, - .ack_interrupt = ___mic_ack_interrupt, - .next_db = ___mic_next_db, - .send_intr = ___mic_send_intr, - .send_p2p_intr = ___mic_send_p2p_intr, - .remap = ___mic_ioremap, - .unmap = ___mic_iounmap, -}; - -static inline struct mic_driver *vpdev_to_mdrv(struct vop_device *vpdev) -{ - return dev_get_drvdata(vpdev->dev.parent); -} - -static struct mic_irq * -__mic_request_irq(struct vop_device *vpdev, - irqreturn_t (*func)(int irq, void *data), - const char *name, void *data, int intr_src) -{ - return mic_request_card_irq(func, NULL, name, data, intr_src); -} - -static void __mic_free_irq(struct vop_device *vpdev, - struct mic_irq *cookie, void *data) -{ - return mic_free_card_irq(cookie, data); -} - -static void __mic_ack_interrupt(struct vop_device *vpdev, int num) -{ - struct mic_driver *mdrv = vpdev_to_mdrv(vpdev); - - mic_ack_interrupt(&mdrv->mdev); -} - -static int __mic_next_db(struct vop_device *vpdev) -{ - return mic_next_card_db(); -} - -static void __iomem *__mic_get_remote_dp(struct vop_device *vpdev) -{ - struct mic_driver *mdrv = vpdev_to_mdrv(vpdev); - - return mdrv->dp; -} - -static void __mic_send_intr(struct vop_device *vpdev, int db) -{ - struct mic_driver *mdrv = vpdev_to_mdrv(vpdev); - - mic_send_intr(&mdrv->mdev, db); -} - -static void __iomem *__mic_ioremap(struct vop_device *vpdev, - dma_addr_t pa, size_t len) -{ - struct mic_driver *mdrv = vpdev_to_mdrv(vpdev); - - return mic_card_map(&mdrv->mdev, pa, len); -} - -static void __mic_iounmap(struct vop_device *vpdev, void __iomem *va) -{ - struct mic_driver *mdrv = vpdev_to_mdrv(vpdev); - - mic_card_unmap(&mdrv->mdev, va); -} - -static struct vop_hw_ops vop_hw_ops = { - .request_irq = __mic_request_irq, - .free_irq = __mic_free_irq, - .ack_interrupt = __mic_ack_interrupt, - .next_db = __mic_next_db, - .get_remote_dp = __mic_get_remote_dp, - .send_intr = __mic_send_intr, - .remap = __mic_ioremap, - .unmap = __mic_iounmap, -}; - -static int mic_request_dma_chans(struct mic_driver *mdrv) -{ - dma_cap_mask_t mask; - struct dma_chan *chan; - - dma_cap_zero(mask); - dma_cap_set(DMA_MEMCPY, mask); - - do { - chan = dma_request_channel(mask, NULL, NULL); - if (chan) { - mdrv->dma_ch[mdrv->num_dma_ch++] = chan; - if (mdrv->num_dma_ch >= MIC_MAX_DMA_CHAN) - break; - } - } while (chan); - dev_info(mdrv->dev, "DMA channels # %d\n", mdrv->num_dma_ch); - return mdrv->num_dma_ch; -} - -static void mic_free_dma_chans(struct mic_driver *mdrv) -{ - int i = 0; - - for (i = 0; i < mdrv->num_dma_ch; i++) { - dma_release_channel(mdrv->dma_ch[i]); - mdrv->dma_ch[i] = NULL; - } - mdrv->num_dma_ch = 0; -} - -/* - * mic_driver_init - MIC driver initialization tasks. - * - * Returns 0 in success. Appropriate error code on failure. - */ -int __init mic_driver_init(struct mic_driver *mdrv) -{ - int rc; - struct mic_bootparam __iomem *bootparam; - u8 node_id; - - g_drv = mdrv; - /* Unloading the card module is not supported. */ - if (!try_module_get(mdrv->dev->driver->owner)) { - rc = -ENODEV; - goto done; - } - rc = mic_dp_init(); - if (rc) - goto put; - rc = mic_init_irq(); - if (rc) - goto dp_uninit; - if (!mic_request_dma_chans(mdrv)) { - rc = -ENODEV; - goto irq_uninit; - } - mdrv->vpdev = vop_register_device(mdrv->dev, VOP_DEV_TRNSP, - NULL, &vop_hw_ops, 0, - NULL, mdrv->dma_ch[0]); - if (IS_ERR(mdrv->vpdev)) { - rc = PTR_ERR(mdrv->vpdev); - goto dma_free; - } - bootparam = mdrv->dp; - node_id = ioread8(&bootparam->node_id); - mdrv->scdev = scif_register_device(mdrv->dev, MIC_SCIF_DEV, - NULL, &scif_hw_ops, - 0, node_id, &mdrv->mdev.mmio, NULL, - NULL, mdrv->dp, mdrv->dma_ch, - mdrv->num_dma_ch, true); - if (IS_ERR(mdrv->scdev)) { - rc = PTR_ERR(mdrv->scdev); - goto vop_remove; - } - mic_create_card_debug_dir(mdrv); -done: - return rc; -vop_remove: - vop_unregister_device(mdrv->vpdev); -dma_free: - mic_free_dma_chans(mdrv); -irq_uninit: - mic_uninit_irq(); -dp_uninit: - mic_dp_uninit(); -put: - module_put(mdrv->dev->driver->owner); - return rc; -} - -/* - * mic_driver_uninit - MIC driver uninitialization tasks. - * - * Returns None - */ -void mic_driver_uninit(struct mic_driver *mdrv) -{ - mic_delete_card_debug_dir(mdrv); - scif_unregister_device(mdrv->scdev); - vop_unregister_device(mdrv->vpdev); - mic_free_dma_chans(mdrv); - mic_uninit_irq(); - mic_dp_uninit(); - module_put(mdrv->dev->driver->owner); -} diff --git a/drivers/misc/mic/card/mic_device.h b/drivers/misc/mic/card/mic_device.h deleted file mode 100644 index d6cc69a235a3..000000000000 --- a/drivers/misc/mic/card/mic_device.h +++ /dev/null @@ -1,137 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Disclaimer: The codes contained in these modules may be specific to - * the Intel Software Development Platform codenamed: Knights Ferry, and - * the Intel product codenamed: Knights Corner, and are not backward - * compatible with other Intel products. Additionally, Intel will NOT - * support the codes or instruction set in future products. - * - * Intel MIC Card driver. - */ -#ifndef _MIC_CARD_DEVICE_H_ -#define _MIC_CARD_DEVICE_H_ - -#include <linux/workqueue.h> -#include <linux/io.h> -#include <linux/interrupt.h> -#include <linux/mic_bus.h> -#include "../bus/scif_bus.h" -#include "../bus/vop_bus.h" - -/** - * struct mic_intr_info - Contains h/w specific interrupt sources info - * - * @num_intr: The number of irqs available - */ -struct mic_intr_info { - u32 num_intr; -}; - -/** - * struct mic_irq_info - OS specific irq information - * - * @irq_usage_count: usage count array tracking the number of sources - * assigned for each irq. - */ -struct mic_irq_info { - int *irq_usage_count; -}; - -/** - * struct mic_device - MIC device information. - * - * @mmio: MMIO bar information. - */ -struct mic_device { - struct mic_mw mmio; -}; - -/** - * struct mic_driver - MIC card driver information. - * - * @name: Name for MIC driver. - * @dbg_dir: debugfs directory of this MIC device. - * @dev: The device backing this MIC. - * @dp: The pointer to the virtio device page. - * @mdev: MIC device information for the host. - * @hotplug_work: Hot plug work for adding/removing virtio devices. - * @irq_info: The OS specific irq information - * @intr_info: H/W specific interrupt information. - * @dma_mbdev: dma device on the MIC virtual bus. - * @dma_ch - Array of DMA channels - * @num_dma_ch - Number of DMA channels available - * @scdev: SCIF device on the SCIF virtual bus. - * @vpdev: Virtio over PCIe device on the VOP virtual bus. - */ -struct mic_driver { - char name[20]; - struct dentry *dbg_dir; - struct device *dev; - void __iomem *dp; - struct mic_device mdev; - struct work_struct hotplug_work; - struct mic_irq_info irq_info; - struct mic_intr_info intr_info; - struct mbus_device *dma_mbdev; - struct dma_chan *dma_ch[MIC_MAX_DMA_CHAN]; - int num_dma_ch; - struct scif_hw_dev *scdev; - struct vop_device *vpdev; -}; - -/** - * struct mic_irq - opaque pointer used as cookie - */ -struct mic_irq; - -/** - * mic_mmio_read - read from an MMIO register. - * @mw: MMIO register base virtual address. - * @offset: register offset. - * - * RETURNS: register value. - */ -static inline u32 mic_mmio_read(struct mic_mw *mw, u32 offset) -{ - return ioread32(mw->va + offset); -} - -/** - * mic_mmio_write - write to an MMIO register. - * @mw: MMIO register base virtual address. - * @val: the data value to put into the register - * @offset: register offset. - * - * RETURNS: none. - */ -static inline void -mic_mmio_write(struct mic_mw *mw, u32 val, u32 offset) -{ - iowrite32(val, mw->va + offset); -} - -int mic_driver_init(struct mic_driver *mdrv); -void mic_driver_uninit(struct mic_driver *mdrv); -int mic_next_card_db(void); -struct mic_irq * -mic_request_card_irq(irq_handler_t handler, irq_handler_t thread_fn, - const char *name, void *data, int db); -void mic_free_card_irq(struct mic_irq *cookie, void *data); -u32 mic_read_spad(struct mic_device *mdev, unsigned int idx); -void mic_send_intr(struct mic_device *mdev, int doorbell); -void mic_send_p2p_intr(int doorbell, struct mic_mw *mw); -int mic_db_to_irq(struct mic_driver *mdrv, int db); -u32 mic_ack_interrupt(struct mic_device *mdev); -void mic_hw_intr_init(struct mic_driver *mdrv); -void __iomem * -mic_card_map(struct mic_device *mdev, dma_addr_t addr, size_t size); -void mic_card_unmap(struct mic_device *mdev, void __iomem *addr); -void __init mic_create_card_debug_dir(struct mic_driver *mdrv); -void mic_delete_card_debug_dir(struct mic_driver *mdrv); -void __init mic_init_card_debugfs(void); -void mic_exit_card_debugfs(void); -#endif diff --git a/drivers/misc/mic/card/mic_x100.c b/drivers/misc/mic/card/mic_x100.c deleted file mode 100644 index c8bff2916d3d..000000000000 --- a/drivers/misc/mic/card/mic_x100.c +++ /dev/null @@ -1,347 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Disclaimer: The codes contained in these modules may be specific to - * the Intel Software Development Platform codenamed: Knights Ferry, and - * the Intel product codenamed: Knights Corner, and are not backward - * compatible with other Intel products. Additionally, Intel will NOT - * support the codes or instruction set in future products. - * - * Intel MIC Card driver. - */ -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/platform_device.h> - -#include "../common/mic_dev.h" -#include "mic_device.h" -#include "mic_x100.h" - -static const char mic_driver_name[] = "mic"; - -static struct mic_driver g_drv; - -/** - * mic_read_spad - read from the scratchpad register - * @mdev: pointer to mic_device instance - * @idx: index to scratchpad register, 0 based - * - * This function allows reading of the 32bit scratchpad register. - * - * RETURNS: An appropriate -ERRNO error value on error, or zero for success. - */ -u32 mic_read_spad(struct mic_device *mdev, unsigned int idx) -{ - return mic_mmio_read(&mdev->mmio, - MIC_X100_SBOX_BASE_ADDRESS + - MIC_X100_SBOX_SPAD0 + idx * 4); -} - -/** - * __mic_send_intr - Send interrupt to Host. - * @mdev: pointer to mic_device instance - * @doorbell: Doorbell number. - */ -void mic_send_intr(struct mic_device *mdev, int doorbell) -{ - struct mic_mw *mw = &mdev->mmio; - - if (doorbell > MIC_X100_MAX_DOORBELL_IDX) - return; - /* Ensure that the interrupt is ordered w.r.t previous stores. */ - wmb(); - mic_mmio_write(mw, MIC_X100_SBOX_SDBIC0_DBREQ_BIT, - MIC_X100_SBOX_BASE_ADDRESS + - (MIC_X100_SBOX_SDBIC0 + (4 * doorbell))); -} - -/* - * mic_x100_send_sbox_intr - Send an MIC_X100_SBOX interrupt to MIC. - */ -static void mic_x100_send_sbox_intr(struct mic_mw *mw, int doorbell) -{ - u64 apic_icr_offset = MIC_X100_SBOX_APICICR0 + doorbell * 8; - u32 apicicr_low = mic_mmio_read(mw, MIC_X100_SBOX_BASE_ADDRESS + - apic_icr_offset); - - /* for MIC we need to make sure we "hit" the send_icr bit (13) */ - apicicr_low = (apicicr_low | (1 << 13)); - /* - * Ensure that the interrupt is ordered w.r.t. previous stores - * to main memory. Fence instructions are not implemented in X100 - * since execution is in order but a compiler barrier is still - * required. - */ - wmb(); - mic_mmio_write(mw, apicicr_low, - MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset); -} - -static void mic_x100_send_rdmasr_intr(struct mic_mw *mw, int doorbell) -{ - int rdmasr_offset = MIC_X100_SBOX_RDMASR0 + (doorbell << 2); - /* - * Ensure that the interrupt is ordered w.r.t. previous stores - * to main memory. Fence instructions are not implemented in X100 - * since execution is in order but a compiler barrier is still - * required. - */ - wmb(); - mic_mmio_write(mw, 0, MIC_X100_SBOX_BASE_ADDRESS + rdmasr_offset); -} - -/** - * mic_ack_interrupt - Device specific interrupt handling. - * @mdev: pointer to mic_device instance - * - * Returns: bitmask of doorbell events triggered. - */ -u32 mic_ack_interrupt(struct mic_device *mdev) -{ - return 0; -} - -static inline int mic_get_sbox_irq(int db) -{ - return MIC_X100_IRQ_BASE + db; -} - -static inline int mic_get_rdmasr_irq(int index) -{ - return MIC_X100_RDMASR_IRQ_BASE + index; -} - -void mic_send_p2p_intr(int db, struct mic_mw *mw) -{ - int rdmasr_index; - - if (db < MIC_X100_NUM_SBOX_IRQ) { - mic_x100_send_sbox_intr(mw, db); - } else { - rdmasr_index = db - MIC_X100_NUM_SBOX_IRQ; - mic_x100_send_rdmasr_intr(mw, rdmasr_index); - } -} - -/** - * mic_hw_intr_init - Initialize h/w specific interrupt - * information. - * @mdrv: pointer to mic_driver - */ -void mic_hw_intr_init(struct mic_driver *mdrv) -{ - mdrv->intr_info.num_intr = MIC_X100_NUM_SBOX_IRQ + - MIC_X100_NUM_RDMASR_IRQ; -} - -/** - * mic_db_to_irq - Retrieve irq number corresponding to a doorbell. - * @mdrv: pointer to mic_driver - * @db: The doorbell obtained for which the irq is needed. Doorbell - * may correspond to an sbox doorbell or an rdmasr index. - * - * Returns the irq corresponding to the doorbell. - */ -int mic_db_to_irq(struct mic_driver *mdrv, int db) -{ - int rdmasr_index; - - /* - * The total number of doorbell interrupts on the card are 16. Indices - * 0-8 falls in the SBOX category and 8-15 fall in the RDMASR category. - */ - if (db < MIC_X100_NUM_SBOX_IRQ) { - return mic_get_sbox_irq(db); - } else { - rdmasr_index = db - MIC_X100_NUM_SBOX_IRQ; - return mic_get_rdmasr_irq(rdmasr_index); - } -} - -/* - * mic_card_map - Allocate virtual address for a remote memory region. - * @mdev: pointer to mic_device instance. - * @addr: Remote DMA address. - * @size: Size of the region. - * - * Returns: Virtual address backing the remote memory region. - */ -void __iomem * -mic_card_map(struct mic_device *mdev, dma_addr_t addr, size_t size) -{ - return ioremap(addr, size); -} - -/* - * mic_card_unmap - Unmap the virtual address for a remote memory region. - * @mdev: pointer to mic_device instance. - * @addr: Virtual address for remote memory region. - * - * Returns: None. - */ -void mic_card_unmap(struct mic_device *mdev, void __iomem *addr) -{ - iounmap(addr); -} - -static inline struct mic_driver *mbdev_to_mdrv(struct mbus_device *mbdev) -{ - return dev_get_drvdata(mbdev->dev.parent); -} - -static struct mic_irq * -_mic_request_threaded_irq(struct mbus_device *mbdev, - irq_handler_t handler, irq_handler_t thread_fn, - const char *name, void *data, int intr_src) -{ - int rc = 0; - unsigned int irq = intr_src; - unsigned long cookie = irq; - - rc = request_threaded_irq(irq, handler, thread_fn, 0, name, data); - if (rc) { - dev_err(mbdev_to_mdrv(mbdev)->dev, - "request_threaded_irq failed rc = %d\n", rc); - return ERR_PTR(rc); - } - return (struct mic_irq *)cookie; -} - -static void _mic_free_irq(struct mbus_device *mbdev, - struct mic_irq *cookie, void *data) -{ - unsigned long irq = (unsigned long)cookie; - free_irq(irq, data); -} - -static void _mic_ack_interrupt(struct mbus_device *mbdev, int num) -{ - mic_ack_interrupt(&mbdev_to_mdrv(mbdev)->mdev); -} - -static struct mbus_hw_ops mbus_hw_ops = { - .request_threaded_irq = _mic_request_threaded_irq, - .free_irq = _mic_free_irq, - .ack_interrupt = _mic_ack_interrupt, -}; - -static int __init mic_probe(struct platform_device *pdev) -{ - struct mic_driver *mdrv = &g_drv; - struct mic_device *mdev = &mdrv->mdev; - int rc = 0; - - mdrv->dev = &pdev->dev; - snprintf(mdrv->name, sizeof(mic_driver_name), mic_driver_name); - - /* FIXME: use dma_set_mask_and_coherent() and check result */ - dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); - - mdev->mmio.pa = MIC_X100_MMIO_BASE; - mdev->mmio.len = MIC_X100_MMIO_LEN; - mdev->mmio.va = devm_ioremap(&pdev->dev, MIC_X100_MMIO_BASE, - MIC_X100_MMIO_LEN); - if (!mdev->mmio.va) { - dev_err(&pdev->dev, "Cannot remap MMIO BAR\n"); - rc = -EIO; - goto done; - } - mic_hw_intr_init(mdrv); - platform_set_drvdata(pdev, mdrv); - mdrv->dma_mbdev = mbus_register_device(mdrv->dev, MBUS_DEV_DMA_MIC, - NULL, &mbus_hw_ops, 0, - mdrv->mdev.mmio.va); - if (IS_ERR(mdrv->dma_mbdev)) { - rc = PTR_ERR(mdrv->dma_mbdev); - dev_err(&pdev->dev, "mbus_add_device failed rc %d\n", rc); - goto done; - } - rc = mic_driver_init(mdrv); - if (rc) { - dev_err(&pdev->dev, "mic_driver_init failed rc %d\n", rc); - goto remove_dma; - } -done: - return rc; -remove_dma: - mbus_unregister_device(mdrv->dma_mbdev); - return rc; -} - -static int mic_remove(struct platform_device *pdev) -{ - struct mic_driver *mdrv = &g_drv; - - mic_driver_uninit(mdrv); - mbus_unregister_device(mdrv->dma_mbdev); - return 0; -} - -static void mic_platform_shutdown(struct platform_device *pdev) -{ - mic_remove(pdev); -} - -static struct platform_driver __refdata mic_platform_driver = { - .probe = mic_probe, - .remove = mic_remove, - .shutdown = mic_platform_shutdown, - .driver = { - .name = mic_driver_name, - }, -}; - -static struct platform_device *mic_platform_dev; - -static int __init mic_init(void) -{ - int ret; - struct cpuinfo_x86 *c = &cpu_data(0); - - if (!(c->x86 == 11 && c->x86_model == 1)) { - ret = -ENODEV; - pr_err("%s not running on X100 ret %d\n", __func__, ret); - goto done; - } - - request_module("mic_x100_dma"); - mic_init_card_debugfs(); - - mic_platform_dev = platform_device_register_simple(mic_driver_name, - 0, NULL, 0); - ret = PTR_ERR_OR_ZERO(mic_platform_dev); - if (ret) { - pr_err("platform_device_register_full ret %d\n", ret); - goto cleanup_debugfs; - } - ret = platform_driver_register(&mic_platform_driver); - if (ret) { - pr_err("platform_driver_register ret %d\n", ret); - goto device_unregister; - } - return ret; - -device_unregister: - platform_device_unregister(mic_platform_dev); -cleanup_debugfs: - mic_exit_card_debugfs(); -done: - return ret; -} - -static void __exit mic_exit(void) -{ - platform_driver_unregister(&mic_platform_driver); - platform_device_unregister(mic_platform_dev); - mic_exit_card_debugfs(); -} - -module_init(mic_init); -module_exit(mic_exit); - -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) MIC X100 Card driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mic/card/mic_x100.h b/drivers/misc/mic/card/mic_x100.h deleted file mode 100644 index 46644dde0c07..000000000000 --- a/drivers/misc/mic/card/mic_x100.h +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Disclaimer: The codes contained in these modules may be specific to - * the Intel Software Development Platform codenamed: Knights Ferry, and - * the Intel product codenamed: Knights Corner, and are not backward - * compatible with other Intel products. Additionally, Intel will NOT - * support the codes or instruction set in future products. - * - * Intel MIC Card driver. - */ -#ifndef _MIC_X100_CARD_H_ -#define _MIC_X100_CARD_H_ - -#define MIC_X100_MMIO_BASE 0x08007C0000ULL -#define MIC_X100_MMIO_LEN 0x00020000ULL -#define MIC_X100_SBOX_BASE_ADDRESS 0x00010000ULL - -#define MIC_X100_SBOX_SPAD0 0x0000AB20 -#define MIC_X100_SBOX_SDBIC0 0x0000CC90 -#define MIC_X100_SBOX_SDBIC0_DBREQ_BIT 0x80000000 -#define MIC_X100_SBOX_RDMASR0 0x0000B180 -#define MIC_X100_SBOX_APICICR0 0x0000A9D0 - -#define MIC_X100_MAX_DOORBELL_IDX 8 - -#define MIC_X100_NUM_SBOX_IRQ 8 -#define MIC_X100_NUM_RDMASR_IRQ 8 -#define MIC_X100_SBOX_IRQ_BASE 0 -#define MIC_X100_RDMASR_IRQ_BASE 17 - -#define MIC_X100_IRQ_BASE 26 - -#endif diff --git a/drivers/misc/mic/common/mic_dev.h b/drivers/misc/mic/common/mic_dev.h deleted file mode 100644 index f94f08df0260..000000000000 --- a/drivers/misc/mic/common/mic_dev.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Intel MIC driver. - */ -#ifndef __MIC_DEV_H__ -#define __MIC_DEV_H__ - -/* The maximum number of MIC devices supported in a single host system. */ -#define MIC_MAX_NUM_DEVS 128 - -/** - * enum mic_hw_family - The hardware family to which a device belongs. - */ -enum mic_hw_family { - MIC_FAMILY_X100 = 0, - MIC_FAMILY_X200, - MIC_FAMILY_UNKNOWN, - MIC_FAMILY_LAST -}; - -/** - * struct mic_mw - MIC memory window - * - * @pa: Base physical address. - * @va: Base ioremap'd virtual address. - * @len: Size of the memory window. - */ -struct mic_mw { - phys_addr_t pa; - void __iomem *va; - resource_size_t len; -}; - -/* - * Scratch pad register offsets used by the host to communicate - * device page DMA address to the card. - */ -#define MIC_DPLO_SPAD 14 -#define MIC_DPHI_SPAD 15 - -/* - * These values are supposed to be in the config_change field of the - * device page when the host sends a config change interrupt to the card. - */ -#define MIC_VIRTIO_PARAM_DEV_REMOVE 0x1 -#define MIC_VIRTIO_PARAM_CONFIG_CHANGED 0x2 - -/* Maximum number of DMA channels */ -#define MIC_MAX_DMA_CHAN 4 - -#endif diff --git a/drivers/misc/mic/cosm/Makefile b/drivers/misc/mic/cosm/Makefile deleted file mode 100644 index 97d74cb12030..000000000000 --- a/drivers/misc/mic/cosm/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile - Intel MIC Coprocessor State Management (COSM) Driver -# Copyright(c) 2015, Intel Corporation. -# -obj-$(CONFIG_MIC_COSM) += mic_cosm.o - -mic_cosm-objs := cosm_main.o -mic_cosm-objs += cosm_debugfs.o -mic_cosm-objs += cosm_sysfs.o -mic_cosm-objs += cosm_scif_server.o diff --git a/drivers/misc/mic/cosm/cosm_debugfs.c b/drivers/misc/mic/cosm/cosm_debugfs.c deleted file mode 100644 index cb55653cf1f9..000000000000 --- a/drivers/misc/mic/cosm/cosm_debugfs.c +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel MIC Coprocessor State Management (COSM) Driver - */ - -#include <linux/debugfs.h> -#include <linux/slab.h> -#include <linux/io.h> -#include "cosm_main.h" - -/* Debugfs parent dir */ -static struct dentry *cosm_dbg; - -/* - * log_buf_show - Display MIC kernel log buffer - * - * log_buf addr/len is read from System.map by user space - * and populated in sysfs entries. - */ -static int log_buf_show(struct seq_file *s, void *unused) -{ - void __iomem *log_buf_va; - int __iomem *log_buf_len_va; - struct cosm_device *cdev = s->private; - void *kva; - int size; - u64 aper_offset; - - if (!cdev || !cdev->log_buf_addr || !cdev->log_buf_len) - goto done; - - mutex_lock(&cdev->cosm_mutex); - switch (cdev->state) { - case MIC_BOOTING: - case MIC_ONLINE: - case MIC_SHUTTING_DOWN: - break; - default: - goto unlock; - } - - /* - * Card kernel will never be relocated and any kernel text/data mapping - * can be translated to phys address by subtracting __START_KERNEL_map. - */ - aper_offset = (u64)cdev->log_buf_len - __START_KERNEL_map; - log_buf_len_va = cdev->hw_ops->aper(cdev)->va + aper_offset; - aper_offset = (u64)cdev->log_buf_addr - __START_KERNEL_map; - log_buf_va = cdev->hw_ops->aper(cdev)->va + aper_offset; - - size = ioread32(log_buf_len_va); - kva = kmalloc(size, GFP_KERNEL); - if (!kva) - goto unlock; - - memcpy_fromio(kva, log_buf_va, size); - seq_write(s, kva, size); - kfree(kva); -unlock: - mutex_unlock(&cdev->cosm_mutex); -done: - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(log_buf); - -/* - * force_reset_show - Force MIC reset - * - * Invokes the force_reset COSM bus op instead of the standard reset - * op in case a force reset of the MIC device is required - */ -static int force_reset_show(struct seq_file *s, void *pos) -{ - struct cosm_device *cdev = s->private; - - cosm_stop(cdev, true); - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(force_reset); - -void cosm_create_debug_dir(struct cosm_device *cdev) -{ - char name[16]; - - if (!cosm_dbg) - return; - - scnprintf(name, sizeof(name), "mic%d", cdev->index); - cdev->dbg_dir = debugfs_create_dir(name, cosm_dbg); - - debugfs_create_file("log_buf", 0444, cdev->dbg_dir, cdev, - &log_buf_fops); - debugfs_create_file("force_reset", 0444, cdev->dbg_dir, cdev, - &force_reset_fops); -} - -void cosm_delete_debug_dir(struct cosm_device *cdev) -{ - debugfs_remove_recursive(cdev->dbg_dir); -} - -void cosm_init_debugfs(void) -{ - cosm_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); -} - -void cosm_exit_debugfs(void) -{ - debugfs_remove(cosm_dbg); -} diff --git a/drivers/misc/mic/cosm/cosm_main.c b/drivers/misc/mic/cosm/cosm_main.c deleted file mode 100644 index ebb0eac43754..000000000000 --- a/drivers/misc/mic/cosm/cosm_main.c +++ /dev/null @@ -1,382 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel MIC Coprocessor State Management (COSM) Driver - */ - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/idr.h> -#include <linux/slab.h> -#include <linux/cred.h> -#include "cosm_main.h" - -static const char cosm_driver_name[] = "mic"; - -/* COSM ID allocator */ -static struct ida g_cosm_ida; -/* Class of MIC devices for sysfs accessibility. */ -static struct class *g_cosm_class; -/* Number of MIC devices */ -static atomic_t g_num_dev; - -/** - * cosm_hw_reset - Issue a HW reset for the MIC device - * @cdev: pointer to cosm_device instance - * @force: force a MIC to reset even if it is already reset and ready - */ -static void cosm_hw_reset(struct cosm_device *cdev, bool force) -{ - int i; - -#define MIC_RESET_TO (45) - if (force && cdev->hw_ops->force_reset) - cdev->hw_ops->force_reset(cdev); - else - cdev->hw_ops->reset(cdev); - - for (i = 0; i < MIC_RESET_TO; i++) { - if (cdev->hw_ops->ready(cdev)) { - cosm_set_state(cdev, MIC_READY); - return; - } - /* - * Resets typically take 10s of seconds to complete. - * Since an MMIO read is required to check if the - * firmware is ready or not, a 1 second delay works nicely. - */ - msleep(1000); - } - cosm_set_state(cdev, MIC_RESET_FAILED); -} - -/** - * cosm_start - Start the MIC - * @cdev: pointer to cosm_device instance - * - * This function prepares an MIC for boot and initiates boot. - * RETURNS: An appropriate -ERRNO error value on error, or 0 for success. - */ -int cosm_start(struct cosm_device *cdev) -{ - const struct cred *orig_cred; - struct cred *override_cred; - int rc; - - mutex_lock(&cdev->cosm_mutex); - if (!cdev->bootmode) { - dev_err(&cdev->dev, "%s %d bootmode not set\n", - __func__, __LINE__); - rc = -EINVAL; - goto unlock_ret; - } -retry: - if (cdev->state != MIC_READY) { - dev_err(&cdev->dev, "%s %d MIC state not READY\n", - __func__, __LINE__); - rc = -EINVAL; - goto unlock_ret; - } - if (!cdev->hw_ops->ready(cdev)) { - cosm_hw_reset(cdev, false); - /* - * The state will either be MIC_READY if the reset succeeded - * or MIC_RESET_FAILED if the firmware reset failed. - */ - goto retry; - } - - /* - * Set credentials to root to allow non-root user to download initramsfs - * with 600 permissions - */ - override_cred = prepare_creds(); - if (!override_cred) { - dev_err(&cdev->dev, "%s %d prepare_creds failed\n", - __func__, __LINE__); - rc = -ENOMEM; - goto unlock_ret; - } - override_cred->fsuid = GLOBAL_ROOT_UID; - orig_cred = override_creds(override_cred); - - rc = cdev->hw_ops->start(cdev, cdev->index); - - revert_creds(orig_cred); - put_cred(override_cred); - if (rc) - goto unlock_ret; - - /* - * If linux is being booted, card is treated 'online' only - * when the scif interface in the card is up. If anything else - * is booted, we set card to 'online' immediately. - */ - if (!strcmp(cdev->bootmode, "linux")) - cosm_set_state(cdev, MIC_BOOTING); - else - cosm_set_state(cdev, MIC_ONLINE); -unlock_ret: - mutex_unlock(&cdev->cosm_mutex); - if (rc) - dev_err(&cdev->dev, "cosm_start failed rc %d\n", rc); - return rc; -} - -/** - * cosm_stop - Prepare the MIC for reset and trigger reset - * @cdev: pointer to cosm_device instance - * @force: force a MIC to reset even if it is already reset and ready. - * - * RETURNS: None - */ -void cosm_stop(struct cosm_device *cdev, bool force) -{ - mutex_lock(&cdev->cosm_mutex); - if (cdev->state != MIC_READY || force) { - /* - * Don't call hw_ops if they have been called previously. - * stop(..) calls device_unregister and will crash the system if - * called multiple times. - */ - u8 state = cdev->state == MIC_RESETTING ? - cdev->prev_state : cdev->state; - bool call_hw_ops = state != MIC_RESET_FAILED && - state != MIC_READY; - - if (cdev->state != MIC_RESETTING) - cosm_set_state(cdev, MIC_RESETTING); - cdev->heartbeat_watchdog_enable = false; - if (call_hw_ops) - cdev->hw_ops->stop(cdev, force); - cosm_hw_reset(cdev, force); - cosm_set_shutdown_status(cdev, MIC_NOP); - if (call_hw_ops && cdev->hw_ops->post_reset) - cdev->hw_ops->post_reset(cdev, cdev->state); - } - mutex_unlock(&cdev->cosm_mutex); - flush_work(&cdev->scif_work); -} - -/** - * cosm_reset_trigger_work - Trigger MIC reset - * @work: The work structure - * - * This work is scheduled whenever the host wants to reset the MIC. - */ -static void cosm_reset_trigger_work(struct work_struct *work) -{ - struct cosm_device *cdev = container_of(work, struct cosm_device, - reset_trigger_work); - cosm_stop(cdev, false); -} - -/** - * cosm_reset - Schedule MIC reset - * @cdev: pointer to cosm_device instance - * - * RETURNS: An -EINVAL if the card is already READY or 0 for success. - */ -int cosm_reset(struct cosm_device *cdev) -{ - int rc = 0; - - mutex_lock(&cdev->cosm_mutex); - if (cdev->state != MIC_READY) { - if (cdev->state != MIC_RESETTING) { - cdev->prev_state = cdev->state; - cosm_set_state(cdev, MIC_RESETTING); - schedule_work(&cdev->reset_trigger_work); - } - } else { - dev_err(&cdev->dev, "%s %d MIC is READY\n", __func__, __LINE__); - rc = -EINVAL; - } - mutex_unlock(&cdev->cosm_mutex); - return rc; -} - -/** - * cosm_shutdown - Initiate MIC shutdown. - * @cdev: pointer to cosm_device instance - * - * RETURNS: None - */ -int cosm_shutdown(struct cosm_device *cdev) -{ - struct cosm_msg msg = { .id = COSM_MSG_SHUTDOWN }; - int rc = 0; - - mutex_lock(&cdev->cosm_mutex); - if (cdev->state != MIC_ONLINE) { - rc = -EINVAL; - dev_err(&cdev->dev, "%s %d skipping shutdown in state: %s\n", - __func__, __LINE__, cosm_state_string[cdev->state]); - goto err; - } - - if (!cdev->epd) { - rc = -ENOTCONN; - dev_err(&cdev->dev, "%s %d scif endpoint not connected rc %d\n", - __func__, __LINE__, rc); - goto err; - } - - rc = scif_send(cdev->epd, &msg, sizeof(msg), SCIF_SEND_BLOCK); - if (rc < 0) { - dev_err(&cdev->dev, "%s %d scif_send failed rc %d\n", - __func__, __LINE__, rc); - goto err; - } - cdev->heartbeat_watchdog_enable = false; - cosm_set_state(cdev, MIC_SHUTTING_DOWN); - rc = 0; -err: - mutex_unlock(&cdev->cosm_mutex); - return rc; -} - -static int cosm_driver_probe(struct cosm_device *cdev) -{ - int rc; - - /* Initialize SCIF server at first probe */ - if (atomic_add_return(1, &g_num_dev) == 1) { - rc = cosm_scif_init(); - if (rc) - goto scif_exit; - } - mutex_init(&cdev->cosm_mutex); - INIT_WORK(&cdev->reset_trigger_work, cosm_reset_trigger_work); - INIT_WORK(&cdev->scif_work, cosm_scif_work); - cdev->sysfs_heartbeat_enable = true; - cosm_sysfs_init(cdev); - cdev->sdev = device_create_with_groups(g_cosm_class, cdev->dev.parent, - MKDEV(0, cdev->index), cdev, cdev->attr_group, - "mic%d", cdev->index); - if (IS_ERR(cdev->sdev)) { - rc = PTR_ERR(cdev->sdev); - dev_err(&cdev->dev, "device_create_with_groups failed rc %d\n", - rc); - goto scif_exit; - } - - cdev->state_sysfs = sysfs_get_dirent(cdev->sdev->kobj.sd, - "state"); - if (!cdev->state_sysfs) { - rc = -ENODEV; - dev_err(&cdev->dev, "sysfs_get_dirent failed rc %d\n", rc); - goto destroy_device; - } - cosm_create_debug_dir(cdev); - return 0; -destroy_device: - device_destroy(g_cosm_class, MKDEV(0, cdev->index)); -scif_exit: - if (atomic_dec_and_test(&g_num_dev)) - cosm_scif_exit(); - return rc; -} - -static void cosm_driver_remove(struct cosm_device *cdev) -{ - cosm_delete_debug_dir(cdev); - sysfs_put(cdev->state_sysfs); - device_destroy(g_cosm_class, MKDEV(0, cdev->index)); - flush_work(&cdev->reset_trigger_work); - cosm_stop(cdev, false); - if (atomic_dec_and_test(&g_num_dev)) - cosm_scif_exit(); - - /* These sysfs entries might have allocated */ - kfree(cdev->cmdline); - kfree(cdev->firmware); - kfree(cdev->ramdisk); - kfree(cdev->bootmode); -} - -static int cosm_suspend(struct device *dev) -{ - struct cosm_device *cdev = dev_to_cosm(dev); - - mutex_lock(&cdev->cosm_mutex); - switch (cdev->state) { - /** - * Suspend/freeze hooks in userspace have already shutdown the card. - * Card should be 'ready' in most cases. It is however possible that - * some userspace application initiated a boot. In those cases, we - * simply reset the card. - */ - case MIC_ONLINE: - case MIC_BOOTING: - case MIC_SHUTTING_DOWN: - mutex_unlock(&cdev->cosm_mutex); - cosm_stop(cdev, false); - break; - default: - mutex_unlock(&cdev->cosm_mutex); - break; - } - return 0; -} - -static const struct dev_pm_ops cosm_pm_ops = { - .suspend = cosm_suspend, - .freeze = cosm_suspend -}; - -static struct cosm_driver cosm_driver = { - .driver = { - .name = KBUILD_MODNAME, - .owner = THIS_MODULE, - .pm = &cosm_pm_ops, - }, - .probe = cosm_driver_probe, - .remove = cosm_driver_remove -}; - -static int __init cosm_init(void) -{ - int ret; - - cosm_init_debugfs(); - - g_cosm_class = class_create(THIS_MODULE, cosm_driver_name); - if (IS_ERR(g_cosm_class)) { - ret = PTR_ERR(g_cosm_class); - pr_err("class_create failed ret %d\n", ret); - goto cleanup_debugfs; - } - - ida_init(&g_cosm_ida); - ret = cosm_register_driver(&cosm_driver); - if (ret) { - pr_err("cosm_register_driver failed ret %d\n", ret); - goto ida_destroy; - } - return 0; -ida_destroy: - ida_destroy(&g_cosm_ida); - class_destroy(g_cosm_class); -cleanup_debugfs: - cosm_exit_debugfs(); - return ret; -} - -static void __exit cosm_exit(void) -{ - cosm_unregister_driver(&cosm_driver); - ida_destroy(&g_cosm_ida); - class_destroy(g_cosm_class); - cosm_exit_debugfs(); -} - -module_init(cosm_init); -module_exit(cosm_exit); - -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) MIC Coprocessor State Management (COSM) Driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mic/cosm/cosm_main.h b/drivers/misc/mic/cosm/cosm_main.h deleted file mode 100644 index 5188ad245814..000000000000 --- a/drivers/misc/mic/cosm/cosm_main.h +++ /dev/null @@ -1,61 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel MIC Coprocessor State Management (COSM) Driver - */ -#ifndef _COSM_COSM_H_ -#define _COSM_COSM_H_ - -#include <linux/scif.h> -#include "../bus/cosm_bus.h" - -#define COSM_HEARTBEAT_SEND_SEC 30 -#define SCIF_COSM_LISTEN_PORT 201 - -/** - * enum COSM msg id's - * @COSM_MSG_SHUTDOWN: host->card trigger shutdown - * @COSM_MSG_SYNC_TIME: host->card send host time to card to sync time - * @COSM_MSG_HEARTBEAT: card->host heartbeat - * @COSM_MSG_SHUTDOWN_STATUS: card->host with shutdown status as payload - */ -enum cosm_msg_id { - COSM_MSG_SHUTDOWN, - COSM_MSG_SYNC_TIME, - COSM_MSG_HEARTBEAT, - COSM_MSG_SHUTDOWN_STATUS, -}; - -struct cosm_msg { - u64 id; - union { - u64 shutdown_status; - struct { - u64 tv_sec; - u64 tv_nsec; - } timespec; - }; -}; - -extern const char * const cosm_state_string[]; -extern const char * const cosm_shutdown_status_string[]; - -void cosm_sysfs_init(struct cosm_device *cdev); -int cosm_start(struct cosm_device *cdev); -void cosm_stop(struct cosm_device *cdev, bool force); -int cosm_reset(struct cosm_device *cdev); -int cosm_shutdown(struct cosm_device *cdev); -void cosm_set_state(struct cosm_device *cdev, u8 state); -void cosm_set_shutdown_status(struct cosm_device *cdev, u8 status); -void cosm_init_debugfs(void); -void cosm_exit_debugfs(void); -void cosm_create_debug_dir(struct cosm_device *cdev); -void cosm_delete_debug_dir(struct cosm_device *cdev); -int cosm_scif_init(void); -void cosm_scif_exit(void); -void cosm_scif_work(struct work_struct *work); - -#endif diff --git a/drivers/misc/mic/cosm/cosm_scif_server.c b/drivers/misc/mic/cosm/cosm_scif_server.c deleted file mode 100644 index 7baec9fd8756..000000000000 --- a/drivers/misc/mic/cosm/cosm_scif_server.c +++ /dev/null @@ -1,399 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel MIC Coprocessor State Management (COSM) Driver - */ -#include <linux/kthread.h> -#include <linux/sched/signal.h> - -#include "cosm_main.h" - -/* - * The COSM driver uses SCIF to communicate between the management node and the - * MIC cards. SCIF is used to (a) Send a shutdown command to the card (b) - * receive a shutdown status back from the card upon completion of shutdown and - * (c) receive periodic heartbeat messages from the card used to deduce if the - * card has crashed. - * - * A COSM server consisting of a SCIF listening endpoint waits for incoming - * connections from the card. Upon acceptance of the connection, a separate - * work-item is scheduled to handle SCIF message processing for that card. The - * life-time of this work-item is therefore the time from which the connection - * from a card is accepted to the time at which the connection is closed. A new - * work-item starts each time the card boots and is alive till the card (a) - * shuts down (b) is reset (c) crashes (d) cosm_client driver on the card is - * unloaded. - * - * From the point of view of COSM interactions with SCIF during card - * shutdown, reset and crash are as follows: - * - * Card shutdown - * ------------- - * 1. COSM client on the card invokes orderly_poweroff() in response to SHUTDOWN - * message from the host. - * 2. Card driver shutdown callback invokes scif_unregister_device(..) resulting - * in scif_remove(..) getting called on the card - * 3. scif_remove -> scif_stop -> scif_handle_remove_node -> - * scif_peer_unregister_device -> device_unregister for the host peer device - * 4. During device_unregister remove(..) method of cosm_client is invoked which - * closes the COSM SCIF endpoint on the card. This results in a SCIF_DISCNCT - * message being sent to host SCIF. SCIF_DISCNCT message processing on the - * host SCIF sets the host COSM SCIF endpoint state to DISCONNECTED and wakes - * up the host COSM thread blocked in scif_poll(..) resulting in - * scif_poll(..) returning EPOLLHUP. - * 5. On the card, scif_peer_release_dev is next called which results in an - * SCIF_EXIT message being sent to the host and after receiving the - * SCIF_EXIT_ACK from the host the peer device teardown on the card is - * complete. - * 6. As part of the SCIF_EXIT message processing on the host, host sends a - * SCIF_REMOVE_NODE to itself corresponding to the card being removed. This - * starts a similar SCIF peer device teardown sequence on the host - * corresponding to the card being shut down. - * - * Card reset - * ---------- - * The case of interest here is when the card has not been previously shut down - * since most of the steps below are skipped in that case: - - * 1. cosm_stop(..) invokes hw_ops->stop(..) method of the base PCIe driver - * which unregisters the SCIF HW device resulting in scif_remove(..) being - * called on the host. - * 2. scif_remove(..) calls scif_disconnect_node(..) which results in a - * SCIF_EXIT message being sent to the card. - * 3. The card executes scif_stop() as part of SCIF_EXIT message - * processing. This results in the COSM endpoint on the card being closed and - * the SCIF host peer device on the card getting unregistered similar to - * steps 3, 4 and 5 for the card shutdown case above. scif_poll(..) on the - * host returns EPOLLHUP as a result. - * 4. On the host, card peer device unregister and SCIF HW remove(..) also - * subsequently complete. - * - * Card crash - * ---------- - * If a reset is issued after the card has crashed, there is no SCIF_DISCNT - * message from the card which would result in scif_poll(..) returning - * EPOLLHUP. In this case when the host SCIF driver sends a SCIF_REMOVE_NODE - * message to itself resulting in the card SCIF peer device being unregistered, - * this results in a scif_peer_release_dev -> scif_cleanup_scifdev-> - * scif_invalidate_ep call sequence which sets the endpoint state to - * DISCONNECTED and results in scif_poll(..) returning EPOLLHUP. - */ - -#define COSM_SCIF_BACKLOG 16 -#define COSM_HEARTBEAT_CHECK_DELTA_SEC 10 -#define COSM_HEARTBEAT_TIMEOUT_SEC \ - (COSM_HEARTBEAT_SEND_SEC + COSM_HEARTBEAT_CHECK_DELTA_SEC) -#define COSM_HEARTBEAT_TIMEOUT_MSEC (COSM_HEARTBEAT_TIMEOUT_SEC * MSEC_PER_SEC) - -static struct task_struct *server_thread; -static scif_epd_t listen_epd; - -/* Publish MIC card's shutdown status to user space MIC daemon */ -static void cosm_update_mic_status(struct cosm_device *cdev) -{ - if (cdev->shutdown_status_int != MIC_NOP) { - cosm_set_shutdown_status(cdev, cdev->shutdown_status_int); - cdev->shutdown_status_int = MIC_NOP; - } -} - -/* Store MIC card's shutdown status internally when it is received */ -static void cosm_shutdown_status_int(struct cosm_device *cdev, - enum mic_status shutdown_status) -{ - switch (shutdown_status) { - case MIC_HALTED: - case MIC_POWER_OFF: - case MIC_RESTART: - case MIC_CRASHED: - break; - default: - dev_err(&cdev->dev, "%s %d Unexpected shutdown_status %d\n", - __func__, __LINE__, shutdown_status); - return; - }; - cdev->shutdown_status_int = shutdown_status; - cdev->heartbeat_watchdog_enable = false; - - if (cdev->state != MIC_SHUTTING_DOWN) - cosm_set_state(cdev, MIC_SHUTTING_DOWN); -} - -/* Non-blocking recv. Read and process all available messages */ -static void cosm_scif_recv(struct cosm_device *cdev) -{ - struct cosm_msg msg; - int rc; - - while (1) { - rc = scif_recv(cdev->epd, &msg, sizeof(msg), 0); - if (!rc) { - break; - } else if (rc < 0) { - dev_dbg(&cdev->dev, "%s: %d rc %d\n", - __func__, __LINE__, rc); - break; - } - dev_dbg(&cdev->dev, "%s: %d rc %d id 0x%llx\n", - __func__, __LINE__, rc, msg.id); - - switch (msg.id) { - case COSM_MSG_SHUTDOWN_STATUS: - cosm_shutdown_status_int(cdev, msg.shutdown_status); - break; - case COSM_MSG_HEARTBEAT: - /* Nothing to do, heartbeat only unblocks scif_poll */ - break; - default: - dev_err(&cdev->dev, "%s: %d unknown msg.id %lld\n", - __func__, __LINE__, msg.id); - break; - } - } -} - -/* Publish crashed status for this MIC card */ -static void cosm_set_crashed(struct cosm_device *cdev) -{ - dev_err(&cdev->dev, "node alive timeout\n"); - cosm_shutdown_status_int(cdev, MIC_CRASHED); - cosm_update_mic_status(cdev); -} - -/* Send host time to the MIC card to sync system time between host and MIC */ -static void cosm_send_time(struct cosm_device *cdev) -{ - struct cosm_msg msg = { .id = COSM_MSG_SYNC_TIME }; - struct timespec64 ts; - int rc; - - ktime_get_real_ts64(&ts); - msg.timespec.tv_sec = ts.tv_sec; - msg.timespec.tv_nsec = ts.tv_nsec; - - rc = scif_send(cdev->epd, &msg, sizeof(msg), SCIF_SEND_BLOCK); - if (rc < 0) - dev_err(&cdev->dev, "%s %d scif_send failed rc %d\n", - __func__, __LINE__, rc); -} - -/* - * Close this cosm_device's endpoint after its peer endpoint on the card has - * been closed. In all cases except MIC card crash EPOLLHUP on the host is - * triggered by the client's endpoint being closed. - */ -static void cosm_scif_close(struct cosm_device *cdev) -{ - /* - * Because SHUTDOWN_STATUS message is sent by the MIC cards in the - * reboot notifier when shutdown is still not complete, we notify mpssd - * to reset the card when SCIF endpoint is closed. - */ - cosm_update_mic_status(cdev); - scif_close(cdev->epd); - cdev->epd = NULL; - dev_dbg(&cdev->dev, "%s %d\n", __func__, __LINE__); -} - -/* - * Set card state to ONLINE when a new SCIF connection from a MIC card is - * received. Normally the state is BOOTING when the connection comes in, but can - * be ONLINE if cosm_client driver on the card was unloaded and then reloaded. - */ -static int cosm_set_online(struct cosm_device *cdev) -{ - int rc = 0; - - if (MIC_BOOTING == cdev->state || MIC_ONLINE == cdev->state) { - cdev->heartbeat_watchdog_enable = cdev->sysfs_heartbeat_enable; - cdev->epd = cdev->newepd; - if (cdev->state == MIC_BOOTING) - cosm_set_state(cdev, MIC_ONLINE); - cosm_send_time(cdev); - dev_dbg(&cdev->dev, "%s %d\n", __func__, __LINE__); - } else { - dev_warn(&cdev->dev, "%s %d not going online in state: %s\n", - __func__, __LINE__, cosm_state_string[cdev->state]); - rc = -EINVAL; - } - /* Drop reference acquired by bus_find_device in the server thread */ - put_device(&cdev->dev); - return rc; -} - -/* - * Work function for handling work for a SCIF connection from a particular MIC - * card. It first sets the card state to ONLINE and then calls scif_poll to - * block on activity such as incoming messages on the SCIF endpoint. When the - * endpoint is closed, the work function exits, completing its life cycle, from - * MIC card boot to card shutdown/reset/crash. - */ -void cosm_scif_work(struct work_struct *work) -{ - struct cosm_device *cdev = container_of(work, struct cosm_device, - scif_work); - struct scif_pollepd pollepd; - int rc; - - mutex_lock(&cdev->cosm_mutex); - if (cosm_set_online(cdev)) - goto exit; - - while (1) { - pollepd.epd = cdev->epd; - pollepd.events = EPOLLIN; - - /* Drop the mutex before blocking in scif_poll(..) */ - mutex_unlock(&cdev->cosm_mutex); - /* poll(..) with timeout on our endpoint */ - rc = scif_poll(&pollepd, 1, COSM_HEARTBEAT_TIMEOUT_MSEC); - mutex_lock(&cdev->cosm_mutex); - if (rc < 0) { - dev_err(&cdev->dev, "%s %d scif_poll rc %d\n", - __func__, __LINE__, rc); - continue; - } - - /* There is a message from the card */ - if (pollepd.revents & EPOLLIN) - cosm_scif_recv(cdev); - - /* The peer endpoint is closed or this endpoint disconnected */ - if (pollepd.revents & EPOLLHUP) { - cosm_scif_close(cdev); - break; - } - - /* Did we timeout from poll? */ - if (!rc && cdev->heartbeat_watchdog_enable) - cosm_set_crashed(cdev); - } -exit: - dev_dbg(&cdev->dev, "%s %d exiting\n", __func__, __LINE__); - mutex_unlock(&cdev->cosm_mutex); -} - -/* - * COSM SCIF server thread function. Accepts incoming SCIF connections from MIC - * cards, finds the correct cosm_device to associate that connection with and - * schedules individual work items for each MIC card. - */ -static int cosm_scif_server(void *unused) -{ - struct cosm_device *cdev; - scif_epd_t newepd; - struct scif_port_id port_id; - int rc; - - allow_signal(SIGKILL); - - while (!kthread_should_stop()) { - rc = scif_accept(listen_epd, &port_id, &newepd, - SCIF_ACCEPT_SYNC); - if (rc < 0) { - if (-ERESTARTSYS != rc) - pr_err("%s %d rc %d\n", __func__, __LINE__, rc); - continue; - } - - /* - * Associate the incoming connection with a particular - * cosm_device, COSM device ID == SCIF node ID - 1 - */ - cdev = cosm_find_cdev_by_id(port_id.node - 1); - if (!cdev) - continue; - cdev->newepd = newepd; - schedule_work(&cdev->scif_work); - } - - pr_debug("%s %d Server thread stopped\n", __func__, __LINE__); - return 0; -} - -static int cosm_scif_listen(void) -{ - int rc; - - listen_epd = scif_open(); - if (!listen_epd) { - pr_err("%s %d scif_open failed\n", __func__, __LINE__); - return -ENOMEM; - } - - rc = scif_bind(listen_epd, SCIF_COSM_LISTEN_PORT); - if (rc < 0) { - pr_err("%s %d scif_bind failed rc %d\n", - __func__, __LINE__, rc); - goto err; - } - - rc = scif_listen(listen_epd, COSM_SCIF_BACKLOG); - if (rc < 0) { - pr_err("%s %d scif_listen rc %d\n", __func__, __LINE__, rc); - goto err; - } - pr_debug("%s %d listen_epd set up\n", __func__, __LINE__); - return 0; -err: - scif_close(listen_epd); - listen_epd = NULL; - return rc; -} - -static void cosm_scif_listen_exit(void) -{ - pr_debug("%s %d closing listen_epd\n", __func__, __LINE__); - if (listen_epd) { - scif_close(listen_epd); - listen_epd = NULL; - } -} - -/* - * Create a listening SCIF endpoint and a server kthread which accepts incoming - * SCIF connections from MIC cards - */ -int cosm_scif_init(void) -{ - int rc = cosm_scif_listen(); - - if (rc) { - pr_err("%s %d cosm_scif_listen rc %d\n", - __func__, __LINE__, rc); - goto err; - } - - server_thread = kthread_run(cosm_scif_server, NULL, "cosm_server"); - if (IS_ERR(server_thread)) { - rc = PTR_ERR(server_thread); - pr_err("%s %d kthread_run rc %d\n", __func__, __LINE__, rc); - goto listen_exit; - } - return 0; -listen_exit: - cosm_scif_listen_exit(); -err: - return rc; -} - -/* Stop the running server thread and close the listening SCIF endpoint */ -void cosm_scif_exit(void) -{ - int rc; - - if (!IS_ERR_OR_NULL(server_thread)) { - rc = send_sig(SIGKILL, server_thread, 0); - if (rc) { - pr_err("%s %d send_sig rc %d\n", - __func__, __LINE__, rc); - return; - } - kthread_stop(server_thread); - } - - cosm_scif_listen_exit(); -} diff --git a/drivers/misc/mic/cosm/cosm_sysfs.c b/drivers/misc/mic/cosm/cosm_sysfs.c deleted file mode 100644 index e6dac967c1af..000000000000 --- a/drivers/misc/mic/cosm/cosm_sysfs.c +++ /dev/null @@ -1,449 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel MIC Coprocessor State Management (COSM) Driver - */ -#include <linux/slab.h> -#include "cosm_main.h" - -/* - * A state-to-string lookup table, for exposing a human readable state - * via sysfs. Always keep in sync with enum cosm_states - */ -const char * const cosm_state_string[] = { - [MIC_READY] = "ready", - [MIC_BOOTING] = "booting", - [MIC_ONLINE] = "online", - [MIC_SHUTTING_DOWN] = "shutting_down", - [MIC_RESETTING] = "resetting", - [MIC_RESET_FAILED] = "reset_failed", -}; - -/* - * A shutdown-status-to-string lookup table, for exposing a human - * readable state via sysfs. Always keep in sync with enum cosm_shutdown_status - */ -const char * const cosm_shutdown_status_string[] = { - [MIC_NOP] = "nop", - [MIC_CRASHED] = "crashed", - [MIC_HALTED] = "halted", - [MIC_POWER_OFF] = "poweroff", - [MIC_RESTART] = "restart", -}; - -void cosm_set_shutdown_status(struct cosm_device *cdev, u8 shutdown_status) -{ - dev_dbg(&cdev->dev, "Shutdown Status %s -> %s\n", - cosm_shutdown_status_string[cdev->shutdown_status], - cosm_shutdown_status_string[shutdown_status]); - cdev->shutdown_status = shutdown_status; -} - -void cosm_set_state(struct cosm_device *cdev, u8 state) -{ - dev_dbg(&cdev->dev, "State %s -> %s\n", - cosm_state_string[cdev->state], - cosm_state_string[state]); - cdev->state = state; - sysfs_notify_dirent(cdev->state_sysfs); -} - -static ssize_t -family_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - - if (!cdev) - return -EINVAL; - - return cdev->hw_ops->family(cdev, buf); -} -static DEVICE_ATTR_RO(family); - -static ssize_t -stepping_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - - if (!cdev) - return -EINVAL; - - return cdev->hw_ops->stepping(cdev, buf); -} -static DEVICE_ATTR_RO(stepping); - -static ssize_t -state_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - - if (!cdev || cdev->state >= MIC_LAST) - return -EINVAL; - - return scnprintf(buf, PAGE_SIZE, "%s\n", - cosm_state_string[cdev->state]); -} - -static ssize_t -state_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - int rc; - - if (!cdev) - return -EINVAL; - - if (sysfs_streq(buf, "boot")) { - rc = cosm_start(cdev); - goto done; - } - if (sysfs_streq(buf, "reset")) { - rc = cosm_reset(cdev); - goto done; - } - - if (sysfs_streq(buf, "shutdown")) { - rc = cosm_shutdown(cdev); - goto done; - } - rc = -EINVAL; -done: - if (rc) - count = rc; - return count; -} -static DEVICE_ATTR_RW(state); - -static ssize_t shutdown_status_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - - if (!cdev || cdev->shutdown_status >= MIC_STATUS_LAST) - return -EINVAL; - - return scnprintf(buf, PAGE_SIZE, "%s\n", - cosm_shutdown_status_string[cdev->shutdown_status]); -} -static DEVICE_ATTR_RO(shutdown_status); - -static ssize_t -heartbeat_enable_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - - if (!cdev) - return -EINVAL; - - return scnprintf(buf, PAGE_SIZE, "%d\n", cdev->sysfs_heartbeat_enable); -} - -static ssize_t -heartbeat_enable_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - int enable; - int ret; - - if (!cdev) - return -EINVAL; - - mutex_lock(&cdev->cosm_mutex); - ret = kstrtoint(buf, 10, &enable); - if (ret) - goto unlock; - - cdev->sysfs_heartbeat_enable = enable; - /* if state is not online, cdev->heartbeat_watchdog_enable is 0 */ - if (cdev->state == MIC_ONLINE) - cdev->heartbeat_watchdog_enable = enable; - ret = count; -unlock: - mutex_unlock(&cdev->cosm_mutex); - return ret; -} -static DEVICE_ATTR_RW(heartbeat_enable); - -static ssize_t -cmdline_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - char *cmdline; - - if (!cdev) - return -EINVAL; - - cmdline = cdev->cmdline; - - if (cmdline) - return scnprintf(buf, PAGE_SIZE, "%s\n", cmdline); - return 0; -} - -static ssize_t -cmdline_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - - if (!cdev) - return -EINVAL; - - mutex_lock(&cdev->cosm_mutex); - kfree(cdev->cmdline); - - cdev->cmdline = kmalloc(count + 1, GFP_KERNEL); - if (!cdev->cmdline) { - count = -ENOMEM; - goto unlock; - } - - strncpy(cdev->cmdline, buf, count); - - if (cdev->cmdline[count - 1] == '\n') - cdev->cmdline[count - 1] = '\0'; - else - cdev->cmdline[count] = '\0'; -unlock: - mutex_unlock(&cdev->cosm_mutex); - return count; -} -static DEVICE_ATTR_RW(cmdline); - -static ssize_t -firmware_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - char *firmware; - - if (!cdev) - return -EINVAL; - - firmware = cdev->firmware; - - if (firmware) - return scnprintf(buf, PAGE_SIZE, "%s\n", firmware); - return 0; -} - -static ssize_t -firmware_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - - if (!cdev) - return -EINVAL; - - mutex_lock(&cdev->cosm_mutex); - kfree(cdev->firmware); - - cdev->firmware = kmalloc(count + 1, GFP_KERNEL); - if (!cdev->firmware) { - count = -ENOMEM; - goto unlock; - } - strncpy(cdev->firmware, buf, count); - - if (cdev->firmware[count - 1] == '\n') - cdev->firmware[count - 1] = '\0'; - else - cdev->firmware[count] = '\0'; -unlock: - mutex_unlock(&cdev->cosm_mutex); - return count; -} -static DEVICE_ATTR_RW(firmware); - -static ssize_t -ramdisk_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - char *ramdisk; - - if (!cdev) - return -EINVAL; - - ramdisk = cdev->ramdisk; - - if (ramdisk) - return scnprintf(buf, PAGE_SIZE, "%s\n", ramdisk); - return 0; -} - -static ssize_t -ramdisk_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - - if (!cdev) - return -EINVAL; - - mutex_lock(&cdev->cosm_mutex); - kfree(cdev->ramdisk); - - cdev->ramdisk = kmalloc(count + 1, GFP_KERNEL); - if (!cdev->ramdisk) { - count = -ENOMEM; - goto unlock; - } - - strncpy(cdev->ramdisk, buf, count); - - if (cdev->ramdisk[count - 1] == '\n') - cdev->ramdisk[count - 1] = '\0'; - else - cdev->ramdisk[count] = '\0'; -unlock: - mutex_unlock(&cdev->cosm_mutex); - return count; -} -static DEVICE_ATTR_RW(ramdisk); - -static ssize_t -bootmode_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - char *bootmode; - - if (!cdev) - return -EINVAL; - - bootmode = cdev->bootmode; - - if (bootmode) - return scnprintf(buf, PAGE_SIZE, "%s\n", bootmode); - return 0; -} - -static ssize_t -bootmode_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - - if (!cdev) - return -EINVAL; - - if (!sysfs_streq(buf, "linux") && !sysfs_streq(buf, "flash")) - return -EINVAL; - - mutex_lock(&cdev->cosm_mutex); - kfree(cdev->bootmode); - - cdev->bootmode = kmalloc(count + 1, GFP_KERNEL); - if (!cdev->bootmode) { - count = -ENOMEM; - goto unlock; - } - - strncpy(cdev->bootmode, buf, count); - - if (cdev->bootmode[count - 1] == '\n') - cdev->bootmode[count - 1] = '\0'; - else - cdev->bootmode[count] = '\0'; -unlock: - mutex_unlock(&cdev->cosm_mutex); - return count; -} -static DEVICE_ATTR_RW(bootmode); - -static ssize_t -log_buf_addr_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - - if (!cdev) - return -EINVAL; - - return scnprintf(buf, PAGE_SIZE, "%p\n", cdev->log_buf_addr); -} - -static ssize_t -log_buf_addr_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - int ret; - unsigned long addr; - - if (!cdev) - return -EINVAL; - - ret = kstrtoul(buf, 16, &addr); - if (ret) - goto exit; - - cdev->log_buf_addr = (void *)addr; - ret = count; -exit: - return ret; -} -static DEVICE_ATTR_RW(log_buf_addr); - -static ssize_t -log_buf_len_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - - if (!cdev) - return -EINVAL; - - return scnprintf(buf, PAGE_SIZE, "%p\n", cdev->log_buf_len); -} - -static ssize_t -log_buf_len_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct cosm_device *cdev = dev_get_drvdata(dev); - int ret; - unsigned long addr; - - if (!cdev) - return -EINVAL; - - ret = kstrtoul(buf, 16, &addr); - if (ret) - goto exit; - - cdev->log_buf_len = (int *)addr; - ret = count; -exit: - return ret; -} -static DEVICE_ATTR_RW(log_buf_len); - -static struct attribute *cosm_default_attrs[] = { - &dev_attr_family.attr, - &dev_attr_stepping.attr, - &dev_attr_state.attr, - &dev_attr_shutdown_status.attr, - &dev_attr_heartbeat_enable.attr, - &dev_attr_cmdline.attr, - &dev_attr_firmware.attr, - &dev_attr_ramdisk.attr, - &dev_attr_bootmode.attr, - &dev_attr_log_buf_addr.attr, - &dev_attr_log_buf_len.attr, - - NULL -}; - -ATTRIBUTE_GROUPS(cosm_default); - -void cosm_sysfs_init(struct cosm_device *cdev) -{ - cdev->attr_group = cosm_default_groups; -} diff --git a/drivers/misc/mic/cosm_client/Makefile b/drivers/misc/mic/cosm_client/Makefile deleted file mode 100644 index 5b62270bc2ab..000000000000 --- a/drivers/misc/mic/cosm_client/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile - Intel MIC COSM Client Driver -# Copyright(c) 2015, Intel Corporation. -# -obj-$(CONFIG_MIC_COSM) += cosm_client.o - -cosm_client-objs += cosm_scif_client.o diff --git a/drivers/misc/mic/cosm_client/cosm_scif_client.c b/drivers/misc/mic/cosm_client/cosm_scif_client.c deleted file mode 100644 index a03213dd9319..000000000000 --- a/drivers/misc/mic/cosm_client/cosm_scif_client.c +++ /dev/null @@ -1,269 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel MIC COSM Client Driver - */ -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/reboot.h> -#include <linux/kthread.h> -#include <linux/sched/signal.h> - -#include "../cosm/cosm_main.h" - -#define COSM_SCIF_MAX_RETRIES 10 -#define COSM_HEARTBEAT_SEND_MSEC (COSM_HEARTBEAT_SEND_SEC * MSEC_PER_SEC) - -static struct task_struct *client_thread; -static scif_epd_t client_epd; -static struct scif_peer_dev *client_spdev; - -/* - * Reboot notifier: receives shutdown status from the OS and communicates it - * back to the COSM process on the host - */ -static int cosm_reboot_event(struct notifier_block *this, unsigned long event, - void *ptr) -{ - struct cosm_msg msg = { .id = COSM_MSG_SHUTDOWN_STATUS }; - int rc; - - event = (event == SYS_RESTART) ? SYSTEM_RESTART : event; - dev_info(&client_spdev->dev, "%s %d received event %ld\n", - __func__, __LINE__, event); - - msg.shutdown_status = event; - rc = scif_send(client_epd, &msg, sizeof(msg), SCIF_SEND_BLOCK); - if (rc < 0) - dev_err(&client_spdev->dev, "%s %d scif_send rc %d\n", - __func__, __LINE__, rc); - - return NOTIFY_DONE; -} - -static struct notifier_block cosm_reboot = { - .notifier_call = cosm_reboot_event, -}; - -/* Set system time from timespec value received from the host */ -static void cosm_set_time(struct cosm_msg *msg) -{ - struct timespec64 ts = { - .tv_sec = msg->timespec.tv_sec, - .tv_nsec = msg->timespec.tv_nsec, - }; - int rc = do_settimeofday64(&ts); - - if (rc) - dev_err(&client_spdev->dev, "%s: %d settimeofday rc %d\n", - __func__, __LINE__, rc); -} - -/* COSM client receive message processing */ -static void cosm_client_recv(void) -{ - struct cosm_msg msg; - int rc; - - while (1) { - rc = scif_recv(client_epd, &msg, sizeof(msg), 0); - if (!rc) { - return; - } else if (rc < 0) { - dev_err(&client_spdev->dev, "%s: %d rc %d\n", - __func__, __LINE__, rc); - return; - } - - dev_dbg(&client_spdev->dev, "%s: %d rc %d id 0x%llx\n", - __func__, __LINE__, rc, msg.id); - - switch (msg.id) { - case COSM_MSG_SYNC_TIME: - cosm_set_time(&msg); - break; - case COSM_MSG_SHUTDOWN: - orderly_poweroff(true); - break; - default: - dev_err(&client_spdev->dev, "%s: %d unknown id %lld\n", - __func__, __LINE__, msg.id); - break; - } - } -} - -/* Initiate connection to the COSM server on the host */ -static int cosm_scif_connect(void) -{ - struct scif_port_id port_id; - int i, rc; - - client_epd = scif_open(); - if (!client_epd) { - dev_err(&client_spdev->dev, "%s %d scif_open failed\n", - __func__, __LINE__); - return -ENOMEM; - } - - port_id.node = 0; - port_id.port = SCIF_COSM_LISTEN_PORT; - - for (i = 0; i < COSM_SCIF_MAX_RETRIES; i++) { - rc = scif_connect(client_epd, &port_id); - if (rc < 0) - msleep(1000); - else - break; - } - - if (rc < 0) { - dev_err(&client_spdev->dev, "%s %d scif_connect rc %d\n", - __func__, __LINE__, rc); - scif_close(client_epd); - client_epd = NULL; - } - return rc < 0 ? rc : 0; -} - -/* Close host SCIF connection */ -static void cosm_scif_connect_exit(void) -{ - if (client_epd) { - scif_close(client_epd); - client_epd = NULL; - } -} - -/* - * COSM SCIF client thread function: waits for messages from the host and sends - * a heartbeat to the host - */ -static int cosm_scif_client(void *unused) -{ - struct cosm_msg msg = { .id = COSM_MSG_HEARTBEAT }; - struct scif_pollepd pollepd; - int rc; - - allow_signal(SIGKILL); - - while (!kthread_should_stop()) { - pollepd.epd = client_epd; - pollepd.events = EPOLLIN; - - rc = scif_poll(&pollepd, 1, COSM_HEARTBEAT_SEND_MSEC); - if (rc < 0) { - if (-EINTR != rc) - dev_err(&client_spdev->dev, - "%s %d scif_poll rc %d\n", - __func__, __LINE__, rc); - continue; - } - - if (pollepd.revents & EPOLLIN) - cosm_client_recv(); - - msg.id = COSM_MSG_HEARTBEAT; - rc = scif_send(client_epd, &msg, sizeof(msg), SCIF_SEND_BLOCK); - if (rc < 0) - dev_err(&client_spdev->dev, "%s %d scif_send rc %d\n", - __func__, __LINE__, rc); - } - - dev_dbg(&client_spdev->dev, "%s %d Client thread stopped\n", - __func__, __LINE__); - return 0; -} - -static void cosm_scif_probe(struct scif_peer_dev *spdev) -{ - int rc; - - dev_dbg(&spdev->dev, "%s %d: dnode %d\n", - __func__, __LINE__, spdev->dnode); - - /* We are only interested in the host with spdev->dnode == 0 */ - if (spdev->dnode) - return; - - client_spdev = spdev; - rc = cosm_scif_connect(); - if (rc) - goto exit; - - rc = register_reboot_notifier(&cosm_reboot); - if (rc) { - dev_err(&spdev->dev, - "reboot notifier registration failed rc %d\n", rc); - goto connect_exit; - } - - client_thread = kthread_run(cosm_scif_client, NULL, "cosm_client"); - if (IS_ERR(client_thread)) { - rc = PTR_ERR(client_thread); - dev_err(&spdev->dev, "%s %d kthread_run rc %d\n", - __func__, __LINE__, rc); - goto unreg_reboot; - } - return; -unreg_reboot: - unregister_reboot_notifier(&cosm_reboot); -connect_exit: - cosm_scif_connect_exit(); -exit: - client_spdev = NULL; -} - -static void cosm_scif_remove(struct scif_peer_dev *spdev) -{ - int rc; - - dev_dbg(&spdev->dev, "%s %d: dnode %d\n", - __func__, __LINE__, spdev->dnode); - - if (spdev->dnode) - return; - - if (!IS_ERR_OR_NULL(client_thread)) { - rc = send_sig(SIGKILL, client_thread, 0); - if (rc) { - pr_err("%s %d send_sig rc %d\n", - __func__, __LINE__, rc); - return; - } - kthread_stop(client_thread); - } - unregister_reboot_notifier(&cosm_reboot); - cosm_scif_connect_exit(); - client_spdev = NULL; -} - -static struct scif_client scif_client_cosm = { - .name = KBUILD_MODNAME, - .probe = cosm_scif_probe, - .remove = cosm_scif_remove, -}; - -static int __init cosm_client_init(void) -{ - int rc = scif_client_register(&scif_client_cosm); - - if (rc) - pr_err("scif_client_register failed rc %d\n", rc); - return rc; -} - -static void __exit cosm_client_exit(void) -{ - scif_client_unregister(&scif_client_cosm); -} - -module_init(cosm_client_init); -module_exit(cosm_client_exit); - -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) MIC card OS state management client driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mic/host/Makefile b/drivers/misc/mic/host/Makefile deleted file mode 100644 index 25f153367980..000000000000 --- a/drivers/misc/mic/host/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile - Intel MIC Linux driver. -# Copyright(c) 2013, Intel Corporation. -# -obj-$(CONFIG_INTEL_MIC_HOST) += mic_host.o -mic_host-objs := mic_main.o -mic_host-objs += mic_x100.o -mic_host-objs += mic_smpt.o -mic_host-objs += mic_intr.o -mic_host-objs += mic_boot.o -mic_host-objs += mic_debugfs.o diff --git a/drivers/misc/mic/host/mic_boot.c b/drivers/misc/mic/host/mic_boot.c deleted file mode 100644 index 8cb85b8b3e19..000000000000 --- a/drivers/misc/mic/host/mic_boot.c +++ /dev/null @@ -1,588 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Intel MIC Host driver. - */ -#include <linux/delay.h> -#include <linux/firmware.h> -#include <linux/pci.h> -#include <linux/kmod.h> -#include <linux/dma-map-ops.h> -#include <linux/mic_common.h> -#include <linux/mic_bus.h> -#include "../bus/scif_bus.h" -#include "../bus/vop_bus.h" -#include "../common/mic_dev.h" -#include "mic_device.h" -#include "mic_smpt.h" - -static inline struct mic_device *vpdev_to_mdev(struct device *dev) -{ - return dev_get_drvdata(dev->parent); -} - -static dma_addr_t -_mic_dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, unsigned long attrs) -{ - void *va = phys_to_virt(page_to_phys(page)) + offset; - struct mic_device *mdev = vpdev_to_mdev(dev); - - return mic_map_single(mdev, va, size); -} - -static void _mic_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction dir, - unsigned long attrs) -{ - struct mic_device *mdev = vpdev_to_mdev(dev); - - mic_unmap_single(mdev, dma_addr, size); -} - -static const struct dma_map_ops _mic_dma_ops = { - .map_page = _mic_dma_map_page, - .unmap_page = _mic_dma_unmap_page, -}; - -static struct mic_irq * -__mic_request_irq(struct vop_device *vpdev, - irqreturn_t (*func)(int irq, void *data), - const char *name, void *data, int intr_src) -{ - struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); - - return mic_request_threaded_irq(mdev, func, NULL, name, data, - intr_src, MIC_INTR_DB); -} - -static void __mic_free_irq(struct vop_device *vpdev, - struct mic_irq *cookie, void *data) -{ - struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); - - mic_free_irq(mdev, cookie, data); -} - -static void __mic_ack_interrupt(struct vop_device *vpdev, int num) -{ - struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); - - mdev->ops->intr_workarounds(mdev); -} - -static int __mic_next_db(struct vop_device *vpdev) -{ - struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); - - return mic_next_db(mdev); -} - -static void *__mic_get_dp(struct vop_device *vpdev) -{ - struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); - - return mdev->dp; -} - -static void __iomem *__mic_get_remote_dp(struct vop_device *vpdev) -{ - return NULL; -} - -static void __mic_send_intr(struct vop_device *vpdev, int db) -{ - struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); - - mdev->ops->send_intr(mdev, db); -} - -static void __iomem *__mic_ioremap(struct vop_device *vpdev, - dma_addr_t pa, size_t len) -{ - struct mic_device *mdev = vpdev_to_mdev(&vpdev->dev); - - return mdev->aper.va + pa; -} - -static void __mic_iounmap(struct vop_device *vpdev, void __iomem *va) -{ - /* nothing to do */ -} - -static struct vop_hw_ops vop_hw_ops = { - .request_irq = __mic_request_irq, - .free_irq = __mic_free_irq, - .ack_interrupt = __mic_ack_interrupt, - .next_db = __mic_next_db, - .get_dp = __mic_get_dp, - .get_remote_dp = __mic_get_remote_dp, - .send_intr = __mic_send_intr, - .remap = __mic_ioremap, - .unmap = __mic_iounmap, -}; - -static inline struct mic_device *scdev_to_mdev(struct scif_hw_dev *scdev) -{ - return dev_get_drvdata(scdev->dev.parent); -} - -static void *__mic_dma_alloc(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, - unsigned long attrs) -{ - struct scif_hw_dev *scdev = dev_get_drvdata(dev); - struct mic_device *mdev = scdev_to_mdev(scdev); - dma_addr_t tmp; - void *va = kzalloc(size, gfp); - - if (va) { - tmp = mic_map_single(mdev, va, size); - if (dma_mapping_error(dev, tmp)) { - kfree(va); - va = NULL; - } else { - *dma_handle = tmp; - } - } - return va; -} - -static void __mic_dma_free(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_handle, unsigned long attrs) -{ - struct scif_hw_dev *scdev = dev_get_drvdata(dev); - struct mic_device *mdev = scdev_to_mdev(scdev); - - mic_unmap_single(mdev, dma_handle, size); - kfree(vaddr); -} - -static dma_addr_t -__mic_dma_map_page(struct device *dev, struct page *page, unsigned long offset, - size_t size, enum dma_data_direction dir, - unsigned long attrs) -{ - void *va = phys_to_virt(page_to_phys(page)) + offset; - struct scif_hw_dev *scdev = dev_get_drvdata(dev); - struct mic_device *mdev = scdev_to_mdev(scdev); - - return mic_map_single(mdev, va, size); -} - -static void -__mic_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction dir, - unsigned long attrs) -{ - struct scif_hw_dev *scdev = dev_get_drvdata(dev); - struct mic_device *mdev = scdev_to_mdev(scdev); - - mic_unmap_single(mdev, dma_addr, size); -} - -static int __mic_dma_map_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction dir, - unsigned long attrs) -{ - struct scif_hw_dev *scdev = dev_get_drvdata(dev); - struct mic_device *mdev = scdev_to_mdev(scdev); - struct scatterlist *s; - int i, j, ret; - dma_addr_t da; - - ret = dma_map_sg(&mdev->pdev->dev, sg, nents, dir); - if (ret <= 0) - return 0; - - for_each_sg(sg, s, nents, i) { - da = mic_map(mdev, sg_dma_address(s) + s->offset, s->length); - if (!da) - goto err; - sg_dma_address(s) = da; - } - return nents; -err: - for_each_sg(sg, s, i, j) { - mic_unmap(mdev, sg_dma_address(s), s->length); - sg_dma_address(s) = mic_to_dma_addr(mdev, sg_dma_address(s)); - } - dma_unmap_sg(&mdev->pdev->dev, sg, nents, dir); - return 0; -} - -static void __mic_dma_unmap_sg(struct device *dev, - struct scatterlist *sg, int nents, - enum dma_data_direction dir, - unsigned long attrs) -{ - struct scif_hw_dev *scdev = dev_get_drvdata(dev); - struct mic_device *mdev = scdev_to_mdev(scdev); - struct scatterlist *s; - dma_addr_t da; - int i; - - for_each_sg(sg, s, nents, i) { - da = mic_to_dma_addr(mdev, sg_dma_address(s)); - mic_unmap(mdev, sg_dma_address(s), s->length); - sg_dma_address(s) = da; - } - dma_unmap_sg(&mdev->pdev->dev, sg, nents, dir); -} - -static const struct dma_map_ops __mic_dma_ops = { - .alloc = __mic_dma_alloc, - .free = __mic_dma_free, - .map_page = __mic_dma_map_page, - .unmap_page = __mic_dma_unmap_page, - .map_sg = __mic_dma_map_sg, - .unmap_sg = __mic_dma_unmap_sg, -}; - -static struct mic_irq * -___mic_request_irq(struct scif_hw_dev *scdev, - irqreturn_t (*func)(int irq, void *data), - const char *name, - void *data, int db) -{ - struct mic_device *mdev = scdev_to_mdev(scdev); - - return mic_request_threaded_irq(mdev, func, NULL, name, data, - db, MIC_INTR_DB); -} - -static void -___mic_free_irq(struct scif_hw_dev *scdev, - struct mic_irq *cookie, void *data) -{ - struct mic_device *mdev = scdev_to_mdev(scdev); - - mic_free_irq(mdev, cookie, data); -} - -static void ___mic_ack_interrupt(struct scif_hw_dev *scdev, int num) -{ - struct mic_device *mdev = scdev_to_mdev(scdev); - - mdev->ops->intr_workarounds(mdev); -} - -static int ___mic_next_db(struct scif_hw_dev *scdev) -{ - struct mic_device *mdev = scdev_to_mdev(scdev); - - return mic_next_db(mdev); -} - -static void ___mic_send_intr(struct scif_hw_dev *scdev, int db) -{ - struct mic_device *mdev = scdev_to_mdev(scdev); - - mdev->ops->send_intr(mdev, db); -} - -static void __iomem *___mic_ioremap(struct scif_hw_dev *scdev, - phys_addr_t pa, size_t len) -{ - struct mic_device *mdev = scdev_to_mdev(scdev); - - return mdev->aper.va + pa; -} - -static void ___mic_iounmap(struct scif_hw_dev *scdev, void __iomem *va) -{ - /* nothing to do */ -} - -static struct scif_hw_ops scif_hw_ops = { - .request_irq = ___mic_request_irq, - .free_irq = ___mic_free_irq, - .ack_interrupt = ___mic_ack_interrupt, - .next_db = ___mic_next_db, - .send_intr = ___mic_send_intr, - .remap = ___mic_ioremap, - .unmap = ___mic_iounmap, -}; - -static inline struct mic_device *mbdev_to_mdev(struct mbus_device *mbdev) -{ - return dev_get_drvdata(mbdev->dev.parent); -} - -static dma_addr_t -mic_dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, enum dma_data_direction dir, - unsigned long attrs) -{ - void *va = phys_to_virt(page_to_phys(page)) + offset; - struct mic_device *mdev = dev_get_drvdata(dev->parent); - - return mic_map_single(mdev, va, size); -} - -static void -mic_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction dir, - unsigned long attrs) -{ - struct mic_device *mdev = dev_get_drvdata(dev->parent); - mic_unmap_single(mdev, dma_addr, size); -} - -static const struct dma_map_ops mic_dma_ops = { - .map_page = mic_dma_map_page, - .unmap_page = mic_dma_unmap_page, -}; - -static struct mic_irq * -_mic_request_threaded_irq(struct mbus_device *mbdev, - irq_handler_t handler, irq_handler_t thread_fn, - const char *name, void *data, int intr_src) -{ - return mic_request_threaded_irq(mbdev_to_mdev(mbdev), handler, - thread_fn, name, data, - intr_src, MIC_INTR_DMA); -} - -static void _mic_free_irq(struct mbus_device *mbdev, - struct mic_irq *cookie, void *data) -{ - mic_free_irq(mbdev_to_mdev(mbdev), cookie, data); -} - -static void _mic_ack_interrupt(struct mbus_device *mbdev, int num) -{ - struct mic_device *mdev = mbdev_to_mdev(mbdev); - mdev->ops->intr_workarounds(mdev); -} - -static struct mbus_hw_ops mbus_hw_ops = { - .request_threaded_irq = _mic_request_threaded_irq, - .free_irq = _mic_free_irq, - .ack_interrupt = _mic_ack_interrupt, -}; - -/* Initialize the MIC bootparams */ -void mic_bootparam_init(struct mic_device *mdev) -{ - struct mic_bootparam *bootparam = mdev->dp; - - bootparam->magic = cpu_to_le32(MIC_MAGIC); - bootparam->h2c_config_db = -1; - bootparam->node_id = mdev->id + 1; - bootparam->scif_host_dma_addr = 0x0; - bootparam->scif_card_dma_addr = 0x0; - bootparam->c2h_scif_db = -1; - bootparam->h2c_scif_db = -1; -} - -static inline struct mic_device *cosmdev_to_mdev(struct cosm_device *cdev) -{ - return dev_get_drvdata(cdev->dev.parent); -} - -static void _mic_reset(struct cosm_device *cdev) -{ - struct mic_device *mdev = cosmdev_to_mdev(cdev); - - mdev->ops->reset_fw_ready(mdev); - mdev->ops->reset(mdev); -} - -static bool _mic_ready(struct cosm_device *cdev) -{ - struct mic_device *mdev = cosmdev_to_mdev(cdev); - - return mdev->ops->is_fw_ready(mdev); -} - -/** - * mic_request_dma_chans - Request DMA channels - * @mdev: pointer to mic_device instance - * - * returns number of DMA channels acquired - */ -static int mic_request_dma_chans(struct mic_device *mdev) -{ - dma_cap_mask_t mask; - struct dma_chan *chan; - - dma_cap_zero(mask); - dma_cap_set(DMA_MEMCPY, mask); - - do { - chan = dma_request_channel(mask, mdev->ops->dma_filter, - &mdev->pdev->dev); - if (chan) { - mdev->dma_ch[mdev->num_dma_ch++] = chan; - if (mdev->num_dma_ch >= MIC_MAX_DMA_CHAN) - break; - } - } while (chan); - dev_info(&mdev->pdev->dev, "DMA channels # %d\n", mdev->num_dma_ch); - return mdev->num_dma_ch; -} - -/** - * mic_free_dma_chans - release DMA channels - * @mdev: pointer to mic_device instance - * - * returns none - */ -static void mic_free_dma_chans(struct mic_device *mdev) -{ - int i = 0; - - for (i = 0; i < mdev->num_dma_ch; i++) { - dma_release_channel(mdev->dma_ch[i]); - mdev->dma_ch[i] = NULL; - } - mdev->num_dma_ch = 0; -} - -/** - * _mic_start - Start the MIC. - * @cdev: pointer to cosm_device instance - * @id: MIC device id/index provided by COSM used in other drivers like SCIF - * - * This function prepares an MIC for boot and initiates boot. - * RETURNS: An appropriate -ERRNO error value on error, or zero for success. - * - * For all cosm_hw_ops the caller holds a mutex to ensure serialization. - */ -static int _mic_start(struct cosm_device *cdev, int id) -{ - struct mic_device *mdev = cosmdev_to_mdev(cdev); - int rc; - - mic_bootparam_init(mdev); - mdev->dma_mbdev = mbus_register_device(&mdev->pdev->dev, - MBUS_DEV_DMA_HOST, &mic_dma_ops, - &mbus_hw_ops, id, mdev->mmio.va); - if (IS_ERR(mdev->dma_mbdev)) { - rc = PTR_ERR(mdev->dma_mbdev); - goto unlock_ret; - } - if (!mic_request_dma_chans(mdev)) { - rc = -ENODEV; - goto dma_remove; - } - mdev->scdev = scif_register_device(&mdev->pdev->dev, MIC_SCIF_DEV, - &__mic_dma_ops, &scif_hw_ops, - id + 1, 0, &mdev->mmio, - &mdev->aper, mdev->dp, NULL, - mdev->dma_ch, mdev->num_dma_ch, - true); - if (IS_ERR(mdev->scdev)) { - rc = PTR_ERR(mdev->scdev); - goto dma_free; - } - - mdev->vpdev = vop_register_device(&mdev->pdev->dev, - VOP_DEV_TRNSP, &_mic_dma_ops, - &vop_hw_ops, id + 1, &mdev->aper, - mdev->dma_ch[0]); - if (IS_ERR(mdev->vpdev)) { - rc = PTR_ERR(mdev->vpdev); - goto scif_remove; - } - - rc = mdev->ops->load_mic_fw(mdev, NULL); - if (rc) - goto vop_remove; - mic_smpt_restore(mdev); - mic_intr_restore(mdev); - mdev->intr_ops->enable_interrupts(mdev); - mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr); - mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32); - mdev->ops->send_firmware_intr(mdev); - goto unlock_ret; -vop_remove: - vop_unregister_device(mdev->vpdev); -scif_remove: - scif_unregister_device(mdev->scdev); -dma_free: - mic_free_dma_chans(mdev); -dma_remove: - mbus_unregister_device(mdev->dma_mbdev); -unlock_ret: - return rc; -} - -/** - * _mic_stop - Prepare the MIC for reset and trigger reset. - * @cdev: pointer to cosm_device instance - * @force: force a MIC to reset even if it is already offline. - * - * RETURNS: None. - */ -static void _mic_stop(struct cosm_device *cdev, bool force) -{ - struct mic_device *mdev = cosmdev_to_mdev(cdev); - - /* - * Since SCIF handles card shutdown and reset (using COSM), it will - * will be the first to be registered and the last to be - * unregistered. - */ - vop_unregister_device(mdev->vpdev); - scif_unregister_device(mdev->scdev); - mic_free_dma_chans(mdev); - mbus_unregister_device(mdev->dma_mbdev); - mic_bootparam_init(mdev); -} - -static ssize_t _mic_family(struct cosm_device *cdev, char *buf) -{ - struct mic_device *mdev = cosmdev_to_mdev(cdev); - static const char *family[MIC_FAMILY_LAST] = { "x100", "Unknown" }; - - return scnprintf(buf, PAGE_SIZE, "%s\n", family[mdev->family]); -} - -static ssize_t _mic_stepping(struct cosm_device *cdev, char *buf) -{ - struct mic_device *mdev = cosmdev_to_mdev(cdev); - const char *string = "??"; - - switch (mdev->stepping) { - case MIC_A0_STEP: - string = "A0"; - break; - case MIC_B0_STEP: - string = "B0"; - break; - case MIC_B1_STEP: - string = "B1"; - break; - case MIC_C0_STEP: - string = "C0"; - break; - default: - break; - } - return scnprintf(buf, PAGE_SIZE, "%s\n", string); -} - -static struct mic_mw *_mic_aper(struct cosm_device *cdev) -{ - struct mic_device *mdev = cosmdev_to_mdev(cdev); - - return &mdev->aper; -} - -struct cosm_hw_ops cosm_hw_ops = { - .reset = _mic_reset, - .force_reset = _mic_reset, - .post_reset = NULL, - .ready = _mic_ready, - .start = _mic_start, - .stop = _mic_stop, - .family = _mic_family, - .stepping = _mic_stepping, - .aper = _mic_aper, -}; diff --git a/drivers/misc/mic/host/mic_debugfs.c b/drivers/misc/mic/host/mic_debugfs.c deleted file mode 100644 index ffda740e20d5..000000000000 --- a/drivers/misc/mic/host/mic_debugfs.c +++ /dev/null @@ -1,149 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Intel MIC Host driver. - */ -#include <linux/debugfs.h> -#include <linux/pci.h> -#include <linux/seq_file.h> - -#include <linux/mic_common.h> -#include "../common/mic_dev.h" -#include "mic_device.h" -#include "mic_smpt.h" - -/* Debugfs parent dir */ -static struct dentry *mic_dbg; - -static int mic_smpt_show(struct seq_file *s, void *pos) -{ - int i; - struct mic_device *mdev = s->private; - unsigned long flags; - - seq_printf(s, "MIC %-2d |%-10s| %-14s %-10s\n", - mdev->id, "SMPT entry", "SW DMA addr", "RefCount"); - seq_puts(s, "====================================================\n"); - - if (mdev->smpt) { - struct mic_smpt_info *smpt_info = mdev->smpt; - spin_lock_irqsave(&smpt_info->smpt_lock, flags); - for (i = 0; i < smpt_info->info.num_reg; i++) { - seq_printf(s, "%9s|%-10d| %-#14llx %-10lld\n", - " ", i, smpt_info->entry[i].dma_addr, - smpt_info->entry[i].ref_count); - } - spin_unlock_irqrestore(&smpt_info->smpt_lock, flags); - } - seq_puts(s, "====================================================\n"); - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(mic_smpt); - -static int mic_post_code_show(struct seq_file *s, void *pos) -{ - struct mic_device *mdev = s->private; - u32 reg = mdev->ops->get_postcode(mdev); - - seq_printf(s, "%c%c", reg & 0xff, (reg >> 8) & 0xff); - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(mic_post_code); - -static int mic_msi_irq_info_show(struct seq_file *s, void *pos) -{ - struct mic_device *mdev = s->private; - int reg; - int i, j; - u16 entry; - u16 vector; - struct pci_dev *pdev = mdev->pdev; - - if (pci_dev_msi_enabled(pdev)) { - for (i = 0; i < mdev->irq_info.num_vectors; i++) { - if (pdev->msix_enabled) { - entry = mdev->irq_info.msix_entries[i].entry; - vector = mdev->irq_info.msix_entries[i].vector; - } else { - entry = 0; - vector = pdev->irq; - } - - reg = mdev->intr_ops->read_msi_to_src_map(mdev, entry); - - seq_printf(s, "%s %-10d %s %-10d MXAR[%d]: %08X\n", - "IRQ:", vector, "Entry:", entry, i, reg); - - seq_printf(s, "%-10s", "offset:"); - for (j = (MIC_NUM_OFFSETS - 1); j >= 0; j--) - seq_printf(s, "%4d ", j); - seq_puts(s, "\n"); - - - seq_printf(s, "%-10s", "count:"); - for (j = (MIC_NUM_OFFSETS - 1); j >= 0; j--) - seq_printf(s, "%4d ", - (mdev->irq_info.mic_msi_map[i] & - BIT(j)) ? 1 : 0); - seq_puts(s, "\n\n"); - } - } else { - seq_puts(s, "MSI/MSIx interrupts not enabled\n"); - } - - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(mic_msi_irq_info); - -/* - * mic_create_debug_dir - Initialize MIC debugfs entries. - */ -void mic_create_debug_dir(struct mic_device *mdev) -{ - char name[16]; - - if (!mic_dbg) - return; - - scnprintf(name, sizeof(name), "mic%d", mdev->id); - mdev->dbg_dir = debugfs_create_dir(name, mic_dbg); - - debugfs_create_file("smpt", 0444, mdev->dbg_dir, mdev, - &mic_smpt_fops); - - debugfs_create_file("post_code", 0444, mdev->dbg_dir, mdev, - &mic_post_code_fops); - - debugfs_create_file("msi_irq_info", 0444, mdev->dbg_dir, mdev, - &mic_msi_irq_info_fops); -} - -/* - * mic_delete_debug_dir - Uninitialize MIC debugfs entries. - */ -void mic_delete_debug_dir(struct mic_device *mdev) -{ - debugfs_remove_recursive(mdev->dbg_dir); -} - -/* - * mic_init_debugfs - Initialize global debugfs entry. - */ -void __init mic_init_debugfs(void) -{ - mic_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); -} - -/* - * mic_exit_debugfs - Uninitialize global debugfs entry - */ -void mic_exit_debugfs(void) -{ - debugfs_remove(mic_dbg); -} diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h deleted file mode 100644 index 41bcd308ae59..000000000000 --- a/drivers/misc/mic/host/mic_device.h +++ /dev/null @@ -1,157 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Intel MIC Host driver. - */ -#ifndef _MIC_DEVICE_H_ -#define _MIC_DEVICE_H_ - -#include <linux/cdev.h> -#include <linux/idr.h> -#include <linux/notifier.h> -#include <linux/irqreturn.h> -#include <linux/dmaengine.h> -#include <linux/miscdevice.h> -#include <linux/mic_bus.h> -#include "../bus/scif_bus.h" -#include "../bus/vop_bus.h" -#include "../bus/cosm_bus.h" -#include "mic_intr.h" - -/** - * enum mic_stepping - MIC stepping ids. - */ -enum mic_stepping { - MIC_A0_STEP = 0x0, - MIC_B0_STEP = 0x10, - MIC_B1_STEP = 0x11, - MIC_C0_STEP = 0x20, -}; - -extern struct cosm_hw_ops cosm_hw_ops; - -/** - * struct mic_device - MIC device information for each card. - * - * @mmio: MMIO bar information. - * @aper: Aperture bar information. - * @family: The MIC family to which this device belongs. - * @ops: MIC HW specific operations. - * @id: The unique device id for this MIC device. - * @stepping: Stepping ID. - * @pdev: Underlying PCI device. - * @mic_mutex: Mutex for synchronizing access to mic_device. - * @intr_ops: HW specific interrupt operations. - * @smpt_ops: Hardware specific SMPT operations. - * @smpt: MIC SMPT information. - * @intr_info: H/W specific interrupt information. - * @irq_info: The OS specific irq information - * @dbg_dir: debugfs directory of this MIC device. - * @bootaddr: MIC boot address. - * @dp: virtio device page - * @dp_dma_addr: virtio device page DMA address. - * @dma_mbdev: MIC BUS DMA device. - * @dma_ch - Array of DMA channels - * @num_dma_ch - Number of DMA channels available - * @scdev: SCIF device on the SCIF virtual bus. - * @vpdev: Virtio over PCIe device on the VOP virtual bus. - * @cosm_dev: COSM device - */ -struct mic_device { - struct mic_mw mmio; - struct mic_mw aper; - enum mic_hw_family family; - struct mic_hw_ops *ops; - int id; - enum mic_stepping stepping; - struct pci_dev *pdev; - struct mutex mic_mutex; - struct mic_hw_intr_ops *intr_ops; - struct mic_smpt_ops *smpt_ops; - struct mic_smpt_info *smpt; - struct mic_intr_info *intr_info; - struct mic_irq_info irq_info; - struct dentry *dbg_dir; - u32 bootaddr; - void *dp; - dma_addr_t dp_dma_addr; - struct mbus_device *dma_mbdev; - struct dma_chan *dma_ch[MIC_MAX_DMA_CHAN]; - int num_dma_ch; - struct scif_hw_dev *scdev; - struct vop_device *vpdev; - struct cosm_device *cosm_dev; -}; - -/** - * struct mic_hw_ops - MIC HW specific operations. - * @aper_bar: Aperture bar resource number. - * @mmio_bar: MMIO bar resource number. - * @read_spad: Read from scratch pad register. - * @write_spad: Write to scratch pad register. - * @send_intr: Send an interrupt for a particular doorbell on the card. - * @ack_interrupt: Hardware specific operations to ack the h/w on - * receipt of an interrupt. - * @intr_workarounds: Hardware specific workarounds needed after - * handling an interrupt. - * @reset: Reset the remote processor. - * @reset_fw_ready: Reset firmware ready field. - * @is_fw_ready: Check if firmware is ready for OS download. - * @send_firmware_intr: Send an interrupt to the card firmware. - * @load_mic_fw: Load firmware segments required to boot the card - * into card memory. This includes the kernel, command line, ramdisk etc. - * @get_postcode: Get post code status from firmware. - * @dma_filter: DMA filter function to be used. - */ -struct mic_hw_ops { - u8 aper_bar; - u8 mmio_bar; - u32 (*read_spad)(struct mic_device *mdev, unsigned int idx); - void (*write_spad)(struct mic_device *mdev, unsigned int idx, u32 val); - void (*send_intr)(struct mic_device *mdev, int doorbell); - u32 (*ack_interrupt)(struct mic_device *mdev); - void (*intr_workarounds)(struct mic_device *mdev); - void (*reset)(struct mic_device *mdev); - void (*reset_fw_ready)(struct mic_device *mdev); - bool (*is_fw_ready)(struct mic_device *mdev); - void (*send_firmware_intr)(struct mic_device *mdev); - int (*load_mic_fw)(struct mic_device *mdev, const char *buf); - u32 (*get_postcode)(struct mic_device *mdev); - bool (*dma_filter)(struct dma_chan *chan, void *param); -}; - -/** - * mic_mmio_read - read from an MMIO register. - * @mw: MMIO register base virtual address. - * @offset: register offset. - * - * RETURNS: register value. - */ -static inline u32 mic_mmio_read(struct mic_mw *mw, u32 offset) -{ - return ioread32(mw->va + offset); -} - -/** - * mic_mmio_write - write to an MMIO register. - * @mw: MMIO register base virtual address. - * @val: the data value to put into the register - * @offset: register offset. - * - * RETURNS: none. - */ -static inline void -mic_mmio_write(struct mic_mw *mw, u32 val, u32 offset) -{ - iowrite32(val, mw->va + offset); -} - -void mic_bootparam_init(struct mic_device *mdev); -void mic_create_debug_dir(struct mic_device *dev); -void mic_delete_debug_dir(struct mic_device *dev); -void __init mic_init_debugfs(void); -void mic_exit_debugfs(void); -#endif diff --git a/drivers/misc/mic/host/mic_intr.c b/drivers/misc/mic/host/mic_intr.c deleted file mode 100644 index 85b3221b5d40..000000000000 --- a/drivers/misc/mic/host/mic_intr.c +++ /dev/null @@ -1,635 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Intel MIC Host driver. - */ -#include <linux/pci.h> -#include <linux/interrupt.h> - -#include "../common/mic_dev.h" -#include "mic_device.h" - -static irqreturn_t mic_thread_fn(int irq, void *dev) -{ - struct mic_device *mdev = dev; - struct mic_intr_info *intr_info = mdev->intr_info; - struct mic_irq_info *irq_info = &mdev->irq_info; - struct mic_intr_cb *intr_cb; - struct pci_dev *pdev = mdev->pdev; - int i; - - spin_lock(&irq_info->mic_thread_lock); - for (i = intr_info->intr_start_idx[MIC_INTR_DB]; - i < intr_info->intr_len[MIC_INTR_DB]; i++) - if (test_and_clear_bit(i, &irq_info->mask)) { - list_for_each_entry(intr_cb, &irq_info->cb_list[i], - list) - if (intr_cb->thread_fn) - intr_cb->thread_fn(pdev->irq, - intr_cb->data); - } - spin_unlock(&irq_info->mic_thread_lock); - return IRQ_HANDLED; -} -/** - * mic_interrupt - Generic interrupt handler for - * MSI and INTx based interrupts. - * @irq: interrupt to handle (unused) - * @dev: pointer to the mic_device instance - */ -static irqreturn_t mic_interrupt(int irq, void *dev) -{ - struct mic_device *mdev = dev; - struct mic_intr_info *intr_info = mdev->intr_info; - struct mic_irq_info *irq_info = &mdev->irq_info; - struct mic_intr_cb *intr_cb; - struct pci_dev *pdev = mdev->pdev; - u32 mask; - int i; - - mask = mdev->ops->ack_interrupt(mdev); - if (!mask) - return IRQ_NONE; - - spin_lock(&irq_info->mic_intr_lock); - for (i = intr_info->intr_start_idx[MIC_INTR_DB]; - i < intr_info->intr_len[MIC_INTR_DB]; i++) - if (mask & BIT(i)) { - list_for_each_entry(intr_cb, &irq_info->cb_list[i], - list) - if (intr_cb->handler) - intr_cb->handler(pdev->irq, - intr_cb->data); - set_bit(i, &irq_info->mask); - } - spin_unlock(&irq_info->mic_intr_lock); - return IRQ_WAKE_THREAD; -} - -/* Return the interrupt offset from the index. Index is 0 based. */ -static u16 mic_map_src_to_offset(struct mic_device *mdev, - int intr_src, enum mic_intr_type type) -{ - if (type >= MIC_NUM_INTR_TYPES) - return MIC_NUM_OFFSETS; - if (intr_src >= mdev->intr_info->intr_len[type]) - return MIC_NUM_OFFSETS; - - return mdev->intr_info->intr_start_idx[type] + intr_src; -} - -/* Return next available msix_entry. */ -static struct msix_entry *mic_get_available_vector(struct mic_device *mdev) -{ - int i; - struct mic_irq_info *info = &mdev->irq_info; - - for (i = 0; i < info->num_vectors; i++) - if (!info->mic_msi_map[i]) - return &info->msix_entries[i]; - return NULL; -} - -/** - * mic_register_intr_callback - Register a callback handler for the - * given source id. - * - * @mdev: pointer to the mic_device instance - * @idx: The source id to be registered. - * @handler: The function to be called when the source id receives - * the interrupt. - * @thread_fn: thread fn. corresponding to the handler - * @data: Private data of the requester. - * Return the callback structure that was registered or an - * appropriate error on failure. - */ -static struct mic_intr_cb *mic_register_intr_callback(struct mic_device *mdev, - u8 idx, irq_handler_t handler, irq_handler_t thread_fn, - void *data) -{ - struct mic_intr_cb *intr_cb; - unsigned long flags; - int rc; - intr_cb = kmalloc(sizeof(*intr_cb), GFP_KERNEL); - - if (!intr_cb) - return ERR_PTR(-ENOMEM); - - intr_cb->handler = handler; - intr_cb->thread_fn = thread_fn; - intr_cb->data = data; - intr_cb->cb_id = ida_simple_get(&mdev->irq_info.cb_ida, - 0, 0, GFP_KERNEL); - if (intr_cb->cb_id < 0) { - rc = intr_cb->cb_id; - goto ida_fail; - } - - spin_lock(&mdev->irq_info.mic_thread_lock); - spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags); - list_add_tail(&intr_cb->list, &mdev->irq_info.cb_list[idx]); - spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags); - spin_unlock(&mdev->irq_info.mic_thread_lock); - - return intr_cb; -ida_fail: - kfree(intr_cb); - return ERR_PTR(rc); -} - -/** - * mic_unregister_intr_callback - Unregister the callback handler - * identified by its callback id. - * - * @mdev: pointer to the mic_device instance - * @idx: The callback structure id to be unregistered. - * Return the source id that was unregistered or MIC_NUM_OFFSETS if no - * such callback handler was found. - */ -static u8 mic_unregister_intr_callback(struct mic_device *mdev, u32 idx) -{ - struct list_head *pos, *tmp; - struct mic_intr_cb *intr_cb; - unsigned long flags; - int i; - - spin_lock(&mdev->irq_info.mic_thread_lock); - spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags); - for (i = 0; i < MIC_NUM_OFFSETS; i++) { - list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) { - intr_cb = list_entry(pos, struct mic_intr_cb, list); - if (intr_cb->cb_id == idx) { - list_del(pos); - ida_simple_remove(&mdev->irq_info.cb_ida, - intr_cb->cb_id); - kfree(intr_cb); - spin_unlock_irqrestore( - &mdev->irq_info.mic_intr_lock, flags); - spin_unlock(&mdev->irq_info.mic_thread_lock); - return i; - } - } - } - spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags); - spin_unlock(&mdev->irq_info.mic_thread_lock); - return MIC_NUM_OFFSETS; -} - -/** - * mic_setup_msix - Initializes MSIx interrupts. - * - * @mdev: pointer to mic_device instance - * @pdev: PCI device structure - * - * RETURNS: An appropriate -ERRNO error value on error, or zero for success. - */ -static int mic_setup_msix(struct mic_device *mdev, struct pci_dev *pdev) -{ - int rc, i; - int entry_size = sizeof(*mdev->irq_info.msix_entries); - - mdev->irq_info.msix_entries = kmalloc_array(MIC_MIN_MSIX, - entry_size, GFP_KERNEL); - if (!mdev->irq_info.msix_entries) { - rc = -ENOMEM; - goto err_nomem1; - } - - for (i = 0; i < MIC_MIN_MSIX; i++) - mdev->irq_info.msix_entries[i].entry = i; - - rc = pci_enable_msix_exact(pdev, mdev->irq_info.msix_entries, - MIC_MIN_MSIX); - if (rc) { - dev_dbg(&pdev->dev, "Error enabling MSIx. rc = %d\n", rc); - goto err_enable_msix; - } - - mdev->irq_info.num_vectors = MIC_MIN_MSIX; - mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) * - mdev->irq_info.num_vectors), GFP_KERNEL); - - if (!mdev->irq_info.mic_msi_map) { - rc = -ENOMEM; - goto err_nomem2; - } - - dev_dbg(&mdev->pdev->dev, - "%d MSIx irqs setup\n", mdev->irq_info.num_vectors); - return 0; -err_nomem2: - pci_disable_msix(pdev); -err_enable_msix: - kfree(mdev->irq_info.msix_entries); -err_nomem1: - mdev->irq_info.num_vectors = 0; - return rc; -} - -/** - * mic_setup_callbacks - Initialize data structures needed - * to handle callbacks. - * - * @mdev: pointer to mic_device instance - */ -static int mic_setup_callbacks(struct mic_device *mdev) -{ - int i; - - mdev->irq_info.cb_list = kmalloc_array(MIC_NUM_OFFSETS, - sizeof(*mdev->irq_info.cb_list), - GFP_KERNEL); - if (!mdev->irq_info.cb_list) - return -ENOMEM; - - for (i = 0; i < MIC_NUM_OFFSETS; i++) - INIT_LIST_HEAD(&mdev->irq_info.cb_list[i]); - ida_init(&mdev->irq_info.cb_ida); - spin_lock_init(&mdev->irq_info.mic_intr_lock); - spin_lock_init(&mdev->irq_info.mic_thread_lock); - return 0; -} - -/** - * mic_release_callbacks - Uninitialize data structures needed - * to handle callbacks. - * - * @mdev: pointer to mic_device instance - */ -static void mic_release_callbacks(struct mic_device *mdev) -{ - unsigned long flags; - struct list_head *pos, *tmp; - struct mic_intr_cb *intr_cb; - int i; - - spin_lock(&mdev->irq_info.mic_thread_lock); - spin_lock_irqsave(&mdev->irq_info.mic_intr_lock, flags); - for (i = 0; i < MIC_NUM_OFFSETS; i++) { - if (list_empty(&mdev->irq_info.cb_list[i])) - break; - - list_for_each_safe(pos, tmp, &mdev->irq_info.cb_list[i]) { - intr_cb = list_entry(pos, struct mic_intr_cb, list); - list_del(pos); - ida_simple_remove(&mdev->irq_info.cb_ida, - intr_cb->cb_id); - kfree(intr_cb); - } - } - spin_unlock_irqrestore(&mdev->irq_info.mic_intr_lock, flags); - spin_unlock(&mdev->irq_info.mic_thread_lock); - ida_destroy(&mdev->irq_info.cb_ida); - kfree(mdev->irq_info.cb_list); -} - -/** - * mic_setup_msi - Initializes MSI interrupts. - * - * @mdev: pointer to mic_device instance - * @pdev: PCI device structure - * - * RETURNS: An appropriate -ERRNO error value on error, or zero for success. - */ -static int mic_setup_msi(struct mic_device *mdev, struct pci_dev *pdev) -{ - int rc; - - rc = pci_enable_msi(pdev); - if (rc) { - dev_dbg(&pdev->dev, "Error enabling MSI. rc = %d\n", rc); - return rc; - } - - mdev->irq_info.num_vectors = 1; - mdev->irq_info.mic_msi_map = kzalloc((sizeof(u32) * - mdev->irq_info.num_vectors), GFP_KERNEL); - - if (!mdev->irq_info.mic_msi_map) { - rc = -ENOMEM; - goto err_nomem1; - } - - rc = mic_setup_callbacks(mdev); - if (rc) { - dev_err(&pdev->dev, "Error setting up callbacks\n"); - goto err_nomem2; - } - - rc = request_threaded_irq(pdev->irq, mic_interrupt, mic_thread_fn, - 0, "mic-msi", mdev); - if (rc) { - dev_err(&pdev->dev, "Error allocating MSI interrupt\n"); - goto err_irq_req_fail; - } - - dev_dbg(&pdev->dev, "%d MSI irqs setup\n", mdev->irq_info.num_vectors); - return 0; -err_irq_req_fail: - mic_release_callbacks(mdev); -err_nomem2: - kfree(mdev->irq_info.mic_msi_map); -err_nomem1: - pci_disable_msi(pdev); - mdev->irq_info.num_vectors = 0; - return rc; -} - -/** - * mic_setup_intx - Initializes legacy interrupts. - * - * @mdev: pointer to mic_device instance - * @pdev: PCI device structure - * - * RETURNS: An appropriate -ERRNO error value on error, or zero for success. - */ -static int mic_setup_intx(struct mic_device *mdev, struct pci_dev *pdev) -{ - int rc; - - /* Enable intx */ - pci_intx(pdev, 1); - rc = mic_setup_callbacks(mdev); - if (rc) { - dev_err(&pdev->dev, "Error setting up callbacks\n"); - goto err_nomem; - } - - rc = request_threaded_irq(pdev->irq, mic_interrupt, mic_thread_fn, - IRQF_SHARED, "mic-intx", mdev); - if (rc) - goto err; - - dev_dbg(&pdev->dev, "intx irq setup\n"); - return 0; -err: - mic_release_callbacks(mdev); -err_nomem: - return rc; -} - -/** - * mic_next_db - Retrieve the next doorbell interrupt source id. - * The id is picked sequentially from the available pool of - * doorlbell ids. - * - * @mdev: pointer to the mic_device instance. - * - * Returns the next doorbell interrupt source. - */ -int mic_next_db(struct mic_device *mdev) -{ - int next_db; - - next_db = mdev->irq_info.next_avail_src % - mdev->intr_info->intr_len[MIC_INTR_DB]; - mdev->irq_info.next_avail_src++; - return next_db; -} - -#define COOKIE_ID_SHIFT 16 -#define GET_ENTRY(cookie) ((cookie) & 0xFFFF) -#define GET_OFFSET(cookie) ((cookie) >> COOKIE_ID_SHIFT) -#define MK_COOKIE(x, y) ((x) | (y) << COOKIE_ID_SHIFT) - -/** - * mic_request_threaded_irq - request an irq. mic_mutex needs - * to be held before calling this function. - * - * @mdev: pointer to mic_device instance - * @handler: The callback function that handles the interrupt. - * The function needs to call ack_interrupts - * (mdev->ops->ack_interrupt(mdev)) when handling the interrupts. - * @thread_fn: thread fn required by request_threaded_irq. - * @name: The ASCII name of the callee requesting the irq. - * @data: private data that is returned back when calling the - * function handler. - * @intr_src: The source id of the requester. Its the doorbell id - * for Doorbell interrupts and DMA channel id for DMA interrupts. - * @type: The type of interrupt. Values defined in mic_intr_type - * - * returns: The cookie that is transparent to the caller. Passed - * back when calling mic_free_irq. An appropriate error code - * is returned on failure. Caller needs to use IS_ERR(return_val) - * to check for failure and PTR_ERR(return_val) to obtained the - * error code. - * - */ -struct mic_irq * -mic_request_threaded_irq(struct mic_device *mdev, - irq_handler_t handler, irq_handler_t thread_fn, - const char *name, void *data, int intr_src, - enum mic_intr_type type) -{ - u16 offset; - int rc = 0; - struct msix_entry *msix = NULL; - unsigned long cookie = 0; - u16 entry; - struct mic_intr_cb *intr_cb; - struct pci_dev *pdev = mdev->pdev; - - offset = mic_map_src_to_offset(mdev, intr_src, type); - if (offset >= MIC_NUM_OFFSETS) { - dev_err(&mdev->pdev->dev, - "Error mapping index %d to a valid source id.\n", - intr_src); - rc = -EINVAL; - goto err; - } - - if (mdev->irq_info.num_vectors > 1) { - msix = mic_get_available_vector(mdev); - if (!msix) { - dev_err(&mdev->pdev->dev, - "No MSIx vectors available for use.\n"); - rc = -ENOSPC; - goto err; - } - - rc = request_threaded_irq(msix->vector, handler, thread_fn, - 0, name, data); - if (rc) { - dev_dbg(&mdev->pdev->dev, - "request irq failed rc = %d\n", rc); - goto err; - } - entry = msix->entry; - mdev->irq_info.mic_msi_map[entry] |= BIT(offset); - mdev->intr_ops->program_msi_to_src_map(mdev, - entry, offset, true); - cookie = MK_COOKIE(entry, offset); - dev_dbg(&mdev->pdev->dev, "irq: %d assigned for src: %d\n", - msix->vector, intr_src); - } else { - intr_cb = mic_register_intr_callback(mdev, offset, handler, - thread_fn, data); - if (IS_ERR(intr_cb)) { - dev_err(&mdev->pdev->dev, - "No available callback entries for use\n"); - rc = PTR_ERR(intr_cb); - goto err; - } - - entry = 0; - if (pci_dev_msi_enabled(pdev)) { - mdev->irq_info.mic_msi_map[entry] |= (1 << offset); - mdev->intr_ops->program_msi_to_src_map(mdev, - entry, offset, true); - } - cookie = MK_COOKIE(entry, intr_cb->cb_id); - dev_dbg(&mdev->pdev->dev, "callback %d registered for src: %d\n", - intr_cb->cb_id, intr_src); - } - return (struct mic_irq *)cookie; -err: - return ERR_PTR(rc); -} - -/** - * mic_free_irq - free irq. mic_mutex - * needs to be held before calling this function. - * - * @mdev: pointer to mic_device instance - * @cookie: cookie obtained during a successful call to mic_request_threaded_irq - * @data: private data specified by the calling function during the - * mic_request_threaded_irq - * - * returns: none. - */ -void mic_free_irq(struct mic_device *mdev, - struct mic_irq *cookie, void *data) -{ - u32 offset; - u32 entry; - u8 src_id; - unsigned int irq; - struct pci_dev *pdev = mdev->pdev; - - entry = GET_ENTRY((unsigned long)cookie); - offset = GET_OFFSET((unsigned long)cookie); - if (mdev->irq_info.num_vectors > 1) { - if (entry >= mdev->irq_info.num_vectors) { - dev_warn(&mdev->pdev->dev, - "entry %d should be < num_irq %d\n", - entry, mdev->irq_info.num_vectors); - return; - } - irq = mdev->irq_info.msix_entries[entry].vector; - free_irq(irq, data); - mdev->irq_info.mic_msi_map[entry] &= ~(BIT(offset)); - mdev->intr_ops->program_msi_to_src_map(mdev, - entry, offset, false); - - dev_dbg(&mdev->pdev->dev, "irq: %d freed\n", irq); - } else { - irq = pdev->irq; - src_id = mic_unregister_intr_callback(mdev, offset); - if (src_id >= MIC_NUM_OFFSETS) { - dev_warn(&mdev->pdev->dev, "Error unregistering callback\n"); - return; - } - if (pci_dev_msi_enabled(pdev)) { - mdev->irq_info.mic_msi_map[entry] &= ~(BIT(src_id)); - mdev->intr_ops->program_msi_to_src_map(mdev, - entry, src_id, false); - } - dev_dbg(&mdev->pdev->dev, "callback %d unregistered for src: %d\n", - offset, src_id); - } -} - -/** - * mic_setup_interrupts - Initializes interrupts. - * - * @mdev: pointer to mic_device instance - * @pdev: PCI device structure - * - * RETURNS: An appropriate -ERRNO error value on error, or zero for success. - */ -int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev) -{ - int rc; - - rc = mic_setup_msix(mdev, pdev); - if (!rc) - goto done; - - rc = mic_setup_msi(mdev, pdev); - if (!rc) - goto done; - - rc = mic_setup_intx(mdev, pdev); - if (rc) { - dev_err(&mdev->pdev->dev, "no usable interrupts\n"); - return rc; - } -done: - mdev->intr_ops->enable_interrupts(mdev); - return 0; -} - -/** - * mic_free_interrupts - Frees interrupts setup by mic_setup_interrupts - * - * @mdev: pointer to mic_device instance - * @pdev: PCI device structure - * - * returns none. - */ -void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev) -{ - int i; - - mdev->intr_ops->disable_interrupts(mdev); - if (mdev->irq_info.num_vectors > 1) { - for (i = 0; i < mdev->irq_info.num_vectors; i++) { - if (mdev->irq_info.mic_msi_map[i]) - dev_warn(&pdev->dev, "irq %d may still be in use.\n", - mdev->irq_info.msix_entries[i].vector); - } - kfree(mdev->irq_info.mic_msi_map); - kfree(mdev->irq_info.msix_entries); - pci_disable_msix(pdev); - } else { - if (pci_dev_msi_enabled(pdev)) { - free_irq(pdev->irq, mdev); - kfree(mdev->irq_info.mic_msi_map); - pci_disable_msi(pdev); - } else { - free_irq(pdev->irq, mdev); - } - mic_release_callbacks(mdev); - } -} - -/** - * mic_intr_restore - Restore MIC interrupt registers. - * - * @mdev: pointer to mic_device instance. - * - * Restore the interrupt registers to values previously - * stored in the SW data structures. mic_mutex needs to - * be held before calling this function. - * - * returns None. - */ -void mic_intr_restore(struct mic_device *mdev) -{ - int entry, offset; - struct pci_dev *pdev = mdev->pdev; - - if (!pci_dev_msi_enabled(pdev)) - return; - - for (entry = 0; entry < mdev->irq_info.num_vectors; entry++) { - for (offset = 0; offset < MIC_NUM_OFFSETS; offset++) { - if (mdev->irq_info.mic_msi_map[entry] & BIT(offset)) - mdev->intr_ops->program_msi_to_src_map(mdev, - entry, offset, true); - } - } -} diff --git a/drivers/misc/mic/host/mic_intr.h b/drivers/misc/mic/host/mic_intr.h deleted file mode 100644 index b14ba818006f..000000000000 --- a/drivers/misc/mic/host/mic_intr.h +++ /dev/null @@ -1,137 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Intel MIC Host driver. - */ -#ifndef _MIC_INTR_H_ -#define _MIC_INTR_H_ - -#include <linux/bitops.h> -#include <linux/interrupt.h> -/* - * The minimum number of msix vectors required for normal operation. - * 3 for virtio network, console and block devices. - * 1 for card shutdown notifications. - * 4 for host owned DMA channels. - * 1 for SCIF - */ -#define MIC_MIN_MSIX 9 -#define MIC_NUM_OFFSETS 32 - -/** - * mic_intr_source - The type of source that will generate - * the interrupt.The number of types needs to be in sync with - * MIC_NUM_INTR_TYPES - * - * MIC_INTR_DB: The source is a doorbell - * MIC_INTR_DMA: The source is a DMA channel - * MIC_INTR_ERR: The source is an error interrupt e.g. SBOX ERR - * MIC_NUM_INTR_TYPES: Total number of interrupt sources. - */ -enum mic_intr_type { - MIC_INTR_DB = 0, - MIC_INTR_DMA, - MIC_INTR_ERR, - MIC_NUM_INTR_TYPES -}; - -/** - * struct mic_intr_info - Contains h/w specific interrupt sources - * information. - * - * @intr_start_idx: Contains the starting indexes of the - * interrupt types. - * @intr_len: Contains the length of the interrupt types. - */ -struct mic_intr_info { - u16 intr_start_idx[MIC_NUM_INTR_TYPES]; - u16 intr_len[MIC_NUM_INTR_TYPES]; -}; - -/** - * struct mic_irq_info - OS specific irq information - * - * @next_avail_src: next available doorbell that can be assigned. - * @msix_entries: msix entries allocated while setting up MSI-x - * @mic_msi_map: The MSI/MSI-x mapping information. - * @num_vectors: The number of MSI/MSI-x vectors that have been allocated. - * @cb_ida: callback ID allocator to track the callbacks registered. - * @mic_intr_lock: spinlock to protect the interrupt callback list. - * @mic_thread_lock: spinlock to protect the thread callback list. - * This lock is used to protect against thread_fn while - * mic_intr_lock is used to protect against interrupt handler. - * @cb_list: Array of callback lists one for each source. - * @mask: Mask used by the main thread fn to call the underlying thread fns. - */ -struct mic_irq_info { - int next_avail_src; - struct msix_entry *msix_entries; - u32 *mic_msi_map; - u16 num_vectors; - struct ida cb_ida; - spinlock_t mic_intr_lock; - spinlock_t mic_thread_lock; - struct list_head *cb_list; - unsigned long mask; -}; - -/** - * struct mic_intr_cb - Interrupt callback structure. - * - * @handler: The callback function - * @thread_fn: The thread_fn. - * @data: Private data of the requester. - * @cb_id: The callback id. Identifies this callback. - * @list: list head pointing to the next callback structure. - */ -struct mic_intr_cb { - irq_handler_t handler; - irq_handler_t thread_fn; - void *data; - int cb_id; - struct list_head list; -}; - -/** - * struct mic_irq - opaque pointer used as cookie - */ -struct mic_irq; - -/* Forward declaration */ -struct mic_device; - -/** - * struct mic_hw_intr_ops: MIC HW specific interrupt operations - * @intr_init: Initialize H/W specific interrupt information. - * @enable_interrupts: Enable interrupts from the hardware. - * @disable_interrupts: Disable interrupts from the hardware. - * @program_msi_to_src_map: Update MSI mapping registers with - * irq information. - * @read_msi_to_src_map: Read MSI mapping registers containing - * irq information. - */ -struct mic_hw_intr_ops { - void (*intr_init)(struct mic_device *mdev); - void (*enable_interrupts)(struct mic_device *mdev); - void (*disable_interrupts)(struct mic_device *mdev); - void (*program_msi_to_src_map) (struct mic_device *mdev, - int idx, int intr_src, bool set); - u32 (*read_msi_to_src_map) (struct mic_device *mdev, - int idx); -}; - -int mic_next_db(struct mic_device *mdev); -struct mic_irq * -mic_request_threaded_irq(struct mic_device *mdev, - irq_handler_t handler, irq_handler_t thread_fn, - const char *name, void *data, int intr_src, - enum mic_intr_type type); -void mic_free_irq(struct mic_device *mdev, - struct mic_irq *cookie, void *data); -int mic_setup_interrupts(struct mic_device *mdev, struct pci_dev *pdev); -void mic_free_interrupts(struct mic_device *mdev, struct pci_dev *pdev); -void mic_intr_restore(struct mic_device *mdev); -#endif diff --git a/drivers/misc/mic/host/mic_main.c b/drivers/misc/mic/host/mic_main.c deleted file mode 100644 index ea4608527ea0..000000000000 --- a/drivers/misc/mic/host/mic_main.c +++ /dev/null @@ -1,335 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Intel MIC Host driver. - */ -#include <linux/fs.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/poll.h> - -#include <linux/mic_common.h> -#include "../common/mic_dev.h" -#include "mic_device.h" -#include "mic_x100.h" -#include "mic_smpt.h" - -static const char mic_driver_name[] = "mic"; - -static const struct pci_device_id mic_pci_tbl[] = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2250)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2251)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2252)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2253)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2254)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2255)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2256)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2257)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2258)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_2259)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225a)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225b)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225c)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225d)}, - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MIC_X100_PCI_DEVICE_225e)}, - - /* required last entry */ - { 0, } -}; - -MODULE_DEVICE_TABLE(pci, mic_pci_tbl); - -/* ID allocator for MIC devices */ -static struct ida g_mic_ida; - -/* Initialize the device page */ -static int mic_dp_init(struct mic_device *mdev) -{ - mdev->dp = kzalloc(MIC_DP_SIZE, GFP_KERNEL); - if (!mdev->dp) - return -ENOMEM; - - mdev->dp_dma_addr = mic_map_single(mdev, - mdev->dp, MIC_DP_SIZE); - if (mic_map_error(mdev->dp_dma_addr)) { - kfree(mdev->dp); - dev_err(&mdev->pdev->dev, "%s %d err %d\n", - __func__, __LINE__, -ENOMEM); - return -ENOMEM; - } - mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr); - mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32); - return 0; -} - -/* Uninitialize the device page */ -static void mic_dp_uninit(struct mic_device *mdev) -{ - mic_unmap_single(mdev, mdev->dp_dma_addr, MIC_DP_SIZE); - kfree(mdev->dp); -} - -/** - * mic_ops_init: Initialize HW specific operation tables. - * - * @mdev: pointer to mic_device instance - * - * returns none. - */ -static void mic_ops_init(struct mic_device *mdev) -{ - switch (mdev->family) { - case MIC_FAMILY_X100: - mdev->ops = &mic_x100_ops; - mdev->intr_ops = &mic_x100_intr_ops; - mdev->smpt_ops = &mic_x100_smpt_ops; - break; - default: - break; - } -} - -/** - * mic_get_family - Determine hardware family to which this MIC belongs. - * - * @pdev: The pci device structure - * - * returns family. - */ -static enum mic_hw_family mic_get_family(struct pci_dev *pdev) -{ - enum mic_hw_family family; - - switch (pdev->device) { - case MIC_X100_PCI_DEVICE_2250: - case MIC_X100_PCI_DEVICE_2251: - case MIC_X100_PCI_DEVICE_2252: - case MIC_X100_PCI_DEVICE_2253: - case MIC_X100_PCI_DEVICE_2254: - case MIC_X100_PCI_DEVICE_2255: - case MIC_X100_PCI_DEVICE_2256: - case MIC_X100_PCI_DEVICE_2257: - case MIC_X100_PCI_DEVICE_2258: - case MIC_X100_PCI_DEVICE_2259: - case MIC_X100_PCI_DEVICE_225a: - case MIC_X100_PCI_DEVICE_225b: - case MIC_X100_PCI_DEVICE_225c: - case MIC_X100_PCI_DEVICE_225d: - case MIC_X100_PCI_DEVICE_225e: - family = MIC_FAMILY_X100; - break; - default: - family = MIC_FAMILY_UNKNOWN; - break; - } - return family; -} - -/** - * mic_device_init - Allocates and initializes the MIC device structure - * - * @mdev: pointer to mic_device instance - * @pdev: The pci device structure - * - * returns none. - */ -static void -mic_device_init(struct mic_device *mdev, struct pci_dev *pdev) -{ - mdev->pdev = pdev; - mdev->family = mic_get_family(pdev); - mdev->stepping = pdev->revision; - mic_ops_init(mdev); - mutex_init(&mdev->mic_mutex); - mdev->irq_info.next_avail_src = 0; -} - -/** - * mic_probe - Device Initialization Routine - * - * @pdev: PCI device structure - * @ent: entry in mic_pci_tbl - * - * returns 0 on success, < 0 on failure. - */ -static int mic_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - int rc; - struct mic_device *mdev; - - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); - if (!mdev) { - rc = -ENOMEM; - goto mdev_alloc_fail; - } - mdev->id = ida_simple_get(&g_mic_ida, 0, MIC_MAX_NUM_DEVS, GFP_KERNEL); - if (mdev->id < 0) { - rc = mdev->id; - dev_err(&pdev->dev, "ida_simple_get failed rc %d\n", rc); - goto ida_fail; - } - - mic_device_init(mdev, pdev); - - rc = pci_enable_device(pdev); - if (rc) { - dev_err(&pdev->dev, "failed to enable pci device.\n"); - goto ida_remove; - } - - pci_set_master(pdev); - - rc = pci_request_regions(pdev, mic_driver_name); - if (rc) { - dev_err(&pdev->dev, "failed to get pci regions.\n"); - goto disable_device; - } - - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); - if (rc) { - dev_err(&pdev->dev, "Cannot set DMA mask\n"); - goto release_regions; - } - - mdev->mmio.pa = pci_resource_start(pdev, mdev->ops->mmio_bar); - mdev->mmio.len = pci_resource_len(pdev, mdev->ops->mmio_bar); - mdev->mmio.va = pci_ioremap_bar(pdev, mdev->ops->mmio_bar); - if (!mdev->mmio.va) { - dev_err(&pdev->dev, "Cannot remap MMIO BAR\n"); - rc = -EIO; - goto release_regions; - } - - mdev->aper.pa = pci_resource_start(pdev, mdev->ops->aper_bar); - mdev->aper.len = pci_resource_len(pdev, mdev->ops->aper_bar); - mdev->aper.va = ioremap_wc(mdev->aper.pa, mdev->aper.len); - if (!mdev->aper.va) { - dev_err(&pdev->dev, "Cannot remap Aperture BAR\n"); - rc = -EIO; - goto unmap_mmio; - } - - mdev->intr_ops->intr_init(mdev); - rc = mic_setup_interrupts(mdev, pdev); - if (rc) { - dev_err(&pdev->dev, "mic_setup_interrupts failed %d\n", rc); - goto unmap_aper; - } - rc = mic_smpt_init(mdev); - if (rc) { - dev_err(&pdev->dev, "smpt_init failed %d\n", rc); - goto free_interrupts; - } - - pci_set_drvdata(pdev, mdev); - - rc = mic_dp_init(mdev); - if (rc) { - dev_err(&pdev->dev, "mic_dp_init failed rc %d\n", rc); - goto smpt_uninit; - } - mic_bootparam_init(mdev); - mic_create_debug_dir(mdev); - - mdev->cosm_dev = cosm_register_device(&mdev->pdev->dev, &cosm_hw_ops); - if (IS_ERR(mdev->cosm_dev)) { - rc = PTR_ERR(mdev->cosm_dev); - dev_err(&pdev->dev, "cosm_add_device failed rc %d\n", rc); - goto cleanup_debug_dir; - } - return 0; -cleanup_debug_dir: - mic_delete_debug_dir(mdev); - mic_dp_uninit(mdev); -smpt_uninit: - mic_smpt_uninit(mdev); -free_interrupts: - mic_free_interrupts(mdev, pdev); -unmap_aper: - iounmap(mdev->aper.va); -unmap_mmio: - iounmap(mdev->mmio.va); -release_regions: - pci_release_regions(pdev); -disable_device: - pci_disable_device(pdev); -ida_remove: - ida_simple_remove(&g_mic_ida, mdev->id); -ida_fail: - kfree(mdev); -mdev_alloc_fail: - dev_err(&pdev->dev, "Probe failed rc %d\n", rc); - return rc; -} - -/** - * mic_remove - Device Removal Routine - * mic_remove is called by the PCI subsystem to alert the driver - * that it should release a PCI device. - * - * @pdev: PCI device structure - */ -static void mic_remove(struct pci_dev *pdev) -{ - struct mic_device *mdev; - - mdev = pci_get_drvdata(pdev); - if (!mdev) - return; - - cosm_unregister_device(mdev->cosm_dev); - mic_delete_debug_dir(mdev); - mic_dp_uninit(mdev); - mic_smpt_uninit(mdev); - mic_free_interrupts(mdev, pdev); - iounmap(mdev->aper.va); - iounmap(mdev->mmio.va); - pci_release_regions(pdev); - pci_disable_device(pdev); - ida_simple_remove(&g_mic_ida, mdev->id); - kfree(mdev); -} - -static struct pci_driver mic_driver = { - .name = mic_driver_name, - .id_table = mic_pci_tbl, - .probe = mic_probe, - .remove = mic_remove -}; - -static int __init mic_init(void) -{ - int ret; - - request_module("mic_x100_dma"); - mic_init_debugfs(); - ida_init(&g_mic_ida); - ret = pci_register_driver(&mic_driver); - if (ret) { - pr_err("pci_register_driver failed ret %d\n", ret); - goto cleanup_debugfs; - } - return 0; -cleanup_debugfs: - ida_destroy(&g_mic_ida); - mic_exit_debugfs(); - return ret; -} - -static void __exit mic_exit(void) -{ - pci_unregister_driver(&mic_driver); - ida_destroy(&g_mic_ida); - mic_exit_debugfs(); -} - -module_init(mic_init); -module_exit(mic_exit); - -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) MIC X100 Host driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mic/host/mic_smpt.c b/drivers/misc/mic/host/mic_smpt.c deleted file mode 100644 index 50d1bebecd54..000000000000 --- a/drivers/misc/mic/host/mic_smpt.c +++ /dev/null @@ -1,427 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Intel MIC Host driver. - */ -#include <linux/pci.h> - -#include "../common/mic_dev.h" -#include "mic_device.h" -#include "mic_smpt.h" - -static inline u64 mic_system_page_mask(struct mic_device *mdev) -{ - return (1ULL << mdev->smpt->info.page_shift) - 1ULL; -} - -static inline u8 mic_sys_addr_to_smpt(struct mic_device *mdev, dma_addr_t pa) -{ - return (pa - mdev->smpt->info.base) >> mdev->smpt->info.page_shift; -} - -static inline u64 mic_smpt_to_pa(struct mic_device *mdev, u8 index) -{ - return mdev->smpt->info.base + (index * mdev->smpt->info.page_size); -} - -static inline u64 mic_smpt_offset(struct mic_device *mdev, dma_addr_t pa) -{ - return pa & mic_system_page_mask(mdev); -} - -static inline u64 mic_smpt_align_low(struct mic_device *mdev, dma_addr_t pa) -{ - return ALIGN(pa - mic_system_page_mask(mdev), - mdev->smpt->info.page_size); -} - -static inline u64 mic_smpt_align_high(struct mic_device *mdev, dma_addr_t pa) -{ - return ALIGN(pa, mdev->smpt->info.page_size); -} - -/* Total Cumulative system memory accessible by MIC across all SMPT entries */ -static inline u64 mic_max_system_memory(struct mic_device *mdev) -{ - return mdev->smpt->info.num_reg * mdev->smpt->info.page_size; -} - -/* Maximum system memory address accessible by MIC */ -static inline u64 mic_max_system_addr(struct mic_device *mdev) -{ - return mdev->smpt->info.base + mic_max_system_memory(mdev) - 1ULL; -} - -/* Check if the DMA address is a MIC system memory address */ -static inline bool -mic_is_system_addr(struct mic_device *mdev, dma_addr_t pa) -{ - return pa >= mdev->smpt->info.base && pa <= mic_max_system_addr(mdev); -} - -/* Populate an SMPT entry and update the reference counts. */ -static void mic_add_smpt_entry(int spt, s64 *ref, u64 addr, - int entries, struct mic_device *mdev) -{ - struct mic_smpt_info *smpt_info = mdev->smpt; - int i; - - for (i = spt; i < spt + entries; i++, - addr += smpt_info->info.page_size) { - if (!smpt_info->entry[i].ref_count && - (smpt_info->entry[i].dma_addr != addr)) { - mdev->smpt_ops->set(mdev, addr, i); - smpt_info->entry[i].dma_addr = addr; - } - smpt_info->entry[i].ref_count += ref[i - spt]; - } -} - -/* - * Find an available MIC address in MIC SMPT address space - * for a given DMA address and size. - */ -static dma_addr_t mic_smpt_op(struct mic_device *mdev, u64 dma_addr, - int entries, s64 *ref, size_t size) -{ - int spt; - int ae = 0; - int i; - unsigned long flags; - dma_addr_t mic_addr = 0; - dma_addr_t addr = dma_addr; - struct mic_smpt_info *smpt_info = mdev->smpt; - - spin_lock_irqsave(&smpt_info->smpt_lock, flags); - - /* find existing entries */ - for (i = 0; i < smpt_info->info.num_reg; i++) { - if (smpt_info->entry[i].dma_addr == addr) { - ae++; - addr += smpt_info->info.page_size; - } else if (ae) /* cannot find contiguous entries */ - goto not_found; - - if (ae == entries) - goto found; - } - - /* find free entry */ - for (ae = 0, i = 0; i < smpt_info->info.num_reg; i++) { - ae = (smpt_info->entry[i].ref_count == 0) ? ae + 1 : 0; - if (ae == entries) - goto found; - } - -not_found: - spin_unlock_irqrestore(&smpt_info->smpt_lock, flags); - return mic_addr; - -found: - spt = i - entries + 1; - mic_addr = mic_smpt_to_pa(mdev, spt); - mic_add_smpt_entry(spt, ref, dma_addr, entries, mdev); - smpt_info->map_count++; - smpt_info->ref_count += (s64)size; - spin_unlock_irqrestore(&smpt_info->smpt_lock, flags); - return mic_addr; -} - -/* - * Returns number of smpt entries needed for dma_addr to dma_addr + size - * also returns the reference count array for each of those entries - * and the starting smpt address - */ -static int mic_get_smpt_ref_count(struct mic_device *mdev, dma_addr_t dma_addr, - size_t size, s64 *ref, u64 *smpt_start) -{ - u64 start = dma_addr; - u64 end = dma_addr + size; - int i = 0; - - while (start < end) { - ref[i++] = min(mic_smpt_align_high(mdev, start + 1), - end) - start; - start = mic_smpt_align_high(mdev, start + 1); - } - - if (smpt_start) - *smpt_start = mic_smpt_align_low(mdev, dma_addr); - - return i; -} - -/* - * mic_to_dma_addr - Converts a MIC address to a DMA address. - * - * @mdev: pointer to mic_device instance. - * @mic_addr: MIC address. - * - * returns a DMA address. - */ -dma_addr_t mic_to_dma_addr(struct mic_device *mdev, dma_addr_t mic_addr) -{ - struct mic_smpt_info *smpt_info = mdev->smpt; - int spt; - dma_addr_t dma_addr; - - if (!mic_is_system_addr(mdev, mic_addr)) { - dev_err(&mdev->pdev->dev, - "mic_addr is invalid. mic_addr = 0x%llx\n", mic_addr); - return -EINVAL; - } - spt = mic_sys_addr_to_smpt(mdev, mic_addr); - dma_addr = smpt_info->entry[spt].dma_addr + - mic_smpt_offset(mdev, mic_addr); - return dma_addr; -} - -/** - * mic_map - Maps a DMA address to a MIC physical address. - * - * @mdev: pointer to mic_device instance. - * @dma_addr: DMA address. - * @size: Size of the region to be mapped. - * - * This API converts the DMA address provided to a DMA address understood - * by MIC. Caller should check for errors by calling mic_map_error(..). - * - * returns DMA address as required by MIC. - */ -dma_addr_t mic_map(struct mic_device *mdev, dma_addr_t dma_addr, size_t size) -{ - dma_addr_t mic_addr = 0; - int num_entries; - s64 *ref; - u64 smpt_start; - - if (!size || size > mic_max_system_memory(mdev)) - return mic_addr; - - ref = kmalloc_array(mdev->smpt->info.num_reg, sizeof(s64), GFP_ATOMIC); - if (!ref) - return mic_addr; - - num_entries = mic_get_smpt_ref_count(mdev, dma_addr, size, - ref, &smpt_start); - - /* Set the smpt table appropriately and get 16G aligned mic address */ - mic_addr = mic_smpt_op(mdev, smpt_start, num_entries, ref, size); - - kfree(ref); - - /* - * If mic_addr is zero then its an error case - * since mic_addr can never be zero. - * else generate mic_addr by adding the 16G offset in dma_addr - */ - if (!mic_addr && MIC_FAMILY_X100 == mdev->family) { - dev_err(&mdev->pdev->dev, - "mic_map failed dma_addr 0x%llx size 0x%lx\n", - dma_addr, size); - return mic_addr; - } else { - return mic_addr + mic_smpt_offset(mdev, dma_addr); - } -} - -/** - * mic_unmap - Unmaps a MIC physical address. - * - * @mdev: pointer to mic_device instance. - * @mic_addr: MIC physical address. - * @size: Size of the region to be unmapped. - * - * This API unmaps the mappings created by mic_map(..). - * - * returns None. - */ -void mic_unmap(struct mic_device *mdev, dma_addr_t mic_addr, size_t size) -{ - struct mic_smpt_info *smpt_info = mdev->smpt; - s64 *ref; - int num_smpt; - int spt; - int i; - unsigned long flags; - - if (!size) - return; - - if (!mic_is_system_addr(mdev, mic_addr)) { - dev_err(&mdev->pdev->dev, - "invalid address: 0x%llx\n", mic_addr); - return; - } - - spt = mic_sys_addr_to_smpt(mdev, mic_addr); - ref = kmalloc_array(mdev->smpt->info.num_reg, sizeof(s64), GFP_ATOMIC); - if (!ref) - return; - - /* Get number of smpt entries to be mapped, ref count array */ - num_smpt = mic_get_smpt_ref_count(mdev, mic_addr, size, ref, NULL); - - spin_lock_irqsave(&smpt_info->smpt_lock, flags); - smpt_info->unmap_count++; - smpt_info->ref_count -= (s64)size; - - for (i = spt; i < spt + num_smpt; i++) { - smpt_info->entry[i].ref_count -= ref[i - spt]; - if (smpt_info->entry[i].ref_count < 0) - dev_warn(&mdev->pdev->dev, - "ref count for entry %d is negative\n", i); - } - spin_unlock_irqrestore(&smpt_info->smpt_lock, flags); - kfree(ref); -} - -/** - * mic_map_single - Maps a virtual address to a MIC physical address. - * - * @mdev: pointer to mic_device instance. - * @va: Kernel direct mapped virtual address. - * @size: Size of the region to be mapped. - * - * This API calls pci_map_single(..) for the direct mapped virtual address - * and then converts the DMA address provided to a DMA address understood - * by MIC. Caller should check for errors by calling mic_map_error(..). - * - * returns DMA address as required by MIC. - */ -dma_addr_t mic_map_single(struct mic_device *mdev, void *va, size_t size) -{ - dma_addr_t mic_addr = 0; - struct pci_dev *pdev = mdev->pdev; - dma_addr_t dma_addr = - pci_map_single(pdev, va, size, PCI_DMA_BIDIRECTIONAL); - - if (!pci_dma_mapping_error(pdev, dma_addr)) { - mic_addr = mic_map(mdev, dma_addr, size); - if (!mic_addr) { - dev_err(&mdev->pdev->dev, - "mic_map failed dma_addr 0x%llx size 0x%lx\n", - dma_addr, size); - pci_unmap_single(pdev, dma_addr, - size, PCI_DMA_BIDIRECTIONAL); - } - } - return mic_addr; -} - -/** - * mic_unmap_single - Unmaps a MIC physical address. - * - * @mdev: pointer to mic_device instance. - * @mic_addr: MIC physical address. - * @size: Size of the region to be unmapped. - * - * This API unmaps the mappings created by mic_map_single(..). - * - * returns None. - */ -void -mic_unmap_single(struct mic_device *mdev, dma_addr_t mic_addr, size_t size) -{ - struct pci_dev *pdev = mdev->pdev; - dma_addr_t dma_addr = mic_to_dma_addr(mdev, mic_addr); - mic_unmap(mdev, mic_addr, size); - pci_unmap_single(pdev, dma_addr, size, PCI_DMA_BIDIRECTIONAL); -} - -/** - * mic_smpt_init - Initialize MIC System Memory Page Tables. - * - * @mdev: pointer to mic_device instance. - * - * returns 0 for success and -errno for error. - */ -int mic_smpt_init(struct mic_device *mdev) -{ - int i, err = 0; - dma_addr_t dma_addr; - struct mic_smpt_info *smpt_info; - - mdev->smpt = kmalloc(sizeof(*mdev->smpt), GFP_KERNEL); - if (!mdev->smpt) - return -ENOMEM; - - smpt_info = mdev->smpt; - mdev->smpt_ops->init(mdev); - smpt_info->entry = kmalloc_array(smpt_info->info.num_reg, - sizeof(*smpt_info->entry), GFP_KERNEL); - if (!smpt_info->entry) { - err = -ENOMEM; - goto free_smpt; - } - spin_lock_init(&smpt_info->smpt_lock); - for (i = 0; i < smpt_info->info.num_reg; i++) { - dma_addr = i * smpt_info->info.page_size; - smpt_info->entry[i].dma_addr = dma_addr; - smpt_info->entry[i].ref_count = 0; - mdev->smpt_ops->set(mdev, dma_addr, i); - } - smpt_info->ref_count = 0; - smpt_info->map_count = 0; - smpt_info->unmap_count = 0; - return 0; -free_smpt: - kfree(smpt_info); - return err; -} - -/** - * mic_smpt_uninit - UnInitialize MIC System Memory Page Tables. - * - * @mdev: pointer to mic_device instance. - * - * returns None. - */ -void mic_smpt_uninit(struct mic_device *mdev) -{ - struct mic_smpt_info *smpt_info = mdev->smpt; - int i; - - dev_dbg(&mdev->pdev->dev, - "nodeid %d SMPT ref count %lld map %lld unmap %lld\n", - mdev->id, smpt_info->ref_count, - smpt_info->map_count, smpt_info->unmap_count); - - for (i = 0; i < smpt_info->info.num_reg; i++) { - dev_dbg(&mdev->pdev->dev, - "SMPT entry[%d] dma_addr = 0x%llx ref_count = %lld\n", - i, smpt_info->entry[i].dma_addr, - smpt_info->entry[i].ref_count); - if (smpt_info->entry[i].ref_count) - dev_warn(&mdev->pdev->dev, - "ref count for entry %d is not zero\n", i); - } - kfree(smpt_info->entry); - kfree(smpt_info); -} - -/** - * mic_smpt_restore - Restore MIC System Memory Page Tables. - * - * @mdev: pointer to mic_device instance. - * - * Restore the SMPT registers to values previously stored in the - * SW data structures. Some MIC steppings lose register state - * across resets and this API should be called for performing - * a restore operation if required. - * - * returns None. - */ -void mic_smpt_restore(struct mic_device *mdev) -{ - int i; - dma_addr_t dma_addr; - - for (i = 0; i < mdev->smpt->info.num_reg; i++) { - dma_addr = mdev->smpt->entry[i].dma_addr; - mdev->smpt_ops->set(mdev, dma_addr, i); - } -} diff --git a/drivers/misc/mic/host/mic_smpt.h b/drivers/misc/mic/host/mic_smpt.h deleted file mode 100644 index 3b1ec14a9d81..000000000000 --- a/drivers/misc/mic/host/mic_smpt.h +++ /dev/null @@ -1,87 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Intel MIC Host driver. - */ -#ifndef MIC_SMPT_H -#define MIC_SMPT_H -/** - * struct mic_smpt_ops - MIC HW specific SMPT operations. - * @init: Initialize hardware specific SMPT information in mic_smpt_hw_info. - * @set: Set the value for a particular SMPT entry. - */ -struct mic_smpt_ops { - void (*init)(struct mic_device *mdev); - void (*set)(struct mic_device *mdev, dma_addr_t dma_addr, u8 index); -}; - -/** - * struct mic_smpt - MIC SMPT entry information. - * @dma_addr: Base DMA address for this SMPT entry. - * @ref_count: Number of active mappings for this SMPT entry in bytes. - */ -struct mic_smpt { - dma_addr_t dma_addr; - s64 ref_count; -}; - -/** - * struct mic_smpt_hw_info - MIC SMPT hardware specific information. - * @num_reg: Number of SMPT registers. - * @page_shift: System memory page shift. - * @page_size: System memory page size. - * @base: System address base. - */ -struct mic_smpt_hw_info { - u8 num_reg; - u8 page_shift; - u64 page_size; - u64 base; -}; - -/** - * struct mic_smpt_info - MIC SMPT information. - * @entry: Array of SMPT entries. - * @smpt_lock: Spin lock protecting access to SMPT data structures. - * @info: Hardware specific SMPT information. - * @ref_count: Number of active SMPT mappings (for debug). - * @map_count: Number of SMPT mappings created (for debug). - * @unmap_count: Number of SMPT mappings destroyed (for debug). - */ -struct mic_smpt_info { - struct mic_smpt *entry; - spinlock_t smpt_lock; - struct mic_smpt_hw_info info; - s64 ref_count; - s64 map_count; - s64 unmap_count; -}; - -dma_addr_t mic_map_single(struct mic_device *mdev, void *va, size_t size); -void mic_unmap_single(struct mic_device *mdev, - dma_addr_t mic_addr, size_t size); -dma_addr_t mic_map(struct mic_device *mdev, - dma_addr_t dma_addr, size_t size); -void mic_unmap(struct mic_device *mdev, dma_addr_t mic_addr, size_t size); -dma_addr_t mic_to_dma_addr(struct mic_device *mdev, dma_addr_t mic_addr); - -/** - * mic_map_error - Check a MIC address for errors. - * - * @mdev: pointer to mic_device instance. - * - * returns Whether there was an error during mic_map..(..) APIs. - */ -static inline bool mic_map_error(dma_addr_t mic_addr) -{ - return !mic_addr; -} - -int mic_smpt_init(struct mic_device *mdev); -void mic_smpt_uninit(struct mic_device *mdev); -void mic_smpt_restore(struct mic_device *mdev); - -#endif diff --git a/drivers/misc/mic/host/mic_x100.c b/drivers/misc/mic/host/mic_x100.c deleted file mode 100644 index f5536c1ad607..000000000000 --- a/drivers/misc/mic/host/mic_x100.c +++ /dev/null @@ -1,585 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Intel MIC Host driver. - */ -#include <linux/fs.h> -#include <linux/pci.h> -#include <linux/sched.h> -#include <linux/firmware.h> -#include <linux/delay.h> - -#include "../common/mic_dev.h" -#include "mic_device.h" -#include "mic_x100.h" -#include "mic_smpt.h" - -static const u16 mic_x100_intr_init[] = { - MIC_X100_DOORBELL_IDX_START, - MIC_X100_DMA_IDX_START, - MIC_X100_ERR_IDX_START, - MIC_X100_NUM_DOORBELL, - MIC_X100_NUM_DMA, - MIC_X100_NUM_ERR, -}; - -/** - * mic_x100_write_spad - write to the scratchpad register - * @mdev: pointer to mic_device instance - * @idx: index to the scratchpad register, 0 based - * @val: the data value to put into the register - * - * This function allows writing of a 32bit value to the indexed scratchpad - * register. - * - * RETURNS: none. - */ -static void -mic_x100_write_spad(struct mic_device *mdev, unsigned int idx, u32 val) -{ - dev_dbg(&mdev->pdev->dev, "Writing 0x%x to scratch pad index %d\n", - val, idx); - mic_mmio_write(&mdev->mmio, val, - MIC_X100_SBOX_BASE_ADDRESS + - MIC_X100_SBOX_SPAD0 + idx * 4); -} - -/** - * mic_x100_read_spad - read from the scratchpad register - * @mdev: pointer to mic_device instance - * @idx: index to scratchpad register, 0 based - * - * This function allows reading of the 32bit scratchpad register. - * - * RETURNS: An appropriate -ERRNO error value on error, or zero for success. - */ -static u32 -mic_x100_read_spad(struct mic_device *mdev, unsigned int idx) -{ - u32 val = mic_mmio_read(&mdev->mmio, - MIC_X100_SBOX_BASE_ADDRESS + - MIC_X100_SBOX_SPAD0 + idx * 4); - - dev_dbg(&mdev->pdev->dev, - "Reading 0x%x from scratch pad index %d\n", val, idx); - return val; -} - -/** - * mic_x100_enable_interrupts - Enable interrupts. - * @mdev: pointer to mic_device instance - */ -static void mic_x100_enable_interrupts(struct mic_device *mdev) -{ - u32 reg; - struct mic_mw *mw = &mdev->mmio; - u32 sice0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICE0; - u32 siac0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SIAC0; - - reg = mic_mmio_read(mw, sice0); - reg |= MIC_X100_SBOX_DBR_BITS(0xf) | MIC_X100_SBOX_DMA_BITS(0xff); - mic_mmio_write(mw, reg, sice0); - - /* - * Enable auto-clear when enabling interrupts. Applicable only for - * MSI-x. Legacy and MSI mode cannot have auto-clear enabled. - */ - if (mdev->irq_info.num_vectors > 1) { - reg = mic_mmio_read(mw, siac0); - reg |= MIC_X100_SBOX_DBR_BITS(0xf) | - MIC_X100_SBOX_DMA_BITS(0xff); - mic_mmio_write(mw, reg, siac0); - } -} - -/** - * mic_x100_disable_interrupts - Disable interrupts. - * @mdev: pointer to mic_device instance - */ -static void mic_x100_disable_interrupts(struct mic_device *mdev) -{ - u32 reg; - struct mic_mw *mw = &mdev->mmio; - u32 sice0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICE0; - u32 siac0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SIAC0; - u32 sicc0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICC0; - - reg = mic_mmio_read(mw, sice0); - mic_mmio_write(mw, reg, sicc0); - - if (mdev->irq_info.num_vectors > 1) { - reg = mic_mmio_read(mw, siac0); - reg &= ~(MIC_X100_SBOX_DBR_BITS(0xf) | - MIC_X100_SBOX_DMA_BITS(0xff)); - mic_mmio_write(mw, reg, siac0); - } -} - -/** - * mic_x100_send_sbox_intr - Send an MIC_X100_SBOX interrupt to MIC. - * @mdev: pointer to mic_device instance - * @doorbell: doorbell number - */ -static void mic_x100_send_sbox_intr(struct mic_device *mdev, - int doorbell) -{ - struct mic_mw *mw = &mdev->mmio; - u64 apic_icr_offset = MIC_X100_SBOX_APICICR0 + doorbell * 8; - u32 apicicr_low = mic_mmio_read(mw, MIC_X100_SBOX_BASE_ADDRESS + - apic_icr_offset); - - /* for MIC we need to make sure we "hit" the send_icr bit (13) */ - apicicr_low = (apicicr_low | (1 << 13)); - - /* Ensure that the interrupt is ordered w.r.t. previous stores. */ - wmb(); - mic_mmio_write(mw, apicicr_low, - MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset); -} - -/** - * mic_x100_send_rdmasr_intr - Send an RDMASR interrupt to MIC. - * @mdev: pointer to mic_device instance - * @doorbell: doorbell number - */ -static void mic_x100_send_rdmasr_intr(struct mic_device *mdev, - int doorbell) -{ - int rdmasr_offset = MIC_X100_SBOX_RDMASR0 + (doorbell << 2); - /* Ensure that the interrupt is ordered w.r.t. previous stores. */ - wmb(); - mic_mmio_write(&mdev->mmio, 0, - MIC_X100_SBOX_BASE_ADDRESS + rdmasr_offset); -} - -/** - * __mic_x100_send_intr - Send interrupt to MIC. - * @mdev: pointer to mic_device instance - * @doorbell: doorbell number. - */ -static void mic_x100_send_intr(struct mic_device *mdev, int doorbell) -{ - int rdmasr_db; - if (doorbell < MIC_X100_NUM_SBOX_IRQ) { - mic_x100_send_sbox_intr(mdev, doorbell); - } else { - rdmasr_db = doorbell - MIC_X100_NUM_SBOX_IRQ; - mic_x100_send_rdmasr_intr(mdev, rdmasr_db); - } -} - -/** - * mic_x100_ack_interrupt - Read the interrupt sources register and - * clear it. This function will be called in the MSI/INTx case. - * @mdev: Pointer to mic_device instance. - * - * Returns: bitmask of interrupt sources triggered. - */ -static u32 mic_x100_ack_interrupt(struct mic_device *mdev) -{ - u32 sicr0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICR0; - u32 reg = mic_mmio_read(&mdev->mmio, sicr0); - mic_mmio_write(&mdev->mmio, reg, sicr0); - return reg; -} - -/** - * mic_x100_intr_workarounds - These hardware specific workarounds are - * to be invoked everytime an interrupt is handled. - * @mdev: Pointer to mic_device instance. - * - * Returns: none - */ -static void mic_x100_intr_workarounds(struct mic_device *mdev) -{ - struct mic_mw *mw = &mdev->mmio; - - /* Clear pending bit array. */ - if (MIC_A0_STEP == mdev->stepping) - mic_mmio_write(mw, 1, MIC_X100_SBOX_BASE_ADDRESS + - MIC_X100_SBOX_MSIXPBACR); - - if (mdev->stepping >= MIC_B0_STEP) - mdev->intr_ops->enable_interrupts(mdev); -} - -/** - * mic_x100_hw_intr_init - Initialize h/w specific interrupt - * information. - * @mdev: pointer to mic_device instance - */ -static void mic_x100_hw_intr_init(struct mic_device *mdev) -{ - mdev->intr_info = (struct mic_intr_info *)mic_x100_intr_init; -} - -/** - * mic_x100_read_msi_to_src_map - read from the MSI mapping registers - * @mdev: pointer to mic_device instance - * @idx: index to the mapping register, 0 based - * - * This function allows reading of the 32bit MSI mapping register. - * - * RETURNS: The value in the register. - */ -static u32 -mic_x100_read_msi_to_src_map(struct mic_device *mdev, int idx) -{ - return mic_mmio_read(&mdev->mmio, - MIC_X100_SBOX_BASE_ADDRESS + - MIC_X100_SBOX_MXAR0 + idx * 4); -} - -/** - * mic_x100_program_msi_to_src_map - program the MSI mapping registers - * @mdev: pointer to mic_device instance - * @idx: index to the mapping register, 0 based - * @offset: The bit offset in the register that needs to be updated. - * @set: boolean specifying if the bit in the specified offset needs - * to be set or cleared. - * - * RETURNS: None. - */ -static void -mic_x100_program_msi_to_src_map(struct mic_device *mdev, - int idx, int offset, bool set) -{ - unsigned long reg; - struct mic_mw *mw = &mdev->mmio; - u32 mxar = MIC_X100_SBOX_BASE_ADDRESS + - MIC_X100_SBOX_MXAR0 + idx * 4; - - reg = mic_mmio_read(mw, mxar); - if (set) - __set_bit(offset, ®); - else - __clear_bit(offset, ®); - mic_mmio_write(mw, reg, mxar); -} - -/* - * mic_x100_reset_fw_ready - Reset Firmware ready status field. - * @mdev: pointer to mic_device instance - */ -static void mic_x100_reset_fw_ready(struct mic_device *mdev) -{ - mdev->ops->write_spad(mdev, MIC_X100_DOWNLOAD_INFO, 0); -} - -/* - * mic_x100_is_fw_ready - Check if firmware is ready. - * @mdev: pointer to mic_device instance - */ -static bool mic_x100_is_fw_ready(struct mic_device *mdev) -{ - u32 scratch2 = mdev->ops->read_spad(mdev, MIC_X100_DOWNLOAD_INFO); - return MIC_X100_SPAD2_DOWNLOAD_STATUS(scratch2) ? true : false; -} - -/** - * mic_x100_get_apic_id - Get bootstrap APIC ID. - * @mdev: pointer to mic_device instance - */ -static u32 mic_x100_get_apic_id(struct mic_device *mdev) -{ - u32 scratch2 = 0; - - scratch2 = mdev->ops->read_spad(mdev, MIC_X100_DOWNLOAD_INFO); - return MIC_X100_SPAD2_APIC_ID(scratch2); -} - -/** - * mic_x100_send_firmware_intr - Send an interrupt to the firmware on MIC. - * @mdev: pointer to mic_device instance - */ -static void mic_x100_send_firmware_intr(struct mic_device *mdev) -{ - u32 apicicr_low; - u64 apic_icr_offset = MIC_X100_SBOX_APICICR7; - int vector = MIC_X100_BSP_INTERRUPT_VECTOR; - struct mic_mw *mw = &mdev->mmio; - - /* - * For MIC we need to make sure we "hit" - * the send_icr bit (13). - */ - apicicr_low = (vector | (1 << 13)); - - mic_mmio_write(mw, mic_x100_get_apic_id(mdev), - MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset + 4); - - /* Ensure that the interrupt is ordered w.r.t. previous stores. */ - wmb(); - mic_mmio_write(mw, apicicr_low, - MIC_X100_SBOX_BASE_ADDRESS + apic_icr_offset); -} - -/** - * mic_x100_hw_reset - Reset the MIC device. - * @mdev: pointer to mic_device instance - */ -static void mic_x100_hw_reset(struct mic_device *mdev) -{ - u32 reset_reg; - u32 rgcr = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_RGCR; - struct mic_mw *mw = &mdev->mmio; - - /* Ensure that the reset is ordered w.r.t. previous loads and stores */ - mb(); - /* Trigger reset */ - reset_reg = mic_mmio_read(mw, rgcr); - reset_reg |= 0x1; - mic_mmio_write(mw, reset_reg, rgcr); - /* - * It seems we really want to delay at least 1 second - * after touching reset to prevent a lot of problems. - */ - msleep(1000); -} - -/** - * mic_x100_load_command_line - Load command line to MIC. - * @mdev: pointer to mic_device instance - * @fw: the firmware image - * - * RETURNS: An appropriate -ERRNO error value on error, or zero for success. - */ -static int -mic_x100_load_command_line(struct mic_device *mdev, const struct firmware *fw) -{ - u32 len = 0; - u32 boot_mem; - char *buf; - void __iomem *cmd_line_va = mdev->aper.va + mdev->bootaddr + fw->size; -#define CMDLINE_SIZE 2048 - - boot_mem = mdev->aper.len >> 20; - buf = kzalloc(CMDLINE_SIZE, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - len += scnprintf(buf, CMDLINE_SIZE - len, - " mem=%dM", boot_mem); - if (mdev->cosm_dev->cmdline) - scnprintf(buf + len, CMDLINE_SIZE - len, " %s", - mdev->cosm_dev->cmdline); - memcpy_toio(cmd_line_va, buf, strlen(buf) + 1); - kfree(buf); - return 0; -} - -/** - * mic_x100_load_ramdisk - Load ramdisk to MIC. - * @mdev: pointer to mic_device instance - * - * RETURNS: An appropriate -ERRNO error value on error, or zero for success. - */ -static int -mic_x100_load_ramdisk(struct mic_device *mdev) -{ - const struct firmware *fw; - int rc; - struct boot_params __iomem *bp = mdev->aper.va + mdev->bootaddr; - - rc = request_firmware(&fw, mdev->cosm_dev->ramdisk, &mdev->pdev->dev); - if (rc < 0) { - dev_err(&mdev->pdev->dev, - "ramdisk request_firmware failed: %d %s\n", - rc, mdev->cosm_dev->ramdisk); - goto error; - } - /* - * Typically the bootaddr for card OS is 64M - * so copy over the ramdisk @ 128M. - */ - memcpy_toio(mdev->aper.va + (mdev->bootaddr << 1), fw->data, fw->size); - iowrite32(mdev->bootaddr << 1, &bp->hdr.ramdisk_image); - iowrite32(fw->size, &bp->hdr.ramdisk_size); - release_firmware(fw); -error: - return rc; -} - -/** - * mic_x100_get_boot_addr - Get MIC boot address. - * @mdev: pointer to mic_device instance - * - * This function is called during firmware load to determine - * the address at which the OS should be downloaded in card - * memory i.e. GDDR. - * RETURNS: An appropriate -ERRNO error value on error, or zero for success. - */ -static int -mic_x100_get_boot_addr(struct mic_device *mdev) -{ - u32 scratch2, boot_addr; - int rc = 0; - - scratch2 = mdev->ops->read_spad(mdev, MIC_X100_DOWNLOAD_INFO); - boot_addr = MIC_X100_SPAD2_DOWNLOAD_ADDR(scratch2); - dev_dbg(&mdev->pdev->dev, "%s %d boot_addr 0x%x\n", - __func__, __LINE__, boot_addr); - if (boot_addr > (1 << 31)) { - dev_err(&mdev->pdev->dev, - "incorrect bootaddr 0x%x\n", - boot_addr); - rc = -EINVAL; - goto error; - } - mdev->bootaddr = boot_addr; -error: - return rc; -} - -/** - * mic_x100_load_firmware - Load firmware to MIC. - * @mdev: pointer to mic_device instance - * @buf: buffer containing boot string including firmware/ramdisk path. - * - * RETURNS: An appropriate -ERRNO error value on error, or zero for success. - */ -static int -mic_x100_load_firmware(struct mic_device *mdev, const char *buf) -{ - int rc; - const struct firmware *fw; - - rc = mic_x100_get_boot_addr(mdev); - if (rc) - return rc; - /* load OS */ - rc = request_firmware(&fw, mdev->cosm_dev->firmware, &mdev->pdev->dev); - if (rc < 0) { - dev_err(&mdev->pdev->dev, - "ramdisk request_firmware failed: %d %s\n", - rc, mdev->cosm_dev->firmware); - return rc; - } - if (mdev->bootaddr > mdev->aper.len - fw->size) { - rc = -EINVAL; - dev_err(&mdev->pdev->dev, "%s %d rc %d bootaddr 0x%x\n", - __func__, __LINE__, rc, mdev->bootaddr); - goto error; - } - memcpy_toio(mdev->aper.va + mdev->bootaddr, fw->data, fw->size); - mdev->ops->write_spad(mdev, MIC_X100_FW_SIZE, fw->size); - if (!strcmp(mdev->cosm_dev->bootmode, "flash")) { - rc = -EINVAL; - dev_err(&mdev->pdev->dev, "%s %d rc %d\n", - __func__, __LINE__, rc); - goto error; - } - /* load command line */ - rc = mic_x100_load_command_line(mdev, fw); - if (rc) { - dev_err(&mdev->pdev->dev, "%s %d rc %d\n", - __func__, __LINE__, rc); - goto error; - } - release_firmware(fw); - /* load ramdisk */ - if (mdev->cosm_dev->ramdisk) - rc = mic_x100_load_ramdisk(mdev); - - return rc; - -error: - release_firmware(fw); - return rc; -} - -/** - * mic_x100_get_postcode - Get postcode status from firmware. - * @mdev: pointer to mic_device instance - * - * RETURNS: postcode. - */ -static u32 mic_x100_get_postcode(struct mic_device *mdev) -{ - return mic_mmio_read(&mdev->mmio, MIC_X100_POSTCODE); -} - -/** - * mic_x100_smpt_set - Update an SMPT entry with a DMA address. - * @mdev: pointer to mic_device instance - * @dma_addr: DMA address to use - * @index: entry to write to - * - * RETURNS: none. - */ -static void -mic_x100_smpt_set(struct mic_device *mdev, dma_addr_t dma_addr, u8 index) -{ -#define SNOOP_ON (0 << 0) -#define SNOOP_OFF (1 << 0) -/* - * Sbox Smpt Reg Bits: - * Bits 31:2 Host address - * Bits 1 RSVD - * Bits 0 No snoop - */ -#define BUILD_SMPT(NO_SNOOP, HOST_ADDR) \ - (u32)(((HOST_ADDR) << 2) | ((NO_SNOOP) & 0x01)) - - uint32_t smpt_reg_val = BUILD_SMPT(SNOOP_ON, - dma_addr >> mdev->smpt->info.page_shift); - mic_mmio_write(&mdev->mmio, smpt_reg_val, - MIC_X100_SBOX_BASE_ADDRESS + - MIC_X100_SBOX_SMPT00 + (4 * index)); -} - -/** - * mic_x100_smpt_hw_init - Initialize SMPT X100 specific fields. - * @mdev: pointer to mic_device instance - * - * RETURNS: none. - */ -static void mic_x100_smpt_hw_init(struct mic_device *mdev) -{ - struct mic_smpt_hw_info *info = &mdev->smpt->info; - - info->num_reg = 32; - info->page_shift = 34; - info->page_size = (1ULL << info->page_shift); - info->base = 0x8000000000ULL; -} - -struct mic_smpt_ops mic_x100_smpt_ops = { - .init = mic_x100_smpt_hw_init, - .set = mic_x100_smpt_set, -}; - -static bool mic_x100_dma_filter(struct dma_chan *chan, void *param) -{ - if (chan->device->dev->parent == (struct device *)param) - return true; - return false; -} - -struct mic_hw_ops mic_x100_ops = { - .aper_bar = MIC_X100_APER_BAR, - .mmio_bar = MIC_X100_MMIO_BAR, - .read_spad = mic_x100_read_spad, - .write_spad = mic_x100_write_spad, - .send_intr = mic_x100_send_intr, - .ack_interrupt = mic_x100_ack_interrupt, - .intr_workarounds = mic_x100_intr_workarounds, - .reset = mic_x100_hw_reset, - .reset_fw_ready = mic_x100_reset_fw_ready, - .is_fw_ready = mic_x100_is_fw_ready, - .send_firmware_intr = mic_x100_send_firmware_intr, - .load_mic_fw = mic_x100_load_firmware, - .get_postcode = mic_x100_get_postcode, - .dma_filter = mic_x100_dma_filter, -}; - -struct mic_hw_intr_ops mic_x100_intr_ops = { - .intr_init = mic_x100_hw_intr_init, - .enable_interrupts = mic_x100_enable_interrupts, - .disable_interrupts = mic_x100_disable_interrupts, - .program_msi_to_src_map = mic_x100_program_msi_to_src_map, - .read_msi_to_src_map = mic_x100_read_msi_to_src_map, -}; diff --git a/drivers/misc/mic/host/mic_x100.h b/drivers/misc/mic/host/mic_x100.h deleted file mode 100644 index aebcaed6fa72..000000000000 --- a/drivers/misc/mic/host/mic_x100.h +++ /dev/null @@ -1,77 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2013 Intel Corporation. - * - * Intel MIC Host driver. - */ -#ifndef _MIC_X100_HW_H_ -#define _MIC_X100_HW_H_ - -#define MIC_X100_PCI_DEVICE_2250 0x2250 -#define MIC_X100_PCI_DEVICE_2251 0x2251 -#define MIC_X100_PCI_DEVICE_2252 0x2252 -#define MIC_X100_PCI_DEVICE_2253 0x2253 -#define MIC_X100_PCI_DEVICE_2254 0x2254 -#define MIC_X100_PCI_DEVICE_2255 0x2255 -#define MIC_X100_PCI_DEVICE_2256 0x2256 -#define MIC_X100_PCI_DEVICE_2257 0x2257 -#define MIC_X100_PCI_DEVICE_2258 0x2258 -#define MIC_X100_PCI_DEVICE_2259 0x2259 -#define MIC_X100_PCI_DEVICE_225a 0x225a -#define MIC_X100_PCI_DEVICE_225b 0x225b -#define MIC_X100_PCI_DEVICE_225c 0x225c -#define MIC_X100_PCI_DEVICE_225d 0x225d -#define MIC_X100_PCI_DEVICE_225e 0x225e - -#define MIC_X100_APER_BAR 0 -#define MIC_X100_MMIO_BAR 4 - -#define MIC_X100_SBOX_BASE_ADDRESS 0x00010000 -#define MIC_X100_SBOX_SPAD0 0x0000AB20 -#define MIC_X100_SBOX_SICR0_DBR(x) ((x) & 0xf) -#define MIC_X100_SBOX_SICR0_DMA(x) (((x) >> 8) & 0xff) -#define MIC_X100_SBOX_SICE0_DBR(x) ((x) & 0xf) -#define MIC_X100_SBOX_DBR_BITS(x) ((x) & 0xf) -#define MIC_X100_SBOX_SICE0_DMA(x) (((x) >> 8) & 0xff) -#define MIC_X100_SBOX_DMA_BITS(x) (((x) & 0xff) << 8) - -#define MIC_X100_SBOX_APICICR0 0x0000A9D0 -#define MIC_X100_SBOX_SICR0 0x00009004 -#define MIC_X100_SBOX_SICE0 0x0000900C -#define MIC_X100_SBOX_SICC0 0x00009010 -#define MIC_X100_SBOX_SIAC0 0x00009014 -#define MIC_X100_SBOX_MSIXPBACR 0x00009084 -#define MIC_X100_SBOX_MXAR0 0x00009044 -#define MIC_X100_SBOX_SMPT00 0x00003100 -#define MIC_X100_SBOX_RDMASR0 0x0000B180 - -#define MIC_X100_DOORBELL_IDX_START 0 -#define MIC_X100_NUM_DOORBELL 4 -#define MIC_X100_DMA_IDX_START 8 -#define MIC_X100_NUM_DMA 8 -#define MIC_X100_ERR_IDX_START 30 -#define MIC_X100_NUM_ERR 1 - -#define MIC_X100_NUM_SBOX_IRQ 8 -#define MIC_X100_NUM_RDMASR_IRQ 8 -#define MIC_X100_RDMASR_IRQ_BASE 17 -#define MIC_X100_SPAD2_DOWNLOAD_STATUS(x) ((x) & 0x1) -#define MIC_X100_SPAD2_APIC_ID(x) (((x) >> 1) & 0x1ff) -#define MIC_X100_SPAD2_DOWNLOAD_ADDR(x) ((x) & 0xfffff000) -#define MIC_X100_SBOX_APICICR7 0x0000AA08 -#define MIC_X100_SBOX_RGCR 0x00004010 -#define MIC_X100_SBOX_SDBIC0 0x0000CC90 -#define MIC_X100_DOWNLOAD_INFO 2 -#define MIC_X100_FW_SIZE 5 -#define MIC_X100_POSTCODE 0x242c - -/* Host->Card(bootstrap) Interrupt Vector */ -#define MIC_X100_BSP_INTERRUPT_VECTOR 229 - -extern struct mic_hw_ops mic_x100_ops; -extern struct mic_smpt_ops mic_x100_smpt_ops; -extern struct mic_hw_intr_ops mic_x100_intr_ops; - -#endif diff --git a/drivers/misc/mic/scif/Makefile b/drivers/misc/mic/scif/Makefile deleted file mode 100644 index ff372555d118..000000000000 --- a/drivers/misc/mic/scif/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile - SCIF driver. -# Copyright(c) 2014, Intel Corporation. -# -obj-$(CONFIG_SCIF) += scif.o -scif-objs := scif_main.o -scif-objs += scif_peer_bus.o -scif-objs += scif_ports.o -scif-objs += scif_debugfs.o -scif-objs += scif_fd.o -scif-objs += scif_api.o -scif-objs += scif_epd.o -scif-objs += scif_rb.o -scif-objs += scif_nodeqp.o -scif-objs += scif_nm.o -scif-objs += scif_dma.o -scif-objs += scif_fence.o -scif-objs += scif_mmap.o -scif-objs += scif_rma.o -scif-objs += scif_rma_list.o diff --git a/drivers/misc/mic/scif/scif_api.c b/drivers/misc/mic/scif/scif_api.c deleted file mode 100644 index 304d6c833712..000000000000 --- a/drivers/misc/mic/scif/scif_api.c +++ /dev/null @@ -1,1485 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#include <linux/scif.h> -#include "scif_main.h" -#include "scif_map.h" - -static const char * const scif_ep_states[] = { - "Unbound", - "Bound", - "Listening", - "Connected", - "Connecting", - "Mapping", - "Closing", - "Close Listening", - "Disconnected", - "Zombie"}; - -enum conn_async_state { - ASYNC_CONN_IDLE = 1, /* ep setup for async connect */ - ASYNC_CONN_INPROGRESS, /* async connect in progress */ - ASYNC_CONN_FLUSH_WORK /* async work flush in progress */ -}; - -/* - * File operations for anonymous inode file associated with a SCIF endpoint, - * used in kernel mode SCIF poll. Kernel mode SCIF poll calls portions of the - * poll API in the kernel and these take in a struct file *. Since a struct - * file is not available to kernel mode SCIF, it uses an anonymous file for - * this purpose. - */ -const struct file_operations scif_anon_fops = { - .owner = THIS_MODULE, -}; - -scif_epd_t scif_open(void) -{ - struct scif_endpt *ep; - int err; - - might_sleep(); - ep = kzalloc(sizeof(*ep), GFP_KERNEL); - if (!ep) - goto err_ep_alloc; - - ep->qp_info.qp = kzalloc(sizeof(*ep->qp_info.qp), GFP_KERNEL); - if (!ep->qp_info.qp) - goto err_qp_alloc; - - err = scif_anon_inode_getfile(ep); - if (err) - goto err_anon_inode; - - spin_lock_init(&ep->lock); - mutex_init(&ep->sendlock); - mutex_init(&ep->recvlock); - - scif_rma_ep_init(ep); - ep->state = SCIFEP_UNBOUND; - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI open: ep %p success\n", ep); - return ep; - -err_anon_inode: - kfree(ep->qp_info.qp); -err_qp_alloc: - kfree(ep); -err_ep_alloc: - return NULL; -} -EXPORT_SYMBOL_GPL(scif_open); - -/* - * scif_disconnect_ep - Disconnects the endpoint if found - * @epd: The end point returned from scif_open() - */ -static struct scif_endpt *scif_disconnect_ep(struct scif_endpt *ep) -{ - struct scifmsg msg; - struct scif_endpt *fep = NULL; - struct scif_endpt *tmpep; - struct list_head *pos, *tmpq; - int err; - - /* - * Wake up any threads blocked in send()/recv() before closing - * out the connection. Grabbing and releasing the send/recv lock - * will ensure that any blocked senders/receivers have exited for - * Ring 0 endpoints. It is a Ring 0 bug to call send/recv after - * close. Ring 3 endpoints are not affected since close will not - * be called while there are IOCTLs executing. - */ - wake_up_interruptible(&ep->sendwq); - wake_up_interruptible(&ep->recvwq); - mutex_lock(&ep->sendlock); - mutex_unlock(&ep->sendlock); - mutex_lock(&ep->recvlock); - mutex_unlock(&ep->recvlock); - - /* Remove from the connected list */ - mutex_lock(&scif_info.connlock); - list_for_each_safe(pos, tmpq, &scif_info.connected) { - tmpep = list_entry(pos, struct scif_endpt, list); - if (tmpep == ep) { - list_del(pos); - fep = tmpep; - spin_lock(&ep->lock); - break; - } - } - - if (!fep) { - /* - * The other side has completed the disconnect before - * the end point can be removed from the list. Therefore - * the ep lock is not locked, traverse the disconnected - * list to find the endpoint and release the conn lock. - */ - list_for_each_safe(pos, tmpq, &scif_info.disconnected) { - tmpep = list_entry(pos, struct scif_endpt, list); - if (tmpep == ep) { - list_del(pos); - break; - } - } - mutex_unlock(&scif_info.connlock); - return NULL; - } - - init_completion(&ep->discon); - msg.uop = SCIF_DISCNCT; - msg.src = ep->port; - msg.dst = ep->peer; - msg.payload[0] = (u64)ep; - msg.payload[1] = ep->remote_ep; - - err = scif_nodeqp_send(ep->remote_dev, &msg); - spin_unlock(&ep->lock); - mutex_unlock(&scif_info.connlock); - - if (!err) - /* Wait for the remote node to respond with SCIF_DISCNT_ACK */ - wait_for_completion_timeout(&ep->discon, - SCIF_NODE_ALIVE_TIMEOUT); - return ep; -} - -int scif_close(scif_epd_t epd) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - struct scif_endpt *tmpep; - struct list_head *pos, *tmpq; - enum scif_epd_state oldstate; - bool flush_conn; - - dev_dbg(scif_info.mdev.this_device, "SCIFAPI close: ep %p %s\n", - ep, scif_ep_states[ep->state]); - might_sleep(); - spin_lock(&ep->lock); - flush_conn = (ep->conn_async_state == ASYNC_CONN_INPROGRESS); - spin_unlock(&ep->lock); - - if (flush_conn) - flush_work(&scif_info.conn_work); - - spin_lock(&ep->lock); - oldstate = ep->state; - - ep->state = SCIFEP_CLOSING; - - switch (oldstate) { - case SCIFEP_ZOMBIE: - dev_err(scif_info.mdev.this_device, - "SCIFAPI close: zombie state unexpected\n"); - fallthrough; - case SCIFEP_DISCONNECTED: - spin_unlock(&ep->lock); - scif_unregister_all_windows(epd); - /* Remove from the disconnected list */ - mutex_lock(&scif_info.connlock); - list_for_each_safe(pos, tmpq, &scif_info.disconnected) { - tmpep = list_entry(pos, struct scif_endpt, list); - if (tmpep == ep) { - list_del(pos); - break; - } - } - mutex_unlock(&scif_info.connlock); - break; - case SCIFEP_UNBOUND: - case SCIFEP_BOUND: - case SCIFEP_CONNECTING: - spin_unlock(&ep->lock); - break; - case SCIFEP_MAPPING: - case SCIFEP_CONNECTED: - case SCIFEP_CLOSING: - { - spin_unlock(&ep->lock); - scif_unregister_all_windows(epd); - scif_disconnect_ep(ep); - break; - } - case SCIFEP_LISTENING: - case SCIFEP_CLLISTEN: - { - struct scif_conreq *conreq; - struct scifmsg msg; - struct scif_endpt *aep; - - spin_unlock(&ep->lock); - mutex_lock(&scif_info.eplock); - - /* remove from listen list */ - list_for_each_safe(pos, tmpq, &scif_info.listen) { - tmpep = list_entry(pos, struct scif_endpt, list); - if (tmpep == ep) - list_del(pos); - } - /* Remove any dangling accepts */ - while (ep->acceptcnt) { - aep = list_first_entry(&ep->li_accept, - struct scif_endpt, liacceptlist); - list_del(&aep->liacceptlist); - scif_put_port(aep->port.port); - list_for_each_safe(pos, tmpq, &scif_info.uaccept) { - tmpep = list_entry(pos, struct scif_endpt, - miacceptlist); - if (tmpep == aep) { - list_del(pos); - break; - } - } - mutex_unlock(&scif_info.eplock); - mutex_lock(&scif_info.connlock); - list_for_each_safe(pos, tmpq, &scif_info.connected) { - tmpep = list_entry(pos, - struct scif_endpt, list); - if (tmpep == aep) { - list_del(pos); - break; - } - } - list_for_each_safe(pos, tmpq, &scif_info.disconnected) { - tmpep = list_entry(pos, - struct scif_endpt, list); - if (tmpep == aep) { - list_del(pos); - break; - } - } - mutex_unlock(&scif_info.connlock); - scif_teardown_ep(aep); - mutex_lock(&scif_info.eplock); - scif_add_epd_to_zombie_list(aep, SCIF_EPLOCK_HELD); - ep->acceptcnt--; - } - - spin_lock(&ep->lock); - mutex_unlock(&scif_info.eplock); - - /* Remove and reject any pending connection requests. */ - while (ep->conreqcnt) { - conreq = list_first_entry(&ep->conlist, - struct scif_conreq, list); - list_del(&conreq->list); - - msg.uop = SCIF_CNCT_REJ; - msg.dst.node = conreq->msg.src.node; - msg.dst.port = conreq->msg.src.port; - msg.payload[0] = conreq->msg.payload[0]; - msg.payload[1] = conreq->msg.payload[1]; - /* - * No Error Handling on purpose for scif_nodeqp_send(). - * If the remote node is lost we still want free the - * connection requests on the self node. - */ - scif_nodeqp_send(&scif_dev[conreq->msg.src.node], - &msg); - ep->conreqcnt--; - kfree(conreq); - } - - spin_unlock(&ep->lock); - /* If a kSCIF accept is waiting wake it up */ - wake_up_interruptible(&ep->conwq); - break; - } - } - scif_put_port(ep->port.port); - scif_anon_inode_fput(ep); - scif_teardown_ep(ep); - scif_add_epd_to_zombie_list(ep, !SCIF_EPLOCK_HELD); - return 0; -} -EXPORT_SYMBOL_GPL(scif_close); - -/** - * scif_flush() - Wakes up any blocking accepts. The endpoint will no longer - * accept new connections. - * @epd: The end point returned from scif_open() - */ -int __scif_flush(scif_epd_t epd) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - - switch (ep->state) { - case SCIFEP_LISTENING: - { - ep->state = SCIFEP_CLLISTEN; - - /* If an accept is waiting wake it up */ - wake_up_interruptible(&ep->conwq); - break; - } - default: - break; - } - return 0; -} - -int scif_bind(scif_epd_t epd, u16 pn) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - int ret = 0; - int tmp; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI bind: ep %p %s requested port number %d\n", - ep, scif_ep_states[ep->state], pn); - if (pn) { - /* - * Similar to IETF RFC 1700, SCIF ports below - * SCIF_ADMIN_PORT_END can only be bound by system (or root) - * processes or by processes executed by privileged users. - */ - if (pn < SCIF_ADMIN_PORT_END && !capable(CAP_SYS_ADMIN)) { - ret = -EACCES; - goto scif_bind_admin_exit; - } - } - - spin_lock(&ep->lock); - if (ep->state == SCIFEP_BOUND) { - ret = -EINVAL; - goto scif_bind_exit; - } else if (ep->state != SCIFEP_UNBOUND) { - ret = -EISCONN; - goto scif_bind_exit; - } - - if (pn) { - tmp = scif_rsrv_port(pn); - if (tmp != pn) { - ret = -EINVAL; - goto scif_bind_exit; - } - } else { - ret = scif_get_new_port(); - if (ret < 0) - goto scif_bind_exit; - pn = ret; - } - - ep->state = SCIFEP_BOUND; - ep->port.node = scif_info.nodeid; - ep->port.port = pn; - ep->conn_async_state = ASYNC_CONN_IDLE; - ret = pn; - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI bind: bound to port number %d\n", pn); -scif_bind_exit: - spin_unlock(&ep->lock); -scif_bind_admin_exit: - return ret; -} -EXPORT_SYMBOL_GPL(scif_bind); - -int scif_listen(scif_epd_t epd, int backlog) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI listen: ep %p %s\n", ep, scif_ep_states[ep->state]); - spin_lock(&ep->lock); - switch (ep->state) { - case SCIFEP_ZOMBIE: - case SCIFEP_CLOSING: - case SCIFEP_CLLISTEN: - case SCIFEP_UNBOUND: - case SCIFEP_DISCONNECTED: - spin_unlock(&ep->lock); - return -EINVAL; - case SCIFEP_LISTENING: - case SCIFEP_CONNECTED: - case SCIFEP_CONNECTING: - case SCIFEP_MAPPING: - spin_unlock(&ep->lock); - return -EISCONN; - case SCIFEP_BOUND: - break; - } - - ep->state = SCIFEP_LISTENING; - ep->backlog = backlog; - - ep->conreqcnt = 0; - ep->acceptcnt = 0; - INIT_LIST_HEAD(&ep->conlist); - init_waitqueue_head(&ep->conwq); - INIT_LIST_HEAD(&ep->li_accept); - spin_unlock(&ep->lock); - - /* - * Listen status is complete so delete the qp information not needed - * on a listen before placing on the list of listening ep's - */ - scif_teardown_ep(ep); - ep->qp_info.qp = NULL; - - mutex_lock(&scif_info.eplock); - list_add_tail(&ep->list, &scif_info.listen); - mutex_unlock(&scif_info.eplock); - return 0; -} -EXPORT_SYMBOL_GPL(scif_listen); - -/* - ************************************************************************ - * SCIF connection flow: - * - * 1) A SCIF listening endpoint can call scif_accept(..) to wait for SCIF - * connections via a SCIF_CNCT_REQ message - * 2) A SCIF endpoint can initiate a SCIF connection by calling - * scif_connect(..) which calls scif_setup_qp_connect(..) which - * allocates the local qp for the endpoint ring buffer and then sends - * a SCIF_CNCT_REQ to the remote node and waits for a SCIF_CNCT_GNT or - * a SCIF_CNCT_REJ message - * 3) The peer node handles a SCIF_CNCT_REQ via scif_cnctreq_resp(..) which - * wakes up any threads blocked in step 1 or sends a SCIF_CNCT_REJ - * message otherwise - * 4) A thread blocked waiting for incoming connections allocates its local - * endpoint QP and ring buffer following which it sends a SCIF_CNCT_GNT - * and waits for a SCIF_CNCT_GNT(N)ACK. If the allocation fails then - * the node sends a SCIF_CNCT_REJ message - * 5) Upon receipt of a SCIF_CNCT_GNT or a SCIF_CNCT_REJ message the - * connecting endpoint is woken up as part of handling - * scif_cnctgnt_resp(..) following which it maps the remote endpoints' - * QP, updates its outbound QP and sends a SCIF_CNCT_GNTACK message on - * success or a SCIF_CNCT_GNTNACK message on failure and completes - * the scif_connect(..) API - * 6) Upon receipt of a SCIF_CNCT_GNT(N)ACK the accepting endpoint blocked - * in step 4 is woken up and completes the scif_accept(..) API - * 7) The SCIF connection is now established between the two SCIF endpoints. - */ -static int scif_conn_func(struct scif_endpt *ep) -{ - int err = 0; - struct scifmsg msg; - struct device *spdev; - - err = scif_reserve_dma_chan(ep); - if (err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); - ep->state = SCIFEP_BOUND; - goto connect_error_simple; - } - /* Initiate the first part of the endpoint QP setup */ - err = scif_setup_qp_connect(ep->qp_info.qp, &ep->qp_info.qp_offset, - SCIF_ENDPT_QP_SIZE, ep->remote_dev); - if (err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s err %d qp_offset 0x%llx\n", - __func__, err, ep->qp_info.qp_offset); - ep->state = SCIFEP_BOUND; - goto connect_error_simple; - } - - spdev = scif_get_peer_dev(ep->remote_dev); - if (IS_ERR(spdev)) { - err = PTR_ERR(spdev); - goto cleanup_qp; - } - /* Format connect message and send it */ - msg.src = ep->port; - msg.dst = ep->conn_port; - msg.uop = SCIF_CNCT_REQ; - msg.payload[0] = (u64)ep; - msg.payload[1] = ep->qp_info.qp_offset; - err = _scif_nodeqp_send(ep->remote_dev, &msg); - if (err) - goto connect_error_dec; - scif_put_peer_dev(spdev); - /* - * Wait for the remote node to respond with SCIF_CNCT_GNT or - * SCIF_CNCT_REJ message. - */ - err = wait_event_timeout(ep->conwq, ep->state != SCIFEP_CONNECTING, - SCIF_NODE_ALIVE_TIMEOUT); - if (!err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s %d timeout\n", __func__, __LINE__); - ep->state = SCIFEP_BOUND; - } - spdev = scif_get_peer_dev(ep->remote_dev); - if (IS_ERR(spdev)) { - err = PTR_ERR(spdev); - goto cleanup_qp; - } - if (ep->state == SCIFEP_MAPPING) { - err = scif_setup_qp_connect_response(ep->remote_dev, - ep->qp_info.qp, - ep->qp_info.gnt_pld); - /* - * If the resource to map the queue are not available then - * we need to tell the other side to terminate the accept - */ - if (err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); - msg.uop = SCIF_CNCT_GNTNACK; - msg.payload[0] = ep->remote_ep; - _scif_nodeqp_send(ep->remote_dev, &msg); - ep->state = SCIFEP_BOUND; - goto connect_error_dec; - } - - msg.uop = SCIF_CNCT_GNTACK; - msg.payload[0] = ep->remote_ep; - err = _scif_nodeqp_send(ep->remote_dev, &msg); - if (err) { - ep->state = SCIFEP_BOUND; - goto connect_error_dec; - } - ep->state = SCIFEP_CONNECTED; - mutex_lock(&scif_info.connlock); - list_add_tail(&ep->list, &scif_info.connected); - mutex_unlock(&scif_info.connlock); - dev_dbg(&ep->remote_dev->sdev->dev, - "SCIFAPI connect: ep %p connected\n", ep); - } else if (ep->state == SCIFEP_BOUND) { - dev_dbg(&ep->remote_dev->sdev->dev, - "SCIFAPI connect: ep %p connection refused\n", ep); - err = -ECONNREFUSED; - goto connect_error_dec; - } - scif_put_peer_dev(spdev); - return err; -connect_error_dec: - scif_put_peer_dev(spdev); -cleanup_qp: - scif_cleanup_ep_qp(ep); -connect_error_simple: - return err; -} - -/* - * scif_conn_handler: - * - * Workqueue handler for servicing non-blocking SCIF connect - * - */ -void scif_conn_handler(struct work_struct *work) -{ - struct scif_endpt *ep; - - do { - ep = NULL; - spin_lock(&scif_info.nb_connect_lock); - if (!list_empty(&scif_info.nb_connect_list)) { - ep = list_first_entry(&scif_info.nb_connect_list, - struct scif_endpt, conn_list); - list_del(&ep->conn_list); - } - spin_unlock(&scif_info.nb_connect_lock); - if (ep) { - ep->conn_err = scif_conn_func(ep); - wake_up_interruptible(&ep->conn_pend_wq); - } - } while (ep); -} - -int __scif_connect(scif_epd_t epd, struct scif_port_id *dst, bool non_block) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - int err = 0; - struct scif_dev *remote_dev; - struct device *spdev; - - dev_dbg(scif_info.mdev.this_device, "SCIFAPI connect: ep %p %s\n", ep, - scif_ep_states[ep->state]); - - if (!scif_dev || dst->node > scif_info.maxid) - return -ENODEV; - - might_sleep(); - - remote_dev = &scif_dev[dst->node]; - spdev = scif_get_peer_dev(remote_dev); - if (IS_ERR(spdev)) { - err = PTR_ERR(spdev); - return err; - } - - spin_lock(&ep->lock); - switch (ep->state) { - case SCIFEP_ZOMBIE: - case SCIFEP_CLOSING: - err = -EINVAL; - break; - case SCIFEP_DISCONNECTED: - if (ep->conn_async_state == ASYNC_CONN_INPROGRESS) - ep->conn_async_state = ASYNC_CONN_FLUSH_WORK; - else - err = -EINVAL; - break; - case SCIFEP_LISTENING: - case SCIFEP_CLLISTEN: - err = -EOPNOTSUPP; - break; - case SCIFEP_CONNECTING: - case SCIFEP_MAPPING: - if (ep->conn_async_state == ASYNC_CONN_INPROGRESS) - err = -EINPROGRESS; - else - err = -EISCONN; - break; - case SCIFEP_CONNECTED: - if (ep->conn_async_state == ASYNC_CONN_INPROGRESS) - ep->conn_async_state = ASYNC_CONN_FLUSH_WORK; - else - err = -EISCONN; - break; - case SCIFEP_UNBOUND: - err = scif_get_new_port(); - if (err < 0) - break; - ep->port.port = err; - ep->port.node = scif_info.nodeid; - ep->conn_async_state = ASYNC_CONN_IDLE; - fallthrough; - case SCIFEP_BOUND: - /* - * If a non-blocking connect has been already initiated - * (conn_async_state is either ASYNC_CONN_INPROGRESS or - * ASYNC_CONN_FLUSH_WORK), the end point could end up in - * SCIF_BOUND due an error in the connection process - * (e.g., connection refused) If conn_async_state is - * ASYNC_CONN_INPROGRESS - transition to ASYNC_CONN_FLUSH_WORK - * so that the error status can be collected. If the state is - * already ASYNC_CONN_FLUSH_WORK - then set the error to - * EINPROGRESS since some other thread is waiting to collect - * error status. - */ - if (ep->conn_async_state == ASYNC_CONN_INPROGRESS) { - ep->conn_async_state = ASYNC_CONN_FLUSH_WORK; - } else if (ep->conn_async_state == ASYNC_CONN_FLUSH_WORK) { - err = -EINPROGRESS; - } else { - ep->conn_port = *dst; - init_waitqueue_head(&ep->sendwq); - init_waitqueue_head(&ep->recvwq); - init_waitqueue_head(&ep->conwq); - ep->conn_async_state = 0; - - if (unlikely(non_block)) - ep->conn_async_state = ASYNC_CONN_INPROGRESS; - } - break; - } - - if (err || ep->conn_async_state == ASYNC_CONN_FLUSH_WORK) - goto connect_simple_unlock1; - - ep->state = SCIFEP_CONNECTING; - ep->remote_dev = &scif_dev[dst->node]; - ep->qp_info.qp->magic = SCIFEP_MAGIC; - if (ep->conn_async_state == ASYNC_CONN_INPROGRESS) { - init_waitqueue_head(&ep->conn_pend_wq); - spin_lock(&scif_info.nb_connect_lock); - list_add_tail(&ep->conn_list, &scif_info.nb_connect_list); - spin_unlock(&scif_info.nb_connect_lock); - err = -EINPROGRESS; - schedule_work(&scif_info.conn_work); - } -connect_simple_unlock1: - spin_unlock(&ep->lock); - scif_put_peer_dev(spdev); - if (err) { - return err; - } else if (ep->conn_async_state == ASYNC_CONN_FLUSH_WORK) { - flush_work(&scif_info.conn_work); - err = ep->conn_err; - spin_lock(&ep->lock); - ep->conn_async_state = ASYNC_CONN_IDLE; - spin_unlock(&ep->lock); - } else { - err = scif_conn_func(ep); - } - return err; -} - -int scif_connect(scif_epd_t epd, struct scif_port_id *dst) -{ - return __scif_connect(epd, dst, false); -} -EXPORT_SYMBOL_GPL(scif_connect); - -/* - * scif_accept() - Accept a connection request from the remote node - * - * The function accepts a connection request from the remote node. Successful - * complete is indicate by a new end point being created and passed back - * to the caller for future reference. - * - * Upon successful complete a zero will be returned and the peer information - * will be filled in. - * - * If the end point is not in the listening state -EINVAL will be returned. - * - * If during the connection sequence resource allocation fails the -ENOMEM - * will be returned. - * - * If the function is called with the ASYNC flag set and no connection requests - * are pending it will return -EAGAIN. - * - * If the remote side is not sending any connection requests the caller may - * terminate this function with a signal. If so a -EINTR will be returned. - */ -int scif_accept(scif_epd_t epd, struct scif_port_id *peer, - scif_epd_t *newepd, int flags) -{ - struct scif_endpt *lep = (struct scif_endpt *)epd; - struct scif_endpt *cep; - struct scif_conreq *conreq; - struct scifmsg msg; - int err; - struct device *spdev; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI accept: ep %p %s\n", lep, scif_ep_states[lep->state]); - - if (flags & ~SCIF_ACCEPT_SYNC) - return -EINVAL; - - if (!peer || !newepd) - return -EINVAL; - - might_sleep(); - spin_lock(&lep->lock); - if (lep->state != SCIFEP_LISTENING) { - spin_unlock(&lep->lock); - return -EINVAL; - } - - if (!lep->conreqcnt && !(flags & SCIF_ACCEPT_SYNC)) { - /* No connection request present and we do not want to wait */ - spin_unlock(&lep->lock); - return -EAGAIN; - } - - lep->files = current->files; -retry_connection: - spin_unlock(&lep->lock); - /* Wait for the remote node to send us a SCIF_CNCT_REQ */ - err = wait_event_interruptible(lep->conwq, - (lep->conreqcnt || - (lep->state != SCIFEP_LISTENING))); - if (err) - return err; - - if (lep->state != SCIFEP_LISTENING) - return -EINTR; - - spin_lock(&lep->lock); - - if (!lep->conreqcnt) - goto retry_connection; - - /* Get the first connect request off the list */ - conreq = list_first_entry(&lep->conlist, struct scif_conreq, list); - list_del(&conreq->list); - lep->conreqcnt--; - spin_unlock(&lep->lock); - - /* Fill in the peer information */ - peer->node = conreq->msg.src.node; - peer->port = conreq->msg.src.port; - - cep = kzalloc(sizeof(*cep), GFP_KERNEL); - if (!cep) { - err = -ENOMEM; - goto scif_accept_error_epalloc; - } - spin_lock_init(&cep->lock); - mutex_init(&cep->sendlock); - mutex_init(&cep->recvlock); - cep->state = SCIFEP_CONNECTING; - cep->remote_dev = &scif_dev[peer->node]; - cep->remote_ep = conreq->msg.payload[0]; - - scif_rma_ep_init(cep); - - err = scif_reserve_dma_chan(cep); - if (err) { - dev_err(scif_info.mdev.this_device, - "%s %d err %d\n", __func__, __LINE__, err); - goto scif_accept_error_qpalloc; - } - - cep->qp_info.qp = kzalloc(sizeof(*cep->qp_info.qp), GFP_KERNEL); - if (!cep->qp_info.qp) { - err = -ENOMEM; - goto scif_accept_error_qpalloc; - } - - err = scif_anon_inode_getfile(cep); - if (err) - goto scif_accept_error_anon_inode; - - cep->qp_info.qp->magic = SCIFEP_MAGIC; - spdev = scif_get_peer_dev(cep->remote_dev); - if (IS_ERR(spdev)) { - err = PTR_ERR(spdev); - goto scif_accept_error_map; - } - err = scif_setup_qp_accept(cep->qp_info.qp, &cep->qp_info.qp_offset, - conreq->msg.payload[1], SCIF_ENDPT_QP_SIZE, - cep->remote_dev); - if (err) { - dev_dbg(&cep->remote_dev->sdev->dev, - "SCIFAPI accept: ep %p new %p scif_setup_qp_accept %d qp_offset 0x%llx\n", - lep, cep, err, cep->qp_info.qp_offset); - scif_put_peer_dev(spdev); - goto scif_accept_error_map; - } - - cep->port.node = lep->port.node; - cep->port.port = lep->port.port; - cep->peer.node = peer->node; - cep->peer.port = peer->port; - init_waitqueue_head(&cep->sendwq); - init_waitqueue_head(&cep->recvwq); - init_waitqueue_head(&cep->conwq); - - msg.uop = SCIF_CNCT_GNT; - msg.src = cep->port; - msg.payload[0] = cep->remote_ep; - msg.payload[1] = cep->qp_info.qp_offset; - msg.payload[2] = (u64)cep; - - err = _scif_nodeqp_send(cep->remote_dev, &msg); - scif_put_peer_dev(spdev); - if (err) - goto scif_accept_error_map; -retry: - /* Wait for the remote node to respond with SCIF_CNCT_GNT(N)ACK */ - err = wait_event_timeout(cep->conwq, cep->state != SCIFEP_CONNECTING, - SCIF_NODE_ACCEPT_TIMEOUT); - if (!err && scifdev_alive(cep)) - goto retry; - err = !err ? -ENODEV : 0; - if (err) - goto scif_accept_error_map; - kfree(conreq); - - spin_lock(&cep->lock); - - if (cep->state == SCIFEP_CLOSING) { - /* - * Remote failed to allocate resources and NAKed the grant. - * There is at this point nothing referencing the new end point. - */ - spin_unlock(&cep->lock); - scif_teardown_ep(cep); - kfree(cep); - - /* If call with sync flag then go back and wait. */ - if (flags & SCIF_ACCEPT_SYNC) { - spin_lock(&lep->lock); - goto retry_connection; - } - return -EAGAIN; - } - - scif_get_port(cep->port.port); - *newepd = (scif_epd_t)cep; - spin_unlock(&cep->lock); - return 0; -scif_accept_error_map: - scif_anon_inode_fput(cep); -scif_accept_error_anon_inode: - scif_teardown_ep(cep); -scif_accept_error_qpalloc: - kfree(cep); -scif_accept_error_epalloc: - msg.uop = SCIF_CNCT_REJ; - msg.dst.node = conreq->msg.src.node; - msg.dst.port = conreq->msg.src.port; - msg.payload[0] = conreq->msg.payload[0]; - msg.payload[1] = conreq->msg.payload[1]; - scif_nodeqp_send(&scif_dev[conreq->msg.src.node], &msg); - kfree(conreq); - return err; -} -EXPORT_SYMBOL_GPL(scif_accept); - -/* - * scif_msg_param_check: - * @epd: The end point returned from scif_open() - * @len: Length to receive - * @flags: blocking or non blocking - * - * Validate parameters for messaging APIs scif_send(..)/scif_recv(..). - */ -static inline int scif_msg_param_check(scif_epd_t epd, int len, int flags) -{ - int ret = -EINVAL; - - if (len < 0) - goto err_ret; - if (flags && (!(flags & SCIF_RECV_BLOCK))) - goto err_ret; - ret = 0; -err_ret: - return ret; -} - -static int _scif_send(scif_epd_t epd, void *msg, int len, int flags) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - struct scifmsg notif_msg; - int curr_xfer_len = 0, sent_len = 0, write_count; - int ret = 0; - struct scif_qp *qp = ep->qp_info.qp; - - if (flags & SCIF_SEND_BLOCK) - might_sleep(); - - spin_lock(&ep->lock); - while (sent_len != len && SCIFEP_CONNECTED == ep->state) { - write_count = scif_rb_space(&qp->outbound_q); - if (write_count) { - /* Best effort to send as much data as possible */ - curr_xfer_len = min(len - sent_len, write_count); - ret = scif_rb_write(&qp->outbound_q, msg, - curr_xfer_len); - if (ret < 0) - break; - /* Success. Update write pointer */ - scif_rb_commit(&qp->outbound_q); - /* - * Send a notification to the peer about the - * produced data message. - */ - notif_msg.src = ep->port; - notif_msg.uop = SCIF_CLIENT_SENT; - notif_msg.payload[0] = ep->remote_ep; - ret = _scif_nodeqp_send(ep->remote_dev, ¬if_msg); - if (ret) - break; - sent_len += curr_xfer_len; - msg = msg + curr_xfer_len; - continue; - } - curr_xfer_len = min(len - sent_len, SCIF_ENDPT_QP_SIZE - 1); - /* Not enough RB space. return for the Non Blocking case */ - if (!(flags & SCIF_SEND_BLOCK)) - break; - - spin_unlock(&ep->lock); - /* Wait for a SCIF_CLIENT_RCVD message in the Blocking case */ - ret = - wait_event_interruptible(ep->sendwq, - (SCIFEP_CONNECTED != ep->state) || - (scif_rb_space(&qp->outbound_q) >= - curr_xfer_len)); - spin_lock(&ep->lock); - if (ret) - break; - } - if (sent_len) - ret = sent_len; - else if (!ret && SCIFEP_CONNECTED != ep->state) - ret = SCIFEP_DISCONNECTED == ep->state ? - -ECONNRESET : -ENOTCONN; - spin_unlock(&ep->lock); - return ret; -} - -static int _scif_recv(scif_epd_t epd, void *msg, int len, int flags) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - struct scifmsg notif_msg; - int curr_recv_len = 0, remaining_len = len, read_count; - int ret = 0; - struct scif_qp *qp = ep->qp_info.qp; - - if (flags & SCIF_RECV_BLOCK) - might_sleep(); - spin_lock(&ep->lock); - while (remaining_len && (SCIFEP_CONNECTED == ep->state || - SCIFEP_DISCONNECTED == ep->state)) { - read_count = scif_rb_count(&qp->inbound_q, remaining_len); - if (read_count) { - /* - * Best effort to recv as much data as there - * are bytes to read in the RB particularly - * important for the Non Blocking case. - */ - curr_recv_len = min(remaining_len, read_count); - scif_rb_get_next(&qp->inbound_q, msg, curr_recv_len); - if (ep->state == SCIFEP_CONNECTED) { - /* - * Update the read pointer only if the endpoint - * is still connected else the read pointer - * might no longer exist since the peer has - * freed resources! - */ - scif_rb_update_read_ptr(&qp->inbound_q); - /* - * Send a notification to the peer about the - * consumed data message only if the EP is in - * SCIFEP_CONNECTED state. - */ - notif_msg.src = ep->port; - notif_msg.uop = SCIF_CLIENT_RCVD; - notif_msg.payload[0] = ep->remote_ep; - ret = _scif_nodeqp_send(ep->remote_dev, - ¬if_msg); - if (ret) - break; - } - remaining_len -= curr_recv_len; - msg = msg + curr_recv_len; - continue; - } - /* - * Bail out now if the EP is in SCIFEP_DISCONNECTED state else - * we will keep looping forever. - */ - if (ep->state == SCIFEP_DISCONNECTED) - break; - /* - * Return in the Non Blocking case if there is no data - * to read in this iteration. - */ - if (!(flags & SCIF_RECV_BLOCK)) - break; - curr_recv_len = min(remaining_len, SCIF_ENDPT_QP_SIZE - 1); - spin_unlock(&ep->lock); - /* - * Wait for a SCIF_CLIENT_SEND message in the blocking case - * or until other side disconnects. - */ - ret = - wait_event_interruptible(ep->recvwq, - SCIFEP_CONNECTED != ep->state || - scif_rb_count(&qp->inbound_q, - curr_recv_len) - >= curr_recv_len); - spin_lock(&ep->lock); - if (ret) - break; - } - if (len - remaining_len) - ret = len - remaining_len; - else if (!ret && ep->state != SCIFEP_CONNECTED) - ret = ep->state == SCIFEP_DISCONNECTED ? - -ECONNRESET : -ENOTCONN; - spin_unlock(&ep->lock); - return ret; -} - -/** - * scif_user_send() - Send data to connection queue - * @epd: The end point returned from scif_open() - * @msg: Address to place data - * @len: Length to receive - * @flags: blocking or non blocking - * - * This function is called from the driver IOCTL entry point - * only and is a wrapper for _scif_send(). - */ -int scif_user_send(scif_epd_t epd, void __user *msg, int len, int flags) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - int err = 0; - int sent_len = 0; - char *tmp; - int loop_len; - int chunk_len = min(len, (1 << (MAX_ORDER + PAGE_SHIFT - 1))); - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI send (U): ep %p %s\n", ep, scif_ep_states[ep->state]); - if (!len) - return 0; - - err = scif_msg_param_check(epd, len, flags); - if (err) - goto send_err; - - tmp = kmalloc(chunk_len, GFP_KERNEL); - if (!tmp) { - err = -ENOMEM; - goto send_err; - } - /* - * Grabbing the lock before breaking up the transfer in - * multiple chunks is required to ensure that messages do - * not get fragmented and reordered. - */ - mutex_lock(&ep->sendlock); - while (sent_len != len) { - loop_len = len - sent_len; - loop_len = min(chunk_len, loop_len); - if (copy_from_user(tmp, msg, loop_len)) { - err = -EFAULT; - goto send_free_err; - } - err = _scif_send(epd, tmp, loop_len, flags); - if (err < 0) - goto send_free_err; - sent_len += err; - msg += err; - if (err != loop_len) - goto send_free_err; - } -send_free_err: - mutex_unlock(&ep->sendlock); - kfree(tmp); -send_err: - return err < 0 ? err : sent_len; -} - -/** - * scif_user_recv() - Receive data from connection queue - * @epd: The end point returned from scif_open() - * @msg: Address to place data - * @len: Length to receive - * @flags: blocking or non blocking - * - * This function is called from the driver IOCTL entry point - * only and is a wrapper for _scif_recv(). - */ -int scif_user_recv(scif_epd_t epd, void __user *msg, int len, int flags) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - int err = 0; - int recv_len = 0; - char *tmp; - int loop_len; - int chunk_len = min(len, (1 << (MAX_ORDER + PAGE_SHIFT - 1))); - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI recv (U): ep %p %s\n", ep, scif_ep_states[ep->state]); - if (!len) - return 0; - - err = scif_msg_param_check(epd, len, flags); - if (err) - goto recv_err; - - tmp = kmalloc(chunk_len, GFP_KERNEL); - if (!tmp) { - err = -ENOMEM; - goto recv_err; - } - /* - * Grabbing the lock before breaking up the transfer in - * multiple chunks is required to ensure that messages do - * not get fragmented and reordered. - */ - mutex_lock(&ep->recvlock); - while (recv_len != len) { - loop_len = len - recv_len; - loop_len = min(chunk_len, loop_len); - err = _scif_recv(epd, tmp, loop_len, flags); - if (err < 0) - goto recv_free_err; - if (copy_to_user(msg, tmp, err)) { - err = -EFAULT; - goto recv_free_err; - } - recv_len += err; - msg += err; - if (err != loop_len) - goto recv_free_err; - } -recv_free_err: - mutex_unlock(&ep->recvlock); - kfree(tmp); -recv_err: - return err < 0 ? err : recv_len; -} - -/** - * scif_send() - Send data to connection queue - * @epd: The end point returned from scif_open() - * @msg: Address to place data - * @len: Length to receive - * @flags: blocking or non blocking - * - * This function is called from the kernel mode only and is - * a wrapper for _scif_send(). - */ -int scif_send(scif_epd_t epd, void *msg, int len, int flags) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - int ret; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI send (K): ep %p %s\n", ep, scif_ep_states[ep->state]); - if (!len) - return 0; - - ret = scif_msg_param_check(epd, len, flags); - if (ret) - return ret; - if (!ep->remote_dev) - return -ENOTCONN; - /* - * Grab the mutex lock in the blocking case only - * to ensure messages do not get fragmented/reordered. - * The non blocking mode is protected using spin locks - * in _scif_send(). - */ - if (flags & SCIF_SEND_BLOCK) - mutex_lock(&ep->sendlock); - - ret = _scif_send(epd, msg, len, flags); - - if (flags & SCIF_SEND_BLOCK) - mutex_unlock(&ep->sendlock); - return ret; -} -EXPORT_SYMBOL_GPL(scif_send); - -/** - * scif_recv() - Receive data from connection queue - * @epd: The end point returned from scif_open() - * @msg: Address to place data - * @len: Length to receive - * @flags: blocking or non blocking - * - * This function is called from the kernel mode only and is - * a wrapper for _scif_recv(). - */ -int scif_recv(scif_epd_t epd, void *msg, int len, int flags) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - int ret; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI recv (K): ep %p %s\n", ep, scif_ep_states[ep->state]); - if (!len) - return 0; - - ret = scif_msg_param_check(epd, len, flags); - if (ret) - return ret; - /* - * Grab the mutex lock in the blocking case only - * to ensure messages do not get fragmented/reordered. - * The non blocking mode is protected using spin locks - * in _scif_send(). - */ - if (flags & SCIF_RECV_BLOCK) - mutex_lock(&ep->recvlock); - - ret = _scif_recv(epd, msg, len, flags); - - if (flags & SCIF_RECV_BLOCK) - mutex_unlock(&ep->recvlock); - - return ret; -} -EXPORT_SYMBOL_GPL(scif_recv); - -static inline void _scif_poll_wait(struct file *f, wait_queue_head_t *wq, - poll_table *p, struct scif_endpt *ep) -{ - /* - * Because poll_wait makes a GFP_KERNEL allocation, give up the lock - * and regrab it afterwards. Because the endpoint state might have - * changed while the lock was given up, the state must be checked - * again after re-acquiring the lock. The code in __scif_pollfd(..) - * does this. - */ - spin_unlock(&ep->lock); - poll_wait(f, wq, p); - spin_lock(&ep->lock); -} - -__poll_t -__scif_pollfd(struct file *f, poll_table *wait, struct scif_endpt *ep) -{ - __poll_t mask = 0; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI pollfd: ep %p %s\n", ep, scif_ep_states[ep->state]); - - spin_lock(&ep->lock); - - /* Endpoint is waiting for a non-blocking connect to complete */ - if (ep->conn_async_state == ASYNC_CONN_INPROGRESS) { - _scif_poll_wait(f, &ep->conn_pend_wq, wait, ep); - if (ep->conn_async_state == ASYNC_CONN_INPROGRESS) { - if (ep->state == SCIFEP_CONNECTED || - ep->state == SCIFEP_DISCONNECTED || - ep->conn_err) - mask |= EPOLLOUT; - goto exit; - } - } - - /* Endpoint is listening for incoming connection requests */ - if (ep->state == SCIFEP_LISTENING) { - _scif_poll_wait(f, &ep->conwq, wait, ep); - if (ep->state == SCIFEP_LISTENING) { - if (ep->conreqcnt) - mask |= EPOLLIN; - goto exit; - } - } - - /* Endpoint is connected or disconnected */ - if (ep->state == SCIFEP_CONNECTED || ep->state == SCIFEP_DISCONNECTED) { - if (poll_requested_events(wait) & EPOLLIN) - _scif_poll_wait(f, &ep->recvwq, wait, ep); - if (poll_requested_events(wait) & EPOLLOUT) - _scif_poll_wait(f, &ep->sendwq, wait, ep); - if (ep->state == SCIFEP_CONNECTED || - ep->state == SCIFEP_DISCONNECTED) { - /* Data can be read without blocking */ - if (scif_rb_count(&ep->qp_info.qp->inbound_q, 1)) - mask |= EPOLLIN; - /* Data can be written without blocking */ - if (scif_rb_space(&ep->qp_info.qp->outbound_q)) - mask |= EPOLLOUT; - /* Return EPOLLHUP if endpoint is disconnected */ - if (ep->state == SCIFEP_DISCONNECTED) - mask |= EPOLLHUP; - goto exit; - } - } - - /* Return EPOLLERR if the endpoint is in none of the above states */ - mask |= EPOLLERR; -exit: - spin_unlock(&ep->lock); - return mask; -} - -/** - * scif_poll() - Kernel mode SCIF poll - * @ufds: Array of scif_pollepd structures containing the end points - * and events to poll on - * @nfds: Size of the ufds array - * @timeout_msecs: Timeout in msecs, -ve implies infinite timeout - * - * The code flow in this function is based on do_poll(..) in select.c - * - * Returns the number of endpoints which have pending events or 0 in - * the event of a timeout. If a signal is used for wake up, -EINTR is - * returned. - */ -int -scif_poll(struct scif_pollepd *ufds, unsigned int nfds, long timeout_msecs) -{ - struct poll_wqueues table; - poll_table *pt; - int i, count = 0, timed_out = timeout_msecs == 0; - __poll_t mask; - u64 timeout = timeout_msecs < 0 ? MAX_SCHEDULE_TIMEOUT - : msecs_to_jiffies(timeout_msecs); - - poll_initwait(&table); - pt = &table.pt; - while (1) { - for (i = 0; i < nfds; i++) { - pt->_key = ufds[i].events | EPOLLERR | EPOLLHUP; - mask = __scif_pollfd(ufds[i].epd->anon, - pt, ufds[i].epd); - mask &= ufds[i].events | EPOLLERR | EPOLLHUP; - if (mask) { - count++; - pt->_qproc = NULL; - } - ufds[i].revents = mask; - } - pt->_qproc = NULL; - if (!count) { - count = table.error; - if (signal_pending(current)) - count = -EINTR; - } - if (count || timed_out) - break; - - if (!schedule_timeout_interruptible(timeout)) - timed_out = 1; - } - poll_freewait(&table); - return count; -} -EXPORT_SYMBOL_GPL(scif_poll); - -int scif_get_node_ids(u16 *nodes, int len, u16 *self) -{ - int online = 0; - int offset = 0; - int node; - - if (!scif_is_mgmt_node()) - scif_get_node_info(); - - *self = scif_info.nodeid; - mutex_lock(&scif_info.conflock); - len = min_t(int, len, scif_info.total); - for (node = 0; node <= scif_info.maxid; node++) { - if (_scifdev_alive(&scif_dev[node])) { - online++; - if (offset < len) - nodes[offset++] = node; - } - } - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI get_node_ids total %d online %d filled in %d nodes\n", - scif_info.total, online, offset); - mutex_unlock(&scif_info.conflock); - - return online; -} -EXPORT_SYMBOL_GPL(scif_get_node_ids); - -static int scif_add_client_dev(struct device *dev, struct subsys_interface *si) -{ - struct scif_client *client = - container_of(si, struct scif_client, si); - struct scif_peer_dev *spdev = - container_of(dev, struct scif_peer_dev, dev); - - if (client->probe) - client->probe(spdev); - return 0; -} - -static void scif_remove_client_dev(struct device *dev, - struct subsys_interface *si) -{ - struct scif_client *client = - container_of(si, struct scif_client, si); - struct scif_peer_dev *spdev = - container_of(dev, struct scif_peer_dev, dev); - - if (client->remove) - client->remove(spdev); -} - -void scif_client_unregister(struct scif_client *client) -{ - subsys_interface_unregister(&client->si); -} -EXPORT_SYMBOL_GPL(scif_client_unregister); - -int scif_client_register(struct scif_client *client) -{ - struct subsys_interface *si = &client->si; - - si->name = client->name; - si->subsys = &scif_peer_bus; - si->add_dev = scif_add_client_dev; - si->remove_dev = scif_remove_client_dev; - - return subsys_interface_register(&client->si); -} -EXPORT_SYMBOL_GPL(scif_client_register); diff --git a/drivers/misc/mic/scif/scif_debugfs.c b/drivers/misc/mic/scif/scif_debugfs.c deleted file mode 100644 index 8fe38e7ca6e6..000000000000 --- a/drivers/misc/mic/scif/scif_debugfs.c +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#include <linux/debugfs.h> -#include <linux/seq_file.h> - -#include "../common/mic_dev.h" -#include "scif_main.h" - -/* Debugfs parent dir */ -static struct dentry *scif_dbg; - -static int scif_dev_show(struct seq_file *s, void *unused) -{ - int node; - - seq_printf(s, "Total Nodes %d Self Node Id %d Maxid %d\n", - scif_info.total, scif_info.nodeid, - scif_info.maxid); - - if (!scif_dev) - return 0; - - seq_printf(s, "%-16s\t%-16s\n", "node_id", "state"); - - for (node = 0; node <= scif_info.maxid; node++) - seq_printf(s, "%-16d\t%-16s\n", scif_dev[node].node, - _scifdev_alive(&scif_dev[node]) ? - "Running" : "Offline"); - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(scif_dev); - -static void scif_display_window(struct scif_window *window, struct seq_file *s) -{ - int j; - struct scatterlist *sg; - scif_pinned_pages_t pin = window->pinned_pages; - - seq_printf(s, "window %p type %d temp %d offset 0x%llx ", - window, window->type, window->temp, window->offset); - seq_printf(s, "nr_pages 0x%llx nr_contig_chunks 0x%x prot %d ", - window->nr_pages, window->nr_contig_chunks, window->prot); - seq_printf(s, "ref_count %d magic 0x%llx peer_window 0x%llx ", - window->ref_count, window->magic, window->peer_window); - seq_printf(s, "unreg_state 0x%x va_for_temp 0x%lx\n", - window->unreg_state, window->va_for_temp); - - for (j = 0; j < window->nr_contig_chunks; j++) - seq_printf(s, "page[%d] dma_addr 0x%llx num_pages 0x%llx\n", j, - window->dma_addr[j], window->num_pages[j]); - - if (window->type == SCIF_WINDOW_SELF && pin) - for (j = 0; j < window->nr_pages; j++) - seq_printf(s, "page[%d] = pinned_pages %p address %p\n", - j, pin->pages[j], - page_address(pin->pages[j])); - - if (window->st) - for_each_sg(window->st->sgl, sg, window->st->nents, j) - seq_printf(s, "sg[%d] dma addr 0x%llx length 0x%x\n", - j, sg_dma_address(sg), sg_dma_len(sg)); -} - -static void scif_display_all_windows(struct list_head *head, struct seq_file *s) -{ - struct list_head *item; - struct scif_window *window; - - list_for_each(item, head) { - window = list_entry(item, struct scif_window, list); - scif_display_window(window, s); - } -} - -static int scif_rma_show(struct seq_file *s, void *unused) -{ - struct scif_endpt *ep; - struct list_head *pos; - - mutex_lock(&scif_info.connlock); - list_for_each(pos, &scif_info.connected) { - ep = list_entry(pos, struct scif_endpt, list); - seq_printf(s, "ep %p self windows\n", ep); - mutex_lock(&ep->rma_info.rma_lock); - scif_display_all_windows(&ep->rma_info.reg_list, s); - seq_printf(s, "ep %p remote windows\n", ep); - scif_display_all_windows(&ep->rma_info.remote_reg_list, s); - mutex_unlock(&ep->rma_info.rma_lock); - } - mutex_unlock(&scif_info.connlock); - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(scif_rma); - -void __init scif_init_debugfs(void) -{ - scif_dbg = debugfs_create_dir(KBUILD_MODNAME, NULL); - - debugfs_create_file("scif_dev", 0444, scif_dbg, NULL, &scif_dev_fops); - debugfs_create_file("scif_rma", 0444, scif_dbg, NULL, &scif_rma_fops); - debugfs_create_u8("en_msg_log", 0666, scif_dbg, &scif_info.en_msg_log); - debugfs_create_u8("p2p_enable", 0666, scif_dbg, &scif_info.p2p_enable); -} - -void scif_exit_debugfs(void) -{ - debugfs_remove_recursive(scif_dbg); -} diff --git a/drivers/misc/mic/scif/scif_dma.c b/drivers/misc/mic/scif/scif_dma.c deleted file mode 100644 index 401b98e5ad79..000000000000 --- a/drivers/misc/mic/scif/scif_dma.c +++ /dev/null @@ -1,1940 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel SCIF driver. - */ -#include "scif_main.h" -#include "scif_map.h" - -/* - * struct scif_dma_comp_cb - SCIF DMA completion callback - * - * @dma_completion_func: DMA completion callback - * @cb_cookie: DMA completion callback cookie - * @temp_buf: Temporary buffer - * @temp_buf_to_free: Temporary buffer to be freed - * @is_cache: Is a kmem_cache allocated buffer - * @dst_offset: Destination registration offset - * @dst_window: Destination registration window - * @len: Length of the temp buffer - * @temp_phys: DMA address of the temp buffer - * @sdev: The SCIF device - * @header_padding: padding for cache line alignment - */ -struct scif_dma_comp_cb { - void (*dma_completion_func)(void *cookie); - void *cb_cookie; - u8 *temp_buf; - u8 *temp_buf_to_free; - bool is_cache; - s64 dst_offset; - struct scif_window *dst_window; - size_t len; - dma_addr_t temp_phys; - struct scif_dev *sdev; - int header_padding; -}; - -/** - * struct scif_copy_work - Work for DMA copy - * - * @src_offset: Starting source offset - * @dst_offset: Starting destination offset - * @src_window: Starting src registered window - * @dst_window: Starting dst registered window - * @loopback: true if this is a loopback DMA transfer - * @len: Length of the transfer - * @comp_cb: DMA copy completion callback - * @remote_dev: The remote SCIF peer device - * @fence_type: polling or interrupt based - * @ordered: is this a tail byte ordered DMA transfer - */ -struct scif_copy_work { - s64 src_offset; - s64 dst_offset; - struct scif_window *src_window; - struct scif_window *dst_window; - int loopback; - size_t len; - struct scif_dma_comp_cb *comp_cb; - struct scif_dev *remote_dev; - int fence_type; - bool ordered; -}; - -/** - * scif_reserve_dma_chan: - * @ep: Endpoint Descriptor. - * - * This routine reserves a DMA channel for a particular - * endpoint. All DMA transfers for an endpoint are always - * programmed on the same DMA channel. - */ -int scif_reserve_dma_chan(struct scif_endpt *ep) -{ - int err = 0; - struct scif_dev *scifdev; - struct scif_hw_dev *sdev; - struct dma_chan *chan; - - /* Loopback DMAs are not supported on the management node */ - if (!scif_info.nodeid && scifdev_self(ep->remote_dev)) - return 0; - if (scif_info.nodeid) - scifdev = &scif_dev[0]; - else - scifdev = ep->remote_dev; - sdev = scifdev->sdev; - if (!sdev->num_dma_ch) - return -ENODEV; - chan = sdev->dma_ch[scifdev->dma_ch_idx]; - scifdev->dma_ch_idx = (scifdev->dma_ch_idx + 1) % sdev->num_dma_ch; - mutex_lock(&ep->rma_info.rma_lock); - ep->rma_info.dma_chan = chan; - mutex_unlock(&ep->rma_info.rma_lock); - return err; -} - -#ifdef CONFIG_MMU_NOTIFIER -/* - * scif_rma_destroy_tcw: - * - * This routine destroys temporary cached windows - */ -static -void __scif_rma_destroy_tcw(struct scif_mmu_notif *mmn, - u64 start, u64 len) -{ - struct list_head *item, *tmp; - struct scif_window *window; - u64 start_va, end_va; - u64 end = start + len; - - if (end <= start) - return; - - list_for_each_safe(item, tmp, &mmn->tc_reg_list) { - window = list_entry(item, struct scif_window, list); - if (!len) - break; - start_va = window->va_for_temp; - end_va = start_va + (window->nr_pages << PAGE_SHIFT); - if (start < start_va && end <= start_va) - break; - if (start >= end_va) - continue; - __scif_rma_destroy_tcw_helper(window); - } -} - -static void scif_rma_destroy_tcw(struct scif_mmu_notif *mmn, u64 start, u64 len) -{ - struct scif_endpt *ep = mmn->ep; - - spin_lock(&ep->rma_info.tc_lock); - __scif_rma_destroy_tcw(mmn, start, len); - spin_unlock(&ep->rma_info.tc_lock); -} - -static void scif_rma_destroy_tcw_ep(struct scif_endpt *ep) -{ - struct list_head *item, *tmp; - struct scif_mmu_notif *mmn; - - list_for_each_safe(item, tmp, &ep->rma_info.mmn_list) { - mmn = list_entry(item, struct scif_mmu_notif, list); - scif_rma_destroy_tcw(mmn, 0, ULONG_MAX); - } -} - -static void __scif_rma_destroy_tcw_ep(struct scif_endpt *ep) -{ - struct list_head *item, *tmp; - struct scif_mmu_notif *mmn; - - spin_lock(&ep->rma_info.tc_lock); - list_for_each_safe(item, tmp, &ep->rma_info.mmn_list) { - mmn = list_entry(item, struct scif_mmu_notif, list); - __scif_rma_destroy_tcw(mmn, 0, ULONG_MAX); - } - spin_unlock(&ep->rma_info.tc_lock); -} - -static bool scif_rma_tc_can_cache(struct scif_endpt *ep, size_t cur_bytes) -{ - if ((cur_bytes >> PAGE_SHIFT) > scif_info.rma_tc_limit) - return false; - if ((atomic_read(&ep->rma_info.tcw_total_pages) - + (cur_bytes >> PAGE_SHIFT)) > - scif_info.rma_tc_limit) { - dev_info(scif_info.mdev.this_device, - "%s %d total=%d, current=%zu reached max\n", - __func__, __LINE__, - atomic_read(&ep->rma_info.tcw_total_pages), - (1 + (cur_bytes >> PAGE_SHIFT))); - scif_rma_destroy_tcw_invalid(); - __scif_rma_destroy_tcw_ep(ep); - } - return true; -} - -static void scif_mmu_notifier_release(struct mmu_notifier *mn, - struct mm_struct *mm) -{ - struct scif_mmu_notif *mmn; - - mmn = container_of(mn, struct scif_mmu_notif, ep_mmu_notifier); - scif_rma_destroy_tcw(mmn, 0, ULONG_MAX); - schedule_work(&scif_info.misc_work); -} - -static int scif_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn, - const struct mmu_notifier_range *range) -{ - struct scif_mmu_notif *mmn; - - mmn = container_of(mn, struct scif_mmu_notif, ep_mmu_notifier); - scif_rma_destroy_tcw(mmn, range->start, range->end - range->start); - - return 0; -} - -static void scif_mmu_notifier_invalidate_range_end(struct mmu_notifier *mn, - const struct mmu_notifier_range *range) -{ - /* - * Nothing to do here, everything needed was done in - * invalidate_range_start. - */ -} - -static const struct mmu_notifier_ops scif_mmu_notifier_ops = { - .release = scif_mmu_notifier_release, - .clear_flush_young = NULL, - .invalidate_range_start = scif_mmu_notifier_invalidate_range_start, - .invalidate_range_end = scif_mmu_notifier_invalidate_range_end}; - -static void scif_ep_unregister_mmu_notifier(struct scif_endpt *ep) -{ - struct scif_endpt_rma_info *rma = &ep->rma_info; - struct scif_mmu_notif *mmn = NULL; - struct list_head *item, *tmp; - - mutex_lock(&ep->rma_info.mmn_lock); - list_for_each_safe(item, tmp, &rma->mmn_list) { - mmn = list_entry(item, struct scif_mmu_notif, list); - mmu_notifier_unregister(&mmn->ep_mmu_notifier, mmn->mm); - list_del(item); - kfree(mmn); - } - mutex_unlock(&ep->rma_info.mmn_lock); -} - -static void scif_init_mmu_notifier(struct scif_mmu_notif *mmn, - struct mm_struct *mm, struct scif_endpt *ep) -{ - mmn->ep = ep; - mmn->mm = mm; - mmn->ep_mmu_notifier.ops = &scif_mmu_notifier_ops; - INIT_LIST_HEAD(&mmn->list); - INIT_LIST_HEAD(&mmn->tc_reg_list); -} - -static struct scif_mmu_notif * -scif_find_mmu_notifier(struct mm_struct *mm, struct scif_endpt_rma_info *rma) -{ - struct scif_mmu_notif *mmn; - - list_for_each_entry(mmn, &rma->mmn_list, list) - if (mmn->mm == mm) - return mmn; - return NULL; -} - -static struct scif_mmu_notif * -scif_add_mmu_notifier(struct mm_struct *mm, struct scif_endpt *ep) -{ - struct scif_mmu_notif *mmn - = kzalloc(sizeof(*mmn), GFP_KERNEL); - - if (!mmn) - return ERR_PTR(-ENOMEM); - - scif_init_mmu_notifier(mmn, current->mm, ep); - if (mmu_notifier_register(&mmn->ep_mmu_notifier, current->mm)) { - kfree(mmn); - return ERR_PTR(-EBUSY); - } - list_add(&mmn->list, &ep->rma_info.mmn_list); - return mmn; -} - -/* - * Called from the misc thread to destroy temporary cached windows and - * unregister the MMU notifier for the SCIF endpoint. - */ -void scif_mmu_notif_handler(struct work_struct *work) -{ - struct list_head *pos, *tmpq; - struct scif_endpt *ep; -restart: - scif_rma_destroy_tcw_invalid(); - spin_lock(&scif_info.rmalock); - list_for_each_safe(pos, tmpq, &scif_info.mmu_notif_cleanup) { - ep = list_entry(pos, struct scif_endpt, mmu_list); - list_del(&ep->mmu_list); - spin_unlock(&scif_info.rmalock); - scif_rma_destroy_tcw_ep(ep); - scif_ep_unregister_mmu_notifier(ep); - goto restart; - } - spin_unlock(&scif_info.rmalock); -} - -static bool scif_is_set_reg_cache(int flags) -{ - return !!(flags & SCIF_RMA_USECACHE); -} -#else -static struct scif_mmu_notif * -scif_find_mmu_notifier(struct mm_struct *mm, - struct scif_endpt_rma_info *rma) -{ - return NULL; -} - -static struct scif_mmu_notif * -scif_add_mmu_notifier(struct mm_struct *mm, struct scif_endpt *ep) -{ - return NULL; -} - -void scif_mmu_notif_handler(struct work_struct *work) -{ -} - -static bool scif_is_set_reg_cache(int flags) -{ - return false; -} - -static bool scif_rma_tc_can_cache(struct scif_endpt *ep, size_t cur_bytes) -{ - return false; -} -#endif - -/** - * scif_register_temp: - * @epd: End Point Descriptor. - * @addr: virtual address to/from which to copy - * @len: length of range to copy - * @prot: read/write protection - * @out_offset: computed offset returned by reference. - * @out_window: allocated registered window returned by reference. - * - * Create a temporary registered window. The peer will not know about this - * window. This API is used for scif_vreadfrom()/scif_vwriteto() API's. - */ -static int -scif_register_temp(scif_epd_t epd, unsigned long addr, size_t len, int prot, - off_t *out_offset, struct scif_window **out_window) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - int err; - scif_pinned_pages_t pinned_pages; - size_t aligned_len; - - aligned_len = ALIGN(len, PAGE_SIZE); - - err = __scif_pin_pages((void *)(addr & PAGE_MASK), - aligned_len, &prot, 0, &pinned_pages); - if (err) - return err; - - pinned_pages->prot = prot; - - /* Compute the offset for this registration */ - err = scif_get_window_offset(ep, 0, 0, - aligned_len >> PAGE_SHIFT, - (s64 *)out_offset); - if (err) - goto error_unpin; - - /* Allocate and prepare self registration window */ - *out_window = scif_create_window(ep, aligned_len >> PAGE_SHIFT, - *out_offset, true); - if (!*out_window) { - scif_free_window_offset(ep, NULL, *out_offset); - err = -ENOMEM; - goto error_unpin; - } - - (*out_window)->pinned_pages = pinned_pages; - (*out_window)->nr_pages = pinned_pages->nr_pages; - (*out_window)->prot = pinned_pages->prot; - - (*out_window)->va_for_temp = addr & PAGE_MASK; - err = scif_map_window(ep->remote_dev, *out_window); - if (err) { - /* Something went wrong! Rollback */ - scif_destroy_window(ep, *out_window); - *out_window = NULL; - } else { - *out_offset |= (addr - (*out_window)->va_for_temp); - } - return err; -error_unpin: - if (err) - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); - scif_unpin_pages(pinned_pages); - return err; -} - -#define SCIF_DMA_TO (3 * HZ) - -/* - * scif_sync_dma - Program a DMA without an interrupt descriptor - * - * @dev - The address of the pointer to the device instance used - * for DMA registration. - * @chan - DMA channel to be used. - * @sync_wait: Wait for DMA to complete? - * - * Return 0 on success and -errno on error. - */ -static int scif_sync_dma(struct scif_hw_dev *sdev, struct dma_chan *chan, - bool sync_wait) -{ - int err = 0; - struct dma_async_tx_descriptor *tx = NULL; - enum dma_ctrl_flags flags = DMA_PREP_FENCE; - dma_cookie_t cookie; - struct dma_device *ddev; - - if (!chan) { - err = -EIO; - dev_err(&sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - return err; - } - ddev = chan->device; - - tx = ddev->device_prep_dma_memcpy(chan, 0, 0, 0, flags); - if (!tx) { - err = -ENOMEM; - dev_err(&sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - goto release; - } - cookie = tx->tx_submit(tx); - - if (dma_submit_error(cookie)) { - err = -ENOMEM; - dev_err(&sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - goto release; - } - if (!sync_wait) { - dma_async_issue_pending(chan); - } else { - if (dma_sync_wait(chan, cookie) == DMA_COMPLETE) { - err = 0; - } else { - err = -EIO; - dev_err(&sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - } - } -release: - return err; -} - -static void scif_dma_callback(void *arg) -{ - struct completion *done = (struct completion *)arg; - - complete(done); -} - -#define SCIF_DMA_SYNC_WAIT true -#define SCIF_DMA_POLL BIT(0) -#define SCIF_DMA_INTR BIT(1) - -/* - * scif_async_dma - Program a DMA with an interrupt descriptor - * - * @dev - The address of the pointer to the device instance used - * for DMA registration. - * @chan - DMA channel to be used. - * Return 0 on success and -errno on error. - */ -static int scif_async_dma(struct scif_hw_dev *sdev, struct dma_chan *chan) -{ - int err = 0; - struct dma_device *ddev; - struct dma_async_tx_descriptor *tx = NULL; - enum dma_ctrl_flags flags = DMA_PREP_INTERRUPT | DMA_PREP_FENCE; - DECLARE_COMPLETION_ONSTACK(done_wait); - dma_cookie_t cookie; - enum dma_status status; - - if (!chan) { - err = -EIO; - dev_err(&sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - return err; - } - ddev = chan->device; - - tx = ddev->device_prep_dma_memcpy(chan, 0, 0, 0, flags); - if (!tx) { - err = -ENOMEM; - dev_err(&sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - goto release; - } - reinit_completion(&done_wait); - tx->callback = scif_dma_callback; - tx->callback_param = &done_wait; - cookie = tx->tx_submit(tx); - - if (dma_submit_error(cookie)) { - err = -ENOMEM; - dev_err(&sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - goto release; - } - dma_async_issue_pending(chan); - - err = wait_for_completion_timeout(&done_wait, SCIF_DMA_TO); - if (!err) { - err = -EIO; - dev_err(&sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - goto release; - } - err = 0; - status = dma_async_is_tx_complete(chan, cookie, NULL, NULL); - if (status != DMA_COMPLETE) { - err = -EIO; - dev_err(&sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - goto release; - } -release: - return err; -} - -/* - * scif_drain_dma_poll - Drain all outstanding DMA operations for a particular - * DMA channel via polling. - * - * @sdev - The SCIF device - * @chan - DMA channel - * Return 0 on success and -errno on error. - */ -static int scif_drain_dma_poll(struct scif_hw_dev *sdev, struct dma_chan *chan) -{ - if (!chan) - return -EINVAL; - return scif_sync_dma(sdev, chan, SCIF_DMA_SYNC_WAIT); -} - -/* - * scif_drain_dma_intr - Drain all outstanding DMA operations for a particular - * DMA channel via interrupt based blocking wait. - * - * @sdev - The SCIF device - * @chan - DMA channel - * Return 0 on success and -errno on error. - */ -int scif_drain_dma_intr(struct scif_hw_dev *sdev, struct dma_chan *chan) -{ - if (!chan) - return -EINVAL; - return scif_async_dma(sdev, chan); -} - -/** - * scif_rma_destroy_windows: - * - * This routine destroys all windows queued for cleanup - */ -void scif_rma_destroy_windows(void) -{ - struct list_head *item, *tmp; - struct scif_window *window; - struct scif_endpt *ep; - struct dma_chan *chan; - - might_sleep(); -restart: - spin_lock(&scif_info.rmalock); - list_for_each_safe(item, tmp, &scif_info.rma) { - window = list_entry(item, struct scif_window, - list); - ep = (struct scif_endpt *)window->ep; - chan = ep->rma_info.dma_chan; - - list_del_init(&window->list); - spin_unlock(&scif_info.rmalock); - if (!chan || !scifdev_alive(ep) || - !scif_drain_dma_intr(ep->remote_dev->sdev, - ep->rma_info.dma_chan)) - /* Remove window from global list */ - window->unreg_state = OP_COMPLETED; - else - dev_warn(&ep->remote_dev->sdev->dev, - "DMA engine hung?\n"); - if (window->unreg_state == OP_COMPLETED) { - if (window->type == SCIF_WINDOW_SELF) - scif_destroy_window(ep, window); - else - scif_destroy_remote_window(window); - atomic_dec(&ep->rma_info.tw_refcount); - } - goto restart; - } - spin_unlock(&scif_info.rmalock); -} - -/** - * scif_rma_destroy_tcw: - * - * This routine destroys temporary cached registered windows - * which have been queued for cleanup. - */ -void scif_rma_destroy_tcw_invalid(void) -{ - struct list_head *item, *tmp; - struct scif_window *window; - struct scif_endpt *ep; - struct dma_chan *chan; - - might_sleep(); -restart: - spin_lock(&scif_info.rmalock); - list_for_each_safe(item, tmp, &scif_info.rma_tc) { - window = list_entry(item, struct scif_window, list); - ep = (struct scif_endpt *)window->ep; - chan = ep->rma_info.dma_chan; - list_del_init(&window->list); - spin_unlock(&scif_info.rmalock); - mutex_lock(&ep->rma_info.rma_lock); - if (!chan || !scifdev_alive(ep) || - !scif_drain_dma_intr(ep->remote_dev->sdev, - ep->rma_info.dma_chan)) { - atomic_sub(window->nr_pages, - &ep->rma_info.tcw_total_pages); - scif_destroy_window(ep, window); - atomic_dec(&ep->rma_info.tcw_refcount); - } else { - dev_warn(&ep->remote_dev->sdev->dev, - "DMA engine hung?\n"); - } - mutex_unlock(&ep->rma_info.rma_lock); - goto restart; - } - spin_unlock(&scif_info.rmalock); -} - -static inline -void *_get_local_va(off_t off, struct scif_window *window, size_t len) -{ - int page_nr = (off - window->offset) >> PAGE_SHIFT; - off_t page_off = off & ~PAGE_MASK; - void *va = NULL; - - if (window->type == SCIF_WINDOW_SELF) { - struct page **pages = window->pinned_pages->pages; - - va = page_address(pages[page_nr]) + page_off; - } - return va; -} - -static inline -void *ioremap_remote(off_t off, struct scif_window *window, - size_t len, struct scif_dev *dev, - struct scif_window_iter *iter) -{ - dma_addr_t phys = scif_off_to_dma_addr(window, off, NULL, iter); - - /* - * If the DMA address is not card relative then we need the DMA - * addresses to be an offset into the bar. The aperture base was already - * added so subtract it here since scif_ioremap is going to add it again - */ - if (!scifdev_self(dev) && window->type == SCIF_WINDOW_PEER && - dev->sdev->aper && !dev->sdev->card_rel_da) - phys = phys - dev->sdev->aper->pa; - return scif_ioremap(phys, len, dev); -} - -static inline void -iounmap_remote(void *virt, size_t size, struct scif_copy_work *work) -{ - scif_iounmap(virt, size, work->remote_dev); -} - -/* - * Takes care of ordering issue caused by - * 1. Hardware: Only in the case of cpu copy from mgmt node to card - * because of WC memory. - * 2. Software: If memcpy reorders copy instructions for optimization. - * This could happen at both mgmt node and card. - */ -static inline void -scif_ordered_memcpy_toio(char *dst, const char *src, size_t count) -{ - if (!count) - return; - - memcpy_toio((void __iomem __force *)dst, src, --count); - /* Order the last byte with the previous stores */ - wmb(); - *(dst + count) = *(src + count); -} - -static inline void scif_unaligned_cpy_toio(char *dst, const char *src, - size_t count, bool ordered) -{ - if (ordered) - scif_ordered_memcpy_toio(dst, src, count); - else - memcpy_toio((void __iomem __force *)dst, src, count); -} - -static inline -void scif_ordered_memcpy_fromio(char *dst, const char *src, size_t count) -{ - if (!count) - return; - - memcpy_fromio(dst, (void __iomem __force *)src, --count); - /* Order the last byte with the previous loads */ - rmb(); - *(dst + count) = *(src + count); -} - -static inline void scif_unaligned_cpy_fromio(char *dst, const char *src, - size_t count, bool ordered) -{ - if (ordered) - scif_ordered_memcpy_fromio(dst, src, count); - else - memcpy_fromio(dst, (void __iomem __force *)src, count); -} - -#define SCIF_RMA_ERROR_CODE (~(dma_addr_t)0x0) - -/* - * scif_off_to_dma_addr: - * Obtain the dma_addr given the window and the offset. - * @window: Registered window. - * @off: Window offset. - * @nr_bytes: Return the number of contiguous bytes till next DMA addr index. - * @index: Return the index of the dma_addr array found. - * @start_off: start offset of index of the dma addr array found. - * The nr_bytes provides the callee an estimate of the maximum possible - * DMA xfer possible while the index/start_off provide faster lookups - * for the next iteration. - */ -dma_addr_t scif_off_to_dma_addr(struct scif_window *window, s64 off, - size_t *nr_bytes, struct scif_window_iter *iter) -{ - int i, page_nr; - s64 start, end; - off_t page_off; - - if (window->nr_pages == window->nr_contig_chunks) { - page_nr = (off - window->offset) >> PAGE_SHIFT; - page_off = off & ~PAGE_MASK; - - if (nr_bytes) - *nr_bytes = PAGE_SIZE - page_off; - return window->dma_addr[page_nr] | page_off; - } - if (iter) { - i = iter->index; - start = iter->offset; - } else { - i = 0; - start = window->offset; - } - for (; i < window->nr_contig_chunks; i++) { - end = start + (window->num_pages[i] << PAGE_SHIFT); - if (off >= start && off < end) { - if (iter) { - iter->index = i; - iter->offset = start; - } - if (nr_bytes) - *nr_bytes = end - off; - return (window->dma_addr[i] + (off - start)); - } - start += (window->num_pages[i] << PAGE_SHIFT); - } - dev_err(scif_info.mdev.this_device, - "%s %d BUG. Addr not found? window %p off 0x%llx\n", - __func__, __LINE__, window, off); - return SCIF_RMA_ERROR_CODE; -} - -/* - * Copy between rma window and temporary buffer - */ -static void scif_rma_local_cpu_copy(s64 offset, struct scif_window *window, - u8 *temp, size_t rem_len, bool to_temp) -{ - void *window_virt; - size_t loop_len; - int offset_in_page; - s64 end_offset; - - offset_in_page = offset & ~PAGE_MASK; - loop_len = PAGE_SIZE - offset_in_page; - - if (rem_len < loop_len) - loop_len = rem_len; - - window_virt = _get_local_va(offset, window, loop_len); - if (!window_virt) - return; - if (to_temp) - memcpy(temp, window_virt, loop_len); - else - memcpy(window_virt, temp, loop_len); - - offset += loop_len; - temp += loop_len; - rem_len -= loop_len; - - end_offset = window->offset + - (window->nr_pages << PAGE_SHIFT); - while (rem_len) { - if (offset == end_offset) { - window = list_next_entry(window, list); - end_offset = window->offset + - (window->nr_pages << PAGE_SHIFT); - } - loop_len = min(PAGE_SIZE, rem_len); - window_virt = _get_local_va(offset, window, loop_len); - if (!window_virt) - return; - if (to_temp) - memcpy(temp, window_virt, loop_len); - else - memcpy(window_virt, temp, loop_len); - offset += loop_len; - temp += loop_len; - rem_len -= loop_len; - } -} - -/** - * scif_rma_completion_cb: - * @data: RMA cookie - * - * RMA interrupt completion callback. - */ -static void scif_rma_completion_cb(void *data) -{ - struct scif_dma_comp_cb *comp_cb = data; - - /* Free DMA Completion CB. */ - if (comp_cb->dst_window) - scif_rma_local_cpu_copy(comp_cb->dst_offset, - comp_cb->dst_window, - comp_cb->temp_buf + - comp_cb->header_padding, - comp_cb->len, false); - scif_unmap_single(comp_cb->temp_phys, comp_cb->sdev, - SCIF_KMEM_UNALIGNED_BUF_SIZE); - if (comp_cb->is_cache) - kmem_cache_free(unaligned_cache, - comp_cb->temp_buf_to_free); - else - kfree(comp_cb->temp_buf_to_free); -} - -/* Copies between temporary buffer and offsets provided in work */ -static int -scif_rma_list_dma_copy_unaligned(struct scif_copy_work *work, - u8 *temp, struct dma_chan *chan, - bool src_local) -{ - struct scif_dma_comp_cb *comp_cb = work->comp_cb; - dma_addr_t window_dma_addr, temp_dma_addr; - dma_addr_t temp_phys = comp_cb->temp_phys; - size_t loop_len, nr_contig_bytes = 0, remaining_len = work->len; - int offset_in_ca, ret = 0; - s64 end_offset, offset; - struct scif_window *window; - void *window_virt_addr; - size_t tail_len; - struct dma_async_tx_descriptor *tx; - struct dma_device *dev = chan->device; - dma_cookie_t cookie; - - if (src_local) { - offset = work->dst_offset; - window = work->dst_window; - } else { - offset = work->src_offset; - window = work->src_window; - } - - offset_in_ca = offset & (L1_CACHE_BYTES - 1); - if (offset_in_ca) { - loop_len = L1_CACHE_BYTES - offset_in_ca; - loop_len = min(loop_len, remaining_len); - window_virt_addr = ioremap_remote(offset, window, - loop_len, - work->remote_dev, - NULL); - if (!window_virt_addr) - return -ENOMEM; - if (src_local) - scif_unaligned_cpy_toio(window_virt_addr, temp, - loop_len, - work->ordered && - !(remaining_len - loop_len)); - else - scif_unaligned_cpy_fromio(temp, window_virt_addr, - loop_len, work->ordered && - !(remaining_len - loop_len)); - iounmap_remote(window_virt_addr, loop_len, work); - - offset += loop_len; - temp += loop_len; - temp_phys += loop_len; - remaining_len -= loop_len; - } - - offset_in_ca = offset & ~PAGE_MASK; - end_offset = window->offset + - (window->nr_pages << PAGE_SHIFT); - - tail_len = remaining_len & (L1_CACHE_BYTES - 1); - remaining_len -= tail_len; - while (remaining_len) { - if (offset == end_offset) { - window = list_next_entry(window, list); - end_offset = window->offset + - (window->nr_pages << PAGE_SHIFT); - } - if (scif_is_mgmt_node()) - temp_dma_addr = temp_phys; - else - /* Fix if we ever enable IOMMU on the card */ - temp_dma_addr = (dma_addr_t)virt_to_phys(temp); - window_dma_addr = scif_off_to_dma_addr(window, offset, - &nr_contig_bytes, - NULL); - loop_len = min(nr_contig_bytes, remaining_len); - if (src_local) { - if (work->ordered && !tail_len && - !(remaining_len - loop_len) && - loop_len != L1_CACHE_BYTES) { - /* - * Break up the last chunk of the transfer into - * two steps. if there is no tail to guarantee - * DMA ordering. SCIF_DMA_POLLING inserts - * a status update descriptor in step 1 which - * acts as a double sided synchronization fence - * for the DMA engine to ensure that the last - * cache line in step 2 is updated last. - */ - /* Step 1) DMA: Body Length - L1_CACHE_BYTES. */ - tx = - dev->device_prep_dma_memcpy(chan, - window_dma_addr, - temp_dma_addr, - loop_len - - L1_CACHE_BYTES, - DMA_PREP_FENCE); - if (!tx) { - ret = -ENOMEM; - goto err; - } - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - ret = -ENOMEM; - goto err; - } - dma_async_issue_pending(chan); - offset += (loop_len - L1_CACHE_BYTES); - temp_dma_addr += (loop_len - L1_CACHE_BYTES); - window_dma_addr += (loop_len - L1_CACHE_BYTES); - remaining_len -= (loop_len - L1_CACHE_BYTES); - loop_len = remaining_len; - - /* Step 2) DMA: L1_CACHE_BYTES */ - tx = - dev->device_prep_dma_memcpy(chan, - window_dma_addr, - temp_dma_addr, - loop_len, 0); - if (!tx) { - ret = -ENOMEM; - goto err; - } - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - ret = -ENOMEM; - goto err; - } - dma_async_issue_pending(chan); - } else { - tx = - dev->device_prep_dma_memcpy(chan, - window_dma_addr, - temp_dma_addr, - loop_len, 0); - if (!tx) { - ret = -ENOMEM; - goto err; - } - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - ret = -ENOMEM; - goto err; - } - dma_async_issue_pending(chan); - } - } else { - tx = dev->device_prep_dma_memcpy(chan, temp_dma_addr, - window_dma_addr, loop_len, 0); - if (!tx) { - ret = -ENOMEM; - goto err; - } - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - ret = -ENOMEM; - goto err; - } - dma_async_issue_pending(chan); - } - offset += loop_len; - temp += loop_len; - temp_phys += loop_len; - remaining_len -= loop_len; - offset_in_ca = 0; - } - if (tail_len) { - if (offset == end_offset) { - window = list_next_entry(window, list); - end_offset = window->offset + - (window->nr_pages << PAGE_SHIFT); - } - window_virt_addr = ioremap_remote(offset, window, tail_len, - work->remote_dev, - NULL); - if (!window_virt_addr) - return -ENOMEM; - /* - * The CPU copy for the tail bytes must be initiated only once - * previous DMA transfers for this endpoint have completed - * to guarantee ordering. - */ - if (work->ordered) { - struct scif_dev *rdev = work->remote_dev; - - ret = scif_drain_dma_intr(rdev->sdev, chan); - if (ret) - return ret; - } - if (src_local) - scif_unaligned_cpy_toio(window_virt_addr, temp, - tail_len, work->ordered); - else - scif_unaligned_cpy_fromio(temp, window_virt_addr, - tail_len, work->ordered); - iounmap_remote(window_virt_addr, tail_len, work); - } - tx = dev->device_prep_dma_memcpy(chan, 0, 0, 0, DMA_PREP_INTERRUPT); - if (!tx) { - ret = -ENOMEM; - return ret; - } - tx->callback = &scif_rma_completion_cb; - tx->callback_param = comp_cb; - cookie = tx->tx_submit(tx); - - if (dma_submit_error(cookie)) { - ret = -ENOMEM; - return ret; - } - dma_async_issue_pending(chan); - return 0; -err: - dev_err(scif_info.mdev.this_device, - "%s %d Desc Prog Failed ret %d\n", - __func__, __LINE__, ret); - return ret; -} - -/* - * _scif_rma_list_dma_copy_aligned: - * - * Traverse all the windows and perform DMA copy. - */ -static int _scif_rma_list_dma_copy_aligned(struct scif_copy_work *work, - struct dma_chan *chan) -{ - dma_addr_t src_dma_addr, dst_dma_addr; - size_t loop_len, remaining_len, src_contig_bytes = 0; - size_t dst_contig_bytes = 0; - struct scif_window_iter src_win_iter; - struct scif_window_iter dst_win_iter; - s64 end_src_offset, end_dst_offset; - struct scif_window *src_window = work->src_window; - struct scif_window *dst_window = work->dst_window; - s64 src_offset = work->src_offset, dst_offset = work->dst_offset; - int ret = 0; - struct dma_async_tx_descriptor *tx; - struct dma_device *dev = chan->device; - dma_cookie_t cookie; - - remaining_len = work->len; - - scif_init_window_iter(src_window, &src_win_iter); - scif_init_window_iter(dst_window, &dst_win_iter); - end_src_offset = src_window->offset + - (src_window->nr_pages << PAGE_SHIFT); - end_dst_offset = dst_window->offset + - (dst_window->nr_pages << PAGE_SHIFT); - while (remaining_len) { - if (src_offset == end_src_offset) { - src_window = list_next_entry(src_window, list); - end_src_offset = src_window->offset + - (src_window->nr_pages << PAGE_SHIFT); - scif_init_window_iter(src_window, &src_win_iter); - } - if (dst_offset == end_dst_offset) { - dst_window = list_next_entry(dst_window, list); - end_dst_offset = dst_window->offset + - (dst_window->nr_pages << PAGE_SHIFT); - scif_init_window_iter(dst_window, &dst_win_iter); - } - - /* compute dma addresses for transfer */ - src_dma_addr = scif_off_to_dma_addr(src_window, src_offset, - &src_contig_bytes, - &src_win_iter); - dst_dma_addr = scif_off_to_dma_addr(dst_window, dst_offset, - &dst_contig_bytes, - &dst_win_iter); - loop_len = min(src_contig_bytes, dst_contig_bytes); - loop_len = min(loop_len, remaining_len); - if (work->ordered && !(remaining_len - loop_len)) { - /* - * Break up the last chunk of the transfer into two - * steps to ensure that the last byte in step 2 is - * updated last. - */ - /* Step 1) DMA: Body Length - 1 */ - tx = dev->device_prep_dma_memcpy(chan, dst_dma_addr, - src_dma_addr, - loop_len - 1, - DMA_PREP_FENCE); - if (!tx) { - ret = -ENOMEM; - goto err; - } - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - ret = -ENOMEM; - goto err; - } - src_offset += (loop_len - 1); - dst_offset += (loop_len - 1); - src_dma_addr += (loop_len - 1); - dst_dma_addr += (loop_len - 1); - remaining_len -= (loop_len - 1); - loop_len = remaining_len; - - /* Step 2) DMA: 1 BYTES */ - tx = dev->device_prep_dma_memcpy(chan, dst_dma_addr, - src_dma_addr, loop_len, 0); - if (!tx) { - ret = -ENOMEM; - goto err; - } - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - ret = -ENOMEM; - goto err; - } - dma_async_issue_pending(chan); - } else { - tx = dev->device_prep_dma_memcpy(chan, dst_dma_addr, - src_dma_addr, loop_len, 0); - if (!tx) { - ret = -ENOMEM; - goto err; - } - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - ret = -ENOMEM; - goto err; - } - } - src_offset += loop_len; - dst_offset += loop_len; - remaining_len -= loop_len; - } - return ret; -err: - dev_err(scif_info.mdev.this_device, - "%s %d Desc Prog Failed ret %d\n", - __func__, __LINE__, ret); - return ret; -} - -/* - * scif_rma_list_dma_copy_aligned: - * - * Traverse all the windows and perform DMA copy. - */ -static int scif_rma_list_dma_copy_aligned(struct scif_copy_work *work, - struct dma_chan *chan) -{ - dma_addr_t src_dma_addr, dst_dma_addr; - size_t loop_len, remaining_len, tail_len, src_contig_bytes = 0; - size_t dst_contig_bytes = 0; - int src_cache_off; - s64 end_src_offset, end_dst_offset; - struct scif_window_iter src_win_iter; - struct scif_window_iter dst_win_iter; - void *src_virt, *dst_virt; - struct scif_window *src_window = work->src_window; - struct scif_window *dst_window = work->dst_window; - s64 src_offset = work->src_offset, dst_offset = work->dst_offset; - int ret = 0; - struct dma_async_tx_descriptor *tx; - struct dma_device *dev = chan->device; - dma_cookie_t cookie; - - remaining_len = work->len; - scif_init_window_iter(src_window, &src_win_iter); - scif_init_window_iter(dst_window, &dst_win_iter); - - src_cache_off = src_offset & (L1_CACHE_BYTES - 1); - if (src_cache_off != 0) { - /* Head */ - loop_len = L1_CACHE_BYTES - src_cache_off; - loop_len = min(loop_len, remaining_len); - src_dma_addr = __scif_off_to_dma_addr(src_window, src_offset); - dst_dma_addr = __scif_off_to_dma_addr(dst_window, dst_offset); - if (src_window->type == SCIF_WINDOW_SELF) - src_virt = _get_local_va(src_offset, src_window, - loop_len); - else - src_virt = ioremap_remote(src_offset, src_window, - loop_len, - work->remote_dev, NULL); - if (!src_virt) - return -ENOMEM; - if (dst_window->type == SCIF_WINDOW_SELF) - dst_virt = _get_local_va(dst_offset, dst_window, - loop_len); - else - dst_virt = ioremap_remote(dst_offset, dst_window, - loop_len, - work->remote_dev, NULL); - if (!dst_virt) { - if (src_window->type != SCIF_WINDOW_SELF) - iounmap_remote(src_virt, loop_len, work); - return -ENOMEM; - } - if (src_window->type == SCIF_WINDOW_SELF) - scif_unaligned_cpy_toio(dst_virt, src_virt, loop_len, - remaining_len == loop_len ? - work->ordered : false); - else - scif_unaligned_cpy_fromio(dst_virt, src_virt, loop_len, - remaining_len == loop_len ? - work->ordered : false); - if (src_window->type != SCIF_WINDOW_SELF) - iounmap_remote(src_virt, loop_len, work); - if (dst_window->type != SCIF_WINDOW_SELF) - iounmap_remote(dst_virt, loop_len, work); - src_offset += loop_len; - dst_offset += loop_len; - remaining_len -= loop_len; - } - - end_src_offset = src_window->offset + - (src_window->nr_pages << PAGE_SHIFT); - end_dst_offset = dst_window->offset + - (dst_window->nr_pages << PAGE_SHIFT); - tail_len = remaining_len & (L1_CACHE_BYTES - 1); - remaining_len -= tail_len; - while (remaining_len) { - if (src_offset == end_src_offset) { - src_window = list_next_entry(src_window, list); - end_src_offset = src_window->offset + - (src_window->nr_pages << PAGE_SHIFT); - scif_init_window_iter(src_window, &src_win_iter); - } - if (dst_offset == end_dst_offset) { - dst_window = list_next_entry(dst_window, list); - end_dst_offset = dst_window->offset + - (dst_window->nr_pages << PAGE_SHIFT); - scif_init_window_iter(dst_window, &dst_win_iter); - } - - /* compute dma addresses for transfer */ - src_dma_addr = scif_off_to_dma_addr(src_window, src_offset, - &src_contig_bytes, - &src_win_iter); - dst_dma_addr = scif_off_to_dma_addr(dst_window, dst_offset, - &dst_contig_bytes, - &dst_win_iter); - loop_len = min(src_contig_bytes, dst_contig_bytes); - loop_len = min(loop_len, remaining_len); - if (work->ordered && !tail_len && - !(remaining_len - loop_len)) { - /* - * Break up the last chunk of the transfer into two - * steps. if there is no tail to gurantee DMA ordering. - * Passing SCIF_DMA_POLLING inserts a status update - * descriptor in step 1 which acts as a double sided - * synchronization fence for the DMA engine to ensure - * that the last cache line in step 2 is updated last. - */ - /* Step 1) DMA: Body Length - L1_CACHE_BYTES. */ - tx = dev->device_prep_dma_memcpy(chan, dst_dma_addr, - src_dma_addr, - loop_len - - L1_CACHE_BYTES, - DMA_PREP_FENCE); - if (!tx) { - ret = -ENOMEM; - goto err; - } - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - ret = -ENOMEM; - goto err; - } - dma_async_issue_pending(chan); - src_offset += (loop_len - L1_CACHE_BYTES); - dst_offset += (loop_len - L1_CACHE_BYTES); - src_dma_addr += (loop_len - L1_CACHE_BYTES); - dst_dma_addr += (loop_len - L1_CACHE_BYTES); - remaining_len -= (loop_len - L1_CACHE_BYTES); - loop_len = remaining_len; - - /* Step 2) DMA: L1_CACHE_BYTES */ - tx = dev->device_prep_dma_memcpy(chan, dst_dma_addr, - src_dma_addr, - loop_len, 0); - if (!tx) { - ret = -ENOMEM; - goto err; - } - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - ret = -ENOMEM; - goto err; - } - dma_async_issue_pending(chan); - } else { - tx = dev->device_prep_dma_memcpy(chan, dst_dma_addr, - src_dma_addr, - loop_len, 0); - if (!tx) { - ret = -ENOMEM; - goto err; - } - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - ret = -ENOMEM; - goto err; - } - dma_async_issue_pending(chan); - } - src_offset += loop_len; - dst_offset += loop_len; - remaining_len -= loop_len; - } - remaining_len = tail_len; - if (remaining_len) { - loop_len = remaining_len; - if (src_offset == end_src_offset) - src_window = list_next_entry(src_window, list); - if (dst_offset == end_dst_offset) - dst_window = list_next_entry(dst_window, list); - - src_dma_addr = __scif_off_to_dma_addr(src_window, src_offset); - dst_dma_addr = __scif_off_to_dma_addr(dst_window, dst_offset); - /* - * The CPU copy for the tail bytes must be initiated only once - * previous DMA transfers for this endpoint have completed to - * guarantee ordering. - */ - if (work->ordered) { - struct scif_dev *rdev = work->remote_dev; - - ret = scif_drain_dma_poll(rdev->sdev, chan); - if (ret) - return ret; - } - if (src_window->type == SCIF_WINDOW_SELF) - src_virt = _get_local_va(src_offset, src_window, - loop_len); - else - src_virt = ioremap_remote(src_offset, src_window, - loop_len, - work->remote_dev, NULL); - if (!src_virt) - return -ENOMEM; - - if (dst_window->type == SCIF_WINDOW_SELF) - dst_virt = _get_local_va(dst_offset, dst_window, - loop_len); - else - dst_virt = ioremap_remote(dst_offset, dst_window, - loop_len, - work->remote_dev, NULL); - if (!dst_virt) { - if (src_window->type != SCIF_WINDOW_SELF) - iounmap_remote(src_virt, loop_len, work); - return -ENOMEM; - } - - if (src_window->type == SCIF_WINDOW_SELF) - scif_unaligned_cpy_toio(dst_virt, src_virt, loop_len, - work->ordered); - else - scif_unaligned_cpy_fromio(dst_virt, src_virt, - loop_len, work->ordered); - if (src_window->type != SCIF_WINDOW_SELF) - iounmap_remote(src_virt, loop_len, work); - - if (dst_window->type != SCIF_WINDOW_SELF) - iounmap_remote(dst_virt, loop_len, work); - remaining_len -= loop_len; - } - return ret; -err: - dev_err(scif_info.mdev.this_device, - "%s %d Desc Prog Failed ret %d\n", - __func__, __LINE__, ret); - return ret; -} - -/* - * scif_rma_list_cpu_copy: - * - * Traverse all the windows and perform CPU copy. - */ -static int scif_rma_list_cpu_copy(struct scif_copy_work *work) -{ - void *src_virt, *dst_virt; - size_t loop_len, remaining_len; - int src_page_off, dst_page_off; - s64 src_offset = work->src_offset, dst_offset = work->dst_offset; - struct scif_window *src_window = work->src_window; - struct scif_window *dst_window = work->dst_window; - s64 end_src_offset, end_dst_offset; - int ret = 0; - struct scif_window_iter src_win_iter; - struct scif_window_iter dst_win_iter; - - remaining_len = work->len; - - scif_init_window_iter(src_window, &src_win_iter); - scif_init_window_iter(dst_window, &dst_win_iter); - while (remaining_len) { - src_page_off = src_offset & ~PAGE_MASK; - dst_page_off = dst_offset & ~PAGE_MASK; - loop_len = min(PAGE_SIZE - - max(src_page_off, dst_page_off), - remaining_len); - - if (src_window->type == SCIF_WINDOW_SELF) - src_virt = _get_local_va(src_offset, src_window, - loop_len); - else - src_virt = ioremap_remote(src_offset, src_window, - loop_len, - work->remote_dev, - &src_win_iter); - if (!src_virt) { - ret = -ENOMEM; - goto error; - } - - if (dst_window->type == SCIF_WINDOW_SELF) - dst_virt = _get_local_va(dst_offset, dst_window, - loop_len); - else - dst_virt = ioremap_remote(dst_offset, dst_window, - loop_len, - work->remote_dev, - &dst_win_iter); - if (!dst_virt) { - if (src_window->type == SCIF_WINDOW_PEER) - iounmap_remote(src_virt, loop_len, work); - ret = -ENOMEM; - goto error; - } - - if (work->loopback) { - memcpy(dst_virt, src_virt, loop_len); - } else { - if (src_window->type == SCIF_WINDOW_SELF) - memcpy_toio((void __iomem __force *)dst_virt, - src_virt, loop_len); - else - memcpy_fromio(dst_virt, - (void __iomem __force *)src_virt, - loop_len); - } - if (src_window->type == SCIF_WINDOW_PEER) - iounmap_remote(src_virt, loop_len, work); - - if (dst_window->type == SCIF_WINDOW_PEER) - iounmap_remote(dst_virt, loop_len, work); - - src_offset += loop_len; - dst_offset += loop_len; - remaining_len -= loop_len; - if (remaining_len) { - end_src_offset = src_window->offset + - (src_window->nr_pages << PAGE_SHIFT); - end_dst_offset = dst_window->offset + - (dst_window->nr_pages << PAGE_SHIFT); - if (src_offset == end_src_offset) { - src_window = list_next_entry(src_window, list); - scif_init_window_iter(src_window, - &src_win_iter); - } - if (dst_offset == end_dst_offset) { - dst_window = list_next_entry(dst_window, list); - scif_init_window_iter(dst_window, - &dst_win_iter); - } - } - } -error: - return ret; -} - -static int scif_rma_list_dma_copy_wrapper(struct scif_endpt *epd, - struct scif_copy_work *work, - struct dma_chan *chan, off_t loffset) -{ - int src_cache_off, dst_cache_off; - s64 src_offset = work->src_offset, dst_offset = work->dst_offset; - u8 *temp = NULL; - bool src_local = true; - struct scif_dma_comp_cb *comp_cb; - int err; - - if (is_dma_copy_aligned(chan->device, 1, 1, 1)) - return _scif_rma_list_dma_copy_aligned(work, chan); - - src_cache_off = src_offset & (L1_CACHE_BYTES - 1); - dst_cache_off = dst_offset & (L1_CACHE_BYTES - 1); - - if (dst_cache_off == src_cache_off) - return scif_rma_list_dma_copy_aligned(work, chan); - - if (work->loopback) - return scif_rma_list_cpu_copy(work); - src_local = work->src_window->type == SCIF_WINDOW_SELF; - - /* Allocate dma_completion cb */ - comp_cb = kzalloc(sizeof(*comp_cb), GFP_KERNEL); - if (!comp_cb) - goto error; - - work->comp_cb = comp_cb; - comp_cb->cb_cookie = comp_cb; - comp_cb->dma_completion_func = &scif_rma_completion_cb; - - if (work->len + (L1_CACHE_BYTES << 1) < SCIF_KMEM_UNALIGNED_BUF_SIZE) { - comp_cb->is_cache = false; - /* Allocate padding bytes to align to a cache line */ - temp = kmalloc(work->len + (L1_CACHE_BYTES << 1), - GFP_KERNEL); - if (!temp) - goto free_comp_cb; - comp_cb->temp_buf_to_free = temp; - /* kmalloc(..) does not guarantee cache line alignment */ - if (!IS_ALIGNED((u64)temp, L1_CACHE_BYTES)) - temp = PTR_ALIGN(temp, L1_CACHE_BYTES); - } else { - comp_cb->is_cache = true; - temp = kmem_cache_alloc(unaligned_cache, GFP_KERNEL); - if (!temp) - goto free_comp_cb; - comp_cb->temp_buf_to_free = temp; - } - - if (src_local) { - temp += dst_cache_off; - scif_rma_local_cpu_copy(work->src_offset, work->src_window, - temp, work->len, true); - } else { - comp_cb->dst_window = work->dst_window; - comp_cb->dst_offset = work->dst_offset; - work->src_offset = work->src_offset - src_cache_off; - comp_cb->len = work->len; - work->len = ALIGN(work->len + src_cache_off, L1_CACHE_BYTES); - comp_cb->header_padding = src_cache_off; - } - comp_cb->temp_buf = temp; - - err = scif_map_single(&comp_cb->temp_phys, temp, - work->remote_dev, SCIF_KMEM_UNALIGNED_BUF_SIZE); - if (err) - goto free_temp_buf; - comp_cb->sdev = work->remote_dev; - if (scif_rma_list_dma_copy_unaligned(work, temp, chan, src_local) < 0) - goto free_temp_buf; - if (!src_local) - work->fence_type = SCIF_DMA_INTR; - return 0; -free_temp_buf: - if (comp_cb->is_cache) - kmem_cache_free(unaligned_cache, comp_cb->temp_buf_to_free); - else - kfree(comp_cb->temp_buf_to_free); -free_comp_cb: - kfree(comp_cb); -error: - return -ENOMEM; -} - -/** - * scif_rma_copy: - * @epd: end point descriptor. - * @loffset: offset in local registered address space to/from which to copy - * @addr: user virtual address to/from which to copy - * @len: length of range to copy - * @roffset: offset in remote registered address space to/from which to copy - * @flags: flags - * @dir: LOCAL->REMOTE or vice versa. - * @last_chunk: true if this is the last chunk of a larger transfer - * - * Validate parameters, check if src/dst registered ranges requested for copy - * are valid and initiate either CPU or DMA copy. - */ -static int scif_rma_copy(scif_epd_t epd, off_t loffset, unsigned long addr, - size_t len, off_t roffset, int flags, - enum scif_rma_dir dir, bool last_chunk) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - struct scif_rma_req remote_req; - struct scif_rma_req req; - struct scif_window *local_window = NULL; - struct scif_window *remote_window = NULL; - struct scif_copy_work copy_work; - bool loopback; - int err = 0; - struct dma_chan *chan; - struct scif_mmu_notif *mmn = NULL; - bool cache = false; - struct device *spdev; - - err = scif_verify_epd(ep); - if (err) - return err; - - if (flags && !(flags & (SCIF_RMA_USECPU | SCIF_RMA_USECACHE | - SCIF_RMA_SYNC | SCIF_RMA_ORDERED))) - return -EINVAL; - - loopback = scifdev_self(ep->remote_dev) ? true : false; - copy_work.fence_type = ((flags & SCIF_RMA_SYNC) && last_chunk) ? - SCIF_DMA_POLL : 0; - copy_work.ordered = !!((flags & SCIF_RMA_ORDERED) && last_chunk); - - /* Use CPU for Mgmt node <-> Mgmt node copies */ - if (loopback && scif_is_mgmt_node()) { - flags |= SCIF_RMA_USECPU; - copy_work.fence_type = 0x0; - } - - cache = scif_is_set_reg_cache(flags); - - remote_req.out_window = &remote_window; - remote_req.offset = roffset; - remote_req.nr_bytes = len; - /* - * If transfer is from local to remote then the remote window - * must be writeable and vice versa. - */ - remote_req.prot = dir == SCIF_LOCAL_TO_REMOTE ? VM_WRITE : VM_READ; - remote_req.type = SCIF_WINDOW_PARTIAL; - remote_req.head = &ep->rma_info.remote_reg_list; - - spdev = scif_get_peer_dev(ep->remote_dev); - if (IS_ERR(spdev)) { - err = PTR_ERR(spdev); - return err; - } - - if (addr && cache) { - mutex_lock(&ep->rma_info.mmn_lock); - mmn = scif_find_mmu_notifier(current->mm, &ep->rma_info); - if (!mmn) - mmn = scif_add_mmu_notifier(current->mm, ep); - mutex_unlock(&ep->rma_info.mmn_lock); - if (IS_ERR(mmn)) { - scif_put_peer_dev(spdev); - return PTR_ERR(mmn); - } - cache = cache && !scif_rma_tc_can_cache(ep, len); - } - mutex_lock(&ep->rma_info.rma_lock); - if (addr) { - req.out_window = &local_window; - req.nr_bytes = ALIGN(len + (addr & ~PAGE_MASK), - PAGE_SIZE); - req.va_for_temp = addr & PAGE_MASK; - req.prot = (dir == SCIF_LOCAL_TO_REMOTE ? - VM_READ : VM_WRITE | VM_READ); - /* Does a valid local window exist? */ - if (mmn) { - spin_lock(&ep->rma_info.tc_lock); - req.head = &mmn->tc_reg_list; - err = scif_query_tcw(ep, &req); - spin_unlock(&ep->rma_info.tc_lock); - } - if (!mmn || err) { - err = scif_register_temp(epd, req.va_for_temp, - req.nr_bytes, req.prot, - &loffset, &local_window); - if (err) { - mutex_unlock(&ep->rma_info.rma_lock); - goto error; - } - if (!cache) - goto skip_cache; - atomic_inc(&ep->rma_info.tcw_refcount); - atomic_add_return(local_window->nr_pages, - &ep->rma_info.tcw_total_pages); - if (mmn) { - spin_lock(&ep->rma_info.tc_lock); - scif_insert_tcw(local_window, - &mmn->tc_reg_list); - spin_unlock(&ep->rma_info.tc_lock); - } - } -skip_cache: - loffset = local_window->offset + - (addr - local_window->va_for_temp); - } else { - req.out_window = &local_window; - req.offset = loffset; - /* - * If transfer is from local to remote then the self window - * must be readable and vice versa. - */ - req.prot = dir == SCIF_LOCAL_TO_REMOTE ? VM_READ : VM_WRITE; - req.nr_bytes = len; - req.type = SCIF_WINDOW_PARTIAL; - req.head = &ep->rma_info.reg_list; - /* Does a valid local window exist? */ - err = scif_query_window(&req); - if (err) { - mutex_unlock(&ep->rma_info.rma_lock); - goto error; - } - } - - /* Does a valid remote window exist? */ - err = scif_query_window(&remote_req); - if (err) { - mutex_unlock(&ep->rma_info.rma_lock); - goto error; - } - - /* - * Prepare copy_work for submitting work to the DMA kernel thread - * or CPU copy routine. - */ - copy_work.len = len; - copy_work.loopback = loopback; - copy_work.remote_dev = ep->remote_dev; - if (dir == SCIF_LOCAL_TO_REMOTE) { - copy_work.src_offset = loffset; - copy_work.src_window = local_window; - copy_work.dst_offset = roffset; - copy_work.dst_window = remote_window; - } else { - copy_work.src_offset = roffset; - copy_work.src_window = remote_window; - copy_work.dst_offset = loffset; - copy_work.dst_window = local_window; - } - - if (flags & SCIF_RMA_USECPU) { - scif_rma_list_cpu_copy(©_work); - } else { - chan = ep->rma_info.dma_chan; - err = scif_rma_list_dma_copy_wrapper(epd, ©_work, - chan, loffset); - } - if (addr && !cache) - atomic_inc(&ep->rma_info.tw_refcount); - - mutex_unlock(&ep->rma_info.rma_lock); - - if (last_chunk) { - struct scif_dev *rdev = ep->remote_dev; - - if (copy_work.fence_type == SCIF_DMA_POLL) - err = scif_drain_dma_poll(rdev->sdev, - ep->rma_info.dma_chan); - else if (copy_work.fence_type == SCIF_DMA_INTR) - err = scif_drain_dma_intr(rdev->sdev, - ep->rma_info.dma_chan); - } - - if (addr && !cache) - scif_queue_for_cleanup(local_window, &scif_info.rma); - scif_put_peer_dev(spdev); - return err; -error: - if (err) { - if (addr && local_window && !cache) - scif_destroy_window(ep, local_window); - dev_err(scif_info.mdev.this_device, - "%s %d err %d len 0x%lx\n", - __func__, __LINE__, err, len); - } - scif_put_peer_dev(spdev); - return err; -} - -int scif_readfrom(scif_epd_t epd, off_t loffset, size_t len, - off_t roffset, int flags) -{ - int err; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI readfrom: ep %p loffset 0x%lx len 0x%lx offset 0x%lx flags 0x%x\n", - epd, loffset, len, roffset, flags); - if (scif_unaligned(loffset, roffset)) { - while (len > SCIF_MAX_UNALIGNED_BUF_SIZE) { - err = scif_rma_copy(epd, loffset, 0x0, - SCIF_MAX_UNALIGNED_BUF_SIZE, - roffset, flags, - SCIF_REMOTE_TO_LOCAL, false); - if (err) - goto readfrom_err; - loffset += SCIF_MAX_UNALIGNED_BUF_SIZE; - roffset += SCIF_MAX_UNALIGNED_BUF_SIZE; - len -= SCIF_MAX_UNALIGNED_BUF_SIZE; - } - } - err = scif_rma_copy(epd, loffset, 0x0, len, - roffset, flags, SCIF_REMOTE_TO_LOCAL, true); -readfrom_err: - return err; -} -EXPORT_SYMBOL_GPL(scif_readfrom); - -int scif_writeto(scif_epd_t epd, off_t loffset, size_t len, - off_t roffset, int flags) -{ - int err; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI writeto: ep %p loffset 0x%lx len 0x%lx roffset 0x%lx flags 0x%x\n", - epd, loffset, len, roffset, flags); - if (scif_unaligned(loffset, roffset)) { - while (len > SCIF_MAX_UNALIGNED_BUF_SIZE) { - err = scif_rma_copy(epd, loffset, 0x0, - SCIF_MAX_UNALIGNED_BUF_SIZE, - roffset, flags, - SCIF_LOCAL_TO_REMOTE, false); - if (err) - goto writeto_err; - loffset += SCIF_MAX_UNALIGNED_BUF_SIZE; - roffset += SCIF_MAX_UNALIGNED_BUF_SIZE; - len -= SCIF_MAX_UNALIGNED_BUF_SIZE; - } - } - err = scif_rma_copy(epd, loffset, 0x0, len, - roffset, flags, SCIF_LOCAL_TO_REMOTE, true); -writeto_err: - return err; -} -EXPORT_SYMBOL_GPL(scif_writeto); - -int scif_vreadfrom(scif_epd_t epd, void *addr, size_t len, - off_t roffset, int flags) -{ - int err; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI vreadfrom: ep %p addr %p len 0x%lx roffset 0x%lx flags 0x%x\n", - epd, addr, len, roffset, flags); - if (scif_unaligned((off_t __force)addr, roffset)) { - if (len > SCIF_MAX_UNALIGNED_BUF_SIZE) - flags &= ~SCIF_RMA_USECACHE; - - while (len > SCIF_MAX_UNALIGNED_BUF_SIZE) { - err = scif_rma_copy(epd, 0, (u64)addr, - SCIF_MAX_UNALIGNED_BUF_SIZE, - roffset, flags, - SCIF_REMOTE_TO_LOCAL, false); - if (err) - goto vreadfrom_err; - addr += SCIF_MAX_UNALIGNED_BUF_SIZE; - roffset += SCIF_MAX_UNALIGNED_BUF_SIZE; - len -= SCIF_MAX_UNALIGNED_BUF_SIZE; - } - } - err = scif_rma_copy(epd, 0, (u64)addr, len, - roffset, flags, SCIF_REMOTE_TO_LOCAL, true); -vreadfrom_err: - return err; -} -EXPORT_SYMBOL_GPL(scif_vreadfrom); - -int scif_vwriteto(scif_epd_t epd, void *addr, size_t len, - off_t roffset, int flags) -{ - int err; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI vwriteto: ep %p addr %p len 0x%lx roffset 0x%lx flags 0x%x\n", - epd, addr, len, roffset, flags); - if (scif_unaligned((off_t __force)addr, roffset)) { - if (len > SCIF_MAX_UNALIGNED_BUF_SIZE) - flags &= ~SCIF_RMA_USECACHE; - - while (len > SCIF_MAX_UNALIGNED_BUF_SIZE) { - err = scif_rma_copy(epd, 0, (u64)addr, - SCIF_MAX_UNALIGNED_BUF_SIZE, - roffset, flags, - SCIF_LOCAL_TO_REMOTE, false); - if (err) - goto vwriteto_err; - addr += SCIF_MAX_UNALIGNED_BUF_SIZE; - roffset += SCIF_MAX_UNALIGNED_BUF_SIZE; - len -= SCIF_MAX_UNALIGNED_BUF_SIZE; - } - } - err = scif_rma_copy(epd, 0, (u64)addr, len, - roffset, flags, SCIF_LOCAL_TO_REMOTE, true); -vwriteto_err: - return err; -} -EXPORT_SYMBOL_GPL(scif_vwriteto); diff --git a/drivers/misc/mic/scif/scif_epd.c b/drivers/misc/mic/scif/scif_epd.c deleted file mode 100644 index 426687f6696b..000000000000 --- a/drivers/misc/mic/scif/scif_epd.c +++ /dev/null @@ -1,357 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#include "scif_main.h" -#include "scif_map.h" - -void scif_cleanup_ep_qp(struct scif_endpt *ep) -{ - struct scif_qp *qp = ep->qp_info.qp; - - if (qp->outbound_q.rb_base) { - scif_iounmap((void *)qp->outbound_q.rb_base, - qp->outbound_q.size, ep->remote_dev); - qp->outbound_q.rb_base = NULL; - } - if (qp->remote_qp) { - scif_iounmap((void *)qp->remote_qp, - sizeof(struct scif_qp), ep->remote_dev); - qp->remote_qp = NULL; - } - if (qp->local_qp) { - scif_unmap_single(qp->local_qp, ep->remote_dev, - sizeof(struct scif_qp)); - qp->local_qp = 0x0; - } - if (qp->local_buf) { - scif_unmap_single(qp->local_buf, ep->remote_dev, - SCIF_ENDPT_QP_SIZE); - qp->local_buf = 0; - } -} - -void scif_teardown_ep(void *endpt) -{ - struct scif_endpt *ep = endpt; - struct scif_qp *qp = ep->qp_info.qp; - - if (qp) { - spin_lock(&ep->lock); - scif_cleanup_ep_qp(ep); - spin_unlock(&ep->lock); - kfree(qp->inbound_q.rb_base); - kfree(qp); - } -} - -/* - * Enqueue the endpoint to the zombie list for cleanup. - * The endpoint should not be accessed once this API returns. - */ -void scif_add_epd_to_zombie_list(struct scif_endpt *ep, bool eplock_held) -{ - if (!eplock_held) - mutex_lock(&scif_info.eplock); - spin_lock(&ep->lock); - ep->state = SCIFEP_ZOMBIE; - spin_unlock(&ep->lock); - list_add_tail(&ep->list, &scif_info.zombie); - scif_info.nr_zombies++; - if (!eplock_held) - mutex_unlock(&scif_info.eplock); - schedule_work(&scif_info.misc_work); -} - -static struct scif_endpt *scif_find_listen_ep(u16 port) -{ - struct scif_endpt *ep = NULL; - struct list_head *pos, *tmpq; - - mutex_lock(&scif_info.eplock); - list_for_each_safe(pos, tmpq, &scif_info.listen) { - ep = list_entry(pos, struct scif_endpt, list); - if (ep->port.port == port) { - mutex_unlock(&scif_info.eplock); - return ep; - } - } - mutex_unlock(&scif_info.eplock); - return NULL; -} - -void scif_cleanup_zombie_epd(void) -{ - struct list_head *pos, *tmpq; - struct scif_endpt *ep; - - mutex_lock(&scif_info.eplock); - list_for_each_safe(pos, tmpq, &scif_info.zombie) { - ep = list_entry(pos, struct scif_endpt, list); - if (scif_rma_ep_can_uninit(ep)) { - list_del(pos); - scif_info.nr_zombies--; - put_iova_domain(&ep->rma_info.iovad); - kfree(ep); - } - } - mutex_unlock(&scif_info.eplock); -} - -/** - * scif_cnctreq() - Respond to SCIF_CNCT_REQ interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * This message is initiated by the remote node to request a connection - * to the local node. This function looks for an end point in the - * listen state on the requested port id. - * - * If it finds a listening port it places the connect request on the - * listening end points queue and wakes up any pending accept calls. - * - * If it does not find a listening end point it sends a connection - * reject message to the remote node. - */ -void scif_cnctreq(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = NULL; - struct scif_conreq *conreq; - - conreq = kmalloc(sizeof(*conreq), GFP_KERNEL); - if (!conreq) - /* Lack of resources so reject the request. */ - goto conreq_sendrej; - - ep = scif_find_listen_ep(msg->dst.port); - if (!ep) - /* Send reject due to no listening ports */ - goto conreq_sendrej_free; - else - spin_lock(&ep->lock); - - if (ep->backlog <= ep->conreqcnt) { - /* Send reject due to too many pending requests */ - spin_unlock(&ep->lock); - goto conreq_sendrej_free; - } - - conreq->msg = *msg; - list_add_tail(&conreq->list, &ep->conlist); - ep->conreqcnt++; - wake_up_interruptible(&ep->conwq); - spin_unlock(&ep->lock); - return; - -conreq_sendrej_free: - kfree(conreq); -conreq_sendrej: - msg->uop = SCIF_CNCT_REJ; - scif_nodeqp_send(&scif_dev[msg->src.node], msg); -} - -/** - * scif_cnctgnt() - Respond to SCIF_CNCT_GNT interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * An accept() on the remote node has occurred and sent this message - * to indicate success. Place the end point in the MAPPING state and - * save the remote nodes memory information. Then wake up the connect - * request so it can finish. - */ -void scif_cnctgnt(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - - spin_lock(&ep->lock); - if (SCIFEP_CONNECTING == ep->state) { - ep->peer.node = msg->src.node; - ep->peer.port = msg->src.port; - ep->qp_info.gnt_pld = msg->payload[1]; - ep->remote_ep = msg->payload[2]; - ep->state = SCIFEP_MAPPING; - - wake_up(&ep->conwq); - } - spin_unlock(&ep->lock); -} - -/** - * scif_cnctgnt_ack() - Respond to SCIF_CNCT_GNTACK interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * The remote connection request has finished mapping the local memory. - * Place the connection in the connected state and wake up the pending - * accept() call. - */ -void scif_cnctgnt_ack(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - - mutex_lock(&scif_info.connlock); - spin_lock(&ep->lock); - /* New ep is now connected with all resources set. */ - ep->state = SCIFEP_CONNECTED; - list_add_tail(&ep->list, &scif_info.connected); - wake_up(&ep->conwq); - spin_unlock(&ep->lock); - mutex_unlock(&scif_info.connlock); -} - -/** - * scif_cnctgnt_nack() - Respond to SCIF_CNCT_GNTNACK interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * The remote connection request failed to map the local memory it was sent. - * Place the end point in the CLOSING state to indicate it and wake up - * the pending accept(); - */ -void scif_cnctgnt_nack(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - - spin_lock(&ep->lock); - ep->state = SCIFEP_CLOSING; - wake_up(&ep->conwq); - spin_unlock(&ep->lock); -} - -/** - * scif_cnctrej() - Respond to SCIF_CNCT_REJ interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * The remote end has rejected the connection request. Set the end - * point back to the bound state and wake up the pending connect(). - */ -void scif_cnctrej(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - - spin_lock(&ep->lock); - if (SCIFEP_CONNECTING == ep->state) { - ep->state = SCIFEP_BOUND; - wake_up(&ep->conwq); - } - spin_unlock(&ep->lock); -} - -/** - * scif_discnct() - Respond to SCIF_DISCNCT interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * The remote node has indicated close() has been called on its end - * point. Remove the local end point from the connected list, set its - * state to disconnected and ensure accesses to the remote node are - * shutdown. - * - * When all accesses to the remote end have completed then send a - * DISCNT_ACK to indicate it can remove its resources and complete - * the close routine. - */ -void scif_discnct(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = NULL; - struct scif_endpt *tmpep; - struct list_head *pos, *tmpq; - - mutex_lock(&scif_info.connlock); - list_for_each_safe(pos, tmpq, &scif_info.connected) { - tmpep = list_entry(pos, struct scif_endpt, list); - /* - * The local ep may have sent a disconnect and and been closed - * due to a message response time out. It may have been - * allocated again and formed a new connection so we want to - * check if the remote ep matches - */ - if (((u64)tmpep == msg->payload[1]) && - ((u64)tmpep->remote_ep == msg->payload[0])) { - list_del(pos); - ep = tmpep; - spin_lock(&ep->lock); - break; - } - } - - /* - * If the terminated end is not found then this side started closing - * before the other side sent the disconnect. If so the ep will no - * longer be on the connected list. Regardless the other side - * needs to be acked to let it know close is complete. - */ - if (!ep) { - mutex_unlock(&scif_info.connlock); - goto discnct_ack; - } - - ep->state = SCIFEP_DISCONNECTED; - list_add_tail(&ep->list, &scif_info.disconnected); - - wake_up_interruptible(&ep->sendwq); - wake_up_interruptible(&ep->recvwq); - spin_unlock(&ep->lock); - mutex_unlock(&scif_info.connlock); - -discnct_ack: - msg->uop = SCIF_DISCNT_ACK; - scif_nodeqp_send(&scif_dev[msg->src.node], msg); -} - -/** - * scif_discnct_ack() - Respond to SCIF_DISCNT_ACK interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * Remote side has indicated it has not more references to local resources - */ -void scif_discnt_ack(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - - spin_lock(&ep->lock); - ep->state = SCIFEP_DISCONNECTED; - spin_unlock(&ep->lock); - complete(&ep->discon); -} - -/** - * scif_clientsend() - Respond to SCIF_CLIENT_SEND interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * Remote side is confirming send or receive interrupt handling is complete. - */ -void scif_clientsend(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - - spin_lock(&ep->lock); - if (SCIFEP_CONNECTED == ep->state) - wake_up_interruptible(&ep->recvwq); - spin_unlock(&ep->lock); -} - -/** - * scif_clientrcvd() - Respond to SCIF_CLIENT_RCVD interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * Remote side is confirming send or receive interrupt handling is complete. - */ -void scif_clientrcvd(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - - spin_lock(&ep->lock); - if (SCIFEP_CONNECTED == ep->state) - wake_up_interruptible(&ep->sendwq); - spin_unlock(&ep->lock); -} diff --git a/drivers/misc/mic/scif/scif_epd.h b/drivers/misc/mic/scif/scif_epd.h deleted file mode 100644 index 0b9dfe1cc06c..000000000000 --- a/drivers/misc/mic/scif/scif_epd.h +++ /dev/null @@ -1,200 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#ifndef SCIF_EPD_H -#define SCIF_EPD_H - -#include <linux/delay.h> -#include <linux/scif.h> -#include <linux/scif_ioctl.h> - -#define SCIF_EPLOCK_HELD true - -enum scif_epd_state { - SCIFEP_UNBOUND, - SCIFEP_BOUND, - SCIFEP_LISTENING, - SCIFEP_CONNECTED, - SCIFEP_CONNECTING, - SCIFEP_MAPPING, - SCIFEP_CLOSING, - SCIFEP_CLLISTEN, - SCIFEP_DISCONNECTED, - SCIFEP_ZOMBIE -}; - -/* - * struct scif_conreq - Data structure added to the connection list. - * - * @msg: connection request message received - * @list: link to list of connection requests - */ -struct scif_conreq { - struct scifmsg msg; - struct list_head list; -}; - -/* Size of the RB for the Endpoint QP */ -#define SCIF_ENDPT_QP_SIZE 0x1000 - -/* - * scif_endpt_qp_info - SCIF endpoint queue pair - * - * @qp - Qpair for this endpoint - * @qp_offset - DMA address of the QP - * @gnt_pld - Payload in a SCIF_CNCT_GNT message containing the - * physical address of the remote_qp. - */ -struct scif_endpt_qp_info { - struct scif_qp *qp; - dma_addr_t qp_offset; - dma_addr_t gnt_pld; -}; - -/* - * struct scif_endpt - The SCIF endpoint data structure - * - * @state: end point state - * @lock: lock synchronizing access to endpoint fields like state etc - * @port: self port information - * @peer: peer port information - * @backlog: maximum pending connection requests - * @qp_info: Endpoint QP information for SCIF messaging - * @remote_dev: scifdev used by this endpt to communicate with remote node. - * @remote_ep: remote endpoint - * @conreqcnt: Keep track of number of connection requests. - * @files: Open file information used to match the id passed in with - * the flush routine. - * @conlist: list of connection requests - * @conwq: waitqueue for connection processing - * @discon: completion used during disconnection - * @sendwq: waitqueue used during sending messages - * @recvwq: waitqueue used during message receipt - * @sendlock: Synchronize ordering of messages sent - * @recvlock: Synchronize ordering of messages received - * @list: link to list of various endpoints like connected, listening etc - * @li_accept: pending ACCEPTREG - * @acceptcnt: pending ACCEPTREG cnt - * @liacceptlist: link to listen accept - * @miacceptlist: link to uaccept - * @listenep: associated listen ep - * @conn_work: Non blocking connect work - * @conn_port: Connection port - * @conn_err: Errors during connection - * @conn_async_state: Async connection - * @conn_pend_wq: Used by poll while waiting for incoming connections - * @conn_list: List of async connection requests - * @rma_info: Information for triggering SCIF RMA and DMA operations - * @mmu_list: link to list of MMU notifier cleanup work - * @anon: anonymous file for use in kernel mode scif poll - */ -struct scif_endpt { - enum scif_epd_state state; - spinlock_t lock; - struct scif_port_id port; - struct scif_port_id peer; - int backlog; - struct scif_endpt_qp_info qp_info; - struct scif_dev *remote_dev; - u64 remote_ep; - int conreqcnt; - struct files_struct *files; - struct list_head conlist; - wait_queue_head_t conwq; - struct completion discon; - wait_queue_head_t sendwq; - wait_queue_head_t recvwq; - struct mutex sendlock; - struct mutex recvlock; - struct list_head list; - struct list_head li_accept; - int acceptcnt; - struct list_head liacceptlist; - struct list_head miacceptlist; - struct scif_endpt *listenep; - struct scif_port_id conn_port; - int conn_err; - int conn_async_state; - wait_queue_head_t conn_pend_wq; - struct list_head conn_list; - struct scif_endpt_rma_info rma_info; - struct list_head mmu_list; - struct file *anon; -}; - -static inline int scifdev_alive(struct scif_endpt *ep) -{ - return _scifdev_alive(ep->remote_dev); -} - -/* - * scif_verify_epd: - * ep: SCIF endpoint - * - * Checks several generic error conditions and returns the - * appropriate error. - */ -static inline int scif_verify_epd(struct scif_endpt *ep) -{ - if (ep->state == SCIFEP_DISCONNECTED) - return -ECONNRESET; - - if (ep->state != SCIFEP_CONNECTED) - return -ENOTCONN; - - if (!scifdev_alive(ep)) - return -ENODEV; - - return 0; -} - -static inline int scif_anon_inode_getfile(scif_epd_t epd) -{ - epd->anon = anon_inode_getfile("scif", &scif_anon_fops, NULL, 0); - - return PTR_ERR_OR_ZERO(epd->anon); -} - -static inline void scif_anon_inode_fput(scif_epd_t epd) -{ - if (epd->anon) { - fput(epd->anon); - epd->anon = NULL; - } -} - -void scif_cleanup_zombie_epd(void); -void scif_teardown_ep(void *endpt); -void scif_cleanup_ep_qp(struct scif_endpt *ep); -void scif_add_epd_to_zombie_list(struct scif_endpt *ep, bool eplock_held); -void scif_get_node_info(void); -void scif_send_acks(struct scif_dev *dev); -void scif_conn_handler(struct work_struct *work); -int scif_rsrv_port(u16 port); -void scif_get_port(u16 port); -int scif_get_new_port(void); -void scif_put_port(u16 port); -int scif_user_send(scif_epd_t epd, void __user *msg, int len, int flags); -int scif_user_recv(scif_epd_t epd, void __user *msg, int len, int flags); -void scif_cnctreq(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_cnctgnt(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_cnctgnt_ack(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_cnctgnt_nack(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_cnctrej(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_discnct(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_discnt_ack(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_clientsend(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_clientrcvd(struct scif_dev *scifdev, struct scifmsg *msg); -int __scif_connect(scif_epd_t epd, struct scif_port_id *dst, bool non_block); -int __scif_flush(scif_epd_t epd); -int scif_mmap(struct vm_area_struct *vma, scif_epd_t epd); -__poll_t __scif_pollfd(struct file *f, poll_table *wait, - struct scif_endpt *ep); -int __scif_pin_pages(void *addr, size_t len, int *out_prot, - int map_flags, scif_pinned_pages_t *pages); -#endif /* SCIF_EPD_H */ diff --git a/drivers/misc/mic/scif/scif_fd.c b/drivers/misc/mic/scif/scif_fd.c deleted file mode 100644 index 3f08646cd78a..000000000000 --- a/drivers/misc/mic/scif/scif_fd.c +++ /dev/null @@ -1,462 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#include "scif_main.h" - -static int scif_fdopen(struct inode *inode, struct file *f) -{ - struct scif_endpt *priv = scif_open(); - - if (!priv) - return -ENOMEM; - f->private_data = priv; - return 0; -} - -static int scif_fdclose(struct inode *inode, struct file *f) -{ - struct scif_endpt *priv = f->private_data; - - return scif_close(priv); -} - -static int scif_fdmmap(struct file *f, struct vm_area_struct *vma) -{ - struct scif_endpt *priv = f->private_data; - - return scif_mmap(vma, priv); -} - -static __poll_t scif_fdpoll(struct file *f, poll_table *wait) -{ - struct scif_endpt *priv = f->private_data; - - return __scif_pollfd(f, wait, priv); -} - -static int scif_fdflush(struct file *f, fl_owner_t id) -{ - struct scif_endpt *ep = f->private_data; - - spin_lock(&ep->lock); - /* - * The listening endpoint stashes the open file information before - * waiting for incoming connections. The release callback would never be - * called if the application closed the endpoint, while waiting for - * incoming connections from a separate thread since the file descriptor - * reference count is bumped up in the accept IOCTL. Call the flush - * routine if the id matches the endpoint open file information so that - * the listening endpoint can be woken up and the fd released. - */ - if (ep->files == id) - __scif_flush(ep); - spin_unlock(&ep->lock); - return 0; -} - -static __always_inline void scif_err_debug(int err, const char *str) -{ - /* - * ENOTCONN is a common uninteresting error which is - * flooding debug messages to the console unnecessarily. - */ - if (err < 0 && err != -ENOTCONN) - dev_dbg(scif_info.mdev.this_device, "%s err %d\n", str, err); -} - -static long scif_fdioctl(struct file *f, unsigned int cmd, unsigned long arg) -{ - struct scif_endpt *priv = f->private_data; - void __user *argp = (void __user *)arg; - int err = 0; - struct scifioctl_msg request; - bool non_block = false; - - non_block = !!(f->f_flags & O_NONBLOCK); - - switch (cmd) { - case SCIF_BIND: - { - int pn; - - if (copy_from_user(&pn, argp, sizeof(pn))) - return -EFAULT; - - pn = scif_bind(priv, pn); - if (pn < 0) - return pn; - - if (copy_to_user(argp, &pn, sizeof(pn))) - return -EFAULT; - - return 0; - } - case SCIF_LISTEN: - return scif_listen(priv, arg); - case SCIF_CONNECT: - { - struct scifioctl_connect req; - struct scif_endpt *ep = (struct scif_endpt *)priv; - - if (copy_from_user(&req, argp, sizeof(req))) - return -EFAULT; - - err = __scif_connect(priv, &req.peer, non_block); - if (err < 0) - return err; - - req.self.node = ep->port.node; - req.self.port = ep->port.port; - - if (copy_to_user(argp, &req, sizeof(req))) - return -EFAULT; - - return 0; - } - /* - * Accept is done in two halves. The request ioctl does the basic - * functionality of accepting the request and returning the information - * about it including the internal ID of the end point. The register - * is done with the internal ID on a new file descriptor opened by the - * requesting process. - */ - case SCIF_ACCEPTREQ: - { - struct scifioctl_accept request; - scif_epd_t *ep = (scif_epd_t *)&request.endpt; - - if (copy_from_user(&request, argp, sizeof(request))) - return -EFAULT; - - err = scif_accept(priv, &request.peer, ep, request.flags); - if (err < 0) - return err; - - if (copy_to_user(argp, &request, sizeof(request))) { - scif_close(*ep); - return -EFAULT; - } - /* - * Add to the list of user mode eps where the second half - * of the accept is not yet completed. - */ - mutex_lock(&scif_info.eplock); - list_add_tail(&((*ep)->miacceptlist), &scif_info.uaccept); - list_add_tail(&((*ep)->liacceptlist), &priv->li_accept); - (*ep)->listenep = priv; - priv->acceptcnt++; - mutex_unlock(&scif_info.eplock); - - return 0; - } - case SCIF_ACCEPTREG: - { - struct scif_endpt *priv = f->private_data; - struct scif_endpt *newep; - struct scif_endpt *lisep; - struct scif_endpt *fep = NULL; - struct scif_endpt *tmpep; - struct list_head *pos, *tmpq; - - /* Finally replace the pointer to the accepted endpoint */ - if (copy_from_user(&newep, argp, sizeof(void *))) - return -EFAULT; - - /* Remove form the user accept queue */ - mutex_lock(&scif_info.eplock); - list_for_each_safe(pos, tmpq, &scif_info.uaccept) { - tmpep = list_entry(pos, - struct scif_endpt, miacceptlist); - if (tmpep == newep) { - list_del(pos); - fep = tmpep; - break; - } - } - - if (!fep) { - mutex_unlock(&scif_info.eplock); - return -ENOENT; - } - - lisep = newep->listenep; - list_for_each_safe(pos, tmpq, &lisep->li_accept) { - tmpep = list_entry(pos, - struct scif_endpt, liacceptlist); - if (tmpep == newep) { - list_del(pos); - lisep->acceptcnt--; - break; - } - } - - mutex_unlock(&scif_info.eplock); - - /* Free the resources automatically created from the open. */ - scif_anon_inode_fput(priv); - scif_teardown_ep(priv); - scif_add_epd_to_zombie_list(priv, !SCIF_EPLOCK_HELD); - f->private_data = newep; - return 0; - } - case SCIF_SEND: - { - struct scif_endpt *priv = f->private_data; - - if (copy_from_user(&request, argp, - sizeof(struct scifioctl_msg))) { - err = -EFAULT; - goto send_err; - } - err = scif_user_send(priv, (void __user *)request.msg, - request.len, request.flags); - if (err < 0) - goto send_err; - if (copy_to_user(& - ((struct scifioctl_msg __user *)argp)->out_len, - &err, sizeof(err))) { - err = -EFAULT; - goto send_err; - } - err = 0; -send_err: - scif_err_debug(err, "scif_send"); - return err; - } - case SCIF_RECV: - { - struct scif_endpt *priv = f->private_data; - - if (copy_from_user(&request, argp, - sizeof(struct scifioctl_msg))) { - err = -EFAULT; - goto recv_err; - } - - err = scif_user_recv(priv, (void __user *)request.msg, - request.len, request.flags); - if (err < 0) - goto recv_err; - - if (copy_to_user(& - ((struct scifioctl_msg __user *)argp)->out_len, - &err, sizeof(err))) { - err = -EFAULT; - goto recv_err; - } - err = 0; -recv_err: - scif_err_debug(err, "scif_recv"); - return err; - } - case SCIF_GET_NODEIDS: - { - struct scifioctl_node_ids node_ids; - int entries; - u16 *nodes; - void __user *unodes, *uself; - u16 self; - - if (copy_from_user(&node_ids, argp, sizeof(node_ids))) { - err = -EFAULT; - goto getnodes_err2; - } - - entries = min_t(int, scif_info.maxid, node_ids.len); - nodes = kmalloc_array(entries, sizeof(u16), GFP_KERNEL); - if (entries && !nodes) { - err = -ENOMEM; - goto getnodes_err2; - } - node_ids.len = scif_get_node_ids(nodes, entries, &self); - - unodes = (void __user *)node_ids.nodes; - if (copy_to_user(unodes, nodes, sizeof(u16) * entries)) { - err = -EFAULT; - goto getnodes_err1; - } - - uself = (void __user *)node_ids.self; - if (copy_to_user(uself, &self, sizeof(u16))) { - err = -EFAULT; - goto getnodes_err1; - } - - if (copy_to_user(argp, &node_ids, sizeof(node_ids))) { - err = -EFAULT; - goto getnodes_err1; - } -getnodes_err1: - kfree(nodes); -getnodes_err2: - return err; - } - case SCIF_REG: - { - struct scif_endpt *priv = f->private_data; - struct scifioctl_reg reg; - off_t ret; - - if (copy_from_user(®, argp, sizeof(reg))) { - err = -EFAULT; - goto reg_err; - } - if (reg.flags & SCIF_MAP_KERNEL) { - err = -EINVAL; - goto reg_err; - } - ret = scif_register(priv, (void *)reg.addr, reg.len, - reg.offset, reg.prot, reg.flags); - if (ret < 0) { - err = (int)ret; - goto reg_err; - } - - if (copy_to_user(&((struct scifioctl_reg __user *)argp) - ->out_offset, &ret, sizeof(reg.out_offset))) { - err = -EFAULT; - goto reg_err; - } - err = 0; -reg_err: - scif_err_debug(err, "scif_register"); - return err; - } - case SCIF_UNREG: - { - struct scif_endpt *priv = f->private_data; - struct scifioctl_unreg unreg; - - if (copy_from_user(&unreg, argp, sizeof(unreg))) { - err = -EFAULT; - goto unreg_err; - } - err = scif_unregister(priv, unreg.offset, unreg.len); -unreg_err: - scif_err_debug(err, "scif_unregister"); - return err; - } - case SCIF_READFROM: - { - struct scif_endpt *priv = f->private_data; - struct scifioctl_copy copy; - - if (copy_from_user(©, argp, sizeof(copy))) { - err = -EFAULT; - goto readfrom_err; - } - err = scif_readfrom(priv, copy.loffset, copy.len, copy.roffset, - copy.flags); -readfrom_err: - scif_err_debug(err, "scif_readfrom"); - return err; - } - case SCIF_WRITETO: - { - struct scif_endpt *priv = f->private_data; - struct scifioctl_copy copy; - - if (copy_from_user(©, argp, sizeof(copy))) { - err = -EFAULT; - goto writeto_err; - } - err = scif_writeto(priv, copy.loffset, copy.len, copy.roffset, - copy.flags); -writeto_err: - scif_err_debug(err, "scif_writeto"); - return err; - } - case SCIF_VREADFROM: - { - struct scif_endpt *priv = f->private_data; - struct scifioctl_copy copy; - - if (copy_from_user(©, argp, sizeof(copy))) { - err = -EFAULT; - goto vreadfrom_err; - } - err = scif_vreadfrom(priv, (void __force *)copy.addr, copy.len, - copy.roffset, copy.flags); -vreadfrom_err: - scif_err_debug(err, "scif_vreadfrom"); - return err; - } - case SCIF_VWRITETO: - { - struct scif_endpt *priv = f->private_data; - struct scifioctl_copy copy; - - if (copy_from_user(©, argp, sizeof(copy))) { - err = -EFAULT; - goto vwriteto_err; - } - err = scif_vwriteto(priv, (void __force *)copy.addr, copy.len, - copy.roffset, copy.flags); -vwriteto_err: - scif_err_debug(err, "scif_vwriteto"); - return err; - } - case SCIF_FENCE_MARK: - { - struct scif_endpt *priv = f->private_data; - struct scifioctl_fence_mark mark; - int tmp_mark = 0; - - if (copy_from_user(&mark, argp, sizeof(mark))) { - err = -EFAULT; - goto fence_mark_err; - } - err = scif_fence_mark(priv, mark.flags, &tmp_mark); - if (err) - goto fence_mark_err; - if (copy_to_user((void __user *)mark.mark, &tmp_mark, - sizeof(tmp_mark))) { - err = -EFAULT; - goto fence_mark_err; - } -fence_mark_err: - scif_err_debug(err, "scif_fence_mark"); - return err; - } - case SCIF_FENCE_WAIT: - { - struct scif_endpt *priv = f->private_data; - - err = scif_fence_wait(priv, arg); - scif_err_debug(err, "scif_fence_wait"); - return err; - } - case SCIF_FENCE_SIGNAL: - { - struct scif_endpt *priv = f->private_data; - struct scifioctl_fence_signal signal; - - if (copy_from_user(&signal, argp, sizeof(signal))) { - err = -EFAULT; - goto fence_signal_err; - } - - err = scif_fence_signal(priv, signal.loff, signal.lval, - signal.roff, signal.rval, signal.flags); -fence_signal_err: - scif_err_debug(err, "scif_fence_signal"); - return err; - } - } - return -EINVAL; -} - -const struct file_operations scif_fops = { - .open = scif_fdopen, - .release = scif_fdclose, - .unlocked_ioctl = scif_fdioctl, - .mmap = scif_fdmmap, - .poll = scif_fdpoll, - .flush = scif_fdflush, - .owner = THIS_MODULE, -}; diff --git a/drivers/misc/mic/scif/scif_fence.c b/drivers/misc/mic/scif/scif_fence.c deleted file mode 100644 index 4fedf6183951..000000000000 --- a/drivers/misc/mic/scif/scif_fence.c +++ /dev/null @@ -1,783 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel SCIF driver. - */ - -#include "scif_main.h" - -/** - * scif_recv_mark: Handle SCIF_MARK request - * @scifdev: SCIF device - * @msg: Interrupt message - * - * The peer has requested a mark. - */ -void scif_recv_mark(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - int mark = 0; - int err; - - err = _scif_fence_mark(ep, &mark); - if (err) - msg->uop = SCIF_MARK_NACK; - else - msg->uop = SCIF_MARK_ACK; - msg->payload[0] = ep->remote_ep; - msg->payload[2] = mark; - scif_nodeqp_send(ep->remote_dev, msg); -} - -/** - * scif_recv_mark_resp: Handle SCIF_MARK_(N)ACK messages. - * @scifdev: SCIF device - * @msg: Interrupt message - * - * The peer has responded to a SCIF_MARK message. - */ -void scif_recv_mark_resp(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - struct scif_fence_info *fence_req = - (struct scif_fence_info *)msg->payload[1]; - - mutex_lock(&ep->rma_info.rma_lock); - if (msg->uop == SCIF_MARK_ACK) { - fence_req->state = OP_COMPLETED; - fence_req->dma_mark = (int)msg->payload[2]; - } else { - fence_req->state = OP_FAILED; - } - mutex_unlock(&ep->rma_info.rma_lock); - complete(&fence_req->comp); -} - -/** - * scif_recv_wait: Handle SCIF_WAIT request - * @scifdev: SCIF device - * @msg: Interrupt message - * - * The peer has requested waiting on a fence. - */ -void scif_recv_wait(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - struct scif_remote_fence_info *fence; - - /* - * Allocate structure for remote fence information and - * send a NACK if the allocation failed. The peer will - * return ENOMEM upon receiving a NACK. - */ - fence = kmalloc(sizeof(*fence), GFP_KERNEL); - if (!fence) { - msg->payload[0] = ep->remote_ep; - msg->uop = SCIF_WAIT_NACK; - scif_nodeqp_send(ep->remote_dev, msg); - return; - } - - /* Prepare the fence request */ - memcpy(&fence->msg, msg, sizeof(struct scifmsg)); - INIT_LIST_HEAD(&fence->list); - - /* Insert to the global remote fence request list */ - mutex_lock(&scif_info.fencelock); - atomic_inc(&ep->rma_info.fence_refcount); - list_add_tail(&fence->list, &scif_info.fence); - mutex_unlock(&scif_info.fencelock); - - schedule_work(&scif_info.misc_work); -} - -/** - * scif_recv_wait_resp: Handle SCIF_WAIT_(N)ACK messages. - * @scifdev: SCIF device - * @msg: Interrupt message - * - * The peer has responded to a SCIF_WAIT message. - */ -void scif_recv_wait_resp(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - struct scif_fence_info *fence_req = - (struct scif_fence_info *)msg->payload[1]; - - mutex_lock(&ep->rma_info.rma_lock); - if (msg->uop == SCIF_WAIT_ACK) - fence_req->state = OP_COMPLETED; - else - fence_req->state = OP_FAILED; - mutex_unlock(&ep->rma_info.rma_lock); - complete(&fence_req->comp); -} - -/** - * scif_recv_sig_local: Handle SCIF_SIG_LOCAL request - * @scifdev: SCIF device - * @msg: Interrupt message - * - * The peer has requested a signal on a local offset. - */ -void scif_recv_sig_local(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - int err; - - err = scif_prog_signal(ep, msg->payload[1], msg->payload[2], - SCIF_WINDOW_SELF); - if (err) - msg->uop = SCIF_SIG_NACK; - else - msg->uop = SCIF_SIG_ACK; - msg->payload[0] = ep->remote_ep; - scif_nodeqp_send(ep->remote_dev, msg); -} - -/** - * scif_recv_sig_remote: Handle SCIF_SIGNAL_REMOTE request - * @scifdev: SCIF device - * @msg: Interrupt message - * - * The peer has requested a signal on a remote offset. - */ -void scif_recv_sig_remote(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - int err; - - err = scif_prog_signal(ep, msg->payload[1], msg->payload[2], - SCIF_WINDOW_PEER); - if (err) - msg->uop = SCIF_SIG_NACK; - else - msg->uop = SCIF_SIG_ACK; - msg->payload[0] = ep->remote_ep; - scif_nodeqp_send(ep->remote_dev, msg); -} - -/** - * scif_recv_sig_resp: Handle SCIF_SIG_(N)ACK messages. - * @scifdev: SCIF device - * @msg: Interrupt message - * - * The peer has responded to a signal request. - */ -void scif_recv_sig_resp(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - struct scif_fence_info *fence_req = - (struct scif_fence_info *)msg->payload[3]; - - mutex_lock(&ep->rma_info.rma_lock); - if (msg->uop == SCIF_SIG_ACK) - fence_req->state = OP_COMPLETED; - else - fence_req->state = OP_FAILED; - mutex_unlock(&ep->rma_info.rma_lock); - complete(&fence_req->comp); -} - -static inline void *scif_get_local_va(off_t off, struct scif_window *window) -{ - struct page **pages = window->pinned_pages->pages; - int page_nr = (off - window->offset) >> PAGE_SHIFT; - off_t page_off = off & ~PAGE_MASK; - - return page_address(pages[page_nr]) + page_off; -} - -static void scif_prog_signal_cb(void *arg) -{ - struct scif_cb_arg *cb_arg = arg; - - dma_pool_free(cb_arg->ep->remote_dev->signal_pool, cb_arg->status, - cb_arg->src_dma_addr); - kfree(cb_arg); -} - -static int _scif_prog_signal(scif_epd_t epd, dma_addr_t dst, u64 val) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - struct dma_chan *chan = ep->rma_info.dma_chan; - struct dma_device *ddev = chan->device; - bool x100 = !is_dma_copy_aligned(chan->device, 1, 1, 1); - struct dma_async_tx_descriptor *tx; - struct scif_status *status = NULL; - struct scif_cb_arg *cb_arg = NULL; - dma_addr_t src; - dma_cookie_t cookie; - int err; - - tx = ddev->device_prep_dma_memcpy(chan, 0, 0, 0, DMA_PREP_FENCE); - if (!tx) { - err = -ENOMEM; - dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - goto alloc_fail; - } - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - err = (int)cookie; - dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - goto alloc_fail; - } - dma_async_issue_pending(chan); - if (x100) { - /* - * For X100 use the status descriptor to write the value to - * the destination. - */ - tx = ddev->device_prep_dma_imm_data(chan, dst, val, 0); - } else { - status = dma_pool_alloc(ep->remote_dev->signal_pool, GFP_KERNEL, - &src); - if (!status) { - err = -ENOMEM; - dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - goto alloc_fail; - } - status->val = val; - status->src_dma_addr = src; - status->ep = ep; - src += offsetof(struct scif_status, val); - tx = ddev->device_prep_dma_memcpy(chan, dst, src, sizeof(val), - DMA_PREP_INTERRUPT); - } - if (!tx) { - err = -ENOMEM; - dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - goto dma_fail; - } - if (!x100) { - cb_arg = kmalloc(sizeof(*cb_arg), GFP_KERNEL); - if (!cb_arg) { - err = -ENOMEM; - goto dma_fail; - } - cb_arg->src_dma_addr = src; - cb_arg->status = status; - cb_arg->ep = ep; - tx->callback = scif_prog_signal_cb; - tx->callback_param = cb_arg; - } - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - err = -EIO; - dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - goto dma_fail; - } - dma_async_issue_pending(chan); - return 0; -dma_fail: - if (!x100) { - dma_pool_free(ep->remote_dev->signal_pool, status, - src - offsetof(struct scif_status, val)); - kfree(cb_arg); - } -alloc_fail: - return err; -} - -/** - * scif_prog_signal: - * @epd: Endpoint Descriptor - * @offset: registered address to write @val to - * @val: Value to be written at @offset - * @type: Type of the window. - * - * Arrange to write a value to the registered offset after ensuring that the - * offset provided is indeed valid. - */ -int scif_prog_signal(scif_epd_t epd, off_t offset, u64 val, - enum scif_window_type type) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - struct scif_window *window = NULL; - struct scif_rma_req req; - dma_addr_t dst_dma_addr; - int err; - - mutex_lock(&ep->rma_info.rma_lock); - req.out_window = &window; - req.offset = offset; - req.nr_bytes = sizeof(u64); - req.prot = SCIF_PROT_WRITE; - req.type = SCIF_WINDOW_SINGLE; - if (type == SCIF_WINDOW_SELF) - req.head = &ep->rma_info.reg_list; - else - req.head = &ep->rma_info.remote_reg_list; - /* Does a valid window exist? */ - err = scif_query_window(&req); - if (err) { - dev_err(scif_info.mdev.this_device, - "%s %d err %d\n", __func__, __LINE__, err); - goto unlock_ret; - } - - if (scif_is_mgmt_node() && scifdev_self(ep->remote_dev)) { - u64 *dst_virt; - - if (type == SCIF_WINDOW_SELF) - dst_virt = scif_get_local_va(offset, window); - else - dst_virt = - scif_get_local_va(offset, (struct scif_window *) - window->peer_window); - *dst_virt = val; - } else { - dst_dma_addr = __scif_off_to_dma_addr(window, offset); - err = _scif_prog_signal(epd, dst_dma_addr, val); - } -unlock_ret: - mutex_unlock(&ep->rma_info.rma_lock); - return err; -} - -static int _scif_fence_wait(scif_epd_t epd, int mark) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - dma_cookie_t cookie = mark & ~SCIF_REMOTE_FENCE; - int err; - - /* Wait for DMA callback in scif_fence_mark_cb(..) */ - err = wait_event_interruptible_timeout(ep->rma_info.markwq, - dma_async_is_tx_complete( - ep->rma_info.dma_chan, - cookie, NULL, NULL) == - DMA_COMPLETE, - SCIF_NODE_ALIVE_TIMEOUT); - if (!err) - err = -ETIMEDOUT; - else if (err > 0) - err = 0; - return err; -} - -/** - * scif_rma_handle_remote_fences: - * - * This routine services remote fence requests. - */ -void scif_rma_handle_remote_fences(void) -{ - struct list_head *item, *tmp; - struct scif_remote_fence_info *fence; - struct scif_endpt *ep; - int mark, err; - - might_sleep(); - mutex_lock(&scif_info.fencelock); - list_for_each_safe(item, tmp, &scif_info.fence) { - fence = list_entry(item, struct scif_remote_fence_info, - list); - /* Remove fence from global list */ - list_del(&fence->list); - - /* Initiate the fence operation */ - ep = (struct scif_endpt *)fence->msg.payload[0]; - mark = fence->msg.payload[2]; - err = _scif_fence_wait(ep, mark); - if (err) - fence->msg.uop = SCIF_WAIT_NACK; - else - fence->msg.uop = SCIF_WAIT_ACK; - fence->msg.payload[0] = ep->remote_ep; - scif_nodeqp_send(ep->remote_dev, &fence->msg); - kfree(fence); - if (!atomic_sub_return(1, &ep->rma_info.fence_refcount)) - schedule_work(&scif_info.misc_work); - } - mutex_unlock(&scif_info.fencelock); -} - -static int _scif_send_fence(scif_epd_t epd, int uop, int mark, int *out_mark) -{ - int err; - struct scifmsg msg; - struct scif_fence_info *fence_req; - struct scif_endpt *ep = (struct scif_endpt *)epd; - - fence_req = kmalloc(sizeof(*fence_req), GFP_KERNEL); - if (!fence_req) { - err = -ENOMEM; - goto error; - } - - fence_req->state = OP_IN_PROGRESS; - init_completion(&fence_req->comp); - - msg.src = ep->port; - msg.uop = uop; - msg.payload[0] = ep->remote_ep; - msg.payload[1] = (u64)fence_req; - if (uop == SCIF_WAIT) - msg.payload[2] = mark; - spin_lock(&ep->lock); - if (ep->state == SCIFEP_CONNECTED) - err = scif_nodeqp_send(ep->remote_dev, &msg); - else - err = -ENOTCONN; - spin_unlock(&ep->lock); - if (err) - goto error_free; -retry: - /* Wait for a SCIF_WAIT_(N)ACK message */ - err = wait_for_completion_timeout(&fence_req->comp, - SCIF_NODE_ALIVE_TIMEOUT); - if (!err && scifdev_alive(ep)) - goto retry; - if (!err) - err = -ENODEV; - if (err > 0) - err = 0; - mutex_lock(&ep->rma_info.rma_lock); - if (err < 0) { - if (fence_req->state == OP_IN_PROGRESS) - fence_req->state = OP_FAILED; - } - if (fence_req->state == OP_FAILED && !err) - err = -ENOMEM; - if (uop == SCIF_MARK && fence_req->state == OP_COMPLETED) - *out_mark = SCIF_REMOTE_FENCE | fence_req->dma_mark; - mutex_unlock(&ep->rma_info.rma_lock); -error_free: - kfree(fence_req); -error: - return err; -} - -/** - * scif_send_fence_mark: - * @epd: end point descriptor. - * @out_mark: Output DMA mark reported by peer. - * - * Send a remote fence mark request. - */ -static int scif_send_fence_mark(scif_epd_t epd, int *out_mark) -{ - return _scif_send_fence(epd, SCIF_MARK, 0, out_mark); -} - -/** - * scif_send_fence_wait: - * @epd: end point descriptor. - * @mark: DMA mark to wait for. - * - * Send a remote fence wait request. - */ -static int scif_send_fence_wait(scif_epd_t epd, int mark) -{ - return _scif_send_fence(epd, SCIF_WAIT, mark, NULL); -} - -static int _scif_send_fence_signal_wait(struct scif_endpt *ep, - struct scif_fence_info *fence_req) -{ - int err; - -retry: - /* Wait for a SCIF_SIG_(N)ACK message */ - err = wait_for_completion_timeout(&fence_req->comp, - SCIF_NODE_ALIVE_TIMEOUT); - if (!err && scifdev_alive(ep)) - goto retry; - if (!err) - err = -ENODEV; - if (err > 0) - err = 0; - if (err < 0) { - mutex_lock(&ep->rma_info.rma_lock); - if (fence_req->state == OP_IN_PROGRESS) - fence_req->state = OP_FAILED; - mutex_unlock(&ep->rma_info.rma_lock); - } - if (fence_req->state == OP_FAILED && !err) - err = -ENXIO; - return err; -} - -/** - * scif_send_fence_signal: - * @epd: endpoint descriptor - * @loff: local offset - * @lval: local value to write to loffset - * @roff: remote offset - * @rval: remote value to write to roffset - * @flags: flags - * - * Sends a remote fence signal request - */ -static int scif_send_fence_signal(scif_epd_t epd, off_t roff, u64 rval, - off_t loff, u64 lval, int flags) -{ - int err = 0; - struct scifmsg msg; - struct scif_fence_info *fence_req; - struct scif_endpt *ep = (struct scif_endpt *)epd; - - fence_req = kmalloc(sizeof(*fence_req), GFP_KERNEL); - if (!fence_req) { - err = -ENOMEM; - goto error; - } - - fence_req->state = OP_IN_PROGRESS; - init_completion(&fence_req->comp); - msg.src = ep->port; - if (flags & SCIF_SIGNAL_LOCAL) { - msg.uop = SCIF_SIG_LOCAL; - msg.payload[0] = ep->remote_ep; - msg.payload[1] = roff; - msg.payload[2] = rval; - msg.payload[3] = (u64)fence_req; - spin_lock(&ep->lock); - if (ep->state == SCIFEP_CONNECTED) - err = scif_nodeqp_send(ep->remote_dev, &msg); - else - err = -ENOTCONN; - spin_unlock(&ep->lock); - if (err) - goto error_free; - err = _scif_send_fence_signal_wait(ep, fence_req); - if (err) - goto error_free; - } - fence_req->state = OP_IN_PROGRESS; - - if (flags & SCIF_SIGNAL_REMOTE) { - msg.uop = SCIF_SIG_REMOTE; - msg.payload[0] = ep->remote_ep; - msg.payload[1] = loff; - msg.payload[2] = lval; - msg.payload[3] = (u64)fence_req; - spin_lock(&ep->lock); - if (ep->state == SCIFEP_CONNECTED) - err = scif_nodeqp_send(ep->remote_dev, &msg); - else - err = -ENOTCONN; - spin_unlock(&ep->lock); - if (err) - goto error_free; - err = _scif_send_fence_signal_wait(ep, fence_req); - } -error_free: - kfree(fence_req); -error: - return err; -} - -static void scif_fence_mark_cb(void *arg) -{ - struct scif_endpt *ep = (struct scif_endpt *)arg; - - wake_up_interruptible(&ep->rma_info.markwq); - atomic_dec(&ep->rma_info.fence_refcount); -} - -/** - * _scif_fence_mark: - * @epd: endpoint descriptor - * @mark: DMA mark to set-up - * - * Set up a mark for this endpoint and return the value of the mark. - */ -int _scif_fence_mark(scif_epd_t epd, int *mark) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - struct dma_chan *chan = ep->rma_info.dma_chan; - struct dma_device *ddev = chan->device; - struct dma_async_tx_descriptor *tx; - dma_cookie_t cookie; - int err; - - tx = ddev->device_prep_dma_memcpy(chan, 0, 0, 0, DMA_PREP_FENCE); - if (!tx) { - err = -ENOMEM; - dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - return err; - } - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - err = (int)cookie; - dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - return err; - } - dma_async_issue_pending(chan); - tx = ddev->device_prep_dma_interrupt(chan, DMA_PREP_INTERRUPT); - if (!tx) { - err = -ENOMEM; - dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - return err; - } - tx->callback = scif_fence_mark_cb; - tx->callback_param = ep; - *mark = cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - err = (int)cookie; - dev_err(&ep->remote_dev->sdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - return err; - } - atomic_inc(&ep->rma_info.fence_refcount); - dma_async_issue_pending(chan); - return 0; -} - -#define SCIF_LOOPB_MAGIC_MARK 0xdead - -int scif_fence_mark(scif_epd_t epd, int flags, int *mark) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - int err = 0; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI fence_mark: ep %p flags 0x%x mark 0x%x\n", - ep, flags, *mark); - err = scif_verify_epd(ep); - if (err) - return err; - - /* Invalid flags? */ - if (flags & ~(SCIF_FENCE_INIT_SELF | SCIF_FENCE_INIT_PEER)) - return -EINVAL; - - /* At least one of init self or peer RMA should be set */ - if (!(flags & (SCIF_FENCE_INIT_SELF | SCIF_FENCE_INIT_PEER))) - return -EINVAL; - - /* Exactly one of init self or peer RMA should be set but not both */ - if ((flags & SCIF_FENCE_INIT_SELF) && (flags & SCIF_FENCE_INIT_PEER)) - return -EINVAL; - - /* - * Management node loopback does not need to use DMA. - * Return a valid mark to be symmetric. - */ - if (scifdev_self(ep->remote_dev) && scif_is_mgmt_node()) { - *mark = SCIF_LOOPB_MAGIC_MARK; - return 0; - } - - if (flags & SCIF_FENCE_INIT_SELF) - err = _scif_fence_mark(epd, mark); - else - err = scif_send_fence_mark(ep, mark); - - if (err) - dev_err(scif_info.mdev.this_device, - "%s %d err %d\n", __func__, __LINE__, err); - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI fence_mark: ep %p flags 0x%x mark 0x%x err %d\n", - ep, flags, *mark, err); - return err; -} -EXPORT_SYMBOL_GPL(scif_fence_mark); - -int scif_fence_wait(scif_epd_t epd, int mark) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - int err = 0; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI fence_wait: ep %p mark 0x%x\n", - ep, mark); - err = scif_verify_epd(ep); - if (err) - return err; - /* - * Management node loopback does not need to use DMA. - * The only valid mark provided is 0 so simply - * return success if the mark is valid. - */ - if (scifdev_self(ep->remote_dev) && scif_is_mgmt_node()) { - if (mark == SCIF_LOOPB_MAGIC_MARK) - return 0; - else - return -EINVAL; - } - if (mark & SCIF_REMOTE_FENCE) - err = scif_send_fence_wait(epd, mark); - else - err = _scif_fence_wait(epd, mark); - if (err < 0) - dev_err(scif_info.mdev.this_device, - "%s %d err %d\n", __func__, __LINE__, err); - return err; -} -EXPORT_SYMBOL_GPL(scif_fence_wait); - -int scif_fence_signal(scif_epd_t epd, off_t loff, u64 lval, - off_t roff, u64 rval, int flags) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - int err = 0; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI fence_signal: ep %p loff 0x%lx lval 0x%llx roff 0x%lx rval 0x%llx flags 0x%x\n", - ep, loff, lval, roff, rval, flags); - err = scif_verify_epd(ep); - if (err) - return err; - - /* Invalid flags? */ - if (flags & ~(SCIF_FENCE_INIT_SELF | SCIF_FENCE_INIT_PEER | - SCIF_SIGNAL_LOCAL | SCIF_SIGNAL_REMOTE)) - return -EINVAL; - - /* At least one of init self or peer RMA should be set */ - if (!(flags & (SCIF_FENCE_INIT_SELF | SCIF_FENCE_INIT_PEER))) - return -EINVAL; - - /* Exactly one of init self or peer RMA should be set but not both */ - if ((flags & SCIF_FENCE_INIT_SELF) && (flags & SCIF_FENCE_INIT_PEER)) - return -EINVAL; - - /* At least one of SCIF_SIGNAL_LOCAL or SCIF_SIGNAL_REMOTE required */ - if (!(flags & (SCIF_SIGNAL_LOCAL | SCIF_SIGNAL_REMOTE))) - return -EINVAL; - - /* Only Dword offsets allowed */ - if ((flags & SCIF_SIGNAL_LOCAL) && (loff & (sizeof(u32) - 1))) - return -EINVAL; - - /* Only Dword aligned offsets allowed */ - if ((flags & SCIF_SIGNAL_REMOTE) && (roff & (sizeof(u32) - 1))) - return -EINVAL; - - if (flags & SCIF_FENCE_INIT_PEER) { - err = scif_send_fence_signal(epd, roff, rval, loff, - lval, flags); - } else { - /* Local Signal in Local RAS */ - if (flags & SCIF_SIGNAL_LOCAL) { - err = scif_prog_signal(epd, loff, lval, - SCIF_WINDOW_SELF); - if (err) - goto error_ret; - } - - /* Signal in Remote RAS */ - if (flags & SCIF_SIGNAL_REMOTE) - err = scif_prog_signal(epd, roff, - rval, SCIF_WINDOW_PEER); - } -error_ret: - if (err) - dev_err(scif_info.mdev.this_device, - "%s %d err %d\n", __func__, __LINE__, err); - return err; -} -EXPORT_SYMBOL_GPL(scif_fence_signal); diff --git a/drivers/misc/mic/scif/scif_main.c b/drivers/misc/mic/scif/scif_main.c deleted file mode 100644 index e2278bf9f11d..000000000000 --- a/drivers/misc/mic/scif/scif_main.c +++ /dev/null @@ -1,351 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#include <linux/module.h> -#include <linux/idr.h> - -#include <linux/mic_common.h> -#include "../common/mic_dev.h" -#include "../bus/scif_bus.h" -#include "scif_peer_bus.h" -#include "scif_main.h" -#include "scif_map.h" - -struct scif_info scif_info = { - .mdev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "scif", - .fops = &scif_fops, - } -}; - -struct scif_dev *scif_dev; -struct kmem_cache *unaligned_cache; -static atomic_t g_loopb_cnt; - -/* Runs in the context of intr_wq */ -static void scif_intr_bh_handler(struct work_struct *work) -{ - struct scif_dev *scifdev = - container_of(work, struct scif_dev, intr_bh); - - if (scifdev_self(scifdev)) - scif_loopb_msg_handler(scifdev, scifdev->qpairs); - else - scif_nodeqp_intrhandler(scifdev, scifdev->qpairs); -} - -int scif_setup_intr_wq(struct scif_dev *scifdev) -{ - if (!scifdev->intr_wq) { - snprintf(scifdev->intr_wqname, sizeof(scifdev->intr_wqname), - "SCIF INTR %d", scifdev->node); - scifdev->intr_wq = - alloc_ordered_workqueue(scifdev->intr_wqname, 0); - if (!scifdev->intr_wq) - return -ENOMEM; - INIT_WORK(&scifdev->intr_bh, scif_intr_bh_handler); - } - return 0; -} - -void scif_destroy_intr_wq(struct scif_dev *scifdev) -{ - if (scifdev->intr_wq) { - destroy_workqueue(scifdev->intr_wq); - scifdev->intr_wq = NULL; - } -} - -irqreturn_t scif_intr_handler(int irq, void *data) -{ - struct scif_dev *scifdev = data; - struct scif_hw_dev *sdev = scifdev->sdev; - - sdev->hw_ops->ack_interrupt(sdev, scifdev->db); - queue_work(scifdev->intr_wq, &scifdev->intr_bh); - return IRQ_HANDLED; -} - -static void scif_qp_setup_handler(struct work_struct *work) -{ - struct scif_dev *scifdev = container_of(work, struct scif_dev, - qp_dwork.work); - struct scif_hw_dev *sdev = scifdev->sdev; - dma_addr_t da = 0; - int err; - - if (scif_is_mgmt_node()) { - struct mic_bootparam *bp = sdev->dp; - - da = bp->scif_card_dma_addr; - scifdev->rdb = bp->h2c_scif_db; - } else { - struct mic_bootparam __iomem *bp = sdev->rdp; - - da = readq(&bp->scif_host_dma_addr); - scifdev->rdb = ioread8(&bp->c2h_scif_db); - } - if (da) { - err = scif_qp_response(da, scifdev); - if (err) - dev_err(&scifdev->sdev->dev, - "scif_qp_response err %d\n", err); - } else { - schedule_delayed_work(&scifdev->qp_dwork, - msecs_to_jiffies(1000)); - } -} - -static int scif_setup_scifdev(void) -{ - /* We support a maximum of 129 SCIF nodes including the mgmt node */ -#define MAX_SCIF_NODES 129 - int i; - u8 num_nodes = MAX_SCIF_NODES; - - scif_dev = kcalloc(num_nodes, sizeof(*scif_dev), GFP_KERNEL); - if (!scif_dev) - return -ENOMEM; - for (i = 0; i < num_nodes; i++) { - struct scif_dev *scifdev = &scif_dev[i]; - - scifdev->node = i; - scifdev->exit = OP_IDLE; - init_waitqueue_head(&scifdev->disconn_wq); - mutex_init(&scifdev->lock); - INIT_WORK(&scifdev->peer_add_work, scif_add_peer_device); - INIT_DELAYED_WORK(&scifdev->p2p_dwork, - scif_poll_qp_state); - INIT_DELAYED_WORK(&scifdev->qp_dwork, - scif_qp_setup_handler); - INIT_LIST_HEAD(&scifdev->p2p); - RCU_INIT_POINTER(scifdev->spdev, NULL); - } - return 0; -} - -static void scif_destroy_scifdev(void) -{ - kfree(scif_dev); - scif_dev = NULL; -} - -static int scif_probe(struct scif_hw_dev *sdev) -{ - struct scif_dev *scifdev = &scif_dev[sdev->dnode]; - int rc; - - dev_set_drvdata(&sdev->dev, sdev); - scifdev->sdev = sdev; - - if (1 == atomic_add_return(1, &g_loopb_cnt)) { - struct scif_dev *loopb_dev = &scif_dev[sdev->snode]; - - loopb_dev->sdev = sdev; - rc = scif_setup_loopback_qp(loopb_dev); - if (rc) - goto exit; - } - - rc = scif_setup_intr_wq(scifdev); - if (rc) - goto destroy_loopb; - rc = scif_setup_qp(scifdev); - if (rc) - goto destroy_intr; - scifdev->db = sdev->hw_ops->next_db(sdev); - scifdev->cookie = sdev->hw_ops->request_irq(sdev, scif_intr_handler, - "SCIF_INTR", scifdev, - scifdev->db); - if (IS_ERR(scifdev->cookie)) { - rc = PTR_ERR(scifdev->cookie); - goto free_qp; - } - if (scif_is_mgmt_node()) { - struct mic_bootparam *bp = sdev->dp; - - bp->c2h_scif_db = scifdev->db; - bp->scif_host_dma_addr = scifdev->qp_dma_addr; - } else { - struct mic_bootparam __iomem *bp = sdev->rdp; - - iowrite8(scifdev->db, &bp->h2c_scif_db); - writeq(scifdev->qp_dma_addr, &bp->scif_card_dma_addr); - } - schedule_delayed_work(&scifdev->qp_dwork, - msecs_to_jiffies(1000)); - return rc; -free_qp: - scif_free_qp(scifdev); -destroy_intr: - scif_destroy_intr_wq(scifdev); -destroy_loopb: - if (atomic_dec_and_test(&g_loopb_cnt)) - scif_destroy_loopback_qp(&scif_dev[sdev->snode]); -exit: - return rc; -} - -void scif_stop(struct scif_dev *scifdev) -{ - struct scif_dev *dev; - int i; - - for (i = scif_info.maxid; i >= 0; i--) { - dev = &scif_dev[i]; - if (scifdev_self(dev)) - continue; - scif_handle_remove_node(i); - } -} - -static void scif_remove(struct scif_hw_dev *sdev) -{ - struct scif_dev *scifdev = &scif_dev[sdev->dnode]; - - if (scif_is_mgmt_node()) { - struct mic_bootparam *bp = sdev->dp; - - bp->c2h_scif_db = -1; - bp->scif_host_dma_addr = 0x0; - } else { - struct mic_bootparam __iomem *bp = sdev->rdp; - - iowrite8(-1, &bp->h2c_scif_db); - writeq(0x0, &bp->scif_card_dma_addr); - } - if (scif_is_mgmt_node()) { - scif_disconnect_node(scifdev->node, true); - } else { - scif_info.card_initiated_exit = true; - scif_stop(scifdev); - } - if (atomic_dec_and_test(&g_loopb_cnt)) - scif_destroy_loopback_qp(&scif_dev[sdev->snode]); - if (scifdev->cookie) { - sdev->hw_ops->free_irq(sdev, scifdev->cookie, scifdev); - scifdev->cookie = NULL; - } - scif_destroy_intr_wq(scifdev); - cancel_delayed_work(&scifdev->qp_dwork); - scif_free_qp(scifdev); - scifdev->rdb = -1; - scifdev->sdev = NULL; -} - -static struct scif_hw_dev_id id_table[] = { - { MIC_SCIF_DEV, SCIF_DEV_ANY_ID }, - { 0 }, -}; - -static struct scif_driver scif_driver = { - .driver.name = KBUILD_MODNAME, - .driver.owner = THIS_MODULE, - .id_table = id_table, - .probe = scif_probe, - .remove = scif_remove, -}; - -static int _scif_init(void) -{ - int rc; - - mutex_init(&scif_info.eplock); - spin_lock_init(&scif_info.rmalock); - spin_lock_init(&scif_info.nb_connect_lock); - spin_lock_init(&scif_info.port_lock); - mutex_init(&scif_info.conflock); - mutex_init(&scif_info.connlock); - mutex_init(&scif_info.fencelock); - INIT_LIST_HEAD(&scif_info.uaccept); - INIT_LIST_HEAD(&scif_info.listen); - INIT_LIST_HEAD(&scif_info.zombie); - INIT_LIST_HEAD(&scif_info.connected); - INIT_LIST_HEAD(&scif_info.disconnected); - INIT_LIST_HEAD(&scif_info.rma); - INIT_LIST_HEAD(&scif_info.rma_tc); - INIT_LIST_HEAD(&scif_info.mmu_notif_cleanup); - INIT_LIST_HEAD(&scif_info.fence); - INIT_LIST_HEAD(&scif_info.nb_connect_list); - init_waitqueue_head(&scif_info.exitwq); - scif_info.rma_tc_limit = SCIF_RMA_TEMP_CACHE_LIMIT; - scif_info.en_msg_log = 0; - scif_info.p2p_enable = 1; - rc = scif_setup_scifdev(); - if (rc) - goto error; - unaligned_cache = kmem_cache_create("Unaligned_DMA", - SCIF_KMEM_UNALIGNED_BUF_SIZE, - 0, SLAB_HWCACHE_ALIGN, NULL); - if (!unaligned_cache) { - rc = -ENOMEM; - goto free_sdev; - } - INIT_WORK(&scif_info.misc_work, scif_misc_handler); - INIT_WORK(&scif_info.mmu_notif_work, scif_mmu_notif_handler); - INIT_WORK(&scif_info.conn_work, scif_conn_handler); - idr_init(&scif_ports); - return 0; -free_sdev: - scif_destroy_scifdev(); -error: - return rc; -} - -static void _scif_exit(void) -{ - idr_destroy(&scif_ports); - kmem_cache_destroy(unaligned_cache); - scif_destroy_scifdev(); -} - -static int __init scif_init(void) -{ - struct miscdevice *mdev = &scif_info.mdev; - int rc; - - _scif_init(); - iova_cache_get(); - rc = scif_peer_bus_init(); - if (rc) - goto exit; - rc = scif_register_driver(&scif_driver); - if (rc) - goto peer_bus_exit; - rc = misc_register(mdev); - if (rc) - goto unreg_scif; - scif_init_debugfs(); - return 0; -unreg_scif: - scif_unregister_driver(&scif_driver); -peer_bus_exit: - scif_peer_bus_exit(); -exit: - _scif_exit(); - return rc; -} - -static void __exit scif_exit(void) -{ - scif_exit_debugfs(); - misc_deregister(&scif_info.mdev); - scif_unregister_driver(&scif_driver); - scif_peer_bus_exit(); - iova_cache_put(); - _scif_exit(); -} - -module_init(scif_init); -module_exit(scif_exit); - -MODULE_DEVICE_TABLE(scif, id_table); -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) SCIF driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mic/scif/scif_main.h b/drivers/misc/mic/scif/scif_main.h deleted file mode 100644 index bb3ab97d5b35..000000000000 --- a/drivers/misc/mic/scif/scif_main.h +++ /dev/null @@ -1,274 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#ifndef SCIF_MAIN_H -#define SCIF_MAIN_H - -#include <linux/sched/signal.h> -#include <linux/pci.h> -#include <linux/miscdevice.h> -#include <linux/dmaengine.h> -#include <linux/iova.h> -#include <linux/anon_inodes.h> -#include <linux/file.h> -#include <linux/vmalloc.h> -#include <linux/scif.h> -#include "../common/mic_dev.h" - -#define SCIF_MGMT_NODE 0 -#define SCIF_DEFAULT_WATCHDOG_TO 30 -#define SCIF_NODE_ACCEPT_TIMEOUT (3 * HZ) -#define SCIF_NODE_ALIVE_TIMEOUT (SCIF_DEFAULT_WATCHDOG_TO * HZ) -#define SCIF_RMA_TEMP_CACHE_LIMIT 0x20000 - -/* - * Generic state used for certain node QP message exchanges - * like Unregister, Alloc etc. - */ -enum scif_msg_state { - OP_IDLE = 1, - OP_IN_PROGRESS, - OP_COMPLETED, - OP_FAILED -}; - -/* - * struct scif_info - Global SCIF information - * - * @nodeid: Node ID this node is to others - * @maxid: Max known node ID - * @total: Total number of SCIF nodes - * @nr_zombies: number of zombie endpoints - * @eplock: Lock to synchronize listening, zombie endpoint lists - * @connlock: Lock to synchronize connected and disconnected lists - * @nb_connect_lock: Synchronize non blocking connect operations - * @port_lock: Synchronize access to SCIF ports - * @uaccept: List of user acceptreq waiting for acceptreg - * @listen: List of listening end points - * @zombie: List of zombie end points with pending RMA's - * @connected: List of end points in connected state - * @disconnected: List of end points in disconnected state - * @nb_connect_list: List for non blocking connections - * @misc_work: miscellaneous SCIF tasks - * @conflock: Lock to synchronize SCIF node configuration changes - * @en_msg_log: Enable debug message logging - * @p2p_enable: Enable P2P SCIF network - * @mdev: The MISC device - * @conn_work: Work for workqueue handling all connections - * @exitwq: Wait queue for waiting for an EXIT node QP message response - * @loopb_dev: Dummy SCIF device used for loopback - * @loopb_wq: Workqueue used for handling loopback messages - * @loopb_wqname[16]: Name of loopback workqueue - * @loopb_work: Used for submitting work to loopb_wq - * @loopb_recv_q: List of messages received on the loopb_wq - * @card_initiated_exit: set when the card has initiated the exit - * @rmalock: Synchronize access to RMA operations - * @fencelock: Synchronize access to list of remote fences requested. - * @rma: List of temporary registered windows to be destroyed. - * @rma_tc: List of temporary registered & cached Windows to be destroyed - * @fence: List of remote fence requests - * @mmu_notif_work: Work for registration caching MMU notifier workqueue - * @mmu_notif_cleanup: List of temporary cached windows for reg cache - * @rma_tc_limit: RMA temporary cache limit - */ -struct scif_info { - u8 nodeid; - u8 maxid; - u8 total; - u32 nr_zombies; - struct mutex eplock; - struct mutex connlock; - spinlock_t nb_connect_lock; - spinlock_t port_lock; - struct list_head uaccept; - struct list_head listen; - struct list_head zombie; - struct list_head connected; - struct list_head disconnected; - struct list_head nb_connect_list; - struct work_struct misc_work; - struct mutex conflock; - u8 en_msg_log; - u8 p2p_enable; - struct miscdevice mdev; - struct work_struct conn_work; - wait_queue_head_t exitwq; - struct scif_dev *loopb_dev; - struct workqueue_struct *loopb_wq; - char loopb_wqname[16]; - struct work_struct loopb_work; - struct list_head loopb_recv_q; - bool card_initiated_exit; - spinlock_t rmalock; - struct mutex fencelock; - struct list_head rma; - struct list_head rma_tc; - struct list_head fence; - struct work_struct mmu_notif_work; - struct list_head mmu_notif_cleanup; - unsigned long rma_tc_limit; -}; - -/* - * struct scif_p2p_info - SCIF mapping information used for P2P - * - * @ppi_peer_id - SCIF peer node id - * @ppi_sg - Scatter list for bar information (One for mmio and one for aper) - * @sg_nentries - Number of entries in the scatterlist - * @ppi_da: DMA address for MMIO and APER bars - * @ppi_len: Length of MMIO and APER bars - * @ppi_list: Link in list of mapping information - */ -struct scif_p2p_info { - u8 ppi_peer_id; - struct scatterlist *ppi_sg[2]; - u64 sg_nentries[2]; - dma_addr_t ppi_da[2]; - u64 ppi_len[2]; -#define SCIF_PPI_MMIO 0 -#define SCIF_PPI_APER 1 - struct list_head ppi_list; -}; - -/* - * struct scif_dev - SCIF remote device specific fields - * - * @node: Node id - * @p2p: List of P2P mapping information - * @qpairs: The node queue pair for exchanging control messages - * @intr_wq: Workqueue for handling Node QP messages - * @intr_wqname: Name of node QP workqueue for handling interrupts - * @intr_bh: Used for submitting work to intr_wq - * @lock: Lock used for synchronizing access to the scif device - * @sdev: SCIF hardware device on the SCIF hardware bus - * @db: doorbell the peer will trigger to generate an interrupt on self - * @rdb: Doorbell to trigger on the peer to generate an interrupt on the peer - * @cookie: Cookie received while registering the interrupt handler - * @peer_add_work: Work for handling device_add for peer devices - * @p2p_dwork: Delayed work to enable polling for P2P state - * @qp_dwork: Delayed work for enabling polling for remote QP information - * @p2p_retry: Number of times to retry polling of P2P state - * @base_addr: P2P aperture bar base address - * @mic_mw mmio: The peer MMIO information used for P2P - * @spdev: SCIF peer device on the SCIF peer bus - * @node_remove_ack_pending: True if a node_remove_ack is pending - * @exit_ack_pending: true if an exit_ack is pending - * @disconn_wq: Used while waiting for a node remove response - * @disconn_rescnt: Keeps track of number of node remove requests sent - * @exit: Status of exit message - * @qp_dma_addr: Queue pair DMA address passed to the peer - * @dma_ch_idx: Round robin index for DMA channels - * @signal_pool: DMA pool used for scheduling scif_fence_signal DMA's -*/ -struct scif_dev { - u8 node; - struct list_head p2p; - struct scif_qp *qpairs; - struct workqueue_struct *intr_wq; - char intr_wqname[16]; - struct work_struct intr_bh; - struct mutex lock; - struct scif_hw_dev *sdev; - int db; - int rdb; - struct mic_irq *cookie; - struct work_struct peer_add_work; - struct delayed_work p2p_dwork; - struct delayed_work qp_dwork; - int p2p_retry; - dma_addr_t base_addr; - struct mic_mw mmio; - struct scif_peer_dev __rcu *spdev; - bool node_remove_ack_pending; - bool exit_ack_pending; - wait_queue_head_t disconn_wq; - atomic_t disconn_rescnt; - enum scif_msg_state exit; - dma_addr_t qp_dma_addr; - int dma_ch_idx; - struct dma_pool *signal_pool; -}; - -extern bool scif_reg_cache_enable; -extern bool scif_ulimit_check; -extern struct scif_info scif_info; -extern struct idr scif_ports; -extern struct bus_type scif_peer_bus; -extern struct scif_dev *scif_dev; -extern const struct file_operations scif_fops; -extern const struct file_operations scif_anon_fops; - -/* Size of the RB for the Node QP */ -#define SCIF_NODE_QP_SIZE 0x10000 - -#include "scif_nodeqp.h" -#include "scif_rma.h" -#include "scif_rma_list.h" - -/* - * scifdev_self: - * @dev: The remote SCIF Device - * - * Returns true if the SCIF Device passed is the self aka Loopback SCIF device. - */ -static inline int scifdev_self(struct scif_dev *dev) -{ - return dev->node == scif_info.nodeid; -} - -static inline bool scif_is_mgmt_node(void) -{ - return !scif_info.nodeid; -} - -/* - * scifdev_is_p2p: - * @dev: The remote SCIF Device - * - * Returns true if the SCIF Device is a MIC Peer to Peer SCIF device. - */ -static inline bool scifdev_is_p2p(struct scif_dev *dev) -{ - if (scif_is_mgmt_node()) - return false; - else - return dev != &scif_dev[SCIF_MGMT_NODE] && - !scifdev_self(dev); -} - -/* - * scifdev_alive: - * @scifdev: The remote SCIF Device - * - * Returns true if the remote SCIF Device is running or sleeping for - * this endpoint. - */ -static inline int _scifdev_alive(struct scif_dev *scifdev) -{ - struct scif_peer_dev *spdev; - - rcu_read_lock(); - spdev = rcu_dereference(scifdev->spdev); - rcu_read_unlock(); - return !!spdev; -} - -#include "scif_epd.h" - -void __init scif_init_debugfs(void); -void scif_exit_debugfs(void); -int scif_setup_intr_wq(struct scif_dev *scifdev); -void scif_destroy_intr_wq(struct scif_dev *scifdev); -void scif_cleanup_scifdev(struct scif_dev *dev); -void scif_handle_remove_node(int node); -void scif_disconnect_node(u32 node_id, bool mgmt_initiated); -void scif_free_qp(struct scif_dev *dev); -void scif_misc_handler(struct work_struct *work); -void scif_stop(struct scif_dev *scifdev); -irqreturn_t scif_intr_handler(int irq, void *data); -#endif /* SCIF_MAIN_H */ diff --git a/drivers/misc/mic/scif/scif_map.h b/drivers/misc/mic/scif/scif_map.h deleted file mode 100644 index 96b760819bfc..000000000000 --- a/drivers/misc/mic/scif/scif_map.h +++ /dev/null @@ -1,127 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#ifndef SCIF_MAP_H -#define SCIF_MAP_H - -#include "../bus/scif_bus.h" - -static __always_inline void * -scif_alloc_coherent(dma_addr_t *dma_handle, - struct scif_dev *scifdev, size_t size, - gfp_t gfp) -{ - void *va; - - if (scifdev_self(scifdev)) { - va = kmalloc(size, gfp); - if (va) - *dma_handle = virt_to_phys(va); - } else { - va = dma_alloc_coherent(&scifdev->sdev->dev, - size, dma_handle, gfp); - if (va && scifdev_is_p2p(scifdev)) - *dma_handle = *dma_handle + scifdev->base_addr; - } - return va; -} - -static __always_inline void -scif_free_coherent(void *va, dma_addr_t local, - struct scif_dev *scifdev, size_t size) -{ - if (scifdev_self(scifdev)) { - kfree(va); - } else { - if (scifdev_is_p2p(scifdev) && local > scifdev->base_addr) - local = local - scifdev->base_addr; - dma_free_coherent(&scifdev->sdev->dev, - size, va, local); - } -} - -static __always_inline int -scif_map_single(dma_addr_t *dma_handle, - void *local, struct scif_dev *scifdev, size_t size) -{ - int err = 0; - - if (scifdev_self(scifdev)) { - *dma_handle = virt_to_phys((local)); - } else { - *dma_handle = dma_map_single(&scifdev->sdev->dev, - local, size, DMA_BIDIRECTIONAL); - if (dma_mapping_error(&scifdev->sdev->dev, *dma_handle)) - err = -ENOMEM; - else if (scifdev_is_p2p(scifdev)) - *dma_handle = *dma_handle + scifdev->base_addr; - } - if (err) - *dma_handle = 0; - return err; -} - -static __always_inline void -scif_unmap_single(dma_addr_t local, struct scif_dev *scifdev, - size_t size) -{ - if (!scifdev_self(scifdev)) { - if (scifdev_is_p2p(scifdev)) - local = local - scifdev->base_addr; - dma_unmap_single(&scifdev->sdev->dev, local, - size, DMA_BIDIRECTIONAL); - } -} - -static __always_inline void * -scif_ioremap(dma_addr_t phys, size_t size, struct scif_dev *scifdev) -{ - void *out_virt; - struct scif_hw_dev *sdev = scifdev->sdev; - - if (scifdev_self(scifdev)) - out_virt = phys_to_virt(phys); - else - out_virt = (void __force *) - sdev->hw_ops->remap(sdev, phys, size); - return out_virt; -} - -static __always_inline void -scif_iounmap(void *virt, size_t len, struct scif_dev *scifdev) -{ - if (!scifdev_self(scifdev)) { - struct scif_hw_dev *sdev = scifdev->sdev; - - sdev->hw_ops->unmap(sdev, (void __force __iomem *)virt); - } -} - -static __always_inline int -scif_map_page(dma_addr_t *dma_handle, struct page *page, - struct scif_dev *scifdev) -{ - int err = 0; - - if (scifdev_self(scifdev)) { - *dma_handle = page_to_phys(page); - } else { - struct scif_hw_dev *sdev = scifdev->sdev; - *dma_handle = dma_map_page(&sdev->dev, - page, 0x0, PAGE_SIZE, - DMA_BIDIRECTIONAL); - if (dma_mapping_error(&sdev->dev, *dma_handle)) - err = -ENOMEM; - else if (scifdev_is_p2p(scifdev)) - *dma_handle = *dma_handle + scifdev->base_addr; - } - if (err) - *dma_handle = 0; - return err; -} -#endif /* SCIF_MAP_H */ diff --git a/drivers/misc/mic/scif/scif_mmap.c b/drivers/misc/mic/scif/scif_mmap.c deleted file mode 100644 index a151d416f39c..000000000000 --- a/drivers/misc/mic/scif/scif_mmap.c +++ /dev/null @@ -1,690 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel SCIF driver. - */ -#include "scif_main.h" - -/* - * struct scif_vma_info - Information about a remote memory mapping - * created via scif_mmap(..) - * @vma: VM area struct - * @list: link to list of active vmas - */ -struct scif_vma_info { - struct vm_area_struct *vma; - struct list_head list; -}; - -void scif_recv_munmap(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_rma_req req; - struct scif_window *window = NULL; - struct scif_window *recv_window = - (struct scif_window *)msg->payload[0]; - struct scif_endpt *ep; - - ep = (struct scif_endpt *)recv_window->ep; - req.out_window = &window; - req.offset = recv_window->offset; - req.prot = recv_window->prot; - req.nr_bytes = recv_window->nr_pages << PAGE_SHIFT; - req.type = SCIF_WINDOW_FULL; - req.head = &ep->rma_info.reg_list; - msg->payload[0] = ep->remote_ep; - - mutex_lock(&ep->rma_info.rma_lock); - /* Does a valid window exist? */ - if (scif_query_window(&req)) { - dev_err(&scifdev->sdev->dev, - "%s %d -ENXIO\n", __func__, __LINE__); - msg->uop = SCIF_UNREGISTER_ACK; - goto error; - } - - scif_put_window(window, window->nr_pages); - - if (!window->ref_count) { - atomic_inc(&ep->rma_info.tw_refcount); - ep->rma_info.async_list_del = 1; - list_del_init(&window->list); - scif_free_window_offset(ep, window, window->offset); - } -error: - mutex_unlock(&ep->rma_info.rma_lock); - if (window && !window->ref_count) - scif_queue_for_cleanup(window, &scif_info.rma); -} - -/* - * Remove valid remote memory mappings created via scif_mmap(..) from the - * process address space since the remote node is lost - */ -static void __scif_zap_mmaps(struct scif_endpt *ep) -{ - struct list_head *item; - struct scif_vma_info *info; - struct vm_area_struct *vma; - unsigned long size; - - spin_lock(&ep->lock); - list_for_each(item, &ep->rma_info.vma_list) { - info = list_entry(item, struct scif_vma_info, list); - vma = info->vma; - size = vma->vm_end - vma->vm_start; - zap_vma_ptes(vma, vma->vm_start, size); - dev_dbg(scif_info.mdev.this_device, - "%s ep %p zap vma %p size 0x%lx\n", - __func__, ep, info->vma, size); - } - spin_unlock(&ep->lock); -} - -/* - * Traverse the list of endpoints for a particular remote node and - * zap valid remote memory mappings since the remote node is lost - */ -static void _scif_zap_mmaps(int node, struct list_head *head) -{ - struct scif_endpt *ep; - struct list_head *item; - - mutex_lock(&scif_info.connlock); - list_for_each(item, head) { - ep = list_entry(item, struct scif_endpt, list); - if (ep->remote_dev->node == node) - __scif_zap_mmaps(ep); - } - mutex_unlock(&scif_info.connlock); -} - -/* - * Wrapper for removing remote memory mappings for a particular node. This API - * is called by peer nodes as part of handling a lost node. - */ -void scif_zap_mmaps(int node) -{ - _scif_zap_mmaps(node, &scif_info.connected); - _scif_zap_mmaps(node, &scif_info.disconnected); -} - -/* - * This API is only called while handling a lost node: - * a) Remote node is dead. - * b) Remote memory mappings have been zapped - * So we can traverse the remote_reg_list without any locks. Since - * the window has not yet been unregistered we can drop the ref count - * and queue it to the cleanup thread. - */ -static void __scif_cleanup_rma_for_zombies(struct scif_endpt *ep) -{ - struct list_head *pos, *tmp; - struct scif_window *window; - - list_for_each_safe(pos, tmp, &ep->rma_info.remote_reg_list) { - window = list_entry(pos, struct scif_window, list); - if (window->ref_count) - scif_put_window(window, window->nr_pages); - else - dev_err(scif_info.mdev.this_device, - "%s %d unexpected\n", - __func__, __LINE__); - if (!window->ref_count) { - atomic_inc(&ep->rma_info.tw_refcount); - list_del_init(&window->list); - scif_queue_for_cleanup(window, &scif_info.rma); - } - } -} - -/* Cleanup remote registration lists for zombie endpoints */ -void scif_cleanup_rma_for_zombies(int node) -{ - struct scif_endpt *ep; - struct list_head *item; - - mutex_lock(&scif_info.eplock); - list_for_each(item, &scif_info.zombie) { - ep = list_entry(item, struct scif_endpt, list); - if (ep->remote_dev && ep->remote_dev->node == node) - __scif_cleanup_rma_for_zombies(ep); - } - mutex_unlock(&scif_info.eplock); - flush_work(&scif_info.misc_work); -} - -/* Insert the VMA into the per endpoint VMA list */ -static int scif_insert_vma(struct scif_endpt *ep, struct vm_area_struct *vma) -{ - struct scif_vma_info *info; - int err = 0; - - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) { - err = -ENOMEM; - goto done; - } - info->vma = vma; - spin_lock(&ep->lock); - list_add_tail(&info->list, &ep->rma_info.vma_list); - spin_unlock(&ep->lock); -done: - return err; -} - -/* Delete the VMA from the per endpoint VMA list */ -static void scif_delete_vma(struct scif_endpt *ep, struct vm_area_struct *vma) -{ - struct list_head *item; - struct scif_vma_info *info; - - spin_lock(&ep->lock); - list_for_each(item, &ep->rma_info.vma_list) { - info = list_entry(item, struct scif_vma_info, list); - if (info->vma == vma) { - list_del(&info->list); - kfree(info); - break; - } - } - spin_unlock(&ep->lock); -} - -static phys_addr_t scif_get_phys(phys_addr_t phys, struct scif_endpt *ep) -{ - struct scif_dev *scifdev = (struct scif_dev *)ep->remote_dev; - struct scif_hw_dev *sdev = scifdev->sdev; - phys_addr_t out_phys, apt_base = 0; - - /* - * If the DMA address is card relative then we need to add the - * aperture base for mmap to work correctly - */ - if (!scifdev_self(scifdev) && sdev->aper && sdev->card_rel_da) - apt_base = sdev->aper->pa; - out_phys = apt_base + phys; - return out_phys; -} - -int scif_get_pages(scif_epd_t epd, off_t offset, size_t len, - struct scif_range **pages) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - struct scif_rma_req req; - struct scif_window *window = NULL; - int nr_pages, err, i; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI get_pinned_pages: ep %p offset 0x%lx len 0x%lx\n", - ep, offset, len); - err = scif_verify_epd(ep); - if (err) - return err; - - if (!len || (offset < 0) || - (offset + len < offset) || - (ALIGN(offset, PAGE_SIZE) != offset) || - (ALIGN(len, PAGE_SIZE) != len)) - return -EINVAL; - - nr_pages = len >> PAGE_SHIFT; - - req.out_window = &window; - req.offset = offset; - req.prot = 0; - req.nr_bytes = len; - req.type = SCIF_WINDOW_SINGLE; - req.head = &ep->rma_info.remote_reg_list; - - mutex_lock(&ep->rma_info.rma_lock); - /* Does a valid window exist? */ - err = scif_query_window(&req); - if (err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); - goto error; - } - - /* Allocate scif_range */ - *pages = kzalloc(sizeof(**pages), GFP_KERNEL); - if (!*pages) { - err = -ENOMEM; - goto error; - } - - /* Allocate phys addr array */ - (*pages)->phys_addr = scif_zalloc(nr_pages * sizeof(dma_addr_t)); - if (!((*pages)->phys_addr)) { - err = -ENOMEM; - goto error; - } - - if (scif_is_mgmt_node() && !scifdev_self(ep->remote_dev)) { - /* Allocate virtual address array */ - ((*pages)->va = scif_zalloc(nr_pages * sizeof(void *))); - if (!(*pages)->va) { - err = -ENOMEM; - goto error; - } - } - /* Populate the values */ - (*pages)->cookie = window; - (*pages)->nr_pages = nr_pages; - (*pages)->prot_flags = window->prot; - - for (i = 0; i < nr_pages; i++) { - (*pages)->phys_addr[i] = - __scif_off_to_dma_addr(window, offset + - (i * PAGE_SIZE)); - (*pages)->phys_addr[i] = scif_get_phys((*pages)->phys_addr[i], - ep); - if (scif_is_mgmt_node() && !scifdev_self(ep->remote_dev)) - (*pages)->va[i] = - ep->remote_dev->sdev->aper->va + - (*pages)->phys_addr[i] - - ep->remote_dev->sdev->aper->pa; - } - - scif_get_window(window, nr_pages); -error: - mutex_unlock(&ep->rma_info.rma_lock); - if (err) { - if (*pages) { - scif_free((*pages)->phys_addr, - nr_pages * sizeof(dma_addr_t)); - scif_free((*pages)->va, - nr_pages * sizeof(void *)); - kfree(*pages); - *pages = NULL; - } - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); - } - return err; -} -EXPORT_SYMBOL_GPL(scif_get_pages); - -int scif_put_pages(struct scif_range *pages) -{ - struct scif_endpt *ep; - struct scif_window *window; - struct scifmsg msg; - - if (!pages || !pages->cookie) - return -EINVAL; - - window = pages->cookie; - - if (!window || window->magic != SCIFEP_MAGIC) - return -EINVAL; - - ep = (struct scif_endpt *)window->ep; - /* - * If the state is SCIFEP_CONNECTED or SCIFEP_DISCONNECTED then the - * callee should be allowed to release references to the pages, - * else the endpoint was not connected in the first place, - * hence the ENOTCONN. - */ - if (ep->state != SCIFEP_CONNECTED && ep->state != SCIFEP_DISCONNECTED) - return -ENOTCONN; - - mutex_lock(&ep->rma_info.rma_lock); - - scif_put_window(window, pages->nr_pages); - - /* Initiate window destruction if ref count is zero */ - if (!window->ref_count) { - list_del(&window->list); - mutex_unlock(&ep->rma_info.rma_lock); - scif_drain_dma_intr(ep->remote_dev->sdev, - ep->rma_info.dma_chan); - /* Inform the peer about this window being destroyed. */ - msg.uop = SCIF_MUNMAP; - msg.src = ep->port; - msg.payload[0] = window->peer_window; - /* No error handling for notification messages */ - scif_nodeqp_send(ep->remote_dev, &msg); - /* Destroy this window from the peer's registered AS */ - scif_destroy_remote_window(window); - } else { - mutex_unlock(&ep->rma_info.rma_lock); - } - - scif_free(pages->phys_addr, pages->nr_pages * sizeof(dma_addr_t)); - scif_free(pages->va, pages->nr_pages * sizeof(void *)); - kfree(pages); - return 0; -} -EXPORT_SYMBOL_GPL(scif_put_pages); - -/* - * scif_rma_list_mmap: - * - * Traverse the remote registration list starting from start_window: - * 1) Create VtoP mappings via remap_pfn_range(..) - * 2) Once step 1) and 2) complete successfully then traverse the range of - * windows again and bump the reference count. - * RMA lock must be held. - */ -static int scif_rma_list_mmap(struct scif_window *start_window, s64 offset, - int nr_pages, struct vm_area_struct *vma) -{ - s64 end_offset, loop_offset = offset; - struct scif_window *window = start_window; - int loop_nr_pages, nr_pages_left = nr_pages; - struct scif_endpt *ep = (struct scif_endpt *)start_window->ep; - struct list_head *head = &ep->rma_info.remote_reg_list; - int i, err = 0; - dma_addr_t phys_addr; - struct scif_window_iter src_win_iter; - size_t contig_bytes = 0; - - might_sleep(); - list_for_each_entry_from(window, head, list) { - end_offset = window->offset + - (window->nr_pages << PAGE_SHIFT); - loop_nr_pages = min_t(int, - (end_offset - loop_offset) >> PAGE_SHIFT, - nr_pages_left); - scif_init_window_iter(window, &src_win_iter); - for (i = 0; i < loop_nr_pages; i++) { - phys_addr = scif_off_to_dma_addr(window, loop_offset, - &contig_bytes, - &src_win_iter); - phys_addr = scif_get_phys(phys_addr, ep); - err = remap_pfn_range(vma, - vma->vm_start + - loop_offset - offset, - phys_addr >> PAGE_SHIFT, - PAGE_SIZE, - vma->vm_page_prot); - if (err) - goto error; - loop_offset += PAGE_SIZE; - } - nr_pages_left -= loop_nr_pages; - if (!nr_pages_left) - break; - } - /* - * No more failures expected. Bump up the ref count for all - * the windows. Another traversal from start_window required - * for handling errors encountered across windows during - * remap_pfn_range(..). - */ - loop_offset = offset; - nr_pages_left = nr_pages; - window = start_window; - head = &ep->rma_info.remote_reg_list; - list_for_each_entry_from(window, head, list) { - end_offset = window->offset + - (window->nr_pages << PAGE_SHIFT); - loop_nr_pages = min_t(int, - (end_offset - loop_offset) >> PAGE_SHIFT, - nr_pages_left); - scif_get_window(window, loop_nr_pages); - nr_pages_left -= loop_nr_pages; - loop_offset += (loop_nr_pages << PAGE_SHIFT); - if (!nr_pages_left) - break; - } -error: - if (err) - dev_err(scif_info.mdev.this_device, - "%s %d err %d\n", __func__, __LINE__, err); - return err; -} - -/* - * scif_rma_list_munmap: - * - * Traverse the remote registration list starting from window: - * 1) Decrement ref count. - * 2) If the ref count drops to zero then send a SCIF_MUNMAP message to peer. - * RMA lock must be held. - */ -static void scif_rma_list_munmap(struct scif_window *start_window, - s64 offset, int nr_pages) -{ - struct scifmsg msg; - s64 loop_offset = offset, end_offset; - int loop_nr_pages, nr_pages_left = nr_pages; - struct scif_endpt *ep = (struct scif_endpt *)start_window->ep; - struct list_head *head = &ep->rma_info.remote_reg_list; - struct scif_window *window = start_window, *_window; - - msg.uop = SCIF_MUNMAP; - msg.src = ep->port; - loop_offset = offset; - nr_pages_left = nr_pages; - list_for_each_entry_safe_from(window, _window, head, list) { - end_offset = window->offset + - (window->nr_pages << PAGE_SHIFT); - loop_nr_pages = min_t(int, - (end_offset - loop_offset) >> PAGE_SHIFT, - nr_pages_left); - scif_put_window(window, loop_nr_pages); - if (!window->ref_count) { - struct scif_dev *rdev = ep->remote_dev; - - scif_drain_dma_intr(rdev->sdev, - ep->rma_info.dma_chan); - /* Inform the peer about this munmap */ - msg.payload[0] = window->peer_window; - /* No error handling for Notification messages. */ - scif_nodeqp_send(ep->remote_dev, &msg); - list_del(&window->list); - /* Destroy this window from the peer's registered AS */ - scif_destroy_remote_window(window); - } - nr_pages_left -= loop_nr_pages; - loop_offset += (loop_nr_pages << PAGE_SHIFT); - if (!nr_pages_left) - break; - } -} - -/* - * The private data field of each VMA used to mmap a remote window - * points to an instance of struct vma_pvt - */ -struct vma_pvt { - struct scif_endpt *ep; /* End point for remote window */ - s64 offset; /* offset within remote window */ - bool valid_offset; /* offset is valid only if the original - * mmap request was for a single page - * else the offset within the vma is - * the correct offset - */ - struct kref ref; -}; - -static void vma_pvt_release(struct kref *ref) -{ - struct vma_pvt *vmapvt = container_of(ref, struct vma_pvt, ref); - - kfree(vmapvt); -} - -/** - * scif_vma_open - VMA open driver callback - * @vma: VMM memory area. - * The open method is called by the kernel to allow the subsystem implementing - * the VMA to initialize the area. This method is invoked any time a new - * reference to the VMA is made (when a process forks, for example). - * The one exception happens when the VMA is first created by mmap; - * in this case, the driver's mmap method is called instead. - * This function is also invoked when an existing VMA is split by the kernel - * due to a call to munmap on a subset of the VMA resulting in two VMAs. - * The kernel invokes this function only on one of the two VMAs. - */ -static void scif_vma_open(struct vm_area_struct *vma) -{ - struct vma_pvt *vmapvt = vma->vm_private_data; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI vma open: vma_start 0x%lx vma_end 0x%lx\n", - vma->vm_start, vma->vm_end); - scif_insert_vma(vmapvt->ep, vma); - kref_get(&vmapvt->ref); -} - -/** - * scif_munmap - VMA close driver callback. - * @vma: VMM memory area. - * When an area is destroyed, the kernel calls its close operation. - * Note that there's no usage count associated with VMA's; the area - * is opened and closed exactly once by each process that uses it. - */ -static void scif_munmap(struct vm_area_struct *vma) -{ - struct scif_endpt *ep; - struct vma_pvt *vmapvt = vma->vm_private_data; - int nr_pages = vma_pages(vma); - s64 offset; - struct scif_rma_req req; - struct scif_window *window = NULL; - int err; - - might_sleep(); - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI munmap: vma_start 0x%lx vma_end 0x%lx\n", - vma->vm_start, vma->vm_end); - ep = vmapvt->ep; - offset = vmapvt->valid_offset ? vmapvt->offset : - (vma->vm_pgoff) << PAGE_SHIFT; - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI munmap: ep %p nr_pages 0x%x offset 0x%llx\n", - ep, nr_pages, offset); - req.out_window = &window; - req.offset = offset; - req.nr_bytes = vma->vm_end - vma->vm_start; - req.prot = vma->vm_flags & (VM_READ | VM_WRITE); - req.type = SCIF_WINDOW_PARTIAL; - req.head = &ep->rma_info.remote_reg_list; - - mutex_lock(&ep->rma_info.rma_lock); - - err = scif_query_window(&req); - if (err) - dev_err(scif_info.mdev.this_device, - "%s %d err %d\n", __func__, __LINE__, err); - else - scif_rma_list_munmap(window, offset, nr_pages); - - mutex_unlock(&ep->rma_info.rma_lock); - /* - * The kernel probably zeroes these out but we still want - * to clean up our own mess just in case. - */ - vma->vm_ops = NULL; - vma->vm_private_data = NULL; - kref_put(&vmapvt->ref, vma_pvt_release); - scif_delete_vma(ep, vma); -} - -static const struct vm_operations_struct scif_vm_ops = { - .open = scif_vma_open, - .close = scif_munmap, -}; - -/** - * scif_mmap - Map pages in virtual address space to a remote window. - * @vma: VMM memory area. - * @epd: endpoint descriptor - * - * Return: Upon successful completion, scif_mmap() returns zero - * else an apt error is returned as documented in scif.h - */ -int scif_mmap(struct vm_area_struct *vma, scif_epd_t epd) -{ - struct scif_rma_req req; - struct scif_window *window = NULL; - struct scif_endpt *ep = (struct scif_endpt *)epd; - s64 start_offset = vma->vm_pgoff << PAGE_SHIFT; - int nr_pages = vma_pages(vma); - int err; - struct vma_pvt *vmapvt; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI mmap: ep %p start_offset 0x%llx nr_pages 0x%x\n", - ep, start_offset, nr_pages); - err = scif_verify_epd(ep); - if (err) - return err; - - might_sleep(); - - err = scif_insert_vma(ep, vma); - if (err) - return err; - - vmapvt = kzalloc(sizeof(*vmapvt), GFP_KERNEL); - if (!vmapvt) { - scif_delete_vma(ep, vma); - return -ENOMEM; - } - - vmapvt->ep = ep; - kref_init(&vmapvt->ref); - - req.out_window = &window; - req.offset = start_offset; - req.nr_bytes = vma->vm_end - vma->vm_start; - req.prot = vma->vm_flags & (VM_READ | VM_WRITE); - req.type = SCIF_WINDOW_PARTIAL; - req.head = &ep->rma_info.remote_reg_list; - - mutex_lock(&ep->rma_info.rma_lock); - /* Does a valid window exist? */ - err = scif_query_window(&req); - if (err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); - goto error_unlock; - } - - /* Default prot for loopback */ - if (!scifdev_self(ep->remote_dev)) - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - - /* - * VM_DONTCOPY - Do not copy this vma on fork - * VM_DONTEXPAND - Cannot expand with mremap() - * VM_RESERVED - Count as reserved_vm like IO - * VM_PFNMAP - Page-ranges managed without "struct page" - * VM_IO - Memory mapped I/O or similar - * - * We do not want to copy this VMA automatically on a fork(), - * expand this VMA due to mremap() or swap out these pages since - * the VMA is actually backed by physical pages in the remote - * node's physical memory and not via a struct page. - */ - vma->vm_flags |= VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP; - - if (!scifdev_self(ep->remote_dev)) - vma->vm_flags |= VM_IO | VM_PFNMAP; - - /* Map this range of windows */ - err = scif_rma_list_mmap(window, start_offset, nr_pages, vma); - if (err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); - goto error_unlock; - } - /* Set up the driver call back */ - vma->vm_ops = &scif_vm_ops; - vma->vm_private_data = vmapvt; -error_unlock: - mutex_unlock(&ep->rma_info.rma_lock); - if (err) { - kfree(vmapvt); - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); - scif_delete_vma(ep, vma); - } - return err; -} diff --git a/drivers/misc/mic/scif/scif_nm.c b/drivers/misc/mic/scif/scif_nm.c deleted file mode 100644 index c4d9422082b7..000000000000 --- a/drivers/misc/mic/scif/scif_nm.c +++ /dev/null @@ -1,229 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#include "scif_peer_bus.h" - -#include "scif_main.h" -#include "scif_map.h" - -/** - * scif_invalidate_ep() - Set state for all connected endpoints - * to disconnected and wake up all send/recv waitqueues - * - * @node: Node to invalidate - */ -static void scif_invalidate_ep(int node) -{ - struct scif_endpt *ep; - struct list_head *pos, *tmpq; - - flush_work(&scif_info.conn_work); - mutex_lock(&scif_info.connlock); - list_for_each_safe(pos, tmpq, &scif_info.disconnected) { - ep = list_entry(pos, struct scif_endpt, list); - if (ep->remote_dev->node == node) { - scif_unmap_all_windows(ep); - spin_lock(&ep->lock); - scif_cleanup_ep_qp(ep); - spin_unlock(&ep->lock); - } - } - list_for_each_safe(pos, tmpq, &scif_info.connected) { - ep = list_entry(pos, struct scif_endpt, list); - if (ep->remote_dev->node == node) { - list_del(pos); - spin_lock(&ep->lock); - ep->state = SCIFEP_DISCONNECTED; - list_add_tail(&ep->list, &scif_info.disconnected); - scif_cleanup_ep_qp(ep); - wake_up_interruptible(&ep->sendwq); - wake_up_interruptible(&ep->recvwq); - spin_unlock(&ep->lock); - scif_unmap_all_windows(ep); - } - } - mutex_unlock(&scif_info.connlock); -} - -void scif_free_qp(struct scif_dev *scifdev) -{ - struct scif_qp *qp = scifdev->qpairs; - - if (!qp) - return; - scif_unmap_single(qp->local_buf, scifdev, qp->inbound_q.size); - kfree(qp->inbound_q.rb_base); - scif_unmap_single(qp->local_qp, scifdev, sizeof(struct scif_qp)); - kfree(scifdev->qpairs); - scifdev->qpairs = NULL; -} - -static void scif_cleanup_qp(struct scif_dev *dev) -{ - struct scif_qp *qp = &dev->qpairs[0]; - - if (!qp) - return; - scif_iounmap((void *)qp->remote_qp, sizeof(struct scif_qp), dev); - scif_iounmap((void *)qp->outbound_q.rb_base, - sizeof(struct scif_qp), dev); - qp->remote_qp = NULL; - qp->local_write = 0; - qp->inbound_q.current_write_offset = 0; - qp->inbound_q.current_read_offset = 0; - if (scifdev_is_p2p(dev)) - scif_free_qp(dev); -} - -void scif_send_acks(struct scif_dev *dev) -{ - struct scifmsg msg; - - if (dev->node_remove_ack_pending) { - msg.uop = SCIF_NODE_REMOVE_ACK; - msg.src.node = scif_info.nodeid; - msg.dst.node = SCIF_MGMT_NODE; - msg.payload[0] = dev->node; - scif_nodeqp_send(&scif_dev[SCIF_MGMT_NODE], &msg); - dev->node_remove_ack_pending = false; - } - if (dev->exit_ack_pending) { - msg.uop = SCIF_EXIT_ACK; - msg.src.node = scif_info.nodeid; - msg.dst.node = dev->node; - scif_nodeqp_send(dev, &msg); - dev->exit_ack_pending = false; - } -} - -/** - * scif_cleanup_scifdev - Uninitialize SCIF data structures for remote - * SCIF device. - * @dev: Remote SCIF device. - */ -void scif_cleanup_scifdev(struct scif_dev *dev) -{ - struct scif_hw_dev *sdev = dev->sdev; - - if (!dev->sdev) - return; - if (scifdev_is_p2p(dev)) { - if (dev->cookie) { - sdev->hw_ops->free_irq(sdev, dev->cookie, dev); - dev->cookie = NULL; - } - scif_destroy_intr_wq(dev); - } - flush_work(&scif_info.misc_work); - scif_destroy_p2p(dev); - scif_invalidate_ep(dev->node); - scif_zap_mmaps(dev->node); - scif_cleanup_rma_for_zombies(dev->node); - flush_work(&scif_info.misc_work); - scif_send_acks(dev); - if (!dev->node && scif_info.card_initiated_exit) { - /* - * Send an SCIF_EXIT message which is the last message from MIC - * to the Host and wait for a SCIF_EXIT_ACK - */ - scif_send_exit(dev); - scif_info.card_initiated_exit = false; - } - scif_cleanup_qp(dev); -} - -/** - * scif_remove_node - * - * @node: Node to remove - */ -void scif_handle_remove_node(int node) -{ - struct scif_dev *scifdev = &scif_dev[node]; - - if (scif_peer_unregister_device(scifdev)) - scif_send_acks(scifdev); -} - -static int scif_send_rmnode_msg(int node, int remove_node) -{ - struct scifmsg notif_msg; - struct scif_dev *dev = &scif_dev[node]; - - notif_msg.uop = SCIF_NODE_REMOVE; - notif_msg.src.node = scif_info.nodeid; - notif_msg.dst.node = node; - notif_msg.payload[0] = remove_node; - return scif_nodeqp_send(dev, ¬if_msg); -} - -/** - * scif_node_disconnect - * - * @node_id: source node id [in] - * @mgmt_initiated: Disconnection initiated from the mgmt node - * - * Disconnect a node from the scif network. - */ -void scif_disconnect_node(u32 node_id, bool mgmt_initiated) -{ - int ret; - int msg_cnt = 0; - u32 i = 0; - struct scif_dev *scifdev = &scif_dev[node_id]; - - if (!node_id) - return; - - atomic_set(&scifdev->disconn_rescnt, 0); - - /* Destroy p2p network */ - for (i = 1; i <= scif_info.maxid; i++) { - if (i == node_id) - continue; - ret = scif_send_rmnode_msg(i, node_id); - if (!ret) - msg_cnt++; - } - /* Wait for the remote nodes to respond with SCIF_NODE_REMOVE_ACK */ - ret = wait_event_timeout(scifdev->disconn_wq, - (atomic_read(&scifdev->disconn_rescnt) - == msg_cnt), SCIF_NODE_ALIVE_TIMEOUT); - /* Tell the card to clean up */ - if (mgmt_initiated && _scifdev_alive(scifdev)) - /* - * Send an SCIF_EXIT message which is the last message from Host - * to the MIC and wait for a SCIF_EXIT_ACK - */ - scif_send_exit(scifdev); - atomic_set(&scifdev->disconn_rescnt, 0); - /* Tell the mgmt node to clean up */ - ret = scif_send_rmnode_msg(SCIF_MGMT_NODE, node_id); - if (!ret) - /* Wait for mgmt node to respond with SCIF_NODE_REMOVE_ACK */ - wait_event_timeout(scifdev->disconn_wq, - (atomic_read(&scifdev->disconn_rescnt) == 1), - SCIF_NODE_ALIVE_TIMEOUT); -} - -void scif_get_node_info(void) -{ - struct scifmsg msg; - DECLARE_COMPLETION_ONSTACK(node_info); - - msg.uop = SCIF_GET_NODE_INFO; - msg.src.node = scif_info.nodeid; - msg.dst.node = SCIF_MGMT_NODE; - msg.payload[3] = (u64)&node_info; - - if ((scif_nodeqp_send(&scif_dev[SCIF_MGMT_NODE], &msg))) - return; - - /* Wait for a response with SCIF_GET_NODE_INFO */ - wait_for_completion(&node_info); -} diff --git a/drivers/misc/mic/scif/scif_nodeqp.c b/drivers/misc/mic/scif/scif_nodeqp.c deleted file mode 100644 index 384ce08fa98a..000000000000 --- a/drivers/misc/mic/scif/scif_nodeqp.c +++ /dev/null @@ -1,1349 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#include "../bus/scif_bus.h" -#include "scif_peer_bus.h" -#include "scif_main.h" -#include "scif_nodeqp.h" -#include "scif_map.h" - -/* - ************************************************************************ - * SCIF node Queue Pair (QP) setup flow: - * - * 1) SCIF driver gets probed with a scif_hw_dev via the scif_hw_bus - * 2) scif_setup_qp(..) allocates the local qp and calls - * scif_setup_qp_connect(..) which allocates and maps the local - * buffer for the inbound QP - * 3) The local node updates the device page with the DMA address of the QP - * 4) A delayed work is scheduled (qp_dwork) which periodically reads if - * the peer node has updated its QP DMA address - * 5) Once a valid non zero address is found in the QP DMA address field - * in the device page, the local node maps the remote node's QP, - * updates its outbound QP and sends a SCIF_INIT message to the peer - * 6) The SCIF_INIT message is received by the peer node QP interrupt bottom - * half handler by calling scif_init(..) - * 7) scif_init(..) registers a new SCIF peer node by calling - * scif_peer_register_device(..) which signifies the addition of a new - * SCIF node - * 8) On the mgmt node, P2P network setup/teardown is initiated if all the - * remote nodes are online via scif_p2p_setup(..) - * 9) For P2P setup, the host maps the remote nodes' aperture and memory - * bars and sends a SCIF_NODE_ADD message to both nodes - * 10) As part of scif_nodeadd, both nodes set up their local inbound - * QPs and send a SCIF_NODE_ADD_ACK to the mgmt node - * 11) As part of scif_node_add_ack(..) the mgmt node forwards the - * SCIF_NODE_ADD_ACK to the remote nodes - * 12) As part of scif_node_add_ack(..) the remote nodes update their - * outbound QPs, make sure they can access memory on the remote node - * and then add a new SCIF peer node by calling - * scif_peer_register_device(..) which signifies the addition of a new - * SCIF node. - * 13) The SCIF network is now established across all nodes. - * - ************************************************************************ - * SCIF node QP teardown flow (initiated by non mgmt node): - * - * 1) SCIF driver gets a remove callback with a scif_hw_dev via the scif_hw_bus - * 2) The device page QP DMA address field is updated with 0x0 - * 3) A non mgmt node now cleans up all local data structures and sends a - * SCIF_EXIT message to the peer and waits for a SCIF_EXIT_ACK - * 4) As part of scif_exit(..) handling scif_disconnect_node(..) is called - * 5) scif_disconnect_node(..) sends a SCIF_NODE_REMOVE message to all the - * peers and waits for a SCIF_NODE_REMOVE_ACK - * 6) As part of scif_node_remove(..) a remote node unregisters the peer - * node from the SCIF network and sends a SCIF_NODE_REMOVE_ACK - * 7) When the mgmt node has received all the SCIF_NODE_REMOVE_ACKs - * it sends itself a node remove message whose handling cleans up local - * data structures and unregisters the peer node from the SCIF network - * 8) The mgmt node sends a SCIF_EXIT_ACK - * 9) Upon receipt of the SCIF_EXIT_ACK the node initiating the teardown - * completes the SCIF remove routine - * 10) The SCIF network is now torn down for the node initiating the - * teardown sequence - * - ************************************************************************ - * SCIF node QP teardown flow (initiated by mgmt node): - * - * 1) SCIF driver gets a remove callback with a scif_hw_dev via the scif_hw_bus - * 2) The device page QP DMA address field is updated with 0x0 - * 3) The mgmt node calls scif_disconnect_node(..) - * 4) scif_disconnect_node(..) sends a SCIF_NODE_REMOVE message to all the peers - * and waits for a SCIF_NODE_REMOVE_ACK - * 5) As part of scif_node_remove(..) a remote node unregisters the peer - * node from the SCIF network and sends a SCIF_NODE_REMOVE_ACK - * 6) When the mgmt node has received all the SCIF_NODE_REMOVE_ACKs - * it unregisters the peer node from the SCIF network - * 7) The mgmt node sends a SCIF_EXIT message and waits for a SCIF_EXIT_ACK. - * 8) A non mgmt node upon receipt of a SCIF_EXIT message calls scif_stop(..) - * which would clean up local data structures for all SCIF nodes and - * then send a SCIF_EXIT_ACK back to the mgmt node - * 9) Upon receipt of the SCIF_EXIT_ACK the the mgmt node sends itself a node - * remove message whose handling cleans up local data structures and - * destroys any P2P mappings. - * 10) The SCIF hardware device for which a remove callback was received is now - * disconnected from the SCIF network. - */ -/* - * Initializes "local" data structures for the QP. Allocates the QP - * ring buffer (rb) and initializes the "in bound" queue. - */ -int scif_setup_qp_connect(struct scif_qp *qp, dma_addr_t *qp_offset, - int local_size, struct scif_dev *scifdev) -{ - void *local_q = qp->inbound_q.rb_base; - int err = 0; - u32 tmp_rd = 0; - - spin_lock_init(&qp->send_lock); - spin_lock_init(&qp->recv_lock); - - /* Allocate rb only if not already allocated */ - if (!local_q) { - local_q = kzalloc(local_size, GFP_KERNEL); - if (!local_q) { - err = -ENOMEM; - return err; - } - } - - err = scif_map_single(&qp->local_buf, local_q, scifdev, local_size); - if (err) - goto kfree; - /* - * To setup the inbound_q, the buffer lives locally, the read pointer - * is remote and the write pointer is local. - */ - scif_rb_init(&qp->inbound_q, - &tmp_rd, - &qp->local_write, - local_q, get_count_order(local_size)); - /* - * The read pointer is NULL initially and it is unsafe to use the ring - * buffer til this changes! - */ - qp->inbound_q.read_ptr = NULL; - err = scif_map_single(qp_offset, qp, - scifdev, sizeof(struct scif_qp)); - if (err) - goto unmap; - qp->local_qp = *qp_offset; - return err; -unmap: - scif_unmap_single(qp->local_buf, scifdev, local_size); - qp->local_buf = 0; -kfree: - kfree(local_q); - return err; -} - -/* When the other side has already done it's allocation, this is called */ -int scif_setup_qp_accept(struct scif_qp *qp, dma_addr_t *qp_offset, - dma_addr_t phys, int local_size, - struct scif_dev *scifdev) -{ - void *local_q; - void *remote_q; - struct scif_qp *remote_qp; - int remote_size; - int err = 0; - - spin_lock_init(&qp->send_lock); - spin_lock_init(&qp->recv_lock); - /* Start by figuring out where we need to point */ - remote_qp = scif_ioremap(phys, sizeof(struct scif_qp), scifdev); - if (!remote_qp) - return -EIO; - qp->remote_qp = remote_qp; - if (qp->remote_qp->magic != SCIFEP_MAGIC) { - err = -EIO; - goto iounmap; - } - qp->remote_buf = remote_qp->local_buf; - remote_size = qp->remote_qp->inbound_q.size; - remote_q = scif_ioremap(qp->remote_buf, remote_size, scifdev); - if (!remote_q) { - err = -EIO; - goto iounmap; - } - qp->remote_qp->local_write = 0; - /* - * To setup the outbound_q, the buffer lives in remote memory, - * the read pointer is local, the write pointer is remote - */ - scif_rb_init(&qp->outbound_q, - &qp->local_read, - &qp->remote_qp->local_write, - remote_q, - get_count_order(remote_size)); - local_q = kzalloc(local_size, GFP_KERNEL); - if (!local_q) { - err = -ENOMEM; - goto iounmap_1; - } - err = scif_map_single(&qp->local_buf, local_q, scifdev, local_size); - if (err) - goto kfree; - qp->remote_qp->local_read = 0; - /* - * To setup the inbound_q, the buffer lives locally, the read pointer - * is remote and the write pointer is local - */ - scif_rb_init(&qp->inbound_q, - &qp->remote_qp->local_read, - &qp->local_write, - local_q, get_count_order(local_size)); - err = scif_map_single(qp_offset, qp, scifdev, - sizeof(struct scif_qp)); - if (err) - goto unmap; - qp->local_qp = *qp_offset; - return err; -unmap: - scif_unmap_single(qp->local_buf, scifdev, local_size); - qp->local_buf = 0; -kfree: - kfree(local_q); -iounmap_1: - scif_iounmap(remote_q, remote_size, scifdev); - qp->outbound_q.rb_base = NULL; -iounmap: - scif_iounmap(qp->remote_qp, sizeof(struct scif_qp), scifdev); - qp->remote_qp = NULL; - return err; -} - -int scif_setup_qp_connect_response(struct scif_dev *scifdev, - struct scif_qp *qp, u64 payload) -{ - int err = 0; - void *r_buf; - int remote_size; - phys_addr_t tmp_phys; - - qp->remote_qp = scif_ioremap(payload, sizeof(struct scif_qp), scifdev); - - if (!qp->remote_qp) { - err = -ENOMEM; - goto error; - } - - if (qp->remote_qp->magic != SCIFEP_MAGIC) { - dev_err(&scifdev->sdev->dev, - "SCIFEP_MAGIC mismatch between self %d remote %d\n", - scif_dev[scif_info.nodeid].node, scifdev->node); - err = -ENODEV; - goto error; - } - - tmp_phys = qp->remote_qp->local_buf; - remote_size = qp->remote_qp->inbound_q.size; - r_buf = scif_ioremap(tmp_phys, remote_size, scifdev); - - if (!r_buf) - return -EIO; - - qp->local_read = 0; - scif_rb_init(&qp->outbound_q, - &qp->local_read, - &qp->remote_qp->local_write, - r_buf, - get_count_order(remote_size)); - /* - * Because the node QP may already be processing an INIT message, set - * the read pointer so the cached read offset isn't lost - */ - qp->remote_qp->local_read = qp->inbound_q.current_read_offset; - /* - * resetup the inbound_q now that we know where the - * inbound_read really is. - */ - scif_rb_init(&qp->inbound_q, - &qp->remote_qp->local_read, - &qp->local_write, - qp->inbound_q.rb_base, - get_count_order(qp->inbound_q.size)); -error: - return err; -} - -static __always_inline void -scif_send_msg_intr(struct scif_dev *scifdev) -{ - struct scif_hw_dev *sdev = scifdev->sdev; - - if (scifdev_is_p2p(scifdev)) - sdev->hw_ops->send_p2p_intr(sdev, scifdev->rdb, &scifdev->mmio); - else - sdev->hw_ops->send_intr(sdev, scifdev->rdb); -} - -int scif_qp_response(phys_addr_t phys, struct scif_dev *scifdev) -{ - int err = 0; - struct scifmsg msg; - - err = scif_setup_qp_connect_response(scifdev, scifdev->qpairs, phys); - if (!err) { - /* - * Now that everything is setup and mapped, we're ready - * to tell the peer about our queue's location - */ - msg.uop = SCIF_INIT; - msg.dst.node = scifdev->node; - err = scif_nodeqp_send(scifdev, &msg); - } - return err; -} - -void scif_send_exit(struct scif_dev *scifdev) -{ - struct scifmsg msg; - int ret; - - scifdev->exit = OP_IN_PROGRESS; - msg.uop = SCIF_EXIT; - msg.src.node = scif_info.nodeid; - msg.dst.node = scifdev->node; - ret = scif_nodeqp_send(scifdev, &msg); - if (ret) - goto done; - /* Wait for a SCIF_EXIT_ACK message */ - wait_event_timeout(scif_info.exitwq, scifdev->exit == OP_COMPLETED, - SCIF_NODE_ALIVE_TIMEOUT); -done: - scifdev->exit = OP_IDLE; -} - -int scif_setup_qp(struct scif_dev *scifdev) -{ - int err = 0; - int local_size; - struct scif_qp *qp; - - local_size = SCIF_NODE_QP_SIZE; - - qp = kzalloc(sizeof(*qp), GFP_KERNEL); - if (!qp) { - err = -ENOMEM; - return err; - } - qp->magic = SCIFEP_MAGIC; - scifdev->qpairs = qp; - err = scif_setup_qp_connect(qp, &scifdev->qp_dma_addr, - local_size, scifdev); - if (err) - goto free_qp; - /* - * We're as setup as we can be. The inbound_q is setup, w/o a usable - * outbound q. When we get a message, the read_ptr will be updated, - * and we will pull the message. - */ - return err; -free_qp: - kfree(scifdev->qpairs); - scifdev->qpairs = NULL; - return err; -} - -static void scif_p2p_freesg(struct scatterlist *sg) -{ - kfree(sg); -} - -static struct scatterlist * -scif_p2p_setsg(phys_addr_t pa, int page_size, int page_cnt) -{ - struct scatterlist *sg; - struct page *page; - int i; - - sg = kmalloc_array(page_cnt, sizeof(struct scatterlist), GFP_KERNEL); - if (!sg) - return NULL; - sg_init_table(sg, page_cnt); - for (i = 0; i < page_cnt; i++) { - page = pfn_to_page(pa >> PAGE_SHIFT); - sg_set_page(&sg[i], page, page_size, 0); - pa += page_size; - } - return sg; -} - -/* Init p2p mappings required to access peerdev from scifdev */ -static struct scif_p2p_info * -scif_init_p2p_info(struct scif_dev *scifdev, struct scif_dev *peerdev) -{ - struct scif_p2p_info *p2p; - int num_mmio_pages, num_aper_pages, sg_page_shift, err, num_aper_chunks; - struct scif_hw_dev *psdev = peerdev->sdev; - struct scif_hw_dev *sdev = scifdev->sdev; - - num_mmio_pages = psdev->mmio->len >> PAGE_SHIFT; - num_aper_pages = psdev->aper->len >> PAGE_SHIFT; - - p2p = kzalloc(sizeof(*p2p), GFP_KERNEL); - if (!p2p) - return NULL; - p2p->ppi_sg[SCIF_PPI_MMIO] = scif_p2p_setsg(psdev->mmio->pa, - PAGE_SIZE, num_mmio_pages); - if (!p2p->ppi_sg[SCIF_PPI_MMIO]) - goto free_p2p; - p2p->sg_nentries[SCIF_PPI_MMIO] = num_mmio_pages; - sg_page_shift = get_order(min(psdev->aper->len, (u64)(1 << 30))); - num_aper_chunks = num_aper_pages >> (sg_page_shift - PAGE_SHIFT); - p2p->ppi_sg[SCIF_PPI_APER] = scif_p2p_setsg(psdev->aper->pa, - 1 << sg_page_shift, - num_aper_chunks); - p2p->sg_nentries[SCIF_PPI_APER] = num_aper_chunks; - err = dma_map_sg(&sdev->dev, p2p->ppi_sg[SCIF_PPI_MMIO], - num_mmio_pages, PCI_DMA_BIDIRECTIONAL); - if (err != num_mmio_pages) - goto scif_p2p_free; - err = dma_map_sg(&sdev->dev, p2p->ppi_sg[SCIF_PPI_APER], - num_aper_chunks, PCI_DMA_BIDIRECTIONAL); - if (err != num_aper_chunks) - goto dma_unmap; - p2p->ppi_da[SCIF_PPI_MMIO] = sg_dma_address(p2p->ppi_sg[SCIF_PPI_MMIO]); - p2p->ppi_da[SCIF_PPI_APER] = sg_dma_address(p2p->ppi_sg[SCIF_PPI_APER]); - p2p->ppi_len[SCIF_PPI_MMIO] = num_mmio_pages; - p2p->ppi_len[SCIF_PPI_APER] = num_aper_pages; - p2p->ppi_peer_id = peerdev->node; - return p2p; -dma_unmap: - dma_unmap_sg(&sdev->dev, p2p->ppi_sg[SCIF_PPI_MMIO], - p2p->sg_nentries[SCIF_PPI_MMIO], DMA_BIDIRECTIONAL); -scif_p2p_free: - scif_p2p_freesg(p2p->ppi_sg[SCIF_PPI_MMIO]); - scif_p2p_freesg(p2p->ppi_sg[SCIF_PPI_APER]); -free_p2p: - kfree(p2p); - return NULL; -} - -/* Uninitialize and release resources from a p2p mapping */ -static void scif_deinit_p2p_info(struct scif_dev *scifdev, - struct scif_p2p_info *p2p) -{ - struct scif_hw_dev *sdev = scifdev->sdev; - - dma_unmap_sg(&sdev->dev, p2p->ppi_sg[SCIF_PPI_MMIO], - p2p->sg_nentries[SCIF_PPI_MMIO], DMA_BIDIRECTIONAL); - dma_unmap_sg(&sdev->dev, p2p->ppi_sg[SCIF_PPI_APER], - p2p->sg_nentries[SCIF_PPI_APER], DMA_BIDIRECTIONAL); - scif_p2p_freesg(p2p->ppi_sg[SCIF_PPI_MMIO]); - scif_p2p_freesg(p2p->ppi_sg[SCIF_PPI_APER]); - kfree(p2p); -} - -/** - * scif_node_connect: Respond to SCIF_NODE_CONNECT interrupt message - * @scifdev: SCIF device - * @dst: Destination node - * - * Connect the src and dst node by setting up the p2p connection - * between them. Management node here acts like a proxy. - */ -static void scif_node_connect(struct scif_dev *scifdev, int dst) -{ - struct scif_dev *dev_j = scifdev; - struct scif_dev *dev_i = NULL; - struct scif_p2p_info *p2p_ij = NULL; /* bus addr for j from i */ - struct scif_p2p_info *p2p_ji = NULL; /* bus addr for i from j */ - struct scif_p2p_info *p2p; - struct list_head *pos, *tmp; - struct scifmsg msg; - int err; - u64 tmppayload; - - if (dst < 1 || dst > scif_info.maxid) - return; - - dev_i = &scif_dev[dst]; - - if (!_scifdev_alive(dev_i)) - return; - /* - * If the p2p connection is already setup or in the process of setting - * up then just ignore this request. The requested node will get - * informed by SCIF_NODE_ADD_ACK or SCIF_NODE_ADD_NACK - */ - if (!list_empty(&dev_i->p2p)) { - list_for_each_safe(pos, tmp, &dev_i->p2p) { - p2p = list_entry(pos, struct scif_p2p_info, ppi_list); - if (p2p->ppi_peer_id == dev_j->node) - return; - } - } - p2p_ij = scif_init_p2p_info(dev_i, dev_j); - if (!p2p_ij) - return; - p2p_ji = scif_init_p2p_info(dev_j, dev_i); - if (!p2p_ji) { - scif_deinit_p2p_info(dev_i, p2p_ij); - return; - } - list_add_tail(&p2p_ij->ppi_list, &dev_i->p2p); - list_add_tail(&p2p_ji->ppi_list, &dev_j->p2p); - - /* - * Send a SCIF_NODE_ADD to dev_i, pass it its bus address - * as seen from dev_j - */ - msg.uop = SCIF_NODE_ADD; - msg.src.node = dev_j->node; - msg.dst.node = dev_i->node; - - msg.payload[0] = p2p_ji->ppi_da[SCIF_PPI_APER]; - msg.payload[1] = p2p_ij->ppi_da[SCIF_PPI_MMIO]; - msg.payload[2] = p2p_ij->ppi_da[SCIF_PPI_APER]; - msg.payload[3] = p2p_ij->ppi_len[SCIF_PPI_APER] << PAGE_SHIFT; - - err = scif_nodeqp_send(dev_i, &msg); - if (err) { - dev_err(&scifdev->sdev->dev, - "%s %d error %d\n", __func__, __LINE__, err); - return; - } - - /* Same as above but to dev_j */ - msg.uop = SCIF_NODE_ADD; - msg.src.node = dev_i->node; - msg.dst.node = dev_j->node; - - tmppayload = msg.payload[0]; - msg.payload[0] = msg.payload[2]; - msg.payload[2] = tmppayload; - msg.payload[1] = p2p_ji->ppi_da[SCIF_PPI_MMIO]; - msg.payload[3] = p2p_ji->ppi_len[SCIF_PPI_APER] << PAGE_SHIFT; - - scif_nodeqp_send(dev_j, &msg); -} - -static void scif_p2p_setup(void) -{ - int i, j; - - if (!scif_info.p2p_enable) - return; - - for (i = 1; i <= scif_info.maxid; i++) - if (!_scifdev_alive(&scif_dev[i])) - return; - - for (i = 1; i <= scif_info.maxid; i++) { - for (j = 1; j <= scif_info.maxid; j++) { - struct scif_dev *scifdev = &scif_dev[i]; - - if (i == j) - continue; - scif_node_connect(scifdev, j); - } - } -} - -static char *message_types[] = {"BAD", - "INIT", - "EXIT", - "SCIF_EXIT_ACK", - "SCIF_NODE_ADD", - "SCIF_NODE_ADD_ACK", - "SCIF_NODE_ADD_NACK", - "REMOVE_NODE", - "REMOVE_NODE_ACK", - "CNCT_REQ", - "CNCT_GNT", - "CNCT_GNTACK", - "CNCT_GNTNACK", - "CNCT_REJ", - "DISCNCT", - "DISCNT_ACK", - "CLIENT_SENT", - "CLIENT_RCVD", - "SCIF_GET_NODE_INFO", - "REGISTER", - "REGISTER_ACK", - "REGISTER_NACK", - "UNREGISTER", - "UNREGISTER_ACK", - "UNREGISTER_NACK", - "ALLOC_REQ", - "ALLOC_GNT", - "ALLOC_REJ", - "FREE_PHYS", - "FREE_VIRT", - "MUNMAP", - "MARK", - "MARK_ACK", - "MARK_NACK", - "WAIT", - "WAIT_ACK", - "WAIT_NACK", - "SIGNAL_LOCAL", - "SIGNAL_REMOTE", - "SIG_ACK", - "SIG_NACK"}; - -static void -scif_display_message(struct scif_dev *scifdev, struct scifmsg *msg, - const char *label) -{ - if (!scif_info.en_msg_log) - return; - if (msg->uop > SCIF_MAX_MSG) { - dev_err(&scifdev->sdev->dev, - "%s: unknown msg type %d\n", label, msg->uop); - return; - } - dev_info(&scifdev->sdev->dev, - "%s: msg type %s, src %d:%d, dest %d:%d payload 0x%llx:0x%llx:0x%llx:0x%llx\n", - label, message_types[msg->uop], msg->src.node, msg->src.port, - msg->dst.node, msg->dst.port, msg->payload[0], msg->payload[1], - msg->payload[2], msg->payload[3]); -} - -int _scif_nodeqp_send(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_qp *qp = scifdev->qpairs; - int err = -ENOMEM, loop_cnt = 0; - - scif_display_message(scifdev, msg, "Sent"); - if (!qp) { - err = -EINVAL; - goto error; - } - spin_lock(&qp->send_lock); - - while ((err = scif_rb_write(&qp->outbound_q, - msg, sizeof(struct scifmsg)))) { - mdelay(1); -#define SCIF_NODEQP_SEND_TO_MSEC (3 * 1000) - if (loop_cnt++ > (SCIF_NODEQP_SEND_TO_MSEC)) { - err = -ENODEV; - break; - } - } - if (!err) - scif_rb_commit(&qp->outbound_q); - spin_unlock(&qp->send_lock); - if (!err) { - if (scifdev_self(scifdev)) - /* - * For loopback we need to emulate an interrupt by - * queuing work for the queue handling real node - * Qp interrupts. - */ - queue_work(scifdev->intr_wq, &scifdev->intr_bh); - else - scif_send_msg_intr(scifdev); - } -error: - if (err) - dev_dbg(&scifdev->sdev->dev, - "%s %d error %d uop %d\n", - __func__, __LINE__, err, msg->uop); - return err; -} - -/** - * scif_nodeqp_send - Send a message on the node queue pair - * @scifdev: Scif Device. - * @msg: The message to be sent. - */ -int scif_nodeqp_send(struct scif_dev *scifdev, struct scifmsg *msg) -{ - int err; - struct device *spdev = NULL; - - if (msg->uop > SCIF_EXIT_ACK) { - /* Don't send messages once the exit flow has begun */ - if (OP_IDLE != scifdev->exit) - return -ENODEV; - spdev = scif_get_peer_dev(scifdev); - if (IS_ERR(spdev)) { - err = PTR_ERR(spdev); - return err; - } - } - err = _scif_nodeqp_send(scifdev, msg); - if (msg->uop > SCIF_EXIT_ACK) - scif_put_peer_dev(spdev); - return err; -} - -/* - * scif_misc_handler: - * - * Work queue handler for servicing miscellaneous SCIF tasks. - * Examples include: - * 1) Remote fence requests. - * 2) Destruction of temporary registered windows - * created during scif_vreadfrom()/scif_vwriteto(). - * 3) Cleanup of zombie endpoints. - */ -void scif_misc_handler(struct work_struct *work) -{ - scif_rma_handle_remote_fences(); - scif_rma_destroy_windows(); - scif_rma_destroy_tcw_invalid(); - scif_cleanup_zombie_epd(); -} - -/** - * scif_init() - Respond to SCIF_INIT interrupt message - * @scifdev: Remote SCIF device node - * @msg: Interrupt message - */ -static __always_inline void -scif_init(struct scif_dev *scifdev, struct scifmsg *msg) -{ - /* - * Allow the thread waiting for device page updates for the peer QP DMA - * address to complete initializing the inbound_q. - */ - flush_delayed_work(&scifdev->qp_dwork); - - scif_peer_register_device(scifdev); - - if (scif_is_mgmt_node()) { - mutex_lock(&scif_info.conflock); - scif_p2p_setup(); - mutex_unlock(&scif_info.conflock); - } -} - -/** - * scif_exit() - Respond to SCIF_EXIT interrupt message - * @scifdev: Remote SCIF device node - * @unused: Interrupt message (unused) - * - * This function stops the SCIF interface for the node which sent - * the SCIF_EXIT message and starts waiting for that node to - * resetup the queue pair again. - */ -static __always_inline void -scif_exit(struct scif_dev *scifdev, struct scifmsg *unused) -{ - scifdev->exit_ack_pending = true; - if (scif_is_mgmt_node()) - scif_disconnect_node(scifdev->node, false); - else - scif_stop(scifdev); - schedule_delayed_work(&scifdev->qp_dwork, - msecs_to_jiffies(1000)); -} - -/** - * scif_exitack() - Respond to SCIF_EXIT_ACK interrupt message - * @scifdev: Remote SCIF device node - * @unused: Interrupt message (unused) - * - */ -static __always_inline void -scif_exit_ack(struct scif_dev *scifdev, struct scifmsg *unused) -{ - scifdev->exit = OP_COMPLETED; - wake_up(&scif_info.exitwq); -} - -/** - * scif_node_add() - Respond to SCIF_NODE_ADD interrupt message - * @scifdev: Remote SCIF device node - * @msg: Interrupt message - * - * When the mgmt node driver has finished initializing a MIC node queue pair it - * marks the node as online. It then looks for all currently online MIC cards - * and send a SCIF_NODE_ADD message to identify the ID of the new card for - * peer to peer initialization - * - * The local node allocates its incoming queue and sends its address in the - * SCIF_NODE_ADD_ACK message back to the mgmt node, the mgmt node "reflects" - * this message to the new node - */ -static __always_inline void -scif_node_add(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_dev *newdev; - dma_addr_t qp_offset; - int qp_connect; - struct scif_hw_dev *sdev; - - dev_dbg(&scifdev->sdev->dev, - "Scifdev %d:%d received NODE_ADD msg for node %d\n", - scifdev->node, msg->dst.node, msg->src.node); - dev_dbg(&scifdev->sdev->dev, - "Remote address for this node's aperture %llx\n", - msg->payload[0]); - newdev = &scif_dev[msg->src.node]; - newdev->node = msg->src.node; - newdev->sdev = scif_dev[SCIF_MGMT_NODE].sdev; - sdev = newdev->sdev; - - if (scif_setup_intr_wq(newdev)) { - dev_err(&scifdev->sdev->dev, - "failed to setup interrupts for %d\n", msg->src.node); - goto interrupt_setup_error; - } - newdev->mmio.va = ioremap(msg->payload[1], sdev->mmio->len); - if (!newdev->mmio.va) { - dev_err(&scifdev->sdev->dev, - "failed to map mmio for %d\n", msg->src.node); - goto mmio_map_error; - } - newdev->qpairs = kzalloc(sizeof(*newdev->qpairs), GFP_KERNEL); - if (!newdev->qpairs) - goto qp_alloc_error; - /* - * Set the base address of the remote node's memory since it gets - * added to qp_offset - */ - newdev->base_addr = msg->payload[0]; - - qp_connect = scif_setup_qp_connect(newdev->qpairs, &qp_offset, - SCIF_NODE_QP_SIZE, newdev); - if (qp_connect) { - dev_err(&scifdev->sdev->dev, - "failed to setup qp_connect %d\n", qp_connect); - goto qp_connect_error; - } - - newdev->db = sdev->hw_ops->next_db(sdev); - newdev->cookie = sdev->hw_ops->request_irq(sdev, scif_intr_handler, - "SCIF_INTR", newdev, - newdev->db); - if (IS_ERR(newdev->cookie)) - goto qp_connect_error; - newdev->qpairs->magic = SCIFEP_MAGIC; - newdev->qpairs->qp_state = SCIF_QP_OFFLINE; - - msg->uop = SCIF_NODE_ADD_ACK; - msg->dst.node = msg->src.node; - msg->src.node = scif_info.nodeid; - msg->payload[0] = qp_offset; - msg->payload[2] = newdev->db; - scif_nodeqp_send(&scif_dev[SCIF_MGMT_NODE], msg); - return; -qp_connect_error: - kfree(newdev->qpairs); - newdev->qpairs = NULL; -qp_alloc_error: - iounmap(newdev->mmio.va); - newdev->mmio.va = NULL; -mmio_map_error: -interrupt_setup_error: - dev_err(&scifdev->sdev->dev, - "node add failed for node %d\n", msg->src.node); - msg->uop = SCIF_NODE_ADD_NACK; - msg->dst.node = msg->src.node; - msg->src.node = scif_info.nodeid; - scif_nodeqp_send(&scif_dev[SCIF_MGMT_NODE], msg); -} - -void scif_poll_qp_state(struct work_struct *work) -{ -#define SCIF_NODE_QP_RETRY 100 -#define SCIF_NODE_QP_TIMEOUT 100 - struct scif_dev *peerdev = container_of(work, struct scif_dev, - p2p_dwork.work); - struct scif_qp *qp = &peerdev->qpairs[0]; - - if (qp->qp_state != SCIF_QP_ONLINE || - qp->remote_qp->qp_state != SCIF_QP_ONLINE) { - if (peerdev->p2p_retry++ == SCIF_NODE_QP_RETRY) { - dev_err(&peerdev->sdev->dev, - "Warning: QP check timeout with state %d\n", - qp->qp_state); - goto timeout; - } - schedule_delayed_work(&peerdev->p2p_dwork, - msecs_to_jiffies(SCIF_NODE_QP_TIMEOUT)); - return; - } - return; -timeout: - dev_err(&peerdev->sdev->dev, - "%s %d remote node %d offline, state = 0x%x\n", - __func__, __LINE__, peerdev->node, qp->qp_state); - qp->remote_qp->qp_state = SCIF_QP_OFFLINE; - scif_peer_unregister_device(peerdev); - scif_cleanup_scifdev(peerdev); -} - -/** - * scif_node_add_ack() - Respond to SCIF_NODE_ADD_ACK interrupt message - * @scifdev: Remote SCIF device node - * @msg: Interrupt message - * - * After a MIC node receives the SCIF_NODE_ADD_ACK message it send this - * message to the mgmt node to confirm the sequence is finished. - * - */ -static __always_inline void -scif_node_add_ack(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_dev *peerdev; - struct scif_qp *qp; - struct scif_dev *dst_dev = &scif_dev[msg->dst.node]; - - dev_dbg(&scifdev->sdev->dev, - "Scifdev %d received SCIF_NODE_ADD_ACK msg src %d dst %d\n", - scifdev->node, msg->src.node, msg->dst.node); - dev_dbg(&scifdev->sdev->dev, - "payload %llx %llx %llx %llx\n", msg->payload[0], - msg->payload[1], msg->payload[2], msg->payload[3]); - if (scif_is_mgmt_node()) { - /* - * the lock serializes with scif_qp_response_ack. The mgmt node - * is forwarding the NODE_ADD_ACK message from src to dst we - * need to make sure that the dst has already received a - * NODE_ADD for src and setup its end of the qp to dst - */ - mutex_lock(&scif_info.conflock); - msg->payload[1] = scif_info.maxid; - scif_nodeqp_send(dst_dev, msg); - mutex_unlock(&scif_info.conflock); - return; - } - peerdev = &scif_dev[msg->src.node]; - peerdev->sdev = scif_dev[SCIF_MGMT_NODE].sdev; - peerdev->node = msg->src.node; - - qp = &peerdev->qpairs[0]; - - if ((scif_setup_qp_connect_response(peerdev, &peerdev->qpairs[0], - msg->payload[0]))) - goto local_error; - peerdev->rdb = msg->payload[2]; - qp->remote_qp->qp_state = SCIF_QP_ONLINE; - - scif_peer_register_device(peerdev); - - schedule_delayed_work(&peerdev->p2p_dwork, 0); - return; -local_error: - scif_cleanup_scifdev(peerdev); -} - -/** - * scif_node_add_nack: Respond to SCIF_NODE_ADD_NACK interrupt message - * @scifdev: Remote SCIF device node - * @msg: Interrupt message - * - * SCIF_NODE_ADD failed, so inform the waiting wq. - */ -static __always_inline void -scif_node_add_nack(struct scif_dev *scifdev, struct scifmsg *msg) -{ - if (scif_is_mgmt_node()) { - struct scif_dev *dst_dev = &scif_dev[msg->dst.node]; - - dev_dbg(&scifdev->sdev->dev, - "SCIF_NODE_ADD_NACK received from %d\n", scifdev->node); - scif_nodeqp_send(dst_dev, msg); - } -} - -/** - * scif_node_remove: Handle SCIF_NODE_REMOVE message - * @scifdev: Remote SCIF device node - * @msg: Interrupt message - * - * Handle node removal. - */ -static __always_inline void -scif_node_remove(struct scif_dev *scifdev, struct scifmsg *msg) -{ - int node = msg->payload[0]; - struct scif_dev *scdev = &scif_dev[node]; - - scdev->node_remove_ack_pending = true; - scif_handle_remove_node(node); -} - -/** - * scif_node_remove_ack: Handle SCIF_NODE_REMOVE_ACK message - * @scifdev: Remote SCIF device node - * @msg: Interrupt message - * - * The peer has acked a SCIF_NODE_REMOVE message. - */ -static __always_inline void -scif_node_remove_ack(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_dev *sdev = &scif_dev[msg->payload[0]]; - - atomic_inc(&sdev->disconn_rescnt); - wake_up(&sdev->disconn_wq); -} - -/** - * scif_get_node_info: Respond to SCIF_GET_NODE_INFO interrupt message - * @scifdev: Remote SCIF device node - * @msg: Interrupt message - * - * Retrieve node info i.e maxid and total from the mgmt node. - */ -static __always_inline void -scif_get_node_info_resp(struct scif_dev *scifdev, struct scifmsg *msg) -{ - if (scif_is_mgmt_node()) { - swap(msg->dst.node, msg->src.node); - mutex_lock(&scif_info.conflock); - msg->payload[1] = scif_info.maxid; - msg->payload[2] = scif_info.total; - mutex_unlock(&scif_info.conflock); - scif_nodeqp_send(scifdev, msg); - } else { - struct completion *node_info = - (struct completion *)msg->payload[3]; - - mutex_lock(&scif_info.conflock); - scif_info.maxid = msg->payload[1]; - scif_info.total = msg->payload[2]; - complete_all(node_info); - mutex_unlock(&scif_info.conflock); - } -} - -static void -scif_msg_unknown(struct scif_dev *scifdev, struct scifmsg *msg) -{ - /* Bogus Node Qp Message? */ - dev_err(&scifdev->sdev->dev, - "Unknown message 0x%xn scifdev->node 0x%x\n", - msg->uop, scifdev->node); -} - -static void (*scif_intr_func[SCIF_MAX_MSG + 1]) - (struct scif_dev *, struct scifmsg *msg) = { - scif_msg_unknown, /* Error */ - scif_init, /* SCIF_INIT */ - scif_exit, /* SCIF_EXIT */ - scif_exit_ack, /* SCIF_EXIT_ACK */ - scif_node_add, /* SCIF_NODE_ADD */ - scif_node_add_ack, /* SCIF_NODE_ADD_ACK */ - scif_node_add_nack, /* SCIF_NODE_ADD_NACK */ - scif_node_remove, /* SCIF_NODE_REMOVE */ - scif_node_remove_ack, /* SCIF_NODE_REMOVE_ACK */ - scif_cnctreq, /* SCIF_CNCT_REQ */ - scif_cnctgnt, /* SCIF_CNCT_GNT */ - scif_cnctgnt_ack, /* SCIF_CNCT_GNTACK */ - scif_cnctgnt_nack, /* SCIF_CNCT_GNTNACK */ - scif_cnctrej, /* SCIF_CNCT_REJ */ - scif_discnct, /* SCIF_DISCNCT */ - scif_discnt_ack, /* SCIF_DISCNT_ACK */ - scif_clientsend, /* SCIF_CLIENT_SENT */ - scif_clientrcvd, /* SCIF_CLIENT_RCVD */ - scif_get_node_info_resp,/* SCIF_GET_NODE_INFO */ - scif_recv_reg, /* SCIF_REGISTER */ - scif_recv_reg_ack, /* SCIF_REGISTER_ACK */ - scif_recv_reg_nack, /* SCIF_REGISTER_NACK */ - scif_recv_unreg, /* SCIF_UNREGISTER */ - scif_recv_unreg_ack, /* SCIF_UNREGISTER_ACK */ - scif_recv_unreg_nack, /* SCIF_UNREGISTER_NACK */ - scif_alloc_req, /* SCIF_ALLOC_REQ */ - scif_alloc_gnt_rej, /* SCIF_ALLOC_GNT */ - scif_alloc_gnt_rej, /* SCIF_ALLOC_REJ */ - scif_free_virt, /* SCIF_FREE_VIRT */ - scif_recv_munmap, /* SCIF_MUNMAP */ - scif_recv_mark, /* SCIF_MARK */ - scif_recv_mark_resp, /* SCIF_MARK_ACK */ - scif_recv_mark_resp, /* SCIF_MARK_NACK */ - scif_recv_wait, /* SCIF_WAIT */ - scif_recv_wait_resp, /* SCIF_WAIT_ACK */ - scif_recv_wait_resp, /* SCIF_WAIT_NACK */ - scif_recv_sig_local, /* SCIF_SIG_LOCAL */ - scif_recv_sig_remote, /* SCIF_SIG_REMOTE */ - scif_recv_sig_resp, /* SCIF_SIG_ACK */ - scif_recv_sig_resp, /* SCIF_SIG_NACK */ -}; - -static int scif_max_msg_id = SCIF_MAX_MSG; -/** - * scif_nodeqp_msg_handler() - Common handler for node messages - * @scifdev: Remote device to respond to - * @qp: Remote memory pointer - * @msg: The message to be handled. - * - * This routine calls the appropriate routine to handle a Node Qp - * message receipt - */ -static void -scif_nodeqp_msg_handler(struct scif_dev *scifdev, - struct scif_qp *qp, struct scifmsg *msg) -{ - scif_display_message(scifdev, msg, "Rcvd"); - - if (msg->uop > (u32)scif_max_msg_id) { - /* Bogus Node Qp Message? */ - dev_err(&scifdev->sdev->dev, - "Unknown message 0x%xn scifdev->node 0x%x\n", - msg->uop, scifdev->node); - return; - } - - scif_intr_func[msg->uop](scifdev, msg); -} - -/** - * scif_nodeqp_intrhandler() - Interrupt handler for node messages - * @scifdev: Remote device to respond to - * @qp: Remote memory pointer - * - * This routine is triggered by the interrupt mechanism. It reads - * messages from the node queue RB and calls the Node QP Message handling - * routine. - */ -void scif_nodeqp_intrhandler(struct scif_dev *scifdev, struct scif_qp *qp) -{ - struct scifmsg msg; - int read_size; - - do { - read_size = scif_rb_get_next(&qp->inbound_q, &msg, sizeof(msg)); - if (!read_size) - break; - scif_nodeqp_msg_handler(scifdev, qp, &msg); - /* - * The node queue pair is unmapped so skip the read pointer - * update after receipt of a SCIF_EXIT_ACK - */ - if (SCIF_EXIT_ACK == msg.uop) - break; - scif_rb_update_read_ptr(&qp->inbound_q); - } while (1); -} - -/** - * scif_loopb_wq_handler - Loopback Workqueue Handler. - * @unused: loop back work (unused) - * - * This work queue routine is invoked by the loopback work queue handler. - * It grabs the recv lock, dequeues any available messages from the head - * of the loopback message list, calls the node QP message handler, - * waits for it to return, then frees up this message and dequeues more - * elements of the list if available. - */ -static void scif_loopb_wq_handler(struct work_struct *unused) -{ - struct scif_dev *scifdev = scif_info.loopb_dev; - struct scif_qp *qp = scifdev->qpairs; - struct scif_loopb_msg *msg; - - do { - msg = NULL; - spin_lock(&qp->recv_lock); - if (!list_empty(&scif_info.loopb_recv_q)) { - msg = list_first_entry(&scif_info.loopb_recv_q, - struct scif_loopb_msg, - list); - list_del(&msg->list); - } - spin_unlock(&qp->recv_lock); - - if (msg) { - scif_nodeqp_msg_handler(scifdev, qp, &msg->msg); - kfree(msg); - } - } while (msg); -} - -/** - * scif_loopb_msg_handler() - Workqueue handler for loopback messages. - * @scifdev: SCIF device - * @qp: Queue pair. - * - * This work queue routine is triggered when a loopback message is received. - * - * We need special handling for receiving Node Qp messages on a loopback SCIF - * device via two workqueues for receiving messages. - * - * The reason we need the extra workqueue which is not required with *normal* - * non-loopback SCIF devices is the potential classic deadlock described below: - * - * Thread A tries to send a message on a loopback SCIF device and blocks since - * there is no space in the RB while it has the send_lock held or another - * lock called lock X for example. - * - * Thread B: The Loopback Node QP message receive workqueue receives the message - * and tries to send a message (eg an ACK) to the loopback SCIF device. It tries - * to grab the send lock again or lock X and deadlocks with Thread A. The RB - * cannot be drained any further due to this classic deadlock. - * - * In order to avoid deadlocks as mentioned above we have an extra level of - * indirection achieved by having two workqueues. - * 1) The first workqueue whose handler is scif_loopb_msg_handler reads - * messages from the Node QP RB, adds them to a list and queues work for the - * second workqueue. - * - * 2) The second workqueue whose handler is scif_loopb_wq_handler dequeues - * messages from the list, handles them, frees up the memory and dequeues - * more elements from the list if possible. - */ -int -scif_loopb_msg_handler(struct scif_dev *scifdev, struct scif_qp *qp) -{ - int read_size; - struct scif_loopb_msg *msg; - - do { - msg = kmalloc(sizeof(*msg), GFP_KERNEL); - if (!msg) - return -ENOMEM; - read_size = scif_rb_get_next(&qp->inbound_q, &msg->msg, - sizeof(struct scifmsg)); - if (read_size != sizeof(struct scifmsg)) { - kfree(msg); - scif_rb_update_read_ptr(&qp->inbound_q); - break; - } - spin_lock(&qp->recv_lock); - list_add_tail(&msg->list, &scif_info.loopb_recv_q); - spin_unlock(&qp->recv_lock); - queue_work(scif_info.loopb_wq, &scif_info.loopb_work); - scif_rb_update_read_ptr(&qp->inbound_q); - } while (read_size == sizeof(struct scifmsg)); - return read_size; -} - -/** - * scif_setup_loopback_qp - One time setup work for Loopback Node Qp. - * @scifdev: SCIF device - * - * Sets up the required loopback workqueues, queue pairs and ring buffers - */ -int scif_setup_loopback_qp(struct scif_dev *scifdev) -{ - int err = 0; - void *local_q; - struct scif_qp *qp; - - err = scif_setup_intr_wq(scifdev); - if (err) - goto exit; - INIT_LIST_HEAD(&scif_info.loopb_recv_q); - snprintf(scif_info.loopb_wqname, sizeof(scif_info.loopb_wqname), - "SCIF LOOPB %d", scifdev->node); - scif_info.loopb_wq = - alloc_ordered_workqueue(scif_info.loopb_wqname, 0); - if (!scif_info.loopb_wq) { - err = -ENOMEM; - goto destroy_intr; - } - INIT_WORK(&scif_info.loopb_work, scif_loopb_wq_handler); - /* Allocate Self Qpair */ - scifdev->qpairs = kzalloc(sizeof(*scifdev->qpairs), GFP_KERNEL); - if (!scifdev->qpairs) { - err = -ENOMEM; - goto destroy_loopb_wq; - } - - qp = scifdev->qpairs; - qp->magic = SCIFEP_MAGIC; - spin_lock_init(&qp->send_lock); - spin_lock_init(&qp->recv_lock); - - local_q = kzalloc(SCIF_NODE_QP_SIZE, GFP_KERNEL); - if (!local_q) { - err = -ENOMEM; - goto free_qpairs; - } - /* - * For loopback the inbound_q and outbound_q are essentially the same - * since the Node sends a message on the loopback interface to the - * outbound_q which is then received on the inbound_q. - */ - scif_rb_init(&qp->outbound_q, - &qp->local_read, - &qp->local_write, - local_q, get_count_order(SCIF_NODE_QP_SIZE)); - - scif_rb_init(&qp->inbound_q, - &qp->local_read, - &qp->local_write, - local_q, get_count_order(SCIF_NODE_QP_SIZE)); - scif_info.nodeid = scifdev->node; - - scif_peer_register_device(scifdev); - - scif_info.loopb_dev = scifdev; - return err; -free_qpairs: - kfree(scifdev->qpairs); -destroy_loopb_wq: - destroy_workqueue(scif_info.loopb_wq); -destroy_intr: - scif_destroy_intr_wq(scifdev); -exit: - return err; -} - -/** - * scif_destroy_loopback_qp - One time uninit work for Loopback Node Qp - * @scifdev: SCIF device - * - * Destroys the workqueues and frees up the Ring Buffer and Queue Pair memory. - */ -int scif_destroy_loopback_qp(struct scif_dev *scifdev) -{ - scif_peer_unregister_device(scifdev); - destroy_workqueue(scif_info.loopb_wq); - scif_destroy_intr_wq(scifdev); - kfree(scifdev->qpairs->outbound_q.rb_base); - kfree(scifdev->qpairs); - scifdev->sdev = NULL; - scif_info.loopb_dev = NULL; - return 0; -} - -void scif_destroy_p2p(struct scif_dev *scifdev) -{ - struct scif_dev *peer_dev; - struct scif_p2p_info *p2p; - struct list_head *pos, *tmp; - int bd; - - mutex_lock(&scif_info.conflock); - /* Free P2P mappings in the given node for all its peer nodes */ - list_for_each_safe(pos, tmp, &scifdev->p2p) { - p2p = list_entry(pos, struct scif_p2p_info, ppi_list); - dma_unmap_sg(&scifdev->sdev->dev, p2p->ppi_sg[SCIF_PPI_MMIO], - p2p->sg_nentries[SCIF_PPI_MMIO], - DMA_BIDIRECTIONAL); - dma_unmap_sg(&scifdev->sdev->dev, p2p->ppi_sg[SCIF_PPI_APER], - p2p->sg_nentries[SCIF_PPI_APER], - DMA_BIDIRECTIONAL); - scif_p2p_freesg(p2p->ppi_sg[SCIF_PPI_MMIO]); - scif_p2p_freesg(p2p->ppi_sg[SCIF_PPI_APER]); - list_del(pos); - kfree(p2p); - } - - /* Free P2P mapping created in the peer nodes for the given node */ - for (bd = SCIF_MGMT_NODE + 1; bd <= scif_info.maxid; bd++) { - peer_dev = &scif_dev[bd]; - list_for_each_safe(pos, tmp, &peer_dev->p2p) { - p2p = list_entry(pos, struct scif_p2p_info, ppi_list); - if (p2p->ppi_peer_id == scifdev->node) { - dma_unmap_sg(&peer_dev->sdev->dev, - p2p->ppi_sg[SCIF_PPI_MMIO], - p2p->sg_nentries[SCIF_PPI_MMIO], - DMA_BIDIRECTIONAL); - dma_unmap_sg(&peer_dev->sdev->dev, - p2p->ppi_sg[SCIF_PPI_APER], - p2p->sg_nentries[SCIF_PPI_APER], - DMA_BIDIRECTIONAL); - scif_p2p_freesg(p2p->ppi_sg[SCIF_PPI_MMIO]); - scif_p2p_freesg(p2p->ppi_sg[SCIF_PPI_APER]); - list_del(pos); - kfree(p2p); - } - } - } - mutex_unlock(&scif_info.conflock); -} diff --git a/drivers/misc/mic/scif/scif_nodeqp.h b/drivers/misc/mic/scif/scif_nodeqp.h deleted file mode 100644 index 95896273138e..000000000000 --- a/drivers/misc/mic/scif/scif_nodeqp.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2014 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * BSD LICENSE - * - * Copyright(c) 2014 Intel Corporation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Intel SCIF driver. - * - */ -#ifndef SCIF_NODEQP -#define SCIF_NODEQP - -#include "scif_rb.h" -#include "scif_peer_bus.h" - -#define SCIF_INIT 1 /* First message sent to the peer node for discovery */ -#define SCIF_EXIT 2 /* Last message from the peer informing intent to exit */ -#define SCIF_EXIT_ACK 3 /* Response to SCIF_EXIT message */ -#define SCIF_NODE_ADD 4 /* Tell Online nodes a new node exits */ -#define SCIF_NODE_ADD_ACK 5 /* Confirm to mgmt node sequence is finished */ -#define SCIF_NODE_ADD_NACK 6 /* SCIF_NODE_ADD failed */ -#define SCIF_NODE_REMOVE 7 /* Request to deactivate a SCIF node */ -#define SCIF_NODE_REMOVE_ACK 8 /* Response to a SCIF_NODE_REMOVE message */ -#define SCIF_CNCT_REQ 9 /* Phys addr of Request connection to a port */ -#define SCIF_CNCT_GNT 10 /* Phys addr of new Grant connection request */ -#define SCIF_CNCT_GNTACK 11 /* Error type Reject a connection request */ -#define SCIF_CNCT_GNTNACK 12 /* Error type Reject a connection request */ -#define SCIF_CNCT_REJ 13 /* Error type Reject a connection request */ -#define SCIF_DISCNCT 14 /* Notify peer that connection is being terminated */ -#define SCIF_DISCNT_ACK 15 /* Notify peer that connection is being terminated */ -#define SCIF_CLIENT_SENT 16 /* Notify the peer that data has been written */ -#define SCIF_CLIENT_RCVD 17 /* Notify the peer that data has been read */ -#define SCIF_GET_NODE_INFO 18 /* Get current node mask from the mgmt node*/ -#define SCIF_REGISTER 19 /* Tell peer about a new registered window */ -#define SCIF_REGISTER_ACK 20 /* Notify peer about unregistration success */ -#define SCIF_REGISTER_NACK 21 /* Notify peer about registration success */ -#define SCIF_UNREGISTER 22 /* Tell peer about unregistering a window */ -#define SCIF_UNREGISTER_ACK 23 /* Notify peer about registration failure */ -#define SCIF_UNREGISTER_NACK 24 /* Notify peer about unregistration failure */ -#define SCIF_ALLOC_REQ 25 /* Request a mapped buffer */ -#define SCIF_ALLOC_GNT 26 /* Notify peer about allocation success */ -#define SCIF_ALLOC_REJ 27 /* Notify peer about allocation failure */ -#define SCIF_FREE_VIRT 28 /* Free previously allocated virtual memory */ -#define SCIF_MUNMAP 29 /* Acknowledgment for a SCIF_MMAP request */ -#define SCIF_MARK 30 /* SCIF Remote Fence Mark Request */ -#define SCIF_MARK_ACK 31 /* SCIF Remote Fence Mark Success */ -#define SCIF_MARK_NACK 32 /* SCIF Remote Fence Mark Failure */ -#define SCIF_WAIT 33 /* SCIF Remote Fence Wait Request */ -#define SCIF_WAIT_ACK 34 /* SCIF Remote Fence Wait Success */ -#define SCIF_WAIT_NACK 35 /* SCIF Remote Fence Wait Failure */ -#define SCIF_SIG_LOCAL 36 /* SCIF Remote Fence Local Signal Request */ -#define SCIF_SIG_REMOTE 37 /* SCIF Remote Fence Remote Signal Request */ -#define SCIF_SIG_ACK 38 /* SCIF Remote Fence Remote Signal Success */ -#define SCIF_SIG_NACK 39 /* SCIF Remote Fence Remote Signal Failure */ -#define SCIF_MAX_MSG SCIF_SIG_NACK - -/* - * struct scifmsg - Node QP message format - * - * @src: Source information - * @dst: Destination information - * @uop: The message opcode - * @payload: Unique payload format for each message - */ -struct scifmsg { - struct scif_port_id src; - struct scif_port_id dst; - u32 uop; - u64 payload[4]; -} __packed; - -/* - * struct scif_allocmsg - Used with SCIF_ALLOC_REQ to request - * the remote note to allocate memory - * - * phys_addr: Physical address of the buffer - * vaddr: Virtual address of the buffer - * size: Size of the buffer - * state: Current state - * allocwq: wait queue for status - */ -struct scif_allocmsg { - dma_addr_t phys_addr; - unsigned long vaddr; - size_t size; - enum scif_msg_state state; - wait_queue_head_t allocwq; -}; - -/* - * struct scif_qp - Node Queue Pair - * - * Interesting structure -- a little difficult because we can only - * write across the PCIe, so any r/w pointer we need to read is - * local. We only need to read the read pointer on the inbound_q - * and read the write pointer in the outbound_q - * - * @magic: Magic value to ensure the peer sees the QP correctly - * @outbound_q: The outbound ring buffer for sending messages - * @inbound_q: The inbound ring buffer for receiving messages - * @local_write: Local write index - * @local_read: Local read index - * @remote_qp: The remote queue pair - * @local_buf: DMA address of local ring buffer - * @local_qp: DMA address of the local queue pair data structure - * @remote_buf: DMA address of remote ring buffer - * @qp_state: QP state i.e. online or offline used for P2P - * @send_lock: synchronize access to outbound queue - * @recv_lock: Synchronize access to inbound queue - */ -struct scif_qp { - u64 magic; -#define SCIFEP_MAGIC 0x5c1f000000005c1fULL - struct scif_rb outbound_q; - struct scif_rb inbound_q; - - u32 local_write __aligned(64); - u32 local_read __aligned(64); - struct scif_qp *remote_qp; - dma_addr_t local_buf; - dma_addr_t local_qp; - dma_addr_t remote_buf; - u32 qp_state; -#define SCIF_QP_OFFLINE 0xdead -#define SCIF_QP_ONLINE 0xc0de - spinlock_t send_lock; - spinlock_t recv_lock; -}; - -/* - * struct scif_loopb_msg - An element in the loopback Node QP message list. - * - * @msg - The SCIF node QP message - * @list - link in the list of messages - */ -struct scif_loopb_msg { - struct scifmsg msg; - struct list_head list; -}; - -int scif_nodeqp_send(struct scif_dev *scifdev, struct scifmsg *msg); -int _scif_nodeqp_send(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_nodeqp_intrhandler(struct scif_dev *scifdev, struct scif_qp *qp); -int scif_loopb_msg_handler(struct scif_dev *scifdev, struct scif_qp *qp); -int scif_setup_qp(struct scif_dev *scifdev); -int scif_qp_response(phys_addr_t phys, struct scif_dev *dev); -int scif_setup_qp_connect(struct scif_qp *qp, dma_addr_t *qp_offset, - int local_size, struct scif_dev *scifdev); -int scif_setup_qp_accept(struct scif_qp *qp, dma_addr_t *qp_offset, - dma_addr_t phys, int local_size, - struct scif_dev *scifdev); -int scif_setup_qp_connect_response(struct scif_dev *scifdev, - struct scif_qp *qp, u64 payload); -int scif_setup_loopback_qp(struct scif_dev *scifdev); -int scif_destroy_loopback_qp(struct scif_dev *scifdev); -void scif_poll_qp_state(struct work_struct *work); -void scif_destroy_p2p(struct scif_dev *scifdev); -void scif_send_exit(struct scif_dev *scifdev); -static inline struct device *scif_get_peer_dev(struct scif_dev *scifdev) -{ - struct scif_peer_dev *spdev; - struct device *spdev_ret; - - rcu_read_lock(); - spdev = rcu_dereference(scifdev->spdev); - if (spdev) - spdev_ret = get_device(&spdev->dev); - else - spdev_ret = ERR_PTR(-ENODEV); - rcu_read_unlock(); - return spdev_ret; -} - -static inline void scif_put_peer_dev(struct device *dev) -{ - put_device(dev); -} -#endif /* SCIF_NODEQP */ diff --git a/drivers/misc/mic/scif/scif_peer_bus.c b/drivers/misc/mic/scif/scif_peer_bus.c deleted file mode 100644 index 6d608308bb60..000000000000 --- a/drivers/misc/mic/scif/scif_peer_bus.c +++ /dev/null @@ -1,175 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#include "scif_main.h" -#include "../bus/scif_bus.h" -#include "scif_peer_bus.h" - -static inline struct scif_peer_dev * -dev_to_scif_peer(struct device *dev) -{ - return container_of(dev, struct scif_peer_dev, dev); -} - -struct bus_type scif_peer_bus = { - .name = "scif_peer_bus", -}; - -static void scif_peer_release_dev(struct device *d) -{ - struct scif_peer_dev *sdev = dev_to_scif_peer(d); - struct scif_dev *scifdev = &scif_dev[sdev->dnode]; - - scif_cleanup_scifdev(scifdev); - kfree(sdev); -} - -static int scif_peer_initialize_device(struct scif_dev *scifdev) -{ - struct scif_peer_dev *spdev; - int ret; - - spdev = kzalloc(sizeof(*spdev), GFP_KERNEL); - if (!spdev) { - ret = -ENOMEM; - goto err; - } - - spdev->dev.parent = scifdev->sdev->dev.parent; - spdev->dev.release = scif_peer_release_dev; - spdev->dnode = scifdev->node; - spdev->dev.bus = &scif_peer_bus; - dev_set_name(&spdev->dev, "scif_peer-dev%u", spdev->dnode); - - device_initialize(&spdev->dev); - get_device(&spdev->dev); - rcu_assign_pointer(scifdev->spdev, spdev); - - mutex_lock(&scif_info.conflock); - scif_info.total++; - scif_info.maxid = max_t(u32, spdev->dnode, scif_info.maxid); - mutex_unlock(&scif_info.conflock); - return 0; -err: - dev_err(&scifdev->sdev->dev, - "dnode %d: initialize_device rc %d\n", scifdev->node, ret); - return ret; -} - -static int scif_peer_add_device(struct scif_dev *scifdev) -{ - struct scif_peer_dev *spdev = rcu_dereference(scifdev->spdev); - char pool_name[16]; - int ret; - - ret = device_add(&spdev->dev); - put_device(&spdev->dev); - if (ret) { - dev_err(&scifdev->sdev->dev, - "dnode %d: peer device_add failed\n", scifdev->node); - goto put_spdev; - } - - scnprintf(pool_name, sizeof(pool_name), "scif-%d", spdev->dnode); - scifdev->signal_pool = dmam_pool_create(pool_name, &scifdev->sdev->dev, - sizeof(struct scif_status), 1, - 0); - if (!scifdev->signal_pool) { - dev_err(&scifdev->sdev->dev, - "dnode %d: dmam_pool_create failed\n", scifdev->node); - ret = -ENOMEM; - goto del_spdev; - } - dev_dbg(&spdev->dev, "Added peer dnode %d\n", spdev->dnode); - return 0; -del_spdev: - device_del(&spdev->dev); -put_spdev: - RCU_INIT_POINTER(scifdev->spdev, NULL); - synchronize_rcu(); - put_device(&spdev->dev); - - mutex_lock(&scif_info.conflock); - scif_info.total--; - mutex_unlock(&scif_info.conflock); - return ret; -} - -void scif_add_peer_device(struct work_struct *work) -{ - struct scif_dev *scifdev = container_of(work, struct scif_dev, - peer_add_work); - - scif_peer_add_device(scifdev); -} - -/* - * Peer device registration is split into a device_initialize and a device_add. - * The reason for doing this is as follows: First, peer device registration - * itself cannot be done in the message processing thread and must be delegated - * to another workqueue, otherwise if SCIF client probe, called during peer - * device registration, calls scif_connect(..), it will block the message - * processing thread causing a deadlock. Next, device_initialize is done in the - * "top-half" message processing thread and device_add in the "bottom-half" - * workqueue. If this is not done, SCIF_CNCT_REQ message processing executing - * concurrently with SCIF_INIT message processing is unable to get a reference - * on the peer device, thereby failing the connect request. - */ -void scif_peer_register_device(struct scif_dev *scifdev) -{ - int ret; - - mutex_lock(&scifdev->lock); - ret = scif_peer_initialize_device(scifdev); - if (ret) - goto exit; - schedule_work(&scifdev->peer_add_work); -exit: - mutex_unlock(&scifdev->lock); -} - -int scif_peer_unregister_device(struct scif_dev *scifdev) -{ - struct scif_peer_dev *spdev; - - mutex_lock(&scifdev->lock); - /* Flush work to ensure device register is complete */ - flush_work(&scifdev->peer_add_work); - - /* - * Continue holding scifdev->lock since theoretically unregister_device - * can be called simultaneously from multiple threads - */ - spdev = rcu_dereference(scifdev->spdev); - if (!spdev) { - mutex_unlock(&scifdev->lock); - return -ENODEV; - } - - RCU_INIT_POINTER(scifdev->spdev, NULL); - synchronize_rcu(); - mutex_unlock(&scifdev->lock); - - dev_dbg(&spdev->dev, "Removing peer dnode %d\n", spdev->dnode); - device_unregister(&spdev->dev); - - mutex_lock(&scif_info.conflock); - scif_info.total--; - mutex_unlock(&scif_info.conflock); - return 0; -} - -int scif_peer_bus_init(void) -{ - return bus_register(&scif_peer_bus); -} - -void scif_peer_bus_exit(void) -{ - bus_unregister(&scif_peer_bus); -} diff --git a/drivers/misc/mic/scif/scif_peer_bus.h b/drivers/misc/mic/scif/scif_peer_bus.h deleted file mode 100644 index 2ea4c51c18c1..000000000000 --- a/drivers/misc/mic/scif/scif_peer_bus.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#ifndef _SCIF_PEER_BUS_H_ -#define _SCIF_PEER_BUS_H_ - -#include <linux/device.h> -#include <linux/mic_common.h> -#include <linux/scif.h> - -struct scif_dev; - -void scif_add_peer_device(struct work_struct *work); -void scif_peer_register_device(struct scif_dev *sdev); -int scif_peer_unregister_device(struct scif_dev *scifdev); -int scif_peer_bus_init(void); -void scif_peer_bus_exit(void); -#endif /* _SCIF_PEER_BUS_H */ diff --git a/drivers/misc/mic/scif/scif_ports.c b/drivers/misc/mic/scif/scif_ports.c deleted file mode 100644 index 4bdb5ef9a139..000000000000 --- a/drivers/misc/mic/scif/scif_ports.c +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#include <linux/idr.h> - -#include "scif_main.h" - -#define SCIF_PORT_COUNT 0x10000 /* Ports available */ - -struct idr scif_ports; - -/** - * struct scif_port - SCIF port information - * - * @ref_cnt: Reference count since there can be multiple endpoints - * created via scif_accept(..) simultaneously using a port. - */ -struct scif_port { - int ref_cnt; -}; - -/** - * __scif_get_port - Reserve a specified port # for SCIF and add it - * to the global list. - * @start: lowest port # to be reserved (inclusive). - * @end: highest port # to be reserved (exclusive). - * - * @return : Allocated SCIF port #, or -ENOSPC if port unavailable. - * On memory allocation failure, returns -ENOMEM. - */ -static int __scif_get_port(int start, int end) -{ - int id; - struct scif_port *port = kzalloc(sizeof(*port), GFP_ATOMIC); - - if (!port) - return -ENOMEM; - spin_lock(&scif_info.port_lock); - id = idr_alloc(&scif_ports, port, start, end, GFP_ATOMIC); - if (id >= 0) - port->ref_cnt++; - spin_unlock(&scif_info.port_lock); - return id; -} - -/** - * scif_rsrv_port - Reserve a specified port # for SCIF. - * @port : port # to be reserved. - * - * @return : Allocated SCIF port #, or -ENOSPC if port unavailable. - * On memory allocation failure, returns -ENOMEM. - */ -int scif_rsrv_port(u16 port) -{ - return __scif_get_port(port, port + 1); -} - -/** - * scif_get_new_port - Get and reserve any port # for SCIF in the range - * SCIF_PORT_RSVD + 1 to SCIF_PORT_COUNT - 1. - * - * @return : Allocated SCIF port #, or -ENOSPC if no ports available. - * On memory allocation failure, returns -ENOMEM. - */ -int scif_get_new_port(void) -{ - return __scif_get_port(SCIF_PORT_RSVD + 1, SCIF_PORT_COUNT); -} - -/** - * scif_get_port - Increment the reference count for a SCIF port - * @id : SCIF port - * - * @return : None - */ -void scif_get_port(u16 id) -{ - struct scif_port *port; - - if (!id) - return; - spin_lock(&scif_info.port_lock); - port = idr_find(&scif_ports, id); - if (port) - port->ref_cnt++; - spin_unlock(&scif_info.port_lock); -} - -/** - * scif_put_port - Release a reserved SCIF port - * @id : SCIF port to be released. - * - * @return : None - */ -void scif_put_port(u16 id) -{ - struct scif_port *port; - - if (!id) - return; - spin_lock(&scif_info.port_lock); - port = idr_find(&scif_ports, id); - if (port) { - port->ref_cnt--; - if (!port->ref_cnt) { - idr_remove(&scif_ports, id); - kfree(port); - } - } - spin_unlock(&scif_info.port_lock); -} diff --git a/drivers/misc/mic/scif/scif_rb.c b/drivers/misc/mic/scif/scif_rb.c deleted file mode 100644 index e425882ae06d..000000000000 --- a/drivers/misc/mic/scif/scif_rb.c +++ /dev/null @@ -1,240 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2014 Intel Corporation. - * - * Intel SCIF driver. - */ -#include <linux/circ_buf.h> -#include <linux/types.h> -#include <linux/io.h> -#include <linux/errno.h> - -#include "scif_rb.h" - -#define scif_rb_ring_cnt(head, tail, size) CIRC_CNT(head, tail, size) -#define scif_rb_ring_space(head, tail, size) CIRC_SPACE(head, tail, size) - -/** - * scif_rb_init - Initializes the ring buffer - * @rb: ring buffer - * @read_ptr: A pointer to the read offset - * @write_ptr: A pointer to the write offset - * @rb_base: A pointer to the base of the ring buffer - * @size: The size of the ring buffer in powers of two - */ -void scif_rb_init(struct scif_rb *rb, u32 *read_ptr, u32 *write_ptr, - void *rb_base, u8 size) -{ - rb->rb_base = rb_base; - rb->size = (1 << size); - rb->read_ptr = read_ptr; - rb->write_ptr = write_ptr; - rb->current_read_offset = *read_ptr; - rb->current_write_offset = *write_ptr; -} - -/* Copies a message to the ring buffer -- handles the wrap around case */ -static void memcpy_torb(struct scif_rb *rb, void *header, - void *msg, u32 size) -{ - u32 size1, size2; - - if (header + size >= rb->rb_base + rb->size) { - /* Need to call two copies if it wraps around */ - size1 = (u32)(rb->rb_base + rb->size - header); - size2 = size - size1; - memcpy_toio((void __iomem __force *)header, msg, size1); - memcpy_toio((void __iomem __force *)rb->rb_base, - msg + size1, size2); - } else { - memcpy_toio((void __iomem __force *)header, msg, size); - } -} - -/* Copies a message from the ring buffer -- handles the wrap around case */ -static void memcpy_fromrb(struct scif_rb *rb, void *header, - void *msg, u32 size) -{ - u32 size1, size2; - - if (header + size >= rb->rb_base + rb->size) { - /* Need to call two copies if it wraps around */ - size1 = (u32)(rb->rb_base + rb->size - header); - size2 = size - size1; - memcpy_fromio(msg, (void __iomem __force *)header, size1); - memcpy_fromio(msg + size1, - (void __iomem __force *)rb->rb_base, size2); - } else { - memcpy_fromio(msg, (void __iomem __force *)header, size); - } -} - -/** - * scif_rb_space - Query space available for writing to the RB - * @rb: ring buffer - * - * Return: size available for writing to RB in bytes. - */ -u32 scif_rb_space(struct scif_rb *rb) -{ - rb->current_read_offset = *rb->read_ptr; - /* - * Update from the HW read pointer only once the peer has exposed the - * new empty slot. This barrier is paired with the memory barrier - * scif_rb_update_read_ptr() - */ - mb(); - return scif_rb_ring_space(rb->current_write_offset, - rb->current_read_offset, rb->size); -} - -/** - * scif_rb_write - Write a message to the RB - * @rb: ring buffer - * @msg: buffer to send the message. Must be at least size bytes long - * @size: the size (in bytes) to be copied to the RB - * - * This API does not block if there isn't enough space in the RB. - * Returns: 0 on success or -ENOMEM on failure - */ -int scif_rb_write(struct scif_rb *rb, void *msg, u32 size) -{ - void *header; - - if (scif_rb_space(rb) < size) - return -ENOMEM; - header = rb->rb_base + rb->current_write_offset; - memcpy_torb(rb, header, msg, size); - /* - * Wait until scif_rb_commit(). Update the local ring - * buffer data, not the shared data until commit. - */ - rb->current_write_offset = - (rb->current_write_offset + size) & (rb->size - 1); - return 0; -} - -/** - * scif_rb_commit - To submit the message to let the peer fetch it - * @rb: ring buffer - */ -void scif_rb_commit(struct scif_rb *rb) -{ - /* - * We must ensure ordering between the all the data committed - * previously before we expose the new message to the peer by - * updating the write_ptr. This write barrier is paired with - * the read barrier in scif_rb_count(..) - */ - wmb(); - WRITE_ONCE(*rb->write_ptr, rb->current_write_offset); -#ifdef CONFIG_INTEL_MIC_CARD - /* - * X100 Si bug: For the case where a Core is performing an EXT_WR - * followed by a Doorbell Write, the Core must perform two EXT_WR to the - * same address with the same data before it does the Doorbell Write. - * This way, if ordering is violated for the Interrupt Message, it will - * fall just behind the first Posted associated with the first EXT_WR. - */ - WRITE_ONCE(*rb->write_ptr, rb->current_write_offset); -#endif -} - -/** - * scif_rb_get - To get next message from the ring buffer - * @rb: ring buffer - * @size: Number of bytes to be read - * - * Return: NULL if no bytes to be read from the ring buffer, otherwise the - * pointer to the next byte - */ -static void *scif_rb_get(struct scif_rb *rb, u32 size) -{ - void *header = NULL; - - if (scif_rb_count(rb, size) >= size) - header = rb->rb_base + rb->current_read_offset; - return header; -} - -/* - * scif_rb_get_next - Read from ring buffer. - * @rb: ring buffer - * @msg: buffer to hold the message. Must be at least size bytes long - * @size: Number of bytes to be read - * - * Return: number of bytes read if available bytes are >= size, otherwise - * returns zero. - */ -u32 scif_rb_get_next(struct scif_rb *rb, void *msg, u32 size) -{ - void *header = NULL; - int read_size = 0; - - header = scif_rb_get(rb, size); - if (header) { - u32 next_cmd_offset = - (rb->current_read_offset + size) & (rb->size - 1); - - read_size = size; - rb->current_read_offset = next_cmd_offset; - memcpy_fromrb(rb, header, msg, size); - } - return read_size; -} - -/** - * scif_rb_update_read_ptr - * @rb: ring buffer - */ -void scif_rb_update_read_ptr(struct scif_rb *rb) -{ - u32 new_offset; - - new_offset = rb->current_read_offset; - /* - * We must ensure ordering between the all the data committed or read - * previously before we expose the empty slot to the peer by updating - * the read_ptr. This barrier is paired with the memory barrier in - * scif_rb_space(..) - */ - mb(); - WRITE_ONCE(*rb->read_ptr, new_offset); -#ifdef CONFIG_INTEL_MIC_CARD - /* - * X100 Si Bug: For the case where a Core is performing an EXT_WR - * followed by a Doorbell Write, the Core must perform two EXT_WR to the - * same address with the same data before it does the Doorbell Write. - * This way, if ordering is violated for the Interrupt Message, it will - * fall just behind the first Posted associated with the first EXT_WR. - */ - WRITE_ONCE(*rb->read_ptr, new_offset); -#endif -} - -/** - * scif_rb_count - * @rb: ring buffer - * @size: Number of bytes expected to be read - * - * Return: number of bytes that can be read from the RB - */ -u32 scif_rb_count(struct scif_rb *rb, u32 size) -{ - if (scif_rb_ring_cnt(rb->current_write_offset, - rb->current_read_offset, - rb->size) < size) { - rb->current_write_offset = *rb->write_ptr; - /* - * Update from the HW write pointer if empty only once the peer - * has exposed the new message. This read barrier is paired - * with the write barrier in scif_rb_commit(..) - */ - smp_rmb(); - } - return scif_rb_ring_cnt(rb->current_write_offset, - rb->current_read_offset, - rb->size); -} diff --git a/drivers/misc/mic/scif/scif_rb.h b/drivers/misc/mic/scif/scif_rb.h deleted file mode 100644 index 166dffe3093d..000000000000 --- a/drivers/misc/mic/scif/scif_rb.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2014 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * BSD LICENSE - * - * Copyright(c) 2014 Intel Corporation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Intel SCIF driver. - */ -#ifndef SCIF_RB_H -#define SCIF_RB_H -/* - * This file describes a general purpose, byte based ring buffer. Writers to the - * ring buffer need to synchronize using a lock. The same is true for readers, - * although in practice, the ring buffer has a single reader. It is lockless - * between producer and consumer so it can handle being used across the PCIe - * bus. The ring buffer ensures that there are no reads across the PCIe bus for - * performance reasons. Two of these are used to form a single bidirectional - * queue-pair across PCIe. - */ -/* - * struct scif_rb - SCIF Ring Buffer - * - * @rb_base: The base of the memory used for storing RB messages - * @read_ptr: Pointer to the read offset - * @write_ptr: Pointer to the write offset - * @size: Size of the memory in rb_base - * @current_read_offset: Cached read offset for performance - * @current_write_offset: Cached write offset for performance - */ -struct scif_rb { - void *rb_base; - u32 *read_ptr; - u32 *write_ptr; - u32 size; - u32 current_read_offset; - u32 current_write_offset; -}; - -/* methods used by both */ -void scif_rb_init(struct scif_rb *rb, u32 *read_ptr, u32 *write_ptr, - void *rb_base, u8 size); -/* writer only methods */ -/* write a new command, then scif_rb_commit() */ -int scif_rb_write(struct scif_rb *rb, void *msg, u32 size); -/* after write(), then scif_rb_commit() */ -void scif_rb_commit(struct scif_rb *rb); -/* query space available for writing to a RB. */ -u32 scif_rb_space(struct scif_rb *rb); - -/* reader only methods */ -/* read a new message from the ring buffer of size bytes */ -u32 scif_rb_get_next(struct scif_rb *rb, void *msg, u32 size); -/* update the read pointer so that the space can be reused */ -void scif_rb_update_read_ptr(struct scif_rb *rb); -/* count the number of bytes that can be read */ -u32 scif_rb_count(struct scif_rb *rb, u32 size); -#endif diff --git a/drivers/misc/mic/scif/scif_rma.c b/drivers/misc/mic/scif/scif_rma.c deleted file mode 100644 index 18fb9d8b8a4b..000000000000 --- a/drivers/misc/mic/scif/scif_rma.c +++ /dev/null @@ -1,1760 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel SCIF driver. - */ -#include <linux/intel-iommu.h> -#include <linux/pagemap.h> -#include <linux/sched/mm.h> -#include <linux/sched/signal.h> - -#include "scif_main.h" -#include "scif_map.h" - -/* Used to skip ulimit checks for registrations with SCIF_MAP_KERNEL flag */ -#define SCIF_MAP_ULIMIT 0x40 - -bool scif_ulimit_check = 1; - -/** - * scif_rma_ep_init: - * @ep: end point - * - * Initialize RMA per EP data structures. - */ -void scif_rma_ep_init(struct scif_endpt *ep) -{ - struct scif_endpt_rma_info *rma = &ep->rma_info; - - mutex_init(&rma->rma_lock); - init_iova_domain(&rma->iovad, PAGE_SIZE, SCIF_IOVA_START_PFN); - spin_lock_init(&rma->tc_lock); - mutex_init(&rma->mmn_lock); - INIT_LIST_HEAD(&rma->reg_list); - INIT_LIST_HEAD(&rma->remote_reg_list); - atomic_set(&rma->tw_refcount, 0); - atomic_set(&rma->tcw_refcount, 0); - atomic_set(&rma->tcw_total_pages, 0); - atomic_set(&rma->fence_refcount, 0); - - rma->async_list_del = 0; - rma->dma_chan = NULL; - INIT_LIST_HEAD(&rma->mmn_list); - INIT_LIST_HEAD(&rma->vma_list); - init_waitqueue_head(&rma->markwq); -} - -/** - * scif_rma_ep_can_uninit: - * @ep: end point - * - * Returns 1 if an endpoint can be uninitialized and 0 otherwise. - */ -int scif_rma_ep_can_uninit(struct scif_endpt *ep) -{ - int ret = 0; - - mutex_lock(&ep->rma_info.rma_lock); - /* Destroy RMA Info only if both lists are empty */ - if (list_empty(&ep->rma_info.reg_list) && - list_empty(&ep->rma_info.remote_reg_list) && - list_empty(&ep->rma_info.mmn_list) && - !atomic_read(&ep->rma_info.tw_refcount) && - !atomic_read(&ep->rma_info.tcw_refcount) && - !atomic_read(&ep->rma_info.fence_refcount)) - ret = 1; - mutex_unlock(&ep->rma_info.rma_lock); - return ret; -} - -/** - * scif_create_pinned_pages: - * @nr_pages: number of pages in window - * @prot: read/write protection - * - * Allocate and prepare a set of pinned pages. - */ -static struct scif_pinned_pages * -scif_create_pinned_pages(int nr_pages, int prot) -{ - struct scif_pinned_pages *pin; - - might_sleep(); - pin = scif_zalloc(sizeof(*pin)); - if (!pin) - goto error; - - pin->pages = scif_zalloc(nr_pages * sizeof(*pin->pages)); - if (!pin->pages) - goto error_free_pinned_pages; - - pin->prot = prot; - pin->magic = SCIFEP_MAGIC; - return pin; - -error_free_pinned_pages: - scif_free(pin, sizeof(*pin)); -error: - return NULL; -} - -/** - * scif_destroy_pinned_pages: - * @pin: A set of pinned pages. - * - * Deallocate resources for pinned pages. - */ -static int scif_destroy_pinned_pages(struct scif_pinned_pages *pin) -{ - int j; - int writeable = pin->prot & SCIF_PROT_WRITE; - int kernel = SCIF_MAP_KERNEL & pin->map_flags; - - if (kernel) { - for (j = 0; j < pin->nr_pages; j++) { - if (pin->pages[j] && !kernel) { - if (writeable) - set_page_dirty_lock(pin->pages[j]); - put_page(pin->pages[j]); - } - } - } else - unpin_user_pages_dirty_lock(pin->pages, pin->nr_pages, - writeable); - scif_free(pin->pages, - pin->nr_pages * sizeof(*pin->pages)); - scif_free(pin, sizeof(*pin)); - return 0; -} - -/* - * scif_create_window: - * @ep: end point - * @nr_pages: number of pages - * @offset: registration offset - * @temp: true if a temporary window is being created - * - * Allocate and prepare a self registration window. - */ -struct scif_window *scif_create_window(struct scif_endpt *ep, int nr_pages, - s64 offset, bool temp) -{ - struct scif_window *window; - - might_sleep(); - window = scif_zalloc(sizeof(*window)); - if (!window) - goto error; - - window->dma_addr = scif_zalloc(nr_pages * sizeof(*window->dma_addr)); - if (!window->dma_addr) - goto error_free_window; - - window->num_pages = scif_zalloc(nr_pages * sizeof(*window->num_pages)); - if (!window->num_pages) - goto error_free_window; - - window->offset = offset; - window->ep = (u64)ep; - window->magic = SCIFEP_MAGIC; - window->reg_state = OP_IDLE; - init_waitqueue_head(&window->regwq); - window->unreg_state = OP_IDLE; - init_waitqueue_head(&window->unregwq); - INIT_LIST_HEAD(&window->list); - window->type = SCIF_WINDOW_SELF; - window->temp = temp; - return window; - -error_free_window: - scif_free(window->dma_addr, - nr_pages * sizeof(*window->dma_addr)); - scif_free(window, sizeof(*window)); -error: - return NULL; -} - -/** - * scif_destroy_incomplete_window: - * @ep: end point - * @window: registration window - * - * Deallocate resources for self window. - */ -static void scif_destroy_incomplete_window(struct scif_endpt *ep, - struct scif_window *window) -{ - int err; - int nr_pages = window->nr_pages; - struct scif_allocmsg *alloc = &window->alloc_handle; - struct scifmsg msg; - -retry: - /* Wait for a SCIF_ALLOC_GNT/REJ message */ - err = wait_event_timeout(alloc->allocwq, - alloc->state != OP_IN_PROGRESS, - SCIF_NODE_ALIVE_TIMEOUT); - if (!err && scifdev_alive(ep)) - goto retry; - - mutex_lock(&ep->rma_info.rma_lock); - if (alloc->state == OP_COMPLETED) { - msg.uop = SCIF_FREE_VIRT; - msg.src = ep->port; - msg.payload[0] = ep->remote_ep; - msg.payload[1] = window->alloc_handle.vaddr; - msg.payload[2] = (u64)window; - msg.payload[3] = SCIF_REGISTER; - _scif_nodeqp_send(ep->remote_dev, &msg); - } - mutex_unlock(&ep->rma_info.rma_lock); - - scif_free_window_offset(ep, window, window->offset); - scif_free(window->dma_addr, nr_pages * sizeof(*window->dma_addr)); - scif_free(window->num_pages, nr_pages * sizeof(*window->num_pages)); - scif_free(window, sizeof(*window)); -} - -/** - * scif_unmap_window: - * @remote_dev: SCIF remote device - * @window: registration window - * - * Delete any DMA mappings created for a registered self window - */ -void scif_unmap_window(struct scif_dev *remote_dev, struct scif_window *window) -{ - int j; - - if (scif_is_iommu_enabled() && !scifdev_self(remote_dev)) { - if (window->st) { - dma_unmap_sg(&remote_dev->sdev->dev, - window->st->sgl, window->st->nents, - DMA_BIDIRECTIONAL); - sg_free_table(window->st); - kfree(window->st); - window->st = NULL; - } - } else { - for (j = 0; j < window->nr_contig_chunks; j++) { - if (window->dma_addr[j]) { - scif_unmap_single(window->dma_addr[j], - remote_dev, - window->num_pages[j] << - PAGE_SHIFT); - window->dma_addr[j] = 0x0; - } - } - } -} - -static inline struct mm_struct *__scif_acquire_mm(void) -{ - if (scif_ulimit_check) - return get_task_mm(current); - return NULL; -} - -static inline void __scif_release_mm(struct mm_struct *mm) -{ - if (mm) - mmput(mm); -} - -static inline int -__scif_dec_pinned_vm_lock(struct mm_struct *mm, - int nr_pages) -{ - if (!mm || !nr_pages || !scif_ulimit_check) - return 0; - - atomic64_sub(nr_pages, &mm->pinned_vm); - return 0; -} - -static inline int __scif_check_inc_pinned_vm(struct mm_struct *mm, - int nr_pages) -{ - unsigned long locked, lock_limit; - - if (!mm || !nr_pages || !scif_ulimit_check) - return 0; - - lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; - locked = atomic64_add_return(nr_pages, &mm->pinned_vm); - - if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) { - atomic64_sub(nr_pages, &mm->pinned_vm); - dev_err(scif_info.mdev.this_device, - "locked(%lu) > lock_limit(%lu)\n", - locked, lock_limit); - return -ENOMEM; - } - return 0; -} - -/** - * scif_destroy_window: - * @ep: end point - * @window: registration window - * - * Deallocate resources for self window. - */ -int scif_destroy_window(struct scif_endpt *ep, struct scif_window *window) -{ - int j; - struct scif_pinned_pages *pinned_pages = window->pinned_pages; - int nr_pages = window->nr_pages; - - might_sleep(); - if (!window->temp && window->mm) { - __scif_dec_pinned_vm_lock(window->mm, window->nr_pages); - __scif_release_mm(window->mm); - window->mm = NULL; - } - - scif_free_window_offset(ep, window, window->offset); - scif_unmap_window(ep->remote_dev, window); - /* - * Decrement references for this set of pinned pages from - * this window. - */ - j = atomic_sub_return(1, &pinned_pages->ref_count); - if (j < 0) - dev_err(scif_info.mdev.this_device, - "%s %d incorrect ref count %d\n", - __func__, __LINE__, j); - /* - * If the ref count for pinned_pages is zero then someone - * has already called scif_unpin_pages() for it and we should - * destroy the page cache. - */ - if (!j) - scif_destroy_pinned_pages(window->pinned_pages); - scif_free(window->dma_addr, nr_pages * sizeof(*window->dma_addr)); - scif_free(window->num_pages, nr_pages * sizeof(*window->num_pages)); - window->magic = 0; - scif_free(window, sizeof(*window)); - return 0; -} - -/** - * scif_create_remote_lookup: - * @remote_dev: SCIF remote device - * @window: remote window - * - * Allocate and prepare lookup entries for the remote - * end to copy over the physical addresses. - * Returns 0 on success and appropriate errno on failure. - */ -static int scif_create_remote_lookup(struct scif_dev *remote_dev, - struct scif_window *window) -{ - int i, j, err = 0; - int nr_pages = window->nr_pages; - bool vmalloc_dma_phys, vmalloc_num_pages; - - might_sleep(); - /* Map window */ - err = scif_map_single(&window->mapped_offset, - window, remote_dev, sizeof(*window)); - if (err) - goto error_window; - - /* Compute the number of lookup entries. 21 == 2MB Shift */ - window->nr_lookup = ALIGN(nr_pages * PAGE_SIZE, - ((2) * 1024 * 1024)) >> 21; - - window->dma_addr_lookup.lookup = - scif_alloc_coherent(&window->dma_addr_lookup.offset, - remote_dev, window->nr_lookup * - sizeof(*window->dma_addr_lookup.lookup), - GFP_KERNEL | __GFP_ZERO); - if (!window->dma_addr_lookup.lookup) { - err = -ENOMEM; - goto error_window; - } - - window->num_pages_lookup.lookup = - scif_alloc_coherent(&window->num_pages_lookup.offset, - remote_dev, window->nr_lookup * - sizeof(*window->num_pages_lookup.lookup), - GFP_KERNEL | __GFP_ZERO); - if (!window->num_pages_lookup.lookup) { - err = -ENOMEM; - goto error_window; - } - - vmalloc_dma_phys = is_vmalloc_addr(&window->dma_addr[0]); - vmalloc_num_pages = is_vmalloc_addr(&window->num_pages[0]); - - /* Now map each of the pages containing physical addresses */ - for (i = 0, j = 0; i < nr_pages; i += SCIF_NR_ADDR_IN_PAGE, j++) { - err = scif_map_page(&window->dma_addr_lookup.lookup[j], - vmalloc_dma_phys ? - vmalloc_to_page(&window->dma_addr[i]) : - virt_to_page(&window->dma_addr[i]), - remote_dev); - if (err) - goto error_window; - err = scif_map_page(&window->num_pages_lookup.lookup[j], - vmalloc_num_pages ? - vmalloc_to_page(&window->num_pages[i]) : - virt_to_page(&window->num_pages[i]), - remote_dev); - if (err) - goto error_window; - } - return 0; -error_window: - return err; -} - -/** - * scif_destroy_remote_lookup: - * @remote_dev: SCIF remote device - * @window: remote window - * - * Destroy lookup entries used for the remote - * end to copy over the physical addresses. - */ -static void scif_destroy_remote_lookup(struct scif_dev *remote_dev, - struct scif_window *window) -{ - int i, j; - - if (window->nr_lookup) { - struct scif_rma_lookup *lup = &window->dma_addr_lookup; - struct scif_rma_lookup *npup = &window->num_pages_lookup; - - for (i = 0, j = 0; i < window->nr_pages; - i += SCIF_NR_ADDR_IN_PAGE, j++) { - if (lup->lookup && lup->lookup[j]) - scif_unmap_single(lup->lookup[j], - remote_dev, - PAGE_SIZE); - if (npup->lookup && npup->lookup[j]) - scif_unmap_single(npup->lookup[j], - remote_dev, - PAGE_SIZE); - } - if (lup->lookup) - scif_free_coherent(lup->lookup, lup->offset, - remote_dev, window->nr_lookup * - sizeof(*lup->lookup)); - if (npup->lookup) - scif_free_coherent(npup->lookup, npup->offset, - remote_dev, window->nr_lookup * - sizeof(*npup->lookup)); - if (window->mapped_offset) - scif_unmap_single(window->mapped_offset, - remote_dev, sizeof(*window)); - window->nr_lookup = 0; - } -} - -/** - * scif_create_remote_window: - * @scifdev: SCIF device - * @nr_pages: number of pages in window - * - * Allocate and prepare a remote registration window. - */ -static struct scif_window * -scif_create_remote_window(struct scif_dev *scifdev, int nr_pages) -{ - struct scif_window *window; - - might_sleep(); - window = scif_zalloc(sizeof(*window)); - if (!window) - goto error_ret; - - window->magic = SCIFEP_MAGIC; - window->nr_pages = nr_pages; - - window->dma_addr = scif_zalloc(nr_pages * sizeof(*window->dma_addr)); - if (!window->dma_addr) - goto error_window; - - window->num_pages = scif_zalloc(nr_pages * - sizeof(*window->num_pages)); - if (!window->num_pages) - goto error_window; - - if (scif_create_remote_lookup(scifdev, window)) - goto error_window; - - window->type = SCIF_WINDOW_PEER; - window->unreg_state = OP_IDLE; - INIT_LIST_HEAD(&window->list); - return window; -error_window: - scif_destroy_remote_window(window); -error_ret: - return NULL; -} - -/** - * scif_destroy_remote_window: - * @window: remote registration window - * - * Deallocate resources for remote window. - */ -void -scif_destroy_remote_window(struct scif_window *window) -{ - scif_free(window->dma_addr, window->nr_pages * - sizeof(*window->dma_addr)); - scif_free(window->num_pages, window->nr_pages * - sizeof(*window->num_pages)); - window->magic = 0; - scif_free(window, sizeof(*window)); -} - -/** - * scif_iommu_map: create DMA mappings if the IOMMU is enabled - * @remote_dev: SCIF remote device - * @window: remote registration window - * - * Map the physical pages using dma_map_sg(..) and then detect the number - * of contiguous DMA mappings allocated - */ -static int scif_iommu_map(struct scif_dev *remote_dev, - struct scif_window *window) -{ - struct scatterlist *sg; - int i, err; - scif_pinned_pages_t pin = window->pinned_pages; - - window->st = kzalloc(sizeof(*window->st), GFP_KERNEL); - if (!window->st) - return -ENOMEM; - - err = sg_alloc_table(window->st, window->nr_pages, GFP_KERNEL); - if (err) - return err; - - for_each_sg(window->st->sgl, sg, window->st->nents, i) - sg_set_page(sg, pin->pages[i], PAGE_SIZE, 0x0); - - err = dma_map_sg(&remote_dev->sdev->dev, window->st->sgl, - window->st->nents, DMA_BIDIRECTIONAL); - if (!err) - return -ENOMEM; - /* Detect contiguous ranges of DMA mappings */ - sg = window->st->sgl; - for (i = 0; sg; i++) { - dma_addr_t last_da; - - window->dma_addr[i] = sg_dma_address(sg); - window->num_pages[i] = sg_dma_len(sg) >> PAGE_SHIFT; - last_da = sg_dma_address(sg) + sg_dma_len(sg); - while ((sg = sg_next(sg)) && sg_dma_address(sg) == last_da) { - window->num_pages[i] += - (sg_dma_len(sg) >> PAGE_SHIFT); - last_da = window->dma_addr[i] + - sg_dma_len(sg); - } - window->nr_contig_chunks++; - } - return 0; -} - -/** - * scif_map_window: - * @remote_dev: SCIF remote device - * @window: self registration window - * - * Map pages of a window into the aperture/PCI. - * Also determine addresses required for DMA. - */ -int -scif_map_window(struct scif_dev *remote_dev, struct scif_window *window) -{ - int i, j, k, err = 0, nr_contig_pages; - scif_pinned_pages_t pin; - phys_addr_t phys_prev, phys_curr; - - might_sleep(); - - pin = window->pinned_pages; - - if (intel_iommu_enabled && !scifdev_self(remote_dev)) - return scif_iommu_map(remote_dev, window); - - for (i = 0, j = 0; i < window->nr_pages; i += nr_contig_pages, j++) { - phys_prev = page_to_phys(pin->pages[i]); - nr_contig_pages = 1; - - /* Detect physically contiguous chunks */ - for (k = i + 1; k < window->nr_pages; k++) { - phys_curr = page_to_phys(pin->pages[k]); - if (phys_curr != (phys_prev + PAGE_SIZE)) - break; - phys_prev = phys_curr; - nr_contig_pages++; - } - window->num_pages[j] = nr_contig_pages; - window->nr_contig_chunks++; - if (scif_is_mgmt_node()) { - /* - * Management node has to deal with SMPT on X100 and - * hence the DMA mapping is required - */ - err = scif_map_single(&window->dma_addr[j], - phys_to_virt(page_to_phys( - pin->pages[i])), - remote_dev, - nr_contig_pages << PAGE_SHIFT); - if (err) - return err; - } else { - window->dma_addr[j] = page_to_phys(pin->pages[i]); - } - } - return err; -} - -/** - * scif_send_scif_unregister: - * @ep: end point - * @window: self registration window - * - * Send a SCIF_UNREGISTER message. - */ -static int scif_send_scif_unregister(struct scif_endpt *ep, - struct scif_window *window) -{ - struct scifmsg msg; - - msg.uop = SCIF_UNREGISTER; - msg.src = ep->port; - msg.payload[0] = window->alloc_handle.vaddr; - msg.payload[1] = (u64)window; - return scif_nodeqp_send(ep->remote_dev, &msg); -} - -/** - * scif_unregister_window: - * @window: self registration window - * - * Send an unregistration request and wait for a response. - */ -int scif_unregister_window(struct scif_window *window) -{ - int err = 0; - struct scif_endpt *ep = (struct scif_endpt *)window->ep; - bool send_msg = false; - - might_sleep(); - switch (window->unreg_state) { - case OP_IDLE: - { - window->unreg_state = OP_IN_PROGRESS; - send_msg = true; - } - fallthrough; - case OP_IN_PROGRESS: - { - scif_get_window(window, 1); - mutex_unlock(&ep->rma_info.rma_lock); - if (send_msg) { - err = scif_send_scif_unregister(ep, window); - if (err) { - window->unreg_state = OP_COMPLETED; - goto done; - } - } else { - /* Return ENXIO since unregistration is in progress */ - mutex_lock(&ep->rma_info.rma_lock); - return -ENXIO; - } -retry: - /* Wait for a SCIF_UNREGISTER_(N)ACK message */ - err = wait_event_timeout(window->unregwq, - window->unreg_state != OP_IN_PROGRESS, - SCIF_NODE_ALIVE_TIMEOUT); - if (!err && scifdev_alive(ep)) - goto retry; - if (!err) { - err = -ENODEV; - window->unreg_state = OP_COMPLETED; - dev_err(scif_info.mdev.this_device, - "%s %d err %d\n", __func__, __LINE__, err); - } - if (err > 0) - err = 0; -done: - mutex_lock(&ep->rma_info.rma_lock); - scif_put_window(window, 1); - break; - } - case OP_FAILED: - { - if (!scifdev_alive(ep)) { - err = -ENODEV; - window->unreg_state = OP_COMPLETED; - } - break; - } - case OP_COMPLETED: - break; - default: - err = -ENODEV; - } - - if (window->unreg_state == OP_COMPLETED && window->ref_count) - scif_put_window(window, window->nr_pages); - - if (!window->ref_count) { - atomic_inc(&ep->rma_info.tw_refcount); - list_del_init(&window->list); - scif_free_window_offset(ep, window, window->offset); - mutex_unlock(&ep->rma_info.rma_lock); - if ((!!(window->pinned_pages->map_flags & SCIF_MAP_KERNEL)) && - scifdev_alive(ep)) { - scif_drain_dma_intr(ep->remote_dev->sdev, - ep->rma_info.dma_chan); - } else { - if (!__scif_dec_pinned_vm_lock(window->mm, - window->nr_pages)) { - __scif_release_mm(window->mm); - window->mm = NULL; - } - } - scif_queue_for_cleanup(window, &scif_info.rma); - mutex_lock(&ep->rma_info.rma_lock); - } - return err; -} - -/** - * scif_send_alloc_request: - * @ep: end point - * @window: self registration window - * - * Send a remote window allocation request - */ -static int scif_send_alloc_request(struct scif_endpt *ep, - struct scif_window *window) -{ - struct scifmsg msg; - struct scif_allocmsg *alloc = &window->alloc_handle; - - /* Set up the Alloc Handle */ - alloc->state = OP_IN_PROGRESS; - init_waitqueue_head(&alloc->allocwq); - - /* Send out an allocation request */ - msg.uop = SCIF_ALLOC_REQ; - msg.payload[1] = window->nr_pages; - msg.payload[2] = (u64)&window->alloc_handle; - return _scif_nodeqp_send(ep->remote_dev, &msg); -} - -/** - * scif_prep_remote_window: - * @ep: end point - * @window: self registration window - * - * Send a remote window allocation request, wait for an allocation response, - * and prepares the remote window by copying over the page lists - */ -static int scif_prep_remote_window(struct scif_endpt *ep, - struct scif_window *window) -{ - struct scifmsg msg; - struct scif_window *remote_window; - struct scif_allocmsg *alloc = &window->alloc_handle; - dma_addr_t *dma_phys_lookup, *tmp, *num_pages_lookup, *tmp1; - int i = 0, j = 0; - int nr_contig_chunks, loop_nr_contig_chunks; - int remaining_nr_contig_chunks, nr_lookup; - int err, map_err; - - map_err = scif_map_window(ep->remote_dev, window); - if (map_err) - dev_err(&ep->remote_dev->sdev->dev, - "%s %d map_err %d\n", __func__, __LINE__, map_err); - remaining_nr_contig_chunks = window->nr_contig_chunks; - nr_contig_chunks = window->nr_contig_chunks; -retry: - /* Wait for a SCIF_ALLOC_GNT/REJ message */ - err = wait_event_timeout(alloc->allocwq, - alloc->state != OP_IN_PROGRESS, - SCIF_NODE_ALIVE_TIMEOUT); - mutex_lock(&ep->rma_info.rma_lock); - /* Synchronize with the thread waking up allocwq */ - mutex_unlock(&ep->rma_info.rma_lock); - if (!err && scifdev_alive(ep)) - goto retry; - - if (!err) - err = -ENODEV; - - if (err > 0) - err = 0; - else - return err; - - /* Bail out. The remote end rejected this request */ - if (alloc->state == OP_FAILED) - return -ENOMEM; - - if (map_err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, map_err); - msg.uop = SCIF_FREE_VIRT; - msg.src = ep->port; - msg.payload[0] = ep->remote_ep; - msg.payload[1] = window->alloc_handle.vaddr; - msg.payload[2] = (u64)window; - msg.payload[3] = SCIF_REGISTER; - spin_lock(&ep->lock); - if (ep->state == SCIFEP_CONNECTED) - err = _scif_nodeqp_send(ep->remote_dev, &msg); - else - err = -ENOTCONN; - spin_unlock(&ep->lock); - return err; - } - - remote_window = scif_ioremap(alloc->phys_addr, sizeof(*window), - ep->remote_dev); - - /* Compute the number of lookup entries. 21 == 2MB Shift */ - nr_lookup = ALIGN(nr_contig_chunks, SCIF_NR_ADDR_IN_PAGE) - >> ilog2(SCIF_NR_ADDR_IN_PAGE); - - dma_phys_lookup = - scif_ioremap(remote_window->dma_addr_lookup.offset, - nr_lookup * - sizeof(*remote_window->dma_addr_lookup.lookup), - ep->remote_dev); - num_pages_lookup = - scif_ioremap(remote_window->num_pages_lookup.offset, - nr_lookup * - sizeof(*remote_window->num_pages_lookup.lookup), - ep->remote_dev); - - while (remaining_nr_contig_chunks) { - loop_nr_contig_chunks = min_t(int, remaining_nr_contig_chunks, - (int)SCIF_NR_ADDR_IN_PAGE); - /* #1/2 - Copy physical addresses over to the remote side */ - - /* #2/2 - Copy DMA addresses (addresses that are fed into the - * DMA engine) We transfer bus addresses which are then - * converted into a MIC physical address on the remote - * side if it is a MIC, if the remote node is a mgmt node we - * transfer the MIC physical address - */ - tmp = scif_ioremap(dma_phys_lookup[j], - loop_nr_contig_chunks * - sizeof(*window->dma_addr), - ep->remote_dev); - tmp1 = scif_ioremap(num_pages_lookup[j], - loop_nr_contig_chunks * - sizeof(*window->num_pages), - ep->remote_dev); - if (scif_is_mgmt_node()) { - memcpy_toio((void __force __iomem *)tmp, - &window->dma_addr[i], loop_nr_contig_chunks - * sizeof(*window->dma_addr)); - memcpy_toio((void __force __iomem *)tmp1, - &window->num_pages[i], loop_nr_contig_chunks - * sizeof(*window->num_pages)); - } else { - if (scifdev_is_p2p(ep->remote_dev)) { - /* - * add remote node's base address for this node - * to convert it into a MIC address - */ - int m; - dma_addr_t dma_addr; - - for (m = 0; m < loop_nr_contig_chunks; m++) { - dma_addr = window->dma_addr[i + m] + - ep->remote_dev->base_addr; - writeq(dma_addr, - (void __force __iomem *)&tmp[m]); - } - memcpy_toio((void __force __iomem *)tmp1, - &window->num_pages[i], - loop_nr_contig_chunks - * sizeof(*window->num_pages)); - } else { - /* Mgmt node or loopback - transfer DMA - * addresses as is, this is the same as a - * MIC physical address (we use the dma_addr - * and not the phys_addr array since the - * phys_addr is only setup if there is a mmap() - * request from the mgmt node) - */ - memcpy_toio((void __force __iomem *)tmp, - &window->dma_addr[i], - loop_nr_contig_chunks * - sizeof(*window->dma_addr)); - memcpy_toio((void __force __iomem *)tmp1, - &window->num_pages[i], - loop_nr_contig_chunks * - sizeof(*window->num_pages)); - } - } - remaining_nr_contig_chunks -= loop_nr_contig_chunks; - i += loop_nr_contig_chunks; - j++; - scif_iounmap(tmp, loop_nr_contig_chunks * - sizeof(*window->dma_addr), ep->remote_dev); - scif_iounmap(tmp1, loop_nr_contig_chunks * - sizeof(*window->num_pages), ep->remote_dev); - } - - /* Prepare the remote window for the peer */ - remote_window->peer_window = (u64)window; - remote_window->offset = window->offset; - remote_window->prot = window->prot; - remote_window->nr_contig_chunks = nr_contig_chunks; - remote_window->ep = ep->remote_ep; - scif_iounmap(num_pages_lookup, - nr_lookup * - sizeof(*remote_window->num_pages_lookup.lookup), - ep->remote_dev); - scif_iounmap(dma_phys_lookup, - nr_lookup * - sizeof(*remote_window->dma_addr_lookup.lookup), - ep->remote_dev); - scif_iounmap(remote_window, sizeof(*remote_window), ep->remote_dev); - window->peer_window = alloc->vaddr; - return err; -} - -/** - * scif_send_scif_register: - * @ep: end point - * @window: self registration window - * - * Send a SCIF_REGISTER message if EP is connected and wait for a - * SCIF_REGISTER_(N)ACK message else send a SCIF_FREE_VIRT - * message so that the peer can free its remote window allocated earlier. - */ -static int scif_send_scif_register(struct scif_endpt *ep, - struct scif_window *window) -{ - int err = 0; - struct scifmsg msg; - - msg.src = ep->port; - msg.payload[0] = ep->remote_ep; - msg.payload[1] = window->alloc_handle.vaddr; - msg.payload[2] = (u64)window; - spin_lock(&ep->lock); - if (ep->state == SCIFEP_CONNECTED) { - msg.uop = SCIF_REGISTER; - window->reg_state = OP_IN_PROGRESS; - err = _scif_nodeqp_send(ep->remote_dev, &msg); - spin_unlock(&ep->lock); - if (!err) { -retry: - /* Wait for a SCIF_REGISTER_(N)ACK message */ - err = wait_event_timeout(window->regwq, - window->reg_state != - OP_IN_PROGRESS, - SCIF_NODE_ALIVE_TIMEOUT); - if (!err && scifdev_alive(ep)) - goto retry; - err = !err ? -ENODEV : 0; - if (window->reg_state == OP_FAILED) - err = -ENOTCONN; - } - } else { - msg.uop = SCIF_FREE_VIRT; - msg.payload[3] = SCIF_REGISTER; - err = _scif_nodeqp_send(ep->remote_dev, &msg); - spin_unlock(&ep->lock); - if (!err) - err = -ENOTCONN; - } - return err; -} - -/** - * scif_get_window_offset: - * @ep: end point descriptor - * @flags: flags - * @offset: offset hint - * @num_pages: number of pages - * @out_offset: computed offset returned by reference. - * - * Compute/Claim a new offset for this EP. - */ -int scif_get_window_offset(struct scif_endpt *ep, int flags, s64 offset, - int num_pages, s64 *out_offset) -{ - s64 page_index; - struct iova *iova_ptr; - int err = 0; - - if (flags & SCIF_MAP_FIXED) { - page_index = SCIF_IOVA_PFN(offset); - iova_ptr = reserve_iova(&ep->rma_info.iovad, page_index, - page_index + num_pages - 1); - if (!iova_ptr) - err = -EADDRINUSE; - } else { - iova_ptr = alloc_iova(&ep->rma_info.iovad, num_pages, - SCIF_DMA_63BIT_PFN - 1, 0); - if (!iova_ptr) - err = -ENOMEM; - } - if (!err) - *out_offset = (iova_ptr->pfn_lo) << PAGE_SHIFT; - return err; -} - -/** - * scif_free_window_offset: - * @ep: end point descriptor - * @window: registration window - * @offset: Offset to be freed - * - * Free offset for this EP. The callee is supposed to grab - * the RMA mutex before calling this API. - */ -void scif_free_window_offset(struct scif_endpt *ep, - struct scif_window *window, s64 offset) -{ - if ((window && !window->offset_freed) || !window) { - free_iova(&ep->rma_info.iovad, offset >> PAGE_SHIFT); - if (window) - window->offset_freed = true; - } -} - -/** - * scif_alloc_req: Respond to SCIF_ALLOC_REQ interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * Remote side is requesting a memory allocation. - */ -void scif_alloc_req(struct scif_dev *scifdev, struct scifmsg *msg) -{ - int err; - struct scif_window *window = NULL; - int nr_pages = msg->payload[1]; - - window = scif_create_remote_window(scifdev, nr_pages); - if (!window) { - err = -ENOMEM; - goto error; - } - - /* The peer's allocation request is granted */ - msg->uop = SCIF_ALLOC_GNT; - msg->payload[0] = (u64)window; - msg->payload[1] = window->mapped_offset; - err = scif_nodeqp_send(scifdev, msg); - if (err) - scif_destroy_remote_window(window); - return; -error: - /* The peer's allocation request is rejected */ - dev_err(&scifdev->sdev->dev, - "%s %d error %d alloc_ptr %p nr_pages 0x%x\n", - __func__, __LINE__, err, window, nr_pages); - msg->uop = SCIF_ALLOC_REJ; - scif_nodeqp_send(scifdev, msg); -} - -/** - * scif_alloc_gnt_rej: Respond to SCIF_ALLOC_GNT/REJ interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * Remote side responded to a memory allocation. - */ -void scif_alloc_gnt_rej(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_allocmsg *handle = (struct scif_allocmsg *)msg->payload[2]; - struct scif_window *window = container_of(handle, struct scif_window, - alloc_handle); - struct scif_endpt *ep = (struct scif_endpt *)window->ep; - - mutex_lock(&ep->rma_info.rma_lock); - handle->vaddr = msg->payload[0]; - handle->phys_addr = msg->payload[1]; - if (msg->uop == SCIF_ALLOC_GNT) - handle->state = OP_COMPLETED; - else - handle->state = OP_FAILED; - wake_up(&handle->allocwq); - mutex_unlock(&ep->rma_info.rma_lock); -} - -/** - * scif_free_virt: Respond to SCIF_FREE_VIRT interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * Free up memory kmalloc'd earlier. - */ -void scif_free_virt(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_window *window = (struct scif_window *)msg->payload[1]; - - scif_destroy_remote_window(window); -} - -static void -scif_fixup_aper_base(struct scif_dev *dev, struct scif_window *window) -{ - int j; - struct scif_hw_dev *sdev = dev->sdev; - phys_addr_t apt_base = 0; - - /* - * Add the aperture base if the DMA address is not card relative - * since the DMA addresses need to be an offset into the bar - */ - if (!scifdev_self(dev) && window->type == SCIF_WINDOW_PEER && - sdev->aper && !sdev->card_rel_da) - apt_base = sdev->aper->pa; - else - return; - - for (j = 0; j < window->nr_contig_chunks; j++) { - if (window->num_pages[j]) - window->dma_addr[j] += apt_base; - else - break; - } -} - -/** - * scif_recv_reg: Respond to SCIF_REGISTER interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * Update remote window list with a new registered window. - */ -void scif_recv_reg(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_endpt *ep = (struct scif_endpt *)msg->payload[0]; - struct scif_window *window = - (struct scif_window *)msg->payload[1]; - - mutex_lock(&ep->rma_info.rma_lock); - spin_lock(&ep->lock); - if (ep->state == SCIFEP_CONNECTED) { - msg->uop = SCIF_REGISTER_ACK; - scif_nodeqp_send(ep->remote_dev, msg); - scif_fixup_aper_base(ep->remote_dev, window); - /* No further failures expected. Insert new window */ - scif_insert_window(window, &ep->rma_info.remote_reg_list); - } else { - msg->uop = SCIF_REGISTER_NACK; - scif_nodeqp_send(ep->remote_dev, msg); - } - spin_unlock(&ep->lock); - mutex_unlock(&ep->rma_info.rma_lock); - /* free up any lookup resources now that page lists are transferred */ - scif_destroy_remote_lookup(ep->remote_dev, window); - /* - * We could not insert the window but we need to - * destroy the window. - */ - if (msg->uop == SCIF_REGISTER_NACK) - scif_destroy_remote_window(window); -} - -/** - * scif_recv_unreg: Respond to SCIF_UNREGISTER interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * Remove window from remote registration list; - */ -void scif_recv_unreg(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_rma_req req; - struct scif_window *window = NULL; - struct scif_window *recv_window = - (struct scif_window *)msg->payload[0]; - struct scif_endpt *ep; - int del_window = 0; - - ep = (struct scif_endpt *)recv_window->ep; - req.out_window = &window; - req.offset = recv_window->offset; - req.prot = 0; - req.nr_bytes = recv_window->nr_pages << PAGE_SHIFT; - req.type = SCIF_WINDOW_FULL; - req.head = &ep->rma_info.remote_reg_list; - msg->payload[0] = ep->remote_ep; - - mutex_lock(&ep->rma_info.rma_lock); - /* Does a valid window exist? */ - if (scif_query_window(&req)) { - dev_err(&scifdev->sdev->dev, - "%s %d -ENXIO\n", __func__, __LINE__); - msg->uop = SCIF_UNREGISTER_ACK; - goto error; - } - if (window) { - if (window->ref_count) - scif_put_window(window, window->nr_pages); - else - dev_err(&scifdev->sdev->dev, - "%s %d ref count should be +ve\n", - __func__, __LINE__); - window->unreg_state = OP_COMPLETED; - if (!window->ref_count) { - msg->uop = SCIF_UNREGISTER_ACK; - atomic_inc(&ep->rma_info.tw_refcount); - ep->rma_info.async_list_del = 1; - list_del_init(&window->list); - del_window = 1; - } else { - /* NACK! There are valid references to this window */ - msg->uop = SCIF_UNREGISTER_NACK; - } - } else { - /* The window did not make its way to the list at all. ACK */ - msg->uop = SCIF_UNREGISTER_ACK; - scif_destroy_remote_window(recv_window); - } -error: - mutex_unlock(&ep->rma_info.rma_lock); - if (del_window) - scif_drain_dma_intr(ep->remote_dev->sdev, - ep->rma_info.dma_chan); - scif_nodeqp_send(ep->remote_dev, msg); - if (del_window) - scif_queue_for_cleanup(window, &scif_info.rma); -} - -/** - * scif_recv_reg_ack: Respond to SCIF_REGISTER_ACK interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * Wake up the window waiting to complete registration. - */ -void scif_recv_reg_ack(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_window *window = - (struct scif_window *)msg->payload[2]; - struct scif_endpt *ep = (struct scif_endpt *)window->ep; - - mutex_lock(&ep->rma_info.rma_lock); - window->reg_state = OP_COMPLETED; - wake_up(&window->regwq); - mutex_unlock(&ep->rma_info.rma_lock); -} - -/** - * scif_recv_reg_nack: Respond to SCIF_REGISTER_NACK interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * Wake up the window waiting to inform it that registration - * cannot be completed. - */ -void scif_recv_reg_nack(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_window *window = - (struct scif_window *)msg->payload[2]; - struct scif_endpt *ep = (struct scif_endpt *)window->ep; - - mutex_lock(&ep->rma_info.rma_lock); - window->reg_state = OP_FAILED; - wake_up(&window->regwq); - mutex_unlock(&ep->rma_info.rma_lock); -} - -/** - * scif_recv_unreg_ack: Respond to SCIF_UNREGISTER_ACK interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * Wake up the window waiting to complete unregistration. - */ -void scif_recv_unreg_ack(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_window *window = - (struct scif_window *)msg->payload[1]; - struct scif_endpt *ep = (struct scif_endpt *)window->ep; - - mutex_lock(&ep->rma_info.rma_lock); - window->unreg_state = OP_COMPLETED; - wake_up(&window->unregwq); - mutex_unlock(&ep->rma_info.rma_lock); -} - -/** - * scif_recv_unreg_nack: Respond to SCIF_UNREGISTER_NACK interrupt message - * @scifdev: SCIF device - * @msg: Interrupt message - * - * Wake up the window waiting to inform it that unregistration - * cannot be completed immediately. - */ -void scif_recv_unreg_nack(struct scif_dev *scifdev, struct scifmsg *msg) -{ - struct scif_window *window = - (struct scif_window *)msg->payload[1]; - struct scif_endpt *ep = (struct scif_endpt *)window->ep; - - mutex_lock(&ep->rma_info.rma_lock); - window->unreg_state = OP_FAILED; - wake_up(&window->unregwq); - mutex_unlock(&ep->rma_info.rma_lock); -} - -int __scif_pin_pages(void *addr, size_t len, int *out_prot, - int map_flags, scif_pinned_pages_t *pages) -{ - struct scif_pinned_pages *pinned_pages; - int nr_pages, err = 0, i; - bool vmalloc_addr = false; - bool try_upgrade = false; - int prot = *out_prot; - int ulimit = 0; - struct mm_struct *mm = NULL; - - /* Unsupported flags */ - if (map_flags & ~(SCIF_MAP_KERNEL | SCIF_MAP_ULIMIT)) - return -EINVAL; - ulimit = !!(map_flags & SCIF_MAP_ULIMIT); - - /* Unsupported protection requested */ - if (prot & ~(SCIF_PROT_READ | SCIF_PROT_WRITE)) - return -EINVAL; - - /* addr/len must be page aligned. len should be non zero */ - if (!len || - (ALIGN((u64)addr, PAGE_SIZE) != (u64)addr) || - (ALIGN((u64)len, PAGE_SIZE) != (u64)len)) - return -EINVAL; - - might_sleep(); - - nr_pages = len >> PAGE_SHIFT; - - /* Allocate a set of pinned pages */ - pinned_pages = scif_create_pinned_pages(nr_pages, prot); - if (!pinned_pages) - return -ENOMEM; - - if (map_flags & SCIF_MAP_KERNEL) { - if (is_vmalloc_addr(addr)) - vmalloc_addr = true; - - for (i = 0; i < nr_pages; i++) { - if (vmalloc_addr) - pinned_pages->pages[i] = - vmalloc_to_page(addr + (i * PAGE_SIZE)); - else - pinned_pages->pages[i] = - virt_to_page(addr + (i * PAGE_SIZE)); - } - pinned_pages->nr_pages = nr_pages; - pinned_pages->map_flags = SCIF_MAP_KERNEL; - } else { - /* - * SCIF supports registration caching. If a registration has - * been requested with read only permissions, then we try - * to pin the pages with RW permissions so that a subsequent - * transfer with RW permission can hit the cache instead of - * invalidating it. If the upgrade fails with RW then we - * revert back to R permission and retry - */ - if (prot == SCIF_PROT_READ) - try_upgrade = true; - prot |= SCIF_PROT_WRITE; -retry: - mm = current->mm; - if (ulimit) { - err = __scif_check_inc_pinned_vm(mm, nr_pages); - if (err) { - pinned_pages->nr_pages = 0; - goto error_unmap; - } - } - - pinned_pages->nr_pages = pin_user_pages_fast( - (u64)addr, - nr_pages, - (prot & SCIF_PROT_WRITE) ? FOLL_WRITE : 0, - pinned_pages->pages); - if (nr_pages != pinned_pages->nr_pages) { - if (pinned_pages->nr_pages < 0) - pinned_pages->nr_pages = 0; - if (try_upgrade) { - if (ulimit) - __scif_dec_pinned_vm_lock(mm, nr_pages); - /* Roll back any pinned pages */ - unpin_user_pages(pinned_pages->pages, - pinned_pages->nr_pages); - prot &= ~SCIF_PROT_WRITE; - try_upgrade = false; - goto retry; - } - } - pinned_pages->map_flags = 0; - } - - if (pinned_pages->nr_pages < nr_pages) { - err = -EFAULT; - goto dec_pinned; - } - - *out_prot = prot; - atomic_set(&pinned_pages->ref_count, 1); - *pages = pinned_pages; - return err; -dec_pinned: - if (ulimit) - __scif_dec_pinned_vm_lock(mm, nr_pages); - /* Something went wrong! Rollback */ -error_unmap: - scif_destroy_pinned_pages(pinned_pages); - *pages = NULL; - dev_dbg(scif_info.mdev.this_device, - "%s %d err %d len 0x%lx\n", __func__, __LINE__, err, len); - return err; -} - -int scif_pin_pages(void *addr, size_t len, int prot, - int map_flags, scif_pinned_pages_t *pages) -{ - return __scif_pin_pages(addr, len, &prot, map_flags, pages); -} -EXPORT_SYMBOL_GPL(scif_pin_pages); - -int scif_unpin_pages(scif_pinned_pages_t pinned_pages) -{ - int err = 0, ret; - - if (!pinned_pages || SCIFEP_MAGIC != pinned_pages->magic) - return -EINVAL; - - ret = atomic_sub_return(1, &pinned_pages->ref_count); - if (ret < 0) { - dev_err(scif_info.mdev.this_device, - "%s %d scif_unpin_pages called without pinning? rc %d\n", - __func__, __LINE__, ret); - return -EINVAL; - } - /* - * Destroy the window if the ref count for this set of pinned - * pages has dropped to zero. If it is positive then there is - * a valid registered window which is backed by these pages and - * it will be destroyed once all such windows are unregistered. - */ - if (!ret) - err = scif_destroy_pinned_pages(pinned_pages); - - return err; -} -EXPORT_SYMBOL_GPL(scif_unpin_pages); - -static inline void -scif_insert_local_window(struct scif_window *window, struct scif_endpt *ep) -{ - mutex_lock(&ep->rma_info.rma_lock); - scif_insert_window(window, &ep->rma_info.reg_list); - mutex_unlock(&ep->rma_info.rma_lock); -} - -off_t scif_register_pinned_pages(scif_epd_t epd, - scif_pinned_pages_t pinned_pages, - off_t offset, int map_flags) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - s64 computed_offset; - struct scif_window *window; - int err; - size_t len; - struct device *spdev; - - /* Unsupported flags */ - if (map_flags & ~SCIF_MAP_FIXED) - return -EINVAL; - - len = pinned_pages->nr_pages << PAGE_SHIFT; - - /* - * Offset is not page aligned/negative or offset+len - * wraps around with SCIF_MAP_FIXED. - */ - if ((map_flags & SCIF_MAP_FIXED) && - ((ALIGN(offset, PAGE_SIZE) != offset) || - (offset < 0) || - (len > LONG_MAX - offset))) - return -EINVAL; - - might_sleep(); - - err = scif_verify_epd(ep); - if (err) - return err; - /* - * It is an error to pass pinned_pages to scif_register_pinned_pages() - * after calling scif_unpin_pages(). - */ - if (!atomic_add_unless(&pinned_pages->ref_count, 1, 0)) - return -EINVAL; - - /* Compute the offset for this registration */ - err = scif_get_window_offset(ep, map_flags, offset, - len, &computed_offset); - if (err) { - atomic_sub(1, &pinned_pages->ref_count); - return err; - } - - /* Allocate and prepare self registration window */ - window = scif_create_window(ep, pinned_pages->nr_pages, - computed_offset, false); - if (!window) { - atomic_sub(1, &pinned_pages->ref_count); - scif_free_window_offset(ep, NULL, computed_offset); - return -ENOMEM; - } - - window->pinned_pages = pinned_pages; - window->nr_pages = pinned_pages->nr_pages; - window->prot = pinned_pages->prot; - - spdev = scif_get_peer_dev(ep->remote_dev); - if (IS_ERR(spdev)) { - err = PTR_ERR(spdev); - scif_destroy_window(ep, window); - return err; - } - err = scif_send_alloc_request(ep, window); - if (err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); - goto error_unmap; - } - - /* Prepare the remote registration window */ - err = scif_prep_remote_window(ep, window); - if (err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); - goto error_unmap; - } - - /* Tell the peer about the new window */ - err = scif_send_scif_register(ep, window); - if (err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); - goto error_unmap; - } - - scif_put_peer_dev(spdev); - /* No further failures expected. Insert new window */ - scif_insert_local_window(window, ep); - return computed_offset; -error_unmap: - scif_destroy_window(ep, window); - scif_put_peer_dev(spdev); - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); - return err; -} -EXPORT_SYMBOL_GPL(scif_register_pinned_pages); - -off_t scif_register(scif_epd_t epd, void *addr, size_t len, off_t offset, - int prot, int map_flags) -{ - scif_pinned_pages_t pinned_pages; - off_t err; - struct scif_endpt *ep = (struct scif_endpt *)epd; - s64 computed_offset; - struct scif_window *window; - struct mm_struct *mm = NULL; - struct device *spdev; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI register: ep %p addr %p len 0x%lx offset 0x%lx prot 0x%x map_flags 0x%x\n", - epd, addr, len, offset, prot, map_flags); - /* Unsupported flags */ - if (map_flags & ~(SCIF_MAP_FIXED | SCIF_MAP_KERNEL)) - return -EINVAL; - - /* - * Offset is not page aligned/negative or offset+len - * wraps around with SCIF_MAP_FIXED. - */ - if ((map_flags & SCIF_MAP_FIXED) && - ((ALIGN(offset, PAGE_SIZE) != offset) || - (offset < 0) || - (len > LONG_MAX - offset))) - return -EINVAL; - - /* Unsupported protection requested */ - if (prot & ~(SCIF_PROT_READ | SCIF_PROT_WRITE)) - return -EINVAL; - - /* addr/len must be page aligned. len should be non zero */ - if (!len || (ALIGN((u64)addr, PAGE_SIZE) != (u64)addr) || - (ALIGN(len, PAGE_SIZE) != len)) - return -EINVAL; - - might_sleep(); - - err = scif_verify_epd(ep); - if (err) - return err; - - /* Compute the offset for this registration */ - err = scif_get_window_offset(ep, map_flags, offset, - len >> PAGE_SHIFT, &computed_offset); - if (err) - return err; - - spdev = scif_get_peer_dev(ep->remote_dev); - if (IS_ERR(spdev)) { - err = PTR_ERR(spdev); - scif_free_window_offset(ep, NULL, computed_offset); - return err; - } - /* Allocate and prepare self registration window */ - window = scif_create_window(ep, len >> PAGE_SHIFT, - computed_offset, false); - if (!window) { - scif_free_window_offset(ep, NULL, computed_offset); - scif_put_peer_dev(spdev); - return -ENOMEM; - } - - window->nr_pages = len >> PAGE_SHIFT; - - err = scif_send_alloc_request(ep, window); - if (err) { - scif_destroy_incomplete_window(ep, window); - scif_put_peer_dev(spdev); - return err; - } - - if (!(map_flags & SCIF_MAP_KERNEL)) { - mm = __scif_acquire_mm(); - map_flags |= SCIF_MAP_ULIMIT; - } - /* Pin down the pages */ - err = __scif_pin_pages(addr, len, &prot, - map_flags & (SCIF_MAP_KERNEL | SCIF_MAP_ULIMIT), - &pinned_pages); - if (err) { - scif_destroy_incomplete_window(ep, window); - __scif_release_mm(mm); - goto error; - } - - window->pinned_pages = pinned_pages; - window->prot = pinned_pages->prot; - window->mm = mm; - - /* Prepare the remote registration window */ - err = scif_prep_remote_window(ep, window); - if (err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %ld\n", __func__, __LINE__, err); - goto error_unmap; - } - - /* Tell the peer about the new window */ - err = scif_send_scif_register(ep, window); - if (err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %ld\n", __func__, __LINE__, err); - goto error_unmap; - } - - scif_put_peer_dev(spdev); - /* No further failures expected. Insert new window */ - scif_insert_local_window(window, ep); - dev_dbg(&ep->remote_dev->sdev->dev, - "SCIFAPI register: ep %p addr %p len 0x%lx computed_offset 0x%llx\n", - epd, addr, len, computed_offset); - return computed_offset; -error_unmap: - scif_destroy_window(ep, window); -error: - scif_put_peer_dev(spdev); - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %ld\n", __func__, __LINE__, err); - return err; -} -EXPORT_SYMBOL_GPL(scif_register); - -int -scif_unregister(scif_epd_t epd, off_t offset, size_t len) -{ - struct scif_endpt *ep = (struct scif_endpt *)epd; - struct scif_window *window = NULL; - struct scif_rma_req req; - int nr_pages, err; - struct device *spdev; - - dev_dbg(scif_info.mdev.this_device, - "SCIFAPI unregister: ep %p offset 0x%lx len 0x%lx\n", - ep, offset, len); - /* len must be page aligned. len should be non zero */ - if (!len || - (ALIGN((u64)len, PAGE_SIZE) != (u64)len)) - return -EINVAL; - - /* Offset is not page aligned or offset+len wraps around */ - if ((ALIGN(offset, PAGE_SIZE) != offset) || - (offset < 0) || - (len > LONG_MAX - offset)) - return -EINVAL; - - err = scif_verify_epd(ep); - if (err) - return err; - - might_sleep(); - nr_pages = len >> PAGE_SHIFT; - - req.out_window = &window; - req.offset = offset; - req.prot = 0; - req.nr_bytes = len; - req.type = SCIF_WINDOW_FULL; - req.head = &ep->rma_info.reg_list; - - spdev = scif_get_peer_dev(ep->remote_dev); - if (IS_ERR(spdev)) { - err = PTR_ERR(spdev); - return err; - } - mutex_lock(&ep->rma_info.rma_lock); - /* Does a valid window exist? */ - err = scif_query_window(&req); - if (err) { - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); - goto error; - } - /* Unregister all the windows in this range */ - err = scif_rma_list_unregister(window, offset, nr_pages); - if (err) - dev_err(&ep->remote_dev->sdev->dev, - "%s %d err %d\n", __func__, __LINE__, err); -error: - mutex_unlock(&ep->rma_info.rma_lock); - scif_put_peer_dev(spdev); - return err; -} -EXPORT_SYMBOL_GPL(scif_unregister); diff --git a/drivers/misc/mic/scif/scif_rma.h b/drivers/misc/mic/scif/scif_rma.h deleted file mode 100644 index 964dd0fc3657..000000000000 --- a/drivers/misc/mic/scif/scif_rma.h +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * This file is provided under a dual BSD/GPLv2 license. When using or - * redistributing this file, you may do so under either license. - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2015 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * BSD LICENSE - * - * Copyright(c) 2015 Intel Corporation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Intel SCIF driver. - * - */ -#ifndef SCIF_RMA_H -#define SCIF_RMA_H - -#include <linux/intel-iommu.h> -#include <linux/mmu_notifier.h> - -#include "../bus/scif_bus.h" - -/* If this bit is set then the mark is a remote fence mark */ -#define SCIF_REMOTE_FENCE_BIT 31 -/* Magic value used to indicate a remote fence request */ -#define SCIF_REMOTE_FENCE BIT_ULL(SCIF_REMOTE_FENCE_BIT) - -#define SCIF_MAX_UNALIGNED_BUF_SIZE (1024 * 1024ULL) -#define SCIF_KMEM_UNALIGNED_BUF_SIZE (SCIF_MAX_UNALIGNED_BUF_SIZE + \ - (L1_CACHE_BYTES << 1)) - -#define SCIF_IOVA_START_PFN (1) -#define SCIF_IOVA_PFN(addr) ((addr) >> PAGE_SHIFT) -#define SCIF_DMA_64BIT_PFN SCIF_IOVA_PFN(DMA_BIT_MASK(64)) -#define SCIF_DMA_63BIT_PFN SCIF_IOVA_PFN(DMA_BIT_MASK(63)) - -/* - * struct scif_endpt_rma_info - Per Endpoint Remote Memory Access Information - * - * @reg_list: List of registration windows for self - * @remote_reg_list: List of registration windows for peer - * @iovad: Offset generator - * @rma_lock: Synchronizes access to self/remote list and also protects the - * window from being destroyed while RMAs are in progress. - * @tc_lock: Synchronizes access to temporary cached windows list - * for SCIF Registration Caching. - * @mmn_lock: Synchronizes access to the list of MMU notifiers registered - * @tw_refcount: Keeps track of number of outstanding temporary registered - * windows created by scif_vreadfrom/scif_vwriteto which have - * not been destroyed. - * @tcw_refcount: Same as tw_refcount but for temporary cached windows - * @tcw_total_pages: Same as tcw_refcount but in terms of pages pinned - * @mmn_list: MMU notifier so that we can destroy the windows when required - * @fence_refcount: Keeps track of number of outstanding remote fence - * requests which have been received by the peer. - * @dma_chan: DMA channel used for all DMA transfers for this endpoint. - * @async_list_del: Detect asynchronous list entry deletion - * @vma_list: List of vmas with remote memory mappings - * @markwq: Wait queue used for scif_fence_mark/scif_fence_wait -*/ -struct scif_endpt_rma_info { - struct list_head reg_list; - struct list_head remote_reg_list; - struct iova_domain iovad; - struct mutex rma_lock; - spinlock_t tc_lock; - struct mutex mmn_lock; - atomic_t tw_refcount; - atomic_t tcw_refcount; - atomic_t tcw_total_pages; - struct list_head mmn_list; - atomic_t fence_refcount; - struct dma_chan *dma_chan; - int async_list_del; - struct list_head vma_list; - wait_queue_head_t markwq; -}; - -/* - * struct scif_fence_info - used for tracking fence requests - * - * @state: State of this transfer - * @wq: Fences wait on this queue - * @dma_mark: Used for storing the DMA mark - */ -struct scif_fence_info { - enum scif_msg_state state; - struct completion comp; - int dma_mark; -}; - -/* - * struct scif_remote_fence_info - used for tracking remote fence requests - * - * @msg: List of SCIF node QP fence messages - * @list: Link to list of remote fence requests - */ -struct scif_remote_fence_info { - struct scifmsg msg; - struct list_head list; -}; - -/* - * Specifies whether an RMA operation can span across partial windows, a single - * window or multiple contiguous windows. Mmaps can span across partial windows. - * Unregistration can span across complete windows. scif_get_pages() can span a - * single window. A window can also be of type self or peer. - */ -enum scif_window_type { - SCIF_WINDOW_PARTIAL, - SCIF_WINDOW_SINGLE, - SCIF_WINDOW_FULL, - SCIF_WINDOW_SELF, - SCIF_WINDOW_PEER -}; - -/* The number of physical addresses that can be stored in a PAGE. */ -#define SCIF_NR_ADDR_IN_PAGE (0x1000 >> 3) - -/* - * struct scif_rma_lookup - RMA lookup data structure for page list transfers - * - * Store an array of lookup offsets. Each offset in this array maps - * one 4K page containing 512 physical addresses i.e. 2MB. 512 such - * offsets in a 4K page will correspond to 1GB of registered address space. - - * @lookup: Array of offsets - * @offset: DMA offset of lookup array - */ -struct scif_rma_lookup { - dma_addr_t *lookup; - dma_addr_t offset; -}; - -/* - * struct scif_pinned_pages - A set of pinned pages obtained with - * scif_pin_pages() which could be part of multiple registered - * windows across different end points. - * - * @nr_pages: Number of pages which is defined as a s64 instead of an int - * to avoid sign extension with buffers >= 2GB - * @prot: read/write protections - * @map_flags: Flags specified during the pin operation - * @ref_count: Reference count bumped in terms of number of pages - * @magic: A magic value - * @pages: Array of pointers to struct pages populated with get_user_pages(..) - */ -struct scif_pinned_pages { - s64 nr_pages; - int prot; - int map_flags; - atomic_t ref_count; - u64 magic; - struct page **pages; -}; - -/* - * struct scif_status - Stores DMA status update information - * - * @src_dma_addr: Source buffer DMA address - * @val: src location for value to be written to the destination - * @ep: SCIF endpoint - */ -struct scif_status { - dma_addr_t src_dma_addr; - u64 val; - struct scif_endpt *ep; -}; - -/* - * struct scif_cb_arg - Stores the argument of the callback func - * - * @src_dma_addr: Source buffer DMA address - * @status: DMA status - * @ep: SCIF endpoint - */ -struct scif_cb_arg { - dma_addr_t src_dma_addr; - struct scif_status *status; - struct scif_endpt *ep; -}; - -/* - * struct scif_window - Registration Window for Self and Remote - * - * @nr_pages: Number of pages which is defined as a s64 instead of an int - * to avoid sign extension with buffers >= 2GB - * @nr_contig_chunks: Number of contiguous physical chunks - * @prot: read/write protections - * @ref_count: reference count in terms of number of pages - * @magic: Cookie to detect corruption - * @offset: registered offset - * @va_for_temp: va address that this window represents - * @dma_mark: Used to determine if all DMAs against the window are done - * @ep: Pointer to EP. Useful for passing EP around with messages to - avoid expensive list traversals. - * @list: link to list of windows for the endpoint - * @type: self or peer window - * @peer_window: Pointer to peer window. Useful for sending messages to peer - * without requiring an extra list traversal - * @unreg_state: unregistration state - * @offset_freed: True if the offset has been freed - * @temp: True for temporary windows created via scif_vreadfrom/scif_vwriteto - * @mm: memory descriptor for the task_struct which initiated the RMA - * @st: scatter gather table for DMA mappings with IOMMU enabled - * @pinned_pages: The set of pinned_pages backing this window - * @alloc_handle: Handle for sending ALLOC_REQ - * @regwq: Wait Queue for an registration (N)ACK - * @reg_state: Registration state - * @unregwq: Wait Queue for an unregistration (N)ACK - * @dma_addr_lookup: Lookup for physical addresses used for DMA - * @nr_lookup: Number of entries in lookup - * @mapped_offset: Offset used to map the window by the peer - * @dma_addr: Array of physical addresses used for Mgmt node & MIC initiated DMA - * @num_pages: Array specifying number of pages for each physical address - */ -struct scif_window { - s64 nr_pages; - int nr_contig_chunks; - int prot; - int ref_count; - u64 magic; - s64 offset; - unsigned long va_for_temp; - int dma_mark; - u64 ep; - struct list_head list; - enum scif_window_type type; - u64 peer_window; - enum scif_msg_state unreg_state; - bool offset_freed; - bool temp; - struct mm_struct *mm; - struct sg_table *st; - union { - struct { - struct scif_pinned_pages *pinned_pages; - struct scif_allocmsg alloc_handle; - wait_queue_head_t regwq; - enum scif_msg_state reg_state; - wait_queue_head_t unregwq; - }; - struct { - struct scif_rma_lookup dma_addr_lookup; - struct scif_rma_lookup num_pages_lookup; - int nr_lookup; - dma_addr_t mapped_offset; - }; - }; - dma_addr_t *dma_addr; - u64 *num_pages; -} __packed; - -/* - * scif_mmu_notif - SCIF mmu notifier information - * - * @mmu_notifier ep_mmu_notifier: MMU notifier operations - * @tc_reg_list: List of temp registration windows for self - * @mm: memory descriptor for the task_struct which initiated the RMA - * @ep: SCIF endpoint - * @list: link to list of MMU notifier information - */ -struct scif_mmu_notif { -#ifdef CONFIG_MMU_NOTIFIER - struct mmu_notifier ep_mmu_notifier; -#endif - struct list_head tc_reg_list; - struct mm_struct *mm; - struct scif_endpt *ep; - struct list_head list; -}; - -enum scif_rma_dir { - SCIF_LOCAL_TO_REMOTE, - SCIF_REMOTE_TO_LOCAL -}; - -extern struct kmem_cache *unaligned_cache; -/* Initialize RMA for this EP */ -void scif_rma_ep_init(struct scif_endpt *ep); -/* Check if epd can be uninitialized */ -int scif_rma_ep_can_uninit(struct scif_endpt *ep); -/* Obtain a new offset. Callee must grab RMA lock */ -int scif_get_window_offset(struct scif_endpt *ep, int flags, - s64 offset, int nr_pages, s64 *out_offset); -/* Free offset. Callee must grab RMA lock */ -void scif_free_window_offset(struct scif_endpt *ep, - struct scif_window *window, s64 offset); -/* Create self registration window */ -struct scif_window *scif_create_window(struct scif_endpt *ep, int nr_pages, - s64 offset, bool temp); -/* Destroy self registration window.*/ -int scif_destroy_window(struct scif_endpt *ep, struct scif_window *window); -void scif_unmap_window(struct scif_dev *remote_dev, struct scif_window *window); -/* Map pages of self window to Aperture/PCI */ -int scif_map_window(struct scif_dev *remote_dev, - struct scif_window *window); -/* Unregister a self window */ -int scif_unregister_window(struct scif_window *window); -/* Destroy remote registration window */ -void -scif_destroy_remote_window(struct scif_window *window); -/* remove valid remote memory mappings from process address space */ -void scif_zap_mmaps(int node); -/* Query if any applications have remote memory mappings */ -bool scif_rma_do_apps_have_mmaps(int node); -/* Cleanup remote registration lists for zombie endpoints */ -void scif_cleanup_rma_for_zombies(int node); -/* Reserve a DMA channel for a particular endpoint */ -int scif_reserve_dma_chan(struct scif_endpt *ep); -/* Setup a DMA mark for an endpoint */ -int _scif_fence_mark(scif_epd_t epd, int *mark); -int scif_prog_signal(scif_epd_t epd, off_t offset, u64 val, - enum scif_window_type type); -void scif_alloc_req(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_alloc_gnt_rej(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_free_virt(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_reg(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_unreg(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_reg_ack(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_reg_nack(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_unreg_ack(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_unreg_nack(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_munmap(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_mark(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_mark_resp(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_wait(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_wait_resp(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_sig_local(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_sig_remote(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_recv_sig_resp(struct scif_dev *scifdev, struct scifmsg *msg); -void scif_mmu_notif_handler(struct work_struct *work); -void scif_rma_handle_remote_fences(void); -void scif_rma_destroy_windows(void); -void scif_rma_destroy_tcw_invalid(void); -int scif_drain_dma_intr(struct scif_hw_dev *sdev, struct dma_chan *chan); - -struct scif_window_iter { - s64 offset; - int index; -}; - -static inline void -scif_init_window_iter(struct scif_window *window, struct scif_window_iter *iter) -{ - iter->offset = window->offset; - iter->index = 0; -} - -dma_addr_t scif_off_to_dma_addr(struct scif_window *window, s64 off, - size_t *nr_bytes, - struct scif_window_iter *iter); -static inline -dma_addr_t __scif_off_to_dma_addr(struct scif_window *window, s64 off) -{ - return scif_off_to_dma_addr(window, off, NULL, NULL); -} - -static inline bool scif_unaligned(off_t src_offset, off_t dst_offset) -{ - src_offset = src_offset & (L1_CACHE_BYTES - 1); - dst_offset = dst_offset & (L1_CACHE_BYTES - 1); - return !(src_offset == dst_offset); -} - -/* - * scif_zalloc: - * @size: Size of the allocation request. - * - * Helper API which attempts to allocate zeroed pages via - * __get_free_pages(..) first and then falls back on - * vzalloc(..) if that fails. - */ -static inline void *scif_zalloc(size_t size) -{ - void *ret = NULL; - size_t align = ALIGN(size, PAGE_SIZE); - - if (align && get_order(align) < MAX_ORDER) - ret = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, - get_order(align)); - return ret ? ret : vzalloc(align); -} - -/* - * scif_free: - * @addr: Address to be freed. - * @size: Size of the allocation. - * Helper API which frees memory allocated via scif_zalloc(). - */ -static inline void scif_free(void *addr, size_t size) -{ - size_t align = ALIGN(size, PAGE_SIZE); - - if (is_vmalloc_addr(addr)) - vfree(addr); - else - free_pages((unsigned long)addr, get_order(align)); -} - -static inline void scif_get_window(struct scif_window *window, int nr_pages) -{ - window->ref_count += nr_pages; -} - -static inline void scif_put_window(struct scif_window *window, int nr_pages) -{ - window->ref_count -= nr_pages; -} - -static inline void scif_set_window_ref(struct scif_window *window, int nr_pages) -{ - window->ref_count = nr_pages; -} - -static inline void -scif_queue_for_cleanup(struct scif_window *window, struct list_head *list) -{ - spin_lock(&scif_info.rmalock); - list_add_tail(&window->list, list); - spin_unlock(&scif_info.rmalock); - schedule_work(&scif_info.misc_work); -} - -static inline void __scif_rma_destroy_tcw_helper(struct scif_window *window) -{ - list_del_init(&window->list); - scif_queue_for_cleanup(window, &scif_info.rma_tc); -} - -static inline bool scif_is_iommu_enabled(void) -{ -#ifdef CONFIG_INTEL_IOMMU - return intel_iommu_enabled; -#else - return false; -#endif -} -#endif /* SCIF_RMA_H */ diff --git a/drivers/misc/mic/scif/scif_rma_list.c b/drivers/misc/mic/scif/scif_rma_list.c deleted file mode 100644 index ef923ba134c8..000000000000 --- a/drivers/misc/mic/scif/scif_rma_list.c +++ /dev/null @@ -1,282 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel SCIF driver. - */ -#include "scif_main.h" -#include <linux/mmu_notifier.h> -#include <linux/highmem.h> - -/* - * scif_insert_tcw: - * - * Insert a temp window to the temp registration list sorted by va_for_temp. - * RMA lock must be held. - */ -void scif_insert_tcw(struct scif_window *window, struct list_head *head) -{ - struct scif_window *curr = NULL; - struct scif_window *prev = list_entry(head, struct scif_window, list); - struct list_head *item; - - INIT_LIST_HEAD(&window->list); - /* Compare with tail and if the entry is new tail add it to the end */ - if (!list_empty(head)) { - curr = list_entry(head->prev, struct scif_window, list); - if (curr->va_for_temp < window->va_for_temp) { - list_add_tail(&window->list, head); - return; - } - } - list_for_each(item, head) { - curr = list_entry(item, struct scif_window, list); - if (curr->va_for_temp > window->va_for_temp) - break; - prev = curr; - } - list_add(&window->list, &prev->list); -} - -/* - * scif_insert_window: - * - * Insert a window to the self registration list sorted by offset. - * RMA lock must be held. - */ -void scif_insert_window(struct scif_window *window, struct list_head *head) -{ - struct scif_window *curr = NULL, *prev = NULL; - struct list_head *item; - - INIT_LIST_HEAD(&window->list); - list_for_each(item, head) { - curr = list_entry(item, struct scif_window, list); - if (curr->offset > window->offset) - break; - prev = curr; - } - if (!prev) - list_add(&window->list, head); - else - list_add(&window->list, &prev->list); - scif_set_window_ref(window, window->nr_pages); -} - -/* - * scif_query_tcw: - * - * Query the temp cached registration list of ep for an overlapping window - * in case of permission mismatch, destroy the previous window. if permissions - * match and overlap is partial, destroy the window but return the new range - * RMA lock must be held. - */ -int scif_query_tcw(struct scif_endpt *ep, struct scif_rma_req *req) -{ - struct list_head *item, *temp, *head = req->head; - struct scif_window *window; - u64 start_va_window, start_va_req = req->va_for_temp; - u64 end_va_window, end_va_req = start_va_req + req->nr_bytes; - - if (!req->nr_bytes) - return -EINVAL; - /* - * Avoid traversing the entire list to find out that there - * is no entry that matches - */ - if (!list_empty(head)) { - window = list_last_entry(head, struct scif_window, list); - end_va_window = window->va_for_temp + - (window->nr_pages << PAGE_SHIFT); - if (start_va_req > end_va_window) - return -ENXIO; - } - list_for_each_safe(item, temp, head) { - window = list_entry(item, struct scif_window, list); - start_va_window = window->va_for_temp; - end_va_window = window->va_for_temp + - (window->nr_pages << PAGE_SHIFT); - if (start_va_req < start_va_window && - end_va_req < start_va_window) - break; - if (start_va_req >= end_va_window) - continue; - if ((window->prot & req->prot) == req->prot) { - if (start_va_req >= start_va_window && - end_va_req <= end_va_window) { - *req->out_window = window; - return 0; - } - /* expand window */ - if (start_va_req < start_va_window) { - req->nr_bytes += - start_va_window - start_va_req; - req->va_for_temp = start_va_window; - } - if (end_va_req >= end_va_window) - req->nr_bytes += end_va_window - end_va_req; - } - /* Destroy the old window to create a new one */ - __scif_rma_destroy_tcw_helper(window); - break; - } - return -ENXIO; -} - -/* - * scif_query_window: - * - * Query the registration list and check if a valid contiguous - * range of windows exist. - * RMA lock must be held. - */ -int scif_query_window(struct scif_rma_req *req) -{ - struct list_head *item; - struct scif_window *window; - s64 end_offset, offset = req->offset; - u64 tmp_min, nr_bytes_left = req->nr_bytes; - - if (!req->nr_bytes) - return -EINVAL; - - list_for_each(item, req->head) { - window = list_entry(item, struct scif_window, list); - end_offset = window->offset + - (window->nr_pages << PAGE_SHIFT); - if (offset < window->offset) - /* Offset not found! */ - return -ENXIO; - if (offset >= end_offset) - continue; - /* Check read/write protections. */ - if ((window->prot & req->prot) != req->prot) - return -EPERM; - if (nr_bytes_left == req->nr_bytes) - /* Store the first window */ - *req->out_window = window; - tmp_min = min((u64)end_offset - offset, nr_bytes_left); - nr_bytes_left -= tmp_min; - offset += tmp_min; - /* - * Range requested encompasses - * multiple windows contiguously. - */ - if (!nr_bytes_left) { - /* Done for partial window */ - if (req->type == SCIF_WINDOW_PARTIAL || - req->type == SCIF_WINDOW_SINGLE) - return 0; - /* Extra logic for full windows */ - if (offset == end_offset) - /* Spanning multiple whole windows */ - return 0; - /* Not spanning multiple whole windows */ - return -ENXIO; - } - if (req->type == SCIF_WINDOW_SINGLE) - break; - } - dev_err(scif_info.mdev.this_device, - "%s %d ENXIO\n", __func__, __LINE__); - return -ENXIO; -} - -/* - * scif_rma_list_unregister: - * - * Traverse the self registration list starting from window: - * 1) Call scif_unregister_window(..) - * RMA lock must be held. - */ -int scif_rma_list_unregister(struct scif_window *window, - s64 offset, int nr_pages) -{ - struct scif_endpt *ep = (struct scif_endpt *)window->ep; - struct list_head *head = &ep->rma_info.reg_list; - s64 end_offset; - int err = 0; - int loop_nr_pages; - struct scif_window *_window; - - list_for_each_entry_safe_from(window, _window, head, list) { - end_offset = window->offset + (window->nr_pages << PAGE_SHIFT); - loop_nr_pages = min((int)((end_offset - offset) >> PAGE_SHIFT), - nr_pages); - err = scif_unregister_window(window); - if (err) - return err; - nr_pages -= loop_nr_pages; - offset += (loop_nr_pages << PAGE_SHIFT); - if (!nr_pages) - break; - } - return 0; -} - -/* - * scif_unmap_all_window: - * - * Traverse all the windows in the self registration list and: - * 1) Delete any DMA mappings created - */ -void scif_unmap_all_windows(scif_epd_t epd) -{ - struct list_head *item, *tmp; - struct scif_window *window; - struct scif_endpt *ep = (struct scif_endpt *)epd; - struct list_head *head = &ep->rma_info.reg_list; - - mutex_lock(&ep->rma_info.rma_lock); - list_for_each_safe(item, tmp, head) { - window = list_entry(item, struct scif_window, list); - scif_unmap_window(ep->remote_dev, window); - } - mutex_unlock(&ep->rma_info.rma_lock); -} - -/* - * scif_unregister_all_window: - * - * Traverse all the windows in the self registration list and: - * 1) Call scif_unregister_window(..) - * RMA lock must be held. - */ -int scif_unregister_all_windows(scif_epd_t epd) -{ - struct list_head *item, *tmp; - struct scif_window *window; - struct scif_endpt *ep = (struct scif_endpt *)epd; - struct list_head *head = &ep->rma_info.reg_list; - int err = 0; - - mutex_lock(&ep->rma_info.rma_lock); -retry: - item = NULL; - tmp = NULL; - list_for_each_safe(item, tmp, head) { - window = list_entry(item, struct scif_window, list); - ep->rma_info.async_list_del = 0; - err = scif_unregister_window(window); - if (err) - dev_err(scif_info.mdev.this_device, - "%s %d err %d\n", - __func__, __LINE__, err); - /* - * Need to restart list traversal if there has been - * an asynchronous list entry deletion. - */ - if (READ_ONCE(ep->rma_info.async_list_del)) - goto retry; - } - mutex_unlock(&ep->rma_info.rma_lock); - if (!list_empty(&ep->rma_info.mmn_list)) { - spin_lock(&scif_info.rmalock); - list_add_tail(&ep->mmu_list, &scif_info.mmu_notif_cleanup); - spin_unlock(&scif_info.rmalock); - schedule_work(&scif_info.mmu_notif_work); - } - return err; -} diff --git a/drivers/misc/mic/scif/scif_rma_list.h b/drivers/misc/mic/scif/scif_rma_list.h deleted file mode 100644 index 0f8e0ed65614..000000000000 --- a/drivers/misc/mic/scif/scif_rma_list.h +++ /dev/null @@ -1,48 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2015 Intel Corporation. - * - * Intel SCIF driver. - */ -#ifndef SCIF_RMA_LIST_H -#define SCIF_RMA_LIST_H - -/* - * struct scif_rma_req - Self Registration list RMA Request query - * - * @out_window - Returns the window if found - * @offset: Starting offset - * @nr_bytes: number of bytes - * @prot: protection requested i.e. read or write or both - * @type: Specify single, partial or multiple windows - * @head: Head of list on which to search - * @va_for_temp: VA for searching temporary cached windows - */ -struct scif_rma_req { - struct scif_window **out_window; - union { - s64 offset; - unsigned long va_for_temp; - }; - size_t nr_bytes; - int prot; - enum scif_window_type type; - struct list_head *head; -}; - -/* Insert */ -void scif_insert_window(struct scif_window *window, struct list_head *head); -void scif_insert_tcw(struct scif_window *window, - struct list_head *head); -/* Query */ -int scif_query_window(struct scif_rma_req *request); -int scif_query_tcw(struct scif_endpt *ep, struct scif_rma_req *request); -/* Called from close to unregister all self windows */ -int scif_unregister_all_windows(scif_epd_t epd); -void scif_unmap_all_windows(scif_epd_t epd); -/* Traverse list and unregister */ -int scif_rma_list_unregister(struct scif_window *window, s64 offset, - int nr_pages); -#endif /* SCIF_RMA_LIST_H */ diff --git a/drivers/misc/mic/vop/Makefile b/drivers/misc/mic/vop/Makefile deleted file mode 100644 index 51b9b0022786..000000000000 --- a/drivers/misc/mic/vop/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile - Intel MIC Linux driver. -# Copyright(c) 2016, Intel Corporation. -# -obj-$(CONFIG_VOP) := vop.o - -vop-objs += vop_main.o -vop-objs += vop_debugfs.o -vop-objs += vop_vringh.o diff --git a/drivers/misc/mic/vop/vop_debugfs.c b/drivers/misc/mic/vop/vop_debugfs.c deleted file mode 100644 index 9d4f175f4dd1..000000000000 --- a/drivers/misc/mic/vop/vop_debugfs.c +++ /dev/null @@ -1,184 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2016 Intel Corporation. - * - * Intel Virtio Over PCIe (VOP) driver. - */ -#include <linux/debugfs.h> -#include <linux/seq_file.h> - -#include "vop_main.h" - -static int vop_dp_show(struct seq_file *s, void *pos) -{ - struct mic_device_desc *d; - struct mic_device_ctrl *dc; - struct mic_vqconfig *vqconfig; - __u32 *features; - __u8 *config; - struct vop_info *vi = s->private; - struct vop_device *vpdev = vi->vpdev; - struct mic_bootparam *bootparam = vpdev->hw_ops->get_dp(vpdev); - int j, k; - - seq_printf(s, "Bootparam: magic 0x%x\n", - bootparam->magic); - seq_printf(s, "Bootparam: h2c_config_db %d\n", - bootparam->h2c_config_db); - seq_printf(s, "Bootparam: node_id %d\n", - bootparam->node_id); - seq_printf(s, "Bootparam: c2h_scif_db %d\n", - bootparam->c2h_scif_db); - seq_printf(s, "Bootparam: h2c_scif_db %d\n", - bootparam->h2c_scif_db); - seq_printf(s, "Bootparam: scif_host_dma_addr 0x%llx\n", - bootparam->scif_host_dma_addr); - seq_printf(s, "Bootparam: scif_card_dma_addr 0x%llx\n", - bootparam->scif_card_dma_addr); - - for (j = sizeof(*bootparam); - j < MIC_DP_SIZE; j += mic_total_desc_size(d)) { - d = (void *)bootparam + j; - dc = (void *)d + mic_aligned_desc_size(d); - - /* end of list */ - if (d->type == 0) - break; - - if (d->type == -1) - continue; - - seq_printf(s, "Type %d ", d->type); - seq_printf(s, "Num VQ %d ", d->num_vq); - seq_printf(s, "Feature Len %d\n", d->feature_len); - seq_printf(s, "Config Len %d ", d->config_len); - seq_printf(s, "Shutdown Status %d\n", d->status); - - for (k = 0; k < d->num_vq; k++) { - vqconfig = mic_vq_config(d) + k; - seq_printf(s, "vqconfig[%d]: ", k); - seq_printf(s, "address 0x%llx ", - vqconfig->address); - seq_printf(s, "num %d ", vqconfig->num); - seq_printf(s, "used address 0x%llx\n", - vqconfig->used_address); - } - - features = (__u32 *)mic_vq_features(d); - seq_printf(s, "Features: Host 0x%x ", features[0]); - seq_printf(s, "Guest 0x%x\n", features[1]); - - config = mic_vq_configspace(d); - for (k = 0; k < d->config_len; k++) - seq_printf(s, "config[%d]=%d\n", k, config[k]); - - seq_puts(s, "Device control:\n"); - seq_printf(s, "Config Change %d ", dc->config_change); - seq_printf(s, "Vdev reset %d\n", dc->vdev_reset); - seq_printf(s, "Guest Ack %d ", dc->guest_ack); - seq_printf(s, "Host ack %d\n", dc->host_ack); - seq_printf(s, "Used address updated %d ", - dc->used_address_updated); - seq_printf(s, "Vdev 0x%llx\n", dc->vdev); - seq_printf(s, "c2h doorbell %d ", dc->c2h_vdev_db); - seq_printf(s, "h2c doorbell %d\n", dc->h2c_vdev_db); - } - schedule_work(&vi->hotplug_work); - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(vop_dp); - -static int vop_vdev_info_show(struct seq_file *s, void *unused) -{ - struct vop_info *vi = s->private; - struct list_head *pos, *tmp; - struct vop_vdev *vdev; - int i, j; - - mutex_lock(&vi->vop_mutex); - list_for_each_safe(pos, tmp, &vi->vdev_list) { - vdev = list_entry(pos, struct vop_vdev, list); - seq_printf(s, "VDEV type %d state %s in %ld out %ld in_dma %ld out_dma %ld\n", - vdev->virtio_id, - vop_vdevup(vdev) ? "UP" : "DOWN", - vdev->in_bytes, - vdev->out_bytes, - vdev->in_bytes_dma, - vdev->out_bytes_dma); - for (i = 0; i < MIC_MAX_VRINGS; i++) { - struct vring_desc *desc; - struct vring_avail *avail; - struct vring_used *used; - struct vop_vringh *vvr = &vdev->vvr[i]; - struct vringh *vrh = &vvr->vrh; - int num = vrh->vring.num; - - if (!num) - continue; - desc = vrh->vring.desc; - seq_printf(s, "vring i %d avail_idx %d", - i, vvr->vring.info->avail_idx & (num - 1)); - seq_printf(s, " vring i %d avail_idx %d\n", - i, vvr->vring.info->avail_idx); - seq_printf(s, "vrh i %d weak_barriers %d", - i, vrh->weak_barriers); - seq_printf(s, " last_avail_idx %d last_used_idx %d", - vrh->last_avail_idx, vrh->last_used_idx); - seq_printf(s, " completed %d\n", vrh->completed); - for (j = 0; j < num; j++) { - seq_printf(s, "desc[%d] addr 0x%llx len %d", - j, desc->addr, desc->len); - seq_printf(s, " flags 0x%x next %d\n", - desc->flags, desc->next); - desc++; - } - avail = vrh->vring.avail; - seq_printf(s, "avail flags 0x%x idx %d\n", - vringh16_to_cpu(vrh, avail->flags), - vringh16_to_cpu(vrh, - avail->idx) & (num - 1)); - seq_printf(s, "avail flags 0x%x idx %d\n", - vringh16_to_cpu(vrh, avail->flags), - vringh16_to_cpu(vrh, avail->idx)); - for (j = 0; j < num; j++) - seq_printf(s, "avail ring[%d] %d\n", - j, avail->ring[j]); - used = vrh->vring.used; - seq_printf(s, "used flags 0x%x idx %d\n", - vringh16_to_cpu(vrh, used->flags), - vringh16_to_cpu(vrh, used->idx) & (num - 1)); - seq_printf(s, "used flags 0x%x idx %d\n", - vringh16_to_cpu(vrh, used->flags), - vringh16_to_cpu(vrh, used->idx)); - for (j = 0; j < num; j++) - seq_printf(s, "used ring[%d] id %d len %d\n", - j, vringh32_to_cpu(vrh, - used->ring[j].id), - vringh32_to_cpu(vrh, - used->ring[j].len)); - } - } - mutex_unlock(&vi->vop_mutex); - - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(vop_vdev_info); - -void vop_init_debugfs(struct vop_info *vi) -{ - char name[16]; - - snprintf(name, sizeof(name), "%s%d", KBUILD_MODNAME, vi->vpdev->dnode); - vi->dbg = debugfs_create_dir(name, NULL); - debugfs_create_file("dp", 0444, vi->dbg, vi, &vop_dp_fops); - debugfs_create_file("vdev_info", 0444, vi->dbg, vi, &vop_vdev_info_fops); -} - -void vop_exit_debugfs(struct vop_info *vi) -{ - debugfs_remove_recursive(vi->dbg); -} diff --git a/drivers/misc/mic/vop/vop_main.c b/drivers/misc/mic/vop/vop_main.c deleted file mode 100644 index 714b94f42d38..000000000000 --- a/drivers/misc/mic/vop/vop_main.c +++ /dev/null @@ -1,784 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2016 Intel Corporation. - * - * Adapted from: - * - * virtio for kvm on s390 - * - * Copyright IBM Corp. 2008 - * - * Author(s): Christian Borntraeger <[email protected]> - * - * Intel Virtio Over PCIe (VOP) driver. - */ -#include <linux/delay.h> -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/dma-mapping.h> -#include <linux/io-64-nonatomic-lo-hi.h> - -#include "vop_main.h" - -#define VOP_MAX_VRINGS 4 - -/* - * _vop_vdev - Allocated per virtio device instance injected by the peer. - * - * @vdev: Virtio device - * @desc: Virtio device page descriptor - * @dc: Virtio device control - * @vpdev: VOP device which is the parent for this virtio device - * @vr: Buffer for accessing the VRING - * @used_virt: Virtual address of used ring - * @used: DMA address of used ring - * @used_size: Size of the used buffer - * @reset_done: Track whether VOP reset is complete - * @virtio_cookie: Cookie returned upon requesting a interrupt - * @c2h_vdev_db: The doorbell used by the guest to interrupt the host - * @h2c_vdev_db: The doorbell used by the host to interrupt the guest - * @dnode: The destination node - */ -struct _vop_vdev { - struct virtio_device vdev; - struct mic_device_desc __iomem *desc; - struct mic_device_ctrl __iomem *dc; - struct vop_device *vpdev; - void __iomem *vr[VOP_MAX_VRINGS]; - void *used_virt[VOP_MAX_VRINGS]; - dma_addr_t used[VOP_MAX_VRINGS]; - int used_size[VOP_MAX_VRINGS]; - struct completion reset_done; - struct mic_irq *virtio_cookie; - int c2h_vdev_db; - int h2c_vdev_db; - int dnode; -}; - -#define to_vopvdev(vd) container_of(vd, struct _vop_vdev, vdev) - -#define _vop_aligned_desc_size(d) __mic_align(_vop_desc_size(d), 8) - -/* Helper API to obtain the parent of the virtio device */ -static inline struct device *_vop_dev(struct _vop_vdev *vdev) -{ - return vdev->vdev.dev.parent; -} - -static inline unsigned _vop_desc_size(struct mic_device_desc __iomem *desc) -{ - return sizeof(*desc) - + ioread8(&desc->num_vq) * sizeof(struct mic_vqconfig) - + ioread8(&desc->feature_len) * 2 - + ioread8(&desc->config_len); -} - -static inline struct mic_vqconfig __iomem * -_vop_vq_config(struct mic_device_desc __iomem *desc) -{ - return (struct mic_vqconfig __iomem *)(desc + 1); -} - -static inline u8 __iomem * -_vop_vq_features(struct mic_device_desc __iomem *desc) -{ - return (u8 __iomem *)(_vop_vq_config(desc) + ioread8(&desc->num_vq)); -} - -static inline u8 __iomem * -_vop_vq_configspace(struct mic_device_desc __iomem *desc) -{ - return _vop_vq_features(desc) + ioread8(&desc->feature_len) * 2; -} - -static inline unsigned -_vop_total_desc_size(struct mic_device_desc __iomem *desc) -{ - return _vop_aligned_desc_size(desc) + sizeof(struct mic_device_ctrl); -} - -/* This gets the device's feature bits. */ -static u64 vop_get_features(struct virtio_device *vdev) -{ - unsigned int i, bits; - u64 features = 0; - struct mic_device_desc __iomem *desc = to_vopvdev(vdev)->desc; - u8 __iomem *in_features = _vop_vq_features(desc); - int feature_len = ioread8(&desc->feature_len); - - bits = min_t(unsigned, feature_len, sizeof(vdev->features)) * 8; - for (i = 0; i < bits; i++) - if (ioread8(&in_features[i / 8]) & (BIT(i % 8))) - features |= BIT_ULL(i); - - return features; -} - -static void vop_transport_features(struct virtio_device *vdev) -{ - /* - * Packed ring isn't enabled on virtio_vop for now, - * because virtio_vop uses vring_new_virtqueue() which - * creates virtio rings on preallocated memory. - */ - __virtio_clear_bit(vdev, VIRTIO_F_RING_PACKED); - __virtio_set_bit(vdev, VIRTIO_F_ACCESS_PLATFORM); -} - -static int vop_finalize_features(struct virtio_device *vdev) -{ - unsigned int i, bits; - struct mic_device_desc __iomem *desc = to_vopvdev(vdev)->desc; - u8 feature_len = ioread8(&desc->feature_len); - /* Second half of bitmap is features we accept. */ - u8 __iomem *out_features = - _vop_vq_features(desc) + feature_len; - - /* Give virtio_ring a chance to accept features. */ - vring_transport_features(vdev); - - /* Give virtio_vop a chance to accept features. */ - vop_transport_features(vdev); - - memset_io(out_features, 0, feature_len); - bits = min_t(unsigned, feature_len, - sizeof(vdev->features)) * 8; - for (i = 0; i < bits; i++) { - if (__virtio_test_bit(vdev, i)) - iowrite8(ioread8(&out_features[i / 8]) | (1 << (i % 8)), - &out_features[i / 8]); - } - return 0; -} - -/* - * Reading and writing elements in config space - */ -static void vop_get(struct virtio_device *vdev, unsigned int offset, - void *buf, unsigned len) -{ - struct mic_device_desc __iomem *desc = to_vopvdev(vdev)->desc; - - if (offset + len > ioread8(&desc->config_len)) - return; - memcpy_fromio(buf, _vop_vq_configspace(desc) + offset, len); -} - -static void vop_set(struct virtio_device *vdev, unsigned int offset, - const void *buf, unsigned len) -{ - struct mic_device_desc __iomem *desc = to_vopvdev(vdev)->desc; - - if (offset + len > ioread8(&desc->config_len)) - return; - memcpy_toio(_vop_vq_configspace(desc) + offset, buf, len); -} - -/* - * The operations to get and set the status word just access the status - * field of the device descriptor. set_status also interrupts the host - * to tell about status changes. - */ -static u8 vop_get_status(struct virtio_device *vdev) -{ - return ioread8(&to_vopvdev(vdev)->desc->status); -} - -static void vop_set_status(struct virtio_device *dev, u8 status) -{ - struct _vop_vdev *vdev = to_vopvdev(dev); - struct vop_device *vpdev = vdev->vpdev; - - if (!status) - return; - iowrite8(status, &vdev->desc->status); - vpdev->hw_ops->send_intr(vpdev, vdev->c2h_vdev_db); -} - -/* Inform host on a virtio device reset and wait for ack from host */ -static void vop_reset_inform_host(struct virtio_device *dev) -{ - struct _vop_vdev *vdev = to_vopvdev(dev); - struct mic_device_ctrl __iomem *dc = vdev->dc; - struct vop_device *vpdev = vdev->vpdev; - int retry; - - iowrite8(0, &dc->host_ack); - iowrite8(1, &dc->vdev_reset); - vpdev->hw_ops->send_intr(vpdev, vdev->c2h_vdev_db); - - /* Wait till host completes all card accesses and acks the reset */ - for (retry = 100; retry--;) { - if (ioread8(&dc->host_ack)) - break; - msleep(100); - } - - dev_dbg(_vop_dev(vdev), "%s: retry: %d\n", __func__, retry); - - /* Reset status to 0 in case we timed out */ - iowrite8(0, &vdev->desc->status); -} - -static void vop_reset(struct virtio_device *dev) -{ - struct _vop_vdev *vdev = to_vopvdev(dev); - - dev_dbg(_vop_dev(vdev), "%s: virtio id %d\n", - __func__, dev->id.device); - - vop_reset_inform_host(dev); - complete_all(&vdev->reset_done); -} - -/* - * The virtio_ring code calls this API when it wants to notify the Host. - */ -static bool vop_notify(struct virtqueue *vq) -{ - struct _vop_vdev *vdev = vq->priv; - struct vop_device *vpdev = vdev->vpdev; - - vpdev->hw_ops->send_intr(vpdev, vdev->c2h_vdev_db); - return true; -} - -static void vop_del_vq(struct virtqueue *vq, int n) -{ - struct _vop_vdev *vdev = to_vopvdev(vq->vdev); - struct vop_device *vpdev = vdev->vpdev; - - dma_unmap_single(&vpdev->dev, vdev->used[n], - vdev->used_size[n], DMA_BIDIRECTIONAL); - free_pages((unsigned long)vdev->used_virt[n], - get_order(vdev->used_size[n])); - vring_del_virtqueue(vq); - vpdev->hw_ops->unmap(vpdev, vdev->vr[n]); - vdev->vr[n] = NULL; -} - -static void vop_del_vqs(struct virtio_device *dev) -{ - struct _vop_vdev *vdev = to_vopvdev(dev); - struct virtqueue *vq, *n; - int idx = 0; - - dev_dbg(_vop_dev(vdev), "%s\n", __func__); - - list_for_each_entry_safe(vq, n, &dev->vqs, list) - vop_del_vq(vq, idx++); -} - -static struct virtqueue *vop_new_virtqueue(unsigned int index, - unsigned int num, - struct virtio_device *vdev, - bool context, - void *pages, - bool (*notify)(struct virtqueue *vq), - void (*callback)(struct virtqueue *vq), - const char *name, - void *used) -{ - bool weak_barriers = false; - struct vring vring; - - vring_init(&vring, num, pages, MIC_VIRTIO_RING_ALIGN); - vring.used = used; - - return __vring_new_virtqueue(index, vring, vdev, weak_barriers, context, - notify, callback, name); -} - -/* - * This routine will assign vring's allocated in host/io memory. Code in - * virtio_ring.c however continues to access this io memory as if it were local - * memory without io accessors. - */ -static struct virtqueue *vop_find_vq(struct virtio_device *dev, - unsigned index, - void (*callback)(struct virtqueue *vq), - const char *name, bool ctx) -{ - struct _vop_vdev *vdev = to_vopvdev(dev); - struct vop_device *vpdev = vdev->vpdev; - struct mic_vqconfig __iomem *vqconfig; - struct mic_vqconfig config; - struct virtqueue *vq; - void __iomem *va; - struct _mic_vring_info __iomem *info; - void *used; - int vr_size, _vr_size, err, magic; - u8 type = ioread8(&vdev->desc->type); - - if (index >= ioread8(&vdev->desc->num_vq)) - return ERR_PTR(-ENOENT); - - if (!name) - return ERR_PTR(-ENOENT); - - /* First assign the vring's allocated in host memory */ - vqconfig = _vop_vq_config(vdev->desc) + index; - memcpy_fromio(&config, vqconfig, sizeof(config)); - _vr_size = round_up(vring_size(le16_to_cpu(config.num), MIC_VIRTIO_RING_ALIGN), 4); - vr_size = PAGE_ALIGN(_vr_size + sizeof(struct _mic_vring_info)); - va = vpdev->hw_ops->remap(vpdev, le64_to_cpu(config.address), vr_size); - if (!va) - return ERR_PTR(-ENOMEM); - vdev->vr[index] = va; - memset_io(va, 0x0, _vr_size); - - info = va + _vr_size; - magic = ioread32(&info->magic); - - if (WARN(magic != MIC_MAGIC + type + index, "magic mismatch")) { - err = -EIO; - goto unmap; - } - - vdev->used_size[index] = PAGE_ALIGN(sizeof(__u16) * 3 + - sizeof(struct vring_used_elem) * - le16_to_cpu(config.num)); - used = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, - get_order(vdev->used_size[index])); - vdev->used_virt[index] = used; - if (!used) { - err = -ENOMEM; - dev_err(_vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, err); - goto unmap; - } - - vq = vop_new_virtqueue(index, le16_to_cpu(config.num), dev, ctx, - (void __force *)va, vop_notify, callback, - name, used); - if (!vq) { - err = -ENOMEM; - goto free_used; - } - - vdev->used[index] = dma_map_single(&vpdev->dev, used, - vdev->used_size[index], - DMA_BIDIRECTIONAL); - if (dma_mapping_error(&vpdev->dev, vdev->used[index])) { - err = -ENOMEM; - dev_err(_vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, err); - goto del_vq; - } - writeq(vdev->used[index], &vqconfig->used_address); - - vq->priv = vdev; - return vq; -del_vq: - vring_del_virtqueue(vq); -free_used: - free_pages((unsigned long)used, - get_order(vdev->used_size[index])); -unmap: - vpdev->hw_ops->unmap(vpdev, vdev->vr[index]); - return ERR_PTR(err); -} - -static int vop_find_vqs(struct virtio_device *dev, unsigned nvqs, - struct virtqueue *vqs[], - vq_callback_t *callbacks[], - const char * const names[], const bool *ctx, - struct irq_affinity *desc) -{ - struct _vop_vdev *vdev = to_vopvdev(dev); - struct vop_device *vpdev = vdev->vpdev; - struct mic_device_ctrl __iomem *dc = vdev->dc; - int i, err, retry, queue_idx = 0; - - /* We must have this many virtqueues. */ - if (nvqs > ioread8(&vdev->desc->num_vq)) - return -ENOENT; - - for (i = 0; i < nvqs; ++i) { - if (!names[i]) { - vqs[i] = NULL; - continue; - } - - dev_dbg(_vop_dev(vdev), "%s: %d: %s\n", - __func__, i, names[i]); - vqs[i] = vop_find_vq(dev, queue_idx++, callbacks[i], names[i], - ctx ? ctx[i] : false); - if (IS_ERR(vqs[i])) { - err = PTR_ERR(vqs[i]); - goto error; - } - } - - iowrite8(1, &dc->used_address_updated); - /* - * Send an interrupt to the host to inform it that used - * rings have been re-assigned. - */ - vpdev->hw_ops->send_intr(vpdev, vdev->c2h_vdev_db); - for (retry = 100; --retry;) { - if (!ioread8(&dc->used_address_updated)) - break; - msleep(100); - } - - dev_dbg(_vop_dev(vdev), "%s: retry: %d\n", __func__, retry); - if (!retry) { - err = -ENODEV; - goto error; - } - - return 0; -error: - vop_del_vqs(dev); - return err; -} - -/* - * The config ops structure as defined by virtio config - */ -static const struct virtio_config_ops vop_vq_config_ops = { - .get_features = vop_get_features, - .finalize_features = vop_finalize_features, - .get = vop_get, - .set = vop_set, - .get_status = vop_get_status, - .set_status = vop_set_status, - .reset = vop_reset, - .find_vqs = vop_find_vqs, - .del_vqs = vop_del_vqs, -}; - -static irqreturn_t vop_virtio_intr_handler(int irq, void *data) -{ - struct _vop_vdev *vdev = data; - struct vop_device *vpdev = vdev->vpdev; - struct virtqueue *vq; - - vpdev->hw_ops->ack_interrupt(vpdev, vdev->h2c_vdev_db); - list_for_each_entry(vq, &vdev->vdev.vqs, list) - vring_interrupt(0, vq); - - return IRQ_HANDLED; -} - -static void vop_virtio_release_dev(struct device *_d) -{ - struct virtio_device *vdev = - container_of(_d, struct virtio_device, dev); - struct _vop_vdev *vop_vdev = - container_of(vdev, struct _vop_vdev, vdev); - - kfree(vop_vdev); -} - -/* - * adds a new device and register it with virtio - * appropriate drivers are loaded by the device model - */ -static int _vop_add_device(struct mic_device_desc __iomem *d, - unsigned int offset, struct vop_device *vpdev, - int dnode) -{ - struct _vop_vdev *vdev, *reg_dev = NULL; - int ret; - u8 type = ioread8(&d->type); - - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); - if (!vdev) - return -ENOMEM; - - vdev->vpdev = vpdev; - vdev->vdev.dev.parent = &vpdev->dev; - vdev->vdev.dev.release = vop_virtio_release_dev; - vdev->vdev.id.device = type; - vdev->vdev.config = &vop_vq_config_ops; - vdev->desc = d; - vdev->dc = (void __iomem *)d + _vop_aligned_desc_size(d); - vdev->dnode = dnode; - vdev->vdev.priv = (void *)(unsigned long)dnode; - init_completion(&vdev->reset_done); - - vdev->h2c_vdev_db = vpdev->hw_ops->next_db(vpdev); - vdev->virtio_cookie = vpdev->hw_ops->request_irq(vpdev, - vop_virtio_intr_handler, "virtio intr", - vdev, vdev->h2c_vdev_db); - if (IS_ERR(vdev->virtio_cookie)) { - ret = PTR_ERR(vdev->virtio_cookie); - goto kfree; - } - iowrite8((u8)vdev->h2c_vdev_db, &vdev->dc->h2c_vdev_db); - vdev->c2h_vdev_db = ioread8(&vdev->dc->c2h_vdev_db); - - ret = register_virtio_device(&vdev->vdev); - reg_dev = vdev; - if (ret) { - dev_err(_vop_dev(vdev), - "Failed to register vop device %u type %u\n", - offset, type); - goto free_irq; - } - writeq((unsigned long)vdev, &vdev->dc->vdev); - dev_dbg(_vop_dev(vdev), "%s: registered vop device %u type %u vdev %p\n", - __func__, offset, type, vdev); - - return 0; - -free_irq: - vpdev->hw_ops->free_irq(vpdev, vdev->virtio_cookie, vdev); -kfree: - if (reg_dev) - put_device(&vdev->vdev.dev); - else - kfree(vdev); - return ret; -} - -/* - * match for a vop device with a specific desc pointer - */ -static int vop_match_desc(struct device *dev, void *data) -{ - struct virtio_device *_dev = dev_to_virtio(dev); - struct _vop_vdev *vdev = to_vopvdev(_dev); - - return vdev->desc == (void __iomem *)data; -} - -static struct _vop_vdev *vop_dc_to_vdev(struct mic_device_ctrl __iomem *dc) -{ - return (struct _vop_vdev *)(unsigned long)readq(&dc->vdev); -} - -static void _vop_handle_config_change(struct mic_device_desc __iomem *d, - unsigned int offset, - struct vop_device *vpdev) -{ - struct mic_device_ctrl __iomem *dc - = (void __iomem *)d + _vop_aligned_desc_size(d); - struct _vop_vdev *vdev = vop_dc_to_vdev(dc); - - if (ioread8(&dc->config_change) != MIC_VIRTIO_PARAM_CONFIG_CHANGED) - return; - - dev_dbg(&vpdev->dev, "%s %d\n", __func__, __LINE__); - virtio_config_changed(&vdev->vdev); - iowrite8(1, &dc->guest_ack); -} - -/* - * removes a virtio device if a hot remove event has been - * requested by the host. - */ -static int _vop_remove_device(struct mic_device_desc __iomem *d, - unsigned int offset, struct vop_device *vpdev) -{ - struct mic_device_ctrl __iomem *dc - = (void __iomem *)d + _vop_aligned_desc_size(d); - struct _vop_vdev *vdev = vop_dc_to_vdev(dc); - u8 status; - int ret = -1; - - if (ioread8(&dc->config_change) == MIC_VIRTIO_PARAM_DEV_REMOVE) { - struct device *dev = get_device(&vdev->vdev.dev); - - dev_dbg(&vpdev->dev, - "%s %d config_change %d type %d vdev %p\n", - __func__, __LINE__, - ioread8(&dc->config_change), ioread8(&d->type), vdev); - status = ioread8(&d->status); - reinit_completion(&vdev->reset_done); - unregister_virtio_device(&vdev->vdev); - vpdev->hw_ops->free_irq(vpdev, vdev->virtio_cookie, vdev); - iowrite8(-1, &dc->h2c_vdev_db); - if (status & VIRTIO_CONFIG_S_DRIVER_OK) - wait_for_completion(&vdev->reset_done); - put_device(dev); - iowrite8(1, &dc->guest_ack); - dev_dbg(&vpdev->dev, "%s %d guest_ack %d\n", - __func__, __LINE__, ioread8(&dc->guest_ack)); - iowrite8(-1, &d->type); - ret = 0; - } - return ret; -} - -#define REMOVE_DEVICES true - -static void _vop_scan_devices(void __iomem *dp, struct vop_device *vpdev, - bool remove, int dnode) -{ - s8 type; - unsigned int i; - struct mic_device_desc __iomem *d; - struct mic_device_ctrl __iomem *dc; - struct device *dev; - - for (i = sizeof(struct mic_bootparam); - i < MIC_DP_SIZE; i += _vop_total_desc_size(d)) { - d = dp + i; - dc = (void __iomem *)d + _vop_aligned_desc_size(d); - /* - * This read barrier is paired with the corresponding write - * barrier on the host which is inserted before adding or - * removing a virtio device descriptor, by updating the type. - */ - rmb(); - type = ioread8(&d->type); - - /* end of list */ - if (type == 0) - break; - - if (type == -1) - continue; - - /* device already exists */ - dev = device_find_child(&vpdev->dev, (void __force *)d, - vop_match_desc); - if (dev) { - if (remove) - iowrite8(MIC_VIRTIO_PARAM_DEV_REMOVE, - &dc->config_change); - put_device(dev); - _vop_handle_config_change(d, i, vpdev); - _vop_remove_device(d, i, vpdev); - if (remove) { - iowrite8(0, &dc->config_change); - iowrite8(0, &dc->guest_ack); - } - continue; - } - - /* new device */ - dev_dbg(&vpdev->dev, "%s %d Adding new virtio device %p\n", - __func__, __LINE__, d); - if (!remove) - _vop_add_device(d, i, vpdev, dnode); - } -} - -static void vop_scan_devices(struct vop_info *vi, - struct vop_device *vpdev, bool remove) -{ - void __iomem *dp = vpdev->hw_ops->get_remote_dp(vpdev); - - if (!dp) - return; - mutex_lock(&vi->vop_mutex); - _vop_scan_devices(dp, vpdev, remove, vpdev->dnode); - mutex_unlock(&vi->vop_mutex); -} - -/* - * vop_hotplug_device tries to find changes in the device page. - */ -static void vop_hotplug_devices(struct work_struct *work) -{ - struct vop_info *vi = container_of(work, struct vop_info, - hotplug_work); - - vop_scan_devices(vi, vi->vpdev, !REMOVE_DEVICES); -} - -/* - * Interrupt handler for hot plug/config changes etc. - */ -static irqreturn_t vop_extint_handler(int irq, void *data) -{ - struct vop_info *vi = data; - struct mic_bootparam __iomem *bp; - struct vop_device *vpdev = vi->vpdev; - - bp = vpdev->hw_ops->get_remote_dp(vpdev); - dev_dbg(&vpdev->dev, "%s %d hotplug work\n", - __func__, __LINE__); - vpdev->hw_ops->ack_interrupt(vpdev, ioread8(&bp->h2c_config_db)); - schedule_work(&vi->hotplug_work); - return IRQ_HANDLED; -} - -static int vop_driver_probe(struct vop_device *vpdev) -{ - struct vop_info *vi; - int rc; - - vi = kzalloc(sizeof(*vi), GFP_KERNEL); - if (!vi) { - rc = -ENOMEM; - goto exit; - } - dev_set_drvdata(&vpdev->dev, vi); - vi->vpdev = vpdev; - - mutex_init(&vi->vop_mutex); - INIT_WORK(&vi->hotplug_work, vop_hotplug_devices); - if (vpdev->dnode) { - rc = vop_host_init(vi); - if (rc < 0) - goto free; - } else { - struct mic_bootparam __iomem *bootparam; - - vop_scan_devices(vi, vpdev, !REMOVE_DEVICES); - - vi->h2c_config_db = vpdev->hw_ops->next_db(vpdev); - vi->cookie = vpdev->hw_ops->request_irq(vpdev, - vop_extint_handler, - "virtio_config_intr", - vi, vi->h2c_config_db); - if (IS_ERR(vi->cookie)) { - rc = PTR_ERR(vi->cookie); - goto free; - } - bootparam = vpdev->hw_ops->get_remote_dp(vpdev); - iowrite8(vi->h2c_config_db, &bootparam->h2c_config_db); - } - vop_init_debugfs(vi); - return 0; -free: - kfree(vi); -exit: - return rc; -} - -static void vop_driver_remove(struct vop_device *vpdev) -{ - struct vop_info *vi = dev_get_drvdata(&vpdev->dev); - - if (vpdev->dnode) { - vop_host_uninit(vi); - } else { - struct mic_bootparam __iomem *bootparam = - vpdev->hw_ops->get_remote_dp(vpdev); - if (bootparam) - iowrite8(-1, &bootparam->h2c_config_db); - vpdev->hw_ops->free_irq(vpdev, vi->cookie, vi); - flush_work(&vi->hotplug_work); - vop_scan_devices(vi, vpdev, REMOVE_DEVICES); - } - vop_exit_debugfs(vi); - kfree(vi); -} - -static const struct vop_device_id id_table[] = { - { VOP_DEV_TRNSP, VOP_DEV_ANY_ID }, - { 0 }, -}; - -static struct vop_driver vop_driver = { - .driver.name = KBUILD_MODNAME, - .driver.owner = THIS_MODULE, - .id_table = id_table, - .probe = vop_driver_probe, - .remove = vop_driver_remove, -}; - -module_vop_driver(vop_driver); - -MODULE_DEVICE_TABLE(mbus, id_table); -MODULE_AUTHOR("Intel Corporation"); -MODULE_DESCRIPTION("Intel(R) Virtio Over PCIe (VOP) driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/mic/vop/vop_main.h b/drivers/misc/mic/vop/vop_main.h deleted file mode 100644 index 2451d9218137..000000000000 --- a/drivers/misc/mic/vop/vop_main.h +++ /dev/null @@ -1,158 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2016 Intel Corporation. - * - * Intel Virtio Over PCIe (VOP) driver. - */ -#ifndef _VOP_MAIN_H_ -#define _VOP_MAIN_H_ - -#include <linux/vringh.h> -#include <linux/virtio_config.h> -#include <linux/virtio.h> -#include <linux/miscdevice.h> - -#include <linux/mic_common.h> -#include "../common/mic_dev.h" - -#include "../bus/vop_bus.h" - -/* - * Note on endianness. - * 1. Host can be both BE or LE - * 2. Guest/card is LE. Host uses le_to_cpu to access desc/avail - * rings and ioreadXX/iowriteXX to access used ring. - * 3. Device page exposed by host to guest contains LE values. Guest - * accesses these using ioreadXX/iowriteXX etc. This way in general we - * obey the virtio spec according to which guest works with native - * endianness and host is aware of guest endianness and does all - * required endianness conversion. - * 4. Data provided from user space to guest (in ADD_DEVICE and - * CONFIG_CHANGE ioctl's) is not interpreted by the driver and should be - * in guest endianness. - */ - -/* - * vop_info - Allocated per invocation of VOP probe - * - * @vpdev: VOP device - * @hotplug_work: Handle virtio device creation, deletion and configuration - * @cookie: Cookie received upon requesting a virtio configuration interrupt - * @h2c_config_db: The doorbell used by the peer to indicate a config change - * @vdev_list: List of "active" virtio devices injected in the peer node - * @vop_mutex: Synchronize access to the device page as well as serialize - * creation/deletion of virtio devices on the peer node - * @dp: Peer device page information - * @dbg: Debugfs entry - * @dma_ch: The DMA channel used by this transport for data transfers. - * @name: Name for this transport used in misc device creation. - * @miscdev: The misc device registered. - */ -struct vop_info { - struct vop_device *vpdev; - struct work_struct hotplug_work; - struct mic_irq *cookie; - int h2c_config_db; - struct list_head vdev_list; - struct mutex vop_mutex; - void __iomem *dp; - struct dentry *dbg; - struct dma_chan *dma_ch; - char name[16]; - struct miscdevice miscdev; -}; - -/** - * struct vop_vringh - Virtio ring host information. - * - * @vring: The VOP vring used for setting up user space mappings. - * @vrh: The host VRINGH used for accessing the card vrings. - * @riov: The VRINGH read kernel IOV. - * @wiov: The VRINGH write kernel IOV. - * @head: The VRINGH head index address passed to vringh_getdesc_kern(..). - * @vr_mutex: Mutex for synchronizing access to the VRING. - * @buf: Temporary kernel buffer used to copy in/out data - * from/to the card via DMA. - * @buf_da: dma address of buf. - * @vdev: Back pointer to VOP virtio device for vringh_notify(..). - */ -struct vop_vringh { - struct mic_vring vring; - struct vringh vrh; - struct vringh_kiov riov; - struct vringh_kiov wiov; - u16 head; - struct mutex vr_mutex; - void *buf; - dma_addr_t buf_da; - struct vop_vdev *vdev; -}; - -/** - * struct vop_vdev - Host information for a card Virtio device. - * - * @virtio_id - Virtio device id. - * @waitq - Waitqueue to allow ring3 apps to poll. - * @vpdev - pointer to VOP bus device. - * @poll_wake - Used for waking up threads blocked in poll. - * @out_bytes - Debug stats for number of bytes copied from host to card. - * @in_bytes - Debug stats for number of bytes copied from card to host. - * @out_bytes_dma - Debug stats for number of bytes copied from host to card - * using DMA. - * @in_bytes_dma - Debug stats for number of bytes copied from card to host - * using DMA. - * @tx_len_unaligned - Debug stats for number of bytes copied to the card where - * the transfer length did not have the required DMA alignment. - * @tx_dst_unaligned - Debug stats for number of bytes copied where the - * destination address on the card did not have the required DMA alignment. - * @vvr - Store per VRING data structures. - * @virtio_bh_work - Work struct used to schedule virtio bottom half handling. - * @dd - Virtio device descriptor. - * @dc - Virtio device control fields. - * @list - List of Virtio devices. - * @virtio_db - The doorbell used by the card to interrupt the host. - * @virtio_cookie - The cookie returned while requesting interrupts. - * @vi: Transport information. - * @vdev_mutex: Mutex synchronizing virtio device injection, - * removal and data transfers. - * @destroy: Track if a virtio device is being destroyed. - * @deleted: The virtio device has been deleted. - */ -struct vop_vdev { - int virtio_id; - wait_queue_head_t waitq; - struct vop_device *vpdev; - int poll_wake; - unsigned long out_bytes; - unsigned long in_bytes; - unsigned long out_bytes_dma; - unsigned long in_bytes_dma; - unsigned long tx_len_unaligned; - unsigned long tx_dst_unaligned; - unsigned long rx_dst_unaligned; - struct vop_vringh vvr[MIC_MAX_VRINGS]; - struct work_struct virtio_bh_work; - struct mic_device_desc *dd; - struct mic_device_ctrl *dc; - struct list_head list; - int virtio_db; - struct mic_irq *virtio_cookie; - struct vop_info *vi; - struct mutex vdev_mutex; - struct completion destroy; - bool deleted; -}; - -/* Helper API to check if a virtio device is running */ -static inline bool vop_vdevup(struct vop_vdev *vdev) -{ - return !!vdev->dd->status; -} - -void vop_init_debugfs(struct vop_info *vi); -void vop_exit_debugfs(struct vop_info *vi); -int vop_host_init(struct vop_info *vi); -void vop_host_uninit(struct vop_info *vi); -#endif diff --git a/drivers/misc/mic/vop/vop_vringh.c b/drivers/misc/mic/vop/vop_vringh.c deleted file mode 100644 index 7014ffe88632..000000000000 --- a/drivers/misc/mic/vop/vop_vringh.c +++ /dev/null @@ -1,1166 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Intel MIC Platform Software Stack (MPSS) - * - * Copyright(c) 2016 Intel Corporation. - * - * Intel Virtio Over PCIe (VOP) driver. - */ -#include <linux/sched.h> -#include <linux/poll.h> -#include <linux/dma-mapping.h> - -#include <linux/mic_common.h> -#include "../common/mic_dev.h" - -#include <linux/mic_ioctl.h> -#include "vop_main.h" - -/* Helper API to obtain the VOP PCIe device */ -static inline struct device *vop_dev(struct vop_vdev *vdev) -{ - return vdev->vpdev->dev.parent; -} - -/* Helper API to check if a virtio device is initialized */ -static inline int vop_vdev_inited(struct vop_vdev *vdev) -{ - if (!vdev) - return -EINVAL; - /* Device has not been created yet */ - if (!vdev->dd || !vdev->dd->type) { - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, -EINVAL); - return -EINVAL; - } - /* Device has been removed/deleted */ - if (vdev->dd->type == -1) { - dev_dbg(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, -ENODEV); - return -ENODEV; - } - return 0; -} - -static void _vop_notify(struct vringh *vrh) -{ - struct vop_vringh *vvrh = container_of(vrh, struct vop_vringh, vrh); - struct vop_vdev *vdev = vvrh->vdev; - struct vop_device *vpdev = vdev->vpdev; - s8 db = vdev->dc->h2c_vdev_db; - - if (db != -1) - vpdev->hw_ops->send_intr(vpdev, db); -} - -static void vop_virtio_init_post(struct vop_vdev *vdev) -{ - struct mic_vqconfig *vqconfig = mic_vq_config(vdev->dd); - struct vop_device *vpdev = vdev->vpdev; - int i, used_size; - - for (i = 0; i < vdev->dd->num_vq; i++) { - used_size = PAGE_ALIGN(sizeof(u16) * 3 + - sizeof(struct vring_used_elem) * - le16_to_cpu(vqconfig->num)); - if (!le64_to_cpu(vqconfig[i].used_address)) { - dev_warn(vop_dev(vdev), "used_address zero??\n"); - continue; - } - vdev->vvr[i].vrh.vring.used = - (void __force *)vpdev->hw_ops->remap( - vpdev, - le64_to_cpu(vqconfig[i].used_address), - used_size); - } - - vdev->dc->used_address_updated = 0; - - dev_info(vop_dev(vdev), "%s: device type %d LINKUP\n", - __func__, vdev->virtio_id); -} - -static inline void vop_virtio_device_reset(struct vop_vdev *vdev) -{ - int i; - - dev_dbg(vop_dev(vdev), "%s: status %d device type %d RESET\n", - __func__, vdev->dd->status, vdev->virtio_id); - - for (i = 0; i < vdev->dd->num_vq; i++) - /* - * Avoid lockdep false positive. The + 1 is for the vop - * mutex which is held in the reset devices code path. - */ - mutex_lock_nested(&vdev->vvr[i].vr_mutex, i + 1); - - /* 0 status means "reset" */ - vdev->dd->status = 0; - vdev->dc->vdev_reset = 0; - vdev->dc->host_ack = 1; - - for (i = 0; i < vdev->dd->num_vq; i++) { - struct vringh *vrh = &vdev->vvr[i].vrh; - - vdev->vvr[i].vring.info->avail_idx = 0; - vrh->completed = 0; - vrh->last_avail_idx = 0; - vrh->last_used_idx = 0; - } - - for (i = 0; i < vdev->dd->num_vq; i++) - mutex_unlock(&vdev->vvr[i].vr_mutex); -} - -static void vop_virtio_reset_devices(struct vop_info *vi) -{ - struct list_head *pos, *tmp; - struct vop_vdev *vdev; - - list_for_each_safe(pos, tmp, &vi->vdev_list) { - vdev = list_entry(pos, struct vop_vdev, list); - vop_virtio_device_reset(vdev); - vdev->poll_wake = 1; - wake_up(&vdev->waitq); - } -} - -static void vop_bh_handler(struct work_struct *work) -{ - struct vop_vdev *vdev = container_of(work, struct vop_vdev, - virtio_bh_work); - - if (vdev->dc->used_address_updated) - vop_virtio_init_post(vdev); - - if (vdev->dc->vdev_reset) - vop_virtio_device_reset(vdev); - - vdev->poll_wake = 1; - wake_up(&vdev->waitq); -} - -static irqreturn_t _vop_virtio_intr_handler(int irq, void *data) -{ - struct vop_vdev *vdev = data; - struct vop_device *vpdev = vdev->vpdev; - - vpdev->hw_ops->ack_interrupt(vpdev, vdev->virtio_db); - schedule_work(&vdev->virtio_bh_work); - return IRQ_HANDLED; -} - -static int vop_virtio_config_change(struct vop_vdev *vdev, void *argp) -{ - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake); - int ret = 0, retry, i; - struct vop_device *vpdev = vdev->vpdev; - struct vop_info *vi = dev_get_drvdata(&vpdev->dev); - struct mic_bootparam *bootparam = vpdev->hw_ops->get_dp(vpdev); - s8 db = bootparam->h2c_config_db; - - mutex_lock(&vi->vop_mutex); - for (i = 0; i < vdev->dd->num_vq; i++) - mutex_lock_nested(&vdev->vvr[i].vr_mutex, i + 1); - - if (db == -1 || vdev->dd->type == -1) { - ret = -EIO; - goto exit; - } - - memcpy(mic_vq_configspace(vdev->dd), argp, vdev->dd->config_len); - vdev->dc->config_change = MIC_VIRTIO_PARAM_CONFIG_CHANGED; - vpdev->hw_ops->send_intr(vpdev, db); - - for (retry = 100; retry--;) { - ret = wait_event_timeout(wake, vdev->dc->guest_ack, - msecs_to_jiffies(100)); - if (ret) - break; - } - - dev_dbg(vop_dev(vdev), - "%s %d retry: %d\n", __func__, __LINE__, retry); - vdev->dc->config_change = 0; - vdev->dc->guest_ack = 0; -exit: - for (i = 0; i < vdev->dd->num_vq; i++) - mutex_unlock(&vdev->vvr[i].vr_mutex); - mutex_unlock(&vi->vop_mutex); - return ret; -} - -static int vop_copy_dp_entry(struct vop_vdev *vdev, - struct mic_device_desc *argp, __u8 *type, - struct mic_device_desc **devpage) -{ - struct vop_device *vpdev = vdev->vpdev; - struct mic_device_desc *devp; - struct mic_vqconfig *vqconfig; - int ret = 0, i; - bool slot_found = false; - - vqconfig = mic_vq_config(argp); - for (i = 0; i < argp->num_vq; i++) { - if (le16_to_cpu(vqconfig[i].num) > MIC_MAX_VRING_ENTRIES) { - ret = -EINVAL; - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, ret); - goto exit; - } - } - - /* Find the first free device page entry */ - for (i = sizeof(struct mic_bootparam); - i < MIC_DP_SIZE - mic_total_desc_size(argp); - i += mic_total_desc_size(devp)) { - devp = vpdev->hw_ops->get_dp(vpdev) + i; - if (devp->type == 0 || devp->type == -1) { - slot_found = true; - break; - } - } - if (!slot_found) { - ret = -EINVAL; - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, ret); - goto exit; - } - /* - * Save off the type before doing the memcpy. Type will be set in the - * end after completing all initialization for the new device. - */ - *type = argp->type; - argp->type = 0; - memcpy(devp, argp, mic_desc_size(argp)); - - *devpage = devp; -exit: - return ret; -} - -static void vop_init_device_ctrl(struct vop_vdev *vdev, - struct mic_device_desc *devpage) -{ - struct mic_device_ctrl *dc; - - dc = (void *)devpage + mic_aligned_desc_size(devpage); - - dc->config_change = 0; - dc->guest_ack = 0; - dc->vdev_reset = 0; - dc->host_ack = 0; - dc->used_address_updated = 0; - dc->c2h_vdev_db = -1; - dc->h2c_vdev_db = -1; - vdev->dc = dc; -} - -static int vop_virtio_add_device(struct vop_vdev *vdev, - struct mic_device_desc *argp) -{ - struct vop_info *vi = vdev->vi; - struct vop_device *vpdev = vi->vpdev; - struct mic_device_desc *dd = NULL; - struct mic_vqconfig *vqconfig; - int vr_size, i, j, ret; - u8 type = 0; - s8 db = -1; - char irqname[16]; - struct mic_bootparam *bootparam; - u16 num; - dma_addr_t vr_addr; - - bootparam = vpdev->hw_ops->get_dp(vpdev); - init_waitqueue_head(&vdev->waitq); - INIT_LIST_HEAD(&vdev->list); - vdev->vpdev = vpdev; - - ret = vop_copy_dp_entry(vdev, argp, &type, &dd); - if (ret) { - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, ret); - return ret; - } - - vop_init_device_ctrl(vdev, dd); - - vdev->dd = dd; - vdev->virtio_id = type; - vqconfig = mic_vq_config(dd); - INIT_WORK(&vdev->virtio_bh_work, vop_bh_handler); - - for (i = 0; i < dd->num_vq; i++) { - struct vop_vringh *vvr = &vdev->vvr[i]; - struct mic_vring *vr = &vdev->vvr[i].vring; - - num = le16_to_cpu(vqconfig[i].num); - mutex_init(&vvr->vr_mutex); - vr_size = PAGE_ALIGN(round_up(vring_size(num, MIC_VIRTIO_RING_ALIGN), 4) + - sizeof(struct _mic_vring_info)); - vr->va = (void *) - __get_free_pages(GFP_KERNEL | __GFP_ZERO, - get_order(vr_size)); - if (!vr->va) { - ret = -ENOMEM; - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, ret); - goto err; - } - vr->len = vr_size; - vr->info = vr->va + round_up(vring_size(num, MIC_VIRTIO_RING_ALIGN), 4); - vr->info->magic = cpu_to_le32(MIC_MAGIC + vdev->virtio_id + i); - vr_addr = dma_map_single(&vpdev->dev, vr->va, vr_size, - DMA_BIDIRECTIONAL); - if (dma_mapping_error(&vpdev->dev, vr_addr)) { - free_pages((unsigned long)vr->va, get_order(vr_size)); - ret = -ENOMEM; - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, ret); - goto err; - } - vqconfig[i].address = cpu_to_le64(vr_addr); - - vring_init(&vr->vr, num, vr->va, MIC_VIRTIO_RING_ALIGN); - ret = vringh_init_kern(&vvr->vrh, - *(u32 *)mic_vq_features(vdev->dd), - num, false, vr->vr.desc, vr->vr.avail, - vr->vr.used); - if (ret) { - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, ret); - goto err; - } - vringh_kiov_init(&vvr->riov, NULL, 0); - vringh_kiov_init(&vvr->wiov, NULL, 0); - vvr->head = USHRT_MAX; - vvr->vdev = vdev; - vvr->vrh.notify = _vop_notify; - dev_dbg(&vpdev->dev, - "%s %d index %d va %p info %p vr_size 0x%x\n", - __func__, __LINE__, i, vr->va, vr->info, vr_size); - vvr->buf = (void *)__get_free_pages(GFP_KERNEL, - get_order(VOP_INT_DMA_BUF_SIZE)); - vvr->buf_da = dma_map_single(&vpdev->dev, - vvr->buf, VOP_INT_DMA_BUF_SIZE, - DMA_BIDIRECTIONAL); - } - - snprintf(irqname, sizeof(irqname), "vop%dvirtio%d", vpdev->index, - vdev->virtio_id); - vdev->virtio_db = vpdev->hw_ops->next_db(vpdev); - vdev->virtio_cookie = vpdev->hw_ops->request_irq(vpdev, - _vop_virtio_intr_handler, irqname, vdev, - vdev->virtio_db); - if (IS_ERR(vdev->virtio_cookie)) { - ret = PTR_ERR(vdev->virtio_cookie); - dev_dbg(&vpdev->dev, "request irq failed\n"); - goto err; - } - - vdev->dc->c2h_vdev_db = vdev->virtio_db; - - /* - * Order the type update with previous stores. This write barrier - * is paired with the corresponding read barrier before the uncached - * system memory read of the type, on the card while scanning the - * device page. - */ - smp_wmb(); - dd->type = type; - argp->type = type; - - if (bootparam) { - db = bootparam->h2c_config_db; - if (db != -1) - vpdev->hw_ops->send_intr(vpdev, db); - } - dev_dbg(&vpdev->dev, "Added virtio id %d db %d\n", dd->type, db); - return 0; -err: - vqconfig = mic_vq_config(dd); - for (j = 0; j < i; j++) { - struct vop_vringh *vvr = &vdev->vvr[j]; - - dma_unmap_single(&vpdev->dev, le64_to_cpu(vqconfig[j].address), - vvr->vring.len, DMA_BIDIRECTIONAL); - free_pages((unsigned long)vvr->vring.va, - get_order(vvr->vring.len)); - } - return ret; -} - -static void vop_dev_remove(struct vop_info *pvi, struct mic_device_ctrl *devp, - struct vop_device *vpdev) -{ - struct mic_bootparam *bootparam = vpdev->hw_ops->get_dp(vpdev); - s8 db; - int ret, retry; - DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake); - - devp->config_change = MIC_VIRTIO_PARAM_DEV_REMOVE; - db = bootparam->h2c_config_db; - if (db != -1) - vpdev->hw_ops->send_intr(vpdev, db); - else - goto done; - for (retry = 15; retry--;) { - ret = wait_event_timeout(wake, devp->guest_ack, - msecs_to_jiffies(1000)); - if (ret) - break; - } -done: - devp->config_change = 0; - devp->guest_ack = 0; -} - -static void vop_virtio_del_device(struct vop_vdev *vdev) -{ - struct vop_info *vi = vdev->vi; - struct vop_device *vpdev = vdev->vpdev; - int i; - struct mic_vqconfig *vqconfig; - struct mic_bootparam *bootparam = vpdev->hw_ops->get_dp(vpdev); - - if (!bootparam) - goto skip_hot_remove; - vop_dev_remove(vi, vdev->dc, vpdev); -skip_hot_remove: - vpdev->hw_ops->free_irq(vpdev, vdev->virtio_cookie, vdev); - flush_work(&vdev->virtio_bh_work); - vqconfig = mic_vq_config(vdev->dd); - for (i = 0; i < vdev->dd->num_vq; i++) { - struct vop_vringh *vvr = &vdev->vvr[i]; - - dma_unmap_single(&vpdev->dev, - vvr->buf_da, VOP_INT_DMA_BUF_SIZE, - DMA_BIDIRECTIONAL); - free_pages((unsigned long)vvr->buf, - get_order(VOP_INT_DMA_BUF_SIZE)); - vringh_kiov_cleanup(&vvr->riov); - vringh_kiov_cleanup(&vvr->wiov); - dma_unmap_single(&vpdev->dev, le64_to_cpu(vqconfig[i].address), - vvr->vring.len, DMA_BIDIRECTIONAL); - free_pages((unsigned long)vvr->vring.va, - get_order(vvr->vring.len)); - } - /* - * Order the type update with previous stores. This write barrier - * is paired with the corresponding read barrier before the uncached - * system memory read of the type, on the card while scanning the - * device page. - */ - smp_wmb(); - vdev->dd->type = -1; -} - -/* - * vop_sync_dma - Wrapper for synchronous DMAs. - * - * @dev - The address of the pointer to the device instance used - * for DMA registration. - * @dst - destination DMA address. - * @src - source DMA address. - * @len - size of the transfer. - * - * Return DMA_SUCCESS on success - */ -static int vop_sync_dma(struct vop_vdev *vdev, dma_addr_t dst, dma_addr_t src, - size_t len) -{ - int err = 0; - struct dma_device *ddev; - struct dma_async_tx_descriptor *tx; - struct vop_info *vi = dev_get_drvdata(&vdev->vpdev->dev); - struct dma_chan *vop_ch = vi->dma_ch; - - if (!vop_ch) { - err = -EBUSY; - goto error; - } - ddev = vop_ch->device; - tx = ddev->device_prep_dma_memcpy(vop_ch, dst, src, len, - DMA_PREP_FENCE); - if (!tx) { - err = -ENOMEM; - goto error; - } else { - dma_cookie_t cookie; - - cookie = tx->tx_submit(tx); - if (dma_submit_error(cookie)) { - err = -ENOMEM; - goto error; - } - dma_async_issue_pending(vop_ch); - err = dma_sync_wait(vop_ch, cookie); - } -error: - if (err) - dev_err(&vi->vpdev->dev, "%s %d err %d\n", - __func__, __LINE__, err); - return err; -} - -#define VOP_USE_DMA true - -/* - * Initiates the copies across the PCIe bus from card memory to a user - * space buffer. When transfers are done using DMA, source/destination - * addresses and transfer length must follow the alignment requirements of - * the MIC DMA engine. - */ -static int vop_virtio_copy_to_user(struct vop_vdev *vdev, void __user *ubuf, - size_t len, u64 daddr, size_t dlen, - int vr_idx) -{ - struct vop_device *vpdev = vdev->vpdev; - void __iomem *dbuf = vpdev->hw_ops->remap(vpdev, daddr, len); - struct vop_vringh *vvr = &vdev->vvr[vr_idx]; - struct vop_info *vi = dev_get_drvdata(&vpdev->dev); - size_t dma_alignment; - bool x200; - size_t dma_offset, partlen; - int err; - - if (!VOP_USE_DMA || !vi->dma_ch) { - if (copy_to_user(ubuf, (void __force *)dbuf, len)) { - err = -EFAULT; - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, err); - goto err; - } - vdev->in_bytes += len; - err = 0; - goto err; - } - - dma_alignment = 1 << vi->dma_ch->device->copy_align; - x200 = is_dma_copy_aligned(vi->dma_ch->device, 1, 1, 1); - - dma_offset = daddr - round_down(daddr, dma_alignment); - daddr -= dma_offset; - len += dma_offset; - /* - * X100 uses DMA addresses as seen by the card so adding - * the aperture base is not required for DMA. However x200 - * requires DMA addresses to be an offset into the bar so - * add the aperture base for x200. - */ - if (x200) - daddr += vpdev->aper->pa; - while (len) { - partlen = min_t(size_t, len, VOP_INT_DMA_BUF_SIZE); - err = vop_sync_dma(vdev, vvr->buf_da, daddr, - ALIGN(partlen, dma_alignment)); - if (err) { - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, err); - goto err; - } - if (copy_to_user(ubuf, vvr->buf + dma_offset, - partlen - dma_offset)) { - err = -EFAULT; - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, err); - goto err; - } - daddr += partlen; - ubuf += partlen; - dbuf += partlen; - vdev->in_bytes_dma += partlen; - vdev->in_bytes += partlen; - len -= partlen; - dma_offset = 0; - } - err = 0; -err: - vpdev->hw_ops->unmap(vpdev, dbuf); - dev_dbg(vop_dev(vdev), - "%s: ubuf %p dbuf %p len 0x%zx vr_idx 0x%x\n", - __func__, ubuf, dbuf, len, vr_idx); - return err; -} - -/* - * Initiates copies across the PCIe bus from a user space buffer to card - * memory. When transfers are done using DMA, source/destination addresses - * and transfer length must follow the alignment requirements of the MIC - * DMA engine. - */ -static int vop_virtio_copy_from_user(struct vop_vdev *vdev, void __user *ubuf, - size_t len, u64 daddr, size_t dlen, - int vr_idx) -{ - struct vop_device *vpdev = vdev->vpdev; - void __iomem *dbuf = vpdev->hw_ops->remap(vpdev, daddr, len); - struct vop_vringh *vvr = &vdev->vvr[vr_idx]; - struct vop_info *vi = dev_get_drvdata(&vdev->vpdev->dev); - size_t dma_alignment; - bool x200; - size_t partlen; - bool dma = VOP_USE_DMA && vi->dma_ch; - int err = 0; - size_t offset = 0; - - if (dma) { - dma_alignment = 1 << vi->dma_ch->device->copy_align; - x200 = is_dma_copy_aligned(vi->dma_ch->device, 1, 1, 1); - - if (daddr & (dma_alignment - 1)) { - vdev->tx_dst_unaligned += len; - dma = false; - } else if (ALIGN(len, dma_alignment) > dlen) { - vdev->tx_len_unaligned += len; - dma = false; - } - } - - if (!dma) - goto memcpy; - - /* - * X100 uses DMA addresses as seen by the card so adding - * the aperture base is not required for DMA. However x200 - * requires DMA addresses to be an offset into the bar so - * add the aperture base for x200. - */ - if (x200) - daddr += vpdev->aper->pa; - while (len) { - partlen = min_t(size_t, len, VOP_INT_DMA_BUF_SIZE); - - if (copy_from_user(vvr->buf, ubuf, partlen)) { - err = -EFAULT; - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, err); - goto err; - } - err = vop_sync_dma(vdev, daddr, vvr->buf_da, - ALIGN(partlen, dma_alignment)); - if (err) { - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, err); - goto err; - } - daddr += partlen; - ubuf += partlen; - dbuf += partlen; - vdev->out_bytes_dma += partlen; - vdev->out_bytes += partlen; - len -= partlen; - } -memcpy: - /* - * We are copying to IO below and should ideally use something - * like copy_from_user_toio(..) if it existed. - */ - while (len) { - partlen = min_t(size_t, len, VOP_INT_DMA_BUF_SIZE); - - if (copy_from_user(vvr->buf, ubuf + offset, partlen)) { - err = -EFAULT; - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, err); - goto err; - } - memcpy_toio(dbuf + offset, vvr->buf, partlen); - offset += partlen; - vdev->out_bytes += partlen; - len -= partlen; - } - err = 0; -err: - vpdev->hw_ops->unmap(vpdev, dbuf); - dev_dbg(vop_dev(vdev), - "%s: ubuf %p dbuf %p len 0x%zx vr_idx 0x%x\n", - __func__, ubuf, dbuf, len, vr_idx); - return err; -} - -#define MIC_VRINGH_READ true - -/* Determine the total number of bytes consumed in a VRINGH KIOV */ -static inline u32 vop_vringh_iov_consumed(struct vringh_kiov *iov) -{ - int i; - u32 total = iov->consumed; - - for (i = 0; i < iov->i; i++) - total += iov->iov[i].iov_len; - return total; -} - -/* - * Traverse the VRINGH KIOV and issue the APIs to trigger the copies. - * This API is heavily based on the vringh_iov_xfer(..) implementation - * in vringh.c. The reason we cannot reuse vringh_iov_pull_kern(..) - * and vringh_iov_push_kern(..) directly is because there is no - * way to override the VRINGH xfer(..) routines as of v3.10. - */ -static int vop_vringh_copy(struct vop_vdev *vdev, struct vringh_kiov *iov, - void __user *ubuf, size_t len, bool read, int vr_idx, - size_t *out_len) -{ - int ret = 0; - size_t partlen, tot_len = 0; - - while (len && iov->i < iov->used) { - struct kvec *kiov = &iov->iov[iov->i]; - unsigned long daddr = (unsigned long)kiov->iov_base; - - partlen = min(kiov->iov_len, len); - if (read) - ret = vop_virtio_copy_to_user(vdev, ubuf, partlen, - daddr, - kiov->iov_len, - vr_idx); - else - ret = vop_virtio_copy_from_user(vdev, ubuf, partlen, - daddr, - kiov->iov_len, - vr_idx); - if (ret) { - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, ret); - break; - } - len -= partlen; - ubuf += partlen; - tot_len += partlen; - iov->consumed += partlen; - kiov->iov_len -= partlen; - kiov->iov_base += partlen; - if (!kiov->iov_len) { - /* Fix up old iov element then increment. */ - kiov->iov_len = iov->consumed; - kiov->iov_base -= iov->consumed; - - iov->consumed = 0; - iov->i++; - } - } - *out_len = tot_len; - return ret; -} - -/* - * Use the standard VRINGH infrastructure in the kernel to fetch new - * descriptors, initiate the copies and update the used ring. - */ -static int _vop_virtio_copy(struct vop_vdev *vdev, struct mic_copy_desc *copy) -{ - int ret = 0; - u32 iovcnt = copy->iovcnt; - struct iovec iov; - struct iovec __user *u_iov = copy->iov; - void __user *ubuf = NULL; - struct vop_vringh *vvr = &vdev->vvr[copy->vr_idx]; - struct vringh_kiov *riov = &vvr->riov; - struct vringh_kiov *wiov = &vvr->wiov; - struct vringh *vrh = &vvr->vrh; - u16 *head = &vvr->head; - struct mic_vring *vr = &vvr->vring; - size_t len = 0, out_len; - - copy->out_len = 0; - /* Fetch a new IOVEC if all previous elements have been processed */ - if (riov->i == riov->used && wiov->i == wiov->used) { - ret = vringh_getdesc_kern(vrh, riov, wiov, - head, GFP_KERNEL); - /* Check if there are available descriptors */ - if (ret <= 0) - return ret; - } - while (iovcnt) { - if (!len) { - /* Copy over a new iovec from user space. */ - ret = copy_from_user(&iov, u_iov, sizeof(*u_iov)); - if (ret) { - ret = -EINVAL; - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, ret); - break; - } - len = iov.iov_len; - ubuf = iov.iov_base; - } - /* Issue all the read descriptors first */ - ret = vop_vringh_copy(vdev, riov, ubuf, len, - MIC_VRINGH_READ, copy->vr_idx, &out_len); - if (ret) { - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, ret); - break; - } - len -= out_len; - ubuf += out_len; - copy->out_len += out_len; - /* Issue the write descriptors next */ - ret = vop_vringh_copy(vdev, wiov, ubuf, len, - !MIC_VRINGH_READ, copy->vr_idx, &out_len); - if (ret) { - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, ret); - break; - } - len -= out_len; - ubuf += out_len; - copy->out_len += out_len; - if (!len) { - /* One user space iovec is now completed */ - iovcnt--; - u_iov++; - } - /* Exit loop if all elements in KIOVs have been processed. */ - if (riov->i == riov->used && wiov->i == wiov->used) - break; - } - /* - * Update the used ring if a descriptor was available and some data was - * copied in/out and the user asked for a used ring update. - */ - if (*head != USHRT_MAX && copy->out_len && copy->update_used) { - u32 total = 0; - - /* Determine the total data consumed */ - total += vop_vringh_iov_consumed(riov); - total += vop_vringh_iov_consumed(wiov); - vringh_complete_kern(vrh, *head, total); - *head = USHRT_MAX; - if (vringh_need_notify_kern(vrh) > 0) - vringh_notify(vrh); - vringh_kiov_cleanup(riov); - vringh_kiov_cleanup(wiov); - /* Update avail idx for user space */ - vr->info->avail_idx = vrh->last_avail_idx; - } - return ret; -} - -static inline int vop_verify_copy_args(struct vop_vdev *vdev, - struct mic_copy_desc *copy) -{ - if (!vdev || copy->vr_idx >= vdev->dd->num_vq) - return -EINVAL; - return 0; -} - -/* Copy a specified number of virtio descriptors in a chain */ -static int vop_virtio_copy_desc(struct vop_vdev *vdev, - struct mic_copy_desc *copy) -{ - int err; - struct vop_vringh *vvr; - - err = vop_verify_copy_args(vdev, copy); - if (err) - return err; - - vvr = &vdev->vvr[copy->vr_idx]; - mutex_lock(&vvr->vr_mutex); - if (!vop_vdevup(vdev)) { - err = -ENODEV; - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, err); - goto err; - } - err = _vop_virtio_copy(vdev, copy); - if (err) { - dev_err(vop_dev(vdev), "%s %d err %d\n", - __func__, __LINE__, err); - } -err: - mutex_unlock(&vvr->vr_mutex); - return err; -} - -static int vop_open(struct inode *inode, struct file *f) -{ - struct vop_vdev *vdev; - struct vop_info *vi = container_of(f->private_data, - struct vop_info, miscdev); - - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); - if (!vdev) - return -ENOMEM; - vdev->vi = vi; - mutex_init(&vdev->vdev_mutex); - f->private_data = vdev; - init_completion(&vdev->destroy); - complete(&vdev->destroy); - return 0; -} - -static int vop_release(struct inode *inode, struct file *f) -{ - struct vop_vdev *vdev = f->private_data, *vdev_tmp; - struct vop_info *vi = vdev->vi; - struct list_head *pos, *tmp; - bool found = false; - - mutex_lock(&vdev->vdev_mutex); - if (vdev->deleted) - goto unlock; - mutex_lock(&vi->vop_mutex); - list_for_each_safe(pos, tmp, &vi->vdev_list) { - vdev_tmp = list_entry(pos, struct vop_vdev, list); - if (vdev == vdev_tmp) { - vop_virtio_del_device(vdev); - list_del(pos); - found = true; - break; - } - } - mutex_unlock(&vi->vop_mutex); -unlock: - mutex_unlock(&vdev->vdev_mutex); - if (!found) - wait_for_completion(&vdev->destroy); - f->private_data = NULL; - kfree(vdev); - return 0; -} - -static long vop_ioctl(struct file *f, unsigned int cmd, unsigned long arg) -{ - struct vop_vdev *vdev = f->private_data; - struct vop_info *vi = vdev->vi; - void __user *argp = (void __user *)arg; - int ret; - - switch (cmd) { - case MIC_VIRTIO_ADD_DEVICE: - { - struct mic_device_desc dd, *dd_config; - - if (copy_from_user(&dd, argp, sizeof(dd))) - return -EFAULT; - - if (mic_aligned_desc_size(&dd) > MIC_MAX_DESC_BLK_SIZE || - dd.num_vq > MIC_MAX_VRINGS) - return -EINVAL; - - dd_config = memdup_user(argp, mic_desc_size(&dd)); - if (IS_ERR(dd_config)) - return PTR_ERR(dd_config); - - /* Ensure desc has not changed between the two reads */ - if (memcmp(&dd, dd_config, sizeof(dd))) { - ret = -EINVAL; - goto free_ret; - } - mutex_lock(&vdev->vdev_mutex); - mutex_lock(&vi->vop_mutex); - ret = vop_virtio_add_device(vdev, dd_config); - if (ret) - goto unlock_ret; - list_add_tail(&vdev->list, &vi->vdev_list); -unlock_ret: - mutex_unlock(&vi->vop_mutex); - mutex_unlock(&vdev->vdev_mutex); -free_ret: - kfree(dd_config); - return ret; - } - case MIC_VIRTIO_COPY_DESC: - { - struct mic_copy_desc copy; - - mutex_lock(&vdev->vdev_mutex); - ret = vop_vdev_inited(vdev); - if (ret) - goto _unlock_ret; - - if (copy_from_user(©, argp, sizeof(copy))) { - ret = -EFAULT; - goto _unlock_ret; - } - - ret = vop_virtio_copy_desc(vdev, ©); - if (ret < 0) - goto _unlock_ret; - if (copy_to_user( - &((struct mic_copy_desc __user *)argp)->out_len, - ©.out_len, sizeof(copy.out_len))) - ret = -EFAULT; -_unlock_ret: - mutex_unlock(&vdev->vdev_mutex); - return ret; - } - case MIC_VIRTIO_CONFIG_CHANGE: - { - void *buf; - - mutex_lock(&vdev->vdev_mutex); - ret = vop_vdev_inited(vdev); - if (ret) - goto __unlock_ret; - buf = memdup_user(argp, vdev->dd->config_len); - if (IS_ERR(buf)) { - ret = PTR_ERR(buf); - goto __unlock_ret; - } - ret = vop_virtio_config_change(vdev, buf); - kfree(buf); -__unlock_ret: - mutex_unlock(&vdev->vdev_mutex); - return ret; - } - default: - return -ENOIOCTLCMD; - }; - return 0; -} - -/* - * We return EPOLLIN | EPOLLOUT from poll when new buffers are enqueued, and - * not when previously enqueued buffers may be available. This means that - * in the card->host (TX) path, when userspace is unblocked by poll it - * must drain all available descriptors or it can stall. - */ -static __poll_t vop_poll(struct file *f, poll_table *wait) -{ - struct vop_vdev *vdev = f->private_data; - __poll_t mask = 0; - - mutex_lock(&vdev->vdev_mutex); - if (vop_vdev_inited(vdev)) { - mask = EPOLLERR; - goto done; - } - poll_wait(f, &vdev->waitq, wait); - if (vop_vdev_inited(vdev)) { - mask = EPOLLERR; - } else if (vdev->poll_wake) { - vdev->poll_wake = 0; - mask = EPOLLIN | EPOLLOUT; - } -done: - mutex_unlock(&vdev->vdev_mutex); - return mask; -} - -static inline int -vop_query_offset(struct vop_vdev *vdev, unsigned long offset, - unsigned long *size, unsigned long *pa) -{ - struct vop_device *vpdev = vdev->vpdev; - unsigned long start = MIC_DP_SIZE; - int i; - - /* - * MMAP interface is as follows: - * offset region - * 0x0 virtio device_page - * 0x1000 first vring - * 0x1000 + size of 1st vring second vring - * .... - */ - if (!offset) { - *pa = virt_to_phys(vpdev->hw_ops->get_dp(vpdev)); - *size = MIC_DP_SIZE; - return 0; - } - - for (i = 0; i < vdev->dd->num_vq; i++) { - struct vop_vringh *vvr = &vdev->vvr[i]; - - if (offset == start) { - *pa = virt_to_phys(vvr->vring.va); - *size = vvr->vring.len; - return 0; - } - start += vvr->vring.len; - } - return -1; -} - -/* - * Maps the device page and virtio rings to user space for readonly access. - */ -static int vop_mmap(struct file *f, struct vm_area_struct *vma) -{ - struct vop_vdev *vdev = f->private_data; - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; - unsigned long pa, size = vma->vm_end - vma->vm_start, size_rem = size; - int i, err; - - err = vop_vdev_inited(vdev); - if (err) - goto ret; - if (vma->vm_flags & VM_WRITE) { - err = -EACCES; - goto ret; - } - while (size_rem) { - i = vop_query_offset(vdev, offset, &size, &pa); - if (i < 0) { - err = -EINVAL; - goto ret; - } - err = remap_pfn_range(vma, vma->vm_start + offset, - pa >> PAGE_SHIFT, size, - vma->vm_page_prot); - if (err) - goto ret; - size_rem -= size; - offset += size; - } -ret: - return err; -} - -static const struct file_operations vop_fops = { - .open = vop_open, - .release = vop_release, - .unlocked_ioctl = vop_ioctl, - .poll = vop_poll, - .mmap = vop_mmap, - .owner = THIS_MODULE, -}; - -int vop_host_init(struct vop_info *vi) -{ - int rc; - struct miscdevice *mdev; - struct vop_device *vpdev = vi->vpdev; - - INIT_LIST_HEAD(&vi->vdev_list); - vi->dma_ch = vpdev->dma_ch; - mdev = &vi->miscdev; - mdev->minor = MISC_DYNAMIC_MINOR; - snprintf(vi->name, sizeof(vi->name), "vop_virtio%d", vpdev->index); - mdev->name = vi->name; - mdev->fops = &vop_fops; - mdev->parent = &vpdev->dev; - - rc = misc_register(mdev); - if (rc) - dev_err(&vpdev->dev, "%s failed rc %d\n", __func__, rc); - return rc; -} - -void vop_host_uninit(struct vop_info *vi) -{ - struct list_head *pos, *tmp; - struct vop_vdev *vdev; - - mutex_lock(&vi->vop_mutex); - vop_virtio_reset_devices(vi); - list_for_each_safe(pos, tmp, &vi->vdev_list) { - vdev = list_entry(pos, struct vop_vdev, list); - list_del(pos); - reinit_completion(&vdev->destroy); - mutex_unlock(&vi->vop_mutex); - mutex_lock(&vdev->vdev_mutex); - vop_virtio_del_device(vdev); - vdev->deleted = true; - mutex_unlock(&vdev->vdev_mutex); - complete(&vdev->destroy); - mutex_lock(&vi->vop_mutex); - } - mutex_unlock(&vi->vop_mutex); - misc_deregister(&vi->miscdev); -} diff --git a/drivers/misc/ocxl/config.c b/drivers/misc/ocxl/config.c index 4d490b92d951..a68738f38252 100644 --- a/drivers/misc/ocxl/config.c +++ b/drivers/misc/ocxl/config.c @@ -73,7 +73,7 @@ static int find_dvsec_afu_ctrl(struct pci_dev *dev, u8 afu_idx) /** * get_function_0() - Find a related PCI device (function 0) - * @device: PCI device to match + * @dev: PCI device to match * * Returns a pointer to the related device, or null if not found */ diff --git a/drivers/misc/ocxl/context.c b/drivers/misc/ocxl/context.c index c21f65a5c762..9eb0d93b01c6 100644 --- a/drivers/misc/ocxl/context.c +++ b/drivers/misc/ocxl/context.c @@ -70,6 +70,7 @@ int ocxl_context_attach(struct ocxl_context *ctx, u64 amr, struct mm_struct *mm) { int rc; unsigned long pidr = 0; + struct pci_dev *dev; // Locks both status & tidr mutex_lock(&ctx->status_mutex); @@ -81,8 +82,9 @@ int ocxl_context_attach(struct ocxl_context *ctx, u64 amr, struct mm_struct *mm) if (mm) pidr = mm->context.id; + dev = to_pci_dev(ctx->afu->fn->dev.parent); rc = ocxl_link_add_pe(ctx->afu->fn->link, ctx->pasid, pidr, ctx->tidr, - amr, mm, xsl_fault_error, ctx); + amr, pci_dev_id(dev), mm, xsl_fault_error, ctx); if (rc) goto out; diff --git a/drivers/misc/ocxl/link.c b/drivers/misc/ocxl/link.c index fd73d3bc0eb6..ab039c115381 100644 --- a/drivers/misc/ocxl/link.c +++ b/drivers/misc/ocxl/link.c @@ -2,8 +2,10 @@ // Copyright 2017 IBM Corp. #include <linux/sched/mm.h> #include <linux/mutex.h> +#include <linux/mm.h> #include <linux/mm_types.h> #include <linux/mmu_context.h> +#include <linux/mmu_notifier.h> #include <asm/copro.h> #include <asm/pnv-ocxl.h> #include <asm/xive.h> @@ -33,6 +35,7 @@ #define SPA_PE_VALID 0x80000000 +struct ocxl_link; struct pe_data { struct mm_struct *mm; @@ -41,6 +44,8 @@ struct pe_data { /* opaque pointer to be passed to the above callback */ void *xsl_err_data; struct rcu_head rcu; + struct ocxl_link *link; + struct mmu_notifier mmu_notifier; }; struct spa { @@ -83,6 +88,8 @@ struct ocxl_link { int domain; int bus; int dev; + void __iomem *arva; /* ATSD register virtual address */ + spinlock_t atsd_lock; /* to serialize shootdowns */ atomic_t irq_available; struct spa *spa; void *platform_data; @@ -388,6 +395,7 @@ static int alloc_link(struct pci_dev *dev, int PE_mask, struct ocxl_link **out_l link->bus = dev->bus->number; link->dev = PCI_SLOT(dev->devfn); atomic_set(&link->irq_available, MAX_IRQ_PER_LINK); + spin_lock_init(&link->atsd_lock); rc = alloc_spa(dev, link); if (rc) @@ -403,6 +411,13 @@ static int alloc_link(struct pci_dev *dev, int PE_mask, struct ocxl_link **out_l if (rc) goto err_xsl_irq; + /* if link->arva is not defeined, MMIO registers are not used to + * generate TLB invalidate. PowerBus snooping is enabled. + * Otherwise, PowerBus snooping is disabled. TLB Invalidates are + * initiated using MMIO registers. + */ + pnv_ocxl_map_lpar(dev, mfspr(SPRN_LPID), 0, &link->arva); + *out_link = link; return 0; @@ -454,6 +469,11 @@ static void release_xsl(struct kref *ref) { struct ocxl_link *link = container_of(ref, struct ocxl_link, ref); + if (link->arva) { + pnv_ocxl_unmap_lpar(link->arva); + link->arva = NULL; + } + list_del(&link->list); /* call platform code before releasing data */ pnv_ocxl_spa_release(link->platform_data); @@ -470,6 +490,27 @@ void ocxl_link_release(struct pci_dev *dev, void *link_handle) } EXPORT_SYMBOL_GPL(ocxl_link_release); +static void invalidate_range(struct mmu_notifier *mn, + struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + struct pe_data *pe_data = container_of(mn, struct pe_data, mmu_notifier); + struct ocxl_link *link = pe_data->link; + unsigned long addr, pid, page_size = PAGE_SIZE; + + pid = mm->context.id; + trace_ocxl_mmu_notifier_range(start, end, pid); + + spin_lock(&link->atsd_lock); + for (addr = start; addr < end; addr += page_size) + pnv_ocxl_tlb_invalidate(link->arva, pid, addr, page_size); + spin_unlock(&link->atsd_lock); +} + +static const struct mmu_notifier_ops ocxl_mmu_notifier_ops = { + .invalidate_range = invalidate_range, +}; + static u64 calculate_cfg_state(bool kernel) { u64 state; @@ -494,7 +535,7 @@ static u64 calculate_cfg_state(bool kernel) } int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr, - u64 amr, struct mm_struct *mm, + u64 amr, u16 bdf, struct mm_struct *mm, void (*xsl_err_cb)(void *data, u64 addr, u64 dsisr), void *xsl_err_data) { @@ -526,9 +567,13 @@ int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr, pe_data->mm = mm; pe_data->xsl_err_cb = xsl_err_cb; pe_data->xsl_err_data = xsl_err_data; + pe_data->link = link; + pe_data->mmu_notifier.ops = &ocxl_mmu_notifier_ops; memset(pe, 0, sizeof(struct ocxl_process_element)); pe->config_state = cpu_to_be64(calculate_cfg_state(pidr == 0)); + pe->pasid = cpu_to_be32(pasid << (31 - 19)); + pe->bdf = cpu_to_be16(bdf); pe->lpid = cpu_to_be32(mfspr(SPRN_LPID)); pe->pid = cpu_to_be32(pidr); pe->tid = cpu_to_be32(tidr); @@ -540,8 +585,17 @@ int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr, * by the nest MMU. If we have a kernel context, TLBIs are * already global. */ - if (mm) + if (mm) { mm_context_add_copro(mm); + if (link->arva) { + /* Use MMIO registers for the TLB Invalidate + * operations. + */ + trace_ocxl_init_mmu_notifier(pasid, mm->context.id); + mmu_notifier_register(&pe_data->mmu_notifier, mm); + } + } + /* * Barrier is to make sure PE is visible in the SPA before it * is used by the device. It also helps with the global TLBI @@ -672,6 +726,18 @@ int ocxl_link_remove_pe(void *link_handle, int pasid) WARN(1, "Couldn't find pe data when removing PE\n"); } else { if (pe_data->mm) { + if (link->arva) { + trace_ocxl_release_mmu_notifier(pasid, + pe_data->mm->context.id); + mmu_notifier_unregister(&pe_data->mmu_notifier, + pe_data->mm); + spin_lock(&link->atsd_lock); + pnv_ocxl_tlb_invalidate(link->arva, + pe_data->mm->context.id, + 0ull, + PAGE_SIZE); + spin_unlock(&link->atsd_lock); + } mm_context_remove_copro(pe_data->mm); mmdrop(pe_data->mm); } diff --git a/drivers/misc/ocxl/ocxl_internal.h b/drivers/misc/ocxl/ocxl_internal.h index 0bad0a123af6..10125a22d5a5 100644 --- a/drivers/misc/ocxl/ocxl_internal.h +++ b/drivers/misc/ocxl/ocxl_internal.h @@ -84,13 +84,16 @@ struct ocxl_context { struct ocxl_process_element { __be64 config_state; - __be32 reserved1[11]; + __be32 pasid; + __be16 bdf; + __be16 reserved1; + __be32 reserved2[9]; __be32 lpid; __be32 tid; __be32 pid; - __be32 reserved2[10]; + __be32 reserved3[10]; __be64 amr; - __be32 reserved3[3]; + __be32 reserved4[3]; __be32 software_state; }; diff --git a/drivers/misc/ocxl/trace.h b/drivers/misc/ocxl/trace.h index 17e21cb2addd..a33a5094ff6c 100644 --- a/drivers/misc/ocxl/trace.h +++ b/drivers/misc/ocxl/trace.h @@ -8,6 +8,70 @@ #include <linux/tracepoint.h> + +TRACE_EVENT(ocxl_mmu_notifier_range, + TP_PROTO(unsigned long start, unsigned long end, unsigned long pidr), + TP_ARGS(start, end, pidr), + + TP_STRUCT__entry( + __field(unsigned long, start) + __field(unsigned long, end) + __field(unsigned long, pidr) + ), + + TP_fast_assign( + __entry->start = start; + __entry->end = end; + __entry->pidr = pidr; + ), + + TP_printk("start=0x%lx end=0x%lx pidr=0x%lx", + __entry->start, + __entry->end, + __entry->pidr + ) +); + +TRACE_EVENT(ocxl_init_mmu_notifier, + TP_PROTO(int pasid, unsigned long pidr), + TP_ARGS(pasid, pidr), + + TP_STRUCT__entry( + __field(int, pasid) + __field(unsigned long, pidr) + ), + + TP_fast_assign( + __entry->pasid = pasid; + __entry->pidr = pidr; + ), + + TP_printk("pasid=%d, pidr=0x%lx", + __entry->pasid, + __entry->pidr + ) +); + +TRACE_EVENT(ocxl_release_mmu_notifier, + TP_PROTO(int pasid, unsigned long pidr), + TP_ARGS(pasid, pidr), + + TP_STRUCT__entry( + __field(int, pasid) + __field(unsigned long, pidr) + ), + + TP_fast_assign( + __entry->pasid = pasid; + __entry->pidr = pidr; + ), + + TP_printk("pasid=%d, pidr=0x%lx", + __entry->pasid, + __entry->pidr + ) +); + DECLARE_EVENT_CLASS(ocxl_context, TP_PROTO(pid_t pid, void *spa, int pasid, u32 pidr, u32 tidr), TP_ARGS(pid, spa, pasid, pidr, tidr), diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c index 146ca6fb3260..eff481ce08ee 100644 --- a/drivers/misc/pci_endpoint_test.c +++ b/drivers/misc/pci_endpoint_test.c @@ -708,7 +708,7 @@ static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd, switch (cmd) { case PCITEST_BAR: bar = arg; - if (bar < 0 || bar > 5) + if (bar > BAR_5) goto ret; if (is_am654_pci_dev(pdev) && bar == BAR_0) goto ret; @@ -811,8 +811,10 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, pci_set_master(pdev); - if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) + if (!pci_endpoint_test_alloc_irq_vectors(test, irq_type)) { + err = -EINVAL; goto err_disable_irq; + } for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) { if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) { @@ -849,8 +851,10 @@ static int pci_endpoint_test_probe(struct pci_dev *pdev, goto err_ida_remove; } - if (!pci_endpoint_test_request_irq(test)) + if (!pci_endpoint_test_request_irq(test)) { + err = -EINVAL; goto err_kfree_test_name; + } misc_device = &test->miscdev; misc_device->minor = MISC_DYNAMIC_MINOR; diff --git a/drivers/misc/pvpanic.c b/drivers/misc/pvpanic.c index e16a5e51006e..951b37da5e3c 100644 --- a/drivers/misc/pvpanic.c +++ b/drivers/misc/pvpanic.c @@ -8,14 +8,14 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#include <linux/acpi.h> +#include <linux/io.h> #include <linux/kernel.h> #include <linux/kexec.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/of.h> -#include <linux/of_address.h> #include <linux/platform_device.h> #include <linux/types.h> + #include <uapi/misc/pvpanic.h> static void __iomem *base; @@ -49,101 +49,16 @@ static struct notifier_block pvpanic_panic_nb = { .priority = 1, /* let this called before broken drm_fb_helper */ }; -#ifdef CONFIG_ACPI -static int pvpanic_add(struct acpi_device *device); -static int pvpanic_remove(struct acpi_device *device); - -static const struct acpi_device_id pvpanic_device_ids[] = { - { "QEMU0001", 0 }, - { "", 0 } -}; -MODULE_DEVICE_TABLE(acpi, pvpanic_device_ids); - -static struct acpi_driver pvpanic_driver = { - .name = "pvpanic", - .class = "QEMU", - .ids = pvpanic_device_ids, - .ops = { - .add = pvpanic_add, - .remove = pvpanic_remove, - }, - .owner = THIS_MODULE, -}; - -static acpi_status -pvpanic_walk_resources(struct acpi_resource *res, void *context) -{ - struct resource r; - - if (acpi_dev_resource_io(res, &r)) { -#ifdef CONFIG_HAS_IOPORT_MAP - base = ioport_map(r.start, resource_size(&r)); - return AE_OK; -#else - return AE_ERROR; -#endif - } else if (acpi_dev_resource_memory(res, &r)) { - base = ioremap(r.start, resource_size(&r)); - return AE_OK; - } - - return AE_ERROR; -} - -static int pvpanic_add(struct acpi_device *device) -{ - int ret; - - ret = acpi_bus_get_status(device); - if (ret < 0) - return ret; - - if (!device->status.enabled || !device->status.functional) - return -ENODEV; - - acpi_walk_resources(device->handle, METHOD_NAME__CRS, - pvpanic_walk_resources, NULL); - - if (!base) - return -ENODEV; - - atomic_notifier_chain_register(&panic_notifier_list, - &pvpanic_panic_nb); - - return 0; -} - -static int pvpanic_remove(struct acpi_device *device) -{ - - atomic_notifier_chain_unregister(&panic_notifier_list, - &pvpanic_panic_nb); - iounmap(base); - - return 0; -} - -static int pvpanic_register_acpi_driver(void) -{ - return acpi_bus_register_driver(&pvpanic_driver); -} - -static void pvpanic_unregister_acpi_driver(void) -{ - acpi_bus_unregister_driver(&pvpanic_driver); -} -#else -static int pvpanic_register_acpi_driver(void) -{ - return -ENODEV; -} - -static void pvpanic_unregister_acpi_driver(void) {} -#endif - static int pvpanic_mmio_probe(struct platform_device *pdev) { - base = devm_platform_ioremap_resource(pdev, 0); + struct device *dev = &pdev->dev; + struct resource *res; + + res = platform_get_mem_or_io(pdev, 0); + if (res && resource_type(res) == IORESOURCE_IO) + base = devm_ioport_map(dev, res->start, resource_size(res)); + else + base = devm_ioremap_resource(dev, res); if (IS_ERR(base)) return PTR_ERR(base); @@ -167,30 +82,19 @@ static const struct of_device_id pvpanic_mmio_match[] = { {} }; +static const struct acpi_device_id pvpanic_device_ids[] = { + { "QEMU0001", 0 }, + { "", 0 } +}; +MODULE_DEVICE_TABLE(acpi, pvpanic_device_ids); + static struct platform_driver pvpanic_mmio_driver = { .driver = { .name = "pvpanic-mmio", .of_match_table = pvpanic_mmio_match, + .acpi_match_table = pvpanic_device_ids, }, .probe = pvpanic_mmio_probe, .remove = pvpanic_mmio_remove, }; - -static int __init pvpanic_mmio_init(void) -{ - if (acpi_disabled) - return platform_driver_register(&pvpanic_mmio_driver); - else - return pvpanic_register_acpi_driver(); -} - -static void __exit pvpanic_mmio_exit(void) -{ - if (acpi_disabled) - platform_driver_unregister(&pvpanic_mmio_driver); - else - pvpanic_unregister_acpi_driver(); -} - -module_init(pvpanic_mmio_init); -module_exit(pvpanic_mmio_exit); +module_platform_driver(pvpanic_mmio_driver); diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h index 71db60edff65..225f2bb84e39 100644 --- a/drivers/misc/sgi-xp/xpc.h +++ b/drivers/misc/sgi-xp/xpc.h @@ -634,6 +634,7 @@ extern int xpc_setup_rsvd_page(void); extern void xpc_teardown_rsvd_page(void); extern int xpc_identify_activate_IRQ_sender(void); extern int xpc_partition_disengaged(struct xpc_partition *); +extern int xpc_partition_disengaged_from_timer(struct xpc_partition *part); extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *); extern void xpc_mark_partition_inactive(struct xpc_partition *); extern void xpc_discovery(void); diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index e5244fc1dab3..84610bbcc131 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c @@ -179,7 +179,7 @@ xpc_timeout_partition_disengage(struct timer_list *t) DBUG_ON(time_is_after_jiffies(part->disengage_timeout)); - (void)xpc_partition_disengaged(part); + xpc_partition_disengaged_from_timer(part); DBUG_ON(part->disengage_timeout != 0); DBUG_ON(xpc_arch_ops.partition_engaged(XPC_PARTID(part))); diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c index 57df06820bae..1999d02923de 100644 --- a/drivers/misc/sgi-xp/xpc_partition.c +++ b/drivers/misc/sgi-xp/xpc_partition.c @@ -262,8 +262,8 @@ xpc_get_remote_rp(int nasid, unsigned long *discovered_nasids, * from us. Though we requested the remote partition to deactivate with regard * to us, we really only need to wait for the other side to disengage from us. */ -int -xpc_partition_disengaged(struct xpc_partition *part) +static int __xpc_partition_disengaged(struct xpc_partition *part, + bool from_timer) { short partid = XPC_PARTID(part); int disengaged; @@ -289,9 +289,9 @@ xpc_partition_disengaged(struct xpc_partition *part) } part->disengage_timeout = 0; - /* cancel the timer function, provided it's not us */ - if (!in_interrupt()) - del_singleshot_timer_sync(&part->disengage_timer); + /* Cancel the timer function if not called from it */ + if (!from_timer) + del_timer_sync(&part->disengage_timer); DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING && part->act_state != XPC_P_AS_INACTIVE); @@ -303,6 +303,16 @@ xpc_partition_disengaged(struct xpc_partition *part) return disengaged; } +int xpc_partition_disengaged(struct xpc_partition *part) +{ + return __xpc_partition_disengaged(part, false); +} + +int xpc_partition_disengaged_from_timer(struct xpc_partition *part) +{ + return __xpc_partition_disengaged(part, true); +} + /* * Mark specified partition as active. */ diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index f4ddd1e67015..5a0a5fc3d3ab 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -380,7 +380,7 @@ void st_int_recv(void *disc_data, st_gdata->rx_state = ST_W4_HEADER; st_gdata->rx_count = st_gdata->list[type]->hdr_len; pr_debug("rx_count %ld\n", st_gdata->rx_count); - }; + } ptr++; count--; } diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c index 56dd98ab5a81..d07af4edfcac 100644 --- a/drivers/misc/uacce/uacce.c +++ b/drivers/misc/uacce/uacce.c @@ -231,17 +231,6 @@ static int uacce_fops_mmap(struct file *filep, struct vm_area_struct *vma) switch (type) { case UACCE_QFRT_MMIO: - if (!uacce->ops->mmap) { - ret = -EINVAL; - goto out_with_lock; - } - - ret = uacce->ops->mmap(q, vma, qfr); - if (ret) - goto out_with_lock; - - break; - case UACCE_QFRT_DUS: if (!uacce->ops->mmap) { ret = -EINVAL; @@ -533,5 +522,5 @@ subsys_initcall(uacce_init); module_exit(uacce_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Hisilicon Tech. Co., Ltd."); +MODULE_AUTHOR("HiSilicon Tech. Co., Ltd."); MODULE_DESCRIPTION("Accelerator interface for Userland applications"); diff --git a/drivers/misc/vmw_vmci/vmci_context.c b/drivers/misc/vmw_vmci/vmci_context.c index 16695366ec92..26ff49fdf0f7 100644 --- a/drivers/misc/vmw_vmci/vmci_context.c +++ b/drivers/misc/vmw_vmci/vmci_context.c @@ -743,7 +743,7 @@ static int vmci_ctx_get_chkpt_doorbells(struct vmci_ctx *context, return VMCI_ERROR_MORE_DATA; } - dbells = kmalloc(data_size, GFP_ATOMIC); + dbells = kzalloc(data_size, GFP_ATOMIC); if (!dbells) return VMCI_ERROR_NO_MEM; diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c index 92291292756a..23c8448a9c3b 100644 --- a/drivers/misc/xilinx_sdfec.c +++ b/drivers/misc/xilinx_sdfec.c @@ -944,8 +944,8 @@ static long xsdfec_dev_ioctl(struct file *fptr, unsigned int cmd, unsigned long data) { struct xsdfec_dev *xsdfec; - void __user *arg = NULL; - int rval = -EINVAL; + void __user *arg = (void __user *)data; + int rval; xsdfec = container_of(fptr->private_data, struct xsdfec_dev, miscdev); @@ -956,16 +956,6 @@ static long xsdfec_dev_ioctl(struct file *fptr, unsigned int cmd, return -EPERM; } - if (_IOC_TYPE(cmd) != XSDFEC_MAGIC) - return -ENOTTY; - - /* check if ioctl argument is present and valid */ - if (_IOC_DIR(cmd) != _IOC_NONE) { - arg = (void __user *)data; - if (!arg) - return rval; - } - switch (cmd) { case XSDFEC_START_DEV: rval = xsdfec_start(xsdfec); @@ -1010,20 +1000,12 @@ static long xsdfec_dev_ioctl(struct file *fptr, unsigned int cmd, rval = xsdfec_is_active(xsdfec, (bool __user *)arg); break; default: - /* Should not get here */ + rval = -ENOTTY; break; } return rval; } -#ifdef CONFIG_COMPAT -static long xsdfec_dev_compat_ioctl(struct file *file, unsigned int cmd, - unsigned long data) -{ - return xsdfec_dev_ioctl(file, cmd, (unsigned long)compat_ptr(data)); -} -#endif - static __poll_t xsdfec_poll(struct file *file, poll_table *wait) { __poll_t mask = 0; @@ -1054,9 +1036,7 @@ static const struct file_operations xsdfec_fops = { .release = xsdfec_dev_release, .unlocked_ioctl = xsdfec_dev_ioctl, .poll = xsdfec_poll, -#ifdef CONFIG_COMPAT - .compat_ioctl = xsdfec_dev_compat_ioctl, -#endif + .compat_ioctl = compat_ptr_ioctl, }; static int xsdfec_parse_of(struct xsdfec_dev *xsdfec) |