Skip to content

Commit

Permalink
igb: Add support for enabling VFs to PF driver.
Browse files Browse the repository at this point in the history
This patch adds the support to handle requests from the VF to perform
operations such as completing resets, setting/reading mac address, adding
vlans, adding multicast addresses, setting rlpml, and general
communications between the PF and all VFs.

Signed-off-by: Alexander Duyck <[email protected]>
Signed-off-by: Jeff Kirsher <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Alexander Duyck authored and davem330 committed Feb 20, 2009
1 parent e173952 commit 4ae196d
Show file tree
Hide file tree
Showing 12 changed files with 1,077 additions and 26 deletions.
2 changes: 1 addition & 1 deletion drivers/net/igb/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@
obj-$(CONFIG_IGB) += igb.o

igb-objs := igb_main.o igb_ethtool.o e1000_82575.o \
e1000_mac.o e1000_nvm.o e1000_phy.o
e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o

42 changes: 42 additions & 0 deletions drivers/net/igb/e1000_82575.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
return -E1000_ERR_PHY;
}

/* if 82576 then initialize mailbox parameters */
if (mac->type == e1000_82576)
igb_init_mbx_params_pf(hw);

return 0;
}

Expand Down Expand Up @@ -1413,6 +1417,44 @@ void igb_rx_fifo_flush_82575(struct e1000_hw *hw)
rd32(E1000_MPC);
}

/**
* igb_vmdq_set_loopback_pf - enable or disable vmdq loopback
* @hw: pointer to the hardware struct
* @enable: state to enter, either enabled or disabled
*
* enables/disables L2 switch loopback functionality.
**/
void igb_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
{
u32 dtxswc = rd32(E1000_DTXSWC);

if (enable)
dtxswc |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
else
dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;

wr32(E1000_DTXSWC, dtxswc);
}

/**
* igb_vmdq_set_replication_pf - enable or disable vmdq replication
* @hw: pointer to the hardware struct
* @enable: state to enter, either enabled or disabled
*
* enables/disables replication of packets across multiple pools.
**/
void igb_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
{
u32 vt_ctl = rd32(E1000_VT_CTL);

if (enable)
vt_ctl |= E1000_VT_CTL_VM_REPL_EN;
else
vt_ctl &= ~E1000_VT_CTL_VM_REPL_EN;

wr32(E1000_VT_CTL, vt_ctl);
}

static struct e1000_mac_operations e1000_mac_ops_82575 = {
.reset_hw = igb_reset_hw_82575,
.init_hw = igb_init_hw_82575,
Expand Down
17 changes: 17 additions & 0 deletions drivers/net/igb/e1000_82575.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ struct e1000_adv_tx_context_desc {
#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */

#define MAX_NUM_VFS 8

#define E1000_DTXSWC_VMDQ_LOOPBACK_EN (1 << 31) /* global VF LB enable */

/* Easy defines for setting default pool, would normally be left a zero */
#define E1000_VT_CTL_DEFAULT_POOL_SHIFT 7
#define E1000_VT_CTL_DEFAULT_POOL_MASK (0x7 << E1000_VT_CTL_DEFAULT_POOL_SHIFT)
Expand All @@ -181,8 +185,21 @@ struct e1000_adv_tx_context_desc {
#define E1000_VMOLR_BAM 0x08000000 /* Accept Broadcast packets */
#define E1000_VMOLR_MPME 0x10000000 /* Multicast promiscuous mode */
#define E1000_VMOLR_STRVLAN 0x40000000 /* Vlan stripping enable */
#define E1000_VMOLR_STRCRC 0x80000000 /* CRC stripping enable */

#define E1000_VLVF_ARRAY_SIZE 32
#define E1000_VLVF_VLANID_MASK 0x00000FFF
#define E1000_VLVF_POOLSEL_SHIFT 12
#define E1000_VLVF_POOLSEL_MASK (0xFF << E1000_VLVF_POOLSEL_SHIFT)
#define E1000_VLVF_LVLAN 0x00100000
#define E1000_VLVF_VLANID_ENABLE 0x80000000

#define E1000_IOVCTL 0x05BBC
#define E1000_IOVCTL_REUSE_VFQ 0x00000001

#define ALL_QUEUES 0xFFFF

void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool);
void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);

#endif
9 changes: 9 additions & 0 deletions drivers/net/igb/e1000_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@

/* Extended Device Control */
#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
/* Physical Func Reset Done Indication */
#define E1000_CTRL_EXT_PFRSTD 0x00004000
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000
#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000
Expand Down Expand Up @@ -325,6 +327,7 @@
#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */
#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */
#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */
#define E1000_ICR_VMMB 0x00000100 /* VM MB event */
/* If this bit asserted, the driver should claim the interrupt */
#define E1000_ICR_INT_ASSERTED 0x80000000
/* LAN connected device generates an interrupt */
Expand Down Expand Up @@ -362,6 +365,7 @@
/* Interrupt Mask Set */
#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
#define E1000_IMS_VMMB E1000_ICR_VMMB /* Mail box activity */
#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
Expand Down Expand Up @@ -413,6 +417,7 @@
#define E1000_BLK_PHY_RESET 12
#define E1000_ERR_SWFW_SYNC 13
#define E1000_NOT_IMPLEMENTED 14
#define E1000_ERR_MBX 15

/* Loop limit on how long we wait for auto-negotiation to complete */
#define COPPER_LINK_UP_LIMIT 10
Expand Down Expand Up @@ -659,4 +664,8 @@
#define E1000_GEN_CTL_ADDRESS_SHIFT 8
#define E1000_GEN_POLL_TIMEOUT 640

#define E1000_VFTA_ENTRY_SHIFT 5
#define E1000_VFTA_ENTRY_MASK 0x7F
#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F

#endif
31 changes: 30 additions & 1 deletion drivers/net/igb/e1000_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <linux/delay.h>
#include <linux/io.h>

#include "e1000_mac.h"
#include "e1000_regs.h"
#include "e1000_defines.h"

Expand Down Expand Up @@ -272,6 +271,7 @@ struct e1000_host_mng_command_info {
#include "e1000_mac.h"
#include "e1000_phy.h"
#include "e1000_nvm.h"
#include "e1000_mbx.h"

struct e1000_mac_operations {
s32 (*check_for_link)(struct e1000_hw *);
Expand Down Expand Up @@ -427,6 +427,34 @@ struct e1000_fc_info {
enum e1000_fc_type original_type;
};

struct e1000_mbx_operations {
s32 (*init_params)(struct e1000_hw *hw);
s32 (*read)(struct e1000_hw *, u32 *, u16, u16);
s32 (*write)(struct e1000_hw *, u32 *, u16, u16);
s32 (*read_posted)(struct e1000_hw *, u32 *, u16, u16);
s32 (*write_posted)(struct e1000_hw *, u32 *, u16, u16);
s32 (*check_for_msg)(struct e1000_hw *, u16);
s32 (*check_for_ack)(struct e1000_hw *, u16);
s32 (*check_for_rst)(struct e1000_hw *, u16);
};

struct e1000_mbx_stats {
u32 msgs_tx;
u32 msgs_rx;

u32 acks;
u32 reqs;
u32 rsts;
};

struct e1000_mbx_info {
struct e1000_mbx_operations ops;
struct e1000_mbx_stats stats;
u32 timeout;
u32 usec_delay;
u16 size;
};

struct e1000_dev_spec_82575 {
bool sgmii_active;
};
Expand All @@ -443,6 +471,7 @@ struct e1000_hw {
struct e1000_phy_info phy;
struct e1000_nvm_info nvm;
struct e1000_bus_info bus;
struct e1000_mbx_info mbx;
struct e1000_host_mng_dhcp_cookie mng_cookie;

union {
Expand Down
24 changes: 24 additions & 0 deletions drivers/net/igb/e1000_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,30 @@ void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
wrfl();
}

/**
* igb_vfta_set - enable or disable vlan in VLAN filter table
* @hw: pointer to the HW structure
* @vid: VLAN id to add or remove
* @add: if true add filter, if false remove
*
* Sets or clears a bit in the VLAN filter table array based on VLAN id
* and if we are adding or removing the filter
**/
void igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add)
{
u32 index = (vid >> E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK;
u32 mask = 1 < (vid & E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
u32 vfta;

vfta = array_rd32(E1000_VFTA, index);
if (add)
vfta |= mask;
else
vfta &= ~mask;

igb_write_vfta(hw, index, vfta);
}

/**
* igb_check_alt_mac_addr - Check for alternate MAC addr
* @hw: pointer to the HW structure
Expand Down
1 change: 1 addition & 0 deletions drivers/net/igb/e1000_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,

void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
void igb_clear_vfta(struct e1000_hw *hw);
void igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add);
void igb_config_collision_dist(struct e1000_hw *hw);
void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
void igb_put_hw_semaphore(struct e1000_hw *hw);
Expand Down
Loading

0 comments on commit 4ae196d

Please sign in to comment.