1a2443fd1SAndrew Lunn // SPDX-License-Identifier: GPL-2.0 27ce236faSRuslan Babayev #include <linux/acpi.h> 31323061aSAndrew Lunn #include <linux/ctype.h> 49cc8976cSRussell King #include <linux/debugfs.h> 573970055SRussell King #include <linux/delay.h> 654a2fc62SFlorian Fainelli #include <linux/gpio/consumer.h> 71323061aSAndrew Lunn #include <linux/hwmon.h> 873970055SRussell King #include <linux/i2c.h> 973970055SRussell King #include <linux/interrupt.h> 1073970055SRussell King #include <linux/jiffies.h> 11fcba68bdSAndrew Lunn #include <linux/mdio/mdio-i2c.h> 1273970055SRussell King #include <linux/module.h> 1373970055SRussell King #include <linux/mutex.h> 1473970055SRussell King #include <linux/of.h> 1573970055SRussell King #include <linux/phy.h> 1673970055SRussell King #include <linux/platform_device.h> 1773970055SRussell King #include <linux/rtnetlink.h> 1873970055SRussell King #include <linux/slab.h> 1973970055SRussell King #include <linux/workqueue.h> 2073970055SRussell King 2173970055SRussell King #include "sfp.h" 2273970055SRussell King #include "swphy.h" 2373970055SRussell King 2473970055SRussell King enum { 2573970055SRussell King GPIO_MODDEF0, 2673970055SRussell King GPIO_LOS, 2773970055SRussell King GPIO_TX_FAULT, 2873970055SRussell King GPIO_TX_DISABLE, 2973970055SRussell King GPIO_RATE_SELECT, 3073970055SRussell King GPIO_MAX, 3173970055SRussell King 3273970055SRussell King SFP_F_PRESENT = BIT(GPIO_MODDEF0), 3373970055SRussell King SFP_F_LOS = BIT(GPIO_LOS), 3473970055SRussell King SFP_F_TX_FAULT = BIT(GPIO_TX_FAULT), 3573970055SRussell King SFP_F_TX_DISABLE = BIT(GPIO_TX_DISABLE), 3673970055SRussell King SFP_F_RATE_SELECT = BIT(GPIO_RATE_SELECT), 3773970055SRussell King 3873970055SRussell King SFP_E_INSERT = 0, 3973970055SRussell King SFP_E_REMOVE, 406b0da5c9SRussell King SFP_E_DEV_ATTACH, 416b0da5c9SRussell King SFP_E_DEV_DETACH, 4273970055SRussell King SFP_E_DEV_DOWN, 4373970055SRussell King SFP_E_DEV_UP, 4473970055SRussell King SFP_E_TX_FAULT, 4573970055SRussell King SFP_E_TX_CLEAR, 4673970055SRussell King SFP_E_LOS_HIGH, 4773970055SRussell King SFP_E_LOS_LOW, 4873970055SRussell King SFP_E_TIMEOUT, 4973970055SRussell King 5073970055SRussell King SFP_MOD_EMPTY = 0, 5173f5e847SRussell King SFP_MOD_ERROR, 5273970055SRussell King SFP_MOD_PROBE, 5373f5e847SRussell King SFP_MOD_WAITDEV, 543bb35261SJon Nettleton SFP_MOD_HPOWER, 55b036a554SRussell King SFP_MOD_WAITPWR, 5673970055SRussell King SFP_MOD_PRESENT, 5773970055SRussell King 586b0da5c9SRussell King SFP_DEV_DETACHED = 0, 596b0da5c9SRussell King SFP_DEV_DOWN, 6073970055SRussell King SFP_DEV_UP, 6173970055SRussell King 6273970055SRussell King SFP_S_DOWN = 0, 6374c551caSRussell King SFP_S_FAIL, 64eefa6f1fSRussell King SFP_S_WAIT, 6573970055SRussell King SFP_S_INIT, 661cb89a14SRussell King SFP_S_INIT_PHY, 67d23751a0SRussell King SFP_S_INIT_TX_FAULT, 6873970055SRussell King SFP_S_WAIT_LOS, 6973970055SRussell King SFP_S_LINK_UP, 7073970055SRussell King SFP_S_TX_FAULT, 7173970055SRussell King SFP_S_REINIT, 7273970055SRussell King SFP_S_TX_DISABLE, 7373970055SRussell King }; 7473970055SRussell King 754005a7cbSAndrew Lunn static const char * const mod_state_strings[] = { 764005a7cbSAndrew Lunn [SFP_MOD_EMPTY] = "empty", 7773f5e847SRussell King [SFP_MOD_ERROR] = "error", 784005a7cbSAndrew Lunn [SFP_MOD_PROBE] = "probe", 7973f5e847SRussell King [SFP_MOD_WAITDEV] = "waitdev", 804005a7cbSAndrew Lunn [SFP_MOD_HPOWER] = "hpower", 81b036a554SRussell King [SFP_MOD_WAITPWR] = "waitpwr", 824005a7cbSAndrew Lunn [SFP_MOD_PRESENT] = "present", 834005a7cbSAndrew Lunn }; 844005a7cbSAndrew Lunn 854005a7cbSAndrew Lunn static const char *mod_state_to_str(unsigned short mod_state) 864005a7cbSAndrew Lunn { 874005a7cbSAndrew Lunn if (mod_state >= ARRAY_SIZE(mod_state_strings)) 884005a7cbSAndrew Lunn return "Unknown module state"; 894005a7cbSAndrew Lunn return mod_state_strings[mod_state]; 904005a7cbSAndrew Lunn } 914005a7cbSAndrew Lunn 924005a7cbSAndrew Lunn static const char * const dev_state_strings[] = { 936b0da5c9SRussell King [SFP_DEV_DETACHED] = "detached", 944005a7cbSAndrew Lunn [SFP_DEV_DOWN] = "down", 954005a7cbSAndrew Lunn [SFP_DEV_UP] = "up", 964005a7cbSAndrew Lunn }; 974005a7cbSAndrew Lunn 984005a7cbSAndrew Lunn static const char *dev_state_to_str(unsigned short dev_state) 994005a7cbSAndrew Lunn { 1004005a7cbSAndrew Lunn if (dev_state >= ARRAY_SIZE(dev_state_strings)) 1014005a7cbSAndrew Lunn return "Unknown device state"; 1024005a7cbSAndrew Lunn return dev_state_strings[dev_state]; 1034005a7cbSAndrew Lunn } 1044005a7cbSAndrew Lunn 1054005a7cbSAndrew Lunn static const char * const event_strings[] = { 1064005a7cbSAndrew Lunn [SFP_E_INSERT] = "insert", 1074005a7cbSAndrew Lunn [SFP_E_REMOVE] = "remove", 1086b0da5c9SRussell King [SFP_E_DEV_ATTACH] = "dev_attach", 1096b0da5c9SRussell King [SFP_E_DEV_DETACH] = "dev_detach", 1104005a7cbSAndrew Lunn [SFP_E_DEV_DOWN] = "dev_down", 1114005a7cbSAndrew Lunn [SFP_E_DEV_UP] = "dev_up", 1124005a7cbSAndrew Lunn [SFP_E_TX_FAULT] = "tx_fault", 1134005a7cbSAndrew Lunn [SFP_E_TX_CLEAR] = "tx_clear", 1144005a7cbSAndrew Lunn [SFP_E_LOS_HIGH] = "los_high", 1154005a7cbSAndrew Lunn [SFP_E_LOS_LOW] = "los_low", 1164005a7cbSAndrew Lunn [SFP_E_TIMEOUT] = "timeout", 1174005a7cbSAndrew Lunn }; 1184005a7cbSAndrew Lunn 1194005a7cbSAndrew Lunn static const char *event_to_str(unsigned short event) 1204005a7cbSAndrew Lunn { 1214005a7cbSAndrew Lunn if (event >= ARRAY_SIZE(event_strings)) 1224005a7cbSAndrew Lunn return "Unknown event"; 1234005a7cbSAndrew Lunn return event_strings[event]; 1244005a7cbSAndrew Lunn } 1254005a7cbSAndrew Lunn 1264005a7cbSAndrew Lunn static const char * const sm_state_strings[] = { 1274005a7cbSAndrew Lunn [SFP_S_DOWN] = "down", 12874c551caSRussell King [SFP_S_FAIL] = "fail", 129eefa6f1fSRussell King [SFP_S_WAIT] = "wait", 1304005a7cbSAndrew Lunn [SFP_S_INIT] = "init", 1311cb89a14SRussell King [SFP_S_INIT_PHY] = "init_phy", 132d23751a0SRussell King [SFP_S_INIT_TX_FAULT] = "init_tx_fault", 1334005a7cbSAndrew Lunn [SFP_S_WAIT_LOS] = "wait_los", 1344005a7cbSAndrew Lunn [SFP_S_LINK_UP] = "link_up", 1354005a7cbSAndrew Lunn [SFP_S_TX_FAULT] = "tx_fault", 1364005a7cbSAndrew Lunn [SFP_S_REINIT] = "reinit", 13725a9da66SSean Anderson [SFP_S_TX_DISABLE] = "tx_disable", 1384005a7cbSAndrew Lunn }; 1394005a7cbSAndrew Lunn 1404005a7cbSAndrew Lunn static const char *sm_state_to_str(unsigned short sm_state) 1414005a7cbSAndrew Lunn { 1424005a7cbSAndrew Lunn if (sm_state >= ARRAY_SIZE(sm_state_strings)) 1434005a7cbSAndrew Lunn return "Unknown state"; 1444005a7cbSAndrew Lunn return sm_state_strings[sm_state]; 1454005a7cbSAndrew Lunn } 1464005a7cbSAndrew Lunn 14773970055SRussell King static const char *gpio_of_names[] = { 14825ee0793SBaruch Siach "mod-def0", 14973970055SRussell King "los", 15073970055SRussell King "tx-fault", 15173970055SRussell King "tx-disable", 15225ee0793SBaruch Siach "rate-select0", 15373970055SRussell King }; 15473970055SRussell King 15573970055SRussell King static const enum gpiod_flags gpio_flags[] = { 15673970055SRussell King GPIOD_IN, 15773970055SRussell King GPIOD_IN, 15873970055SRussell King GPIOD_IN, 15973970055SRussell King GPIOD_ASIS, 16073970055SRussell King GPIOD_ASIS, 16173970055SRussell King }; 16273970055SRussell King 16326c97a2dSRussell King /* t_start_up (SFF-8431) or t_init (SFF-8472) is the time required for a 16426c97a2dSRussell King * non-cooled module to initialise its laser safety circuitry. We wait 16526c97a2dSRussell King * an initial T_WAIT period before we check the tx fault to give any PHY 16626c97a2dSRussell King * on board (for a copper SFP) time to initialise. 16726c97a2dSRussell King */ 168eefa6f1fSRussell King #define T_WAIT msecs_to_jiffies(50) 16926c97a2dSRussell King #define T_START_UP msecs_to_jiffies(300) 17026c97a2dSRussell King #define T_START_UP_BAD_GPON msecs_to_jiffies(60000) 17126c97a2dSRussell King 17226c97a2dSRussell King /* t_reset is the time required to assert the TX_DISABLE signal to reset 17326c97a2dSRussell King * an indicated TX_FAULT. 17426c97a2dSRussell King */ 17573970055SRussell King #define T_RESET_US 10 17673970055SRussell King #define T_FAULT_RECOVER msecs_to_jiffies(1000) 17773970055SRussell King 17865ef2d5cSRussell King /* N_FAULT_INIT is the number of recovery attempts at module initialisation 17965ef2d5cSRussell King * time. If the TX_FAULT signal is not deasserted after this number of 18065ef2d5cSRussell King * attempts at clearing it, we decide that the module is faulty. 18165ef2d5cSRussell King * N_FAULT is the same but after the module has initialised. 18265ef2d5cSRussell King */ 18365ef2d5cSRussell King #define N_FAULT_INIT 5 18465ef2d5cSRussell King #define N_FAULT 5 18565ef2d5cSRussell King 1861cb89a14SRussell King /* T_PHY_RETRY is the time interval between attempts to probe the PHY. 1871cb89a14SRussell King * R_PHY_RETRY is the number of attempts. 1881cb89a14SRussell King */ 1891cb89a14SRussell King #define T_PHY_RETRY msecs_to_jiffies(50) 1901cb89a14SRussell King #define R_PHY_RETRY 12 1911cb89a14SRussell King 19273970055SRussell King /* SFP module presence detection is poor: the three MOD DEF signals are 19373970055SRussell King * the same length on the PCB, which means it's possible for MOD DEF 0 to 19473970055SRussell King * connect before the I2C bus on MOD DEF 1/2. 19573970055SRussell King * 196d900954fSRussell King * The SFF-8472 specifies t_serial ("Time from power on until module is 197d900954fSRussell King * ready for data transmission over the two wire serial bus.") as 300ms. 19873970055SRussell King */ 199d900954fSRussell King #define T_SERIAL msecs_to_jiffies(300) 2003bb35261SJon Nettleton #define T_HPOWER_LEVEL msecs_to_jiffies(300) 201e117be74SRussell King #define T_PROBE_RETRY_INIT msecs_to_jiffies(100) 202e117be74SRussell King #define R_PROBE_RETRY_INIT 10 203e117be74SRussell King #define T_PROBE_RETRY_SLOW msecs_to_jiffies(5000) 204e117be74SRussell King #define R_PROBE_RETRY_SLOW 12 20573970055SRussell King 206516b29edSFlorian Fainelli /* SFP modules appear to always have their PHY configured for bus address 20773970055SRussell King * 0x56 (which with mdio-i2c, translates to a PHY address of 22). 20873970055SRussell King */ 20973970055SRussell King #define SFP_PHY_ADDR 22 21073970055SRussell King 211259c8618SRussell King struct sff_data { 212259c8618SRussell King unsigned int gpios; 213259c8618SRussell King bool (*module_supported)(const struct sfp_eeprom_id *id); 214259c8618SRussell King }; 215259c8618SRussell King 21673970055SRussell King struct sfp { 21773970055SRussell King struct device *dev; 21873970055SRussell King struct i2c_adapter *i2c; 21973970055SRussell King struct mii_bus *i2c_mii; 22073970055SRussell King struct sfp_bus *sfp_bus; 22173970055SRussell King struct phy_device *mod_phy; 222259c8618SRussell King const struct sff_data *type; 2230d035bedSRussell King size_t i2c_block_size; 2243bb35261SJon Nettleton u32 max_power_mW; 22573970055SRussell King 22673970055SRussell King unsigned int (*get_state)(struct sfp *); 22773970055SRussell King void (*set_state)(struct sfp *, unsigned int); 22873970055SRussell King int (*read)(struct sfp *, bool, u8, void *, size_t); 2293bb35261SJon Nettleton int (*write)(struct sfp *, bool, u8, void *, size_t); 23073970055SRussell King 23173970055SRussell King struct gpio_desc *gpio[GPIO_MAX]; 232257c2559SRobert Hancock int gpio_irq[GPIO_MAX]; 23373970055SRussell King 234f3c9a666SRussell King bool need_poll; 235f3c9a666SRussell King 2362158e856SRobert Hancock struct mutex st_mutex; /* Protects state */ 2378475c4b7SRussell King (Oracle) unsigned int state_hw_mask; 238f3c9a666SRussell King unsigned int state_soft_mask; 23973970055SRussell King unsigned int state; 24073970055SRussell King struct delayed_work poll; 24173970055SRussell King struct delayed_work timeout; 2422158e856SRobert Hancock struct mutex sm_mutex; /* Protects state machine */ 24373970055SRussell King unsigned char sm_mod_state; 244e117be74SRussell King unsigned char sm_mod_tries_init; 245e117be74SRussell King unsigned char sm_mod_tries; 24673970055SRussell King unsigned char sm_dev_state; 24773970055SRussell King unsigned short sm_state; 248281e4eabSRussell King unsigned char sm_fault_retries; 2491cb89a14SRussell King unsigned char sm_phy_retries; 25073970055SRussell King 25173970055SRussell King struct sfp_eeprom_id id; 252ed32abb1SRussell King unsigned int module_power_mW; 25326c97a2dSRussell King unsigned int module_t_start_up; 2542069624dSMatthew Hagan bool tx_fault_ignore; 255ed32abb1SRussell King 25623571c7bSRussell King (Oracle) const struct sfp_quirk *quirk; 25723571c7bSRussell King (Oracle) 2581323061aSAndrew Lunn #if IS_ENABLED(CONFIG_HWMON) 2591323061aSAndrew Lunn struct sfp_diag diag; 260139d3a21SRussell King struct delayed_work hwmon_probe; 261139d3a21SRussell King unsigned int hwmon_tries; 2621323061aSAndrew Lunn struct device *hwmon_dev; 2631323061aSAndrew Lunn char *hwmon_name; 2641323061aSAndrew Lunn #endif 2651323061aSAndrew Lunn 2669cc8976cSRussell King #if IS_ENABLED(CONFIG_DEBUG_FS) 2679cc8976cSRussell King struct dentry *debugfs_dir; 2689cc8976cSRussell King #endif 26973970055SRussell King }; 27073970055SRussell King 271259c8618SRussell King static bool sff_module_supported(const struct sfp_eeprom_id *id) 272259c8618SRussell King { 2730fbd26a9SRussell King return id->base.phys_id == SFF8024_ID_SFF_8472 && 274259c8618SRussell King id->base.phys_ext_id == SFP_PHYS_EXT_ID_SFP; 275259c8618SRussell King } 276259c8618SRussell King 277259c8618SRussell King static const struct sff_data sff_data = { 278259c8618SRussell King .gpios = SFP_F_LOS | SFP_F_TX_FAULT | SFP_F_TX_DISABLE, 279259c8618SRussell King .module_supported = sff_module_supported, 280259c8618SRussell King }; 281259c8618SRussell King 282259c8618SRussell King static bool sfp_module_supported(const struct sfp_eeprom_id *id) 283259c8618SRussell King { 284f0b4f847SPali Rohár if (id->base.phys_id == SFF8024_ID_SFP && 285f0b4f847SPali Rohár id->base.phys_ext_id == SFP_PHYS_EXT_ID_SFP) 286f0b4f847SPali Rohár return true; 287f0b4f847SPali Rohár 288f0b4f847SPali Rohár /* SFP GPON module Ubiquiti U-Fiber Instant has in its EEPROM stored 289f0b4f847SPali Rohár * phys id SFF instead of SFP. Therefore mark this module explicitly 290f0b4f847SPali Rohár * as supported based on vendor name and pn match. 291f0b4f847SPali Rohár */ 292f0b4f847SPali Rohár if (id->base.phys_id == SFF8024_ID_SFF_8472 && 293f0b4f847SPali Rohár id->base.phys_ext_id == SFP_PHYS_EXT_ID_SFP && 294f0b4f847SPali Rohár !memcmp(id->base.vendor_name, "UBNT ", 16) && 295f0b4f847SPali Rohár !memcmp(id->base.vendor_pn, "UF-INSTANT ", 16)) 296f0b4f847SPali Rohár return true; 297f0b4f847SPali Rohár 298f0b4f847SPali Rohár return false; 299259c8618SRussell King } 300259c8618SRussell King 301259c8618SRussell King static const struct sff_data sfp_data = { 302259c8618SRussell King .gpios = SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT | 303259c8618SRussell King SFP_F_TX_DISABLE | SFP_F_RATE_SELECT, 304259c8618SRussell King .module_supported = sfp_module_supported, 305259c8618SRussell King }; 306259c8618SRussell King 307259c8618SRussell King static const struct of_device_id sfp_of_match[] = { 308259c8618SRussell King { .compatible = "sff,sff", .data = &sff_data, }, 309259c8618SRussell King { .compatible = "sff,sfp", .data = &sfp_data, }, 310259c8618SRussell King { }, 311259c8618SRussell King }; 312259c8618SRussell King MODULE_DEVICE_TABLE(of, sfp_of_match); 313259c8618SRussell King 31427541675SRussell King (Oracle) static void sfp_fixup_long_startup(struct sfp *sfp) 31527541675SRussell King (Oracle) { 31627541675SRussell King (Oracle) sfp->module_t_start_up = T_START_UP_BAD_GPON; 31727541675SRussell King (Oracle) } 31827541675SRussell King (Oracle) 3195029be76SRussell King (Oracle) static void sfp_fixup_ignore_tx_fault(struct sfp *sfp) 3205029be76SRussell King (Oracle) { 3215029be76SRussell King (Oracle) sfp->tx_fault_ignore = true; 3225029be76SRussell King (Oracle) } 3235029be76SRussell King (Oracle) 324*73472c83SRussell King (Oracle) static void sfp_fixup_halny_gsfp(struct sfp *sfp) 325*73472c83SRussell King (Oracle) { 326*73472c83SRussell King (Oracle) /* Ignore the TX_FAULT and LOS signals on this module. 327*73472c83SRussell King (Oracle) * these are possibly used for other purposes on this 328*73472c83SRussell King (Oracle) * module, e.g. a serial port. 329*73472c83SRussell King (Oracle) */ 330*73472c83SRussell King (Oracle) sfp->state_hw_mask &= ~(SFP_F_TX_FAULT | SFP_F_LOS); 331*73472c83SRussell King (Oracle) } 332*73472c83SRussell King (Oracle) 33323571c7bSRussell King (Oracle) static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id, 33423571c7bSRussell King (Oracle) unsigned long *modes) 33523571c7bSRussell King (Oracle) { 33623571c7bSRussell King (Oracle) linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, modes); 33723571c7bSRussell King (Oracle) } 33823571c7bSRussell King (Oracle) 33923571c7bSRussell King (Oracle) static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id, 34023571c7bSRussell King (Oracle) unsigned long *modes) 34123571c7bSRussell King (Oracle) { 34223571c7bSRussell King (Oracle) /* Ubiquiti U-Fiber Instant module claims that support all transceiver 34323571c7bSRussell King (Oracle) * types including 10G Ethernet which is not truth. So clear all claimed 34423571c7bSRussell King (Oracle) * modes and set only one mode which module supports: 1000baseX_Full. 34523571c7bSRussell King (Oracle) */ 34623571c7bSRussell King (Oracle) linkmode_zero(modes); 34723571c7bSRussell King (Oracle) linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, modes); 34823571c7bSRussell King (Oracle) } 34923571c7bSRussell King (Oracle) 35023571c7bSRussell King (Oracle) static const struct sfp_quirk sfp_quirks[] = { 35123571c7bSRussell King (Oracle) { 35223571c7bSRussell King (Oracle) // Alcatel Lucent G-010S-P can operate at 2500base-X, but 35323571c7bSRussell King (Oracle) // incorrectly report 2500MBd NRZ in their EEPROM 35423571c7bSRussell King (Oracle) .vendor = "ALCATELLUCENT", 35523571c7bSRussell King (Oracle) .part = "G010SP", 35623571c7bSRussell King (Oracle) .modes = sfp_quirk_2500basex, 35723571c7bSRussell King (Oracle) }, { 35823571c7bSRussell King (Oracle) // Alcatel Lucent G-010S-A can operate at 2500base-X, but 35923571c7bSRussell King (Oracle) // report 3.2GBd NRZ in their EEPROM 36023571c7bSRussell King (Oracle) .vendor = "ALCATELLUCENT", 36123571c7bSRussell King (Oracle) .part = "3FE46541AA", 36223571c7bSRussell King (Oracle) .modes = sfp_quirk_2500basex, 36327541675SRussell King (Oracle) .fixup = sfp_fixup_long_startup, 36423571c7bSRussell King (Oracle) }, { 365*73472c83SRussell King (Oracle) .vendor = "HALNy", 366*73472c83SRussell King (Oracle) .part = "HL-GSFP", 367*73472c83SRussell King (Oracle) .fixup = sfp_fixup_halny_gsfp, 368*73472c83SRussell King (Oracle) }, { 36923571c7bSRussell King (Oracle) // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd 37023571c7bSRussell King (Oracle) // NRZ in their EEPROM 37123571c7bSRussell King (Oracle) .vendor = "HUAWEI", 37223571c7bSRussell King (Oracle) .part = "MA5671A", 37323571c7bSRussell King (Oracle) .modes = sfp_quirk_2500basex, 3745029be76SRussell King (Oracle) .fixup = sfp_fixup_ignore_tx_fault, 37523571c7bSRussell King (Oracle) }, { 37623571c7bSRussell King (Oracle) // Lantech 8330-262D-E can operate at 2500base-X, but 37723571c7bSRussell King (Oracle) // incorrectly report 2500MBd NRZ in their EEPROM 37823571c7bSRussell King (Oracle) .vendor = "Lantech", 37923571c7bSRussell King (Oracle) .part = "8330-262D-E", 38023571c7bSRussell King (Oracle) .modes = sfp_quirk_2500basex, 38123571c7bSRussell King (Oracle) }, { 38223571c7bSRussell King (Oracle) .vendor = "UBNT", 38323571c7bSRussell King (Oracle) .part = "UF-INSTANT", 38423571c7bSRussell King (Oracle) .modes = sfp_quirk_ubnt_uf_instant, 385*73472c83SRussell King (Oracle) } 38623571c7bSRussell King (Oracle) }; 38723571c7bSRussell King (Oracle) 38823571c7bSRussell King (Oracle) static size_t sfp_strlen(const char *str, size_t maxlen) 38923571c7bSRussell King (Oracle) { 39023571c7bSRussell King (Oracle) size_t size, i; 39123571c7bSRussell King (Oracle) 392*73472c83SRussell King (Oracle) /* Trailing characters should be filled with space chars, but 393*73472c83SRussell King (Oracle) * some manufacturers can't read SFF-8472 and use NUL. 394*73472c83SRussell King (Oracle) */ 39523571c7bSRussell King (Oracle) for (i = 0, size = 0; i < maxlen; i++) 396*73472c83SRussell King (Oracle) if (str[i] != ' ' && str[i] != '\0') 39723571c7bSRussell King (Oracle) size = i + 1; 39823571c7bSRussell King (Oracle) 39923571c7bSRussell King (Oracle) return size; 40023571c7bSRussell King (Oracle) } 40123571c7bSRussell King (Oracle) 40223571c7bSRussell King (Oracle) static bool sfp_match(const char *qs, const char *str, size_t len) 40323571c7bSRussell King (Oracle) { 40423571c7bSRussell King (Oracle) if (!qs) 40523571c7bSRussell King (Oracle) return true; 40623571c7bSRussell King (Oracle) if (strlen(qs) != len) 40723571c7bSRussell King (Oracle) return false; 40823571c7bSRussell King (Oracle) return !strncmp(qs, str, len); 40923571c7bSRussell King (Oracle) } 41023571c7bSRussell King (Oracle) 41123571c7bSRussell King (Oracle) static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id) 41223571c7bSRussell King (Oracle) { 41323571c7bSRussell King (Oracle) const struct sfp_quirk *q; 41423571c7bSRussell King (Oracle) unsigned int i; 41523571c7bSRussell King (Oracle) size_t vs, ps; 41623571c7bSRussell King (Oracle) 41723571c7bSRussell King (Oracle) vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name)); 41823571c7bSRussell King (Oracle) ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn)); 41923571c7bSRussell King (Oracle) 42023571c7bSRussell King (Oracle) for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++) 42123571c7bSRussell King (Oracle) if (sfp_match(q->vendor, id->base.vendor_name, vs) && 42223571c7bSRussell King (Oracle) sfp_match(q->part, id->base.vendor_pn, ps)) 42323571c7bSRussell King (Oracle) return q; 42423571c7bSRussell King (Oracle) 42523571c7bSRussell King (Oracle) return NULL; 42623571c7bSRussell King (Oracle) } 42723571c7bSRussell King (Oracle) 42873970055SRussell King static unsigned long poll_jiffies; 42973970055SRussell King 43073970055SRussell King static unsigned int sfp_gpio_get_state(struct sfp *sfp) 43173970055SRussell King { 43273970055SRussell King unsigned int i, state, v; 43373970055SRussell King 43473970055SRussell King for (i = state = 0; i < GPIO_MAX; i++) { 43573970055SRussell King if (gpio_flags[i] != GPIOD_IN || !sfp->gpio[i]) 43673970055SRussell King continue; 43773970055SRussell King 43873970055SRussell King v = gpiod_get_value_cansleep(sfp->gpio[i]); 43973970055SRussell King if (v) 44073970055SRussell King state |= BIT(i); 44173970055SRussell King } 44273970055SRussell King 44373970055SRussell King return state; 44473970055SRussell King } 44573970055SRussell King 446259c8618SRussell King static unsigned int sff_gpio_get_state(struct sfp *sfp) 447259c8618SRussell King { 448259c8618SRussell King return sfp_gpio_get_state(sfp) | SFP_F_PRESENT; 449259c8618SRussell King } 450259c8618SRussell King 45173970055SRussell King static void sfp_gpio_set_state(struct sfp *sfp, unsigned int state) 45273970055SRussell King { 45373970055SRussell King if (state & SFP_F_PRESENT) { 45473970055SRussell King /* If the module is present, drive the signals */ 45573970055SRussell King if (sfp->gpio[GPIO_TX_DISABLE]) 45673970055SRussell King gpiod_direction_output(sfp->gpio[GPIO_TX_DISABLE], 45773970055SRussell King state & SFP_F_TX_DISABLE); 45873970055SRussell King if (state & SFP_F_RATE_SELECT) 45973970055SRussell King gpiod_direction_output(sfp->gpio[GPIO_RATE_SELECT], 46073970055SRussell King state & SFP_F_RATE_SELECT); 46173970055SRussell King } else { 46273970055SRussell King /* Otherwise, let them float to the pull-ups */ 46373970055SRussell King if (sfp->gpio[GPIO_TX_DISABLE]) 46473970055SRussell King gpiod_direction_input(sfp->gpio[GPIO_TX_DISABLE]); 46573970055SRussell King if (state & SFP_F_RATE_SELECT) 46673970055SRussell King gpiod_direction_input(sfp->gpio[GPIO_RATE_SELECT]); 46773970055SRussell King } 46873970055SRussell King } 46973970055SRussell King 4703bb35261SJon Nettleton static int sfp_i2c_read(struct sfp *sfp, bool a2, u8 dev_addr, void *buf, 4713bb35261SJon Nettleton size_t len) 47273970055SRussell King { 47373970055SRussell King struct i2c_msg msgs[2]; 474426c6cbcSPali Rohár u8 bus_addr = a2 ? 0x51 : 0x50; 475426c6cbcSPali Rohár size_t block_size = sfp->i2c_block_size; 47628e74a7cSRussell King size_t this_len; 47773970055SRussell King int ret; 47873970055SRussell King 47973970055SRussell King msgs[0].addr = bus_addr; 48073970055SRussell King msgs[0].flags = 0; 48173970055SRussell King msgs[0].len = 1; 48273970055SRussell King msgs[0].buf = &dev_addr; 48373970055SRussell King msgs[1].addr = bus_addr; 48473970055SRussell King msgs[1].flags = I2C_M_RD; 48573970055SRussell King msgs[1].len = len; 48673970055SRussell King msgs[1].buf = buf; 48773970055SRussell King 48828e74a7cSRussell King while (len) { 48928e74a7cSRussell King this_len = len; 4900d035bedSRussell King if (this_len > block_size) 4910d035bedSRussell King this_len = block_size; 49228e74a7cSRussell King 49328e74a7cSRussell King msgs[1].len = this_len; 49428e74a7cSRussell King 4953bb35261SJon Nettleton ret = i2c_transfer(sfp->i2c, msgs, ARRAY_SIZE(msgs)); 49673970055SRussell King if (ret < 0) 49773970055SRussell King return ret; 49873970055SRussell King 49928e74a7cSRussell King if (ret != ARRAY_SIZE(msgs)) 50028e74a7cSRussell King break; 50128e74a7cSRussell King 50228e74a7cSRussell King msgs[1].buf += this_len; 50328e74a7cSRussell King dev_addr += this_len; 50428e74a7cSRussell King len -= this_len; 50528e74a7cSRussell King } 50628e74a7cSRussell King 50728e74a7cSRussell King return msgs[1].buf - (u8 *)buf; 50873970055SRussell King } 50973970055SRussell King 5103bb35261SJon Nettleton static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf, 51173970055SRussell King size_t len) 51273970055SRussell King { 5133bb35261SJon Nettleton struct i2c_msg msgs[1]; 5143bb35261SJon Nettleton u8 bus_addr = a2 ? 0x51 : 0x50; 5153bb35261SJon Nettleton int ret; 5163bb35261SJon Nettleton 5173bb35261SJon Nettleton msgs[0].addr = bus_addr; 5183bb35261SJon Nettleton msgs[0].flags = 0; 5193bb35261SJon Nettleton msgs[0].len = 1 + len; 5203bb35261SJon Nettleton msgs[0].buf = kmalloc(1 + len, GFP_KERNEL); 5213bb35261SJon Nettleton if (!msgs[0].buf) 5223bb35261SJon Nettleton return -ENOMEM; 5233bb35261SJon Nettleton 5243bb35261SJon Nettleton msgs[0].buf[0] = dev_addr; 5253bb35261SJon Nettleton memcpy(&msgs[0].buf[1], buf, len); 5263bb35261SJon Nettleton 5273bb35261SJon Nettleton ret = i2c_transfer(sfp->i2c, msgs, ARRAY_SIZE(msgs)); 5283bb35261SJon Nettleton 5293bb35261SJon Nettleton kfree(msgs[0].buf); 5303bb35261SJon Nettleton 5313bb35261SJon Nettleton if (ret < 0) 5323bb35261SJon Nettleton return ret; 5333bb35261SJon Nettleton 5343bb35261SJon Nettleton return ret == ARRAY_SIZE(msgs) ? len : 0; 53573970055SRussell King } 53673970055SRussell King 53773970055SRussell King static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c) 53873970055SRussell King { 53973970055SRussell King struct mii_bus *i2c_mii; 54073970055SRussell King int ret; 54173970055SRussell King 54273970055SRussell King if (!i2c_check_functionality(i2c, I2C_FUNC_I2C)) 54373970055SRussell King return -EINVAL; 54473970055SRussell King 54573970055SRussell King sfp->i2c = i2c; 54673970055SRussell King sfp->read = sfp_i2c_read; 5473bb35261SJon Nettleton sfp->write = sfp_i2c_write; 54873970055SRussell King 54973970055SRussell King i2c_mii = mdio_i2c_alloc(sfp->dev, i2c); 55073970055SRussell King if (IS_ERR(i2c_mii)) 55173970055SRussell King return PTR_ERR(i2c_mii); 55273970055SRussell King 55373970055SRussell King i2c_mii->name = "SFP I2C Bus"; 55473970055SRussell King i2c_mii->phy_mask = ~0; 55573970055SRussell King 55673970055SRussell King ret = mdiobus_register(i2c_mii); 55773970055SRussell King if (ret < 0) { 55873970055SRussell King mdiobus_free(i2c_mii); 55973970055SRussell King return ret; 56073970055SRussell King } 56173970055SRussell King 56273970055SRussell King sfp->i2c_mii = i2c_mii; 56373970055SRussell King 56473970055SRussell King return 0; 56573970055SRussell King } 56673970055SRussell King 56773970055SRussell King /* Interface */ 56873970055SRussell King static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len) 56973970055SRussell King { 57073970055SRussell King return sfp->read(sfp, a2, addr, buf, len); 57173970055SRussell King } 57273970055SRussell King 5733bb35261SJon Nettleton static int sfp_write(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len) 5743bb35261SJon Nettleton { 5753bb35261SJon Nettleton return sfp->write(sfp, a2, addr, buf, len); 5763bb35261SJon Nettleton } 5773bb35261SJon Nettleton 578f3c9a666SRussell King static unsigned int sfp_soft_get_state(struct sfp *sfp) 579f3c9a666SRussell King { 580f3c9a666SRussell King unsigned int state = 0; 581f3c9a666SRussell King u8 status; 5820dea4d03SRussell King int ret; 583f3c9a666SRussell King 5840dea4d03SRussell King ret = sfp_read(sfp, true, SFP_STATUS, &status, sizeof(status)); 5850dea4d03SRussell King if (ret == sizeof(status)) { 586f3c9a666SRussell King if (status & SFP_STATUS_RX_LOS) 587f3c9a666SRussell King state |= SFP_F_LOS; 588f3c9a666SRussell King if (status & SFP_STATUS_TX_FAULT) 589f3c9a666SRussell King state |= SFP_F_TX_FAULT; 5900dea4d03SRussell King } else { 5910dea4d03SRussell King dev_err_ratelimited(sfp->dev, 5929ae1ef4bSRussell King (Oracle) "failed to read SFP soft status: %pe\n", 5939ae1ef4bSRussell King (Oracle) ERR_PTR(ret)); 5940dea4d03SRussell King /* Preserve the current state */ 5950dea4d03SRussell King state = sfp->state; 596f3c9a666SRussell King } 597f3c9a666SRussell King 598f3c9a666SRussell King return state & sfp->state_soft_mask; 599f3c9a666SRussell King } 600f3c9a666SRussell King 601f3c9a666SRussell King static void sfp_soft_set_state(struct sfp *sfp, unsigned int state) 602f3c9a666SRussell King { 603f3c9a666SRussell King u8 status; 604f3c9a666SRussell King 605f3c9a666SRussell King if (sfp_read(sfp, true, SFP_STATUS, &status, sizeof(status)) == 606f3c9a666SRussell King sizeof(status)) { 607f3c9a666SRussell King if (state & SFP_F_TX_DISABLE) 608f3c9a666SRussell King status |= SFP_STATUS_TX_DISABLE_FORCE; 609f3c9a666SRussell King else 610f3c9a666SRussell King status &= ~SFP_STATUS_TX_DISABLE_FORCE; 611f3c9a666SRussell King 612f3c9a666SRussell King sfp_write(sfp, true, SFP_STATUS, &status, sizeof(status)); 613f3c9a666SRussell King } 614f3c9a666SRussell King } 615f3c9a666SRussell King 616f3c9a666SRussell King static void sfp_soft_start_poll(struct sfp *sfp) 617f3c9a666SRussell King { 618f3c9a666SRussell King const struct sfp_eeprom_id *id = &sfp->id; 6198475c4b7SRussell King (Oracle) unsigned int mask = 0; 620f3c9a666SRussell King 621f3c9a666SRussell King sfp->state_soft_mask = 0; 6228475c4b7SRussell King (Oracle) if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE) 6238475c4b7SRussell King (Oracle) mask |= SFP_F_TX_DISABLE; 6248475c4b7SRussell King (Oracle) if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT) 6258475c4b7SRussell King (Oracle) mask |= SFP_F_TX_FAULT; 6268475c4b7SRussell King (Oracle) if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS) 6278475c4b7SRussell King (Oracle) mask |= SFP_F_LOS; 6288475c4b7SRussell King (Oracle) 6298475c4b7SRussell King (Oracle) // Poll the soft state for hardware pins we want to ignore 6308475c4b7SRussell King (Oracle) sfp->state_soft_mask = ~sfp->state_hw_mask & mask; 631f3c9a666SRussell King 632f3c9a666SRussell King if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) && 633f3c9a666SRussell King !sfp->need_poll) 634f3c9a666SRussell King mod_delayed_work(system_wq, &sfp->poll, poll_jiffies); 635f3c9a666SRussell King } 636f3c9a666SRussell King 637f3c9a666SRussell King static void sfp_soft_stop_poll(struct sfp *sfp) 638f3c9a666SRussell King { 639f3c9a666SRussell King sfp->state_soft_mask = 0; 640f3c9a666SRussell King } 641f3c9a666SRussell King 642f3c9a666SRussell King static unsigned int sfp_get_state(struct sfp *sfp) 643f3c9a666SRussell King { 6448475c4b7SRussell King (Oracle) unsigned int soft = sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT); 6458475c4b7SRussell King (Oracle) unsigned int state; 646f3c9a666SRussell King 6478475c4b7SRussell King (Oracle) state = sfp->get_state(sfp) & sfp->state_hw_mask; 6488475c4b7SRussell King (Oracle) if (state & SFP_F_PRESENT && soft) 649f3c9a666SRussell King state |= sfp_soft_get_state(sfp); 650f3c9a666SRussell King 651f3c9a666SRussell King return state; 652f3c9a666SRussell King } 653f3c9a666SRussell King 654f3c9a666SRussell King static void sfp_set_state(struct sfp *sfp, unsigned int state) 655f3c9a666SRussell King { 656f3c9a666SRussell King sfp->set_state(sfp, state); 657f3c9a666SRussell King 658f3c9a666SRussell King if (state & SFP_F_PRESENT && 659f3c9a666SRussell King sfp->state_soft_mask & SFP_F_TX_DISABLE) 660f3c9a666SRussell King sfp_soft_set_state(sfp, state); 661f3c9a666SRussell King } 662f3c9a666SRussell King 66373970055SRussell King static unsigned int sfp_check(void *buf, size_t len) 66473970055SRussell King { 66573970055SRussell King u8 *p, check; 66673970055SRussell King 66773970055SRussell King for (p = buf, check = 0; len; p++, len--) 66873970055SRussell King check += *p; 66973970055SRussell King 67073970055SRussell King return check; 67173970055SRussell King } 67273970055SRussell King 6731323061aSAndrew Lunn /* hwmon */ 6741323061aSAndrew Lunn #if IS_ENABLED(CONFIG_HWMON) 6751323061aSAndrew Lunn static umode_t sfp_hwmon_is_visible(const void *data, 6761323061aSAndrew Lunn enum hwmon_sensor_types type, 6771323061aSAndrew Lunn u32 attr, int channel) 6781323061aSAndrew Lunn { 6791323061aSAndrew Lunn const struct sfp *sfp = data; 6801323061aSAndrew Lunn 6811323061aSAndrew Lunn switch (type) { 6821323061aSAndrew Lunn case hwmon_temp: 6831323061aSAndrew Lunn switch (attr) { 6841323061aSAndrew Lunn case hwmon_temp_min_alarm: 6851323061aSAndrew Lunn case hwmon_temp_max_alarm: 6861323061aSAndrew Lunn case hwmon_temp_lcrit_alarm: 6871323061aSAndrew Lunn case hwmon_temp_crit_alarm: 6881323061aSAndrew Lunn case hwmon_temp_min: 6891323061aSAndrew Lunn case hwmon_temp_max: 6901323061aSAndrew Lunn case hwmon_temp_lcrit: 6911323061aSAndrew Lunn case hwmon_temp_crit: 692a33710bdSAndrew Lunn if (!(sfp->id.ext.enhopts & SFP_ENHOPTS_ALARMWARN)) 693a33710bdSAndrew Lunn return 0; 694df561f66SGustavo A. R. Silva fallthrough; 695a33710bdSAndrew Lunn case hwmon_temp_input: 696c1236979SAndrew Lunn case hwmon_temp_label: 6971323061aSAndrew Lunn return 0444; 6981323061aSAndrew Lunn default: 6991323061aSAndrew Lunn return 0; 7001323061aSAndrew Lunn } 7011323061aSAndrew Lunn case hwmon_in: 7021323061aSAndrew Lunn switch (attr) { 7031323061aSAndrew Lunn case hwmon_in_min_alarm: 7041323061aSAndrew Lunn case hwmon_in_max_alarm: 7051323061aSAndrew Lunn case hwmon_in_lcrit_alarm: 7061323061aSAndrew Lunn case hwmon_in_crit_alarm: 7071323061aSAndrew Lunn case hwmon_in_min: 7081323061aSAndrew Lunn case hwmon_in_max: 7091323061aSAndrew Lunn case hwmon_in_lcrit: 7101323061aSAndrew Lunn case hwmon_in_crit: 711a33710bdSAndrew Lunn if (!(sfp->id.ext.enhopts & SFP_ENHOPTS_ALARMWARN)) 712a33710bdSAndrew Lunn return 0; 713df561f66SGustavo A. R. Silva fallthrough; 714a33710bdSAndrew Lunn case hwmon_in_input: 715c1236979SAndrew Lunn case hwmon_in_label: 7161323061aSAndrew Lunn return 0444; 7171323061aSAndrew Lunn default: 7181323061aSAndrew Lunn return 0; 7191323061aSAndrew Lunn } 7201323061aSAndrew Lunn case hwmon_curr: 7211323061aSAndrew Lunn switch (attr) { 7221323061aSAndrew Lunn case hwmon_curr_min_alarm: 7231323061aSAndrew Lunn case hwmon_curr_max_alarm: 7241323061aSAndrew Lunn case hwmon_curr_lcrit_alarm: 7251323061aSAndrew Lunn case hwmon_curr_crit_alarm: 7261323061aSAndrew Lunn case hwmon_curr_min: 7271323061aSAndrew Lunn case hwmon_curr_max: 7281323061aSAndrew Lunn case hwmon_curr_lcrit: 7291323061aSAndrew Lunn case hwmon_curr_crit: 730a33710bdSAndrew Lunn if (!(sfp->id.ext.enhopts & SFP_ENHOPTS_ALARMWARN)) 731a33710bdSAndrew Lunn return 0; 732df561f66SGustavo A. R. Silva fallthrough; 733a33710bdSAndrew Lunn case hwmon_curr_input: 734c1236979SAndrew Lunn case hwmon_curr_label: 7351323061aSAndrew Lunn return 0444; 7361323061aSAndrew Lunn default: 7371323061aSAndrew Lunn return 0; 7381323061aSAndrew Lunn } 7391323061aSAndrew Lunn case hwmon_power: 7401323061aSAndrew Lunn /* External calibration of receive power requires 7411323061aSAndrew Lunn * floating point arithmetic. Doing that in the kernel 7421323061aSAndrew Lunn * is not easy, so just skip it. If the module does 7431323061aSAndrew Lunn * not require external calibration, we can however 7441323061aSAndrew Lunn * show receiver power, since FP is then not needed. 7451323061aSAndrew Lunn */ 7461323061aSAndrew Lunn if (sfp->id.ext.diagmon & SFP_DIAGMON_EXT_CAL && 7471323061aSAndrew Lunn channel == 1) 7481323061aSAndrew Lunn return 0; 7491323061aSAndrew Lunn switch (attr) { 7501323061aSAndrew Lunn case hwmon_power_min_alarm: 7511323061aSAndrew Lunn case hwmon_power_max_alarm: 7521323061aSAndrew Lunn case hwmon_power_lcrit_alarm: 7531323061aSAndrew Lunn case hwmon_power_crit_alarm: 7541323061aSAndrew Lunn case hwmon_power_min: 7551323061aSAndrew Lunn case hwmon_power_max: 7561323061aSAndrew Lunn case hwmon_power_lcrit: 7571323061aSAndrew Lunn case hwmon_power_crit: 758a33710bdSAndrew Lunn if (!(sfp->id.ext.enhopts & SFP_ENHOPTS_ALARMWARN)) 759a33710bdSAndrew Lunn return 0; 760df561f66SGustavo A. R. Silva fallthrough; 761a33710bdSAndrew Lunn case hwmon_power_input: 762c1236979SAndrew Lunn case hwmon_power_label: 7631323061aSAndrew Lunn return 0444; 7641323061aSAndrew Lunn default: 7651323061aSAndrew Lunn return 0; 7661323061aSAndrew Lunn } 7671323061aSAndrew Lunn default: 7681323061aSAndrew Lunn return 0; 7691323061aSAndrew Lunn } 7701323061aSAndrew Lunn } 7711323061aSAndrew Lunn 7721323061aSAndrew Lunn static int sfp_hwmon_read_sensor(struct sfp *sfp, int reg, long *value) 7731323061aSAndrew Lunn { 7741323061aSAndrew Lunn __be16 val; 7751323061aSAndrew Lunn int err; 7761323061aSAndrew Lunn 7771323061aSAndrew Lunn err = sfp_read(sfp, true, reg, &val, sizeof(val)); 7781323061aSAndrew Lunn if (err < 0) 7791323061aSAndrew Lunn return err; 7801323061aSAndrew Lunn 7811323061aSAndrew Lunn *value = be16_to_cpu(val); 7821323061aSAndrew Lunn 7831323061aSAndrew Lunn return 0; 7841323061aSAndrew Lunn } 7851323061aSAndrew Lunn 7861323061aSAndrew Lunn static void sfp_hwmon_to_rx_power(long *value) 7871323061aSAndrew Lunn { 7880cea0e11SAndrew Lunn *value = DIV_ROUND_CLOSEST(*value, 10); 7891323061aSAndrew Lunn } 7901323061aSAndrew Lunn 7911323061aSAndrew Lunn static void sfp_hwmon_calibrate(struct sfp *sfp, unsigned int slope, int offset, 7921323061aSAndrew Lunn long *value) 7931323061aSAndrew Lunn { 7941323061aSAndrew Lunn if (sfp->id.ext.diagmon & SFP_DIAGMON_EXT_CAL) 7951323061aSAndrew Lunn *value = DIV_ROUND_CLOSEST(*value * slope, 256) + offset; 7961323061aSAndrew Lunn } 7971323061aSAndrew Lunn 7981323061aSAndrew Lunn static void sfp_hwmon_calibrate_temp(struct sfp *sfp, long *value) 7991323061aSAndrew Lunn { 8001323061aSAndrew Lunn sfp_hwmon_calibrate(sfp, be16_to_cpu(sfp->diag.cal_t_slope), 8011323061aSAndrew Lunn be16_to_cpu(sfp->diag.cal_t_offset), value); 8021323061aSAndrew Lunn 8031323061aSAndrew Lunn if (*value >= 0x8000) 8041323061aSAndrew Lunn *value -= 0x10000; 8051323061aSAndrew Lunn 8061323061aSAndrew Lunn *value = DIV_ROUND_CLOSEST(*value * 1000, 256); 8071323061aSAndrew Lunn } 8081323061aSAndrew Lunn 8091323061aSAndrew Lunn static void sfp_hwmon_calibrate_vcc(struct sfp *sfp, long *value) 8101323061aSAndrew Lunn { 8111323061aSAndrew Lunn sfp_hwmon_calibrate(sfp, be16_to_cpu(sfp->diag.cal_v_slope), 8121323061aSAndrew Lunn be16_to_cpu(sfp->diag.cal_v_offset), value); 8131323061aSAndrew Lunn 8141323061aSAndrew Lunn *value = DIV_ROUND_CLOSEST(*value, 10); 8151323061aSAndrew Lunn } 8161323061aSAndrew Lunn 8171323061aSAndrew Lunn static void sfp_hwmon_calibrate_bias(struct sfp *sfp, long *value) 8181323061aSAndrew Lunn { 8191323061aSAndrew Lunn sfp_hwmon_calibrate(sfp, be16_to_cpu(sfp->diag.cal_txi_slope), 8201323061aSAndrew Lunn be16_to_cpu(sfp->diag.cal_txi_offset), value); 8211323061aSAndrew Lunn 8221323061aSAndrew Lunn *value = DIV_ROUND_CLOSEST(*value, 500); 8231323061aSAndrew Lunn } 8241323061aSAndrew Lunn 8251323061aSAndrew Lunn static void sfp_hwmon_calibrate_tx_power(struct sfp *sfp, long *value) 8261323061aSAndrew Lunn { 8271323061aSAndrew Lunn sfp_hwmon_calibrate(sfp, be16_to_cpu(sfp->diag.cal_txpwr_slope), 8281323061aSAndrew Lunn be16_to_cpu(sfp->diag.cal_txpwr_offset), value); 8291323061aSAndrew Lunn 8301323061aSAndrew Lunn *value = DIV_ROUND_CLOSEST(*value, 10); 8311323061aSAndrew Lunn } 8321323061aSAndrew Lunn 8331323061aSAndrew Lunn static int sfp_hwmon_read_temp(struct sfp *sfp, int reg, long *value) 8341323061aSAndrew Lunn { 8351323061aSAndrew Lunn int err; 8361323061aSAndrew Lunn 8371323061aSAndrew Lunn err = sfp_hwmon_read_sensor(sfp, reg, value); 8381323061aSAndrew Lunn if (err < 0) 8391323061aSAndrew Lunn return err; 8401323061aSAndrew Lunn 8411323061aSAndrew Lunn sfp_hwmon_calibrate_temp(sfp, value); 8421323061aSAndrew Lunn 8431323061aSAndrew Lunn return 0; 8441323061aSAndrew Lunn } 8451323061aSAndrew Lunn 8461323061aSAndrew Lunn static int sfp_hwmon_read_vcc(struct sfp *sfp, int reg, long *value) 8471323061aSAndrew Lunn { 8481323061aSAndrew Lunn int err; 8491323061aSAndrew Lunn 8501323061aSAndrew Lunn err = sfp_hwmon_read_sensor(sfp, reg, value); 8511323061aSAndrew Lunn if (err < 0) 8521323061aSAndrew Lunn return err; 8531323061aSAndrew Lunn 8541323061aSAndrew Lunn sfp_hwmon_calibrate_vcc(sfp, value); 8551323061aSAndrew Lunn 8561323061aSAndrew Lunn return 0; 8571323061aSAndrew Lunn } 8581323061aSAndrew Lunn 8591323061aSAndrew Lunn static int sfp_hwmon_read_bias(struct sfp *sfp, int reg, long *value) 8601323061aSAndrew Lunn { 8611323061aSAndrew Lunn int err; 8621323061aSAndrew Lunn 8631323061aSAndrew Lunn err = sfp_hwmon_read_sensor(sfp, reg, value); 8641323061aSAndrew Lunn if (err < 0) 8651323061aSAndrew Lunn return err; 8661323061aSAndrew Lunn 8671323061aSAndrew Lunn sfp_hwmon_calibrate_bias(sfp, value); 8681323061aSAndrew Lunn 8691323061aSAndrew Lunn return 0; 8701323061aSAndrew Lunn } 8711323061aSAndrew Lunn 8721323061aSAndrew Lunn static int sfp_hwmon_read_tx_power(struct sfp *sfp, int reg, long *value) 8731323061aSAndrew Lunn { 8741323061aSAndrew Lunn int err; 8751323061aSAndrew Lunn 8761323061aSAndrew Lunn err = sfp_hwmon_read_sensor(sfp, reg, value); 8771323061aSAndrew Lunn if (err < 0) 8781323061aSAndrew Lunn return err; 8791323061aSAndrew Lunn 8801323061aSAndrew Lunn sfp_hwmon_calibrate_tx_power(sfp, value); 8811323061aSAndrew Lunn 8821323061aSAndrew Lunn return 0; 8831323061aSAndrew Lunn } 8841323061aSAndrew Lunn 8851323061aSAndrew Lunn static int sfp_hwmon_read_rx_power(struct sfp *sfp, int reg, long *value) 8861323061aSAndrew Lunn { 8871323061aSAndrew Lunn int err; 8881323061aSAndrew Lunn 8891323061aSAndrew Lunn err = sfp_hwmon_read_sensor(sfp, reg, value); 8901323061aSAndrew Lunn if (err < 0) 8911323061aSAndrew Lunn return err; 8921323061aSAndrew Lunn 8931323061aSAndrew Lunn sfp_hwmon_to_rx_power(value); 8941323061aSAndrew Lunn 8951323061aSAndrew Lunn return 0; 8961323061aSAndrew Lunn } 8971323061aSAndrew Lunn 8981323061aSAndrew Lunn static int sfp_hwmon_temp(struct sfp *sfp, u32 attr, long *value) 8991323061aSAndrew Lunn { 9001323061aSAndrew Lunn u8 status; 9011323061aSAndrew Lunn int err; 9021323061aSAndrew Lunn 9031323061aSAndrew Lunn switch (attr) { 9041323061aSAndrew Lunn case hwmon_temp_input: 9051323061aSAndrew Lunn return sfp_hwmon_read_temp(sfp, SFP_TEMP, value); 9061323061aSAndrew Lunn 9071323061aSAndrew Lunn case hwmon_temp_lcrit: 9081323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.temp_low_alarm); 9091323061aSAndrew Lunn sfp_hwmon_calibrate_temp(sfp, value); 9101323061aSAndrew Lunn return 0; 9111323061aSAndrew Lunn 9121323061aSAndrew Lunn case hwmon_temp_min: 9131323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.temp_low_warn); 9141323061aSAndrew Lunn sfp_hwmon_calibrate_temp(sfp, value); 9151323061aSAndrew Lunn return 0; 9161323061aSAndrew Lunn case hwmon_temp_max: 9171323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.temp_high_warn); 9181323061aSAndrew Lunn sfp_hwmon_calibrate_temp(sfp, value); 9191323061aSAndrew Lunn return 0; 9201323061aSAndrew Lunn 9211323061aSAndrew Lunn case hwmon_temp_crit: 9221323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.temp_high_alarm); 9231323061aSAndrew Lunn sfp_hwmon_calibrate_temp(sfp, value); 9241323061aSAndrew Lunn return 0; 9251323061aSAndrew Lunn 9261323061aSAndrew Lunn case hwmon_temp_lcrit_alarm: 9271323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_ALARM0, &status, sizeof(status)); 9281323061aSAndrew Lunn if (err < 0) 9291323061aSAndrew Lunn return err; 9301323061aSAndrew Lunn 9311323061aSAndrew Lunn *value = !!(status & SFP_ALARM0_TEMP_LOW); 9321323061aSAndrew Lunn return 0; 9331323061aSAndrew Lunn 9341323061aSAndrew Lunn case hwmon_temp_min_alarm: 9351323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_WARN0, &status, sizeof(status)); 9361323061aSAndrew Lunn if (err < 0) 9371323061aSAndrew Lunn return err; 9381323061aSAndrew Lunn 9391323061aSAndrew Lunn *value = !!(status & SFP_WARN0_TEMP_LOW); 9401323061aSAndrew Lunn return 0; 9411323061aSAndrew Lunn 9421323061aSAndrew Lunn case hwmon_temp_max_alarm: 9431323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_WARN0, &status, sizeof(status)); 9441323061aSAndrew Lunn if (err < 0) 9451323061aSAndrew Lunn return err; 9461323061aSAndrew Lunn 9471323061aSAndrew Lunn *value = !!(status & SFP_WARN0_TEMP_HIGH); 9481323061aSAndrew Lunn return 0; 9491323061aSAndrew Lunn 9501323061aSAndrew Lunn case hwmon_temp_crit_alarm: 9511323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_ALARM0, &status, sizeof(status)); 9521323061aSAndrew Lunn if (err < 0) 9531323061aSAndrew Lunn return err; 9541323061aSAndrew Lunn 9551323061aSAndrew Lunn *value = !!(status & SFP_ALARM0_TEMP_HIGH); 9561323061aSAndrew Lunn return 0; 9571323061aSAndrew Lunn default: 9581323061aSAndrew Lunn return -EOPNOTSUPP; 9591323061aSAndrew Lunn } 9601323061aSAndrew Lunn 9611323061aSAndrew Lunn return -EOPNOTSUPP; 9621323061aSAndrew Lunn } 9631323061aSAndrew Lunn 9641323061aSAndrew Lunn static int sfp_hwmon_vcc(struct sfp *sfp, u32 attr, long *value) 9651323061aSAndrew Lunn { 9661323061aSAndrew Lunn u8 status; 9671323061aSAndrew Lunn int err; 9681323061aSAndrew Lunn 9691323061aSAndrew Lunn switch (attr) { 9701323061aSAndrew Lunn case hwmon_in_input: 9711323061aSAndrew Lunn return sfp_hwmon_read_vcc(sfp, SFP_VCC, value); 9721323061aSAndrew Lunn 9731323061aSAndrew Lunn case hwmon_in_lcrit: 9741323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.volt_low_alarm); 9751323061aSAndrew Lunn sfp_hwmon_calibrate_vcc(sfp, value); 9761323061aSAndrew Lunn return 0; 9771323061aSAndrew Lunn 9781323061aSAndrew Lunn case hwmon_in_min: 9791323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.volt_low_warn); 9801323061aSAndrew Lunn sfp_hwmon_calibrate_vcc(sfp, value); 9811323061aSAndrew Lunn return 0; 9821323061aSAndrew Lunn 9831323061aSAndrew Lunn case hwmon_in_max: 9841323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.volt_high_warn); 9851323061aSAndrew Lunn sfp_hwmon_calibrate_vcc(sfp, value); 9861323061aSAndrew Lunn return 0; 9871323061aSAndrew Lunn 9881323061aSAndrew Lunn case hwmon_in_crit: 9891323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.volt_high_alarm); 9901323061aSAndrew Lunn sfp_hwmon_calibrate_vcc(sfp, value); 9911323061aSAndrew Lunn return 0; 9921323061aSAndrew Lunn 9931323061aSAndrew Lunn case hwmon_in_lcrit_alarm: 9941323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_ALARM0, &status, sizeof(status)); 9951323061aSAndrew Lunn if (err < 0) 9961323061aSAndrew Lunn return err; 9971323061aSAndrew Lunn 9981323061aSAndrew Lunn *value = !!(status & SFP_ALARM0_VCC_LOW); 9991323061aSAndrew Lunn return 0; 10001323061aSAndrew Lunn 10011323061aSAndrew Lunn case hwmon_in_min_alarm: 10021323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_WARN0, &status, sizeof(status)); 10031323061aSAndrew Lunn if (err < 0) 10041323061aSAndrew Lunn return err; 10051323061aSAndrew Lunn 10061323061aSAndrew Lunn *value = !!(status & SFP_WARN0_VCC_LOW); 10071323061aSAndrew Lunn return 0; 10081323061aSAndrew Lunn 10091323061aSAndrew Lunn case hwmon_in_max_alarm: 10101323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_WARN0, &status, sizeof(status)); 10111323061aSAndrew Lunn if (err < 0) 10121323061aSAndrew Lunn return err; 10131323061aSAndrew Lunn 10141323061aSAndrew Lunn *value = !!(status & SFP_WARN0_VCC_HIGH); 10151323061aSAndrew Lunn return 0; 10161323061aSAndrew Lunn 10171323061aSAndrew Lunn case hwmon_in_crit_alarm: 10181323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_ALARM0, &status, sizeof(status)); 10191323061aSAndrew Lunn if (err < 0) 10201323061aSAndrew Lunn return err; 10211323061aSAndrew Lunn 10221323061aSAndrew Lunn *value = !!(status & SFP_ALARM0_VCC_HIGH); 10231323061aSAndrew Lunn return 0; 10241323061aSAndrew Lunn default: 10251323061aSAndrew Lunn return -EOPNOTSUPP; 10261323061aSAndrew Lunn } 10271323061aSAndrew Lunn 10281323061aSAndrew Lunn return -EOPNOTSUPP; 10291323061aSAndrew Lunn } 10301323061aSAndrew Lunn 10311323061aSAndrew Lunn static int sfp_hwmon_bias(struct sfp *sfp, u32 attr, long *value) 10321323061aSAndrew Lunn { 10331323061aSAndrew Lunn u8 status; 10341323061aSAndrew Lunn int err; 10351323061aSAndrew Lunn 10361323061aSAndrew Lunn switch (attr) { 10371323061aSAndrew Lunn case hwmon_curr_input: 10381323061aSAndrew Lunn return sfp_hwmon_read_bias(sfp, SFP_TX_BIAS, value); 10391323061aSAndrew Lunn 10401323061aSAndrew Lunn case hwmon_curr_lcrit: 10411323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.bias_low_alarm); 10421323061aSAndrew Lunn sfp_hwmon_calibrate_bias(sfp, value); 10431323061aSAndrew Lunn return 0; 10441323061aSAndrew Lunn 10451323061aSAndrew Lunn case hwmon_curr_min: 10461323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.bias_low_warn); 10471323061aSAndrew Lunn sfp_hwmon_calibrate_bias(sfp, value); 10481323061aSAndrew Lunn return 0; 10491323061aSAndrew Lunn 10501323061aSAndrew Lunn case hwmon_curr_max: 10511323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.bias_high_warn); 10521323061aSAndrew Lunn sfp_hwmon_calibrate_bias(sfp, value); 10531323061aSAndrew Lunn return 0; 10541323061aSAndrew Lunn 10551323061aSAndrew Lunn case hwmon_curr_crit: 10561323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.bias_high_alarm); 10571323061aSAndrew Lunn sfp_hwmon_calibrate_bias(sfp, value); 10581323061aSAndrew Lunn return 0; 10591323061aSAndrew Lunn 10601323061aSAndrew Lunn case hwmon_curr_lcrit_alarm: 10611323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_ALARM0, &status, sizeof(status)); 10621323061aSAndrew Lunn if (err < 0) 10631323061aSAndrew Lunn return err; 10641323061aSAndrew Lunn 10651323061aSAndrew Lunn *value = !!(status & SFP_ALARM0_TX_BIAS_LOW); 10661323061aSAndrew Lunn return 0; 10671323061aSAndrew Lunn 10681323061aSAndrew Lunn case hwmon_curr_min_alarm: 10691323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_WARN0, &status, sizeof(status)); 10701323061aSAndrew Lunn if (err < 0) 10711323061aSAndrew Lunn return err; 10721323061aSAndrew Lunn 10731323061aSAndrew Lunn *value = !!(status & SFP_WARN0_TX_BIAS_LOW); 10741323061aSAndrew Lunn return 0; 10751323061aSAndrew Lunn 10761323061aSAndrew Lunn case hwmon_curr_max_alarm: 10771323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_WARN0, &status, sizeof(status)); 10781323061aSAndrew Lunn if (err < 0) 10791323061aSAndrew Lunn return err; 10801323061aSAndrew Lunn 10811323061aSAndrew Lunn *value = !!(status & SFP_WARN0_TX_BIAS_HIGH); 10821323061aSAndrew Lunn return 0; 10831323061aSAndrew Lunn 10841323061aSAndrew Lunn case hwmon_curr_crit_alarm: 10851323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_ALARM0, &status, sizeof(status)); 10861323061aSAndrew Lunn if (err < 0) 10871323061aSAndrew Lunn return err; 10881323061aSAndrew Lunn 10891323061aSAndrew Lunn *value = !!(status & SFP_ALARM0_TX_BIAS_HIGH); 10901323061aSAndrew Lunn return 0; 10911323061aSAndrew Lunn default: 10921323061aSAndrew Lunn return -EOPNOTSUPP; 10931323061aSAndrew Lunn } 10941323061aSAndrew Lunn 10951323061aSAndrew Lunn return -EOPNOTSUPP; 10961323061aSAndrew Lunn } 10971323061aSAndrew Lunn 10981323061aSAndrew Lunn static int sfp_hwmon_tx_power(struct sfp *sfp, u32 attr, long *value) 10991323061aSAndrew Lunn { 11001323061aSAndrew Lunn u8 status; 11011323061aSAndrew Lunn int err; 11021323061aSAndrew Lunn 11031323061aSAndrew Lunn switch (attr) { 11041323061aSAndrew Lunn case hwmon_power_input: 11051323061aSAndrew Lunn return sfp_hwmon_read_tx_power(sfp, SFP_TX_POWER, value); 11061323061aSAndrew Lunn 11071323061aSAndrew Lunn case hwmon_power_lcrit: 11081323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.txpwr_low_alarm); 11091323061aSAndrew Lunn sfp_hwmon_calibrate_tx_power(sfp, value); 11101323061aSAndrew Lunn return 0; 11111323061aSAndrew Lunn 11121323061aSAndrew Lunn case hwmon_power_min: 11131323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.txpwr_low_warn); 11141323061aSAndrew Lunn sfp_hwmon_calibrate_tx_power(sfp, value); 11151323061aSAndrew Lunn return 0; 11161323061aSAndrew Lunn 11171323061aSAndrew Lunn case hwmon_power_max: 11181323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.txpwr_high_warn); 11191323061aSAndrew Lunn sfp_hwmon_calibrate_tx_power(sfp, value); 11201323061aSAndrew Lunn return 0; 11211323061aSAndrew Lunn 11221323061aSAndrew Lunn case hwmon_power_crit: 11231323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.txpwr_high_alarm); 11241323061aSAndrew Lunn sfp_hwmon_calibrate_tx_power(sfp, value); 11251323061aSAndrew Lunn return 0; 11261323061aSAndrew Lunn 11271323061aSAndrew Lunn case hwmon_power_lcrit_alarm: 11281323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_ALARM0, &status, sizeof(status)); 11291323061aSAndrew Lunn if (err < 0) 11301323061aSAndrew Lunn return err; 11311323061aSAndrew Lunn 11321323061aSAndrew Lunn *value = !!(status & SFP_ALARM0_TXPWR_LOW); 11331323061aSAndrew Lunn return 0; 11341323061aSAndrew Lunn 11351323061aSAndrew Lunn case hwmon_power_min_alarm: 11361323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_WARN0, &status, sizeof(status)); 11371323061aSAndrew Lunn if (err < 0) 11381323061aSAndrew Lunn return err; 11391323061aSAndrew Lunn 11401323061aSAndrew Lunn *value = !!(status & SFP_WARN0_TXPWR_LOW); 11411323061aSAndrew Lunn return 0; 11421323061aSAndrew Lunn 11431323061aSAndrew Lunn case hwmon_power_max_alarm: 11441323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_WARN0, &status, sizeof(status)); 11451323061aSAndrew Lunn if (err < 0) 11461323061aSAndrew Lunn return err; 11471323061aSAndrew Lunn 11481323061aSAndrew Lunn *value = !!(status & SFP_WARN0_TXPWR_HIGH); 11491323061aSAndrew Lunn return 0; 11501323061aSAndrew Lunn 11511323061aSAndrew Lunn case hwmon_power_crit_alarm: 11521323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_ALARM0, &status, sizeof(status)); 11531323061aSAndrew Lunn if (err < 0) 11541323061aSAndrew Lunn return err; 11551323061aSAndrew Lunn 11561323061aSAndrew Lunn *value = !!(status & SFP_ALARM0_TXPWR_HIGH); 11571323061aSAndrew Lunn return 0; 11581323061aSAndrew Lunn default: 11591323061aSAndrew Lunn return -EOPNOTSUPP; 11601323061aSAndrew Lunn } 11611323061aSAndrew Lunn 11621323061aSAndrew Lunn return -EOPNOTSUPP; 11631323061aSAndrew Lunn } 11641323061aSAndrew Lunn 11651323061aSAndrew Lunn static int sfp_hwmon_rx_power(struct sfp *sfp, u32 attr, long *value) 11661323061aSAndrew Lunn { 11671323061aSAndrew Lunn u8 status; 11681323061aSAndrew Lunn int err; 11691323061aSAndrew Lunn 11701323061aSAndrew Lunn switch (attr) { 11711323061aSAndrew Lunn case hwmon_power_input: 11721323061aSAndrew Lunn return sfp_hwmon_read_rx_power(sfp, SFP_RX_POWER, value); 11731323061aSAndrew Lunn 11741323061aSAndrew Lunn case hwmon_power_lcrit: 11751323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.rxpwr_low_alarm); 11761323061aSAndrew Lunn sfp_hwmon_to_rx_power(value); 11771323061aSAndrew Lunn return 0; 11781323061aSAndrew Lunn 11791323061aSAndrew Lunn case hwmon_power_min: 11801323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.rxpwr_low_warn); 11811323061aSAndrew Lunn sfp_hwmon_to_rx_power(value); 11821323061aSAndrew Lunn return 0; 11831323061aSAndrew Lunn 11841323061aSAndrew Lunn case hwmon_power_max: 11851323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.rxpwr_high_warn); 11861323061aSAndrew Lunn sfp_hwmon_to_rx_power(value); 11871323061aSAndrew Lunn return 0; 11881323061aSAndrew Lunn 11891323061aSAndrew Lunn case hwmon_power_crit: 11901323061aSAndrew Lunn *value = be16_to_cpu(sfp->diag.rxpwr_high_alarm); 11911323061aSAndrew Lunn sfp_hwmon_to_rx_power(value); 11921323061aSAndrew Lunn return 0; 11931323061aSAndrew Lunn 11941323061aSAndrew Lunn case hwmon_power_lcrit_alarm: 11951323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_ALARM1, &status, sizeof(status)); 11961323061aSAndrew Lunn if (err < 0) 11971323061aSAndrew Lunn return err; 11981323061aSAndrew Lunn 11991323061aSAndrew Lunn *value = !!(status & SFP_ALARM1_RXPWR_LOW); 12001323061aSAndrew Lunn return 0; 12011323061aSAndrew Lunn 12021323061aSAndrew Lunn case hwmon_power_min_alarm: 12031323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_WARN1, &status, sizeof(status)); 12041323061aSAndrew Lunn if (err < 0) 12051323061aSAndrew Lunn return err; 12061323061aSAndrew Lunn 12071323061aSAndrew Lunn *value = !!(status & SFP_WARN1_RXPWR_LOW); 12081323061aSAndrew Lunn return 0; 12091323061aSAndrew Lunn 12101323061aSAndrew Lunn case hwmon_power_max_alarm: 12111323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_WARN1, &status, sizeof(status)); 12121323061aSAndrew Lunn if (err < 0) 12131323061aSAndrew Lunn return err; 12141323061aSAndrew Lunn 12151323061aSAndrew Lunn *value = !!(status & SFP_WARN1_RXPWR_HIGH); 12161323061aSAndrew Lunn return 0; 12171323061aSAndrew Lunn 12181323061aSAndrew Lunn case hwmon_power_crit_alarm: 12191323061aSAndrew Lunn err = sfp_read(sfp, true, SFP_ALARM1, &status, sizeof(status)); 12201323061aSAndrew Lunn if (err < 0) 12211323061aSAndrew Lunn return err; 12221323061aSAndrew Lunn 12231323061aSAndrew Lunn *value = !!(status & SFP_ALARM1_RXPWR_HIGH); 12241323061aSAndrew Lunn return 0; 12251323061aSAndrew Lunn default: 12261323061aSAndrew Lunn return -EOPNOTSUPP; 12271323061aSAndrew Lunn } 12281323061aSAndrew Lunn 12291323061aSAndrew Lunn return -EOPNOTSUPP; 12301323061aSAndrew Lunn } 12311323061aSAndrew Lunn 12321323061aSAndrew Lunn static int sfp_hwmon_read(struct device *dev, enum hwmon_sensor_types type, 12331323061aSAndrew Lunn u32 attr, int channel, long *value) 12341323061aSAndrew Lunn { 12351323061aSAndrew Lunn struct sfp *sfp = dev_get_drvdata(dev); 12361323061aSAndrew Lunn 12371323061aSAndrew Lunn switch (type) { 12381323061aSAndrew Lunn case hwmon_temp: 12391323061aSAndrew Lunn return sfp_hwmon_temp(sfp, attr, value); 12401323061aSAndrew Lunn case hwmon_in: 12411323061aSAndrew Lunn return sfp_hwmon_vcc(sfp, attr, value); 12421323061aSAndrew Lunn case hwmon_curr: 12431323061aSAndrew Lunn return sfp_hwmon_bias(sfp, attr, value); 12441323061aSAndrew Lunn case hwmon_power: 12451323061aSAndrew Lunn switch (channel) { 12461323061aSAndrew Lunn case 0: 12471323061aSAndrew Lunn return sfp_hwmon_tx_power(sfp, attr, value); 12481323061aSAndrew Lunn case 1: 12491323061aSAndrew Lunn return sfp_hwmon_rx_power(sfp, attr, value); 12501323061aSAndrew Lunn default: 12511323061aSAndrew Lunn return -EOPNOTSUPP; 12521323061aSAndrew Lunn } 12531323061aSAndrew Lunn default: 12541323061aSAndrew Lunn return -EOPNOTSUPP; 12551323061aSAndrew Lunn } 12561323061aSAndrew Lunn } 12571323061aSAndrew Lunn 1258c1236979SAndrew Lunn static const char *const sfp_hwmon_power_labels[] = { 1259c1236979SAndrew Lunn "TX_power", 1260c1236979SAndrew Lunn "RX_power", 1261c1236979SAndrew Lunn }; 1262c1236979SAndrew Lunn 1263c1236979SAndrew Lunn static int sfp_hwmon_read_string(struct device *dev, 1264c1236979SAndrew Lunn enum hwmon_sensor_types type, 1265c1236979SAndrew Lunn u32 attr, int channel, const char **str) 1266c1236979SAndrew Lunn { 1267c1236979SAndrew Lunn switch (type) { 1268c1236979SAndrew Lunn case hwmon_curr: 1269c1236979SAndrew Lunn switch (attr) { 1270c1236979SAndrew Lunn case hwmon_curr_label: 1271c1236979SAndrew Lunn *str = "bias"; 1272c1236979SAndrew Lunn return 0; 1273c1236979SAndrew Lunn default: 1274c1236979SAndrew Lunn return -EOPNOTSUPP; 1275c1236979SAndrew Lunn } 1276c1236979SAndrew Lunn break; 1277c1236979SAndrew Lunn case hwmon_temp: 1278c1236979SAndrew Lunn switch (attr) { 1279c1236979SAndrew Lunn case hwmon_temp_label: 1280c1236979SAndrew Lunn *str = "temperature"; 1281c1236979SAndrew Lunn return 0; 1282c1236979SAndrew Lunn default: 1283c1236979SAndrew Lunn return -EOPNOTSUPP; 1284c1236979SAndrew Lunn } 1285c1236979SAndrew Lunn break; 1286c1236979SAndrew Lunn case hwmon_in: 1287c1236979SAndrew Lunn switch (attr) { 1288c1236979SAndrew Lunn case hwmon_in_label: 1289c1236979SAndrew Lunn *str = "VCC"; 1290c1236979SAndrew Lunn return 0; 1291c1236979SAndrew Lunn default: 1292c1236979SAndrew Lunn return -EOPNOTSUPP; 1293c1236979SAndrew Lunn } 1294c1236979SAndrew Lunn break; 1295c1236979SAndrew Lunn case hwmon_power: 1296c1236979SAndrew Lunn switch (attr) { 1297c1236979SAndrew Lunn case hwmon_power_label: 1298c1236979SAndrew Lunn *str = sfp_hwmon_power_labels[channel]; 1299c1236979SAndrew Lunn return 0; 1300c1236979SAndrew Lunn default: 1301c1236979SAndrew Lunn return -EOPNOTSUPP; 1302c1236979SAndrew Lunn } 1303c1236979SAndrew Lunn break; 1304c1236979SAndrew Lunn default: 1305c1236979SAndrew Lunn return -EOPNOTSUPP; 1306c1236979SAndrew Lunn } 1307c1236979SAndrew Lunn 1308c1236979SAndrew Lunn return -EOPNOTSUPP; 1309c1236979SAndrew Lunn } 1310c1236979SAndrew Lunn 13111323061aSAndrew Lunn static const struct hwmon_ops sfp_hwmon_ops = { 13121323061aSAndrew Lunn .is_visible = sfp_hwmon_is_visible, 13131323061aSAndrew Lunn .read = sfp_hwmon_read, 1314c1236979SAndrew Lunn .read_string = sfp_hwmon_read_string, 13151323061aSAndrew Lunn }; 13161323061aSAndrew Lunn 1317815f5f57SBeniamin Sandu static const struct hwmon_channel_info *sfp_hwmon_info[] = { 1318815f5f57SBeniamin Sandu HWMON_CHANNEL_INFO(chip, 1319815f5f57SBeniamin Sandu HWMON_C_REGISTER_TZ), 1320815f5f57SBeniamin Sandu HWMON_CHANNEL_INFO(in, 13211323061aSAndrew Lunn HWMON_I_INPUT | 13221323061aSAndrew Lunn HWMON_I_MAX | HWMON_I_MIN | 13231323061aSAndrew Lunn HWMON_I_MAX_ALARM | HWMON_I_MIN_ALARM | 13241323061aSAndrew Lunn HWMON_I_CRIT | HWMON_I_LCRIT | 1325c1236979SAndrew Lunn HWMON_I_CRIT_ALARM | HWMON_I_LCRIT_ALARM | 1326815f5f57SBeniamin Sandu HWMON_I_LABEL), 1327815f5f57SBeniamin Sandu HWMON_CHANNEL_INFO(temp, 1328815f5f57SBeniamin Sandu HWMON_T_INPUT | 1329815f5f57SBeniamin Sandu HWMON_T_MAX | HWMON_T_MIN | 1330815f5f57SBeniamin Sandu HWMON_T_MAX_ALARM | HWMON_T_MIN_ALARM | 1331815f5f57SBeniamin Sandu HWMON_T_CRIT | HWMON_T_LCRIT | 1332815f5f57SBeniamin Sandu HWMON_T_CRIT_ALARM | HWMON_T_LCRIT_ALARM | 1333815f5f57SBeniamin Sandu HWMON_T_LABEL), 1334815f5f57SBeniamin Sandu HWMON_CHANNEL_INFO(curr, 13351323061aSAndrew Lunn HWMON_C_INPUT | 13361323061aSAndrew Lunn HWMON_C_MAX | HWMON_C_MIN | 13371323061aSAndrew Lunn HWMON_C_MAX_ALARM | HWMON_C_MIN_ALARM | 13381323061aSAndrew Lunn HWMON_C_CRIT | HWMON_C_LCRIT | 1339c1236979SAndrew Lunn HWMON_C_CRIT_ALARM | HWMON_C_LCRIT_ALARM | 1340815f5f57SBeniamin Sandu HWMON_C_LABEL), 1341815f5f57SBeniamin Sandu HWMON_CHANNEL_INFO(power, 13421323061aSAndrew Lunn /* Transmit power */ 13431323061aSAndrew Lunn HWMON_P_INPUT | 13441323061aSAndrew Lunn HWMON_P_MAX | HWMON_P_MIN | 13451323061aSAndrew Lunn HWMON_P_MAX_ALARM | HWMON_P_MIN_ALARM | 13461323061aSAndrew Lunn HWMON_P_CRIT | HWMON_P_LCRIT | 1347c1236979SAndrew Lunn HWMON_P_CRIT_ALARM | HWMON_P_LCRIT_ALARM | 1348c1236979SAndrew Lunn HWMON_P_LABEL, 13491323061aSAndrew Lunn /* Receive power */ 13501323061aSAndrew Lunn HWMON_P_INPUT | 13511323061aSAndrew Lunn HWMON_P_MAX | HWMON_P_MIN | 13521323061aSAndrew Lunn HWMON_P_MAX_ALARM | HWMON_P_MIN_ALARM | 13531323061aSAndrew Lunn HWMON_P_CRIT | HWMON_P_LCRIT | 1354c1236979SAndrew Lunn HWMON_P_CRIT_ALARM | HWMON_P_LCRIT_ALARM | 1355815f5f57SBeniamin Sandu HWMON_P_LABEL), 13561323061aSAndrew Lunn NULL, 13571323061aSAndrew Lunn }; 13581323061aSAndrew Lunn 13591323061aSAndrew Lunn static const struct hwmon_chip_info sfp_hwmon_chip_info = { 13601323061aSAndrew Lunn .ops = &sfp_hwmon_ops, 13611323061aSAndrew Lunn .info = sfp_hwmon_info, 13621323061aSAndrew Lunn }; 13631323061aSAndrew Lunn 1364139d3a21SRussell King static void sfp_hwmon_probe(struct work_struct *work) 13651323061aSAndrew Lunn { 1366139d3a21SRussell King struct sfp *sfp = container_of(work, struct sfp, hwmon_probe.work); 13673f118c44SMichael Walle int err; 13681323061aSAndrew Lunn 1369426c6cbcSPali Rohár /* hwmon interface needs to access 16bit registers in atomic way to 1370426c6cbcSPali Rohár * guarantee coherency of the diagnostic monitoring data. If it is not 1371426c6cbcSPali Rohár * possible to guarantee coherency because EEPROM is broken in such way 1372426c6cbcSPali Rohár * that does not support atomic 16bit read operation then we have to 1373426c6cbcSPali Rohár * skip registration of hwmon device. 1374426c6cbcSPali Rohár */ 1375426c6cbcSPali Rohár if (sfp->i2c_block_size < 2) { 1376426c6cbcSPali Rohár dev_info(sfp->dev, 1377426c6cbcSPali Rohár "skipping hwmon device registration due to broken EEPROM\n"); 1378426c6cbcSPali Rohár dev_info(sfp->dev, 1379426c6cbcSPali Rohár "diagnostic EEPROM area cannot be read atomically to guarantee data coherency\n"); 1380426c6cbcSPali Rohár return; 1381426c6cbcSPali Rohár } 1382426c6cbcSPali Rohár 1383139d3a21SRussell King err = sfp_read(sfp, true, 0, &sfp->diag, sizeof(sfp->diag)); 1384139d3a21SRussell King if (err < 0) { 1385139d3a21SRussell King if (sfp->hwmon_tries--) { 1386139d3a21SRussell King mod_delayed_work(system_wq, &sfp->hwmon_probe, 1387139d3a21SRussell King T_PROBE_RETRY_SLOW); 1388139d3a21SRussell King } else { 13899ae1ef4bSRussell King (Oracle) dev_warn(sfp->dev, "hwmon probe failed: %pe\n", 13909ae1ef4bSRussell King (Oracle) ERR_PTR(err)); 1391139d3a21SRussell King } 1392139d3a21SRussell King return; 1393139d3a21SRussell King } 1394139d3a21SRussell King 13953f118c44SMichael Walle sfp->hwmon_name = hwmon_sanitize_name(dev_name(sfp->dev)); 13963f118c44SMichael Walle if (IS_ERR(sfp->hwmon_name)) { 1397139d3a21SRussell King dev_err(sfp->dev, "out of memory for hwmon name\n"); 1398139d3a21SRussell King return; 1399139d3a21SRussell King } 1400139d3a21SRussell King 1401139d3a21SRussell King sfp->hwmon_dev = hwmon_device_register_with_info(sfp->dev, 1402139d3a21SRussell King sfp->hwmon_name, sfp, 1403139d3a21SRussell King &sfp_hwmon_chip_info, 1404139d3a21SRussell King NULL); 1405139d3a21SRussell King if (IS_ERR(sfp->hwmon_dev)) 1406139d3a21SRussell King dev_err(sfp->dev, "failed to register hwmon device: %ld\n", 1407139d3a21SRussell King PTR_ERR(sfp->hwmon_dev)); 1408139d3a21SRussell King } 1409139d3a21SRussell King 1410139d3a21SRussell King static int sfp_hwmon_insert(struct sfp *sfp) 1411139d3a21SRussell King { 14121323061aSAndrew Lunn if (sfp->id.ext.sff8472_compliance == SFP_SFF8472_COMPLIANCE_NONE) 14131323061aSAndrew Lunn return 0; 14141323061aSAndrew Lunn 14151323061aSAndrew Lunn if (!(sfp->id.ext.diagmon & SFP_DIAGMON_DDM)) 14161323061aSAndrew Lunn return 0; 14171323061aSAndrew Lunn 14181323061aSAndrew Lunn if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE) 14191323061aSAndrew Lunn /* This driver in general does not support address 14201323061aSAndrew Lunn * change. 14211323061aSAndrew Lunn */ 14221323061aSAndrew Lunn return 0; 14231323061aSAndrew Lunn 1424139d3a21SRussell King mod_delayed_work(system_wq, &sfp->hwmon_probe, 1); 1425139d3a21SRussell King sfp->hwmon_tries = R_PROBE_RETRY_SLOW; 14261323061aSAndrew Lunn 1427139d3a21SRussell King return 0; 14281323061aSAndrew Lunn } 14291323061aSAndrew Lunn 14301323061aSAndrew Lunn static void sfp_hwmon_remove(struct sfp *sfp) 14311323061aSAndrew Lunn { 1432139d3a21SRussell King cancel_delayed_work_sync(&sfp->hwmon_probe); 14333e322474SAndrew Lunn if (!IS_ERR_OR_NULL(sfp->hwmon_dev)) { 14341323061aSAndrew Lunn hwmon_device_unregister(sfp->hwmon_dev); 14353e322474SAndrew Lunn sfp->hwmon_dev = NULL; 14361323061aSAndrew Lunn kfree(sfp->hwmon_name); 14371323061aSAndrew Lunn } 14383e322474SAndrew Lunn } 1439139d3a21SRussell King 1440139d3a21SRussell King static int sfp_hwmon_init(struct sfp *sfp) 1441139d3a21SRussell King { 1442139d3a21SRussell King INIT_DELAYED_WORK(&sfp->hwmon_probe, sfp_hwmon_probe); 1443139d3a21SRussell King 1444139d3a21SRussell King return 0; 1445139d3a21SRussell King } 1446139d3a21SRussell King 1447139d3a21SRussell King static void sfp_hwmon_exit(struct sfp *sfp) 1448139d3a21SRussell King { 1449139d3a21SRussell King cancel_delayed_work_sync(&sfp->hwmon_probe); 1450139d3a21SRussell King } 14511323061aSAndrew Lunn #else 14521323061aSAndrew Lunn static int sfp_hwmon_insert(struct sfp *sfp) 14531323061aSAndrew Lunn { 14541323061aSAndrew Lunn return 0; 14551323061aSAndrew Lunn } 14561323061aSAndrew Lunn 14571323061aSAndrew Lunn static void sfp_hwmon_remove(struct sfp *sfp) 14581323061aSAndrew Lunn { 14591323061aSAndrew Lunn } 1460139d3a21SRussell King 1461139d3a21SRussell King static int sfp_hwmon_init(struct sfp *sfp) 1462139d3a21SRussell King { 1463139d3a21SRussell King return 0; 1464139d3a21SRussell King } 1465139d3a21SRussell King 1466139d3a21SRussell King static void sfp_hwmon_exit(struct sfp *sfp) 1467139d3a21SRussell King { 1468139d3a21SRussell King } 14691323061aSAndrew Lunn #endif 14701323061aSAndrew Lunn 147173970055SRussell King /* Helpers */ 147273970055SRussell King static void sfp_module_tx_disable(struct sfp *sfp) 147373970055SRussell King { 147473970055SRussell King dev_dbg(sfp->dev, "tx disable %u -> %u\n", 147573970055SRussell King sfp->state & SFP_F_TX_DISABLE ? 1 : 0, 1); 147673970055SRussell King sfp->state |= SFP_F_TX_DISABLE; 147773970055SRussell King sfp_set_state(sfp, sfp->state); 147873970055SRussell King } 147973970055SRussell King 148073970055SRussell King static void sfp_module_tx_enable(struct sfp *sfp) 148173970055SRussell King { 148273970055SRussell King dev_dbg(sfp->dev, "tx disable %u -> %u\n", 148373970055SRussell King sfp->state & SFP_F_TX_DISABLE ? 1 : 0, 0); 148473970055SRussell King sfp->state &= ~SFP_F_TX_DISABLE; 148573970055SRussell King sfp_set_state(sfp, sfp->state); 148673970055SRussell King } 148773970055SRussell King 14889cc8976cSRussell King #if IS_ENABLED(CONFIG_DEBUG_FS) 14899cc8976cSRussell King static int sfp_debug_state_show(struct seq_file *s, void *data) 14909cc8976cSRussell King { 14919cc8976cSRussell King struct sfp *sfp = s->private; 14929cc8976cSRussell King 14939cc8976cSRussell King seq_printf(s, "Module state: %s\n", 14949cc8976cSRussell King mod_state_to_str(sfp->sm_mod_state)); 14959cc8976cSRussell King seq_printf(s, "Module probe attempts: %d %d\n", 14969cc8976cSRussell King R_PROBE_RETRY_INIT - sfp->sm_mod_tries_init, 14979cc8976cSRussell King R_PROBE_RETRY_SLOW - sfp->sm_mod_tries); 14989cc8976cSRussell King seq_printf(s, "Device state: %s\n", 14999cc8976cSRussell King dev_state_to_str(sfp->sm_dev_state)); 15009cc8976cSRussell King seq_printf(s, "Main state: %s\n", 15019cc8976cSRussell King sm_state_to_str(sfp->sm_state)); 15029cc8976cSRussell King seq_printf(s, "Fault recovery remaining retries: %d\n", 15039cc8976cSRussell King sfp->sm_fault_retries); 15049cc8976cSRussell King seq_printf(s, "PHY probe remaining retries: %d\n", 15059cc8976cSRussell King sfp->sm_phy_retries); 15069cc8976cSRussell King seq_printf(s, "moddef0: %d\n", !!(sfp->state & SFP_F_PRESENT)); 15079cc8976cSRussell King seq_printf(s, "rx_los: %d\n", !!(sfp->state & SFP_F_LOS)); 15089cc8976cSRussell King seq_printf(s, "tx_fault: %d\n", !!(sfp->state & SFP_F_TX_FAULT)); 15099cc8976cSRussell King seq_printf(s, "tx_disable: %d\n", !!(sfp->state & SFP_F_TX_DISABLE)); 15109cc8976cSRussell King return 0; 15119cc8976cSRussell King } 15129cc8976cSRussell King DEFINE_SHOW_ATTRIBUTE(sfp_debug_state); 15139cc8976cSRussell King 15149cc8976cSRussell King static void sfp_debugfs_init(struct sfp *sfp) 15159cc8976cSRussell King { 15169cc8976cSRussell King sfp->debugfs_dir = debugfs_create_dir(dev_name(sfp->dev), NULL); 15179cc8976cSRussell King 15189cc8976cSRussell King debugfs_create_file("state", 0600, sfp->debugfs_dir, sfp, 15199cc8976cSRussell King &sfp_debug_state_fops); 15209cc8976cSRussell King } 15219cc8976cSRussell King 15229cc8976cSRussell King static void sfp_debugfs_exit(struct sfp *sfp) 15239cc8976cSRussell King { 15249cc8976cSRussell King debugfs_remove_recursive(sfp->debugfs_dir); 15259cc8976cSRussell King } 15269cc8976cSRussell King #else 15279cc8976cSRussell King static void sfp_debugfs_init(struct sfp *sfp) 15289cc8976cSRussell King { 15299cc8976cSRussell King } 15309cc8976cSRussell King 15319cc8976cSRussell King static void sfp_debugfs_exit(struct sfp *sfp) 15329cc8976cSRussell King { 15339cc8976cSRussell King } 15349cc8976cSRussell King #endif 15359cc8976cSRussell King 153673970055SRussell King static void sfp_module_tx_fault_reset(struct sfp *sfp) 153773970055SRussell King { 153873970055SRussell King unsigned int state = sfp->state; 153973970055SRussell King 154073970055SRussell King if (state & SFP_F_TX_DISABLE) 154173970055SRussell King return; 154273970055SRussell King 154373970055SRussell King sfp_set_state(sfp, state | SFP_F_TX_DISABLE); 154473970055SRussell King 154573970055SRussell King udelay(T_RESET_US); 154673970055SRussell King 154773970055SRussell King sfp_set_state(sfp, state); 154873970055SRussell King } 154973970055SRussell King 155073970055SRussell King /* SFP state machine */ 155173970055SRussell King static void sfp_sm_set_timer(struct sfp *sfp, unsigned int timeout) 155273970055SRussell King { 155373970055SRussell King if (timeout) 155473970055SRussell King mod_delayed_work(system_power_efficient_wq, &sfp->timeout, 155573970055SRussell King timeout); 155673970055SRussell King else 155773970055SRussell King cancel_delayed_work(&sfp->timeout); 155873970055SRussell King } 155973970055SRussell King 156073970055SRussell King static void sfp_sm_next(struct sfp *sfp, unsigned int state, 156173970055SRussell King unsigned int timeout) 156273970055SRussell King { 156373970055SRussell King sfp->sm_state = state; 156473970055SRussell King sfp_sm_set_timer(sfp, timeout); 156573970055SRussell King } 156673970055SRussell King 15670936ebc4SRussell King static void sfp_sm_mod_next(struct sfp *sfp, unsigned int state, 1568516b29edSFlorian Fainelli unsigned int timeout) 156973970055SRussell King { 157073970055SRussell King sfp->sm_mod_state = state; 157173970055SRussell King sfp_sm_set_timer(sfp, timeout); 157273970055SRussell King } 157373970055SRussell King 157473970055SRussell King static void sfp_sm_phy_detach(struct sfp *sfp) 157573970055SRussell King { 157673970055SRussell King sfp_remove_phy(sfp->sfp_bus); 157773970055SRussell King phy_device_remove(sfp->mod_phy); 157873970055SRussell King phy_device_free(sfp->mod_phy); 157973970055SRussell King sfp->mod_phy = NULL; 158073970055SRussell King } 158173970055SRussell King 1582256e43cbSRussell King static int sfp_sm_probe_phy(struct sfp *sfp, bool is_c45) 158373970055SRussell King { 158473970055SRussell King struct phy_device *phy; 158573970055SRussell King int err; 158673970055SRussell King 15879a484621SRussell King phy = get_phy_device(sfp->i2c_mii, SFP_PHY_ADDR, is_c45); 15881cb89a14SRussell King if (phy == ERR_PTR(-ENODEV)) 15891cb89a14SRussell King return PTR_ERR(phy); 159020b56ed9SRussell King if (IS_ERR(phy)) { 15919ae1ef4bSRussell King (Oracle) dev_err(sfp->dev, "mdiobus scan returned %pe\n", phy); 1592256e43cbSRussell King return PTR_ERR(phy); 159373970055SRussell King } 159473970055SRussell King 15959a484621SRussell King err = phy_device_register(phy); 15969a484621SRussell King if (err) { 15979a484621SRussell King phy_device_free(phy); 15989ae1ef4bSRussell King (Oracle) dev_err(sfp->dev, "phy_device_register failed: %pe\n", 15999ae1ef4bSRussell King (Oracle) ERR_PTR(err)); 1600256e43cbSRussell King return err; 16019a484621SRussell King } 16029a484621SRussell King 160373970055SRussell King err = sfp_add_phy(sfp->sfp_bus, phy); 160473970055SRussell King if (err) { 160573970055SRussell King phy_device_remove(phy); 160673970055SRussell King phy_device_free(phy); 16079ae1ef4bSRussell King (Oracle) dev_err(sfp->dev, "sfp_add_phy failed: %pe\n", ERR_PTR(err)); 1608256e43cbSRussell King return err; 160973970055SRussell King } 161073970055SRussell King 161173970055SRussell King sfp->mod_phy = phy; 1612256e43cbSRussell King 1613256e43cbSRussell King return 0; 161473970055SRussell King } 161573970055SRussell King 161673970055SRussell King static void sfp_sm_link_up(struct sfp *sfp) 161773970055SRussell King { 161873970055SRussell King sfp_link_up(sfp->sfp_bus); 161973970055SRussell King sfp_sm_next(sfp, SFP_S_LINK_UP, 0); 162073970055SRussell King } 162173970055SRussell King 162273970055SRussell King static void sfp_sm_link_down(struct sfp *sfp) 162373970055SRussell King { 162473970055SRussell King sfp_link_down(sfp->sfp_bus); 162573970055SRussell King } 162673970055SRussell King 162773970055SRussell King static void sfp_sm_link_check_los(struct sfp *sfp) 162873970055SRussell King { 1629624407d2SRussell King const __be16 los_inverted = cpu_to_be16(SFP_OPTIONS_LOS_INVERTED); 1630624407d2SRussell King const __be16 los_normal = cpu_to_be16(SFP_OPTIONS_LOS_NORMAL); 1631624407d2SRussell King __be16 los_options = sfp->id.ext.options & (los_inverted | los_normal); 1632624407d2SRussell King bool los = false; 163373970055SRussell King 1634710dfbb0SRussell King /* If neither SFP_OPTIONS_LOS_INVERTED nor SFP_OPTIONS_LOS_NORMAL 1635624407d2SRussell King * are set, we assume that no LOS signal is available. If both are 1636624407d2SRussell King * set, we assume LOS is not implemented (and is meaningless.) 163773970055SRussell King */ 1638624407d2SRussell King if (los_options == los_inverted) 1639624407d2SRussell King los = !(sfp->state & SFP_F_LOS); 1640624407d2SRussell King else if (los_options == los_normal) 1641624407d2SRussell King los = !!(sfp->state & SFP_F_LOS); 164273970055SRussell King 164373970055SRussell King if (los) 164473970055SRussell King sfp_sm_next(sfp, SFP_S_WAIT_LOS, 0); 164573970055SRussell King else 164673970055SRussell King sfp_sm_link_up(sfp); 164773970055SRussell King } 164873970055SRussell King 1649710dfbb0SRussell King static bool sfp_los_event_active(struct sfp *sfp, unsigned int event) 1650710dfbb0SRussell King { 1651624407d2SRussell King const __be16 los_inverted = cpu_to_be16(SFP_OPTIONS_LOS_INVERTED); 1652624407d2SRussell King const __be16 los_normal = cpu_to_be16(SFP_OPTIONS_LOS_NORMAL); 1653624407d2SRussell King __be16 los_options = sfp->id.ext.options & (los_inverted | los_normal); 1654624407d2SRussell King 1655624407d2SRussell King return (los_options == los_inverted && event == SFP_E_LOS_LOW) || 1656624407d2SRussell King (los_options == los_normal && event == SFP_E_LOS_HIGH); 1657710dfbb0SRussell King } 1658710dfbb0SRussell King 1659710dfbb0SRussell King static bool sfp_los_event_inactive(struct sfp *sfp, unsigned int event) 1660710dfbb0SRussell King { 1661624407d2SRussell King const __be16 los_inverted = cpu_to_be16(SFP_OPTIONS_LOS_INVERTED); 1662624407d2SRussell King const __be16 los_normal = cpu_to_be16(SFP_OPTIONS_LOS_NORMAL); 1663624407d2SRussell King __be16 los_options = sfp->id.ext.options & (los_inverted | los_normal); 1664624407d2SRussell King 1665624407d2SRussell King return (los_options == los_inverted && event == SFP_E_LOS_HIGH) || 1666624407d2SRussell King (los_options == los_normal && event == SFP_E_LOS_LOW); 1667710dfbb0SRussell King } 1668710dfbb0SRussell King 166963ec1c7cSRussell King static void sfp_sm_fault(struct sfp *sfp, unsigned int next_state, bool warn) 167073970055SRussell King { 1671281e4eabSRussell King if (sfp->sm_fault_retries && !--sfp->sm_fault_retries) { 1672516b29edSFlorian Fainelli dev_err(sfp->dev, 1673516b29edSFlorian Fainelli "module persistently indicates fault, disabling\n"); 167473970055SRussell King sfp_sm_next(sfp, SFP_S_TX_DISABLE, 0); 167573970055SRussell King } else { 167673970055SRussell King if (warn) 167773970055SRussell King dev_err(sfp->dev, "module transmit fault indicated\n"); 167873970055SRussell King 167963ec1c7cSRussell King sfp_sm_next(sfp, next_state, T_FAULT_RECOVER); 168073970055SRussell King } 168173970055SRussell King } 168273970055SRussell King 16839a484621SRussell King /* Probe a SFP for a PHY device if the module supports copper - the PHY 16849a484621SRussell King * normally sits at I2C bus address 0x56, and may either be a clause 22 16859a484621SRussell King * or clause 45 PHY. 16869a484621SRussell King * 16879a484621SRussell King * Clause 22 copper SFP modules normally operate in Cisco SGMII mode with 16889a484621SRussell King * negotiation enabled, but some may be in 1000base-X - which is for the 16899a484621SRussell King * PHY driver to determine. 16909a484621SRussell King * 16919a484621SRussell King * Clause 45 copper SFP+ modules (10G) appear to switch their interface 16929a484621SRussell King * mode according to the negotiated line speed. 16939a484621SRussell King */ 1694256e43cbSRussell King static int sfp_sm_probe_for_phy(struct sfp *sfp) 1695181f29daSRussell King { 1696256e43cbSRussell King int err = 0; 1697256e43cbSRussell King 16989a484621SRussell King switch (sfp->id.base.extended_cc) { 16999a484621SRussell King case SFF8024_ECC_10GBASE_T_SFI: 17009a484621SRussell King case SFF8024_ECC_10GBASE_T_SR: 17019a484621SRussell King case SFF8024_ECC_5GBASE_T: 17029a484621SRussell King case SFF8024_ECC_2_5GBASE_T: 1703256e43cbSRussell King err = sfp_sm_probe_phy(sfp, true); 17049a484621SRussell King break; 17059a484621SRussell King 17069a484621SRussell King default: 1707fa2de660SRussell King if (sfp->id.base.e1000_base_t) 1708256e43cbSRussell King err = sfp_sm_probe_phy(sfp, false); 17099a484621SRussell King break; 17109a484621SRussell King } 1711256e43cbSRussell King return err; 171273970055SRussell King } 171373970055SRussell King 1714ed32abb1SRussell King static int sfp_module_parse_power(struct sfp *sfp) 17153bb35261SJon Nettleton { 1716ed32abb1SRussell King u32 power_mW = 1000; 17175765cee1SRussell King (Oracle) bool supports_a2; 17183bb35261SJon Nettleton 17193bb35261SJon Nettleton if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_POWER_DECL)) 1720ed32abb1SRussell King power_mW = 1500; 17213bb35261SJon Nettleton if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_HIGH_POWER_LEVEL)) 1722ed32abb1SRussell King power_mW = 2000; 17233bb35261SJon Nettleton 17245765cee1SRussell King (Oracle) supports_a2 = sfp->id.ext.sff8472_compliance != 17255765cee1SRussell King (Oracle) SFP_SFF8472_COMPLIANCE_NONE || 17265765cee1SRussell King (Oracle) sfp->id.ext.diagmon & SFP_DIAGMON_DDM; 17275765cee1SRussell King (Oracle) 1728ed32abb1SRussell King if (power_mW > sfp->max_power_mW) { 17297cfa9c92SRussell King /* Module power specification exceeds the allowed maximum. */ 17305765cee1SRussell King (Oracle) if (!supports_a2) { 17317cfa9c92SRussell King /* The module appears not to implement bus address 17327cfa9c92SRussell King * 0xa2, so assume that the module powers up in the 17337cfa9c92SRussell King * indicated mode. 17347cfa9c92SRussell King */ 17353bb35261SJon Nettleton dev_err(sfp->dev, 17363bb35261SJon Nettleton "Host does not support %u.%uW modules\n", 1737ed32abb1SRussell King power_mW / 1000, (power_mW / 100) % 10); 17383bb35261SJon Nettleton return -EINVAL; 17397cfa9c92SRussell King } else { 17403bb35261SJon Nettleton dev_warn(sfp->dev, 17413bb35261SJon Nettleton "Host does not support %u.%uW modules, module left in power mode 1\n", 1742ed32abb1SRussell King power_mW / 1000, (power_mW / 100) % 10); 17433bb35261SJon Nettleton return 0; 17443bb35261SJon Nettleton } 17457cfa9c92SRussell King } 17467cfa9c92SRussell King 17475765cee1SRussell King (Oracle) if (power_mW <= 1000) { 17485765cee1SRussell King (Oracle) /* Modules below 1W do not require a power change sequence */ 17495765cee1SRussell King (Oracle) sfp->module_power_mW = power_mW; 17505765cee1SRussell King (Oracle) return 0; 17515765cee1SRussell King (Oracle) } 17525765cee1SRussell King (Oracle) 17535765cee1SRussell King (Oracle) if (!supports_a2) { 17545765cee1SRussell King (Oracle) /* The module power level is below the host maximum and the 17555765cee1SRussell King (Oracle) * module appears not to implement bus address 0xa2, so assume 17565765cee1SRussell King (Oracle) * that the module powers up in the indicated mode. 17575765cee1SRussell King (Oracle) */ 17585765cee1SRussell King (Oracle) return 0; 17595765cee1SRussell King (Oracle) } 17605765cee1SRussell King (Oracle) 17617cfa9c92SRussell King /* If the module requires a higher power mode, but also requires 17627cfa9c92SRussell King * an address change sequence, warn the user that the module may 17637cfa9c92SRussell King * not be functional. 17647cfa9c92SRussell King */ 17655765cee1SRussell King (Oracle) if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE) { 17667cfa9c92SRussell King dev_warn(sfp->dev, 176707f23d90SColin Ian King "Address Change Sequence not supported but module requires %u.%uW, module may not be functional\n", 17687cfa9c92SRussell King power_mW / 1000, (power_mW / 100) % 10); 17697cfa9c92SRussell King return 0; 17707cfa9c92SRussell King } 17713bb35261SJon Nettleton 1772ed32abb1SRussell King sfp->module_power_mW = power_mW; 1773ed32abb1SRussell King 1774ed32abb1SRussell King return 0; 1775ed32abb1SRussell King } 1776ed32abb1SRussell King 1777b036a554SRussell King static int sfp_sm_mod_hpower(struct sfp *sfp, bool enable) 1778ed32abb1SRussell King { 1779ed32abb1SRussell King u8 val; 1780ed32abb1SRussell King int err; 1781ed32abb1SRussell King 17823bb35261SJon Nettleton err = sfp_read(sfp, true, SFP_EXT_STATUS, &val, sizeof(val)); 17833bb35261SJon Nettleton if (err != sizeof(val)) { 17849ae1ef4bSRussell King (Oracle) dev_err(sfp->dev, "Failed to read EEPROM: %pe\n", ERR_PTR(err)); 1785b036a554SRussell King return -EAGAIN; 17863bb35261SJon Nettleton } 17873bb35261SJon Nettleton 17889a484621SRussell King /* DM7052 reports as a high power module, responds to reads (with 17899a484621SRussell King * all bytes 0xff) at 0x51 but does not accept writes. In any case, 17909a484621SRussell King * if the bit is already set, we're already in high power mode. 17919a484621SRussell King */ 17929a484621SRussell King if (!!(val & BIT(0)) == enable) 17939a484621SRussell King return 0; 17949a484621SRussell King 1795b036a554SRussell King if (enable) 17963bb35261SJon Nettleton val |= BIT(0); 1797b036a554SRussell King else 1798b036a554SRussell King val &= ~BIT(0); 17993bb35261SJon Nettleton 18003bb35261SJon Nettleton err = sfp_write(sfp, true, SFP_EXT_STATUS, &val, sizeof(val)); 18013bb35261SJon Nettleton if (err != sizeof(val)) { 18029ae1ef4bSRussell King (Oracle) dev_err(sfp->dev, "Failed to write EEPROM: %pe\n", 18039ae1ef4bSRussell King (Oracle) ERR_PTR(err)); 1804b036a554SRussell King return -EAGAIN; 18053bb35261SJon Nettleton } 18063bb35261SJon Nettleton 1807b036a554SRussell King if (enable) 18083bb35261SJon Nettleton dev_info(sfp->dev, "Module switched to %u.%uW power level\n", 1809ed32abb1SRussell King sfp->module_power_mW / 1000, 1810ed32abb1SRussell King (sfp->module_power_mW / 100) % 10); 18113bb35261SJon Nettleton 1812b036a554SRussell King return 0; 18133bb35261SJon Nettleton } 18143bb35261SJon Nettleton 1815426c6cbcSPali Rohár /* GPON modules based on Realtek RTL8672 and RTL9601C chips (e.g. V-SOL 1816426c6cbcSPali Rohár * V2801F, CarlitoxxPro CPGOS03-0490, Ubiquiti U-Fiber Instant, ...) do 1817426c6cbcSPali Rohár * not support multibyte reads from the EEPROM. Each multi-byte read 1818426c6cbcSPali Rohár * operation returns just one byte of EEPROM followed by zeros. There is 1819426c6cbcSPali Rohár * no way to identify which modules are using Realtek RTL8672 and RTL9601C 1820426c6cbcSPali Rohár * chips. Moreover every OEM of V-SOL V2801F module puts its own vendor 1821426c6cbcSPali Rohár * name and vendor id into EEPROM, so there is even no way to detect if 1822426c6cbcSPali Rohár * module is V-SOL V2801F. Therefore check for those zeros in the read 1823426c6cbcSPali Rohár * data and then based on check switch to reading EEPROM to one byte 1824426c6cbcSPali Rohár * at a time. 18250d035bedSRussell King */ 1826426c6cbcSPali Rohár static bool sfp_id_needs_byte_io(struct sfp *sfp, void *buf, size_t len) 18270d035bedSRussell King { 1828426c6cbcSPali Rohár size_t i, block_size = sfp->i2c_block_size; 18290d035bedSRussell King 1830426c6cbcSPali Rohár /* Already using byte IO */ 1831426c6cbcSPali Rohár if (block_size == 1) 1832426c6cbcSPali Rohár return false; 1833426c6cbcSPali Rohár 1834426c6cbcSPali Rohár for (i = 1; i < len; i += block_size) { 1835426c6cbcSPali Rohár if (memchr_inv(buf + i, '\0', min(block_size - 1, len - i))) 1836426c6cbcSPali Rohár return false; 18370d035bedSRussell King } 1838426c6cbcSPali Rohár return true; 18390d035bedSRussell King } 18400d035bedSRussell King 1841b18432c5SChris Healy static int sfp_cotsworks_fixup_check(struct sfp *sfp, struct sfp_eeprom_id *id) 1842b18432c5SChris Healy { 1843b18432c5SChris Healy u8 check; 1844b18432c5SChris Healy int err; 1845b18432c5SChris Healy 1846b18432c5SChris Healy if (id->base.phys_id != SFF8024_ID_SFF_8472 || 1847b18432c5SChris Healy id->base.phys_ext_id != SFP_PHYS_EXT_ID_SFP || 1848b18432c5SChris Healy id->base.connector != SFF8024_CONNECTOR_LC) { 1849b18432c5SChris Healy dev_warn(sfp->dev, "Rewriting fiber module EEPROM with corrected values\n"); 1850b18432c5SChris Healy id->base.phys_id = SFF8024_ID_SFF_8472; 1851b18432c5SChris Healy id->base.phys_ext_id = SFP_PHYS_EXT_ID_SFP; 1852b18432c5SChris Healy id->base.connector = SFF8024_CONNECTOR_LC; 1853b18432c5SChris Healy err = sfp_write(sfp, false, SFP_PHYS_ID, &id->base, 3); 1854b18432c5SChris Healy if (err != 3) { 18559ae1ef4bSRussell King (Oracle) dev_err(sfp->dev, 18569ae1ef4bSRussell King (Oracle) "Failed to rewrite module EEPROM: %pe\n", 18579ae1ef4bSRussell King (Oracle) ERR_PTR(err)); 1858b18432c5SChris Healy return err; 1859b18432c5SChris Healy } 1860b18432c5SChris Healy 1861b18432c5SChris Healy /* Cotsworks modules have been found to require a delay between write operations. */ 1862b18432c5SChris Healy mdelay(50); 1863b18432c5SChris Healy 1864b18432c5SChris Healy /* Update base structure checksum */ 1865b18432c5SChris Healy check = sfp_check(&id->base, sizeof(id->base) - 1); 1866b18432c5SChris Healy err = sfp_write(sfp, false, SFP_CC_BASE, &check, 1); 1867b18432c5SChris Healy if (err != 1) { 18689ae1ef4bSRussell King (Oracle) dev_err(sfp->dev, 18699ae1ef4bSRussell King (Oracle) "Failed to update base structure checksum in fiber module EEPROM: %pe\n", 18709ae1ef4bSRussell King (Oracle) ERR_PTR(err)); 1871b18432c5SChris Healy return err; 1872b18432c5SChris Healy } 1873b18432c5SChris Healy } 1874b18432c5SChris Healy return 0; 1875b18432c5SChris Healy } 1876b18432c5SChris Healy 1877e117be74SRussell King static int sfp_sm_mod_probe(struct sfp *sfp, bool report) 187873970055SRussell King { 187973970055SRussell King /* SFP module inserted - read I2C data */ 188073970055SRussell King struct sfp_eeprom_id id; 1881b18432c5SChris Healy bool cotsworks_sfbg; 1882981f1f80SRussell King bool cotsworks; 188373970055SRussell King u8 check; 18843bb35261SJon Nettleton int ret; 188573970055SRussell King 1886426c6cbcSPali Rohár /* Some SFP modules and also some Linux I2C drivers do not like reads 1887426c6cbcSPali Rohár * longer than 16 bytes, so read the EEPROM in chunks of 16 bytes at 1888426c6cbcSPali Rohár * a time. 18890d035bedSRussell King */ 1890426c6cbcSPali Rohár sfp->i2c_block_size = 16; 18910d035bedSRussell King 18920d035bedSRussell King ret = sfp_read(sfp, false, 0, &id.base, sizeof(id.base)); 18933bb35261SJon Nettleton if (ret < 0) { 1894e117be74SRussell King if (report) 18959ae1ef4bSRussell King (Oracle) dev_err(sfp->dev, "failed to read EEPROM: %pe\n", 18969ae1ef4bSRussell King (Oracle) ERR_PTR(ret)); 189773970055SRussell King return -EAGAIN; 189873970055SRussell King } 189973970055SRussell King 19000d035bedSRussell King if (ret != sizeof(id.base)) { 19019ae1ef4bSRussell King (Oracle) dev_err(sfp->dev, "EEPROM short read: %pe\n", ERR_PTR(ret)); 190273970055SRussell King return -EAGAIN; 190373970055SRussell King } 190473970055SRussell King 1905426c6cbcSPali Rohár /* Some SFP modules (e.g. Nokia 3FE46541AA) lock up if read from 1906426c6cbcSPali Rohár * address 0x51 is just one byte at a time. Also SFF-8472 requires 1907426c6cbcSPali Rohár * that EEPROM supports atomic 16bit read operation for diagnostic 1908426c6cbcSPali Rohár * fields, so do not switch to one byte reading at a time unless it 1909426c6cbcSPali Rohár * is really required and we have no other option. 1910426c6cbcSPali Rohár */ 1911426c6cbcSPali Rohár if (sfp_id_needs_byte_io(sfp, &id.base, sizeof(id.base))) { 1912426c6cbcSPali Rohár dev_info(sfp->dev, 1913426c6cbcSPali Rohár "Detected broken RTL8672/RTL9601C emulated EEPROM\n"); 1914426c6cbcSPali Rohár dev_info(sfp->dev, 1915426c6cbcSPali Rohár "Switching to reading EEPROM to one byte at a time\n"); 1916426c6cbcSPali Rohár sfp->i2c_block_size = 1; 1917426c6cbcSPali Rohár 1918426c6cbcSPali Rohár ret = sfp_read(sfp, false, 0, &id.base, sizeof(id.base)); 1919426c6cbcSPali Rohár if (ret < 0) { 1920426c6cbcSPali Rohár if (report) 19219ae1ef4bSRussell King (Oracle) dev_err(sfp->dev, 19229ae1ef4bSRussell King (Oracle) "failed to read EEPROM: %pe\n", 19239ae1ef4bSRussell King (Oracle) ERR_PTR(ret)); 1924426c6cbcSPali Rohár return -EAGAIN; 1925426c6cbcSPali Rohár } 1926426c6cbcSPali Rohár 1927426c6cbcSPali Rohár if (ret != sizeof(id.base)) { 19289ae1ef4bSRussell King (Oracle) dev_err(sfp->dev, "EEPROM short read: %pe\n", 19299ae1ef4bSRussell King (Oracle) ERR_PTR(ret)); 1930426c6cbcSPali Rohár return -EAGAIN; 1931426c6cbcSPali Rohár } 1932426c6cbcSPali Rohár } 1933426c6cbcSPali Rohár 1934981f1f80SRussell King /* Cotsworks do not seem to update the checksums when they 1935981f1f80SRussell King * do the final programming with the final module part number, 1936981f1f80SRussell King * serial number and date code. 1937981f1f80SRussell King */ 1938981f1f80SRussell King cotsworks = !memcmp(id.base.vendor_name, "COTSWORKS ", 16); 1939b18432c5SChris Healy cotsworks_sfbg = !memcmp(id.base.vendor_pn, "SFBG", 4); 1940b18432c5SChris Healy 1941b18432c5SChris Healy /* Cotsworks SFF module EEPROM do not always have valid phys_id, 1942b18432c5SChris Healy * phys_ext_id, and connector bytes. Rewrite SFF EEPROM bytes if 1943b18432c5SChris Healy * Cotsworks PN matches and bytes are not correct. 1944b18432c5SChris Healy */ 1945b18432c5SChris Healy if (cotsworks && cotsworks_sfbg) { 1946b18432c5SChris Healy ret = sfp_cotsworks_fixup_check(sfp, &id); 1947b18432c5SChris Healy if (ret < 0) 1948b18432c5SChris Healy return ret; 1949b18432c5SChris Healy } 1950981f1f80SRussell King 195173970055SRussell King /* Validate the checksum over the base structure */ 195273970055SRussell King check = sfp_check(&id.base, sizeof(id.base) - 1); 195373970055SRussell King if (check != id.base.cc_base) { 1954981f1f80SRussell King if (cotsworks) { 1955981f1f80SRussell King dev_warn(sfp->dev, 1956981f1f80SRussell King "EEPROM base structure checksum failure (0x%02x != 0x%02x)\n", 1957981f1f80SRussell King check, id.base.cc_base); 1958981f1f80SRussell King } else { 195973970055SRussell King dev_err(sfp->dev, 1960981f1f80SRussell King "EEPROM base structure checksum failure: 0x%02x != 0x%02x\n", 1961981f1f80SRussell King check, id.base.cc_base); 196273970055SRussell King print_hex_dump(KERN_ERR, "sfp EE: ", DUMP_PREFIX_OFFSET, 1963981f1f80SRussell King 16, 1, &id, sizeof(id), true); 196473970055SRussell King return -EINVAL; 196573970055SRussell King } 1966981f1f80SRussell King } 196773970055SRussell King 19680d035bedSRussell King ret = sfp_read(sfp, false, SFP_CC_BASE + 1, &id.ext, sizeof(id.ext)); 19690d035bedSRussell King if (ret < 0) { 19700d035bedSRussell King if (report) 19719ae1ef4bSRussell King (Oracle) dev_err(sfp->dev, "failed to read EEPROM: %pe\n", 19729ae1ef4bSRussell King (Oracle) ERR_PTR(ret)); 19730d035bedSRussell King return -EAGAIN; 19740d035bedSRussell King } 19750d035bedSRussell King 19760d035bedSRussell King if (ret != sizeof(id.ext)) { 19779ae1ef4bSRussell King (Oracle) dev_err(sfp->dev, "EEPROM short read: %pe\n", ERR_PTR(ret)); 19780d035bedSRussell King return -EAGAIN; 19790d035bedSRussell King } 19800d035bedSRussell King 198173970055SRussell King check = sfp_check(&id.ext, sizeof(id.ext) - 1); 198273970055SRussell King if (check != id.ext.cc_ext) { 1983981f1f80SRussell King if (cotsworks) { 1984981f1f80SRussell King dev_warn(sfp->dev, 1985981f1f80SRussell King "EEPROM extended structure checksum failure (0x%02x != 0x%02x)\n", 1986981f1f80SRussell King check, id.ext.cc_ext); 1987981f1f80SRussell King } else { 198873970055SRussell King dev_err(sfp->dev, 1989981f1f80SRussell King "EEPROM extended structure checksum failure: 0x%02x != 0x%02x\n", 1990981f1f80SRussell King check, id.ext.cc_ext); 1991981f1f80SRussell King print_hex_dump(KERN_ERR, "sfp EE: ", DUMP_PREFIX_OFFSET, 1992981f1f80SRussell King 16, 1, &id, sizeof(id), true); 199373970055SRussell King memset(&id.ext, 0, sizeof(id.ext)); 199473970055SRussell King } 1995981f1f80SRussell King } 199673970055SRussell King 199773970055SRussell King sfp->id = id; 199873970055SRussell King 1999a2f247efSRussell King dev_info(sfp->dev, "module %.*s %.*s rev %.*s sn %.*s dc %.*s\n", 2000a2f247efSRussell King (int)sizeof(id.base.vendor_name), id.base.vendor_name, 2001a2f247efSRussell King (int)sizeof(id.base.vendor_pn), id.base.vendor_pn, 2002a2f247efSRussell King (int)sizeof(id.base.vendor_rev), id.base.vendor_rev, 2003a2f247efSRussell King (int)sizeof(id.ext.vendor_sn), id.ext.vendor_sn, 2004a2f247efSRussell King (int)sizeof(id.ext.datecode), id.ext.datecode); 200573970055SRussell King 2006259c8618SRussell King /* Check whether we support this module */ 2007f3c9a666SRussell King if (!sfp->type->module_supported(&id)) { 2008259c8618SRussell King dev_err(sfp->dev, 2009259c8618SRussell King "module is not supported - phys id 0x%02x 0x%02x\n", 201073970055SRussell King sfp->id.base.phys_id, sfp->id.base.phys_ext_id); 201173970055SRussell King return -EINVAL; 201273970055SRussell King } 201373970055SRussell King 2014ec7681bdSRussell King /* If the module requires address swap mode, warn about it */ 2015ec7681bdSRussell King if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE) 2016ec7681bdSRussell King dev_warn(sfp->dev, 2017ec7681bdSRussell King "module address swap to access page 0xA2 is not supported.\n"); 2018ec7681bdSRussell King 2019ed32abb1SRussell King /* Parse the module power requirement */ 2020ed32abb1SRussell King ret = sfp_module_parse_power(sfp); 2021ed32abb1SRussell King if (ret < 0) 2022ed32abb1SRussell King return ret; 2023ed32abb1SRussell King 20248475c4b7SRussell King (Oracle) /* Initialise state bits to use from hardware */ 20258475c4b7SRussell King (Oracle) sfp->state_hw_mask = SFP_F_PRESENT; 20268475c4b7SRussell King (Oracle) if (sfp->gpio[GPIO_TX_DISABLE]) 20278475c4b7SRussell King (Oracle) sfp->state_hw_mask |= SFP_F_TX_DISABLE; 20288475c4b7SRussell King (Oracle) if (sfp->gpio[GPIO_TX_FAULT]) 20298475c4b7SRussell King (Oracle) sfp->state_hw_mask |= SFP_F_TX_FAULT; 20308475c4b7SRussell King (Oracle) if (sfp->gpio[GPIO_LOS]) 20318475c4b7SRussell King (Oracle) sfp->state_hw_mask |= SFP_F_LOS; 20328475c4b7SRussell King (Oracle) 203326c97a2dSRussell King sfp->module_t_start_up = T_START_UP; 203426c97a2dSRussell King 20352069624dSMatthew Hagan sfp->tx_fault_ignore = false; 20362069624dSMatthew Hagan 203723571c7bSRussell King (Oracle) sfp->quirk = sfp_lookup_quirk(&id); 203827541675SRussell King (Oracle) if (sfp->quirk && sfp->quirk->fixup) 203927541675SRussell King (Oracle) sfp->quirk->fixup(sfp); 204023571c7bSRussell King (Oracle) 2041b036a554SRussell King return 0; 204273970055SRussell King } 204373970055SRussell King 204473970055SRussell King static void sfp_sm_mod_remove(struct sfp *sfp) 204573970055SRussell King { 204673f5e847SRussell King if (sfp->sm_mod_state > SFP_MOD_WAITDEV) 204773970055SRussell King sfp_module_remove(sfp->sfp_bus); 204873970055SRussell King 20491323061aSAndrew Lunn sfp_hwmon_remove(sfp); 20501323061aSAndrew Lunn 205173970055SRussell King memset(&sfp->id, 0, sizeof(sfp->id)); 2052ed32abb1SRussell King sfp->module_power_mW = 0; 205373970055SRussell King 205473970055SRussell King dev_info(sfp->dev, "module removed\n"); 205573970055SRussell King } 205673970055SRussell King 20576b0da5c9SRussell King /* This state machine tracks the upstream's state */ 2058e85d81a1SRussell King static void sfp_sm_device(struct sfp *sfp, unsigned int event) 205973970055SRussell King { 2060e85d81a1SRussell King switch (sfp->sm_dev_state) { 2061e85d81a1SRussell King default: 20626b0da5c9SRussell King if (event == SFP_E_DEV_ATTACH) 20636b0da5c9SRussell King sfp->sm_dev_state = SFP_DEV_DOWN; 20646b0da5c9SRussell King break; 20656b0da5c9SRussell King 20666b0da5c9SRussell King case SFP_DEV_DOWN: 20676b0da5c9SRussell King if (event == SFP_E_DEV_DETACH) 20686b0da5c9SRussell King sfp->sm_dev_state = SFP_DEV_DETACHED; 20696b0da5c9SRussell King else if (event == SFP_E_DEV_UP) 2070e85d81a1SRussell King sfp->sm_dev_state = SFP_DEV_UP; 2071e85d81a1SRussell King break; 207273970055SRussell King 2073e85d81a1SRussell King case SFP_DEV_UP: 20746b0da5c9SRussell King if (event == SFP_E_DEV_DETACH) 20756b0da5c9SRussell King sfp->sm_dev_state = SFP_DEV_DETACHED; 20766b0da5c9SRussell King else if (event == SFP_E_DEV_DOWN) 2077e85d81a1SRussell King sfp->sm_dev_state = SFP_DEV_DOWN; 2078e85d81a1SRussell King break; 2079e85d81a1SRussell King } 2080e85d81a1SRussell King } 208173970055SRussell King 2082d900954fSRussell King /* This state machine tracks the insert/remove state of the module, probes 2083d900954fSRussell King * the on-board EEPROM, and sets up the power level. 208473970055SRussell King */ 2085e85d81a1SRussell King static void sfp_sm_module(struct sfp *sfp, unsigned int event) 2086e85d81a1SRussell King { 2087b036a554SRussell King int err; 2088b036a554SRussell King 2089b036a554SRussell King /* Handle remove event globally, it resets this state machine */ 2090b036a554SRussell King if (event == SFP_E_REMOVE) { 2091d2e816c0SRussell King if (sfp->sm_mod_state > SFP_MOD_PROBE) 2092d2e816c0SRussell King sfp_sm_mod_remove(sfp); 2093b036a554SRussell King sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); 2094b036a554SRussell King return; 2095b036a554SRussell King } 2096b036a554SRussell King 2097b036a554SRussell King /* Handle device detach globally */ 209873f5e847SRussell King if (sfp->sm_dev_state < SFP_DEV_DOWN && 209973f5e847SRussell King sfp->sm_mod_state > SFP_MOD_WAITDEV) { 2100b036a554SRussell King if (sfp->module_power_mW > 1000 && 2101b036a554SRussell King sfp->sm_mod_state > SFP_MOD_HPOWER) 2102b036a554SRussell King sfp_sm_mod_hpower(sfp, false); 210373f5e847SRussell King sfp_sm_mod_next(sfp, SFP_MOD_WAITDEV, 0); 2104d2e816c0SRussell King return; 2105d2e816c0SRussell King } 2106d2e816c0SRussell King 210773970055SRussell King switch (sfp->sm_mod_state) { 210873970055SRussell King default: 2109e117be74SRussell King if (event == SFP_E_INSERT) { 2110d900954fSRussell King sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_SERIAL); 2111e117be74SRussell King sfp->sm_mod_tries_init = R_PROBE_RETRY_INIT; 2112e117be74SRussell King sfp->sm_mod_tries = R_PROBE_RETRY_SLOW; 2113e117be74SRussell King } 211473970055SRussell King break; 211573970055SRussell King 211673970055SRussell King case SFP_MOD_PROBE: 211773f5e847SRussell King /* Wait for T_PROBE_INIT to time out */ 2118b036a554SRussell King if (event != SFP_E_TIMEOUT) 2119b036a554SRussell King break; 212073970055SRussell King 2121e117be74SRussell King err = sfp_sm_mod_probe(sfp, sfp->sm_mod_tries == 1); 2122b036a554SRussell King if (err == -EAGAIN) { 2123e117be74SRussell King if (sfp->sm_mod_tries_init && 2124e117be74SRussell King --sfp->sm_mod_tries_init) { 2125e117be74SRussell King sfp_sm_set_timer(sfp, T_PROBE_RETRY_INIT); 2126b036a554SRussell King break; 2127e117be74SRussell King } else if (sfp->sm_mod_tries && --sfp->sm_mod_tries) { 2128e117be74SRussell King if (sfp->sm_mod_tries == R_PROBE_RETRY_SLOW - 1) 2129e117be74SRussell King dev_warn(sfp->dev, 2130e117be74SRussell King "please wait, module slow to respond\n"); 2131e117be74SRussell King sfp_sm_set_timer(sfp, T_PROBE_RETRY_SLOW); 2132e117be74SRussell King break; 2133e117be74SRussell King } 2134b036a554SRussell King } 2135b036a554SRussell King if (err < 0) { 2136b036a554SRussell King sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); 2137b036a554SRussell King break; 2138b036a554SRussell King } 2139b036a554SRussell King 214038ecd706SRussell King err = sfp_hwmon_insert(sfp); 214138ecd706SRussell King if (err) 21429ae1ef4bSRussell King (Oracle) dev_warn(sfp->dev, "hwmon probe failed: %pe\n", 21439ae1ef4bSRussell King (Oracle) ERR_PTR(err)); 214438ecd706SRussell King 214573f5e847SRussell King sfp_sm_mod_next(sfp, SFP_MOD_WAITDEV, 0); 2146df561f66SGustavo A. R. Silva fallthrough; 214773f5e847SRussell King case SFP_MOD_WAITDEV: 214873f5e847SRussell King /* Ensure that the device is attached before proceeding */ 214973f5e847SRussell King if (sfp->sm_dev_state < SFP_DEV_DOWN) 215073f5e847SRussell King break; 215173f5e847SRussell King 215273f5e847SRussell King /* Report the module insertion to the upstream device */ 215323571c7bSRussell King (Oracle) err = sfp_module_insert(sfp->sfp_bus, &sfp->id, 215423571c7bSRussell King (Oracle) sfp->quirk); 215573f5e847SRussell King if (err < 0) { 215673f5e847SRussell King sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); 215773f5e847SRussell King break; 215873f5e847SRussell King } 215973f5e847SRussell King 2160b036a554SRussell King /* If this is a power level 1 module, we are done */ 2161b036a554SRussell King if (sfp->module_power_mW <= 1000) 2162b036a554SRussell King goto insert; 2163b036a554SRussell King 2164b036a554SRussell King sfp_sm_mod_next(sfp, SFP_MOD_HPOWER, 0); 2165df561f66SGustavo A. R. Silva fallthrough; 2166b036a554SRussell King case SFP_MOD_HPOWER: 2167b036a554SRussell King /* Enable high power mode */ 2168b036a554SRussell King err = sfp_sm_mod_hpower(sfp, true); 216973f5e847SRussell King if (err < 0) { 217073f5e847SRussell King if (err != -EAGAIN) { 217173f5e847SRussell King sfp_module_remove(sfp->sfp_bus); 21720936ebc4SRussell King sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); 217373f5e847SRussell King } else { 2174e117be74SRussell King sfp_sm_set_timer(sfp, T_PROBE_RETRY_INIT); 217573f5e847SRussell King } 217673f5e847SRussell King break; 217773f5e847SRussell King } 217873f5e847SRussell King 217973f5e847SRussell King sfp_sm_mod_next(sfp, SFP_MOD_WAITPWR, T_HPOWER_LEVEL); 218073970055SRussell King break; 218173970055SRussell King 2182b036a554SRussell King case SFP_MOD_WAITPWR: 2183b036a554SRussell King /* Wait for T_HPOWER_LEVEL to time out */ 2184b036a554SRussell King if (event != SFP_E_TIMEOUT) 2185b036a554SRussell King break; 2186b036a554SRussell King 2187b036a554SRussell King insert: 21880936ebc4SRussell King sfp_sm_mod_next(sfp, SFP_MOD_PRESENT, 0); 21893bb35261SJon Nettleton break; 2190b036a554SRussell King 219173970055SRussell King case SFP_MOD_PRESENT: 219273970055SRussell King case SFP_MOD_ERROR: 219373970055SRussell King break; 219473970055SRussell King } 219573970055SRussell King } 219673970055SRussell King 2197e85d81a1SRussell King static void sfp_sm_main(struct sfp *sfp, unsigned int event) 2198e85d81a1SRussell King { 2199eefa6f1fSRussell King unsigned long timeout; 22001cb89a14SRussell King int ret; 2201eefa6f1fSRussell King 220273970055SRussell King /* Some events are global */ 220373970055SRussell King if (sfp->sm_state != SFP_S_DOWN && 220473970055SRussell King (sfp->sm_mod_state != SFP_MOD_PRESENT || 220573970055SRussell King sfp->sm_dev_state != SFP_DEV_UP)) { 220673970055SRussell King if (sfp->sm_state == SFP_S_LINK_UP && 220773970055SRussell King sfp->sm_dev_state == SFP_DEV_UP) 220873970055SRussell King sfp_sm_link_down(sfp); 220974c551caSRussell King if (sfp->sm_state > SFP_S_INIT) 221074c551caSRussell King sfp_module_stop(sfp->sfp_bus); 221173970055SRussell King if (sfp->mod_phy) 221273970055SRussell King sfp_sm_phy_detach(sfp); 22131539e0d3SRussell King sfp_module_tx_disable(sfp); 2214f3c9a666SRussell King sfp_soft_stop_poll(sfp); 221573970055SRussell King sfp_sm_next(sfp, SFP_S_DOWN, 0); 221673970055SRussell King return; 221773970055SRussell King } 221873970055SRussell King 221973970055SRussell King /* The main state machine */ 222073970055SRussell King switch (sfp->sm_state) { 222173970055SRussell King case SFP_S_DOWN: 2222eefa6f1fSRussell King if (sfp->sm_mod_state != SFP_MOD_PRESENT || 2223eefa6f1fSRussell King sfp->sm_dev_state != SFP_DEV_UP) 2224eefa6f1fSRussell King break; 2225eefa6f1fSRussell King 2226f3c9a666SRussell King if (!(sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE)) 2227f3c9a666SRussell King sfp_soft_start_poll(sfp); 2228f3c9a666SRussell King 2229f3c9a666SRussell King sfp_module_tx_enable(sfp); 2230eefa6f1fSRussell King 2231eefa6f1fSRussell King /* Initialise the fault clearance retries */ 2232281e4eabSRussell King sfp->sm_fault_retries = N_FAULT_INIT; 2233eefa6f1fSRussell King 2234eefa6f1fSRussell King /* We need to check the TX_FAULT state, which is not defined 2235eefa6f1fSRussell King * while TX_DISABLE is asserted. The earliest we want to do 2236eefa6f1fSRussell King * anything (such as probe for a PHY) is 50ms. 2237eefa6f1fSRussell King */ 2238eefa6f1fSRussell King sfp_sm_next(sfp, SFP_S_WAIT, T_WAIT); 2239eefa6f1fSRussell King break; 2240eefa6f1fSRussell King 2241eefa6f1fSRussell King case SFP_S_WAIT: 2242eefa6f1fSRussell King if (event != SFP_E_TIMEOUT) 2243eefa6f1fSRussell King break; 2244eefa6f1fSRussell King 2245eefa6f1fSRussell King if (sfp->state & SFP_F_TX_FAULT) { 224626c97a2dSRussell King /* Wait up to t_init (SFF-8472) or t_start_up (SFF-8431) 224726c97a2dSRussell King * from the TX_DISABLE deassertion for the module to 224826c97a2dSRussell King * initialise, which is indicated by TX_FAULT 224926c97a2dSRussell King * deasserting. 2250181f29daSRussell King */ 225126c97a2dSRussell King timeout = sfp->module_t_start_up; 2252eefa6f1fSRussell King if (timeout > T_WAIT) 2253eefa6f1fSRussell King timeout -= T_WAIT; 2254eefa6f1fSRussell King else 2255eefa6f1fSRussell King timeout = 1; 2256eefa6f1fSRussell King 2257eefa6f1fSRussell King sfp_sm_next(sfp, SFP_S_INIT, timeout); 2258eefa6f1fSRussell King } else { 2259eefa6f1fSRussell King /* TX_FAULT is not asserted, assume the module has 2260eefa6f1fSRussell King * finished initialising. 2261eefa6f1fSRussell King */ 2262eefa6f1fSRussell King goto init_done; 2263181f29daSRussell King } 226473970055SRussell King break; 226573970055SRussell King 226673970055SRussell King case SFP_S_INIT: 2267d23751a0SRussell King if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) { 2268e1f82127SWenpeng Liang /* TX_FAULT is still asserted after t_init 226926c97a2dSRussell King * or t_start_up, so assume there is a fault. 2270d23751a0SRussell King */ 2271d23751a0SRussell King sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT, 2272281e4eabSRussell King sfp->sm_fault_retries == N_FAULT_INIT); 2273d23751a0SRussell King } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) { 22741cb89a14SRussell King init_done: 22751cb89a14SRussell King sfp->sm_phy_retries = R_PHY_RETRY; 22761cb89a14SRussell King goto phy_probe; 22771cb89a14SRussell King } 22781cb89a14SRussell King break; 22791cb89a14SRussell King 22801cb89a14SRussell King case SFP_S_INIT_PHY: 22811cb89a14SRussell King if (event != SFP_E_TIMEOUT) 22821cb89a14SRussell King break; 22831cb89a14SRussell King phy_probe: 22841cb89a14SRussell King /* TX_FAULT deasserted or we timed out with TX_FAULT 2285d23751a0SRussell King * clear. Probe for the PHY and check the LOS state. 2286d23751a0SRussell King */ 22871cb89a14SRussell King ret = sfp_sm_probe_for_phy(sfp); 22881cb89a14SRussell King if (ret == -ENODEV) { 22891cb89a14SRussell King if (--sfp->sm_phy_retries) { 22901cb89a14SRussell King sfp_sm_next(sfp, SFP_S_INIT_PHY, T_PHY_RETRY); 22911cb89a14SRussell King break; 22921cb89a14SRussell King } else { 22931cb89a14SRussell King dev_info(sfp->dev, "no PHY detected\n"); 22941cb89a14SRussell King } 22951cb89a14SRussell King } else if (ret) { 2296256e43cbSRussell King sfp_sm_next(sfp, SFP_S_FAIL, 0); 2297256e43cbSRussell King break; 2298256e43cbSRussell King } 229974c551caSRussell King if (sfp_module_start(sfp->sfp_bus)) { 230074c551caSRussell King sfp_sm_next(sfp, SFP_S_FAIL, 0); 230174c551caSRussell King break; 230274c551caSRussell King } 2303d23751a0SRussell King sfp_sm_link_check_los(sfp); 2304d23751a0SRussell King 2305d23751a0SRussell King /* Reset the fault retry count */ 2306281e4eabSRussell King sfp->sm_fault_retries = N_FAULT; 2307d23751a0SRussell King break; 2308d23751a0SRussell King 2309d23751a0SRussell King case SFP_S_INIT_TX_FAULT: 2310d23751a0SRussell King if (event == SFP_E_TIMEOUT) { 2311d23751a0SRussell King sfp_module_tx_fault_reset(sfp); 231226c97a2dSRussell King sfp_sm_next(sfp, SFP_S_INIT, sfp->module_t_start_up); 2313d23751a0SRussell King } 231473970055SRussell King break; 231573970055SRussell King 231673970055SRussell King case SFP_S_WAIT_LOS: 231773970055SRussell King if (event == SFP_E_TX_FAULT) 231863ec1c7cSRussell King sfp_sm_fault(sfp, SFP_S_TX_FAULT, true); 2319710dfbb0SRussell King else if (sfp_los_event_inactive(sfp, event)) 232073970055SRussell King sfp_sm_link_up(sfp); 232173970055SRussell King break; 232273970055SRussell King 232373970055SRussell King case SFP_S_LINK_UP: 232473970055SRussell King if (event == SFP_E_TX_FAULT) { 232573970055SRussell King sfp_sm_link_down(sfp); 232663ec1c7cSRussell King sfp_sm_fault(sfp, SFP_S_TX_FAULT, true); 2327710dfbb0SRussell King } else if (sfp_los_event_active(sfp, event)) { 232873970055SRussell King sfp_sm_link_down(sfp); 232973970055SRussell King sfp_sm_next(sfp, SFP_S_WAIT_LOS, 0); 233073970055SRussell King } 233173970055SRussell King break; 233273970055SRussell King 233373970055SRussell King case SFP_S_TX_FAULT: 233473970055SRussell King if (event == SFP_E_TIMEOUT) { 233573970055SRussell King sfp_module_tx_fault_reset(sfp); 233626c97a2dSRussell King sfp_sm_next(sfp, SFP_S_REINIT, sfp->module_t_start_up); 233773970055SRussell King } 233873970055SRussell King break; 233973970055SRussell King 234073970055SRussell King case SFP_S_REINIT: 234173970055SRussell King if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) { 234263ec1c7cSRussell King sfp_sm_fault(sfp, SFP_S_TX_FAULT, false); 234373970055SRussell King } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) { 234473970055SRussell King dev_info(sfp->dev, "module transmit fault recovered\n"); 234573970055SRussell King sfp_sm_link_check_los(sfp); 234673970055SRussell King } 234773970055SRussell King break; 234873970055SRussell King 234973970055SRussell King case SFP_S_TX_DISABLE: 235073970055SRussell King break; 235173970055SRussell King } 2352e85d81a1SRussell King } 2353e85d81a1SRussell King 2354e85d81a1SRussell King static void sfp_sm_event(struct sfp *sfp, unsigned int event) 2355e85d81a1SRussell King { 2356e85d81a1SRussell King mutex_lock(&sfp->sm_mutex); 2357e85d81a1SRussell King 2358e85d81a1SRussell King dev_dbg(sfp->dev, "SM: enter %s:%s:%s event %s\n", 2359e85d81a1SRussell King mod_state_to_str(sfp->sm_mod_state), 2360e85d81a1SRussell King dev_state_to_str(sfp->sm_dev_state), 2361e85d81a1SRussell King sm_state_to_str(sfp->sm_state), 2362e85d81a1SRussell King event_to_str(event)); 2363e85d81a1SRussell King 2364e85d81a1SRussell King sfp_sm_device(sfp, event); 23656b0da5c9SRussell King sfp_sm_module(sfp, event); 2366e85d81a1SRussell King sfp_sm_main(sfp, event); 236773970055SRussell King 23684005a7cbSAndrew Lunn dev_dbg(sfp->dev, "SM: exit %s:%s:%s\n", 23694005a7cbSAndrew Lunn mod_state_to_str(sfp->sm_mod_state), 23704005a7cbSAndrew Lunn dev_state_to_str(sfp->sm_dev_state), 23714005a7cbSAndrew Lunn sm_state_to_str(sfp->sm_state)); 237273970055SRussell King 237373970055SRussell King mutex_unlock(&sfp->sm_mutex); 237473970055SRussell King } 237573970055SRussell King 2376b5bfc21aSRussell King static void sfp_attach(struct sfp *sfp) 2377b5bfc21aSRussell King { 23786b0da5c9SRussell King sfp_sm_event(sfp, SFP_E_DEV_ATTACH); 2379b5bfc21aSRussell King } 2380b5bfc21aSRussell King 2381b5bfc21aSRussell King static void sfp_detach(struct sfp *sfp) 2382b5bfc21aSRussell King { 23836b0da5c9SRussell King sfp_sm_event(sfp, SFP_E_DEV_DETACH); 2384b5bfc21aSRussell King } 2385b5bfc21aSRussell King 238673970055SRussell King static void sfp_start(struct sfp *sfp) 238773970055SRussell King { 238873970055SRussell King sfp_sm_event(sfp, SFP_E_DEV_UP); 238973970055SRussell King } 239073970055SRussell King 239173970055SRussell King static void sfp_stop(struct sfp *sfp) 239273970055SRussell King { 239373970055SRussell King sfp_sm_event(sfp, SFP_E_DEV_DOWN); 239473970055SRussell King } 239573970055SRussell King 239673970055SRussell King static int sfp_module_info(struct sfp *sfp, struct ethtool_modinfo *modinfo) 239773970055SRussell King { 239873970055SRussell King /* locking... and check module is present */ 239973970055SRussell King 2400ec7681bdSRussell King if (sfp->id.ext.sff8472_compliance && 2401ec7681bdSRussell King !(sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE)) { 240273970055SRussell King modinfo->type = ETH_MODULE_SFF_8472; 240373970055SRussell King modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; 240473970055SRussell King } else { 240573970055SRussell King modinfo->type = ETH_MODULE_SFF_8079; 240673970055SRussell King modinfo->eeprom_len = ETH_MODULE_SFF_8079_LEN; 240773970055SRussell King } 240873970055SRussell King return 0; 240973970055SRussell King } 241073970055SRussell King 241173970055SRussell King static int sfp_module_eeprom(struct sfp *sfp, struct ethtool_eeprom *ee, 241273970055SRussell King u8 *data) 241373970055SRussell King { 241473970055SRussell King unsigned int first, last, len; 241573970055SRussell King int ret; 241673970055SRussell King 241773970055SRussell King if (ee->len == 0) 241873970055SRussell King return -EINVAL; 241973970055SRussell King 242073970055SRussell King first = ee->offset; 242173970055SRussell King last = ee->offset + ee->len; 242273970055SRussell King if (first < ETH_MODULE_SFF_8079_LEN) { 242373970055SRussell King len = min_t(unsigned int, last, ETH_MODULE_SFF_8079_LEN); 242473970055SRussell King len -= first; 242573970055SRussell King 24262794ffc4SRussell King ret = sfp_read(sfp, false, first, data, len); 242773970055SRussell King if (ret < 0) 242873970055SRussell King return ret; 242973970055SRussell King 243073970055SRussell King first += len; 243173970055SRussell King data += len; 243273970055SRussell King } 24332794ffc4SRussell King if (first < ETH_MODULE_SFF_8472_LEN && last > ETH_MODULE_SFF_8079_LEN) { 243473970055SRussell King len = min_t(unsigned int, last, ETH_MODULE_SFF_8472_LEN); 243573970055SRussell King len -= first; 243673970055SRussell King first -= ETH_MODULE_SFF_8079_LEN; 243773970055SRussell King 24382794ffc4SRussell King ret = sfp_read(sfp, true, first, data, len); 243973970055SRussell King if (ret < 0) 244073970055SRussell King return ret; 244173970055SRussell King } 244273970055SRussell King return 0; 244373970055SRussell King } 244473970055SRussell King 2445d740513fSAndrew Lunn static int sfp_module_eeprom_by_page(struct sfp *sfp, 2446d740513fSAndrew Lunn const struct ethtool_module_eeprom *page, 2447d740513fSAndrew Lunn struct netlink_ext_ack *extack) 2448d740513fSAndrew Lunn { 2449d740513fSAndrew Lunn if (page->bank) { 2450d740513fSAndrew Lunn NL_SET_ERR_MSG(extack, "Banks not supported"); 2451d740513fSAndrew Lunn return -EOPNOTSUPP; 2452d740513fSAndrew Lunn } 2453d740513fSAndrew Lunn 2454d740513fSAndrew Lunn if (page->page) { 2455d740513fSAndrew Lunn NL_SET_ERR_MSG(extack, "Only page 0 supported"); 2456d740513fSAndrew Lunn return -EOPNOTSUPP; 2457d740513fSAndrew Lunn } 2458d740513fSAndrew Lunn 2459d740513fSAndrew Lunn if (page->i2c_address != 0x50 && 2460d740513fSAndrew Lunn page->i2c_address != 0x51) { 2461d740513fSAndrew Lunn NL_SET_ERR_MSG(extack, "Only address 0x50 and 0x51 supported"); 2462d740513fSAndrew Lunn return -EOPNOTSUPP; 2463d740513fSAndrew Lunn } 2464d740513fSAndrew Lunn 2465d740513fSAndrew Lunn return sfp_read(sfp, page->i2c_address == 0x51, page->offset, 2466d740513fSAndrew Lunn page->data, page->length); 2467d740513fSAndrew Lunn }; 2468d740513fSAndrew Lunn 246973970055SRussell King static const struct sfp_socket_ops sfp_module_ops = { 2470b5bfc21aSRussell King .attach = sfp_attach, 2471b5bfc21aSRussell King .detach = sfp_detach, 247273970055SRussell King .start = sfp_start, 247373970055SRussell King .stop = sfp_stop, 247473970055SRussell King .module_info = sfp_module_info, 247573970055SRussell King .module_eeprom = sfp_module_eeprom, 2476d740513fSAndrew Lunn .module_eeprom_by_page = sfp_module_eeprom_by_page, 247773970055SRussell King }; 247873970055SRussell King 247973970055SRussell King static void sfp_timeout(struct work_struct *work) 248073970055SRussell King { 248173970055SRussell King struct sfp *sfp = container_of(work, struct sfp, timeout.work); 248273970055SRussell King 248373970055SRussell King rtnl_lock(); 248473970055SRussell King sfp_sm_event(sfp, SFP_E_TIMEOUT); 248573970055SRussell King rtnl_unlock(); 248673970055SRussell King } 248773970055SRussell King 248873970055SRussell King static void sfp_check_state(struct sfp *sfp) 248973970055SRussell King { 249073970055SRussell King unsigned int state, i, changed; 249173970055SRussell King 24922158e856SRobert Hancock mutex_lock(&sfp->st_mutex); 249373970055SRussell King state = sfp_get_state(sfp); 249473970055SRussell King changed = state ^ sfp->state; 24952069624dSMatthew Hagan if (sfp->tx_fault_ignore) 24962069624dSMatthew Hagan changed &= SFP_F_PRESENT | SFP_F_LOS; 24972069624dSMatthew Hagan else 249873970055SRussell King changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT; 249973970055SRussell King 250073970055SRussell King for (i = 0; i < GPIO_MAX; i++) 250173970055SRussell King if (changed & BIT(i)) 250273970055SRussell King dev_dbg(sfp->dev, "%s %u -> %u\n", gpio_of_names[i], 250373970055SRussell King !!(sfp->state & BIT(i)), !!(state & BIT(i))); 250473970055SRussell King 250573970055SRussell King state |= sfp->state & (SFP_F_TX_DISABLE | SFP_F_RATE_SELECT); 250673970055SRussell King sfp->state = state; 250773970055SRussell King 250873970055SRussell King rtnl_lock(); 250973970055SRussell King if (changed & SFP_F_PRESENT) 251073970055SRussell King sfp_sm_event(sfp, state & SFP_F_PRESENT ? 251173970055SRussell King SFP_E_INSERT : SFP_E_REMOVE); 251273970055SRussell King 251373970055SRussell King if (changed & SFP_F_TX_FAULT) 251473970055SRussell King sfp_sm_event(sfp, state & SFP_F_TX_FAULT ? 251573970055SRussell King SFP_E_TX_FAULT : SFP_E_TX_CLEAR); 251673970055SRussell King 251773970055SRussell King if (changed & SFP_F_LOS) 251873970055SRussell King sfp_sm_event(sfp, state & SFP_F_LOS ? 251973970055SRussell King SFP_E_LOS_HIGH : SFP_E_LOS_LOW); 252073970055SRussell King rtnl_unlock(); 25212158e856SRobert Hancock mutex_unlock(&sfp->st_mutex); 252273970055SRussell King } 252373970055SRussell King 252473970055SRussell King static irqreturn_t sfp_irq(int irq, void *data) 252573970055SRussell King { 252673970055SRussell King struct sfp *sfp = data; 252773970055SRussell King 252873970055SRussell King sfp_check_state(sfp); 252973970055SRussell King 253073970055SRussell King return IRQ_HANDLED; 253173970055SRussell King } 253273970055SRussell King 253373970055SRussell King static void sfp_poll(struct work_struct *work) 253473970055SRussell King { 253573970055SRussell King struct sfp *sfp = container_of(work, struct sfp, poll.work); 253673970055SRussell King 253773970055SRussell King sfp_check_state(sfp); 2538f3c9a666SRussell King 2539f3c9a666SRussell King if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) || 2540f3c9a666SRussell King sfp->need_poll) 254173970055SRussell King mod_delayed_work(system_wq, &sfp->poll, poll_jiffies); 254273970055SRussell King } 254373970055SRussell King 254473970055SRussell King static struct sfp *sfp_alloc(struct device *dev) 254573970055SRussell King { 254673970055SRussell King struct sfp *sfp; 254773970055SRussell King 254873970055SRussell King sfp = kzalloc(sizeof(*sfp), GFP_KERNEL); 254973970055SRussell King if (!sfp) 255073970055SRussell King return ERR_PTR(-ENOMEM); 255173970055SRussell King 255273970055SRussell King sfp->dev = dev; 255373970055SRussell King 255473970055SRussell King mutex_init(&sfp->sm_mutex); 25552158e856SRobert Hancock mutex_init(&sfp->st_mutex); 255673970055SRussell King INIT_DELAYED_WORK(&sfp->poll, sfp_poll); 255773970055SRussell King INIT_DELAYED_WORK(&sfp->timeout, sfp_timeout); 255873970055SRussell King 2559139d3a21SRussell King sfp_hwmon_init(sfp); 2560139d3a21SRussell King 256173970055SRussell King return sfp; 256273970055SRussell King } 256373970055SRussell King 256473970055SRussell King static void sfp_cleanup(void *data) 256573970055SRussell King { 256673970055SRussell King struct sfp *sfp = data; 256773970055SRussell King 2568139d3a21SRussell King sfp_hwmon_exit(sfp); 2569139d3a21SRussell King 257073970055SRussell King cancel_delayed_work_sync(&sfp->poll); 257173970055SRussell King cancel_delayed_work_sync(&sfp->timeout); 257273970055SRussell King if (sfp->i2c_mii) { 257373970055SRussell King mdiobus_unregister(sfp->i2c_mii); 257473970055SRussell King mdiobus_free(sfp->i2c_mii); 257573970055SRussell King } 257673970055SRussell King if (sfp->i2c) 257773970055SRussell King i2c_put_adapter(sfp->i2c); 257873970055SRussell King kfree(sfp); 257973970055SRussell King } 258073970055SRussell King 258173970055SRussell King static int sfp_probe(struct platform_device *pdev) 258273970055SRussell King { 2583259c8618SRussell King const struct sff_data *sff; 25847ce236faSRuslan Babayev struct i2c_adapter *i2c; 25855411ca71SChris Healy char *sfp_irq_name; 258673970055SRussell King struct sfp *sfp; 2587257c2559SRobert Hancock int err, i; 258873970055SRussell King 258973970055SRussell King sfp = sfp_alloc(&pdev->dev); 259073970055SRussell King if (IS_ERR(sfp)) 259173970055SRussell King return PTR_ERR(sfp); 259273970055SRussell King 259373970055SRussell King platform_set_drvdata(pdev, sfp); 259473970055SRussell King 25950a18d802SJianglei Nie err = devm_add_action_or_reset(sfp->dev, sfp_cleanup, sfp); 259673970055SRussell King if (err < 0) 259773970055SRussell King return err; 259873970055SRussell King 2599259c8618SRussell King sff = sfp->type = &sfp_data; 2600259c8618SRussell King 260173970055SRussell King if (pdev->dev.of_node) { 260273970055SRussell King struct device_node *node = pdev->dev.of_node; 2603259c8618SRussell King const struct of_device_id *id; 260473970055SRussell King struct device_node *np; 260573970055SRussell King 2606259c8618SRussell King id = of_match_node(sfp_of_match, node); 2607259c8618SRussell King if (WARN_ON(!id)) 2608259c8618SRussell King return -EINVAL; 2609259c8618SRussell King 2610259c8618SRussell King sff = sfp->type = id->data; 2611259c8618SRussell King 261273970055SRussell King np = of_parse_phandle(node, "i2c-bus", 0); 261366ede1f9SAntoine Tenart if (!np) { 261466ede1f9SAntoine Tenart dev_err(sfp->dev, "missing 'i2c-bus' property\n"); 261566ede1f9SAntoine Tenart return -ENODEV; 261666ede1f9SAntoine Tenart } 261773970055SRussell King 261873970055SRussell King i2c = of_find_i2c_adapter_by_node(np); 261973970055SRussell King of_node_put(np); 26207ce236faSRuslan Babayev } else if (has_acpi_companion(&pdev->dev)) { 26217ce236faSRuslan Babayev struct acpi_device *adev = ACPI_COMPANION(&pdev->dev); 26227ce236faSRuslan Babayev struct fwnode_handle *fw = acpi_fwnode_handle(adev); 26237ce236faSRuslan Babayev struct fwnode_reference_args args; 26247ce236faSRuslan Babayev struct acpi_handle *acpi_handle; 26257ce236faSRuslan Babayev int ret; 26267ce236faSRuslan Babayev 26277ce236faSRuslan Babayev ret = acpi_node_get_property_reference(fw, "i2c-bus", 0, &args); 26281086ca3aSDan Carpenter if (ret || !is_acpi_device_node(args.fwnode)) { 26297ce236faSRuslan Babayev dev_err(&pdev->dev, "missing 'i2c-bus' property\n"); 26307ce236faSRuslan Babayev return -ENODEV; 26317ce236faSRuslan Babayev } 26327ce236faSRuslan Babayev 26337ce236faSRuslan Babayev acpi_handle = ACPI_HANDLE_FWNODE(args.fwnode); 26347ce236faSRuslan Babayev i2c = i2c_acpi_find_adapter_by_handle(acpi_handle); 26357ce236faSRuslan Babayev } else { 26367ce236faSRuslan Babayev return -EINVAL; 26377ce236faSRuslan Babayev } 26387ce236faSRuslan Babayev 263973970055SRussell King if (!i2c) 264073970055SRussell King return -EPROBE_DEFER; 264173970055SRussell King 264273970055SRussell King err = sfp_i2c_configure(sfp, i2c); 264373970055SRussell King if (err < 0) { 264473970055SRussell King i2c_put_adapter(i2c); 264573970055SRussell King return err; 264673970055SRussell King } 264773970055SRussell King 2648259c8618SRussell King for (i = 0; i < GPIO_MAX; i++) 2649259c8618SRussell King if (sff->gpios & BIT(i)) { 265073970055SRussell King sfp->gpio[i] = devm_gpiod_get_optional(sfp->dev, 265173970055SRussell King gpio_of_names[i], gpio_flags[i]); 265273970055SRussell King if (IS_ERR(sfp->gpio[i])) 265373970055SRussell King return PTR_ERR(sfp->gpio[i]); 265473970055SRussell King } 265573970055SRussell King 26568475c4b7SRussell King (Oracle) sfp->state_hw_mask = SFP_F_PRESENT; 26578475c4b7SRussell King (Oracle) 265873970055SRussell King sfp->get_state = sfp_gpio_get_state; 265973970055SRussell King sfp->set_state = sfp_gpio_set_state; 2660259c8618SRussell King 2661259c8618SRussell King /* Modules that have no detect signal are always present */ 2662259c8618SRussell King if (!(sfp->gpio[GPIO_MODDEF0])) 2663259c8618SRussell King sfp->get_state = sff_gpio_get_state; 266473970055SRussell King 26653bb35261SJon Nettleton device_property_read_u32(&pdev->dev, "maximum-power-milliwatt", 26663bb35261SJon Nettleton &sfp->max_power_mW); 26673bb35261SJon Nettleton if (!sfp->max_power_mW) 26683bb35261SJon Nettleton sfp->max_power_mW = 1000; 26693bb35261SJon Nettleton 26703bb35261SJon Nettleton dev_info(sfp->dev, "Host maximum power %u.%uW\n", 26713bb35261SJon Nettleton sfp->max_power_mW / 1000, (sfp->max_power_mW / 100) % 10); 26723bb35261SJon Nettleton 267373970055SRussell King /* Get the initial state, and always signal TX disable, 267473970055SRussell King * since the network interface will not be up. 267573970055SRussell King */ 267673970055SRussell King sfp->state = sfp_get_state(sfp) | SFP_F_TX_DISABLE; 267773970055SRussell King 267873970055SRussell King if (sfp->gpio[GPIO_RATE_SELECT] && 267973970055SRussell King gpiod_get_value_cansleep(sfp->gpio[GPIO_RATE_SELECT])) 268073970055SRussell King sfp->state |= SFP_F_RATE_SELECT; 268173970055SRussell King sfp_set_state(sfp, sfp->state); 268273970055SRussell King sfp_module_tx_disable(sfp); 268373f5e847SRussell King if (sfp->state & SFP_F_PRESENT) { 268473f5e847SRussell King rtnl_lock(); 268573f5e847SRussell King sfp_sm_event(sfp, SFP_E_INSERT); 268673f5e847SRussell King rtnl_unlock(); 268773f5e847SRussell King } 268873970055SRussell King 268973970055SRussell King for (i = 0; i < GPIO_MAX; i++) { 269073970055SRussell King if (gpio_flags[i] != GPIOD_IN || !sfp->gpio[i]) 269173970055SRussell King continue; 269273970055SRussell King 2693257c2559SRobert Hancock sfp->gpio_irq[i] = gpiod_to_irq(sfp->gpio[i]); 269496216181SYueHaibing if (sfp->gpio_irq[i] < 0) { 269596216181SYueHaibing sfp->gpio_irq[i] = 0; 2696f3c9a666SRussell King sfp->need_poll = true; 269773970055SRussell King continue; 269873970055SRussell King } 269973970055SRussell King 27005411ca71SChris Healy sfp_irq_name = devm_kasprintf(sfp->dev, GFP_KERNEL, 27015411ca71SChris Healy "%s-%s", dev_name(sfp->dev), 27025411ca71SChris Healy gpio_of_names[i]); 27035411ca71SChris Healy 27048cb601f1SChris Healy if (!sfp_irq_name) 27058cb601f1SChris Healy return -ENOMEM; 27068cb601f1SChris Healy 2707257c2559SRobert Hancock err = devm_request_threaded_irq(sfp->dev, sfp->gpio_irq[i], 2708257c2559SRobert Hancock NULL, sfp_irq, 270973970055SRussell King IRQF_ONESHOT | 271073970055SRussell King IRQF_TRIGGER_RISING | 271173970055SRussell King IRQF_TRIGGER_FALLING, 27125411ca71SChris Healy sfp_irq_name, sfp); 2713257c2559SRobert Hancock if (err) { 2714257c2559SRobert Hancock sfp->gpio_irq[i] = 0; 2715f3c9a666SRussell King sfp->need_poll = true; 271673970055SRussell King } 2717257c2559SRobert Hancock } 271873970055SRussell King 2719f3c9a666SRussell King if (sfp->need_poll) 272073970055SRussell King mod_delayed_work(system_wq, &sfp->poll, poll_jiffies); 272173970055SRussell King 2722a1f5d1f0SAntoine Tenart /* We could have an issue in cases no Tx disable pin is available or 2723a1f5d1f0SAntoine Tenart * wired as modules using a laser as their light source will continue to 2724a1f5d1f0SAntoine Tenart * be active when the fiber is removed. This could be a safety issue and 2725a1f5d1f0SAntoine Tenart * we should at least warn the user about that. 2726a1f5d1f0SAntoine Tenart */ 2727a1f5d1f0SAntoine Tenart if (!sfp->gpio[GPIO_TX_DISABLE]) 2728a1f5d1f0SAntoine Tenart dev_warn(sfp->dev, 2729a1f5d1f0SAntoine Tenart "No tx_disable pin: SFP modules will always be emitting.\n"); 2730a1f5d1f0SAntoine Tenart 2731b5bfc21aSRussell King sfp->sfp_bus = sfp_register_socket(sfp->dev, sfp, &sfp_module_ops); 2732b5bfc21aSRussell King if (!sfp->sfp_bus) 2733b5bfc21aSRussell King return -ENOMEM; 2734b5bfc21aSRussell King 27359cc8976cSRussell King sfp_debugfs_init(sfp); 27369cc8976cSRussell King 273773970055SRussell King return 0; 273873970055SRussell King } 273973970055SRussell King 274073970055SRussell King static int sfp_remove(struct platform_device *pdev) 274173970055SRussell King { 274273970055SRussell King struct sfp *sfp = platform_get_drvdata(pdev); 274373970055SRussell King 27449cc8976cSRussell King sfp_debugfs_exit(sfp); 274573970055SRussell King sfp_unregister_socket(sfp->sfp_bus); 274673970055SRussell King 27470cb96b57SRussell King rtnl_lock(); 27480cb96b57SRussell King sfp_sm_event(sfp, SFP_E_REMOVE); 27490cb96b57SRussell King rtnl_unlock(); 27500cb96b57SRussell King 275173970055SRussell King return 0; 275273970055SRussell King } 275373970055SRussell King 2754257c2559SRobert Hancock static void sfp_shutdown(struct platform_device *pdev) 2755257c2559SRobert Hancock { 2756257c2559SRobert Hancock struct sfp *sfp = platform_get_drvdata(pdev); 2757257c2559SRobert Hancock int i; 2758257c2559SRobert Hancock 2759257c2559SRobert Hancock for (i = 0; i < GPIO_MAX; i++) { 2760257c2559SRobert Hancock if (!sfp->gpio_irq[i]) 2761257c2559SRobert Hancock continue; 2762257c2559SRobert Hancock 2763257c2559SRobert Hancock devm_free_irq(sfp->dev, sfp->gpio_irq[i], sfp); 2764257c2559SRobert Hancock } 2765257c2559SRobert Hancock 2766257c2559SRobert Hancock cancel_delayed_work_sync(&sfp->poll); 2767257c2559SRobert Hancock cancel_delayed_work_sync(&sfp->timeout); 2768257c2559SRobert Hancock } 2769257c2559SRobert Hancock 277073970055SRussell King static struct platform_driver sfp_driver = { 277173970055SRussell King .probe = sfp_probe, 277273970055SRussell King .remove = sfp_remove, 2773257c2559SRobert Hancock .shutdown = sfp_shutdown, 277473970055SRussell King .driver = { 277573970055SRussell King .name = "sfp", 277673970055SRussell King .of_match_table = sfp_of_match, 277773970055SRussell King }, 277873970055SRussell King }; 277973970055SRussell King 278073970055SRussell King static int sfp_init(void) 278173970055SRussell King { 278273970055SRussell King poll_jiffies = msecs_to_jiffies(100); 278373970055SRussell King 278473970055SRussell King return platform_driver_register(&sfp_driver); 278573970055SRussell King } 278673970055SRussell King module_init(sfp_init); 278773970055SRussell King 278873970055SRussell King static void sfp_exit(void) 278973970055SRussell King { 279073970055SRussell King platform_driver_unregister(&sfp_driver); 279173970055SRussell King } 279273970055SRussell King module_exit(sfp_exit); 279373970055SRussell King 279473970055SRussell King MODULE_ALIAS("platform:sfp"); 279573970055SRussell King MODULE_AUTHOR("Russell King"); 279673970055SRussell King MODULE_LICENSE("GPL v2"); 2797