@@ -135,20 +135,71 @@ static int gve_adminq_parse_err(struct gve_priv *priv, u32 status)
135135 }
136136}
137137
138+ /* Flushes all AQ commands currently queued and waits for them to complete.
139+ * If there are failures, it will return the first error.
140+ */
141+ static int gve_adminq_kick_and_wait (struct gve_priv * priv )
142+ {
143+ u32 tail , head ;
144+ int i ;
145+
146+ tail = ioread32be (& priv -> reg_bar0 -> adminq_event_counter );
147+ head = priv -> adminq_prod_cnt ;
148+
149+ gve_adminq_kick_cmd (priv , head );
150+ if (!gve_adminq_wait_for_cmd (priv , head )) {
151+ dev_err (& priv -> pdev -> dev , "AQ commands timed out, need to reset AQ\n" );
152+ priv -> adminq_timeouts ++ ;
153+ return - ENOTRECOVERABLE ;
154+ }
155+
156+ for (i = tail ; i < head ; i ++ ) {
157+ union gve_adminq_command * cmd ;
158+ u32 status , err ;
159+
160+ cmd = & priv -> adminq [i & priv -> adminq_mask ];
161+ status = be32_to_cpu (READ_ONCE (cmd -> status ));
162+ err = gve_adminq_parse_err (priv , status );
163+ if (err )
164+ // Return the first error if we failed.
165+ return err ;
166+ }
167+
168+ return 0 ;
169+ }
170+
138171/* This function is not threadsafe - the caller is responsible for any
139172 * necessary locks.
140173 */
141- int gve_adminq_execute_cmd (struct gve_priv * priv ,
142- union gve_adminq_command * cmd_orig )
174+ static int gve_adminq_issue_cmd (struct gve_priv * priv ,
175+ union gve_adminq_command * cmd_orig )
143176{
144177 union gve_adminq_command * cmd ;
145- u32 status = 0 ;
146- u32 prod_cnt ;
147178 u32 opcode ;
179+ u32 tail ;
180+
181+ tail = ioread32be (& priv -> reg_bar0 -> adminq_event_counter );
182+
183+ // Check if next command will overflow the buffer.
184+ if (((priv -> adminq_prod_cnt + 1 ) & priv -> adminq_mask ) == tail ) {
185+ int err ;
186+
187+ // Flush existing commands to make room.
188+ err = gve_adminq_kick_and_wait (priv );
189+ if (err )
190+ return err ;
191+
192+ // Retry.
193+ tail = ioread32be (& priv -> reg_bar0 -> adminq_event_counter );
194+ if (((priv -> adminq_prod_cnt + 1 ) & priv -> adminq_mask ) == tail ) {
195+ // This should never happen. We just flushed the
196+ // command queue so there should be enough space.
197+ return - ENOMEM ;
198+ }
199+ }
148200
149201 cmd = & priv -> adminq [priv -> adminq_prod_cnt & priv -> adminq_mask ];
150202 priv -> adminq_prod_cnt ++ ;
151- prod_cnt = priv -> adminq_prod_cnt ;
152203
153204 memcpy (cmd , cmd_orig , sizeof (* cmd_orig ));
154205 opcode = be32_to_cpu (READ_ONCE (cmd -> opcode ));
@@ -191,16 +242,30 @@ int gve_adminq_execute_cmd(struct gve_priv *priv,
191242 dev_err (& priv -> pdev -> dev , "unknown AQ command opcode %d\n" , opcode );
192243 }
193244
194- gve_adminq_kick_cmd (priv , prod_cnt );
195- if (!gve_adminq_wait_for_cmd (priv , prod_cnt )) {
196- dev_err (& priv -> pdev -> dev , "AQ command timed out, need to reset AQ\n" );
197- priv -> adminq_timeouts ++ ;
198- return - ENOTRECOVERABLE ;
199- }
245+ return 0 ;
246+ }
200247
201- memcpy (cmd_orig , cmd , sizeof (* cmd ));
202- status = be32_to_cpu (READ_ONCE (cmd -> status ));
203- return gve_adminq_parse_err (priv , status );
248+ /* This function is not threadsafe - the caller is responsible for any
249+ * necessary locks.
250+ * The caller is also responsible for making sure there are no commands
251+ * waiting to be executed.
252+ */
253+ static int gve_adminq_execute_cmd (struct gve_priv * priv , union gve_adminq_command * cmd_orig )
254+ {
255+ u32 tail , head ;
256+ int err ;
257+
258+ tail = ioread32be (& priv -> reg_bar0 -> adminq_event_counter );
259+ head = priv -> adminq_prod_cnt ;
260+ if (tail != head )
261+ // This is not a valid path
262+ return - EINVAL ;
263+
264+ err = gve_adminq_issue_cmd (priv , cmd_orig );
265+ if (err )
266+ return err ;
267+
268+ return gve_adminq_kick_and_wait (priv );
204269}
205270
206271/* The device specifies that the management vector can either be the first irq
@@ -245,29 +310,50 @@ int gve_adminq_deconfigure_device_resources(struct gve_priv *priv)
245310 return gve_adminq_execute_cmd (priv , & cmd );
246311}
247312
248- int gve_adminq_create_tx_queue (struct gve_priv * priv , u32 queue_index )
313+ static int gve_adminq_create_tx_queue (struct gve_priv * priv , u32 queue_index )
249314{
250315 struct gve_tx_ring * tx = & priv -> tx [queue_index ];
251316 union gve_adminq_command cmd ;
317+ int err ;
252318
253319 memset (& cmd , 0 , sizeof (cmd ));
254320 cmd .opcode = cpu_to_be32 (GVE_ADMINQ_CREATE_TX_QUEUE );
255321 cmd .create_tx_queue = (struct gve_adminq_create_tx_queue ) {
256322 .queue_id = cpu_to_be32 (queue_index ),
257323 .reserved = 0 ,
258- .queue_resources_addr = cpu_to_be64 (tx -> q_resources_bus ),
324+ .queue_resources_addr =
325+ cpu_to_be64 (tx -> q_resources_bus ),
259326 .tx_ring_addr = cpu_to_be64 (tx -> bus ),
260327 .queue_page_list_id = cpu_to_be32 (tx -> tx_fifo .qpl -> id ),
261328 .ntfy_id = cpu_to_be32 (tx -> ntfy_id ),
262329 };
263330
264- return gve_adminq_execute_cmd (priv , & cmd );
331+ err = gve_adminq_issue_cmd (priv , & cmd );
332+ if (err )
333+ return err ;
334+
335+ return 0 ;
265336}
266337
267- int gve_adminq_create_rx_queue (struct gve_priv * priv , u32 queue_index )
338+ int gve_adminq_create_tx_queues (struct gve_priv * priv , u32 num_queues )
339+ {
340+ int err ;
341+ int i ;
342+
343+ for (i = 0 ; i < num_queues ; i ++ ) {
344+ err = gve_adminq_create_tx_queue (priv , i );
345+ if (err )
346+ return err ;
347+ }
348+
349+ return gve_adminq_kick_and_wait (priv );
350+ }
351+
352+ static int gve_adminq_create_rx_queue (struct gve_priv * priv , u32 queue_index )
268353{
269354 struct gve_rx_ring * rx = & priv -> rx [queue_index ];
270355 union gve_adminq_command cmd ;
356+ int err ;
271357
272358 memset (& cmd , 0 , sizeof (cmd ));
273359 cmd .opcode = cpu_to_be32 (GVE_ADMINQ_CREATE_RX_QUEUE );
@@ -282,33 +368,89 @@ int gve_adminq_create_rx_queue(struct gve_priv *priv, u32 queue_index)
282368 .queue_page_list_id = cpu_to_be32 (rx -> data .qpl -> id ),
283369 };
284370
285- return gve_adminq_execute_cmd (priv , & cmd );
371+ err = gve_adminq_issue_cmd (priv , & cmd );
372+ if (err )
373+ return err ;
374+
375+ return 0 ;
286376}
287377
288- int gve_adminq_destroy_tx_queue (struct gve_priv * priv , u32 queue_index )
378+ int gve_adminq_create_rx_queues (struct gve_priv * priv , u32 num_queues )
379+ {
380+ int err ;
381+ int i ;
382+
383+ for (i = 0 ; i < num_queues ; i ++ ) {
384+ err = gve_adminq_create_rx_queue (priv , i );
385+ if (err )
386+ return err ;
387+ }
388+
389+ return gve_adminq_kick_and_wait (priv );
390+ }
391+
392+ static int gve_adminq_destroy_tx_queue (struct gve_priv * priv , u32 queue_index )
289393{
290394 union gve_adminq_command cmd ;
395+ int err ;
291396
292397 memset (& cmd , 0 , sizeof (cmd ));
293398 cmd .opcode = cpu_to_be32 (GVE_ADMINQ_DESTROY_TX_QUEUE );
294399 cmd .destroy_tx_queue = (struct gve_adminq_destroy_tx_queue ) {
295400 .queue_id = cpu_to_be32 (queue_index ),
296401 };
297402
298- return gve_adminq_execute_cmd (priv , & cmd );
403+ err = gve_adminq_issue_cmd (priv , & cmd );
404+ if (err )
405+ return err ;
406+
407+ return 0 ;
299408}
300409
301- int gve_adminq_destroy_rx_queue (struct gve_priv * priv , u32 queue_index )
410+ int gve_adminq_destroy_tx_queues (struct gve_priv * priv , u32 num_queues )
411+ {
412+ int err ;
413+ int i ;
414+
415+ for (i = 0 ; i < num_queues ; i ++ ) {
416+ err = gve_adminq_destroy_tx_queue (priv , i );
417+ if (err )
418+ return err ;
419+ }
420+
421+ return gve_adminq_kick_and_wait (priv );
422+ }
423+
424+ static int gve_adminq_destroy_rx_queue (struct gve_priv * priv , u32 queue_index )
302425{
303426 union gve_adminq_command cmd ;
427+ int err ;
304428
305429 memset (& cmd , 0 , sizeof (cmd ));
306430 cmd .opcode = cpu_to_be32 (GVE_ADMINQ_DESTROY_RX_QUEUE );
307431 cmd .destroy_rx_queue = (struct gve_adminq_destroy_rx_queue ) {
308432 .queue_id = cpu_to_be32 (queue_index ),
309433 };
310434
311- return gve_adminq_execute_cmd (priv , & cmd );
435+ err = gve_adminq_issue_cmd (priv , & cmd );
436+ if (err )
437+ return err ;
438+
439+ return 0 ;
440+ }
441+
442+ int gve_adminq_destroy_rx_queues (struct gve_priv * priv , u32 num_queues )
443+ {
444+ int err ;
445+ int i ;
446+
447+ for (i = 0 ; i < num_queues ; i ++ ) {
448+ err = gve_adminq_destroy_rx_queue (priv , i );
449+ if (err )
450+ return err ;
451+ }
452+
453+ return gve_adminq_kick_and_wait (priv );
312454}
313455
314456int gve_adminq_describe_device (struct gve_priv * priv )
0 commit comments