diff options
author | Anish Bhatt <anish@chelsio.com> | 2015-01-30 20:20:17 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-02-02 21:54:35 -0500 |
commit | ba0c39cb98a1eec3635ae5f959fef963738d12a5 (patch) | |
tree | 43754a78e09e563bd1a42be444e2d2206c2b751d /drivers/net/ethernet | |
parent | 98830dd0fed031264b9d6ccb85b582506da95886 (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.c | 98 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/cxgb4_dcb.h | 11 |
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 | ||
906 | static 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 | |||
961 | static 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 */ | ||
967 | static 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 | |||
983 | static 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 | ||
1114 | const struct dcbnl_rtnl_ops cxgb4_dcb_ops = { | 1204 | const 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 *); | |||
136 | void cxgb4_dcb_set_caps(struct adapter *, const struct fw_port_cmd *); | 136 | void cxgb4_dcb_set_caps(struct adapter *, const struct fw_port_cmd *); |
137 | extern const struct dcbnl_rtnl_ops cxgb4_dcb_ops; | 137 | extern const struct dcbnl_rtnl_ops cxgb4_dcb_ops; |
138 | 138 | ||
139 | static 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 */ |