staticconstchar ixgbe_overheat_msg[] = "Network adapter has been stopped because it has over heated. Restart the computer. If the problem persists, power off the system and replace the adapter";
#ifdef CONFIG_PCI_IOV staticunsignedint max_vfs;
module_param(max_vfs, uint, 0);
MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate per physical function - default is zero and maximum value is 63. (Deprecated)"); #endif/* CONFIG_PCI_IOV */
staticbool allow_unsupported_sfp;
module_param(allow_unsupported_sfp, bool, 0444);
MODULE_PARM_DESC(allow_unsupported_sfp, "Allow unsupported and untested SFP+ modules on 82599-based adapters");
/* Get the negotiated link width and speed from PCI config space of the *parent,asthisdeviceisbehindaswitch
*/
err = ixgbe_read_pci_cfg_word_parent(adapter, 18, &link_status);
/* assume caller will handle error case */ if (err) return err;
/* Some devices are not connected over PCIe and thus do not negotiate *speed.Thesedevicesdonothavevalidbusinfo,andthusanyreport *wegeneratemaynotbecorrect.
*/ if (hw->bus.type == ixgbe_bus_type_internal) return;
/* determine whether to use the parent device */ if (ixgbe_pcie_from_parent(&adapter->hw))
pdev = adapter->pdev->bus->parent->self; else
pdev = adapter->pdev;
reg_addr = READ_ONCE(hw->hw_addr); if (ixgbe_removed(reg_addr)) return IXGBE_FAILED_READ_REG;
/* Register read of 0xFFFFFFF can indicate the adapter has been removed, *soperformseveralstatusregisterreadstodetermineiftheadapter *hasbeenremoved.
*/ for (i = 0; i < IXGBE_FAILED_READ_RETRIES; i++) {
value = readl(reg_addr + IXGBE_STATUS); if (value != IXGBE_FAILED_READ_REG) break;
mdelay(3);
}
if (value == IXGBE_FAILED_READ_REG)
ixgbe_remove_adapter(hw); else
value = readl(reg_addr + reg); return value;
}
if (ixgbe_removed(reg_addr)) return IXGBE_FAILED_READ_REG; if (unlikely(hw->phy.nw_mng_if_sel &
IXGBE_NW_MNG_IF_SEL_SGMII_ENABLE)) { struct ixgbe_adapter *adapter; int i;
for (i = 0; i < 200; ++i) {
value = readl(reg_addr + IXGBE_MAC_SGMII_BUSY); if (likely(!value)) goto writes_completed; if (value == IXGBE_FAILED_READ_REG) {
ixgbe_remove_adapter(hw); return IXGBE_FAILED_READ_REG;
}
udelay(5);
}
switch (reginfo->ofs) { case IXGBE_SRRCTL(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_SRRCTL(i)); break; case IXGBE_DCA_RXCTRL(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i)); break; case IXGBE_RDLEN(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_RDLEN(i)); break; case IXGBE_RDH(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_RDH(i)); break; case IXGBE_RDT(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_RDT(i)); break; case IXGBE_RXDCTL(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i)); break; case IXGBE_RDBAL(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_RDBAL(i)); break; case IXGBE_RDBAH(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_RDBAH(i)); break; case IXGBE_TDBAL(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_TDBAL(i)); break; case IXGBE_TDBAH(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_TDBAH(i)); break; case IXGBE_TDLEN(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_TDLEN(i)); break; case IXGBE_TDH(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_TDH(i)); break; case IXGBE_TDT(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_TDT(i)); break; case IXGBE_TXDCTL(0): for (i = 0; i < 64; i++)
regs[i] = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i)); break; default:
pr_info("%-15s %08x\n",
reginfo->name, IXGBE_READ_REG(hw, reginfo->ofs)); return;
}
i = 0; while (i < 64) { int j; char buf[9 * 8 + 1]; char *p = buf;
snprintf(rname, 16, "%s[%d-%d]", reginfo->name, i, i + 7); for (j = 0; j < 8; j++)
p += sprintf(p, " %08x", regs[i++]);
pr_err("%-15s%s\n", rname, buf);
}
}
staticvoid ixgbe_print_buffer(struct ixgbe_ring *ring, int n)
{ struct ixgbe_tx_buffer *tx_buffer;
/* Let firmware take over control of h/w */
ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
}
/* Let firmware know the driver has taken over */
ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
}
/** *ixgbe_set_ivar-settheIVARregisters,mappinginterruptcausestovectors *@adapter:pointertoadapterstruct *@direction:0forRx,1forTx,-1forothercauses *@queue:queuetomapthecorrespondinginterruptto *@msix_vector:thevectortomaptothecorrespondingqueue *
*/ staticvoid ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction,
u8 queue, u8 msix_vector)
{
u32 ivar, index; struct ixgbe_hw *hw = &adapter->hw; switch (hw->mac.type) { case ixgbe_mac_82598EB:
msix_vector |= IXGBE_IVAR_ALLOC_VAL; if (direction == -1)
direction = 0;
index = (((direction * 64) + queue) >> 2) & 0x1F;
ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(index));
ivar &= ~(0xFF << (8 * (queue & 0x3)));
ivar |= (msix_vector << (8 * (queue & 0x3)));
IXGBE_WRITE_REG(hw, IXGBE_IVAR(index), ivar); break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_x550em_a: case ixgbe_mac_e610: if (direction == -1) { /* other causes */
msix_vector |= IXGBE_IVAR_ALLOC_VAL;
index = ((queue & 1) * 8);
ivar = IXGBE_READ_REG(&adapter->hw, IXGBE_IVAR_MISC);
ivar &= ~(0xFF << index);
ivar |= (msix_vector << index);
IXGBE_WRITE_REG(&adapter->hw, IXGBE_IVAR_MISC, ivar); break;
} else { /* tx or rx causes */
msix_vector |= IXGBE_IVAR_ALLOC_VAL;
index = ((16 * (queue & 1)) + (8 * direction));
ivar = IXGBE_READ_REG(hw, IXGBE_IVAR(queue >> 1));
ivar &= ~(0xFF << index);
ivar |= (msix_vector << index);
IXGBE_WRITE_REG(hw, IXGBE_IVAR(queue >> 1), ivar); break;
} default: break;
}
}
/* Do the reset outside of interrupt context */ if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
set_bit(__IXGBE_RESET_REQUESTED, &adapter->state);
e_warn(drv, "initiating reset due to tx timeout\n");
ixgbe_service_event_schedule(adapter);
}
}
/* update the statistics for this packet */
total_bytes += tx_buffer->bytecount;
total_packets += tx_buffer->gso_segs; if (tx_buffer->tx_flags & IXGBE_TX_FLAGS_IPSEC)
total_ipsec++;
/* free the skb */ if (ring_is_xdp(tx_ring))
xdp_return_frame(tx_buffer->xdpf); else
napi_consume_skb(tx_buffer->skb, napi_budget);
/* clear tx_buffer data */
dma_unmap_len_set(tx_buffer, len, 0);
/* unmap remaining buffers */ while (tx_desc != eop_desc) {
tx_buffer++;
tx_desc++;
i++; if (unlikely(!i)) {
i -= tx_ring->count;
tx_buffer = tx_ring->tx_buffer_info;
tx_desc = IXGBE_TX_DESC(tx_ring, 0);
}
/* unmap any remaining paged data */ if (dma_unmap_len(tx_buffer, len)) {
dma_unmap_page(tx_ring->dev,
dma_unmap_addr(tx_buffer, dma),
dma_unmap_len(tx_buffer, len),
DMA_TO_DEVICE);
dma_unmap_len_set(tx_buffer, len, 0);
}
}
/* move us one more past the eop_desc for start of next pkt */
tx_buffer++;
tx_desc++;
i++; if (unlikely(!i)) {
i -= tx_ring->count;
tx_buffer = tx_ring->tx_buffer_info;
tx_desc = IXGBE_TX_DESC(tx_ring, 0);
}
/* issue prefetch for next Tx descriptor */
prefetch(tx_desc);
/* update budget accounting */
budget--;
} while (likely(budget));
staticvoid ixgbe_setup_dca(struct ixgbe_adapter *adapter)
{ int i;
/* always use CB2 mode, difference is masked in the CB driver */ if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL,
IXGBE_DCA_CTRL_DCA_MODE_CB2); else
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL,
IXGBE_DCA_CTRL_DCA_DISABLE);
for (i = 0; i < adapter->num_q_vectors; i++) {
adapter->q_vector[i]->cpu = -1;
ixgbe_update_dca(adapter->q_vector[i]);
}
}
/* Rx csum disabled */ if (!(ring->netdev->features & NETIF_F_RXCSUM)) return;
/* check for VXLAN and Geneve packets */ if (pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_VXLAN)) {
encap_pkt = true;
skb->encapsulation = 1;
}
/* if IP and error */ if (ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_IPCS) &&
ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_IPE)) {
ring->rx_stats.csum_err++; return;
}
if (!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_L4CS)) return;
if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_TCPE)) { /* *82599errata,UDPframeswitha0checksumcanbemarkedas *checksumerrors.
*/ if ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_UDP)) &&
test_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state)) return;
ring->rx_stats.csum_err++; return;
}
/* It must be a TCP or UDP packet with a valid checksum */
skb->ip_summed = CHECKSUM_UNNECESSARY; if (encap_pkt) { if (!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_OUTERIPCS)) return;
if (ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_ERR_OUTERIPER)) {
skb->ip_summed = CHECKSUM_NONE; return;
} /* If we checked the outer header let the stack know */
skb->csum_level = 1;
}
}
/* set gso_size to avoid messing up TCP MSS */
skb_shinfo(skb)->gso_size = DIV_ROUND_UP((skb->len - hdr_len),
IXGBE_CB(skb)->append_cnt);
skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
}
staticvoid ixgbe_update_rsc_stats(struct ixgbe_ring *rx_ring, struct sk_buff *skb)
{ /* if append_cnt is 0 then frame is not RSC */ if (!IXGBE_CB(skb)->append_cnt) return;
/* If the page was released, just unmap it. */ if (unlikely(IXGBE_CB(skb)->page_released)) {
dma_unmap_page_attrs(rx_ring->dev, IXGBE_CB(skb)->dma,
ixgbe_rx_pg_size(rx_ring),
DMA_FROM_DEVICE,
IXGBE_RX_DMA_ATTR);
}
}
/* Verify netdev is present, and that packet does not have any *errorsthatwouldbeunacceptabletothenetdev.
*/ if (!netdev ||
(unlikely(ixgbe_test_staterr(rx_desc,
IXGBE_RXDADV_ERR_FRAME_ERR_MASK) &&
!(netdev->features & NETIF_F_RXALL)))) {
dev_kfree_skb_any(skb); returntrue;
}
/* place header in linear portion of buffer */ if (!skb_headlen(skb))
ixgbe_pull_tail(rx_ring, skb);
#ifdef IXGBE_FCOE /* do not attempt to pad FCoE Frames as this will disrupt DDP */ if (ixgbe_rx_is_fcoe(rx_ring, rx_desc)) returnfalse;
#endif /* if eth_skb_pad returns an error the skb was freed */ if (eth_skb_pad(skb)) returntrue;
/* update, and store next to alloc */
nta++;
rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0;
/* Transfer page from old buffer to new buffer. *Moveeachmemberindividuallytoavoidpossiblestore *forwardingstallsandunnecessarycopyofskb.
*/
new_buff->dma = old_buff->dma;
new_buff->page = old_buff->page;
new_buff->page_offset = old_buff->page_offset;
new_buff->pagecnt_bias = old_buff->pagecnt_bias;
}
/* avoid re-using remote and pfmemalloc pages */ if (!dev_page_is_reusable(page)) returnfalse;
#if (PAGE_SIZE < 8192) /* if we are only owner of page we can reuse it */ if (unlikely((rx_buffer_pgcnt - pagecnt_bias) > 1)) returnfalse; #else /* The last offset is a bit aggressive in that we assume the *worstcaseofFCoEbeingenabledandusinga3Kbuffer. *Howeverthisshouldhaveminimalimpactasthe1Kextrais *stilllessthanonebufferinsize.
*/ #define IXGBE_LAST_OFFSET \
(SKB_WITH_OVERHEAD(PAGE_SIZE) - IXGBE_RXBUFFER_3K) if (rx_buffer->page_offset > IXGBE_LAST_OFFSET) returnfalse; #endif
/* If we have drained the page fragment pool we need to update *thepagecnt_biasandpagecountsothatwefullyrestockthe *numberofreferencesthedriverholds.
*/ if (unlikely(pagecnt_bias == 1)) {
page_ref_add(page, USHRT_MAX - 1);
rx_buffer->pagecnt_bias = USHRT_MAX;
}
/* Delay unmapping of the first packet. It carries the header *information,HWmaystillaccesstheheaderafterthewriteback. *OnlyunmapitwhenEOPisreached
*/ if (!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP)) { if (!*skb) goto skip_sync;
} else { if (*skb)
ixgbe_dma_sync_frag(rx_ring, *skb);
}
/* we are reusing so sync this buffer for CPU use */
dma_sync_single_range_for_cpu(rx_ring->dev,
rx_buffer->dma,
rx_buffer->page_offset,
size,
DMA_FROM_DEVICE);
skip_sync:
rx_buffer->pagecnt_bias--;
return rx_buffer;
}
staticvoid ixgbe_put_rx_buffer(struct ixgbe_ring *rx_ring, struct ixgbe_rx_buffer *rx_buffer, struct sk_buff *skb, int rx_buffer_pgcnt)
{ if (ixgbe_can_reuse_rx_page(rx_buffer, rx_buffer_pgcnt)) { /* hand second half of page back to the ring */
ixgbe_reuse_rx_page(rx_ring, rx_buffer);
} else { if (skb && IXGBE_CB(skb)->dma == rx_buffer->dma) { /* the page has been released from the ring */
IXGBE_CB(skb)->page_released = true;
} else { /* we are not reusing the buffer so unmap it */
dma_unmap_page_attrs(rx_ring->dev, rx_buffer->dma,
ixgbe_rx_pg_size(rx_ring),
DMA_FROM_DEVICE,
IXGBE_RX_DMA_ATTR);
}
__page_frag_cache_drain(rx_buffer->page,
rx_buffer->pagecnt_bias);
}
/* Prefetch first cache line of first page. If xdp->data_meta *isunused,thispointsexactlyasxdp->data,otherwisewe *likelyhaveaconsumeraccessingfirstfewbytesofmeta *data,andthenactualdata.
*/
net_prefetch(xdp->data_meta);
/* build an skb to around the page buffer */
skb = napi_build_skb(xdp->data_hard_start, truesize); if (unlikely(!skb)) return NULL;
/* update pointers within the skb to store the data */
skb_reserve(skb, xdp->data - xdp->data_hard_start);
__skb_put(skb, xdp->data_end - xdp->data); if (metasize)
skb_metadata_set(skb, metasize);
/* record DMA address if this is the start of a chain of buffers */ if (!ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_EOP))
IXGBE_CB(skb)->dma = rx_buffer->dma;
while (likely(total_rx_packets < budget)) { union ixgbe_adv_rx_desc *rx_desc; struct ixgbe_rx_buffer *rx_buffer; struct sk_buff *skb; int rx_buffer_pgcnt; unsignedint size;
/* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= IXGBE_RX_BUFFER_WRITE) {
ixgbe_alloc_rx_buffers(rx_ring, cleaned_count);
cleaned_count = 0;
}
rx_desc = IXGBE_RX_DESC(rx_ring, rx_ring->next_to_clean);
size = le16_to_cpu(rx_desc->wb.upper.length); if (!size) break;
/* This memory barrier is needed to keep us from reading *anyotherfieldsoutoftherx_descuntilweknowthe *descriptorhasbeenwrittenback
*/
dma_rmb();
switch (adapter->hw.mac.type) { case ixgbe_mac_82598EB:
ixgbe_set_ivar(adapter, -1, IXGBE_IVAR_OTHER_CAUSES_INDEX,
v_idx); break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_x550em_a: case ixgbe_mac_e610:
ixgbe_set_ivar(adapter, -1, 1, v_idx); break; default: break;
}
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950);
/* set up to autoclear timer, and the vectors */
mask = IXGBE_EIMS_ENABLE_MASK;
mask &= ~(IXGBE_EIMS_OTHER |
IXGBE_EIMS_MAILBOX |
IXGBE_EIMS_LSC);
if (adapter->hw.mac.type == ixgbe_mac_e610)
mask &= ~IXGBE_EIMS_FW_EVENT;
/* If we don't have any rings just leave ourselves set for maximum *possiblelatencysowetakeourselvesoutoftheequation.
*/ if (!ring_container->ring) return;
/* If we didn't update within up to 1 - 2 jiffies we can assume *thateitherpacketsarecominginsoslowtherehasn'tbeen *anywork,orthatthereissomuchworkthatNAPIisdealing *withinterruptmoderationandwedon'tneedtodoanything.
*/ if (time_after(next_update, ring_container->next_update)) goto clear_counts;
packets = ring_container->total_packets;
/* We have no packets to actually measure against. This means *eitheroneoftheotherqueuesonthisvectorisactiveor *weareaTxqueuedoingTSOwithtoohighofaninterruptrate. * *Whenthisoccursjusttickupourdelaybytheminimumvalue *andhopethatthisextradelaywillpreventusfrombeingcalled *withoutanyworkonourqueue.
*/ if (!packets) {
itr = (q_vector->itr >> 2) + IXGBE_ITR_ADAPTIVE_MIN_INC; if (itr > IXGBE_ITR_ADAPTIVE_MAX_USECS)
itr = IXGBE_ITR_ADAPTIVE_MAX_USECS;
itr += ring_container->itr & IXGBE_ITR_ADAPTIVE_LATENCY; goto clear_counts;
}
bytes = ring_container->total_bytes;
/* If packets are less than 4 or bytes are less than 9000 assume *insufficientdatatousebulkratelimitingapproach.Weare *likelylatencydriven.
*/ if (packets < 4 && bytes < 9000) {
itr = IXGBE_ITR_ADAPTIVE_LATENCY; goto adjust_by_size;
}
/* Between 4 and 48 we can assume that our current interrupt delay *isonlyslightlytoolow.Assuchweshouldincreaseitbyasmall *fixedamount.
*/ if (packets < 48) {
itr = (q_vector->itr >> 2) + IXGBE_ITR_ADAPTIVE_MIN_INC; if (itr > IXGBE_ITR_ADAPTIVE_MAX_USECS)
itr = IXGBE_ITR_ADAPTIVE_MAX_USECS; goto clear_counts;
}
/* Between 48 and 96 is our "goldilocks" zone where we are working *out"justright".JustreportthatourcurrentITRisgoodforus.
*/ if (packets < 96) {
itr = q_vector->itr >> 2; goto clear_counts;
}
/* If packet count is 96 or greater we are likely looking at a slight *overrunofthedelaywewant.Tryhalvingourdelaytoseeifthat *willcutthenumberofpacketsinhalfperinterrupt.
*/ if (packets < 256) {
itr = q_vector->itr >> 3; if (itr < IXGBE_ITR_ADAPTIVE_MIN_USECS)
itr = IXGBE_ITR_ADAPTIVE_MIN_USECS; goto clear_counts;
}
/* The paths below assume we are dealing with a bulk ITR since number *ofpacketsis256orgreater.Wearejustgoingtohavetocompute *avalueandtrytobringthecountundercontrol,thoughforsmaller *packetsizesthereisn'tmuchwecandoasNAPIpollingwilllikely *bekickinginsoonerratherthanlater.
*/
itr = IXGBE_ITR_ADAPTIVE_BULK;
adjust_by_size: /* If packet counts are 256 or greater we can assume we have a gross *overestimationofwhattherateshouldbe.Insteadoftryingtofine *tuneitjustusetheformulabelowtotryanddialinanexactvalue *givethecurrentpacketsizeoftheframe.
*/
avg_wire_size = bytes / packets;
/* The following is a crude approximation of: *wmem_default/(size+overhead)=desired_pkts_per_int *rate/bits_per_byte/(size+ethernetoverhead)=pkt_rate *(desired_pkt_rate/pkt_rate)*usecs_per_sec=ITRvalue * *Assumingwmem_defaultis212992andoverheadis640bytesper *packet,(256skb,64headroom,320sharedinfo),wecanreducethe *formuladownto * *(170*(size+24))/(size+640)=ITR * *Wefirstdosomemathonthepacketsizeandthenfinallybitshift *by8afterroundingup.WealsohavetoaccountforPCIelinkspeed *differenceasITRscalesbasedonthis.
*/ if (avg_wire_size <= 60) { /* Start at 50k ints/sec */
avg_wire_size = 5120;
} elseif (avg_wire_size <= 316) { /* 50K ints/sec to 16K ints/sec */
avg_wire_size *= 40;
avg_wire_size += 2720;
} elseif (avg_wire_size <= 1084) { /* 16K ints/sec to 9.2K ints/sec */
avg_wire_size *= 15;
avg_wire_size += 11452;
} elseif (avg_wire_size < 1968) { /* 9.2K ints/sec to 8K ints/sec */
avg_wire_size *= 5;
avg_wire_size += 22420;
} else { /* plateau at a limit of 8K ints/sec */
avg_wire_size = 32256;
}
/* If we are in low latency mode half our delay which doubles the rate *tosomewherebetween100Kto16Kints/sec
*/ if (itr & IXGBE_ITR_ADAPTIVE_LATENCY)
avg_wire_size >>= 1;
/* Resultant value is 256 times larger than it needs to be. This *givesusroomtoadjustthevalueasneededtoeitherincrease *ordecreasethevaluebasedonlinkspeedsof10G,2.5G,1G,etc. * *Useadditionaswehavealreadyrecordedthenewlatencyflag *fortheITRvalue.
*/ switch (q_vector->adapter->link_speed) { case IXGBE_LINK_SPEED_10GB_FULL: case IXGBE_LINK_SPEED_100_FULL: default:
itr += DIV_ROUND_UP(avg_wire_size,
IXGBE_ITR_ADAPTIVE_MIN_INC * 256) *
IXGBE_ITR_ADAPTIVE_MIN_INC; break; case IXGBE_LINK_SPEED_2_5GB_FULL: case IXGBE_LINK_SPEED_1GB_FULL: case IXGBE_LINK_SPEED_10_FULL: if (avg_wire_size > 8064)
avg_wire_size = 8064;
itr += DIV_ROUND_UP(avg_wire_size,
IXGBE_ITR_ADAPTIVE_MIN_INC * 64) *
IXGBE_ITR_ADAPTIVE_MIN_INC; break;
}
clear_counts: /* write back value */
ring_container->itr = itr;
/* next update should occur within next jiffy */
ring_container->next_update = next_update + 1;
switch (adapter->hw.mac.type) { case ixgbe_mac_82598EB: /* must write high and low 16 bits to reset counter */
itr_reg |= (itr_reg << 16); break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_x550em_a: case ixgbe_mac_e610: /* *settheWDISbittonotclearthetimerbitsandcausean *immediateassertionoftheinterrupt
*/
itr_reg |= IXGBE_EITR_CNT_WDIS; break; default: break;
}
IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg);
}
/* Check if this is not due to overtemp */ if (!hw->phy.ops.check_overtemp(hw)) return;
break; case IXGBE_DEV_ID_X550EM_A_1G_T: case IXGBE_DEV_ID_X550EM_A_1G_T_L: if (!hw->phy.ops.check_overtemp(hw)) return; break; default: if (adapter->hw.mac.type >= ixgbe_mac_X540) return; if (!(eicr & IXGBE_EICR_GPI_SDP0(hw))) return; break;
}
e_crit(drv, "%s\n", ixgbe_overheat_msg);
if (adapter->flags2 & IXGBE_FLAG2_PHY_FW_LOAD_FAILED) return;
if (link_cfg_err & IXGBE_ACI_LINK_EXTERNAL_PHY_LOAD_FAILURE) {
netdev_err(adapter->netdev, "Device failed to load the FW for the external PHY. Please download and install the latest NVM for your device and try again\n");
adapter->flags2 |= IXGBE_FLAG2_PHY_FW_LOAD_FAILED;
}
}
/** *ixgbe_check_module_power-checkmodulepowerlevel *@adapter:pointertoadapterstructure *@link_cfg_err:bitmapfromthelinkinfostructure * *Checkmodulepowerlevelreturnedbyapreviouscalltoaci_get_link_info *andprinterrormessagesifmodulepowerlevelisnotsupported.
*/ staticvoid ixgbe_check_module_power(struct ixgbe_adapter *adapter,
u8 link_cfg_err)
{ /* If module power level is supported, clear the flag. */ if (!(link_cfg_err & (IXGBE_ACI_LINK_INVAL_MAX_POWER_LIMIT |
IXGBE_ACI_LINK_MODULE_POWER_UNSUPPORTED))) {
adapter->flags2 &= ~IXGBE_FLAG2_MOD_POWER_UNSUPPORTED; return;
}
/* If IXGBE_FLAG2_MOD_POWER_UNSUPPORTED was previously set and the *aboveblockdidn'tclearthisbit,there'snothingtodo.
*/ if (adapter->flags2 & IXGBE_FLAG2_MOD_POWER_UNSUPPORTED) return;
if (link_cfg_err & IXGBE_ACI_LINK_INVAL_MAX_POWER_LIMIT) {
netdev_err(adapter->netdev, "The installed module is incompatible with the device's NVM image. Cannot start link.\n");
adapter->flags2 |= IXGBE_FLAG2_MOD_POWER_UNSUPPORTED;
} elseif (link_cfg_err & IXGBE_ACI_LINK_MODULE_POWER_UNSUPPORTED) {
netdev_err(adapter->netdev, "The module's power requirements exceed the device's power supply. Cannot start link.\n");
adapter->flags2 |= IXGBE_FLAG2_MOD_POWER_UNSUPPORTED;
}
}
/* Update the link info structures and re-enable link events, *don'tbailonfailureduetootherbookkeepingneeded.
*/
status = ixgbe_update_link_info(hw); if (status)
e_dev_err("Failed to update link status, err %d aq_err %d\n",
status, hw->aci.last_status);
/* Check if the link state is up after updating link info, and treat *thiseventasanUPeventsincethelinkisactuallyUPnow.
*/ if (hw->link.link_info.link_info & IXGBE_ACI_LINK_UP)
link_up = true;
/* Turn off PHY if media was removed. */ if (!(adapter->flags2 & IXGBE_FLAG2_NO_MEDIA) &&
!(hw->link.link_info.link_info & IXGBE_ACI_MEDIA_AVAILABLE))
adapter->flags2 |= IXGBE_FLAG2_NO_MEDIA;
/* The lower 16bits of the EICR register are for the queue interrupts *whichshouldbemaskedhereinordertonotaccidentallyclearthemif *thebitsarehighwhenixgbe_msix_otheriscalled.Thereisarace *conditionotherwisewhichresultsinpossibleperformanceloss *especiallyiftheixgbe_msix_otherinterruptistriggering *consistently(asitwouldwhenPPSisturnedonfortheX540device)
*/
eicr &= 0xFFFF0000;
IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr);
if (eicr & IXGBE_EICR_LSC)
ixgbe_check_lsc(adapter);
if (eicr & IXGBE_EICR_MAILBOX)
ixgbe_msg_task(adapter);
if (eicr & IXGBE_EICR_FW_EVENT)
ixgbe_schedule_fw_event(adapter);
switch (hw->mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_x550em_a: case ixgbe_mac_e610: if (hw->phy.type == ixgbe_phy_x550em_ext_t &&
(eicr & IXGBE_EICR_GPI_SDP0_X540)) {
adapter->flags2 |= IXGBE_FLAG2_PHY_INTERRUPT;
ixgbe_service_event_schedule(adapter);
IXGBE_WRITE_REG(hw, IXGBE_EICR,
IXGBE_EICR_GPI_SDP0_X540);
} if (eicr & IXGBE_EICR_ECC) {
e_info(link, "Received ECC Err, initiating reset\n");
set_bit(__IXGBE_RESET_REQUESTED, &adapter->state);
ixgbe_service_event_schedule(adapter);
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC);
} /* Handle Flow Director Full threshold interrupt */ if (eicr & IXGBE_EICR_FLOW_DIR) { int reinit_count = 0; int i; for (i = 0; i < adapter->num_tx_queues; i++) { struct ixgbe_ring *ring = adapter->tx_ring[i]; if (test_and_clear_bit(__IXGBE_TX_FDIR_INIT_DONE,
&ring->state))
reinit_count++;
} if (reinit_count) { /* no more flow director interrupts until after init */
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_FLOW_DIR);
adapter->flags2 |= IXGBE_FLAG2_FDIR_REQUIRES_REINIT;
ixgbe_service_event_schedule(adapter);
}
}
ixgbe_check_sfp_event(adapter, eicr);
ixgbe_check_overtemp_event(adapter, eicr); break; default: break;
}
ixgbe_check_fan_failure(adapter, eicr);
if (unlikely(eicr & IXGBE_EICR_TIMESYNC))
ixgbe_ptp_check_pps_event(adapter);
/* re-enable the original interrupt state, no lsc, no queues */ if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable(adapter, false, false);
/* Exit if we are called by netpoll */ if (budget <= 0) return budget;
/* attempt to distribute budget to each queue fairly, but don't allow
* the budget to go below 1 because we'll exit polling */ if (q_vector->rx.count > 1)
per_ring_budget = max(budget/q_vector->rx.count, 1); else
per_ring_budget = budget;
/* If all work not completed, return budget and keep polling */ if (!clean_complete) return budget;
/* all work done, exit the polling mode */ if (likely(napi_complete_done(napi, work_done))) { if (adapter->rx_itr_setting & 1)
ixgbe_set_itr(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable_queues(adapter,
BIT_ULL(q_vector->v_idx));
}
return min(work_done, budget - 1);
}
/** *ixgbe_request_msix_irqs-InitializeMSI-Xinterrupts *@adapter:boardprivatestructure * *ixgbe_request_msix_irqsallocatesMSI-Xvectorsandrequests *interruptsfromthekernel.
**/ staticint ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
{ struct net_device *netdev = adapter->netdev; unsignedint ri = 0, ti = 0; int vector, err;
/* TXDCTL.EN will return 0 on 82598 if link is down, so skip it */ if (hw->mac.type == ixgbe_mac_82598EB &&
!(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) return;
/* poll to verify queue is enabled */ do {
usleep_range(1000, 2000);
txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE)); if (!wait_loop)
hw_dbg(hw, "Could not enable Tx Queue %d\n", reg_idx);
}
if (hw->mac.type != ixgbe_mac_82598EB) { /* DMATXCTL.EN must be before Tx queues are enabled */
dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
dmatxctl |= IXGBE_DMATXCTL_TE;
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl);
}
/* Setup the HW Tx Head and Tail descriptor pointers */ for (i = 0; i < adapter->num_tx_queues; i++)
ixgbe_configure_tx_ring(adapter, adapter->tx_ring[i]); for (i = 0; i < adapter->num_xdp_queues; i++)
ixgbe_configure_tx_ring(adapter, adapter->xdp_ring[i]);
}
/* Fill out the redirection table as follows: *-82598:8bitwideentriescontainingpairof4bitRSS *indices. *-82599/X540:8bitwideentriescontaining4bitRSSindex *-X550:8bitwideentriescontaining6bitRSSindex
*/ if (adapter->hw.mac.type == ixgbe_mac_82598EB)
indices_multi = 0x11; else
indices_multi = 0x1;
/* Write redirection table to HW */ for (i = 0; i < reta_entries; i++) {
reta |= indices_multi * indir_tbl[i] << (i & 0x3) * 8; if ((i & 3) == 3) { if (i < 128)
IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta); else
IXGBE_WRITE_REG(hw, IXGBE_ERETA((i >> 2) - 32),
reta);
reta = 0;
}
}
}
/* Program table for at least 4 queues w/ SR-IOV so that VFs can *makefulluseofanyringstheymayhave.Wewillusethe *PSRTYPEregistertocontrolhowmanyringsweusewithinthePF.
*/ if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) && (rss_i < 4))
rss_i = 4;
/* Fill out hash function seeds */
ixgbe_store_key(adapter);
/* Fill out redirection table */
memset(adapter->rss_indir_tbl, 0, sizeof(adapter->rss_indir_tbl));
for (i = 0, j = 0; i < reta_entries; i++, j++) { if (j == rss_i)
j = 0;
adapter->rss_indir_tbl[i] = j;
}
ixgbe_store_reta(adapter);
}
staticvoid ixgbe_setup_vfreta(struct ixgbe_adapter *adapter)
{ struct ixgbe_hw *hw = &adapter->hw;
u16 rss_i = adapter->ring_feature[RING_F_RSS].indices; int i, j;
/* Fill out hash function seeds */ for (i = 0; i < 10; i++) {
u16 pool = adapter->num_rx_pools;
while (pool--)
IXGBE_WRITE_REG(hw,
IXGBE_PFVFRSSRK(i, VMDQ_P(pool)),
*(adapter->rss_key + i));
}
/* Fill out the redirection table */ for (i = 0, j = 0; i < 64; i++, j++) { if (j == rss_i)
j = 0;
if (ixgbe_removed(hw->hw_addr)) return; /* RXDCTL.EN will return 0 on 82598 if link is down, so skip it */ if (hw->mac.type == ixgbe_mac_82598EB &&
!(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) return;
do {
usleep_range(1000, 2000);
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
} while (--wait_loop && !(rxdctl & IXGBE_RXDCTL_ENABLE));
if (!wait_loop) {
e_err(drv, "RXDCTL.ENABLE on Rx queue %d not set within " "the polling period\n", reg_idx);
}
}
/* disable queue to avoid use of these values while updating state */
rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
rxdctl &= ~IXGBE_RXDCTL_ENABLE;
/* write value back with RXDCTL.ENABLE bit cleared */
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
IXGBE_WRITE_FLUSH(hw);
IXGBE_WRITE_REG(hw, IXGBE_RDBAL(reg_idx), (rdba & DMA_BIT_MASK(32)));
IXGBE_WRITE_REG(hw, IXGBE_RDBAH(reg_idx), (rdba >> 32));
IXGBE_WRITE_REG(hw, IXGBE_RDLEN(reg_idx),
ring->count * sizeof(union ixgbe_adv_rx_desc)); /* Force flushing of IXGBE_RDLEN to prevent MDD */
IXGBE_WRITE_FLUSH(hw);
if (hw->mac.type == ixgbe_mac_82598EB) { /* *enablecachelinefriendlyhardwarewrites: *PTHRESH=32descriptors(halftheinternalcache), *thisalsoremovesuglyrx_no_buffer_countincrement *HTHRESH=4descriptors(tominimizelatencyonfetch) *WTHRESH=8burstwritebackuptotwocachelines
*/
rxdctl &= ~0x3FFFFF;
rxdctl |= 0x080420; #if (PAGE_SIZE < 8192) /* RXDCTL.RLPML does not work on 82599 */
} elseif (hw->mac.type != ixgbe_mac_82599EB) {
rxdctl &= ~(IXGBE_RXDCTL_RLPMLMASK |
IXGBE_RXDCTL_RLPML_EN);
/* Limit the maximum frame size so we don't overrun the skb. *ThiscanhappeninSRIOVmodewhentheMTUoftheVFis *higherthantheMTUofthePF.
*/ if (ring_uses_build_skb(ring) &&
!test_bit(__IXGBE_RX_3K_BUFFER, &ring->state))
rxdctl |= IXGBE_MAX_2K_FRAME_BUILD_SKB |
IXGBE_RXDCTL_RLPML_EN; #endif
}
/* accept untagged packets until a vlan tag is *specificallysetfortheVMDQqueue/pool
*/
vmolr = IXGBE_VMOLR_AUPE; while (pool--)
IXGBE_WRITE_REG(hw, IXGBE_VMOLR(VMDQ_P(pool)), vmolr);
for (i = 0; i < adapter->num_vfs; i++) { /* configure spoof checking */
ixgbe_ndo_set_vf_spoofchk(adapter->netdev, i,
adapter->vfinfo[i].spoofchk_enabled);
#ifdef IXGBE_FCOE /* adjust max frame to be able to do baby jumbo for FCoE */ if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
(max_frame < IXGBE_FCOE_JUMBO_FRAME_SIZE))
max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE;
#endif/* IXGBE_FCOE */
/* adjust max frame to be at least the size of a standard frame */ if (max_frame < (ETH_FRAME_LEN + ETH_FCS_LEN))
max_frame = (ETH_FRAME_LEN + ETH_FCS_LEN);
switch (hw->mac.type) { case ixgbe_mac_82598EB: /* *ForVMDqsupportofdifferentdescriptortypesor *buffersizesthroughtheuseofmultipleSRRCTL *registers,RDRXCTL.MVMENmustbesetto1 * *also,themanualdoesn'tmentionitclearlybutDCAhints *willonlyusequeue0'stagsunlessthisbitisset.Side *effectsofsettingthisbitareonlythatSRRCTLmustbe *fullyprogrammed[0..15]
*/
rdrxctl |= IXGBE_RDRXCTL_MVMEN; break; case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_x550em_a: case ixgbe_mac_e610: if (adapter->num_vfs)
rdrxctl |= IXGBE_RDRXCTL_PSP;
fallthrough; case ixgbe_mac_82599EB: case ixgbe_mac_X540: /* Disable RSC for ACK packets */
IXGBE_WRITE_REG(hw, IXGBE_RSCDBU,
(IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU)));
rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE; /* hardware requires some bits to be set by default */
rdrxctl |= (IXGBE_RDRXCTL_RSCACKC | IXGBE_RDRXCTL_FCOE_WRFIX);
rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP; break; default: /* We should do nothing since we don't know this hardware */ return;
}
/* Program registers for the distribution of queues */
ixgbe_setup_mrqc(adapter);
/* set_rx_buffer_len must be called before ring initialization */
ixgbe_set_rx_buffer_len(adapter);
/* *SetuptheHWRxHeadandTailDescriptorPointersand *theBaseandLengthoftheRxDescriptorRing
*/ for (i = 0; i < adapter->num_rx_queues; i++)
ixgbe_configure_rx_ring(adapter, adapter->rx_ring[i]);
rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); /* disable drop enable for 82598 parts */ if (hw->mac.type == ixgbe_mac_82598EB)
rxctrl |= IXGBE_RXCTRL_DMBYPS;
/* short cut the special case */ if (vlan == 0) return0;
/* Search for the vlan id in the VLVF entries */ for (idx = IXGBE_VLVF_ENTRIES; --idx;) {
vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(idx)); if ((vlvf & VLAN_VID_MASK) == vlan) break;
}
idx = ixgbe_find_vlvf_entry(hw, vid); if (!idx) return;
/* See if any other pools are set for this VLAN filter *entryotherthanthePF.
*/
word = idx * 2 + (VMDQ_P(0) / 32);
bits = ~BIT(VMDQ_P(0) % 32);
bits &= IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
/* Disable the filter so this falls into the default pool. */ if (!bits && !IXGBE_READ_REG(hw, IXGBE_VLVFB(word ^ 1))) { if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), 0);
IXGBE_WRITE_REG(hw, IXGBE_VLVF(idx), 0);
}
}
/* remove VID from filter table */ if (vid && !(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), false, true);
clear_bit(vid, adapter->active_vlans);
return0;
}
/** *ixgbe_vlan_strip_disable-helpertodisablehwvlanstripping *@adapter:driverdata
*/ staticvoid ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter)
{ struct ixgbe_hw *hw = &adapter->hw;
u32 vlnctrl; int i, j;
switch (hw->mac.type) { case ixgbe_mac_82598EB:
vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
vlnctrl &= ~IXGBE_VLNCTRL_VME;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_x550em_a: case ixgbe_mac_e610: for (i = 0; i < adapter->num_rx_queues; i++) { struct ixgbe_ring *ring = adapter->rx_ring[i];
/** *ixgbe_vlan_strip_enable-helpertoenablehwvlanstripping *@adapter:driverdata
*/ staticvoid ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter)
{ struct ixgbe_hw *hw = &adapter->hw;
u32 vlnctrl; int i, j;
switch (hw->mac.type) { case ixgbe_mac_82598EB:
vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
vlnctrl |= IXGBE_VLNCTRL_VME;
IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_x550em_a: case ixgbe_mac_e610: for (i = 0; i < adapter->num_rx_queues; i++) { struct ixgbe_ring *ring = adapter->rx_ring[i];
for (i = IXGBE_VLVF_ENTRIES; --i;) {
u32 vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i));
/* pull VLAN ID from VLVF */
vid = vlvf & VLAN_VID_MASK;
/* only concern ourselves with a certain range */ if (vid < vid_start || vid >= vid_end) continue;
if (vlvf) { /* record VLAN ID in VFTA */
vfta[(vid - vid_start) / 32] |= BIT(vid % 32);
/* if PF is part of this then continue */ if (test_bit(vid, adapter->active_vlans)) continue;
}
/* remove PF from the pool */
word = i * 2 + VMDQ_P(0) / 32;
bits = ~BIT(VMDQ_P(0) % 32);
bits &= IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), bits);
}
/* extract values from active_vlans and write back to VFTA */ for (i = VFTA_BLOCK_SIZE; i--;) {
vid = (vfta_offset + i) * 32;
word = vid / BITS_PER_LONG;
bits = vid % BITS_PER_LONG;
for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) { /* do not count default RAR as available */ if (mac_table->state & IXGBE_MAC_STATE_DEFAULT) continue;
/* only count unused and addresses that belong to us */ if (mac_table->state & IXGBE_MAC_STATE_IN_USE) { if (mac_table->pool != pool) continue;
}
count++;
}
return count;
}
/* this function destroys the first RAR entry */ staticvoid ixgbe_mac_set_default_filter(struct ixgbe_adapter *adapter)
{ struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0]; struct ixgbe_hw *hw = &adapter->hw;
/* search table for addr, if found clear IN_USE flag and sync */ for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) { /* we can only delete an entry if it is in use */ if (!(mac_table->state & IXGBE_MAC_STATE_IN_USE)) continue; /* we only care about entries that belong to the given pool */ if (mac_table->pool != pool) continue; /* we only care about a specific MAC address */ if (!ether_addr_equal(addr, mac_table->addr)) continue;
/* Check for Promiscuous and All Multicast modes */
fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
/* set all bits that we expect to always be set */
fctrl &= ~IXGBE_FCTRL_SBP; /* disable store-bad-packets */
fctrl |= IXGBE_FCTRL_BAM;
fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */
fctrl |= IXGBE_FCTRL_PMCF;
/* clear the bits we are changing the status of */
fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); if (netdev->flags & IFF_PROMISC) {
hw->addr_ctrl.user_set_promisc = true;
fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
vmolr |= IXGBE_VMOLR_MPE;
features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
} else { if (netdev->flags & IFF_ALLMULTI) {
fctrl |= IXGBE_FCTRL_MPE;
vmolr |= IXGBE_VMOLR_MPE;
}
hw->addr_ctrl.user_set_promisc = false;
}
/* This is useful for sniffing bad packets. */ if (features & NETIF_F_RXALL) { /* UPE and MPE will be handled by normal PROMISC logic
* in e1000e_set_rx_mode */
fctrl |= (IXGBE_FCTRL_SBP | /* Receive bad packets */
IXGBE_FCTRL_BAM | /* RX All Bcast Pkts */
IXGBE_FCTRL_PMCF); /* RX All MAC Ctrl Pkts */
fctrl &= ~(IXGBE_FCTRL_DPF); /* NOTE: VLAN filtering is disabled by setting PROMISC */
}
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
if (features & NETIF_F_HW_VLAN_CTAG_RX)
ixgbe_vlan_strip_enable(adapter); else
ixgbe_vlan_strip_disable(adapter);
if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
ixgbe_vlan_promisc_disable(adapter); else
ixgbe_vlan_promisc_enable(adapter);
}
staticvoid ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
{ int q_idx;
for (q_idx = 0; q_idx < adapter->num_q_vectors; q_idx++)
napi_enable(&adapter->q_vector[q_idx]->napi);
}
staticvoid ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
{ int q_idx;
for (q_idx = 0; q_idx < adapter->num_q_vectors; q_idx++)
napi_disable(&adapter->q_vector[q_idx]->napi);
}
/* Calculate delay value for device */ switch (hw->mac.type) { case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_x550em_a: case ixgbe_mac_e610:
dv_id = IXGBE_DV_X540(link, tc); break; default:
dv_id = IXGBE_DV(link, tc); break;
}
/* Delay value is calculated in bit times convert to KB */
kb = IXGBE_BT2KB(dv_id);
rx_pba = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(pb)) >> 10;
marker = rx_pba - kb;
/* It is possible that the packet buffer is not large enough *toproviderequiredheadroom.Inthiscasethrowanerror *touserandadothebestwecan.
*/ if (marker < 0) {
e_warn(drv, "Packet Buffer(%i) can not provide enough" "headroom to support flow control." "Decrease MTU or number of traffic classes\n", pb);
marker = tc + 1;
}
/* Calculate delay value for device */ switch (hw->mac.type) { case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_x550em_a: case ixgbe_mac_e610:
dv_id = IXGBE_LOW_DV_X540(tc); break; default:
dv_id = IXGBE_LOW_DV(tc); break;
}
/* Delay value is calculated in bit times convert to KB */ return IXGBE_BT2KB(dv_id);
}
/* *ixgbe_pbthresh_setup-calculateandsetuphighlowwatermarks
*/ staticvoid ixgbe_pbthresh_setup(struct ixgbe_adapter *adapter)
{ struct ixgbe_hw *hw = &adapter->hw; int num_tc = adapter->hw_tcs; int i;
if (!num_tc)
num_tc = 1;
for (i = 0; i < num_tc; i++) {
hw->fc.high_water[i] = ixgbe_hpbthresh(adapter, i);
hw->fc.low_water[i] = ixgbe_lpbthresh(adapter, i);
/* Low water marks must not be larger than high water marks */ if (hw->fc.low_water[i] > hw->fc.high_water[i])
hw->fc.low_water[i] = 0;
}
for (; i < MAX_TRAFFIC_CLASS; i++)
hw->fc.high_water[i] = 0;
}
if (rx_ring->xsk_pool) {
ixgbe_xsk_clean_rx_ring(rx_ring); goto skip_free;
}
/* Free all the Rx ring sk_buffs */ while (i != rx_ring->next_to_alloc) { if (rx_buffer->skb) { struct sk_buff *skb = rx_buffer->skb; if (IXGBE_CB(skb)->page_released)
dma_unmap_page_attrs(rx_ring->dev,
IXGBE_CB(skb)->dma,
ixgbe_rx_pg_size(rx_ring),
DMA_FROM_DEVICE,
IXGBE_RX_DMA_ATTR);
dev_kfree_skb(skb);
}
/* Invalidate cache lines that may have been written to by *devicesothatweavoidcorruptingmemory.
*/
dma_sync_single_range_for_cpu(rx_ring->dev,
rx_buffer->dma,
rx_buffer->page_offset,
ixgbe_rx_bufsz(rx_ring),
DMA_FROM_DEVICE);
/* record configuration for macvlan interface in vdev */ for (i = 0; i < num_tc; i++)
netdev_bind_sb_channel_queue(adapter->netdev, vdev,
i, rss_i, baseq + (rss_i * i));
for (i = 0; i < adapter->num_rx_queues_per_pool; i++)
adapter->rx_ring[baseq + i]->netdev = vdev;
/* Guarantee all rings are updated before we update the *MACaddressfilter.
*/
wmb();
/* ixgbe_add_mac_filter will return an index if it succeeds, so we *needtoonlytreatitasanerrorvalueifitisnegative.
*/
err = ixgbe_add_mac_filter(adapter, vdev->dev_addr,
VMDQ_P(accel->pool)); if (err >= 0) return0;
/* if we cannot add the MAC rule then disable the offload */
macvlan_release_l2fw_offload(vdev);
for (i = 0; i < adapter->num_rx_queues_per_pool; i++)
adapter->rx_ring[baseq + i]->netdev = NULL;
netdev_err(vdev, "L2FW offload disabled due to L2 filter error\n");
/* unbind the queues and drop the subordinate channel config */
netdev_unbind_sb_channel(adapter->netdev, vdev);
netdev_set_sb_channel(vdev, 0);
if (hw->mac.ops.check_link)
ret = hw->mac.ops.check_link(hw, &speed, &link_up, false);
if (ret) return ret;
speed = hw->phy.autoneg_advertised; if (!speed && hw->mac.ops.get_link_capabilities) {
ret = hw->mac.ops.get_link_capabilities(hw, &speed,
&autoneg); /* remove NBASE-T speeds from default autonegotiation *toaccommodatebrokennetworkswitchesinthefield *whichcannotcopewithadvertisedNBASE-Tspeeds
*/
speed &= ~(IXGBE_LINK_SPEED_5GB_FULL |
IXGBE_LINK_SPEED_2_5GB_FULL);
}
if (ret) return ret;
if (hw->mac.ops.setup_link) { if (adapter->hw.mac.type == ixgbe_mac_e610) {
ret = ixgbe_enable_link_status_events(adapter, mask); if (ret) return ret;
}
ret = hw->mac.ops.setup_link(hw, speed, link_up);
}
if (hw->link.link_info.link_info & IXGBE_ACI_MEDIA_AVAILABLE) { /* PHY settings are reset on media insertion, reconfigure *PHYtopreservesettings.
*/ if (!(ixgbe_non_sfp_link_config(&adapter->hw)))
adapter->flags2 &= ~IXGBE_FLAG2_NO_MEDIA;
/* A Link Status Event will be generated; the event handler *willcompletebringingtheinterfaceup
*/
}
}
if (ixgbe_is_sfp(hw)) {
ixgbe_sfp_link_config(adapter);
} else {
err = ixgbe_non_sfp_link_config(hw); if (err)
e_err(probe, "link_config FAILED %d\n", err);
}
/* clear any pending interrupts, may auto mask */
IXGBE_READ_REG(hw, IXGBE_EICR);
ixgbe_irq_enable(adapter, true, true);
/* *Ifthisadapterhasafan,checktoseeifwehadafailure *beforeweenabledtheinterrupt.
*/ if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) {
u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); if (esdp & IXGBE_ESDP_SDP1)
e_crit(drv, "Fan has stopped, replace the adapter\n");
}
/* bring the link up in the watchdog, this could race with our first
* link up interrupt but shouldn't be a problem */
adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
adapter->link_check_timeout = jiffies;
mod_timer(&adapter->service_timer, jiffies);
ixgbe_clear_vf_stats_counters(adapter); /* Set PF Reset Done bit so PF/VF Mail Ops can work */
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD;
IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
/* update setting rx tx for all active vfs */
ixgbe_set_all_vfs(adapter);
}
void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
{ /* put off any impending NetWatchDogTimeout */
netif_trans_update(adapter->netdev);
while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
usleep_range(1000, 2000); if (adapter->hw.phy.type == ixgbe_phy_fw)
ixgbe_watchdog_link_is_down(adapter);
ixgbe_down(adapter); /* *IfSR-IOVenabledthenwaitabitbeforebringingtheadapter *backuptogivetheVFstimetorespondtothereset.The *twosecondwaitisbaseduponthewatchdogtimercyclein *theVFdriver.
*/ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
msleep(2000);
ixgbe_up(adapter);
clear_bit(__IXGBE_RESETTING, &adapter->state);
}
void ixgbe_up(struct ixgbe_adapter *adapter)
{ /* hardware has been reset, we need to reload some things */
ixgbe_configure(adapter);
switch (devctl2 & IXGBE_PCIDEVCTRL2_TIMEO_MASK) { case IXGBE_PCIDEVCTRL2_17_34s: case IXGBE_PCIDEVCTRL2_4_8s: /* For now we cap the upper limit on delay to 2 seconds *asweendupgoingupto34secondsofdelayinworst *casetimeoutvalue.
*/ case IXGBE_PCIDEVCTRL2_1_2s: return2000000ul; /* 2.0 s */ case IXGBE_PCIDEVCTRL2_260_520ms: return520000ul; /* 520 ms */ case IXGBE_PCIDEVCTRL2_65_130ms: return130000ul; /* 130 ms */ case IXGBE_PCIDEVCTRL2_16_32ms: return32000ul; /* 32 ms */ case IXGBE_PCIDEVCTRL2_1_2ms: return2000ul; /* 2 ms */ case IXGBE_PCIDEVCTRL2_50_100us: return100ul; /* 100 us */ case IXGBE_PCIDEVCTRL2_16_32ms_def: return32000ul; /* 32 ms */ default: break;
}
/* We shouldn't need to hit this path, but just in case default as *thoughcompletiontimeoutisnotsupportedandsupport32ms.
*/ return32000ul;
}
void ixgbe_disable_rx(struct ixgbe_adapter *adapter)
{ unsignedlong wait_delay, delay_interval; struct ixgbe_hw *hw = &adapter->hw; int i, wait_loop;
u32 rxdctl;
/* write value back with RXDCTL.ENABLE bit cleared */
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
}
/* RXDCTL.EN may not change on 82598 if link is down, so skip it */ if (hw->mac.type == ixgbe_mac_82598EB &&
!(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) return;
/* Determine our minimum delay interval. We will increase this value *witheachsubsequenttest.Thiswayifthedevicereturnsquickly *weshouldspendaslittletimeaspossiblewaiting,howeveras *thetimeincreaseswewillwaitforlargerperiodsoftime. * *Thetrickhereisthatweincreasetheintervalusingthe *followingpattern:1x3x5x7x9x11x13x15x17x19x.Theresult *ofthatwaitisthatittotalsupto100xwhateverintervalwe *choose.Sinceourminimumwaitis100uswecanjustdividethe *totaltimeoutby100togetourminimumdelayinterval.
*/
delay_interval = ixgbe_get_completion_timeout(adapter) / 100;
/* OR together the reading of all the active RXDCTL registers, *andthentesttheresult.Weneedthedisabletocomplete *beforewestartfreeingthememoryandinvalidatingthe *DMAmappings.
*/ for (i = 0; i < adapter->num_rx_queues; i++) { struct ixgbe_ring *ring = adapter->rx_ring[i];
u8 reg_idx = ring->reg_idx;
/* If the link is not up there shouldn't be much in the way of *pendingtransactions.Thosethatareleftwillbeflushedout *whentheresetlogicgoesthroughtheflushsequencetocleanout *thependingTxtransactions.
*/ if (!(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) goto dma_engine_disable;
/* Determine our minimum delay interval. We will increase this value *witheachsubsequenttest.Thiswayifthedevicereturnsquickly *weshouldspendaslittletimeaspossiblewaiting,howeveras *thetimeincreaseswewillwaitforlargerperiodsoftime. * *Thetrickhereisthatweincreasetheintervalusingthe *followingpattern:1x3x5x7x9x11x13x15x17x19x.Theresult *ofthatwaitisthatittotalsupto100xwhateverintervalwe *choose.Sinceourminimumwaitis100uswecanjustdividethe *totaltimeoutby100togetourminimumdelayinterval.
*/
delay_interval = ixgbe_get_completion_timeout(adapter) / 100;
/* OR together the reading of all the active TXDCTL registers, *andthentesttheresult.Weneedthedisabletocomplete *beforewestartfreeingthememoryandinvalidatingthe *DMAmappings.
*/ for (i = 0; i < adapter->num_tx_queues; i++) { struct ixgbe_ring *ring = adapter->tx_ring[i];
u8 reg_idx = ring->reg_idx;
txdctl |= IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
} for (i = 0; i < adapter->num_xdp_queues; i++) { struct ixgbe_ring *ring = adapter->xdp_ring[i];
u8 reg_idx = ring->reg_idx;
if (!(txdctl & IXGBE_TXDCTL_ENABLE)) goto dma_engine_disable;
}
e_err(drv, "TXDCTL.ENABLE for one or more queues not cleared within the polling period\n");
dma_engine_disable: /* Disable the Tx DMA engine on 82599 and later MAC */ switch (hw->mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_x550em_a: case ixgbe_mac_e610:
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL,
(IXGBE_READ_REG(hw, IXGBE_DMATXCTL) &
~IXGBE_DMATXCTL_TE));
fallthrough; default: break;
}
}
if (ixgbe_removed(hw->hw_addr)) return; /* lock SFP init bit to prevent race conditions with the watchdog */ while (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
usleep_range(1000, 2000);
/* clear all SFP and link config related flags while holding SFP_INIT */
adapter->flags2 &= ~(IXGBE_FLAG2_SEARCH_FOR_SFP |
IXGBE_FLAG2_SFP_NEEDS_RESET);
adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
err = hw->mac.ops.init_hw(hw); switch (err) { case0: case -ENOENT: case -EOPNOTSUPP: break; case -EALREADY:
e_dev_err("primary disable timed out\n"); break; case -EACCES: /* We are running on a pre-production device, log a warning */
e_dev_warn("This device is a pre-production adapter/LOM. " "Please be aware there may be issues associated with " "your hardware. If you are experiencing problems " "please contact your Intel or hardware " "representative who provided you with this " "hardware.\n"); break; default:
e_dev_err("Hardware Error: %d\n", err);
}
clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
/* flush entries out of MAC table */
ixgbe_flush_sw_mac_table(adapter);
__dev_uc_unsync(netdev, NULL);
/* do not flush user set addresses */
ixgbe_mac_set_default_filter(adapter);
/* update SAN MAC vmdq pool selection */ if (hw->mac.san_mac_rar_index)
hw->mac.ops.set_vmdq_san_mac(hw, VMDQ_P(0));
if (test_bit(__IXGBE_PTP_RUNNING, &adapter->state))
ixgbe_ptp_reset(adapter);
if (hw->phy.ops.set_phy_power) { if (!netif_running(adapter->netdev) && !adapter->wol)
hw->phy.ops.set_phy_power(hw, false); else
hw->phy.ops.set_phy_power(hw, true);
}
}
/* check for eop_desc to determine the end of the packet */
eop_desc = tx_buffer->next_to_watch;
tx_desc = IXGBE_TX_DESC(tx_ring, i);
/* unmap remaining buffers */ while (tx_desc != eop_desc) {
tx_buffer++;
tx_desc++;
i++; if (unlikely(i == tx_ring->count)) {
i = 0;
tx_buffer = tx_ring->tx_buffer_info;
tx_desc = IXGBE_TX_DESC(tx_ring, 0);
}
/* unmap any remaining paged data */ if (dma_unmap_len(tx_buffer, len))
dma_unmap_page(tx_ring->dev,
dma_unmap_addr(tx_buffer, dma),
dma_unmap_len(tx_buffer, len),
DMA_TO_DEVICE);
}
/* move us one more past the eop_desc for start of next pkt */
tx_buffer++;
i++; if (unlikely(i == tx_ring->count)) {
i = 0;
tx_buffer = tx_ring->tx_buffer_info;
}
}
/* reset BQL for queue */ if (!ring_is_xdp(tx_ring))
netdev_tx_reset_queue(txring_txq(tx_ring));
for (i = 0; i < adapter->num_tx_queues; i++)
ixgbe_clean_tx_ring(adapter->tx_ring[i]); for (i = 0; i < adapter->num_xdp_queues; i++)
ixgbe_clean_tx_ring(adapter->xdp_ring[i]);
}
#ifdef CONFIG_PCI_IOV if (max_vfs > 0)
e_dev_warn("Enabling SR-IOV VFs using the max_vfs module parameter is deprecated - please use the pci sysfs interface instead.\n");
/* assign number of SR-IOV VFs */ if (hw->mac.type != ixgbe_mac_82598EB) { if (max_vfs > IXGBE_MAX_VFS_DRV_LIMIT) {
max_vfs = 0;
e_dev_warn("max_vfs parameter out of range. Not assigning any SR-IOV VFs\n");
}
} #endif/* CONFIG_PCI_IOV */
/* enable itr by default in dynamic mode */
adapter->rx_itr_setting = 1;
adapter->tx_itr_setting = 1;
/* set default ring sizes */
adapter->tx_ring_count = IXGBE_DEFAULT_TXD;
adapter->rx_ring_count = IXGBE_DEFAULT_RXD;
/* set default work limits */
adapter->tx_work_limit = IXGBE_DEFAULT_TX_WORK;
return0;
err_setup_tx: /* rewind the index freeing the rings as we go */ while (j--)
ixgbe_free_tx_resources(adapter->xdp_ring[j]); while (i--)
ixgbe_free_tx_resources(adapter->tx_ring[i]); return err;
}
#ifdef IXGBE_FCOE
err = ixgbe_setup_fcoe_ddp_resources(adapter); if (!err) #endif return0;
err_setup_rx: /* rewind the index freeing the rings as we go */ while (i--)
ixgbe_free_rx_resources(adapter->rx_ring[i]); return err;
}
for (i = 0; i < adapter->num_tx_queues; i++) if (adapter->tx_ring[i]->desc)
ixgbe_free_tx_resources(adapter->tx_ring[i]); for (i = 0; i < adapter->num_xdp_queues; i++) if (adapter->xdp_ring[i]->desc)
ixgbe_free_tx_resources(adapter->xdp_ring[i]);
}
err = ixgbe_request_irq(adapter); if (err) goto err_req_irq;
/* Notify the stack of the actual queue counts. */
queues = adapter->num_tx_queues;
err = netif_set_real_num_tx_queues(netdev, queues); if (err) goto err_set_queues;
switch (hw->mac.type) { case ixgbe_mac_82598EB:
pci_wake_from_d3(pdev, false); break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_x550em_a: case ixgbe_mac_e610:
pci_wake_from_d3(pdev, !!wufc); break; default: break;
}
*enable_wake = !!wufc; if (hw->phy.ops.set_phy_power && !*enable_wake)
hw->phy.ops.set_phy_power(hw, false);
ixgbe_release_hw_control(adapter);
if (!test_and_set_bit(__IXGBE_DISABLED, &adapter->state))
pci_disable_device(pdev);
bytes = 0;
packets = 0; /* gather some stats to the adapter struct that are per queue */ for (i = 0; i < adapter->num_tx_queues; i++) { struct ixgbe_ring *tx_ring = READ_ONCE(adapter->tx_ring[i]);
if (!tx_ring) continue;
restart_queue += tx_ring->tx_stats.restart_queue;
tx_busy += tx_ring->tx_stats.tx_busy;
bytes += tx_ring->stats.bytes;
packets += tx_ring->stats.packets;
} for (i = 0; i < adapter->num_xdp_queues; i++) { struct ixgbe_ring *xdp_ring = READ_ONCE(adapter->xdp_ring[i]);
/* If we're down, removing or resetting, just bail */ if (test_bit(__IXGBE_DOWN, &adapter->state) ||
test_bit(__IXGBE_REMOVING, &adapter->state) ||
test_bit(__IXGBE_RESETTING, &adapter->state)) return;
/* Force detection of hung controller */ if (netif_carrier_ok(adapter->netdev)) for (i = 0; i < adapter->num_tx_queues; i++)
set_check_for_tx_hang(adapter->tx_ring[i]);
if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) { /* *forlegacyandMSIinterruptsdon'tsetanybits *thatareenabledforEIAM,becausethisoperation *wouldset*both*EIMSandEICSforanybitinEIAM
*/
IXGBE_WRITE_REG(hw, IXGBE_EICS,
(IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
} else { /* get one bit for every active tx/rx interrupt vector */ for (i = 0; i < adapter->num_q_vectors; i++) { struct ixgbe_q_vector *qv = adapter->q_vector[i]; if (qv->rx.ring || qv->tx.ring)
eics |= BIT_ULL(i);
}
}
/* Cause software interrupt to ensure rings are cleaned */
ixgbe_irq_rearm_queues(adapter, eics);
}
if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE)) return;
if (hw->mac.ops.check_link) {
hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
} else { /* always assume link is up, if no check link function */
link_speed = IXGBE_LINK_SPEED_10GB_FULL;
link_up = true;
}
if (adapter->ixgbe_ieee_pfc)
pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en);
/* resetting the PF is only needed for MAC before X550 */ if (hw->mac.type >= ixgbe_mac_X550) returnfalse;
for (i = 0; i < adapter->num_vfs; i++) { for (j = 0; j < q_per_pool; j++) {
u32 h, t;
h = IXGBE_READ_REG(hw, IXGBE_PVFTDHN(q_per_pool, i, j));
t = IXGBE_READ_REG(hw, IXGBE_PVFTDTN(q_per_pool, i, j));
if (h != t) returntrue;
}
}
returnfalse;
}
/** *ixgbe_watchdog_flush_tx-flushqueuesonlinkdown *@adapter:pointertothedeviceadapterstructure
**/ staticvoid ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter)
{ if (!netif_carrier_ok(adapter->netdev)) { if (ixgbe_ring_tx_pending(adapter) ||
ixgbe_vf_tx_pending(adapter)) { /* We've lost link, so the controller stops DMA, *butwe'vegotqueuedTxworkthat'snevergoing *togetdone,soresetcontrollertoflushTx. *(Dotheresetoutsideofinterruptcontext).
*/
e_warn(drv, "initiating reset to clear Tx work after link loss\n");
set_bit(__IXGBE_RESET_REQUESTED, &adapter->state);
}
}
}
gpc = IXGBE_READ_REG(hw, IXGBE_TXDGPC); if (gpc) /* If incrementing then no need for the check below */ return; /* Check to see if a bad DMA write target from an errant or *maliciousVFhascausedaPCIeerror.Ifsothenwecan *issueaVFLRtotheoffendingVF(s)andthenresumewithout *requestingafullslotreset.
*/
if (!pdev) return;
/* check status reg for all VFs owned by this PF */ for (vf = 0; vf < adapter->num_vfs; ++vf) { struct pci_dev *vfdev = adapter->vfinfo[vf].vfdev;
u16 status_reg;
/* not searching for SFP so there is nothing to do here */ if (!(adapter->flags2 & IXGBE_FLAG2_SEARCH_FOR_SFP) &&
!(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET)) return;
if (adapter->sfp_poll_time &&
time_after(adapter->sfp_poll_time, jiffies)) return; /* If not yet time to poll for SFP */
/* someone else is in init, wait until next service event */ if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state)) return;
err = hw->phy.ops.identify_sfp(hw); if (err == -EOPNOTSUPP) goto sfp_out;
if (err == -ENOENT) { /* If no cable is present, then we need to reset
* the next time we find a good cable. */
adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
}
/* exit on error */ if (err) goto sfp_out;
/* exit if reset not needed */ if (!(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET)) goto sfp_out;
if (err == -EOPNOTSUPP &&
adapter->netdev->reg_state == NETREG_REGISTERED) {
e_dev_err("failed to initialize because an unsupported " "SFP+ module type was detected.\n");
e_dev_err("Reload the driver after installing a " "supported module.\n");
unregister_netdev(adapter->netdev);
}
}
if (hw->mac.ops.get_fw_ver && hw->mac.ops.get_fw_ver(hw)) return0;
if (hw->api_maj_ver > IXGBE_FW_API_VER_MAJOR) {
e_dev_err("The driver for the device stopped because the NVM image is newer than expected. You must install the most recent version of the network driver.\n");
adapter->flags2 |= IXGBE_FLAG2_API_MISMATCH; return -EOPNOTSUPP;
} elseif (hw->api_maj_ver == IXGBE_FW_API_VER_MAJOR &&
hw->api_min_ver > IXGBE_FW_API_VER_MINOR + IXGBE_FW_API_VER_DIFF_ALLOWED) {
e_dev_info("The driver for the device detected a newer version of the NVM image than expected. Please install the most recent version of the network driver.\n");
adapter->flags2 |= IXGBE_FLAG2_API_MISMATCH;
} elseif (hw->api_maj_ver < IXGBE_FW_API_VER_MAJOR ||
hw->api_min_ver < IXGBE_FW_API_VER_MINOR - IXGBE_FW_API_VER_DIFF_ALLOWED) {
e_dev_info("The driver for the device detected an older version of the NVM image than expected. Please update the NVM image.\n");
adapter->flags2 |= IXGBE_FLAG2_API_MISMATCH;
}
/* skip if E610's FW is reloading, warning in that case may be misleading */ if (fwsm & IXGBE_FWSM_EXT_ERR_IND_MASK ||
(!(fwsm & IXGBE_FWSM_FW_VAL_BIT) && !(hw->mac.type == ixgbe_mac_e610)))
e_dev_warn("Warning firmware error detected FWSM: 0x%08X\n",
fwsm);
if (hw->mac.ops.fw_recovery_mode && hw->mac.ops.fw_recovery_mode(hw)) {
e_dev_err("Firmware recovery mode detected. Limiting functionality. Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware recovery mode.\n"); returntrue;
} if (!(adapter->flags2 & IXGBE_FLAG2_API_MISMATCH)) {
err = ixgbe_check_fw_api_mismatch(adapter); if (err) returntrue;
}
/* return here if FW rollback mode has been already detected */ if (adapter->flags2 & IXGBE_FLAG2_FW_ROLLBACK) returnfalse;
if (hw->mac.ops.get_fw_ver && hw->mac.ops.get_fw_ver(hw)) goto no_version;
if (hw->mac.ops.get_nvm_ver &&
hw->mac.ops.get_nvm_ver(hw, nvm_info)) goto no_version;
snprintf(ver_buff, sizeof(ver_buff), "Current version is NVM:%x.%x.%x, FW:%d.%d. ",
nvm_info->major, nvm_info->minor, nvm_info->eetrack,
hw->fw_maj_ver, hw->fw_maj_ver);
no_version:
e_dev_warn("Firmware rollback mode detected. %sDevice may exhibit limited functionality. Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware rollback mode.",
ver_buff);
/* initialize outer IP header fields */ if (ip.v4->version == 4) { unsignedchar *csum_start = skb_checksum_start(skb); unsignedchar *trans_start = ip.hdr + (ip.v4->ihl * 4); int len = csum_start - trans_start;
/* IP header will have to cancel out any data that *isnotapartoftheouterIPheader,sosetto *areversecsumifneeded,elseinitcheckto0.
*/
ip.v4->check = (skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL) ?
csum_fold(csum_partial(trans_start,
len, 0)) : 0;
type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
/* if ring doesn't have a interrupt vector, cannot perform ATR */ if (!q_vector) return;
/* do nothing if sampling is disabled */ if (!ring->atr_sample_rate) return;
ring->atr_count++;
/* currently only IPv4/IPv6 with TCP is supported */ if ((first->protocol != htons(ETH_P_IP)) &&
(first->protocol != htons(ETH_P_IPV6))) return;
/* snag network header to get L4 type and address */
skb = first->skb;
hdr.network = skb_network_header(skb); if (unlikely(hdr.network <= skb->data)) return; if (skb->encapsulation &&
first->protocol == htons(ETH_P_IP) &&
hdr.ipv4->protocol == IPPROTO_UDP) { struct ixgbe_adapter *adapter = q_vector->adapter;
if (unlikely(skb_tail_pointer(skb) < hdr.network +
vxlan_headroom(0))) return;
/* verify the port is recognized as VXLAN */ if (adapter->vxlan_port &&
udp_hdr(skb)->dest == adapter->vxlan_port)
hdr.network = skb_inner_network_header(skb);
if (adapter->geneve_port &&
udp_hdr(skb)->dest == adapter->geneve_port)
hdr.network = skb_inner_network_header(skb);
}
/* Make sure we have at least [minimum IPv4 header + TCP] *or[IPv6header]bytes
*/ if (unlikely(skb_tail_pointer(skb) < hdr.network + 40)) return;
/* Currently only IPv4/IPv6 with TCP is supported */ switch (hdr.ipv4->version) { case IPVERSION: /* access ihl as u8 to avoid unaligned access on ia64 */
hlen = (hdr.network[0] & 0x0F) << 2;
l4_proto = hdr.ipv4->protocol; break; case6:
hlen = hdr.network - skb->data;
l4_proto = ipv6_find_hdr(skb, &hlen, IPPROTO_TCP, NULL, NULL);
hlen -= hdr.network - skb->data; break; default: return;
}
if (l4_proto != IPPROTO_TCP) return;
if (unlikely(skb_tail_pointer(skb) < hdr.network +
hlen + sizeof(struct tcphdr))) return;
th = (struct tcphdr *)(hdr.network + hlen);
/* skip this packet since the socket is closing */ if (th->fin) return;
/* sample on all syn packets or once every atr sample count */ if (!th->syn && (ring->atr_count < ring->atr_sample_rate)) return;
if (hdr.network != skb_network_header(skb))
input.formatted.flow_type |= IXGBE_ATR_L4TYPE_TUNNEL_MASK;
/* This assumes the Rx queue and Tx queue are bound to the same CPU */
ixgbe_fdir_add_signature_filter_82599(&q_vector->adapter->hw,
input, common, ring->queue_index);
}
data = skb_frag_address(&sinfo->frags[i]);
len = skb_frag_size(&sinfo->frags[i]);
i++;
} /* put descriptor type bits */
tx_desc->read.cmd_type_len |= cpu_to_le32(IXGBE_TXD_CMD);
/* Avoid any potential race with xdp_xmit and cleanup */
smp_wmb();
/* *need:1descriptorperpage*PAGE_SIZE/IXGBE_MAX_DATA_PER_TXD, *+1descforskb_headlen/IXGBE_MAX_DATA_PER_TXD, *+2descgaptokeeptailfromtouchinghead, *+1descforcontextdescriptor, *otherwisetrynexttime
*/ for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
count += TXD_USE_COUNT(skb_frag_size(
&skb_shinfo(skb)->frags[f]));
if (ixgbe_maybe_stop_tx(tx_ring, count + 3)) {
tx_ring->tx_stats.tx_busy++; return NETDEV_TX_BUSY;
}
/* record the location of the first descriptor for this packet */
first = &tx_ring->tx_buffer_info[tx_ring->next_to_use];
first->skb = skb;
first->bytecount = skb->len;
first->gso_segs = 1;
/* if we have a HW VLAN tag being added default to the HW one */ if (skb_vlan_tag_present(skb)) {
tx_flags |= skb_vlan_tag_get(skb) << IXGBE_TX_FLAGS_VLAN_SHIFT;
tx_flags |= IXGBE_TX_FLAGS_HW_VLAN; /* else if it is a SW VLAN check the next protocol and store the tag */
} elseif (protocol == htons(ETH_P_8021Q)) { struct vlan_hdr *vhdr, _vhdr;
vhdr = skb_header_pointer(skb, ETH_HLEN, sizeof(_vhdr), &_vhdr); if (!vhdr) goto out_drop;
/* *Theminimumpacketsizeforolinfopaylenis17sopadtheskb *inordertomeetthisminimumsizerequirement.
*/ if (skb_put_padto(skb, 17)) return NETDEV_TX_OK;
tx_ring = ring ? ring : adapter->tx_ring[skb_get_queue_mapping(skb)]; if (unlikely(test_bit(__IXGBE_TX_DISABLED, &tx_ring->state))) return NETDEV_TX_BUSY;
/* we only care about macvlans... */ if (!netif_is_macvlan(vdev)) return0;
/* that have hardware offload enabled... */
accel = macvlan_accel_priv(vdev); if (!accel) return0;
/* If we can relocate to a different bit do so */
pool = find_first_zero_bit(adapter->fwd_bitmask, adapter->num_rx_pools); if (pool < adapter->num_rx_pools) {
set_bit(pool, adapter->fwd_bitmask);
accel->pool = pool; return0;
}
/* if we cannot find a free pool then disable the offload */
netdev_err(vdev, "L2FW offload disabled due to lack of queue resources\n");
macvlan_release_l2fw_offload(vdev);
/* unbind the queues and drop the subordinate channel config */
netdev_unbind_sb_channel(adapter->netdev, vdev);
netdev_set_sb_channel(vdev, 0);
/* Hardware has to reinitialize queues and interrupts to *matchpacketbufferalignment.Unfortunately,the *hardwareisnotflexibleenoughtodothisdynamically.
*/ if (netif_running(dev))
ixgbe_close(dev); else
ixgbe_reset(adapter);
ixgbe_clear_interrupt_scheme(adapter);
#ifdef CONFIG_IXGBE_DCB if (tc) { if (adapter->xdp_prog) {
e_warn(probe, "DCB is not supported with XDP\n");
ixgbe_init_interrupt_scheme(adapter); if (netif_running(dev))
ixgbe_open(dev); return -EINVAL;
}
if ((uhtid != 0x800) && (uhtid >= IXGBE_MAX_LINK_HANDLE)) return -EINVAL;
/* Clear this filter in the link data it is associated with */ if (uhtid != 0x800) {
jump = adapter->jump_tables[uhtid]; if (!jump) return -EINVAL; if (!test_bit(loc - 1, jump->child_loc_map)) return -EINVAL;
clear_bit(loc - 1, jump->child_loc_map);
}
/* Check if the filter being deleted is a link */ for (i = 1; i < IXGBE_MAX_LINK_HANDLE; i++) {
jump = adapter->jump_tables[i]; if (jump && jump->link_hdl == hdl) { /* Delete filters in the hardware in the child hash *tableassociatedwiththislink
*/ for (j = 0; j < IXGBE_MAX_HW_ENTRIES; j++) { if (!test_bit(j, jump->child_loc_map)) continue;
spin_lock(&adapter->fdir_perfect_lock);
err = ixgbe_update_ethtool_fdir_entry(adapter,
NULL,
j + 1);
spin_unlock(&adapter->fdir_perfect_lock);
clear_bit(j, jump->child_loc_map);
} /* Remove resources for this link */
kfree(jump->input);
kfree(jump->mask);
kfree(jump);
adapter->jump_tables[i] = NULL; return err;
}
}
/* At the moment cls_u32 jumps to network layer and skips past *L2headers.ThecanonicalmethodtomatchL2framesistouse *negativevalues.Howeverthisiserrorproneatbestbutreally *justbrokenbecausethereisnowayto"know"whatsortofhdr *isinfrontofthenetworklayer.Fixcls_u32tosupportL2 *headerswhenneeded.
*/ if (protocol != htons(ETH_P_IP)) return err;
if (loc >= ((1024 << adapter->fdir_pballoc) - 2)) {
e_err(drv, "Location out of range\n"); return err;
}
/* cls u32 is a graph starting at root node 0x800. The driver tracks *linksandalsothefieldsusedtoadvancetheparseracrosseach *link(e.g.nexthdr/eatparametersfrom'tc').Thiswaywecanmap *theu32graphontothehardwareparsegraphdenotedinixgbe_model.h *Toaddsupportfornewnodesupdateixgbe_model.hparsestructures *thisfunction_should_begenerictrynottohardcodevalueshere.
*/ if (uhtid == 0x800) {
field_ptr = (adapter->jump_tables[0])->mat;
} else { if (uhtid >= IXGBE_MAX_LINK_HANDLE) return err; if (!adapter->jump_tables[uhtid]) return err;
field_ptr = (adapter->jump_tables[uhtid])->mat;
}
if (!field_ptr) return err;
/* At this point we know the field_ptr is valid and need to either *buildcls_u32linkorattachfilter.Becauseaddingalinkto *ahandlethatdoesnotexistisinvalidandthesameforadding *rulestohandlesthatdon'texist.
*/
if (link_uhtid) { struct ixgbe_nexthdr *nexthdr = ixgbe_ipv4_jumps;
if (link_uhtid >= IXGBE_MAX_LINK_HANDLE) return err;
if (!test_bit(link_uhtid - 1, &adapter->tables)) return err;
/* Multiple filters as links to the same hash table are not *supported.Toaddanewfilterwiththesamenextheader *butdifferentmatch/jumpconditions,createanewhashtable *andlinktoit.
*/ if (adapter->jump_tables[link_uhtid] &&
(adapter->jump_tables[link_uhtid])->link_hdl) {
e_err(drv, "Link filter exists for link: %x\n",
link_uhtid); return err;
}
for (i = 0; nexthdr[i].jump; i++) { if (nexthdr[i].o != cls->knode.sel->offoff ||
nexthdr[i].s != cls->knode.sel->offshift ||
nexthdr[i].m !=
(__force u32)cls->knode.sel->offmask) return err;
if ((uhtid != 0x800) && (adapter->jump_tables[uhtid])) { if ((adapter->jump_tables[uhtid])->input)
memcpy(input, (adapter->jump_tables[uhtid])->input, sizeof(*input)); if ((adapter->jump_tables[uhtid])->mask)
memcpy(mask, (adapter->jump_tables[uhtid])->mask, sizeof(*mask));
/* Lookup in all child hash tables if this location is already *filledwithafilter
*/ for (i = 1; i < IXGBE_MAX_LINK_HANDLE; i++) { struct ixgbe_jump_table *link = adapter->jump_tables[i];
/* go back to full RSS if we're not running SR-IOV */ if (!adapter->ring_feature[RING_F_VMDQ].offset)
adapter->flags &= ~(IXGBE_FLAG_VMDQ_ENABLED |
IXGBE_FLAG_SRIOV_ENABLED);
/* We cannot enable ATR if SR-IOV is enabled */ if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED || /* We cannot enable ATR if we have 2 or more tcs */
(adapter->hw_tcs > 1) || /* We cannot enable ATR if RSS is disabled */
(adapter->ring_feature[RING_F_RSS].limit <= 1) || /* A sample rate of 0 indicates ATR disabled */
(!adapter->atr_sample_rate))
; /* do nothing not supported */ else/* otherwise supported and set the flag */
adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
}
staticvoid *ixgbe_fwd_add(struct net_device *pdev, struct net_device *vdev)
{ struct ixgbe_adapter *adapter = ixgbe_from_netdev(pdev); struct ixgbe_fwd_adapter *accel; int tcs = adapter->hw_tcs ? : 1; int pool, err;
if (adapter->xdp_prog) {
e_warn(probe, "L2FW offload is not supported with XDP\n"); return ERR_PTR(-EINVAL);
}
/* The hardware supported by ixgbe only filters on the destination MAC *address.Inordertoavoidissuesweonlysupportoffloadingmodes *wherethehardwarecanactuallyprovidethefunctionality.
*/ if (!macvlan_supports_dest_filter(vdev)) return ERR_PTR(-EMEDIUMTYPE);
/* We need to lock down the macvlan to be a single queue device so that *wecanreusethetc_to_txqfieldinthemacvlannetdevtorepresent *thequeuemappingtoournetdev.
*/ if (netif_is_multiqueue(vdev)) return ERR_PTR(-ERANGE);
pool = find_first_zero_bit(adapter->fwd_bitmask, adapter->num_rx_pools); if (pool == adapter->num_rx_pools) {
u16 used_pools = adapter->num_vfs + adapter->num_rx_pools;
u16 reserved_pools;
/* Hardware has a limited number of available pools. Each VF, *andthePFrequireapool.Checktoensurewedon't *attempttousemorethentheavailablenumberofpools.
*/ if (used_pools >= IXGBE_MAX_VF_FUNCTIONS) return ERR_PTR(-EBUSY);
/* Enable VMDq flag so device will be set in VM mode */
adapter->flags |= IXGBE_FLAG_VMDQ_ENABLED |
IXGBE_FLAG_SRIOV_ENABLED;
/* Try to reserve as many queues per pool as possible, *westartwiththeconfigurationsthatsupport4queues *perpools,followedby2,andthenbyjust1perpool.
*/ if (used_pools < 32 && adapter->num_rx_pools < 16)
reserved_pools = min_t(u16, 32 - used_pools, 16 - adapter->num_rx_pools); elseif (adapter->num_rx_pools < 32)
reserved_pools = min_t(u16, 64 - used_pools, 32 - adapter->num_rx_pools); else
reserved_pools = 64 - used_pools;
/* Allow remaining Rx packets to get flushed out of the *RxFIFObeforewedropthenetdevforthering.
*/
usleep_range(10000, 20000);
for (i = 0; i < adapter->num_rx_queues_per_pool; i++) { struct ixgbe_ring *ring = adapter->rx_ring[rxbase + i]; struct ixgbe_q_vector *qv = ring->q_vector;
/* Make sure we aren't processing any packets and clear *netdevtoshutdownthering.
*/ if (netif_running(adapter->netdev))
napi_synchronize(&qv->napi);
ring->netdev = NULL;
}
/* unbind the queues and drop the subordinate channel config */
netdev_unbind_sb_channel(pdev, accel->netdev);
netdev_set_sb_channel(accel->netdev, 0);
/* Make certain the headers can be described by a context descriptor */
mac_hdr_len = skb_network_offset(skb); if (unlikely(mac_hdr_len > IXGBE_MAX_MAC_HDR_LEN)) return features & ~(NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC |
NETIF_F_GSO_UDP_L4 |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_TSO |
NETIF_F_TSO6);
/* We can only support IPV4 TSO in tunnels if we can mangle the *innerIPIDfield,sostripTSOifMANGLEIDisnotsupported. *IPsecoffoadsetsskb->encapsulationbutstillcanhandle *theTSO,soit'stheexception.
*/ if (skb->encapsulation && !(features & NETIF_F_TSO_MANGLEID)) { #ifdef CONFIG_IXGBE_IPSEC if (!secpath_exists(skb)) #endif
features &= ~NETIF_F_TSO;
}
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) return -EINVAL;
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) return -EINVAL;
/* verify ixgbe ring attributes are sufficient for XDP */ for (i = 0; i < adapter->num_rx_queues; i++) { struct ixgbe_ring *ring = adapter->rx_ring[i];
if (ring_is_rsc_enabled(ring)) return -EINVAL;
if (frame_size > ixgbe_rx_bufsz(ring)) return -EINVAL;
}
/* if the number of cpus is much larger than the maximum of queues, *weshouldstopitandthenreturnwithENOMEMlikebefore.
*/ if (nr_cpu_ids > IXGBE_MAX_XDP_QS * 2) return -ENOMEM;
/* If transitioning XDP modes reconfigure rings */ if (need_reset) { int err;
if (!prog) /* Wait until ndo_xsk_wakeup completes. */
synchronize_rcu();
err = ixgbe_setup_tc(dev, adapter->hw_tcs);
if (err) return -EINVAL; if (!prog)
xdp_features_clear_redirect_target(dev);
} else { for (i = 0; i < adapter->num_rx_queues; i++) {
WRITE_ONCE(adapter->rx_ring[i]->xdp_prog,
adapter->xdp_prog);
}
}
if (old_prog)
bpf_prog_put(old_prog);
/* Kick start the NAPI context if there is an AF_XDP socket open *onthatqueueid.Thissothatreceivingwillstart.
*/ if (need_reset && prog) {
num_queues = min_t(int, adapter->num_rx_queues,
adapter->num_xdp_queues); for (i = 0; i < num_queues; i++) if (adapter->xdp_ring[i]->xsk_pool)
(void)ixgbe_xsk_wakeup(adapter->netdev, i,
XDP_WAKEUP_RX);
xdp_features_set_redirect_target(dev, true);
}
switch (xdp->command) { case XDP_SETUP_PROG: return ixgbe_xdp_setup(dev, xdp->prog); case XDP_SETUP_XSK_POOL: return ixgbe_xsk_pool_setup(adapter, xdp->xsk.pool,
xdp->xsk.queue_id);
default: return -EINVAL;
}
}
void ixgbe_xdp_ring_update_tail(struct ixgbe_ring *ring)
{ /* Force memory writes to complete before letting h/w know there *arenewdescriptorstofetch.
*/
wmb();
writel(ring->next_to_use, ring->tail);
}
void ixgbe_xdp_ring_update_tail_locked(struct ixgbe_ring *ring)
{ if (static_branch_unlikely(&ixgbe_xdp_locking_key))
spin_lock(&ring->tx_lock);
ixgbe_xdp_ring_update_tail(ring); if (static_branch_unlikely(&ixgbe_xdp_locking_key))
spin_unlock(&ring->tx_lock);
}
staticint ixgbe_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames, u32 flags)
{ struct ixgbe_adapter *adapter = ixgbe_from_netdev(dev); struct ixgbe_ring *ring; int nxmit = 0; int i;
if (unlikely(test_bit(__IXGBE_DOWN, &adapter->state))) return -ENETDOWN;
if (!netif_carrier_ok(adapter->netdev) ||
!netif_running(adapter->netdev)) return -ENETDOWN;
if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) return -EINVAL;
/* During program transitions its possible adapter->xdp_prog is assigned *butringhasnotbeenconfiguredyet.Inthiscasesimplyabortxmit.
*/
ring = adapter->xdp_prog ? ixgbe_determine_xdp_ring(adapter) : NULL; if (unlikely(!ring)) return -ENXIO;
if (unlikely(test_bit(__IXGBE_TX_DISABLED, &ring->state))) return -ENXIO;
if (static_branch_unlikely(&ixgbe_xdp_locking_key))
spin_lock(&ring->tx_lock);
for (i = 0; i < n; i++) { struct xdp_frame *xdpf = frames[i]; int err;
/* write value back with RXDCTL.ENABLE bit cleared */
IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl);
/* RXDCTL.EN may not change on 82598 if link is down, so skip it */ if (hw->mac.type == ixgbe_mac_82598EB &&
!(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) return;
ixgbe_configure_tx_ring(adapter, tx_ring); if (xdp_ring)
ixgbe_configure_tx_ring(adapter, xdp_ring);
ixgbe_configure_rx_ring(adapter, rx_ring);
clear_bit(__IXGBE_TX_DISABLED, &tx_ring->state); if (xdp_ring)
clear_bit(__IXGBE_TX_DISABLED, &xdp_ring->state);
/* Rx/Tx/XDP Tx share the same napi context. */
napi_enable(&rx_ring->q_vector->napi);
ixgbe_irq_enable_queues(adapter, BIT_ULL(ring));
IXGBE_WRITE_FLUSH(&adapter->hw);
}
/* Some cards can not use the generic count PCIe functions method, *becausetheyarebehindaparentswitch,sowehardcodethesewith *thecorrectnumberoffunctions.
*/ if (ixgbe_pcie_from_parent(&adapter->hw))
physfns = 4;
/* When the devices on the bus don't all match our device ID, *wecan'treliablydeterminethecorrectnumberof *functions.Thiscanoccurifafunctionhasbeendirect *attachedtoavirtualmachineusingVT-d,forexample.In *thiscase,simplyreturn-1toindicatethis.
*/ if ((entry->vendor != pdev->vendor) ||
(entry->device != pdev->device)) return -1;
/* WOL not supported on 82598 */ if (hw->mac.type == ixgbe_mac_82598EB) returnfalse;
/* check eeprom to see if WOL is enabled for X540 and newer */ if (hw->mac.type >= ixgbe_mac_X540) { if ((wol_cap == IXGBE_DEVICE_CAPS_WOL_PORT0_1) ||
((wol_cap == IXGBE_DEVICE_CAPS_WOL_PORT0) &&
(hw->bus.func == 0))) returntrue;
}
/* WOL is determined based on device IDs for 82599 MACs */ switch (device_id) { case IXGBE_DEV_ID_82599_SFP: /* Only these subdevices could supports WOL */ switch (subdevice_id) { case IXGBE_SUBDEV_ID_82599_560FLR: case IXGBE_SUBDEV_ID_82599_LOM_SNAP6: case IXGBE_SUBDEV_ID_82599_SFP_WOL0: case IXGBE_SUBDEV_ID_82599_SFP_2OCP: /* only support first port */ if (hw->bus.func != 0) break;
fallthrough; case IXGBE_SUBDEV_ID_82599_SP_560FLR: case IXGBE_SUBDEV_ID_82599_SFP: case IXGBE_SUBDEV_ID_82599_RNDC: case IXGBE_SUBDEV_ID_82599_ECNA_DP: case IXGBE_SUBDEV_ID_82599_SFP_1OCP: case IXGBE_SUBDEV_ID_82599_SFP_LOM_OEM1: case IXGBE_SUBDEV_ID_82599_SFP_LOM_OEM2: returntrue;
} break; case IXGBE_DEV_ID_82599EN_SFP: /* Only these subdevices support WOL */ switch (subdevice_id) { case IXGBE_SUBDEV_ID_82599EN_SFP_OCP1: returntrue;
} break; case IXGBE_DEV_ID_82599_COMBO_BACKPLANE: /* All except this subdevice support WOL */ if (subdevice_id != IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) returntrue; break; case IXGBE_DEV_ID_82599_KX4: returntrue; default: break;
}
if (hw->mac.ops.get_bus_info)
hw->mac.ops.get_bus_info(hw);
pci_set_drvdata(pdev, adapter); /* We are creating devlink interface so NIC can be managed, *e.g.newNVMimageloaded
*/
devl_lock(adapter->devlink);
ixgbe_devlink_register_port(adapter);
SET_NETDEV_DEVLINK_PORT(adapter->netdev,
&adapter->devlink_port);
ixgbe_devlink_init_regions(adapter);
devl_register(adapter->devlink);
devl_unlock(adapter->devlink);
/* Catch broken hardware that put the wrong VF device ID in *thePCIeSR-IOVcapability.
*/ if (pdev->is_virtfn) {
WARN(1, KERN_ERR "%s (%hx:%hx) should not be a VF!\n",
pci_name(pdev), pdev->vendor, pdev->device); return -EINVAL;
}
err = pci_enable_device_mem(pdev); if (err) return err;
err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); if (err) {
dev_err(&pdev->dev, "No usable DMA configuration, aborting\n"); goto err_dma;
}
/* setup the private structure */
err = ixgbe_sw_init(adapter, ii); if (err) goto err_sw_init;
if (ixgbe_check_fw_error(adapter)) return ixgbe_recovery_probe(adapter);
if (adapter->hw.mac.type == ixgbe_mac_e610) {
err = ixgbe_get_caps(&adapter->hw); if (err)
dev_err(&pdev->dev, "ixgbe_get_caps failed %d\n", err);
err = ixgbe_get_flash_data(&adapter->hw); if (err) goto err_sw_init;
}
if (adapter->hw.mac.type == ixgbe_mac_82599EB)
adapter->flags2 |= IXGBE_FLAG2_AUTO_DISABLE_VF;
switch (adapter->hw.mac.type) { case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_e610:
netdev->udp_tunnel_nic_info = &ixgbe_udp_tunnels_x550; break; case ixgbe_mac_x550em_a:
netdev->udp_tunnel_nic_info = &ixgbe_udp_tunnels_x550em_a; break; default: break;
}
/* Make it possible the adapter to be woken up via WOL */ switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: case ixgbe_mac_x550em_a: case ixgbe_mac_e610:
IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0); break; default: break;
}
/* *Ifthereisafanonthisdeviceandithasfailedlogthe *failure.
*/ if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) {
u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); if (esdp & IXGBE_ESDP_SDP1)
e_crit(probe, "Fan has stopped, replace the adapter\n");
}
if (allow_unsupported_sfp)
hw->allow_unsupported_sfp = allow_unsupported_sfp;
/* reset_hw fills in the perm_addr as well */
hw->phy.reset_if_overtemp = true;
err = hw->mac.ops.reset_hw(hw);
hw->phy.reset_if_overtemp = false;
ixgbe_set_eee_capable(adapter); if (err == -ENOENT) {
err = 0;
} elseif (err == -EOPNOTSUPP) {
e_dev_err("failed to load because an unsupported SFP+ or QSFP module type was detected.\n");
e_dev_err("Reload the driver after installing a supported module.\n"); goto err_sw_init;
} elseif (err) {
e_dev_err("HW Init failed: %d\n", err); goto err_sw_init;
}
#ifdef CONFIG_PCI_IOV /* SR-IOV not supported on the 82598 */ if (adapter->hw.mac.type == ixgbe_mac_82598EB) goto skip_sriov; /* Mailbox */
ixgbe_init_mbx_params_pf(hw);
hw->mbx.ops = ii->mbx_ops;
pci_sriov_set_totalvfs(pdev, IXGBE_MAX_VFS_DRV_LIMIT);
ixgbe_enable_sriov(adapter, max_vfs);
skip_sriov:
if (adapter->ipsec)
netdev->features |= IXGBE_ESP_FEATURES; #endif /* copy netdev features into list of user selectable features */
netdev->hw_features |= netdev->features |
NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_RXALL |
NETIF_F_HW_L2FW_DOFFLOAD;
if (hw->mac.type >= ixgbe_mac_82599EB)
netdev->hw_features |= NETIF_F_NTUPLE |
NETIF_F_HW_TC;
/* set this bit last since it cannot be part of vlan_features */
netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_TX;
/* make sure the EEPROM is good */ if (hw->eeprom.ops.validate_checksum(hw, NULL) < 0) {
e_dev_err("The EEPROM Checksum Is Not Valid\n");
err = -EIO; goto err_sw_init;
}
err = ixgbe_init_interrupt_scheme(adapter); if (err) goto err_sw_init;
for (i = 0; i < adapter->num_rx_queues; i++)
u64_stats_init(&adapter->rx_ring[i]->syncp); for (i = 0; i < adapter->num_tx_queues; i++)
u64_stats_init(&adapter->tx_ring[i]->syncp); for (i = 0; i < adapter->num_xdp_queues; i++)
u64_stats_init(&adapter->xdp_ring[i]->syncp);
/* WOL not supported for all devices */
adapter->wol = 0;
hw->eeprom.ops.read(hw, 0x2c, &adapter->eeprom_cap);
hw->wol_enabled = ixgbe_wol_supported(adapter, pdev->device,
pdev->subsystem_device); if (hw->wol_enabled)
adapter->wol = IXGBE_WUFC_MAG;
/* save off EEPROM version number */
ixgbe_set_fw_version(adapter);
/* pick up the PCI bus settings for reporting later */ if (ixgbe_pcie_from_parent(hw))
ixgbe_get_parent_bus_info(adapter); else
hw->mac.ops.get_bus_info(hw);
/* reset the hardware with the new settings */
err = hw->mac.ops.start_hw(hw); if (err == -EACCES) { /* We are running on a pre-production device, log a warning */
e_dev_warn("This device is a pre-production adapter/LOM. " "Please be aware there may be issues associated " "with your hardware. If you are experiencing " "problems please contact your Intel or hardware " "representative who provided you with this " "hardware.\n");
}
strcpy(netdev->name, "eth%d");
pci_set_drvdata(pdev, adapter);
err = register_netdev(netdev); if (err) goto err_register;
/* power down the optics for 82599 SFP+ fiber */ if (hw->mac.ops.disable_tx_laser)
hw->mac.ops.disable_tx_laser(hw);
/* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);
#ifdef CONFIG_IXGBE_DCA if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
ixgbe_setup_dca(adapter);
} #endif if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) {
e_info(probe, "IOV is enabled with %d VFs\n", adapter->num_vfs); for (i = 0; i < adapter->num_vfs; i++)
ixgbe_vf_configuration(pdev, (i | 0x10000000));
}
/* firmware requires driver version to be 0xFFFFFFFF *sinceosdoesnotsupportfeature
*/ if (hw->mac.ops.set_fw_drv_ver)
hw->mac.ops.set_fw_drv_ver(hw, 0xFF, 0xFF, 0xFF, 0xFF, sizeof(UTS_RELEASE) - 1,
UTS_RELEASE);
/* add san mac addr to netdev */
ixgbe_add_sanmac_netdev(netdev);
e_dev_info("%s\n", ixgbe_default_device_descr);
#ifdef CONFIG_IXGBE_HWMON if (ixgbe_sysfs_init(adapter))
e_err(probe, "failed to allocate sysfs resources\n"); #endif/* CONFIG_IXGBE_HWMON */
ixgbe_dbg_adapter_init(adapter);
/* setup link for SFP devices with MNG FW, else wait for IXGBE_UP */ if (ixgbe_mng_enabled(hw) && ixgbe_is_sfp(hw) && hw->mac.ops.setup_link)
hw->mac.ops.setup_link(hw,
IXGBE_LINK_SPEED_10GB_FULL | IXGBE_LINK_SPEED_1GB_FULL, true);
err = ixgbe_mii_bus_init(hw); if (err) goto err_netdev;
for (i = 0; i < IXGBE_MAX_LINK_HANDLE; i++) { if (adapter->jump_tables[i]) {
kfree(adapter->jump_tables[i]->input);
kfree(adapter->jump_tables[i]->mask);
}
kfree(adapter->jump_tables[i]);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.