4141#include "hns_roce_device.h"
4242#include "hns_roce_cmd.h"
4343#include "hns_roce_hem.h"
44+ #include "hns_roce_hw_v2.h"
4445
45- static const struct hns_roce_hw hns_roce_hw_v2 ;
46+ static int hns_roce_cmq_space (struct hns_roce_v2_cmq_ring * ring )
47+ {
48+ int ntu = ring -> next_to_use ;
49+ int ntc = ring -> next_to_clean ;
50+ int used = (ntu - ntc + ring -> desc_num ) % ring -> desc_num ;
51+
52+ return ring -> desc_num - used - 1 ;
53+ }
54+
55+ static int hns_roce_alloc_cmq_desc (struct hns_roce_dev * hr_dev ,
56+ struct hns_roce_v2_cmq_ring * ring )
57+ {
58+ int size = ring -> desc_num * sizeof (struct hns_roce_cmq_desc );
59+
60+ ring -> desc = kzalloc (size , GFP_KERNEL );
61+ if (!ring -> desc )
62+ return - ENOMEM ;
63+
64+ ring -> desc_dma_addr = dma_map_single (hr_dev -> dev , ring -> desc , size ,
65+ DMA_BIDIRECTIONAL );
66+ if (dma_mapping_error (hr_dev -> dev , ring -> desc_dma_addr )) {
67+ ring -> desc_dma_addr = 0 ;
68+ kfree (ring -> desc );
69+ ring -> desc = NULL ;
70+ return - ENOMEM ;
71+ }
72+
73+ return 0 ;
74+ }
75+
76+ static void hns_roce_free_cmq_desc (struct hns_roce_dev * hr_dev ,
77+ struct hns_roce_v2_cmq_ring * ring )
78+ {
79+ dma_unmap_single (hr_dev -> dev , ring -> desc_dma_addr ,
80+ ring -> desc_num * sizeof (struct hns_roce_cmq_desc ),
81+ DMA_BIDIRECTIONAL );
82+ kfree (ring -> desc );
83+ }
84+
85+ static int hns_roce_init_cmq_ring (struct hns_roce_dev * hr_dev , bool ring_type )
86+ {
87+ struct hns_roce_v2_priv * priv = (struct hns_roce_v2_priv * )hr_dev -> priv ;
88+ struct hns_roce_v2_cmq_ring * ring = (ring_type == TYPE_CSQ ) ?
89+ & priv -> cmq .csq : & priv -> cmq .crq ;
90+
91+ ring -> flag = ring_type ;
92+ ring -> next_to_clean = 0 ;
93+ ring -> next_to_use = 0 ;
94+
95+ return hns_roce_alloc_cmq_desc (hr_dev , ring );
96+ }
97+
98+ static void hns_roce_cmq_init_regs (struct hns_roce_dev * hr_dev , bool ring_type )
99+ {
100+ struct hns_roce_v2_priv * priv = (struct hns_roce_v2_priv * )hr_dev -> priv ;
101+ struct hns_roce_v2_cmq_ring * ring = (ring_type == TYPE_CSQ ) ?
102+ & priv -> cmq .csq : & priv -> cmq .crq ;
103+ dma_addr_t dma = ring -> desc_dma_addr ;
104+
105+ if (ring_type == TYPE_CSQ ) {
106+ roce_write (hr_dev , ROCEE_TX_CMQ_BASEADDR_L_REG , (u32 )dma );
107+ roce_write (hr_dev , ROCEE_TX_CMQ_BASEADDR_H_REG ,
108+ upper_32_bits (dma ));
109+ roce_write (hr_dev , ROCEE_TX_CMQ_DEPTH_REG ,
110+ (ring -> desc_num >> HNS_ROCE_CMQ_DESC_NUM_S ) |
111+ HNS_ROCE_CMQ_ENABLE );
112+ roce_write (hr_dev , ROCEE_TX_CMQ_HEAD_REG , 0 );
113+ roce_write (hr_dev , ROCEE_TX_CMQ_TAIL_REG , 0 );
114+ } else {
115+ roce_write (hr_dev , ROCEE_RX_CMQ_BASEADDR_L_REG , (u32 )dma );
116+ roce_write (hr_dev , ROCEE_RX_CMQ_BASEADDR_H_REG ,
117+ upper_32_bits (dma ));
118+ roce_write (hr_dev , ROCEE_RX_CMQ_DEPTH_REG ,
119+ (ring -> desc_num >> HNS_ROCE_CMQ_DESC_NUM_S ) |
120+ HNS_ROCE_CMQ_ENABLE );
121+ roce_write (hr_dev , ROCEE_RX_CMQ_HEAD_REG , 0 );
122+ roce_write (hr_dev , ROCEE_RX_CMQ_TAIL_REG , 0 );
123+ }
124+ }
125+
126+ static int hns_roce_v2_cmq_init (struct hns_roce_dev * hr_dev )
127+ {
128+ struct hns_roce_v2_priv * priv = (struct hns_roce_v2_priv * )hr_dev -> priv ;
129+ int ret ;
130+
131+ /* Setup the queue entries for command queue */
132+ priv -> cmq .csq .desc_num = 1024 ;
133+ priv -> cmq .crq .desc_num = 1024 ;
134+
135+ /* Setup the lock for command queue */
136+ spin_lock_init (& priv -> cmq .csq .lock );
137+ spin_lock_init (& priv -> cmq .crq .lock );
138+
139+ /* Setup Tx write back timeout */
140+ priv -> cmq .tx_timeout = HNS_ROCE_CMQ_TX_TIMEOUT ;
141+
142+ /* Init CSQ */
143+ ret = hns_roce_init_cmq_ring (hr_dev , TYPE_CSQ );
144+ if (ret ) {
145+ dev_err (hr_dev -> dev , "Init CSQ error, ret = %d.\n" , ret );
146+ return ret ;
147+ }
148+
149+ /* Init CRQ */
150+ ret = hns_roce_init_cmq_ring (hr_dev , TYPE_CRQ );
151+ if (ret ) {
152+ dev_err (hr_dev -> dev , "Init CRQ error, ret = %d.\n" , ret );
153+ goto err_crq ;
154+ }
155+
156+ /* Init CSQ REG */
157+ hns_roce_cmq_init_regs (hr_dev , TYPE_CSQ );
158+
159+ /* Init CRQ REG */
160+ hns_roce_cmq_init_regs (hr_dev , TYPE_CRQ );
161+
162+ return 0 ;
163+
164+ err_crq :
165+ hns_roce_free_cmq_desc (hr_dev , & priv -> cmq .csq );
166+
167+ return ret ;
168+ }
169+
170+ static void hns_roce_v2_cmq_exit (struct hns_roce_dev * hr_dev )
171+ {
172+ struct hns_roce_v2_priv * priv = (struct hns_roce_v2_priv * )hr_dev -> priv ;
173+
174+ hns_roce_free_cmq_desc (hr_dev , & priv -> cmq .csq );
175+ hns_roce_free_cmq_desc (hr_dev , & priv -> cmq .crq );
176+ }
177+
178+ void hns_roce_cmq_setup_basic_desc (struct hns_roce_cmq_desc * desc ,
179+ enum hns_roce_opcode_type opcode ,
180+ bool is_read )
181+ {
182+ memset ((void * )desc , 0 , sizeof (struct hns_roce_cmq_desc ));
183+ desc -> opcode = cpu_to_le16 (opcode );
184+ desc -> flag =
185+ cpu_to_le16 (HNS_ROCE_CMD_FLAG_NO_INTR | HNS_ROCE_CMD_FLAG_IN );
186+ if (is_read )
187+ desc -> flag |= cpu_to_le16 (HNS_ROCE_CMD_FLAG_WR );
188+ else
189+ desc -> flag &= cpu_to_le16 (~HNS_ROCE_CMD_FLAG_WR );
190+ }
191+
192+ static int hns_roce_cmq_csq_done (struct hns_roce_dev * hr_dev )
193+ {
194+ struct hns_roce_v2_priv * priv = (struct hns_roce_v2_priv * )hr_dev -> priv ;
195+ u32 head = roce_read (hr_dev , ROCEE_TX_CMQ_HEAD_REG );
196+
197+ return head == priv -> cmq .csq .next_to_use ;
198+ }
199+
200+ static int hns_roce_cmq_csq_clean (struct hns_roce_dev * hr_dev )
201+ {
202+ struct hns_roce_v2_priv * priv = (struct hns_roce_v2_priv * )hr_dev -> priv ;
203+ struct hns_roce_v2_cmq_ring * csq = & priv -> cmq .csq ;
204+ struct hns_roce_cmq_desc * desc ;
205+ u16 ntc = csq -> next_to_clean ;
206+ u32 head ;
207+ int clean = 0 ;
208+
209+ desc = & csq -> desc [ntc ];
210+ head = roce_read (hr_dev , ROCEE_TX_CMQ_HEAD_REG );
211+ while (head != ntc ) {
212+ memset (desc , 0 , sizeof (* desc ));
213+ ntc ++ ;
214+ if (ntc == csq -> desc_num )
215+ ntc = 0 ;
216+ desc = & csq -> desc [ntc ];
217+ clean ++ ;
218+ }
219+ csq -> next_to_clean = ntc ;
220+
221+ return clean ;
222+ }
223+
224+ int hns_roce_cmq_send (struct hns_roce_dev * hr_dev ,
225+ struct hns_roce_cmq_desc * desc , int num )
226+ {
227+ struct hns_roce_v2_priv * priv = (struct hns_roce_v2_priv * )hr_dev -> priv ;
228+ struct hns_roce_v2_cmq_ring * csq = & priv -> cmq .csq ;
229+ struct hns_roce_cmq_desc * desc_to_use ;
230+ bool complete = false;
231+ u32 timeout = 0 ;
232+ int handle = 0 ;
233+ u16 desc_ret ;
234+ int ret = 0 ;
235+ int ntc ;
236+
237+ spin_lock_bh (& csq -> lock );
238+
239+ if (num > hns_roce_cmq_space (csq )) {
240+ spin_unlock_bh (& csq -> lock );
241+ return - EBUSY ;
242+ }
243+
244+ /*
245+ * Record the location of desc in the cmq for this time
246+ * which will be use for hardware to write back
247+ */
248+ ntc = csq -> next_to_use ;
249+
250+ while (handle < num ) {
251+ desc_to_use = & csq -> desc [csq -> next_to_use ];
252+ * desc_to_use = desc [handle ];
253+ dev_dbg (hr_dev -> dev , "set cmq desc:\n" );
254+ csq -> next_to_use ++ ;
255+ if (csq -> next_to_use == csq -> desc_num )
256+ csq -> next_to_use = 0 ;
257+ handle ++ ;
258+ }
259+
260+ /* Write to hardware */
261+ roce_write (hr_dev , ROCEE_TX_CMQ_TAIL_REG , csq -> next_to_use );
262+
263+ /*
264+ * If the command is sync, wait for the firmware to write back,
265+ * if multi descriptors to be sent, use the first one to check
266+ */
267+ if ((desc -> flag ) & HNS_ROCE_CMD_FLAG_NO_INTR ) {
268+ do {
269+ if (hns_roce_cmq_csq_done (hr_dev ))
270+ break ;
271+ usleep_range (1000 , 2000 );
272+ timeout ++ ;
273+ } while (timeout < priv -> cmq .tx_timeout );
274+ }
275+
276+ if (hns_roce_cmq_csq_done (hr_dev )) {
277+ complete = true;
278+ handle = 0 ;
279+ while (handle < num ) {
280+ /* get the result of hardware write back */
281+ desc_to_use = & csq -> desc [ntc ];
282+ desc [handle ] = * desc_to_use ;
283+ dev_dbg (hr_dev -> dev , "Get cmq desc:\n" );
284+ desc_ret = desc [handle ].retval ;
285+ if (desc_ret == CMD_EXEC_SUCCESS )
286+ ret = 0 ;
287+ else
288+ ret = - EIO ;
289+ priv -> cmq .last_status = desc_ret ;
290+ ntc ++ ;
291+ handle ++ ;
292+ if (ntc == csq -> desc_num )
293+ ntc = 0 ;
294+ }
295+ }
296+
297+ if (!complete )
298+ ret = - EAGAIN ;
299+
300+ /* clean the command send queue */
301+ handle = hns_roce_cmq_csq_clean (hr_dev );
302+ if (handle != num )
303+ dev_warn (hr_dev -> dev , "Cleaned %d, need to clean %d\n" ,
304+ handle , num );
305+
306+ spin_unlock_bh (& csq -> lock );
307+
308+ return ret ;
309+ }
310+
311+ static const struct hns_roce_hw hns_roce_hw_v2 = {
312+ .cmq_init = hns_roce_v2_cmq_init ,
313+ .cmq_exit = hns_roce_v2_cmq_exit ,
314+ };
46315
47316static const struct pci_device_id hns_roce_hw_v2_pci_tbl [] = {
48317 {PCI_VDEVICE (HUAWEI , HNAE3_DEV_ID_25GE_RDMA ), 0 },
@@ -87,6 +356,12 @@ static int hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
87356 if (!hr_dev )
88357 return - ENOMEM ;
89358
359+ hr_dev -> priv = kzalloc (sizeof (struct hns_roce_v2_priv ), GFP_KERNEL );
360+ if (!hr_dev -> priv ) {
361+ ret = - ENOMEM ;
362+ goto error_failed_kzalloc ;
363+ }
364+
90365 hr_dev -> pci_dev = handle -> pdev ;
91366 hr_dev -> dev = & handle -> pdev -> dev ;
92367 handle -> priv = hr_dev ;
@@ -106,6 +381,9 @@ static int hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
106381 return 0 ;
107382
108383error_failed_get_cfg :
384+ kfree (hr_dev -> priv );
385+
386+ error_failed_kzalloc :
109387 ib_dealloc_device (& hr_dev -> ib_dev );
110388
111389 return ret ;
@@ -117,6 +395,7 @@ static void hns_roce_hw_v2_uninit_instance(struct hnae3_handle *handle,
117395 struct hns_roce_dev * hr_dev = (struct hns_roce_dev * )handle -> priv ;
118396
119397 hns_roce_exit (hr_dev );
398+ kfree (hr_dev -> priv );
120399 ib_dealloc_device (& hr_dev -> ib_dev );
121400}
122401
0 commit comments