#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/hwmon.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/mdio/mdio-i2c.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/rtnetlink.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include "sfp.h"
#include "swphy.h"
enum { … };
static const char * const mod_state_strings[] = …;
static const char *mod_state_to_str(unsigned short mod_state)
{ … }
static const char * const dev_state_strings[] = …;
static const char *dev_state_to_str(unsigned short dev_state)
{ … }
static const char * const event_strings[] = …;
static const char *event_to_str(unsigned short event)
{ … }
static const char * const sm_state_strings[] = …;
static const char *sm_state_to_str(unsigned short sm_state)
{ … }
static const char *gpio_names[] = …;
static const enum gpiod_flags gpio_flags[] = …;
#define T_WAIT …
#define T_START_UP …
#define T_START_UP_BAD_GPON …
#define T_RESET_US …
#define T_FAULT_RECOVER …
#define N_FAULT_INIT …
#define N_FAULT …
#define T_PHY_RETRY …
#define R_PHY_RETRY …
#define T_SERIAL …
#define T_HPOWER_LEVEL …
#define T_PROBE_RETRY_INIT …
#define R_PROBE_RETRY_INIT …
#define T_PROBE_RETRY_SLOW …
#define R_PROBE_RETRY_SLOW …
#define SFP_PHY_ADDR …
#define SFP_PHY_ADDR_ROLLBALL …
#define SFP_EEPROM_BLOCK_SIZE …
struct sff_data { … };
struct sfp { … };
static bool sff_module_supported(const struct sfp_eeprom_id *id)
{ … }
static const struct sff_data sff_data = …;
static bool sfp_module_supported(const struct sfp_eeprom_id *id)
{ … }
static const struct sff_data sfp_data = …;
static const struct of_device_id sfp_of_match[] = …;
MODULE_DEVICE_TABLE(of, sfp_of_match);
static void sfp_fixup_long_startup(struct sfp *sfp)
{ … }
static void sfp_fixup_ignore_los(struct sfp *sfp)
{ … }
static void sfp_fixup_ignore_tx_fault(struct sfp *sfp)
{ … }
static void sfp_fixup_nokia(struct sfp *sfp)
{ … }
static void sfp_fixup_10gbaset_30m(struct sfp *sfp)
{ … }
static void sfp_fixup_rollball(struct sfp *sfp)
{ … }
static void sfp_fixup_fs_2_5gt(struct sfp *sfp)
{ … }
static void sfp_fixup_fs_10gt(struct sfp *sfp)
{ … }
static void sfp_fixup_halny_gsfp(struct sfp *sfp)
{ … }
static void sfp_fixup_rollball_cc(struct sfp *sfp)
{ … }
static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
unsigned long *modes,
unsigned long *interfaces)
{ … }
static void sfp_quirk_disable_autoneg(const struct sfp_eeprom_id *id,
unsigned long *modes,
unsigned long *interfaces)
{ … }
static void sfp_quirk_oem_2_5g(const struct sfp_eeprom_id *id,
unsigned long *modes,
unsigned long *interfaces)
{ … }
static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
unsigned long *modes,
unsigned long *interfaces)
{ … }
#define SFP_QUIRK(_v, _p, _m, _f) …
#define SFP_QUIRK_M(_v, _p, _m) …
#define SFP_QUIRK_F(_v, _p, _f) …
static const struct sfp_quirk sfp_quirks[] = …;
static size_t sfp_strlen(const char *str, size_t maxlen)
{ … }
static bool sfp_match(const char *qs, const char *str, size_t len)
{ … }
static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
{ … }
static unsigned long poll_jiffies;
static unsigned int sfp_gpio_get_state(struct sfp *sfp)
{ … }
static unsigned int sff_gpio_get_state(struct sfp *sfp)
{ … }
static void sfp_gpio_set_state(struct sfp *sfp, unsigned int state)
{ … }
static int sfp_i2c_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
size_t len)
{ … }
static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
size_t len)
{ … }
static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
{ … }
static int sfp_i2c_mdiobus_create(struct sfp *sfp)
{ … }
static void sfp_i2c_mdiobus_destroy(struct sfp *sfp)
{ … }
static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
{ … }
static int sfp_write(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
{ … }
static int sfp_modify_u8(struct sfp *sfp, bool a2, u8 addr, u8 mask, u8 val)
{ … }
static unsigned int sfp_soft_get_state(struct sfp *sfp)
{ … }
static void sfp_soft_set_state(struct sfp *sfp, unsigned int state,
unsigned int soft)
{ … }
static void sfp_soft_start_poll(struct sfp *sfp)
{ … }
static void sfp_soft_stop_poll(struct sfp *sfp)
{ … }
static unsigned int sfp_get_state(struct sfp *sfp)
{ … }
static void sfp_set_state(struct sfp *sfp, unsigned int state)
{ … }
static void sfp_mod_state(struct sfp *sfp, unsigned int mask, unsigned int set)
{ … }
static unsigned int sfp_check(void *buf, size_t len)
{ … }
#if IS_ENABLED(CONFIG_HWMON)
static umode_t sfp_hwmon_is_visible(const void *data,
enum hwmon_sensor_types type,
u32 attr, int channel)
{ … }
static int sfp_hwmon_read_sensor(struct sfp *sfp, int reg, long *value)
{ … }
static void sfp_hwmon_to_rx_power(long *value)
{ … }
static void sfp_hwmon_calibrate(struct sfp *sfp, unsigned int slope, int offset,
long *value)
{ … }
static void sfp_hwmon_calibrate_temp(struct sfp *sfp, long *value)
{ … }
static void sfp_hwmon_calibrate_vcc(struct sfp *sfp, long *value)
{ … }
static void sfp_hwmon_calibrate_bias(struct sfp *sfp, long *value)
{ … }
static void sfp_hwmon_calibrate_tx_power(struct sfp *sfp, long *value)
{ … }
static int sfp_hwmon_read_temp(struct sfp *sfp, int reg, long *value)
{ … }
static int sfp_hwmon_read_vcc(struct sfp *sfp, int reg, long *value)
{ … }
static int sfp_hwmon_read_bias(struct sfp *sfp, int reg, long *value)
{ … }
static int sfp_hwmon_read_tx_power(struct sfp *sfp, int reg, long *value)
{ … }
static int sfp_hwmon_read_rx_power(struct sfp *sfp, int reg, long *value)
{ … }
static int sfp_hwmon_temp(struct sfp *sfp, u32 attr, long *value)
{ … }
static int sfp_hwmon_vcc(struct sfp *sfp, u32 attr, long *value)
{ … }
static int sfp_hwmon_bias(struct sfp *sfp, u32 attr, long *value)
{ … }
static int sfp_hwmon_tx_power(struct sfp *sfp, u32 attr, long *value)
{ … }
static int sfp_hwmon_rx_power(struct sfp *sfp, u32 attr, long *value)
{ … }
static int sfp_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
u32 attr, int channel, long *value)
{ … }
static const char *const sfp_hwmon_power_labels[] = …;
static int sfp_hwmon_read_string(struct device *dev,
enum hwmon_sensor_types type,
u32 attr, int channel, const char **str)
{ … }
static const struct hwmon_ops sfp_hwmon_ops = …;
static const struct hwmon_channel_info * const sfp_hwmon_info[] = …;
static const struct hwmon_chip_info sfp_hwmon_chip_info = …;
static void sfp_hwmon_probe(struct work_struct *work)
{ … }
static int sfp_hwmon_insert(struct sfp *sfp)
{ … }
static void sfp_hwmon_remove(struct sfp *sfp)
{ … }
static int sfp_hwmon_init(struct sfp *sfp)
{ … }
static void sfp_hwmon_exit(struct sfp *sfp)
{ … }
#else
static int sfp_hwmon_insert(struct sfp *sfp)
{
return 0;
}
static void sfp_hwmon_remove(struct sfp *sfp)
{
}
static int sfp_hwmon_init(struct sfp *sfp)
{
return 0;
}
static void sfp_hwmon_exit(struct sfp *sfp)
{
}
#endif
static void sfp_module_tx_disable(struct sfp *sfp)
{ … }
static void sfp_module_tx_enable(struct sfp *sfp)
{ … }
#if IS_ENABLED(CONFIG_DEBUG_FS)
static int sfp_debug_state_show(struct seq_file *s, void *data)
{ … }
DEFINE_SHOW_ATTRIBUTE(…);
static void sfp_debugfs_init(struct sfp *sfp)
{ … }
static void sfp_debugfs_exit(struct sfp *sfp)
{ … }
#else
static void sfp_debugfs_init(struct sfp *sfp)
{
}
static void sfp_debugfs_exit(struct sfp *sfp)
{
}
#endif
static void sfp_module_tx_fault_reset(struct sfp *sfp)
{ … }
static void sfp_sm_set_timer(struct sfp *sfp, unsigned int timeout)
{ … }
static void sfp_sm_next(struct sfp *sfp, unsigned int state,
unsigned int timeout)
{ … }
static void sfp_sm_mod_next(struct sfp *sfp, unsigned int state,
unsigned int timeout)
{ … }
static void sfp_sm_phy_detach(struct sfp *sfp)
{ … }
static int sfp_sm_probe_phy(struct sfp *sfp, int addr, bool is_c45)
{ … }
static void sfp_sm_link_up(struct sfp *sfp)
{ … }
static void sfp_sm_link_down(struct sfp *sfp)
{ … }
static void sfp_sm_link_check_los(struct sfp *sfp)
{ … }
static bool sfp_los_event_active(struct sfp *sfp, unsigned int event)
{ … }
static bool sfp_los_event_inactive(struct sfp *sfp, unsigned int event)
{ … }
static void sfp_sm_fault(struct sfp *sfp, unsigned int next_state, bool warn)
{ … }
static int sfp_sm_add_mdio_bus(struct sfp *sfp)
{ … }
static int sfp_sm_probe_for_phy(struct sfp *sfp)
{ … }
static int sfp_module_parse_power(struct sfp *sfp)
{ … }
static int sfp_sm_mod_hpower(struct sfp *sfp, bool enable)
{ … }
static void sfp_module_parse_rate_select(struct sfp *sfp)
{ … }
static bool sfp_id_needs_byte_io(struct sfp *sfp, void *buf, size_t len)
{ … }
static int sfp_cotsworks_fixup_check(struct sfp *sfp, struct sfp_eeprom_id *id)
{ … }
static int sfp_module_parse_sff8472(struct sfp *sfp)
{ … }
static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
{ … }
static void sfp_sm_mod_remove(struct sfp *sfp)
{ … }
static void sfp_sm_device(struct sfp *sfp, unsigned int event)
{ … }
static void sfp_sm_module(struct sfp *sfp, unsigned int event)
{ … }
static void sfp_sm_main(struct sfp *sfp, unsigned int event)
{ … }
static void __sfp_sm_event(struct sfp *sfp, unsigned int event)
{ … }
static void sfp_sm_event(struct sfp *sfp, unsigned int event)
{ … }
static void sfp_attach(struct sfp *sfp)
{ … }
static void sfp_detach(struct sfp *sfp)
{ … }
static void sfp_start(struct sfp *sfp)
{ … }
static void sfp_stop(struct sfp *sfp)
{ … }
static void sfp_set_signal_rate(struct sfp *sfp, unsigned int rate_kbd)
{ … }
static int sfp_module_info(struct sfp *sfp, struct ethtool_modinfo *modinfo)
{ … }
static int sfp_module_eeprom(struct sfp *sfp, struct ethtool_eeprom *ee,
u8 *data)
{ … }
static int sfp_module_eeprom_by_page(struct sfp *sfp,
const struct ethtool_module_eeprom *page,
struct netlink_ext_ack *extack)
{
if (!(sfp->state & SFP_F_PRESENT))
return -ENODEV;
if (page->bank) {
NL_SET_ERR_MSG(extack, "Banks not supported");
return -EOPNOTSUPP;
}
if (page->page) {
NL_SET_ERR_MSG(extack, "Only page 0 supported");
return -EOPNOTSUPP;
}
if (page->i2c_address != 0x50 &&
page->i2c_address != 0x51) {
NL_SET_ERR_MSG(extack, "Only address 0x50 and 0x51 supported");
return -EOPNOTSUPP;
}
return sfp_read(sfp, page->i2c_address == 0x51, page->offset,
page->data, page->length);
};
static const struct sfp_socket_ops sfp_module_ops = …;
static void sfp_timeout(struct work_struct *work)
{ … }
static void sfp_check_state(struct sfp *sfp)
{ … }
static irqreturn_t sfp_irq(int irq, void *data)
{ … }
static void sfp_poll(struct work_struct *work)
{ … }
static struct sfp *sfp_alloc(struct device *dev)
{ … }
static void sfp_cleanup(void *data)
{ … }
static int sfp_i2c_get(struct sfp *sfp)
{ … }
static int sfp_probe(struct platform_device *pdev)
{ … }
static void sfp_remove(struct platform_device *pdev)
{ … }
static void sfp_shutdown(struct platform_device *pdev)
{ … }
static struct platform_driver sfp_driver = …;
static int sfp_init(void)
{ … }
module_init(…) …;
static void sfp_exit(void)
{ … }
module_exit(sfp_exit);
MODULE_ALIAS(…) …;
MODULE_AUTHOR(…) …;
MODULE_LICENSE(…) …;
MODULE_DESCRIPTION(…) …;