提交 8206ceb0 编写于 作者: D Doug Ledford

Merge branch 'hfi1' into k.o/for-next

Signed-off-by: NDoug Ledford <dledford@redhat.com>
...@@ -9956,7 +9956,7 @@ int hfi1_get_ib_cfg(struct hfi1_pportdata *ppd, int which) ...@@ -9956,7 +9956,7 @@ int hfi1_get_ib_cfg(struct hfi1_pportdata *ppd, int which)
val = ppd->phy_error_threshold; val = ppd->phy_error_threshold;
break; break;
case HFI1_IB_CFG_LINKDEFAULT: /* IB link default (sleep/poll) */ case HFI1_IB_CFG_LINKDEFAULT: /* IB link default (sleep/poll) */
val = dd->link_default; val = HLS_DEFAULT;
break; break;
case HFI1_IB_CFG_HRTBT: /* Heartbeat off/enable/auto */ case HFI1_IB_CFG_HRTBT: /* Heartbeat off/enable/auto */
...@@ -10159,6 +10159,10 @@ static const char * const state_complete_reasons[] = { ...@@ -10159,6 +10159,10 @@ static const char * const state_complete_reasons[] = {
[0x33] = [0x33] =
"Link partner completed the VerifyCap state, but the passing lanes do not meet the local link width policy", "Link partner completed the VerifyCap state, but the passing lanes do not meet the local link width policy",
[0x34] = tx_out_of_policy, [0x34] = tx_out_of_policy,
[0x35] = "Negotiated link width is mutually exclusive",
[0x36] =
"Timed out before receiving verifycap frames in VerifyCap.Exchange",
[0x37] = "Unable to resolve secure data exchange",
}; };
static const char *state_complete_reason_code_string(struct hfi1_pportdata *ppd, static const char *state_complete_reason_code_string(struct hfi1_pportdata *ppd,
...@@ -10547,7 +10551,7 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state) ...@@ -10547,7 +10551,7 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
orig_new_state = state; orig_new_state = state;
if (state == HLS_DN_DOWNDEF) if (state == HLS_DN_DOWNDEF)
state = dd->link_default; state = HLS_DEFAULT;
/* interpret poll -> poll as a link bounce */ /* interpret poll -> poll as a link bounce */
poll_bounce = ppd->host_link_state == HLS_DN_POLL && poll_bounce = ppd->host_link_state == HLS_DN_POLL &&
...@@ -12925,7 +12929,7 @@ static void clean_up_interrupts(struct hfi1_devdata *dd) ...@@ -12925,7 +12929,7 @@ static void clean_up_interrupts(struct hfi1_devdata *dd)
if (!me->arg) /* => no irq, no affinity */ if (!me->arg) /* => no irq, no affinity */
continue; continue;
hfi1_put_irq_affinity(dd, me); hfi1_put_irq_affinity(dd, me);
free_irq(me->irq, me->arg); pci_free_irq(dd->pcidev, i, me->arg);
} }
/* clean structures */ /* clean structures */
...@@ -12935,7 +12939,7 @@ static void clean_up_interrupts(struct hfi1_devdata *dd) ...@@ -12935,7 +12939,7 @@ static void clean_up_interrupts(struct hfi1_devdata *dd)
} else { } else {
/* INTx */ /* INTx */
if (dd->requested_intx_irq) { if (dd->requested_intx_irq) {
free_irq(dd->pcidev->irq, dd); pci_free_irq(dd->pcidev, 0, dd);
dd->requested_intx_irq = 0; dd->requested_intx_irq = 0;
} }
disable_intx(dd->pcidev); disable_intx(dd->pcidev);
...@@ -12994,10 +12998,8 @@ static int request_intx_irq(struct hfi1_devdata *dd) ...@@ -12994,10 +12998,8 @@ static int request_intx_irq(struct hfi1_devdata *dd)
{ {
int ret; int ret;
snprintf(dd->intx_name, sizeof(dd->intx_name), DRIVER_NAME "_%d", ret = pci_request_irq(dd->pcidev, 0, general_interrupt, NULL, dd,
dd->unit); DRIVER_NAME "_%d", dd->unit);
ret = request_irq(dd->pcidev->irq, general_interrupt,
IRQF_SHARED, dd->intx_name, dd);
if (ret) if (ret)
dd_dev_err(dd, "unable to request INTx interrupt, err %d\n", dd_dev_err(dd, "unable to request INTx interrupt, err %d\n",
ret); ret);
...@@ -13040,13 +13042,14 @@ static int request_msix_irqs(struct hfi1_devdata *dd) ...@@ -13040,13 +13042,14 @@ static int request_msix_irqs(struct hfi1_devdata *dd)
int idx; int idx;
struct hfi1_ctxtdata *rcd = NULL; struct hfi1_ctxtdata *rcd = NULL;
struct sdma_engine *sde = NULL; struct sdma_engine *sde = NULL;
char name[MAX_NAME_SIZE];
/* obtain the arguments to request_irq */ /* obtain the arguments to pci_request_irq */
if (first_general <= i && i < last_general) { if (first_general <= i && i < last_general) {
idx = i - first_general; idx = i - first_general;
handler = general_interrupt; handler = general_interrupt;
arg = dd; arg = dd;
snprintf(me->name, sizeof(me->name), snprintf(name, sizeof(name),
DRIVER_NAME "_%d", dd->unit); DRIVER_NAME "_%d", dd->unit);
err_info = "general"; err_info = "general";
me->type = IRQ_GENERAL; me->type = IRQ_GENERAL;
...@@ -13055,14 +13058,14 @@ static int request_msix_irqs(struct hfi1_devdata *dd) ...@@ -13055,14 +13058,14 @@ static int request_msix_irqs(struct hfi1_devdata *dd)
sde = &dd->per_sdma[idx]; sde = &dd->per_sdma[idx];
handler = sdma_interrupt; handler = sdma_interrupt;
arg = sde; arg = sde;
snprintf(me->name, sizeof(me->name), snprintf(name, sizeof(name),
DRIVER_NAME "_%d sdma%d", dd->unit, idx); DRIVER_NAME "_%d sdma%d", dd->unit, idx);
err_info = "sdma"; err_info = "sdma";
remap_sdma_interrupts(dd, idx, i); remap_sdma_interrupts(dd, idx, i);
me->type = IRQ_SDMA; me->type = IRQ_SDMA;
} else if (first_rx <= i && i < last_rx) { } else if (first_rx <= i && i < last_rx) {
idx = i - first_rx; idx = i - first_rx;
rcd = hfi1_rcd_get_by_index(dd, idx); rcd = hfi1_rcd_get_by_index_safe(dd, idx);
if (rcd) { if (rcd) {
/* /*
* Set the interrupt register and mask for this * Set the interrupt register and mask for this
...@@ -13074,7 +13077,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd) ...@@ -13074,7 +13077,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd)
handler = receive_context_interrupt; handler = receive_context_interrupt;
thread = receive_context_thread; thread = receive_context_thread;
arg = rcd; arg = rcd;
snprintf(me->name, sizeof(me->name), snprintf(name, sizeof(name),
DRIVER_NAME "_%d kctxt%d", DRIVER_NAME "_%d kctxt%d",
dd->unit, idx); dd->unit, idx);
err_info = "receive context"; err_info = "receive context";
...@@ -13095,18 +13098,10 @@ static int request_msix_irqs(struct hfi1_devdata *dd) ...@@ -13095,18 +13098,10 @@ static int request_msix_irqs(struct hfi1_devdata *dd)
if (!arg) if (!arg)
continue; continue;
/* make sure the name is terminated */ /* make sure the name is terminated */
me->name[sizeof(me->name) - 1] = 0; name[sizeof(name) - 1] = 0;
me->irq = pci_irq_vector(dd->pcidev, i); me->irq = pci_irq_vector(dd->pcidev, i);
/* ret = pci_request_irq(dd->pcidev, i, handler, thread, arg,
* On err return me->irq. Don't need to clear this name);
* because 'arg' has not been set, and cleanup will
* do the right thing.
*/
if (me->irq < 0)
return me->irq;
ret = request_threaded_irq(me->irq, handler, thread, 0,
me->name, arg);
if (ret) { if (ret) {
dd_dev_err(dd, dd_dev_err(dd,
"unable to allocate %s interrupt, irq %d, index %d, err %d\n", "unable to allocate %s interrupt, irq %d, index %d, err %d\n",
...@@ -13114,7 +13109,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd) ...@@ -13114,7 +13109,7 @@ static int request_msix_irqs(struct hfi1_devdata *dd)
return ret; return ret;
} }
/* /*
* assign arg after request_irq call, so it will be * assign arg after pci_request_irq call, so it will be
* cleaned up * cleaned up
*/ */
me->arg = arg; me->arg = arg;
...@@ -13132,7 +13127,7 @@ void hfi1_vnic_synchronize_irq(struct hfi1_devdata *dd) ...@@ -13132,7 +13127,7 @@ void hfi1_vnic_synchronize_irq(struct hfi1_devdata *dd)
int i; int i;
if (!dd->num_msix_entries) { if (!dd->num_msix_entries) {
synchronize_irq(dd->pcidev->irq); synchronize_irq(pci_irq_vector(dd->pcidev, 0));
return; return;
} }
...@@ -13153,7 +13148,7 @@ void hfi1_reset_vnic_msix_info(struct hfi1_ctxtdata *rcd) ...@@ -13153,7 +13148,7 @@ void hfi1_reset_vnic_msix_info(struct hfi1_ctxtdata *rcd)
return; return;
hfi1_put_irq_affinity(dd, me); hfi1_put_irq_affinity(dd, me);
free_irq(me->irq, me->arg); pci_free_irq(dd->pcidev, rcd->msix_intr, me->arg);
me->arg = NULL; me->arg = NULL;
} }
...@@ -13176,28 +13171,21 @@ void hfi1_set_vnic_msix_info(struct hfi1_ctxtdata *rcd) ...@@ -13176,28 +13171,21 @@ void hfi1_set_vnic_msix_info(struct hfi1_ctxtdata *rcd)
rcd->ireg = (IS_RCVAVAIL_START + idx) / 64; rcd->ireg = (IS_RCVAVAIL_START + idx) / 64;
rcd->imask = ((u64)1) << rcd->imask = ((u64)1) <<
((IS_RCVAVAIL_START + idx) % 64); ((IS_RCVAVAIL_START + idx) % 64);
snprintf(me->name, sizeof(me->name),
DRIVER_NAME "_%d kctxt%d", dd->unit, idx);
me->name[sizeof(me->name) - 1] = 0;
me->type = IRQ_RCVCTXT; me->type = IRQ_RCVCTXT;
me->irq = pci_irq_vector(dd->pcidev, rcd->msix_intr); me->irq = pci_irq_vector(dd->pcidev, rcd->msix_intr);
if (me->irq < 0) {
dd_dev_err(dd, "vnic irq vector request (idx %d) fail %d\n",
idx, me->irq);
return;
}
remap_intr(dd, IS_RCVAVAIL_START + idx, rcd->msix_intr); remap_intr(dd, IS_RCVAVAIL_START + idx, rcd->msix_intr);
ret = request_threaded_irq(me->irq, receive_context_interrupt, ret = pci_request_irq(dd->pcidev, rcd->msix_intr,
receive_context_thread, 0, me->name, arg); receive_context_interrupt,
receive_context_thread, arg,
DRIVER_NAME "_%d kctxt%d", dd->unit, idx);
if (ret) { if (ret) {
dd_dev_err(dd, "vnic irq request (irq %d, idx %d) fail %d\n", dd_dev_err(dd, "vnic irq request (irq %d, idx %d) fail %d\n",
me->irq, idx, ret); me->irq, idx, ret);
return; return;
} }
/* /*
* assign arg after request_irq call, so it will be * assign arg after pci_request_irq call, so it will be
* cleaned up * cleaned up
*/ */
me->arg = arg; me->arg = arg;
...@@ -13206,7 +13194,7 @@ void hfi1_set_vnic_msix_info(struct hfi1_ctxtdata *rcd) ...@@ -13206,7 +13194,7 @@ void hfi1_set_vnic_msix_info(struct hfi1_ctxtdata *rcd)
if (ret) { if (ret) {
dd_dev_err(dd, dd_dev_err(dd,
"unable to pin IRQ %d\n", ret); "unable to pin IRQ %d\n", ret);
free_irq(me->irq, me->arg); pci_free_irq(dd->pcidev, rcd->msix_intr, me->arg);
} }
} }
...@@ -14907,8 +14895,6 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev, ...@@ -14907,8 +14895,6 @@ struct hfi1_devdata *hfi1_init_dd(struct pci_dev *pdev,
init_vl_arb_caches(ppd); init_vl_arb_caches(ppd);
} }
dd->link_default = HLS_DN_POLL;
/* /*
* Do remaining PCIe setup and save PCIe values in dd. * Do remaining PCIe setup and save PCIe values in dd.
* Any error printing is already done by the init code. * Any error printing is already done by the init code.
......
...@@ -243,7 +243,7 @@ static int _ctx_stats_seq_show(struct seq_file *s, void *v) ...@@ -243,7 +243,7 @@ static int _ctx_stats_seq_show(struct seq_file *s, void *v)
spos = v; spos = v;
i = *spos; i = *spos;
rcd = hfi1_rcd_get_by_index(dd, i); rcd = hfi1_rcd_get_by_index_safe(dd, i);
if (!rcd) if (!rcd)
return SEQ_SKIP; return SEQ_SKIP;
...@@ -402,7 +402,7 @@ static int _rcds_seq_show(struct seq_file *s, void *v) ...@@ -402,7 +402,7 @@ static int _rcds_seq_show(struct seq_file *s, void *v)
loff_t *spos = v; loff_t *spos = v;
loff_t i = *spos; loff_t i = *spos;
rcd = hfi1_rcd_get_by_index(dd, i); rcd = hfi1_rcd_get_by_index_safe(dd, i);
if (rcd) if (rcd)
seqfile_dump_rcd(s, rcd); seqfile_dump_rcd(s, rcd);
hfi1_rcd_put(rcd); hfi1_rcd_put(rcd);
......
...@@ -866,7 +866,7 @@ static inline void set_nodma_rtail(struct hfi1_devdata *dd, u16 ctxt) ...@@ -866,7 +866,7 @@ static inline void set_nodma_rtail(struct hfi1_devdata *dd, u16 ctxt)
* interrupt handler for all statically allocated kernel contexts. * interrupt handler for all statically allocated kernel contexts.
*/ */
if (ctxt >= dd->first_dyn_alloc_ctxt) { if (ctxt >= dd->first_dyn_alloc_ctxt) {
rcd = hfi1_rcd_get_by_index(dd, ctxt); rcd = hfi1_rcd_get_by_index_safe(dd, ctxt);
if (rcd) { if (rcd) {
rcd->do_interrupt = rcd->do_interrupt =
&handle_receive_interrupt_nodma_rtail; &handle_receive_interrupt_nodma_rtail;
...@@ -895,7 +895,7 @@ static inline void set_dma_rtail(struct hfi1_devdata *dd, u16 ctxt) ...@@ -895,7 +895,7 @@ static inline void set_dma_rtail(struct hfi1_devdata *dd, u16 ctxt)
* interrupt handler for all statically allocated kernel contexts. * interrupt handler for all statically allocated kernel contexts.
*/ */
if (ctxt >= dd->first_dyn_alloc_ctxt) { if (ctxt >= dd->first_dyn_alloc_ctxt) {
rcd = hfi1_rcd_get_by_index(dd, ctxt); rcd = hfi1_rcd_get_by_index_safe(dd, ctxt);
if (rcd) { if (rcd) {
rcd->do_interrupt = rcd->do_interrupt =
&handle_receive_interrupt_dma_rtail; &handle_receive_interrupt_dma_rtail;
......
...@@ -535,6 +535,8 @@ struct rvt_sge_state; ...@@ -535,6 +535,8 @@ struct rvt_sge_state;
#define HLS_UP (HLS_UP_INIT | HLS_UP_ARMED | HLS_UP_ACTIVE) #define HLS_UP (HLS_UP_INIT | HLS_UP_ARMED | HLS_UP_ACTIVE)
#define HLS_DOWN ~(HLS_UP) #define HLS_DOWN ~(HLS_UP)
#define HLS_DEFAULT HLS_DN_POLL
/* use this MTU size if none other is given */ /* use this MTU size if none other is given */
#define HFI1_DEFAULT_ACTIVE_MTU 10240 #define HFI1_DEFAULT_ACTIVE_MTU 10240
/* use this MTU size as the default maximum */ /* use this MTU size as the default maximum */
...@@ -616,7 +618,6 @@ struct hfi1_msix_entry { ...@@ -616,7 +618,6 @@ struct hfi1_msix_entry {
enum irq_type type; enum irq_type type;
int irq; int irq;
void *arg; void *arg;
char name[MAX_NAME_SIZE];
cpumask_t mask; cpumask_t mask;
struct irq_affinity_notify notify; struct irq_affinity_notify notify;
}; };
...@@ -1109,8 +1110,7 @@ struct hfi1_devdata { ...@@ -1109,8 +1110,7 @@ struct hfi1_devdata {
u16 rcvegrbufsize_shift; u16 rcvegrbufsize_shift;
/* both sides of the PCIe link are gen3 capable */ /* both sides of the PCIe link are gen3 capable */
u8 link_gen3_capable; u8 link_gen3_capable;
/* default link down value (poll/sleep) */ u8 dc_shutdown;
u8 link_default;
/* localbus width (1, 2,4,8,16,32) from config space */ /* localbus width (1, 2,4,8,16,32) from config space */
u32 lbus_width; u32 lbus_width;
/* localbus speed in MHz */ /* localbus speed in MHz */
...@@ -1183,7 +1183,6 @@ struct hfi1_devdata { ...@@ -1183,7 +1183,6 @@ struct hfi1_devdata {
/* INTx information */ /* INTx information */
u32 requested_intx_irq; /* did we request one? */ u32 requested_intx_irq; /* did we request one? */
char intx_name[MAX_NAME_SIZE]; /* INTx name */
/* general interrupt: mask of handled interrupts */ /* general interrupt: mask of handled interrupts */
u64 gi_mask[CCE_NUM_INT_CSRS]; u64 gi_mask[CCE_NUM_INT_CSRS];
...@@ -1295,7 +1294,6 @@ struct hfi1_devdata { ...@@ -1295,7 +1294,6 @@ struct hfi1_devdata {
u8 oui1; u8 oui1;
u8 oui2; u8 oui2;
u8 oui3; u8 oui3;
u8 dc_shutdown;
/* Timer and counter used to detect RcvBufOvflCnt changes */ /* Timer and counter used to detect RcvBufOvflCnt changes */
struct timer_list rcverr_timer; struct timer_list rcverr_timer;
...@@ -1373,8 +1371,12 @@ struct hfi1_filedata { ...@@ -1373,8 +1371,12 @@ struct hfi1_filedata {
extern struct list_head hfi1_dev_list; extern struct list_head hfi1_dev_list;
extern spinlock_t hfi1_devs_lock; extern spinlock_t hfi1_devs_lock;
struct hfi1_devdata *hfi1_lookup(int unit); struct hfi1_devdata *hfi1_lookup(int unit);
extern u32 hfi1_cpulist_count;
extern unsigned long *hfi1_cpulist; static inline unsigned long uctxt_offset(struct hfi1_ctxtdata *uctxt)
{
return (uctxt->ctxt - uctxt->dd->first_dyn_alloc_ctxt) *
HFI1_MAX_SHARED_CTXTS;
}
int hfi1_init(struct hfi1_devdata *dd, int reinit); int hfi1_init(struct hfi1_devdata *dd, int reinit);
int hfi1_count_active_units(void); int hfi1_count_active_units(void);
...@@ -1396,6 +1398,8 @@ void hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd, ...@@ -1396,6 +1398,8 @@ void hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd,
void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd); void hfi1_free_ctxtdata(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd);
int hfi1_rcd_put(struct hfi1_ctxtdata *rcd); int hfi1_rcd_put(struct hfi1_ctxtdata *rcd);
void hfi1_rcd_get(struct hfi1_ctxtdata *rcd); void hfi1_rcd_get(struct hfi1_ctxtdata *rcd);
struct hfi1_ctxtdata *hfi1_rcd_get_by_index_safe(struct hfi1_devdata *dd,
u16 ctxt);
struct hfi1_ctxtdata *hfi1_rcd_get_by_index(struct hfi1_devdata *dd, u16 ctxt); struct hfi1_ctxtdata *hfi1_rcd_get_by_index(struct hfi1_devdata *dd, u16 ctxt);
int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread); int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread);
int handle_receive_interrupt_nodma_rtail(struct hfi1_ctxtdata *rcd, int thread); int handle_receive_interrupt_nodma_rtail(struct hfi1_ctxtdata *rcd, int thread);
......
...@@ -123,8 +123,6 @@ MODULE_PARM_DESC(user_credit_return_threshold, "Credit return threshold for user ...@@ -123,8 +123,6 @@ MODULE_PARM_DESC(user_credit_return_threshold, "Credit return threshold for user
static inline u64 encode_rcv_header_entry_size(u16 size); static inline u64 encode_rcv_header_entry_size(u16 size);
static struct idr hfi1_unit_table; static struct idr hfi1_unit_table;
u32 hfi1_cpulist_count;
unsigned long *hfi1_cpulist;
static int hfi1_create_kctxt(struct hfi1_devdata *dd, static int hfi1_create_kctxt(struct hfi1_devdata *dd,
struct hfi1_pportdata *ppd) struct hfi1_pportdata *ppd)
...@@ -285,6 +283,27 @@ static int allocate_rcd_index(struct hfi1_devdata *dd, ...@@ -285,6 +283,27 @@ static int allocate_rcd_index(struct hfi1_devdata *dd,
return 0; return 0;
} }
/**
* hfi1_rcd_get_by_index_safe - validate the ctxt index before accessing the
* array
* @dd: pointer to a valid devdata structure
* @ctxt: the index of an possilbe rcd
*
* This is a wrapper for hfi1_rcd_get_by_index() to validate that the given
* ctxt index is valid.
*
* The caller is responsible for making the _put().
*
*/
struct hfi1_ctxtdata *hfi1_rcd_get_by_index_safe(struct hfi1_devdata *dd,
u16 ctxt)
{
if (ctxt < dd->num_rcv_contexts)
return hfi1_rcd_get_by_index(dd, ctxt);
return NULL;
}
/** /**
* hfi1_rcd_get_by_index * hfi1_rcd_get_by_index
* @dd: pointer to a valid devdata structure * @dd: pointer to a valid devdata structure
...@@ -1272,39 +1291,21 @@ struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra) ...@@ -1272,39 +1291,21 @@ struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra)
dd->int_counter = alloc_percpu(u64); dd->int_counter = alloc_percpu(u64);
if (!dd->int_counter) { if (!dd->int_counter) {
ret = -ENOMEM; ret = -ENOMEM;
hfi1_early_err(&pdev->dev,
"Could not allocate per-cpu int_counter\n");
goto bail; goto bail;
} }
dd->rcv_limit = alloc_percpu(u64); dd->rcv_limit = alloc_percpu(u64);
if (!dd->rcv_limit) { if (!dd->rcv_limit) {
ret = -ENOMEM; ret = -ENOMEM;
hfi1_early_err(&pdev->dev,
"Could not allocate per-cpu rcv_limit\n");
goto bail; goto bail;
} }
dd->send_schedule = alloc_percpu(u64); dd->send_schedule = alloc_percpu(u64);
if (!dd->send_schedule) { if (!dd->send_schedule) {
ret = -ENOMEM; ret = -ENOMEM;
hfi1_early_err(&pdev->dev,
"Could not allocate per-cpu int_counter\n");
goto bail; goto bail;
} }
if (!hfi1_cpulist_count) {
u32 count = num_online_cpus();
hfi1_cpulist = kcalloc(BITS_TO_LONGS(count), sizeof(long),
GFP_KERNEL);
if (hfi1_cpulist)
hfi1_cpulist_count = count;
else
hfi1_early_err(
&pdev->dev,
"Could not alloc cpulist info, cpu affinity might be wrong\n");
}
kobject_init(&dd->kobj, &hfi1_devdata_type); kobject_init(&dd->kobj, &hfi1_devdata_type);
return dd; return dd;
...@@ -1477,8 +1478,6 @@ static void __exit hfi1_mod_cleanup(void) ...@@ -1477,8 +1478,6 @@ static void __exit hfi1_mod_cleanup(void)
node_affinity_destroy(); node_affinity_destroy();
hfi1_wss_exit(); hfi1_wss_exit();
hfi1_dbg_exit(); hfi1_dbg_exit();
hfi1_cpulist_count = 0;
kfree(hfi1_cpulist);
idr_destroy(&hfi1_unit_table); idr_destroy(&hfi1_unit_table);
dispose_firmware(); /* asymmetric with obtain_firmware() */ dispose_firmware(); /* asymmetric with obtain_firmware() */
......
...@@ -1392,6 +1392,13 @@ int sdma_init(struct hfi1_devdata *dd, u8 port) ...@@ -1392,6 +1392,13 @@ int sdma_init(struct hfi1_devdata *dd, u8 port)
return ret; return ret;
idle_cnt = ns_to_cclock(dd, idle_cnt); idle_cnt = ns_to_cclock(dd, idle_cnt);
if (idle_cnt)
dd->default_desc1 =
SDMA_DESC1_HEAD_TO_HOST_FLAG;
else
dd->default_desc1 =
SDMA_DESC1_INT_REQ_FLAG;
if (!sdma_desct_intr) if (!sdma_desct_intr)
sdma_desct_intr = SDMA_DESC_INTR; sdma_desct_intr = SDMA_DESC_INTR;
...@@ -1436,13 +1443,6 @@ int sdma_init(struct hfi1_devdata *dd, u8 port) ...@@ -1436,13 +1443,6 @@ int sdma_init(struct hfi1_devdata *dd, u8 port)
sde->tail_csr = sde->tail_csr =
get_kctxt_csr_addr(dd, this_idx, SD(TAIL)); get_kctxt_csr_addr(dd, this_idx, SD(TAIL));
if (idle_cnt)
dd->default_desc1 =
SDMA_DESC1_HEAD_TO_HOST_FLAG;
else
dd->default_desc1 =
SDMA_DESC1_INT_REQ_FLAG;
tasklet_init(&sde->sdma_hw_clean_up_task, sdma_hw_clean_up_task, tasklet_init(&sde->sdma_hw_clean_up_task, sdma_hw_clean_up_task,
(unsigned long)sde); (unsigned long)sde);
......
/* /*
* Copyright(c) 2015, 2016 Intel Corporation. * Copyright(c) 2015 - 2017 Intel Corporation.
* *
* This file is provided under a dual BSD/GPLv2 license. When using or * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * redistributing this file, you may do so under either license.
...@@ -91,12 +91,17 @@ u8 hfi1_trace_opa_hdr_len(struct hfi1_opa_header *opa_hdr) ...@@ -91,12 +91,17 @@ u8 hfi1_trace_opa_hdr_len(struct hfi1_opa_header *opa_hdr)
return __get_16b_hdr_len(&opa_hdr->opah); return __get_16b_hdr_len(&opa_hdr->opah);
} }
const char *hfi1_trace_get_packet_str(struct hfi1_packet *packet) const char *hfi1_trace_get_packet_l4_str(u8 l4)
{ {
if (packet->etype != RHF_RCV_TYPE_BYPASS) if (l4)
return "IB"; return "16B";
else
return "9B";
}
switch (hfi1_16B_get_l2(packet->hdr)) { const char *hfi1_trace_get_packet_l2_str(u8 l2)
{
switch (l2) {
case 0: case 0:
return "0"; return "0";
case 1: case 1:
...@@ -109,14 +114,6 @@ const char *hfi1_trace_get_packet_str(struct hfi1_packet *packet) ...@@ -109,14 +114,6 @@ const char *hfi1_trace_get_packet_str(struct hfi1_packet *packet)
return ""; return "";
} }
const char *hfi1_trace_get_packet_type_str(u8 l4)
{
if (l4)
return "16B";
else
return "9B";
}
#define IMM_PRN "imm:%d" #define IMM_PRN "imm:%d"
#define RETH_PRN "reth vaddr:0x%.16llx rkey:0x%.8x dlen:0x%.8x" #define RETH_PRN "reth vaddr:0x%.16llx rkey:0x%.8x dlen:0x%.8x"
#define AETH_PRN "aeth syn:0x%.2x %s msn:0x%.8x" #define AETH_PRN "aeth syn:0x%.2x %s msn:0x%.8x"
......
...@@ -44,6 +44,16 @@ ...@@ -44,6 +44,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
#define packettype_name(etype) { RHF_RCV_TYPE_##etype, #etype }
#define show_packettype(etype) \
__print_symbolic(etype, \
packettype_name(EXPECTED), \
packettype_name(EAGER), \
packettype_name(IB), \
packettype_name(ERROR), \
packettype_name(BYPASS))
#include "trace_dbg.h" #include "trace_dbg.h"
#include "trace_misc.h" #include "trace_misc.h"
#include "trace_ctxts.h" #include "trace_ctxts.h"
......
/* /*
* Copyright(c) 2015, 2016 Intel Corporation. * Copyright(c) 2015 - 2017 Intel Corporation.
* *
* This file is provided under a dual BSD/GPLv2 license. When using or * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * redistributing this file, you may do so under either license.
...@@ -99,8 +99,7 @@ u8 ibhdr_exhdr_len(struct ib_header *hdr); ...@@ -99,8 +99,7 @@ u8 ibhdr_exhdr_len(struct ib_header *hdr);
const char *parse_everbs_hdrs(struct trace_seq *p, u8 opcode, void *ehdrs); const char *parse_everbs_hdrs(struct trace_seq *p, u8 opcode, void *ehdrs);
u8 hfi1_trace_opa_hdr_len(struct hfi1_opa_header *opah); u8 hfi1_trace_opa_hdr_len(struct hfi1_opa_header *opah);
u8 hfi1_trace_packet_hdr_len(struct hfi1_packet *packet); u8 hfi1_trace_packet_hdr_len(struct hfi1_packet *packet);
const char *hfi1_trace_get_packet_type_str(u8 l4); const char *hfi1_trace_get_packet_l4_str(u8 l4);
const char *hfi1_trace_get_packet_str(struct hfi1_packet *packet);
void hfi1_trace_parse_9b_bth(struct ib_other_headers *ohdr, void hfi1_trace_parse_9b_bth(struct ib_other_headers *ohdr,
u8 *ack, u8 *becn, u8 *fecn, u8 *mig, u8 *ack, u8 *becn, u8 *fecn, u8 *mig,
u8 *se, u8 *pad, u8 *opcode, u8 *tver, u8 *se, u8 *pad, u8 *opcode, u8 *tver,
...@@ -129,6 +128,8 @@ const char *hfi1_trace_fmt_bth(struct trace_seq *p, bool bypass, ...@@ -129,6 +128,8 @@ const char *hfi1_trace_fmt_bth(struct trace_seq *p, bool bypass,
u8 se, u8 pad, u8 opcode, const char *opname, u8 se, u8 pad, u8 opcode, const char *opname,
u8 tver, u16 pkey, u32 psn, u32 qpn); u8 tver, u16 pkey, u32 psn, u32 qpn);
const char *hfi1_trace_get_packet_l2_str(u8 l2);
#define __parse_ib_ehdrs(op, ehdrs) parse_everbs_hdrs(p, op, ehdrs) #define __parse_ib_ehdrs(op, ehdrs) parse_everbs_hdrs(p, op, ehdrs)
#define lrh_name(lrh) { HFI1_##lrh, #lrh } #define lrh_name(lrh) { HFI1_##lrh, #lrh }
...@@ -136,8 +137,6 @@ const char *hfi1_trace_fmt_bth(struct trace_seq *p, bool bypass, ...@@ -136,8 +137,6 @@ const char *hfi1_trace_fmt_bth(struct trace_seq *p, bool bypass,
__print_symbolic(lrh, \ __print_symbolic(lrh, \
lrh_name(LRH_BTH), \ lrh_name(LRH_BTH), \
lrh_name(LRH_GRH)) lrh_name(LRH_GRH))
#define PKT_ENTRY(pkt) __string(ptype, hfi1_trace_get_packet_str(packet))
#define PKT_ASSIGN(pkt) __assign_str(ptype, hfi1_trace_get_packet_str(packet))
DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template, DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template,
TP_PROTO(struct hfi1_devdata *dd, TP_PROTO(struct hfi1_devdata *dd,
...@@ -146,12 +145,12 @@ DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template, ...@@ -146,12 +145,12 @@ DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template,
TP_ARGS(dd, packet, sc5), TP_ARGS(dd, packet, sc5),
TP_STRUCT__entry( TP_STRUCT__entry(
DD_DEV_ENTRY(dd) DD_DEV_ENTRY(dd)
PKT_ENTRY(packet) __field(u8, etype)
__field(bool, bypass)
__field(u8, ack) __field(u8, ack)
__field(u8, age) __field(u8, age)
__field(u8, becn) __field(u8, becn)
__field(u8, fecn) __field(u8, fecn)
__field(u8, l2)
__field(u8, l4) __field(u8, l4)
__field(u8, lnh) __field(u8, lnh)
__field(u8, lver) __field(u8, lver)
...@@ -176,10 +175,10 @@ DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template, ...@@ -176,10 +175,10 @@ DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template,
), ),
TP_fast_assign( TP_fast_assign(
DD_DEV_ASSIGN(dd); DD_DEV_ASSIGN(dd);
PKT_ASSIGN(packet);
if (packet->etype == RHF_RCV_TYPE_BYPASS) { __entry->etype = packet->etype;
__entry->bypass = true; __entry->l2 = hfi1_16B_get_l2(packet->hdr);
if (__entry->etype == RHF_RCV_TYPE_BYPASS) {
hfi1_trace_parse_16b_hdr(packet->hdr, hfi1_trace_parse_16b_hdr(packet->hdr,
&__entry->age, &__entry->age,
&__entry->becn, &__entry->becn,
...@@ -203,7 +202,6 @@ DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template, ...@@ -203,7 +202,6 @@ DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template,
&__entry->psn, &__entry->psn,
&__entry->qpn); &__entry->qpn);
} else { } else {
__entry->bypass = false;
hfi1_trace_parse_9b_hdr(packet->hdr, sc5, hfi1_trace_parse_9b_hdr(packet->hdr, sc5,
&__entry->lnh, &__entry->lnh,
&__entry->lver, &__entry->lver,
...@@ -233,9 +231,13 @@ DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template, ...@@ -233,9 +231,13 @@ DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template,
), ),
TP_printk("[%s] (%s) %s %s hlen:%d %s", TP_printk("[%s] (%s) %s %s hlen:%d %s",
__get_str(dev), __get_str(dev),
__get_str(ptype), __entry->etype != RHF_RCV_TYPE_BYPASS ?
show_packettype(__entry->etype) :
hfi1_trace_get_packet_l2_str(
__entry->l2),
hfi1_trace_fmt_lrh(p, hfi1_trace_fmt_lrh(p,
__entry->bypass, __entry->etype ==
RHF_RCV_TYPE_BYPASS,
__entry->age, __entry->age,
__entry->becn, __entry->becn,
__entry->fecn, __entry->fecn,
...@@ -252,7 +254,8 @@ DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template, ...@@ -252,7 +254,8 @@ DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template,
__entry->dlid, __entry->dlid,
__entry->slid), __entry->slid),
hfi1_trace_fmt_bth(p, hfi1_trace_fmt_bth(p,
__entry->bypass, __entry->etype ==
RHF_RCV_TYPE_BYPASS,
__entry->ack, __entry->ack,
__entry->becn, __entry->becn,
__entry->fecn, __entry->fecn,
...@@ -284,7 +287,7 @@ DECLARE_EVENT_CLASS(hfi1_output_ibhdr_template, ...@@ -284,7 +287,7 @@ DECLARE_EVENT_CLASS(hfi1_output_ibhdr_template,
TP_ARGS(dd, opah, sc5), TP_ARGS(dd, opah, sc5),
TP_STRUCT__entry( TP_STRUCT__entry(
DD_DEV_ENTRY(dd) DD_DEV_ENTRY(dd)
__field(bool, bypass) __field(u8, hdr_type)
__field(u8, ack) __field(u8, ack)
__field(u8, age) __field(u8, age)
__field(u8, becn) __field(u8, becn)
...@@ -316,8 +319,8 @@ DECLARE_EVENT_CLASS(hfi1_output_ibhdr_template, ...@@ -316,8 +319,8 @@ DECLARE_EVENT_CLASS(hfi1_output_ibhdr_template,
DD_DEV_ASSIGN(dd); DD_DEV_ASSIGN(dd);
if (opah->hdr_type) { __entry->hdr_type = opah->hdr_type;
__entry->bypass = true; if (__entry->hdr_type) {
hfi1_trace_parse_16b_hdr(&opah->opah, hfi1_trace_parse_16b_hdr(&opah->opah,
&__entry->age, &__entry->age,
&__entry->becn, &__entry->becn,
...@@ -345,7 +348,6 @@ DECLARE_EVENT_CLASS(hfi1_output_ibhdr_template, ...@@ -345,7 +348,6 @@ DECLARE_EVENT_CLASS(hfi1_output_ibhdr_template,
&__entry->psn, &__entry->psn,
&__entry->qpn); &__entry->qpn);
} else { } else {
__entry->bypass = false;
hfi1_trace_parse_9b_hdr(&opah->ibh, sc5, hfi1_trace_parse_9b_hdr(&opah->ibh, sc5,
&__entry->lnh, &__entry->lnh,
&__entry->lver, &__entry->lver,
...@@ -378,9 +380,9 @@ DECLARE_EVENT_CLASS(hfi1_output_ibhdr_template, ...@@ -378,9 +380,9 @@ DECLARE_EVENT_CLASS(hfi1_output_ibhdr_template,
), ),
TP_printk("[%s] (%s) %s %s hlen:%d %s", TP_printk("[%s] (%s) %s %s hlen:%d %s",
__get_str(dev), __get_str(dev),
hfi1_trace_get_packet_type_str(__entry->l4), hfi1_trace_get_packet_l4_str(__entry->l4),
hfi1_trace_fmt_lrh(p, hfi1_trace_fmt_lrh(p,
__entry->bypass, !!__entry->hdr_type,
__entry->age, __entry->age,
__entry->becn, __entry->becn,
__entry->fecn, __entry->fecn,
...@@ -397,7 +399,7 @@ DECLARE_EVENT_CLASS(hfi1_output_ibhdr_template, ...@@ -397,7 +399,7 @@ DECLARE_EVENT_CLASS(hfi1_output_ibhdr_template,
__entry->dlid, __entry->dlid,
__entry->slid), __entry->slid),
hfi1_trace_fmt_bth(p, hfi1_trace_fmt_bth(p,
__entry->bypass, !!__entry->hdr_type,
__entry->ack, __entry->ack,
__entry->becn, __entry->becn,
__entry->fecn, __entry->fecn,
......
/* /*
* Copyright(c) 2015, 2016 Intel Corporation. * Copyright(c) 2015 - 2017 Intel Corporation.
* *
* This file is provided under a dual BSD/GPLv2 license. When using or * This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license. * redistributing this file, you may do so under either license.
...@@ -62,15 +62,6 @@ __print_symbolic(type, \ ...@@ -62,15 +62,6 @@ __print_symbolic(type, \
#undef TRACE_SYSTEM #undef TRACE_SYSTEM
#define TRACE_SYSTEM hfi1_rx #define TRACE_SYSTEM hfi1_rx
#define packettype_name(etype) { RHF_RCV_TYPE_##etype, #etype }
#define show_packettype(etype) \
__print_symbolic(etype, \
packettype_name(EXPECTED), \
packettype_name(EAGER), \
packettype_name(IB), \
packettype_name(ERROR), \
packettype_name(BYPASS))
TRACE_EVENT(hfi1_rcvhdr, TRACE_EVENT(hfi1_rcvhdr,
TP_PROTO(struct hfi1_devdata *dd, TP_PROTO(struct hfi1_devdata *dd,
u32 ctxt, u32 ctxt,
......
...@@ -542,14 +542,10 @@ int hfi1_user_exp_rcv_invalid(struct hfi1_filedata *fd, ...@@ -542,14 +542,10 @@ int hfi1_user_exp_rcv_invalid(struct hfi1_filedata *fd,
{ {
struct hfi1_ctxtdata *uctxt = fd->uctxt; struct hfi1_ctxtdata *uctxt = fd->uctxt;
unsigned long *ev = uctxt->dd->events + unsigned long *ev = uctxt->dd->events +
(((uctxt->ctxt - uctxt->dd->first_dyn_alloc_ctxt) * (uctxt_offset(uctxt) + fd->subctxt);
HFI1_MAX_SHARED_CTXTS) + fd->subctxt);
u32 *array; u32 *array;
int ret = 0; int ret = 0;
if (!fd->invalid_tids)
return -EINVAL;
/* /*
* copy_to_user() can sleep, which will leave the invalid_lock * copy_to_user() can sleep, which will leave the invalid_lock
* locked and cause the MMU notifier to be blocked on the lock * locked and cause the MMU notifier to be blocked on the lock
...@@ -942,8 +938,7 @@ static int tid_rb_invalidate(void *arg, struct mmu_rb_node *mnode) ...@@ -942,8 +938,7 @@ static int tid_rb_invalidate(void *arg, struct mmu_rb_node *mnode)
* process in question. * process in question.
*/ */
ev = uctxt->dd->events + ev = uctxt->dd->events +
(((uctxt->ctxt - uctxt->dd->first_dyn_alloc_ctxt) * (uctxt_offset(uctxt) + fdata->subctxt);
HFI1_MAX_SHARED_CTXTS) + fdata->subctxt);
set_bit(_HFI1_EVENT_TID_MMU_NOTIFY_BIT, ev); set_bit(_HFI1_EVENT_TID_MMU_NOTIFY_BIT, ev);
} }
fdata->invalid_tid_idx++; fdata->invalid_tid_idx++;
......
...@@ -956,10 +956,8 @@ static int pin_sdma_pages(struct user_sdma_request *req, ...@@ -956,10 +956,8 @@ static int pin_sdma_pages(struct user_sdma_request *req,
struct hfi1_user_sdma_pkt_q *pq = req->pq; struct hfi1_user_sdma_pkt_q *pq = req->pq;
pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL); pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
if (!pages) { if (!pages)
SDMA_DBG(req, "Failed page array alloc");
return -ENOMEM; return -ENOMEM;
}
memcpy(pages, node->pages, node->npages * sizeof(*pages)); memcpy(pages, node->pages, node->npages * sizeof(*pages));
npages -= node->npages; npages -= node->npages;
...@@ -1254,20 +1252,25 @@ static int set_txreq_header_ahg(struct user_sdma_request *req, ...@@ -1254,20 +1252,25 @@ static int set_txreq_header_ahg(struct user_sdma_request *req,
struct user_sdma_txreq *tx, u32 datalen) struct user_sdma_txreq *tx, u32 datalen)
{ {
u32 ahg[AHG_KDETH_ARRAY_SIZE]; u32 ahg[AHG_KDETH_ARRAY_SIZE];
int diff = 0; int idx = 0;
u8 omfactor; /* KDETH.OM */ u8 omfactor; /* KDETH.OM */
struct hfi1_user_sdma_pkt_q *pq = req->pq; struct hfi1_user_sdma_pkt_q *pq = req->pq;
struct hfi1_pkt_header *hdr = &req->hdr; struct hfi1_pkt_header *hdr = &req->hdr;
u16 pbclen = le16_to_cpu(hdr->pbc[0]); u16 pbclen = le16_to_cpu(hdr->pbc[0]);
u32 val32, tidval = 0, lrhlen = get_lrh_len(*hdr, pad_len(datalen)); u32 val32, tidval = 0, lrhlen = get_lrh_len(*hdr, pad_len(datalen));
size_t array_size = ARRAY_SIZE(ahg);
if (PBC2LRH(pbclen) != lrhlen) { if (PBC2LRH(pbclen) != lrhlen) {
/* PBC.PbcLengthDWs */ /* PBC.PbcLengthDWs */
AHG_HEADER_SET(ahg, diff, 0, 0, 12, idx = ahg_header_set(ahg, idx, array_size, 0, 0, 12,
cpu_to_le16(LRH2PBC(lrhlen))); (__force u16)cpu_to_le16(LRH2PBC(lrhlen)));
if (idx < 0)
return idx;
/* LRH.PktLen (we need the full 16 bits due to byte swap) */ /* LRH.PktLen (we need the full 16 bits due to byte swap) */
AHG_HEADER_SET(ahg, diff, 3, 0, 16, idx = ahg_header_set(ahg, idx, array_size, 3, 0, 16,
cpu_to_be16(lrhlen >> 2)); (__force u16)cpu_to_be16(lrhlen >> 2));
if (idx < 0)
return idx;
} }
/* /*
...@@ -1278,12 +1281,23 @@ static int set_txreq_header_ahg(struct user_sdma_request *req, ...@@ -1278,12 +1281,23 @@ static int set_txreq_header_ahg(struct user_sdma_request *req,
(HFI1_CAP_IS_KSET(EXTENDED_PSN) ? 0x7fffffff : 0xffffff); (HFI1_CAP_IS_KSET(EXTENDED_PSN) ? 0x7fffffff : 0xffffff);
if (unlikely(tx->flags & TXREQ_FLAGS_REQ_ACK)) if (unlikely(tx->flags & TXREQ_FLAGS_REQ_ACK))
val32 |= 1UL << 31; val32 |= 1UL << 31;
AHG_HEADER_SET(ahg, diff, 6, 0, 16, cpu_to_be16(val32 >> 16)); idx = ahg_header_set(ahg, idx, array_size, 6, 0, 16,
AHG_HEADER_SET(ahg, diff, 6, 16, 16, cpu_to_be16(val32 & 0xffff)); (__force u16)cpu_to_be16(val32 >> 16));
if (idx < 0)
return idx;
idx = ahg_header_set(ahg, idx, array_size, 6, 16, 16,
(__force u16)cpu_to_be16(val32 & 0xffff));
if (idx < 0)
return idx;
/* KDETH.Offset */ /* KDETH.Offset */
AHG_HEADER_SET(ahg, diff, 15, 0, 16, idx = ahg_header_set(ahg, idx, array_size, 15, 0, 16,
cpu_to_le16(req->koffset & 0xffff)); (__force u16)cpu_to_le16(req->koffset & 0xffff));
AHG_HEADER_SET(ahg, diff, 15, 16, 16, cpu_to_le16(req->koffset >> 16)); if (idx < 0)
return idx;
idx = ahg_header_set(ahg, idx, array_size, 15, 16, 16,
(__force u16)cpu_to_le16(req->koffset >> 16));
if (idx < 0)
return idx;
if (req_opcode(req->info.ctrl) == EXPECTED) { if (req_opcode(req->info.ctrl) == EXPECTED) {
__le16 val; __le16 val;
...@@ -1310,10 +1324,13 @@ static int set_txreq_header_ahg(struct user_sdma_request *req, ...@@ -1310,10 +1324,13 @@ static int set_txreq_header_ahg(struct user_sdma_request *req,
KDETH_OM_MAX_SIZE) ? KDETH_OM_LARGE_SHIFT : KDETH_OM_MAX_SIZE) ? KDETH_OM_LARGE_SHIFT :
KDETH_OM_SMALL_SHIFT; KDETH_OM_SMALL_SHIFT;
/* KDETH.OM and KDETH.OFFSET (TID) */ /* KDETH.OM and KDETH.OFFSET (TID) */
AHG_HEADER_SET(ahg, diff, 7, 0, 16, idx = ahg_header_set(
((!!(omfactor - KDETH_OM_SMALL_SHIFT)) << 15 | ahg, idx, array_size, 7, 0, 16,
((!!(omfactor - KDETH_OM_SMALL_SHIFT)) << 15 |
((req->tidoffset >> omfactor) ((req->tidoffset >> omfactor)
& 0x7fff))); & 0x7fff)));
if (idx < 0)
return idx;
/* KDETH.TIDCtrl, KDETH.TID, KDETH.Intr, KDETH.SH */ /* KDETH.TIDCtrl, KDETH.TID, KDETH.Intr, KDETH.SH */
val = cpu_to_le16(((EXP_TID_GET(tidval, CTRL) & 0x3) << 10) | val = cpu_to_le16(((EXP_TID_GET(tidval, CTRL) & 0x3) << 10) |
(EXP_TID_GET(tidval, IDX) & 0x3ff)); (EXP_TID_GET(tidval, IDX) & 0x3ff));
...@@ -1330,21 +1347,22 @@ static int set_txreq_header_ahg(struct user_sdma_request *req, ...@@ -1330,21 +1347,22 @@ static int set_txreq_header_ahg(struct user_sdma_request *req,
AHG_KDETH_INTR_SHIFT)); AHG_KDETH_INTR_SHIFT));
} }
AHG_HEADER_SET(ahg, diff, 7, 16, 14, val); idx = ahg_header_set(ahg, idx, array_size,
7, 16, 14, (__force u16)val);
if (idx < 0)
return idx;
} }
if (diff < 0)
return diff;
trace_hfi1_sdma_user_header_ahg(pq->dd, pq->ctxt, pq->subctxt, trace_hfi1_sdma_user_header_ahg(pq->dd, pq->ctxt, pq->subctxt,
req->info.comp_idx, req->sde->this_idx, req->info.comp_idx, req->sde->this_idx,
req->ahg_idx, ahg, diff, tidval); req->ahg_idx, ahg, idx, tidval);
sdma_txinit_ahg(&tx->txreq, sdma_txinit_ahg(&tx->txreq,
SDMA_TXREQ_F_USE_AHG, SDMA_TXREQ_F_USE_AHG,
datalen, req->ahg_idx, diff, datalen, req->ahg_idx, idx,
ahg, sizeof(req->hdr), ahg, sizeof(req->hdr),
user_sdma_txreq_cb); user_sdma_txreq_cb);
return diff; return idx;
} }
/* /*
......
...@@ -80,15 +80,26 @@ ...@@ -80,15 +80,26 @@
#define PBC2LRH(x) ((((x) & 0xfff) << 2) - 4) #define PBC2LRH(x) ((((x) & 0xfff) << 2) - 4)
#define LRH2PBC(x) ((((x) >> 2) + 1) & 0xfff) #define LRH2PBC(x) ((((x) >> 2) + 1) & 0xfff)
#define AHG_HEADER_SET(arr, idx, dw, bit, width, value) \ /**
do { \ * Build an SDMA AHG header update descriptor and save it to an array.
if ((idx) < ARRAY_SIZE((arr))) \ * @arr - Array to save the descriptor to.
(arr)[(idx++)] = sdma_build_ahg_descriptor( \ * @idx - Index of the array at which the descriptor will be saved.
(__force u16)(value), (dw), (bit), \ * @array_size - Size of the array arr.
(width)); \ * @dw - Update index into the header in DWs.
else \ * @bit - Start bit.
return -ERANGE; \ * @width - Field width.
} while (0) * @value - 16 bits of immediate data to write into the field.
* Returns -ERANGE if idx is invalid. If successful, returns the next index
* (idx + 1) of the array to be used for the next descriptor.
*/
static inline int ahg_header_set(u32 *arr, int idx, size_t array_size,
u8 dw, u8 bit, u8 width, u16 value)
{
if ((size_t)idx >= array_size)
return -ERANGE;
arr[idx++] = sdma_build_ahg_descriptor(value, dw, bit, width);
return idx;
}
/* Tx request flag bits */ /* Tx request flag bits */
#define TXREQ_FLAGS_REQ_ACK BIT(0) /* Set the ACK bit in the header */ #define TXREQ_FLAGS_REQ_ACK BIT(0) /* Set the ACK bit in the header */
......
...@@ -443,14 +443,12 @@ struct qib_irq_notify; ...@@ -443,14 +443,12 @@ struct qib_irq_notify;
#endif #endif
struct qib_msix_entry { struct qib_msix_entry {
int irq;
void *arg; void *arg;
#ifdef CONFIG_INFINIBAND_QIB_DCA #ifdef CONFIG_INFINIBAND_QIB_DCA
int dca; int dca;
int rcv; int rcv;
struct qib_irq_notify *notifier; struct qib_irq_notify *notifier;
#endif #endif
char name[MAX_NAME_SIZE];
cpumask_var_t mask; cpumask_var_t mask;
}; };
...@@ -1434,10 +1432,8 @@ int qib_pcie_ddinit(struct qib_devdata *, struct pci_dev *, ...@@ -1434,10 +1432,8 @@ int qib_pcie_ddinit(struct qib_devdata *, struct pci_dev *,
const struct pci_device_id *); const struct pci_device_id *);
void qib_pcie_ddcleanup(struct qib_devdata *); void qib_pcie_ddcleanup(struct qib_devdata *);
int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent); int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent);
int qib_reinit_intr(struct qib_devdata *); void qib_free_irq(struct qib_devdata *dd);
void qib_enable_intx(struct qib_devdata *dd); int qib_reinit_intr(struct qib_devdata *dd);
void qib_nomsi(struct qib_devdata *);
void qib_nomsix(struct qib_devdata *);
void qib_pcie_getcmd(struct qib_devdata *, u16 *, u8 *, u8 *); void qib_pcie_getcmd(struct qib_devdata *, u16 *, u8 *, u8 *);
void qib_pcie_reenable(struct qib_devdata *, u16, u8, u8); void qib_pcie_reenable(struct qib_devdata *, u16, u8, u8);
/* interrupts for device */ /* interrupts for device */
......
...@@ -67,7 +67,6 @@ struct qib_chip_specific { ...@@ -67,7 +67,6 @@ struct qib_chip_specific {
u32 lastbuf_for_pio; u32 lastbuf_for_pio;
u32 updthresh; /* current AvailUpdThld */ u32 updthresh; /* current AvailUpdThld */
u32 updthresh_dflt; /* default AvailUpdThld */ u32 updthresh_dflt; /* default AvailUpdThld */
int irq;
u8 presets_needed; u8 presets_needed;
u8 relock_timer_active; u8 relock_timer_active;
char emsgbuf[128]; char emsgbuf[128];
......
...@@ -245,7 +245,6 @@ struct qib_chip_specific { ...@@ -245,7 +245,6 @@ struct qib_chip_specific {
u64 iblnkerrsnap; u64 iblnkerrsnap;
u64 ibcctrl; /* shadow for kr_ibcctrl */ u64 ibcctrl; /* shadow for kr_ibcctrl */
u32 lastlinkrecov; /* link recovery issue */ u32 lastlinkrecov; /* link recovery issue */
int irq;
u32 cntrnamelen; u32 cntrnamelen;
u32 portcntrnamelen; u32 portcntrnamelen;
u32 ncntrs; u32 ncntrs;
...@@ -1485,15 +1484,6 @@ static void qib_6120_setup_setextled(struct qib_pportdata *ppd, u32 on) ...@@ -1485,15 +1484,6 @@ static void qib_6120_setup_setextled(struct qib_pportdata *ppd, u32 on)
spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags); spin_unlock_irqrestore(&dd->cspec->gpio_lock, flags);
} }
static void qib_6120_free_irq(struct qib_devdata *dd)
{
if (dd->cspec->irq) {
free_irq(dd->cspec->irq, dd);
dd->cspec->irq = 0;
}
qib_nomsi(dd);
}
/** /**
* qib_6120_setup_cleanup - clean up any per-chip chip-specific stuff * qib_6120_setup_cleanup - clean up any per-chip chip-specific stuff
* @dd: the qlogic_ib device * @dd: the qlogic_ib device
...@@ -1502,7 +1492,7 @@ static void qib_6120_free_irq(struct qib_devdata *dd) ...@@ -1502,7 +1492,7 @@ static void qib_6120_free_irq(struct qib_devdata *dd)
*/ */
static void qib_6120_setup_cleanup(struct qib_devdata *dd) static void qib_6120_setup_cleanup(struct qib_devdata *dd)
{ {
qib_6120_free_irq(dd); qib_free_irq(dd);
kfree(dd->cspec->cntrs); kfree(dd->cspec->cntrs);
kfree(dd->cspec->portcntrs); kfree(dd->cspec->portcntrs);
if (dd->cspec->dummy_hdrq) { if (dd->cspec->dummy_hdrq) {
...@@ -1706,6 +1696,8 @@ static irqreturn_t qib_6120intr(int irq, void *data) ...@@ -1706,6 +1696,8 @@ static irqreturn_t qib_6120intr(int irq, void *data)
*/ */
static void qib_setup_6120_interrupt(struct qib_devdata *dd) static void qib_setup_6120_interrupt(struct qib_devdata *dd)
{ {
int ret;
/* /*
* If the chip supports added error indication via GPIO pins, * If the chip supports added error indication via GPIO pins,
* enable interrupts on those bits so the interrupt routine * enable interrupts on those bits so the interrupt routine
...@@ -1719,19 +1711,12 @@ static void qib_setup_6120_interrupt(struct qib_devdata *dd) ...@@ -1719,19 +1711,12 @@ static void qib_setup_6120_interrupt(struct qib_devdata *dd)
qib_write_kreg(dd, kr_gpio_mask, dd->cspec->gpio_mask); qib_write_kreg(dd, kr_gpio_mask, dd->cspec->gpio_mask);
} }
if (!dd->cspec->irq) ret = pci_request_irq(dd->pcidev, 0, qib_6120intr, NULL, dd,
QIB_DRV_NAME);
if (ret)
qib_dev_err(dd, qib_dev_err(dd,
"irq is 0, BIOS error? Interrupts won't work\n"); "Couldn't setup interrupt (irq=%d): %d\n",
else { pci_irq_vector(dd->pcidev, 0), ret);
int ret;
ret = request_irq(dd->cspec->irq, qib_6120intr, 0,
QIB_DRV_NAME, dd);
if (ret)
qib_dev_err(dd,
"Couldn't setup interrupt (irq=%d): %d\n",
dd->cspec->irq, ret);
}
} }
/** /**
...@@ -3490,7 +3475,7 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev, ...@@ -3490,7 +3475,7 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev,
dd->f_bringup_serdes = qib_6120_bringup_serdes; dd->f_bringup_serdes = qib_6120_bringup_serdes;
dd->f_cleanup = qib_6120_setup_cleanup; dd->f_cleanup = qib_6120_setup_cleanup;
dd->f_clear_tids = qib_6120_clear_tids; dd->f_clear_tids = qib_6120_clear_tids;
dd->f_free_irq = qib_6120_free_irq; dd->f_free_irq = qib_free_irq;
dd->f_get_base_info = qib_6120_get_base_info; dd->f_get_base_info = qib_6120_get_base_info;
dd->f_get_msgheader = qib_6120_get_msgheader; dd->f_get_msgheader = qib_6120_get_msgheader;
dd->f_getsendbuf = qib_6120_getsendbuf; dd->f_getsendbuf = qib_6120_getsendbuf;
...@@ -3559,8 +3544,6 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev, ...@@ -3559,8 +3544,6 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev,
if (qib_pcie_params(dd, 8, NULL)) if (qib_pcie_params(dd, 8, NULL))
qib_dev_err(dd, qib_dev_err(dd,
"Failed to setup PCIe or interrupts; continuing anyway\n"); "Failed to setup PCIe or interrupts; continuing anyway\n");
dd->cspec->irq = pdev->irq; /* save IRQ */
/* clear diagctrl register, in case diags were running and crashed */ /* clear diagctrl register, in case diags were running and crashed */
qib_write_kreg(dd, kr_hwdiagctrl, 0); qib_write_kreg(dd, kr_hwdiagctrl, 0);
......
...@@ -1780,15 +1780,6 @@ static void qib_setup_7220_setextled(struct qib_pportdata *ppd, u32 on) ...@@ -1780,15 +1780,6 @@ static void qib_setup_7220_setextled(struct qib_pportdata *ppd, u32 on)
qib_write_kreg(dd, kr_rcvpktledcnt, ledblink); qib_write_kreg(dd, kr_rcvpktledcnt, ledblink);
} }
static void qib_7220_free_irq(struct qib_devdata *dd)
{
if (dd->cspec->irq) {
free_irq(dd->cspec->irq, dd);
dd->cspec->irq = 0;
}
qib_nomsi(dd);
}
/* /*
* qib_setup_7220_cleanup - clean up any per-chip chip-specific stuff * qib_setup_7220_cleanup - clean up any per-chip chip-specific stuff
* @dd: the qlogic_ib device * @dd: the qlogic_ib device
...@@ -1798,7 +1789,7 @@ static void qib_7220_free_irq(struct qib_devdata *dd) ...@@ -1798,7 +1789,7 @@ static void qib_7220_free_irq(struct qib_devdata *dd)
*/ */
static void qib_setup_7220_cleanup(struct qib_devdata *dd) static void qib_setup_7220_cleanup(struct qib_devdata *dd)
{ {
qib_7220_free_irq(dd); qib_free_irq(dd);
kfree(dd->cspec->cntrs); kfree(dd->cspec->cntrs);
kfree(dd->cspec->portcntrs); kfree(dd->cspec->portcntrs);
} }
...@@ -2026,20 +2017,14 @@ static irqreturn_t qib_7220intr(int irq, void *data) ...@@ -2026,20 +2017,14 @@ static irqreturn_t qib_7220intr(int irq, void *data)
*/ */
static void qib_setup_7220_interrupt(struct qib_devdata *dd) static void qib_setup_7220_interrupt(struct qib_devdata *dd)
{ {
if (!dd->cspec->irq) int ret;
qib_dev_err(dd,
"irq is 0, BIOS error? Interrupts won't work\n");
else {
int ret = request_irq(dd->cspec->irq, qib_7220intr,
dd->msi_lo ? 0 : IRQF_SHARED,
QIB_DRV_NAME, dd);
if (ret) ret = pci_request_irq(dd->pcidev, 0, qib_7220intr, NULL, dd,
qib_dev_err(dd, QIB_DRV_NAME);
"Couldn't setup %s interrupt (irq=%d): %d\n", if (ret)
dd->msi_lo ? "MSI" : "INTx", qib_dev_err(dd, "Couldn't setup %s interrupt (irq=%d): %d\n",
dd->cspec->irq, ret); dd->pcidev->msi_enabled ? "MSI" : "INTx",
} pci_irq_vector(dd->pcidev, 0), ret);
} }
/** /**
...@@ -3302,16 +3287,12 @@ static int qib_7220_intr_fallback(struct qib_devdata *dd) ...@@ -3302,16 +3287,12 @@ static int qib_7220_intr_fallback(struct qib_devdata *dd)
return 0; return 0;
qib_devinfo(dd->pcidev, qib_devinfo(dd->pcidev,
"MSI interrupt not detected, trying INTx interrupts\n"); "MSI interrupt not detected, trying INTx interrupts\n");
qib_7220_free_irq(dd);
qib_enable_intx(dd); qib_free_irq(dd);
/* dd->msi_lo = 0;
* Some newer kernels require free_irq before disable_msi, if (pci_alloc_irq_vectors(dd->pcidev, 1, 1, PCI_IRQ_LEGACY) < 0)
* and irq can be changed during disable and INTx enable qib_dev_err(dd, "Failed to enable INTx\n");
* and we need to therefore use the pcidev->irq value,
* not our saved MSI value.
*/
dd->cspec->irq = dd->pcidev->irq;
qib_setup_7220_interrupt(dd); qib_setup_7220_interrupt(dd);
return 1; return 1;
} }
...@@ -4535,7 +4516,7 @@ struct qib_devdata *qib_init_iba7220_funcs(struct pci_dev *pdev, ...@@ -4535,7 +4516,7 @@ struct qib_devdata *qib_init_iba7220_funcs(struct pci_dev *pdev,
dd->f_bringup_serdes = qib_7220_bringup_serdes; dd->f_bringup_serdes = qib_7220_bringup_serdes;
dd->f_cleanup = qib_setup_7220_cleanup; dd->f_cleanup = qib_setup_7220_cleanup;
dd->f_clear_tids = qib_7220_clear_tids; dd->f_clear_tids = qib_7220_clear_tids;
dd->f_free_irq = qib_7220_free_irq; dd->f_free_irq = qib_free_irq;
dd->f_get_base_info = qib_7220_get_base_info; dd->f_get_base_info = qib_7220_get_base_info;
dd->f_get_msgheader = qib_7220_get_msgheader; dd->f_get_msgheader = qib_7220_get_msgheader;
dd->f_getsendbuf = qib_7220_getsendbuf; dd->f_getsendbuf = qib_7220_getsendbuf;
...@@ -4618,9 +4599,6 @@ struct qib_devdata *qib_init_iba7220_funcs(struct pci_dev *pdev, ...@@ -4618,9 +4599,6 @@ struct qib_devdata *qib_init_iba7220_funcs(struct pci_dev *pdev,
qib_dev_err(dd, qib_dev_err(dd,
"Failed to setup PCIe or interrupts; continuing anyway\n"); "Failed to setup PCIe or interrupts; continuing anyway\n");
/* save IRQ for possible later use */
dd->cspec->irq = pdev->irq;
if (qib_read_kreg64(dd, kr_hwerrstatus) & if (qib_read_kreg64(dd, kr_hwerrstatus) &
QLOGIC_IB_HWE_SERDESPLLFAILED) QLOGIC_IB_HWE_SERDESPLLFAILED)
qib_write_kreg(dd, kr_hwerrclear, qib_write_kreg(dd, kr_hwerrclear,
......
...@@ -553,7 +553,6 @@ struct qib_chip_specific { ...@@ -553,7 +553,6 @@ struct qib_chip_specific {
u32 updthresh; /* current AvailUpdThld */ u32 updthresh; /* current AvailUpdThld */
u32 updthresh_dflt; /* default AvailUpdThld */ u32 updthresh_dflt; /* default AvailUpdThld */
u32 r1; u32 r1;
int irq;
u32 num_msix_entries; u32 num_msix_entries;
u32 sdmabufcnt; u32 sdmabufcnt;
u32 lastbuf_for_pio; u32 lastbuf_for_pio;
...@@ -756,10 +755,8 @@ static void check_7322_rxe_status(struct qib_pportdata *); ...@@ -756,10 +755,8 @@ static void check_7322_rxe_status(struct qib_pportdata *);
static u32 __iomem *qib_7322_getsendbuf(struct qib_pportdata *, u64, u32 *); static u32 __iomem *qib_7322_getsendbuf(struct qib_pportdata *, u64, u32 *);
#ifdef CONFIG_INFINIBAND_QIB_DCA #ifdef CONFIG_INFINIBAND_QIB_DCA
static void qib_setup_dca(struct qib_devdata *dd); static void qib_setup_dca(struct qib_devdata *dd);
static void setup_dca_notifier(struct qib_devdata *dd, static void setup_dca_notifier(struct qib_devdata *dd, int msixnum);
struct qib_msix_entry *m); static void reset_dca_notifier(struct qib_devdata *dd, int msixnum);
static void reset_dca_notifier(struct qib_devdata *dd,
struct qib_msix_entry *m);
#endif #endif
/** /**
...@@ -2778,7 +2775,7 @@ static void qib_setup_dca(struct qib_devdata *dd) ...@@ -2778,7 +2775,7 @@ static void qib_setup_dca(struct qib_devdata *dd)
qib_write_kreg(dd, KREG_IDX(DCACtrlB) + i, qib_write_kreg(dd, KREG_IDX(DCACtrlB) + i,
cspec->dca_rcvhdr_ctrl[i]); cspec->dca_rcvhdr_ctrl[i]);
for (i = 0; i < cspec->num_msix_entries; i++) for (i = 0; i < cspec->num_msix_entries; i++)
setup_dca_notifier(dd, &cspec->msix_entries[i]); setup_dca_notifier(dd, i);
} }
static void qib_irq_notifier_notify(struct irq_affinity_notify *notify, static void qib_irq_notifier_notify(struct irq_affinity_notify *notify,
...@@ -2820,49 +2817,41 @@ static void qib_irq_notifier_release(struct kref *ref) ...@@ -2820,49 +2817,41 @@ static void qib_irq_notifier_release(struct kref *ref)
} }
#endif #endif
/* static void qib_7322_free_irq(struct qib_devdata *dd)
* Disable MSIx interrupt if enabled, call generic MSIx code
* to cleanup, and clear pending MSIx interrupts.
* Used for fallback to INTx, after reset, and when MSIx setup fails.
*/
static void qib_7322_nomsix(struct qib_devdata *dd)
{ {
u64 intgranted; u64 intgranted;
int n; int i;
dd->cspec->main_int_mask = ~0ULL; dd->cspec->main_int_mask = ~0ULL;
n = dd->cspec->num_msix_entries;
if (n) {
int i;
dd->cspec->num_msix_entries = 0; for (i = 0; i < dd->cspec->num_msix_entries; i++) {
for (i = 0; i < n; i++) { /* only free IRQs that were allocated */
if (dd->cspec->msix_entries[i].arg) {
#ifdef CONFIG_INFINIBAND_QIB_DCA #ifdef CONFIG_INFINIBAND_QIB_DCA
reset_dca_notifier(dd, &dd->cspec->msix_entries[i]); reset_dca_notifier(dd, i);
#endif #endif
irq_set_affinity_hint( irq_set_affinity_hint(pci_irq_vector(dd->pcidev, i),
dd->cspec->msix_entries[i].irq, NULL); NULL);
free_cpumask_var(dd->cspec->msix_entries[i].mask); free_cpumask_var(dd->cspec->msix_entries[i].mask);
free_irq(dd->cspec->msix_entries[i].irq, pci_free_irq(dd->pcidev, i,
dd->cspec->msix_entries[i].arg); dd->cspec->msix_entries[i].arg);
} }
qib_nomsix(dd);
} }
/* If num_msix_entries was 0, disable the INTx IRQ */
if (!dd->cspec->num_msix_entries)
pci_free_irq(dd->pcidev, 0, dd);
else
dd->cspec->num_msix_entries = 0;
pci_free_irq_vectors(dd->pcidev);
/* make sure no MSIx interrupts are left pending */ /* make sure no MSIx interrupts are left pending */
intgranted = qib_read_kreg64(dd, kr_intgranted); intgranted = qib_read_kreg64(dd, kr_intgranted);
if (intgranted) if (intgranted)
qib_write_kreg(dd, kr_intgranted, intgranted); qib_write_kreg(dd, kr_intgranted, intgranted);
} }
static void qib_7322_free_irq(struct qib_devdata *dd)
{
if (dd->cspec->irq) {
free_irq(dd->cspec->irq, dd);
dd->cspec->irq = 0;
}
qib_7322_nomsix(dd);
}
static void qib_setup_7322_cleanup(struct qib_devdata *dd) static void qib_setup_7322_cleanup(struct qib_devdata *dd)
{ {
int i; int i;
...@@ -3329,22 +3318,20 @@ static irqreturn_t sdma_cleanup_intr(int irq, void *data) ...@@ -3329,22 +3318,20 @@ static irqreturn_t sdma_cleanup_intr(int irq, void *data)
#ifdef CONFIG_INFINIBAND_QIB_DCA #ifdef CONFIG_INFINIBAND_QIB_DCA
static void reset_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m) static void reset_dca_notifier(struct qib_devdata *dd, int msixnum)
{ {
if (!m->dca) if (!dd->cspec->msix_entries[msixnum].dca)
return; return;
qib_devinfo(dd->pcidev,
"Disabling notifier on HCA %d irq %d\n", qib_devinfo(dd->pcidev, "Disabling notifier on HCA %d irq %d\n",
dd->unit, dd->unit, pci_irq_vector(dd->pcidev, msixnum));
m->irq); irq_set_affinity_notifier(pci_irq_vector(dd->pcidev, msixnum), NULL);
irq_set_affinity_notifier( dd->cspec->msix_entries[msixnum].notifier = NULL;
m->irq,
NULL);
m->notifier = NULL;
} }
static void setup_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m) static void setup_dca_notifier(struct qib_devdata *dd, int msixnum)
{ {
struct qib_msix_entry *m = &dd->cspec->msix_entries[msixnum];
struct qib_irq_notify *n; struct qib_irq_notify *n;
if (!m->dca) if (!m->dca)
...@@ -3354,7 +3341,7 @@ static void setup_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m) ...@@ -3354,7 +3341,7 @@ static void setup_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m)
int ret; int ret;
m->notifier = n; m->notifier = n;
n->notify.irq = m->irq; n->notify.irq = pci_irq_vector(dd->pcidev, msixnum);
n->notify.notify = qib_irq_notifier_notify; n->notify.notify = qib_irq_notifier_notify;
n->notify.release = qib_irq_notifier_release; n->notify.release = qib_irq_notifier_release;
n->arg = m->arg; n->arg = m->arg;
...@@ -3415,22 +3402,17 @@ static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend) ...@@ -3415,22 +3402,17 @@ static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend)
if (!dd->cspec->num_msix_entries) { if (!dd->cspec->num_msix_entries) {
/* Try to get INTx interrupt */ /* Try to get INTx interrupt */
try_intx: try_intx:
if (!dd->pcidev->irq) { ret = pci_request_irq(dd->pcidev, 0, qib_7322intr, NULL, dd,
qib_dev_err(dd, QIB_DRV_NAME);
"irq is 0, BIOS error? Interrupts won't work\n");
goto bail;
}
ret = request_irq(dd->pcidev->irq, qib_7322intr,
IRQF_SHARED, QIB_DRV_NAME, dd);
if (ret) { if (ret) {
qib_dev_err(dd, qib_dev_err(
dd,
"Couldn't setup INTx interrupt (irq=%d): %d\n", "Couldn't setup INTx interrupt (irq=%d): %d\n",
dd->pcidev->irq, ret); pci_irq_vector(dd->pcidev, 0), ret);
goto bail; return;
} }
dd->cspec->irq = dd->pcidev->irq;
dd->cspec->main_int_mask = ~0ULL; dd->cspec->main_int_mask = ~0ULL;
goto bail; return;
} }
/* Try to get MSIx interrupts */ /* Try to get MSIx interrupts */
...@@ -3458,10 +3440,6 @@ static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend) ...@@ -3458,10 +3440,6 @@ static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend)
#ifdef CONFIG_INFINIBAND_QIB_DCA #ifdef CONFIG_INFINIBAND_QIB_DCA
int dca = 0; int dca = 0;
#endif #endif
dd->cspec->msix_entries[msixnum].
name[sizeof(dd->cspec->msix_entries[msixnum].name) - 1]
= '\0';
if (i < ARRAY_SIZE(irq_table)) { if (i < ARRAY_SIZE(irq_table)) {
if (irq_table[i].port) { if (irq_table[i].port) {
/* skip if for a non-configured port */ /* skip if for a non-configured port */
...@@ -3475,11 +3453,10 @@ static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend) ...@@ -3475,11 +3453,10 @@ static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend)
#endif #endif
lsb = irq_table[i].lsb; lsb = irq_table[i].lsb;
handler = irq_table[i].handler; handler = irq_table[i].handler;
snprintf(dd->cspec->msix_entries[msixnum].name, ret = pci_request_irq(dd->pcidev, msixnum, handler,
sizeof(dd->cspec->msix_entries[msixnum].name) NULL, arg, QIB_DRV_NAME "%d%s",
- 1, dd->unit,
QIB_DRV_NAME "%d%s", dd->unit, irq_table[i].name);
irq_table[i].name);
} else { } else {
unsigned ctxt; unsigned ctxt;
...@@ -3495,37 +3472,25 @@ static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend) ...@@ -3495,37 +3472,25 @@ static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend)
#endif #endif
lsb = QIB_I_RCVAVAIL_LSB + ctxt; lsb = QIB_I_RCVAVAIL_LSB + ctxt;
handler = qib_7322pintr; handler = qib_7322pintr;
snprintf(dd->cspec->msix_entries[msixnum].name, ret = pci_request_irq(dd->pcidev, msixnum, handler,
sizeof(dd->cspec->msix_entries[msixnum].name) NULL, arg,
- 1, QIB_DRV_NAME "%d (kctx)",
QIB_DRV_NAME "%d (kctx)", dd->unit); dd->unit);
} }
dd->cspec->msix_entries[msixnum].irq = pci_irq_vector(
dd->pcidev, msixnum);
if (dd->cspec->msix_entries[msixnum].irq < 0) {
qib_dev_err(dd,
"Couldn't get MSIx irq (vec=%d): %d\n",
msixnum,
dd->cspec->msix_entries[msixnum].irq);
qib_7322_nomsix(dd);
goto try_intx;
}
ret = request_irq(dd->cspec->msix_entries[msixnum].irq,
handler, 0,
dd->cspec->msix_entries[msixnum].name,
arg);
if (ret) { if (ret) {
/* /*
* Shouldn't happen since the enable said we could * Shouldn't happen since the enable said we could
* have as many as we are trying to setup here. * have as many as we are trying to setup here.
*/ */
qib_dev_err(dd, qib_dev_err(dd,
"Couldn't setup MSIx interrupt (vec=%d, irq=%d): %d\n", "Couldn't setup MSIx interrupt (vec=%d, irq=%d): %d\n",
msixnum, msixnum,
dd->cspec->msix_entries[msixnum].irq, pci_irq_vector(dd->pcidev, msixnum),
ret); ret);
qib_7322_nomsix(dd); qib_7322_free_irq(dd);
pci_alloc_irq_vectors(dd->pcidev, 1, 1,
PCI_IRQ_LEGACY);
goto try_intx; goto try_intx;
} }
dd->cspec->msix_entries[msixnum].arg = arg; dd->cspec->msix_entries[msixnum].arg = arg;
...@@ -3559,7 +3524,7 @@ static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend) ...@@ -3559,7 +3524,7 @@ static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend)
dd->cspec->msix_entries[msixnum].mask); dd->cspec->msix_entries[msixnum].mask);
} }
irq_set_affinity_hint( irq_set_affinity_hint(
dd->cspec->msix_entries[msixnum].irq, pci_irq_vector(dd->pcidev, msixnum),
dd->cspec->msix_entries[msixnum].mask); dd->cspec->msix_entries[msixnum].mask);
} }
msixnum++; msixnum++;
...@@ -3570,7 +3535,6 @@ static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend) ...@@ -3570,7 +3535,6 @@ static void qib_setup_7322_interrupt(struct qib_devdata *dd, int clearpend)
dd->cspec->main_int_mask = mask; dd->cspec->main_int_mask = mask;
tasklet_init(&dd->error_tasklet, qib_error_tasklet, tasklet_init(&dd->error_tasklet, qib_error_tasklet,
(unsigned long)dd); (unsigned long)dd);
bail:;
} }
/** /**
...@@ -3674,8 +3638,9 @@ static int qib_do_7322_reset(struct qib_devdata *dd) ...@@ -3674,8 +3638,9 @@ static int qib_do_7322_reset(struct qib_devdata *dd)
/* no interrupts till re-initted */ /* no interrupts till re-initted */
qib_7322_set_intr_state(dd, 0); qib_7322_set_intr_state(dd, 0);
qib_7322_free_irq(dd);
if (msix_entries) { if (msix_entries) {
qib_7322_nomsix(dd);
/* can be up to 512 bytes, too big for stack */ /* can be up to 512 bytes, too big for stack */
msix_vecsave = kmalloc(2 * dd->cspec->num_msix_entries * msix_vecsave = kmalloc(2 * dd->cspec->num_msix_entries *
sizeof(u64), GFP_KERNEL); sizeof(u64), GFP_KERNEL);
...@@ -3765,11 +3730,11 @@ static int qib_do_7322_reset(struct qib_devdata *dd) ...@@ -3765,11 +3730,11 @@ static int qib_do_7322_reset(struct qib_devdata *dd)
write_7322_init_portregs(&dd->pport[i]); write_7322_init_portregs(&dd->pport[i]);
write_7322_initregs(dd); write_7322_initregs(dd);
if (qib_pcie_params(dd, dd->lbus_width, if (qib_pcie_params(dd, dd->lbus_width, &msix_entries))
&dd->cspec->num_msix_entries))
qib_dev_err(dd, qib_dev_err(dd,
"Reset failed to setup PCIe or interrupts; continuing anyway\n"); "Reset failed to setup PCIe or interrupts; continuing anyway\n");
dd->cspec->num_msix_entries = msix_entries;
qib_setup_7322_interrupt(dd, 1); qib_setup_7322_interrupt(dd, 1);
for (i = 0; i < dd->num_pports; ++i) { for (i = 0; i < dd->num_pports; ++i) {
...@@ -5197,8 +5162,9 @@ static int qib_7322_intr_fallback(struct qib_devdata *dd) ...@@ -5197,8 +5162,9 @@ static int qib_7322_intr_fallback(struct qib_devdata *dd)
qib_devinfo(dd->pcidev, qib_devinfo(dd->pcidev,
"MSIx interrupt not detected, trying INTx interrupts\n"); "MSIx interrupt not detected, trying INTx interrupts\n");
qib_7322_nomsix(dd); qib_7322_free_irq(dd);
qib_enable_intx(dd); if (pci_alloc_irq_vectors(dd->pcidev, 1, 1, PCI_IRQ_LEGACY) < 0)
qib_dev_err(dd, "Failed to enable INTx\n");
qib_setup_7322_interrupt(dd, 0); qib_setup_7322_interrupt(dd, 0);
return 1; return 1;
} }
......
...@@ -193,7 +193,7 @@ void qib_pcie_ddcleanup(struct qib_devdata *dd) ...@@ -193,7 +193,7 @@ void qib_pcie_ddcleanup(struct qib_devdata *dd)
* chip reset (the kernel PCI infrastructure doesn't yet handle that * chip reset (the kernel PCI infrastructure doesn't yet handle that
* correctly. * correctly.
*/ */
static void qib_msi_setup(struct qib_devdata *dd, int pos) static void qib_cache_msi_info(struct qib_devdata *dd, int pos)
{ {
struct pci_dev *pdev = dd->pcidev; struct pci_dev *pdev = dd->pcidev;
u16 control; u16 control;
...@@ -208,64 +208,39 @@ static void qib_msi_setup(struct qib_devdata *dd, int pos) ...@@ -208,64 +208,39 @@ static void qib_msi_setup(struct qib_devdata *dd, int pos)
&dd->msi_data); &dd->msi_data);
} }
static int qib_allocate_irqs(struct qib_devdata *dd, u32 maxvec)
{
unsigned int flags = PCI_IRQ_LEGACY;
/* Check our capabilities */
if (dd->pcidev->msix_cap) {
flags |= PCI_IRQ_MSIX;
} else {
if (dd->pcidev->msi_cap) {
flags |= PCI_IRQ_MSI;
/* Get msi_lo and msi_hi */
qib_msi_setup(dd, dd->pcidev->msi_cap);
}
}
if (!(flags & (PCI_IRQ_MSIX | PCI_IRQ_MSI)))
qib_dev_err(dd, "No PCI MSI or MSIx capability!\n");
return pci_alloc_irq_vectors(dd->pcidev, 1, maxvec, flags);
}
int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent) int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent)
{ {
u16 linkstat, speed; u16 linkstat, speed;
int nvec; int nvec;
int maxvec; int maxvec;
int ret = 0; unsigned int flags = PCI_IRQ_MSIX | PCI_IRQ_MSI;
if (!pci_is_pcie(dd->pcidev)) { if (!pci_is_pcie(dd->pcidev)) {
qib_dev_err(dd, "Can't find PCI Express capability!\n"); qib_dev_err(dd, "Can't find PCI Express capability!\n");
/* set up something... */ /* set up something... */
dd->lbus_width = 1; dd->lbus_width = 1;
dd->lbus_speed = 2500; /* Gen1, 2.5GHz */ dd->lbus_speed = 2500; /* Gen1, 2.5GHz */
ret = -1; nvec = -1;
goto bail; goto bail;
} }
if (dd->flags & QIB_HAS_INTX)
flags |= PCI_IRQ_LEGACY;
maxvec = (nent && *nent) ? *nent : 1; maxvec = (nent && *nent) ? *nent : 1;
nvec = qib_allocate_irqs(dd, maxvec); nvec = pci_alloc_irq_vectors(dd->pcidev, 1, maxvec, flags);
if (nvec < 0) { if (nvec < 0)
ret = nvec;
goto bail; goto bail;
}
/* /*
* If nent exists, make sure to record how many vectors were allocated * If nent exists, make sure to record how many vectors were allocated.
* If msix_enabled is false, return 0 so the fallback code works
* correctly.
*/ */
if (nent) { if (nent)
*nent = nvec; *nent = !dd->pcidev->msix_enabled ? 0 : nvec;
/* if (dd->pcidev->msi_enabled)
* If we requested (nent) MSIX, but msix_enabled is not set, qib_cache_msi_info(dd, dd->pcidev->msi_cap);
* pci_alloc_irq_vectors() enabled INTx.
*/
if (!dd->pcidev->msix_enabled)
qib_dev_err(dd,
"no msix vectors allocated, using INTx\n");
}
pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKSTA, &linkstat); pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKSTA, &linkstat);
/* /*
...@@ -306,7 +281,21 @@ int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent) ...@@ -306,7 +281,21 @@ int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent)
/* fill in string, even on errors */ /* fill in string, even on errors */
snprintf(dd->lbus_info, sizeof(dd->lbus_info), snprintf(dd->lbus_info, sizeof(dd->lbus_info),
"PCIe,%uMHz,x%u\n", dd->lbus_speed, dd->lbus_width); "PCIe,%uMHz,x%u\n", dd->lbus_speed, dd->lbus_width);
return ret; return nvec < 0 ? nvec : 0;
}
/**
* qib_free_irq - Cleanup INTx and MSI interrupts
* @dd: valid pointer to qib dev data
*
* Since cleanup for INTx and MSI interrupts is trivial, have a common
* routine.
*
*/
void qib_free_irq(struct qib_devdata *dd)
{
pci_free_irq(dd->pcidev, 0, dd);
pci_free_irq_vectors(dd->pcidev);
} }
/* /*
...@@ -351,10 +340,10 @@ int qib_reinit_intr(struct qib_devdata *dd) ...@@ -351,10 +340,10 @@ int qib_reinit_intr(struct qib_devdata *dd)
dd->msi_data); dd->msi_data);
ret = 1; ret = 1;
bail: bail:
if (!ret && (dd->flags & QIB_HAS_INTX)) { qib_free_irq(dd);
qib_enable_intx(dd);
if (!ret && (dd->flags & QIB_HAS_INTX))
ret = 1; ret = 1;
}
/* and now set the pci master bit again */ /* and now set the pci master bit again */
pci_set_master(dd->pcidev); pci_set_master(dd->pcidev);
...@@ -362,56 +351,6 @@ int qib_reinit_intr(struct qib_devdata *dd) ...@@ -362,56 +351,6 @@ int qib_reinit_intr(struct qib_devdata *dd)
return ret; return ret;
} }
/*
* Disable msi interrupt if enabled, and clear msi_lo.
* This is used primarily for the fallback to INTx, but
* is also used in reinit after reset, and during cleanup.
*/
void qib_nomsi(struct qib_devdata *dd)
{
dd->msi_lo = 0;
pci_free_irq_vectors(dd->pcidev);
}
/*
* Same as qib_nosmi, but for MSIx.
*/
void qib_nomsix(struct qib_devdata *dd)
{
pci_free_irq_vectors(dd->pcidev);
}
/*
* Similar to pci_intx(pdev, 1), except that we make sure
* msi(x) is off.
*/
void qib_enable_intx(struct qib_devdata *dd)
{
u16 cw, new;
int pos;
struct pci_dev *pdev = dd->pcidev;
if (pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY) < 0)
qib_dev_err(dd, "Failed to enable INTx\n");
pos = pdev->msi_cap;
if (pos) {
/* then turn off MSI */
pci_read_config_word(pdev, pos + PCI_MSI_FLAGS, &cw);
new = cw & ~PCI_MSI_FLAGS_ENABLE;
if (new != cw)
pci_write_config_word(pdev, pos + PCI_MSI_FLAGS, new);
}
pos = pdev->msix_cap;
if (pos) {
/* then turn off MSIx */
pci_read_config_word(pdev, pos + PCI_MSIX_FLAGS, &cw);
new = cw & ~PCI_MSIX_FLAGS_ENABLE;
if (new != cw)
pci_write_config_word(pdev, pos + PCI_MSIX_FLAGS, new);
}
}
/* /*
* These two routines are helper routines for the device reset code * These two routines are helper routines for the device reset code
* to move all the pcie code out of the chip-specific driver code. * to move all the pcie code out of the chip-specific driver code.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册