Skip to content

Commit ba0c39c

Browse files
anishdavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 98830dd commit ba0c39c

File tree

2 files changed

+107
-2
lines changed

2 files changed

+107
-2
lines changed

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

Lines changed: 96 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,10 @@ static void cxgb4_getpgtccfg(struct net_device *dev, int tc,
428428
}
429429
*pgid = (be32_to_cpu(pcmd.u.dcb.pgid.pgid) >> (tc * 4)) & 0xf;
430430

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);
432435
pcmd.u.dcb.pgrate.type = FW_PORT_DCB_TYPE_PGRATE;
433436
err = t4_wr_mbox(adap, adap->mbox, &pcmd, sizeof(pcmd), &pcmd);
434437
if (err != FW_PORT_DCB_CFG_SUCCESS) {
@@ -900,6 +903,88 @@ cxgb4_ieee_negotiation_complete(struct net_device *dev,
900903
(dcb->supported & DCB_CAP_DCBX_VER_IEEE));
901904
}
902905

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+
903988
/* Fill in the Application User Priority Map associated with the
904989
* specified Application.
905990
* 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)
11061191
struct port_info *pi = netdev2pinfo(dev);
11071192

11081193
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);
11101200

11111201
return 0;
11121202
}
11131203

11141204
const struct dcbnl_rtnl_ops cxgb4_dcb_ops = {
1205+
.ieee_getets = cxgb4_ieee_get_ets,
1206+
.ieee_getpfc = cxgb4_ieee_get_pfc,
11151207
.ieee_getapp = cxgb4_ieee_getapp,
11161208
.ieee_setapp = cxgb4_ieee_setapp,
1209+
.ieee_peer_getets = cxgb4_ieee_peer_ets,
1210+
.ieee_peer_getpfc = cxgb4_ieee_get_pfc,
11171211

11181212
/* CEE std */
11191213
.getstate = cxgb4_getstate,

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,17 @@ void cxgb4_dcb_handle_fw_update(struct adapter *, const struct fw_port_cmd *);
136136
void cxgb4_dcb_set_caps(struct adapter *, const struct fw_port_cmd *);
137137
extern const struct dcbnl_rtnl_ops cxgb4_dcb_ops;
138138

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+
}
139150
#define CXGB4_DCB_ENABLED true
140151

141152
#else /* !CONFIG_CHELSIO_T4_DCB */

0 commit comments

Comments
 (0)