Skip to content

Commit

Permalink
ethernet: tg3: remove direct netdev->dev_addr writes
Browse files Browse the repository at this point in the history
tg3 does various forms of direct writes to netdev->dev_addr.
Use a local buffer. Make sure local buffer is aligned since
eth_platform_get_mac_address() may call ether_addr_copy().

tg3_get_device_address() returns whenever it finds a method
that found a valid address. Instead of modifying all the exit
points pass the buffer from the outside and commit the address
in the caller.

Constify the argument of the set addr helper.

Signed-off-by: Jakub Kicinski <[email protected]>
Reviewed-by: Michael Chan <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
kuba-moo authored and davem330 committed Oct 9, 2021
1 parent 2b37367 commit a04436b
Showing 1 changed file with 25 additions and 23 deletions.
48 changes: 25 additions & 23 deletions drivers/net/ethernet/broadcom/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -3942,7 +3942,8 @@ static int tg3_load_tso_firmware(struct tg3 *tp)
}

/* tp->lock is held. */
static void __tg3_set_one_mac_addr(struct tg3 *tp, u8 *mac_addr, int index)
static void __tg3_set_one_mac_addr(struct tg3 *tp, const u8 *mac_addr,
int index)
{
u32 addr_high, addr_low;

Expand Down Expand Up @@ -16910,19 +16911,18 @@ static int tg3_get_invariants(struct tg3 *tp, const struct pci_device_id *ent)
return err;
}

static int tg3_get_device_address(struct tg3 *tp)
static int tg3_get_device_address(struct tg3 *tp, u8 *addr)
{
struct net_device *dev = tp->dev;
u32 hi, lo, mac_offset;
int addr_ok = 0;
int err;

if (!eth_platform_get_mac_address(&tp->pdev->dev, dev->dev_addr))
if (!eth_platform_get_mac_address(&tp->pdev->dev, addr))
return 0;

if (tg3_flag(tp, IS_SSB_CORE)) {
err = ssb_gige_get_macaddr(tp->pdev, &dev->dev_addr[0]);
if (!err && is_valid_ether_addr(&dev->dev_addr[0]))
err = ssb_gige_get_macaddr(tp->pdev, addr);
if (!err && is_valid_ether_addr(addr))
return 0;
}

Expand All @@ -16946,41 +16946,41 @@ static int tg3_get_device_address(struct tg3 *tp)
/* First try to get it from MAC address mailbox. */
tg3_read_mem(tp, NIC_SRAM_MAC_ADDR_HIGH_MBOX, &hi);
if ((hi >> 16) == 0x484b) {
dev->dev_addr[0] = (hi >> 8) & 0xff;
dev->dev_addr[1] = (hi >> 0) & 0xff;
addr[0] = (hi >> 8) & 0xff;
addr[1] = (hi >> 0) & 0xff;

tg3_read_mem(tp, NIC_SRAM_MAC_ADDR_LOW_MBOX, &lo);
dev->dev_addr[2] = (lo >> 24) & 0xff;
dev->dev_addr[3] = (lo >> 16) & 0xff;
dev->dev_addr[4] = (lo >> 8) & 0xff;
dev->dev_addr[5] = (lo >> 0) & 0xff;
addr[2] = (lo >> 24) & 0xff;
addr[3] = (lo >> 16) & 0xff;
addr[4] = (lo >> 8) & 0xff;
addr[5] = (lo >> 0) & 0xff;

/* Some old bootcode may report a 0 MAC address in SRAM */
addr_ok = is_valid_ether_addr(&dev->dev_addr[0]);
addr_ok = is_valid_ether_addr(addr);
}
if (!addr_ok) {
/* Next, try NVRAM. */
if (!tg3_flag(tp, NO_NVRAM) &&
!tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
!tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) {
memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2);
memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo));
memcpy(&addr[0], ((char *)&hi) + 2, 2);
memcpy(&addr[2], (char *)&lo, sizeof(lo));
}
/* Finally just fetch it out of the MAC control regs. */
else {
hi = tr32(MAC_ADDR_0_HIGH);
lo = tr32(MAC_ADDR_0_LOW);

dev->dev_addr[5] = lo & 0xff;
dev->dev_addr[4] = (lo >> 8) & 0xff;
dev->dev_addr[3] = (lo >> 16) & 0xff;
dev->dev_addr[2] = (lo >> 24) & 0xff;
dev->dev_addr[1] = hi & 0xff;
dev->dev_addr[0] = (hi >> 8) & 0xff;
addr[5] = lo & 0xff;
addr[4] = (lo >> 8) & 0xff;
addr[3] = (lo >> 16) & 0xff;
addr[2] = (lo >> 24) & 0xff;
addr[1] = hi & 0xff;
addr[0] = (hi >> 8) & 0xff;
}
}

if (!is_valid_ether_addr(&dev->dev_addr[0]))
if (!is_valid_ether_addr(addr))
return -EINVAL;
return 0;
}
Expand Down Expand Up @@ -17556,6 +17556,7 @@ static int tg3_init_one(struct pci_dev *pdev,
char str[40];
u64 dma_mask, persist_dma_mask;
netdev_features_t features = 0;
u8 addr[ETH_ALEN] __aligned(2);

err = pci_enable_device(pdev);
if (err) {
Expand Down Expand Up @@ -17778,12 +17779,13 @@ static int tg3_init_one(struct pci_dev *pdev,
tp->rx_pending = 63;
}

err = tg3_get_device_address(tp);
err = tg3_get_device_address(tp, addr);
if (err) {
dev_err(&pdev->dev,
"Could not obtain valid ethernet address, aborting\n");
goto err_out_apeunmap;
}
eth_hw_addr_set(dev, addr);

intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
Expand Down

0 comments on commit a04436b

Please sign in to comment.