1d9ce1917SZiyang Xuan /* SPDX-License-Identifier: BSD-3-Clause
2d9ce1917SZiyang Xuan * Copyright(c) 2017 Huawei Technologies Co., Ltd
3d9ce1917SZiyang Xuan */
4d9ce1917SZiyang Xuan
5df96fd0dSBruce Richardson #include<ethdev_driver.h>
6*1f37cb2bSDavid Marchand #include <bus_pci_driver.h>
7d9ce1917SZiyang Xuan #include <rte_hash.h>
8d9ce1917SZiyang Xuan #include <rte_jhash.h>
9d9ce1917SZiyang Xuan
10d9ce1917SZiyang Xuan #include "hinic_compat.h"
11d9ce1917SZiyang Xuan #include "hinic_csr.h"
12d9ce1917SZiyang Xuan #include "hinic_pmd_hwdev.h"
13d9ce1917SZiyang Xuan #include "hinic_pmd_hwif.h"
14d9ce1917SZiyang Xuan #include "hinic_pmd_wq.h"
15d9ce1917SZiyang Xuan #include "hinic_pmd_cmdq.h"
16d9ce1917SZiyang Xuan #include "hinic_pmd_mgmt.h"
17d9ce1917SZiyang Xuan #include "hinic_pmd_niccfg.h"
18b8582d05SXiaoyun Wang #include "hinic_pmd_mbox.h"
19d9ce1917SZiyang Xuan
20d9ce1917SZiyang Xuan #define HINIC_DEAULT_EQ_MSIX_PENDING_LIMIT 0
21d9ce1917SZiyang Xuan #define HINIC_DEAULT_EQ_MSIX_COALESC_TIMER_CFG 0xFF
22d9ce1917SZiyang Xuan #define HINIC_DEAULT_EQ_MSIX_RESEND_TIMER_CFG 7
23d9ce1917SZiyang Xuan
24d9ce1917SZiyang Xuan #define HINIC_FLR_TIMEOUT 1000
25d9ce1917SZiyang Xuan
26d9ce1917SZiyang Xuan #define FFM_RECORD_NUM_MAX 32
27d9ce1917SZiyang Xuan
28d9ce1917SZiyang Xuan #define HINIC_DMA_ATTR_ENTRY_ST_SHIFT 0
29d9ce1917SZiyang Xuan #define HINIC_DMA_ATTR_ENTRY_AT_SHIFT 8
30d9ce1917SZiyang Xuan #define HINIC_DMA_ATTR_ENTRY_PH_SHIFT 10
31d9ce1917SZiyang Xuan #define HINIC_DMA_ATTR_ENTRY_NO_SNOOPING_SHIFT 12
32d9ce1917SZiyang Xuan #define HINIC_DMA_ATTR_ENTRY_TPH_EN_SHIFT 13
33d9ce1917SZiyang Xuan
34d9ce1917SZiyang Xuan #define HINIC_DMA_ATTR_ENTRY_ST_MASK 0xFF
35d9ce1917SZiyang Xuan #define HINIC_DMA_ATTR_ENTRY_AT_MASK 0x3
36d9ce1917SZiyang Xuan #define HINIC_DMA_ATTR_ENTRY_PH_MASK 0x3
37d9ce1917SZiyang Xuan #define HINIC_DMA_ATTR_ENTRY_NO_SNOOPING_MASK 0x1
38d9ce1917SZiyang Xuan #define HINIC_DMA_ATTR_ENTRY_TPH_EN_MASK 0x1
39d9ce1917SZiyang Xuan
40d9ce1917SZiyang Xuan #define HINIC_DMA_ATTR_ENTRY_SET(val, member) \
41d9ce1917SZiyang Xuan (((u32)(val) & HINIC_DMA_ATTR_ENTRY_##member##_MASK) << \
42d9ce1917SZiyang Xuan HINIC_DMA_ATTR_ENTRY_##member##_SHIFT)
43d9ce1917SZiyang Xuan
44d9ce1917SZiyang Xuan #define HINIC_DMA_ATTR_ENTRY_CLEAR(val, member) \
45d9ce1917SZiyang Xuan ((val) & (~(HINIC_DMA_ATTR_ENTRY_##member##_MASK \
46d9ce1917SZiyang Xuan << HINIC_DMA_ATTR_ENTRY_##member##_SHIFT)))
47d9ce1917SZiyang Xuan
48d9ce1917SZiyang Xuan #define HINIC_PCIE_ST_DISABLE 0
49d9ce1917SZiyang Xuan #define HINIC_PCIE_AT_DISABLE 0
50d9ce1917SZiyang Xuan #define HINIC_PCIE_PH_DISABLE 0
51d9ce1917SZiyang Xuan #define PCIE_MSIX_ATTR_ENTRY 0
52d9ce1917SZiyang Xuan
53d9ce1917SZiyang Xuan #define HINIC_HASH_FUNC rte_jhash
54d9ce1917SZiyang Xuan #define HINIC_HASH_KEY_LEN (sizeof(dma_addr_t))
55d9ce1917SZiyang Xuan #define HINIC_HASH_FUNC_INIT_VAL 0
56d9ce1917SZiyang Xuan
57d9ce1917SZiyang Xuan static const char *__hw_to_char_fec[HILINK_FEC_MAX_TYPE] = {
58d9ce1917SZiyang Xuan "RS-FEC", "BASE-FEC", "NO-FEC"};
59d9ce1917SZiyang Xuan
60d9ce1917SZiyang Xuan static const char *__hw_to_char_port_type[LINK_PORT_MAX_TYPE] = {
61d9ce1917SZiyang Xuan "Unknown", "Fibre", "Electric", "Direct Attach Copper", "AOC",
62d9ce1917SZiyang Xuan "Back plane", "BaseT"
63d9ce1917SZiyang Xuan };
64d9ce1917SZiyang Xuan
65d9ce1917SZiyang Xuan static const char *hinic_module_link_err[LINK_ERR_NUM] = {
66d9ce1917SZiyang Xuan "Unrecognized module",
67d9ce1917SZiyang Xuan };
68d9ce1917SZiyang Xuan
69b8582d05SXiaoyun Wang struct hinic_vf_dma_attr_table {
70b8582d05SXiaoyun Wang struct hinic_mgmt_msg_head mgmt_msg_head;
71b8582d05SXiaoyun Wang
72b8582d05SXiaoyun Wang u16 func_idx;
73b8582d05SXiaoyun Wang u8 func_dma_entry_num;
74b8582d05SXiaoyun Wang u8 entry_idx;
75b8582d05SXiaoyun Wang u8 st;
76b8582d05SXiaoyun Wang u8 at;
77b8582d05SXiaoyun Wang u8 ph;
78b8582d05SXiaoyun Wang u8 no_snooping;
79b8582d05SXiaoyun Wang u8 tph_en;
80b8582d05SXiaoyun Wang u8 resv1[3];
81b8582d05SXiaoyun Wang };
82b8582d05SXiaoyun Wang
83b8582d05SXiaoyun Wang /**
84b8582d05SXiaoyun Wang * hinic_cpu_to_be32 - convert data to big endian 32 bit format
85b8582d05SXiaoyun Wang * @data: the data to convert
86b8582d05SXiaoyun Wang * @len: length of data to convert, must be Multiple of 4B
87b8582d05SXiaoyun Wang */
hinic_cpu_to_be32(void * data,u32 len)88b8582d05SXiaoyun Wang void hinic_cpu_to_be32(void *data, u32 len)
89b8582d05SXiaoyun Wang {
90b8582d05SXiaoyun Wang u32 i;
91b8582d05SXiaoyun Wang u32 *mem = (u32 *)data;
92b8582d05SXiaoyun Wang
93b8582d05SXiaoyun Wang for (i = 0; i < (len >> 2); i++) {
94b8582d05SXiaoyun Wang *mem = cpu_to_be32(*mem);
95b8582d05SXiaoyun Wang mem++;
96b8582d05SXiaoyun Wang }
97b8582d05SXiaoyun Wang }
98b8582d05SXiaoyun Wang
99b8582d05SXiaoyun Wang /**
100b8582d05SXiaoyun Wang * hinic_be32_to_cpu - convert data from big endian 32 bit format
101b8582d05SXiaoyun Wang * @data: the data to convert
102b8582d05SXiaoyun Wang * @len: length of data to convert, must be Multiple of 4B
103b8582d05SXiaoyun Wang */
hinic_be32_to_cpu(void * data,u32 len)104b8582d05SXiaoyun Wang void hinic_be32_to_cpu(void *data, u32 len)
105b8582d05SXiaoyun Wang {
106b8582d05SXiaoyun Wang u32 i;
107b8582d05SXiaoyun Wang u32 *mem = (u32 *)data;
108b8582d05SXiaoyun Wang
109b8582d05SXiaoyun Wang for (i = 0; i < (len >> 2); i++) {
110b8582d05SXiaoyun Wang *mem = be32_to_cpu(*mem);
111b8582d05SXiaoyun Wang mem++;
112b8582d05SXiaoyun Wang }
113b8582d05SXiaoyun Wang }
114b8582d05SXiaoyun Wang
hinic_dma_mem_zalloc(struct hinic_hwdev * hwdev,size_t size,dma_addr_t * dma_handle,unsigned int align,unsigned int socket_id)1151b7b9f17SXiaoyun Wang static void *hinic_dma_mem_zalloc(struct hinic_hwdev *hwdev, size_t size,
1161b7b9f17SXiaoyun Wang dma_addr_t *dma_handle, unsigned int align,
1171b7b9f17SXiaoyun Wang unsigned int socket_id)
118d9ce1917SZiyang Xuan {
119d9ce1917SZiyang Xuan int rc, alloc_cnt;
120d9ce1917SZiyang Xuan const struct rte_memzone *mz;
121d9ce1917SZiyang Xuan char z_name[RTE_MEMZONE_NAMESIZE];
122d9ce1917SZiyang Xuan hash_sig_t sig;
123d9ce1917SZiyang Xuan rte_iova_t iova;
124d9ce1917SZiyang Xuan
125d9ce1917SZiyang Xuan if (dma_handle == NULL || 0 == size)
126d9ce1917SZiyang Xuan return NULL;
127d9ce1917SZiyang Xuan
128d9ce1917SZiyang Xuan alloc_cnt = rte_atomic32_add_return(&hwdev->os_dep.dma_alloc_cnt, 1);
129d9ce1917SZiyang Xuan snprintf(z_name, sizeof(z_name), "%s_%d",
130d9ce1917SZiyang Xuan hwdev->pcidev_hdl->name, alloc_cnt);
131d9ce1917SZiyang Xuan
1321b7b9f17SXiaoyun Wang mz = rte_memzone_reserve_aligned(z_name, size, socket_id,
1331b7b9f17SXiaoyun Wang RTE_MEMZONE_IOVA_CONTIG, align);
134d9ce1917SZiyang Xuan if (!mz) {
135d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Alloc dma able memory failed, errno: %d, ma_name: %s, size: 0x%zx",
136d9ce1917SZiyang Xuan rte_errno, z_name, size);
137d9ce1917SZiyang Xuan return NULL;
138d9ce1917SZiyang Xuan }
139d9ce1917SZiyang Xuan
140d9ce1917SZiyang Xuan iova = mz->iova;
141d9ce1917SZiyang Xuan
142d9ce1917SZiyang Xuan /* check if phys_addr already exist */
143d9ce1917SZiyang Xuan sig = HINIC_HASH_FUNC(&iova, HINIC_HASH_KEY_LEN,
144d9ce1917SZiyang Xuan HINIC_HASH_FUNC_INIT_VAL);
145d9ce1917SZiyang Xuan rc = rte_hash_lookup_with_hash(hwdev->os_dep.dma_addr_hash,
146d9ce1917SZiyang Xuan &iova, sig);
147d9ce1917SZiyang Xuan if (rc >= 0) {
148d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Dma addr: %p already in hash table, error: %d, mz_name: %s",
149d9ce1917SZiyang Xuan (void *)iova, rc, z_name);
150d9ce1917SZiyang Xuan goto phys_addr_hash_err;
151d9ce1917SZiyang Xuan }
152d9ce1917SZiyang Xuan
153d9ce1917SZiyang Xuan /* record paddr in hash table */
154d9ce1917SZiyang Xuan rte_spinlock_lock(&hwdev->os_dep.dma_hash_lock);
155d9ce1917SZiyang Xuan rc = rte_hash_add_key_with_hash_data(hwdev->os_dep.dma_addr_hash,
156d9ce1917SZiyang Xuan &iova, sig,
157d9ce1917SZiyang Xuan (void *)(u64)mz);
158d9ce1917SZiyang Xuan rte_spinlock_unlock(&hwdev->os_dep.dma_hash_lock);
159d9ce1917SZiyang Xuan if (rc) {
160d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Insert dma addr: %p hash failed, error: %d, mz_name: %s",
161d9ce1917SZiyang Xuan (void *)iova, rc, z_name);
162d9ce1917SZiyang Xuan goto phys_addr_hash_err;
163d9ce1917SZiyang Xuan }
164d9ce1917SZiyang Xuan *dma_handle = iova;
165d9ce1917SZiyang Xuan memset(mz->addr, 0, size);
166d9ce1917SZiyang Xuan
167d9ce1917SZiyang Xuan return mz->addr;
168d9ce1917SZiyang Xuan
169d9ce1917SZiyang Xuan phys_addr_hash_err:
170d9ce1917SZiyang Xuan (void)rte_memzone_free(mz);
171d9ce1917SZiyang Xuan
172d9ce1917SZiyang Xuan return NULL;
173d9ce1917SZiyang Xuan }
174d9ce1917SZiyang Xuan
175d9ce1917SZiyang Xuan static void
hinic_dma_mem_free(struct hinic_hwdev * hwdev,size_t size,void * virt,dma_addr_t phys)176d9ce1917SZiyang Xuan hinic_dma_mem_free(struct hinic_hwdev *hwdev, size_t size,
177d9ce1917SZiyang Xuan void *virt, dma_addr_t phys)
178d9ce1917SZiyang Xuan {
179d9ce1917SZiyang Xuan int rc;
180d9ce1917SZiyang Xuan struct rte_memzone *mz = NULL;
181d9ce1917SZiyang Xuan struct rte_hash *hash;
182d9ce1917SZiyang Xuan hash_sig_t sig;
183d9ce1917SZiyang Xuan
184d9ce1917SZiyang Xuan if (virt == NULL || phys == 0)
185d9ce1917SZiyang Xuan return;
186d9ce1917SZiyang Xuan
187d9ce1917SZiyang Xuan hash = hwdev->os_dep.dma_addr_hash;
188d9ce1917SZiyang Xuan sig = HINIC_HASH_FUNC(&phys, HINIC_HASH_KEY_LEN,
189d9ce1917SZiyang Xuan HINIC_HASH_FUNC_INIT_VAL);
190d9ce1917SZiyang Xuan rc = rte_hash_lookup_with_hash_data(hash, &phys, sig, (void **)&mz);
191d9ce1917SZiyang Xuan if (rc < 0) {
192d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Can not find phys_addr: %p, error: %d",
193d9ce1917SZiyang Xuan (void *)phys, rc);
194d9ce1917SZiyang Xuan return;
195d9ce1917SZiyang Xuan }
196d9ce1917SZiyang Xuan
197d9ce1917SZiyang Xuan if (virt != mz->addr || size > mz->len) {
198d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Match mz_info failed: "
199d9ce1917SZiyang Xuan "mz.name: %s, mz.phys: %p, mz.virt: %p, mz.len: %zu, "
200d9ce1917SZiyang Xuan "phys: %p, virt: %p, size: %zu",
201d9ce1917SZiyang Xuan mz->name, (void *)mz->iova, mz->addr, mz->len,
202d9ce1917SZiyang Xuan (void *)phys, virt, size);
203d9ce1917SZiyang Xuan }
204d9ce1917SZiyang Xuan
205d9ce1917SZiyang Xuan rte_spinlock_lock(&hwdev->os_dep.dma_hash_lock);
206d9ce1917SZiyang Xuan (void)rte_hash_del_key_with_hash(hash, &phys, sig);
207d9ce1917SZiyang Xuan rte_spinlock_unlock(&hwdev->os_dep.dma_hash_lock);
208d9ce1917SZiyang Xuan
209d9ce1917SZiyang Xuan (void)rte_memzone_free(mz);
210d9ce1917SZiyang Xuan }
211d9ce1917SZiyang Xuan
dma_zalloc_coherent(void * hwdev,size_t size,dma_addr_t * dma_handle,unsigned int socket_id)2121b7b9f17SXiaoyun Wang void *dma_zalloc_coherent(void *hwdev, size_t size, dma_addr_t *dma_handle,
2131b7b9f17SXiaoyun Wang unsigned int socket_id)
214d9ce1917SZiyang Xuan {
2151b7b9f17SXiaoyun Wang return hinic_dma_mem_zalloc(hwdev, size, dma_handle,
2161b7b9f17SXiaoyun Wang RTE_CACHE_LINE_SIZE, socket_id);
217d9ce1917SZiyang Xuan }
218d9ce1917SZiyang Xuan
dma_zalloc_coherent_aligned(void * hwdev,size_t size,dma_addr_t * dma_handle,unsigned int socket_id)219d9ce1917SZiyang Xuan void *dma_zalloc_coherent_aligned(void *hwdev, size_t size,
2201b7b9f17SXiaoyun Wang dma_addr_t *dma_handle, unsigned int socket_id)
221d9ce1917SZiyang Xuan {
2221b7b9f17SXiaoyun Wang return hinic_dma_mem_zalloc(hwdev, size, dma_handle, HINIC_PAGE_SIZE,
2231b7b9f17SXiaoyun Wang socket_id);
224d9ce1917SZiyang Xuan }
225d9ce1917SZiyang Xuan
dma_zalloc_coherent_aligned256k(void * hwdev,size_t size,dma_addr_t * dma_handle,unsigned int socket_id)226d9ce1917SZiyang Xuan void *dma_zalloc_coherent_aligned256k(void *hwdev, size_t size,
2271b7b9f17SXiaoyun Wang dma_addr_t *dma_handle,
2281b7b9f17SXiaoyun Wang unsigned int socket_id)
229d9ce1917SZiyang Xuan {
2301b7b9f17SXiaoyun Wang return hinic_dma_mem_zalloc(hwdev, size, dma_handle,
2311b7b9f17SXiaoyun Wang HINIC_PAGE_SIZE * 64, socket_id);
232d9ce1917SZiyang Xuan }
233d9ce1917SZiyang Xuan
dma_free_coherent(void * hwdev,size_t size,void * virt,dma_addr_t phys)234d9ce1917SZiyang Xuan void dma_free_coherent(void *hwdev, size_t size, void *virt, dma_addr_t phys)
235d9ce1917SZiyang Xuan {
236d9ce1917SZiyang Xuan hinic_dma_mem_free(hwdev, size, virt, phys);
237d9ce1917SZiyang Xuan }
238d9ce1917SZiyang Xuan
dma_free_coherent_volatile(void * hwdev,size_t size,volatile void * virt,dma_addr_t phys)239d9ce1917SZiyang Xuan void dma_free_coherent_volatile(void *hwdev, size_t size,
240d9ce1917SZiyang Xuan volatile void *virt, dma_addr_t phys)
241d9ce1917SZiyang Xuan {
242d9ce1917SZiyang Xuan int rc;
243d9ce1917SZiyang Xuan struct rte_memzone *mz = NULL;
244d9ce1917SZiyang Xuan struct hinic_hwdev *dev = hwdev;
245d9ce1917SZiyang Xuan struct rte_hash *hash;
246d9ce1917SZiyang Xuan hash_sig_t sig;
247d9ce1917SZiyang Xuan
248d9ce1917SZiyang Xuan if (virt == NULL || phys == 0)
249d9ce1917SZiyang Xuan return;
250d9ce1917SZiyang Xuan
251d9ce1917SZiyang Xuan hash = dev->os_dep.dma_addr_hash;
252d9ce1917SZiyang Xuan sig = HINIC_HASH_FUNC(&phys, HINIC_HASH_KEY_LEN,
253d9ce1917SZiyang Xuan HINIC_HASH_FUNC_INIT_VAL);
254d9ce1917SZiyang Xuan rc = rte_hash_lookup_with_hash_data(hash, &phys, sig, (void **)&mz);
255d9ce1917SZiyang Xuan if (rc < 0) {
256d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Can not find phys_addr: %p, error: %d",
257d9ce1917SZiyang Xuan (void *)phys, rc);
258d9ce1917SZiyang Xuan return;
259d9ce1917SZiyang Xuan }
260d9ce1917SZiyang Xuan
261d9ce1917SZiyang Xuan if (virt != mz->addr || size > mz->len) {
262d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Match mz_info failed: "
263d9ce1917SZiyang Xuan "mz.name:%s, mz.phys:%p, mz.virt:%p, mz.len:%zu, "
264d9ce1917SZiyang Xuan "phys:%p, virt:%p, size:%zu",
265d9ce1917SZiyang Xuan mz->name, (void *)mz->iova, mz->addr, mz->len,
266d9ce1917SZiyang Xuan (void *)phys, virt, size);
267d9ce1917SZiyang Xuan }
268d9ce1917SZiyang Xuan
269d9ce1917SZiyang Xuan rte_spinlock_lock(&dev->os_dep.dma_hash_lock);
270d9ce1917SZiyang Xuan (void)rte_hash_del_key_with_hash(hash, &phys, sig);
271d9ce1917SZiyang Xuan rte_spinlock_unlock(&dev->os_dep.dma_hash_lock);
272d9ce1917SZiyang Xuan
273d9ce1917SZiyang Xuan (void)rte_memzone_free(mz);
274d9ce1917SZiyang Xuan }
275d9ce1917SZiyang Xuan
dma_pool_create(const char * name,void * dev,size_t size,size_t align,size_t boundary)276d9ce1917SZiyang Xuan struct dma_pool *dma_pool_create(const char *name, void *dev,
277d9ce1917SZiyang Xuan size_t size, size_t align, size_t boundary)
278d9ce1917SZiyang Xuan {
279d9ce1917SZiyang Xuan struct pci_pool *pool;
280d9ce1917SZiyang Xuan
281b8582d05SXiaoyun Wang pool = rte_zmalloc(NULL, sizeof(*pool), HINIC_MEM_ALLOC_ALIGN_MIN);
282d9ce1917SZiyang Xuan if (!pool)
283d9ce1917SZiyang Xuan return NULL;
284d9ce1917SZiyang Xuan
285b8582d05SXiaoyun Wang rte_atomic32_set(&pool->inuse, 0);
286d9ce1917SZiyang Xuan pool->elem_size = size;
287d9ce1917SZiyang Xuan pool->align = align;
288d9ce1917SZiyang Xuan pool->boundary = boundary;
289d9ce1917SZiyang Xuan pool->hwdev = dev;
290d9ce1917SZiyang Xuan strncpy(pool->name, name, (sizeof(pool->name) - 1));
291d9ce1917SZiyang Xuan
292d9ce1917SZiyang Xuan return pool;
293d9ce1917SZiyang Xuan }
294d9ce1917SZiyang Xuan
dma_pool_destroy(struct dma_pool * pool)295d9ce1917SZiyang Xuan void dma_pool_destroy(struct dma_pool *pool)
296d9ce1917SZiyang Xuan {
297d9ce1917SZiyang Xuan if (!pool)
298d9ce1917SZiyang Xuan return;
299d9ce1917SZiyang Xuan
300b8582d05SXiaoyun Wang if (rte_atomic32_read(&pool->inuse) != 0) {
301b8582d05SXiaoyun Wang PMD_DRV_LOG(ERR, "Leak memory, dma_pool: %s, inuse_count: %d",
302b8582d05SXiaoyun Wang pool->name, rte_atomic32_read(&pool->inuse));
303d9ce1917SZiyang Xuan }
304d9ce1917SZiyang Xuan
305d9ce1917SZiyang Xuan rte_free(pool);
306d9ce1917SZiyang Xuan }
307d9ce1917SZiyang Xuan
dma_pool_alloc(struct pci_pool * pool,dma_addr_t * dma_addr)3081b7b9f17SXiaoyun Wang void *dma_pool_alloc(struct pci_pool *pool, dma_addr_t *dma_addr)
309d9ce1917SZiyang Xuan {
310d9ce1917SZiyang Xuan void *buf;
311d9ce1917SZiyang Xuan
3121b7b9f17SXiaoyun Wang buf = hinic_dma_mem_zalloc(pool->hwdev, pool->elem_size, dma_addr,
3131b7b9f17SXiaoyun Wang (u32)pool->align, SOCKET_ID_ANY);
314d9ce1917SZiyang Xuan if (buf)
315b8582d05SXiaoyun Wang rte_atomic32_inc(&pool->inuse);
316d9ce1917SZiyang Xuan
317d9ce1917SZiyang Xuan return buf;
318d9ce1917SZiyang Xuan }
319d9ce1917SZiyang Xuan
dma_pool_free(struct pci_pool * pool,void * vaddr,dma_addr_t dma)320d9ce1917SZiyang Xuan void dma_pool_free(struct pci_pool *pool, void *vaddr, dma_addr_t dma)
321d9ce1917SZiyang Xuan {
322b8582d05SXiaoyun Wang rte_atomic32_dec(&pool->inuse);
323d9ce1917SZiyang Xuan hinic_dma_mem_free(pool->hwdev, pool->elem_size, vaddr, dma);
324d9ce1917SZiyang Xuan }
325d9ce1917SZiyang Xuan
326d9ce1917SZiyang Xuan #define HINIC_MAX_DMA_ENTRIES 8192
hinic_osdep_init(struct hinic_hwdev * hwdev)327d9ce1917SZiyang Xuan int hinic_osdep_init(struct hinic_hwdev *hwdev)
328d9ce1917SZiyang Xuan {
329d9ce1917SZiyang Xuan struct rte_hash_parameters dh_params = { 0 };
330d9ce1917SZiyang Xuan struct rte_hash *paddr_hash = NULL;
331d9ce1917SZiyang Xuan
332d9ce1917SZiyang Xuan rte_atomic32_set(&hwdev->os_dep.dma_alloc_cnt, 0);
333d9ce1917SZiyang Xuan rte_spinlock_init(&hwdev->os_dep.dma_hash_lock);
334d9ce1917SZiyang Xuan
335d9ce1917SZiyang Xuan dh_params.name = hwdev->pcidev_hdl->name;
336d9ce1917SZiyang Xuan dh_params.entries = HINIC_MAX_DMA_ENTRIES;
337d9ce1917SZiyang Xuan dh_params.key_len = HINIC_HASH_KEY_LEN;
338d9ce1917SZiyang Xuan dh_params.hash_func = HINIC_HASH_FUNC;
339d9ce1917SZiyang Xuan dh_params.hash_func_init_val = HINIC_HASH_FUNC_INIT_VAL;
340d9ce1917SZiyang Xuan dh_params.socket_id = SOCKET_ID_ANY;
341d9ce1917SZiyang Xuan
342d9ce1917SZiyang Xuan paddr_hash = rte_hash_find_existing(dh_params.name);
343d9ce1917SZiyang Xuan if (paddr_hash == NULL) {
344d9ce1917SZiyang Xuan paddr_hash = rte_hash_create(&dh_params);
345d9ce1917SZiyang Xuan if (paddr_hash == NULL) {
346d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Create nic_dev phys_addr hash table failed");
347d9ce1917SZiyang Xuan return -ENOMEM;
348d9ce1917SZiyang Xuan }
349d9ce1917SZiyang Xuan } else {
350d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "Using existing dma hash table %s",
351d9ce1917SZiyang Xuan dh_params.name);
352d9ce1917SZiyang Xuan }
353d9ce1917SZiyang Xuan hwdev->os_dep.dma_addr_hash = paddr_hash;
354d9ce1917SZiyang Xuan
355d9ce1917SZiyang Xuan return 0;
356d9ce1917SZiyang Xuan }
357d9ce1917SZiyang Xuan
hinic_osdep_deinit(struct hinic_hwdev * hwdev)358d9ce1917SZiyang Xuan void hinic_osdep_deinit(struct hinic_hwdev *hwdev)
359d9ce1917SZiyang Xuan {
360d9ce1917SZiyang Xuan uint32_t iter = 0;
361d9ce1917SZiyang Xuan dma_addr_t key_pa;
362d9ce1917SZiyang Xuan struct rte_memzone *data_mz = NULL;
363d9ce1917SZiyang Xuan struct rte_hash *paddr_hash = hwdev->os_dep.dma_addr_hash;
364d9ce1917SZiyang Xuan
365d9ce1917SZiyang Xuan if (paddr_hash) {
366d9ce1917SZiyang Xuan /* iterate through the hash table */
367d9ce1917SZiyang Xuan while (rte_hash_iterate(paddr_hash, (const void **)&key_pa,
368d9ce1917SZiyang Xuan (void **)&data_mz, &iter) >= 0) {
369d9ce1917SZiyang Xuan if (data_mz) {
370d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "Free leaked dma_addr: %p, mz: %s",
371d9ce1917SZiyang Xuan (void *)key_pa, data_mz->name);
372d9ce1917SZiyang Xuan (void)rte_memzone_free(data_mz);
373d9ce1917SZiyang Xuan }
374d9ce1917SZiyang Xuan }
375d9ce1917SZiyang Xuan
376d9ce1917SZiyang Xuan /* free phys_addr hash table */
377d9ce1917SZiyang Xuan rte_hash_free(paddr_hash);
378d9ce1917SZiyang Xuan }
379d9ce1917SZiyang Xuan }
380d9ce1917SZiyang Xuan
381d9ce1917SZiyang Xuan /**
382d9ce1917SZiyang Xuan * hinic_set_ci_table - set ci attribute table
383d9ce1917SZiyang Xuan * @hwdev: the hardware interface of a nic device
384d9ce1917SZiyang Xuan * @q_id: Queue id of SQ
385d9ce1917SZiyang Xuan * @attr: Point to SQ CI attribute table
386d9ce1917SZiyang Xuan * @return
387d9ce1917SZiyang Xuan * 0 on success and ci attribute table is filled,
388d9ce1917SZiyang Xuan * negative error value otherwise.
389b8582d05SXiaoyun Wang */
hinic_set_ci_table(void * hwdev,u16 q_id,struct hinic_sq_attr * attr)390d9ce1917SZiyang Xuan int hinic_set_ci_table(void *hwdev, u16 q_id, struct hinic_sq_attr *attr)
391d9ce1917SZiyang Xuan {
392d9ce1917SZiyang Xuan struct hinic_cons_idx_attr cons_idx_attr;
393d807dd7dSXiaoyun Wang u16 out_size = sizeof(cons_idx_attr);
394d807dd7dSXiaoyun Wang int err;
395d9ce1917SZiyang Xuan
396d9ce1917SZiyang Xuan memset(&cons_idx_attr, 0, sizeof(cons_idx_attr));
397d9ce1917SZiyang Xuan cons_idx_attr.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
398d9ce1917SZiyang Xuan cons_idx_attr.func_idx = hinic_global_func_id(hwdev);
399d9ce1917SZiyang Xuan cons_idx_attr.dma_attr_off = attr->dma_attr_off;
400d9ce1917SZiyang Xuan cons_idx_attr.pending_limit = attr->pending_limit;
401d9ce1917SZiyang Xuan cons_idx_attr.coalescing_time = attr->coalescing_time;
402d9ce1917SZiyang Xuan if (attr->intr_en) {
403d9ce1917SZiyang Xuan cons_idx_attr.intr_en = attr->intr_en;
404d9ce1917SZiyang Xuan cons_idx_attr.intr_idx = attr->intr_idx;
405d9ce1917SZiyang Xuan }
406d9ce1917SZiyang Xuan
407d9ce1917SZiyang Xuan cons_idx_attr.l2nic_sqn = attr->l2nic_sqn;
408d9ce1917SZiyang Xuan cons_idx_attr.sq_id = q_id;
409d9ce1917SZiyang Xuan cons_idx_attr.ci_addr = attr->ci_dma_base;
410d9ce1917SZiyang Xuan
411d807dd7dSXiaoyun Wang err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
412d9ce1917SZiyang Xuan HINIC_MGMT_CMD_L2NIC_SQ_CI_ATTR_SET,
413d9ce1917SZiyang Xuan &cons_idx_attr, sizeof(cons_idx_attr),
414d807dd7dSXiaoyun Wang &cons_idx_attr, &out_size, 0);
415d807dd7dSXiaoyun Wang if (err || !out_size || cons_idx_attr.mgmt_msg_head.status) {
416d807dd7dSXiaoyun Wang PMD_DRV_LOG(ERR, "Set ci attribute table failed, err: %d, status: 0x%x, out_size: 0x%x",
417d807dd7dSXiaoyun Wang err, cons_idx_attr.mgmt_msg_head.status, out_size);
418d807dd7dSXiaoyun Wang return -EIO;
419d807dd7dSXiaoyun Wang }
420d807dd7dSXiaoyun Wang
421d807dd7dSXiaoyun Wang return 0;
422d9ce1917SZiyang Xuan }
423d9ce1917SZiyang Xuan
424d9ce1917SZiyang Xuan /**
425d9ce1917SZiyang Xuan * hinic_set_pagesize - set page size to vat table
426d9ce1917SZiyang Xuan * @hwdev: the hardware interface of a nic device
427d9ce1917SZiyang Xuan * @page_size: vat page size
428d9ce1917SZiyang Xuan * @return
429d9ce1917SZiyang Xuan * 0 on success,
430d9ce1917SZiyang Xuan * negative error value otherwise.
431b8582d05SXiaoyun Wang */
hinic_set_pagesize(void * hwdev,u8 page_size)432d9ce1917SZiyang Xuan int hinic_set_pagesize(void *hwdev, u8 page_size)
433d9ce1917SZiyang Xuan {
434d807dd7dSXiaoyun Wang struct hinic_page_size page_size_info;
435d807dd7dSXiaoyun Wang u16 out_size = sizeof(page_size_info);
436d807dd7dSXiaoyun Wang int err;
437d9ce1917SZiyang Xuan
438d9ce1917SZiyang Xuan if (page_size > HINIC_PAGE_SIZE_MAX) {
439d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Invalid page_size %u, bigger than %u",
440d9ce1917SZiyang Xuan page_size, HINIC_PAGE_SIZE_MAX);
441d9ce1917SZiyang Xuan return -EINVAL;
442d9ce1917SZiyang Xuan }
443d9ce1917SZiyang Xuan
444d807dd7dSXiaoyun Wang memset(&page_size_info, 0, sizeof(page_size_info));
445d807dd7dSXiaoyun Wang page_size_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
446d807dd7dSXiaoyun Wang page_size_info.func_idx = hinic_global_func_id(hwdev);
447d807dd7dSXiaoyun Wang page_size_info.ppf_idx = hinic_ppf_idx(hwdev);
448d807dd7dSXiaoyun Wang page_size_info.page_size = page_size;
449d9ce1917SZiyang Xuan
450d807dd7dSXiaoyun Wang err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
451d9ce1917SZiyang Xuan HINIC_MGMT_CMD_PAGESIZE_SET,
452d807dd7dSXiaoyun Wang &page_size_info, sizeof(page_size_info),
453d807dd7dSXiaoyun Wang &page_size_info, &out_size, 0);
454d807dd7dSXiaoyun Wang if (err || !out_size || page_size_info.mgmt_msg_head.status) {
455d807dd7dSXiaoyun Wang PMD_DRV_LOG(ERR, "Set wq page size failed, err: %d, status: 0x%x, out_size: 0x%0x",
456d807dd7dSXiaoyun Wang err, page_size_info.mgmt_msg_head.status, out_size);
457d807dd7dSXiaoyun Wang return -EIO;
458d807dd7dSXiaoyun Wang }
459d807dd7dSXiaoyun Wang
460d807dd7dSXiaoyun Wang return 0;
461d9ce1917SZiyang Xuan }
462d9ce1917SZiyang Xuan
wait_for_flr_finish(struct hinic_hwif * hwif)463d9ce1917SZiyang Xuan static int wait_for_flr_finish(struct hinic_hwif *hwif)
464d9ce1917SZiyang Xuan {
465d9ce1917SZiyang Xuan unsigned long end;
466d9ce1917SZiyang Xuan enum hinic_pf_status status;
467d9ce1917SZiyang Xuan
468d9ce1917SZiyang Xuan end = jiffies + msecs_to_jiffies(HINIC_FLR_TIMEOUT);
469d9ce1917SZiyang Xuan do {
470d9ce1917SZiyang Xuan status = hinic_get_pf_status(hwif);
471d9ce1917SZiyang Xuan if (status == HINIC_PF_STATUS_FLR_FINISH_FLAG) {
472d9ce1917SZiyang Xuan return 0;
473d9ce1917SZiyang Xuan }
474d9ce1917SZiyang Xuan
475d9ce1917SZiyang Xuan rte_delay_ms(10);
476d9ce1917SZiyang Xuan } while (time_before(jiffies, end));
477d9ce1917SZiyang Xuan
4783260064aSXiaoyun Wang return -ETIMEDOUT;
479d9ce1917SZiyang Xuan }
480d9ce1917SZiyang Xuan
481d9ce1917SZiyang Xuan #define HINIC_WAIT_CMDQ_IDLE_TIMEOUT 1000
482d9ce1917SZiyang Xuan
wait_cmdq_stop(struct hinic_hwdev * hwdev)483d9ce1917SZiyang Xuan static int wait_cmdq_stop(struct hinic_hwdev *hwdev)
484d9ce1917SZiyang Xuan {
485d9ce1917SZiyang Xuan enum hinic_cmdq_type cmdq_type;
486d9ce1917SZiyang Xuan struct hinic_cmdqs *cmdqs = hwdev->cmdqs;
487d9ce1917SZiyang Xuan unsigned long end;
488d9ce1917SZiyang Xuan int err = 0;
489d9ce1917SZiyang Xuan
490d9ce1917SZiyang Xuan if (!(cmdqs->status & HINIC_CMDQ_ENABLE))
491d9ce1917SZiyang Xuan return 0;
492d9ce1917SZiyang Xuan
493d9ce1917SZiyang Xuan cmdqs->status &= ~HINIC_CMDQ_ENABLE;
494d9ce1917SZiyang Xuan
495d9ce1917SZiyang Xuan end = jiffies + msecs_to_jiffies(HINIC_WAIT_CMDQ_IDLE_TIMEOUT);
496d9ce1917SZiyang Xuan do {
497d9ce1917SZiyang Xuan err = 0;
498d9ce1917SZiyang Xuan cmdq_type = HINIC_CMDQ_SYNC;
499d9ce1917SZiyang Xuan for (; cmdq_type < HINIC_MAX_CMDQ_TYPES; cmdq_type++) {
500d9ce1917SZiyang Xuan if (!hinic_cmdq_idle(&cmdqs->cmdq[cmdq_type])) {
501d9ce1917SZiyang Xuan err = -EBUSY;
502d9ce1917SZiyang Xuan break;
503d9ce1917SZiyang Xuan }
504d9ce1917SZiyang Xuan }
505d9ce1917SZiyang Xuan
506d9ce1917SZiyang Xuan if (!err)
507d9ce1917SZiyang Xuan return 0;
508d9ce1917SZiyang Xuan
509d9ce1917SZiyang Xuan rte_delay_ms(1);
510d9ce1917SZiyang Xuan } while (time_before(jiffies, end));
511d9ce1917SZiyang Xuan
512d9ce1917SZiyang Xuan cmdqs->status |= HINIC_CMDQ_ENABLE;
513d9ce1917SZiyang Xuan
514d9ce1917SZiyang Xuan return err;
515d9ce1917SZiyang Xuan }
516d9ce1917SZiyang Xuan
hinic_vf_rx_tx_flush(struct hinic_hwdev * hwdev)517b8582d05SXiaoyun Wang static int hinic_vf_rx_tx_flush(struct hinic_hwdev *hwdev)
518b8582d05SXiaoyun Wang {
519b8582d05SXiaoyun Wang struct hinic_clear_resource clr_res;
520b8582d05SXiaoyun Wang int err;
521b8582d05SXiaoyun Wang
522b8582d05SXiaoyun Wang err = wait_cmdq_stop(hwdev);
523b8582d05SXiaoyun Wang if (err) {
524b8582d05SXiaoyun Wang PMD_DRV_LOG(WARNING, "Cmdq is still working");
525b8582d05SXiaoyun Wang return err;
526b8582d05SXiaoyun Wang }
527b8582d05SXiaoyun Wang
528b8582d05SXiaoyun Wang memset(&clr_res, 0, sizeof(clr_res));
529b8582d05SXiaoyun Wang clr_res.func_idx = HINIC_HWIF_GLOBAL_IDX(hwdev->hwif);
530b8582d05SXiaoyun Wang clr_res.ppf_idx = HINIC_HWIF_PPF_IDX(hwdev->hwif);
531b8582d05SXiaoyun Wang err = hinic_mbox_to_pf_no_ack(hwdev, HINIC_MOD_COMM,
532b8582d05SXiaoyun Wang HINIC_MGMT_CMD_START_FLR, &clr_res, sizeof(clr_res));
533b8582d05SXiaoyun Wang if (err)
534b8582d05SXiaoyun Wang PMD_DRV_LOG(WARNING, "Notice flush message failed");
535b8582d05SXiaoyun Wang
536b8582d05SXiaoyun Wang /*
537b8582d05SXiaoyun Wang * PF firstly set VF doorbell flush csr to be disabled. After PF finish
538b8582d05SXiaoyun Wang * VF resources flush, PF will set VF doorbell flush csr to be enabled.
539b8582d05SXiaoyun Wang */
540b8582d05SXiaoyun Wang err = wait_until_doorbell_flush_states(hwdev->hwif, DISABLE_DOORBELL);
541b8582d05SXiaoyun Wang if (err)
542b8582d05SXiaoyun Wang PMD_DRV_LOG(WARNING, "Wait doorbell flush disable timeout");
543b8582d05SXiaoyun Wang
544b8582d05SXiaoyun Wang err = wait_until_doorbell_flush_states(hwdev->hwif, ENABLE_DOORBELL);
545b8582d05SXiaoyun Wang if (err)
546b8582d05SXiaoyun Wang PMD_DRV_LOG(WARNING, "Wait doorbell flush enable timeout");
547b8582d05SXiaoyun Wang
548b8582d05SXiaoyun Wang err = hinic_reinit_cmdq_ctxts(hwdev);
549b8582d05SXiaoyun Wang if (err)
550036b61d8SXiaoyun Wang PMD_DRV_LOG(WARNING, "Reinit cmdq failed when vf flush");
551b8582d05SXiaoyun Wang
552b8582d05SXiaoyun Wang return err;
553b8582d05SXiaoyun Wang }
554b8582d05SXiaoyun Wang
555d9ce1917SZiyang Xuan /**
556d9ce1917SZiyang Xuan * hinic_pf_rx_tx_flush - clean up hardware resource
557d9ce1917SZiyang Xuan * @hwdev: the hardware interface of a nic device
558d9ce1917SZiyang Xuan * @return
559d9ce1917SZiyang Xuan * 0 on success,
560d9ce1917SZiyang Xuan * negative error value otherwise.
561b8582d05SXiaoyun Wang */
hinic_pf_rx_tx_flush(struct hinic_hwdev * hwdev)562d9ce1917SZiyang Xuan static int hinic_pf_rx_tx_flush(struct hinic_hwdev *hwdev)
563d9ce1917SZiyang Xuan {
564d9ce1917SZiyang Xuan struct hinic_hwif *hwif = hwdev->hwif;
565d9ce1917SZiyang Xuan struct hinic_clear_doorbell clear_db;
566d9ce1917SZiyang Xuan struct hinic_clear_resource clr_res;
567d807dd7dSXiaoyun Wang u16 out_size;
568d9ce1917SZiyang Xuan int err;
569d807dd7dSXiaoyun Wang int ret = 0;
570d9ce1917SZiyang Xuan
571d9ce1917SZiyang Xuan rte_delay_ms(100);
572d9ce1917SZiyang Xuan
573d9ce1917SZiyang Xuan err = wait_cmdq_stop(hwdev);
574d9ce1917SZiyang Xuan if (err) {
575d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Cmdq is still working");
576d9ce1917SZiyang Xuan return err;
577d9ce1917SZiyang Xuan }
578d9ce1917SZiyang Xuan
579d9ce1917SZiyang Xuan hinic_disable_doorbell(hwif);
580d807dd7dSXiaoyun Wang out_size = sizeof(clear_db);
581d9ce1917SZiyang Xuan memset(&clear_db, 0, sizeof(clear_db));
582d9ce1917SZiyang Xuan clear_db.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
583d9ce1917SZiyang Xuan clear_db.func_idx = HINIC_HWIF_GLOBAL_IDX(hwif);
584d9ce1917SZiyang Xuan clear_db.ppf_idx = HINIC_HWIF_PPF_IDX(hwif);
585d9ce1917SZiyang Xuan err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
586d9ce1917SZiyang Xuan HINIC_MGMT_CMD_FLUSH_DOORBELL, &clear_db,
587d807dd7dSXiaoyun Wang sizeof(clear_db), &clear_db, &out_size, 0);
588d807dd7dSXiaoyun Wang if (err || !out_size || clear_db.mgmt_msg_head.status) {
589d807dd7dSXiaoyun Wang PMD_DRV_LOG(WARNING, "Flush doorbell failed, err: %d, status: 0x%x, out_size: 0x%x",
590d807dd7dSXiaoyun Wang err, clear_db.mgmt_msg_head.status, out_size);
591d807dd7dSXiaoyun Wang ret = err ? err : (-EIO);
592d807dd7dSXiaoyun Wang }
593d9ce1917SZiyang Xuan
594d9ce1917SZiyang Xuan hinic_set_pf_status(hwif, HINIC_PF_STATUS_FLR_START_FLAG);
595d9ce1917SZiyang Xuan memset(&clr_res, 0, sizeof(clr_res));
596d9ce1917SZiyang Xuan clr_res.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
597d9ce1917SZiyang Xuan clr_res.func_idx = HINIC_HWIF_GLOBAL_IDX(hwif);
598d9ce1917SZiyang Xuan clr_res.ppf_idx = HINIC_HWIF_PPF_IDX(hwif);
599d9ce1917SZiyang Xuan
600d9ce1917SZiyang Xuan err = hinic_msg_to_mgmt_no_ack(hwdev, HINIC_MOD_COMM,
601d9ce1917SZiyang Xuan HINIC_MGMT_CMD_START_FLR, &clr_res,
602214164a6SXiaoyun Wang sizeof(clr_res));
603d807dd7dSXiaoyun Wang if (err) {
604d807dd7dSXiaoyun Wang PMD_DRV_LOG(WARNING, "Notice flush msg failed, err: %d", err);
605d807dd7dSXiaoyun Wang ret = err;
606d807dd7dSXiaoyun Wang }
607d9ce1917SZiyang Xuan
608d9ce1917SZiyang Xuan err = wait_for_flr_finish(hwif);
609d807dd7dSXiaoyun Wang if (err) {
610d807dd7dSXiaoyun Wang PMD_DRV_LOG(WARNING, "Wait firmware FLR timeout, err: %d", err);
611d807dd7dSXiaoyun Wang ret = err;
612d807dd7dSXiaoyun Wang }
613d9ce1917SZiyang Xuan
614d9ce1917SZiyang Xuan hinic_enable_doorbell(hwif);
615d9ce1917SZiyang Xuan
616d9ce1917SZiyang Xuan err = hinic_reinit_cmdq_ctxts(hwdev);
617d807dd7dSXiaoyun Wang if (err) {
618d807dd7dSXiaoyun Wang PMD_DRV_LOG(WARNING,
619d807dd7dSXiaoyun Wang "Reinit cmdq failed when pf flush, err: %d", err);
620d807dd7dSXiaoyun Wang ret = err;
621d807dd7dSXiaoyun Wang }
622d9ce1917SZiyang Xuan
623d807dd7dSXiaoyun Wang return ret;
624d9ce1917SZiyang Xuan }
625d9ce1917SZiyang Xuan
hinic_func_rx_tx_flush(struct hinic_hwdev * hwdev)626d9ce1917SZiyang Xuan int hinic_func_rx_tx_flush(struct hinic_hwdev *hwdev)
627d9ce1917SZiyang Xuan {
628b8582d05SXiaoyun Wang if (HINIC_FUNC_TYPE(hwdev) == TYPE_VF)
629b8582d05SXiaoyun Wang return hinic_vf_rx_tx_flush(hwdev);
630b8582d05SXiaoyun Wang else
631d9ce1917SZiyang Xuan return hinic_pf_rx_tx_flush(hwdev);
632d9ce1917SZiyang Xuan }
633d9ce1917SZiyang Xuan
634d9ce1917SZiyang Xuan /**
635d9ce1917SZiyang Xuan * hinic_get_interrupt_cfg - get interrupt configuration from NIC
636d9ce1917SZiyang Xuan * @hwdev: the hardware interface of a nic device
637d9ce1917SZiyang Xuan * @interrupt_info: Information of Interrupt aggregation
638d9ce1917SZiyang Xuan * Return: 0 on success, negative error value otherwise.
639b8582d05SXiaoyun Wang */
hinic_get_interrupt_cfg(struct hinic_hwdev * hwdev,struct nic_interrupt_info * interrupt_info)640d9ce1917SZiyang Xuan static int hinic_get_interrupt_cfg(struct hinic_hwdev *hwdev,
641d9ce1917SZiyang Xuan struct nic_interrupt_info *interrupt_info)
642d9ce1917SZiyang Xuan {
643d9ce1917SZiyang Xuan struct hinic_msix_config msix_cfg;
644d9ce1917SZiyang Xuan u16 out_size = sizeof(msix_cfg);
645d9ce1917SZiyang Xuan int err;
646d9ce1917SZiyang Xuan
647d9ce1917SZiyang Xuan memset(&msix_cfg, 0, sizeof(msix_cfg));
648d9ce1917SZiyang Xuan msix_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
649d9ce1917SZiyang Xuan msix_cfg.func_id = hinic_global_func_id(hwdev);
650d9ce1917SZiyang Xuan msix_cfg.msix_index = interrupt_info->msix_index;
651d9ce1917SZiyang Xuan
652d9ce1917SZiyang Xuan err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
653d9ce1917SZiyang Xuan HINIC_MGMT_CMD_MSI_CTRL_REG_RD_BY_UP,
654d9ce1917SZiyang Xuan &msix_cfg, sizeof(msix_cfg),
655d9ce1917SZiyang Xuan &msix_cfg, &out_size, 0);
656d9ce1917SZiyang Xuan if (err || !out_size || msix_cfg.mgmt_msg_head.status) {
657d807dd7dSXiaoyun Wang PMD_DRV_LOG(ERR, "Get interrupt config failed, err: %d, status: 0x%x, out size: 0x%x",
658d807dd7dSXiaoyun Wang err, msix_cfg.mgmt_msg_head.status, out_size);
659d807dd7dSXiaoyun Wang return -EIO;
660d9ce1917SZiyang Xuan }
661d9ce1917SZiyang Xuan
662d9ce1917SZiyang Xuan interrupt_info->lli_credit_limit = msix_cfg.lli_credit_cnt;
663d9ce1917SZiyang Xuan interrupt_info->lli_timer_cfg = msix_cfg.lli_tmier_cnt;
664d9ce1917SZiyang Xuan interrupt_info->pending_limt = msix_cfg.pending_cnt;
665d9ce1917SZiyang Xuan interrupt_info->coalesc_timer_cfg = msix_cfg.coalesct_timer_cnt;
666d9ce1917SZiyang Xuan interrupt_info->resend_timer_cfg = msix_cfg.resend_timer_cnt;
667d9ce1917SZiyang Xuan return 0;
668d9ce1917SZiyang Xuan }
669d9ce1917SZiyang Xuan
670d9ce1917SZiyang Xuan /**
671d9ce1917SZiyang Xuan * hinic_set_interrupt_cfg - set interrupt configuration to NIC
672d9ce1917SZiyang Xuan * @hwdev: the hardware interface of a nic device
673d9ce1917SZiyang Xuan * @interrupt_info: Information of Interrupt aggregation
674d9ce1917SZiyang Xuan * Return: 0 on success, negative error value otherwise.
675b8582d05SXiaoyun Wang */
hinic_set_interrupt_cfg(struct hinic_hwdev * hwdev,struct nic_interrupt_info interrupt_info)676d9ce1917SZiyang Xuan int hinic_set_interrupt_cfg(struct hinic_hwdev *hwdev,
677d9ce1917SZiyang Xuan struct nic_interrupt_info interrupt_info)
678d9ce1917SZiyang Xuan {
679d9ce1917SZiyang Xuan struct hinic_msix_config msix_cfg;
680d9ce1917SZiyang Xuan struct nic_interrupt_info temp_info;
681d9ce1917SZiyang Xuan u16 out_size = sizeof(msix_cfg);
682d9ce1917SZiyang Xuan int err;
683d9ce1917SZiyang Xuan
6842ae8e130SXiaoyun Wang temp_info.msix_index = interrupt_info.msix_index;
6852ae8e130SXiaoyun Wang err = hinic_get_interrupt_cfg(hwdev, &temp_info);
6862ae8e130SXiaoyun Wang if (err)
6872ae8e130SXiaoyun Wang return -EIO;
6882ae8e130SXiaoyun Wang
689d9ce1917SZiyang Xuan memset(&msix_cfg, 0, sizeof(msix_cfg));
690d9ce1917SZiyang Xuan msix_cfg.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
691d9ce1917SZiyang Xuan msix_cfg.func_id = hinic_global_func_id(hwdev);
692d9ce1917SZiyang Xuan msix_cfg.msix_index = (u16)interrupt_info.msix_index;
693d9ce1917SZiyang Xuan msix_cfg.lli_credit_cnt = temp_info.lli_credit_limit;
694d9ce1917SZiyang Xuan msix_cfg.lli_tmier_cnt = temp_info.lli_timer_cfg;
695d9ce1917SZiyang Xuan msix_cfg.pending_cnt = temp_info.pending_limt;
696d9ce1917SZiyang Xuan msix_cfg.coalesct_timer_cnt = temp_info.coalesc_timer_cfg;
697d9ce1917SZiyang Xuan msix_cfg.resend_timer_cnt = temp_info.resend_timer_cfg;
698d9ce1917SZiyang Xuan
699d9ce1917SZiyang Xuan if (interrupt_info.lli_set) {
700d9ce1917SZiyang Xuan msix_cfg.lli_credit_cnt = interrupt_info.lli_credit_limit;
701d9ce1917SZiyang Xuan msix_cfg.lli_tmier_cnt = interrupt_info.lli_timer_cfg;
702d9ce1917SZiyang Xuan }
703d9ce1917SZiyang Xuan
704d9ce1917SZiyang Xuan if (interrupt_info.interrupt_coalesc_set) {
705d9ce1917SZiyang Xuan msix_cfg.pending_cnt = interrupt_info.pending_limt;
706d9ce1917SZiyang Xuan msix_cfg.coalesct_timer_cnt = interrupt_info.coalesc_timer_cfg;
707d9ce1917SZiyang Xuan msix_cfg.resend_timer_cnt = interrupt_info.resend_timer_cfg;
708d9ce1917SZiyang Xuan }
709d9ce1917SZiyang Xuan
710d9ce1917SZiyang Xuan err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
711d9ce1917SZiyang Xuan HINIC_MGMT_CMD_MSI_CTRL_REG_WR_BY_UP,
712d9ce1917SZiyang Xuan &msix_cfg, sizeof(msix_cfg),
713d9ce1917SZiyang Xuan &msix_cfg, &out_size, 0);
714d9ce1917SZiyang Xuan if (err || !out_size || msix_cfg.mgmt_msg_head.status) {
715d807dd7dSXiaoyun Wang PMD_DRV_LOG(ERR, "Set interrupt config failed, err: %d, status: 0x%x, out size: 0x%x",
716d807dd7dSXiaoyun Wang err, msix_cfg.mgmt_msg_head.status, out_size);
717d807dd7dSXiaoyun Wang return -EIO;
718d9ce1917SZiyang Xuan }
719d9ce1917SZiyang Xuan
720d9ce1917SZiyang Xuan return 0;
721d9ce1917SZiyang Xuan }
722d9ce1917SZiyang Xuan
723d9ce1917SZiyang Xuan /**
724d9ce1917SZiyang Xuan * init_aeqs_msix_attr - Init interrupt attributes of aeq
725d9ce1917SZiyang Xuan * @hwdev: the hardware interface of a nic device
726d9ce1917SZiyang Xuan * @return
727d9ce1917SZiyang Xuan * 0 on success,
728d9ce1917SZiyang Xuan * negative error value otherwise.
729b8582d05SXiaoyun Wang */
init_aeqs_msix_attr(void * hwdev)730d9ce1917SZiyang Xuan int init_aeqs_msix_attr(void *hwdev)
731d9ce1917SZiyang Xuan {
732d9ce1917SZiyang Xuan struct hinic_hwdev *nic_hwdev = hwdev;
733d9ce1917SZiyang Xuan struct hinic_aeqs *aeqs = nic_hwdev->aeqs;
734d9ce1917SZiyang Xuan struct nic_interrupt_info info = {0};
735d9ce1917SZiyang Xuan struct hinic_eq *eq;
736d9ce1917SZiyang Xuan u16 q_id;
737d9ce1917SZiyang Xuan int err;
738d9ce1917SZiyang Xuan
739d9ce1917SZiyang Xuan info.lli_set = 0;
740d9ce1917SZiyang Xuan info.interrupt_coalesc_set = 1;
741d9ce1917SZiyang Xuan info.pending_limt = HINIC_DEAULT_EQ_MSIX_PENDING_LIMIT;
742d9ce1917SZiyang Xuan info.coalesc_timer_cfg = HINIC_DEAULT_EQ_MSIX_COALESC_TIMER_CFG;
743d9ce1917SZiyang Xuan info.resend_timer_cfg = HINIC_DEAULT_EQ_MSIX_RESEND_TIMER_CFG;
744d9ce1917SZiyang Xuan
745d9ce1917SZiyang Xuan for (q_id = 0; q_id < aeqs->num_aeqs; q_id++) {
746d9ce1917SZiyang Xuan eq = &aeqs->aeq[q_id];
747d9ce1917SZiyang Xuan info.msix_index = eq->eq_irq.msix_entry_idx;
748d9ce1917SZiyang Xuan err = hinic_set_interrupt_cfg(hwdev, info);
749d9ce1917SZiyang Xuan if (err) {
750d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Set msix attr for aeq %d failed",
751d9ce1917SZiyang Xuan q_id);
752d9ce1917SZiyang Xuan return -EFAULT;
753d9ce1917SZiyang Xuan }
754d9ce1917SZiyang Xuan }
755d9ce1917SZiyang Xuan
756d9ce1917SZiyang Xuan return 0;
757d9ce1917SZiyang Xuan }
758d9ce1917SZiyang Xuan
759d9ce1917SZiyang Xuan /**
760d9ce1917SZiyang Xuan * set_pf_dma_attr_entry - set the dma attributes for entry
761d9ce1917SZiyang Xuan * @hwdev: the pointer to the private hardware device object
762d9ce1917SZiyang Xuan * @entry_idx: the entry index in the dma table
763d9ce1917SZiyang Xuan * @st: PCIE TLP steering tag
764d9ce1917SZiyang Xuan * @at: PCIE TLP AT field
765d9ce1917SZiyang Xuan * @ph: PCIE TLP Processing Hint field
766d9ce1917SZiyang Xuan * @no_snooping: PCIE TLP No snooping
767d9ce1917SZiyang Xuan * @tph_en: PCIE TLP Processing Hint Enable
768b8582d05SXiaoyun Wang */
set_pf_dma_attr_entry(struct hinic_hwdev * hwdev,u32 entry_idx,u8 st,u8 at,u8 ph,enum hinic_pcie_nosnoop no_snooping,enum hinic_pcie_tph tph_en)769d9ce1917SZiyang Xuan static void set_pf_dma_attr_entry(struct hinic_hwdev *hwdev, u32 entry_idx,
770d9ce1917SZiyang Xuan u8 st, u8 at, u8 ph,
771d9ce1917SZiyang Xuan enum hinic_pcie_nosnoop no_snooping,
772d9ce1917SZiyang Xuan enum hinic_pcie_tph tph_en)
773d9ce1917SZiyang Xuan {
774d9ce1917SZiyang Xuan u32 addr, val, dma_attr_entry;
775d9ce1917SZiyang Xuan
776d9ce1917SZiyang Xuan /* Read Modify Write */
777d9ce1917SZiyang Xuan addr = HINIC_CSR_DMA_ATTR_TBL_ADDR(entry_idx);
778d9ce1917SZiyang Xuan
779d9ce1917SZiyang Xuan val = hinic_hwif_read_reg(hwdev->hwif, addr);
780d9ce1917SZiyang Xuan val = HINIC_DMA_ATTR_ENTRY_CLEAR(val, ST) &
781d9ce1917SZiyang Xuan HINIC_DMA_ATTR_ENTRY_CLEAR(val, AT) &
782d9ce1917SZiyang Xuan HINIC_DMA_ATTR_ENTRY_CLEAR(val, PH) &
783d9ce1917SZiyang Xuan HINIC_DMA_ATTR_ENTRY_CLEAR(val, NO_SNOOPING) &
784d9ce1917SZiyang Xuan HINIC_DMA_ATTR_ENTRY_CLEAR(val, TPH_EN);
785d9ce1917SZiyang Xuan
786d9ce1917SZiyang Xuan dma_attr_entry = HINIC_DMA_ATTR_ENTRY_SET(st, ST) |
787d9ce1917SZiyang Xuan HINIC_DMA_ATTR_ENTRY_SET(at, AT) |
788d9ce1917SZiyang Xuan HINIC_DMA_ATTR_ENTRY_SET(ph, PH) |
789d9ce1917SZiyang Xuan HINIC_DMA_ATTR_ENTRY_SET(no_snooping, NO_SNOOPING) |
790d9ce1917SZiyang Xuan HINIC_DMA_ATTR_ENTRY_SET(tph_en, TPH_EN);
791d9ce1917SZiyang Xuan
792d9ce1917SZiyang Xuan val |= dma_attr_entry;
793d9ce1917SZiyang Xuan hinic_hwif_write_reg(hwdev->hwif, addr, val);
794d9ce1917SZiyang Xuan }
795d9ce1917SZiyang Xuan
set_vf_dma_attr_entry(struct hinic_hwdev * hwdev,u8 entry_idx,u8 st,u8 at,u8 ph,enum hinic_pcie_nosnoop no_snooping,enum hinic_pcie_tph tph_en)796b8582d05SXiaoyun Wang static int set_vf_dma_attr_entry(struct hinic_hwdev *hwdev, u8 entry_idx,
797b8582d05SXiaoyun Wang u8 st, u8 at, u8 ph,
798b8582d05SXiaoyun Wang enum hinic_pcie_nosnoop no_snooping,
799b8582d05SXiaoyun Wang enum hinic_pcie_tph tph_en)
800b8582d05SXiaoyun Wang {
801b8582d05SXiaoyun Wang struct hinic_vf_dma_attr_table attr;
802d807dd7dSXiaoyun Wang u16 out_size = sizeof(attr);
803d807dd7dSXiaoyun Wang int err;
804b8582d05SXiaoyun Wang
805b8582d05SXiaoyun Wang memset(&attr, 0, sizeof(attr));
806b8582d05SXiaoyun Wang attr.func_idx = hinic_global_func_id(hwdev);
807b8582d05SXiaoyun Wang attr.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
808b8582d05SXiaoyun Wang attr.func_dma_entry_num = hinic_dma_attr_entry_num(hwdev);
809b8582d05SXiaoyun Wang attr.entry_idx = entry_idx;
810b8582d05SXiaoyun Wang attr.st = st;
811b8582d05SXiaoyun Wang attr.at = at;
812b8582d05SXiaoyun Wang attr.ph = ph;
813b8582d05SXiaoyun Wang attr.no_snooping = no_snooping;
814b8582d05SXiaoyun Wang attr.tph_en = tph_en;
815b8582d05SXiaoyun Wang
816d807dd7dSXiaoyun Wang err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
817b8582d05SXiaoyun Wang HINIC_MGMT_CMD_DMA_ATTR_SET,
818d807dd7dSXiaoyun Wang &attr, sizeof(attr), &attr, &out_size, 0);
819d807dd7dSXiaoyun Wang if (err || !out_size || attr.mgmt_msg_head.status) {
820d807dd7dSXiaoyun Wang PMD_DRV_LOG(ERR, "Set dma attribute failed, err: %d, status: 0x%x, out_size: 0x%x",
821d807dd7dSXiaoyun Wang err, attr.mgmt_msg_head.status, out_size);
822d807dd7dSXiaoyun Wang return -EIO;
823d807dd7dSXiaoyun Wang }
824d807dd7dSXiaoyun Wang
825d807dd7dSXiaoyun Wang return 0;
826b8582d05SXiaoyun Wang }
827b8582d05SXiaoyun Wang
828d9ce1917SZiyang Xuan /**
829b53d106dSSean Morrissey * dma_attr_table_init - initialize the default dma attributes
830d9ce1917SZiyang Xuan * @hwdev: the pointer to the private hardware device object
831b8582d05SXiaoyun Wang */
dma_attr_table_init(struct hinic_hwdev * hwdev)832b8582d05SXiaoyun Wang static int dma_attr_table_init(struct hinic_hwdev *hwdev)
833d9ce1917SZiyang Xuan {
834b8582d05SXiaoyun Wang int err = 0;
835d9ce1917SZiyang Xuan
836b8582d05SXiaoyun Wang if (HINIC_IS_VF(hwdev))
837b8582d05SXiaoyun Wang err = set_vf_dma_attr_entry(hwdev, PCIE_MSIX_ATTR_ENTRY,
838b8582d05SXiaoyun Wang HINIC_PCIE_ST_DISABLE, HINIC_PCIE_AT_DISABLE,
839b8582d05SXiaoyun Wang HINIC_PCIE_PH_DISABLE, HINIC_PCIE_SNOOP,
840d9ce1917SZiyang Xuan HINIC_PCIE_TPH_DISABLE);
841b8582d05SXiaoyun Wang else
842b8582d05SXiaoyun Wang set_pf_dma_attr_entry(hwdev, PCIE_MSIX_ATTR_ENTRY,
843b8582d05SXiaoyun Wang HINIC_PCIE_ST_DISABLE, HINIC_PCIE_AT_DISABLE,
844b8582d05SXiaoyun Wang HINIC_PCIE_PH_DISABLE, HINIC_PCIE_SNOOP,
845b8582d05SXiaoyun Wang HINIC_PCIE_TPH_DISABLE);
846b8582d05SXiaoyun Wang
847b8582d05SXiaoyun Wang return err;
848d9ce1917SZiyang Xuan }
849d9ce1917SZiyang Xuan
850b8582d05SXiaoyun Wang /**
851b8582d05SXiaoyun Wang * hinic_init_attr_table - init dma and aeq msix attribute table
852b8582d05SXiaoyun Wang * @hwdev: the pointer to the private hardware device object
853b8582d05SXiaoyun Wang */
hinic_init_attr_table(struct hinic_hwdev * hwdev)854d9ce1917SZiyang Xuan int hinic_init_attr_table(struct hinic_hwdev *hwdev)
855d9ce1917SZiyang Xuan {
856b8582d05SXiaoyun Wang int err;
857d9ce1917SZiyang Xuan
858b8582d05SXiaoyun Wang err = dma_attr_table_init(hwdev);
859b8582d05SXiaoyun Wang if (err) {
860b8582d05SXiaoyun Wang PMD_DRV_LOG(ERR, "Initialize dma attribute table failed, err: %d",
861b8582d05SXiaoyun Wang err);
862b8582d05SXiaoyun Wang return err;
863b8582d05SXiaoyun Wang }
864b8582d05SXiaoyun Wang
865b8582d05SXiaoyun Wang err = init_aeqs_msix_attr(hwdev);
866b8582d05SXiaoyun Wang if (err) {
867b8582d05SXiaoyun Wang PMD_DRV_LOG(ERR, "Initialize aeqs msix attribute failed, err: %d",
868b8582d05SXiaoyun Wang err);
869b8582d05SXiaoyun Wang return err;
870b8582d05SXiaoyun Wang }
871b8582d05SXiaoyun Wang
872b8582d05SXiaoyun Wang return 0;
873d9ce1917SZiyang Xuan }
874d9ce1917SZiyang Xuan
875d9ce1917SZiyang Xuan #define FAULT_SHOW_STR_LEN 16
fault_report_show(struct hinic_hwdev * hwdev,struct hinic_fault_event * event)876d9ce1917SZiyang Xuan static void fault_report_show(struct hinic_hwdev *hwdev,
877d9ce1917SZiyang Xuan struct hinic_fault_event *event)
878d9ce1917SZiyang Xuan {
879d9ce1917SZiyang Xuan char fault_type[FAULT_TYPE_MAX][FAULT_SHOW_STR_LEN + 1] = {
880d9ce1917SZiyang Xuan "chip", "ucode", "mem rd timeout", "mem wr timeout",
881d9ce1917SZiyang Xuan "reg rd timeout", "reg wr timeout"};
882d9ce1917SZiyang Xuan char fault_level[FAULT_LEVEL_MAX][FAULT_SHOW_STR_LEN + 1] = {
883d9ce1917SZiyang Xuan "fatal", "reset", "flr", "general", "suggestion"};
884d9ce1917SZiyang Xuan char type_str[FAULT_SHOW_STR_LEN + 1] = { 0 };
885d9ce1917SZiyang Xuan char level_str[FAULT_SHOW_STR_LEN + 1] = { 0 };
886d9ce1917SZiyang Xuan u8 err_level;
887d9ce1917SZiyang Xuan
888d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "Fault event report received, func_id: %d",
889d9ce1917SZiyang Xuan hinic_global_func_id(hwdev));
890d9ce1917SZiyang Xuan
891d9ce1917SZiyang Xuan if (event->type < FAULT_TYPE_MAX)
892d9ce1917SZiyang Xuan strncpy(type_str, fault_type[event->type], FAULT_SHOW_STR_LEN);
893d9ce1917SZiyang Xuan else
894d9ce1917SZiyang Xuan strncpy(type_str, "unknown", FAULT_SHOW_STR_LEN);
895d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "fault type: %d [%s]",
896d9ce1917SZiyang Xuan event->type, type_str);
897d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "fault val[0]: 0x%08x",
898d9ce1917SZiyang Xuan event->event.val[0]);
899d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "fault val[1]: 0x%08x",
900d9ce1917SZiyang Xuan event->event.val[1]);
901d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "fault val[2]: 0x%08x",
902d9ce1917SZiyang Xuan event->event.val[2]);
903d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "fault val[3]: 0x%08x",
904d9ce1917SZiyang Xuan event->event.val[3]);
905d9ce1917SZiyang Xuan
906d9ce1917SZiyang Xuan switch (event->type) {
907d9ce1917SZiyang Xuan case FAULT_TYPE_CHIP:
908d9ce1917SZiyang Xuan err_level = event->event.chip.err_level;
909d9ce1917SZiyang Xuan if (err_level < FAULT_LEVEL_MAX)
910d9ce1917SZiyang Xuan strncpy(level_str, fault_level[err_level],
911d9ce1917SZiyang Xuan FAULT_SHOW_STR_LEN);
912d9ce1917SZiyang Xuan else
913d9ce1917SZiyang Xuan strncpy(level_str, "unknown",
914d9ce1917SZiyang Xuan FAULT_SHOW_STR_LEN);
915d9ce1917SZiyang Xuan
916d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "err_level: %d [%s]",
917d9ce1917SZiyang Xuan err_level, level_str);
918d9ce1917SZiyang Xuan
919d9ce1917SZiyang Xuan if (err_level == FAULT_LEVEL_SERIOUS_FLR) {
920d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "flr func_id: %d",
921d9ce1917SZiyang Xuan event->event.chip.func_id);
922d9ce1917SZiyang Xuan } else {
923d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "node_id: %d",
924d9ce1917SZiyang Xuan event->event.chip.node_id);
925d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "err_type: %d",
926d9ce1917SZiyang Xuan event->event.chip.err_type);
927d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "err_csr_addr: %d",
928d9ce1917SZiyang Xuan event->event.chip.err_csr_addr);
929d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "err_csr_value: %d",
930d9ce1917SZiyang Xuan event->event.chip.err_csr_value);
931d9ce1917SZiyang Xuan }
932d9ce1917SZiyang Xuan break;
933d9ce1917SZiyang Xuan case FAULT_TYPE_UCODE:
934d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "cause_id: %d",
935d9ce1917SZiyang Xuan event->event.ucode.cause_id);
936d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "core_id: %d",
937d9ce1917SZiyang Xuan event->event.ucode.core_id);
938d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "c_id: %d",
939d9ce1917SZiyang Xuan event->event.ucode.c_id);
940d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "epc: %d",
941d9ce1917SZiyang Xuan event->event.ucode.epc);
942d9ce1917SZiyang Xuan break;
943d9ce1917SZiyang Xuan case FAULT_TYPE_MEM_RD_TIMEOUT:
944d9ce1917SZiyang Xuan case FAULT_TYPE_MEM_WR_TIMEOUT:
945d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "err_csr_ctrl: %d",
946d9ce1917SZiyang Xuan event->event.mem_timeout.err_csr_ctrl);
947d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "err_csr_data: %d",
948d9ce1917SZiyang Xuan event->event.mem_timeout.err_csr_data);
949d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "ctrl_tab: %d",
950d9ce1917SZiyang Xuan event->event.mem_timeout.ctrl_tab);
951d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "mem_index: %d",
952d9ce1917SZiyang Xuan event->event.mem_timeout.mem_index);
953d9ce1917SZiyang Xuan break;
954d9ce1917SZiyang Xuan case FAULT_TYPE_REG_RD_TIMEOUT:
955d9ce1917SZiyang Xuan case FAULT_TYPE_REG_WR_TIMEOUT:
956d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "err_csr: %d",
957d9ce1917SZiyang Xuan event->event.reg_timeout.err_csr);
958d9ce1917SZiyang Xuan break;
959d9ce1917SZiyang Xuan default:
960d9ce1917SZiyang Xuan break;
961d9ce1917SZiyang Xuan }
962d9ce1917SZiyang Xuan }
963d9ce1917SZiyang Xuan
resources_state_set(struct hinic_hwdev * hwdev,enum hinic_res_state state)964d9ce1917SZiyang Xuan static int resources_state_set(struct hinic_hwdev *hwdev,
965d9ce1917SZiyang Xuan enum hinic_res_state state)
966d9ce1917SZiyang Xuan {
967d9ce1917SZiyang Xuan struct hinic_cmd_set_res_state res_state;
968d807dd7dSXiaoyun Wang u16 out_size = sizeof(res_state);
969d807dd7dSXiaoyun Wang int err;
970d9ce1917SZiyang Xuan
971d9ce1917SZiyang Xuan memset(&res_state, 0, sizeof(res_state));
972d9ce1917SZiyang Xuan res_state.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
973d807dd7dSXiaoyun Wang res_state.func_idx = HINIC_HWIF_GLOBAL_IDX(hwdev->hwif);
974d9ce1917SZiyang Xuan res_state.state = state;
975d9ce1917SZiyang Xuan
976d807dd7dSXiaoyun Wang err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
977d9ce1917SZiyang Xuan HINIC_MGMT_CMD_RES_STATE_SET,
978d807dd7dSXiaoyun Wang &res_state, sizeof(res_state),
979d807dd7dSXiaoyun Wang &res_state, &out_size, 0);
980d807dd7dSXiaoyun Wang if (err || !out_size || res_state.mgmt_msg_head.status) {
981d807dd7dSXiaoyun Wang PMD_DRV_LOG(ERR, "Set resources state failed, err: %d, status: 0x%x, out_size: 0x%x",
982d807dd7dSXiaoyun Wang err, res_state.mgmt_msg_head.status, out_size);
983d807dd7dSXiaoyun Wang return -EIO;
984d807dd7dSXiaoyun Wang }
985d807dd7dSXiaoyun Wang
986d807dd7dSXiaoyun Wang return 0;
987d9ce1917SZiyang Xuan }
988d9ce1917SZiyang Xuan
989d9ce1917SZiyang Xuan /**
990d9ce1917SZiyang Xuan * hinic_activate_hwdev_state - Active host nic state and notify mgmt channel
991d9ce1917SZiyang Xuan * that host nic is ready.
992d9ce1917SZiyang Xuan * @hwdev: the hardware interface of a nic device
993d9ce1917SZiyang Xuan * @return
994d9ce1917SZiyang Xuan * 0 on success,
995d9ce1917SZiyang Xuan * negative error value otherwise.
996b8582d05SXiaoyun Wang */
hinic_activate_hwdev_state(struct hinic_hwdev * hwdev)997d9ce1917SZiyang Xuan int hinic_activate_hwdev_state(struct hinic_hwdev *hwdev)
998d9ce1917SZiyang Xuan {
999d9ce1917SZiyang Xuan int rc = HINIC_OK;
1000d9ce1917SZiyang Xuan
1001d9ce1917SZiyang Xuan if (!hwdev)
1002d9ce1917SZiyang Xuan return -EINVAL;
1003d9ce1917SZiyang Xuan
1004b8582d05SXiaoyun Wang hinic_set_pf_status(hwdev->hwif, HINIC_PF_STATUS_ACTIVE_FLAG);
1005d9ce1917SZiyang Xuan
1006d9ce1917SZiyang Xuan rc = resources_state_set(hwdev, HINIC_RES_ACTIVE);
1007d9ce1917SZiyang Xuan if (rc) {
1008d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Initialize resources state failed");
1009d9ce1917SZiyang Xuan return rc;
1010d9ce1917SZiyang Xuan }
1011d9ce1917SZiyang Xuan
1012d9ce1917SZiyang Xuan return 0;
1013d9ce1917SZiyang Xuan }
1014d9ce1917SZiyang Xuan
1015d9ce1917SZiyang Xuan /**
1016d9ce1917SZiyang Xuan * hinic_deactivate_hwdev_state - Deactivate host nic state and notify mgmt
1017d9ce1917SZiyang Xuan * channel that host nic is not ready.
1018d9ce1917SZiyang Xuan * @hwdev: the pointer to the private hardware device object
1019b8582d05SXiaoyun Wang */
hinic_deactivate_hwdev_state(struct hinic_hwdev * hwdev)1020d9ce1917SZiyang Xuan void hinic_deactivate_hwdev_state(struct hinic_hwdev *hwdev)
1021d9ce1917SZiyang Xuan {
1022d9ce1917SZiyang Xuan int rc = HINIC_OK;
1023d9ce1917SZiyang Xuan
1024d9ce1917SZiyang Xuan if (!hwdev)
1025d9ce1917SZiyang Xuan return;
1026d9ce1917SZiyang Xuan
1027d9ce1917SZiyang Xuan rc = resources_state_set(hwdev, HINIC_RES_CLEAN);
1028d9ce1917SZiyang Xuan if (rc)
1029d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Deinit resources state failed");
1030d9ce1917SZiyang Xuan
1031d9ce1917SZiyang Xuan hinic_set_pf_status(hwdev->hwif, HINIC_PF_STATUS_INIT);
1032d9ce1917SZiyang Xuan }
1033d9ce1917SZiyang Xuan
hinic_get_board_info(void * hwdev,struct hinic_board_info * info)1034d9ce1917SZiyang Xuan int hinic_get_board_info(void *hwdev, struct hinic_board_info *info)
1035d9ce1917SZiyang Xuan {
1036d9ce1917SZiyang Xuan struct hinic_comm_board_info board_info;
1037d9ce1917SZiyang Xuan u16 out_size = sizeof(board_info);
1038d9ce1917SZiyang Xuan int err;
1039d9ce1917SZiyang Xuan
1040d9ce1917SZiyang Xuan if (!hwdev || !info)
1041d9ce1917SZiyang Xuan return -EINVAL;
1042d9ce1917SZiyang Xuan
1043d9ce1917SZiyang Xuan memset(&board_info, 0, sizeof(board_info));
1044d9ce1917SZiyang Xuan board_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1045d9ce1917SZiyang Xuan err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
1046d9ce1917SZiyang Xuan HINIC_MGMT_CMD_GET_BOARD_INFO,
1047d9ce1917SZiyang Xuan &board_info, sizeof(board_info),
1048d9ce1917SZiyang Xuan &board_info, &out_size, 0);
1049d9ce1917SZiyang Xuan if (err || board_info.mgmt_msg_head.status || !out_size) {
1050d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Failed to get board info, err: %d, status: 0x%x, out size: 0x%x",
1051d9ce1917SZiyang Xuan err, board_info.mgmt_msg_head.status, out_size);
10522ae8e130SXiaoyun Wang return -EIO;
1053d9ce1917SZiyang Xuan }
1054d9ce1917SZiyang Xuan
1055d9ce1917SZiyang Xuan memcpy(info, &board_info.info, sizeof(*info));
1056d9ce1917SZiyang Xuan return 0;
1057d9ce1917SZiyang Xuan }
1058d9ce1917SZiyang Xuan
1059d9ce1917SZiyang Xuan /**
1060d9ce1917SZiyang Xuan * hinic_l2nic_reset - Restore the initial state of NIC
1061d9ce1917SZiyang Xuan * @hwdev: the hardware interface of a nic device
1062d9ce1917SZiyang Xuan * @return
1063d9ce1917SZiyang Xuan * 0 on success,
1064d9ce1917SZiyang Xuan * negative error value otherwise.
1065b8582d05SXiaoyun Wang */
hinic_l2nic_reset(struct hinic_hwdev * hwdev)1066d9ce1917SZiyang Xuan int hinic_l2nic_reset(struct hinic_hwdev *hwdev)
1067d9ce1917SZiyang Xuan {
1068d9ce1917SZiyang Xuan struct hinic_hwif *hwif = hwdev->hwif;
1069d9ce1917SZiyang Xuan struct hinic_l2nic_reset l2nic_reset;
1070d807dd7dSXiaoyun Wang u16 out_size = sizeof(l2nic_reset);
1071d9ce1917SZiyang Xuan int err = 0;
1072d9ce1917SZiyang Xuan
1073d9ce1917SZiyang Xuan err = hinic_set_vport_enable(hwdev, false);
1074d9ce1917SZiyang Xuan if (err) {
1075d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Set vport disable failed");
1076d9ce1917SZiyang Xuan return err;
1077d9ce1917SZiyang Xuan }
1078d9ce1917SZiyang Xuan
1079d9ce1917SZiyang Xuan rte_delay_ms(100);
1080d9ce1917SZiyang Xuan
1081d9ce1917SZiyang Xuan memset(&l2nic_reset, 0, sizeof(l2nic_reset));
1082d9ce1917SZiyang Xuan l2nic_reset.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1083d9ce1917SZiyang Xuan l2nic_reset.func_id = HINIC_HWIF_GLOBAL_IDX(hwif);
1084d9ce1917SZiyang Xuan err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
1085d9ce1917SZiyang Xuan HINIC_MGMT_CMD_L2NIC_RESET,
1086d9ce1917SZiyang Xuan &l2nic_reset, sizeof(l2nic_reset),
1087d807dd7dSXiaoyun Wang &l2nic_reset, &out_size, 0);
1088d807dd7dSXiaoyun Wang if (err || !out_size || l2nic_reset.mgmt_msg_head.status) {
1089d807dd7dSXiaoyun Wang PMD_DRV_LOG(ERR, "Reset L2NIC resources failed, err: %d, status: 0x%x, out_size: 0x%x",
1090d807dd7dSXiaoyun Wang err, l2nic_reset.mgmt_msg_head.status, out_size);
1091d807dd7dSXiaoyun Wang return -EIO;
1092d9ce1917SZiyang Xuan }
1093d9ce1917SZiyang Xuan
1094d9ce1917SZiyang Xuan return 0;
1095d9ce1917SZiyang Xuan }
1096d9ce1917SZiyang Xuan
1097d9ce1917SZiyang Xuan static void
hinic_show_sw_watchdog_timeout_info(void * buf_in,u16 in_size,void * buf_out,u16 * out_size)1098d9ce1917SZiyang Xuan hinic_show_sw_watchdog_timeout_info(void *buf_in, u16 in_size,
1099d9ce1917SZiyang Xuan void *buf_out, u16 *out_size)
1100d9ce1917SZiyang Xuan {
1101d9ce1917SZiyang Xuan struct hinic_mgmt_watchdog_info *watchdog_info;
1102d9ce1917SZiyang Xuan u32 *dump_addr, *reg, stack_len, i, j;
1103d9ce1917SZiyang Xuan
1104d9ce1917SZiyang Xuan if (in_size != sizeof(*watchdog_info)) {
1105d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Invalid mgmt watchdog report, length: %d, should be %zu",
1106d9ce1917SZiyang Xuan in_size, sizeof(*watchdog_info));
1107d9ce1917SZiyang Xuan return;
1108d9ce1917SZiyang Xuan }
1109d9ce1917SZiyang Xuan
1110d9ce1917SZiyang Xuan watchdog_info = (struct hinic_mgmt_watchdog_info *)buf_in;
1111d9ce1917SZiyang Xuan
1112d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Mgmt deadloop time: 0x%x 0x%x, task id: 0x%x, sp: 0x%x",
1113d9ce1917SZiyang Xuan watchdog_info->curr_time_h, watchdog_info->curr_time_l,
1114d9ce1917SZiyang Xuan watchdog_info->task_id, watchdog_info->sp);
1115d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Stack current used: 0x%x, peak used: 0x%x, overflow flag: 0x%x, top: 0x%x, bottom: 0x%x",
1116d9ce1917SZiyang Xuan watchdog_info->curr_used, watchdog_info->peak_used,
1117d9ce1917SZiyang Xuan watchdog_info->is_overflow, watchdog_info->stack_top,
1118d9ce1917SZiyang Xuan watchdog_info->stack_bottom);
1119d9ce1917SZiyang Xuan
1120d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Mgmt pc: 0x%08x, lr: 0x%08x, cpsr: 0x%08x",
1121d9ce1917SZiyang Xuan watchdog_info->pc, watchdog_info->lr, watchdog_info->cpsr);
1122d9ce1917SZiyang Xuan
1123d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Mgmt register info");
1124d9ce1917SZiyang Xuan
1125d9ce1917SZiyang Xuan for (i = 0; i < 3; i++) {
1126d9ce1917SZiyang Xuan reg = watchdog_info->reg + (u64)(u32)(4 * i);
1127d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "0x%08x 0x%08x 0x%08x 0x%08x",
1128d9ce1917SZiyang Xuan *(reg), *(reg + 1), *(reg + 2), *(reg + 3));
1129d9ce1917SZiyang Xuan }
1130d9ce1917SZiyang Xuan
1131d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "0x%08x", watchdog_info->reg[12]);
1132d9ce1917SZiyang Xuan
1133d9ce1917SZiyang Xuan if (watchdog_info->stack_actlen <= 1024) {
1134d9ce1917SZiyang Xuan stack_len = watchdog_info->stack_actlen;
1135d9ce1917SZiyang Xuan } else {
1136d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Oops stack length: 0x%x is wrong",
1137d9ce1917SZiyang Xuan watchdog_info->stack_actlen);
1138d9ce1917SZiyang Xuan stack_len = 1024;
1139d9ce1917SZiyang Xuan }
1140d9ce1917SZiyang Xuan
1141d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Mgmt dump stack, 16Bytes per line(start from sp)");
1142d9ce1917SZiyang Xuan for (i = 0; i < (stack_len / 16); i++) {
1143d9ce1917SZiyang Xuan dump_addr = (u32 *)(watchdog_info->data + ((u64)(u32)(i * 16)));
1144d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "0x%08x 0x%08x 0x%08x 0x%08x",
1145d9ce1917SZiyang Xuan *dump_addr, *(dump_addr + 1), *(dump_addr + 2),
1146d9ce1917SZiyang Xuan *(dump_addr + 3));
1147d9ce1917SZiyang Xuan }
1148d9ce1917SZiyang Xuan
1149d9ce1917SZiyang Xuan for (j = 0; j < ((stack_len % 16) / 4); j++) {
1150d9ce1917SZiyang Xuan dump_addr = (u32 *)(watchdog_info->data +
1151d9ce1917SZiyang Xuan ((u64)(u32)(i * 16 + j * 4)));
1152d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "0x%08x", *dump_addr);
1153d9ce1917SZiyang Xuan }
1154d9ce1917SZiyang Xuan
1155d9ce1917SZiyang Xuan *out_size = sizeof(*watchdog_info);
1156d9ce1917SZiyang Xuan watchdog_info = (struct hinic_mgmt_watchdog_info *)buf_out;
1157d9ce1917SZiyang Xuan watchdog_info->mgmt_msg_head.status = 0;
1158d9ce1917SZiyang Xuan }
1159d9ce1917SZiyang Xuan
hinic_show_pcie_dfx_info(struct hinic_hwdev * hwdev,void * buf_in,u16 in_size,void * buf_out,u16 * out_size)1160d9ce1917SZiyang Xuan static void hinic_show_pcie_dfx_info(struct hinic_hwdev *hwdev,
1161d9ce1917SZiyang Xuan void *buf_in, u16 in_size,
1162d9ce1917SZiyang Xuan void *buf_out, u16 *out_size)
1163d9ce1917SZiyang Xuan {
1164d9ce1917SZiyang Xuan struct hinic_pcie_dfx_ntc *notice_info =
1165d9ce1917SZiyang Xuan (struct hinic_pcie_dfx_ntc *)buf_in;
1166d9ce1917SZiyang Xuan struct hinic_pcie_dfx_info dfx_info;
1167d9ce1917SZiyang Xuan u16 size = 0;
1168d9ce1917SZiyang Xuan u16 cnt = 0;
1169d9ce1917SZiyang Xuan u32 num = 0;
1170d9ce1917SZiyang Xuan u32 i, j;
1171d9ce1917SZiyang Xuan int err;
1172d9ce1917SZiyang Xuan u32 *reg;
1173d9ce1917SZiyang Xuan
1174d9ce1917SZiyang Xuan if (in_size != sizeof(*notice_info)) {
1175d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Invalid pcie dfx notice info, length: %d, should be %zu.",
1176d9ce1917SZiyang Xuan in_size, sizeof(*notice_info));
1177d9ce1917SZiyang Xuan return;
1178d9ce1917SZiyang Xuan }
1179d9ce1917SZiyang Xuan
1180d9ce1917SZiyang Xuan ((struct hinic_pcie_dfx_ntc *)buf_out)->mgmt_msg_head.status = 0;
1181d9ce1917SZiyang Xuan *out_size = sizeof(*notice_info);
1182d9ce1917SZiyang Xuan memset(&dfx_info, 0, sizeof(dfx_info));
1183d9ce1917SZiyang Xuan num = (u32)(notice_info->len / 1024);
1184d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "INFO LEN: %d", notice_info->len);
1185d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "PCIE DFX:");
1186d9ce1917SZiyang Xuan dfx_info.host_id = 0;
1187d9ce1917SZiyang Xuan dfx_info.mgmt_msg_head.resp_aeq_num = HINIC_AEQ1;
1188d9ce1917SZiyang Xuan for (i = 0; i < num; i++) {
1189d9ce1917SZiyang Xuan dfx_info.offset = i * MAX_PCIE_DFX_BUF_SIZE;
1190d9ce1917SZiyang Xuan if (i == (num - 1))
1191d9ce1917SZiyang Xuan dfx_info.last = 1;
1192d9ce1917SZiyang Xuan size = sizeof(dfx_info);
1193d9ce1917SZiyang Xuan err = hinic_msg_to_mgmt_sync(hwdev, HINIC_MOD_COMM,
1194d9ce1917SZiyang Xuan HINIC_MGMT_CMD_PCIE_DFX_GET,
1195d9ce1917SZiyang Xuan &dfx_info, sizeof(dfx_info),
1196d9ce1917SZiyang Xuan &dfx_info, &size, 0);
1197d9ce1917SZiyang Xuan if (err || dfx_info.mgmt_msg_head.status || !size) {
1198d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Failed to get pcie dfx info, err: %d, status: 0x%x, out size: 0x%x",
1199d9ce1917SZiyang Xuan err, dfx_info.mgmt_msg_head.status, size);
1200d9ce1917SZiyang Xuan return;
1201d9ce1917SZiyang Xuan }
1202d9ce1917SZiyang Xuan
1203d9ce1917SZiyang Xuan reg = (u32 *)dfx_info.data;
1204d9ce1917SZiyang Xuan for (j = 0; j < 256; j = j + 8) {
1205d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "0x%04x: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x",
1206d9ce1917SZiyang Xuan cnt, reg[j], reg[(u32)(j + 1)],
1207d9ce1917SZiyang Xuan reg[(u32)(j + 2)], reg[(u32)(j + 3)],
1208d9ce1917SZiyang Xuan reg[(u32)(j + 4)], reg[(u32)(j + 5)],
1209d9ce1917SZiyang Xuan reg[(u32)(j + 6)], reg[(u32)(j + 7)]);
1210d9ce1917SZiyang Xuan cnt = cnt + 32;
1211d9ce1917SZiyang Xuan }
1212d9ce1917SZiyang Xuan memset(dfx_info.data, 0, MAX_PCIE_DFX_BUF_SIZE);
1213d9ce1917SZiyang Xuan }
1214d9ce1917SZiyang Xuan }
1215d9ce1917SZiyang Xuan
1216d9ce1917SZiyang Xuan static void
hinic_show_ffm_info(struct hinic_hwdev * hwdev,void * buf_in,u16 in_size)1217d9ce1917SZiyang Xuan hinic_show_ffm_info(struct hinic_hwdev *hwdev, void *buf_in, u16 in_size)
1218d9ce1917SZiyang Xuan {
1219d9ce1917SZiyang Xuan struct ffm_intr_info *intr;
1220d9ce1917SZiyang Xuan
1221d9ce1917SZiyang Xuan if (in_size != sizeof(struct ffm_intr_info)) {
1222d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Invalid input buffer len, length: %d, should be %zu.",
1223d9ce1917SZiyang Xuan in_size, sizeof(struct ffm_intr_info));
1224d9ce1917SZiyang Xuan return;
1225d9ce1917SZiyang Xuan }
1226d9ce1917SZiyang Xuan
1227d9ce1917SZiyang Xuan if (hwdev->ffm_num < FFM_RECORD_NUM_MAX) {
1228d9ce1917SZiyang Xuan hwdev->ffm_num++;
1229d9ce1917SZiyang Xuan intr = (struct ffm_intr_info *)buf_in;
1230d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "node_id(%d),err_csr_addr(0x%x),err_csr_val(0x%x),err_level(0x%x),err_type(0x%x)",
1231d9ce1917SZiyang Xuan intr->node_id,
1232d9ce1917SZiyang Xuan intr->err_csr_addr,
1233d9ce1917SZiyang Xuan intr->err_csr_value,
1234d9ce1917SZiyang Xuan intr->err_level,
1235d9ce1917SZiyang Xuan intr->err_type);
1236d9ce1917SZiyang Xuan }
1237d9ce1917SZiyang Xuan }
1238d9ce1917SZiyang Xuan
hinic_comm_async_event_handle(struct hinic_hwdev * hwdev,u8 cmd,void * buf_in,u16 in_size,void * buf_out,u16 * out_size)1239d9ce1917SZiyang Xuan void hinic_comm_async_event_handle(struct hinic_hwdev *hwdev, u8 cmd,
1240d9ce1917SZiyang Xuan void *buf_in, u16 in_size,
1241d9ce1917SZiyang Xuan void *buf_out, u16 *out_size)
1242d9ce1917SZiyang Xuan {
1243d9ce1917SZiyang Xuan struct hinic_cmd_fault_event *fault_event, *ret_fault_event;
1244d9ce1917SZiyang Xuan
1245d9ce1917SZiyang Xuan if (!hwdev)
1246d9ce1917SZiyang Xuan return;
1247d9ce1917SZiyang Xuan
1248d9ce1917SZiyang Xuan *out_size = 0;
1249d9ce1917SZiyang Xuan
1250d9ce1917SZiyang Xuan switch (cmd) {
1251d9ce1917SZiyang Xuan case HINIC_MGMT_CMD_FAULT_REPORT:
1252d9ce1917SZiyang Xuan if (in_size != sizeof(*fault_event)) {
1253d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Invalid fault event report, length: %d, should be %zu",
1254d9ce1917SZiyang Xuan in_size, sizeof(*fault_event));
1255d9ce1917SZiyang Xuan return;
1256d9ce1917SZiyang Xuan }
1257d9ce1917SZiyang Xuan
1258d9ce1917SZiyang Xuan fault_event = (struct hinic_cmd_fault_event *)buf_in;
1259d9ce1917SZiyang Xuan fault_report_show(hwdev, &fault_event->event);
1260d9ce1917SZiyang Xuan
1261d9ce1917SZiyang Xuan if (hinic_func_type(hwdev) != TYPE_VF) {
1262d9ce1917SZiyang Xuan ret_fault_event =
1263d9ce1917SZiyang Xuan (struct hinic_cmd_fault_event *)buf_out;
1264d9ce1917SZiyang Xuan ret_fault_event->mgmt_msg_head.status = 0;
1265d9ce1917SZiyang Xuan *out_size = sizeof(*ret_fault_event);
1266d9ce1917SZiyang Xuan }
1267d9ce1917SZiyang Xuan break;
1268d9ce1917SZiyang Xuan
1269d9ce1917SZiyang Xuan case HINIC_MGMT_CMD_WATCHDOG_INFO:
1270d9ce1917SZiyang Xuan hinic_show_sw_watchdog_timeout_info(buf_in, in_size,
1271d9ce1917SZiyang Xuan buf_out, out_size);
1272d9ce1917SZiyang Xuan break;
1273d9ce1917SZiyang Xuan
1274d9ce1917SZiyang Xuan case HINIC_MGMT_CMD_PCIE_DFX_NTC:
1275d9ce1917SZiyang Xuan hinic_show_pcie_dfx_info(hwdev, buf_in, in_size,
1276d9ce1917SZiyang Xuan buf_out, out_size);
1277d9ce1917SZiyang Xuan break;
1278d9ce1917SZiyang Xuan
1279d9ce1917SZiyang Xuan case HINIC_MGMT_CMD_FFM_SET:
1280d9ce1917SZiyang Xuan hinic_show_ffm_info(hwdev, buf_in, in_size);
1281d9ce1917SZiyang Xuan break;
1282d9ce1917SZiyang Xuan
1283d9ce1917SZiyang Xuan default:
1284d9ce1917SZiyang Xuan break;
1285d9ce1917SZiyang Xuan }
1286d9ce1917SZiyang Xuan }
1287d9ce1917SZiyang Xuan
1288d9ce1917SZiyang Xuan static void
hinic_cable_status_event(u8 cmd,void * buf_in,__rte_unused u16 in_size,void * buf_out,u16 * out_size)1289d9ce1917SZiyang Xuan hinic_cable_status_event(u8 cmd, void *buf_in, __rte_unused u16 in_size,
1290d9ce1917SZiyang Xuan void *buf_out, u16 *out_size)
1291d9ce1917SZiyang Xuan {
1292d9ce1917SZiyang Xuan struct hinic_cable_plug_event *plug_event;
1293d9ce1917SZiyang Xuan struct hinic_link_err_event *link_err;
1294d9ce1917SZiyang Xuan
1295d9ce1917SZiyang Xuan if (cmd == HINIC_PORT_CMD_CABLE_PLUG_EVENT) {
1296d9ce1917SZiyang Xuan plug_event = (struct hinic_cable_plug_event *)buf_in;
1297d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "Port module event: Cable %s",
1298d9ce1917SZiyang Xuan plug_event->plugged ? "plugged" : "unplugged");
1299d9ce1917SZiyang Xuan
1300d9ce1917SZiyang Xuan *out_size = sizeof(*plug_event);
1301d9ce1917SZiyang Xuan plug_event = (struct hinic_cable_plug_event *)buf_out;
1302d9ce1917SZiyang Xuan plug_event->mgmt_msg_head.status = 0;
1303d9ce1917SZiyang Xuan } else if (cmd == HINIC_PORT_CMD_LINK_ERR_EVENT) {
1304d9ce1917SZiyang Xuan link_err = (struct hinic_link_err_event *)buf_in;
1305d9ce1917SZiyang Xuan if (link_err->err_type >= LINK_ERR_NUM) {
1306d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Link failed, Unknown type: 0x%x",
1307d9ce1917SZiyang Xuan link_err->err_type);
1308d9ce1917SZiyang Xuan } else {
1309d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "Link failed, type: 0x%x: %s",
1310d9ce1917SZiyang Xuan link_err->err_type,
1311d9ce1917SZiyang Xuan hinic_module_link_err[link_err->err_type]);
1312d9ce1917SZiyang Xuan }
1313d9ce1917SZiyang Xuan
1314d9ce1917SZiyang Xuan *out_size = sizeof(*link_err);
1315d9ce1917SZiyang Xuan link_err = (struct hinic_link_err_event *)buf_out;
1316d9ce1917SZiyang Xuan link_err->mgmt_msg_head.status = 0;
1317d9ce1917SZiyang Xuan }
1318d9ce1917SZiyang Xuan }
1319d9ce1917SZiyang Xuan
hinic_link_event_process(struct hinic_hwdev * hwdev,struct rte_eth_dev * eth_dev,u8 status)1320d9ce1917SZiyang Xuan static int hinic_link_event_process(struct hinic_hwdev *hwdev,
1321d9ce1917SZiyang Xuan struct rte_eth_dev *eth_dev, u8 status)
1322d9ce1917SZiyang Xuan {
1323295968d1SFerruh Yigit uint32_t port_speed[LINK_SPEED_MAX] = {RTE_ETH_SPEED_NUM_10M,
1324295968d1SFerruh Yigit RTE_ETH_SPEED_NUM_100M, RTE_ETH_SPEED_NUM_1G,
1325295968d1SFerruh Yigit RTE_ETH_SPEED_NUM_10G, RTE_ETH_SPEED_NUM_25G,
1326295968d1SFerruh Yigit RTE_ETH_SPEED_NUM_40G, RTE_ETH_SPEED_NUM_100G};
1327d9ce1917SZiyang Xuan struct nic_port_info port_info;
1328d9ce1917SZiyang Xuan struct rte_eth_link link;
1329d9ce1917SZiyang Xuan int rc = HINIC_OK;
1330d9ce1917SZiyang Xuan
1331d9ce1917SZiyang Xuan if (!status) {
1332295968d1SFerruh Yigit link.link_status = RTE_ETH_LINK_DOWN;
1333d9ce1917SZiyang Xuan link.link_speed = 0;
1334295968d1SFerruh Yigit link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
1335295968d1SFerruh Yigit link.link_autoneg = RTE_ETH_LINK_FIXED;
1336d9ce1917SZiyang Xuan } else {
1337295968d1SFerruh Yigit link.link_status = RTE_ETH_LINK_UP;
1338d9ce1917SZiyang Xuan
1339d9ce1917SZiyang Xuan memset(&port_info, 0, sizeof(port_info));
1340d9ce1917SZiyang Xuan rc = hinic_get_port_info(hwdev, &port_info);
1341d9ce1917SZiyang Xuan if (rc) {
1342295968d1SFerruh Yigit link.link_speed = RTE_ETH_SPEED_NUM_NONE;
1343295968d1SFerruh Yigit link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
1344295968d1SFerruh Yigit link.link_autoneg = RTE_ETH_LINK_FIXED;
1345d9ce1917SZiyang Xuan } else {
1346d9ce1917SZiyang Xuan link.link_speed = port_speed[port_info.speed %
1347d9ce1917SZiyang Xuan LINK_SPEED_MAX];
1348d9ce1917SZiyang Xuan link.link_duplex = port_info.duplex;
1349d9ce1917SZiyang Xuan link.link_autoneg = port_info.autoneg_state;
1350d9ce1917SZiyang Xuan }
1351d9ce1917SZiyang Xuan }
1352d9ce1917SZiyang Xuan (void)rte_eth_linkstatus_set(eth_dev, &link);
1353d9ce1917SZiyang Xuan
1354d9ce1917SZiyang Xuan return rc;
1355d9ce1917SZiyang Xuan }
1356d9ce1917SZiyang Xuan
hinic_lsc_process(struct hinic_hwdev * hwdev,struct rte_eth_dev * rte_dev,u8 status)1357d9ce1917SZiyang Xuan static void hinic_lsc_process(struct hinic_hwdev *hwdev,
1358d9ce1917SZiyang Xuan struct rte_eth_dev *rte_dev, u8 status)
1359d9ce1917SZiyang Xuan {
1360d9ce1917SZiyang Xuan int ret;
1361d9ce1917SZiyang Xuan
1362d9ce1917SZiyang Xuan ret = hinic_link_event_process(hwdev, rte_dev, status);
1363d9ce1917SZiyang Xuan /* check if link has changed, notify callback */
1364d9ce1917SZiyang Xuan if (ret == 0)
13655723fbedSFerruh Yigit rte_eth_dev_callback_process(rte_dev,
1366d9ce1917SZiyang Xuan RTE_ETH_EVENT_INTR_LSC,
1367d9ce1917SZiyang Xuan NULL);
1368d9ce1917SZiyang Xuan }
1369d9ce1917SZiyang Xuan
hinic_l2nic_async_event_handle(struct hinic_hwdev * hwdev,void * param,u8 cmd,void * buf_in,u16 in_size,void * buf_out,u16 * out_size)1370d9ce1917SZiyang Xuan void hinic_l2nic_async_event_handle(struct hinic_hwdev *hwdev,
1371d9ce1917SZiyang Xuan void *param, u8 cmd,
1372d9ce1917SZiyang Xuan void *buf_in, u16 in_size,
1373d9ce1917SZiyang Xuan void *buf_out, u16 *out_size)
1374d9ce1917SZiyang Xuan {
1375d9ce1917SZiyang Xuan struct hinic_port_link_status *in_link;
1376d9ce1917SZiyang Xuan struct rte_eth_dev *eth_dev;
1377d9ce1917SZiyang Xuan
1378d9ce1917SZiyang Xuan if (!hwdev)
1379d9ce1917SZiyang Xuan return;
1380d9ce1917SZiyang Xuan
1381d9ce1917SZiyang Xuan *out_size = 0;
1382d9ce1917SZiyang Xuan
1383d9ce1917SZiyang Xuan switch (cmd) {
1384d9ce1917SZiyang Xuan case HINIC_PORT_CMD_LINK_STATUS_REPORT:
1385d9ce1917SZiyang Xuan eth_dev = param;
1386d9ce1917SZiyang Xuan in_link = (struct hinic_port_link_status *)buf_in;
1387d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "Link status event report, dev_name: %s, port_id: %d, link_status: %s",
1388d9ce1917SZiyang Xuan eth_dev->data->name, eth_dev->data->port_id,
1389d9ce1917SZiyang Xuan in_link->link ? "UP" : "DOWN");
1390d9ce1917SZiyang Xuan
1391d9ce1917SZiyang Xuan hinic_lsc_process(hwdev, eth_dev, in_link->link);
1392d9ce1917SZiyang Xuan break;
1393d9ce1917SZiyang Xuan
1394d9ce1917SZiyang Xuan case HINIC_PORT_CMD_CABLE_PLUG_EVENT:
1395d9ce1917SZiyang Xuan case HINIC_PORT_CMD_LINK_ERR_EVENT:
1396d9ce1917SZiyang Xuan hinic_cable_status_event(cmd, buf_in, in_size,
1397d9ce1917SZiyang Xuan buf_out, out_size);
1398d9ce1917SZiyang Xuan break;
1399d9ce1917SZiyang Xuan
1400d9ce1917SZiyang Xuan case HINIC_PORT_CMD_MGMT_RESET:
1401d9ce1917SZiyang Xuan PMD_DRV_LOG(WARNING, "Mgmt is reset");
1402d9ce1917SZiyang Xuan break;
1403d9ce1917SZiyang Xuan
1404d9ce1917SZiyang Xuan default:
1405d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Unsupported event %d to process",
1406d9ce1917SZiyang Xuan cmd);
1407d9ce1917SZiyang Xuan break;
1408d9ce1917SZiyang Xuan }
1409d9ce1917SZiyang Xuan }
1410d9ce1917SZiyang Xuan
print_cable_info(struct hinic_link_info * info)1411d9ce1917SZiyang Xuan static void print_cable_info(struct hinic_link_info *info)
1412d9ce1917SZiyang Xuan {
1413d9ce1917SZiyang Xuan char tmp_str[512] = {0};
1414d9ce1917SZiyang Xuan char tmp_vendor[17] = {0};
1415d9ce1917SZiyang Xuan const char *port_type = "Unknown port type";
1416d9ce1917SZiyang Xuan int i;
1417d9ce1917SZiyang Xuan
1418d9ce1917SZiyang Xuan if (info->cable_absent) {
1419d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "Cable unpresent");
1420d9ce1917SZiyang Xuan return;
1421d9ce1917SZiyang Xuan }
1422d9ce1917SZiyang Xuan
1423d9ce1917SZiyang Xuan if (info->port_type < LINK_PORT_MAX_TYPE)
1424d9ce1917SZiyang Xuan port_type = __hw_to_char_port_type[info->port_type];
1425d9ce1917SZiyang Xuan else
1426d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "Unknown port type: %u",
1427d9ce1917SZiyang Xuan info->port_type);
1428d9ce1917SZiyang Xuan if (info->port_type == LINK_PORT_FIBRE) {
1429d9ce1917SZiyang Xuan if (info->port_sub_type == FIBRE_SUBTYPE_SR)
1430d9ce1917SZiyang Xuan port_type = "Fibre-SR";
1431d9ce1917SZiyang Xuan else if (info->port_sub_type == FIBRE_SUBTYPE_LR)
1432d9ce1917SZiyang Xuan port_type = "Fibre-LR";
1433d9ce1917SZiyang Xuan }
1434d9ce1917SZiyang Xuan
1435d9ce1917SZiyang Xuan for (i = sizeof(info->vendor_name) - 1; i >= 0; i--) {
1436d9ce1917SZiyang Xuan if (info->vendor_name[i] == ' ')
1437d9ce1917SZiyang Xuan info->vendor_name[i] = '\0';
1438d9ce1917SZiyang Xuan else
1439d9ce1917SZiyang Xuan break;
1440d9ce1917SZiyang Xuan }
1441d9ce1917SZiyang Xuan
1442d9ce1917SZiyang Xuan memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name));
14439c84acabSKevin Traynor snprintf(tmp_str, sizeof(tmp_str),
1444d9ce1917SZiyang Xuan "Vendor: %s, %s, %s, length: %um, max_speed: %uGbps",
1445d9ce1917SZiyang Xuan tmp_vendor, info->sfp_type ? "SFP" : "QSFP", port_type,
1446d9ce1917SZiyang Xuan info->cable_length, info->cable_max_speed);
1447d9ce1917SZiyang Xuan if (info->port_type != LINK_PORT_COPPER)
1448ece8e4c2SKevin Traynor snprintf(tmp_str + strlen(tmp_str),
1449ece8e4c2SKevin Traynor sizeof(tmp_str) - strlen(tmp_str),
1450ece8e4c2SKevin Traynor ", Temperature: %u", info->cable_temp);
1451d9ce1917SZiyang Xuan
1452d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "Cable information: %s", tmp_str);
1453d9ce1917SZiyang Xuan }
1454d9ce1917SZiyang Xuan
print_hi30_status(struct hinic_link_info * info)1455d9ce1917SZiyang Xuan static void print_hi30_status(struct hinic_link_info *info)
1456d9ce1917SZiyang Xuan {
1457d9ce1917SZiyang Xuan struct hi30_ffe_data *ffe_data;
1458d9ce1917SZiyang Xuan struct hi30_ctle_data *ctle_data;
1459d9ce1917SZiyang Xuan
1460d9ce1917SZiyang Xuan ffe_data = (struct hi30_ffe_data *)info->hi30_ffe;
1461d9ce1917SZiyang Xuan ctle_data = (struct hi30_ctle_data *)info->hi30_ctle;
1462d9ce1917SZiyang Xuan
1463d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "TX_FFE: PRE2=%s%d; PRE1=%s%d; MAIN=%d; POST1=%s%d; POST1X=%s%d",
1464d9ce1917SZiyang Xuan (ffe_data->PRE1 & 0x10) ? "-" : "",
1465d9ce1917SZiyang Xuan (int)(ffe_data->PRE1 & 0xf),
1466d9ce1917SZiyang Xuan (ffe_data->PRE2 & 0x10) ? "-" : "",
1467d9ce1917SZiyang Xuan (int)(ffe_data->PRE2 & 0xf),
1468d9ce1917SZiyang Xuan (int)ffe_data->MAIN,
1469d9ce1917SZiyang Xuan (ffe_data->POST1 & 0x10) ? "-" : "",
1470d9ce1917SZiyang Xuan (int)(ffe_data->POST1 & 0xf),
1471d9ce1917SZiyang Xuan (ffe_data->POST2 & 0x10) ? "-" : "",
1472d9ce1917SZiyang Xuan (int)(ffe_data->POST2 & 0xf));
1473d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "RX_CTLE: Gain1~3=%u %u %u; Boost1~3=%u %u %u; Zero1~3=%u %u %u; Squelch1~3=%u %u %u",
1474d9ce1917SZiyang Xuan ctle_data->ctlebst[0], ctle_data->ctlebst[1],
1475d9ce1917SZiyang Xuan ctle_data->ctlebst[2], ctle_data->ctlecmband[0],
1476d9ce1917SZiyang Xuan ctle_data->ctlecmband[1], ctle_data->ctlecmband[2],
1477d9ce1917SZiyang Xuan ctle_data->ctlermband[0], ctle_data->ctlermband[1],
1478d9ce1917SZiyang Xuan ctle_data->ctlermband[2], ctle_data->ctleza[0],
1479d9ce1917SZiyang Xuan ctle_data->ctleza[1], ctle_data->ctleza[2]);
1480d9ce1917SZiyang Xuan }
1481d9ce1917SZiyang Xuan
print_link_info(struct hinic_link_info * info,enum hilink_info_print_event type)1482d9ce1917SZiyang Xuan static void print_link_info(struct hinic_link_info *info,
1483d9ce1917SZiyang Xuan enum hilink_info_print_event type)
1484d9ce1917SZiyang Xuan {
1485d9ce1917SZiyang Xuan const char *fec = "None";
1486d9ce1917SZiyang Xuan
1487d9ce1917SZiyang Xuan if (info->fec < HILINK_FEC_MAX_TYPE)
1488d9ce1917SZiyang Xuan fec = __hw_to_char_fec[info->fec];
1489d9ce1917SZiyang Xuan else
1490d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "Unknown fec type: %u",
1491d9ce1917SZiyang Xuan info->fec);
1492d9ce1917SZiyang Xuan
1493d9ce1917SZiyang Xuan if (type == HILINK_EVENT_LINK_UP || !info->an_state) {
1494d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "Link information: speed %dGbps, %s, autoneg %s",
1495d9ce1917SZiyang Xuan info->speed, fec, info->an_state ? "on" : "off");
1496d9ce1917SZiyang Xuan } else {
1497d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "Link information: antoneg: %s",
1498d9ce1917SZiyang Xuan info->an_state ? "on" : "off");
1499d9ce1917SZiyang Xuan }
1500d9ce1917SZiyang Xuan }
1501d9ce1917SZiyang Xuan
1502d9ce1917SZiyang Xuan static const char *hilink_info_report_type[HILINK_EVENT_MAX_TYPE] = {
1503d9ce1917SZiyang Xuan "", "link up", "link down", "cable plugged"
1504d9ce1917SZiyang Xuan };
1505d9ce1917SZiyang Xuan
hinic_print_hilink_info(void * buf_in,u16 in_size,void * buf_out,u16 * out_size)1506d9ce1917SZiyang Xuan static void hinic_print_hilink_info(void *buf_in, u16 in_size,
1507d9ce1917SZiyang Xuan void *buf_out, u16 *out_size)
1508d9ce1917SZiyang Xuan {
1509d9ce1917SZiyang Xuan struct hinic_hilink_link_info *hilink_info =
1510d9ce1917SZiyang Xuan (struct hinic_hilink_link_info *)buf_in;
1511d9ce1917SZiyang Xuan struct hinic_link_info *info;
1512d9ce1917SZiyang Xuan enum hilink_info_print_event type;
1513d9ce1917SZiyang Xuan
1514d9ce1917SZiyang Xuan if (in_size != sizeof(*hilink_info)) {
1515d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Invalid hilink info message size %d, should be %zu",
1516d9ce1917SZiyang Xuan in_size, sizeof(*hilink_info));
1517d9ce1917SZiyang Xuan return;
1518d9ce1917SZiyang Xuan }
1519d9ce1917SZiyang Xuan
1520d9ce1917SZiyang Xuan ((struct hinic_hilink_link_info *)buf_out)->mgmt_msg_head.status = 0;
1521d9ce1917SZiyang Xuan *out_size = sizeof(*hilink_info);
1522d9ce1917SZiyang Xuan
1523d9ce1917SZiyang Xuan info = &hilink_info->info;
1524d9ce1917SZiyang Xuan type = hilink_info->info_type;
1525d9ce1917SZiyang Xuan
1526d9ce1917SZiyang Xuan if (type < HILINK_EVENT_LINK_UP || type >= HILINK_EVENT_MAX_TYPE) {
1527d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "Invalid hilink info report, type: %d",
1528d9ce1917SZiyang Xuan type);
1529d9ce1917SZiyang Xuan return;
1530d9ce1917SZiyang Xuan }
1531d9ce1917SZiyang Xuan
1532d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "Hilink info report after %s",
1533d9ce1917SZiyang Xuan hilink_info_report_type[type]);
1534d9ce1917SZiyang Xuan
1535d9ce1917SZiyang Xuan print_cable_info(info);
1536d9ce1917SZiyang Xuan
1537d9ce1917SZiyang Xuan print_link_info(info, type);
1538d9ce1917SZiyang Xuan
1539d9ce1917SZiyang Xuan print_hi30_status(info);
1540d9ce1917SZiyang Xuan
1541d9ce1917SZiyang Xuan if (type == HILINK_EVENT_LINK_UP)
1542d9ce1917SZiyang Xuan return;
1543d9ce1917SZiyang Xuan
1544d9ce1917SZiyang Xuan if (type == HILINK_EVENT_CABLE_PLUGGED) {
1545d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "alos: %u, rx_los: %u",
1546d9ce1917SZiyang Xuan info->alos, info->rx_los);
1547d9ce1917SZiyang Xuan return;
1548d9ce1917SZiyang Xuan }
1549d9ce1917SZiyang Xuan
1550d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "PMA ctrl: %s, MAC tx %s, MAC rx %s, PMA debug inforeg: 0x%x, PMA signal ok reg: 0x%x, RF/LF status reg: 0x%x",
1551d9ce1917SZiyang Xuan info->pma_status ? "on" : "off",
1552d9ce1917SZiyang Xuan info->mac_tx_en ? "enable" : "disable",
1553d9ce1917SZiyang Xuan info->mac_rx_en ? "enable" : "disable", info->pma_dbg_info_reg,
1554d9ce1917SZiyang Xuan info->pma_signal_ok_reg, info->rf_lf_status_reg);
1555d9ce1917SZiyang Xuan PMD_DRV_LOG(INFO, "alos: %u, rx_los: %u, PCS block counter reg: 0x%x,PCS link: 0x%x, MAC link: 0x%x PCS_err_cnt: 0x%x",
1556d9ce1917SZiyang Xuan info->alos, info->rx_los, info->pcs_err_blk_cnt_reg,
1557d9ce1917SZiyang Xuan info->pcs_link_reg, info->mac_link_reg, info->pcs_err_cnt);
1558d9ce1917SZiyang Xuan }
1559d9ce1917SZiyang Xuan
hinic_hilink_async_event_handle(struct hinic_hwdev * hwdev,u8 cmd,void * buf_in,u16 in_size,void * buf_out,u16 * out_size)1560d9ce1917SZiyang Xuan void hinic_hilink_async_event_handle(struct hinic_hwdev *hwdev, u8 cmd,
1561d9ce1917SZiyang Xuan void *buf_in, u16 in_size,
1562d9ce1917SZiyang Xuan void *buf_out, u16 *out_size)
1563d9ce1917SZiyang Xuan {
1564d9ce1917SZiyang Xuan if (!hwdev)
1565d9ce1917SZiyang Xuan return;
1566d9ce1917SZiyang Xuan
1567d9ce1917SZiyang Xuan *out_size = 0;
1568d9ce1917SZiyang Xuan
1569d9ce1917SZiyang Xuan switch (cmd) {
1570d9ce1917SZiyang Xuan case HINIC_HILINK_CMD_GET_LINK_INFO:
1571d9ce1917SZiyang Xuan hinic_print_hilink_info(buf_in, in_size, buf_out,
1572d9ce1917SZiyang Xuan out_size);
1573d9ce1917SZiyang Xuan break;
1574d9ce1917SZiyang Xuan
1575d9ce1917SZiyang Xuan default:
1576d9ce1917SZiyang Xuan PMD_DRV_LOG(ERR, "Unsupported event %d to process",
1577d9ce1917SZiyang Xuan cmd);
1578d9ce1917SZiyang Xuan break;
1579d9ce1917SZiyang Xuan }
1580d9ce1917SZiyang Xuan }
1581