2121#include "cmd.h"
2222#include "port.h"
2323#include "resources.h"
24+ #include "txheader.h"
2425
2526#define mlxsw_pci_write32 (mlxsw_pci , reg , val ) \
2627 iowrite32be(val, (mlxsw_pci)->hw_addr + (MLXSW_PCI_ ## reg))
@@ -737,6 +738,7 @@ static void mlxsw_pci_cqe_rdq_md_init(struct sk_buff *skb, const char *cqe)
737738}
738739
739740static void mlxsw_pci_cqe_rdq_handle (struct mlxsw_pci * mlxsw_pci ,
741+ struct napi_struct * napi ,
740742 struct mlxsw_pci_queue * q ,
741743 u16 consumer_counter_limit ,
742744 enum mlxsw_pci_cqe_v cqe_v , char * cqe )
@@ -807,6 +809,7 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci,
807809 }
808810
809811 mlxsw_pci_skb_cb_ts_set (mlxsw_pci , skb , cqe_v , cqe );
812+ mlxsw_skb_cb (skb )-> rx_md_info .napi = napi ;
810813
811814 mlxsw_core_skb_receive (mlxsw_pci -> core , skb , & rx_info );
812815
@@ -869,7 +872,7 @@ static int mlxsw_pci_napi_poll_cq_rx(struct napi_struct *napi, int budget)
869872 continue ;
870873 }
871874
872- mlxsw_pci_cqe_rdq_handle (mlxsw_pci , rdq ,
875+ mlxsw_pci_cqe_rdq_handle (mlxsw_pci , napi , rdq ,
873876 wqe_counter , q -> u .cq .v , cqe );
874877
875878 if (++ work_done == budget )
@@ -2093,6 +2096,39 @@ static void mlxsw_pci_fini(void *bus_priv)
20932096 mlxsw_pci_free_irq_vectors (mlxsw_pci );
20942097}
20952098
2099+ static int mlxsw_pci_txhdr_construct (struct sk_buff * skb ,
2100+ const struct mlxsw_txhdr_info * txhdr_info )
2101+ {
2102+ const struct mlxsw_tx_info tx_info = txhdr_info -> tx_info ;
2103+ char * txhdr ;
2104+
2105+ if (skb_cow_head (skb , MLXSW_TXHDR_LEN ))
2106+ return - ENOMEM ;
2107+
2108+ txhdr = skb_push (skb , MLXSW_TXHDR_LEN );
2109+ memset (txhdr , 0 , MLXSW_TXHDR_LEN );
2110+
2111+ mlxsw_tx_hdr_version_set (txhdr , MLXSW_TXHDR_VERSION_1 );
2112+ mlxsw_tx_hdr_proto_set (txhdr , MLXSW_TXHDR_PROTO_ETH );
2113+ mlxsw_tx_hdr_swid_set (txhdr , 0 );
2114+
2115+ if (unlikely (txhdr_info -> data )) {
2116+ u16 fid = txhdr_info -> max_fid + tx_info .local_port - 1 ;
2117+
2118+ mlxsw_tx_hdr_rx_is_router_set (txhdr , true);
2119+ mlxsw_tx_hdr_fid_valid_set (txhdr , true);
2120+ mlxsw_tx_hdr_fid_set (txhdr , fid );
2121+ mlxsw_tx_hdr_type_set (txhdr , MLXSW_TXHDR_TYPE_DATA );
2122+ } else {
2123+ mlxsw_tx_hdr_ctl_set (txhdr , MLXSW_TXHDR_ETH_CTL );
2124+ mlxsw_tx_hdr_control_tclass_set (txhdr , 1 );
2125+ mlxsw_tx_hdr_port_mid_set (txhdr , tx_info .local_port );
2126+ mlxsw_tx_hdr_type_set (txhdr , MLXSW_TXHDR_TYPE_CONTROL );
2127+ }
2128+
2129+ return 0 ;
2130+ }
2131+
20962132static struct mlxsw_pci_queue *
20972133mlxsw_pci_sdq_pick (struct mlxsw_pci * mlxsw_pci ,
20982134 const struct mlxsw_tx_info * tx_info )
@@ -2120,7 +2156,7 @@ static bool mlxsw_pci_skb_transmit_busy(void *bus_priv,
21202156}
21212157
21222158static int mlxsw_pci_skb_transmit (void * bus_priv , struct sk_buff * skb ,
2123- const struct mlxsw_tx_info * tx_info )
2159+ const struct mlxsw_txhdr_info * txhdr_info )
21242160{
21252161 struct mlxsw_pci * mlxsw_pci = bus_priv ;
21262162 struct mlxsw_pci_queue * q ;
@@ -2129,21 +2165,25 @@ static int mlxsw_pci_skb_transmit(void *bus_priv, struct sk_buff *skb,
21292165 int i ;
21302166 int err ;
21312167
2168+ err = mlxsw_pci_txhdr_construct (skb , txhdr_info );
2169+ if (err )
2170+ return err ;
2171+
21322172 if (skb_shinfo (skb )-> nr_frags > MLXSW_PCI_WQE_SG_ENTRIES - 1 ) {
21332173 err = skb_linearize (skb );
21342174 if (err )
21352175 return err ;
21362176 }
21372177
2138- q = mlxsw_pci_sdq_pick (mlxsw_pci , tx_info );
2178+ q = mlxsw_pci_sdq_pick (mlxsw_pci , & txhdr_info -> tx_info );
21392179 spin_lock_bh (& q -> lock );
21402180 elem_info = mlxsw_pci_queue_elem_info_producer_get (q );
21412181 if (!elem_info ) {
21422182 /* queue is full */
21432183 err = - EAGAIN ;
21442184 goto unlock ;
21452185 }
2146- mlxsw_skb_cb (skb )-> tx_info = * tx_info ;
2186+ mlxsw_skb_cb (skb )-> tx_info = txhdr_info -> tx_info ;
21472187 elem_info -> sdq .skb = skb ;
21482188
21492189 wqe = elem_info -> elem ;
@@ -2174,6 +2214,8 @@ static int mlxsw_pci_skb_transmit(void *bus_priv, struct sk_buff *skb,
21742214 for (i ++ ; i < MLXSW_PCI_WQE_SG_ENTRIES ; i ++ )
21752215 mlxsw_pci_wqe_byte_count_set (wqe , i , 0 );
21762216
2217+ mlxsw_pci_wqe_ipcs_set (wqe , skb -> ip_summed == CHECKSUM_PARTIAL );
2218+
21772219 /* Everything is set up, ring producer doorbell to get HW going */
21782220 q -> producer_counter ++ ;
21792221 mlxsw_pci_queue_doorbell_producer_ring (mlxsw_pci , q );
0 commit comments