@@ -1654,6 +1654,137 @@ static int hw_atl_b0_get_mac_temp(struct aq_hw_s *self, u32 *temp)
16541654 return 0 ;
16551655}
16561656
1657+ #define START_TRANSMIT 0x5001
1658+ #define START_READ_TRANSMIT 0x5101
1659+ #define STOP_TRANSMIT 0x3001
1660+ #define REPEAT_TRANSMIT 0x1001
1661+ #define REPEAT_NACK_TRANSMIT 0x1011
1662+
1663+ static int hw_atl_b0_smb0_wait_result (struct aq_hw_s * self , bool expect_ack )
1664+ {
1665+ int err ;
1666+ u32 val ;
1667+
1668+ err = readx_poll_timeout (hw_atl_smb0_byte_transfer_complete_get ,
1669+ self , val , val == 1 , 100U , 10000U );
1670+ if (err )
1671+ return err ;
1672+ if (hw_atl_smb0_receive_acknowledged_get (self ) != expect_ack )
1673+ return - EIO ;
1674+ return 0 ;
1675+ }
1676+
1677+ /* Starts an I2C/SMBUS write to a given address. addr is in 7-bit format,
1678+ * the read/write bit is not part of it.
1679+ */
1680+ static int hw_atl_b0_smb0_start_write (struct aq_hw_s * self , u32 addr )
1681+ {
1682+ hw_atl_smb0_tx_data_set (self , (addr << 1 ) | 0 );
1683+ hw_atl_smb0_provisioning2_set (self , START_TRANSMIT );
1684+ return hw_atl_b0_smb0_wait_result (self , 0 );
1685+ }
1686+
1687+ /* Writes a single byte as part of an ongoing write started by start_write. */
1688+ static int hw_atl_b0_smb0_write_byte (struct aq_hw_s * self , u32 data )
1689+ {
1690+ hw_atl_smb0_tx_data_set (self , data );
1691+ hw_atl_smb0_provisioning2_set (self , REPEAT_TRANSMIT );
1692+ return hw_atl_b0_smb0_wait_result (self , 0 );
1693+ }
1694+
1695+ /* Starts an I2C/SMBUS read to a given address. addr is in 7-bit format,
1696+ * the read/write bit is not part of it.
1697+ */
1698+ static int hw_atl_b0_smb0_start_read (struct aq_hw_s * self , u32 addr )
1699+ {
1700+ int err ;
1701+
1702+ hw_atl_smb0_tx_data_set (self , (addr << 1 ) | 1 );
1703+ hw_atl_smb0_provisioning2_set (self , START_READ_TRANSMIT );
1704+ err = hw_atl_b0_smb0_wait_result (self , 0 );
1705+ if (err )
1706+ return err ;
1707+ if (hw_atl_smb0_repeated_start_detect_get (self ) == 0 )
1708+ return - EIO ;
1709+ return 0 ;
1710+ }
1711+
1712+ /* Reads a single byte as part of an ongoing read started by start_read. */
1713+ static int hw_atl_b0_smb0_read_byte (struct aq_hw_s * self )
1714+ {
1715+ int err ;
1716+
1717+ hw_atl_smb0_provisioning2_set (self , REPEAT_TRANSMIT );
1718+ err = hw_atl_b0_smb0_wait_result (self , 0 );
1719+ if (err )
1720+ return err ;
1721+ return hw_atl_smb0_rx_data_get (self );
1722+ }
1723+
1724+ /* Reads the last byte of an ongoing read. */
1725+ static int hw_atl_b0_smb0_read_byte_nack (struct aq_hw_s * self )
1726+ {
1727+ int err ;
1728+
1729+ hw_atl_smb0_provisioning2_set (self , REPEAT_NACK_TRANSMIT );
1730+ err = hw_atl_b0_smb0_wait_result (self , 1 );
1731+ if (err )
1732+ return err ;
1733+ return hw_atl_smb0_rx_data_get (self );
1734+ }
1735+
1736+ /* Sends a stop condition and ends a transfer. */
1737+ static void hw_atl_b0_smb0_stop (struct aq_hw_s * self )
1738+ {
1739+ hw_atl_smb0_provisioning2_set (self , STOP_TRANSMIT );
1740+ }
1741+
1742+ static int hw_atl_b0_read_module_eeprom (struct aq_hw_s * self , u8 dev_addr ,
1743+ u8 reg_start_addr , int len , u8 * data )
1744+ {
1745+ int i , b ;
1746+ int err ;
1747+ u32 val ;
1748+
1749+ /* Wait for SMBUS0 to be idle */
1750+ err = readx_poll_timeout (hw_atl_smb0_bus_busy_get , self ,
1751+ val , val == 0 , 100U , 10000U );
1752+ if (err )
1753+ return err ;
1754+
1755+ err = hw_atl_b0_smb0_start_write (self , dev_addr );
1756+ if (err )
1757+ goto out ;
1758+
1759+ err = hw_atl_b0_smb0_write_byte (self , reg_start_addr );
1760+ if (err )
1761+ goto out ;
1762+
1763+ err = hw_atl_b0_smb0_start_read (self , dev_addr );
1764+ if (err )
1765+ goto out ;
1766+
1767+ for (i = 0 ; i < len - 1 ; i ++ ) {
1768+ b = hw_atl_b0_smb0_read_byte (self );
1769+ if (b < 0 ) {
1770+ err = b ;
1771+ goto out ;
1772+ }
1773+ data [i ] = (u8 )b ;
1774+ }
1775+
1776+ b = hw_atl_b0_smb0_read_byte_nack (self );
1777+ if (b < 0 ) {
1778+ err = b ;
1779+ goto out ;
1780+ }
1781+ data [i ] = (u8 )b ;
1782+
1783+ out :
1784+ hw_atl_b0_smb0_stop (self );
1785+ return err ;
1786+ }
1787+
16571788const struct aq_hw_ops hw_atl_ops_b0 = {
16581789 .hw_soft_reset = hw_atl_utils_soft_reset ,
16591790 .hw_prepare = hw_atl_utils_initfw ,
@@ -1712,4 +1843,5 @@ const struct aq_hw_ops hw_atl_ops_b0 = {
17121843 .hw_set_fc = hw_atl_b0_set_fc ,
17131844
17141845 .hw_get_mac_temp = hw_atl_b0_get_mac_temp ,
1846+ .hw_read_module_eeprom = hw_atl_b0_read_module_eeprom ,
17151847};
0 commit comments