forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-11 04dd17822334871b23ea2862f7798fb0e0007777
kernel/drivers/net/ethernet/qlogic/qed/qed_ll2.c
....@@ -1,33 +1,7 @@
1
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
12 /* QLogic qed NIC Driver
23 * Copyright (c) 2015-2017 QLogic Corporation
3
- *
4
- * This software is available to you under a choice of one of two
5
- * licenses. You may choose to be licensed under the terms of the GNU
6
- * General Public License (GPL) Version 2, available from the file
7
- * COPYING in the main directory of this source tree, or the
8
- * OpenIB.org BSD license below:
9
- *
10
- * Redistribution and use in source and binary forms, with or
11
- * without modification, are permitted provided that the following
12
- * conditions are met:
13
- *
14
- * - Redistributions of source code must retain the above
15
- * copyright notice, this list of conditions and the following
16
- * disclaimer.
17
- *
18
- * - Redistributions in binary form must reproduce the above
19
- * copyright notice, this list of conditions and the following
20
- * disclaimer in the documentation and /or other materials
21
- * provided with the distribution.
22
- *
23
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
- * SOFTWARE.
4
+ * Copyright (c) 2019-2020 Marvell International Ltd.
315 */
326
337 #include <linux/types.h>
....@@ -63,8 +37,8 @@
6337 #include "qed_sp.h"
6438 #include "qed_rdma.h"
6539
66
-#define QED_LL2_RX_REGISTERED(ll2) ((ll2)->rx_queue.b_cb_registred)
67
-#define QED_LL2_TX_REGISTERED(ll2) ((ll2)->tx_queue.b_cb_registred)
40
+#define QED_LL2_RX_REGISTERED(ll2) ((ll2)->rx_queue.b_cb_registered)
41
+#define QED_LL2_TX_REGISTERED(ll2) ((ll2)->tx_queue.b_cb_registered)
6842
6943 #define QED_LL2_TX_SIZE (256)
7044 #define QED_LL2_RX_SIZE (4096)
....@@ -239,9 +213,8 @@
239213 buffer->phys_addr = new_phys_addr;
240214
241215 out_post:
242
- rc = qed_ll2_post_rx_buffer(QED_LEADING_HWFN(cdev), cdev->ll2->handle,
243
- buffer->phys_addr, 0, buffer, 1);
244
-
216
+ rc = qed_ll2_post_rx_buffer(p_hwfn, cdev->ll2->handle,
217
+ buffer->phys_addr, 0, buffer, 1);
245218 if (rc)
246219 qed_ll2_dealloc_buffer(cdev, buffer);
247220 }
....@@ -944,16 +917,15 @@
944917 return 0;
945918 }
946919
947
-static void qed_ll2_stop_ooo(struct qed_dev *cdev)
920
+static void qed_ll2_stop_ooo(struct qed_hwfn *p_hwfn)
948921 {
949
- struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
950
- u8 *handle = &hwfn->pf_params.iscsi_pf_params.ll2_ooo_queue_id;
922
+ u8 *handle = &p_hwfn->pf_params.iscsi_pf_params.ll2_ooo_queue_id;
951923
952
- DP_VERBOSE(cdev, QED_MSG_STORAGE, "Stopping LL2 OOO queue [%02x]\n",
953
- *handle);
924
+ DP_VERBOSE(p_hwfn, (QED_MSG_STORAGE | QED_MSG_LL2),
925
+ "Stopping LL2 OOO queue [%02x]\n", *handle);
954926
955
- qed_ll2_terminate_connection(hwfn, *handle);
956
- qed_ll2_release_connection(hwfn, *handle);
927
+ qed_ll2_terminate_connection(p_hwfn, *handle);
928
+ qed_ll2_release_connection(p_hwfn, *handle);
957929 *handle = QED_LL2_UNUSED_HANDLE;
958930 }
959931
....@@ -982,7 +954,7 @@
982954 return rc;
983955
984956 p_ramrod = &p_ent->ramrod.core_rx_queue_start;
985
-
957
+ memset(p_ramrod, 0, sizeof(*p_ramrod));
986958 p_ramrod->sb_id = cpu_to_le16(qed_int_get_sp_sb_id(p_hwfn));
987959 p_ramrod->sb_index = p_rx->rx_sb_index;
988960 p_ramrod->complete_event_flg = 1;
....@@ -1016,6 +988,8 @@
1016988
1017989 p_ramrod->action_on_error.error_type = action_on_error;
1018990 p_ramrod->gsi_offload_flag = p_ll2_conn->input.gsi_enable;
991
+ p_ramrod->zero_prod_flg = 1;
992
+
1019993 return qed_spq_post(p_hwfn, p_ent, NULL);
1020994 }
1021995
....@@ -1103,7 +1077,14 @@
11031077
11041078 p_ramrod->gsi_offload_flag = p_ll2_conn->input.gsi_enable;
11051079
1106
- return qed_spq_post(p_hwfn, p_ent, NULL);
1080
+ rc = qed_spq_post(p_hwfn, p_ent, NULL);
1081
+ if (rc)
1082
+ return rc;
1083
+
1084
+ rc = qed_db_recovery_add(p_hwfn->cdev, p_tx->doorbell_addr,
1085
+ &p_tx->db_msg, DB_REC_WIDTH_32B,
1086
+ DB_REC_KERNEL);
1087
+ return rc;
11071088 }
11081089
11091090 static int qed_sp_ll2_rx_queue_stop(struct qed_hwfn *p_hwfn,
....@@ -1137,9 +1118,11 @@
11371118 static int qed_sp_ll2_tx_queue_stop(struct qed_hwfn *p_hwfn,
11381119 struct qed_ll2_info *p_ll2_conn)
11391120 {
1121
+ struct qed_ll2_tx_queue *p_tx = &p_ll2_conn->tx_queue;
11401122 struct qed_spq_entry *p_ent = NULL;
11411123 struct qed_sp_init_data init_data;
11421124 int rc = -EINVAL;
1125
+ qed_db_recovery_del(p_hwfn->cdev, p_tx->doorbell_addr, &p_tx->db_msg);
11431126
11441127 /* Get SPQ entry */
11451128 memset(&init_data, 0, sizeof(init_data));
....@@ -1160,6 +1143,12 @@
11601143 qed_ll2_acquire_connection_rx(struct qed_hwfn *p_hwfn,
11611144 struct qed_ll2_info *p_ll2_info)
11621145 {
1146
+ struct qed_chain_init_params params = {
1147
+ .intended_use = QED_CHAIN_USE_TO_CONSUME_PRODUCE,
1148
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
1149
+ .num_elems = p_ll2_info->input.rx_num_desc,
1150
+ };
1151
+ struct qed_dev *cdev = p_hwfn->cdev;
11631152 struct qed_ll2_rx_packet *p_descq;
11641153 u32 capacity;
11651154 int rc = 0;
....@@ -1167,13 +1156,10 @@
11671156 if (!p_ll2_info->input.rx_num_desc)
11681157 goto out;
11691158
1170
- rc = qed_chain_alloc(p_hwfn->cdev,
1171
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
1172
- QED_CHAIN_MODE_NEXT_PTR,
1173
- QED_CHAIN_CNT_TYPE_U16,
1174
- p_ll2_info->input.rx_num_desc,
1175
- sizeof(struct core_rx_bd),
1176
- &p_ll2_info->rx_queue.rxq_chain, NULL);
1159
+ params.mode = QED_CHAIN_MODE_NEXT_PTR;
1160
+ params.elem_size = sizeof(struct core_rx_bd);
1161
+
1162
+ rc = qed_chain_alloc(cdev, &p_ll2_info->rx_queue.rxq_chain, &params);
11771163 if (rc) {
11781164 DP_NOTICE(p_hwfn, "Failed to allocate ll2 rxq chain\n");
11791165 goto out;
....@@ -1189,13 +1175,10 @@
11891175 }
11901176 p_ll2_info->rx_queue.descq_array = p_descq;
11911177
1192
- rc = qed_chain_alloc(p_hwfn->cdev,
1193
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
1194
- QED_CHAIN_MODE_PBL,
1195
- QED_CHAIN_CNT_TYPE_U16,
1196
- p_ll2_info->input.rx_num_desc,
1197
- sizeof(struct core_rx_fast_path_cqe),
1198
- &p_ll2_info->rx_queue.rcq_chain, NULL);
1178
+ params.mode = QED_CHAIN_MODE_PBL;
1179
+ params.elem_size = sizeof(struct core_rx_fast_path_cqe);
1180
+
1181
+ rc = qed_chain_alloc(cdev, &p_ll2_info->rx_queue.rcq_chain, &params);
11991182 if (rc) {
12001183 DP_NOTICE(p_hwfn, "Failed to allocate ll2 rcq chain\n");
12011184 goto out;
....@@ -1212,29 +1195,30 @@
12121195 static int qed_ll2_acquire_connection_tx(struct qed_hwfn *p_hwfn,
12131196 struct qed_ll2_info *p_ll2_info)
12141197 {
1198
+ struct qed_chain_init_params params = {
1199
+ .mode = QED_CHAIN_MODE_PBL,
1200
+ .intended_use = QED_CHAIN_USE_TO_CONSUME_PRODUCE,
1201
+ .cnt_type = QED_CHAIN_CNT_TYPE_U16,
1202
+ .num_elems = p_ll2_info->input.tx_num_desc,
1203
+ .elem_size = sizeof(struct core_tx_bd),
1204
+ };
12151205 struct qed_ll2_tx_packet *p_descq;
1216
- u32 desc_size;
1206
+ size_t desc_size;
12171207 u32 capacity;
12181208 int rc = 0;
12191209
12201210 if (!p_ll2_info->input.tx_num_desc)
12211211 goto out;
12221212
1223
- rc = qed_chain_alloc(p_hwfn->cdev,
1224
- QED_CHAIN_USE_TO_CONSUME_PRODUCE,
1225
- QED_CHAIN_MODE_PBL,
1226
- QED_CHAIN_CNT_TYPE_U16,
1227
- p_ll2_info->input.tx_num_desc,
1228
- sizeof(struct core_tx_bd),
1229
- &p_ll2_info->tx_queue.txq_chain, NULL);
1213
+ rc = qed_chain_alloc(p_hwfn->cdev, &p_ll2_info->tx_queue.txq_chain,
1214
+ &params);
12301215 if (rc)
12311216 goto out;
12321217
12331218 capacity = qed_chain_get_capacity(&p_ll2_info->tx_queue.txq_chain);
1234
- /* First element is part of the packet, rest are flexibly added */
1235
- desc_size = (sizeof(*p_descq) +
1236
- (p_ll2_info->input.tx_max_bds_per_packet - 1) *
1237
- sizeof(p_descq->bds_set));
1219
+ /* All bds_set elements are flexibily added. */
1220
+ desc_size = struct_size(p_descq, bds_set,
1221
+ p_ll2_info->input.tx_max_bds_per_packet);
12381222
12391223 p_descq = kcalloc(capacity, desc_size, GFP_KERNEL);
12401224 if (!p_descq) {
....@@ -1328,6 +1312,25 @@
13281312 return 0;
13291313 }
13301314
1315
+static void _qed_ll2_calc_allowed_conns(struct qed_hwfn *p_hwfn,
1316
+ struct qed_ll2_acquire_data *data,
1317
+ u8 *start_idx, u8 *last_idx)
1318
+{
1319
+ /* LL2 queues handles will be split as follows:
1320
+ * First will be the legacy queues, and then the ctx based.
1321
+ */
1322
+ if (data->input.rx_conn_type == QED_LL2_RX_TYPE_LEGACY) {
1323
+ *start_idx = QED_LL2_LEGACY_CONN_BASE_PF;
1324
+ *last_idx = *start_idx +
1325
+ QED_MAX_NUM_OF_LEGACY_LL2_CONNS_PF;
1326
+ } else {
1327
+ /* QED_LL2_RX_TYPE_CTX */
1328
+ *start_idx = QED_LL2_CTX_CONN_BASE_PF;
1329
+ *last_idx = *start_idx +
1330
+ QED_MAX_NUM_OF_CTX_LL2_CONNS_PF;
1331
+ }
1332
+}
1333
+
13311334 static enum core_error_handle
13321335 qed_ll2_get_error_choice(enum qed_ll2_error_handle err)
13331336 {
....@@ -1348,14 +1351,16 @@
13481351 struct qed_hwfn *p_hwfn = cxt;
13491352 qed_int_comp_cb_t comp_rx_cb, comp_tx_cb;
13501353 struct qed_ll2_info *p_ll2_info = NULL;
1351
- u8 i, *p_tx_max;
1354
+ u8 i, first_idx, last_idx, *p_tx_max;
13521355 int rc;
13531356
13541357 if (!data->p_connection_handle || !p_hwfn->p_ll2_info)
13551358 return -EINVAL;
13561359
1360
+ _qed_ll2_calc_allowed_conns(p_hwfn, data, &first_idx, &last_idx);
1361
+
13571362 /* Find a free connection to be used */
1358
- for (i = 0; (i < QED_MAX_NUM_OF_LL2_CONNECTIONS); i++) {
1363
+ for (i = first_idx; i < last_idx; i++) {
13591364 mutex_lock(&p_hwfn->p_ll2_info[i].mutex);
13601365 if (p_hwfn->p_ll2_info[i].b_active) {
13611366 mutex_unlock(&p_hwfn->p_ll2_info[i].mutex);
....@@ -1433,7 +1438,7 @@
14331438 &p_hwfn->p_ll2_info[i],
14341439 &p_ll2_info->rx_queue.rx_sb_index,
14351440 &p_ll2_info->rx_queue.p_fw_cons);
1436
- p_ll2_info->rx_queue.b_cb_registred = true;
1441
+ p_ll2_info->rx_queue.b_cb_registered = true;
14371442 }
14381443
14391444 if (data->input.tx_num_desc) {
....@@ -1442,7 +1447,7 @@
14421447 &p_hwfn->p_ll2_info[i],
14431448 &p_ll2_info->tx_queue.tx_sb_index,
14441449 &p_ll2_info->tx_queue.p_fw_cons);
1445
- p_ll2_info->tx_queue.b_cb_registred = true;
1450
+ p_ll2_info->tx_queue.b_cb_registered = true;
14461451 }
14471452
14481453 *data->p_connection_handle = i;
....@@ -1459,6 +1464,7 @@
14591464 enum qed_ll2_error_handle error_input;
14601465 enum core_error_handle error_mode;
14611466 u8 action_on_error = 0;
1467
+ int rc;
14621468
14631469 if (!QED_LL2_RX_REGISTERED(p_ll2_conn))
14641470 return 0;
....@@ -1472,7 +1478,18 @@
14721478 error_mode = qed_ll2_get_error_choice(error_input);
14731479 SET_FIELD(action_on_error, CORE_RX_ACTION_ON_ERROR_NO_BUFF, error_mode);
14741480
1475
- return qed_sp_ll2_rx_queue_start(p_hwfn, p_ll2_conn, action_on_error);
1481
+ rc = qed_sp_ll2_rx_queue_start(p_hwfn, p_ll2_conn, action_on_error);
1482
+ if (rc)
1483
+ return rc;
1484
+
1485
+ if (p_ll2_conn->rx_queue.ctx_based) {
1486
+ rc = qed_db_recovery_add(p_hwfn->cdev,
1487
+ p_ll2_conn->rx_queue.set_prod_addr,
1488
+ &p_ll2_conn->rx_queue.db_data,
1489
+ DB_REC_WIDTH_64B, DB_REC_KERNEL);
1490
+ }
1491
+
1492
+ return rc;
14761493 }
14771494
14781495 static void
....@@ -1486,17 +1503,45 @@
14861503 qed_ooo_submit_rx_buffers(p_hwfn, p_ll2_conn);
14871504 }
14881505
1506
+static inline u8 qed_ll2_handle_to_queue_id(struct qed_hwfn *p_hwfn,
1507
+ u8 handle,
1508
+ u8 ll2_queue_type)
1509
+{
1510
+ u8 qid;
1511
+
1512
+ if (ll2_queue_type == QED_LL2_RX_TYPE_LEGACY)
1513
+ return p_hwfn->hw_info.resc_start[QED_LL2_RAM_QUEUE] + handle;
1514
+
1515
+ /* QED_LL2_RX_TYPE_CTX
1516
+ * FW distinguishes between the legacy queues (ram based) and the
1517
+ * ctx based queues by the queue_id.
1518
+ * The first MAX_NUM_LL2_RX_RAM_QUEUES queues are legacy
1519
+ * and the queue ids above that are ctx base.
1520
+ */
1521
+ qid = p_hwfn->hw_info.resc_start[QED_LL2_CTX_QUEUE] +
1522
+ MAX_NUM_LL2_RX_RAM_QUEUES;
1523
+
1524
+ /* See comment on the acquire connection for how the ll2
1525
+ * queues handles are divided.
1526
+ */
1527
+ qid += (handle - QED_MAX_NUM_OF_LEGACY_LL2_CONNS_PF);
1528
+
1529
+ return qid;
1530
+}
1531
+
14891532 int qed_ll2_establish_connection(void *cxt, u8 connection_handle)
14901533 {
1491
- struct qed_hwfn *p_hwfn = cxt;
1492
- struct qed_ll2_info *p_ll2_conn;
1534
+ struct e4_core_conn_context *p_cxt;
14931535 struct qed_ll2_tx_packet *p_pkt;
1536
+ struct qed_ll2_info *p_ll2_conn;
1537
+ struct qed_hwfn *p_hwfn = cxt;
14941538 struct qed_ll2_rx_queue *p_rx;
14951539 struct qed_ll2_tx_queue *p_tx;
1540
+ struct qed_cxt_info cxt_info;
14961541 struct qed_ptt *p_ptt;
14971542 int rc = -EINVAL;
14981543 u32 i, capacity;
1499
- u32 desc_size;
1544
+ size_t desc_size;
15001545 u8 qid;
15011546
15021547 p_ptt = qed_ptt_acquire(p_hwfn);
....@@ -1530,10 +1575,9 @@
15301575 INIT_LIST_HEAD(&p_tx->sending_descq);
15311576 spin_lock_init(&p_tx->lock);
15321577 capacity = qed_chain_get_capacity(&p_tx->txq_chain);
1533
- /* First element is part of the packet, rest are flexibly added */
1534
- desc_size = (sizeof(*p_pkt) +
1535
- (p_ll2_conn->input.tx_max_bds_per_packet - 1) *
1536
- sizeof(p_pkt->bds_set));
1578
+ /* All bds_set elements are flexibily added. */
1579
+ desc_size = struct_size(p_pkt, bds_set,
1580
+ p_ll2_conn->input.tx_max_bds_per_packet);
15371581
15381582 for (i = 0; i < capacity; i++) {
15391583 p_pkt = p_tx->descq_mem + desc_size * i;
....@@ -1550,16 +1594,55 @@
15501594 rc = qed_cxt_acquire_cid(p_hwfn, PROTOCOLID_CORE, &p_ll2_conn->cid);
15511595 if (rc)
15521596 goto out;
1597
+ cxt_info.iid = p_ll2_conn->cid;
1598
+ rc = qed_cxt_get_cid_info(p_hwfn, &cxt_info);
1599
+ if (rc) {
1600
+ DP_NOTICE(p_hwfn, "Cannot find context info for cid=%d\n",
1601
+ p_ll2_conn->cid);
1602
+ goto out;
1603
+ }
15531604
1554
- qid = p_hwfn->hw_info.resc_start[QED_LL2_QUEUE] + connection_handle;
1605
+ p_cxt = cxt_info.p_cxt;
1606
+
1607
+ memset(p_cxt, 0, sizeof(*p_cxt));
1608
+
1609
+ qid = qed_ll2_handle_to_queue_id(p_hwfn, connection_handle,
1610
+ p_ll2_conn->input.rx_conn_type);
15551611 p_ll2_conn->queue_id = qid;
15561612 p_ll2_conn->tx_stats_id = qid;
1557
- p_rx->set_prod_addr = (u8 __iomem *)p_hwfn->regview +
1558
- GTT_BAR0_MAP_REG_TSDM_RAM +
1559
- TSTORM_LL2_RX_PRODS_OFFSET(qid);
1613
+
1614
+ DP_VERBOSE(p_hwfn, QED_MSG_LL2,
1615
+ "Establishing ll2 queue. PF %d ctx_based=%d abs qid=%d\n",
1616
+ p_hwfn->rel_pf_id, p_ll2_conn->input.rx_conn_type, qid);
1617
+
1618
+ if (p_ll2_conn->input.rx_conn_type == QED_LL2_RX_TYPE_LEGACY) {
1619
+ p_rx->set_prod_addr = p_hwfn->regview +
1620
+ GTT_BAR0_MAP_REG_TSDM_RAM + TSTORM_LL2_RX_PRODS_OFFSET(qid);
1621
+ } else {
1622
+ /* QED_LL2_RX_TYPE_CTX - using doorbell */
1623
+ p_rx->ctx_based = 1;
1624
+
1625
+ p_rx->set_prod_addr = p_hwfn->doorbells +
1626
+ p_hwfn->dpi_start_offset +
1627
+ DB_ADDR_SHIFT(DQ_PWM_OFFSET_TCM_LL2_PROD_UPDATE);
1628
+
1629
+ /* prepare db data */
1630
+ p_rx->db_data.icid = cpu_to_le16((u16)p_ll2_conn->cid);
1631
+ SET_FIELD(p_rx->db_data.params,
1632
+ CORE_PWM_PROD_UPDATE_DATA_AGG_CMD, DB_AGG_CMD_SET);
1633
+ SET_FIELD(p_rx->db_data.params,
1634
+ CORE_PWM_PROD_UPDATE_DATA_RESERVED1, 0);
1635
+ }
1636
+
15601637 p_tx->doorbell_addr = (u8 __iomem *)p_hwfn->doorbells +
15611638 qed_db_addr(p_ll2_conn->cid,
15621639 DQ_DEMS_LEGACY);
1640
+ /* prepare db data */
1641
+ SET_FIELD(p_tx->db_msg.params, CORE_DB_DATA_DEST, DB_DEST_XCM);
1642
+ SET_FIELD(p_tx->db_msg.params, CORE_DB_DATA_AGG_CMD, DB_AGG_CMD_SET);
1643
+ SET_FIELD(p_tx->db_msg.params, CORE_DB_DATA_AGG_VAL_SEL,
1644
+ DQ_XCM_CORE_TX_BD_PROD_CMD);
1645
+ p_tx->db_msg.agg_flags = DQ_XCM_CORE_DQ_CF_CMD;
15631646
15641647 rc = qed_ll2_establish_connection_rx(p_hwfn, p_ll2_conn);
15651648 if (rc)
....@@ -1576,12 +1659,12 @@
15761659
15771660 if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_FCOE) {
15781661 if (!test_bit(QED_MF_UFP_SPECIFIC, &p_hwfn->cdev->mf_bits))
1579
- qed_llh_add_protocol_filter(p_hwfn, p_ptt,
1580
- ETH_P_FCOE, 0,
1581
- QED_LLH_FILTER_ETHERTYPE);
1582
- qed_llh_add_protocol_filter(p_hwfn, p_ptt,
1583
- ETH_P_FIP, 0,
1584
- QED_LLH_FILTER_ETHERTYPE);
1662
+ qed_llh_add_protocol_filter(p_hwfn->cdev, 0,
1663
+ QED_LLH_FILTER_ETHERTYPE,
1664
+ ETH_P_FCOE, 0);
1665
+ qed_llh_add_protocol_filter(p_hwfn->cdev, 0,
1666
+ QED_LLH_FILTER_ETHERTYPE,
1667
+ ETH_P_FIP, 0);
15851668 }
15861669
15871670 out:
....@@ -1594,7 +1677,7 @@
15941677 struct qed_ll2_rx_packet *p_curp)
15951678 {
15961679 struct qed_ll2_rx_packet *p_posting_packet = NULL;
1597
- struct core_ll2_rx_prod rx_prod = { 0, 0, 0 };
1680
+ struct core_ll2_rx_prod rx_prod = { 0, 0 };
15981681 bool b_notify_fw = false;
15991682 u16 bd_prod, cq_prod;
16001683
....@@ -1619,13 +1702,27 @@
16191702
16201703 bd_prod = qed_chain_get_prod_idx(&p_rx->rxq_chain);
16211704 cq_prod = qed_chain_get_prod_idx(&p_rx->rcq_chain);
1622
- rx_prod.bd_prod = cpu_to_le16(bd_prod);
1623
- rx_prod.cqe_prod = cpu_to_le16(cq_prod);
1705
+ if (p_rx->ctx_based) {
1706
+ /* update producer by giving a doorbell */
1707
+ p_rx->db_data.prod.bd_prod = cpu_to_le16(bd_prod);
1708
+ p_rx->db_data.prod.cqe_prod = cpu_to_le16(cq_prod);
1709
+ /* Make sure chain element is updated before ringing the
1710
+ * doorbell
1711
+ */
1712
+ dma_wmb();
1713
+ DIRECT_REG_WR64(p_rx->set_prod_addr,
1714
+ *((u64 *)&p_rx->db_data));
1715
+ } else {
1716
+ rx_prod.bd_prod = cpu_to_le16(bd_prod);
1717
+ rx_prod.cqe_prod = cpu_to_le16(cq_prod);
16241718
1625
- /* Make sure chain element is updated before ringing the doorbell */
1626
- dma_wmb();
1719
+ /* Make sure chain element is updated before ringing the
1720
+ * doorbell
1721
+ */
1722
+ dma_wmb();
16271723
1628
- DIRECT_REG_WR(p_rx->set_prod_addr, *((u32 *)&rx_prod));
1724
+ DIRECT_REG_WR(p_rx->set_prod_addr, *((u32 *)&rx_prod));
1725
+ }
16291726 }
16301727
16311728 int qed_ll2_post_rx_buffer(void *cxt,
....@@ -1721,6 +1818,7 @@
17211818 enum core_roce_flavor_type roce_flavor;
17221819 enum core_tx_dest tx_dest;
17231820 u16 bd_data = 0, frag_idx;
1821
+ u16 bitfield1;
17241822
17251823 roce_flavor = (pkt->qed_roce_flavor == QED_LL2_ROCE) ? CORE_ROCE
17261824 : CORE_RROCE;
....@@ -1752,9 +1850,11 @@
17521850 pkt->remove_stag = true;
17531851 }
17541852
1755
- SET_FIELD(start_bd->bitfield1, CORE_TX_BD_L4_HDR_OFFSET_W,
1756
- cpu_to_le16(pkt->l4_hdr_offset_w));
1757
- SET_FIELD(start_bd->bitfield1, CORE_TX_BD_TX_DST, tx_dest);
1853
+ bitfield1 = le16_to_cpu(start_bd->bitfield1);
1854
+ SET_FIELD(bitfield1, CORE_TX_BD_L4_HDR_OFFSET_W, pkt->l4_hdr_offset_w);
1855
+ SET_FIELD(bitfield1, CORE_TX_BD_TX_DST, tx_dest);
1856
+ start_bd->bitfield1 = cpu_to_le16(bitfield1);
1857
+
17581858 bd_data |= pkt->bd_flags;
17591859 SET_FIELD(bd_data, CORE_TX_BD_DATA_START_BD, 0x1);
17601860 SET_FIELD(bd_data, CORE_TX_BD_DATA_NBDS, pkt->num_of_bds);
....@@ -1804,7 +1904,6 @@
18041904 bool b_notify = p_ll2_conn->tx_queue.cur_send_packet->notify_fw;
18051905 struct qed_ll2_tx_queue *p_tx = &p_ll2_conn->tx_queue;
18061906 struct qed_ll2_tx_packet *p_pkt = NULL;
1807
- struct core_db_data db_msg = { 0, 0, 0 };
18081907 u16 bd_prod;
18091908
18101909 /* If there are missing BDs, don't do anything now */
....@@ -1833,24 +1932,19 @@
18331932 list_move_tail(&p_pkt->list_entry, &p_tx->active_descq);
18341933 }
18351934
1836
- SET_FIELD(db_msg.params, CORE_DB_DATA_DEST, DB_DEST_XCM);
1837
- SET_FIELD(db_msg.params, CORE_DB_DATA_AGG_CMD, DB_AGG_CMD_SET);
1838
- SET_FIELD(db_msg.params, CORE_DB_DATA_AGG_VAL_SEL,
1839
- DQ_XCM_CORE_TX_BD_PROD_CMD);
1840
- db_msg.agg_flags = DQ_XCM_CORE_DQ_CF_CMD;
1841
- db_msg.spq_prod = cpu_to_le16(bd_prod);
1935
+ p_tx->db_msg.spq_prod = cpu_to_le16(bd_prod);
18421936
18431937 /* Make sure the BDs data is updated before ringing the doorbell */
18441938 wmb();
18451939
1846
- DIRECT_REG_WR(p_tx->doorbell_addr, *((u32 *)&db_msg));
1940
+ DIRECT_REG_WR(p_tx->doorbell_addr, *((u32 *)&p_tx->db_msg));
18471941
18481942 DP_VERBOSE(p_hwfn,
18491943 (NETIF_MSG_TX_QUEUED | QED_MSG_LL2),
18501944 "LL2 [q 0x%02x cid 0x%08x type 0x%08x] Doorbelled [producer 0x%04x]\n",
18511945 p_ll2_conn->queue_id,
18521946 p_ll2_conn->cid,
1853
- p_ll2_conn->input.conn_type, db_msg.spq_prod);
1947
+ p_ll2_conn->input.conn_type, p_tx->db_msg.spq_prod);
18541948 }
18551949
18561950 int qed_ll2_prepare_tx_packet(void *cxt,
....@@ -1964,7 +2058,7 @@
19642058
19652059 /* Stop Tx & Rx of connection, if needed */
19662060 if (QED_LL2_TX_REGISTERED(p_ll2_conn)) {
1967
- p_ll2_conn->tx_queue.b_cb_registred = false;
2061
+ p_ll2_conn->tx_queue.b_cb_registered = false;
19682062 smp_wmb(); /* Make sure this is seen by ll2_lb_rxq_completion */
19692063 rc = qed_sp_ll2_tx_queue_stop(p_hwfn, p_ll2_conn);
19702064 if (rc)
....@@ -1975,8 +2069,14 @@
19752069 }
19762070
19772071 if (QED_LL2_RX_REGISTERED(p_ll2_conn)) {
1978
- p_ll2_conn->rx_queue.b_cb_registred = false;
2072
+ p_ll2_conn->rx_queue.b_cb_registered = false;
19792073 smp_wmb(); /* Make sure this is seen by ll2_lb_rxq_completion */
2074
+
2075
+ if (p_ll2_conn->rx_queue.ctx_based)
2076
+ qed_db_recovery_del(p_hwfn->cdev,
2077
+ p_ll2_conn->rx_queue.set_prod_addr,
2078
+ &p_ll2_conn->rx_queue.db_data);
2079
+
19802080 rc = qed_sp_ll2_rx_queue_stop(p_hwfn, p_ll2_conn);
19812081 if (rc)
19822082 goto out;
....@@ -1990,12 +2090,12 @@
19902090
19912091 if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_FCOE) {
19922092 if (!test_bit(QED_MF_UFP_SPECIFIC, &p_hwfn->cdev->mf_bits))
1993
- qed_llh_remove_protocol_filter(p_hwfn, p_ptt,
1994
- ETH_P_FCOE, 0,
1995
- QED_LLH_FILTER_ETHERTYPE);
1996
- qed_llh_remove_protocol_filter(p_hwfn, p_ptt,
1997
- ETH_P_FIP, 0,
1998
- QED_LLH_FILTER_ETHERTYPE);
2093
+ qed_llh_remove_protocol_filter(p_hwfn->cdev, 0,
2094
+ QED_LLH_FILTER_ETHERTYPE,
2095
+ ETH_P_FCOE, 0);
2096
+ qed_llh_remove_protocol_filter(p_hwfn->cdev, 0,
2097
+ QED_LLH_FILTER_ETHERTYPE,
2098
+ ETH_P_FIP, 0);
19992099 }
20002100
20012101 out:
....@@ -2096,12 +2196,12 @@
20962196 TSTORM_LL2_PORT_STAT_OFFSET(MFW_PORT(p_hwfn)),
20972197 sizeof(port_stats));
20982198
2099
- p_stats->gsi_invalid_hdr = HILO_64_REGPAIR(port_stats.gsi_invalid_hdr);
2100
- p_stats->gsi_invalid_pkt_length =
2199
+ p_stats->gsi_invalid_hdr += HILO_64_REGPAIR(port_stats.gsi_invalid_hdr);
2200
+ p_stats->gsi_invalid_pkt_length +=
21012201 HILO_64_REGPAIR(port_stats.gsi_invalid_pkt_length);
2102
- p_stats->gsi_unsupported_pkt_typ =
2202
+ p_stats->gsi_unsupported_pkt_typ +=
21032203 HILO_64_REGPAIR(port_stats.gsi_unsupported_pkt_typ);
2104
- p_stats->gsi_crcchksm_error =
2204
+ p_stats->gsi_crcchksm_error +=
21052205 HILO_64_REGPAIR(port_stats.gsi_crcchksm_error);
21062206 }
21072207
....@@ -2119,9 +2219,9 @@
21192219 CORE_LL2_TSTORM_PER_QUEUE_STAT_OFFSET(qid);
21202220 qed_memcpy_from(p_hwfn, p_ptt, &tstats, tstats_addr, sizeof(tstats));
21212221
2122
- p_stats->packet_too_big_discard =
2222
+ p_stats->packet_too_big_discard +=
21232223 HILO_64_REGPAIR(tstats.packet_too_big_discard);
2124
- p_stats->no_buff_discard = HILO_64_REGPAIR(tstats.no_buff_discard);
2224
+ p_stats->no_buff_discard += HILO_64_REGPAIR(tstats.no_buff_discard);
21252225 }
21262226
21272227 static void _qed_ll2_get_ustats(struct qed_hwfn *p_hwfn,
....@@ -2138,12 +2238,12 @@
21382238 CORE_LL2_USTORM_PER_QUEUE_STAT_OFFSET(qid);
21392239 qed_memcpy_from(p_hwfn, p_ptt, &ustats, ustats_addr, sizeof(ustats));
21402240
2141
- p_stats->rcv_ucast_bytes = HILO_64_REGPAIR(ustats.rcv_ucast_bytes);
2142
- p_stats->rcv_mcast_bytes = HILO_64_REGPAIR(ustats.rcv_mcast_bytes);
2143
- p_stats->rcv_bcast_bytes = HILO_64_REGPAIR(ustats.rcv_bcast_bytes);
2144
- p_stats->rcv_ucast_pkts = HILO_64_REGPAIR(ustats.rcv_ucast_pkts);
2145
- p_stats->rcv_mcast_pkts = HILO_64_REGPAIR(ustats.rcv_mcast_pkts);
2146
- p_stats->rcv_bcast_pkts = HILO_64_REGPAIR(ustats.rcv_bcast_pkts);
2241
+ p_stats->rcv_ucast_bytes += HILO_64_REGPAIR(ustats.rcv_ucast_bytes);
2242
+ p_stats->rcv_mcast_bytes += HILO_64_REGPAIR(ustats.rcv_mcast_bytes);
2243
+ p_stats->rcv_bcast_bytes += HILO_64_REGPAIR(ustats.rcv_bcast_bytes);
2244
+ p_stats->rcv_ucast_pkts += HILO_64_REGPAIR(ustats.rcv_ucast_pkts);
2245
+ p_stats->rcv_mcast_pkts += HILO_64_REGPAIR(ustats.rcv_mcast_pkts);
2246
+ p_stats->rcv_bcast_pkts += HILO_64_REGPAIR(ustats.rcv_bcast_pkts);
21472247 }
21482248
21492249 static void _qed_ll2_get_pstats(struct qed_hwfn *p_hwfn,
....@@ -2160,22 +2260,20 @@
21602260 CORE_LL2_PSTORM_PER_QUEUE_STAT_OFFSET(stats_id);
21612261 qed_memcpy_from(p_hwfn, p_ptt, &pstats, pstats_addr, sizeof(pstats));
21622262
2163
- p_stats->sent_ucast_bytes = HILO_64_REGPAIR(pstats.sent_ucast_bytes);
2164
- p_stats->sent_mcast_bytes = HILO_64_REGPAIR(pstats.sent_mcast_bytes);
2165
- p_stats->sent_bcast_bytes = HILO_64_REGPAIR(pstats.sent_bcast_bytes);
2166
- p_stats->sent_ucast_pkts = HILO_64_REGPAIR(pstats.sent_ucast_pkts);
2167
- p_stats->sent_mcast_pkts = HILO_64_REGPAIR(pstats.sent_mcast_pkts);
2168
- p_stats->sent_bcast_pkts = HILO_64_REGPAIR(pstats.sent_bcast_pkts);
2263
+ p_stats->sent_ucast_bytes += HILO_64_REGPAIR(pstats.sent_ucast_bytes);
2264
+ p_stats->sent_mcast_bytes += HILO_64_REGPAIR(pstats.sent_mcast_bytes);
2265
+ p_stats->sent_bcast_bytes += HILO_64_REGPAIR(pstats.sent_bcast_bytes);
2266
+ p_stats->sent_ucast_pkts += HILO_64_REGPAIR(pstats.sent_ucast_pkts);
2267
+ p_stats->sent_mcast_pkts += HILO_64_REGPAIR(pstats.sent_mcast_pkts);
2268
+ p_stats->sent_bcast_pkts += HILO_64_REGPAIR(pstats.sent_bcast_pkts);
21692269 }
21702270
2171
-int qed_ll2_get_stats(void *cxt,
2172
- u8 connection_handle, struct qed_ll2_stats *p_stats)
2271
+static int __qed_ll2_get_stats(void *cxt, u8 connection_handle,
2272
+ struct qed_ll2_stats *p_stats)
21732273 {
21742274 struct qed_hwfn *p_hwfn = cxt;
21752275 struct qed_ll2_info *p_ll2_conn = NULL;
21762276 struct qed_ptt *p_ptt;
2177
-
2178
- memset(p_stats, 0, sizeof(*p_stats));
21792277
21802278 if ((connection_handle >= QED_MAX_NUM_OF_LL2_CONNECTIONS) ||
21812279 !p_hwfn->p_ll2_info)
....@@ -2191,13 +2289,24 @@
21912289
21922290 if (p_ll2_conn->input.gsi_enable)
21932291 _qed_ll2_get_port_stats(p_hwfn, p_ptt, p_stats);
2292
+
21942293 _qed_ll2_get_tstats(p_hwfn, p_ptt, p_ll2_conn, p_stats);
2294
+
21952295 _qed_ll2_get_ustats(p_hwfn, p_ptt, p_ll2_conn, p_stats);
2296
+
21962297 if (p_ll2_conn->tx_stats_en)
21972298 _qed_ll2_get_pstats(p_hwfn, p_ptt, p_ll2_conn, p_stats);
21982299
21992300 qed_ptt_release(p_hwfn, p_ptt);
2301
+
22002302 return 0;
2303
+}
2304
+
2305
+int qed_ll2_get_stats(void *cxt,
2306
+ u8 connection_handle, struct qed_ll2_stats *p_stats)
2307
+{
2308
+ memset(p_stats, 0, sizeof(*p_stats));
2309
+ return __qed_ll2_get_stats(cxt, connection_handle, p_stats);
22012310 }
22022311
22032312 static void qed_ll2b_release_rx_packet(void *cxt,
....@@ -2219,14 +2328,14 @@
22192328 cdev->ll2->cb_cookie = cookie;
22202329 }
22212330
2222
-struct qed_ll2_cbs ll2_cbs = {
2331
+static struct qed_ll2_cbs ll2_cbs = {
22232332 .rx_comp_cb = &qed_ll2b_complete_rx_packet,
22242333 .rx_release_cb = &qed_ll2b_release_rx_packet,
22252334 .tx_comp_cb = &qed_ll2b_complete_tx_packet,
22262335 .tx_release_cb = &qed_ll2b_complete_tx_packet,
22272336 };
22282337
2229
-static void qed_ll2_set_conn_data(struct qed_dev *cdev,
2338
+static void qed_ll2_set_conn_data(struct qed_hwfn *p_hwfn,
22302339 struct qed_ll2_acquire_data *data,
22312340 struct qed_ll2_params *params,
22322341 enum qed_ll2_conn_type conn_type,
....@@ -2242,7 +2351,7 @@
22422351 data->input.tx_num_desc = QED_LL2_TX_SIZE;
22432352 data->p_connection_handle = handle;
22442353 data->cbs = &ll2_cbs;
2245
- ll2_cbs.cookie = QED_LEADING_HWFN(cdev);
2354
+ ll2_cbs.cookie = p_hwfn;
22462355
22472356 if (lb) {
22482357 data->input.tx_tc = PKT_LB_TC;
....@@ -2253,74 +2362,102 @@
22532362 }
22542363 }
22552364
2256
-static int qed_ll2_start_ooo(struct qed_dev *cdev,
2365
+static int qed_ll2_start_ooo(struct qed_hwfn *p_hwfn,
22572366 struct qed_ll2_params *params)
22582367 {
2259
- struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
2260
- u8 *handle = &hwfn->pf_params.iscsi_pf_params.ll2_ooo_queue_id;
2368
+ u8 *handle = &p_hwfn->pf_params.iscsi_pf_params.ll2_ooo_queue_id;
22612369 struct qed_ll2_acquire_data data;
22622370 int rc;
22632371
2264
- qed_ll2_set_conn_data(cdev, &data, params,
2372
+ qed_ll2_set_conn_data(p_hwfn, &data, params,
22652373 QED_LL2_TYPE_OOO, handle, true);
22662374
2267
- rc = qed_ll2_acquire_connection(hwfn, &data);
2375
+ rc = qed_ll2_acquire_connection(p_hwfn, &data);
22682376 if (rc) {
2269
- DP_INFO(cdev, "Failed to acquire LL2 OOO connection\n");
2377
+ DP_INFO(p_hwfn, "Failed to acquire LL2 OOO connection\n");
22702378 goto out;
22712379 }
22722380
2273
- rc = qed_ll2_establish_connection(hwfn, *handle);
2381
+ rc = qed_ll2_establish_connection(p_hwfn, *handle);
22742382 if (rc) {
2275
- DP_INFO(cdev, "Failed to establist LL2 OOO connection\n");
2383
+ DP_INFO(p_hwfn, "Failed to establish LL2 OOO connection\n");
22762384 goto fail;
22772385 }
22782386
22792387 return 0;
22802388
22812389 fail:
2282
- qed_ll2_release_connection(hwfn, *handle);
2390
+ qed_ll2_release_connection(p_hwfn, *handle);
22832391 out:
22842392 *handle = QED_LL2_UNUSED_HANDLE;
22852393 return rc;
22862394 }
22872395
2288
-static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
2396
+static bool qed_ll2_is_storage_eng1(struct qed_dev *cdev)
22892397 {
2290
- struct qed_ll2_buffer *buffer, *tmp_buffer;
2291
- enum qed_ll2_conn_type conn_type;
2292
- struct qed_ll2_acquire_data data;
2293
- struct qed_ptt *p_ptt;
2294
- int rc, i;
2398
+ return (QED_IS_FCOE_PERSONALITY(QED_LEADING_HWFN(cdev)) ||
2399
+ QED_IS_ISCSI_PERSONALITY(QED_LEADING_HWFN(cdev))) &&
2400
+ (QED_AFFIN_HWFN(cdev) != QED_LEADING_HWFN(cdev));
2401
+}
22952402
2403
+static int __qed_ll2_stop(struct qed_hwfn *p_hwfn)
2404
+{
2405
+ struct qed_dev *cdev = p_hwfn->cdev;
2406
+ int rc;
22962407
2297
- /* Initialize LL2 locks & lists */
2298
- INIT_LIST_HEAD(&cdev->ll2->list);
2299
- spin_lock_init(&cdev->ll2->lock);
2300
- cdev->ll2->rx_size = NET_SKB_PAD + ETH_HLEN +
2301
- L1_CACHE_BYTES + params->mtu;
2408
+ rc = qed_ll2_terminate_connection(p_hwfn, cdev->ll2->handle);
2409
+ if (rc)
2410
+ DP_INFO(cdev, "Failed to terminate LL2 connection\n");
23022411
2303
- /*Allocate memory for LL2 */
2304
- DP_INFO(cdev, "Allocating LL2 buffers of size %08x bytes\n",
2305
- cdev->ll2->rx_size);
2306
- for (i = 0; i < QED_LL2_RX_SIZE; i++) {
2307
- buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
2308
- if (!buffer) {
2309
- DP_INFO(cdev, "Failed to allocate LL2 buffers\n");
2310
- goto fail;
2311
- }
2412
+ qed_ll2_release_connection(p_hwfn, cdev->ll2->handle);
23122413
2313
- rc = qed_ll2_alloc_buffer(cdev, (u8 **)&buffer->data,
2314
- &buffer->phys_addr);
2315
- if (rc) {
2316
- kfree(buffer);
2317
- goto fail;
2318
- }
2414
+ return rc;
2415
+}
23192416
2320
- list_add_tail(&buffer->list, &cdev->ll2->list);
2417
+static int qed_ll2_stop(struct qed_dev *cdev)
2418
+{
2419
+ bool b_is_storage_eng1 = qed_ll2_is_storage_eng1(cdev);
2420
+ struct qed_hwfn *p_hwfn = QED_AFFIN_HWFN(cdev);
2421
+ int rc = 0, rc2 = 0;
2422
+
2423
+ if (cdev->ll2->handle == QED_LL2_UNUSED_HANDLE)
2424
+ return 0;
2425
+
2426
+ qed_llh_remove_mac_filter(cdev, 0, cdev->ll2_mac_address);
2427
+ eth_zero_addr(cdev->ll2_mac_address);
2428
+
2429
+ if (QED_IS_ISCSI_PERSONALITY(p_hwfn))
2430
+ qed_ll2_stop_ooo(p_hwfn);
2431
+
2432
+ /* In CMT mode, LL2 is always started on engine 0 for a storage PF */
2433
+ if (b_is_storage_eng1) {
2434
+ rc2 = __qed_ll2_stop(QED_LEADING_HWFN(cdev));
2435
+ if (rc2)
2436
+ DP_NOTICE(QED_LEADING_HWFN(cdev),
2437
+ "Failed to stop LL2 on engine 0\n");
23212438 }
23222439
2323
- switch (QED_LEADING_HWFN(cdev)->hw_info.personality) {
2440
+ rc = __qed_ll2_stop(p_hwfn);
2441
+ if (rc)
2442
+ DP_NOTICE(p_hwfn, "Failed to stop LL2\n");
2443
+
2444
+ qed_ll2_kill_buffers(cdev);
2445
+
2446
+ cdev->ll2->handle = QED_LL2_UNUSED_HANDLE;
2447
+
2448
+ return rc | rc2;
2449
+}
2450
+
2451
+static int __qed_ll2_start(struct qed_hwfn *p_hwfn,
2452
+ struct qed_ll2_params *params)
2453
+{
2454
+ struct qed_ll2_buffer *buffer, *tmp_buffer;
2455
+ struct qed_dev *cdev = p_hwfn->cdev;
2456
+ enum qed_ll2_conn_type conn_type;
2457
+ struct qed_ll2_acquire_data data;
2458
+ int rc, rx_cnt;
2459
+
2460
+ switch (p_hwfn->hw_info.personality) {
23242461 case QED_PCI_FCOE:
23252462 conn_type = QED_LL2_TYPE_FCOE;
23262463 break;
....@@ -2331,33 +2468,34 @@
23312468 conn_type = QED_LL2_TYPE_ROCE;
23322469 break;
23332470 default:
2471
+
23342472 conn_type = QED_LL2_TYPE_TEST;
23352473 }
23362474
2337
- qed_ll2_set_conn_data(cdev, &data, params, conn_type,
2475
+ qed_ll2_set_conn_data(p_hwfn, &data, params, conn_type,
23382476 &cdev->ll2->handle, false);
23392477
2340
- rc = qed_ll2_acquire_connection(QED_LEADING_HWFN(cdev), &data);
2478
+ rc = qed_ll2_acquire_connection(p_hwfn, &data);
23412479 if (rc) {
2342
- DP_INFO(cdev, "Failed to acquire LL2 connection\n");
2343
- goto fail;
2480
+ DP_INFO(p_hwfn, "Failed to acquire LL2 connection\n");
2481
+ return rc;
23442482 }
23452483
2346
- rc = qed_ll2_establish_connection(QED_LEADING_HWFN(cdev),
2347
- cdev->ll2->handle);
2484
+ rc = qed_ll2_establish_connection(p_hwfn, cdev->ll2->handle);
23482485 if (rc) {
2349
- DP_INFO(cdev, "Failed to establish LL2 connection\n");
2350
- goto release_fail;
2486
+ DP_INFO(p_hwfn, "Failed to establish LL2 connection\n");
2487
+ goto release_conn;
23512488 }
23522489
23532490 /* Post all Rx buffers to FW */
23542491 spin_lock_bh(&cdev->ll2->lock);
2492
+ rx_cnt = cdev->ll2->rx_cnt;
23552493 list_for_each_entry_safe(buffer, tmp_buffer, &cdev->ll2->list, list) {
2356
- rc = qed_ll2_post_rx_buffer(QED_LEADING_HWFN(cdev),
2494
+ rc = qed_ll2_post_rx_buffer(p_hwfn,
23572495 cdev->ll2->handle,
23582496 buffer->phys_addr, 0, buffer, 1);
23592497 if (rc) {
2360
- DP_INFO(cdev,
2498
+ DP_INFO(p_hwfn,
23612499 "Failed to post an Rx buffer; Deleting it\n");
23622500 dma_unmap_single(&cdev->pdev->dev, buffer->phys_addr,
23632501 cdev->ll2->rx_size, DMA_FROM_DEVICE);
....@@ -2365,100 +2503,127 @@
23652503 list_del(&buffer->list);
23662504 kfree(buffer);
23672505 } else {
2368
- cdev->ll2->rx_cnt++;
2506
+ rx_cnt++;
23692507 }
23702508 }
23712509 spin_unlock_bh(&cdev->ll2->lock);
23722510
2373
- if (!cdev->ll2->rx_cnt) {
2374
- DP_INFO(cdev, "Failed passing even a single Rx buffer\n");
2375
- goto release_terminate;
2511
+ if (rx_cnt == cdev->ll2->rx_cnt) {
2512
+ DP_NOTICE(p_hwfn, "Failed passing even a single Rx buffer\n");
2513
+ goto terminate_conn;
23762514 }
2515
+ cdev->ll2->rx_cnt = rx_cnt;
2516
+
2517
+ return 0;
2518
+
2519
+terminate_conn:
2520
+ qed_ll2_terminate_connection(p_hwfn, cdev->ll2->handle);
2521
+release_conn:
2522
+ qed_ll2_release_connection(p_hwfn, cdev->ll2->handle);
2523
+ return rc;
2524
+}
2525
+
2526
+static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params)
2527
+{
2528
+ bool b_is_storage_eng1 = qed_ll2_is_storage_eng1(cdev);
2529
+ struct qed_hwfn *p_hwfn = QED_AFFIN_HWFN(cdev);
2530
+ struct qed_ll2_buffer *buffer;
2531
+ int rx_num_desc, i, rc;
23772532
23782533 if (!is_valid_ether_addr(params->ll2_mac_address)) {
2379
- DP_INFO(cdev, "Invalid Ethernet address\n");
2380
- goto release_terminate;
2534
+ DP_NOTICE(cdev, "Invalid Ethernet address\n");
2535
+ return -EINVAL;
23812536 }
23822537
2383
- if (QED_LEADING_HWFN(cdev)->hw_info.personality == QED_PCI_ISCSI) {
2384
- DP_VERBOSE(cdev, QED_MSG_STORAGE, "Starting OOO LL2 queue\n");
2385
- rc = qed_ll2_start_ooo(cdev, params);
2538
+ WARN_ON(!cdev->ll2->cbs);
2539
+
2540
+ /* Initialize LL2 locks & lists */
2541
+ INIT_LIST_HEAD(&cdev->ll2->list);
2542
+ spin_lock_init(&cdev->ll2->lock);
2543
+
2544
+ cdev->ll2->rx_size = NET_SKB_PAD + ETH_HLEN +
2545
+ L1_CACHE_BYTES + params->mtu;
2546
+
2547
+ /* Allocate memory for LL2.
2548
+ * In CMT mode, in case of a storage PF which is affintized to engine 1,
2549
+ * LL2 is started also on engine 0 and thus we need twofold buffers.
2550
+ */
2551
+ rx_num_desc = QED_LL2_RX_SIZE * (b_is_storage_eng1 ? 2 : 1);
2552
+ DP_INFO(cdev, "Allocating %d LL2 buffers of size %08x bytes\n",
2553
+ rx_num_desc, cdev->ll2->rx_size);
2554
+ for (i = 0; i < rx_num_desc; i++) {
2555
+ buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
2556
+ if (!buffer) {
2557
+ DP_INFO(cdev, "Failed to allocate LL2 buffers\n");
2558
+ rc = -ENOMEM;
2559
+ goto err0;
2560
+ }
2561
+
2562
+ rc = qed_ll2_alloc_buffer(cdev, (u8 **)&buffer->data,
2563
+ &buffer->phys_addr);
23862564 if (rc) {
2387
- DP_INFO(cdev,
2388
- "Failed to initialize the OOO LL2 queue\n");
2389
- goto release_terminate;
2565
+ kfree(buffer);
2566
+ goto err0;
2567
+ }
2568
+
2569
+ list_add_tail(&buffer->list, &cdev->ll2->list);
2570
+ }
2571
+
2572
+ rc = __qed_ll2_start(p_hwfn, params);
2573
+ if (rc) {
2574
+ DP_NOTICE(cdev, "Failed to start LL2\n");
2575
+ goto err0;
2576
+ }
2577
+
2578
+ /* In CMT mode, always need to start LL2 on engine 0 for a storage PF,
2579
+ * since broadcast/mutlicast packets are routed to engine 0.
2580
+ */
2581
+ if (b_is_storage_eng1) {
2582
+ rc = __qed_ll2_start(QED_LEADING_HWFN(cdev), params);
2583
+ if (rc) {
2584
+ DP_NOTICE(QED_LEADING_HWFN(cdev),
2585
+ "Failed to start LL2 on engine 0\n");
2586
+ goto err1;
23902587 }
23912588 }
23922589
2393
- p_ptt = qed_ptt_acquire(QED_LEADING_HWFN(cdev));
2394
- if (!p_ptt) {
2395
- DP_INFO(cdev, "Failed to acquire PTT\n");
2396
- goto release_terminate;
2590
+ if (QED_IS_ISCSI_PERSONALITY(p_hwfn)) {
2591
+ DP_VERBOSE(cdev, QED_MSG_STORAGE, "Starting OOO LL2 queue\n");
2592
+ rc = qed_ll2_start_ooo(p_hwfn, params);
2593
+ if (rc) {
2594
+ DP_NOTICE(cdev, "Failed to start OOO LL2\n");
2595
+ goto err2;
2596
+ }
23972597 }
23982598
2399
- rc = qed_llh_add_mac_filter(QED_LEADING_HWFN(cdev), p_ptt,
2400
- params->ll2_mac_address);
2401
- qed_ptt_release(QED_LEADING_HWFN(cdev), p_ptt);
2599
+ rc = qed_llh_add_mac_filter(cdev, 0, params->ll2_mac_address);
24022600 if (rc) {
2403
- DP_ERR(cdev, "Failed to allocate LLH filter\n");
2404
- goto release_terminate_all;
2601
+ DP_NOTICE(cdev, "Failed to add an LLH filter\n");
2602
+ goto err3;
24052603 }
24062604
24072605 ether_addr_copy(cdev->ll2_mac_address, params->ll2_mac_address);
2606
+
24082607 return 0;
24092608
2410
-release_terminate_all:
2411
-
2412
-release_terminate:
2413
- qed_ll2_terminate_connection(QED_LEADING_HWFN(cdev), cdev->ll2->handle);
2414
-release_fail:
2415
- qed_ll2_release_connection(QED_LEADING_HWFN(cdev), cdev->ll2->handle);
2416
-fail:
2609
+err3:
2610
+ if (QED_IS_ISCSI_PERSONALITY(p_hwfn))
2611
+ qed_ll2_stop_ooo(p_hwfn);
2612
+err2:
2613
+ if (b_is_storage_eng1)
2614
+ __qed_ll2_stop(QED_LEADING_HWFN(cdev));
2615
+err1:
2616
+ __qed_ll2_stop(p_hwfn);
2617
+err0:
24172618 qed_ll2_kill_buffers(cdev);
24182619 cdev->ll2->handle = QED_LL2_UNUSED_HANDLE;
2419
- return -EINVAL;
2420
-}
2421
-
2422
-static int qed_ll2_stop(struct qed_dev *cdev)
2423
-{
2424
- struct qed_ptt *p_ptt;
2425
- int rc;
2426
-
2427
- if (cdev->ll2->handle == QED_LL2_UNUSED_HANDLE)
2428
- return 0;
2429
-
2430
- p_ptt = qed_ptt_acquire(QED_LEADING_HWFN(cdev));
2431
- if (!p_ptt) {
2432
- DP_INFO(cdev, "Failed to acquire PTT\n");
2433
- goto fail;
2434
- }
2435
-
2436
- qed_llh_remove_mac_filter(QED_LEADING_HWFN(cdev), p_ptt,
2437
- cdev->ll2_mac_address);
2438
- qed_ptt_release(QED_LEADING_HWFN(cdev), p_ptt);
2439
- eth_zero_addr(cdev->ll2_mac_address);
2440
-
2441
- if (QED_LEADING_HWFN(cdev)->hw_info.personality == QED_PCI_ISCSI)
2442
- qed_ll2_stop_ooo(cdev);
2443
-
2444
- rc = qed_ll2_terminate_connection(QED_LEADING_HWFN(cdev),
2445
- cdev->ll2->handle);
2446
- if (rc)
2447
- DP_INFO(cdev, "Failed to terminate LL2 connection\n");
2448
-
2449
- qed_ll2_kill_buffers(cdev);
2450
-
2451
- qed_ll2_release_connection(QED_LEADING_HWFN(cdev), cdev->ll2->handle);
2452
- cdev->ll2->handle = QED_LL2_UNUSED_HANDLE;
2453
-
24542620 return rc;
2455
-fail:
2456
- return -EINVAL;
24572621 }
24582622
24592623 static int qed_ll2_start_xmit(struct qed_dev *cdev, struct sk_buff *skb,
24602624 unsigned long xmit_flags)
24612625 {
2626
+ struct qed_hwfn *p_hwfn = QED_AFFIN_HWFN(cdev);
24622627 struct qed_ll2_tx_pkt_info pkt;
24632628 const skb_frag_t *frag;
24642629 u8 flags = 0, nr_frags;
....@@ -2516,7 +2681,7 @@
25162681 * routine may run and free the SKB, so no dereferencing the SKB
25172682 * beyond this point unless skb has any fragments.
25182683 */
2519
- rc = qed_ll2_prepare_tx_packet(&cdev->hwfns[0], cdev->ll2->handle,
2684
+ rc = qed_ll2_prepare_tx_packet(p_hwfn, cdev->ll2->handle,
25202685 &pkt, 1);
25212686 if (rc)
25222687 goto err;
....@@ -2534,13 +2699,13 @@
25342699 goto err;
25352700 }
25362701
2537
- rc = qed_ll2_set_fragment_of_tx_packet(QED_LEADING_HWFN(cdev),
2702
+ rc = qed_ll2_set_fragment_of_tx_packet(p_hwfn,
25382703 cdev->ll2->handle,
25392704 mapping,
25402705 skb_frag_size(frag));
25412706
25422707 /* if failed not much to do here, partial packet has been posted
2543
- * we can't free memory, will need to wait for completion.
2708
+ * we can't free memory, will need to wait for completion
25442709 */
25452710 if (rc)
25462711 goto err2;
....@@ -2550,18 +2715,37 @@
25502715
25512716 err:
25522717 dma_unmap_single(&cdev->pdev->dev, mapping, skb->len, DMA_TO_DEVICE);
2553
-
25542718 err2:
25552719 return rc;
25562720 }
25572721
25582722 static int qed_ll2_stats(struct qed_dev *cdev, struct qed_ll2_stats *stats)
25592723 {
2724
+ bool b_is_storage_eng1 = qed_ll2_is_storage_eng1(cdev);
2725
+ struct qed_hwfn *p_hwfn = QED_AFFIN_HWFN(cdev);
2726
+ int rc;
2727
+
25602728 if (!cdev->ll2)
25612729 return -EINVAL;
25622730
2563
- return qed_ll2_get_stats(QED_LEADING_HWFN(cdev),
2564
- cdev->ll2->handle, stats);
2731
+ rc = qed_ll2_get_stats(p_hwfn, cdev->ll2->handle, stats);
2732
+ if (rc) {
2733
+ DP_NOTICE(p_hwfn, "Failed to get LL2 stats\n");
2734
+ return rc;
2735
+ }
2736
+
2737
+ /* In CMT mode, LL2 is always started on engine 0 for a storage PF */
2738
+ if (b_is_storage_eng1) {
2739
+ rc = __qed_ll2_get_stats(QED_LEADING_HWFN(cdev),
2740
+ cdev->ll2->handle, stats);
2741
+ if (rc) {
2742
+ DP_NOTICE(QED_LEADING_HWFN(cdev),
2743
+ "Failed to get LL2 stats on engine 0\n");
2744
+ return rc;
2745
+ }
2746
+ }
2747
+
2748
+ return 0;
25652749 }
25662750
25672751 const struct qed_ll2_ops qed_ll2_ops_pass = {