@@ -17,11 +17,29 @@ static void __fbnic_mbx_wr_desc(struct fbnic_dev *fbd, int mbx_idx,
1717{
1818 u32 desc_offset = FBNIC_IPC_MBX (mbx_idx , desc_idx );
1919
20+ /* Write the upper 32b and then the lower 32b. Doing this the
21+ * FW can then read lower, upper, lower to verify that the state
22+ * of the descriptor wasn't changed mid-transaction.
23+ */
2024 fw_wr32 (fbd , desc_offset + 1 , upper_32_bits (desc ));
2125 fw_wrfl (fbd );
2226 fw_wr32 (fbd , desc_offset , lower_32_bits (desc ));
2327}
2428
29+ static void __fbnic_mbx_invalidate_desc (struct fbnic_dev * fbd , int mbx_idx ,
30+ int desc_idx , u32 desc )
31+ {
32+ u32 desc_offset = FBNIC_IPC_MBX (mbx_idx , desc_idx );
33+
34+ /* For initialization we write the lower 32b of the descriptor first.
35+ * This way we can set the state to mark it invalid before we clear the
36+ * upper 32b.
37+ */
38+ fw_wr32 (fbd , desc_offset , desc );
39+ fw_wrfl (fbd );
40+ fw_wr32 (fbd , desc_offset + 1 , 0 );
41+ }
42+
2543static u64 __fbnic_mbx_rd_desc (struct fbnic_dev * fbd , int mbx_idx , int desc_idx )
2644{
2745 u32 desc_offset = FBNIC_IPC_MBX (mbx_idx , desc_idx );
@@ -33,29 +51,41 @@ static u64 __fbnic_mbx_rd_desc(struct fbnic_dev *fbd, int mbx_idx, int desc_idx)
3351 return desc ;
3452}
3553
36- static void fbnic_mbx_init_desc_ring (struct fbnic_dev * fbd , int mbx_idx )
54+ static void fbnic_mbx_reset_desc_ring (struct fbnic_dev * fbd , int mbx_idx )
3755{
3856 int desc_idx ;
3957
58+ /* Disable DMA transactions from the device,
59+ * and flush any transactions triggered during cleaning
60+ */
61+ switch (mbx_idx ) {
62+ case FBNIC_IPC_MBX_RX_IDX :
63+ wr32 (fbd , FBNIC_PUL_OB_TLP_HDR_AW_CFG ,
64+ FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH );
65+ break ;
66+ case FBNIC_IPC_MBX_TX_IDX :
67+ wr32 (fbd , FBNIC_PUL_OB_TLP_HDR_AR_CFG ,
68+ FBNIC_PUL_OB_TLP_HDR_AR_CFG_FLUSH );
69+ break ;
70+ }
71+
72+ wrfl (fbd );
73+
4074 /* Initialize first descriptor to all 0s. Doing this gives us a
4175 * solid stop for the firmware to hit when it is done looping
4276 * through the ring.
4377 */
44- __fbnic_mbx_wr_desc (fbd , mbx_idx , 0 , 0 );
45-
46- fw_wrfl (fbd );
78+ __fbnic_mbx_invalidate_desc (fbd , mbx_idx , 0 , 0 );
4779
4880 /* We then fill the rest of the ring starting at the end and moving
4981 * back toward descriptor 0 with skip descriptors that have no
5082 * length nor address, and tell the firmware that they can skip
5183 * them and just move past them to the one we initialized to 0.
5284 */
53- for (desc_idx = FBNIC_IPC_MBX_DESC_LEN ; -- desc_idx ;) {
54- __fbnic_mbx_wr_desc (fbd , mbx_idx , desc_idx ,
55- FBNIC_IPC_MBX_DESC_FW_CMPL |
56- FBNIC_IPC_MBX_DESC_HOST_CMPL );
57- fw_wrfl (fbd );
58- }
85+ for (desc_idx = FBNIC_IPC_MBX_DESC_LEN ; -- desc_idx ;)
86+ __fbnic_mbx_invalidate_desc (fbd , mbx_idx , desc_idx ,
87+ FBNIC_IPC_MBX_DESC_FW_CMPL |
88+ FBNIC_IPC_MBX_DESC_HOST_CMPL );
5989}
6090
6191void fbnic_mbx_init (struct fbnic_dev * fbd )
@@ -76,7 +106,7 @@ void fbnic_mbx_init(struct fbnic_dev *fbd)
76106 wr32 (fbd , FBNIC_INTR_CLEAR (0 ), 1u << FBNIC_FW_MSIX_ENTRY );
77107
78108 for (i = 0 ; i < FBNIC_IPC_MBX_INDICES ; i ++ )
79- fbnic_mbx_init_desc_ring (fbd , i );
109+ fbnic_mbx_reset_desc_ring (fbd , i );
80110}
81111
82112static int fbnic_mbx_map_msg (struct fbnic_dev * fbd , int mbx_idx ,
@@ -141,7 +171,7 @@ static void fbnic_mbx_clean_desc_ring(struct fbnic_dev *fbd, int mbx_idx)
141171{
142172 int i ;
143173
144- fbnic_mbx_init_desc_ring (fbd , mbx_idx );
174+ fbnic_mbx_reset_desc_ring (fbd , mbx_idx );
145175
146176 for (i = FBNIC_IPC_MBX_DESC_LEN ; i -- ;)
147177 fbnic_mbx_unmap_and_free_msg (fbd , mbx_idx , i );
@@ -322,67 +352,41 @@ static int fbnic_fw_xmit_simple_msg(struct fbnic_dev *fbd, u32 msg_type)
322352 return err ;
323353}
324354
325- /**
326- * fbnic_fw_xmit_cap_msg - Allocate and populate a FW capabilities message
327- * @fbd: FBNIC device structure
328- *
329- * Return: NULL on failure to allocate, error pointer on error, or pointer
330- * to new TLV test message.
331- *
332- * Sends a single TLV header indicating the host wants the firmware to
333- * confirm the capabilities and version.
334- **/
335- static int fbnic_fw_xmit_cap_msg (struct fbnic_dev * fbd )
336- {
337- int err = fbnic_fw_xmit_simple_msg (fbd , FBNIC_TLV_MSG_ID_HOST_CAP_REQ );
338-
339- /* Return 0 if we are not calling this on ASIC */
340- return (err == - EOPNOTSUPP ) ? 0 : err ;
341- }
342-
343- static void fbnic_mbx_postinit_desc_ring (struct fbnic_dev * fbd , int mbx_idx )
355+ static void fbnic_mbx_init_desc_ring (struct fbnic_dev * fbd , int mbx_idx )
344356{
345357 struct fbnic_fw_mbx * mbx = & fbd -> mbx [mbx_idx ];
346358
347- /* This is a one time init, so just exit if it is completed */
348- if (mbx -> ready )
349- return ;
350-
351359 mbx -> ready = true;
352360
353361 switch (mbx_idx ) {
354362 case FBNIC_IPC_MBX_RX_IDX :
363+ /* Enable DMA writes from the device */
364+ wr32 (fbd , FBNIC_PUL_OB_TLP_HDR_AW_CFG ,
365+ FBNIC_PUL_OB_TLP_HDR_AW_CFG_BME );
366+
355367 /* Make sure we have a page for the FW to write to */
356368 fbnic_mbx_alloc_rx_msgs (fbd );
357369 break ;
358370 case FBNIC_IPC_MBX_TX_IDX :
359- /* Force version to 1 if we successfully requested an update
360- * from the firmware. This should be overwritten once we get
361- * the actual version from the firmware in the capabilities
362- * request message.
363- */
364- if (!fbnic_fw_xmit_cap_msg (fbd ) &&
365- !fbd -> fw_cap .running .mgmt .version )
366- fbd -> fw_cap .running .mgmt .version = 1 ;
371+ /* Enable DMA reads from the device */
372+ wr32 (fbd , FBNIC_PUL_OB_TLP_HDR_AR_CFG ,
373+ FBNIC_PUL_OB_TLP_HDR_AR_CFG_BME );
367374 break ;
368375 }
369376}
370377
371- static void fbnic_mbx_postinit (struct fbnic_dev * fbd )
378+ static bool fbnic_mbx_event (struct fbnic_dev * fbd )
372379{
373- int i ;
374-
375- /* We only need to do this on the first interrupt following init.
380+ /* We only need to do this on the first interrupt following reset.
376381 * this primes the mailbox so that we will have cleared all the
377382 * skip descriptors.
378383 */
379384 if (!(rd32 (fbd , FBNIC_INTR_STATUS (0 )) & (1u << FBNIC_FW_MSIX_ENTRY )))
380- return ;
385+ return false ;
381386
382387 wr32 (fbd , FBNIC_INTR_CLEAR (0 ), 1u << FBNIC_FW_MSIX_ENTRY );
383388
384- for (i = 0 ; i < FBNIC_IPC_MBX_INDICES ; i ++ )
385- fbnic_mbx_postinit_desc_ring (fbd , i );
389+ return true;
386390}
387391
388392/**
@@ -859,68 +863,105 @@ static void fbnic_mbx_process_rx_msgs(struct fbnic_dev *fbd)
859863
860864void fbnic_mbx_poll (struct fbnic_dev * fbd )
861865{
862- fbnic_mbx_postinit (fbd );
866+ fbnic_mbx_event (fbd );
863867
864868 fbnic_mbx_process_tx_msgs (fbd );
865869 fbnic_mbx_process_rx_msgs (fbd );
866870}
867871
868872int fbnic_mbx_poll_tx_ready (struct fbnic_dev * fbd )
869873{
870- struct fbnic_fw_mbx * tx_mbx ;
871- int attempts = 50 ;
874+ unsigned long timeout = jiffies + 10 * HZ + 1 ;
875+ int err , i ;
872876
873- /* Immediate fail if BAR4 isn't there */
874- if (!fbnic_fw_present ( fbd ))
875- return - ENODEV ;
877+ do {
878+ if (!time_is_after_jiffies ( timeout ))
879+ return - ETIMEDOUT ;
876880
877- tx_mbx = & fbd -> mbx [FBNIC_IPC_MBX_TX_IDX ];
878- while (!tx_mbx -> ready && -- attempts ) {
879881 /* Force the firmware to trigger an interrupt response to
880882 * avoid the mailbox getting stuck closed if the interrupt
881883 * is reset.
882884 */
883- fbnic_mbx_init_desc_ring (fbd , FBNIC_IPC_MBX_TX_IDX );
885+ fbnic_mbx_reset_desc_ring (fbd , FBNIC_IPC_MBX_TX_IDX );
884886
885- msleep (200 );
887+ /* Immediate fail if BAR4 went away */
888+ if (!fbnic_fw_present (fbd ))
889+ return - ENODEV ;
886890
887- fbnic_mbx_poll (fbd );
888- }
891+ msleep (20 );
892+ } while (!fbnic_mbx_event (fbd ));
893+
894+ /* FW has shown signs of life. Enable DMA and start Tx/Rx */
895+ for (i = 0 ; i < FBNIC_IPC_MBX_INDICES ; i ++ )
896+ fbnic_mbx_init_desc_ring (fbd , i );
897+
898+ /* Request an update from the firmware. This should overwrite
899+ * mgmt.version once we get the actual version from the firmware
900+ * in the capabilities request message.
901+ */
902+ err = fbnic_fw_xmit_simple_msg (fbd , FBNIC_TLV_MSG_ID_HOST_CAP_REQ );
903+ if (err )
904+ goto clean_mbx ;
905+
906+ /* Use "1" to indicate we entered the state waiting for a response */
907+ fbd -> fw_cap .running .mgmt .version = 1 ;
908+
909+ return 0 ;
910+ clean_mbx :
911+ /* Cleanup Rx buffers and disable mailbox */
912+ fbnic_mbx_clean (fbd );
913+ return err ;
914+ }
915+
916+ static void __fbnic_fw_evict_cmpl (struct fbnic_fw_completion * cmpl_data )
917+ {
918+ cmpl_data -> result = - EPIPE ;
919+ complete (& cmpl_data -> done );
920+ }
889921
890- return attempts ? 0 : - ETIMEDOUT ;
922+ static void fbnic_mbx_evict_all_cmpl (struct fbnic_dev * fbd )
923+ {
924+ if (fbd -> cmpl_data ) {
925+ __fbnic_fw_evict_cmpl (fbd -> cmpl_data );
926+ fbd -> cmpl_data = NULL ;
927+ }
891928}
892929
893930void fbnic_mbx_flush_tx (struct fbnic_dev * fbd )
894931{
932+ unsigned long timeout = jiffies + 10 * HZ + 1 ;
895933 struct fbnic_fw_mbx * tx_mbx ;
896- int attempts = 50 ;
897- u8 count = 0 ;
898-
899- /* Nothing to do if there is no mailbox */
900- if (!fbnic_fw_present (fbd ))
901- return ;
934+ u8 tail ;
902935
903936 /* Record current Rx stats */
904937 tx_mbx = & fbd -> mbx [FBNIC_IPC_MBX_TX_IDX ];
905938
906- /* Nothing to do if mailbox never got to ready */
907- if (!tx_mbx -> ready )
908- return ;
939+ spin_lock_irq (& fbd -> fw_tx_lock );
940+
941+ /* Clear ready to prevent any further attempts to transmit */
942+ tx_mbx -> ready = false;
943+
944+ /* Read tail to determine the last tail state for the ring */
945+ tail = tx_mbx -> tail ;
946+
947+ /* Flush any completions as we are no longer processing Rx */
948+ fbnic_mbx_evict_all_cmpl (fbd );
949+
950+ spin_unlock_irq (& fbd -> fw_tx_lock );
909951
910952 /* Give firmware time to process packet,
911- * we will wait up to 10 seconds which is 50 waits of 200ms .
953+ * we will wait up to 10 seconds which is 500 waits of 20ms .
912954 */
913955 do {
914956 u8 head = tx_mbx -> head ;
915957
916- if (head == tx_mbx -> tail )
958+ /* Tx ring is empty once head == tail */
959+ if (head == tail )
917960 break ;
918961
919- msleep (200 );
962+ msleep (20 );
920963 fbnic_mbx_process_tx_msgs (fbd );
921-
922- count += (tx_mbx -> head - head ) % FBNIC_IPC_MBX_DESC_LEN ;
923- } while (count < FBNIC_IPC_MBX_DESC_LEN && -- attempts );
964+ } while (time_is_after_jiffies (timeout ));
924965}
925966
926967void fbnic_get_fw_ver_commit_str (struct fbnic_dev * fbd , char * fw_version ,
0 commit comments