Skip to content

Commit 8a3f9d2

Browse files
committed
Merge branch 'devel'
2 parents 6be06dc + 59e500a commit 8a3f9d2

File tree

2 files changed

+252
-29
lines changed

2 files changed

+252
-29
lines changed

linux/switchtec.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,8 @@ struct ntb_info_regs {
301301
u8 partition_count;
302302
u8 partition_id;
303303
u16 reserved1;
304-
u64 ep_map;
304+
u32 ep_map_low;
305+
u32 ep_map_high;
305306
u16 requester_id;
306307
u16 reserved2;
307308
u32 reserved3[4];

ntb_hw_switchtec.c

Lines changed: 250 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,9 @@ static int switchtec_ntb_init_sndev(struct switchtec_ntb *sndev)
904904
tpart_vec <<= 32;
905905
tpart_vec |= ioread32(&sndev->mmio_ntb->ntp_info[self].target_part_low);
906906

907-
part_map = ioread64(&sndev->mmio_ntb->ep_map);
907+
part_map = ioread32(&sndev->mmio_ntb->ep_map_high);
908+
part_map <<= 32;
909+
part_map |= ioread32(&sndev->mmio_ntb->ep_map_low);
908910
tpart_vec &= part_map;
909911
part_map &= ~(1 << sndev->self_partition);
910912

@@ -992,20 +994,138 @@ static int config_rsvd_lut_win(struct switchtec_ntb *sndev,
992994
return 0;
993995
}
994996

995-
static int config_req_id_table(struct switchtec_ntb *sndev,
996-
struct ntb_ctrl_regs __iomem *mmio_ctrl,
997-
int *req_ids, int count)
997+
static int add_req_id(struct switchtec_ntb *sndev,
998+
struct ntb_ctrl_regs __iomem *mmio_ctrl, int req_id)
998999
{
9991000
int i, rc = 0;
1001+
int slot = -1;
10001002
u32 error;
1001-
u32 proxy_id;
1003+
int table_size;
1004+
u32 proxy_id = 0;
1005+
bool added = true;
1006+
1007+
table_size = ioread16(&mmio_ctrl->req_id_table_size);
1008+
1009+
rc = switchtec_ntb_part_op(sndev, mmio_ctrl,
1010+
NTB_CTRL_PART_OP_LOCK,
1011+
NTB_CTRL_PART_STATUS_LOCKED);
1012+
if (rc)
1013+
return rc;
1014+
1015+
iowrite32(NTB_PART_CTRL_ID_PROT_DIS, &mmio_ctrl->partition_ctrl);
10021016

1003-
if (ioread32(&mmio_ctrl->req_id_table_size) < count) {
1017+
for (i = 0; i < table_size; i++) {
1018+
proxy_id = ioread32(&mmio_ctrl->req_id_table[i]);
1019+
1020+
if (!(proxy_id & NTB_CTRL_REQ_ID_EN) && slot == -1)
1021+
slot = i;
1022+
1023+
if (proxy_id & NTB_CTRL_REQ_ID_EN &&
1024+
proxy_id >> 16 == req_id) {
1025+
goto unlock_exit;
1026+
}
1027+
}
1028+
1029+
if (slot == -1) {
10041030
dev_err(&sndev->stdev->dev,
10051031
"Not enough requester IDs available.\n");
1032+
added = false;
1033+
} else {
1034+
iowrite32(req_id << 16 | NTB_CTRL_REQ_ID_EN,
1035+
&mmio_ctrl->req_id_table[slot]);
1036+
1037+
dev_dbg(&sndev->stdev->dev,
1038+
"Requester ID %02X:%02X.%X -> BB:%02X.%X\n",
1039+
req_id >> 8, (req_id >> 3) & 0x1F,
1040+
req_id & 0x7, (proxy_id >> 4) & 0x1F,
1041+
(proxy_id >> 1) & 0x7);
1042+
added = true;
1043+
}
1044+
1045+
unlock_exit:
1046+
rc = switchtec_ntb_part_op(sndev, mmio_ctrl,
1047+
NTB_CTRL_PART_OP_CFG,
1048+
NTB_CTRL_PART_STATUS_NORMAL);
1049+
1050+
if (rc == -EIO) {
1051+
error = ioread32(&mmio_ctrl->req_id_error);
1052+
dev_err(&sndev->stdev->dev,
1053+
"Error setting up the requester ID table: %08x\n",
1054+
error);
1055+
}
1056+
1057+
if (!added)
10061058
return -EFAULT;
1059+
1060+
return 0;
1061+
}
1062+
1063+
static int del_req_id(struct switchtec_ntb *sndev,
1064+
struct ntb_ctrl_regs __iomem *mmio_ctrl, int req_id)
1065+
{
1066+
int i, rc = 0;
1067+
u32 error;
1068+
int table_size;
1069+
u32 rid;
1070+
bool deleted = true;
1071+
1072+
table_size = ioread16(&mmio_ctrl->req_id_table_size);
1073+
1074+
rc = switchtec_ntb_part_op(sndev, mmio_ctrl,
1075+
NTB_CTRL_PART_OP_LOCK,
1076+
NTB_CTRL_PART_STATUS_LOCKED);
1077+
if (rc)
1078+
return rc;
1079+
1080+
iowrite32(NTB_PART_CTRL_ID_PROT_DIS, &mmio_ctrl->partition_ctrl);
1081+
1082+
for (i = 0; i < table_size; i++) {
1083+
rid = ioread32(&mmio_ctrl->req_id_table[i]);
1084+
1085+
if (!(rid & NTB_CTRL_REQ_ID_EN))
1086+
continue;
1087+
1088+
rid >>= 16;
1089+
if (rid == req_id) {
1090+
iowrite32(0, &mmio_ctrl->req_id_table[i]);
1091+
break;
1092+
}
1093+
}
1094+
1095+
if (i == table_size) {
1096+
dev_err(&sndev->stdev->dev,
1097+
"Requester ID %02X:%02X.%X not in the table.\n",
1098+
PCI_BUS_NUM(req_id), PCI_SLOT(req_id),
1099+
PCI_FUNC(req_id));
1100+
deleted = false;
1101+
}
1102+
1103+
rc = switchtec_ntb_part_op(sndev, mmio_ctrl,
1104+
NTB_CTRL_PART_OP_CFG,
1105+
NTB_CTRL_PART_STATUS_NORMAL);
1106+
1107+
if (rc == -EIO) {
1108+
error = ioread32(&mmio_ctrl->req_id_error);
1109+
dev_err(&sndev->stdev->dev,
1110+
"Error setting up the requester ID table: %08x\n",
1111+
error);
10071112
}
10081113

1114+
if (!deleted)
1115+
return -ENXIO;
1116+
1117+
return 0;
1118+
}
1119+
1120+
static int clr_req_ids(struct switchtec_ntb *sndev,
1121+
struct ntb_ctrl_regs __iomem *mmio_ctrl)
1122+
{
1123+
int i, rc = 0;
1124+
u32 error;
1125+
int table_size;
1126+
1127+
table_size = ioread16(&mmio_ctrl->req_id_table_size);
1128+
10091129
rc = switchtec_ntb_part_op(sndev, mmio_ctrl,
10101130
NTB_CTRL_PART_OP_LOCK,
10111131
NTB_CTRL_PART_STATUS_LOCKED);
@@ -1015,17 +1135,8 @@ static int config_req_id_table(struct switchtec_ntb *sndev,
10151135
iowrite32(NTB_PART_CTRL_ID_PROT_DIS,
10161136
&mmio_ctrl->partition_ctrl);
10171137

1018-
for (i = 0; i < count; i++) {
1019-
iowrite32(req_ids[i] << 16 | NTB_CTRL_REQ_ID_EN,
1020-
&mmio_ctrl->req_id_table[i]);
1021-
1022-
proxy_id = ioread32(&mmio_ctrl->req_id_table[i]);
1023-
dev_dbg(&sndev->stdev->dev,
1024-
"Requester ID %02X:%02X.%X -> BB:%02X.%X\n",
1025-
req_ids[i] >> 8, (req_ids[i] >> 3) & 0x1F,
1026-
req_ids[i] & 0x7, (proxy_id >> 4) & 0x1F,
1027-
(proxy_id >> 1) & 0x7);
1028-
}
1138+
for (i = 0; i < table_size; i++)
1139+
iowrite32(0, &mmio_ctrl->req_id_table[i]);
10291140

10301141
rc = switchtec_ntb_part_op(sndev, mmio_ctrl,
10311142
NTB_CTRL_PART_OP_CFG,
@@ -1110,20 +1221,28 @@ static int crosslink_setup_mws(struct switchtec_ntb *sndev, int ntb_lut_idx,
11101221
static int crosslink_setup_req_ids(struct switchtec_ntb *sndev,
11111222
struct ntb_ctrl_regs __iomem *mmio_ctrl)
11121223
{
1113-
int req_ids[16];
11141224
int i;
11151225
u32 proxy_id;
1226+
int table_size;
1227+
int rc;
11161228

1117-
for (i = 0; i < ARRAY_SIZE(req_ids); i++) {
1229+
table_size = ioread16(&mmio_ctrl->req_id_table_size);
1230+
1231+
clr_req_ids(sndev, mmio_ctrl);
1232+
1233+
for (i = 0; i < table_size; i++) {
11181234
proxy_id = ioread32(&sndev->mmio_self_ctrl->req_id_table[i]);
11191235

11201236
if (!(proxy_id & NTB_CTRL_REQ_ID_EN))
1121-
break;
1237+
continue;
11221238

1123-
req_ids[i] = ((proxy_id >> 1) & 0xFF);
1239+
proxy_id = ((proxy_id >> 1) & 0xFF);
1240+
rc = add_req_id(sndev, mmio_ctrl, proxy_id);
1241+
if (rc)
1242+
return rc;
11241243
}
11251244

1126-
return config_req_id_table(sndev, mmio_ctrl, req_ids, i);
1245+
return 0;
11271246
}
11281247

11291248
/*
@@ -1324,20 +1443,21 @@ static void switchtec_ntb_init_msgs(struct switchtec_ntb *sndev)
13241443
static int
13251444
switchtec_ntb_init_req_id_table(struct switchtec_ntb *sndev)
13261445
{
1327-
int req_ids[2];
1446+
int req_id;
1447+
int rc;
13281448

13291449
/*
13301450
* Root Complex Requester ID (which is 0:00.0)
13311451
*/
1332-
req_ids[0] = 0;
1452+
rc = add_req_id(sndev, sndev->mmio_self_ctrl, 0);
1453+
if (rc)
1454+
return rc;
13331455

13341456
/*
13351457
* Host Bridge Requester ID (as read from the mmap address)
13361458
*/
1337-
req_ids[1] = ioread16(&sndev->mmio_ntb->requester_id);
1338-
1339-
return config_req_id_table(sndev, sndev->mmio_self_ctrl, req_ids,
1340-
ARRAY_SIZE(req_ids));
1459+
req_id = ioread16(&sndev->mmio_ntb->requester_id);
1460+
return add_req_id(sndev, sndev->mmio_self_ctrl, req_id);
13411461
}
13421462

13431463
static void switchtec_ntb_init_shared(struct switchtec_ntb *sndev)
@@ -1518,6 +1638,102 @@ static int switchtec_ntb_reinit_peer(struct switchtec_ntb *sndev)
15181638
return rc;
15191639
}
15201640

1641+
static ssize_t add_requester_id_store(struct device *dev,
1642+
struct device_attribute *attr,
1643+
const char *buf, size_t count)
1644+
{
1645+
struct ntb_dev *ntb = container_of(dev, struct ntb_dev, dev);
1646+
struct switchtec_ntb *sndev = ntb_sndev(ntb);
1647+
int req_id;
1648+
int bus, device, func;
1649+
int rc;
1650+
1651+
if (sscanf(buf, "%x:%x.%x", &bus, &device, &func) != 3)
1652+
return -EINVAL;
1653+
1654+
req_id = PCI_DEVID(bus, PCI_DEVFN(device, func));
1655+
rc = add_req_id(sndev, sndev->mmio_self_ctrl, req_id);
1656+
if (rc)
1657+
return rc;
1658+
1659+
if (crosslink_is_enabled(sndev)) {
1660+
rc = crosslink_setup_req_ids(sndev, sndev->mmio_peer_ctrl);
1661+
if (rc)
1662+
return rc;
1663+
}
1664+
1665+
return count;
1666+
}
1667+
static DEVICE_ATTR_WO(add_requester_id);
1668+
1669+
static ssize_t del_requester_id_store(struct device *dev,
1670+
struct device_attribute *attr,
1671+
const char *buf, size_t count)
1672+
{
1673+
struct ntb_dev *ntb = container_of(dev, struct ntb_dev, dev);
1674+
struct switchtec_ntb *sndev = ntb_sndev(ntb);
1675+
int req_id;
1676+
int bus, device, func;
1677+
int rc;
1678+
1679+
if (sscanf(buf, "%x:%x.%x", &bus, &device, &func) != 3)
1680+
return -EINVAL;
1681+
1682+
req_id = PCI_DEVID(bus, PCI_DEVFN(device, func));
1683+
rc = del_req_id(sndev, sndev->mmio_self_ctrl, req_id);
1684+
if (rc)
1685+
return rc;
1686+
1687+
if (crosslink_is_enabled(sndev)) {
1688+
rc = crosslink_setup_req_ids(sndev, sndev->mmio_peer_ctrl);
1689+
if (rc)
1690+
return rc;
1691+
}
1692+
1693+
return count;
1694+
}
1695+
static DEVICE_ATTR_WO(del_requester_id);
1696+
1697+
static ssize_t requester_ids_show(struct device *dev,
1698+
struct device_attribute *attr, char *buf)
1699+
{
1700+
struct ntb_dev *ntb = container_of(dev, struct ntb_dev, dev);
1701+
struct switchtec_ntb *sndev = ntb_sndev(ntb);
1702+
int i;
1703+
int table_size;
1704+
char req_id_str[32];
1705+
u32 req_id;
1706+
ssize_t n = 0;
1707+
1708+
table_size = ioread16(&sndev->mmio_self_ctrl->req_id_table_size);
1709+
1710+
for (i = 0; i < table_size; i++) {
1711+
req_id = ioread32(&sndev->mmio_self_ctrl->req_id_table[i]);
1712+
1713+
if (req_id & NTB_CTRL_REQ_ID_EN) {
1714+
req_id >>= 16;
1715+
n += sprintf(req_id_str, "%d\t%02X:%02X.%X\n", i,
1716+
PCI_BUS_NUM(req_id), PCI_SLOT(req_id),
1717+
PCI_FUNC(req_id));
1718+
strcat(buf, req_id_str);
1719+
}
1720+
}
1721+
1722+
return n;
1723+
}
1724+
static DEVICE_ATTR_RO(requester_ids);
1725+
1726+
static struct attribute *switchtec_ntb_device_attrs[] = {
1727+
&dev_attr_add_requester_id.attr,
1728+
&dev_attr_del_requester_id.attr,
1729+
&dev_attr_requester_ids.attr,
1730+
NULL,
1731+
};
1732+
1733+
static const struct attribute_group switchtec_ntb_device_group = {
1734+
.attrs = switchtec_ntb_device_attrs,
1735+
};
1736+
15211737
static int switchtec_ntb_add(struct device *dev,
15221738
struct class_interface *class_intf)
15231739
{
@@ -1571,6 +1787,11 @@ static int switchtec_ntb_add(struct device *dev,
15711787
if (rc)
15721788
goto deinit_and_exit;
15731789

1790+
rc = sysfs_create_group(&sndev->ntb.dev.kobj,
1791+
&switchtec_ntb_device_group);
1792+
if (rc)
1793+
goto deinit_and_exit;
1794+
15741795
stdev->sndev = sndev;
15751796
stdev->link_notifier = switchtec_ntb_link_notification;
15761797
dev_info(dev, "NTB device registered\n");
@@ -1600,6 +1821,7 @@ static void switchtec_ntb_remove(struct device *dev,
16001821

16011822
stdev->link_notifier = NULL;
16021823
stdev->sndev = NULL;
1824+
sysfs_remove_group(&sndev->ntb.dev.kobj, &switchtec_ntb_device_group);
16031825
ntb_unregister_device(&sndev->ntb);
16041826
switchtec_ntb_deinit_db_msg_irq(sndev);
16051827
switchtec_ntb_deinit_shared_mw(sndev);

0 commit comments

Comments
 (0)