/* SPDX-License-Identifier: GPL-2.0+ */
/* Copyright (C) 2018 Microchip Technology Inc. */
#include <linux/netdevice.h>
#include <linux/net_tstamp.h>
#include <linux/pci.h>
#include <linux/phy.h>
#include "lan743x_main.h"
#include "lan743x_ethtool.h"
#include <linux/sched.h>
#include <linux/iopoll.h>
/* eeprom */
#define LAN743X_EEPROM_MAGIC (0x74A5)
#define LAN743X_OTP_MAGIC (0x74F3)
#define EEPROM_INDICATOR_1 (0xA5)
#define EEPROM_INDICATOR_2 (0xAA)
#define EEPROM_MAC_OFFSET (0x01)
#define MAX_EEPROM_SIZE (512)
#define MAX_OTP_SIZE (1024)
#define OTP_INDICATOR_1 (0xF3)
#define OTP_INDICATOR_2 (0xF7)
#define LOCK_TIMEOUT_MAX_CNT (100) // 1 sec (10 msce * 100)
#define LAN743X_CSR_READ_OP(offset) lan743x_csr_read(adapter, offset)
static int lan743x_otp_power_up(struct lan743x_adapter *adapter)
{
u32 reg_value;
reg_value = lan743x_csr_read(adapter, OTP_PWR_DN);
if (reg_value & OTP_PWR_DN_PWRDN_N_) {
/* clear it and wait to be cleared */
reg_value &= ~OTP_PWR_DN_PWRDN_N_;
lan743x_csr_write(adapter, OTP_PWR_DN, reg_value);
usleep_range(100, 20000);
}
return 0;
}
static void lan743x_otp_power_down(struct lan743x_adapter *adapter)
{
u32 reg_value;
reg_value = lan743x_csr_read(adapter, OTP_PWR_DN);
if (!(reg_value & OTP_PWR_DN_PWRDN_N_)) {
/* set power down bit */
reg_value |= OTP_PWR_DN_PWRDN_N_;
lan743x_csr_write(adapter, OTP_PWR_DN, reg_value);
}
}
static void lan743x_otp_set_address(struct lan743x_adapter *adapter,
u32 address)
{
lan743x_csr_write(adapter, OTP_ADDR_HIGH, (address >> 8) & 0x03);
lan743x_csr_write(adapter, OTP_ADDR_LOW, address & 0xFF);
}
static void lan743x_otp_read_go(struct lan743x_adapter *adapter)
{
lan743x_csr_write(adapter, OTP_FUNC_CMD, OTP_FUNC_CMD_READ_);
lan743x_csr_write(adapter, OTP_CMD_GO, OTP_CMD_GO_GO_);
}
static int lan743x_otp_wait_till_not_busy(struct lan743x_adapter *adapter)
{
unsigned long timeout;
u32 reg_val;
timeout = jiffies + HZ;
do {
if (time_after(jiffies, timeout)) {
netif_warn(adapter, drv, adapter->netdev,
"Timeout on OTP_STATUS completion\n");
return -EIO;
}
udelay(1);
reg_val = lan743x_csr_read(adapter, OTP_STATUS);
}