Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: stmmac: Populate missing callbacks in HWIF initialization

Some HW specific setups, like sun8i, do not populate all the necessary
callbacks, which is what HWIF helpers were expecting.

Fix this by always trying to get the generic helpers and populate them
if they were not previously populated by HW specific setup.

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Fixes: 5f0456b43140 ("net: stmmac: Implement logic to automatically
select HW Interface")
Reported-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Cc: Corentin Labbe <clabbe.montjoie@gmail.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joao Pinto <jpinto@synopsys.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jose Abreu and committed by
David S. Miller
eb38401c 80a95a80

+22 -16
+22 -16
drivers/net/ethernet/stmicro/stmmac/hwif.c
··· 189 189 bool needs_gmac = priv->plat->has_gmac; 190 190 const struct stmmac_hwif_entry *entry; 191 191 struct mac_device_info *mac; 192 + bool needs_setup = true; 192 193 int i, ret; 193 194 u32 id; 194 195 195 196 if (needs_gmac) { 196 197 id = stmmac_get_id(priv, GMAC_VERSION); 197 - } else { 198 + } else if (needs_gmac4) { 198 199 id = stmmac_get_id(priv, GMAC4_VERSION); 200 + } else { 201 + id = 0; 199 202 } 200 203 201 204 /* Save ID for later use */ ··· 212 209 213 210 /* Check for HW specific setup first */ 214 211 if (priv->plat->setup) { 215 - priv->hw = priv->plat->setup(priv); 216 - if (!priv->hw) 217 - return -ENOMEM; 218 - return 0; 212 + mac = priv->plat->setup(priv); 213 + needs_setup = false; 214 + } else { 215 + mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL); 219 216 } 220 217 221 - mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL); 222 218 if (!mac) 223 219 return -ENOMEM; 224 220 ··· 229 227 continue; 230 228 if (needs_gmac4 ^ entry->gmac4) 231 229 continue; 232 - if (id < entry->min_id) 230 + /* Use synopsys_id var because some setups can override this */ 231 + if (priv->synopsys_id < entry->min_id) 233 232 continue; 234 233 235 - mac->desc = entry->desc; 236 - mac->dma = entry->dma; 237 - mac->mac = entry->mac; 238 - mac->ptp = entry->hwtimestamp; 239 - mac->mode = entry->mode; 240 - mac->tc = entry->tc; 234 + /* Only use generic HW helpers if needed */ 235 + mac->desc = mac->desc ? : entry->desc; 236 + mac->dma = mac->dma ? : entry->dma; 237 + mac->mac = mac->mac ? : entry->mac; 238 + mac->ptp = mac->ptp ? : entry->hwtimestamp; 239 + mac->mode = mac->mode ? : entry->mode; 240 + mac->tc = mac->tc ? : entry->tc; 241 241 242 242 priv->hw = mac; 243 243 priv->ptpaddr = priv->ioaddr + entry->regs.ptp_off; 244 244 priv->mmcaddr = priv->ioaddr + entry->regs.mmc_off; 245 245 246 246 /* Entry found */ 247 - ret = entry->setup(priv); 248 - if (ret) 249 - return ret; 247 + if (needs_setup) { 248 + ret = entry->setup(priv); 249 + if (ret) 250 + return ret; 251 + } 250 252 251 253 /* Run quirks, if needed */ 252 254 if (entry->quirks) {