tg3: Fix single-vector MSI-X code
Kdump kernels leave MSI-X interrupts (as setup by the crashed kernel) enabled. However, kdump only enables one CPU in the new environment, thus causing tg3 to abort MSI-X setup. When the driver attempts to enable INTA or MSI interrupt modes on a kdump kernel, interrupt delivery fails. This patch attempts to workaround the problem by forcing the driver to enable a single MSI-X interrupt. In such a configuration, the device's multivector interrupt mode must be disabled. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
77676fdbd5
commit
c3b5003b62
|
@ -8846,9 +8846,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
|
||||||
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
|
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
|
||||||
udelay(100);
|
udelay(100);
|
||||||
|
|
||||||
if (tg3_flag(tp, USING_MSIX) && tp->irq_cnt > 1) {
|
if (tg3_flag(tp, USING_MSIX)) {
|
||||||
val = tr32(MSGINT_MODE);
|
val = tr32(MSGINT_MODE);
|
||||||
val |= MSGINT_MODE_MULTIVEC_EN | MSGINT_MODE_ENABLE;
|
val |= MSGINT_MODE_ENABLE;
|
||||||
|
if (tp->irq_cnt > 1)
|
||||||
|
val |= MSGINT_MODE_MULTIVEC_EN;
|
||||||
if (!tg3_flag(tp, 1SHOT_MSI))
|
if (!tg3_flag(tp, 1SHOT_MSI))
|
||||||
val |= MSGINT_MODE_ONE_SHOT_DISABLE;
|
val |= MSGINT_MODE_ONE_SHOT_DISABLE;
|
||||||
tw32(MSGINT_MODE, val);
|
tw32(MSGINT_MODE, val);
|
||||||
|
@ -9548,19 +9550,18 @@ static int tg3_request_firmware(struct tg3 *tp)
|
||||||
|
|
||||||
static bool tg3_enable_msix(struct tg3 *tp)
|
static bool tg3_enable_msix(struct tg3 *tp)
|
||||||
{
|
{
|
||||||
int i, rc, cpus = num_online_cpus();
|
int i, rc;
|
||||||
struct msix_entry msix_ent[tp->irq_max];
|
struct msix_entry msix_ent[tp->irq_max];
|
||||||
|
|
||||||
if (cpus == 1)
|
tp->irq_cnt = num_online_cpus();
|
||||||
/* Just fallback to the simpler MSI mode. */
|
if (tp->irq_cnt > 1) {
|
||||||
return false;
|
/* We want as many rx rings enabled as there are cpus.
|
||||||
|
* In multiqueue MSI-X mode, the first MSI-X vector
|
||||||
/*
|
* only deals with link interrupts, etc, so we add
|
||||||
* We want as many rx rings enabled as there are cpus.
|
* one to the number of vectors we are requesting.
|
||||||
* The first MSIX vector only deals with link interrupts, etc,
|
*/
|
||||||
* so we add one to the number of vectors we are requesting.
|
tp->irq_cnt = min_t(unsigned, tp->irq_cnt + 1, tp->irq_max);
|
||||||
*/
|
}
|
||||||
tp->irq_cnt = min_t(unsigned, cpus + 1, tp->irq_max);
|
|
||||||
|
|
||||||
for (i = 0; i < tp->irq_max; i++) {
|
for (i = 0; i < tp->irq_max; i++) {
|
||||||
msix_ent[i].entry = i;
|
msix_ent[i].entry = i;
|
||||||
|
|
Loading…
Reference in New Issue