Skip to content

Commit 9d5fd92

Browse files
Ganesh Goudardavem330
authored andcommitted
cxgb4/cxgb4vf: add support for ndo_set_vf_vlan
implement ndo_set_vf_vlan for mgmt netdevice to configure the PCIe VF. Original work by: Casey Leedom <[email protected]> Signed-off-by: Ganesh Goudar <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 43df215 commit 9d5fd92

File tree

9 files changed

+116
-8
lines changed

9 files changed

+116
-8
lines changed

drivers/net/ethernet/chelsio/cxgb4/cxgb4.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,7 @@ struct vf_info {
820820
unsigned char vf_mac_addr[ETH_ALEN];
821821
unsigned int tx_rate;
822822
bool pf_set_mac;
823+
u16 vlan;
823824
};
824825

825826
struct mbox_list {
@@ -1738,4 +1739,6 @@ void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, struct sge_fl *fl);
17381739
void free_tx_desc(struct adapter *adap, struct sge_txq *q,
17391740
unsigned int n, bool unmap);
17401741
void free_txq(struct adapter *adap, struct sge_txq *q);
1742+
int t4_set_vlan_acl(struct adapter *adap, unsigned int mbox, unsigned int vf,
1743+
u16 vlan);
17411744
#endif /* __CXGB4_H__ */

drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2783,7 +2783,30 @@ static int cxgb4_mgmt_set_vf_rate(struct net_device *dev, int vf,
27832783
return 0;
27842784
}
27852785

2786-
#endif
2786+
static int cxgb4_mgmt_set_vf_vlan(struct net_device *dev, int vf,
2787+
u16 vlan, u8 qos, __be16 vlan_proto)
2788+
{
2789+
struct port_info *pi = netdev_priv(dev);
2790+
struct adapter *adap = pi->adapter;
2791+
int ret;
2792+
2793+
if (vf >= adap->num_vfs || vlan > 4095 || qos > 7)
2794+
return -EINVAL;
2795+
2796+
if (vlan_proto != htons(ETH_P_8021Q) || qos != 0)
2797+
return -EPROTONOSUPPORT;
2798+
2799+
ret = t4_set_vlan_acl(adap, adap->mbox, vf + 1, vlan);
2800+
if (!ret) {
2801+
adap->vfinfo[vf].vlan = vlan;
2802+
return 0;
2803+
}
2804+
2805+
dev_err(adap->pdev_dev, "Err %d %s VLAN ACL for PF/VF %d/%d\n",
2806+
ret, (vlan ? "setting" : "clearing"), adap->pf, vf);
2807+
return ret;
2808+
}
2809+
#endif /* CONFIG_PCI_IOV */
27872810

27882811
static int cxgb_set_mac_addr(struct net_device *dev, void *p)
27892812
{
@@ -3207,6 +3230,7 @@ static const struct net_device_ops cxgb4_mgmt_netdev_ops = {
32073230
.ndo_get_vf_config = cxgb4_mgmt_get_vf_config,
32083231
.ndo_set_vf_rate = cxgb4_mgmt_set_vf_rate,
32093232
.ndo_get_phys_port_id = cxgb4_mgmt_get_phys_port_id,
3233+
.ndo_set_vf_vlan = cxgb4_mgmt_set_vf_vlan,
32103234
};
32113235
#endif
32123236

drivers/net/ethernet/chelsio/cxgb4/t4_hw.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9899,3 +9899,35 @@ int t4_i2c_rd(struct adapter *adap, unsigned int mbox, int port,
98999899

99009900
return ret;
99019901
}
9902+
9903+
/**
9904+
* t4_set_vlan_acl - Set a VLAN id for the specified VF
9905+
* @adapter: the adapter
9906+
* @mbox: mailbox to use for the FW command
9907+
* @vf: one of the VFs instantiated by the specified PF
9908+
* @vlan: The vlanid to be set
9909+
*/
9910+
int t4_set_vlan_acl(struct adapter *adap, unsigned int mbox, unsigned int vf,
9911+
u16 vlan)
9912+
{
9913+
struct fw_acl_vlan_cmd vlan_cmd;
9914+
unsigned int enable;
9915+
9916+
enable = (vlan ? FW_ACL_VLAN_CMD_EN_F : 0);
9917+
memset(&vlan_cmd, 0, sizeof(vlan_cmd));
9918+
vlan_cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_ACL_VLAN_CMD) |
9919+
FW_CMD_REQUEST_F |
9920+
FW_CMD_WRITE_F |
9921+
FW_CMD_EXEC_F |
9922+
FW_ACL_VLAN_CMD_PFN_V(adap->pf) |
9923+
FW_ACL_VLAN_CMD_VFN_V(vf));
9924+
vlan_cmd.en_to_len16 = cpu_to_be32(enable | FW_LEN16(vlan_cmd));
9925+
/* Drop all packets that donot match vlan id */
9926+
vlan_cmd.dropnovlan_fm = FW_ACL_VLAN_CMD_FM_F;
9927+
if (enable != 0) {
9928+
vlan_cmd.nvlan = 1;
9929+
vlan_cmd.vlanid[0] = cpu_to_be16(vlan);
9930+
}
9931+
9932+
return t4_wr_mbox(adap, adap->mbox, &vlan_cmd, sizeof(vlan_cmd), NULL);
9933+
}

drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2353,14 +2353,22 @@ struct fw_acl_vlan_cmd {
23532353
#define FW_ACL_VLAN_CMD_VFN_S 0
23542354
#define FW_ACL_VLAN_CMD_VFN_V(x) ((x) << FW_ACL_VLAN_CMD_VFN_S)
23552355

2356-
#define FW_ACL_VLAN_CMD_EN_S 31
2357-
#define FW_ACL_VLAN_CMD_EN_V(x) ((x) << FW_ACL_VLAN_CMD_EN_S)
2356+
#define FW_ACL_VLAN_CMD_EN_S 31
2357+
#define FW_ACL_VLAN_CMD_EN_M 0x1
2358+
#define FW_ACL_VLAN_CMD_EN_V(x) ((x) << FW_ACL_VLAN_CMD_EN_S)
2359+
#define FW_ACL_VLAN_CMD_EN_G(x) \
2360+
(((x) >> S_FW_ACL_VLAN_CMD_EN_S) & FW_ACL_VLAN_CMD_EN_M)
2361+
#define FW_ACL_VLAN_CMD_EN_F FW_ACL_VLAN_CMD_EN_V(1U)
23582362

23592363
#define FW_ACL_VLAN_CMD_DROPNOVLAN_S 7
23602364
#define FW_ACL_VLAN_CMD_DROPNOVLAN_V(x) ((x) << FW_ACL_VLAN_CMD_DROPNOVLAN_S)
23612365

2362-
#define FW_ACL_VLAN_CMD_FM_S 6
2363-
#define FW_ACL_VLAN_CMD_FM_V(x) ((x) << FW_ACL_VLAN_CMD_FM_S)
2366+
#define FW_ACL_VLAN_CMD_FM_S 6
2367+
#define FW_ACL_VLAN_CMD_FM_M 0x1
2368+
#define FW_ACL_VLAN_CMD_FM_V(x) ((x) << FW_ACL_VLAN_CMD_FM_S)
2369+
#define FW_ACL_VLAN_CMD_FM_G(x) \
2370+
(((x) >> FW_ACL_VLAN_CMD_FM_S) & FW_ACL_VLAN_CMD_FM_M)
2371+
#define FW_ACL_VLAN_CMD_FM_F FW_ACL_VLAN_CMD_FM_V(1U)
23642372

23652373
/* old 16-bit port capabilities bitmap (fw_port_cap16_t) */
23662374
enum fw_port_cap {

drivers/net/ethernet/chelsio/cxgb4vf/adapter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct sge_rspq;
9292
*/
9393
struct port_info {
9494
struct adapter *adapter; /* our adapter */
95+
u32 vlan_id; /* vlan id for VST */
9596
u16 viid; /* virtual interface ID */
9697
s16 xact_addr_filt; /* index of our MAC address filter */
9798
u16 rss_size; /* size of VI's RSS table slice */

drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,8 @@ static int cxgb4vf_open(struct net_device *dev)
791791
if (err)
792792
goto err_unwind;
793793

794+
pi->vlan_id = t4vf_get_vf_vlan_acl(adapter);
795+
794796
netif_tx_start_all_queues(dev);
795797
set_bit(pi->port_id, &adapter->open_device_map);
796798
return 0;

drivers/net/ethernet/chelsio/cxgb4vf/sge.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,10 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev)
12021202
BUG_ON(qidx >= pi->nqsets);
12031203
txq = &adapter->sge.ethtxq[pi->first_qset + qidx];
12041204

1205+
if (pi->vlan_id && !skb_vlan_tag_present(skb))
1206+
__vlan_hwaccel_put_tag(skb, cpu_to_be16(ETH_P_8021Q),
1207+
pi->vlan_id);
1208+
12051209
/*
12061210
* Take this opportunity to reclaim any TX Descriptors whose DMA
12071211
* transfers have completed.
@@ -1570,6 +1574,7 @@ static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl,
15701574
{
15711575
struct adapter *adapter = rxq->rspq.adapter;
15721576
struct sge *s = &adapter->sge;
1577+
struct port_info *pi;
15731578
int ret;
15741579
struct sk_buff *skb;
15751580

@@ -1586,8 +1591,9 @@ static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl,
15861591
skb->truesize += skb->data_len;
15871592
skb->ip_summed = CHECKSUM_UNNECESSARY;
15881593
skb_record_rx_queue(skb, rxq->rspq.idx);
1594+
pi = netdev_priv(skb->dev);
15891595

1590-
if (pkt->vlan_ex) {
1596+
if (pkt->vlan_ex && !pi->vlan_id) {
15911597
__vlan_hwaccel_put_tag(skb, cpu_to_be16(ETH_P_8021Q),
15921598
be16_to_cpu(pkt->vlan));
15931599
rxq->stats.vlan_ex++;
@@ -1620,6 +1626,7 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
16201626
struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq);
16211627
struct adapter *adapter = rspq->adapter;
16221628
struct sge *s = &adapter->sge;
1629+
struct port_info *pi;
16231630

16241631
/*
16251632
* If this is a good TCP packet and we have Generic Receive Offload
@@ -1644,6 +1651,7 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
16441651
__skb_pull(skb, s->pktshift);
16451652
skb->protocol = eth_type_trans(skb, rspq->netdev);
16461653
skb_record_rx_queue(skb, rspq->idx);
1654+
pi = netdev_priv(skb->dev);
16471655
rxq->stats.pkts++;
16481656

16491657
if (csum_ok && !pkt->err_vec &&
@@ -1660,9 +1668,10 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
16601668
} else
16611669
skb_checksum_none_assert(skb);
16621670

1663-
if (pkt->vlan_ex) {
1671+
if (pkt->vlan_ex && !pi->vlan_id) {
16641672
rxq->stats.vlan_ex++;
1665-
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), be16_to_cpu(pkt->vlan));
1673+
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
1674+
be16_to_cpu(pkt->vlan));
16661675
}
16671676

16681677
netif_receive_skb(skb);

drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,5 +413,6 @@ int t4vf_handle_fw_rpl(struct adapter *, const __be64 *);
413413
int t4vf_prep_adapter(struct adapter *);
414414
int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf,
415415
unsigned int *naddr, u8 *addr);
416+
int t4vf_get_vf_vlan_acl(struct adapter *adapter);
416417

417418
#endif /* __T4VF_COMMON_H__ */

drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2147,3 +2147,31 @@ int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf,
21472147

21482148
return ret;
21492149
}
2150+
2151+
/**
2152+
* t4vf_get_vf_vlan_acl - Get the VLAN ID to be set to
2153+
* the VI of this VF.
2154+
* @adapter: The adapter
2155+
*
2156+
* Find the VLAN ID to be set to the VF's VI. The requested VLAN ID
2157+
* is from the host OS via callback in the PF driver.
2158+
*/
2159+
int t4vf_get_vf_vlan_acl(struct adapter *adapter)
2160+
{
2161+
struct fw_acl_vlan_cmd cmd;
2162+
int vlan = 0;
2163+
int ret = 0;
2164+
2165+
cmd.op_to_vfn = htonl(FW_CMD_OP_V(FW_ACL_VLAN_CMD) |
2166+
FW_CMD_REQUEST_F | FW_CMD_READ_F);
2167+
2168+
/* Note: Do not enable the ACL */
2169+
cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd));
2170+
2171+
ret = t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), &cmd);
2172+
2173+
if (!ret)
2174+
vlan = be16_to_cpu(cmd.vlanid[0]);
2175+
2176+
return vlan;
2177+
}

0 commit comments

Comments
 (0)