@@ -796,6 +796,153 @@ static int fxgmac_open(struct net_device *netdev)
return ret;
}
+#define EFUSE_FISRT_UPDATE_ADDR 255
+#define EFUSE_SECOND_UPDATE_ADDR 209
+#define EFUSE_MAX_ENTRY 39
+#define EFUSE_PATCH_ADDR_START 0
+#define EFUSE_PATCH_DATA_START 2
+#define EFUSE_PATCH_SIZE 6
+#define EFUSE_REGION_A_B_LENGTH 18
+
+static bool fxgmac_efuse_read_data(struct fxgmac_pdata *pdata, u32 offset,
+ u8 *value)
+{
+ bool ret = false;
+ u32 wait = 1000;
+ u32 val = 0;
+
+ fxgmac_set_bits(&val, EFUSE_OP_ADDR_POS, EFUSE_OP_ADDR_LEN, offset);
+ fxgmac_set_bits(&val, EFUSE_OP_START_POS, EFUSE_OP_START_LEN, 1);
+ fxgmac_set_bits(&val, EFUSE_OP_MODE_POS, EFUSE_OP_MODE_LEN,
+ EFUSE_OP_MODE_ROW_READ);
+ wr32_mem(pdata, val, EFUSE_OP_CTRL_0);
+
+ while (wait--) {
+ fsleep(20);
+ val = rd32_mem(pdata, EFUSE_OP_CTRL_1);
+ if (FXGMAC_GET_BITS(val, EFUSE_OP_DONE_POS,
+ EFUSE_OP_DONE_LEN)) {
+ ret = true;
+ break;
+ }
+ }
+
+ if (!ret) {
+ yt_err(pdata, "Fail to reading efuse Byte%d\n", offset);
+ return ret;
+ }
+
+ if (value)
+ *value = FXGMAC_GET_BITS(val, EFUSE_OP_RD_DATA_POS,
+ EFUSE_OP_RD_DATA_LEN) & 0xff;
+
+ return ret;
+}
+
+static bool fxgmac_efuse_read_index_patch(struct fxgmac_pdata *pdata, u8 index,
+ u32 *offset, u32 *value)
+{
+ u8 tmp[EFUSE_PATCH_SIZE - EFUSE_PATCH_DATA_START];
+ u32 addr, i;
+ bool ret;
+
+ if (index >= EFUSE_MAX_ENTRY) {
+ yt_err(pdata, "Reading efuse out of range, index %d\n", index);
+ return false;
+ }
+
+ for (i = EFUSE_PATCH_ADDR_START; i < EFUSE_PATCH_DATA_START; i++) {
+ addr = EFUSE_REGION_A_B_LENGTH + index * EFUSE_PATCH_SIZE + i;
+ ret = fxgmac_efuse_read_data(pdata, addr,
+ tmp + i - EFUSE_PATCH_ADDR_START);
+ if (!ret) {
+ yt_err(pdata, "Fail to reading efuse Byte%d\n", addr);
+ return ret;
+ }
+ }
+ if (offset) {
+ /* tmp[0] is low 8bit date, tmp[1] is high 8bit date */
+ *offset = tmp[0] | (tmp[1] << 8);
+ }
+
+ for (i = EFUSE_PATCH_DATA_START; i < EFUSE_PATCH_SIZE; i++) {
+ addr = EFUSE_REGION_A_B_LENGTH + index * EFUSE_PATCH_SIZE + i;
+ ret = fxgmac_efuse_read_data(pdata, addr,
+ tmp + i - EFUSE_PATCH_DATA_START);
+ if (!ret) {
+ yt_err(pdata, "Fail to reading efuse Byte%d\n", addr);
+ return ret;
+ }
+ }
+ if (value) {
+ /* tmp[0] is low 8bit date, tmp[1] is low 8bit date
+ * ... tmp[3] is highest 8bit date
+ */
+ *value = tmp[0] | (tmp[1] << 8) | (tmp[2] << 16) |
+ (tmp[3] << 24);
+ }
+
+ return ret;
+}
+
+static bool fxgmac_efuse_read_mac_subsys(struct fxgmac_pdata *pdata,
+ u8 *mac_addr, u32 *subsys, u32 *revid)
+{
+ u32 machr = 0, maclr = 0;
+ u32 offset = 0, val = 0;
+ bool ret = true;
+ u8 index;
+
+ for (index = 0;; index++) {
+ if (!fxgmac_efuse_read_index_patch(pdata, index, &offset, &val))
+ return false;
+
+ if (offset == 0x00)
+ break; /* Reach the blank. */
+
+ if (offset == MACA0LR_FROM_EFUSE)
+ maclr = val;
+
+ if (offset == MACA0HR_FROM_EFUSE)
+ machr = val;
+
+ if (offset == PCI_REVISION_ID && revid)
+ *revid = val;
+
+ if (offset == PCI_SUBSYSTEM_VENDOR_ID && subsys)
+ *subsys = val;
+ }
+
+ if (mac_addr) {
+ mac_addr[5] = (u8)(maclr & 0xFF);
+ mac_addr[4] = (u8)((maclr >> 8) & 0xFF);
+ mac_addr[3] = (u8)((maclr >> 16) & 0xFF);
+ mac_addr[2] = (u8)((maclr >> 24) & 0xFF);
+ mac_addr[1] = (u8)(machr & 0xFF);
+ mac_addr[0] = (u8)((machr >> 8) & 0xFF);
+ }
+
+ return ret;
+}
+
+static int fxgmac_read_mac_addr(struct fxgmac_pdata *pdata)
+{
+ u8 default_addr[ETH_ALEN] = { 0, 0x55, 0x7b, 0xb5, 0x7d, 0xf7 };
+ struct net_device *netdev = pdata->netdev;
+ int ret;
+
+ /* If efuse have mac addr, use it. if not, use static mac address. */
+ ret = fxgmac_efuse_read_mac_subsys(pdata, pdata->mac_addr, NULL, NULL);
+ if (!ret)
+ return -1;
+
+ if (is_zero_ether_addr(pdata->mac_addr))
+ /* Use a static mac address for test */
+ memcpy(pdata->mac_addr, default_addr, netdev->addr_len);
+
+ return 0;
+}
+
#define FXGMAC_SYSCLOCK 125000000 /* System clock is 125 MHz */
static void fxgmac_default_config(struct fxgmac_pdata *pdata)
Implement the fxgmac_read_mac_addr function to read mac address form efuse. Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com> --- .../ethernet/motorcomm/yt6801/yt6801_net.c | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+)