1cb6b8299SEric Joyner /****************************************************************************** 2cb6b8299SEric Joyner 3ceebc2f3SEric Joyner Copyright (c) 2013-2017, Intel Corporation 4cb6b8299SEric Joyner All rights reserved. 5cb6b8299SEric Joyner 6cb6b8299SEric Joyner Redistribution and use in source and binary forms, with or without 7cb6b8299SEric Joyner modification, are permitted provided that the following conditions are met: 8cb6b8299SEric Joyner 9cb6b8299SEric Joyner 1. Redistributions of source code must retain the above copyright notice, 10cb6b8299SEric Joyner this list of conditions and the following disclaimer. 11cb6b8299SEric Joyner 12cb6b8299SEric Joyner 2. Redistributions in binary form must reproduce the above copyright 13cb6b8299SEric Joyner notice, this list of conditions and the following disclaimer in the 14cb6b8299SEric Joyner documentation and/or other materials provided with the distribution. 15cb6b8299SEric Joyner 16cb6b8299SEric Joyner 3. Neither the name of the Intel Corporation nor the names of its 17cb6b8299SEric Joyner contributors may be used to endorse or promote products derived from 18cb6b8299SEric Joyner this software without specific prior written permission. 19cb6b8299SEric Joyner 20cb6b8299SEric Joyner THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21cb6b8299SEric Joyner AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22cb6b8299SEric Joyner IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23cb6b8299SEric Joyner ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24cb6b8299SEric Joyner LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25cb6b8299SEric Joyner CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26cb6b8299SEric Joyner SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27cb6b8299SEric Joyner INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28cb6b8299SEric Joyner CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29cb6b8299SEric Joyner ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30cb6b8299SEric Joyner POSSIBILITY OF SUCH DAMAGE. 31cb6b8299SEric Joyner 32cb6b8299SEric Joyner ******************************************************************************/ 33cb6b8299SEric Joyner /*$FreeBSD$*/ 34cb6b8299SEric Joyner 35cb6b8299SEric Joyner #include "ixl_pf.h" 36cb6b8299SEric Joyner 37cb6b8299SEric Joyner #define IXL_I2C_T_RISE 1 38cb6b8299SEric Joyner #define IXL_I2C_T_FALL 1 39cb6b8299SEric Joyner #define IXL_I2C_T_SU_DATA 1 40cb6b8299SEric Joyner #define IXL_I2C_T_SU_STA 5 41cb6b8299SEric Joyner #define IXL_I2C_T_SU_STO 4 42cb6b8299SEric Joyner #define IXL_I2C_T_HD_STA 4 43cb6b8299SEric Joyner #define IXL_I2C_T_LOW 5 44cb6b8299SEric Joyner #define IXL_I2C_T_HIGH 4 45cb6b8299SEric Joyner #define IXL_I2C_T_BUF 5 46cb6b8299SEric Joyner #define IXL_I2C_CLOCK_STRETCHING_TIMEOUT 500 47cb6b8299SEric Joyner 48cb6b8299SEric Joyner #define IXL_I2C_REG(_hw) \ 49*1031d839SEric Joyner I40E_GLGEN_I2CPARAMS(_hw->func_caps.mdio_port_num) 50cb6b8299SEric Joyner 51*1031d839SEric Joyner /* I2C bit-banging functions */ 52cb6b8299SEric Joyner static s32 ixl_set_i2c_data(struct ixl_pf *pf, u32 *i2cctl, bool data); 53cb6b8299SEric Joyner static bool ixl_get_i2c_data(struct ixl_pf *pf, u32 *i2cctl); 54cb6b8299SEric Joyner static void ixl_raise_i2c_clk(struct ixl_pf *pf, u32 *i2cctl); 55cb6b8299SEric Joyner static void ixl_lower_i2c_clk(struct ixl_pf *pf, u32 *i2cctl); 56cb6b8299SEric Joyner static s32 ixl_clock_out_i2c_bit(struct ixl_pf *pf, bool data); 57cb6b8299SEric Joyner static s32 ixl_get_i2c_ack(struct ixl_pf *pf); 58cb6b8299SEric Joyner static s32 ixl_clock_out_i2c_byte(struct ixl_pf *pf, u8 data); 59cb6b8299SEric Joyner static s32 ixl_clock_in_i2c_bit(struct ixl_pf *pf, bool *data); 60cb6b8299SEric Joyner static s32 ixl_clock_in_i2c_byte(struct ixl_pf *pf, u8 *data); 61cb6b8299SEric Joyner static void ixl_i2c_bus_clear(struct ixl_pf *pf); 62cb6b8299SEric Joyner static void ixl_i2c_start(struct ixl_pf *pf); 63cb6b8299SEric Joyner static void ixl_i2c_stop(struct ixl_pf *pf); 64cb6b8299SEric Joyner 65*1031d839SEric Joyner static s32 ixl_wait_for_i2c_completion(struct i40e_hw *hw, u8 portnum); 66*1031d839SEric Joyner 67cb6b8299SEric Joyner /** 68cb6b8299SEric Joyner * ixl_i2c_bus_clear - Clears the I2C bus 69cb6b8299SEric Joyner * @hw: pointer to hardware structure 70cb6b8299SEric Joyner * 71cb6b8299SEric Joyner * Clears the I2C bus by sending nine clock pulses. 72cb6b8299SEric Joyner * Used when data line is stuck low. 73cb6b8299SEric Joyner **/ 74cb6b8299SEric Joyner static void 75cb6b8299SEric Joyner ixl_i2c_bus_clear(struct ixl_pf *pf) 76cb6b8299SEric Joyner { 77cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw; 78cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw)); 79cb6b8299SEric Joyner u32 i; 80cb6b8299SEric Joyner 81cb6b8299SEric Joyner DEBUGFUNC("ixl_i2c_bus_clear"); 82cb6b8299SEric Joyner 83cb6b8299SEric Joyner ixl_i2c_start(pf); 84cb6b8299SEric Joyner 85cb6b8299SEric Joyner ixl_set_i2c_data(pf, &i2cctl, 1); 86cb6b8299SEric Joyner 87cb6b8299SEric Joyner for (i = 0; i < 9; i++) { 88cb6b8299SEric Joyner ixl_raise_i2c_clk(pf, &i2cctl); 89cb6b8299SEric Joyner 90cb6b8299SEric Joyner /* Min high period of clock is 4us */ 91cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_HIGH); 92cb6b8299SEric Joyner 93cb6b8299SEric Joyner ixl_lower_i2c_clk(pf, &i2cctl); 94cb6b8299SEric Joyner 95cb6b8299SEric Joyner /* Min low period of clock is 4.7us*/ 96cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_LOW); 97cb6b8299SEric Joyner } 98cb6b8299SEric Joyner 99cb6b8299SEric Joyner ixl_i2c_start(pf); 100cb6b8299SEric Joyner 101cb6b8299SEric Joyner /* Put the i2c bus back to default state */ 102cb6b8299SEric Joyner ixl_i2c_stop(pf); 103cb6b8299SEric Joyner } 104cb6b8299SEric Joyner 105cb6b8299SEric Joyner /** 106cb6b8299SEric Joyner * ixl_i2c_stop - Sets I2C stop condition 107cb6b8299SEric Joyner * @hw: pointer to hardware structure 108cb6b8299SEric Joyner * 109cb6b8299SEric Joyner * Sets I2C stop condition (Low -> High on SDA while SCL is High) 110cb6b8299SEric Joyner **/ 111cb6b8299SEric Joyner static void 112cb6b8299SEric Joyner ixl_i2c_stop(struct ixl_pf *pf) 113cb6b8299SEric Joyner { 114cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw; 115cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw)); 116cb6b8299SEric Joyner 117cb6b8299SEric Joyner DEBUGFUNC("ixl_i2c_stop"); 118cb6b8299SEric Joyner 119cb6b8299SEric Joyner /* Stop condition must begin with data low and clock high */ 120cb6b8299SEric Joyner ixl_set_i2c_data(pf, &i2cctl, 0); 121cb6b8299SEric Joyner ixl_raise_i2c_clk(pf, &i2cctl); 122cb6b8299SEric Joyner 123cb6b8299SEric Joyner /* Setup time for stop condition (4us) */ 124cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_SU_STO); 125cb6b8299SEric Joyner 126cb6b8299SEric Joyner ixl_set_i2c_data(pf, &i2cctl, 1); 127cb6b8299SEric Joyner 128cb6b8299SEric Joyner /* bus free time between stop and start (4.7us)*/ 129cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_BUF); 130cb6b8299SEric Joyner } 131cb6b8299SEric Joyner 132cb6b8299SEric Joyner /** 133cb6b8299SEric Joyner * ixl_clock_in_i2c_byte - Clocks in one byte via I2C 134cb6b8299SEric Joyner * @hw: pointer to hardware structure 135cb6b8299SEric Joyner * @data: data byte to clock in 136cb6b8299SEric Joyner * 137cb6b8299SEric Joyner * Clocks in one byte data via I2C data/clock 138cb6b8299SEric Joyner **/ 139cb6b8299SEric Joyner static s32 140cb6b8299SEric Joyner ixl_clock_in_i2c_byte(struct ixl_pf *pf, u8 *data) 141cb6b8299SEric Joyner { 142cb6b8299SEric Joyner s32 i; 143cb6b8299SEric Joyner bool bit = 0; 144cb6b8299SEric Joyner 145cb6b8299SEric Joyner DEBUGFUNC("ixl_clock_in_i2c_byte"); 146cb6b8299SEric Joyner 147cb6b8299SEric Joyner for (i = 7; i >= 0; i--) { 148cb6b8299SEric Joyner ixl_clock_in_i2c_bit(pf, &bit); 149cb6b8299SEric Joyner *data |= bit << i; 150cb6b8299SEric Joyner } 151cb6b8299SEric Joyner 152cb6b8299SEric Joyner return I40E_SUCCESS; 153cb6b8299SEric Joyner } 154cb6b8299SEric Joyner 155cb6b8299SEric Joyner /** 156cb6b8299SEric Joyner * ixl_clock_in_i2c_bit - Clocks in one bit via I2C data/clock 157cb6b8299SEric Joyner * @hw: pointer to hardware structure 158cb6b8299SEric Joyner * @data: read data value 159cb6b8299SEric Joyner * 160cb6b8299SEric Joyner * Clocks in one bit via I2C data/clock 161cb6b8299SEric Joyner **/ 162cb6b8299SEric Joyner static s32 163cb6b8299SEric Joyner ixl_clock_in_i2c_bit(struct ixl_pf *pf, bool *data) 164cb6b8299SEric Joyner { 165cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw; 166cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw)); 167cb6b8299SEric Joyner 168cb6b8299SEric Joyner DEBUGFUNC("ixl_clock_in_i2c_bit"); 169cb6b8299SEric Joyner 170cb6b8299SEric Joyner ixl_raise_i2c_clk(pf, &i2cctl); 171cb6b8299SEric Joyner 172cb6b8299SEric Joyner /* Minimum high period of clock is 4us */ 173cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_HIGH); 174cb6b8299SEric Joyner 175cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw)); 176cb6b8299SEric Joyner i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK; 177cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl); 178cb6b8299SEric Joyner ixl_flush(hw); 179cb6b8299SEric Joyner 180cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw)); 181cb6b8299SEric Joyner *data = ixl_get_i2c_data(pf, &i2cctl); 182cb6b8299SEric Joyner 183cb6b8299SEric Joyner ixl_lower_i2c_clk(pf, &i2cctl); 184cb6b8299SEric Joyner 185cb6b8299SEric Joyner /* Minimum low period of clock is 4.7 us */ 186cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_LOW); 187cb6b8299SEric Joyner 188cb6b8299SEric Joyner return I40E_SUCCESS; 189cb6b8299SEric Joyner } 190cb6b8299SEric Joyner 191cb6b8299SEric Joyner /** 192cb6b8299SEric Joyner * ixl_get_i2c_ack - Polls for I2C ACK 193cb6b8299SEric Joyner * @hw: pointer to hardware structure 194cb6b8299SEric Joyner * 195cb6b8299SEric Joyner * Clocks in/out one bit via I2C data/clock 196cb6b8299SEric Joyner **/ 197cb6b8299SEric Joyner static s32 198cb6b8299SEric Joyner ixl_get_i2c_ack(struct ixl_pf *pf) 199cb6b8299SEric Joyner { 200cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw; 201cb6b8299SEric Joyner s32 status = I40E_SUCCESS; 202cb6b8299SEric Joyner u32 i = 0; 203cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw)); 204cb6b8299SEric Joyner u32 timeout = 10; 205cb6b8299SEric Joyner bool ack = 1; 206cb6b8299SEric Joyner 207cb6b8299SEric Joyner ixl_raise_i2c_clk(pf, &i2cctl); 208cb6b8299SEric Joyner 209cb6b8299SEric Joyner /* Minimum high period of clock is 4us */ 210cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_HIGH); 211cb6b8299SEric Joyner 212cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw)); 213cb6b8299SEric Joyner i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK; 214cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl); 215cb6b8299SEric Joyner ixl_flush(hw); 216cb6b8299SEric Joyner 217cb6b8299SEric Joyner /* Poll for ACK. Note that ACK in I2C spec is 218cb6b8299SEric Joyner * transition from 1 to 0 */ 219cb6b8299SEric Joyner for (i = 0; i < timeout; i++) { 220cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw)); 221cb6b8299SEric Joyner ack = ixl_get_i2c_data(pf, &i2cctl); 222cb6b8299SEric Joyner 223cb6b8299SEric Joyner i40e_usec_delay(1); 224cb6b8299SEric Joyner if (!ack) 225cb6b8299SEric Joyner break; 226cb6b8299SEric Joyner } 227cb6b8299SEric Joyner 228cb6b8299SEric Joyner if (ack) { 229cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C ack was not received.\n"); 230cb6b8299SEric Joyner status = I40E_ERR_PHY; 231cb6b8299SEric Joyner } 232cb6b8299SEric Joyner 233cb6b8299SEric Joyner ixl_lower_i2c_clk(pf, &i2cctl); 234cb6b8299SEric Joyner 235cb6b8299SEric Joyner /* Minimum low period of clock is 4.7 us */ 236cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_LOW); 237cb6b8299SEric Joyner 238cb6b8299SEric Joyner return status; 239cb6b8299SEric Joyner } 240cb6b8299SEric Joyner 241cb6b8299SEric Joyner /** 242cb6b8299SEric Joyner * ixl_clock_out_i2c_bit - Clocks in/out one bit via I2C data/clock 243cb6b8299SEric Joyner * @hw: pointer to hardware structure 244cb6b8299SEric Joyner * @data: data value to write 245cb6b8299SEric Joyner * 246cb6b8299SEric Joyner * Clocks out one bit via I2C data/clock 247cb6b8299SEric Joyner **/ 248cb6b8299SEric Joyner static s32 249cb6b8299SEric Joyner ixl_clock_out_i2c_bit(struct ixl_pf *pf, bool data) 250cb6b8299SEric Joyner { 251cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw; 252cb6b8299SEric Joyner s32 status; 253cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw)); 254cb6b8299SEric Joyner 255cb6b8299SEric Joyner status = ixl_set_i2c_data(pf, &i2cctl, data); 256cb6b8299SEric Joyner if (status == I40E_SUCCESS) { 257cb6b8299SEric Joyner ixl_raise_i2c_clk(pf, &i2cctl); 258cb6b8299SEric Joyner 259cb6b8299SEric Joyner /* Minimum high period of clock is 4us */ 260cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_HIGH); 261cb6b8299SEric Joyner 262cb6b8299SEric Joyner ixl_lower_i2c_clk(pf, &i2cctl); 263cb6b8299SEric Joyner 264cb6b8299SEric Joyner /* Minimum low period of clock is 4.7 us. 265cb6b8299SEric Joyner * This also takes care of the data hold time. 266cb6b8299SEric Joyner */ 267cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_LOW); 268cb6b8299SEric Joyner } else { 269cb6b8299SEric Joyner status = I40E_ERR_PHY; 270cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C data was not set to %#x\n", data); 271cb6b8299SEric Joyner } 272cb6b8299SEric Joyner 273cb6b8299SEric Joyner return status; 274cb6b8299SEric Joyner } 275cb6b8299SEric Joyner 276cb6b8299SEric Joyner /** 277cb6b8299SEric Joyner * ixl_clock_out_i2c_byte - Clocks out one byte via I2C 278cb6b8299SEric Joyner * @hw: pointer to hardware structure 279cb6b8299SEric Joyner * @data: data byte clocked out 280cb6b8299SEric Joyner * 281cb6b8299SEric Joyner * Clocks out one byte data via I2C data/clock 282cb6b8299SEric Joyner **/ 283cb6b8299SEric Joyner static s32 284cb6b8299SEric Joyner ixl_clock_out_i2c_byte(struct ixl_pf *pf, u8 data) 285cb6b8299SEric Joyner { 286cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw; 287cb6b8299SEric Joyner s32 status = I40E_SUCCESS; 288cb6b8299SEric Joyner s32 i; 289cb6b8299SEric Joyner u32 i2cctl; 290cb6b8299SEric Joyner bool bit; 291cb6b8299SEric Joyner 292cb6b8299SEric Joyner DEBUGFUNC("ixl_clock_out_i2c_byte"); 293cb6b8299SEric Joyner 294cb6b8299SEric Joyner for (i = 7; i >= 0; i--) { 295cb6b8299SEric Joyner bit = (data >> i) & 0x1; 296cb6b8299SEric Joyner status = ixl_clock_out_i2c_bit(pf, bit); 297cb6b8299SEric Joyner 298cb6b8299SEric Joyner if (status != I40E_SUCCESS) 299cb6b8299SEric Joyner break; 300cb6b8299SEric Joyner } 301cb6b8299SEric Joyner 302cb6b8299SEric Joyner /* Release SDA line (set high) */ 303cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw)); 304cb6b8299SEric Joyner i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK; 305cb6b8299SEric Joyner i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK); 306cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl); 307cb6b8299SEric Joyner ixl_flush(hw); 308cb6b8299SEric Joyner 309cb6b8299SEric Joyner return status; 310cb6b8299SEric Joyner } 311cb6b8299SEric Joyner 312cb6b8299SEric Joyner /** 313cb6b8299SEric Joyner * ixl_lower_i2c_clk - Lowers the I2C SCL clock 314cb6b8299SEric Joyner * @hw: pointer to hardware structure 315cb6b8299SEric Joyner * @i2cctl: Current value of I2CCTL register 316cb6b8299SEric Joyner * 317cb6b8299SEric Joyner * Lowers the I2C clock line '1'->'0' 318cb6b8299SEric Joyner **/ 319cb6b8299SEric Joyner static void 320cb6b8299SEric Joyner ixl_lower_i2c_clk(struct ixl_pf *pf, u32 *i2cctl) 321cb6b8299SEric Joyner { 322cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw; 323cb6b8299SEric Joyner 324cb6b8299SEric Joyner *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_MASK); 325cb6b8299SEric Joyner *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK); 326cb6b8299SEric Joyner 327cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), *i2cctl); 328cb6b8299SEric Joyner ixl_flush(hw); 329cb6b8299SEric Joyner 330cb6b8299SEric Joyner /* SCL fall time (300ns) */ 331cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_FALL); 332cb6b8299SEric Joyner } 333cb6b8299SEric Joyner 334cb6b8299SEric Joyner /** 335cb6b8299SEric Joyner * ixl_raise_i2c_clk - Raises the I2C SCL clock 336cb6b8299SEric Joyner * @hw: pointer to hardware structure 337cb6b8299SEric Joyner * @i2cctl: Current value of I2CCTL register 338cb6b8299SEric Joyner * 339cb6b8299SEric Joyner * Raises the I2C clock line '0'->'1' 340cb6b8299SEric Joyner **/ 341cb6b8299SEric Joyner static void 342cb6b8299SEric Joyner ixl_raise_i2c_clk(struct ixl_pf *pf, u32 *i2cctl) 343cb6b8299SEric Joyner { 344cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw; 345cb6b8299SEric Joyner u32 i = 0; 346cb6b8299SEric Joyner u32 timeout = IXL_I2C_CLOCK_STRETCHING_TIMEOUT; 347cb6b8299SEric Joyner u32 i2cctl_r = 0; 348cb6b8299SEric Joyner 349cb6b8299SEric Joyner for (i = 0; i < timeout; i++) { 350cb6b8299SEric Joyner *i2cctl |= I40E_GLGEN_I2CPARAMS_CLK_MASK; 351cb6b8299SEric Joyner *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_CLK_OE_N_MASK); 352cb6b8299SEric Joyner 353cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), *i2cctl); 354cb6b8299SEric Joyner ixl_flush(hw); 355cb6b8299SEric Joyner /* SCL rise time (1000ns) */ 356cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_RISE); 357cb6b8299SEric Joyner 358cb6b8299SEric Joyner i2cctl_r = rd32(hw, IXL_I2C_REG(hw)); 359cb6b8299SEric Joyner if (i2cctl_r & I40E_GLGEN_I2CPARAMS_CLK_IN_MASK) 360cb6b8299SEric Joyner break; 361cb6b8299SEric Joyner } 362cb6b8299SEric Joyner } 363cb6b8299SEric Joyner 364cb6b8299SEric Joyner /** 365cb6b8299SEric Joyner * ixl_get_i2c_data - Reads the I2C SDA data bit 366cb6b8299SEric Joyner * @hw: pointer to hardware structure 367cb6b8299SEric Joyner * @i2cctl: Current value of I2CCTL register 368cb6b8299SEric Joyner * 369cb6b8299SEric Joyner * Returns the I2C data bit value 370cb6b8299SEric Joyner **/ 371cb6b8299SEric Joyner static bool 372cb6b8299SEric Joyner ixl_get_i2c_data(struct ixl_pf *pf, u32 *i2cctl) 373cb6b8299SEric Joyner { 374cb6b8299SEric Joyner bool data; 375cb6b8299SEric Joyner 376cb6b8299SEric Joyner if (*i2cctl & I40E_GLGEN_I2CPARAMS_DATA_IN_MASK) 377cb6b8299SEric Joyner data = 1; 378cb6b8299SEric Joyner else 379cb6b8299SEric Joyner data = 0; 380cb6b8299SEric Joyner 381cb6b8299SEric Joyner return data; 382cb6b8299SEric Joyner } 383cb6b8299SEric Joyner 384cb6b8299SEric Joyner /** 385cb6b8299SEric Joyner * ixl_set_i2c_data - Sets the I2C data bit 386cb6b8299SEric Joyner * @hw: pointer to hardware structure 387cb6b8299SEric Joyner * @i2cctl: Current value of I2CCTL register 388cb6b8299SEric Joyner * @data: I2C data value (0 or 1) to set 389cb6b8299SEric Joyner * 390cb6b8299SEric Joyner * Sets the I2C data bit 391cb6b8299SEric Joyner **/ 392cb6b8299SEric Joyner static s32 393cb6b8299SEric Joyner ixl_set_i2c_data(struct ixl_pf *pf, u32 *i2cctl, bool data) 394cb6b8299SEric Joyner { 395cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw; 396cb6b8299SEric Joyner s32 status = I40E_SUCCESS; 397cb6b8299SEric Joyner 398cb6b8299SEric Joyner DEBUGFUNC("ixl_set_i2c_data"); 399cb6b8299SEric Joyner 400cb6b8299SEric Joyner if (data) 401cb6b8299SEric Joyner *i2cctl |= I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK; 402cb6b8299SEric Joyner else 403cb6b8299SEric Joyner *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OUT_MASK); 404cb6b8299SEric Joyner *i2cctl &= ~(I40E_GLGEN_I2CPARAMS_DATA_OE_N_MASK); 405cb6b8299SEric Joyner 406cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), *i2cctl); 407cb6b8299SEric Joyner ixl_flush(hw); 408cb6b8299SEric Joyner 409cb6b8299SEric Joyner /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */ 410cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_RISE + IXL_I2C_T_FALL + IXL_I2C_T_SU_DATA); 411cb6b8299SEric Joyner 412cb6b8299SEric Joyner /* Verify data was set correctly */ 413cb6b8299SEric Joyner *i2cctl = rd32(hw, IXL_I2C_REG(hw)); 414cb6b8299SEric Joyner if (data != ixl_get_i2c_data(pf, i2cctl)) { 415cb6b8299SEric Joyner status = I40E_ERR_PHY; 416cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "Error - I2C data was not set to %X.\n", data); 417cb6b8299SEric Joyner } 418cb6b8299SEric Joyner 419cb6b8299SEric Joyner return status; 420cb6b8299SEric Joyner } 421cb6b8299SEric Joyner 422cb6b8299SEric Joyner /** 423cb6b8299SEric Joyner * ixl_i2c_start - Sets I2C start condition 424cb6b8299SEric Joyner * Sets I2C start condition (High -> Low on SDA while SCL is High) 425cb6b8299SEric Joyner **/ 426cb6b8299SEric Joyner static void 427cb6b8299SEric Joyner ixl_i2c_start(struct ixl_pf *pf) 428cb6b8299SEric Joyner { 429cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw; 430cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw)); 431cb6b8299SEric Joyner 432cb6b8299SEric Joyner DEBUGFUNC("ixl_i2c_start"); 433cb6b8299SEric Joyner 434cb6b8299SEric Joyner /* Start condition must begin with data and clock high */ 435cb6b8299SEric Joyner ixl_set_i2c_data(pf, &i2cctl, 1); 436cb6b8299SEric Joyner ixl_raise_i2c_clk(pf, &i2cctl); 437cb6b8299SEric Joyner 438cb6b8299SEric Joyner /* Setup time for start condition (4.7us) */ 439cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_SU_STA); 440cb6b8299SEric Joyner 441cb6b8299SEric Joyner ixl_set_i2c_data(pf, &i2cctl, 0); 442cb6b8299SEric Joyner 443cb6b8299SEric Joyner /* Hold time for start condition (4us) */ 444cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_HD_STA); 445cb6b8299SEric Joyner 446cb6b8299SEric Joyner ixl_lower_i2c_clk(pf, &i2cctl); 447cb6b8299SEric Joyner 448cb6b8299SEric Joyner /* Minimum low period of clock is 4.7 us */ 449cb6b8299SEric Joyner i40e_usec_delay(IXL_I2C_T_LOW); 450cb6b8299SEric Joyner 451cb6b8299SEric Joyner } 452cb6b8299SEric Joyner 453cb6b8299SEric Joyner /** 454*1031d839SEric Joyner * ixl_read_i2c_byte_bb - Reads 8 bit word over I2C 455cb6b8299SEric Joyner **/ 456cb6b8299SEric Joyner s32 457*1031d839SEric Joyner ixl_read_i2c_byte_bb(struct ixl_pf *pf, u8 byte_offset, 458cb6b8299SEric Joyner u8 dev_addr, u8 *data) 459cb6b8299SEric Joyner { 460cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw; 461cb6b8299SEric Joyner u32 max_retry = 10; 462cb6b8299SEric Joyner u32 retry = 0; 463cb6b8299SEric Joyner bool nack = 1; 464cb6b8299SEric Joyner s32 status; 465cb6b8299SEric Joyner *data = 0; 466cb6b8299SEric Joyner 467cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw)); 468cb6b8299SEric Joyner i2cctl |= I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK; 469cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl); 470cb6b8299SEric Joyner ixl_flush(hw); 471cb6b8299SEric Joyner 472cb6b8299SEric Joyner do { 473cb6b8299SEric Joyner ixl_i2c_start(pf); 474cb6b8299SEric Joyner 475cb6b8299SEric Joyner /* Device Address and write indication */ 476cb6b8299SEric Joyner status = ixl_clock_out_i2c_byte(pf, dev_addr); 477cb6b8299SEric Joyner if (status != I40E_SUCCESS) { 478cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "dev_addr clock out error\n"); 479cb6b8299SEric Joyner goto fail; 480cb6b8299SEric Joyner } 481cb6b8299SEric Joyner 482cb6b8299SEric Joyner status = ixl_get_i2c_ack(pf); 483cb6b8299SEric Joyner if (status != I40E_SUCCESS) { 484cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "dev_addr i2c ack error\n"); 485cb6b8299SEric Joyner goto fail; 486cb6b8299SEric Joyner } 487cb6b8299SEric Joyner 488cb6b8299SEric Joyner status = ixl_clock_out_i2c_byte(pf, byte_offset); 489cb6b8299SEric Joyner if (status != I40E_SUCCESS) { 490cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "byte_offset clock out error\n"); 491cb6b8299SEric Joyner goto fail; 492cb6b8299SEric Joyner } 493cb6b8299SEric Joyner 494cb6b8299SEric Joyner status = ixl_get_i2c_ack(pf); 495cb6b8299SEric Joyner if (status != I40E_SUCCESS) { 496cb6b8299SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "byte_offset i2c ack error\n"); 497cb6b8299SEric Joyner goto fail; 498cb6b8299SEric Joyner } 499cb6b8299SEric Joyner 500cb6b8299SEric Joyner ixl_i2c_start(pf); 501cb6b8299SEric Joyner 502cb6b8299SEric Joyner /* Device Address and read indication */ 503cb6b8299SEric Joyner status = ixl_clock_out_i2c_byte(pf, (dev_addr | 0x1)); 504cb6b8299SEric Joyner if (status != I40E_SUCCESS) 505cb6b8299SEric Joyner goto fail; 506cb6b8299SEric Joyner 507cb6b8299SEric Joyner status = ixl_get_i2c_ack(pf); 508cb6b8299SEric Joyner if (status != I40E_SUCCESS) 509cb6b8299SEric Joyner goto fail; 510cb6b8299SEric Joyner 511cb6b8299SEric Joyner status = ixl_clock_in_i2c_byte(pf, data); 512cb6b8299SEric Joyner if (status != I40E_SUCCESS) 513cb6b8299SEric Joyner goto fail; 514cb6b8299SEric Joyner 515cb6b8299SEric Joyner status = ixl_clock_out_i2c_bit(pf, nack); 516cb6b8299SEric Joyner if (status != I40E_SUCCESS) 517cb6b8299SEric Joyner goto fail; 518cb6b8299SEric Joyner 519cb6b8299SEric Joyner ixl_i2c_stop(pf); 520cb6b8299SEric Joyner status = I40E_SUCCESS; 521cb6b8299SEric Joyner goto done; 522cb6b8299SEric Joyner 523cb6b8299SEric Joyner fail: 524cb6b8299SEric Joyner ixl_i2c_bus_clear(pf); 525cb6b8299SEric Joyner i40e_msec_delay(100); 526cb6b8299SEric Joyner retry++; 527cb6b8299SEric Joyner if (retry < max_retry) 528*1031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read error - Retrying\n"); 529cb6b8299SEric Joyner else 530*1031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read error\n"); 531cb6b8299SEric Joyner 532cb6b8299SEric Joyner } while (retry < max_retry); 533cb6b8299SEric Joyner done: 534cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw)); 535cb6b8299SEric Joyner i2cctl &= ~I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK; 536cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl); 537cb6b8299SEric Joyner ixl_flush(hw); 538cb6b8299SEric Joyner 539cb6b8299SEric Joyner return status; 540cb6b8299SEric Joyner } 541cb6b8299SEric Joyner 542cb6b8299SEric Joyner /** 543*1031d839SEric Joyner * ixl_write_i2c_byte_bb - Writes 8 bit word over I2C 544cb6b8299SEric Joyner **/ 545cb6b8299SEric Joyner s32 546*1031d839SEric Joyner ixl_write_i2c_byte_bb(struct ixl_pf *pf, u8 byte_offset, 547cb6b8299SEric Joyner u8 dev_addr, u8 data) 548cb6b8299SEric Joyner { 549cb6b8299SEric Joyner struct i40e_hw *hw = &pf->hw; 550cb6b8299SEric Joyner s32 status = I40E_SUCCESS; 551cb6b8299SEric Joyner u32 max_retry = 1; 552cb6b8299SEric Joyner u32 retry = 0; 553cb6b8299SEric Joyner 554cb6b8299SEric Joyner u32 i2cctl = rd32(hw, IXL_I2C_REG(hw)); 555cb6b8299SEric Joyner i2cctl |= I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK; 556cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl); 557cb6b8299SEric Joyner ixl_flush(hw); 558cb6b8299SEric Joyner 559cb6b8299SEric Joyner do { 560cb6b8299SEric Joyner ixl_i2c_start(pf); 561cb6b8299SEric Joyner 562cb6b8299SEric Joyner status = ixl_clock_out_i2c_byte(pf, dev_addr); 563cb6b8299SEric Joyner if (status != I40E_SUCCESS) 564cb6b8299SEric Joyner goto fail; 565cb6b8299SEric Joyner 566cb6b8299SEric Joyner status = ixl_get_i2c_ack(pf); 567cb6b8299SEric Joyner if (status != I40E_SUCCESS) 568cb6b8299SEric Joyner goto fail; 569cb6b8299SEric Joyner 570cb6b8299SEric Joyner status = ixl_clock_out_i2c_byte(pf, byte_offset); 571cb6b8299SEric Joyner if (status != I40E_SUCCESS) 572cb6b8299SEric Joyner goto fail; 573cb6b8299SEric Joyner 574cb6b8299SEric Joyner status = ixl_get_i2c_ack(pf); 575cb6b8299SEric Joyner if (status != I40E_SUCCESS) 576cb6b8299SEric Joyner goto fail; 577cb6b8299SEric Joyner 578cb6b8299SEric Joyner status = ixl_clock_out_i2c_byte(pf, data); 579cb6b8299SEric Joyner if (status != I40E_SUCCESS) 580cb6b8299SEric Joyner goto fail; 581cb6b8299SEric Joyner 582cb6b8299SEric Joyner status = ixl_get_i2c_ack(pf); 583cb6b8299SEric Joyner if (status != I40E_SUCCESS) 584cb6b8299SEric Joyner goto fail; 585cb6b8299SEric Joyner 586cb6b8299SEric Joyner ixl_i2c_stop(pf); 587cb6b8299SEric Joyner goto write_byte_out; 588cb6b8299SEric Joyner 589cb6b8299SEric Joyner fail: 590cb6b8299SEric Joyner ixl_i2c_bus_clear(pf); 591cb6b8299SEric Joyner i40e_msec_delay(100); 592cb6b8299SEric Joyner retry++; 593cb6b8299SEric Joyner if (retry < max_retry) 594*1031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write error - Retrying\n"); 595cb6b8299SEric Joyner else 596*1031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write error\n"); 597cb6b8299SEric Joyner } while (retry < max_retry); 598cb6b8299SEric Joyner 599cb6b8299SEric Joyner write_byte_out: 600cb6b8299SEric Joyner i2cctl = rd32(hw, IXL_I2C_REG(hw)); 601cb6b8299SEric Joyner i2cctl &= ~I40E_GLGEN_I2CPARAMS_I2CBB_EN_MASK; 602cb6b8299SEric Joyner wr32(hw, IXL_I2C_REG(hw), i2cctl); 603cb6b8299SEric Joyner ixl_flush(hw); 604cb6b8299SEric Joyner 605cb6b8299SEric Joyner return status; 606cb6b8299SEric Joyner } 607cb6b8299SEric Joyner 608*1031d839SEric Joyner /** 609*1031d839SEric Joyner * ixl_read_i2c_byte - Reads 8 bit word over I2C using a hardware register 610*1031d839SEric Joyner **/ 611*1031d839SEric Joyner s32 612*1031d839SEric Joyner ixl_read_i2c_byte_reg(struct ixl_pf *pf, u8 byte_offset, 613*1031d839SEric Joyner u8 dev_addr, u8 *data) 614*1031d839SEric Joyner { 615*1031d839SEric Joyner struct i40e_hw *hw = &pf->hw; 616*1031d839SEric Joyner u32 reg = 0; 617*1031d839SEric Joyner s32 status; 618*1031d839SEric Joyner *data = 0; 619*1031d839SEric Joyner 620*1031d839SEric Joyner reg |= (byte_offset << I40E_GLGEN_I2CCMD_REGADD_SHIFT); 621*1031d839SEric Joyner reg |= (((dev_addr >> 1) & 0x7) << I40E_GLGEN_I2CCMD_PHYADD_SHIFT); 622*1031d839SEric Joyner reg |= I40E_GLGEN_I2CCMD_OP_MASK; 623*1031d839SEric Joyner wr32(hw, I40E_GLGEN_I2CCMD(hw->func_caps.mdio_port_num), reg); 624*1031d839SEric Joyner 625*1031d839SEric Joyner status = ixl_wait_for_i2c_completion(hw, hw->func_caps.mdio_port_num); 626*1031d839SEric Joyner 627*1031d839SEric Joyner /* Get data from I2C register */ 628*1031d839SEric Joyner reg = rd32(hw, I40E_GLGEN_I2CCMD(hw->func_caps.mdio_port_num)); 629*1031d839SEric Joyner 630*1031d839SEric Joyner /* Retrieve data readed from EEPROM */ 631*1031d839SEric Joyner *data = (u8)(reg & 0xff); 632*1031d839SEric Joyner 633*1031d839SEric Joyner if (status) 634*1031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read error\n"); 635*1031d839SEric Joyner return status; 636*1031d839SEric Joyner } 637*1031d839SEric Joyner 638*1031d839SEric Joyner /** 639*1031d839SEric Joyner * ixl_write_i2c_byte - Writes 8 bit word over I2C using a hardware register 640*1031d839SEric Joyner **/ 641*1031d839SEric Joyner s32 642*1031d839SEric Joyner ixl_write_i2c_byte_reg(struct ixl_pf *pf, u8 byte_offset, 643*1031d839SEric Joyner u8 dev_addr, u8 data) 644*1031d839SEric Joyner { 645*1031d839SEric Joyner struct i40e_hw *hw = &pf->hw; 646*1031d839SEric Joyner s32 status = I40E_SUCCESS; 647*1031d839SEric Joyner u32 reg = 0; 648*1031d839SEric Joyner u8 upperbyte = 0; 649*1031d839SEric Joyner u16 datai2c = 0; 650*1031d839SEric Joyner 651*1031d839SEric Joyner status = ixl_read_i2c_byte_reg(pf, byte_offset + 1, dev_addr, &upperbyte); 652*1031d839SEric Joyner datai2c = ((u16)upperbyte << 8) | (u16)data; 653*1031d839SEric Joyner reg = rd32(hw, I40E_GLGEN_I2CCMD(hw->func_caps.mdio_port_num)); 654*1031d839SEric Joyner 655*1031d839SEric Joyner /* Form write command */ 656*1031d839SEric Joyner reg &= ~I40E_GLGEN_I2CCMD_PHYADD_MASK; 657*1031d839SEric Joyner reg |= (((dev_addr >> 1) & 0x7) << I40E_GLGEN_I2CCMD_PHYADD_SHIFT); 658*1031d839SEric Joyner reg &= ~I40E_GLGEN_I2CCMD_REGADD_MASK; 659*1031d839SEric Joyner reg |= (byte_offset << I40E_GLGEN_I2CCMD_REGADD_SHIFT); 660*1031d839SEric Joyner reg &= ~I40E_GLGEN_I2CCMD_DATA_MASK; 661*1031d839SEric Joyner reg |= (datai2c << I40E_GLGEN_I2CCMD_DATA_SHIFT); 662*1031d839SEric Joyner reg &= ~I40E_GLGEN_I2CCMD_OP_MASK; 663*1031d839SEric Joyner 664*1031d839SEric Joyner /* Write command to registers controling I2C - data and address. */ 665*1031d839SEric Joyner wr32(hw, I40E_GLGEN_I2CCMD(hw->func_caps.mdio_port_num), reg); 666*1031d839SEric Joyner 667*1031d839SEric Joyner status = ixl_wait_for_i2c_completion(hw, hw->func_caps.mdio_port_num); 668*1031d839SEric Joyner 669*1031d839SEric Joyner if (status) 670*1031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write error\n"); 671*1031d839SEric Joyner return status; 672*1031d839SEric Joyner } 673*1031d839SEric Joyner 674*1031d839SEric Joyner /** 675*1031d839SEric Joyner * ixl_wait_for_i2c_completion 676*1031d839SEric Joyner **/ 677*1031d839SEric Joyner static s32 678*1031d839SEric Joyner ixl_wait_for_i2c_completion(struct i40e_hw *hw, u8 portnum) 679*1031d839SEric Joyner { 680*1031d839SEric Joyner s32 status = 0; 681*1031d839SEric Joyner u32 timeout = 100; 682*1031d839SEric Joyner u32 reg; 683*1031d839SEric Joyner do { 684*1031d839SEric Joyner reg = rd32(hw, I40E_GLGEN_I2CCMD(portnum)); 685*1031d839SEric Joyner if ((reg & I40E_GLGEN_I2CCMD_R_MASK) != 0) 686*1031d839SEric Joyner break; 687*1031d839SEric Joyner i40e_usec_delay(10); 688*1031d839SEric Joyner } while (timeout-- > 0); 689*1031d839SEric Joyner 690*1031d839SEric Joyner if (timeout == 0) 691*1031d839SEric Joyner return I40E_ERR_TIMEOUT; 692*1031d839SEric Joyner else 693*1031d839SEric Joyner return status; 694*1031d839SEric Joyner } 695*1031d839SEric Joyner 696*1031d839SEric Joyner /** 697*1031d839SEric Joyner * ixl_read_i2c_byte - Reads 8 bit word over I2C using a hardware register 698*1031d839SEric Joyner **/ 699*1031d839SEric Joyner s32 700*1031d839SEric Joyner ixl_read_i2c_byte_aq(struct ixl_pf *pf, u8 byte_offset, 701*1031d839SEric Joyner u8 dev_addr, u8 *data) 702*1031d839SEric Joyner { 703*1031d839SEric Joyner struct i40e_hw *hw = &pf->hw; 704*1031d839SEric Joyner s32 status = I40E_SUCCESS; 705*1031d839SEric Joyner u32 reg; 706*1031d839SEric Joyner 707*1031d839SEric Joyner status = i40e_aq_get_phy_register(hw, 708*1031d839SEric Joyner I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE, 709*1031d839SEric Joyner dev_addr, 710*1031d839SEric Joyner byte_offset, 711*1031d839SEric Joyner ®, NULL); 712*1031d839SEric Joyner 713*1031d839SEric Joyner if (status) 714*1031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte read status %s, error %s\n", 715*1031d839SEric Joyner i40e_stat_str(hw, status), i40e_aq_str(hw, hw->aq.asq_last_status)); 716*1031d839SEric Joyner else 717*1031d839SEric Joyner *data = (u8)reg; 718*1031d839SEric Joyner 719*1031d839SEric Joyner return status; 720*1031d839SEric Joyner } 721*1031d839SEric Joyner 722*1031d839SEric Joyner /** 723*1031d839SEric Joyner * ixl_write_i2c_byte - Writes 8 bit word over I2C using a hardware register 724*1031d839SEric Joyner **/ 725*1031d839SEric Joyner s32 726*1031d839SEric Joyner ixl_write_i2c_byte_aq(struct ixl_pf *pf, u8 byte_offset, 727*1031d839SEric Joyner u8 dev_addr, u8 data) 728*1031d839SEric Joyner { 729*1031d839SEric Joyner struct i40e_hw *hw = &pf->hw; 730*1031d839SEric Joyner s32 status = I40E_SUCCESS; 731*1031d839SEric Joyner 732*1031d839SEric Joyner status = i40e_aq_set_phy_register(hw, 733*1031d839SEric Joyner I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE, 734*1031d839SEric Joyner dev_addr, 735*1031d839SEric Joyner byte_offset, 736*1031d839SEric Joyner data, NULL); 737*1031d839SEric Joyner 738*1031d839SEric Joyner if (status) 739*1031d839SEric Joyner ixl_dbg(pf, IXL_DBG_I2C, "I2C byte write status %s, error %s\n", 740*1031d839SEric Joyner i40e_stat_str(hw, status), i40e_aq_str(hw, hw->aq.asq_last_status)); 741*1031d839SEric Joyner 742*1031d839SEric Joyner return status; 743*1031d839SEric Joyner } 744