Files

572 lines
17 KiB
Diff
Raw Permalink Normal View History

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 9b8217523fd2..15d77ccb749d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -771,6 +771,13 @@ struct ixgbe_adapter {
u32 atr_sample_rate;
spinlock_t fdir_perfect_lock;
+ struct ixgbe_etqf_entry {
+ bool used;
+ u32 loc;
+ u16 etype;
+ u8 ring;
+ } etqf_filters[IXGBE_MAX_ETQF_FILTERS];
+
bool fw_emp_reset_disabled;
#ifdef IXGBE_FCOE
@@ -1010,6 +1017,8 @@ void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
int ixgbe_update_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
struct ixgbe_fdir_filter *input,
u16 sw_idx);
+void ixgbe_etqf_filter_restore(struct ixgbe_adapter *adapter);
+void ixgbe_etqf_filter_exit(struct ixgbe_adapter *adapter);
void ixgbe_set_rx_mode(struct net_device *netdev);
#ifdef CONFIG_IXGBE_DCB
void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c
index 5b1cf49df3d3..75689ca7eb2d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c
@@ -5,6 +5,7 @@
#include <linux/module.h>
#include "ixgbe.h"
+#include "ixgbe_phy.h"
static struct dentry *ixgbe_dbg_root;
@@ -185,6 +186,123 @@ static const struct file_operations ixgbe_dbg_netdev_ops_fops = {
.write = ixgbe_dbg_netdev_ops_write,
};
+#define IXGBE_SFF_I2C_MAX 32
+
+struct ixgbe_sff_i2c_ctx {
+ struct ixgbe_adapter *adapter;
+ int resp_len;
+ char resp[IXGBE_SFF_I2C_MAX * 3 + 16];
+};
+
+static int ixgbe_dbg_sff_i2c_open(struct inode *inode, struct file *filp)
+{
+ struct ixgbe_sff_i2c_ctx *ctx;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+ ctx->adapter = inode->i_private;
+ filp->private_data = ctx;
+ return 0;
+}
+
+static int ixgbe_dbg_sff_i2c_release(struct inode *inode, struct file *filp)
+{
+ kfree(filp->private_data);
+ return 0;
+}
+
+static ssize_t ixgbe_dbg_sff_i2c_write(struct file *filp,
+ const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct ixgbe_sff_i2c_ctx *ctx = filp->private_data;
+ struct ixgbe_hw *hw = &ctx->adapter->hw;
+ u8 data[IXGBE_SFF_I2C_MAX];
+ u8 wdata[IXGBE_SFF_I2C_MAX];
+ char cmd[160];
+ unsigned int addr, raddr, delay, n, wn, v;
+ int status, off, consumed, i;
+ char op;
+
+ if (*ppos != 0 || count >= sizeof(cmd))
+ return -EINVAL;
+ if (copy_from_user(cmd, ubuf, count))
+ return -EFAULT;
+ cmd[count] = '\0';
+
+ if (sscanf(cmd, " %c %x %n", &op, &addr, &off) < 2)
+ return -EINVAL;
+
+ if (op == 'r') {
+ if (sscanf(cmd + off, "%x", &n) != 1 || n < 1 ||
+ n > IXGBE_SFF_I2C_MAX)
+ return -EINVAL;
+ status = ixgbe_i2c_raw_read(hw, addr, data, n);
+ } else if (op == 'w') {
+ n = 0;
+ while (n < IXGBE_SFF_I2C_MAX &&
+ sscanf(cmd + off, "%x%n", &v, &consumed) == 1) {
+ data[n++] = v;
+ off += consumed;
+ }
+ status = ixgbe_i2c_raw_write(hw, addr, data, n);
+ } else if (op == 'x') {
+ if (sscanf(cmd + off, "%x %u %x %n", &raddr, &delay, &n,
+ &consumed) < 3)
+ return -EINVAL;
+ off += consumed;
+ if (n > IXGBE_SFF_I2C_MAX || delay > 50000)
+ return -EINVAL;
+ wn = 0;
+ while (wn < IXGBE_SFF_I2C_MAX &&
+ sscanf(cmd + off, "%x%n", &v, &consumed) == 1) {
+ wdata[wn++] = v;
+ off += consumed;
+ }
+ status = ixgbe_i2c_raw_xfer(hw, addr, wdata, wn, delay,
+ raddr, data, n);
+ } else {
+ return -EINVAL;
+ }
+
+ if (status) {
+ ctx->resp_len = scnprintf(ctx->resp, sizeof(ctx->resp),
+ "err %d\n", status);
+ } else if (op == 'r' || (op == 'x' && n)) {
+ off = scnprintf(ctx->resp, sizeof(ctx->resp), "ok");
+ for (i = 0; i < n; i++)
+ off += scnprintf(ctx->resp + off,
+ sizeof(ctx->resp) - off,
+ " %02x", data[i]);
+ off += scnprintf(ctx->resp + off, sizeof(ctx->resp) - off,
+ "\n");
+ ctx->resp_len = off;
+ } else {
+ ctx->resp_len = scnprintf(ctx->resp, sizeof(ctx->resp), "ok\n");
+ }
+
+ *ppos = 0;
+ return count;
+}
+
+static ssize_t ixgbe_dbg_sff_i2c_read(struct file *filp, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct ixgbe_sff_i2c_ctx *ctx = filp->private_data;
+
+ return simple_read_from_buffer(ubuf, count, ppos, ctx->resp,
+ ctx->resp_len);
+}
+
+static const struct file_operations ixgbe_dbg_sff_i2c_fops = {
+ .owner = THIS_MODULE,
+ .open = ixgbe_dbg_sff_i2c_open,
+ .release = ixgbe_dbg_sff_i2c_release,
+ .read = ixgbe_dbg_sff_i2c_read,
+ .write = ixgbe_dbg_sff_i2c_write,
+};
+
/**
* ixgbe_dbg_adapter_init - setup the debugfs directory for the adapter
* @adapter: the adapter that is starting up
@@ -198,6 +316,8 @@ void ixgbe_dbg_adapter_init(struct ixgbe_adapter *adapter)
adapter, &ixgbe_dbg_reg_ops_fops);
debugfs_create_file("netdev_ops", 0600, adapter->ixgbe_dbg_adapter,
adapter, &ixgbe_dbg_netdev_ops_fops);
+ debugfs_create_file("sff_i2c", 0600, adapter->ixgbe_dbg_adapter,
+ adapter, &ixgbe_dbg_sff_i2c_fops);
}
/**
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 36e43b5e88d1..8bcb0ec0e65d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
@@ -2664,6 +2664,142 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
return 0;
}
+static u32 ixgbe_etqf_filter_count(struct ixgbe_adapter *adapter)
+{
+ u32 n = 0;
+ int i;
+
+ for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++)
+ if (adapter->etqf_filters[i].used)
+ n++;
+ return n;
+}
+
+static int ixgbe_add_etqf_entry(struct ixgbe_adapter *adapter,
+ struct ethtool_rxnfc *cmd)
+{
+ struct ethtool_rx_flow_spec *fsp =
+ (struct ethtool_rx_flow_spec *)&cmd->fs;
+ static const u8 zero_mac[ETH_ALEN];
+ struct ixgbe_etqf_entry *slot = NULL;
+ struct ixgbe_hw *hw = &adapter->hw;
+ u16 etype = ntohs(fsp->h_u.ether_spec.h_proto);
+ u32 ring;
+ int i;
+
+ if (fsp->flow_type != ETHER_FLOW)
+ return -EINVAL;
+ if (fsp->m_u.ether_spec.h_proto != htons(0xFFFF) ||
+ !ether_addr_equal(fsp->m_u.ether_spec.h_dest, zero_mac) ||
+ !ether_addr_equal(fsp->m_u.ether_spec.h_source, zero_mac))
+ return -EINVAL;
+ if (etype == ETH_P_1588)
+ return -EINVAL;
+ if (fsp->ring_cookie == RX_CLS_FLOW_DISC)
+ return -EINVAL;
+ ring = ethtool_get_flow_spec_ring(fsp->ring_cookie);
+ if (ethtool_get_flow_spec_ring_vf(fsp->ring_cookie) ||
+ ring >= adapter->num_rx_queues)
+ return -EINVAL;
+ if (fsp->location >= ((1024 << adapter->fdir_pballoc) - 2))
+ return -EINVAL;
+
+ spin_lock(&adapter->fdir_perfect_lock);
+ for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
+ struct ixgbe_etqf_entry *e = &adapter->etqf_filters[i];
+
+ if (!e->used)
+ continue;
+ if (e->etype == etype && e->loc != fsp->location) {
+ spin_unlock(&adapter->fdir_perfect_lock);
+ return -EEXIST;
+ }
+ if (e->loc == fsp->location)
+ slot = e;
+ }
+ if (!slot) {
+ for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
+ if (i == IXGBE_ETQF_FILTER_1588 ||
+ adapter->etqf_filters[i].used ||
+ (IXGBE_READ_REG(hw, IXGBE_ETQF(i)) &
+ IXGBE_ETQF_FILTER_EN))
+ continue;
+ slot = &adapter->etqf_filters[i];
+ break;
+ }
+ }
+ if (!slot) {
+ spin_unlock(&adapter->fdir_perfect_lock);
+ return -ENOSPC;
+ }
+
+ i = slot - adapter->etqf_filters;
+ slot->used = true;
+ slot->loc = fsp->location;
+ slot->etype = etype;
+ slot->ring = ring;
+ IXGBE_WRITE_REG(hw, IXGBE_ETQS(i), IXGBE_ETQS_QUEUE_EN |
+ ((u32)adapter->rx_ring[ring]->reg_idx <<
+ IXGBE_ETQS_RX_QUEUE_SHIFT));
+ IXGBE_WRITE_REG(hw, IXGBE_ETQF(i), IXGBE_ETQF_FILTER_EN | etype);
+ spin_unlock(&adapter->fdir_perfect_lock);
+
+ return 0;
+}
+
+/* Caller holds fdir_perfect_lock. */
+static int ixgbe_del_etqf_entry(struct ixgbe_adapter *adapter, u32 loc)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
+
+ for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
+ struct ixgbe_etqf_entry *e = &adapter->etqf_filters[i];
+
+ if (!e->used || e->loc != loc)
+ continue;
+ IXGBE_WRITE_REG(hw, IXGBE_ETQF(i), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_ETQS(i), 0);
+ e->used = false;
+ return 0;
+ }
+ return -ENOENT;
+}
+
+void ixgbe_etqf_filter_restore(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
+
+ spin_lock(&adapter->fdir_perfect_lock);
+ for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
+ struct ixgbe_etqf_entry *e = &adapter->etqf_filters[i];
+
+ if (!e->used)
+ continue;
+ if (e->ring >= adapter->num_rx_queues) {
+ e->used = false;
+ continue;
+ }
+ IXGBE_WRITE_REG(hw, IXGBE_ETQS(i), IXGBE_ETQS_QUEUE_EN |
+ ((u32)adapter->rx_ring[e->ring]->reg_idx <<
+ IXGBE_ETQS_RX_QUEUE_SHIFT));
+ IXGBE_WRITE_REG(hw, IXGBE_ETQF(i),
+ IXGBE_ETQF_FILTER_EN | e->etype);
+ }
+ spin_unlock(&adapter->fdir_perfect_lock);
+}
+
+void ixgbe_etqf_filter_exit(struct ixgbe_adapter *adapter)
+{
+ int i;
+
+ spin_lock(&adapter->fdir_perfect_lock);
+ for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++)
+ adapter->etqf_filters[i].used = false;
+ spin_unlock(&adapter->fdir_perfect_lock);
+}
+
static int ixgbe_get_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
struct ethtool_rxnfc *cmd)
{
@@ -2672,10 +2808,23 @@ static int ixgbe_get_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
(struct ethtool_rx_flow_spec *)&cmd->fs;
struct hlist_node *node2;
struct ixgbe_fdir_filter *rule = NULL;
+ int i;
/* report total rule count */
cmd->data = (1024 << adapter->fdir_pballoc) - 2;
+ for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
+ struct ixgbe_etqf_entry *e = &adapter->etqf_filters[i];
+
+ if (!e->used || e->loc != fsp->location)
+ continue;
+ fsp->flow_type = ETHER_FLOW;
+ fsp->h_u.ether_spec.h_proto = htons(e->etype);
+ fsp->m_u.ether_spec.h_proto = htons(0xFFFF);
+ fsp->ring_cookie = e->ring;
+ return 0;
+ }
+
hlist_for_each_entry_safe(rule, node2,
&adapter->fdir_filter_list, fdir_node) {
if (fsp->location <= rule->sw_idx)
@@ -2740,6 +2889,7 @@ static int ixgbe_get_ethtool_fdir_all(struct ixgbe_adapter *adapter,
struct hlist_node *node2;
struct ixgbe_fdir_filter *rule;
int cnt = 0;
+ int i;
/* report total rule count */
cmd->data = (1024 << adapter->fdir_pballoc) - 2;
@@ -2752,6 +2902,17 @@ static int ixgbe_get_ethtool_fdir_all(struct ixgbe_adapter *adapter,
cnt++;
}
+ for (i = 0; i < IXGBE_MAX_ETQF_FILTERS; i++) {
+ struct ixgbe_etqf_entry *e = &adapter->etqf_filters[i];
+
+ if (!e->used)
+ continue;
+ if (cnt == cmd->rule_cnt)
+ return -EMSGSIZE;
+ rule_locs[cnt] = e->loc;
+ cnt++;
+ }
+
cmd->rule_cnt = cnt;
return 0;
@@ -2825,7 +2986,9 @@ static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
switch (cmd->cmd) {
case ETHTOOL_GRXCLSRLCNT:
- cmd->rule_cnt = adapter->fdir_filter_count;
+ cmd->rule_cnt = adapter->fdir_filter_count +
+ ixgbe_etqf_filter_count(adapter);
+ cmd->data = (1024 << adapter->fdir_pballoc) - 2;
ret = 0;
break;
case ETHTOOL_GRXCLSRULE:
@@ -3077,7 +3240,10 @@ static int ixgbe_del_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
int err;
spin_lock(&adapter->fdir_perfect_lock);
- err = ixgbe_update_ethtool_fdir_entry(adapter, NULL, fsp->location);
+ err = ixgbe_del_etqf_entry(adapter, fsp->location);
+ if (err)
+ err = ixgbe_update_ethtool_fdir_entry(adapter, NULL,
+ fsp->location);
spin_unlock(&adapter->fdir_perfect_lock);
return err;
@@ -3207,7 +3373,10 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
switch (cmd->cmd) {
case ETHTOOL_SRXCLSRLINS:
- ret = ixgbe_add_ethtool_fdir_entry(adapter, cmd);
+ if ((cmd->fs.flow_type & ~FLOW_EXT) == ETHER_FLOW)
+ ret = ixgbe_add_etqf_entry(adapter, cmd);
+ else
+ ret = ixgbe_add_ethtool_fdir_entry(adapter, cmd);
break;
case ETHTOOL_SRXCLSRLDEL:
ret = ixgbe_del_ethtool_fdir_entry(adapter, cmd);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
index 011fda9c6193..1b5cb4f7bb68 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
@@ -647,6 +647,10 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
if (!(adapter->netdev->features & NETIF_F_FCOE_CRC))
return;
+ /* leave registers un-configured if FCoE is disabled */
+ if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
+ return;
+
/* Enable L2 EtherType filter for FCoE, needed for FCoE CRC and DDP */
etqf = ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN;
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
@@ -656,10 +660,6 @@ void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE), etqf);
IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0);
- /* leave registers un-configured if FCoE is disabled */
- if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
- return;
-
/* Use one or more Rx queues for FCoE by redirection table */
fcreta_size = IXGBE_FCRETA_SIZE;
if (adapter->hw.mac.type == ixgbe_mac_X550)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 8873a8cc4a18..85fdf1ab4177 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -5911,6 +5911,8 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
ixgbe_fdir_filter_restore(adapter);
}
+ ixgbe_etqf_filter_restore(adapter);
+
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
@@ -7533,6 +7535,7 @@ int ixgbe_close(struct net_device *netdev)
ixgbe_close_suspend(adapter);
ixgbe_fdir_filter_exit(adapter);
+ ixgbe_etqf_filter_exit(adapter);
ixgbe_release_hw_control(adapter);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
index ab733e73927d..fb876b9e9395 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
@@ -60,6 +60,102 @@ static int ixgbe_in_i2c_byte_ack(struct ixgbe_hw *hw, u8 *byte)
return ixgbe_clock_out_i2c_bit(hw, false);
}
+static int ixgbe_i2c_raw_write_unlocked(struct ixgbe_hw *hw, u8 addr,
+ const u8 *buf, u8 len)
+{
+ int status;
+ u8 i;
+
+ ixgbe_i2c_start(hw);
+ status = ixgbe_out_i2c_byte_ack(hw, addr);
+ for (i = 0; !status && i < len; i++)
+ status = ixgbe_out_i2c_byte_ack(hw, buf[i]);
+
+ if (status)
+ ixgbe_i2c_bus_clear(hw);
+ else
+ ixgbe_i2c_stop(hw);
+
+ return status;
+}
+
+static int ixgbe_i2c_raw_read_unlocked(struct ixgbe_hw *hw, u8 addr,
+ u8 *buf, u8 len)
+{
+ u32 i2cctl;
+ int status;
+ u8 i;
+
+ ixgbe_i2c_start(hw);
+ status = ixgbe_out_i2c_byte_ack(hw, addr);
+ for (i = 0; !status && i < len; i++) {
+ status = ixgbe_clock_in_i2c_byte(hw, &buf[i]);
+ if (!status)
+ status = ixgbe_clock_out_i2c_bit(hw, i == len - 1);
+ if (!status && i != len - 1) {
+ /* our ACK left SDA driven low; release it so the
+ * slave can drive the next byte
+ */
+ i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw));
+ i2cctl |= IXGBE_I2C_DATA_OUT(hw);
+ i2cctl |= IXGBE_I2C_DATA_OE_N_EN(hw);
+ IXGBE_WRITE_REG(hw, IXGBE_I2CCTL(hw), i2cctl);
+ IXGBE_WRITE_FLUSH(hw);
+ }
+ }
+
+ if (status)
+ ixgbe_i2c_bus_clear(hw);
+ else
+ ixgbe_i2c_stop(hw);
+
+ return status;
+}
+
+int ixgbe_i2c_raw_write(struct ixgbe_hw *hw, u8 addr, const u8 *buf, u8 len)
+{
+ u32 swfw_mask = hw->phy.phy_semaphore_mask;
+ int status;
+
+ if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
+ return -EBUSY;
+ status = ixgbe_i2c_raw_write_unlocked(hw, addr, buf, len);
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+ return status;
+}
+
+int ixgbe_i2c_raw_read(struct ixgbe_hw *hw, u8 addr, u8 *buf, u8 len)
+{
+ u32 swfw_mask = hw->phy.phy_semaphore_mask;
+ int status;
+
+ if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
+ return -EBUSY;
+ status = ixgbe_i2c_raw_read_unlocked(hw, addr, buf, len);
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+ return status;
+}
+
+int ixgbe_i2c_raw_xfer(struct ixgbe_hw *hw, u8 waddr, const u8 *wbuf, u8 wlen,
+ u32 delay_us, u8 raddr, u8 *rbuf, u8 rlen)
+{
+ u32 swfw_mask = hw->phy.phy_semaphore_mask;
+ int status = 0;
+
+ if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask))
+ return -EBUSY;
+
+ if (wlen)
+ status = ixgbe_i2c_raw_write_unlocked(hw, waddr, wbuf, wlen);
+ if (!status && delay_us)
+ usleep_range(delay_us, delay_us + delay_us / 10 + 10);
+ if (!status && rlen)
+ status = ixgbe_i2c_raw_read_unlocked(hw, raddr, rbuf, rlen);
+
+ hw->mac.ops.release_swfw_sync(hw, swfw_mask);
+ return status;
+}
+
/**
* ixgbe_ones_comp_byte_add - Perform one's complement addition
* @add1: addend 1
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
index 039ba4b6c120..b93bdd972d7a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h
@@ -178,4 +178,8 @@ int ixgbe_read_i2c_combined_generic_int(struct ixgbe_hw *, u8 addr, u16 reg,
u16 *val, bool lock);
int ixgbe_write_i2c_combined_generic_int(struct ixgbe_hw *, u8 addr, u16 reg,
u16 val, bool lock);
+int ixgbe_i2c_raw_write(struct ixgbe_hw *hw, u8 addr, const u8 *buf, u8 len);
+int ixgbe_i2c_raw_read(struct ixgbe_hw *hw, u8 addr, u8 *buf, u8 len);
+int ixgbe_i2c_raw_xfer(struct ixgbe_hw *hw, u8 waddr, const u8 *wbuf, u8 wlen,
+ u32 delay_us, u8 raddr, u8 *rbuf, u8 rlen);
#endif /* _IXGBE_PHY_H_ */