Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 327870
b: refs/heads/master
c: 9f66d3e
h: refs/heads/master
v: v3
  • Loading branch information
Alexander Duyck authored and Jeff Kirsher committed Sep 15, 2012
1 parent 3e46191 commit bd26c11
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 42 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b35d4d423c602c44d57c43347c0705a12eec6538
refs/heads/master: 9f66d3eec4e5b32f299b6c7bf21dd54df1496f0b
100 changes: 59 additions & 41 deletions trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
Original file line number Diff line number Diff line change
Expand Up @@ -815,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:
Expand All @@ -829,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_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;
bcnrc_val <<= IXGBE_RTTBCNRC_RF_INT_SHIFT;
bcnrc_val /= tx_rate;

/* 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
Expand All @@ -866,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;
}
Expand Down

0 comments on commit bd26c11

Please sign in to comment.