mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-23 01:09:48 +07:00
staging/rdma/hfi1: Implement LED beaconing for maintenance
This patch implements LED beaconing for maintenance. A MAD packet with the LEDInfo attribute set to 1 will enable LED beaconing with a duty cycle of 2s on and 1.5s off. A MAD packet with the LEDInfo attribute set to 0 will disable beaconing and return the LED to normal operation. Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Easwar Hariharan <easwar.hariharan@intel.com> Signed-off-by: Mitko Haralanov <mitko.haralanov@intel.com> Signed-off-by: Jubin John <jubin.john@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
parent
7b0b01aa8f
commit
91ab4ed334
@ -5,7 +5,7 @@
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2015 Intel Corporation.
|
||||
* Copyright(c) 2015, 2016 Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -18,7 +18,7 @@
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2015 Intel Corporation.
|
||||
* Copyright(c) 2015, 2016 Intel Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -1172,63 +1172,64 @@ int hfi1_set_lid(struct hfi1_pportdata *ppd, u32 lid, u8 lmc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Following deal with the "obviously simple" task of overriding the state
|
||||
* of the LEDs, which normally indicate link physical and logical status.
|
||||
* The complications arise in dealing with different hardware mappings
|
||||
* and the board-dependent routine being called from interrupts.
|
||||
* and then there's the requirement to _flash_ them.
|
||||
*/
|
||||
#define LED_OVER_FREQ_SHIFT 8
|
||||
#define LED_OVER_FREQ_MASK (0xFF<<LED_OVER_FREQ_SHIFT)
|
||||
/* Below is "non-zero" to force override, but both actual LEDs are off */
|
||||
#define LED_OVER_BOTH_OFF (8)
|
||||
void shutdown_led_override(struct hfi1_pportdata *ppd)
|
||||
{
|
||||
struct hfi1_devdata *dd = ppd->dd;
|
||||
|
||||
if (atomic_read(&ppd->led_override_timer_active)) {
|
||||
del_timer_sync(&ppd->led_override_timer);
|
||||
atomic_set(&ppd->led_override_timer_active, 0);
|
||||
}
|
||||
|
||||
/* Shut off LEDs after we are sure timer is not running */
|
||||
setextled(dd, 0);
|
||||
}
|
||||
|
||||
static void run_led_override(unsigned long opaque)
|
||||
{
|
||||
struct hfi1_pportdata *ppd = (struct hfi1_pportdata *)opaque;
|
||||
struct hfi1_devdata *dd = ppd->dd;
|
||||
int timeoff;
|
||||
int ph_idx;
|
||||
unsigned long timeout;
|
||||
int phase_idx;
|
||||
|
||||
if (!(dd->flags & HFI1_INITTED))
|
||||
return;
|
||||
|
||||
ph_idx = ppd->led_override_phase++ & 1;
|
||||
ppd->led_override = ppd->led_override_vals[ph_idx];
|
||||
timeoff = ppd->led_override_timeoff;
|
||||
phase_idx = ppd->led_override_phase & 1;
|
||||
setextled(dd, phase_idx);
|
||||
|
||||
timeout = ppd->led_override_vals[phase_idx];
|
||||
/* Set up for next phase */
|
||||
ppd->led_override_phase = !ppd->led_override_phase;
|
||||
|
||||
/*
|
||||
* don't re-fire the timer if user asked for it to be off; we let
|
||||
* it fire one more time after they turn it off to simplify
|
||||
*/
|
||||
if (ppd->led_override_vals[0] || ppd->led_override_vals[1])
|
||||
mod_timer(&ppd->led_override_timer, jiffies + timeoff);
|
||||
mod_timer(&ppd->led_override_timer, jiffies + timeout);
|
||||
else
|
||||
/* Hand control of the LED to the DC for normal operation */
|
||||
write_csr(dd, DCC_CFG_LED_CNTRL, 0);
|
||||
}
|
||||
|
||||
void hfi1_set_led_override(struct hfi1_pportdata *ppd, unsigned int val)
|
||||
/*
|
||||
* To have the LED blink in a particular pattern, provide timeon and timeoff
|
||||
* in milliseconds. To turn off custom blinking and return to normal operation,
|
||||
* provide timeon = timeoff = 0.
|
||||
*/
|
||||
void hfi1_set_led_override(struct hfi1_pportdata *ppd, unsigned int timeon,
|
||||
unsigned int timeoff)
|
||||
{
|
||||
struct hfi1_devdata *dd = ppd->dd;
|
||||
int timeoff, freq;
|
||||
|
||||
if (!(dd->flags & HFI1_INITTED))
|
||||
return;
|
||||
|
||||
/* First check if we are blinking. If not, use 1HZ polling */
|
||||
timeoff = HZ;
|
||||
freq = (val & LED_OVER_FREQ_MASK) >> LED_OVER_FREQ_SHIFT;
|
||||
|
||||
if (freq) {
|
||||
/* For blink, set each phase from one nybble of val */
|
||||
ppd->led_override_vals[0] = val & 0xF;
|
||||
ppd->led_override_vals[1] = (val >> 4) & 0xF;
|
||||
timeoff = (HZ << 4)/freq;
|
||||
} else {
|
||||
/* Non-blink set both phases the same. */
|
||||
ppd->led_override_vals[0] = val & 0xF;
|
||||
ppd->led_override_vals[1] = val & 0xF;
|
||||
}
|
||||
ppd->led_override_timeoff = timeoff;
|
||||
/* Convert to jiffies for direct use in timer */
|
||||
ppd->led_override_vals[0] = msecs_to_jiffies(timeoff);
|
||||
ppd->led_override_vals[1] = msecs_to_jiffies(timeon);
|
||||
ppd->led_override_phase = 1; /* Arbitrarily start from LED on phase */
|
||||
|
||||
/*
|
||||
* If the timer has not already been started, do so. Use a "quick"
|
||||
@ -1293,14 +1294,8 @@ int hfi1_reset_device(int unit)
|
||||
|
||||
for (pidx = 0; pidx < dd->num_pports; ++pidx) {
|
||||
ppd = dd->pport + pidx;
|
||||
if (atomic_read(&ppd->led_override_timer_active)) {
|
||||
/* Need to stop LED timer, _then_ shut off LEDs */
|
||||
del_timer_sync(&ppd->led_override_timer);
|
||||
atomic_set(&ppd->led_override_timer_active, 0);
|
||||
}
|
||||
|
||||
/* Shut off LEDs after we are sure timer is not running */
|
||||
ppd->led_override = LED_OVER_BOTH_OFF;
|
||||
shutdown_led_override(ppd);
|
||||
}
|
||||
if (dd->flags & HFI1_HAS_SEND_DMA)
|
||||
sdma_exit(dd);
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2015 Intel Corporation.
|
||||
* Copyright(c) 2015, 2016 Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -20,7 +20,7 @@
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2015 Intel Corporation.
|
||||
* Copyright(c) 2015, 2016 Intel Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -669,14 +669,17 @@ struct hfi1_pportdata {
|
||||
u8 overrun_threshold;
|
||||
u8 phy_error_threshold;
|
||||
|
||||
/* used to override LED behavior */
|
||||
u8 led_override; /* Substituted for normal value, if non-zero */
|
||||
u16 led_override_timeoff; /* delta to next timer event */
|
||||
u8 led_override_vals[2]; /* Alternates per blink-frame */
|
||||
u8 led_override_phase; /* Just counts, LSB picks from vals[] */
|
||||
/* Used to override LED behavior for things like maintenance beaconing*/
|
||||
/*
|
||||
* Alternates per phase of blink
|
||||
* [0] holds LED off duration, [1] holds LED on duration
|
||||
*/
|
||||
unsigned long led_override_vals[2];
|
||||
u8 led_override_phase; /* LSB picks from vals[] */
|
||||
atomic_t led_override_timer_active;
|
||||
/* Used to flash LEDs in override mode */
|
||||
struct timer_list led_override_timer;
|
||||
|
||||
u32 sm_trap_qp;
|
||||
u32 sa_qp;
|
||||
|
||||
@ -1599,14 +1602,14 @@ void hfi1_free_devdata(struct hfi1_devdata *);
|
||||
void cc_state_reclaim(struct rcu_head *rcu);
|
||||
struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, size_t extra);
|
||||
|
||||
void hfi1_set_led_override(struct hfi1_pportdata *ppd, unsigned int timeon,
|
||||
unsigned int timeoff);
|
||||
/*
|
||||
* Set LED override, only the two LSBs have "public" meaning, but
|
||||
* any non-zero value substitutes them for the Link and LinkTrain
|
||||
* LED states.
|
||||
* Only to be used for driver unload or device reset where we cannot allow
|
||||
* the timer to fire even the one extra time, else use hfi1_set_led_override
|
||||
* with timeon = timeoff = 0
|
||||
*/
|
||||
#define HFI1_LED_PHYS 1 /* Physical (linktraining) GREEN LED */
|
||||
#define HFI1_LED_LOG 2 /* Logical (link) YELLOW LED */
|
||||
void hfi1_set_led_override(struct hfi1_pportdata *ppd, unsigned int val);
|
||||
void shutdown_led_override(struct hfi1_pportdata *ppd);
|
||||
|
||||
#define HFI1_CREDIT_RETURN_RATE (100)
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2015 Intel Corporation.
|
||||
* Copyright(c) 2015, 2016 Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -18,7 +18,7 @@
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2015 Intel Corporation.
|
||||
* Copyright(c) 2015, 2016 Intel Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -908,6 +908,8 @@ static void shutdown_device(struct hfi1_devdata *dd)
|
||||
/* disable the send device */
|
||||
pio_send_control(dd, PSC_GLOBAL_DISABLE);
|
||||
|
||||
shutdown_led_override(ppd);
|
||||
|
||||
/*
|
||||
* Clear SerdesEnable.
|
||||
* We can't count on interrupts since we are stopping.
|
||||
|
@ -5,7 +5,7 @@
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2015 Intel Corporation.
|
||||
* Copyright(c) 2015, 2016 Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -18,7 +18,7 @@
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2015 Intel Corporation.
|
||||
* Copyright(c) 2015, 2016 Intel Corporation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -3449,7 +3449,10 @@ static int __subn_set_opa_led_info(struct opa_smp *smp, u32 am, u8 *data,
|
||||
return reply((struct ib_mad_hdr *)smp);
|
||||
}
|
||||
|
||||
setextled(dd, on);
|
||||
if (on)
|
||||
hfi1_set_led_override(dd->pport, 2000, 1500);
|
||||
else
|
||||
hfi1_set_led_override(dd->pport, 0, 0);
|
||||
|
||||
return __subn_get_opa_led_info(smp, am, data, ibdev, port, resp_len);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user