aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGanesh Goudar <ganeshgr@chelsio.com>2018-01-24 10:14:07 -0500
committerDavid S. Miller <davem@davemloft.net>2018-01-24 10:48:25 -0500
commit9d5fd927d20b38d9785f510b93b3f0f8e19aba5f (patch)
treef76e3012dd0c0fdd0eb8852c85451287795f0eab
parent43df215d99e6049d4680309c54232689e16ddd6b (diff)
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 <leedom@chelsio.com> Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4.h3
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c26
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.c32
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h16
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/adapter.h1
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c2
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/sge.c15
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h1
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c28
9 files changed, 116 insertions, 8 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 3e0218735b2b..429467364219 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -820,6 +820,7 @@ struct vf_info {
820 unsigned char vf_mac_addr[ETH_ALEN]; 820 unsigned char vf_mac_addr[ETH_ALEN];
821 unsigned int tx_rate; 821 unsigned int tx_rate;
822 bool pf_set_mac; 822 bool pf_set_mac;
823 u16 vlan;
823}; 824};
824 825
825struct mbox_list { 826struct mbox_list {
@@ -1738,4 +1739,6 @@ void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, struct sge_fl *fl);
1738void free_tx_desc(struct adapter *adap, struct sge_txq *q, 1739void free_tx_desc(struct adapter *adap, struct sge_txq *q,
1739 unsigned int n, bool unmap); 1740 unsigned int n, bool unmap);
1740void free_txq(struct adapter *adap, struct sge_txq *q); 1741void free_txq(struct adapter *adap, struct sge_txq *q);
1742int t4_set_vlan_acl(struct adapter *adap, unsigned int mbox, unsigned int vf,
1743 u16 vlan);
1741#endif /* __CXGB4_H__ */ 1744#endif /* __CXGB4_H__ */
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 4716387830ef..f0fd2eba30c2 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -2783,7 +2783,30 @@ static int cxgb4_mgmt_set_vf_rate(struct net_device *dev, int vf,
2783 return 0; 2783 return 0;
2784} 2784}
2785 2785
2786#endif 2786static 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 */
2787 2810
2788static int cxgb_set_mac_addr(struct net_device *dev, void *p) 2811static int cxgb_set_mac_addr(struct net_device *dev, void *p)
2789{ 2812{
@@ -3207,6 +3230,7 @@ static const struct net_device_ops cxgb4_mgmt_netdev_ops = {
3207 .ndo_get_vf_config = cxgb4_mgmt_get_vf_config, 3230 .ndo_get_vf_config = cxgb4_mgmt_get_vf_config,
3208 .ndo_set_vf_rate = cxgb4_mgmt_set_vf_rate, 3231 .ndo_set_vf_rate = cxgb4_mgmt_set_vf_rate,
3209 .ndo_get_phys_port_id = cxgb4_mgmt_get_phys_port_id, 3232 .ndo_get_phys_port_id = cxgb4_mgmt_get_phys_port_id,
3233 .ndo_set_vf_vlan = cxgb4_mgmt_set_vf_vlan,
3210}; 3234};
3211#endif 3235#endif
3212 3236
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 6d76851a4da9..34055476288c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -9899,3 +9899,35 @@ int t4_i2c_rd(struct adapter *adap, unsigned int mbox, int port,
9899 9899
9900 return ret; 9900 return ret;
9901} 9901}
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 */
9910int 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}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
index f3310d5b3c4c..f88766d2401d 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
@@ -2353,14 +2353,22 @@ struct fw_acl_vlan_cmd {
2353#define FW_ACL_VLAN_CMD_VFN_S 0 2353#define FW_ACL_VLAN_CMD_VFN_S 0
2354#define FW_ACL_VLAN_CMD_VFN_V(x) ((x) << FW_ACL_VLAN_CMD_VFN_S) 2354#define FW_ACL_VLAN_CMD_VFN_V(x) ((x) << FW_ACL_VLAN_CMD_VFN_S)
2355 2355
2356#define FW_ACL_VLAN_CMD_EN_S 31 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) 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)
2358 2362
2359#define FW_ACL_VLAN_CMD_DROPNOVLAN_S 7 2363#define FW_ACL_VLAN_CMD_DROPNOVLAN_S 7
2360#define FW_ACL_VLAN_CMD_DROPNOVLAN_V(x) ((x) << FW_ACL_VLAN_CMD_DROPNOVLAN_S) 2364#define FW_ACL_VLAN_CMD_DROPNOVLAN_V(x) ((x) << FW_ACL_VLAN_CMD_DROPNOVLAN_S)
2361 2365
2362#define FW_ACL_VLAN_CMD_FM_S 6 2366#define FW_ACL_VLAN_CMD_FM_S 6
2363#define FW_ACL_VLAN_CMD_FM_V(x) ((x) << FW_ACL_VLAN_CMD_FM_S) 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)
2364 2372
2365/* old 16-bit port capabilities bitmap (fw_port_cap16_t) */ 2373/* old 16-bit port capabilities bitmap (fw_port_cap16_t) */
2366enum fw_port_cap { 2374enum fw_port_cap {
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
index 08c6ddb84a04..5883f09e3804 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
@@ -92,6 +92,7 @@ struct sge_rspq;
92 */ 92 */
93struct port_info { 93struct port_info {
94 struct adapter *adapter; /* our adapter */ 94 struct adapter *adapter; /* our adapter */
95 u32 vlan_id; /* vlan id for VST */
95 u16 viid; /* virtual interface ID */ 96 u16 viid; /* virtual interface ID */
96 s16 xact_addr_filt; /* index of our MAC address filter */ 97 s16 xact_addr_filt; /* index of our MAC address filter */
97 u16 rss_size; /* size of VI's RSS table slice */ 98 u16 rss_size; /* size of VI's RSS table slice */
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index 96f69f80dc99..b7e79e64d2ed 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -791,6 +791,8 @@ static int cxgb4vf_open(struct net_device *dev)
791 if (err) 791 if (err)
792 goto err_unwind; 792 goto err_unwind;
793 793
794 pi->vlan_id = t4vf_get_vf_vlan_acl(adapter);
795
794 netif_tx_start_all_queues(dev); 796 netif_tx_start_all_queues(dev);
795 set_bit(pi->port_id, &adapter->open_device_map); 797 set_bit(pi->port_id, &adapter->open_device_map);
796 return 0; 798 return 0;
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
index 129b914a434c..dfce5df7538e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
@@ -1202,6 +1202,10 @@ int t4vf_eth_xmit(struct sk_buff *skb, struct net_device *dev)
1202 BUG_ON(qidx >= pi->nqsets); 1202 BUG_ON(qidx >= pi->nqsets);
1203 txq = &adapter->sge.ethtxq[pi->first_qset + qidx]; 1203 txq = &adapter->sge.ethtxq[pi->first_qset + qidx];
1204 1204
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
1205 /* 1209 /*
1206 * Take this opportunity to reclaim any TX Descriptors whose DMA 1210 * Take this opportunity to reclaim any TX Descriptors whose DMA
1207 * transfers have completed. 1211 * transfers have completed.
@@ -1570,6 +1574,7 @@ static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl,
1570{ 1574{
1571 struct adapter *adapter = rxq->rspq.adapter; 1575 struct adapter *adapter = rxq->rspq.adapter;
1572 struct sge *s = &adapter->sge; 1576 struct sge *s = &adapter->sge;
1577 struct port_info *pi;
1573 int ret; 1578 int ret;
1574 struct sk_buff *skb; 1579 struct sk_buff *skb;
1575 1580
@@ -1586,8 +1591,9 @@ static void do_gro(struct sge_eth_rxq *rxq, const struct pkt_gl *gl,
1586 skb->truesize += skb->data_len; 1591 skb->truesize += skb->data_len;
1587 skb->ip_summed = CHECKSUM_UNNECESSARY; 1592 skb->ip_summed = CHECKSUM_UNNECESSARY;
1588 skb_record_rx_queue(skb, rxq->rspq.idx); 1593 skb_record_rx_queue(skb, rxq->rspq.idx);
1594 pi = netdev_priv(skb->dev);
1589 1595
1590 if (pkt->vlan_ex) { 1596 if (pkt->vlan_ex && !pi->vlan_id) {
1591 __vlan_hwaccel_put_tag(skb, cpu_to_be16(ETH_P_8021Q), 1597 __vlan_hwaccel_put_tag(skb, cpu_to_be16(ETH_P_8021Q),
1592 be16_to_cpu(pkt->vlan)); 1598 be16_to_cpu(pkt->vlan));
1593 rxq->stats.vlan_ex++; 1599 rxq->stats.vlan_ex++;
@@ -1620,6 +1626,7 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
1620 struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq); 1626 struct sge_eth_rxq *rxq = container_of(rspq, struct sge_eth_rxq, rspq);
1621 struct adapter *adapter = rspq->adapter; 1627 struct adapter *adapter = rspq->adapter;
1622 struct sge *s = &adapter->sge; 1628 struct sge *s = &adapter->sge;
1629 struct port_info *pi;
1623 1630
1624 /* 1631 /*
1625 * If this is a good TCP packet and we have Generic Receive Offload 1632 * 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,
1644 __skb_pull(skb, s->pktshift); 1651 __skb_pull(skb, s->pktshift);
1645 skb->protocol = eth_type_trans(skb, rspq->netdev); 1652 skb->protocol = eth_type_trans(skb, rspq->netdev);
1646 skb_record_rx_queue(skb, rspq->idx); 1653 skb_record_rx_queue(skb, rspq->idx);
1654 pi = netdev_priv(skb->dev);
1647 rxq->stats.pkts++; 1655 rxq->stats.pkts++;
1648 1656
1649 if (csum_ok && !pkt->err_vec && 1657 if (csum_ok && !pkt->err_vec &&
@@ -1660,9 +1668,10 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp,
1660 } else 1668 } else
1661 skb_checksum_none_assert(skb); 1669 skb_checksum_none_assert(skb);
1662 1670
1663 if (pkt->vlan_ex) { 1671 if (pkt->vlan_ex && !pi->vlan_id) {
1664 rxq->stats.vlan_ex++; 1672 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));
1666 } 1675 }
1667 1676
1668 netif_receive_skb(skb); 1677 netif_receive_skb(skb);
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
index 9cf9c56b0f73..712e8f0c71b4 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
@@ -413,5 +413,6 @@ int t4vf_handle_fw_rpl(struct adapter *, const __be64 *);
413int t4vf_prep_adapter(struct adapter *); 413int t4vf_prep_adapter(struct adapter *);
414int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf, 414int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf,
415 unsigned int *naddr, u8 *addr); 415 unsigned int *naddr, u8 *addr);
416int t4vf_get_vf_vlan_acl(struct adapter *adapter);
416 417
417#endif /* __T4VF_COMMON_H__ */ 418#endif /* __T4VF_COMMON_H__ */
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
index 67aec59a14e6..798695bf8678 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
@@ -2147,3 +2147,31 @@ int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf,
2147 2147
2148 return ret; 2148 return ret;
2149} 2149}
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 */
2159int 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}