Skip to content

Commit 075da58

Browse files
hcodinadavem330
authored andcommitted
net: stmmac: fix get_hw_feature() on old hardware
Some old IPs do not provide the hardware feature register. On these IPs, this register is read 0x00000000. In old driver version, this feature was handled but a regression came with the commit f10a6a3 ("stmmac: rework get_hw_feature function"). Indeed, this commit removes the return value in dma->get_hw_feature(). This return value was used to indicate the validity of retrieved information and used later on in stmmac_hw_init() to override priv->plat data if this hardware feature were valid. This patch restores the return code in ->get_hw_feature() in order to indicate the hardware feature validity and override priv->plat data only if this hardware feature is valid. Fixes: f10a6a3 ("stmmac: rework get_hw_feature function") Signed-off-by: Herve Codina <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 612f71d commit 075da58

File tree

4 files changed

+22
-9
lines changed

4 files changed

+22
-9
lines changed

drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,18 @@ static void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
218218
readl(ioaddr + DMA_BUS_MODE + i * 4);
219219
}
220220

221-
static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
222-
struct dma_features *dma_cap)
221+
static int dwmac1000_get_hw_feature(void __iomem *ioaddr,
222+
struct dma_features *dma_cap)
223223
{
224224
u32 hw_cap = readl(ioaddr + DMA_HW_FEATURE);
225225

226+
if (!hw_cap) {
227+
/* 0x00000000 is the value read on old hardware that does not
228+
* implement this register
229+
*/
230+
return -EOPNOTSUPP;
231+
}
232+
226233
dma_cap->mbps_10_100 = (hw_cap & DMA_HW_FEAT_MIISEL);
227234
dma_cap->mbps_1000 = (hw_cap & DMA_HW_FEAT_GMIISEL) >> 1;
228235
dma_cap->half_duplex = (hw_cap & DMA_HW_FEAT_HDSEL) >> 2;
@@ -252,6 +259,8 @@ static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
252259
dma_cap->number_tx_channel = (hw_cap & DMA_HW_FEAT_TXCHCNT) >> 22;
253260
/* Alternate (enhanced) DESC mode */
254261
dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
262+
263+
return 0;
255264
}
256265

257266
static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt,

drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,8 @@ static void dwmac4_dma_tx_chan_op_mode(void __iomem *ioaddr, int mode,
347347
writel(mtl_tx_op, ioaddr + MTL_CHAN_TX_OP_MODE(channel));
348348
}
349349

350-
static void dwmac4_get_hw_feature(void __iomem *ioaddr,
351-
struct dma_features *dma_cap)
350+
static int dwmac4_get_hw_feature(void __iomem *ioaddr,
351+
struct dma_features *dma_cap)
352352
{
353353
u32 hw_cap = readl(ioaddr + GMAC_HW_FEATURE0);
354354

@@ -437,6 +437,8 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
437437
dma_cap->frpbs = (hw_cap & GMAC_HW_FEAT_FRPBS) >> 11;
438438
dma_cap->frpsel = (hw_cap & GMAC_HW_FEAT_FRPSEL) >> 10;
439439
dma_cap->dvlan = (hw_cap & GMAC_HW_FEAT_DVLAN) >> 5;
440+
441+
return 0;
440442
}
441443

442444
/* Enable/disable TSO feature and set MSS */

drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,8 @@ static int dwxgmac2_dma_interrupt(void __iomem *ioaddr,
371371
return ret;
372372
}
373373

374-
static void dwxgmac2_get_hw_feature(void __iomem *ioaddr,
375-
struct dma_features *dma_cap)
374+
static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
375+
struct dma_features *dma_cap)
376376
{
377377
u32 hw_cap;
378378

@@ -445,6 +445,8 @@ static void dwxgmac2_get_hw_feature(void __iomem *ioaddr,
445445
dma_cap->frpes = (hw_cap & XGMAC_HWFEAT_FRPES) >> 11;
446446
dma_cap->frpbs = (hw_cap & XGMAC_HWFEAT_FRPPB) >> 9;
447447
dma_cap->frpsel = (hw_cap & XGMAC_HWFEAT_FRPSEL) >> 3;
448+
449+
return 0;
448450
}
449451

450452
static void dwxgmac2_rx_watchdog(void __iomem *ioaddr, u32 riwt, u32 queue)

drivers/net/ethernet/stmicro/stmmac/hwif.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,8 @@ struct stmmac_dma_ops {
203203
int (*dma_interrupt) (void __iomem *ioaddr,
204204
struct stmmac_extra_stats *x, u32 chan, u32 dir);
205205
/* If supported then get the optional core features */
206-
void (*get_hw_feature)(void __iomem *ioaddr,
207-
struct dma_features *dma_cap);
206+
int (*get_hw_feature)(void __iomem *ioaddr,
207+
struct dma_features *dma_cap);
208208
/* Program the HW RX Watchdog */
209209
void (*rx_watchdog)(void __iomem *ioaddr, u32 riwt, u32 queue);
210210
void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len, u32 chan);
@@ -255,7 +255,7 @@ struct stmmac_dma_ops {
255255
#define stmmac_dma_interrupt_status(__priv, __args...) \
256256
stmmac_do_callback(__priv, dma, dma_interrupt, __args)
257257
#define stmmac_get_hw_feature(__priv, __args...) \
258-
stmmac_do_void_callback(__priv, dma, get_hw_feature, __args)
258+
stmmac_do_callback(__priv, dma, get_hw_feature, __args)
259259
#define stmmac_rx_watchdog(__priv, __args...) \
260260
stmmac_do_void_callback(__priv, dma, rx_watchdog, __args)
261261
#define stmmac_set_tx_ring_len(__priv, __args...) \

0 commit comments

Comments
 (0)