diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/pci.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/pci.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c index c071077aafbd..7f4173c8eda3 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/pci.c +++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c @@ -215,7 +215,7 @@ mlxsw_pci_queue_elem_info_producer_get(struct mlxsw_pci_queue *q) { int index = q->producer_counter & (q->count - 1); - if ((q->producer_counter - q->consumer_counter) == q->count) + if ((u16) (q->producer_counter - q->consumer_counter) == q->count) return NULL; return mlxsw_pci_queue_elem_info_get(q, index); } @@ -1681,11 +1681,18 @@ static const struct mlxsw_bus mlxsw_pci_bus = { static int mlxsw_pci_sw_reset(struct mlxsw_pci *mlxsw_pci) { + unsigned long end; + mlxsw_pci_write32(mlxsw_pci, SW_RESET, MLXSW_PCI_SW_RESET_RST_BIT); - /* Current firware does not let us know when the reset is done. - * So we just wait here for constant time and hope for the best. - */ - msleep(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS); + wmb(); /* reset needs to be written before we read control register */ + end = jiffies + msecs_to_jiffies(MLXSW_PCI_SW_RESET_TIMEOUT_MSECS); + do { + u32 val = mlxsw_pci_read32(mlxsw_pci, FW_READY); + + if ((val & MLXSW_PCI_FW_READY_MASK) == MLXSW_PCI_FW_READY_MAGIC) + break; + cond_resched(); + } while (time_before(jiffies, end)); return 0; } |