Merge branch 'thunderx-fixes'
Sunil Goutham says: ==================== thunderx: miscellaneous fixes This patch series contains fixes for various issues observed with BGX and NIC drivers. Changes from v1: - Fixed comment syle in the first patch of the series - Removed 'Increase transmit queue length' patch from the series, will recheck if it's a driver or system issue and resubmit. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
9f7aec5f56
8 changed files with 66 additions and 16 deletions
|
@ -120,10 +120,9 @@
|
||||||
* Calculated for SCLK of 700Mhz
|
* Calculated for SCLK of 700Mhz
|
||||||
* value written should be a 1/16th of what is expected
|
* value written should be a 1/16th of what is expected
|
||||||
*
|
*
|
||||||
* 1 tick per 0.05usec = value of 2.2
|
* 1 tick per 0.025usec
|
||||||
* This 10% would be covered in CQ timer thresh value
|
|
||||||
*/
|
*/
|
||||||
#define NICPF_CLK_PER_INT_TICK 2
|
#define NICPF_CLK_PER_INT_TICK 1
|
||||||
|
|
||||||
/* Time to wait before we decide that a SQ is stuck.
|
/* Time to wait before we decide that a SQ is stuck.
|
||||||
*
|
*
|
||||||
|
|
|
@ -37,6 +37,7 @@ struct nicpf {
|
||||||
#define NIC_GET_BGX_FROM_VF_LMAC_MAP(map) ((map >> 4) & 0xF)
|
#define NIC_GET_BGX_FROM_VF_LMAC_MAP(map) ((map >> 4) & 0xF)
|
||||||
#define NIC_GET_LMAC_FROM_VF_LMAC_MAP(map) (map & 0xF)
|
#define NIC_GET_LMAC_FROM_VF_LMAC_MAP(map) (map & 0xF)
|
||||||
u8 vf_lmac_map[MAX_LMAC];
|
u8 vf_lmac_map[MAX_LMAC];
|
||||||
|
u8 lmac_cnt;
|
||||||
struct delayed_work dwork;
|
struct delayed_work dwork;
|
||||||
struct workqueue_struct *check_link;
|
struct workqueue_struct *check_link;
|
||||||
u8 link[MAX_LMAC];
|
u8 link[MAX_LMAC];
|
||||||
|
@ -279,6 +280,7 @@ static void nic_set_lmac_vf_mapping(struct nicpf *nic)
|
||||||
u64 lmac_credit;
|
u64 lmac_credit;
|
||||||
|
|
||||||
nic->num_vf_en = 0;
|
nic->num_vf_en = 0;
|
||||||
|
nic->lmac_cnt = 0;
|
||||||
|
|
||||||
for (bgx = 0; bgx < NIC_MAX_BGX; bgx++) {
|
for (bgx = 0; bgx < NIC_MAX_BGX; bgx++) {
|
||||||
if (!(bgx_map & (1 << bgx)))
|
if (!(bgx_map & (1 << bgx)))
|
||||||
|
@ -288,6 +290,7 @@ static void nic_set_lmac_vf_mapping(struct nicpf *nic)
|
||||||
nic->vf_lmac_map[next_bgx_lmac++] =
|
nic->vf_lmac_map[next_bgx_lmac++] =
|
||||||
NIC_SET_VF_LMAC_MAP(bgx, lmac);
|
NIC_SET_VF_LMAC_MAP(bgx, lmac);
|
||||||
nic->num_vf_en += lmac_cnt;
|
nic->num_vf_en += lmac_cnt;
|
||||||
|
nic->lmac_cnt += lmac_cnt;
|
||||||
|
|
||||||
/* Program LMAC credits */
|
/* Program LMAC credits */
|
||||||
lmac_credit = (1ull << 1); /* channel credit enable */
|
lmac_credit = (1ull << 1); /* channel credit enable */
|
||||||
|
@ -715,6 +718,13 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
|
||||||
case NIC_MBOX_MSG_CFG_DONE:
|
case NIC_MBOX_MSG_CFG_DONE:
|
||||||
/* Last message of VF config msg sequence */
|
/* Last message of VF config msg sequence */
|
||||||
nic->vf_enabled[vf] = true;
|
nic->vf_enabled[vf] = true;
|
||||||
|
if (vf >= nic->lmac_cnt)
|
||||||
|
goto unlock;
|
||||||
|
|
||||||
|
bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
|
||||||
|
lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
|
||||||
|
|
||||||
|
bgx_lmac_rx_tx_enable(nic->node, bgx, lmac, true);
|
||||||
goto unlock;
|
goto unlock;
|
||||||
case NIC_MBOX_MSG_SHUTDOWN:
|
case NIC_MBOX_MSG_SHUTDOWN:
|
||||||
/* First msg in VF teardown sequence */
|
/* First msg in VF teardown sequence */
|
||||||
|
@ -722,6 +732,14 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
|
||||||
if (vf >= nic->num_vf_en)
|
if (vf >= nic->num_vf_en)
|
||||||
nic->sqs_used[vf - nic->num_vf_en] = false;
|
nic->sqs_used[vf - nic->num_vf_en] = false;
|
||||||
nic->pqs_vf[vf] = 0;
|
nic->pqs_vf[vf] = 0;
|
||||||
|
|
||||||
|
if (vf >= nic->lmac_cnt)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
|
||||||
|
lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
|
||||||
|
|
||||||
|
bgx_lmac_rx_tx_enable(nic->node, bgx, lmac, false);
|
||||||
break;
|
break;
|
||||||
case NIC_MBOX_MSG_ALLOC_SQS:
|
case NIC_MBOX_MSG_ALLOC_SQS:
|
||||||
nic_alloc_sqs(nic, &mbx.sqs_alloc);
|
nic_alloc_sqs(nic, &mbx.sqs_alloc);
|
||||||
|
@ -940,7 +958,7 @@ static void nic_poll_for_link(struct work_struct *work)
|
||||||
|
|
||||||
mbx.link_status.msg = NIC_MBOX_MSG_BGX_LINK_CHANGE;
|
mbx.link_status.msg = NIC_MBOX_MSG_BGX_LINK_CHANGE;
|
||||||
|
|
||||||
for (vf = 0; vf < nic->num_vf_en; vf++) {
|
for (vf = 0; vf < nic->lmac_cnt; vf++) {
|
||||||
/* Poll only if VF is UP */
|
/* Poll only if VF is UP */
|
||||||
if (!nic->vf_enabled[vf])
|
if (!nic->vf_enabled[vf])
|
||||||
continue;
|
continue;
|
||||||
|
@ -1074,8 +1092,7 @@ static void nic_remove(struct pci_dev *pdev)
|
||||||
|
|
||||||
if (nic->check_link) {
|
if (nic->check_link) {
|
||||||
/* Destroy work Queue */
|
/* Destroy work Queue */
|
||||||
cancel_delayed_work(&nic->dwork);
|
cancel_delayed_work_sync(&nic->dwork);
|
||||||
flush_workqueue(nic->check_link);
|
|
||||||
destroy_workqueue(nic->check_link);
|
destroy_workqueue(nic->check_link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,13 @@ static int nicvf_get_settings(struct net_device *netdev,
|
||||||
|
|
||||||
cmd->supported = 0;
|
cmd->supported = 0;
|
||||||
cmd->transceiver = XCVR_EXTERNAL;
|
cmd->transceiver = XCVR_EXTERNAL;
|
||||||
|
|
||||||
|
if (!nic->link_up) {
|
||||||
|
cmd->duplex = DUPLEX_UNKNOWN;
|
||||||
|
ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (nic->speed <= 1000) {
|
if (nic->speed <= 1000) {
|
||||||
cmd->port = PORT_MII;
|
cmd->port = PORT_MII;
|
||||||
cmd->autoneg = AUTONEG_ENABLE;
|
cmd->autoneg = AUTONEG_ENABLE;
|
||||||
|
@ -125,6 +132,13 @@ static int nicvf_get_settings(struct net_device *netdev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 nicvf_get_link(struct net_device *netdev)
|
||||||
|
{
|
||||||
|
struct nicvf *nic = netdev_priv(netdev);
|
||||||
|
|
||||||
|
return nic->link_up;
|
||||||
|
}
|
||||||
|
|
||||||
static void nicvf_get_drvinfo(struct net_device *netdev,
|
static void nicvf_get_drvinfo(struct net_device *netdev,
|
||||||
struct ethtool_drvinfo *info)
|
struct ethtool_drvinfo *info)
|
||||||
{
|
{
|
||||||
|
@ -660,7 +674,7 @@ static int nicvf_set_channels(struct net_device *dev,
|
||||||
|
|
||||||
static const struct ethtool_ops nicvf_ethtool_ops = {
|
static const struct ethtool_ops nicvf_ethtool_ops = {
|
||||||
.get_settings = nicvf_get_settings,
|
.get_settings = nicvf_get_settings,
|
||||||
.get_link = ethtool_op_get_link,
|
.get_link = nicvf_get_link,
|
||||||
.get_drvinfo = nicvf_get_drvinfo,
|
.get_drvinfo = nicvf_get_drvinfo,
|
||||||
.get_msglevel = nicvf_get_msglevel,
|
.get_msglevel = nicvf_get_msglevel,
|
||||||
.set_msglevel = nicvf_set_msglevel,
|
.set_msglevel = nicvf_set_msglevel,
|
||||||
|
|
|
@ -1057,6 +1057,7 @@ int nicvf_stop(struct net_device *netdev)
|
||||||
|
|
||||||
netif_carrier_off(netdev);
|
netif_carrier_off(netdev);
|
||||||
netif_tx_stop_all_queues(nic->netdev);
|
netif_tx_stop_all_queues(nic->netdev);
|
||||||
|
nic->link_up = false;
|
||||||
|
|
||||||
/* Teardown secondary qsets first */
|
/* Teardown secondary qsets first */
|
||||||
if (!nic->sqs_mode) {
|
if (!nic->sqs_mode) {
|
||||||
|
@ -1211,9 +1212,6 @@ int nicvf_open(struct net_device *netdev)
|
||||||
nic->drv_stats.txq_stop = 0;
|
nic->drv_stats.txq_stop = 0;
|
||||||
nic->drv_stats.txq_wake = 0;
|
nic->drv_stats.txq_wake = 0;
|
||||||
|
|
||||||
netif_carrier_on(netdev);
|
|
||||||
netif_tx_start_all_queues(netdev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
nicvf_disable_intr(nic, NICVF_INTR_MBOX, 0);
|
nicvf_disable_intr(nic, NICVF_INTR_MBOX, 0);
|
||||||
|
|
|
@ -592,7 +592,7 @@ void nicvf_cmp_queue_config(struct nicvf *nic, struct queue_set *qs,
|
||||||
/* Set threshold value for interrupt generation */
|
/* Set threshold value for interrupt generation */
|
||||||
nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_THRESH, qidx, cq->thresh);
|
nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_THRESH, qidx, cq->thresh);
|
||||||
nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG2,
|
nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG2,
|
||||||
qidx, nic->cq_coalesce_usecs);
|
qidx, CMP_QUEUE_TIMER_THRESH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configures transmit queue */
|
/* Configures transmit queue */
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
#define CMP_QSIZE CMP_QUEUE_SIZE2
|
#define CMP_QSIZE CMP_QUEUE_SIZE2
|
||||||
#define CMP_QUEUE_LEN (1ULL << (CMP_QSIZE + 10))
|
#define CMP_QUEUE_LEN (1ULL << (CMP_QSIZE + 10))
|
||||||
#define CMP_QUEUE_CQE_THRESH 0
|
#define CMP_QUEUE_CQE_THRESH 0
|
||||||
#define CMP_QUEUE_TIMER_THRESH 220 /* 10usec */
|
#define CMP_QUEUE_TIMER_THRESH 80 /* ~2usec */
|
||||||
|
|
||||||
#define RBDR_SIZE RBDR_SIZE0
|
#define RBDR_SIZE RBDR_SIZE0
|
||||||
#define RCV_BUF_COUNT (1ULL << (RBDR_SIZE + 13))
|
#define RCV_BUF_COUNT (1ULL << (RBDR_SIZE + 13))
|
||||||
|
|
|
@ -186,6 +186,23 @@ void bgx_set_lmac_mac(int node, int bgx_idx, int lmacid, const u8 *mac)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(bgx_set_lmac_mac);
|
EXPORT_SYMBOL(bgx_set_lmac_mac);
|
||||||
|
|
||||||
|
void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable)
|
||||||
|
{
|
||||||
|
struct bgx *bgx = bgx_vnic[(node * MAX_BGX_PER_CN88XX) + bgx_idx];
|
||||||
|
u64 cfg;
|
||||||
|
|
||||||
|
if (!bgx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG);
|
||||||
|
if (enable)
|
||||||
|
cfg |= CMR_PKT_RX_EN | CMR_PKT_TX_EN;
|
||||||
|
else
|
||||||
|
cfg &= ~(CMR_PKT_RX_EN | CMR_PKT_TX_EN);
|
||||||
|
bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cfg);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(bgx_lmac_rx_tx_enable);
|
||||||
|
|
||||||
static void bgx_sgmii_change_link_state(struct lmac *lmac)
|
static void bgx_sgmii_change_link_state(struct lmac *lmac)
|
||||||
{
|
{
|
||||||
struct bgx *bgx = lmac->bgx;
|
struct bgx *bgx = lmac->bgx;
|
||||||
|
@ -612,6 +629,8 @@ static void bgx_poll_for_link(struct work_struct *work)
|
||||||
lmac->last_duplex = 1;
|
lmac->last_duplex = 1;
|
||||||
} else {
|
} else {
|
||||||
lmac->link_up = 0;
|
lmac->link_up = 0;
|
||||||
|
lmac->last_speed = SPEED_UNKNOWN;
|
||||||
|
lmac->last_duplex = DUPLEX_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lmac->last_link != lmac->link_up) {
|
if (lmac->last_link != lmac->link_up) {
|
||||||
|
@ -654,8 +673,7 @@ static int bgx_lmac_enable(struct bgx *bgx, u8 lmacid)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable lmac */
|
/* Enable lmac */
|
||||||
bgx_reg_modify(bgx, lmacid, BGX_CMRX_CFG,
|
bgx_reg_modify(bgx, lmacid, BGX_CMRX_CFG, CMR_EN);
|
||||||
CMR_EN | CMR_PKT_RX_EN | CMR_PKT_TX_EN);
|
|
||||||
|
|
||||||
/* Restore default cfg, incase low level firmware changed it */
|
/* Restore default cfg, incase low level firmware changed it */
|
||||||
bgx_reg_write(bgx, lmacid, BGX_CMRX_RX_DMAC_CTL, 0x03);
|
bgx_reg_write(bgx, lmacid, BGX_CMRX_RX_DMAC_CTL, 0x03);
|
||||||
|
@ -695,8 +713,7 @@ static void bgx_lmac_disable(struct bgx *bgx, u8 lmacid)
|
||||||
lmac = &bgx->lmac[lmacid];
|
lmac = &bgx->lmac[lmacid];
|
||||||
if (lmac->check_link) {
|
if (lmac->check_link) {
|
||||||
/* Destroy work queue */
|
/* Destroy work queue */
|
||||||
cancel_delayed_work(&lmac->dwork);
|
cancel_delayed_work_sync(&lmac->dwork);
|
||||||
flush_workqueue(lmac->check_link);
|
|
||||||
destroy_workqueue(lmac->check_link);
|
destroy_workqueue(lmac->check_link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1009,6 +1026,9 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
struct bgx *bgx = NULL;
|
struct bgx *bgx = NULL;
|
||||||
u8 lmac;
|
u8 lmac;
|
||||||
|
|
||||||
|
/* Load octeon mdio driver */
|
||||||
|
octeon_mdiobus_force_mod_depencency();
|
||||||
|
|
||||||
bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL);
|
bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL);
|
||||||
if (!bgx)
|
if (!bgx)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
@ -182,6 +182,8 @@ enum MCAST_MODE {
|
||||||
#define BCAST_ACCEPT 1
|
#define BCAST_ACCEPT 1
|
||||||
#define CAM_ACCEPT 1
|
#define CAM_ACCEPT 1
|
||||||
|
|
||||||
|
void octeon_mdiobus_force_mod_depencency(void);
|
||||||
|
void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable);
|
||||||
void bgx_add_dmac_addr(u64 dmac, int node, int bgx_idx, int lmac);
|
void bgx_add_dmac_addr(u64 dmac, int node, int bgx_idx, int lmac);
|
||||||
unsigned bgx_get_map(int node);
|
unsigned bgx_get_map(int node);
|
||||||
int bgx_get_lmac_count(int node, int bgx);
|
int bgx_get_lmac_count(int node, int bgx);
|
||||||
|
|
Loading…
Add table
Reference in a new issue