diff options
author | David S. Miller <davem@davemloft.net> | 2015-12-02 15:58:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-12-02 15:58:51 -0500 |
commit | 9f7aec5f563f6e82efa96342547a5285f751106b (patch) | |
tree | 96c41f3f33164d7591aafb330b9cb2001786ad60 | |
parent | 83e4bf7a7486532df2dc3db27e0e07a250990ed2 (diff) | |
parent | bc69fdfc6c13b7350be9bcb48328d8f231ed98bb (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.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/thunder/nic_main.c | 23 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/thunder/nicvf_main.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/thunder/nicvf_queues.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/thunder/nicvf_queues.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/thunder/thunder_bgx.c | 28 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/thunder/thunder_bgx.h | 2 |
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 | ||
135 | static u32 nicvf_get_link(struct net_device *netdev) | ||
136 | { | ||
137 | struct nicvf *nic = netdev_priv(netdev); | ||
138 | |||
139 | return nic->link_up; | ||
140 | } | ||
141 | |||
128 | static void nicvf_get_drvinfo(struct net_device *netdev, | 142 | static 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 | ||
661 | static const struct ethtool_ops nicvf_ethtool_ops = { | 675 | static 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; |
1218 | cleanup: | 1216 | cleanup: |
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 | } |
187 | EXPORT_SYMBOL(bgx_set_lmac_mac); | 187 | EXPORT_SYMBOL(bgx_set_lmac_mac); |
188 | 188 | ||
189 | void 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 | } | ||
204 | EXPORT_SYMBOL(bgx_lmac_rx_tx_enable); | ||
205 | |||
189 | static void bgx_sgmii_change_link_state(struct lmac *lmac) | 206 | static 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 | ||
185 | void octeon_mdiobus_force_mod_depencency(void); | ||
186 | void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable); | ||
185 | void bgx_add_dmac_addr(u64 dmac, int node, int bgx_idx, int lmac); | 187 | void bgx_add_dmac_addr(u64 dmac, int node, int bgx_idx, int lmac); |
186 | unsigned bgx_get_map(int node); | 188 | unsigned bgx_get_map(int node); |
187 | int bgx_get_lmac_count(int node, int bgx); | 189 | int bgx_get_lmac_count(int node, int bgx); |