diff options
author | Ganesh Goudar <ganeshgr@chelsio.com> | 2018-01-24 10:14:07 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-24 10:48:25 -0500 |
commit | 9d5fd927d20b38d9785f510b93b3f0f8e19aba5f (patch) | |
tree | f76e3012dd0c0fdd0eb8852c85451287795f0eab | |
parent | 43df215d99e6049d4680309c54232689e16ddd6b (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.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 26 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 32 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 15 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 28 |
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 | ||
825 | struct mbox_list { | 826 | struct mbox_list { |
@@ -1738,4 +1739,6 @@ void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, struct sge_fl *fl); | |||
1738 | void free_tx_desc(struct adapter *adap, struct sge_txq *q, | 1739 | void free_tx_desc(struct adapter *adap, struct sge_txq *q, |
1739 | unsigned int n, bool unmap); | 1740 | unsigned int n, bool unmap); |
1740 | void free_txq(struct adapter *adap, struct sge_txq *q); | 1741 | 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); | ||
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 | 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 */ | ||
2787 | 2810 | ||
2788 | static int cxgb_set_mac_addr(struct net_device *dev, void *p) | 2811 | static 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 | */ | ||
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 | } | ||
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) */ |
2366 | enum fw_port_cap { | 2374 | enum 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 | */ |
93 | struct port_info { | 93 | struct 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 *); | |||
413 | int t4vf_prep_adapter(struct adapter *); | 413 | int t4vf_prep_adapter(struct adapter *); |
414 | int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf, | 414 | int t4vf_get_vf_mac_acl(struct adapter *adapter, unsigned int pf, |
415 | unsigned int *naddr, u8 *addr); | 415 | unsigned int *naddr, u8 *addr); |
416 | int 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 | */ | ||
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 | } | ||