aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorAnish Bhatt <anish@chelsio.com>2015-01-30 20:20:17 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-02 21:54:35 -0500
commitba0c39cb98a1eec3635ae5f959fef963738d12a5 (patch)
tree43754a78e09e563bd1a42be444e2d2206c2b751d /drivers/net/ethernet
parent98830dd0fed031264b9d6ccb85b582506da95886 (diff)
cxgb4 : Improve IEEE DCBx support, other minor open-lldp fixes
* Add support for IEEE ets & pfc api. * Fix bug that resulted in incorrect bandwidth percentage being returned for CEE peers * Convert pfc enabled info from firmware format to what dcbnl expects before returning Signed-off-by: Anish Bhatt <anish@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c98
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h11
2 files changed, 107 insertions, 2 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
index a35d1ec6950e..b65a5bda3195 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.c
@@ -428,7 +428,10 @@ static void cxgb4_getpgtccfg(struct net_device *dev, int tc,
428 } 428 }
429 *pgid = (be32_to_cpu(pcmd.u.dcb.pgid.pgid) >> (tc * 4)) & 0xf; 429 *pgid = (be32_to_cpu(pcmd.u.dcb.pgid.pgid) >> (tc * 4)) & 0xf;
430 430
431 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id); 431 if (local)
432 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
433 else
434 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
432 pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE; 435 pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
433 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd); 436 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
434 if (err != FW_PORT_DCB_CFG_SUCCESS) { 437 if (err != FW_PORT_DCB_CFG_SUCCESS) {
@@ -900,6 +903,88 @@ cxgb4_ieee_negotiation_complete(struct net_device *dev,
900 (dcb->supported & DCB_CAP_DCBX_VER_IEEE)); 903 (dcb->supported & DCB_CAP_DCBX_VER_IEEE));
901} 904}
902 905
906static int cxgb4_ieee_read_ets(struct net_device *dev, struct ieee_ets *ets,
907 int local)
908{
909 struct port_info *pi = netdev2pinfo(dev);
910 struct port_dcb_info *dcb = &pi->dcb;
911 struct adapter *adap = pi->adapter;
912 uint32_t tc_info;
913 struct fw_port_cmd pcmd;
914 int i, bwg, err;
915
916 if (!(dcb->msgs & (CXGB4_DCB_FW_PGID | CXGB4_DCB_FW_PGRATE)))
917 return 0;
918
919 ets->ets_cap = dcb->pg_num_tcs_supported;
920
921 if (local) {
922 ets->willing = 1;
923 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
924 } else {
925 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
926 }
927
928 pcmd.u.dcb.pgid.type = FW_PORT_DCB_TYPE_PGID;
929 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
930 if (err != FW_PORT_DCB_CFG_SUCCESS) {
931 dev_err(adap->pdev_dev, "DCB read PGID failed with %d\n", -err);
932 return err;
933 }
934
935 tc_info = be32_to_cpu(pcmd.u.dcb.pgid.pgid);
936
937 if (local)
938 INIT_PORT_DCB_READ_LOCAL_CMD(pcmd, pi->port_id);
939 else
940 INIT_PORT_DCB_READ_PEER_CMD(pcmd, pi->port_id);
941
942 pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
943 err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
944 if (err != FW_PORT_DCB_CFG_SUCCESS) {
945 dev_err(adap->pdev_dev, "DCB read PGRATE failed with %d\n",
946 -err);
947 return err;
948 }
949
950 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
951 bwg = (tc_info >> ((7 - i) * 4)) & 0xF;
952 ets->prio_tc[i] = bwg;
953 ets->tc_tx_bw[i] = pcmd.u.dcb.pgrate.pgrate[i];
954 ets->tc_rx_bw[i] = ets->tc_tx_bw[i];
955 ets->tc_tsa[i] = pcmd.u.dcb.pgrate.tsa[i];
956 }
957
958 return 0;
959}
960
961static int cxgb4_ieee_get_ets(struct net_device *dev, struct ieee_ets *ets)
962{
963 return cxgb4_ieee_read_ets(dev, ets, 1);
964}
965
966/* We reuse this for peer PFC as well, as we can't have it enabled one way */
967static int cxgb4_ieee_get_pfc(struct net_device *dev, struct ieee_pfc *pfc)
968{
969 struct port_info *pi = netdev2pinfo(dev);
970 struct port_dcb_info *dcb = &pi->dcb;
971
972 memset(pfc, 0, sizeof(struct ieee_pfc));
973
974 if (!(dcb->msgs & CXGB4_DCB_FW_PFC))
975 return 0;
976
977 pfc->pfc_cap = dcb->pfc_num_tcs_supported;
978 pfc->pfc_en = bitswap_1(dcb->pfcen);
979
980 return 0;
981}
982
983static int cxgb4_ieee_peer_ets(struct net_device *dev, struct ieee_ets *ets)
984{
985 return cxgb4_ieee_read_ets(dev, ets, 0);
986}
987
903/* Fill in the Application User Priority Map associated with the 988/* Fill in the Application User Priority Map associated with the
904 * specified Application. 989 * specified Application.
905 * Priority for IEEE dcb_app is an integer, with 0 being a valid value 990 * Priority for IEEE dcb_app is an integer, with 0 being a valid value
@@ -1106,14 +1191,23 @@ static int cxgb4_cee_peer_getpfc(struct net_device *dev, struct cee_pfc *pfc)
1106 struct port_info *pi = netdev2pinfo(dev); 1191 struct port_info *pi = netdev2pinfo(dev);
1107 1192
1108 cxgb4_getnumtcs(dev, DCB_NUMTCS_ATTR_PFC, &(pfc->tcs_supported)); 1193 cxgb4_getnumtcs(dev, DCB_NUMTCS_ATTR_PFC, &(pfc->tcs_supported));
1109 pfc->pfc_en = pi->dcb.pfcen; 1194
1195 /* Firmware sends this to us in a formwat that is a bit flipped version
1196 * of spec, correct it before we send it to host. This is taken care of
1197 * by bit shifting in other uses of pfcen
1198 */
1199 pfc->pfc_en = bitswap_1(pi->dcb.pfcen);
1110 1200
1111 return 0; 1201 return 0;
1112} 1202}
1113 1203
1114const struct dcbnl_rtnl_ops cxgb4_dcb_ops = { 1204const struct dcbnl_rtnl_ops cxgb4_dcb_ops = {
1205 .ieee_getets = cxgb4_ieee_get_ets,
1206 .ieee_getpfc = cxgb4_ieee_get_pfc,
1115 .ieee_getapp = cxgb4_ieee_getapp, 1207 .ieee_getapp = cxgb4_ieee_getapp,
1116 .ieee_setapp = cxgb4_ieee_setapp, 1208 .ieee_setapp = cxgb4_ieee_setapp,
1209 .ieee_peer_getets = cxgb4_ieee_peer_ets,
1210 .ieee_peer_getpfc = cxgb4_ieee_get_pfc,
1117 1211
1118 /* CEE std */ 1212 /* CEE std */
1119 .getstate = cxgb4_getstate, 1213 .getstate = cxgb4_getstate,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h
index 31ce425616c9..ccf24d3dc982 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h
@@ -136,6 +136,17 @@ void cxgb4_dcb_handle_fw_update(struct adapter *, const struct fw_port_cmd *);
136void cxgb4_dcb_set_caps(struct adapter *, const struct fw_port_cmd *); 136void cxgb4_dcb_set_caps(struct adapter *, const struct fw_port_cmd *);
137extern const struct dcbnl_rtnl_ops cxgb4_dcb_ops; 137extern const struct dcbnl_rtnl_ops cxgb4_dcb_ops;
138 138
139static inline __u8 bitswap_1(unsigned char val)
140{
141 return ((val & 0x80) >> 7) |
142 ((val & 0x40) >> 5) |
143 ((val & 0x20) >> 3) |
144 ((val & 0x10) >> 1) |
145 ((val & 0x08) << 1) |
146 ((val & 0x04) << 3) |
147 ((val & 0x02) << 5) |
148 ((val & 0x01) << 7);
149}
139#define CXGB4_DCB_ENABLED true 150#define CXGB4_DCB_ENABLED true
140 151
141#else /* !CONFIG_CHELSIO_T4_DCB */ 152#else /* !CONFIG_CHELSIO_T4_DCB */