static void lio_get_strings(struct net_device *netdev, u32 stringset, u8 *data) { struct lio *lio = GET_LIO(netdev); struct octeon_device *oct_dev = lio->oct_dev; int num_iq_stats, num_oq_stats, i, j; int num_stats; switch (stringset) { case ETH_SS_STATS: num_stats = ARRAY_SIZE(oct_stats_strings); for (j = 0; j < num_stats; j++) { sprintf(data, "%s", oct_stats_strings[j]); data += ETH_GSTRING_LEN; } num_iq_stats = ARRAY_SIZE(oct_iq_stats_strings); for (i = 0; i < MAX_OCTEON_INSTR_QUEUES(oct_dev); i++) { if (!(oct_dev->io_qmask.iq & (1ULL << i))) continue; for (j = 0; j < num_iq_stats; j++) { sprintf(data, "tx-%d-%s", i, oct_iq_stats_strings[j]); data += ETH_GSTRING_LEN; } } num_oq_stats = ARRAY_SIZE(oct_droq_stats_strings); /* for (i = 0; i < oct_dev->num_oqs; i++) { */ for (i = 0; i < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); i++) { if (!(oct_dev->io_qmask.oq & (1ULL << i))) continue; for (j = 0; j < num_oq_stats; j++) { sprintf(data, "rx-%d-%s", i, oct_droq_stats_strings[j]); data += ETH_GSTRING_LEN; } } break; default: netif_info(lio, drv, lio->netdev, "Unknown Stringset !!\n"); break; } }
int lio_wait_for_clean_oq(struct octeon_device *oct) { int retry = 100, pending_pkts = 0; int idx; do { pending_pkts = 0; for (idx = 0; idx < MAX_OCTEON_OUTPUT_QUEUES(oct); idx++) { if (!(oct->io_qmask.oq & BIT_ULL(idx))) continue; pending_pkts += atomic_read(&oct->droq[idx]->pkts_pending); } if (pending_pkts > 0) schedule_timeout_uninterruptible(1); } while (retry-- && pending_pkts); return pending_pkts; }
/** * \brief Droq packet processor sceduler * @param oct octeon device */ static void liquidio_schedule_droq_pkt_handlers(struct octeon_device *oct) { struct octeon_device_priv *oct_priv = (struct octeon_device_priv *)oct->priv; struct octeon_droq *droq; u64 oq_no; if (oct->int_status & OCT_DEV_INTR_PKT_DATA) { for (oq_no = 0; oq_no < MAX_OCTEON_OUTPUT_QUEUES(oct); oq_no++) { if (!(oct->droq_intr & BIT_ULL(oq_no))) continue; droq = oct->droq[oq_no]; if (droq->ops.poll_mode) { droq->ops.napi_fn(droq); oct_priv->napi_mask |= (1 << oq_no); } else { tasklet_schedule(&oct_priv->droq_tasklet); } } } }
static void lio_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, u64 *data) { struct lio *lio = GET_LIO(netdev); struct octeon_device *oct_dev = lio->oct_dev; struct net_device_stats *netstats = &netdev->stats; int i = 0, j; netdev->netdev_ops->ndo_get_stats(netdev); octnet_get_link_stats(netdev); /*sum of oct->droq[oq_no]->stats->rx_pkts_received */ data[i++] = CVM_CAST64(netstats->rx_packets); /*sum of oct->instr_queue[iq_no]->stats.tx_done */ data[i++] = CVM_CAST64(netstats->tx_packets); /*sum of oct->droq[oq_no]->stats->rx_bytes_received */ data[i++] = CVM_CAST64(netstats->rx_bytes); /*sum of oct->instr_queue[iq_no]->stats.tx_tot_bytes */ data[i++] = CVM_CAST64(netstats->tx_bytes); data[i++] = CVM_CAST64(netstats->rx_errors); data[i++] = CVM_CAST64(netstats->tx_errors); /*sum of oct->droq[oq_no]->stats->rx_dropped + *oct->droq[oq_no]->stats->dropped_nodispatch + *oct->droq[oq_no]->stats->dropped_toomany + *oct->droq[oq_no]->stats->dropped_nomem */ data[i++] = CVM_CAST64(netstats->rx_dropped); /*sum of oct->instr_queue[iq_no]->stats.tx_dropped */ data[i++] = CVM_CAST64(netstats->tx_dropped); /*data[i++] = CVM_CAST64(stats->multicast); */ /*data[i++] = CVM_CAST64(stats->collisions); */ /* firmware tx stats */ /*per_core_stats[cvmx_get_core_num()].link_stats[mdata->from_ifidx]. *fromhost.fw_total_sent */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_total_sent); /*per_core_stats[i].link_stats[port].fromwire.fw_total_fwd */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_total_fwd); /*per_core_stats[j].link_stats[i].fromhost.fw_err_pko */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_pko); /*per_core_stats[j].link_stats[i].fromhost.fw_err_link */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_link); /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost. *fw_err_drop */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_drop); /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost.fw_tso */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tso); /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost. *fw_tso_fwd */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_tso_fwd); /*per_core_stats[cvmx_get_core_num()].link_stats[idx].fromhost. *fw_err_tso */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fw_err_tso); /* mac tx statistics */ /*CVMX_BGXX_CMRX_TX_STAT5 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_pkts_sent); /*CVMX_BGXX_CMRX_TX_STAT4 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_bytes_sent); /*CVMX_BGXX_CMRX_TX_STAT15 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.mcast_pkts_sent); /*CVMX_BGXX_CMRX_TX_STAT14 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.bcast_pkts_sent); /*CVMX_BGXX_CMRX_TX_STAT17 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.ctl_sent); /*CVMX_BGXX_CMRX_TX_STAT0 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.total_collisions); /*CVMX_BGXX_CMRX_TX_STAT3 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.one_collision_sent); /*CVMX_BGXX_CMRX_TX_STAT2 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.multi_collision_sent); /*CVMX_BGXX_CMRX_TX_STAT0 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.max_collision_fail); /*CVMX_BGXX_CMRX_TX_STAT1 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.max_deferral_fail); /*CVMX_BGXX_CMRX_TX_STAT16 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.fifo_err); /*CVMX_BGXX_CMRX_TX_STAT6 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromhost.runts); /* RX firmware stats */ /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. *fw_total_rcvd */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_rcvd); /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. *fw_total_fwd */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_fwd); /*per_core_stats[core_id].link_stats[ifidx].fromwire.jabber_err */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.jabber_err); /*per_core_stats[core_id].link_stats[ifidx].fromwire.l2_err */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.l2_err); /*per_core_stats[core_id].link_stats[ifidx].fromwire.frame_err */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.frame_err); /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. *fw_err_pko */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_pko); /*per_core_stats[j].link_stats[i].fromwire.fw_err_link */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_link); /*per_core_stats[cvmx_get_core_num()].link_stats[lro_ctx->ifidx]. *fromwire.fw_err_drop */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_err_drop); /* LRO */ /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. *fw_lro_pkts */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_pkts); /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. *fw_lro_octs */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_octs); /*per_core_stats[j].link_stats[i].fromwire.fw_total_lro */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_total_lro); /*per_core_stats[j].link_stats[i].fromwire.fw_lro_aborts */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts); /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. *fw_lro_aborts_port */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_port); /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. *fw_lro_aborts_seq */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_seq); /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. *fw_lro_aborts_tsval */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_tsval); /*per_core_stats[cvmx_get_core_num()].link_stats[ifidx].fromwire. *fw_lro_aborts_timer */ /* intrmod: packet forward rate */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fw_lro_aborts_timer); /*per_core_stats[j].link_stats[i].fromwire.fw_lro_aborts */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fwd_rate); /* mac: link-level stats */ /*CVMX_BGXX_CMRX_RX_STAT0 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_rcvd); /*CVMX_BGXX_CMRX_RX_STAT1 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.bytes_rcvd); /*CVMX_PKI_STATX_STAT5 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_bcst); /*CVMX_PKI_STATX_STAT5 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.total_mcst); /*wqe->word2.err_code or wqe->word2.err_level */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.runts); /*CVMX_BGXX_CMRX_RX_STAT2 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.ctl_rcvd); /*CVMX_BGXX_CMRX_RX_STAT6 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fifo_err); /*CVMX_BGXX_CMRX_RX_STAT4 */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.dmac_drop); /*wqe->word2.err_code or wqe->word2.err_level */ data[i++] = CVM_CAST64(oct_dev->link_stats.fromwire.fcs_err); /*lio->link_changes*/ data[i++] = CVM_CAST64(lio->link_changes); /* TX -- lio_update_stats(lio); */ for (j = 0; j < MAX_OCTEON_INSTR_QUEUES(oct_dev); j++) { if (!(oct_dev->io_qmask.iq & (1ULL << j))) continue; /*packets to network port*/ /*# of packets tx to network */ data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_done); /*# of bytes tx to network */ data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_tot_bytes); /*# of packets dropped */ data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_dropped); /*# of tx fails due to queue full */ data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_iq_busy); /*XXX gather entries sent */ data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.sgentry_sent); /*instruction to firmware: data and control */ /*# of instructions to the queue */ data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.instr_posted); /*# of instructions processed */ data[i++] = CVM_CAST64(oct_dev->instr_queue[j]-> stats.instr_processed); /*# of instructions could not be processed */ data[i++] = CVM_CAST64(oct_dev->instr_queue[j]-> stats.instr_dropped); /*bytes sent through the queue */ data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.bytes_sent); /*tso request*/ data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_gso); /*txq restart*/ data[i++] = CVM_CAST64(oct_dev->instr_queue[j]->stats.tx_restart); } /* RX */ /* for (j = 0; j < oct_dev->num_oqs; j++) { */ for (j = 0; j < MAX_OCTEON_OUTPUT_QUEUES(oct_dev); j++) { if (!(oct_dev->io_qmask.oq & (1ULL << j))) continue; /*packets send to TCP/IP network stack */ /*# of packets to network stack */ data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.rx_pkts_received); /*# of bytes to network stack */ data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.rx_bytes_received); /*# of packets dropped */ data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem + oct_dev->droq[j]->stats.dropped_toomany + oct_dev->droq[j]->stats.rx_dropped); data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nomem); data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_toomany); data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.rx_dropped); /*control and data path*/ data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.pkts_received); data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.bytes_received); data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.dropped_nodispatch); data[i++] = CVM_CAST64(oct_dev->droq[j]->stats.rx_alloc_failure); } }