@@ -116,6 +116,7 @@ static void free_long_term_buff(struct ibmvnic_adapter *adapter,
116116 struct ibmvnic_long_term_buff * ltb );
117117static void ibmvnic_disable_irqs (struct ibmvnic_adapter * adapter );
118118static void flush_reset_queue (struct ibmvnic_adapter * adapter );
119+ static void print_subcrq_error (struct device * dev , int rc , const char * func );
119120
120121struct ibmvnic_stat {
121122 char name [ETH_GSTRING_LEN ];
@@ -1935,63 +1936,49 @@ static int ibmvnic_close(struct net_device *netdev)
19351936}
19361937
19371938/**
1938- * build_hdr_data - creates L2/L3/L4 header data buffer
1939+ * get_hdr_lens - fills list of L2/L3/L4 hdr lens
19391940 * @hdr_field: bitfield determining needed headers
19401941 * @skb: socket buffer
1941- * @hdr_len: array of header lengths
1942- * @hdr_data: buffer to write the header to
1942+ * @hdr_len: array of header lengths to be filled
19431943 *
19441944 * Reads hdr_field to determine which headers are needed by firmware.
19451945 * Builds a buffer containing these headers. Saves individual header
19461946 * lengths and total buffer length to be used to build descriptors.
1947+ *
1948+ * Return: total len of all headers
19471949 */
1948- static int build_hdr_data (u8 hdr_field , struct sk_buff * skb ,
1949- int * hdr_len , u8 * hdr_data )
1950+ static int get_hdr_lens (u8 hdr_field , struct sk_buff * skb ,
1951+ int * hdr_len )
19501952{
19511953 int len = 0 ;
1952- u8 * hdr ;
19531954
1954- if (skb_vlan_tagged (skb ) && !skb_vlan_tag_present (skb ))
1955- hdr_len [0 ] = sizeof (struct vlan_ethhdr );
1956- else
1957- hdr_len [0 ] = sizeof (struct ethhdr );
1955+
1956+ if ((hdr_field >> 6 ) & 1 ) {
1957+ hdr_len [0 ] = skb_mac_header_len (skb );
1958+ len += hdr_len [0 ];
1959+ }
1960+
1961+ if ((hdr_field >> 5 ) & 1 ) {
1962+ hdr_len [1 ] = skb_network_header_len (skb );
1963+ len += hdr_len [1 ];
1964+ }
1965+
1966+ if (!((hdr_field >> 4 ) & 1 ))
1967+ return len ;
19581968
19591969 if (skb -> protocol == htons (ETH_P_IP )) {
1960- hdr_len [1 ] = ip_hdr (skb )-> ihl * 4 ;
19611970 if (ip_hdr (skb )-> protocol == IPPROTO_TCP )
19621971 hdr_len [2 ] = tcp_hdrlen (skb );
19631972 else if (ip_hdr (skb )-> protocol == IPPROTO_UDP )
19641973 hdr_len [2 ] = sizeof (struct udphdr );
19651974 } else if (skb -> protocol == htons (ETH_P_IPV6 )) {
1966- hdr_len [1 ] = sizeof (struct ipv6hdr );
19671975 if (ipv6_hdr (skb )-> nexthdr == IPPROTO_TCP )
19681976 hdr_len [2 ] = tcp_hdrlen (skb );
19691977 else if (ipv6_hdr (skb )-> nexthdr == IPPROTO_UDP )
19701978 hdr_len [2 ] = sizeof (struct udphdr );
1971- } else if (skb -> protocol == htons (ETH_P_ARP )) {
1972- hdr_len [1 ] = arp_hdr_len (skb -> dev );
1973- hdr_len [2 ] = 0 ;
1974- }
1975-
1976- memset (hdr_data , 0 , 120 );
1977- if ((hdr_field >> 6 ) & 1 ) {
1978- hdr = skb_mac_header (skb );
1979- memcpy (hdr_data , hdr , hdr_len [0 ]);
1980- len += hdr_len [0 ];
19811979 }
19821980
1983- if ((hdr_field >> 5 ) & 1 ) {
1984- hdr = skb_network_header (skb );
1985- memcpy (hdr_data + len , hdr , hdr_len [1 ]);
1986- len += hdr_len [1 ];
1987- }
1988-
1989- if ((hdr_field >> 4 ) & 1 ) {
1990- hdr = skb_transport_header (skb );
1991- memcpy (hdr_data + len , hdr , hdr_len [2 ]);
1992- len += hdr_len [2 ];
1993- }
1994- return len ;
1981+ return len + hdr_len [2 ];
19951982}
19961983
19971984/**
@@ -2004,12 +1991,14 @@ static int build_hdr_data(u8 hdr_field, struct sk_buff *skb,
20041991 *
20051992 * Creates header and, if needed, header extension descriptors and
20061993 * places them in a descriptor array, scrq_arr
1994+ *
1995+ * Return: Number of header descs
20071996 */
20081997
20091998static int create_hdr_descs (u8 hdr_field , u8 * hdr_data , int len , int * hdr_len ,
20101999 union sub_crq * scrq_arr )
20112000{
2012- union sub_crq hdr_desc ;
2001+ union sub_crq * hdr_desc ;
20132002 int tmp_len = len ;
20142003 int num_descs = 0 ;
20152004 u8 * data , * cur ;
@@ -2018,28 +2007,26 @@ static int create_hdr_descs(u8 hdr_field, u8 *hdr_data, int len, int *hdr_len,
20182007 while (tmp_len > 0 ) {
20192008 cur = hdr_data + len - tmp_len ;
20202009
2021- memset ( & hdr_desc , 0 , sizeof ( hdr_desc )) ;
2022- if (cur != hdr_data ) {
2023- data = hdr_desc . hdr_ext .data ;
2010+ hdr_desc = & scrq_arr [ num_descs ] ;
2011+ if (num_descs ) {
2012+ data = hdr_desc -> hdr_ext .data ;
20242013 tmp = tmp_len > 29 ? 29 : tmp_len ;
2025- hdr_desc . hdr_ext .first = IBMVNIC_CRQ_CMD ;
2026- hdr_desc . hdr_ext .type = IBMVNIC_HDR_EXT_DESC ;
2027- hdr_desc . hdr_ext .len = tmp ;
2014+ hdr_desc -> hdr_ext .first = IBMVNIC_CRQ_CMD ;
2015+ hdr_desc -> hdr_ext .type = IBMVNIC_HDR_EXT_DESC ;
2016+ hdr_desc -> hdr_ext .len = tmp ;
20282017 } else {
2029- data = hdr_desc . hdr .data ;
2018+ data = hdr_desc -> hdr .data ;
20302019 tmp = tmp_len > 24 ? 24 : tmp_len ;
2031- hdr_desc . hdr .first = IBMVNIC_CRQ_CMD ;
2032- hdr_desc . hdr .type = IBMVNIC_HDR_DESC ;
2033- hdr_desc . hdr .len = tmp ;
2034- hdr_desc . hdr .l2_len = (u8 )hdr_len [0 ];
2035- hdr_desc . hdr .l3_len = cpu_to_be16 ((u16 )hdr_len [1 ]);
2036- hdr_desc . hdr .l4_len = (u8 )hdr_len [2 ];
2037- hdr_desc . hdr .flag = hdr_field << 1 ;
2020+ hdr_desc -> hdr .first = IBMVNIC_CRQ_CMD ;
2021+ hdr_desc -> hdr .type = IBMVNIC_HDR_DESC ;
2022+ hdr_desc -> hdr .len = tmp ;
2023+ hdr_desc -> hdr .l2_len = (u8 )hdr_len [0 ];
2024+ hdr_desc -> hdr .l3_len = cpu_to_be16 ((u16 )hdr_len [1 ]);
2025+ hdr_desc -> hdr .l4_len = (u8 )hdr_len [2 ];
2026+ hdr_desc -> hdr .flag = hdr_field << 1 ;
20382027 }
20392028 memcpy (data , cur , tmp );
20402029 tmp_len -= tmp ;
2041- * scrq_arr = hdr_desc ;
2042- scrq_arr ++ ;
20432030 num_descs ++ ;
20442031 }
20452032
@@ -2062,13 +2049,11 @@ static void build_hdr_descs_arr(struct sk_buff *skb,
20622049 int * num_entries , u8 hdr_field )
20632050{
20642051 int hdr_len [3 ] = {0 , 0 , 0 };
2065- u8 hdr_data [140 ] = {0 };
20662052 int tot_len ;
20672053
2068- tot_len = build_hdr_data (hdr_field , skb , hdr_len ,
2069- hdr_data );
2070- * num_entries += create_hdr_descs (hdr_field , hdr_data , tot_len , hdr_len ,
2071- indir_arr + 1 );
2054+ tot_len = get_hdr_lens (hdr_field , skb , hdr_len );
2055+ * num_entries += create_hdr_descs (hdr_field , skb_mac_header (skb ),
2056+ tot_len , hdr_len , indir_arr + 1 );
20722057}
20732058
20742059static int ibmvnic_xmit_workarounds (struct sk_buff * skb ,
@@ -2145,8 +2130,29 @@ static void ibmvnic_tx_scrq_clean_buffer(struct ibmvnic_adapter *adapter,
21452130 }
21462131}
21472132
2133+ static int send_subcrq_direct (struct ibmvnic_adapter * adapter ,
2134+ u64 remote_handle , u64 * entry )
2135+ {
2136+ unsigned int ua = adapter -> vdev -> unit_address ;
2137+ struct device * dev = & adapter -> vdev -> dev ;
2138+ int rc ;
2139+
2140+ /* Make sure the hypervisor sees the complete request */
2141+ dma_wmb ();
2142+ rc = plpar_hcall_norets (H_SEND_SUB_CRQ , ua ,
2143+ cpu_to_be64 (remote_handle ),
2144+ cpu_to_be64 (entry [0 ]), cpu_to_be64 (entry [1 ]),
2145+ cpu_to_be64 (entry [2 ]), cpu_to_be64 (entry [3 ]));
2146+
2147+ if (rc )
2148+ print_subcrq_error (dev , rc , __func__ );
2149+
2150+ return rc ;
2151+ }
2152+
21482153static int ibmvnic_tx_scrq_flush (struct ibmvnic_adapter * adapter ,
2149- struct ibmvnic_sub_crq_queue * tx_scrq )
2154+ struct ibmvnic_sub_crq_queue * tx_scrq ,
2155+ bool indirect )
21502156{
21512157 struct ibmvnic_ind_xmit_queue * ind_bufp ;
21522158 u64 dma_addr ;
@@ -2161,12 +2167,18 @@ static int ibmvnic_tx_scrq_flush(struct ibmvnic_adapter *adapter,
21612167
21622168 if (!entries )
21632169 return 0 ;
2164- rc = send_subcrq_indirect (adapter , handle , dma_addr , entries );
2170+
2171+ if (indirect )
2172+ rc = send_subcrq_indirect (adapter , handle , dma_addr , entries );
2173+ else
2174+ rc = send_subcrq_direct (adapter , handle ,
2175+ (u64 * )ind_bufp -> indir_arr );
2176+
21652177 if (rc )
21662178 ibmvnic_tx_scrq_clean_buffer (adapter , tx_scrq );
21672179 else
21682180 ind_bufp -> index = 0 ;
2169- return 0 ;
2181+ return rc ;
21702182}
21712183
21722184static netdev_tx_t ibmvnic_xmit (struct sk_buff * skb , struct net_device * netdev )
@@ -2191,6 +2203,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
21912203 unsigned long lpar_rc ;
21922204 union sub_crq tx_crq ;
21932205 unsigned int offset ;
2206+ bool use_scrq_send_direct = false;
21942207 int num_entries = 1 ;
21952208 unsigned char * dst ;
21962209 int bufidx = 0 ;
@@ -2218,7 +2231,9 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
22182231 tx_dropped ++ ;
22192232 tx_send_failed ++ ;
22202233 ret = NETDEV_TX_OK ;
2221- ibmvnic_tx_scrq_flush (adapter , tx_scrq );
2234+ lpar_rc = ibmvnic_tx_scrq_flush (adapter , tx_scrq , true);
2235+ if (lpar_rc != H_SUCCESS )
2236+ goto tx_err ;
22222237 goto out ;
22232238 }
22242239
@@ -2233,8 +2248,10 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
22332248 dev_kfree_skb_any (skb );
22342249 tx_send_failed ++ ;
22352250 tx_dropped ++ ;
2236- ibmvnic_tx_scrq_flush (adapter , tx_scrq );
22372251 ret = NETDEV_TX_OK ;
2252+ lpar_rc = ibmvnic_tx_scrq_flush (adapter , tx_scrq , true);
2253+ if (lpar_rc != H_SUCCESS )
2254+ goto tx_err ;
22382255 goto out ;
22392256 }
22402257
@@ -2245,6 +2262,20 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
22452262 memset (dst , 0 , tx_pool -> buf_size );
22462263 data_dma_addr = tx_pool -> long_term_buff .addr + offset ;
22472264
2265+ /* if we are going to send_subcrq_direct this then we need to
2266+ * update the checksum before copying the data into ltb. Essentially
2267+ * these packets force disable CSO so that we can guarantee that
2268+ * FW does not need header info and we can send direct. Also, vnic
2269+ * server must be able to xmit standard packets without header data
2270+ */
2271+ if (* hdrs == 0 && !skb_is_gso (skb ) &&
2272+ !ind_bufp -> index && !netdev_xmit_more ()) {
2273+ use_scrq_send_direct = true;
2274+ if (skb -> ip_summed == CHECKSUM_PARTIAL &&
2275+ skb_checksum_help (skb ))
2276+ use_scrq_send_direct = false;
2277+ }
2278+
22482279 if (skb_shinfo (skb )-> nr_frags ) {
22492280 int cur , i ;
22502281
@@ -2264,9 +2295,6 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
22642295 skb_copy_from_linear_data (skb , dst , skb -> len );
22652296 }
22662297
2267- /* post changes to long_term_buff *dst before VIOS accessing it */
2268- dma_wmb ();
2269-
22702298 tx_pool -> consumer_index =
22712299 (tx_pool -> consumer_index + 1 ) % tx_pool -> num_buffers ;
22722300
@@ -2329,6 +2357,18 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
23292357 tx_crq .v1 .flags1 |= IBMVNIC_TX_LSO ;
23302358 tx_crq .v1 .mss = cpu_to_be16 (skb_shinfo (skb )-> gso_size );
23312359 hdrs += 2 ;
2360+ } else if (use_scrq_send_direct ) {
2361+ /* See above comment, CSO disabled with direct xmit */
2362+ tx_crq .v1 .flags1 &= ~(IBMVNIC_TX_CHKSUM_OFFLOAD );
2363+ ind_bufp -> index = 1 ;
2364+ tx_buff -> num_entries = 1 ;
2365+ netdev_tx_sent_queue (txq , skb -> len );
2366+ ind_bufp -> indir_arr [0 ] = tx_crq ;
2367+ lpar_rc = ibmvnic_tx_scrq_flush (adapter , tx_scrq , false);
2368+ if (lpar_rc != H_SUCCESS )
2369+ goto tx_err ;
2370+
2371+ goto early_exit ;
23322372 }
23332373
23342374 if ((* hdrs >> 7 ) & 1 )
@@ -2338,23 +2378,25 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
23382378 tx_buff -> num_entries = num_entries ;
23392379 /* flush buffer if current entry can not fit */
23402380 if (num_entries + ind_bufp -> index > IBMVNIC_MAX_IND_DESCS ) {
2341- lpar_rc = ibmvnic_tx_scrq_flush (adapter , tx_scrq );
2381+ lpar_rc = ibmvnic_tx_scrq_flush (adapter , tx_scrq , true );
23422382 if (lpar_rc != H_SUCCESS )
23432383 goto tx_flush_err ;
23442384 }
23452385
23462386 indir_arr [0 ] = tx_crq ;
23472387 memcpy (& ind_bufp -> indir_arr [ind_bufp -> index ], & indir_arr [0 ],
23482388 num_entries * sizeof (struct ibmvnic_generic_scrq ));
2389+
23492390 ind_bufp -> index += num_entries ;
23502391 if (__netdev_tx_sent_queue (txq , skb -> len ,
23512392 netdev_xmit_more () &&
23522393 ind_bufp -> index < IBMVNIC_MAX_IND_DESCS )) {
2353- lpar_rc = ibmvnic_tx_scrq_flush (adapter , tx_scrq );
2394+ lpar_rc = ibmvnic_tx_scrq_flush (adapter , tx_scrq , true );
23542395 if (lpar_rc != H_SUCCESS )
23552396 goto tx_err ;
23562397 }
23572398
2399+ early_exit :
23582400 if (atomic_add_return (num_entries , & tx_scrq -> used )
23592401 >= adapter -> req_tx_entries_per_subcrq ) {
23602402 netdev_dbg (netdev , "Stopping queue %d\n" , queue_num );
@@ -3316,9 +3358,8 @@ static int ibmvnic_poll(struct napi_struct *napi, int budget)
33163358 }
33173359
33183360 if (adapter -> state != VNIC_CLOSING &&
3319- ((atomic_read (& adapter -> rx_pool [scrq_num ].available ) <
3320- adapter -> req_rx_add_entries_per_subcrq / 2 ) ||
3321- frames_processed < budget ))
3361+ (atomic_read (& adapter -> rx_pool [scrq_num ].available ) <
3362+ adapter -> req_rx_add_entries_per_subcrq / 2 ))
33223363 replenish_rx_pool (adapter , & adapter -> rx_pool [scrq_num ]);
33233364 if (frames_processed < budget ) {
33243365 if (napi_complete_done (napi , frames_processed )) {
@@ -4017,20 +4058,17 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
40174058 struct ibmvnic_sub_crq_queue * scrq )
40184059{
40194060 struct device * dev = & adapter -> vdev -> dev ;
4061+ int num_packets = 0 , total_bytes = 0 ;
40204062 struct ibmvnic_tx_pool * tx_pool ;
40214063 struct ibmvnic_tx_buff * txbuff ;
40224064 struct netdev_queue * txq ;
40234065 union sub_crq * next ;
4024- int index ;
4025- int i ;
4066+ int index , i ;
40264067
40274068restart_loop :
40284069 while (pending_scrq (adapter , scrq )) {
40294070 unsigned int pool = scrq -> pool_index ;
40304071 int num_entries = 0 ;
4031- int total_bytes = 0 ;
4032- int num_packets = 0 ;
4033-
40344072 next = ibmvnic_next_scrq (adapter , scrq );
40354073 for (i = 0 ; i < next -> tx_comp .num_comps ; i ++ ) {
40364074 index = be32_to_cpu (next -> tx_comp .correlators [i ]);
@@ -4066,8 +4104,6 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
40664104 /* remove tx_comp scrq*/
40674105 next -> tx_comp .first = 0 ;
40684106
4069- txq = netdev_get_tx_queue (adapter -> netdev , scrq -> pool_index );
4070- netdev_tx_completed_queue (txq , num_packets , total_bytes );
40714107
40724108 if (atomic_sub_return (num_entries , & scrq -> used ) <=
40734109 (adapter -> req_tx_entries_per_subcrq / 2 ) &&
@@ -4092,6 +4128,9 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
40924128 goto restart_loop ;
40934129 }
40944130
4131+ txq = netdev_get_tx_queue (adapter -> netdev , scrq -> pool_index );
4132+ netdev_tx_completed_queue (txq , num_packets , total_bytes );
4133+
40954134 return 0 ;
40964135}
40974136
0 commit comments