Skip to content

Commit 7605583

Browse files
stefanchulskidavem330
authored andcommitted
net: mvpp2: add ethtool flow control configuration support
This patch add ethtool flow control configuration support. Tx flow control retrieved correctly by ethtool get function. FW per port ethtool configuration capability added. Patch also takes care about mtu change procedure, if PPv2 switch BM pools during mtu change. Signed-off-by: Stefan Chulski <[email protected]> Acked-by: Marcin Wojtas <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 3bd17fd commit 7605583

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

drivers/net/ethernet/marvell/mvpp2/mvpp2.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,19 @@
774774
#define MSS_RXQ_TRESH_REG(q, fq) (MSS_RXQ_TRESH_BASE + (((q) + (fq)) \
775775
* MSS_RXQ_TRESH_OFFS))
776776

777+
#define MSS_BUF_POOL_BASE 0x40
778+
#define MSS_BUF_POOL_OFFS 4
779+
#define MSS_BUF_POOL_REG(id) (MSS_BUF_POOL_BASE \
780+
+ (id) * MSS_BUF_POOL_OFFS)
781+
782+
#define MSS_BUF_POOL_STOP_MASK 0xFFF
783+
#define MSS_BUF_POOL_START_MASK (0xFFF << MSS_BUF_POOL_START_OFFS)
784+
#define MSS_BUF_POOL_START_OFFS 12
785+
#define MSS_BUF_POOL_PORTS_MASK (0xF << MSS_BUF_POOL_PORTS_OFFS)
786+
#define MSS_BUF_POOL_PORTS_OFFS 24
787+
#define MSS_BUF_POOL_PORT_OFFS(id) (0x1 << \
788+
((id) + MSS_BUF_POOL_PORTS_OFFS))
789+
777790
#define MSS_RXQ_TRESH_START_MASK 0xFFFF
778791
#define MSS_RXQ_TRESH_STOP_MASK (0xFFFF << MSS_RXQ_TRESH_STOP_OFFS)
779792
#define MSS_RXQ_TRESH_STOP_OFFS 16

drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,59 @@ static void mvpp2_rxq_disable_fc(struct mvpp2_port *port)
845845
spin_unlock_irqrestore(&port->priv->mss_spinlock, flags);
846846
}
847847

848+
/* Routine disable/enable flow control for BM pool condition */
849+
static void mvpp2_bm_pool_update_fc(struct mvpp2_port *port,
850+
struct mvpp2_bm_pool *pool,
851+
bool en)
852+
{
853+
int val, cm3_state;
854+
unsigned long flags;
855+
856+
spin_lock_irqsave(&port->priv->mss_spinlock, flags);
857+
858+
/* Remove Flow control enable bit to prevent race between FW and Kernel
859+
* If Flow control were enabled, it would be re-enabled.
860+
*/
861+
val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
862+
cm3_state = (val & FLOW_CONTROL_ENABLE_BIT);
863+
val &= ~FLOW_CONTROL_ENABLE_BIT;
864+
mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);
865+
866+
/* Check if BM pool should be enabled/disable */
867+
if (en) {
868+
/* Set BM pool start and stop thresholds per port */
869+
val = mvpp2_cm3_read(port->priv, MSS_BUF_POOL_REG(pool->id));
870+
val |= MSS_BUF_POOL_PORT_OFFS(port->id);
871+
val &= ~MSS_BUF_POOL_START_MASK;
872+
val |= (MSS_THRESHOLD_START << MSS_BUF_POOL_START_OFFS);
873+
val &= ~MSS_BUF_POOL_STOP_MASK;
874+
val |= MSS_THRESHOLD_STOP;
875+
mvpp2_cm3_write(port->priv, MSS_BUF_POOL_REG(pool->id), val);
876+
} else {
877+
/* Remove BM pool from the port */
878+
val = mvpp2_cm3_read(port->priv, MSS_BUF_POOL_REG(pool->id));
879+
val &= ~MSS_BUF_POOL_PORT_OFFS(port->id);
880+
881+
/* Zero BM pool start and stop thresholds to disable pool
882+
* flow control if pool empty (not used by any port)
883+
*/
884+
if (!pool->buf_num) {
885+
val &= ~MSS_BUF_POOL_START_MASK;
886+
val &= ~MSS_BUF_POOL_STOP_MASK;
887+
}
888+
889+
mvpp2_cm3_write(port->priv, MSS_BUF_POOL_REG(pool->id), val);
890+
}
891+
892+
/* Notify Firmware that Flow control config space ready for update */
893+
val = mvpp2_cm3_read(port->priv, MSS_FC_COM_REG);
894+
val |= FLOW_CONTROL_UPDATE_COMMAND_BIT;
895+
val |= cm3_state;
896+
mvpp2_cm3_write(port->priv, MSS_FC_COM_REG, val);
897+
898+
spin_unlock_irqrestore(&port->priv->mss_spinlock, flags);
899+
}
900+
848901
/* Release buffer to BM */
849902
static inline void mvpp2_bm_pool_put(struct mvpp2_port *port, int pool,
850903
dma_addr_t buf_dma_addr,
@@ -1175,6 +1228,16 @@ static int mvpp2_bm_update_mtu(struct net_device *dev, int mtu)
11751228
new_long_pool = MVPP2_BM_LONG;
11761229

11771230
if (new_long_pool != port->pool_long->id) {
1231+
if (port->tx_fc) {
1232+
if (pkt_size > MVPP2_BM_LONG_PKT_SIZE)
1233+
mvpp2_bm_pool_update_fc(port,
1234+
port->pool_short,
1235+
false);
1236+
else
1237+
mvpp2_bm_pool_update_fc(port, port->pool_long,
1238+
false);
1239+
}
1240+
11781241
/* Remove port from old short & long pool */
11791242
port->pool_long = mvpp2_bm_pool_use(port, port->pool_long->id,
11801243
port->pool_long->pkt_size);
@@ -1192,6 +1255,25 @@ static int mvpp2_bm_update_mtu(struct net_device *dev, int mtu)
11921255
mvpp2_swf_bm_pool_init(port);
11931256

11941257
mvpp2_set_hw_csum(port, new_long_pool);
1258+
1259+
if (port->tx_fc) {
1260+
if (pkt_size > MVPP2_BM_LONG_PKT_SIZE)
1261+
mvpp2_bm_pool_update_fc(port, port->pool_long,
1262+
true);
1263+
else
1264+
mvpp2_bm_pool_update_fc(port, port->pool_short,
1265+
true);
1266+
}
1267+
1268+
/* Update L4 checksum when jumbo enable/disable on port */
1269+
if (new_long_pool == MVPP2_BM_JUMBO && port->id != 0) {
1270+
dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
1271+
dev->hw_features &= ~(NETIF_F_IP_CSUM |
1272+
NETIF_F_IPV6_CSUM);
1273+
} else {
1274+
dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
1275+
dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
1276+
}
11951277
}
11961278

11971279
out_set:
@@ -6365,6 +6447,7 @@ static void mvpp2_mac_link_up(struct phylink_config *config,
63656447
{
63666448
struct mvpp2_port *port = mvpp2_phylink_to_port(config);
63676449
u32 val;
6450+
int i;
63686451

63696452
if (mvpp2_is_xlg(interface)) {
63706453
if (!phylink_autoneg_inband(mode)) {
@@ -6415,6 +6498,21 @@ static void mvpp2_mac_link_up(struct phylink_config *config,
64156498
val);
64166499
}
64176500

6501+
if (port->priv->global_tx_fc) {
6502+
port->tx_fc = tx_pause;
6503+
if (tx_pause)
6504+
mvpp2_rxq_enable_fc(port);
6505+
else
6506+
mvpp2_rxq_disable_fc(port);
6507+
if (port->priv->percpu_pools) {
6508+
for (i = 0; i < port->nrxqs; i++)
6509+
mvpp2_bm_pool_update_fc(port, &port->priv->bm_pools[i], tx_pause);
6510+
} else {
6511+
mvpp2_bm_pool_update_fc(port, port->pool_long, tx_pause);
6512+
mvpp2_bm_pool_update_fc(port, port->pool_short, tx_pause);
6513+
}
6514+
}
6515+
64186516
mvpp2_port_enable(port);
64196517

64206518
mvpp2_egress_enable(port);

0 commit comments

Comments
 (0)