aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-12-02 15:58:51 -0500
committerDavid S. Miller <davem@davemloft.net>2015-12-02 15:58:51 -0500
commit9f7aec5f563f6e82efa96342547a5285f751106b (patch)
tree96c41f3f33164d7591aafb330b9cb2001786ad60
parent83e4bf7a7486532df2dc3db27e0e07a250990ed2 (diff)
parentbc69fdfc6c13b7350be9bcb48328d8f231ed98bb (diff)
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>
-rw-r--r--drivers/net/ethernet/cavium/thunder/nic.h5
-rw-r--r--drivers/net/ethernet/cavium/thunder/nic_main.c23
-rw-r--r--drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c16
-rw-r--r--drivers/net/ethernet/cavium/thunder/nicvf_main.c4
-rw-r--r--drivers/net/ethernet/cavium/thunder/nicvf_queues.c2
-rw-r--r--drivers/net/ethernet/cavium/thunder/nicvf_queues.h2
-rw-r--r--drivers/net/ethernet/cavium/thunder/thunder_bgx.c28
-rw-r--r--drivers/net/ethernet/cavium/thunder/thunder_bgx.h2
8 files changed, 66 insertions, 16 deletions
diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
index d3950b20feb9..39ca6744a4e6 100644
--- a/drivers/net/ethernet/cavium/thunder/nic.h
+++ b/drivers/net/ethernet/cavium/thunder/nic.h
@@ -120,10 +120,9 @@
120 * Calculated for SCLK of 700Mhz 120 * Calculated for SCLK of 700Mhz
121 * value written should be a 1/16th of what is expected 121 * value written should be a 1/16th of what is expected
122 * 122 *
123 * 1 tick per 0.05usec = value of 2.2 123 * 1 tick per 0.025usec
124 * This 10% would be covered in CQ timer thresh value
125 */ 124 */
126#define NICPF_CLK_PER_INT_TICK 2 125#define NICPF_CLK_PER_INT_TICK 1
127 126
128/* Time to wait before we decide that a SQ is stuck. 127/* Time to wait before we decide that a SQ is stuck.
129 * 128 *
diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c b/drivers/net/ethernet/cavium/thunder/nic_main.c
index c561fdcb79a7..4b7fd63ae57c 100644
--- a/drivers/net/ethernet/cavium/thunder/nic_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nic_main.c
@@ -37,6 +37,7 @@ struct nicpf {
37#define NIC_GET_BGX_FROM_VF_LMAC_MAP(map) ((map >> 4) & 0xF) 37#define NIC_GET_BGX_FROM_VF_LMAC_MAP(map) ((map >> 4) & 0xF)
38#define NIC_GET_LMAC_FROM_VF_LMAC_MAP(map) (map & 0xF) 38#define NIC_GET_LMAC_FROM_VF_LMAC_MAP(map) (map & 0xF)
39 u8 vf_lmac_map[MAX_LMAC]; 39 u8 vf_lmac_map[MAX_LMAC];
40 u8 lmac_cnt;
40 struct delayed_work dwork; 41 struct delayed_work dwork;
41 struct workqueue_struct *check_link; 42 struct workqueue_struct *check_link;
42 u8 link[MAX_LMAC]; 43 u8 link[MAX_LMAC];
@@ -279,6 +280,7 @@ static void nic_set_lmac_vf_mapping(struct nicpf *nic)
279 u64 lmac_credit; 280 u64 lmac_credit;
280 281
281 nic->num_vf_en = 0; 282 nic->num_vf_en = 0;
283 nic->lmac_cnt = 0;
282 284
283 for (bgx = 0; bgx < NIC_MAX_BGX; bgx++) { 285 for (bgx = 0; bgx < NIC_MAX_BGX; bgx++) {
284 if (!(bgx_map & (1 << bgx))) 286 if (!(bgx_map & (1 << bgx)))
@@ -288,6 +290,7 @@ static void nic_set_lmac_vf_mapping(struct nicpf *nic)
288 nic->vf_lmac_map[next_bgx_lmac++] = 290 nic->vf_lmac_map[next_bgx_lmac++] =
289 NIC_SET_VF_LMAC_MAP(bgx, lmac); 291 NIC_SET_VF_LMAC_MAP(bgx, lmac);
290 nic->num_vf_en += lmac_cnt; 292 nic->num_vf_en += lmac_cnt;
293 nic->lmac_cnt += lmac_cnt;
291 294
292 /* Program LMAC credits */ 295 /* Program LMAC credits */
293 lmac_credit = (1ull << 1); /* channel credit enable */ 296 lmac_credit = (1ull << 1); /* channel credit enable */
@@ -715,6 +718,13 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
715 case NIC_MBOX_MSG_CFG_DONE: 718 case NIC_MBOX_MSG_CFG_DONE:
716 /* Last message of VF config msg sequence */ 719 /* Last message of VF config msg sequence */
717 nic->vf_enabled[vf] = true; 720 nic->vf_enabled[vf] = true;
721 if (vf >= nic->lmac_cnt)
722 goto unlock;
723
724 bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
725 lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
726
727 bgx_lmac_rx_tx_enable(nic->node, bgx, lmac, true);
718 goto unlock; 728 goto unlock;
719 case NIC_MBOX_MSG_SHUTDOWN: 729 case NIC_MBOX_MSG_SHUTDOWN:
720 /* First msg in VF teardown sequence */ 730 /* First msg in VF teardown sequence */
@@ -722,6 +732,14 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
722 if (vf >= nic->num_vf_en) 732 if (vf >= nic->num_vf_en)
723 nic->sqs_used[vf - nic->num_vf_en] = false; 733 nic->sqs_used[vf - nic->num_vf_en] = false;
724 nic->pqs_vf[vf] = 0; 734 nic->pqs_vf[vf] = 0;
735
736 if (vf >= nic->lmac_cnt)
737 break;
738
739 bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
740 lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
741
742 bgx_lmac_rx_tx_enable(nic->node, bgx, lmac, false);
725 break; 743 break;
726 case NIC_MBOX_MSG_ALLOC_SQS: 744 case NIC_MBOX_MSG_ALLOC_SQS:
727 nic_alloc_sqs(nic, &mbx.sqs_alloc); 745 nic_alloc_sqs(nic, &mbx.sqs_alloc);
@@ -940,7 +958,7 @@ static void nic_poll_for_link(struct work_struct *work)
940 958
941 mbx.link_status.msg = NIC_MBOX_MSG_BGX_LINK_CHANGE; 959 mbx.link_status.msg = NIC_MBOX_MSG_BGX_LINK_CHANGE;
942 960
943 for (vf = 0; vf < nic->num_vf_en; vf++) { 961 for (vf = 0; vf < nic->lmac_cnt; vf++) {
944 /* Poll only if VF is UP */ 962 /* Poll only if VF is UP */
945 if (!nic->vf_enabled[vf]) 963 if (!nic->vf_enabled[vf])
946 continue; 964 continue;
@@ -1074,8 +1092,7 @@ static void nic_remove(struct pci_dev *pdev)
1074 1092
1075 if (nic->check_link) { 1093 if (nic->check_link) {
1076 /* Destroy work Queue */ 1094 /* Destroy work Queue */
1077 cancel_delayed_work(&nic->dwork); 1095 cancel_delayed_work_sync(&nic->dwork);
1078 flush_workqueue(nic->check_link);
1079 destroy_workqueue(nic->check_link); 1096 destroy_workqueue(nic->check_link);
1080 } 1097 }
1081 1098
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
index af54c10945c2..a12b2e38cf61 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
@@ -112,6 +112,13 @@ static int nicvf_get_settings(struct net_device *netdev,
112 112
113 cmd->supported = 0; 113 cmd->supported = 0;
114 cmd->transceiver = XCVR_EXTERNAL; 114 cmd->transceiver = XCVR_EXTERNAL;
115
116 if (!nic->link_up) {
117 cmd->duplex = DUPLEX_UNKNOWN;
118 ethtool_cmd_speed_set(cmd, SPEED_UNKNOWN);
119 return 0;
120 }
121
115 if (nic->speed <= 1000) { 122 if (nic->speed <= 1000) {
116 cmd->port = PORT_MII; 123 cmd->port = PORT_MII;
117 cmd->autoneg = AUTONEG_ENABLE; 124 cmd->autoneg = AUTONEG_ENABLE;
@@ -125,6 +132,13 @@ static int nicvf_get_settings(struct net_device *netdev,
125 return 0; 132 return 0;
126} 133}
127 134
135static u32 nicvf_get_link(struct net_device *netdev)
136{
137 struct nicvf *nic = netdev_priv(netdev);
138
139 return nic->link_up;
140}
141
128static void nicvf_get_drvinfo(struct net_device *netdev, 142static void nicvf_get_drvinfo(struct net_device *netdev,
129 struct ethtool_drvinfo *info) 143 struct ethtool_drvinfo *info)
130{ 144{
@@ -660,7 +674,7 @@ static int nicvf_set_channels(struct net_device *dev,
660 674
661static const struct ethtool_ops nicvf_ethtool_ops = { 675static const struct ethtool_ops nicvf_ethtool_ops = {
662 .get_settings = nicvf_get_settings, 676 .get_settings = nicvf_get_settings,
663 .get_link = ethtool_op_get_link, 677 .get_link = nicvf_get_link,
664 .get_drvinfo = nicvf_get_drvinfo, 678 .get_drvinfo = nicvf_get_drvinfo,
665 .get_msglevel = nicvf_get_msglevel, 679 .get_msglevel = nicvf_get_msglevel,
666 .set_msglevel = nicvf_set_msglevel, 680 .set_msglevel = nicvf_set_msglevel,
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index 7f709cbdcd87..dde8dc720cd3 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -1057,6 +1057,7 @@ int nicvf_stop(struct net_device *netdev)
1057 1057
1058 netif_carrier_off(netdev); 1058 netif_carrier_off(netdev);
1059 netif_tx_stop_all_queues(nic->netdev); 1059 netif_tx_stop_all_queues(nic->netdev);
1060 nic->link_up = false;
1060 1061
1061 /* Teardown secondary qsets first */ 1062 /* Teardown secondary qsets first */
1062 if (!nic->sqs_mode) { 1063 if (!nic->sqs_mode) {
@@ -1211,9 +1212,6 @@ int nicvf_open(struct net_device *netdev)
1211 nic->drv_stats.txq_stop = 0; 1212 nic->drv_stats.txq_stop = 0;
1212 nic->drv_stats.txq_wake = 0; 1213 nic->drv_stats.txq_wake = 0;
1213 1214
1214 netif_carrier_on(netdev);
1215 netif_tx_start_all_queues(netdev);
1216
1217 return 0; 1215 return 0;
1218cleanup: 1216cleanup:
1219 nicvf_disable_intr(nic, NICVF_INTR_MBOX, 0); 1217 nicvf_disable_intr(nic, NICVF_INTR_MBOX, 0);
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
index e404ea837727..206b6a71a545 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
@@ -592,7 +592,7 @@ void nicvf_cmp_queue_config(struct nicvf *nic, struct queue_set *qs,
592 /* Set threshold value for interrupt generation */ 592 /* Set threshold value for interrupt generation */
593 nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_THRESH, qidx, cq->thresh); 593 nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_THRESH, qidx, cq->thresh);
594 nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG2, 594 nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG2,
595 qidx, nic->cq_coalesce_usecs); 595 qidx, CMP_QUEUE_TIMER_THRESH);
596} 596}
597 597
598/* Configures transmit queue */ 598/* Configures transmit queue */
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
index fb4957d09914..033e8306e91c 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.h
@@ -76,7 +76,7 @@
76#define CMP_QSIZE CMP_QUEUE_SIZE2 76#define CMP_QSIZE CMP_QUEUE_SIZE2
77#define CMP_QUEUE_LEN (1ULL << (CMP_QSIZE + 10)) 77#define CMP_QUEUE_LEN (1ULL << (CMP_QSIZE + 10))
78#define CMP_QUEUE_CQE_THRESH 0 78#define CMP_QUEUE_CQE_THRESH 0
79#define CMP_QUEUE_TIMER_THRESH 220 /* 10usec */ 79#define CMP_QUEUE_TIMER_THRESH 80 /* ~2usec */
80 80
81#define RBDR_SIZE RBDR_SIZE0 81#define RBDR_SIZE RBDR_SIZE0
82#define RCV_BUF_COUNT (1ULL << (RBDR_SIZE + 13)) 82#define RCV_BUF_COUNT (1ULL << (RBDR_SIZE + 13))
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index 180aa9fabf48..9df26c2263bc 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -186,6 +186,23 @@ void bgx_set_lmac_mac(int node, int bgx_idx, int lmacid, const u8 *mac)
186} 186}
187EXPORT_SYMBOL(bgx_set_lmac_mac); 187EXPORT_SYMBOL(bgx_set_lmac_mac);
188 188
189void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable)
190{
191 struct bgx *bgx = bgx_vnic[(node * MAX_BGX_PER_CN88XX) + bgx_idx];
192 u64 cfg;
193
194 if (!bgx)
195 return;
196
197 cfg = bgx_reg_read(bgx, lmacid, BGX_CMRX_CFG);
198 if (enable)
199 cfg |= CMR_PKT_RX_EN | CMR_PKT_TX_EN;
200 else
201 cfg &= ~(CMR_PKT_RX_EN | CMR_PKT_TX_EN);
202 bgx_reg_write(bgx, lmacid, BGX_CMRX_CFG, cfg);
203}
204EXPORT_SYMBOL(bgx_lmac_rx_tx_enable);
205
189static void bgx_sgmii_change_link_state(struct lmac *lmac) 206static void bgx_sgmii_change_link_state(struct lmac *lmac)
190{ 207{
191 struct bgx *bgx = lmac->bgx; 208 struct bgx *bgx = lmac->bgx;
@@ -612,6 +629,8 @@ static void bgx_poll_for_link(struct work_struct *work)
612 lmac->last_duplex = 1; 629 lmac->last_duplex = 1;
613 } else { 630 } else {
614 lmac->link_up = 0; 631 lmac->link_up = 0;
632 lmac->last_speed = SPEED_UNKNOWN;
633 lmac->last_duplex = DUPLEX_UNKNOWN;
615 } 634 }
616 635
617 if (lmac->last_link != lmac->link_up) { 636 if (lmac->last_link != lmac->link_up) {
@@ -654,8 +673,7 @@ static int bgx_lmac_enable(struct bgx *bgx, u8 lmacid)
654 } 673 }
655 674
656 /* Enable lmac */ 675 /* Enable lmac */
657 bgx_reg_modify(bgx, lmacid, BGX_CMRX_CFG, 676 bgx_reg_modify(bgx, lmacid, BGX_CMRX_CFG, CMR_EN);
658 CMR_EN | CMR_PKT_RX_EN | CMR_PKT_TX_EN);
659 677
660 /* Restore default cfg, incase low level firmware changed it */ 678 /* Restore default cfg, incase low level firmware changed it */
661 bgx_reg_write(bgx, lmacid, BGX_CMRX_RX_DMAC_CTL, 0x03); 679 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)
695 lmac = &bgx->lmac[lmacid]; 713 lmac = &bgx->lmac[lmacid];
696 if (lmac->check_link) { 714 if (lmac->check_link) {
697 /* Destroy work queue */ 715 /* Destroy work queue */
698 cancel_delayed_work(&lmac->dwork); 716 cancel_delayed_work_sync(&lmac->dwork);
699 flush_workqueue(lmac->check_link);
700 destroy_workqueue(lmac->check_link); 717 destroy_workqueue(lmac->check_link);
701 } 718 }
702 719
@@ -1009,6 +1026,9 @@ static int bgx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1009 struct bgx *bgx = NULL; 1026 struct bgx *bgx = NULL;
1010 u8 lmac; 1027 u8 lmac;
1011 1028
1029 /* Load octeon mdio driver */
1030 octeon_mdiobus_force_mod_depencency();
1031
1012 bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL); 1032 bgx = devm_kzalloc(dev, sizeof(*bgx), GFP_KERNEL);
1013 if (!bgx) 1033 if (!bgx)
1014 return -ENOMEM; 1034 return -ENOMEM;
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
index 07b7ec66c60d..149e179363a1 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
@@ -182,6 +182,8 @@ enum MCAST_MODE {
182#define BCAST_ACCEPT 1 182#define BCAST_ACCEPT 1
183#define CAM_ACCEPT 1 183#define CAM_ACCEPT 1
184 184
185void octeon_mdiobus_force_mod_depencency(void);
186void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable);
185void bgx_add_dmac_addr(u64 dmac, int node, int bgx_idx, int lmac); 187void bgx_add_dmac_addr(u64 dmac, int node, int bgx_idx, int lmac);
186unsigned bgx_get_map(int node); 188unsigned bgx_get_map(int node);
187int bgx_get_lmac_count(int node, int bgx); 189int bgx_get_lmac_count(int node, int bgx);