int __fbnic_open(struct fbnic_net *fbn)
{ struct fbnic_dev *fbd = fbn->fbd; int err;
err = fbnic_alloc_napi_vectors(fbn); if (err) return err;
err = fbnic_alloc_resources(fbn); if (err) goto free_napi_vectors;
err = fbnic_set_netif_queues(fbn); if (err) goto free_resources;
/* Send ownership message and flush to verify FW has seen it */
err = fbnic_fw_xmit_ownership_msg(fbd, true); if (err) {
dev_warn(fbd->dev, "Error %d sending host ownership message to the firmware\n",
err); goto err_reset_queues;
}
err = fbnic_time_start(fbn); if (err) goto release_ownership;
err = fbnic_fw_init_heartbeat(fbd, false); if (err) goto time_stop;
err = fbnic_pcs_request_irq(fbd); if (err) goto time_stop;
/* Pull the BMC config and initialize the RPC */
fbnic_bmc_rpc_init(fbd);
fbnic_rss_reinit(fbd, fbn);
if (WARN_ON(!is_valid_ether_addr(addr))) return -EADDRNOTAVAIL;
avail_addr = __fbnic_uc_sync(fbn->fbd, addr); if (!avail_addr) return -ENOSPC;
/* Add type flag indicating this address is in use by the host */
set_bit(FBNIC_MAC_ADDR_T_UNICAST, avail_addr->act_tcam);
return0;
}
staticint fbnic_uc_unsync(struct net_device *netdev, constunsignedchar *addr)
{ struct fbnic_net *fbn = netdev_priv(netdev); struct fbnic_dev *fbd = fbn->fbd; int i, ret;
/* Scan from middle of list to bottom, filling bottom up. *Skipthefirstentrywhichisreservedfordev_addrand *leavethelastentrytouseforpromiscuousfiltering.
*/ for (i = fbd->mac_addr_boundary, ret = -ENOENT;
i < FBNIC_RPC_TCAM_MACDA_HOST_ADDR_IDX && ret; i++) { struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
if (!ether_addr_equal(mac_addr->value.addr8, addr)) continue;
if (WARN_ON(!is_multicast_ether_addr(addr))) return -EADDRNOTAVAIL;
avail_addr = __fbnic_mc_sync(fbn->fbd, addr); if (!avail_addr) return -ENOSPC;
/* Add type flag indicating this address is in use by the host */
set_bit(FBNIC_MAC_ADDR_T_MULTICAST, avail_addr->act_tcam);
return0;
}
staticint fbnic_mc_unsync(struct net_device *netdev, constunsignedchar *addr)
{ struct fbnic_net *fbn = netdev_priv(netdev); struct fbnic_dev *fbd = fbn->fbd; int i, ret;
/* Scan from middle of list to top, filling top down. *SkipovertheaddressreservedfortheBMCMACand *excludeindex0asthatbelongstothebroadcastaddress
*/ for (i = fbd->mac_addr_boundary, ret = -ENOENT;
--i > FBNIC_RPC_TCAM_MACDA_BROADCAST_IDX && ret;) { struct fbnic_mac_addr *mac_addr = &fbd->mac_addr[i];
if (!ether_addr_equal(mac_addr->value.addr8, addr)) continue;
/* Populate last TCAM entry with promiscuous entry and 0/1 bit mask */
mac_addr = &fbd->mac_addr[FBNIC_RPC_TCAM_MACDA_PROMISC_IDX]; if (uc_promisc) { if (!is_zero_ether_addr(mac_addr->value.addr8) ||
mac_addr->state != FBNIC_TCAM_S_VALID) {
eth_zero_addr(mac_addr->value.addr8);
eth_broadcast_addr(mac_addr->mask.addr8);
clear_bit(FBNIC_MAC_ADDR_T_ALLMULTI,
mac_addr->act_tcam);
set_bit(FBNIC_MAC_ADDR_T_PROMISC,
mac_addr->act_tcam);
mac_addr->state = FBNIC_TCAM_S_ADD;
}
} elseif (mc_promisc &&
(!fbnic_bmc_present(fbd) || !fbd->fw_cap.all_multi)) { /* We have to add a special handler for multicast as the *BMCmayhaveanall-multirulealreadyinplace.Assuch *addingaruleourselveswon'tdoanygoodsowewillhave *tomodifytherulesfortheALLMULTIbelowiftheBMC *alreadyhastheruleinplace.
*/ if (!is_multicast_ether_addr(mac_addr->value.addr8) ||
mac_addr->state != FBNIC_TCAM_S_VALID) {
eth_zero_addr(mac_addr->value.addr8);
eth_broadcast_addr(mac_addr->mask.addr8);
mac_addr->value.addr8[0] ^= 1;
mac_addr->mask.addr8[0] ^= 1;
set_bit(FBNIC_MAC_ADDR_T_ALLMULTI,
mac_addr->act_tcam);
clear_bit(FBNIC_MAC_ADDR_T_PROMISC,
mac_addr->act_tcam);
mac_addr->state = FBNIC_TCAM_S_ADD;
}
} elseif (mac_addr->state == FBNIC_TCAM_S_VALID) { if (test_bit(FBNIC_MAC_ADDR_T_BMC, mac_addr->act_tcam)) {
clear_bit(FBNIC_MAC_ADDR_T_ALLMULTI,
mac_addr->act_tcam);
clear_bit(FBNIC_MAC_ADDR_T_PROMISC,
mac_addr->act_tcam);
} else {
mac_addr->state = FBNIC_TCAM_S_DELETE;
}
}
/* Add rules for BMC all multicast if it is enabled */
fbnic_bmc_rpc_all_multi_config(fbd, mc_promisc);
/* Sift out any unshared BMC rules and place them in BMC only section */
fbnic_sift_macda(fbd);
/* Write updates to hardware */
fbnic_write_rules(fbd);
fbnic_write_macda(fbd);
fbnic_write_tce_tcam(fbd);
}
staticvoid fbnic_set_rx_mode(struct net_device *netdev)
{ /* No need to update the hardware if we are not running */ if (netif_running(netdev))
__fbnic_set_rx_mode(netdev);
}
if (config->source != HWTSTAMP_SOURCE_NETDEV) return -EOPNOTSUPP;
if (!kernel_hwtstamp_config_changed(config, &fbn->hwtstamp_config)) return0;
/* Upscale the filters */ switch (config->rx_filter) { case HWTSTAMP_FILTER_NONE: case HWTSTAMP_FILTER_ALL: case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: case HWTSTAMP_FILTER_PTP_V2_EVENT: break; case HWTSTAMP_FILTER_NTP_ALL:
config->rx_filter = HWTSTAMP_FILTER_ALL; break; case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
config->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; break; case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT; break; case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; break; case HWTSTAMP_FILTER_PTP_V2_SYNC: case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; break; default: return -ERANGE;
}
spin_lock(&fbd->hw_stats_lock); /* Record drops for the host FIFOs. *4:networktoHost,6:BMCtoHost *ExcludetheBMCandMCFIFOsasthosestatsmaycontaindrops *duetounrelateditemssuchasTCAMmisses.Theyarestill *accessiblethroughtheethtoolstats.
*/
i = FBNIC_RXB_FIFO_HOST;
rx_missed += fbd->hw_stats.rxb.fifo[i].drop.frames.value;
i = FBNIC_RXB_FIFO_BMC_TO_HOST;
rx_missed += fbd->hw_stats.rxb.fifo[i].drop.frames.value;
for (i = 0; i < fbd->max_num_queues; i++) { /* Report packets dropped due to CQ/BDQ being full/empty */
rx_over += fbd->hw_stats.hw_q[i].rde_pkt_cq_drop.value;
rx_over += fbd->hw_stats.hw_q[i].rde_pkt_bdq_drop.value;
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.