Skip to content

Commit 34bfe0e

Browse files
sgoutham-marvelldavem330
authored andcommitted
octeontx2-pf: MTU, MAC and RX mode config support
This patch addes support to change interface MTU, MAC address retrieval and config, RX mode ie unicast, multicast and promiscuous. Also added link loopback support Signed-off-by: Tomasz Duszynski <[email protected]> Signed-off-by: Subbaraya Sundeep <[email protected]> Signed-off-by: Sunil Goutham <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 50fe6c0 commit 34bfe0e

File tree

6 files changed

+242
-6
lines changed

6 files changed

+242
-6
lines changed

drivers/net/ethernet/marvell/octeontx2/af/mbox.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ M(NIX_SET_RX_CFG, 0x8010, nix_set_rx_cfg, nix_rx_cfg, msg_rsp) \
210210
M(NIX_LSO_FORMAT_CFG, 0x8011, nix_lso_format_cfg, \
211211
nix_lso_format_cfg, \
212212
nix_lso_format_cfg_rsp) \
213-
M(NIX_RXVLAN_ALLOC, 0x8012, nix_rxvlan_alloc, msg_req, msg_rsp)
213+
M(NIX_RXVLAN_ALLOC, 0x8012, nix_rxvlan_alloc, msg_req, msg_rsp) \
214+
M(NIX_GET_MAC_ADDR, 0x8018, nix_get_mac_addr, msg_req, nix_get_mac_addr_rsp) \
214215

215216
/* Messages initiated by AF (range 0xC00 - 0xDFF) */
216217
#define MBOX_UP_CGX_MESSAGES \
@@ -618,6 +619,11 @@ struct nix_set_mac_addr {
618619
u8 mac_addr[ETH_ALEN]; /* MAC address to be set for this pcifunc */
619620
};
620621

622+
struct nix_get_mac_addr_rsp {
623+
struct mbox_msghdr hdr;
624+
u8 mac_addr[ETH_ALEN];
625+
};
626+
621627
struct nix_mark_format_cfg {
622628
struct mbox_msghdr hdr;
623629
u8 offset;

drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2546,6 +2546,23 @@ int rvu_mbox_handler_nix_set_mac_addr(struct rvu *rvu,
25462546
return 0;
25472547
}
25482548

2549+
int rvu_mbox_handler_nix_get_mac_addr(struct rvu *rvu,
2550+
struct msg_req *req,
2551+
struct nix_get_mac_addr_rsp *rsp)
2552+
{
2553+
u16 pcifunc = req->hdr.pcifunc;
2554+
struct rvu_pfvf *pfvf;
2555+
2556+
if (!is_nixlf_attached(rvu, pcifunc))
2557+
return NIX_AF_ERR_AF_LF_INVALID;
2558+
2559+
pfvf = rvu_get_pfvf(rvu, pcifunc);
2560+
2561+
ether_addr_copy(rsp->mac_addr, pfvf->mac_addr);
2562+
2563+
return 0;
2564+
}
2565+
25492566
int rvu_mbox_handler_nix_set_rx_mode(struct rvu *rvu, struct nix_rx_mode *req,
25502567
struct msg_rsp *rsp)
25512568
{

drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,97 @@
1515
#include "otx2_common.h"
1616
#include "otx2_struct.h"
1717

18+
/* Sync MAC address with RVU AF */
19+
static int otx2_hw_set_mac_addr(struct otx2_nic *pfvf, u8 *mac)
20+
{
21+
struct nix_set_mac_addr *req;
22+
int err;
23+
24+
otx2_mbox_lock(&pfvf->mbox);
25+
req = otx2_mbox_alloc_msg_nix_set_mac_addr(&pfvf->mbox);
26+
if (!req) {
27+
otx2_mbox_unlock(&pfvf->mbox);
28+
return -ENOMEM;
29+
}
30+
31+
ether_addr_copy(req->mac_addr, mac);
32+
33+
err = otx2_sync_mbox_msg(&pfvf->mbox);
34+
otx2_mbox_unlock(&pfvf->mbox);
35+
return err;
36+
}
37+
38+
static int otx2_hw_get_mac_addr(struct otx2_nic *pfvf,
39+
struct net_device *netdev)
40+
{
41+
struct nix_get_mac_addr_rsp *rsp;
42+
struct mbox_msghdr *msghdr;
43+
struct msg_req *req;
44+
int err;
45+
46+
otx2_mbox_lock(&pfvf->mbox);
47+
req = otx2_mbox_alloc_msg_nix_get_mac_addr(&pfvf->mbox);
48+
if (!req) {
49+
otx2_mbox_unlock(&pfvf->mbox);
50+
return -ENOMEM;
51+
}
52+
53+
err = otx2_sync_mbox_msg(&pfvf->mbox);
54+
if (err) {
55+
otx2_mbox_unlock(&pfvf->mbox);
56+
return err;
57+
}
58+
59+
msghdr = otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
60+
if (!msghdr) {
61+
otx2_mbox_unlock(&pfvf->mbox);
62+
return -ENOMEM;
63+
}
64+
rsp = (struct nix_get_mac_addr_rsp *)msghdr;
65+
ether_addr_copy(netdev->dev_addr, rsp->mac_addr);
66+
otx2_mbox_unlock(&pfvf->mbox);
67+
68+
return 0;
69+
}
70+
71+
int otx2_set_mac_address(struct net_device *netdev, void *p)
72+
{
73+
struct otx2_nic *pfvf = netdev_priv(netdev);
74+
struct sockaddr *addr = p;
75+
76+
if (!is_valid_ether_addr(addr->sa_data))
77+
return -EADDRNOTAVAIL;
78+
79+
if (!otx2_hw_set_mac_addr(pfvf, addr->sa_data))
80+
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
81+
else
82+
return -EPERM;
83+
84+
return 0;
85+
}
86+
87+
int otx2_hw_set_mtu(struct otx2_nic *pfvf, int mtu)
88+
{
89+
struct nix_frs_cfg *req;
90+
int err;
91+
92+
otx2_mbox_lock(&pfvf->mbox);
93+
req = otx2_mbox_alloc_msg_nix_set_hw_frs(&pfvf->mbox);
94+
if (!req) {
95+
otx2_mbox_unlock(&pfvf->mbox);
96+
return -ENOMEM;
97+
}
98+
99+
/* SMQ config limits maximum pkt size that can be transmitted */
100+
req->update_smq = true;
101+
pfvf->max_frs = mtu + OTX2_ETH_HLEN;
102+
req->maxlen = pfvf->max_frs;
103+
104+
err = otx2_sync_mbox_msg(&pfvf->mbox);
105+
otx2_mbox_unlock(&pfvf->mbox);
106+
return err;
107+
}
108+
18109
void otx2_config_irq_coalescing(struct otx2_nic *pfvf, int qidx)
19110
{
20111
/* Configure CQE interrupt coalescing parameters
@@ -63,6 +154,20 @@ dma_addr_t otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool,
63154
return iova;
64155
}
65156

157+
void otx2_get_mac_from_af(struct net_device *netdev)
158+
{
159+
struct otx2_nic *pfvf = netdev_priv(netdev);
160+
int err;
161+
162+
err = otx2_hw_get_mac_addr(pfvf, netdev);
163+
if (err)
164+
dev_warn(pfvf->dev, "Failed to read mac from hardware\n");
165+
166+
/* If AF doesn't provide a valid MAC, generate a random one */
167+
if (!is_valid_ether_addr(netdev->dev_addr))
168+
eth_hw_addr_random(netdev);
169+
}
170+
66171
static int otx2_get_link(struct otx2_nic *pfvf)
67172
{
68173
int link = 0;
@@ -97,6 +202,9 @@ int otx2_txschq_config(struct otx2_nic *pfvf, int lvl)
97202
/* Set topology e.t.c configuration */
98203
if (lvl == NIX_TXSCH_LVL_SMQ) {
99204
req->reg[0] = NIX_AF_SMQX_CFG(schq);
205+
req->regval[0] = ((pfvf->netdev->mtu + OTX2_ETH_HLEN) << 8) |
206+
OTX2_MIN_MTU;
207+
100208
req->regval[0] |= (0x20ULL << 51) | (0x80ULL << 39) |
101209
(0x2ULL << 36);
102210
req->num_regs++;

drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ struct otx2_nic {
133133
void __iomem *reg_base;
134134
struct net_device *netdev;
135135
void *iommu_domain;
136+
u16 max_frs;
136137
u16 rbsize; /* Receive buffer size */
137138

138139
#define OTX2_FLAG_INTF_DOWN BIT_ULL(2)
@@ -469,7 +470,9 @@ static inline void otx2_dma_unmap_page(struct otx2_nic *pfvf,
469470
/* MSI-X APIs */
470471
void otx2_free_cints(struct otx2_nic *pfvf, int n);
471472
void otx2_set_cints_affinity(struct otx2_nic *pfvf);
472-
473+
int otx2_set_mac_address(struct net_device *netdev, void *p);
474+
int otx2_hw_set_mtu(struct otx2_nic *pfvf, int mtu);
475+
void otx2_get_mac_from_af(struct net_device *netdev);
473476
void otx2_config_irq_coalescing(struct otx2_nic *pfvf, int qidx);
474477

475478
/* RVU block related APIs */
@@ -503,4 +506,7 @@ void mbox_handler_nix_lf_alloc(struct otx2_nic *pfvf,
503506
struct nix_lf_alloc_rsp *rsp);
504507
void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf,
505508
struct nix_txsch_alloc_rsp *rsp);
509+
510+
int otx2_open(struct net_device *netdev);
511+
int otx2_stop(struct net_device *netdev);
506512
#endif /* OTX2_COMMON_H */

drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,24 @@ enum {
4343
TYPE_PFVF,
4444
};
4545

46+
static int otx2_change_mtu(struct net_device *netdev, int new_mtu)
47+
{
48+
bool if_up = netif_running(netdev);
49+
int err = 0;
50+
51+
if (if_up)
52+
otx2_stop(netdev);
53+
54+
netdev_info(netdev, "Changing MTU from %d to %d\n",
55+
netdev->mtu, new_mtu);
56+
netdev->mtu = new_mtu;
57+
58+
if (if_up)
59+
err = otx2_open(netdev);
60+
61+
return err;
62+
}
63+
4664
static void otx2_queue_work(struct mbox *mw, struct workqueue_struct *mbox_wq,
4765
int first, int mdevs, u64 intr, int type)
4866
{
@@ -420,6 +438,27 @@ static int otx2_cgx_config_linkevents(struct otx2_nic *pf, bool enable)
420438
return err;
421439
}
422440

441+
static int otx2_cgx_config_loopback(struct otx2_nic *pf, bool enable)
442+
{
443+
struct msg_req *msg;
444+
int err;
445+
446+
otx2_mbox_lock(&pf->mbox);
447+
if (enable)
448+
msg = otx2_mbox_alloc_msg_cgx_intlbk_enable(&pf->mbox);
449+
else
450+
msg = otx2_mbox_alloc_msg_cgx_intlbk_disable(&pf->mbox);
451+
452+
if (!msg) {
453+
otx2_mbox_unlock(&pf->mbox);
454+
return -ENOMEM;
455+
}
456+
457+
err = otx2_sync_mbox_msg(&pf->mbox);
458+
otx2_mbox_unlock(&pf->mbox);
459+
return err;
460+
}
461+
423462
static int otx2_set_real_num_queues(struct net_device *netdev,
424463
int tx_queues, int rx_queues)
425464
{
@@ -519,7 +558,7 @@ static int otx2_init_hw_resources(struct otx2_nic *pf)
519558
hw->pool_cnt = hw->rqpool_cnt + hw->sqpool_cnt;
520559

521560
/* Get the size of receive buffers to allocate */
522-
pf->rbsize = RCV_FRAG_LEN(pf->netdev->mtu);
561+
pf->rbsize = RCV_FRAG_LEN(pf->netdev->mtu + OTX2_ETH_HLEN);
523562

524563
otx2_mbox_lock(mbox);
525564
/* NPA init */
@@ -658,7 +697,7 @@ static void otx2_free_hw_resources(struct otx2_nic *pf)
658697
otx2_mbox_unlock(mbox);
659698
}
660699

661-
static int otx2_open(struct net_device *netdev)
700+
int otx2_open(struct net_device *netdev)
662701
{
663702
struct otx2_nic *pf = netdev_priv(netdev);
664703
struct otx2_cq_poll *cq_poll = NULL;
@@ -715,6 +754,11 @@ static int otx2_open(struct net_device *netdev)
715754
napi_enable(&cq_poll->napi);
716755
}
717756

757+
/* Set maximum frame size allowed in HW */
758+
err = otx2_hw_set_mtu(pf, netdev->mtu);
759+
if (err)
760+
goto err_disable_napi;
761+
718762
/* Register CQ IRQ handlers */
719763
vec = pf->hw.nix_msixoff + NIX_LF_CINT_VEC_START;
720764
for (qidx = 0; qidx < pf->hw.cint_cnt; qidx++) {
@@ -759,6 +803,7 @@ static int otx2_open(struct net_device *netdev)
759803

760804
err_free_cints:
761805
otx2_free_cints(pf, qidx);
806+
err_disable_napi:
762807
otx2_disable_napi(pf);
763808
otx2_free_hw_resources(pf);
764809
err_free_mem:
@@ -768,7 +813,7 @@ static int otx2_open(struct net_device *netdev)
768813
return err;
769814
}
770815

771-
static int otx2_stop(struct net_device *netdev)
816+
int otx2_stop(struct net_device *netdev)
772817
{
773818
struct otx2_nic *pf = netdev_priv(netdev);
774819
struct otx2_cq_poll *cq_poll = NULL;
@@ -847,10 +892,53 @@ static netdev_tx_t otx2_xmit(struct sk_buff *skb, struct net_device *netdev)
847892
return NETDEV_TX_OK;
848893
}
849894

895+
static void otx2_set_rx_mode(struct net_device *netdev)
896+
{
897+
struct otx2_nic *pf = netdev_priv(netdev);
898+
struct nix_rx_mode *req;
899+
900+
if (!(netdev->flags & IFF_UP))
901+
return;
902+
903+
otx2_mbox_lock(&pf->mbox);
904+
req = otx2_mbox_alloc_msg_nix_set_rx_mode(&pf->mbox);
905+
if (!req) {
906+
otx2_mbox_unlock(&pf->mbox);
907+
return;
908+
}
909+
910+
req->mode = NIX_RX_MODE_UCAST;
911+
912+
/* We don't support MAC address filtering yet */
913+
if (netdev->flags & IFF_PROMISC)
914+
req->mode |= NIX_RX_MODE_PROMISC;
915+
else if (netdev->flags & (IFF_ALLMULTI | IFF_MULTICAST))
916+
req->mode |= NIX_RX_MODE_ALLMULTI;
917+
918+
otx2_sync_mbox_msg(&pf->mbox);
919+
otx2_mbox_unlock(&pf->mbox);
920+
}
921+
922+
static int otx2_set_features(struct net_device *netdev,
923+
netdev_features_t features)
924+
{
925+
netdev_features_t changed = features ^ netdev->features;
926+
struct otx2_nic *pf = netdev_priv(netdev);
927+
928+
if ((changed & NETIF_F_LOOPBACK) && netif_running(netdev))
929+
return otx2_cgx_config_loopback(pf,
930+
features & NETIF_F_LOOPBACK);
931+
return 0;
932+
}
933+
850934
static const struct net_device_ops otx2_netdev_ops = {
851935
.ndo_open = otx2_open,
852936
.ndo_stop = otx2_stop,
853937
.ndo_start_xmit = otx2_xmit,
938+
.ndo_set_mac_address = otx2_set_mac_address,
939+
.ndo_change_mtu = otx2_change_mtu,
940+
.ndo_set_rx_mode = otx2_set_rx_mode,
941+
.ndo_set_features = otx2_set_features,
854942
};
855943

856944
static int otx2_check_pf_usable(struct otx2_nic *nic)
@@ -1005,6 +1093,9 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
10051093

10061094
otx2_setup_dev_hw_settings(pf);
10071095

1096+
/* Assign default mac address */
1097+
otx2_get_mac_from_af(netdev);
1098+
10081099
/* NPA's pool is a stack to which SW frees buffer pointers via Aura.
10091100
* HW allocates buffer pointer from stack and uses it for DMA'ing
10101101
* ingress packet. In some scenarios HW can free back allocated buffer
@@ -1022,10 +1113,14 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)
10221113
NETIF_F_IPV6_CSUM | NETIF_F_SG);
10231114
netdev->features |= netdev->hw_features;
10241115

1025-
netdev->hw_features |= NETIF_F_RXALL;
1116+
netdev->hw_features |= NETIF_F_LOOPBACK | NETIF_F_RXALL;
10261117

10271118
netdev->netdev_ops = &otx2_netdev_ops;
10281119

1120+
/* MTU range: 64 - 9190 */
1121+
netdev->min_mtu = OTX2_MIN_MTU;
1122+
netdev->max_mtu = OTX2_MAX_MTU;
1123+
10291124
err = register_netdev(netdev);
10301125
if (err) {
10311126
dev_err(dev, "Failed to register netdevice\n");

drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#define OTX2_DATA_ALIGN(X) ALIGN(X, OTX2_ALIGN)
2323
#define OTX2_HEAD_ROOM OTX2_ALIGN
2424

25+
#define OTX2_ETH_HLEN (VLAN_ETH_HLEN + VLAN_HLEN)
26+
#define OTX2_MIN_MTU 64
27+
#define OTX2_MAX_MTU (9212 - OTX2_ETH_HLEN)
28+
2529
#define OTX2_MAX_FRAGS_IN_SQE 9
2630

2731
/* Rx buffer size should be in multiples of 128bytes */

0 commit comments

Comments
 (0)