Commit 58bb4bd0 authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/jkirsher/net-next-2.6

parents dd68153d 1b1c0a48
......@@ -1963,8 +1963,15 @@ static int e1000_set_coalesce(struct net_device *netdev,
static int e1000_nway_reset(struct net_device *netdev)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
if (netif_running(netdev))
e1000e_reinit_locked(adapter);
if (!netif_running(netdev))
return -EAGAIN;
if (!adapter->hw.mac.autoneg)
return -EINVAL;
e1000e_reinit_locked(adapter);
return 0;
}
......@@ -2006,7 +2013,7 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset,
switch (stringset) {
case ETH_SS_TEST:
memcpy(data, *e1000_gstrings_test, sizeof(e1000_gstrings_test));
memcpy(data, e1000_gstrings_test, sizeof(e1000_gstrings_test));
break;
case ETH_SS_STATS:
for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
......
......@@ -1843,7 +1843,9 @@ static int e1000_request_msix(struct e1000_adapter *adapter)
int err = 0, vector = 0;
if (strlen(netdev->name) < (IFNAMSIZ - 5))
sprintf(adapter->rx_ring->name, "%s-rx-0", netdev->name);
snprintf(adapter->rx_ring->name,
sizeof(adapter->rx_ring->name) - 1,
"%s-rx-0", netdev->name);
else
memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ);
err = request_irq(adapter->msix_entries[vector].vector,
......@@ -1856,7 +1858,9 @@ static int e1000_request_msix(struct e1000_adapter *adapter)
vector++;
if (strlen(netdev->name) < (IFNAMSIZ - 5))
sprintf(adapter->tx_ring->name, "%s-tx-0", netdev->name);
snprintf(adapter->tx_ring->name,
sizeof(adapter->tx_ring->name) - 1,
"%s-tx-0", netdev->name);
else
memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ);
err = request_irq(adapter->msix_entries[vector].vector,
......
......@@ -238,9 +238,15 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
size = 14;
nvm->word_size = 1 << size;
/* if 82576 then initialize mailbox parameters */
if (mac->type == e1000_82576)
/* if part supports SR-IOV then initialize mailbox parameters */
switch (mac->type) {
case e1000_82576:
case e1000_i350:
igb_init_mbx_params_pf(hw);
break;
default:
break;
}
/* setup PHY parameters */
if (phy->media_type != e1000_media_type_copper) {
......
......@@ -422,26 +422,24 @@ s32 igb_init_mbx_params_pf(struct e1000_hw *hw)
{
struct e1000_mbx_info *mbx = &hw->mbx;
if (hw->mac.type == e1000_82576) {
mbx->timeout = 0;
mbx->usec_delay = 0;
mbx->size = E1000_VFMAILBOX_SIZE;
mbx->ops.read = igb_read_mbx_pf;
mbx->ops.write = igb_write_mbx_pf;
mbx->ops.read_posted = igb_read_posted_mbx;
mbx->ops.write_posted = igb_write_posted_mbx;
mbx->ops.check_for_msg = igb_check_for_msg_pf;
mbx->ops.check_for_ack = igb_check_for_ack_pf;
mbx->ops.check_for_rst = igb_check_for_rst_pf;
mbx->stats.msgs_tx = 0;
mbx->stats.msgs_rx = 0;
mbx->stats.reqs = 0;
mbx->stats.acks = 0;
mbx->stats.rsts = 0;
}
mbx->timeout = 0;
mbx->usec_delay = 0;
mbx->size = E1000_VFMAILBOX_SIZE;
mbx->ops.read = igb_read_mbx_pf;
mbx->ops.write = igb_write_mbx_pf;
mbx->ops.read_posted = igb_read_posted_mbx;
mbx->ops.write_posted = igb_write_posted_mbx;
mbx->ops.check_for_msg = igb_check_for_msg_pf;
mbx->ops.check_for_ack = igb_check_for_ack_pf;
mbx->ops.check_for_rst = igb_check_for_rst_pf;
mbx->stats.msgs_tx = 0;
mbx->stats.msgs_rx = 0;
mbx->stats.reqs = 0;
mbx->stats.acks = 0;
mbx->stats.rsts = 0;
return 0;
}
......
......@@ -2287,9 +2287,14 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter)
spin_lock_init(&adapter->stats64_lock);
#ifdef CONFIG_PCI_IOV
if (hw->mac.type == e1000_82576)
switch (hw->mac.type) {
case e1000_82576:
case e1000_i350:
adapter->vfs_allocated_count = (max_vfs > 7) ? 7 : max_vfs;
break;
default:
break;
}
#endif /* CONFIG_PCI_IOV */
adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus());
......
......@@ -334,6 +334,10 @@ struct ixgbe_adapter {
u16 bd_number;
struct work_struct reset_task;
struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
/* DCB parameters */
struct ieee_pfc *ixgbe_ieee_pfc;
struct ieee_ets *ixgbe_ieee_ets;
struct ixgbe_dcb_config dcb_cfg;
struct ixgbe_dcb_config temp_dcb_cfg;
u8 dcb_set_bitmap;
......@@ -521,7 +525,6 @@ extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *,
extern void ixgbe_alloc_rx_buffers(struct ixgbe_ring *, u16);
extern void ixgbe_write_eitr(struct ixgbe_q_vector *);
extern int ethtool_ioctl(struct ifreq *ifr);
extern u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 index);
extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw);
extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc);
extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc);
......
......@@ -29,6 +29,7 @@
#define _IXGBE_COMMON_H_
#include "ixgbe_type.h"
#include "ixgbe.h"
u32 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw);
s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
......@@ -110,9 +111,8 @@ void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf);
#define IXGBE_WRITE_FLUSH(a) IXGBE_READ_REG(a, IXGBE_STATUS)
extern struct net_device *ixgbe_get_hw_dev(struct ixgbe_hw *hw);
#define hw_dbg(hw, format, arg...) \
netdev_dbg(ixgbe_get_hw_dev(hw), format, ##arg)
netdev_dbg(((struct ixgbe_adapter *)(hw->back))->netdev, format, ##arg)
#define e_dev_info(format, arg...) \
dev_info(&adapter->pdev->dev, format, ## arg)
#define e_dev_warn(format, arg...) \
......
......@@ -33,6 +33,42 @@
#include "ixgbe_dcb_82598.h"
#include "ixgbe_dcb_82599.h"
/**
* ixgbe_ieee_credits - This calculates the ieee traffic class
* credits from the configured bandwidth percentages. Credits
* are the smallest unit programable into the underlying
* hardware. The IEEE 802.1Qaz specification do not use bandwidth
* groups so this is much simplified from the CEE case.
*/
s32 ixgbe_ieee_credits(__u8 *bw, __u16 *refill, __u16 *max, int max_frame)
{
int min_percent = 100;
int min_credit, multiplier;
int i;
min_credit = ((max_frame / 2) + DCB_CREDIT_QUANTUM - 1) /
DCB_CREDIT_QUANTUM;
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
if (bw[i] < min_percent && bw[i])
min_percent = bw[i];
}
multiplier = (min_credit / min_percent) + 1;
/* Find out the hw credits for each TC */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
int val = min(bw[i] * multiplier, MAX_CREDIT_REFILL);
if (val < min_credit)
val = min_credit;
refill[i] = val;
max[i] = (bw[i] * MAX_CREDIT)/100;
}
return 0;
}
/**
* ixgbe_dcb_calculate_tc_credits - Calculates traffic class credits
* @ixgbe_dcb_config: Struct containing DCB settings.
......@@ -141,6 +177,59 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *hw,
return ret_val;
}
void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en)
{
int i;
*pfc_en = 0;
for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
*pfc_en |= (cfg->tc_config[i].dcb_pfc & 0xF) << i;
}
void ixgbe_dcb_unpack_refill(struct ixgbe_dcb_config *cfg, int direction,
u16 *refill)
{
struct tc_bw_alloc *p;
int i;
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
p = &cfg->tc_config[i].path[direction];
refill[i] = p->data_credits_refill;
}
}
void ixgbe_dcb_unpack_max(struct ixgbe_dcb_config *cfg, u16 *max)
{
int i;
for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
max[i] = cfg->tc_config[i].desc_credits_max;
}
void ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config *cfg, int direction,
u8 *bwgid)
{
struct tc_bw_alloc *p;
int i;
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
p = &cfg->tc_config[i].path[direction];
bwgid[i] = p->bwg_id;
}
}
void ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config *cfg, int direction,
u8 *ptype)
{
struct tc_bw_alloc *p;
int i;
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
p = &cfg->tc_config[i].path[direction];
ptype[i] = p->prio_type;
}
}
/**
* ixgbe_dcb_hw_config - Config and enable DCB
* @hw: pointer to hardware structure
......@@ -152,13 +241,30 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
{
s32 ret = 0;
u8 pfc_en;
u8 ptype[MAX_TRAFFIC_CLASS];
u8 bwgid[MAX_TRAFFIC_CLASS];
u16 refill[MAX_TRAFFIC_CLASS];
u16 max[MAX_TRAFFIC_CLASS];
/* Unpack CEE standard containers */
ixgbe_dcb_unpack_pfc(dcb_config, &pfc_en);
ixgbe_dcb_unpack_refill(dcb_config, DCB_TX_CONFIG, refill);
ixgbe_dcb_unpack_max(dcb_config, max);
ixgbe_dcb_unpack_bwgid(dcb_config, DCB_TX_CONFIG, bwgid);
ixgbe_dcb_unpack_prio(dcb_config, DCB_TX_CONFIG, ptype);
switch (hw->mac.type) {
case ixgbe_mac_82598EB:
ret = ixgbe_dcb_hw_config_82598(hw, dcb_config);
ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->rx_pba_cfg,
pfc_en, refill, max, bwgid,
ptype);
break;
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
ret = ixgbe_dcb_hw_config_82599(hw, dcb_config);
ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->rx_pba_cfg,
pfc_en, refill, max, bwgid,
ptype);
break;
default:
break;
......@@ -166,3 +272,70 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
return ret;
}
/* Helper routines to abstract HW specifics from DCB netlink ops */
s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en)
{
int ret = -EINVAL;
switch (hw->mac.type) {
case ixgbe_mac_82598EB:
ret = ixgbe_dcb_config_pfc_82598(hw, pfc_en);
break;
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
ret = ixgbe_dcb_config_pfc_82599(hw, pfc_en);
break;
default:
break;
}
return ret;
}
s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw,
u16 *refill, u16 *max, u8 *bwg_id, u8 *tsa)
{
int i;
u8 prio_type[IEEE_8021QAZ_MAX_TCS];
/* Map TSA onto CEE prio type */
for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
switch (tsa[i]) {
case IEEE_8021QAZ_TSA_STRICT:
prio_type[i] = 2;
break;
case IEEE_8021QAZ_TSA_ETS:
prio_type[i] = 0;
break;
default:
/* Hardware only supports priority strict or
* ETS transmission selection algorithms if
* we receive some other value from dcbnl
* throw an error
*/
return -EINVAL;
}
}
switch (hw->mac.type) {
case ixgbe_mac_82598EB:
ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max,
prio_type);
ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
bwg_id, prio_type);
ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
bwg_id, prio_type);
break;
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max,
bwg_id, prio_type);
ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
bwg_id, prio_type);
ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max,
bwg_id, prio_type);
break;
default:
break;
}
return 0;
}
......@@ -139,7 +139,6 @@ struct ixgbe_dcb_config {
struct tc_configuration tc_config[MAX_TRAFFIC_CLASS];
u8 bw_percentage[2][MAX_BW_GROUP]; /* One each for Tx/Rx */
bool pfc_mode_enable;
bool round_robin_enable;
enum dcb_rx_pba_cfg rx_pba_cfg;
......@@ -148,12 +147,21 @@ struct ixgbe_dcb_config {
};
/* DCB driver APIs */
void ixgbe_dcb_unpack_pfc(struct ixgbe_dcb_config *cfg, u8 *pfc_en);
void ixgbe_dcb_unpack_refill(struct ixgbe_dcb_config *, int, u16 *);
void ixgbe_dcb_unpack_max(struct ixgbe_dcb_config *, u16 *);
void ixgbe_dcb_unpack_bwgid(struct ixgbe_dcb_config *, int, u8 *);
void ixgbe_dcb_unpack_prio(struct ixgbe_dcb_config *, int, u8 *);
/* DCB credits calculation */
s32 ixgbe_ieee_credits(__u8 *bw, __u16 *refill, __u16 *max, int max_frame);
s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_hw *,
struct ixgbe_dcb_config *, int, u8);
/* DCB hw initialization */
s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw,
u16 *refill, u16 *max, u8 *bwg_id, u8 *prio_type);
s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en);
s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *);
/* DCB definitions for credit calculation */
......
......@@ -38,15 +38,14 @@
*
* Configure packet buffers for DCB mode.
*/
static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw, u8 rx_pba)
{
s32 ret_val = 0;
u32 value = IXGBE_RXPBSIZE_64KB;
u8 i = 0;
/* Setup Rx packet buffer sizes */
switch (dcb_config->rx_pba_cfg) {
switch (rx_pba) {
case pba_80_48:
/* Setup the first four at 80KB */
value = IXGBE_RXPBSIZE_80KB;
......@@ -78,10 +77,11 @@ static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw,
*
* Configure Rx Data Arbiter and credits for each traffic class.
*/
static s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw,
u16 *refill,
u16 *max,
u8 *prio_type)
{
struct tc_bw_alloc *p;
u32 reg = 0;
u32 credit_refill = 0;
u32 credit_max = 0;
......@@ -102,13 +102,12 @@ static s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw,
/* Configure traffic class credits and priority */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
p = &dcb_config->tc_config[i].path[DCB_RX_CONFIG];
credit_refill = p->data_credits_refill;
credit_max = p->data_credits_max;
credit_refill = refill[i];
credit_max = max[i];
reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT);
if (p->prio_type == prio_link)
if (prio_type[i] == prio_link)
reg |= IXGBE_RT2CR_LSP;
IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg);
......@@ -135,10 +134,12 @@ static s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw,
*
* Configure Tx Descriptor Arbiter and credits for each traffic class.
*/
static s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
u16 *refill,
u16 *max,
u8 *bwg_id,
u8 *prio_type)
{
struct tc_bw_alloc *p;
u32 reg, max_credits;
u8 i;
......@@ -146,10 +147,8 @@ static s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
/* Enable arbiter */
reg &= ~IXGBE_DPMCS_ARBDIS;
if (!(dcb_config->round_robin_enable)) {
/* Enable DFP and Recycle mode */
reg |= (IXGBE_DPMCS_TDPAC | IXGBE_DPMCS_TRM);
}
/* Enable DFP and Recycle mode */
reg |= (IXGBE_DPMCS_TDPAC | IXGBE_DPMCS_TRM);
reg |= IXGBE_DPMCS_TSOEF;
/* Configure Max TSO packet size 34KB including payload and headers */
reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT);
......@@ -158,16 +157,15 @@ static s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
/* Configure traffic class credits and priority */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
max_credits = dcb_config->tc_config[i].desc_credits_max;
max_credits = max[i];
reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT;
reg |= p->data_credits_refill;
reg |= (u32)(p->bwg_id) << IXGBE_TDTQ2TCCR_BWG_SHIFT;
reg |= refill[i];
reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT;
if (p->prio_type == prio_group)
if (prio_type[i] == prio_group)
reg |= IXGBE_TDTQ2TCCR_GSP;
if (p->prio_type == prio_link)
if (prio_type[i] == prio_link)
reg |= IXGBE_TDTQ2TCCR_LSP;
IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg);
......@@ -183,10 +181,12 @@ static s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
*
* Configure Tx Data Arbiter and credits for each traffic class.
*/
static s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
u16 *refill,
u16 *max,
u8 *bwg_id,
u8 *prio_type)
{
struct tc_bw_alloc *p;
u32 reg;
u8 i;
......@@ -200,15 +200,14 @@ static s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
/* Configure traffic class credits and priority */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
reg = p->data_credits_refill;
reg |= (u32)(p->data_credits_max) << IXGBE_TDPT2TCCR_MCL_SHIFT;
reg |= (u32)(p->bwg_id) << IXGBE_TDPT2TCCR_BWG_SHIFT;
reg = refill[i];
reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT;
reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT;
if (p->prio_type == prio_group)
if (prio_type[i] == prio_group)
reg |= IXGBE_TDPT2TCCR_GSP;
if (p->prio_type == prio_link)
if (prio_type[i] == prio_link)
reg |= IXGBE_TDPT2TCCR_LSP;
IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg);
......@@ -229,13 +228,12 @@ static s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
*
* Configure Priority Flow Control for each traffic class.
*/
s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
{
u32 reg, rx_pba_size;
u8 i;
if (!dcb_config->pfc_mode_enable)
if (!pfc_en)
goto out;
/* Enable Transmit Priority Flow Control */
......@@ -256,19 +254,20 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw,
* for each traffic class.
*/
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
int enabled = pfc_en & (1 << i);
rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i));
rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
reg = (rx_pba_size - hw->fc.low_water) << 10;
if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx ||
dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full)
if (enabled == pfc_enabled_tx ||
enabled == pfc_enabled_full)
reg |= IXGBE_FCRTL_XONE;
IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg);
reg = (rx_pba_size - hw->fc.high_water) << 10;
if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx ||
dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full)
if (enabled == pfc_enabled_tx ||
enabled == pfc_enabled_full)
reg |= IXGBE_FCRTH_FCEN;
IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
......@@ -292,7 +291,7 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw,
* Configure queue statistics registers, all queues belonging to same traffic
* class uses a single set of queue statistics counters.
*/
static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
{
u32 reg = 0;
u8 i = 0;
......@@ -325,13 +324,16 @@ static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
* Configure dcb settings and enable dcb mode.
*/
s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
u8 rx_pba, u8 pfc_en, u16 *refill,
u16 *max, u8 *bwg_id, u8 *prio_type)
{
ixgbe_dcb_config_packet_buffers_82598(hw, dcb_config);
ixgbe_dcb_config_rx_arbiter_82598(hw, dcb_config);
ixgbe_dcb_config_tx_desc_arbiter_82598(hw, dcb_config);
ixgbe_dcb_config_tx_data_arbiter_82598(hw, dcb_config);
ixgbe_dcb_config_pfc_82598(hw, dcb_config);
ixgbe_dcb_config_packet_buffers_82598(hw, rx_pba);
ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, prio_type);
ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
bwg_id, prio_type);
ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
bwg_id, prio_type);
ixgbe_dcb_config_pfc_82598(hw, pfc_en);
ixgbe_dcb_config_tc_stats_82598(hw);
return 0;
......
......@@ -71,9 +71,28 @@
/* DCB hardware-specific driver APIs */
/* DCB PFC functions */
s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *, struct ixgbe_dcb_config *);
s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *, u8 pfc_en);
/* DCB hw initialization */
s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *, struct ixgbe_dcb_config *);
s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw,
u16 *refill,
u16 *max,
u8 *prio_type);
s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
u16 *refill,
u16 *max,
u8 *bwg_id,
u8 *prio_type);
s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
u16 *refill,
u16 *max,
u8 *bwg_id,
u8 *prio_type);
s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw,
u8 rx_pba, u8 pfc_en, u16 *refill,
u16 *max, u8 *bwg_id, u8 *prio_type);
#endif /* _DCB_82598_CONFIG_H */
......@@ -33,19 +33,18 @@
/**
* ixgbe_dcb_config_packet_buffers_82599 - Configure DCB packet buffers
* @hw: pointer to hardware structure
* @dcb_config: pointer to ixgbe_dcb_config structure
* @rx_pba: method to distribute packet buffer
*
* Configure packet buffers for DCB mode.
*/
static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, u8 rx_pba)
{
s32 ret_val = 0;
u32 value = IXGBE_RXPBSIZE_64KB;
u8 i = 0;
/* Setup Rx packet buffer sizes */
switch (dcb_config->rx_pba_cfg) {
switch (rx_pba) {
case pba_80_48:
/* Setup the first four at 80KB */
value = IXGBE_RXPBSIZE_80KB;
......@@ -75,14 +74,19 @@ static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw,
/**
* ixgbe_dcb_config_rx_arbiter_82599 - Config Rx Data arbiter
* @hw: pointer to hardware structure
* @dcb_config: pointer to ixgbe_dcb_config structure
* @refill: refill credits index by traffic class
* @max: max credits index by traffic class
* @bwg_id: bandwidth grouping indexed by traffic class
* @prio_type: priority type indexed by traffic class
*
* Configure Rx Packet Arbiter and credits for each traffic class.
*/
static s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
u16 *refill,
u16 *max,
u8 *bwg_id,
u8 *prio_type)
{
struct tc_bw_alloc *p;
u32 reg = 0;
u32 credit_refill = 0;
u32 credit_max = 0;
......@@ -103,15 +107,13 @@ static s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
/* Configure traffic class credits and priority */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
p = &dcb_config->tc_config[i].path[DCB_RX_CONFIG];
credit_refill = p->data_credits_refill;
credit_max = p->data_credits_max;
credit_refill = refill[i];
credit_max = max[i];
reg = credit_refill | (credit_max << IXGBE_RTRPT4C_MCL_SHIFT);
reg |= (u32)(p->bwg_id) << IXGBE_RTRPT4C_BWG_SHIFT;
reg |= (u32)(bwg_id[i]) << IXGBE_RTRPT4C_BWG_SHIFT;
if (p->prio_type == prio_link)
if (prio_type[i] == prio_link)
reg |= IXGBE_RTRPT4C_LSP;
IXGBE_WRITE_REG(hw, IXGBE_RTRPT4C(i), reg);
......@@ -130,14 +132,19 @@ static s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
/**
* ixgbe_dcb_config_tx_desc_arbiter_82599 - Config Tx Desc. arbiter
* @hw: pointer to hardware structure
* @dcb_config: pointer to ixgbe_dcb_config structure
* @refill: refill credits index by traffic class
* @max: max credits index by traffic class
* @bwg_id: bandwidth grouping indexed by traffic class
* @prio_type: priority type indexed by traffic class
*
* Configure Tx Descriptor Arbiter and credits for each traffic class.
*/
static s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
u16 *refill,
u16 *max,
u8 *bwg_id,
u8 *prio_type)
{
struct tc_bw_alloc *p;
u32 reg, max_credits;
u8 i;
......@@ -149,16 +156,15 @@ static s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
/* Configure traffic class credits and priority */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
max_credits = dcb_config->tc_config[i].desc_credits_max;
max_credits = max[i];
reg = max_credits << IXGBE_RTTDT2C_MCL_SHIFT;
reg |= p->data_credits_refill;
reg |= (u32)(p->bwg_id) << IXGBE_RTTDT2C_BWG_SHIFT;
reg |= refill[i];
reg |= (u32)(bwg_id[i]) << IXGBE_RTTDT2C_BWG_SHIFT;
if (p->prio_type == prio_group)
if (prio_type[i] == prio_group)
reg |= IXGBE_RTTDT2C_GSP;
if (p->prio_type == prio_link)
if (prio_type[i] == prio_link)
reg |= IXGBE_RTTDT2C_LSP;
IXGBE_WRITE_REG(hw, IXGBE_RTTDT2C(i), reg);
......@@ -177,14 +183,19 @@ static s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
/**
* ixgbe_dcb_config_tx_data_arbiter_82599 - Config Tx Data arbiter
* @hw: pointer to hardware structure
* @dcb_config: pointer to ixgbe_dcb_config structure
* @refill: refill credits index by traffic class
* @max: max credits index by traffic class
* @bwg_id: bandwidth grouping indexed by traffic class
* @prio_type: priority type indexed by traffic class
*
* Configure Tx Packet Arbiter and credits for each traffic class.
*/
static s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
u16 *refill,
u16 *max,
u8 *bwg_id,
u8 *prio_type)
{
struct tc_bw_alloc *p;
u32 reg;
u8 i;
......@@ -205,15 +216,14 @@ static s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
/* Configure traffic class credits and priority */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
reg = p->data_credits_refill;
reg |= (u32)(p->data_credits_max) << IXGBE_RTTPT2C_MCL_SHIFT;
reg |= (u32)(p->bwg_id) << IXGBE_RTTPT2C_BWG_SHIFT;
reg = refill[i];
reg |= (u32)(max[i]) << IXGBE_RTTPT2C_MCL_SHIFT;
reg |= (u32)(bwg_id[i]) << IXGBE_RTTPT2C_BWG_SHIFT;
if (p->prio_type == prio_group)
if (prio_type[i] == prio_group)
reg |= IXGBE_RTTPT2C_GSP;
if (p->prio_type == prio_link)
if (prio_type[i] == prio_link)
reg |= IXGBE_RTTPT2C_LSP;
IXGBE_WRITE_REG(hw, IXGBE_RTTPT2C(i), reg);
......@@ -233,17 +243,16 @@ static s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
/**
* ixgbe_dcb_config_pfc_82599 - Configure priority flow control
* @hw: pointer to hardware structure
* @dcb_config: pointer to ixgbe_dcb_config structure
* @pfc_en: enabled pfc bitmask
*
* Configure Priority Flow Control (PFC) for each traffic class.
*/
s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en)
{
u32 i, reg, rx_pba_size;
/* If PFC is disabled globally then fall back to LFC. */
if (!dcb_config->pfc_mode_enable) {
if (!pfc_en) {
for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
hw->mac.ops.fc_enable(hw, i);
goto out;
......@@ -251,19 +260,18 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
/* Configure PFC Tx thresholds per TC */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
int enabled = pfc_en & (1 << i);
rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i));
rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT;
reg = (rx_pba_size - hw->fc.low_water) << 10;
if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
if (enabled)
reg |= IXGBE_FCRTL_XONE;
IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
reg = (rx_pba_size - hw->fc.high_water) << 10;
if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx)
if (enabled)
reg |= IXGBE_FCRTH_FCEN;
IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
}
......@@ -349,7 +357,6 @@ static s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw)
/**
* ixgbe_dcb_config_82599 - Configure general DCB parameters
* @hw: pointer to hardware structure
* @dcb_config: pointer to ixgbe_dcb_config structure
*
* Configure general DCB parameters.
*/
......@@ -406,19 +413,27 @@ static s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw)
/**
* ixgbe_dcb_hw_config_82599 - Configure and enable DCB
* @hw: pointer to hardware structure
* @dcb_config: pointer to ixgbe_dcb_config structure
* @rx_pba: method to distribute packet buffer
* @refill: refill credits index by traffic class
* @max: max credits index by traffic class
* @bwg_id: bandwidth grouping indexed by traffic class
* @prio_type: priority type indexed by traffic class
* @pfc_en: enabled pfc bitmask
*
* Configure dcb settings and enable dcb mode.
*/
s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config)
u8 rx_pba, u8 pfc_en, u16 *refill,
u16 *max, u8 *bwg_id, u8 *prio_type)
{
ixgbe_dcb_config_packet_buffers_82599(hw, dcb_config);
ixgbe_dcb_config_packet_buffers_82599(hw, rx_pba);
ixgbe_dcb_config_82599(hw);
ixgbe_dcb_config_rx_arbiter_82599(hw, dcb_config);
ixgbe_dcb_config_tx_desc_arbiter_82599(hw, dcb_config);
ixgbe_dcb_config_tx_data_arbiter_82599(hw, dcb_config);
ixgbe_dcb_config_pfc_82599(hw, dcb_config);
ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, bwg_id, prio_type);
ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
bwg_id, prio_type);
ixgbe_dcb_config_tx_data_arbiter_82599(hw, refill, max,
bwg_id, prio_type);
ixgbe_dcb_config_pfc_82599(hw, pfc_en);
ixgbe_dcb_config_tc_stats_82599(hw);
return 0;
......
......@@ -102,11 +102,29 @@
/* DCB hardware-specific driver APIs */
/* DCB PFC functions */
s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *dcb_config);
s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en);
/* DCB hw initialization */
s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
u16 *refill,
u16 *max,
u8 *bwg_id,
u8 *prio_type);
s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
u16 *refill,
u16 *max,
u8 *bwg_id,
u8 *prio_type);
s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
u16 *refill,
u16 *max,
u8 *bwg_id,
u8 *prio_type);
s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw,
struct ixgbe_dcb_config *config);
u8 rx_pba, u8 pfc_en, u16 *refill,
u16 *max, u8 *bwg_id, u8 *prio_type);
#endif /* _DCB_82599_CONFIG_H */
......@@ -37,7 +37,6 @@
#define BIT_PG_RX 0x04
#define BIT_PG_TX 0x08
#define BIT_APP_UPCHG 0x10
#define BIT_RESETLINK 0x40
#define BIT_LINKSPEED 0x80
/* Responses for the DCB_C_SET_ALL command */
......@@ -225,10 +224,8 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
(adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent !=
adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent) ||
(adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap !=
adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)) {
adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap))
adapter->dcb_set_bitmap |= BIT_PG_TX;
adapter->dcb_set_bitmap |= BIT_RESETLINK;
}
}
static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
......@@ -239,10 +236,8 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct;
if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] !=
adapter->dcb_cfg.bw_percentage[0][bwg_id]) {
adapter->dcb_cfg.bw_percentage[0][bwg_id])
adapter->dcb_set_bitmap |= BIT_PG_TX;
adapter->dcb_set_bitmap |= BIT_RESETLINK;
}
}
static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
......@@ -269,10 +264,8 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
(adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent !=
adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent) ||
(adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap !=
adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap)) {
adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap))
adapter->dcb_set_bitmap |= BIT_PG_RX;
adapter->dcb_set_bitmap |= BIT_RESETLINK;
}
}
static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
......@@ -283,10 +276,8 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct;
if (adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] !=
adapter->dcb_cfg.bw_percentage[1][bwg_id]) {
adapter->dcb_cfg.bw_percentage[1][bwg_id])
adapter->dcb_set_bitmap |= BIT_PG_RX;
adapter->dcb_set_bitmap |= BIT_RESETLINK;
}
}
static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc,
......@@ -365,21 +356,17 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
return DCB_NO_HW_CHG;
/*
* Only take down the adapter if the configuration change
* requires a reset.
* Only take down the adapter if an app change occured. FCoE
* may shuffle tx rings in this case and this can not be done
* without a reset currently.
*/
if (adapter->dcb_set_bitmap & BIT_RESETLINK) {
if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
msleep(1);
if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
if (netif_running(netdev))
netdev->netdev_ops->ndo_stop(netdev);
ixgbe_clear_interrupt_scheme(adapter);
} else {
if (netif_running(netdev))
ixgbe_down(adapter);
}
if (netif_running(netdev))
netdev->netdev_ops->ndo_stop(netdev);
ixgbe_clear_interrupt_scheme(adapter);
}
if (adapter->dcb_cfg.pfc_mode_enable) {
......@@ -408,29 +395,51 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
}
}
if (adapter->dcb_set_bitmap & BIT_RESETLINK) {
if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
ixgbe_init_interrupt_scheme(adapter);
if (netif_running(netdev))
netdev->netdev_ops->ndo_open(netdev);
} else {
if (netif_running(netdev))
ixgbe_up(adapter);
}
if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
ixgbe_init_interrupt_scheme(adapter);
if (netif_running(netdev))
netdev->netdev_ops->ndo_open(netdev);
ret = DCB_HW_CHG_RST;
} else if (adapter->dcb_set_bitmap & BIT_PFC) {
if (adapter->hw.mac.type == ixgbe_mac_82598EB)
ixgbe_dcb_config_pfc_82598(&adapter->hw,
&adapter->dcb_cfg);
else if (adapter->hw.mac.type == ixgbe_mac_82599EB)
ixgbe_dcb_config_pfc_82599(&adapter->hw,
&adapter->dcb_cfg);
}
if (adapter->dcb_set_bitmap & BIT_PFC) {
u8 pfc_en;
ixgbe_dcb_unpack_pfc(&adapter->dcb_cfg, &pfc_en);
ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc_en);
ret = DCB_HW_CHG;
}
if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) {
u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS];
u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS];
int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
#ifdef CONFIG_FCOE
if (adapter->netdev->features & NETIF_F_FCOE_MTU)
max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE);
#endif
ixgbe_dcb_calculate_tc_credits(&adapter->hw, &adapter->dcb_cfg,
max_frame, DCB_TX_CONFIG);
ixgbe_dcb_calculate_tc_credits(&adapter->hw, &adapter->dcb_cfg,
max_frame, DCB_RX_CONFIG);
ixgbe_dcb_unpack_refill(&adapter->dcb_cfg,
DCB_TX_CONFIG, refill);
ixgbe_dcb_unpack_max(&adapter->dcb_cfg, max);
ixgbe_dcb_unpack_bwgid(&adapter->dcb_cfg,
DCB_TX_CONFIG, bwg_id);
ixgbe_dcb_unpack_prio(&adapter->dcb_cfg,
DCB_TX_CONFIG, prio_type);
ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max,
bwg_id, prio_type);
}
if (adapter->dcb_cfg.pfc_mode_enable)
adapter->hw.fc.current_mode = ixgbe_fc_pfc;
if (adapter->dcb_set_bitmap & BIT_RESETLINK)
if (adapter->dcb_set_bitmap & BIT_APP_UPCHG)
clear_bit(__IXGBE_RESETTING, &adapter->state);
adapter->dcb_set_bitmap = 0x00;
return ret;
......@@ -568,18 +577,29 @@ static u8 ixgbe_dcbnl_setapp(struct net_device *netdev,
case DCB_APP_IDTYPE_ETHTYPE:
#ifdef IXGBE_FCOE
if (id == ETH_P_FCOE) {
u8 tc;
struct ixgbe_adapter *adapter;
u8 old_tc;
struct ixgbe_adapter *adapter = netdev_priv(netdev);
adapter = netdev_priv(netdev);
tc = adapter->fcoe.tc;
/* Get current programmed tc */
old_tc = adapter->fcoe.tc;
rval = ixgbe_fcoe_setapp(adapter, up);
if ((!rval) && (tc != adapter->fcoe.tc) &&
(adapter->flags & IXGBE_FLAG_DCB_ENABLED) &&
(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) {
if (rval ||
!(adapter->flags & IXGBE_FLAG_DCB_ENABLED) ||
!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
break;
/* The FCoE application priority may be changed multiple
* times in quick sucession with switches that build up
* TLVs. To avoid creating uneeded device resets this
* checks the actual HW configuration and clears
* BIT_APP_UPCHG if a HW configuration change is not
* need
*/
if (old_tc == adapter->fcoe.tc)
adapter->dcb_set_bitmap &= ~BIT_APP_UPCHG;
else
adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
adapter->dcb_set_bitmap |= BIT_RESETLINK;
}
}
#endif
break;
......@@ -591,7 +611,98 @@ static u8 ixgbe_dcbnl_setapp(struct net_device *netdev,
return rval;
}
static int ixgbe_dcbnl_ieee_getets(struct net_device *dev,
struct ieee_ets *ets)
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
struct ieee_ets *my_ets = adapter->ixgbe_ieee_ets;
/* No IEEE PFC settings available */
if (!my_ets)
return -EINVAL;
ets->ets_cap = MAX_TRAFFIC_CLASS;
ets->cbs = my_ets->cbs;
memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw));
memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw));
memcpy(ets->tc_tsa, my_ets->tc_tsa, sizeof(ets->tc_tsa));
memcpy(ets->prio_tc, my_ets->prio_tc, sizeof(ets->prio_tc));
return 0;
}
static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
struct ieee_ets *ets)
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
__u16 refill[IEEE_8021QAZ_MAX_TCS], max[IEEE_8021QAZ_MAX_TCS];
int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
int err;
/* naively give each TC a bwg to map onto CEE hardware */
__u8 bwg_id[IEEE_8021QAZ_MAX_TCS] = {0, 1, 2, 3, 4, 5, 6, 7};
if (!adapter->ixgbe_ieee_ets) {
adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets),
GFP_KERNEL);
if (!adapter->ixgbe_ieee_ets)
return -ENOMEM;
}
memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets));
ixgbe_ieee_credits(ets->tc_tx_bw, refill, max, max_frame);
err = ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max,
bwg_id, ets->tc_tsa);
return err;
}
static int ixgbe_dcbnl_ieee_getpfc(struct net_device *dev,
struct ieee_pfc *pfc)
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
struct ieee_pfc *my_pfc = adapter->ixgbe_ieee_pfc;
int i;
/* No IEEE PFC settings available */
if (!my_pfc)
return -EINVAL;
pfc->pfc_cap = MAX_TRAFFIC_CLASS;
pfc->pfc_en = my_pfc->pfc_en;
pfc->mbc = my_pfc->mbc;
pfc->delay = my_pfc->delay;
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
pfc->requests[i] = adapter->stats.pxoffrxc[i];
pfc->indications[i] = adapter->stats.pxofftxc[i];
}
return 0;
}
static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev,
struct ieee_pfc *pfc)
{
struct ixgbe_adapter *adapter = netdev_priv(dev);
int err;
if (!adapter->ixgbe_ieee_pfc) {
adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc),
GFP_KERNEL);
if (!adapter->ixgbe_ieee_pfc)
return -ENOMEM;
}
memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc));
err = ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc->pfc_en);
return err;
}
const struct dcbnl_rtnl_ops dcbnl_ops = {
.ieee_getets = ixgbe_dcbnl_ieee_getets,
.ieee_setets = ixgbe_dcbnl_ieee_setets,
.ieee_getpfc = ixgbe_dcbnl_ieee_getpfc,
.ieee_setpfc = ixgbe_dcbnl_ieee_setpfc,
.getstate = ixgbe_dcbnl_get_state,
.setstate = ixgbe_dcbnl_set_state,
.getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr,
......
......@@ -152,7 +152,17 @@ static int ixgbe_get_settings(struct net_device *netdev,
ecmd->supported |= (SUPPORTED_1000baseT_Full |
SUPPORTED_Autoneg);
switch (hw->mac.type) {
case ixgbe_mac_X540:
ecmd->supported |= SUPPORTED_100baseT_Full;
break;
default:
break;
}
ecmd->advertising = ADVERTISED_Autoneg;
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
ecmd->advertising |= ADVERTISED_100baseT_Full;
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
ecmd->advertising |= ADVERTISED_10000baseT_Full;
if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
......@@ -167,6 +177,15 @@ static int ixgbe_get_settings(struct net_device *netdev,
ecmd->advertising |= (ADVERTISED_10000baseT_Full |
ADVERTISED_1000baseT_Full);
switch (hw->mac.type) {
case ixgbe_mac_X540:
if (!(ecmd->advertising & ADVERTISED_100baseT_Full))
ecmd->advertising |= (ADVERTISED_100baseT_Full);
break;
default:
break;
}
if (hw->phy.media_type == ixgbe_media_type_copper) {
ecmd->supported |= SUPPORTED_TP;
ecmd->advertising |= ADVERTISED_TP;
......@@ -271,8 +290,19 @@ static int ixgbe_get_settings(struct net_device *netdev,
hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
if (link_up) {
ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
SPEED_10000 : SPEED_1000;
switch (link_speed) {
case IXGBE_LINK_SPEED_10GB_FULL:
ecmd->speed = SPEED_10000;
break;
case IXGBE_LINK_SPEED_1GB_FULL:
ecmd->speed = SPEED_1000;
break;
case IXGBE_LINK_SPEED_100_FULL:
ecmd->speed = SPEED_100;
break;
default:
break;
}
ecmd->duplex = DUPLEX_FULL;
} else {
ecmd->speed = -1;
......
......@@ -648,7 +648,7 @@ void ixgbe_unmap_and_free_tx_resource(struct ixgbe_ring *tx_ring,
*
* Returns : a tc index for use in range 0-7, or 0-3
*/
u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx)
static u8 ixgbe_dcb_txq_to_tc(struct ixgbe_adapter *adapter, u8 reg_idx)
{
int tc = -1;
int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
......@@ -5173,7 +5173,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->dcb_cfg.bw_percentage[DCB_RX_CONFIG][0] = 100;
adapter->dcb_cfg.rx_pba_cfg = pba_equal;
adapter->dcb_cfg.pfc_mode_enable = false;
adapter->dcb_cfg.round_robin_enable = false;
adapter->dcb_set_bitmap = 0x00;
ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg,
adapter->ring_feature[RING_F_DCB].indices);
......@@ -5610,6 +5609,10 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
}
ixgbe_clear_interrupt_scheme(adapter);
#ifdef CONFIG_DCB
kfree(adapter->ixgbe_ieee_pfc);
kfree(adapter->ixgbe_ieee_ets);
#endif
#ifdef CONFIG_PM
retval = pci_save_state(pdev);
......@@ -6099,7 +6102,10 @@ static void ixgbe_watchdog_task(struct work_struct *work)
(link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
"10 Gbps" :
(link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
"1 Gbps" : "unknown speed")),
"1 Gbps" :
(link_speed == IXGBE_LINK_SPEED_100_FULL ?
"100 Mbps" :
"unknown speed"))),
((flow_rx && flow_tx) ? "RX/TX" :
(flow_rx ? "RX" :
(flow_tx ? "TX" : "None"))));
......@@ -7704,16 +7710,6 @@ static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event,
#endif /* CONFIG_IXGBE_DCA */
/**
* ixgbe_get_hw_dev return device
* used by hardware layer to print debugging information
**/
struct net_device *ixgbe_get_hw_dev(struct ixgbe_hw *hw)
{
struct ixgbe_adapter *adapter = hw->back;
return adapter->netdev;
}
module_exit(ixgbe_exit_module);
/* ixgbe_main.c */
......@@ -437,6 +437,7 @@ static s32 ixgbe_read_mbx_pf(struct ixgbe_hw *hw, u32 *msg, u16 size,
return ret_val;
}
#ifdef CONFIG_PCI_IOV
/**
* ixgbe_init_mbx_params_pf - set initial values for pf mailbox
* @hw: pointer to the HW structure
......@@ -465,6 +466,7 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
break;
}
}
#endif /* CONFIG_PCI_IOV */
struct ixgbe_mbx_operations mbx_ops_generic = {
.read = ixgbe_read_mbx_pf,
......
......@@ -86,7 +86,9 @@ s32 ixgbe_write_mbx(struct ixgbe_hw *, u32 *, u16, u16);
s32 ixgbe_check_for_msg(struct ixgbe_hw *, u16);
s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16);
s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16);
#ifdef CONFIG_PCI_IOV
void ixgbe_init_mbx_params_pf(struct ixgbe_hw *);
#endif /* CONFIG_PCI_IOV */
extern struct ixgbe_mbx_operations mbx_ops_generic;
......
......@@ -25,6 +25,11 @@
/* IEEE 802.1Qaz std supported values */
#define IEEE_8021QAZ_MAX_TCS 8
#define IEEE_8021QAZ_TSA_STRICT 0
#define IEEE_8021QAZ_TSA_CB_SHABER 1
#define IEEE_8021QAZ_TSA_ETS 2
#define IEEE_8021QAZ_TSA_VENDOR 255
/* This structure contains the IEEE 802.1Qaz ETS managed object
*
* @willing: willing bit in ETS configuratin TLV
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment