#ifndef KSZSW_REGS_ACC_H
#define KSZSW_REGS_ACC_H

#include "lip/lip_defs.h"
#include "kszsw_regs.h"
#include "lip/phy/lip_phy_cfg_defs.h"
#include "lip/link/lip_eth_defs.h"

typedef t_lip_errs (*t_kszsw_reg_read8)(void *ctx, uint16_t regaddr, uint8_t *regval);
typedef t_lip_errs (*t_kszsw_reg_read16)(void *ctx, uint16_t regaddr, uint16_t *regval);
typedef t_lip_errs (*t_kszsw_reg_read32)(void *ctx, uint16_t regaddr, uint32_t *regval);

typedef t_lip_errs (*t_kszsw_reg_write8)(void *ctx, uint16_t regaddr, uint8_t regval);
typedef t_lip_errs (*t_kszsw_reg_write16)(void *ctx, uint16_t regaddr, uint16_t regval);
typedef t_lip_errs (*t_kszsw_reg_write32)(void *ctx, uint16_t regaddr, uint32_t regval);


typedef struct {
    t_kszsw_reg_read8   rd8;
    t_kszsw_reg_read16  rd16;
    t_kszsw_reg_read32  rd32;
    t_kszsw_reg_write8  wr8;
    t_kszsw_reg_write16 wr16;
    t_kszsw_reg_write32 wr32;
} t_kszsw_reg_iface;

typedef struct {
    void *ctx;
    const t_kszsw_reg_iface *iface;
} t_kszsw_reg_acc;


typedef enum {
    KSZSW_MIB_VALUE_FLAG_VALID = 1 << 0,
    KSZSW_MIB_VALUE_FLAG_OV    = 1 << 1,
} t_kszsw_mib_value_flags;

typedef struct {
    uint16_t flags;
    uint16_t hval;
    uint32_t lval;
} t_kszsw_mib_value;



typedef enum {
    KSZSW_STADDR_ENTRY_FLAG_VALID      = 1 << 0, /* Entry is valid */
    KSZSW_STADDR_ENTRY_FLAG_SRC_FLT    = 1 << 1, /* Drop packet if source address match during source learning */
    KSZSW_STADDR_ENTRY_FLAG_DST_FLT    = 1 << 2, /* Drop packet if destination address match during lookup */
    KSZSW_STADDR_ENTRY_FLAG_PORTST_OV  = 1 << 3, /* Enable overriding of port state */
    KSZSW_STADDR_ENTRY_FLAG_USE_FID    = 1 << 4, /* Use FID on multicast packets for matching */
} t_kszsw_staddr_entry_flags;

typedef struct {
    uint16_t flags; /* flags from t_kszsw_staddr_entry_flags  */
    uint8_t  prio; /* Priority */
    uint8_t  mstp; /* Multiple Spanning Tree Protocol group ID for matching */
    uint8_t  fid;  /* VLAN group ID for matching */
    uint8_t  port_fwd; /* Forward to specified ports */
    uint8_t  mac[LIP_MAC_ADDR_SIZE]; /* MAC адрес */
} t_kszsw_staddr_entry;

t_lip_errs kszsw_global_reg_read8(const t_kszsw_reg_acc *reg_acc, uint16_t regaddr, uint8_t *regval);
t_lip_errs kszsw_global_reg_read16(const t_kszsw_reg_acc *reg_acc, uint16_t regaddr, uint16_t *regval);
t_lip_errs kszsw_global_reg_read32(const t_kszsw_reg_acc *reg_acc, uint16_t regaddr, uint32_t *regval);

t_lip_errs kszsw_global_reg_write8(const t_kszsw_reg_acc *reg_acc, uint16_t regaddr, uint8_t val);
t_lip_errs kszsw_global_reg_write16(const t_kszsw_reg_acc *reg_acc, uint16_t regaddr, uint16_t val);
t_lip_errs kszsw_global_reg_write32(const t_kszsw_reg_acc *reg_acc, uint16_t regaddr, uint32_t val);

t_lip_errs kszsw_port_reg_read8(const t_kszsw_reg_acc *reg_acc, uint8_t port, uint16_t regaddr, uint8_t *regval);
t_lip_errs kszsw_port_reg_read16(const t_kszsw_reg_acc *reg_acc, uint8_t port, uint16_t regaddr, uint16_t *regval);
t_lip_errs kszsw_port_reg_read32(const t_kszsw_reg_acc *reg_acc, uint8_t port, uint16_t regaddr, uint32_t *regval);

t_lip_errs kszsw_port_reg_write8(const t_kszsw_reg_acc *reg_acc, uint8_t port, uint16_t regaddr, uint8_t val);
t_lip_errs kszsw_port_reg_write16(const t_kszsw_reg_acc *reg_acc, uint8_t port, uint16_t regaddr, uint16_t val);
t_lip_errs kszsw_port_reg_write32(const t_kszsw_reg_acc *reg_acc, uint8_t port, uint16_t regaddr, uint32_t val);

t_lip_errs kszsw_get_id(const t_kszsw_reg_acc *reg_acc, uint16_t *id);

t_lip_errs kszsw_phy_reg_read(const t_kszsw_reg_acc *reg_acc, uint8_t port, uint8_t regaddr, uint16_t *regval);
t_lip_errs kszsw_phy_reg_write(const t_kszsw_reg_acc *reg_acc, uint8_t port, uint8_t regaddr, uint16_t val);


t_lip_errs kszsw_port_mib_read(const t_kszsw_reg_acc *reg_acc, uint8_t port, uint8_t mib_idx, t_kszsw_mib_value *result);

t_lip_errs kszsw_tbl_staddr_rd_wrds(const t_kszsw_reg_acc *reg_acc, uint8_t idx, uint32_t *tbl_entry);
t_lip_errs kszsw_tbl_staddr_wr_wrds(const t_kszsw_reg_acc *reg_acc, uint8_t idx, const uint32_t *tbl_entry);
t_lip_errs kszsw_tbl_staddr_wr(const t_kszsw_reg_acc *reg_acc, uint8_t idx, const t_kszsw_staddr_entry *tbl_entry);


#endif // KSZSW_REGS_ACC_H
