FJES_STAT("tx_dropped", stats64.tx_dropped),
};
+#define FJES_EP_STATS_LEN 14
+#define FJES_STATS_LEN \
+ (ARRAY_SIZE(fjes_gstrings_stats) + \
+ ((&((struct fjes_adapter *)netdev_priv(netdev))->hw)->max_epid - 1) * \
+ FJES_EP_STATS_LEN)
+
static void fjes_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, u64 *data)
{
struct fjes_adapter *adapter = netdev_priv(netdev);
+ struct fjes_hw *hw = &adapter->hw;
+ int epidx;
char *p;
int i;
data[i] = (fjes_gstrings_stats[i].sizeof_stat == sizeof(u64))
? *(u64 *)p : *(u32 *)p;
}
+ for (epidx = 0; epidx < hw->max_epid; epidx++) {
+ if (epidx == hw->my_epid)
+ continue;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats
+ .com_regist_buf_exec;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats
+ .com_unregist_buf_exec;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats.send_intr_rx;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats.send_intr_unshare;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats
+ .send_intr_zoneupdate;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats.recv_intr_rx;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats.recv_intr_unshare;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats.recv_intr_stop;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats
+ .recv_intr_zoneupdate;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats.tx_buffer_full;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats
+ .tx_dropped_not_shared;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats
+ .tx_dropped_ver_mismatch;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats
+ .tx_dropped_buf_size_mismatch;
+ data[i++] = hw->ep_shm_info[epidx].ep_stats
+ .tx_dropped_vlanid_mismatch;
+ }
}
static void fjes_get_strings(struct net_device *netdev,
u32 stringset, u8 *data)
{
+ struct fjes_adapter *adapter = netdev_priv(netdev);
+ struct fjes_hw *hw = &adapter->hw;
u8 *p = data;
int i;
ETH_GSTRING_LEN);
p += ETH_GSTRING_LEN;
}
+ for (i = 0; i < hw->max_epid; i++) {
+ if (i == hw->my_epid)
+ continue;
+ sprintf(p, "ep%u_com_regist_buf_exec", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "ep%u_com_unregist_buf_exec", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "ep%u_send_intr_rx", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "ep%u_send_intr_unshare", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "ep%u_send_intr_zoneupdate", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "ep%u_recv_intr_rx", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "ep%u_recv_intr_unshare", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "ep%u_recv_intr_stop", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "ep%u_recv_intr_zoneupdate", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "ep%u_tx_buffer_full", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "ep%u_tx_dropped_not_shared", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "ep%u_tx_dropped_ver_mismatch", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "ep%u_tx_dropped_buf_size_mismatch", i);
+ p += ETH_GSTRING_LEN;
+ sprintf(p, "ep%u_tx_dropped_vlanid_mismatch", i);
+ p += ETH_GSTRING_LEN;
+ }
break;
}
}
{
switch (sset) {
case ETH_SS_STATS:
- return ARRAY_SIZE(fjes_gstrings_stats);
+ return FJES_STATS_LEN;
default:
return -EOPNOTSUPP;
}
case EP_PARTNER_SHARED:
fjes_hw_raise_interrupt(hw, epidx,
REG_ICTL_MASK_TXRX_STOP_REQ);
+ hw->ep_shm_info[epidx].ep_stats.send_intr_unshare += 1;
break;
default:
break;
break;
}
mutex_unlock(&hw->hw_info.lock);
+
+ hw->ep_shm_info[epidx].ep_stats
+ .com_regist_buf_exec += 1;
}
if (test_bit(epidx, &unshare_bit)) {
mutex_unlock(&hw->hw_info.lock);
+ hw->ep_shm_info[epidx].ep_stats
+ .com_unregist_buf_exec += 1;
+
if (ret == 0) {
spin_lock_irqsave(&hw->rx_status_lock, flags);
fjes_hw_setup_epbuf(
fjes_hw_raise_interrupt(hw, epidx,
REG_ICTL_MASK_TXRX_STOP_REQ);
+ hw->ep_shm_info[epidx].ep_stats.send_intr_unshare += 1;
+
set_bit(epidx, &hw->txrx_stop_req_bit);
spin_lock_irqsave(&hw->rx_status_lock, flags);
hw->ep_shm_info[epidx].tx.
};
+/* statistics of EP */
+struct fjes_drv_ep_stats {
+ u64 com_regist_buf_exec;
+ u64 com_unregist_buf_exec;
+ u64 send_intr_rx;
+ u64 send_intr_unshare;
+ u64 send_intr_zoneupdate;
+ u64 recv_intr_rx;
+ u64 recv_intr_unshare;
+ u64 recv_intr_stop;
+ u64 recv_intr_zoneupdate;
+ u64 tx_buffer_full;
+ u64 tx_dropped_not_shared;
+ u64 tx_dropped_ver_mismatch;
+ u64 tx_dropped_buf_size_mismatch;
+ u64 tx_dropped_vlanid_mismatch;
+};
+
/* buffer pair for Extended Partition */
struct ep_share_mem_info {
struct epbuf_handler {
} tx, rx;
struct rtnl_link_stats64 net_stats;
+ struct fjes_drv_ep_stats ep_stats;
u16 tx_status_work;
FJES_ZONING_STATUS_ENABLE)) {
fjes_hw_raise_interrupt(hw, epidx,
REG_ICTL_MASK_INFO_UPDATE);
+ hw->ep_shm_info[epidx].ep_stats
+ .send_intr_zoneupdate += 1;
}
}
adapter->force_reset = true;
return result;
}
+
+ hw->ep_shm_info[epidx].ep_stats
+ .com_regist_buf_exec += 1;
}
}
result = fjes_hw_unregister_buff_addr(hw, epidx);
mutex_unlock(&hw->hw_info.lock);
+ hw->ep_shm_info[epidx].ep_stats.com_unregist_buf_exec += 1;
+
if (result)
reset_flag = true;
FJES_RX_POLL_WORK)) {
fjes_hw_raise_interrupt(hw, epid,
REG_ICTL_MASK_RX_DATA);
+ hw->ep_shm_info[epid].ep_stats.send_intr_rx += 1;
}
}
pstatus = fjes_hw_get_partner_ep_status(hw, dest_epid);
if (pstatus != EP_PARTNER_SHARED) {
+ if (!is_multi)
+ hw->ep_shm_info[dest_epid].ep_stats
+ .tx_dropped_not_shared += 1;
ret = NETDEV_TX_OK;
} else if (!fjes_hw_check_epbuf_version(
&adapter->hw.ep_shm_info[dest_epid].rx, 0)) {
adapter->stats64.tx_carrier_errors += 1;
hw->ep_shm_info[dest_epid].net_stats
.tx_carrier_errors += 1;
+ hw->ep_shm_info[dest_epid].ep_stats
+ .tx_dropped_ver_mismatch += 1;
ret = NETDEV_TX_OK;
} else if (!fjes_hw_check_mtu(
hw->ep_shm_info[dest_epid].net_stats.tx_dropped += 1;
adapter->stats64.tx_errors += 1;
hw->ep_shm_info[dest_epid].net_stats.tx_errors += 1;
+ hw->ep_shm_info[dest_epid].ep_stats
+ .tx_dropped_buf_size_mismatch += 1;
ret = NETDEV_TX_OK;
} else if (vlan &&
!fjes_hw_check_vlan_id(
&adapter->hw.ep_shm_info[dest_epid].rx,
vlan_id)) {
+ hw->ep_shm_info[dest_epid].ep_stats
+ .tx_dropped_vlanid_mismatch += 1;
ret = NETDEV_TX_OK;
} else {
if (len < VLAN_ETH_HLEN) {
ret = NETDEV_TX_OK;
} else {
netif_trans_update(netdev);
+ hw->ep_shm_info[dest_epid].ep_stats
+ .tx_buffer_full += 1;
netif_tx_stop_queue(cur_queue);
if (!work_pending(&adapter->tx_stall_task))
icr = fjes_hw_capture_interrupt_status(hw);
if (icr & REG_IS_MASK_IS_ASSERT) {
- if (icr & REG_ICTL_MASK_RX_DATA)
+ if (icr & REG_ICTL_MASK_RX_DATA) {
fjes_rx_irq(adapter, icr & REG_IS_MASK_EPID);
+ hw->ep_shm_info[icr & REG_IS_MASK_EPID].ep_stats
+ .recv_intr_rx += 1;
+ }
- if (icr & REG_ICTL_MASK_DEV_STOP_REQ)
+ if (icr & REG_ICTL_MASK_DEV_STOP_REQ) {
fjes_stop_req_irq(adapter, icr & REG_IS_MASK_EPID);
+ hw->ep_shm_info[icr & REG_IS_MASK_EPID].ep_stats
+ .recv_intr_stop += 1;
+ }
- if (icr & REG_ICTL_MASK_TXRX_STOP_REQ)
+ if (icr & REG_ICTL_MASK_TXRX_STOP_REQ) {
fjes_txrx_stop_req_irq(adapter, icr & REG_IS_MASK_EPID);
+ hw->ep_shm_info[icr & REG_IS_MASK_EPID].ep_stats
+ .recv_intr_unshare += 1;
+ }
if (icr & REG_ICTL_MASK_TXRX_STOP_DONE)
fjes_hw_set_irqmask(hw,
REG_ICTL_MASK_TXRX_STOP_DONE, true);
- if (icr & REG_ICTL_MASK_INFO_UPDATE)
+ if (icr & REG_ICTL_MASK_INFO_UPDATE) {
fjes_update_zone_irq(adapter, icr & REG_IS_MASK_EPID);
+ hw->ep_shm_info[icr & REG_IS_MASK_EPID].ep_stats
+ .recv_intr_zoneupdate += 1;
+ }
ret = IRQ_HANDLED;
} else {
break;
}
mutex_unlock(&hw->hw_info.lock);
+ hw->ep_shm_info[epidx].ep_stats
+ .com_unregist_buf_exec += 1;
spin_lock_irqsave(&hw->rx_status_lock, flags);
fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
}
mutex_unlock(&hw->hw_info.lock);
+ hw->ep_shm_info[epidx].ep_stats
+ .com_unregist_buf_exec += 1;
+
spin_lock_irqsave(&hw->rx_status_lock, flags);
fjes_hw_setup_epbuf(
&hw->ep_shm_info[epidx].tx,