Skip to content

Commit 9eb27a1

Browse files
committed
Merge branch 'master' into backport_4.4_to_4.7
2 parents a683334 + 9850f46 commit 9eb27a1

File tree

4 files changed

+94
-62
lines changed

4 files changed

+94
-62
lines changed

linux/switchtec.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ struct sw_event_regs {
101101
u32 gpio_interrupt_hdr;
102102
u32 gpio_interrupt_data;
103103
u32 reserved16[4];
104+
u32 gfms_event_hdr;
105+
u32 gfms_event_data;
106+
u32 reserved17[4];
104107
} __packed;
105108

106109
enum {
@@ -360,7 +363,7 @@ struct switchtec_dev {
360363
atomic_t event_cnt;
361364

362365
struct work_struct link_event_work;
363-
struct blocking_notifier_head link_notifier;
366+
void (*link_notifier)(struct switchtec_dev *stdev);
364367
u8 link_event_count[SWITCHTEC_MAX_PFF_CSR];
365368

366369
struct switchtec_ntb *sndev;

linux/switchtec_ioctl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ struct switchtec_ioctl_event_summary {
8787
#define SWITCHTEC_IOCTL_EVENT_FORCE_SPEED 26
8888
#define SWITCHTEC_IOCTL_EVENT_CREDIT_TIMEOUT 27
8989
#define SWITCHTEC_IOCTL_EVENT_LINK_STATE 28
90-
#define SWITCHTEC_IOCTL_MAX_EVENTS 29
90+
#define SWITCHTEC_IOCTL_EVENT_GFMS 29
91+
#define SWITCHTEC_IOCTL_MAX_EVENTS 30
9192

9293
#define SWITCHTEC_IOCTL_EVENT_LOCAL_PART_IDX -1
9394
#define SWITCHTEC_IOCTL_EVENT_IDX_ALL -2

switchtec.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,7 @@ const struct event_reg {
709709
EV_GLB(SWITCHTEC_IOCTL_EVENT_CLI_MRPC_COMP_ASYNC,
710710
cli_mrpc_comp_async_hdr),
711711
EV_GLB(SWITCHTEC_IOCTL_EVENT_GPIO_INT, gpio_interrupt_hdr),
712+
EV_GLB(SWITCHTEC_IOCTL_EVENT_GFMS, gfms_event_hdr),
712713
EV_PAR(SWITCHTEC_IOCTL_EVENT_PART_RESET, part_reset_hdr),
713714
EV_PAR(SWITCHTEC_IOCTL_EVENT_MRPC_COMP, mrpc_comp_hdr),
714715
EV_PAR(SWITCHTEC_IOCTL_EVENT_MRPC_COMP_ASYNC, mrpc_comp_async_hdr),
@@ -986,9 +987,8 @@ static void link_event_work(struct work_struct *work)
986987

987988
stdev = container_of(work, struct switchtec_dev, link_event_work);
988989

989-
dev_dbg(&stdev->dev, "link event work occurred\n");
990-
991-
blocking_notifier_call_chain(&stdev->link_notifier, 0, stdev);
990+
if (stdev->link_notifier)
991+
stdev->link_notifier(stdev);
992992
}
993993

994994
static void check_link_state_events(struct switchtec_dev *stdev)
@@ -1000,7 +1000,7 @@ static void check_link_state_events(struct switchtec_dev *stdev)
10001000

10011001
for (idx = 0; idx < stdev->pff_csr_count; idx++) {
10021002
reg = ioread32(&stdev->mmio_pff_csr[idx].link_state_hdr);
1003-
dev_dbg(&stdev->dev, "link state: %d->%08x\n", idx, reg);
1003+
dev_dbg(&stdev->dev, "link_state: %d->%08x\n", idx, reg);
10041004
count = (reg >> 5) & 0xFF;
10051005

10061006
if (count != stdev->link_event_count[idx]) {
@@ -1077,7 +1077,6 @@ static struct switchtec_dev *stdev_create(struct pci_dev *pdev)
10771077
INIT_WORK(&stdev->mrpc_work, mrpc_event_work);
10781078
INIT_DELAYED_WORK(&stdev->mrpc_timeout, mrpc_timeout_work);
10791079
INIT_WORK(&stdev->link_event_work, link_event_work);
1080-
BLOCKING_INIT_NOTIFIER_HEAD(&stdev->link_notifier);
10811080
init_waitqueue_head(&stdev->event_wq);
10821081
atomic_set(&stdev->event_cnt, 0);
10831082

switchtec_ntb.c

Lines changed: 84 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
#include <linux/switchtec.h>
1717
#include <linux/module.h>
1818
#include <linux/delay.h>
19-
#include <linux/interrupt.h>
2019
#include <linux/kthread.h>
20+
#include <linux/interrupt.h>
2121
#include <linux/ntb.h>
2222

2323
MODULE_DESCRIPTION("Microsemi Switchtec(tm) NTB Driver");
@@ -28,7 +28,7 @@ MODULE_AUTHOR("Microsemi Corporation");
2828
static ulong max_mw_size = SZ_2M;
2929
module_param(max_mw_size, ulong, 0644);
3030
MODULE_PARM_DESC(max_mw_size,
31-
"Limit the size of the memory windows reported to the upper layer");
31+
"Max memory window size reported to the upper layer");
3232

3333
static bool use_lut_mws;
3434
module_param(use_lut_mws, bool, 0644);
@@ -65,11 +65,13 @@ static inline void _iowrite64(u64 val, void __iomem *mmio)
6565
#endif
6666

6767
#define SWITCHTEC_NTB_MAGIC 0x45CC0001
68+
#define MAX_MWS 128
6869

6970
struct shared_mw {
7071
u32 magic;
7172
u32 link_sta;
7273
u32 partition_id;
74+
u64 mw_sizes[MAX_MWS];
7375
u32 spad[128];
7476
};
7577

@@ -109,10 +111,13 @@ struct switchtec_ntb {
109111
int nr_lut_mw;
110112
int direct_mw_to_bar[MAX_DIRECT_MW];
111113

114+
int peer_nr_direct_mw;
115+
int peer_nr_lut_mw;
116+
int peer_direct_mw_to_bar[MAX_DIRECT_MW];
117+
112118
bool link_is_up;
113119
enum ntb_speed link_speed;
114120
enum ntb_width link_width;
115-
struct notifier_block link_notifier;
116121
};
117122

118123
static struct switchtec_ntb *ntb_sndev(struct ntb_dev *ntb)
@@ -191,18 +196,25 @@ static int switchtec_ntb_send_msg(struct switchtec_ntb *sndev, int idx,
191196
static int switchtec_ntb_mw_count(struct ntb_dev *ntb)
192197
{
193198
struct switchtec_ntb *sndev = ntb_sndev(ntb);
199+
int nr_direct_mw = sndev->peer_nr_direct_mw;
200+
int nr_lut_mw = sndev->peer_nr_lut_mw - 1;
194201

195-
if (use_lut_mws)
196-
return sndev->nr_direct_mw + sndev->nr_lut_mw - 1;
197-
else
198-
return sndev->nr_direct_mw;
202+
if (!use_lut_mws)
203+
nr_lut_mw = 0;
204+
205+
return nr_direct_mw + nr_lut_mw;
199206
}
200207

201208
static int lut_index(struct switchtec_ntb *sndev, int mw_idx)
202209
{
203210
return mw_idx - sndev->nr_direct_mw + 1;
204211
}
205212

213+
static int peer_lut_index(struct switchtec_ntb *sndev, int mw_idx)
214+
{
215+
return mw_idx - sndev->peer_nr_direct_mw + 1;
216+
}
217+
206218
static int switchtec_ntb_mw_direct_get_range(struct switchtec_ntb *sndev,
207219
int idx, phys_addr_t *base,
208220
resource_size_t *size,
@@ -295,7 +307,7 @@ static int switchtec_ntb_mw_get_range(struct ntb_dev *ntb, int idx,
295307
static void switchtec_ntb_mw_clr_direct(struct switchtec_ntb *sndev, int idx)
296308
{
297309
struct ntb_ctrl_regs __iomem *ctl = sndev->mmio_peer_ctrl;
298-
int bar = sndev->direct_mw_to_bar[idx];
310+
int bar = sndev->peer_direct_mw_to_bar[idx];
299311
u32 ctl_val;
300312

301313
ctl_val = ioread32(&ctl->bar_entry[bar].ctl);
@@ -309,14 +321,14 @@ static void switchtec_ntb_mw_clr_lut(struct switchtec_ntb *sndev, int idx)
309321
{
310322
struct ntb_ctrl_regs __iomem *ctl = sndev->mmio_peer_ctrl;
311323

312-
iowrite64(0, &ctl->lut_entry[lut_index(sndev, idx)]);
324+
iowrite64(0, &ctl->lut_entry[peer_lut_index(sndev, idx)]);
313325
}
314326

315327
static void switchtec_ntb_mw_set_direct(struct switchtec_ntb *sndev, int idx,
316328
dma_addr_t addr, resource_size_t size)
317329
{
318330
int xlate_pos = ilog2(size);
319-
int bar = sndev->direct_mw_to_bar[idx];
331+
int bar = sndev->peer_direct_mw_to_bar[idx];
320332
struct ntb_ctrl_regs __iomem *ctl = sndev->mmio_peer_ctrl;
321333
u32 ctl_val;
322334

@@ -335,7 +347,7 @@ static void switchtec_ntb_mw_set_lut(struct switchtec_ntb *sndev, int idx,
335347
struct ntb_ctrl_regs __iomem *ctl = sndev->mmio_peer_ctrl;
336348

337349
iowrite64((NTB_CTRL_LUT_EN | (sndev->self_partition << 1) | addr),
338-
&ctl->lut_entry[lut_index(sndev, idx)]);
350+
&ctl->lut_entry[peer_lut_index(sndev, idx)]);
339351
}
340352

341353
static int switchtec_ntb_mw_set_trans(struct ntb_dev *ntb, int idx,
@@ -344,6 +356,7 @@ static int switchtec_ntb_mw_set_trans(struct ntb_dev *ntb, int idx,
344356
struct switchtec_ntb *sndev = ntb_sndev(ntb);
345357
struct ntb_ctrl_regs __iomem *ctl = sndev->mmio_peer_ctrl;
346358
int xlate_pos = ilog2(size);
359+
int nr_direct_mw = sndev->peer_nr_direct_mw;
347360
int rc;
348361

349362
dev_dbg(&sndev->stdev->dev, "MW %d: %016llx %016llx", idx, addr, size);
@@ -360,12 +373,12 @@ static int switchtec_ntb_mw_set_trans(struct ntb_dev *ntb, int idx,
360373
return rc;
361374

362375
if (addr == 0 || size == 0) {
363-
if (idx < sndev->nr_direct_mw)
376+
if (idx < nr_direct_mw)
364377
switchtec_ntb_mw_clr_direct(sndev, idx);
365378
else
366379
switchtec_ntb_mw_clr_lut(sndev, idx);
367380
} else {
368-
if (idx < sndev->nr_direct_mw)
381+
if (idx < nr_direct_mw)
369382
switchtec_ntb_mw_set_direct(sndev, idx, addr, size);
370383
else
371384
switchtec_ntb_mw_set_lut(sndev, idx, addr, size);
@@ -379,7 +392,7 @@ static int switchtec_ntb_mw_set_trans(struct ntb_dev *ntb, int idx,
379392
"Hardware reported an error configuring mw %d: %08x",
380393
idx, ioread32(&ctl->bar_error));
381394

382-
if (idx < sndev->nr_direct_mw)
395+
if (idx < nr_direct_mw)
383396
switchtec_ntb_mw_clr_direct(sndev, idx);
384397
else
385398
switchtec_ntb_mw_clr_lut(sndev, idx);
@@ -461,35 +474,11 @@ static void switchtec_ntb_check_link(struct switchtec_ntb *sndev)
461474
}
462475
}
463476

464-
static void switchtec_ntb_link_event(struct switchtec_ntb *sndev, int msg)
465-
{
466-
switchtec_ntb_check_link(sndev);
467-
}
468-
469-
static int switchtec_ntb_link_notification(struct notifier_block *nb,
470-
unsigned long event, void *data)
477+
static void switchtec_ntb_link_notification(struct switchtec_dev *stdev)
471478
{
472-
struct switchtec_ntb *sndev = container_of(nb, struct switchtec_ntb,
473-
link_notifier);
479+
struct switchtec_ntb *sndev = stdev->sndev;
474480

475-
dev_dbg(&sndev->stdev->dev, "link message received");
476481
switchtec_ntb_check_link(sndev);
477-
478-
return NOTIFY_OK;
479-
}
480-
481-
static int switchtec_ntb_init_link_notifier(struct switchtec_ntb *sndev)
482-
{
483-
sndev->link_notifier.notifier_call = switchtec_ntb_link_notification;
484-
485-
return blocking_notifier_chain_register(&sndev->stdev->link_notifier,
486-
&sndev->link_notifier);
487-
}
488-
489-
static void switchtec_ntb_deinit_link_notifier(struct switchtec_ntb *sndev)
490-
{
491-
blocking_notifier_chain_unregister(&sndev->stdev->link_notifier,
492-
&sndev->link_notifier);
493482
}
494483

495484
static int switchtec_ntb_link_is_up(struct ntb_dev *ntb,
@@ -782,23 +771,42 @@ static void switchtec_ntb_init_sndev(struct switchtec_ntb *sndev)
782771
sndev->mmio_self_dbmsg = &sndev->mmio_dbmsg[sndev->self_partition];
783772
}
784773

785-
static void switchtec_ntb_init_mw(struct switchtec_ntb *sndev)
774+
static int map_bars(int *map, struct ntb_ctrl_regs __iomem *ctrl)
786775
{
787776
int i;
777+
int cnt = 0;
788778

789-
sndev->nr_direct_mw = 0;
790-
for (i = 0; i < ARRAY_SIZE(sndev->mmio_self_ctrl->bar_entry); i++) {
791-
u32 r = ioread32(&sndev->mmio_self_ctrl->bar_entry[i].ctl);
779+
for (i = 0; i < ARRAY_SIZE(ctrl->bar_entry); i++) {
780+
u32 r = ioread32(&ctrl->bar_entry[i].ctl);
792781

793782
if (r & NTB_CTRL_BAR_VALID)
794-
sndev->direct_mw_to_bar[sndev->nr_direct_mw++] = i;
783+
map[cnt++] = i;
795784
}
796785

786+
return cnt;
787+
}
788+
789+
static void switchtec_ntb_init_mw(struct switchtec_ntb *sndev)
790+
{
791+
sndev->nr_direct_mw = map_bars(sndev->direct_mw_to_bar,
792+
sndev->mmio_self_ctrl);
793+
797794
sndev->nr_lut_mw = ioread16(&sndev->mmio_self_ctrl->lut_table_entries);
798795
sndev->nr_lut_mw = rounddown_pow_of_two(sndev->nr_lut_mw);
799796

800797
dev_dbg(&sndev->stdev->dev, "MWs: %d direct, %d lut",
801798
sndev->nr_direct_mw, sndev->nr_lut_mw);
799+
800+
sndev->peer_nr_direct_mw = map_bars(sndev->peer_direct_mw_to_bar,
801+
sndev->mmio_peer_ctrl);
802+
803+
sndev->peer_nr_lut_mw =
804+
ioread16(&sndev->mmio_peer_ctrl->lut_table_entries);
805+
sndev->peer_nr_lut_mw = rounddown_pow_of_two(sndev->peer_nr_lut_mw);
806+
807+
dev_dbg(&sndev->stdev->dev, "Peer MWs: %d direct, %d lut",
808+
sndev->peer_nr_direct_mw, sndev->peer_nr_lut_mw);
809+
802810
}
803811

804812
/*
@@ -887,6 +895,32 @@ static int switchtec_ntb_init_req_id_table(struct switchtec_ntb *sndev)
887895
return rc;
888896
}
889897

898+
static void switchtec_ntb_init_shared(struct switchtec_ntb *sndev)
899+
{
900+
int i;
901+
902+
memset(sndev->self_shared, 0, LUT_SIZE);
903+
sndev->self_shared->magic = SWITCHTEC_NTB_MAGIC;
904+
sndev->self_shared->partition_id = sndev->stdev->partition;
905+
906+
for (i = 0; i < sndev->nr_direct_mw; i++) {
907+
int bar = sndev->direct_mw_to_bar[i];
908+
resource_size_t sz = pci_resource_len(sndev->stdev->pdev, bar);
909+
910+
if (i == 0)
911+
sz = min_t(resource_size_t, sz,
912+
LUT_SIZE * sndev->nr_lut_mw);
913+
914+
sndev->self_shared->mw_sizes[i] = sz;
915+
}
916+
917+
for (i = 0; i < sndev->nr_lut_mw; i++) {
918+
int idx = sndev->nr_direct_mw + i;
919+
920+
sndev->self_shared->mw_sizes[idx] = LUT_SIZE;
921+
}
922+
}
923+
890924
static int switchtec_ntb_init_shared_mw(struct switchtec_ntb *sndev)
891925
{
892926
struct ntb_ctrl_regs __iomem *ctl = sndev->mmio_peer_ctrl;
@@ -904,9 +938,7 @@ static int switchtec_ntb_init_shared_mw(struct switchtec_ntb *sndev)
904938
return -ENOMEM;
905939
}
906940

907-
memset(sndev->self_shared, 0, LUT_SIZE);
908-
sndev->self_shared->magic = SWITCHTEC_NTB_MAGIC;
909-
sndev->self_shared->partition_id = sndev->stdev->partition;
941+
switchtec_ntb_init_shared(sndev);
910942

911943
rc = switchtec_ntb_part_op(sndev, ctl, NTB_CTRL_PART_OP_LOCK,
912944
NTB_CTRL_PART_STATUS_LOCKED);
@@ -989,7 +1021,7 @@ static irqreturn_t switchtec_ntb_message_isr(int irq, void *dev)
9891021
iowrite8(1, &sndev->mmio_self_dbmsg->imsg[i].status);
9901022

9911023
if (i == LINK_MESSAGE)
992-
switchtec_ntb_link_event(sndev, msg);
1024+
switchtec_ntb_check_link(sndev);
9931025
}
9941026
}
9951027

@@ -1087,22 +1119,19 @@ static int switchtec_ntb_add(struct device *dev,
10871119
if (rc)
10881120
goto deinit_shared_and_exit;
10891121

1090-
rc = switchtec_ntb_init_link_notifier(sndev);
1091-
if (rc)
1092-
goto denit_db_msg_and_exit;
1122+
switchtec_ntb_init_mw(sndev);
10931123

10941124
rc = ntb_register_device(&sndev->ntb);
10951125
if (rc)
10961126
goto deinit_and_exit;
10971127

10981128
stdev->sndev = sndev;
1129+
stdev->link_notifier = switchtec_ntb_link_notification;
10991130
dev_info(dev, "NTB device registered");
11001131

11011132
return 0;
11021133

11031134
deinit_and_exit:
1104-
switchtec_ntb_deinit_link_notifier(sndev);
1105-
denit_db_msg_and_exit:
11061135
switchtec_ntb_deinit_db_msg_irq(sndev);
11071136
deinit_shared_and_exit:
11081137
switchtec_ntb_deinit_shared_mw(sndev);
@@ -1121,9 +1150,9 @@ void switchtec_ntb_remove(struct device *dev,
11211150
if (!sndev)
11221151
return;
11231152

1153+
stdev->link_notifier = NULL;
11241154
stdev->sndev = NULL;
11251155
ntb_unregister_device(&sndev->ntb);
1126-
switchtec_ntb_deinit_link_notifier(sndev);
11271156
switchtec_ntb_deinit_db_msg_irq(sndev);
11281157
switchtec_ntb_deinit_shared_mw(sndev);
11291158
kfree(sndev);

0 commit comments

Comments
 (0)