Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next
Jerr Kirsher says: > This series contains updates to igb (specifically PTP code). Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
e97563989a
6 changed files with 422 additions and 63 deletions
|
@ -2014,6 +2014,7 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
|
|||
e1000_unmap_and_free_tx_resource(adapter, buffer_info);
|
||||
}
|
||||
|
||||
netdev_reset_queue(adapter->netdev);
|
||||
size = sizeof(struct e1000_buffer) * tx_ring->count;
|
||||
memset(tx_ring->buffer_info, 0, size);
|
||||
|
||||
|
@ -3262,6 +3263,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
|
|||
nr_frags, mss);
|
||||
|
||||
if (count) {
|
||||
netdev_sent_queue(netdev, skb->len);
|
||||
skb_tx_timestamp(skb);
|
||||
|
||||
e1000_tx_queue(adapter, tx_ring, tx_flags, count);
|
||||
|
@ -3849,6 +3851,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
|
|||
unsigned int i, eop;
|
||||
unsigned int count = 0;
|
||||
unsigned int total_tx_bytes=0, total_tx_packets=0;
|
||||
unsigned int bytes_compl = 0, pkts_compl = 0;
|
||||
|
||||
i = tx_ring->next_to_clean;
|
||||
eop = tx_ring->buffer_info[i].next_to_watch;
|
||||
|
@ -3866,6 +3869,11 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
|
|||
if (cleaned) {
|
||||
total_tx_packets += buffer_info->segs;
|
||||
total_tx_bytes += buffer_info->bytecount;
|
||||
if (buffer_info->skb) {
|
||||
bytes_compl += buffer_info->skb->len;
|
||||
pkts_compl++;
|
||||
}
|
||||
|
||||
}
|
||||
e1000_unmap_and_free_tx_resource(adapter, buffer_info);
|
||||
tx_desc->upper.data = 0;
|
||||
|
@ -3879,6 +3887,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
|
|||
|
||||
tx_ring->next_to_clean = i;
|
||||
|
||||
netdev_completed_queue(netdev, pkts_compl, bytes_compl);
|
||||
|
||||
#define TX_WAKE_THRESHOLD 32
|
||||
if (unlikely(count && netif_carrier_ok(netdev) &&
|
||||
E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
obj-$(CONFIG_IXGBE) += ixgbe.o
|
||||
|
||||
ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
|
||||
ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o ixgbe_debugfs.o\
|
||||
ixgbe_82599.o ixgbe_82598.o ixgbe_phy.o ixgbe_sriov.o \
|
||||
ixgbe_mbx.o ixgbe_x540.o ixgbe_lib.o
|
||||
|
||||
|
|
|
@ -597,6 +597,9 @@ struct ixgbe_adapter {
|
|||
#ifdef CONFIG_IXGBE_HWMON
|
||||
struct hwmon_buff ixgbe_hwmon_buff;
|
||||
#endif /* CONFIG_IXGBE_HWMON */
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *ixgbe_dbg_adapter;
|
||||
#endif /*CONFIG_DEBUG_FS*/
|
||||
};
|
||||
|
||||
struct ixgbe_fdir_filter {
|
||||
|
@ -725,7 +728,12 @@ extern int ixgbe_fcoe_get_hbainfo(struct net_device *netdev,
|
|||
struct netdev_fcoe_hbainfo *info);
|
||||
extern u8 ixgbe_fcoe_get_tc(struct ixgbe_adapter *adapter);
|
||||
#endif /* IXGBE_FCOE */
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
extern void ixgbe_dbg_adapter_init(struct ixgbe_adapter *adapter);
|
||||
extern void ixgbe_dbg_adapter_exit(struct ixgbe_adapter *adapter);
|
||||
extern void ixgbe_dbg_init(void);
|
||||
extern void ixgbe_dbg_exit(void);
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
static inline struct netdev_queue *txring_txq(const struct ixgbe_ring *ring)
|
||||
{
|
||||
return netdev_get_tx_queue(ring->netdev, ring->queue_index);
|
||||
|
|
300
drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c
Normal file
300
drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c
Normal file
|
@ -0,0 +1,300 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Intel 10 Gigabit PCI Express Linux driver
|
||||
Copyright(c) 1999 - 2012 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
||||
|
||||
This program is distributed in the hope it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
The full GNU General Public License is included in this distribution in
|
||||
the file called "COPYING".
|
||||
|
||||
Contact Information:
|
||||
e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
|
||||
Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "ixgbe.h"
|
||||
|
||||
static struct dentry *ixgbe_dbg_root;
|
||||
|
||||
static char ixgbe_dbg_reg_ops_buf[256] = "";
|
||||
|
||||
/**
|
||||
* ixgbe_dbg_reg_ops_open - prep the debugfs pokee data item when opened
|
||||
* @inode: inode that was opened
|
||||
* @filp: file info
|
||||
*
|
||||
* Stash the adapter pointer hiding in the inode into the file pointer where
|
||||
* we can find it later in the read and write calls
|
||||
**/
|
||||
static int ixgbe_dbg_reg_ops_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
filp->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_dbg_reg_ops_read - read for reg_ops datum
|
||||
* @filp: the opened file
|
||||
* @buffer: where to write the data for the user to read
|
||||
* @count: the size of the user's buffer
|
||||
* @ppos: file position offset
|
||||
**/
|
||||
static ssize_t ixgbe_dbg_reg_ops_read(struct file *filp, char __user *buffer,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = filp->private_data;
|
||||
char buf[256];
|
||||
int bytes_not_copied;
|
||||
int len;
|
||||
|
||||
/* don't allow partial reads */
|
||||
if (*ppos != 0)
|
||||
return 0;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%s: %s\n",
|
||||
adapter->netdev->name, ixgbe_dbg_reg_ops_buf);
|
||||
if (count < len)
|
||||
return -ENOSPC;
|
||||
bytes_not_copied = copy_to_user(buffer, buf, len);
|
||||
if (bytes_not_copied < 0)
|
||||
return bytes_not_copied;
|
||||
|
||||
*ppos = len;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_dbg_reg_ops_write - write into reg_ops datum
|
||||
* @filp: the opened file
|
||||
* @buffer: where to find the user's data
|
||||
* @count: the length of the user's data
|
||||
* @ppos: file position offset
|
||||
**/
|
||||
static ssize_t ixgbe_dbg_reg_ops_write(struct file *filp,
|
||||
const char __user *buffer,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = filp->private_data;
|
||||
int bytes_not_copied;
|
||||
|
||||
/* don't allow partial writes */
|
||||
if (*ppos != 0)
|
||||
return 0;
|
||||
if (count >= sizeof(ixgbe_dbg_reg_ops_buf))
|
||||
return -ENOSPC;
|
||||
|
||||
bytes_not_copied = copy_from_user(ixgbe_dbg_reg_ops_buf, buffer, count);
|
||||
if (bytes_not_copied < 0)
|
||||
return bytes_not_copied;
|
||||
else if (bytes_not_copied < count)
|
||||
count -= bytes_not_copied;
|
||||
else
|
||||
return -ENOSPC;
|
||||
ixgbe_dbg_reg_ops_buf[count] = '\0';
|
||||
|
||||
if (strncmp(ixgbe_dbg_reg_ops_buf, "write", 5) == 0) {
|
||||
u32 reg, value;
|
||||
int cnt;
|
||||
cnt = sscanf(&ixgbe_dbg_reg_ops_buf[5], "%x %x", ®, &value);
|
||||
if (cnt == 2) {
|
||||
IXGBE_WRITE_REG(&adapter->hw, reg, value);
|
||||
value = IXGBE_READ_REG(&adapter->hw, reg);
|
||||
e_dev_info("write: 0x%08x = 0x%08x\n", reg, value);
|
||||
} else {
|
||||
e_dev_info("write <reg> <value>\n");
|
||||
}
|
||||
} else if (strncmp(ixgbe_dbg_reg_ops_buf, "read", 4) == 0) {
|
||||
u32 reg, value;
|
||||
int cnt;
|
||||
cnt = sscanf(&ixgbe_dbg_reg_ops_buf[4], "%x", ®);
|
||||
if (cnt == 1) {
|
||||
value = IXGBE_READ_REG(&adapter->hw, reg);
|
||||
e_dev_info("read 0x%08x = 0x%08x\n", reg, value);
|
||||
} else {
|
||||
e_dev_info("read <reg>\n");
|
||||
}
|
||||
} else {
|
||||
e_dev_info("Unknown command %s\n", ixgbe_dbg_reg_ops_buf);
|
||||
e_dev_info("Available commands:\n");
|
||||
e_dev_info(" read <reg>\n");
|
||||
e_dev_info(" write <reg> <value>\n");
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations ixgbe_dbg_reg_ops_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = ixgbe_dbg_reg_ops_open,
|
||||
.read = ixgbe_dbg_reg_ops_read,
|
||||
.write = ixgbe_dbg_reg_ops_write,
|
||||
};
|
||||
|
||||
static char ixgbe_dbg_netdev_ops_buf[256] = "";
|
||||
|
||||
/**
|
||||
* ixgbe_dbg_netdev_ops_open - prep the debugfs netdev_ops data item
|
||||
* @inode: inode that was opened
|
||||
* @filp: file info
|
||||
*
|
||||
* Stash the adapter pointer hiding in the inode into the file pointer
|
||||
* where we can find it later in the read and write calls
|
||||
**/
|
||||
static int ixgbe_dbg_netdev_ops_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
filp->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_dbg_netdev_ops_read - read for netdev_ops datum
|
||||
* @filp: the opened file
|
||||
* @buffer: where to write the data for the user to read
|
||||
* @count: the size of the user's buffer
|
||||
* @ppos: file position offset
|
||||
**/
|
||||
static ssize_t ixgbe_dbg_netdev_ops_read(struct file *filp,
|
||||
char __user *buffer,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = filp->private_data;
|
||||
char buf[256];
|
||||
int bytes_not_copied;
|
||||
int len;
|
||||
|
||||
/* don't allow partial reads */
|
||||
if (*ppos != 0)
|
||||
return 0;
|
||||
|
||||
len = snprintf(buf, sizeof(buf), "%s: %s\n",
|
||||
adapter->netdev->name, ixgbe_dbg_netdev_ops_buf);
|
||||
if (count < len)
|
||||
return -ENOSPC;
|
||||
bytes_not_copied = copy_to_user(buffer, buf, len);
|
||||
if (bytes_not_copied < 0)
|
||||
return bytes_not_copied;
|
||||
|
||||
*ppos = len;
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_dbg_netdev_ops_write - write into netdev_ops datum
|
||||
* @filp: the opened file
|
||||
* @buffer: where to find the user's data
|
||||
* @count: the length of the user's data
|
||||
* @ppos: file position offset
|
||||
**/
|
||||
static ssize_t ixgbe_dbg_netdev_ops_write(struct file *filp,
|
||||
const char __user *buffer,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = filp->private_data;
|
||||
int bytes_not_copied;
|
||||
|
||||
/* don't allow partial writes */
|
||||
if (*ppos != 0)
|
||||
return 0;
|
||||
if (count >= sizeof(ixgbe_dbg_netdev_ops_buf))
|
||||
return -ENOSPC;
|
||||
|
||||
bytes_not_copied = copy_from_user(ixgbe_dbg_netdev_ops_buf,
|
||||
buffer, count);
|
||||
if (bytes_not_copied < 0)
|
||||
return bytes_not_copied;
|
||||
else if (bytes_not_copied < count)
|
||||
count -= bytes_not_copied;
|
||||
else
|
||||
return -ENOSPC;
|
||||
ixgbe_dbg_netdev_ops_buf[count] = '\0';
|
||||
|
||||
if (strncmp(ixgbe_dbg_netdev_ops_buf, "tx_timeout", 10) == 0) {
|
||||
adapter->netdev->netdev_ops->ndo_tx_timeout(adapter->netdev);
|
||||
e_dev_info("tx_timeout called\n");
|
||||
} else {
|
||||
e_dev_info("Unknown command: %s\n", ixgbe_dbg_netdev_ops_buf);
|
||||
e_dev_info("Available commands:\n");
|
||||
e_dev_info(" tx_timeout\n");
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations ixgbe_dbg_netdev_ops_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = ixgbe_dbg_netdev_ops_open,
|
||||
.read = ixgbe_dbg_netdev_ops_read,
|
||||
.write = ixgbe_dbg_netdev_ops_write,
|
||||
};
|
||||
|
||||
/**
|
||||
* ixgbe_dbg_adapter_init - setup the debugfs directory for the adapter
|
||||
* @adapter: the adapter that is starting up
|
||||
**/
|
||||
void ixgbe_dbg_adapter_init(struct ixgbe_adapter *adapter)
|
||||
{
|
||||
const char *name = pci_name(adapter->pdev);
|
||||
struct dentry *pfile;
|
||||
adapter->ixgbe_dbg_adapter = debugfs_create_dir(name, ixgbe_dbg_root);
|
||||
if (adapter->ixgbe_dbg_adapter) {
|
||||
pfile = debugfs_create_file("reg_ops", 0600,
|
||||
adapter->ixgbe_dbg_adapter, adapter,
|
||||
&ixgbe_dbg_reg_ops_fops);
|
||||
if (!pfile)
|
||||
e_dev_err("debugfs reg_ops for %s failed\n", name);
|
||||
pfile = debugfs_create_file("netdev_ops", 0600,
|
||||
adapter->ixgbe_dbg_adapter, adapter,
|
||||
&ixgbe_dbg_netdev_ops_fops);
|
||||
if (!pfile)
|
||||
e_dev_err("debugfs netdev_ops for %s failed\n", name);
|
||||
} else {
|
||||
e_dev_err("debugfs entry for %s failed\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_dbg_adapter_exit - clear out the adapter's debugfs entries
|
||||
* @pf: the pf that is stopping
|
||||
**/
|
||||
void ixgbe_dbg_adapter_exit(struct ixgbe_adapter *adapter)
|
||||
{
|
||||
if (adapter->ixgbe_dbg_adapter)
|
||||
debugfs_remove_recursive(adapter->ixgbe_dbg_adapter);
|
||||
adapter->ixgbe_dbg_adapter = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_dbg_init - start up debugfs for the driver
|
||||
**/
|
||||
void ixgbe_dbg_init(void)
|
||||
{
|
||||
ixgbe_dbg_root = debugfs_create_dir(ixgbe_driver_name, NULL);
|
||||
if (ixgbe_dbg_root == NULL)
|
||||
pr_err("init of debugfs failed\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_dbg_exit - clean out the driver's debugfs entries
|
||||
**/
|
||||
void ixgbe_dbg_exit(void)
|
||||
{
|
||||
debugfs_remove_recursive(ixgbe_dbg_root);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DEBUG_FS */
|
|
@ -1785,7 +1785,8 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
|
|||
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
|
||||
#ifdef IXGBE_FCOE
|
||||
struct ixgbe_adapter *adapter = q_vector->adapter;
|
||||
int ddp_bytes = 0;
|
||||
int ddp_bytes;
|
||||
unsigned int mss = 0;
|
||||
#endif /* IXGBE_FCOE */
|
||||
u16 cleaned_count = ixgbe_desc_unused(rx_ring);
|
||||
|
||||
|
@ -1839,6 +1840,20 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
|
|||
/* if ddp, not passing to ULD unless for FCP_RSP or error */
|
||||
if (ixgbe_rx_is_fcoe(rx_ring, rx_desc)) {
|
||||
ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb);
|
||||
/* include DDPed FCoE data */
|
||||
if (ddp_bytes > 0) {
|
||||
if (!mss) {
|
||||
mss = rx_ring->netdev->mtu -
|
||||
sizeof(struct fcoe_hdr) -
|
||||
sizeof(struct fc_frame_header) -
|
||||
sizeof(struct fcoe_crc_eof);
|
||||
if (mss > 512)
|
||||
mss &= ~511;
|
||||
}
|
||||
total_rx_bytes += ddp_bytes;
|
||||
total_rx_packets += DIV_ROUND_UP(ddp_bytes,
|
||||
mss);
|
||||
}
|
||||
if (!ddp_bytes) {
|
||||
dev_kfree_skb_any(skb);
|
||||
continue;
|
||||
|
@ -1852,21 +1867,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
|
|||
budget--;
|
||||
} while (likely(budget));
|
||||
|
||||
#ifdef IXGBE_FCOE
|
||||
/* include DDPed FCoE data */
|
||||
if (ddp_bytes > 0) {
|
||||
unsigned int mss;
|
||||
|
||||
mss = rx_ring->netdev->mtu - sizeof(struct fcoe_hdr) -
|
||||
sizeof(struct fc_frame_header) -
|
||||
sizeof(struct fcoe_crc_eof);
|
||||
if (mss > 512)
|
||||
mss &= ~511;
|
||||
total_rx_bytes += ddp_bytes;
|
||||
total_rx_packets += DIV_ROUND_UP(ddp_bytes, mss);
|
||||
}
|
||||
|
||||
#endif /* IXGBE_FCOE */
|
||||
u64_stats_update_begin(&rx_ring->syncp);
|
||||
rx_ring->stats.packets += total_rx_packets;
|
||||
rx_ring->stats.bytes += total_rx_bytes;
|
||||
|
@ -3660,8 +3660,6 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
|
|||
if (hw->mac.type == ixgbe_mac_82598EB)
|
||||
netif_set_gso_max_size(adapter->netdev, 32768);
|
||||
|
||||
hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true);
|
||||
|
||||
#ifdef IXGBE_FCOE
|
||||
if (adapter->netdev->features & NETIF_F_FCOE_MTU)
|
||||
max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE);
|
||||
|
@ -3861,6 +3859,11 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
|
|||
#ifdef CONFIG_IXGBE_DCB
|
||||
ixgbe_configure_dcb(adapter);
|
||||
#endif
|
||||
/*
|
||||
* We must restore virtualization before VLANs or else
|
||||
* the VLVF registers will not be populated
|
||||
*/
|
||||
ixgbe_configure_virtualization(adapter);
|
||||
|
||||
ixgbe_set_rx_mode(adapter->netdev);
|
||||
ixgbe_restore_vlan(adapter);
|
||||
|
@ -3892,8 +3895,6 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
|
|||
break;
|
||||
}
|
||||
|
||||
ixgbe_configure_virtualization(adapter);
|
||||
|
||||
#ifdef IXGBE_FCOE
|
||||
/* configure FCoE L2 filters, redirection table, and Rx control */
|
||||
ixgbe_configure_fcoe(adapter);
|
||||
|
@ -5572,7 +5573,7 @@ static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)
|
|||
if (!ssvpc)
|
||||
return;
|
||||
|
||||
e_warn(drv, "%d Spoofed packets detected\n", ssvpc);
|
||||
e_warn(drv, "%u Spoofed packets detected\n", ssvpc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7447,6 +7448,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
|
|||
e_err(probe, "failed to allocate sysfs resources\n");
|
||||
#endif /* CONFIG_IXGBE_HWMON */
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
ixgbe_dbg_adapter_init(adapter);
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
return 0;
|
||||
|
||||
err_register:
|
||||
|
@ -7481,6 +7486,10 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
|
|||
struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
ixgbe_dbg_adapter_exit(adapter);
|
||||
#endif /*CONFIG_DEBUG_FS */
|
||||
|
||||
set_bit(__IXGBE_DOWN, &adapter->state);
|
||||
cancel_work_sync(&adapter->service_task);
|
||||
|
||||
|
@ -7736,6 +7745,10 @@ static int __init ixgbe_init_module(void)
|
|||
pr_info("%s - version %s\n", ixgbe_driver_string, ixgbe_driver_version);
|
||||
pr_info("%s\n", ixgbe_copyright);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
ixgbe_dbg_init();
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
#ifdef CONFIG_IXGBE_DCA
|
||||
dca_register_notify(&dca_notifier);
|
||||
#endif
|
||||
|
@ -7758,6 +7771,11 @@ static void __exit ixgbe_exit_module(void)
|
|||
dca_unregister_notify(&dca_notifier);
|
||||
#endif
|
||||
pci_unregister_driver(&ixgbe_driver);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
ixgbe_dbg_exit();
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
rcu_barrier(); /* Wait for completion of call_rcu()'s */
|
||||
}
|
||||
|
||||
|
|
|
@ -346,6 +346,10 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
|
|||
static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
|
||||
u32 vf)
|
||||
{
|
||||
/* VLAN 0 is a special case, don't allow it to be removed */
|
||||
if (!vid && !add)
|
||||
return 0;
|
||||
|
||||
return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add);
|
||||
}
|
||||
|
||||
|
@ -414,6 +418,7 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
|
|||
VLAN_PRIO_SHIFT)), vf);
|
||||
ixgbe_set_vmolr(hw, vf, false);
|
||||
} else {
|
||||
ixgbe_set_vf_vlan(adapter, true, 0, vf);
|
||||
ixgbe_set_vmvir(adapter, 0, vf);
|
||||
ixgbe_set_vmolr(hw, vf, true);
|
||||
}
|
||||
|
@ -810,9 +815,9 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int ixgbe_link_mbps(int internal_link_speed)
|
||||
static int ixgbe_link_mbps(struct ixgbe_adapter *adapter)
|
||||
{
|
||||
switch (internal_link_speed) {
|
||||
switch (adapter->link_speed) {
|
||||
case IXGBE_LINK_SPEED_100_FULL:
|
||||
return 100;
|
||||
case IXGBE_LINK_SPEED_1GB_FULL:
|
||||
|
@ -824,27 +829,30 @@ static int ixgbe_link_mbps(int internal_link_speed)
|
|||
}
|
||||
}
|
||||
|
||||
static void ixgbe_set_vf_rate_limit(struct ixgbe_hw *hw, int vf, int tx_rate,
|
||||
int link_speed)
|
||||
static void ixgbe_set_vf_rate_limit(struct ixgbe_adapter *adapter, int vf)
|
||||
{
|
||||
int rf_dec, rf_int;
|
||||
u32 bcnrc_val;
|
||||
struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
u32 bcnrc_val = 0;
|
||||
u16 queue, queues_per_pool;
|
||||
u16 tx_rate = adapter->vfinfo[vf].tx_rate;
|
||||
|
||||
if (tx_rate) {
|
||||
/* start with base link speed value */
|
||||
bcnrc_val = adapter->vf_rate_link_speed;
|
||||
|
||||
if (tx_rate != 0) {
|
||||
/* Calculate the rate factor values to set */
|
||||
rf_int = link_speed / tx_rate;
|
||||
rf_dec = (link_speed - (rf_int * tx_rate));
|
||||
rf_dec = (rf_dec * (1<<IXGBE_RTTBCNRC_RF_INT_SHIFT)) / tx_rate;
|
||||
bcnrc_val <<= IXGBE_RTTBCNRC_RF_INT_SHIFT;
|
||||
bcnrc_val /= tx_rate;
|
||||
|
||||
bcnrc_val = IXGBE_RTTBCNRC_RS_ENA;
|
||||
bcnrc_val |= ((rf_int<<IXGBE_RTTBCNRC_RF_INT_SHIFT) &
|
||||
IXGBE_RTTBCNRC_RF_INT_MASK);
|
||||
bcnrc_val |= (rf_dec & IXGBE_RTTBCNRC_RF_DEC_MASK);
|
||||
} else {
|
||||
bcnrc_val = 0;
|
||||
/* clear everything but the rate factor */
|
||||
bcnrc_val &= IXGBE_RTTBCNRC_RF_INT_MASK |
|
||||
IXGBE_RTTBCNRC_RF_DEC_MASK;
|
||||
|
||||
/* enable the rate scheduler */
|
||||
bcnrc_val |= IXGBE_RTTBCNRC_RS_ENA;
|
||||
}
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, 2*vf); /* vf Y uses queue 2*Y */
|
||||
/*
|
||||
* Set global transmit compensation time to the MMW_SIZE in RTTBCNRM
|
||||
* register. Typically MMW_SIZE=0x014 if 9728-byte jumbo is supported
|
||||
|
@ -861,53 +869,68 @@ static void ixgbe_set_vf_rate_limit(struct ixgbe_hw *hw, int vf, int tx_rate,
|
|||
break;
|
||||
}
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, bcnrc_val);
|
||||
/* determine how many queues per pool based on VMDq mask */
|
||||
queues_per_pool = __ALIGN_MASK(1, ~vmdq->mask);
|
||||
|
||||
/* write value for all Tx queues belonging to VF */
|
||||
for (queue = 0; queue < queues_per_pool; queue++) {
|
||||
unsigned int reg_idx = (vf * queues_per_pool) + queue;
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, reg_idx);
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, bcnrc_val);
|
||||
}
|
||||
}
|
||||
|
||||
void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter)
|
||||
{
|
||||
int actual_link_speed, i;
|
||||
bool reset_rate = false;
|
||||
int i;
|
||||
|
||||
/* VF Tx rate limit was not set */
|
||||
if (adapter->vf_rate_link_speed == 0)
|
||||
if (!adapter->vf_rate_link_speed)
|
||||
return;
|
||||
|
||||
actual_link_speed = ixgbe_link_mbps(adapter->link_speed);
|
||||
if (actual_link_speed != adapter->vf_rate_link_speed) {
|
||||
reset_rate = true;
|
||||
if (ixgbe_link_mbps(adapter) != adapter->vf_rate_link_speed) {
|
||||
adapter->vf_rate_link_speed = 0;
|
||||
dev_info(&adapter->pdev->dev,
|
||||
"Link speed has been changed. VF Transmit rate "
|
||||
"is disabled\n");
|
||||
"Link speed has been changed. VF Transmit rate is disabled\n");
|
||||
}
|
||||
|
||||
for (i = 0; i < adapter->num_vfs; i++) {
|
||||
if (reset_rate)
|
||||
if (!adapter->vf_rate_link_speed)
|
||||
adapter->vfinfo[i].tx_rate = 0;
|
||||
|
||||
ixgbe_set_vf_rate_limit(&adapter->hw, i,
|
||||
adapter->vfinfo[i].tx_rate,
|
||||
actual_link_speed);
|
||||
ixgbe_set_vf_rate_limit(adapter, i);
|
||||
}
|
||||
}
|
||||
|
||||
int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate)
|
||||
{
|
||||
struct ixgbe_adapter *adapter = netdev_priv(netdev);
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
int actual_link_speed;
|
||||
int link_speed;
|
||||
|
||||
actual_link_speed = ixgbe_link_mbps(adapter->link_speed);
|
||||
if ((vf >= adapter->num_vfs) || (!adapter->link_up) ||
|
||||
(tx_rate > actual_link_speed) || (actual_link_speed != 10000) ||
|
||||
((tx_rate != 0) && (tx_rate <= 10)))
|
||||
/* rate limit cannot be set to 10Mb or less in 10Gb adapters */
|
||||
/* verify VF is active */
|
||||
if (vf >= adapter->num_vfs)
|
||||
return -EINVAL;
|
||||
|
||||
adapter->vf_rate_link_speed = actual_link_speed;
|
||||
adapter->vfinfo[vf].tx_rate = (u16)tx_rate;
|
||||
ixgbe_set_vf_rate_limit(hw, vf, tx_rate, actual_link_speed);
|
||||
/* verify link is up */
|
||||
if (!adapter->link_up)
|
||||
return -EINVAL;
|
||||
|
||||
/* verify we are linked at 10Gbps */
|
||||
link_speed = ixgbe_link_mbps(adapter);
|
||||
if (link_speed != 10000)
|
||||
return -EINVAL;
|
||||
|
||||
/* rate limit cannot be less than 10Mbs or greater than link speed */
|
||||
if (tx_rate && ((tx_rate <= 10) || (tx_rate > link_speed)))
|
||||
return -EINVAL;
|
||||
|
||||
/* store values */
|
||||
adapter->vf_rate_link_speed = link_speed;
|
||||
adapter->vfinfo[vf].tx_rate = tx_rate;
|
||||
|
||||
/* update hardware configuration */
|
||||
ixgbe_set_vf_rate_limit(adapter, vf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue