-/* $OpenBSD: if_iwx.c,v 1.143 2022/05/09 21:57:26 stsp Exp $ */
+/* $OpenBSD: if_iwx.c,v 1.144 2022/05/10 09:11:44 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
uint8_t);
void iwx_ba_task(void *);
-int iwx_set_mac_addr_from_csr(struct iwx_softc *, struct iwx_nvm_data *);
+void iwx_set_mac_addr_from_csr(struct iwx_softc *, struct iwx_nvm_data *);
int iwx_is_valid_mac_addr(const uint8_t *);
+void iwx_flip_hw_address(uint32_t, uint32_t, uint8_t *);
int iwx_nvm_get(struct iwx_softc *);
int iwx_load_firmware(struct iwx_softc *);
int iwx_start_fw(struct iwx_softc *);
return EBUSY;
}
-/* Read the mac address from WFMP registers. */
-int
+void
iwx_set_mac_addr_from_csr(struct iwx_softc *sc, struct iwx_nvm_data *data)
{
- const uint8_t *hw_addr;
uint32_t mac_addr0, mac_addr1;
+ memset(data->hw_addr, 0, sizeof(data->hw_addr));
+
if (!iwx_nic_lock(sc))
- return EBUSY;
+ return;
- mac_addr0 = htole32(iwx_read_prph(sc, IWX_WFMP_MAC_ADDR_0));
- mac_addr1 = htole32(iwx_read_prph(sc, IWX_WFMP_MAC_ADDR_1));
+ mac_addr0 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR0_STRAP(sc)));
+ mac_addr1 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR1_STRAP(sc)));
- hw_addr = (const uint8_t *)&mac_addr0;
- data->hw_addr[0] = hw_addr[3];
- data->hw_addr[1] = hw_addr[2];
- data->hw_addr[2] = hw_addr[1];
- data->hw_addr[3] = hw_addr[0];
+ iwx_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
- hw_addr = (const uint8_t *)&mac_addr1;
- data->hw_addr[4] = hw_addr[1];
- data->hw_addr[5] = hw_addr[0];
+ /* If OEM fused a valid address, use it instead of the one in OTP. */
+ if (iwx_is_valid_mac_addr(data->hw_addr)) {
+ iwx_nic_unlock(sc);
+ return;
+ }
+
+ mac_addr0 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR0_OTP(sc)));
+ mac_addr1 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR1_OTP(sc)));
+
+ iwx_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
iwx_nic_unlock(sc);
- return 0;
}
int
!ETHER_IS_MULTICAST(addr));
}
+void
+iwx_flip_hw_address(uint32_t mac_addr0, uint32_t mac_addr1, uint8_t *dest)
+{
+ const uint8_t *hw_addr;
+
+ hw_addr = (const uint8_t *)&mac_addr0;
+ dest[0] = hw_addr[3];
+ dest[1] = hw_addr[2];
+ dest[2] = hw_addr[1];
+ dest[3] = hw_addr[0];
+
+ hw_addr = (const uint8_t *)&mac_addr1;
+ dest[4] = hw_addr[1];
+ dest[5] = hw_addr[0];
+}
+
int
iwx_nvm_get(struct iwx_softc *sc)
{
}
}
+ sc->mac_addr_from_csr = 0x380; /* differs on BZ hw generation */
+
if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
sc->sc_umac_prph_offset = 0x300000;
sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX_GEN3;
-/* $OpenBSD: if_iwxreg.h,v 1.38 2022/05/09 21:57:26 stsp Exp $ */
+/* $OpenBSD: if_iwxreg.h,v 1.39 2022/05/10 09:11:44 stsp Exp $ */
/*-
* Based on BSD-licensed source modules in the Linux iwlwifi driver,
#define IWX_MSIX_AUTO_CLEAR_CAUSE (0 << 7)
#define IWX_MSIX_NON_AUTO_CLEAR_CAUSE (1 << 7)
+#define IWX_CSR_ADDR_BASE(sc) ((sc)->mac_addr_from_csr)
+#define IWX_CSR_MAC_ADDR0_OTP(sc) (IWX_CSR_ADDR_BASE(sc) + 0x00)
+#define IWX_CSR_MAC_ADDR1_OTP(sc) (IWX_CSR_ADDR_BASE(sc) + 0x04)
+#define IWX_CSR_MAC_ADDR0_STRAP(sc) (IWX_CSR_ADDR_BASE(sc) + 0x08)
+#define IWX_CSR_MAC_ADDR1_STRAP(sc) (IWX_CSR_ADDR_BASE(sc) + 0x0c)
+
/**
* uCode API flags
* @IWX_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously