1
0
Files
2022-02-26 21:12:47 +07:00

135 lines
3.7 KiB
C

#ifndef __INCLUDE_LINUX_ETH_SWITCH_HOOKS_H
#define __INCLUDE_LINUX_ETH_SWITCH_HOOKS_H
#include <linux/types.h>
#include <linux/spinlock.h>
#define ETH_SWITCH_HOOKS_MARK_MR_MAC
struct net_device;
typedef int eth_switch_map_mc_mac_fn(const struct net_device *const dev,
const u8 *const uc_mac,
const u8 *const mc_mac);
typedef int eth_switch_unmap_mc_mac_fn(const struct net_device *const dev,
const u8 *const uc_mac,
const u8 *const mc_mac);
typedef int eth_switch_mark_mr_mac_fn(const struct net_device *const dev,
const u8 *const mr_mac,
bool gquery);
typedef int eth_switch_set_wan_port_fn(const unsigned char port);
typedef int eth_switch_mt7530_reg_write_bh_fn(const u32 addr,
const u32 data);
typedef int eth_switch_rtl83xx_reg_write_bh_fn(const u32 addr,
const u32 data);
#define ETH_SWITCH_DECLARE_HOOK_RCU(name) \
extern eth_switch_##name##_fn __rcu *eth_switch_##name##_hook; \
\
static inline eth_switch_##name##_fn * \
eth_switch_##name##_hook_get_rcu(void) \
{ \
return rcu_dereference(eth_switch_##name##_hook); \
} \
\
static inline void \
eth_switch_##name##_hook_set(eth_switch_##name##_fn *name##_hook) \
{ \
rcu_assign_pointer(eth_switch_##name##_hook, name##_hook); \
}
extern rwlock_t eth_switch_lock;
#define ETH_SWITCH_DECLARE_HOOK(name) \
extern eth_switch_##name##_fn *eth_switch_##name##_hook; \
\
static inline eth_switch_##name##_fn * \
eth_switch_##name##_hook_get(void) \
{ \
read_lock_bh(&eth_switch_lock); \
return eth_switch_##name##_hook; \
} \
\
static inline void \
eth_switch_##name##_hook_put(void) \
{ \
read_unlock_bh(&eth_switch_lock); \
} \
\
static inline void \
eth_switch_##name##_hook_set(eth_switch_##name##_fn *name##_hook) \
{ \
write_lock_bh(&eth_switch_lock); \
eth_switch_##name##_hook = name##_hook; \
write_unlock_bh(&eth_switch_lock); \
}
ETH_SWITCH_DECLARE_HOOK_RCU(map_mc_mac)
ETH_SWITCH_DECLARE_HOOK_RCU(unmap_mc_mac)
ETH_SWITCH_DECLARE_HOOK_RCU(mark_mr_mac)
ETH_SWITCH_DECLARE_HOOK_RCU(set_wan_port)
ETH_SWITCH_DECLARE_HOOK(mt7530_reg_write_bh);
ETH_SWITCH_DECLARE_HOOK(rtl83xx_reg_write_bh);
#define ETH_SWITCH_DECLARE_OPS(name) \
extern struct eth_switch_##name##_ops *__eth_switch_##name##_ops; \
\
static inline bool \
eth_switch_##name##_ops_get_bh(struct eth_switch_##name##_ops **ops) \
{ \
read_lock_bh(&eth_switch_lock); \
*ops = __eth_switch_##name##_ops; \
\
if (*ops == NULL) { \
read_unlock_bh(&eth_switch_lock); \
return false; \
} \
\
return true; \
} \
\
static inline void \
eth_switch_##name##_ops_put_bh(struct eth_switch_##name##_ops **ops) \
{ \
*ops = NULL; \
read_unlock_bh(&eth_switch_lock); \
} \
\
static inline void \
eth_switch_##name##_ops_set_bh(struct eth_switch_##name##_ops *ops) \
{ \
write_lock_bh(&eth_switch_lock); \
__eth_switch_##name##_ops = ops; \
write_unlock_bh(&eth_switch_lock); \
}
struct eth_switch_mt7531_ops {
int (*r32_bh)(const u32 addr, u32 *data);
int (*w32_bh)(const u32 addr, const u32 data);
};
ETH_SWITCH_DECLARE_OPS(mt7531);
struct eth_switch_rtl8211_ops {
int (*r16_bh)(const u16 page, const u16 addr, u16 *data);
int (*w16_bh)(const u16 page, const u16 addr, const u16 data);
};
ETH_SWITCH_DECLARE_OPS(rtl8211);
struct eth_switch_rtl8221_ops {
int (*r32_bh)(const u32 addr, u32 *data);
int (*w32_bh)(const u32 addr, const u32 data);
};
ETH_SWITCH_DECLARE_OPS(rtl8221);
#endif /* __INCLUDE_LINUX_ETH_SWITCH_HOOKS_H */