Skip to content

Commit d808f7c

Browse files
Raju Lakkarajudavem330
authored andcommitted
net: lan743x: Add support for OTP
Add new the OTP read and write access functions for PCI11010/PCI11414 chips PCI11010/PCI11414 OTP module register offsets are different from LAN743x OTP module Signed-off-by: Raju Lakkaraju <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent cdea83c commit d808f7c

File tree

2 files changed

+180
-3
lines changed

2 files changed

+180
-3
lines changed

drivers/net/ethernet/microchip/lan743x_ethtool.c

Lines changed: 166 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,160 @@ static void lan743x_hs_syslock_release(struct lan743x_adapter *adapter)
212212
spin_unlock(&adapter->eth_syslock_spinlock);
213213
}
214214

215+
static void lan743x_hs_otp_power_up(struct lan743x_adapter *adapter)
216+
{
217+
u32 reg_value;
218+
219+
reg_value = lan743x_csr_read(adapter, HS_OTP_PWR_DN);
220+
if (reg_value & OTP_PWR_DN_PWRDN_N_) {
221+
reg_value &= ~OTP_PWR_DN_PWRDN_N_;
222+
lan743x_csr_write(adapter, HS_OTP_PWR_DN, reg_value);
223+
/* To flush the posted write so the subsequent delay is
224+
* guaranteed to happen after the write at the hardware
225+
*/
226+
lan743x_csr_read(adapter, HS_OTP_PWR_DN);
227+
udelay(1);
228+
}
229+
}
230+
231+
static void lan743x_hs_otp_power_down(struct lan743x_adapter *adapter)
232+
{
233+
u32 reg_value;
234+
235+
reg_value = lan743x_csr_read(adapter, HS_OTP_PWR_DN);
236+
if (!(reg_value & OTP_PWR_DN_PWRDN_N_)) {
237+
reg_value |= OTP_PWR_DN_PWRDN_N_;
238+
lan743x_csr_write(adapter, HS_OTP_PWR_DN, reg_value);
239+
/* To flush the posted write so the subsequent delay is
240+
* guaranteed to happen after the write at the hardware
241+
*/
242+
lan743x_csr_read(adapter, HS_OTP_PWR_DN);
243+
udelay(1);
244+
}
245+
}
246+
247+
static void lan743x_hs_otp_set_address(struct lan743x_adapter *adapter,
248+
u32 address)
249+
{
250+
lan743x_csr_write(adapter, HS_OTP_ADDR_HIGH, (address >> 8) & 0x03);
251+
lan743x_csr_write(adapter, HS_OTP_ADDR_LOW, address & 0xFF);
252+
}
253+
254+
static void lan743x_hs_otp_read_go(struct lan743x_adapter *adapter)
255+
{
256+
lan743x_csr_write(adapter, HS_OTP_FUNC_CMD, OTP_FUNC_CMD_READ_);
257+
lan743x_csr_write(adapter, HS_OTP_CMD_GO, OTP_CMD_GO_GO_);
258+
}
259+
260+
static int lan743x_hs_otp_cmd_cmplt_chk(struct lan743x_adapter *adapter)
261+
{
262+
u32 val;
263+
264+
return readx_poll_timeout(LAN743X_CSR_READ_OP, HS_OTP_STATUS, val,
265+
!(val & OTP_STATUS_BUSY_),
266+
80, 10000);
267+
}
268+
269+
static int lan743x_hs_otp_read(struct lan743x_adapter *adapter, u32 offset,
270+
u32 length, u8 *data)
271+
{
272+
int ret;
273+
int i;
274+
275+
ret = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT);
276+
if (ret < 0)
277+
return ret;
278+
279+
lan743x_hs_otp_power_up(adapter);
280+
281+
ret = lan743x_hs_otp_cmd_cmplt_chk(adapter);
282+
if (ret < 0)
283+
goto power_down;
284+
285+
lan743x_hs_syslock_release(adapter);
286+
287+
for (i = 0; i < length; i++) {
288+
ret = lan743x_hs_syslock_acquire(adapter,
289+
LOCK_TIMEOUT_MAX_CNT);
290+
if (ret < 0)
291+
return ret;
292+
293+
lan743x_hs_otp_set_address(adapter, offset + i);
294+
295+
lan743x_hs_otp_read_go(adapter);
296+
ret = lan743x_hs_otp_cmd_cmplt_chk(adapter);
297+
if (ret < 0)
298+
goto power_down;
299+
300+
data[i] = lan743x_csr_read(adapter, HS_OTP_READ_DATA);
301+
302+
lan743x_hs_syslock_release(adapter);
303+
}
304+
305+
ret = lan743x_hs_syslock_acquire(adapter,
306+
LOCK_TIMEOUT_MAX_CNT);
307+
if (ret < 0)
308+
return ret;
309+
310+
power_down:
311+
lan743x_hs_otp_power_down(adapter);
312+
lan743x_hs_syslock_release(adapter);
313+
314+
return ret;
315+
}
316+
317+
static int lan743x_hs_otp_write(struct lan743x_adapter *adapter, u32 offset,
318+
u32 length, u8 *data)
319+
{
320+
int ret;
321+
int i;
322+
323+
ret = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT);
324+
if (ret < 0)
325+
return ret;
326+
327+
lan743x_hs_otp_power_up(adapter);
328+
329+
ret = lan743x_hs_otp_cmd_cmplt_chk(adapter);
330+
if (ret < 0)
331+
goto power_down;
332+
333+
/* set to BYTE program mode */
334+
lan743x_csr_write(adapter, HS_OTP_PRGM_MODE, OTP_PRGM_MODE_BYTE_);
335+
336+
lan743x_hs_syslock_release(adapter);
337+
338+
for (i = 0; i < length; i++) {
339+
ret = lan743x_hs_syslock_acquire(adapter,
340+
LOCK_TIMEOUT_MAX_CNT);
341+
if (ret < 0)
342+
return ret;
343+
344+
lan743x_hs_otp_set_address(adapter, offset + i);
345+
346+
lan743x_csr_write(adapter, HS_OTP_PRGM_DATA, data[i]);
347+
lan743x_csr_write(adapter, HS_OTP_TST_CMD,
348+
OTP_TST_CMD_PRGVRFY_);
349+
lan743x_csr_write(adapter, HS_OTP_CMD_GO, OTP_CMD_GO_GO_);
350+
351+
ret = lan743x_hs_otp_cmd_cmplt_chk(adapter);
352+
if (ret < 0)
353+
goto power_down;
354+
355+
lan743x_hs_syslock_release(adapter);
356+
}
357+
358+
ret = lan743x_hs_syslock_acquire(adapter, LOCK_TIMEOUT_MAX_CNT);
359+
if (ret < 0)
360+
return ret;
361+
362+
power_down:
363+
lan743x_hs_otp_power_down(adapter);
364+
lan743x_hs_syslock_release(adapter);
365+
366+
return ret;
367+
}
368+
215369
static int lan743x_eeprom_wait(struct lan743x_adapter *adapter)
216370
{
217371
unsigned long start_time = jiffies;
@@ -462,7 +616,12 @@ static int lan743x_ethtool_get_eeprom(struct net_device *netdev,
462616
int ret = 0;
463617

464618
if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP) {
465-
ret = lan743x_otp_read(adapter, ee->offset, ee->len, data);
619+
if (adapter->is_pci11x1x)
620+
ret = lan743x_hs_otp_read(adapter, ee->offset,
621+
ee->len, data);
622+
else
623+
ret = lan743x_otp_read(adapter, ee->offset,
624+
ee->len, data);
466625
} else {
467626
if (adapter->is_pci11x1x)
468627
ret = lan743x_hs_eeprom_read(adapter, ee->offset,
@@ -484,8 +643,12 @@ static int lan743x_ethtool_set_eeprom(struct net_device *netdev,
484643
if (adapter->flags & LAN743X_ADAPTER_FLAG_OTP) {
485644
/* Beware! OTP is One Time Programming ONLY! */
486645
if (ee->magic == LAN743X_OTP_MAGIC) {
487-
ret = lan743x_otp_write(adapter, ee->offset,
488-
ee->len, data);
646+
if (adapter->is_pci11x1x)
647+
ret = lan743x_hs_otp_write(adapter, ee->offset,
648+
ee->len, data);
649+
else
650+
ret = lan743x_otp_write(adapter, ee->offset,
651+
ee->len, data);
489652
}
490653
} else {
491654
if (ee->magic == LAN743X_EEPROM_MAGIC) {

drivers/net/ethernet/microchip/lan743x_main.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,20 @@
556556
#define OTP_STATUS (0x1030)
557557
#define OTP_STATUS_BUSY_ BIT(0)
558558

559+
/* Hearthstone OTP block registers */
560+
#define HS_OTP_BLOCK_BASE (ETH_SYS_REG_ADDR_BASE + \
561+
ETH_OTP_REG_ADDR_BASE)
562+
#define HS_OTP_PWR_DN (HS_OTP_BLOCK_BASE + 0x0)
563+
#define HS_OTP_ADDR_HIGH (HS_OTP_BLOCK_BASE + 0x4)
564+
#define HS_OTP_ADDR_LOW (HS_OTP_BLOCK_BASE + 0x8)
565+
#define HS_OTP_PRGM_DATA (HS_OTP_BLOCK_BASE + 0x10)
566+
#define HS_OTP_PRGM_MODE (HS_OTP_BLOCK_BASE + 0x14)
567+
#define HS_OTP_READ_DATA (HS_OTP_BLOCK_BASE + 0x18)
568+
#define HS_OTP_FUNC_CMD (HS_OTP_BLOCK_BASE + 0x20)
569+
#define HS_OTP_TST_CMD (HS_OTP_BLOCK_BASE + 0x24)
570+
#define HS_OTP_CMD_GO (HS_OTP_BLOCK_BASE + 0x28)
571+
#define HS_OTP_STATUS (HS_OTP_BLOCK_BASE + 0x30)
572+
559573
/* MAC statistics registers */
560574
#define STAT_RX_FCS_ERRORS (0x1200)
561575
#define STAT_RX_ALIGNMENT_ERRORS (0x1204)

0 commit comments

Comments
 (0)