in hw/mscc/ntb_hw_switchtec.c [996:1060]
static int crosslink_setup_mws(struct switchtec_ntb *sndev, int ntb_lut_idx,
u64 *mw_addrs, int mw_count)
{
int rc, i;
struct ntb_ctrl_regs __iomem *ctl = sndev->mmio_self_ctrl;
u64 addr;
size_t size, offset;
int bar;
int xlate_pos;
u32 ctl_val;
rc = switchtec_ntb_part_op(sndev, ctl, NTB_CTRL_PART_OP_LOCK,
NTB_CTRL_PART_STATUS_LOCKED);
if (rc)
return rc;
for (i = 0; i < sndev->nr_lut_mw; i++) {
if (i == ntb_lut_idx)
continue;
addr = mw_addrs[0] + LUT_SIZE * i;
iowrite64((NTB_CTRL_LUT_EN | (sndev->peer_partition << 1) |
addr),
&ctl->lut_entry[i]);
}
sndev->nr_direct_mw = min_t(int, sndev->nr_direct_mw, mw_count);
for (i = 0; i < sndev->nr_direct_mw; i++) {
bar = sndev->direct_mw_to_bar[i];
offset = (i == 0) ? LUT_SIZE * sndev->nr_lut_mw : 0;
addr = mw_addrs[i] + offset;
size = pci_resource_len(sndev->ntb.pdev, bar) - offset;
xlate_pos = ilog2(size);
if (offset && size > offset)
size = offset;
ctl_val = ioread32(&ctl->bar_entry[bar].ctl);
ctl_val |= NTB_CTRL_BAR_DIR_WIN_EN;
iowrite32(ctl_val, &ctl->bar_entry[bar].ctl);
iowrite32(xlate_pos | (lower_32_bits(size) & 0xFFFFF000),
&ctl->bar_entry[bar].win_size);
iowrite32(upper_32_bits(size), &ctl->bar_ext_entry[bar].win_size);
iowrite64(sndev->peer_partition | addr,
&ctl->bar_entry[bar].xlate_addr);
}
rc = switchtec_ntb_part_op(sndev, ctl, NTB_CTRL_PART_OP_CFG,
NTB_CTRL_PART_STATUS_NORMAL);
if (rc) {
u32 bar_error, lut_error;
bar_error = ioread32(&ctl->bar_error);
lut_error = ioread32(&ctl->lut_error);
dev_err(&sndev->stdev->dev,
"Error setting up cross link windows: %08x / %08x\n",
bar_error, lut_error);
return rc;
}
return 0;
}