diff --git a/drivers/ethernet/eth_lan865x.c b/drivers/ethernet/eth_lan865x.c index 870d6ab82cb..a9a3673ed99 100644 --- a/drivers/ethernet/eth_lan865x.c +++ b/drivers/ethernet/eth_lan865x.c @@ -179,65 +179,109 @@ static uint8_t lan865x_read_indirect_reg(const struct device *dev, uint8_t addr, return (uint8_t) val & mask; } +/* + * Values in the below table for LAN865x rev. B0 and B1 (with place + * holders for cfgparamX. + */ +static oa_mem_map_t lan865x_conf[] = { + { .mms = 0x1, .address = 0x00, .value = 0x0000 }, + { .mms = 0x4, .address = 0xD0, .value = 0x3F31 }, + { .mms = 0x4, .address = 0xE0, .value = 0xC000 }, + { .mms = 0x4, .address = 0x84, .value = 0x0000 }, /* cfgparam1 */ + { .mms = 0x4, .address = 0x8A, .value = 0x0000 }, /* cfgparam2 */ + { .mms = 0x4, .address = 0xE9, .value = 0x9E50 }, + { .mms = 0x4, .address = 0xF5, .value = 0x1CF8 }, + { .mms = 0x4, .address = 0xF4, .value = 0xC020 }, + { .mms = 0x4, .address = 0xF8, .value = 0xB900 }, + { .mms = 0x4, .address = 0xF9, .value = 0x4E53 }, + { .mms = 0x4, .address = 0x91, .value = 0x9660 }, + { .mms = 0x4, .address = 0x77, .value = 0x0028 }, + { .mms = 0x4, .address = 0x43, .value = 0x00FF }, + { .mms = 0x4, .address = 0x44, .value = 0xFFFF }, + { .mms = 0x4, .address = 0x45, .value = 0x0000 }, + { .mms = 0x4, .address = 0x53, .value = 0x00FF }, + { .mms = 0x4, .address = 0x54, .value = 0xFFFF }, + { .mms = 0x4, .address = 0x55, .value = 0x0000 }, + { .mms = 0x4, .address = 0x40, .value = 0x0002 }, + { .mms = 0x4, .address = 0x50, .value = 0x0002 }, + { .mms = 0x4, .address = 0xAD, .value = 0x0000 }, /* cfgparam3 */ + { .mms = 0x4, .address = 0xAE, .value = 0x0000 }, /* cfgparam4 */ + { .mms = 0x4, .address = 0xAF, .value = 0x0000 }, /* cfgparam5 */ + { .mms = 0x4, .address = 0xB0, .value = 0x0103 }, + { .mms = 0x4, .address = 0xB1, .value = 0x0910 }, + { .mms = 0x4, .address = 0xB2, .value = 0x1D26 }, + { .mms = 0x4, .address = 0xB3, .value = 0x002A }, + { .mms = 0x4, .address = 0xB4, .value = 0x0103 }, + { .mms = 0x4, .address = 0xB5, .value = 0x070D }, + { .mms = 0x4, .address = 0xB6, .value = 0x1720 }, + { .mms = 0x4, .address = 0xB7, .value = 0x0027 }, + { .mms = 0x4, .address = 0xB8, .value = 0x0509 }, + { .mms = 0x4, .address = 0xB9, .value = 0x0E13 }, + { .mms = 0x4, .address = 0xBA, .value = 0x1C25 }, + { .mms = 0x4, .address = 0xBB, .value = 0x002B }, + { .mms = 0x4, .address = 0x0C, .value = 0x0100 }, + { .mms = 0x4, .address = 0x81, .value = 0x00E0 }, +}; + +/* Based on AN1760 DS60001760G pseudo code */ static int lan865x_init_chip(const struct device *dev, uint8_t silicon_rev) { + uint16_t cfgparam1, cfgparam2, cfgparam3, cfgparam4, cfgparam5; + uint8_t i, size = ARRAY_SIZE(lan865x_conf); struct lan865x_data *ctx = dev->data; + int8_t offset1 = 0, offset2 = 0; uint8_t value1, value2; - int8_t offset1 = 0, offset2 = 0, ret; - uint16_t value3, value4, value5, value6, value7; - uint16_t cfgparam1, cfgparam2, cfgparam3, cfgparam4, cfgparam5; - uint32_t val; - ret = lan865x_read_indirect_reg(dev, 0x05, 0x40); - if (ret == 0) { - LOG_ERR("LAN865x error! Please contact microchip support for replacement."); - return -EIO; - } + /* Enable protected control RW */ + oa_tc6_set_protected_ctrl(ctx->tc6, true); value1 = lan865x_read_indirect_reg(dev, 0x04, 0x1F); if ((value1 & 0x10) != 0) { /* Convert uint8_t to int8_t */ - offset1 = value1 | 0xE0; - if (offset1 < -5) { - LOG_ERR("LAN865x internal error!"); - return -EIO; - } + offset1 = (int8_t)((uint8_t)value1 - 0x20); } else { - offset1 = value1; + offset1 = (int8_t)value1; } value2 = lan865x_read_indirect_reg(dev, 0x08, 0x1F); if ((value2 & 0x10) != 0) { /* Convert uint8_t to int8_t */ - offset2 = value2 | 0xE0; + offset2 = (int8_t)((uint8_t)value2 - 0x20); } else { - offset2 = value2; - } - - oa_tc6_reg_read(ctx->tc6, 0x00040084, &val); - value3 = (uint16_t)val; - - oa_tc6_reg_read(ctx->tc6, 0x0004008A, &val); - value4 = (uint16_t)val; - - oa_tc6_reg_read(ctx->tc6, 0x000400AD, &val); - value5 = (uint16_t)val; - - oa_tc6_reg_read(ctx->tc6, 0x000400AE, &val); - value6 = (uint8_t)val; - - oa_tc6_reg_read(ctx->tc6, 0x000400AF, &val); - value7 = (uint8_t)val; + offset2 = (int8_t)value2; + } + + cfgparam1 = (uint16_t) (((9 + offset1) & 0x3F) << 10) | + (uint16_t) (((14 + offset1) & 0x3F) << 4) | 0x03; + cfgparam2 = (uint16_t) (((40 + offset2) & 0x3F) << 10); + cfgparam3 = (uint16_t) (((5 + offset1) & 0x3F) << 8) | + (uint16_t) ((9 + offset1) & 0x3F); + cfgparam4 = (uint16_t) (((9 + offset1) & 0x3F) << 8) | + (uint16_t) ((14 + offset1) & 0x3F); + cfgparam5 = (uint16_t) (((17 + offset1) & 0x3F) << 8) | + (uint16_t) ((22 + offset1) & 0x3F); + + lan865x_update_dev_cfg_array(lan865x_conf, size, + MMS_REG(0x4, 0x84), cfgparam1); + lan865x_update_dev_cfg_array(lan865x_conf, size, + MMS_REG(0x4, 0x8A), cfgparam2); + lan865x_update_dev_cfg_array(lan865x_conf, size, + MMS_REG(0x4, 0xAD), cfgparam3); + lan865x_update_dev_cfg_array(lan865x_conf, size, + MMS_REG(0x4, 0xAE), cfgparam4); + lan865x_update_dev_cfg_array(lan865x_conf, size, + MMS_REG(0x4, 0xAF), cfgparam5); - cfgparam1 = (value3 & 0xF) | (((9 + offset1) << 10) | ((14 + offset1) << 4)); - cfgparam2 = (value4 & 0x3FF) | ((40 + offset2) << 10); - cfgparam3 = (value5 & 0xC0C0) | (((5 + offset1) << 8) | (9 + offset1)); - cfgparam4 = (value6 & 0xC0C0) | (((9 + offset1) << 8) | (14 + offset1)); - cfgparam5 = (value7 & 0xC0C0) | (((17 + offset1) << 8) | (22 + offset1)); + if (silicon_rev == 1) { + /* For silicon rev 1 (B0): (bit [3..0] from 0x0A0084 */ + lan865x_update_dev_cfg_array(lan865x_conf, size, + MMS_REG(0x4, 0xD0), 0x5F21); + } - oa_tc6_reg_write(ctx->tc6, 0x00040084, (uint32_t) cfgparam1); - oa_tc6_reg_write(ctx->tc6, 0x0004008A, (uint32_t) cfgparam2); - oa_tc6_reg_write(ctx->tc6, 0x000400AD, (uint32_t) cfgparam3); - oa_tc6_reg_write(ctx->tc6, 0x000400AE, (uint32_t) cfgparam4); - oa_tc6_reg_write(ctx->tc6, 0x000400AF, (uint32_t) cfgparam5); + /* Write LAN865x config with correct order */ + for (i = 0; i < size; i++) { + oa_tc6_reg_write(ctx->tc6, MMS_REG(lan865x_conf[i].mms, + lan865x_conf[i].address), + (uint32_t)lan865x_conf[i].value); + } return 0; } @@ -312,58 +356,9 @@ static int lan865x_set_specific_multicast_addr(const struct device *dev) static int lan865x_default_config(const struct device *dev, uint8_t silicon_rev) { - /* Values in the below table are the same for LAN865x rev. B0 and B1 */ - static const oa_mem_map_t lan865x_conf[] = { - { .address = 0x00010000, .value = 0x00000000 }, - { .address = 0x00040091, .value = 0x00009660 }, - { .address = 0x00040081, .value = 0x00000080 }, - { .address = 0x00010077, .value = 0x00000028 }, - { .address = 0x00040043, .value = 0x000000FF }, - { .address = 0x00040044, .value = 0x0000FFFF }, - { .address = 0x00040045, .value = 0x00000000 }, - { .address = 0x00040053, .value = 0x000000FF }, - { .address = 0x00040054, .value = 0x0000FFFF }, - { .address = 0x00040055, .value = 0x00000000 }, - { .address = 0x00040040, .value = 0x00000002 }, - { .address = 0x00040050, .value = 0x00000002 }, - { .address = 0x000400E9, .value = 0x00009E50 }, - { .address = 0x000400F5, .value = 0x00001CF8 }, - { .address = 0x000400F4, .value = 0x0000C020 }, - { .address = 0x000400F8, .value = 0x00009B00 }, - { .address = 0x000400F9, .value = 0x00004E53 }, - { .address = 0x000400B0, .value = 0x00000103 }, - { .address = 0x000400B1, .value = 0x00000910 }, - { .address = 0x000400B2, .value = 0x00001D26 }, - { .address = 0x000400B3, .value = 0x0000002A }, - { .address = 0x000400B4, .value = 0x00000103 }, - { .address = 0x000400B5, .value = 0x0000070D }, - { .address = 0x000400B6, .value = 0x00001720 }, - { .address = 0x000400B7, .value = 0x00000027 }, - { .address = 0x000400B8, .value = 0x00000509 }, - { .address = 0x000400B9, .value = 0x00000E13 }, - { .address = 0x000400BA, .value = 0x00001C25 }, - { .address = 0x000400BB, .value = 0x0000002B }, - { .address = 0x0000000C, .value = 0x00000100 }, - { .address = 0x00040081, .value = 0x000000E0 }, - }; const struct lan865x_config *cfg = dev->config; - uint8_t i, size = ARRAY_SIZE(lan865x_conf); - struct lan865x_data *ctx = dev->data; int ret; - /* Enable protected control RW */ - oa_tc6_set_protected_ctrl(ctx->tc6, true); - - for (i = 0; i < size; i++) { - oa_tc6_reg_write(ctx->tc6, lan865x_conf[i].address, - lan865x_conf[i].value); - } - - if (silicon_rev == 1) { - /* For silicon rev 1 (B0): (bit [3..0] from 0x0A0084 */ - oa_tc6_reg_write(ctx->tc6, 0x000400D0, 0x5F21); - } - lan865x_write_macaddress(dev); lan865x_set_specific_multicast_addr(dev); diff --git a/drivers/ethernet/eth_lan865x_priv.h b/drivers/ethernet/eth_lan865x_priv.h index 1de2c6c7ca1..1ba84bd9ff7 100644 --- a/drivers/ethernet/eth_lan865x_priv.h +++ b/drivers/ethernet/eth_lan865x_priv.h @@ -81,4 +81,14 @@ struct lan865x_data { k_tid_t tid_int; }; +static inline void lan865x_update_dev_cfg_array(oa_mem_map_t *cfg, uint8_t size, + uint32_t addr, uint16_t val) +{ + for (uint8_t i = 0; i < size; i++) { + if (cfg[i].address == addr) { + cfg[i].value = val; + } + } +} + #endif /* ETH_LAN865X_PRIV_H__ */ diff --git a/drivers/ethernet/oa_tc6.h b/drivers/ethernet/oa_tc6.h index 0918e1382fa..c61e0359d99 100644 --- a/drivers/ethernet/oa_tc6.h +++ b/drivers/ethernet/oa_tc6.h @@ -113,8 +113,9 @@ struct oa_tc6 { }; typedef struct { - uint32_t address; - uint32_t value; + uint8_t mms; + uint8_t address; + uint16_t value; } oa_mem_map_t; /**