Skip to content

Commit

Permalink
octeon_ep: add support for ndo ops
Browse files Browse the repository at this point in the history
Add support for ndo ops to set MAC address, change MTU, get stats.
Add control path support to set MAC address, change MTU, get stats,
set speed, get and set link mode.

Signed-off-by: Veerasenareddy Burru <vburru@marvell.com>
Signed-off-by: Abhijit Ayarekar <aayarekar@marvell.com>
Signed-off-by: Satananda Burla <sburla@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Veerasenareddy Burru authored and David S. Miller committed Apr 13, 2022
1 parent 397dfb5 commit 6a610a4
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 1 deletion.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_mbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ struct octep_ctrl_mbox {
/* size of bar memory */
u32 barmem_sz;
/* pointer to BAR memory */
void __iomem *barmem;
u8 __iomem *barmem;
/* user context for callback, can be null */
void *user_ctx;
/* callback handler for processing request, called from octep_ctrl_mbox_recv */
Expand Down
60 changes: 60 additions & 0 deletions drivers/net/ethernet/marvell/octeon_ep/octep_ctrl_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,66 @@ int octep_get_mac_addr(struct octep_device *oct, u8 *addr)
return err;
}

int octep_set_mac_addr(struct octep_device *oct, u8 *addr)
{
struct octep_ctrl_net_h2f_req req = {};
struct octep_ctrl_mbox_msg msg = {};

req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_MAC;
req.mac.cmd = OCTEP_CTRL_NET_CMD_SET;
memcpy(&req.mac.addr, addr, ETH_ALEN);

msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
msg.hdr.sizew = OCTEP_CTRL_NET_H2F_MAC_REQ_SZW;
msg.msg = &req;

return octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
}

int octep_set_mtu(struct octep_device *oct, int mtu)
{
struct octep_ctrl_net_h2f_req req = {};
struct octep_ctrl_mbox_msg msg = {};

req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_MTU;
req.mtu.cmd = OCTEP_CTRL_NET_CMD_SET;
req.mtu.val = mtu;

msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
msg.hdr.sizew = OCTEP_CTRL_NET_H2F_MTU_REQ_SZW;
msg.msg = &req;

return octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
}

int octep_get_if_stats(struct octep_device *oct)
{
void __iomem *iface_rx_stats;
void __iomem *iface_tx_stats;
struct octep_ctrl_net_h2f_req req = {};
struct octep_ctrl_mbox_msg msg = {};
int err;

req.hdr.cmd = OCTEP_CTRL_NET_H2F_CMD_GET_IF_STATS;
req.mac.cmd = OCTEP_CTRL_NET_CMD_GET;
req.get_stats.offset = oct->ctrl_mbox_ifstats_offset;

msg.hdr.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ;
msg.hdr.sizew = OCTEP_CTRL_NET_H2F_GET_STATS_REQ_SZW;
msg.msg = &req;
err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &msg);
if (err)
return err;

iface_rx_stats = oct->ctrl_mbox.barmem + oct->ctrl_mbox_ifstats_offset;
iface_tx_stats = oct->ctrl_mbox.barmem + oct->ctrl_mbox_ifstats_offset +
sizeof(struct octep_iface_rx_stats);
memcpy_fromio(&oct->iface_rx_stats, iface_rx_stats, sizeof(struct octep_iface_rx_stats));
memcpy_fromio(&oct->iface_tx_stats, iface_tx_stats, sizeof(struct octep_iface_tx_stats));

return err;
}

int octep_get_link_info(struct octep_device *oct)
{
struct octep_ctrl_net_h2f_req req = {};
Expand Down
78 changes: 78 additions & 0 deletions drivers/net/ethernet/marvell/octeon_ep/octep_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,43 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
}

/**
* octep_get_stats64() - Get Octeon network device statistics.
*
* @netdev: kernel network device.
* @stats: pointer to stats structure to be filled in.
*/
static void octep_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *stats)
{
u64 tx_packets, tx_bytes, rx_packets, rx_bytes;
struct octep_device *oct = netdev_priv(netdev);
int q;

octep_get_if_stats(oct);
tx_packets = 0;
tx_bytes = 0;
rx_packets = 0;
rx_bytes = 0;
for (q = 0; q < oct->num_oqs; q++) {
struct octep_iq *iq = oct->iq[q];
struct octep_oq *oq = oct->oq[q];

tx_packets += iq->stats.instr_completed;
tx_bytes += iq->stats.bytes_sent;
rx_packets += oq->stats.packets;
rx_bytes += oq->stats.bytes;
}
stats->tx_packets = tx_packets;
stats->tx_bytes = tx_bytes;
stats->rx_packets = rx_packets;
stats->rx_bytes = rx_bytes;
stats->multicast = oct->iface_rx_stats.mcast_pkts;
stats->rx_errors = oct->iface_rx_stats.err_pkts;
stats->collisions = oct->iface_tx_stats.xscol;
stats->tx_fifo_errors = oct->iface_tx_stats.undflw;
}

/**
* octep_tx_timeout_task - work queue task to Handle Tx queue timeout.
*
Expand Down Expand Up @@ -190,11 +227,52 @@ static void octep_tx_timeout(struct net_device *netdev, unsigned int txqueue)
queue_work(octep_wq, &oct->tx_timeout_task);
}

static int octep_set_mac(struct net_device *netdev, void *p)
{
struct octep_device *oct = netdev_priv(netdev);
struct sockaddr *addr = (struct sockaddr *)p;
int err;

if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;

err = octep_set_mac_addr(oct, addr->sa_data);
if (err)
return err;

memcpy(oct->mac_addr, addr->sa_data, ETH_ALEN);
eth_hw_addr_set(netdev, addr->sa_data);

return 0;
}

static int octep_change_mtu(struct net_device *netdev, int new_mtu)
{
struct octep_device *oct = netdev_priv(netdev);
struct octep_iface_link_info *link_info;
int err = 0;

link_info = &oct->link_info;
if (link_info->mtu == new_mtu)
return 0;

err = octep_set_mtu(oct, new_mtu);
if (!err) {
oct->link_info.mtu = new_mtu;
netdev->mtu = new_mtu;
}

return err;
}

static const struct net_device_ops octep_netdev_ops = {
.ndo_open = octep_open,
.ndo_stop = octep_stop,
.ndo_start_xmit = octep_start_xmit,
.ndo_get_stats64 = octep_get_stats64,
.ndo_tx_timeout = octep_tx_timeout,
.ndo_set_mac_address = octep_set_mac,
.ndo_change_mtu = octep_change_mtu,
};

/**
Expand Down

0 comments on commit 6a610a4

Please sign in to comment.