Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153407248
D12599.id34305.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D12599.id34305.diff
View Options
Index: head/sys/dev/bnxt/bnxt.h
===================================================================
--- head/sys/dev/bnxt/bnxt.h
+++ head/sys/dev/bnxt/bnxt.h
@@ -211,6 +211,10 @@
#define BNXT_HWRM_LOCK_DESTROY(_softc) mtx_destroy(&(_softc)->hwrm_lock)
#define BNXT_HWRM_LOCK_ASSERT(_softc) mtx_assert(&(_softc)->hwrm_lock, \
MA_OWNED)
+#define BNXT_IS_FLOW_CTRL_CHANGED(link_info) \
+ ((link_info->last_flow_ctrl.tx != link_info->flow_ctrl.tx) || \
+ (link_info->last_flow_ctrl.rx != link_info->flow_ctrl.rx) || \
+ (link_info->last_flow_ctrl.autoneg != link_info->flow_ctrl.autoneg))
/* Chip info */
#define BNXT_TSO_SIZE UINT16_MAX
@@ -288,6 +292,12 @@
int rid;
};
+struct bnxt_flow_ctrl {
+ bool rx;
+ bool tx;
+ bool autoneg;
+};
+
struct bnxt_link_info {
uint8_t media_type;
uint8_t transceiver;
@@ -299,10 +309,8 @@
uint8_t last_link_up;
uint8_t duplex;
uint8_t last_duplex;
- uint8_t pause;
- uint8_t last_pause;
- uint8_t auto_pause;
- uint8_t force_pause;
+ struct bnxt_flow_ctrl flow_ctrl;
+ struct bnxt_flow_ctrl last_flow_ctrl;
uint8_t duplex_setting;
uint8_t auto_mode;
#define PHY_VER_LEN 3
@@ -320,7 +328,6 @@
#define BNXT_AUTONEG_SPEED 1
#define BNXT_AUTONEG_FLOW_CTRL 2
uint8_t req_duplex;
- uint8_t req_flow_ctrl;
uint16_t req_link_speed;
};
@@ -596,6 +603,8 @@
struct sysctl_oid *hw_stats_oid;
struct sysctl_ctx_list hw_lro_ctx;
struct sysctl_oid *hw_lro_oid;
+ struct sysctl_ctx_list flow_ctrl_ctx;
+ struct sysctl_oid *flow_ctrl_oid;
struct bnxt_ver_info *ver_info;
struct bnxt_nvram_info *nvm_info;
Index: head/sys/dev/bnxt/bnxt_hwrm.h
===================================================================
--- head/sys/dev/bnxt/bnxt_hwrm.h
+++ head/sys/dev/bnxt/bnxt_hwrm.h
@@ -32,6 +32,11 @@
#ifndef _BNXT_HWRM_H
#define _BNXT_HWRM_H
+#define BNXT_PAUSE_TX (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX)
+#define BNXT_PAUSE_RX (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)
+#define BNXT_AUTO_PAUSE_AUTONEG_PAUSE \
+ (HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_AUTONEG_PAUSE)
+
/* HWRM Function Prototypes */
int bnxt_alloc_hwrm_dma_mem(struct bnxt_softc *softc);
void bnxt_free_hwrm_dma_mem(struct bnxt_softc *softc);
@@ -45,8 +50,8 @@
int bnxt_hwrm_func_qcaps(struct bnxt_softc *softc);
int bnxt_hwrm_func_qcfg(struct bnxt_softc *softc);
int bnxt_hwrm_func_reset(struct bnxt_softc *softc);
-int bnxt_hwrm_set_link_setting(struct bnxt_softc *, bool set_pause,
- bool set_eee);
+int bnxt_hwrm_set_link_setting(struct bnxt_softc *softc, bool set_pause,
+ bool set_eee, bool set_link);
int bnxt_hwrm_set_pause(struct bnxt_softc *softc);
int bnxt_hwrm_vnic_ctx_alloc(struct bnxt_softc *softc, uint16_t *ctx_id);
int bnxt_hwrm_vnic_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic);
Index: head/sys/dev/bnxt/bnxt_hwrm.c
===================================================================
--- head/sys/dev/bnxt/bnxt_hwrm.c
+++ head/sys/dev/bnxt/bnxt_hwrm.c
@@ -503,33 +503,28 @@
bnxt_hwrm_set_pause_common(struct bnxt_softc *softc,
struct hwrm_port_phy_cfg_input *req)
{
- if (softc->link_info.autoneg & BNXT_AUTONEG_FLOW_CTRL) {
+ struct bnxt_link_info *link_info = &softc->link_info;
+
+ if (link_info->flow_ctrl.autoneg) {
req->auto_pause =
HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_AUTONEG_PAUSE;
- if (softc->link_info.req_flow_ctrl &
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)
+ if (link_info->flow_ctrl.rx)
req->auto_pause |=
HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX;
- if (softc->link_info.req_flow_ctrl &
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX)
+ if (link_info->flow_ctrl.tx)
req->auto_pause |=
- HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX;
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX;
req->enables |=
htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE);
} else {
- if (softc->link_info.req_flow_ctrl &
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)
+ if (link_info->flow_ctrl.rx)
req->force_pause |=
HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX;
- if (softc->link_info.req_flow_ctrl &
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX)
+ if (link_info->flow_ctrl.tx)
req->force_pause |=
HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX;
req->enables |=
htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE);
- req->auto_pause = req->force_pause;
- req->enables |= htole32(
- HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE);
}
}
@@ -563,49 +558,41 @@
int
bnxt_hwrm_set_link_setting(struct bnxt_softc *softc, bool set_pause,
- bool set_eee)
+ bool set_eee, bool set_link)
{
struct hwrm_port_phy_cfg_input req = {0};
+ int rc;
if (softc->flags & BNXT_FLAG_NPAR)
return ENOTSUP;
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_CFG);
- if (set_pause)
+
+ if (set_pause) {
bnxt_hwrm_set_pause_common(softc, &req);
- bnxt_hwrm_set_link_common(softc, &req);
- if (set_eee)
- bnxt_hwrm_set_eee(softc, &req);
- return hwrm_send_message(softc, &req, sizeof(req));
-}
+ if (softc->link_info.flow_ctrl.autoneg)
+ set_link = true;
+ }
-
-int
-bnxt_hwrm_set_pause(struct bnxt_softc *softc)
-{
- struct hwrm_port_phy_cfg_input req = {0};
- int rc;
-
- if (softc->flags & BNXT_FLAG_NPAR)
- return ENOTSUP;
-
- bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_CFG);
- bnxt_hwrm_set_pause_common(softc, &req);
-
- if (softc->link_info.autoneg & BNXT_AUTONEG_FLOW_CTRL)
+ if (set_link)
bnxt_hwrm_set_link_common(softc, &req);
-
+
+ if (set_eee)
+ bnxt_hwrm_set_eee(softc, &req);
+
BNXT_HWRM_LOCK(softc);
rc = _hwrm_send_message(softc, &req, sizeof(req));
- if (!rc && !(softc->link_info.autoneg & BNXT_AUTONEG_FLOW_CTRL)) {
- /* since changing of pause setting doesn't trigger any link
- * change event, the driver needs to update the current pause
- * result upon successfully return of the phy_cfg command */
- softc->link_info.pause =
- softc->link_info.force_pause = softc->link_info.req_flow_ctrl;
- softc->link_info.auto_pause = 0;
- bnxt_report_link(softc);
+
+ if (!rc) {
+ if (set_pause) {
+ /* since changing of 'force pause' setting doesn't
+ * trigger any link change event, the driver needs to
+ * update the current pause result upon successfully i
+ * return of the phy_cfg command */
+ if (!softc->link_info.flow_ctrl.autoneg)
+ bnxt_report_link(softc);
+ }
}
BNXT_HWRM_UNLOCK(softc);
return rc;
@@ -1536,10 +1523,43 @@
link_info->phy_link_status = resp->link;
link_info->duplex = resp->duplex_cfg;
- link_info->pause = resp->pause;
link_info->auto_mode = resp->auto_mode;
- link_info->auto_pause = resp->auto_pause;
- link_info->force_pause = resp->force_pause;
+
+ /*
+ * When AUTO_PAUSE_AUTONEG_PAUSE bit is set to 1,
+ * the advertisement of pause is enabled.
+ * 1. When the auto_mode is not set to none and this flag is set to 1,
+ * then the auto_pause bits on this port are being advertised and
+ * autoneg pause results are being interpreted.
+ * 2. When the auto_mode is not set to none and this flag is set to 0,
+ * the pause is forced as indicated in force_pause, and also
+ * advertised as auto_pause bits, but the autoneg results are not
+ * interpreted since the pause configuration is being forced.
+ * 3. When the auto_mode is set to none and this flag is set to 1,
+ * auto_pause bits should be ignored and should be set to 0.
+ */
+
+ link_info->flow_ctrl.autoneg = false;
+ link_info->flow_ctrl.tx = false;
+ link_info->flow_ctrl.rx = false;
+
+ if ((resp->auto_mode) &&
+ (resp->auto_pause & BNXT_AUTO_PAUSE_AUTONEG_PAUSE)) {
+ link_info->flow_ctrl.autoneg = true;
+ }
+
+ if (link_info->flow_ctrl.autoneg) {
+ if (resp->auto_pause & BNXT_PAUSE_TX)
+ link_info->flow_ctrl.tx = true;
+ if (resp->auto_pause & BNXT_PAUSE_RX)
+ link_info->flow_ctrl.rx = true;
+ } else {
+ if (resp->force_pause & BNXT_PAUSE_TX)
+ link_info->flow_ctrl.tx = true;
+ if (resp->force_pause & BNXT_PAUSE_RX)
+ link_info->flow_ctrl.rx = true;
+ }
+
link_info->duplex_setting = resp->duplex_cfg;
if (link_info->phy_link_status == HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK)
link_info->link_speed = le16toh(resp->link_speed);
Index: head/sys/dev/bnxt/bnxt_sysctl.h
===================================================================
--- head/sys/dev/bnxt/bnxt_sysctl.h
+++ head/sys/dev/bnxt/bnxt_sysctl.h
@@ -41,3 +41,4 @@
int bnxt_create_config_sysctls_pre(struct bnxt_softc *softc);
int bnxt_create_config_sysctls_post(struct bnxt_softc *softc);
int bnxt_create_hw_lro_sysctls(struct bnxt_softc *softc);
+int bnxt_create_pause_fc_sysctls(struct bnxt_softc *softc);
Index: head/sys/dev/bnxt/bnxt_sysctl.c
===================================================================
--- head/sys/dev/bnxt/bnxt_sysctl.c
+++ head/sys/dev/bnxt/bnxt_sysctl.c
@@ -94,6 +94,16 @@
return ENOMEM;
}
+ sysctl_ctx_init(&softc->flow_ctrl_ctx);
+ ctx = device_get_sysctl_ctx(softc->dev);
+ softc->flow_ctrl_oid = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(device_get_sysctl_tree(softc->dev)), OID_AUTO,
+ "fc", CTLFLAG_RD, 0, "flow ctrl");
+ if (!softc->flow_ctrl_oid) {
+ sysctl_ctx_free(&softc->flow_ctrl_ctx);
+ return ENOMEM;
+ }
+
return 0;
}
@@ -132,6 +142,14 @@
softc->hw_lro_oid = NULL;
}
+ if (softc->flow_ctrl_oid != NULL) {
+ orc = sysctl_ctx_free(&softc->flow_ctrl_ctx);
+ if (orc)
+ rc = orc;
+ else
+ softc->flow_ctrl_oid = NULL;
+ }
+
return rc;
}
@@ -1257,6 +1275,62 @@
BNXT_HW_LRO_FN(bnxt_hw_lro_set_max_agg_segs, max_agg_segs)
BNXT_HW_LRO_FN(bnxt_hw_lro_set_max_aggs, max_aggs)
BNXT_HW_LRO_FN(bnxt_hw_lro_set_min_agg_len, min_agg_len)
+
+#define BNXT_FLOW_CTRL_FN(fn_name, arg) \
+static int \
+fn_name(SYSCTL_HANDLER_ARGS) { \
+ struct bnxt_softc *softc = arg1; \
+ int rc; \
+ int val; \
+ \
+ if (softc == NULL) \
+ return EBUSY; \
+ \
+ val = softc->link_info.flow_ctrl.arg; \
+ rc = sysctl_handle_int(oidp, &val, 0, req); \
+ if (rc || !req->newptr) \
+ return rc; \
+ \
+ if (val) \
+ val = 1; \
+ \
+ if (softc->link_info.flow_ctrl.arg != val) { \
+ softc->link_info.flow_ctrl.arg = val; \
+ rc = bnxt_hwrm_set_link_setting(softc, true, false, false);\
+ rc = bnxt_hwrm_port_phy_qcfg(softc); \
+ } \
+ \
+ return rc; \
+}
+
+BNXT_FLOW_CTRL_FN(bnxt_flow_ctrl_tx, tx)
+BNXT_FLOW_CTRL_FN(bnxt_flow_ctrl_rx, rx)
+BNXT_FLOW_CTRL_FN(bnxt_flow_ctrl_autoneg, autoneg)
+int
+bnxt_create_pause_fc_sysctls(struct bnxt_softc *softc)
+{
+ struct sysctl_oid *oid = softc->flow_ctrl_oid;
+
+ if (!oid)
+ return ENOMEM;
+
+ SYSCTL_ADD_PROC(&softc->flow_ctrl_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+ "tx", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0,
+ bnxt_flow_ctrl_tx, "A",
+ "Enable or Disable Tx Flow Ctrl: 0 / 1");
+
+ SYSCTL_ADD_PROC(&softc->flow_ctrl_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+ "rx", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0,
+ bnxt_flow_ctrl_rx, "A",
+ "Enable or Disable Tx Flow Ctrl: 0 / 1");
+
+ SYSCTL_ADD_PROC(&softc->flow_ctrl_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+ "autoneg", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0,
+ bnxt_flow_ctrl_autoneg, "A",
+ "Enable or Disable Autoneg Flow Ctrl: 0 / 1");
+
+ return 0;
+}
int
bnxt_create_hw_lro_sysctls(struct bnxt_softc *softc)
Index: head/sys/dev/bnxt/if_bnxt.c
===================================================================
--- head/sys/dev/bnxt/if_bnxt.c
+++ head/sys/dev/bnxt/if_bnxt.c
@@ -878,6 +878,10 @@
if (rc)
goto failed;
+ rc = bnxt_create_pause_fc_sysctls(softc);
+ if (rc)
+ goto failed;
+
/* Initialize the vlan list */
SLIST_INIT(&softc->vnic_info.vlan_tags);
softc->vnic_info.vlan_tag_list.idi_vaddr = NULL;
@@ -1377,13 +1381,10 @@
return;
}
- if (link_info->pause == (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX |
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX))
- ifmr->ifm_active |= (IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE);
- else if (link_info->pause == HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX)
- ifmr->ifm_active |= IFM_ETH_TXPAUSE;
- else if (link_info->pause == HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)
+ if (link_info->flow_ctrl.rx)
ifmr->ifm_active |= IFM_ETH_RXPAUSE;
+ if (link_info->flow_ctrl.tx)
+ ifmr->ifm_active |= IFM_ETH_TXPAUSE;
bnxt_report_link(softc);
return;
@@ -1471,7 +1472,7 @@
softc->link_info.autoneg |= BNXT_AUTONEG_SPEED;
break;
}
- rc = bnxt_hwrm_set_link_setting(softc, true, true);
+ rc = bnxt_hwrm_set_link_setting(softc, true, true, true);
bnxt_media_status(softc->ctx, &ifmr);
return rc;
}
@@ -2096,18 +2097,6 @@
if (link_info->auto_mode != HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE)
link_info->autoneg |= BNXT_AUTONEG_SPEED;
- if (link_info->auto_pause & (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX |
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)) {
- if (link_info->auto_pause == (
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX |
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX))
- link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL;
- link_info->req_flow_ctrl = link_info->auto_pause;
- } else if (link_info->force_pause & (
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX |
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)) {
- link_info->req_flow_ctrl = link_info->force_pause;
- }
link_info->req_duplex = link_info->duplex_setting;
if (link_info->autoneg & BNXT_AUTONEG_SPEED)
link_info->req_link_speed = link_info->auto_link_speed;
@@ -2352,47 +2341,46 @@
void
bnxt_report_link(struct bnxt_softc *softc)
{
+ struct bnxt_link_info *link_info = &softc->link_info;
const char *duplex = NULL, *flow_ctrl = NULL;
- if (softc->link_info.link_up == softc->link_info.last_link_up) {
- if (!softc->link_info.link_up)
+ if (link_info->link_up == link_info->last_link_up) {
+ if (!link_info->link_up)
return;
- if (softc->link_info.pause == softc->link_info.last_pause &&
- softc->link_info.duplex == softc->link_info.last_duplex)
+ if ((link_info->duplex == link_info->last_duplex) &&
+ (!(BNXT_IS_FLOW_CTRL_CHANGED(link_info))))
return;
}
- if (softc->link_info.link_up) {
- if (softc->link_info.duplex ==
+ if (link_info->link_up) {
+ if (link_info->duplex ==
HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_CFG_FULL)
duplex = "full duplex";
else
duplex = "half duplex";
- if (softc->link_info.pause == (
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX |
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX))
+ if (link_info->flow_ctrl.tx & link_info->flow_ctrl.rx)
flow_ctrl = "FC - receive & transmit";
- else if (softc->link_info.pause ==
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX)
+ else if (link_info->flow_ctrl.tx)
flow_ctrl = "FC - transmit";
- else if (softc->link_info.pause ==
- HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX)
+ else if (link_info->flow_ctrl.rx)
flow_ctrl = "FC - receive";
else
flow_ctrl = "FC - none";
iflib_link_state_change(softc->ctx, LINK_STATE_UP,
IF_Gbps(100));
device_printf(softc->dev, "Link is UP %s, %s - %d Mbps \n", duplex,
- flow_ctrl, (softc->link_info.link_speed * 100));
+ flow_ctrl, (link_info->link_speed * 100));
} else {
iflib_link_state_change(softc->ctx, LINK_STATE_DOWN,
bnxt_get_baudrate(&softc->link_info));
device_printf(softc->dev, "Link is Down\n");
}
- softc->link_info.last_link_up = softc->link_info.link_up;
- softc->link_info.last_pause = softc->link_info.pause;
- softc->link_info.last_duplex = softc->link_info.duplex;
+ link_info->last_link_up = link_info->link_up;
+ link_info->last_duplex = link_info->duplex;
+ link_info->last_flow_ctrl.tx = link_info->flow_ctrl.tx;
+ link_info->last_flow_ctrl.rx = link_info->flow_ctrl.rx;
+ link_info->last_flow_ctrl.autoneg = link_info->flow_ctrl.autoneg;
}
static int
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 22, 12:09 AM (10 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31925478
Default Alt Text
D12599.id34305.diff (15 KB)
Attached To
Mode
D12599: bnxt: Add support for Flow control setting using sysctl
Attached
Detach File
Event Timeline
Log In to Comment