igb: implement VFRE and VFTE registers
Also introduce: - Checks for RXDCTL/TXDCTL queue enable bits - IGB_NUM_VM_POOLS enum (Sec 1.5: Table 1-7) Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech> Signed-off-by: Jason Wang <jasowang@redhat.com>
This commit is contained in:
parent
1c1e649761
commit
3269ebb3e0
@ -784,6 +784,18 @@ igb_txdesc_writeback(IGBCore *core, dma_addr_t base,
|
|||||||
return igb_tx_wb_eic(core, txi->idx);
|
return igb_tx_wb_eic(core, txi->idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
igb_tx_enabled(IGBCore *core, const E1000E_RingInfo *txi)
|
||||||
|
{
|
||||||
|
bool vmdq = core->mac[MRQC] & 1;
|
||||||
|
uint16_t qn = txi->idx;
|
||||||
|
uint16_t pool = qn % IGB_NUM_VM_POOLS;
|
||||||
|
|
||||||
|
return (core->mac[TCTL] & E1000_TCTL_EN) &&
|
||||||
|
(!vmdq || core->mac[VFTE] & BIT(pool)) &&
|
||||||
|
(core->mac[TXDCTL0 + (qn * 16)] & E1000_TXDCTL_QUEUE_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
igb_start_xmit(IGBCore *core, const IGB_TxRing *txr)
|
igb_start_xmit(IGBCore *core, const IGB_TxRing *txr)
|
||||||
{
|
{
|
||||||
@ -793,8 +805,7 @@ igb_start_xmit(IGBCore *core, const IGB_TxRing *txr)
|
|||||||
const E1000E_RingInfo *txi = txr->i;
|
const E1000E_RingInfo *txi = txr->i;
|
||||||
uint32_t eic = 0;
|
uint32_t eic = 0;
|
||||||
|
|
||||||
/* TODO: check if the queue itself is enabled too. */
|
if (!igb_tx_enabled(core, txi)) {
|
||||||
if (!(core->mac[TCTL] & E1000_TCTL_EN)) {
|
|
||||||
trace_e1000e_tx_disabled();
|
trace_e1000e_tx_disabled();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -872,6 +883,9 @@ igb_can_receive(IGBCore *core)
|
|||||||
|
|
||||||
for (i = 0; i < IGB_NUM_QUEUES; i++) {
|
for (i = 0; i < IGB_NUM_QUEUES; i++) {
|
||||||
E1000E_RxRing rxr;
|
E1000E_RxRing rxr;
|
||||||
|
if (!(core->mac[RXDCTL0 + (i * 16)] & E1000_RXDCTL_QUEUE_ENABLE)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
igb_rx_ring_init(core, &rxr, i);
|
igb_rx_ring_init(core, &rxr, i);
|
||||||
if (igb_ring_enabled(core, rxr.i) && igb_has_rxbufs(core, rxr.i, 1)) {
|
if (igb_ring_enabled(core, rxr.i) && igb_has_rxbufs(core, rxr.i, 1)) {
|
||||||
@ -938,7 +952,7 @@ static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header *ehdr,
|
|||||||
|
|
||||||
if (core->mac[MRQC] & 1) {
|
if (core->mac[MRQC] & 1) {
|
||||||
if (is_broadcast_ether_addr(ehdr->h_dest)) {
|
if (is_broadcast_ether_addr(ehdr->h_dest)) {
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < IGB_NUM_VM_POOLS; i++) {
|
||||||
if (core->mac[VMOLR0 + i] & E1000_VMOLR_BAM) {
|
if (core->mac[VMOLR0 + i] & E1000_VMOLR_BAM) {
|
||||||
queues |= BIT(i);
|
queues |= BIT(i);
|
||||||
}
|
}
|
||||||
@ -972,7 +986,7 @@ static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header *ehdr,
|
|||||||
f = ta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3];
|
f = ta_shift[(rctl >> E1000_RCTL_MO_SHIFT) & 3];
|
||||||
f = (((ehdr->h_dest[5] << 8) | ehdr->h_dest[4]) >> f) & 0xfff;
|
f = (((ehdr->h_dest[5] << 8) | ehdr->h_dest[4]) >> f) & 0xfff;
|
||||||
if (macp[f >> 5] & (1 << (f & 0x1f))) {
|
if (macp[f >> 5] & (1 << (f & 0x1f))) {
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < IGB_NUM_VM_POOLS; i++) {
|
||||||
if (core->mac[VMOLR0 + i] & E1000_VMOLR_ROMPE) {
|
if (core->mac[VMOLR0 + i] & E1000_VMOLR_ROMPE) {
|
||||||
queues |= BIT(i);
|
queues |= BIT(i);
|
||||||
}
|
}
|
||||||
@ -995,7 +1009,7 @@ static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header *ehdr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < IGB_NUM_VM_POOLS; i++) {
|
||||||
if (core->mac[VMOLR0 + i] & E1000_VMOLR_AUPE) {
|
if (core->mac[VMOLR0 + i] & E1000_VMOLR_AUPE) {
|
||||||
mask |= BIT(i);
|
mask |= BIT(i);
|
||||||
}
|
}
|
||||||
@ -1011,6 +1025,7 @@ static uint16_t igb_receive_assign(IGBCore *core, const struct eth_header *ehdr,
|
|||||||
queues = BIT(def_pl >> E1000_VT_CTL_DEFAULT_POOL_SHIFT);
|
queues = BIT(def_pl >> E1000_VT_CTL_DEFAULT_POOL_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
queues &= core->mac[VFRE];
|
||||||
igb_rss_parse_packet(core, core->rx_pkt, external_tx != NULL, rss_info);
|
igb_rss_parse_packet(core, core->rx_pkt, external_tx != NULL, rss_info);
|
||||||
if (rss_info->queue & 1) {
|
if (rss_info->queue & 1) {
|
||||||
queues <<= 8;
|
queues <<= 8;
|
||||||
@ -1571,7 +1586,8 @@ igb_receive_internal(IGBCore *core, const struct iovec *iov, int iovcnt,
|
|||||||
e1000x_fcs_len(core->mac);
|
e1000x_fcs_len(core->mac);
|
||||||
|
|
||||||
for (i = 0; i < IGB_NUM_QUEUES; i++) {
|
for (i = 0; i < IGB_NUM_QUEUES; i++) {
|
||||||
if (!(queues & BIT(i))) {
|
if (!(queues & BIT(i)) ||
|
||||||
|
!(core->mac[RXDCTL0 + (i * 16)] & E1000_RXDCTL_QUEUE_ENABLE)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1977,9 +1993,16 @@ static void igb_set_vfmailbox(IGBCore *core, int index, uint32_t val)
|
|||||||
|
|
||||||
static void igb_vf_reset(IGBCore *core, uint16_t vfn)
|
static void igb_vf_reset(IGBCore *core, uint16_t vfn)
|
||||||
{
|
{
|
||||||
|
uint16_t qn0 = vfn;
|
||||||
|
uint16_t qn1 = vfn + IGB_NUM_VM_POOLS;
|
||||||
|
|
||||||
/* disable Rx and Tx for the VF*/
|
/* disable Rx and Tx for the VF*/
|
||||||
core->mac[VFTE] &= ~BIT(vfn);
|
core->mac[RXDCTL0 + (qn0 * 16)] &= ~E1000_RXDCTL_QUEUE_ENABLE;
|
||||||
|
core->mac[RXDCTL0 + (qn1 * 16)] &= ~E1000_RXDCTL_QUEUE_ENABLE;
|
||||||
|
core->mac[TXDCTL0 + (qn0 * 16)] &= ~E1000_TXDCTL_QUEUE_ENABLE;
|
||||||
|
core->mac[TXDCTL0 + (qn1 * 16)] &= ~E1000_TXDCTL_QUEUE_ENABLE;
|
||||||
core->mac[VFRE] &= ~BIT(vfn);
|
core->mac[VFRE] &= ~BIT(vfn);
|
||||||
|
core->mac[VFTE] &= ~BIT(vfn);
|
||||||
/* indicate VF reset to PF */
|
/* indicate VF reset to PF */
|
||||||
core->mac[VFLRE] |= BIT(vfn);
|
core->mac[VFLRE] |= BIT(vfn);
|
||||||
/* VFLRE and mailbox use the same interrupt cause */
|
/* VFLRE and mailbox use the same interrupt cause */
|
||||||
@ -3914,6 +3937,7 @@ igb_phy_reg_init[] = {
|
|||||||
static const uint32_t igb_mac_reg_init[] = {
|
static const uint32_t igb_mac_reg_init[] = {
|
||||||
[LEDCTL] = 2 | (3 << 8) | BIT(15) | (6 << 16) | (7 << 24),
|
[LEDCTL] = 2 | (3 << 8) | BIT(15) | (6 << 16) | (7 << 24),
|
||||||
[EEMNGCTL] = BIT(31),
|
[EEMNGCTL] = BIT(31),
|
||||||
|
[TXDCTL0] = E1000_TXDCTL_QUEUE_ENABLE,
|
||||||
[RXDCTL0] = E1000_RXDCTL_QUEUE_ENABLE | (1 << 16),
|
[RXDCTL0] = E1000_RXDCTL_QUEUE_ENABLE | (1 << 16),
|
||||||
[RXDCTL1] = 1 << 16,
|
[RXDCTL1] = 1 << 16,
|
||||||
[RXDCTL2] = 1 << 16,
|
[RXDCTL2] = 1 << 16,
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#define IGB_MSIX_VEC_NUM (10)
|
#define IGB_MSIX_VEC_NUM (10)
|
||||||
#define IGBVF_MSIX_VEC_NUM (3)
|
#define IGBVF_MSIX_VEC_NUM (3)
|
||||||
#define IGB_NUM_QUEUES (16)
|
#define IGB_NUM_QUEUES (16)
|
||||||
|
#define IGB_NUM_VM_POOLS (8)
|
||||||
|
|
||||||
typedef struct IGBCore IGBCore;
|
typedef struct IGBCore IGBCore;
|
||||||
|
|
||||||
|
@ -160,6 +160,9 @@ union e1000_adv_rx_desc {
|
|||||||
#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
|
#define E1000_MRQC_RSS_FIELD_IPV6_UDP 0x00800000
|
||||||
#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
|
#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
|
||||||
|
|
||||||
|
/* Additional Transmit Descriptor Control definitions */
|
||||||
|
#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Tx Queue */
|
||||||
|
|
||||||
/* Additional Receive Descriptor Control definitions */
|
/* Additional Receive Descriptor Control definitions */
|
||||||
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
|
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user