mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-03 21:48:15 +00:00 
			
		
		
		
	Changes:
 * Fix initial send sequence always zero issue
 * Use state machine close to RFC 9293. This should make TCP
   transfers more reliable (now we can upload a huge array
   of data from the board to external server)
 * Improve TCP framework a lot. This should make tcp client
   code much more simple.
 * rewrite wget with new tcp stack
 * rewrite fastboot_tcp with new tcp stack
It's quite hard to fix the initial send sequence (ISS) issue
with the separate patch. A naive attempt to fix an issue
inside the tcp_set_tcp_header() function will break tcp packet
retransmit logic in wget and other clients.
Example:
  Wget stores tcp_seq_num value before tcp_set_tcp_header() will
  be called and (on failure) retransmit the packet with the stored
  tcp_seq_num value. Thus:
    * the same ISS must allways be used (current case)
    * or tcp clients needs to generate a proper ISS when
      required.
A proper ISS fix will require a big redesing comparable with
a this one.
Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
Reviewed-by: Simon Glass <sjg@chromium.org>
		
	
			
		
			
				
	
	
		
			525 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			525 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* SPDX-License-Identifier: GPL-2.0 */
 | 
						|
/*
 | 
						|
 * TCP Support with SACK for file transfer.
 | 
						|
 *
 | 
						|
 * Copyright 2017 Duncan Hare, All rights reserved.
 | 
						|
 */
 | 
						|
 | 
						|
#define TCP_ACTIVITY 127		/* Number of packets received   */
 | 
						|
					/* before console progress mark */
 | 
						|
/**
 | 
						|
 * struct ip_tcp_hdr - IP and TCP header
 | 
						|
 * @ip_hl_v: header length and version
 | 
						|
 * @ip_tos: type of service
 | 
						|
 * @ip_len: total length
 | 
						|
 * @ip_id: identification
 | 
						|
 * @ip_off: fragment offset field
 | 
						|
 * @ip_ttl: time to live
 | 
						|
 * @ip_p: protocol
 | 
						|
 * @ip_sum: checksum
 | 
						|
 * @ip_src: Source IP address
 | 
						|
 * @ip_dst: Destination IP address
 | 
						|
 * @tcp_src: TCP source port
 | 
						|
 * @tcp_dst: TCP destination port
 | 
						|
 * @tcp_seq: TCP sequence number
 | 
						|
 * @tcp_ack: TCP Acknowledgment number
 | 
						|
 * @tcp_hlen: 4 bits TCP header Length/4, 4 bits reserved, 2 more bits reserved
 | 
						|
 * @tcp_flag: flags of TCP
 | 
						|
 * @tcp_win: TCP windows size
 | 
						|
 * @tcp_xsum: Checksum
 | 
						|
 * @tcp_ugr: Pointer to urgent data
 | 
						|
 */
 | 
						|
struct ip_tcp_hdr {
 | 
						|
	u8		ip_hl_v;
 | 
						|
	u8		ip_tos;
 | 
						|
	u16		ip_len;
 | 
						|
	u16		ip_id;
 | 
						|
	u16		ip_off;
 | 
						|
	u8		ip_ttl;
 | 
						|
	u8		ip_p;
 | 
						|
	u16		ip_sum;
 | 
						|
	struct in_addr	ip_src;
 | 
						|
	struct in_addr	ip_dst;
 | 
						|
	u16		tcp_src;
 | 
						|
	u16		tcp_dst;
 | 
						|
	u32		tcp_seq;
 | 
						|
	u32		tcp_ack;
 | 
						|
	u8		tcp_hlen;
 | 
						|
	u8		tcp_flags;
 | 
						|
	u16		tcp_win;
 | 
						|
	u16		tcp_xsum;
 | 
						|
	u16		tcp_ugr;
 | 
						|
} __packed;
 | 
						|
 | 
						|
#define IP_TCP_HDR_SIZE		(sizeof(struct ip_tcp_hdr))
 | 
						|
#define TCP_HDR_SIZE		(IP_TCP_HDR_SIZE  - IP_HDR_SIZE)
 | 
						|
 | 
						|
#define TCP_DATA	0x00	/* Data Packet - internal use only	*/
 | 
						|
#define TCP_FIN		0x01	/* Finish flag				*/
 | 
						|
#define TCP_SYN		0x02	/* Synch (start) flag			*/
 | 
						|
#define TCP_RST		0x04	/* reset flag				*/
 | 
						|
#define TCP_PUSH	0x08	/* Push - Notify app			*/
 | 
						|
#define TCP_ACK		0x10	/* Acknowledgment of data received	*/
 | 
						|
#define TCP_URG		0x20	/* Urgent				*/
 | 
						|
#define TCP_ECE		0x40	/* Congestion control			*/
 | 
						|
#define TCP_CWR		0x80	/* Congestion Control			*/
 | 
						|
 | 
						|
/*
 | 
						|
 * TCP header options, Seq, MSS, and SACK
 | 
						|
 */
 | 
						|
 | 
						|
#define TCP_SACK 32			/* Number of packets analyzed   */
 | 
						|
					/* on leading edge of stream    */
 | 
						|
 | 
						|
#define TCP_O_END	0x00		/* End of option list		*/
 | 
						|
#define TCP_1_NOP	0x01		/* Single padding NOP		*/
 | 
						|
#define TCP_O_NOP	0x01010101	/* NOPs pad to 32 bit boundary	*/
 | 
						|
#define TCP_O_MSS	0x02		/* MSS Size option		*/
 | 
						|
#define TCP_O_SCL	0x03		/* Window Scale option		*/
 | 
						|
#define TCP_P_SACK	0x04		/* SACK permitted		*/
 | 
						|
#define TCP_V_SACK	0x05		/* SACK values			*/
 | 
						|
#define TCP_O_TS	0x08		/* Timestamp option		*/
 | 
						|
#define TCP_OPT_LEN_2	0x02
 | 
						|
#define TCP_OPT_LEN_3	0x03
 | 
						|
#define TCP_OPT_LEN_4	0x04
 | 
						|
#define TCP_OPT_LEN_6	0x06
 | 
						|
#define TCP_OPT_LEN_8	0x08
 | 
						|
#define TCP_OPT_LEN_A	0x0a		/* Timestamp Length		*/
 | 
						|
#define TCP_MSS		1460		/* Max segment size		*/
 | 
						|
#define TCP_SCALE	0x01		/* Scale			*/
 | 
						|
 | 
						|
/**
 | 
						|
 * struct tcp_mss - TCP option structure for MSS (Max segment size)
 | 
						|
 * @kind: Field ID
 | 
						|
 * @len: Field length
 | 
						|
 * @mss: Segment size value
 | 
						|
 */
 | 
						|
struct tcp_mss {
 | 
						|
	u8	kind;
 | 
						|
	u8	len;
 | 
						|
	u16	mss;
 | 
						|
} __packed;
 | 
						|
 | 
						|
/**
 | 
						|
 * struct tcp_scale - TCP option structure for Windows scale
 | 
						|
 * @kind: Field ID
 | 
						|
 * @len: Field length
 | 
						|
 * @scale: windows shift value used for networks with many hops.
 | 
						|
 *         Typically 4 or more hops
 | 
						|
 */
 | 
						|
struct tcp_scale {
 | 
						|
	u8	kind;
 | 
						|
	u8	len;
 | 
						|
	u8	scale;
 | 
						|
} __packed;
 | 
						|
 | 
						|
/**
 | 
						|
 * struct tcp_sack_p - TCP option structure for SACK permitted
 | 
						|
 * @kind: Field ID
 | 
						|
 * @len: Field length
 | 
						|
 */
 | 
						|
struct tcp_sack_p {
 | 
						|
	u8	kind;
 | 
						|
	u8	len;
 | 
						|
} __packed;
 | 
						|
 | 
						|
/**
 | 
						|
 * struct sack_edges - structure for SACK edges
 | 
						|
 * @l: Left edge of stream
 | 
						|
 * @r: right edge of stream
 | 
						|
 */
 | 
						|
struct sack_edges {
 | 
						|
	u32	l;
 | 
						|
	u32	r;
 | 
						|
} __packed;
 | 
						|
 | 
						|
#define TCP_SACK_SIZE (sizeof(struct sack_edges))
 | 
						|
 | 
						|
/*
 | 
						|
 * A TCP stream has holes when packets are missing or disordered.
 | 
						|
 * A hill is the inverse of a hole, and is data received.
 | 
						|
 * TCP received hills (a sequence of data), and inferrs Holes
 | 
						|
 * from the "hills" or packets received.
 | 
						|
 */
 | 
						|
 | 
						|
#define TCP_SACK_HILLS	4
 | 
						|
 | 
						|
/**
 | 
						|
 * struct tcp_sack_v - TCP option structure for SACK
 | 
						|
 * @kind: Field ID
 | 
						|
 * @len: Field length
 | 
						|
 * @hill: L & R window edges
 | 
						|
 */
 | 
						|
struct tcp_sack_v {
 | 
						|
	u8	kind;
 | 
						|
	u8	len;
 | 
						|
	struct	sack_edges hill[TCP_SACK_HILLS];
 | 
						|
} __packed;
 | 
						|
 | 
						|
/**
 | 
						|
 * struct tcp_t_opt - TCP option structure for time stamps
 | 
						|
 * @kind: Field ID
 | 
						|
 * @len: Field length
 | 
						|
 * @t_snd: Sender timestamp
 | 
						|
 * @t_rcv: Receiver timestamp
 | 
						|
 */
 | 
						|
struct tcp_t_opt {
 | 
						|
	u8	kind;
 | 
						|
	u8	len;
 | 
						|
	u32	t_snd;
 | 
						|
	u32	t_rcv;
 | 
						|
} __packed;
 | 
						|
 | 
						|
#define TCP_TSOPT_SIZE (sizeof(struct tcp_t_opt))
 | 
						|
 | 
						|
/*
 | 
						|
 * ip tcp  structure with options
 | 
						|
 */
 | 
						|
 | 
						|
/**
 | 
						|
 * struct ip_tcp_hdr_o - IP + TCP header + TCP options
 | 
						|
 * @hdr: IP + TCP header
 | 
						|
 * @mss: TCP MSS Option
 | 
						|
 * @scale: TCP Windows Scale Option
 | 
						|
 * @sack_p: TCP Sack-Permitted Option
 | 
						|
 * @t_opt: TCP Timestamp Option
 | 
						|
 * @end: end of options
 | 
						|
 */
 | 
						|
struct ip_tcp_hdr_o {
 | 
						|
	struct	ip_tcp_hdr hdr;
 | 
						|
	struct	tcp_mss	   mss;
 | 
						|
	struct	tcp_scale  scale;
 | 
						|
	struct	tcp_sack_p sack_p;
 | 
						|
	struct	tcp_t_opt  t_opt;
 | 
						|
	u8	end;
 | 
						|
} __packed;
 | 
						|
 | 
						|
#define IP_TCP_O_SIZE (sizeof(struct ip_tcp_hdr_o))
 | 
						|
 | 
						|
/**
 | 
						|
 * struct ip_tcp_hdr_s - IP + TCP header + TCP options
 | 
						|
 * @hdr: IP + TCP header
 | 
						|
 * @t_opt: TCP Timestamp Option
 | 
						|
 * @sack_v: TCP SACK Option
 | 
						|
 * @end: end of options
 | 
						|
 */
 | 
						|
struct ip_tcp_hdr_s {
 | 
						|
	struct	ip_tcp_hdr	hdr;
 | 
						|
	struct	tcp_t_opt	t_opt;
 | 
						|
	struct	tcp_sack_v	sack_v;
 | 
						|
	u8	end;
 | 
						|
} __packed;
 | 
						|
 | 
						|
#define IP_TCP_SACK_SIZE (sizeof(struct ip_tcp_hdr_s))
 | 
						|
 | 
						|
/*
 | 
						|
 * TCP pseudo header definitions
 | 
						|
 */
 | 
						|
#define PSEUDO_PAD_SIZE	8
 | 
						|
 | 
						|
/**
 | 
						|
 * struct pseudo_hdr - Pseudo Header
 | 
						|
 * @padding: pseudo hdr size = ip_tcp hdr size
 | 
						|
 * @p_src: Source IP address
 | 
						|
 * @p_dst: Destination IP address
 | 
						|
 * @rsvd: reserved
 | 
						|
 * @p: protocol
 | 
						|
 * @len: length of header
 | 
						|
 */
 | 
						|
struct pseudo_hdr {
 | 
						|
	u8 padding[PSEUDO_PAD_SIZE];
 | 
						|
	struct in_addr p_src;
 | 
						|
	struct in_addr p_dst;
 | 
						|
	u8      rsvd;
 | 
						|
	u8      p;
 | 
						|
	u16     len;
 | 
						|
} __packed;
 | 
						|
 | 
						|
#define PSEUDO_HDR_SIZE	(sizeof(struct pseudo_hdr)) - PSEUDO_PAD_SIZE
 | 
						|
 | 
						|
/**
 | 
						|
 * union tcp_build_pkt - union for building TCP/IP packet.
 | 
						|
 * @ph: pseudo header
 | 
						|
 * @ip: IP and TCP header plus TCP options
 | 
						|
 * @sack: IP and TCP header plus SACK options
 | 
						|
 * @raw: buffer
 | 
						|
 *
 | 
						|
 * Build Pseudo header in packed buffer
 | 
						|
 * first, calculate TCP checksum, then build IP header in packed buffer.
 | 
						|
 *
 | 
						|
 */
 | 
						|
union tcp_build_pkt {
 | 
						|
	struct pseudo_hdr ph;
 | 
						|
	struct ip_tcp_hdr_o ip;
 | 
						|
	struct ip_tcp_hdr_s sack;
 | 
						|
	uchar  raw[1600];
 | 
						|
} __packed;
 | 
						|
 | 
						|
/**
 | 
						|
 * enum tcp_state - TCP State machine states for connection
 | 
						|
 * @TCP_CLOSED: Need to send SYN to connect
 | 
						|
 * @TCP_SYN_SENT: Trying to connect, waiting for SYN ACK
 | 
						|
 * @TCP_SYN_RECEIVED: Initial SYN received, waiting for ACK
 | 
						|
 * @TCP_ESTABLISHED: both server & client have a connection
 | 
						|
 * @TCP_CLOSE_WAIT: Rec FIN, passed to app for FIN, ACK rsp
 | 
						|
 * @TCP_CLOSING: Rec FIN, sent FIN, ACK waiting for ACK
 | 
						|
 * @TCP_FIN_WAIT_1: Sent FIN waiting for response
 | 
						|
 * @TCP_FIN_WAIT_2: Rec ACK from FIN sent, waiting for FIN
 | 
						|
 * @TCP_LAST_ACK: Waiting for ACK of the connection termination
 | 
						|
 */
 | 
						|
enum tcp_state {
 | 
						|
	TCP_CLOSED,
 | 
						|
	TCP_SYN_SENT,
 | 
						|
	TCP_SYN_RECEIVED,
 | 
						|
	TCP_ESTABLISHED,
 | 
						|
	TCP_CLOSE_WAIT,
 | 
						|
	TCP_CLOSING,
 | 
						|
	TCP_FIN_WAIT_1,
 | 
						|
	TCP_FIN_WAIT_2,
 | 
						|
	TCP_LAST_ACK,
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * enum tcp_status - TCP stream status for connection
 | 
						|
 * @TCP_ERR_OK: no rx/tx errors
 | 
						|
 * @TCP_ERR_TOUT: rx/tx timeout happened
 | 
						|
 * @TCP_ERR_RST: connection was reset
 | 
						|
 * @TCP_ERR_IO: input/output error
 | 
						|
 */
 | 
						|
enum tcp_status {
 | 
						|
	TCP_ERR_OK = 0,
 | 
						|
	TCP_ERR_TOUT,
 | 
						|
	TCP_ERR_RST,
 | 
						|
	TCP_ERR_IO
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * struct tcp_stream - TCP data stream structure
 | 
						|
 * @rhost:		Remote host, network byte order
 | 
						|
 * @rport:		Remote port, host byte order
 | 
						|
 * @lport:		Local port, host byte order
 | 
						|
 *
 | 
						|
 * @priv:		User private data (not used by tcp module)
 | 
						|
 *
 | 
						|
 * @max_retry_count:	Maximum retransmit attempts (default 3)
 | 
						|
 * @initial_timeout:	Timeout from initial TX to reTX (default 2 sec)
 | 
						|
 * @rx_inactiv_timeout:	Maximum time from last rx till connection drop
 | 
						|
 *			  (default 30 sec)
 | 
						|
 *
 | 
						|
 * @on_closed:		User callback, called just before destroying TCP stream
 | 
						|
 * @on_established:	User callback, called when TCP stream enters
 | 
						|
 *			  TCP_ESTABLISHED state
 | 
						|
 * @on_rcv_nxt_update:	User callback, called when all data in the segment
 | 
						|
 *			  [0..rx_bytes - 1] was received
 | 
						|
 * @on_snd_una_update:	User callback, called when all data in the segment
 | 
						|
 *			  [0..tx_bytes - 1] were transferred and acknowledged
 | 
						|
 * @rx:			User callback, called on receive of segment
 | 
						|
 *			  [rx_offs..rx_offs+len-1]. If NULL -- all incoming data
 | 
						|
 *			  will be ignored. User SHOULD store the segment and
 | 
						|
 *			  return the number of accepted bytes or negative value
 | 
						|
 *			  on error.
 | 
						|
 *			  WARNING: Previous segmengs may not be received yet
 | 
						|
 * @tx:			User callback, called on transmit/retransmit of segment
 | 
						|
 *			  [tx_offs..tx_offs+maxlen-1]. If NULL -- no data will
 | 
						|
 *			  be transmitted. User SHOULD fill provided buffer and
 | 
						|
 *			  return the number of bytes in the buffer or negative
 | 
						|
 *			  value on error.
 | 
						|
 *			  WARNING: do not use tcp_stream_close() from this
 | 
						|
 *			    callback (it will break stream). Better use
 | 
						|
 *			    on_snd_una_update() callback for such purposes.
 | 
						|
 *
 | 
						|
 * @time_last_rx:	Arrival time of last valid incoming package (ticks)
 | 
						|
 * @time_start:		Timeout start time (ticks)
 | 
						|
 * @time_delta:		Timeout duration (ticks)
 | 
						|
 * @time_handler	Timeout handler for a stream
 | 
						|
 *
 | 
						|
 * @state:		TCP connection state
 | 
						|
 * @status:		TCP stream status (OK or ERR)
 | 
						|
 * @rx_packets:		total number of received packets
 | 
						|
 * @tx_packets:		total number of transmitted packets
 | 
						|
 *
 | 
						|
 * @fin_rx:		Non-zero if TCP_FIN was received
 | 
						|
 * @fin_rx_seq:		TCP sequence of rx FIN bit
 | 
						|
 * @fin_tx:		Non-zero if TCP_FIN was sent (or planned to send)
 | 
						|
 * @fin_tx_seq:		TCP sequence of tx FIN bit
 | 
						|
 *
 | 
						|
 * @iss:		Initial send sequence number
 | 
						|
 * @snd_una:		Send unacknowledged
 | 
						|
 * @snd_nxt:		Send next
 | 
						|
 * @snd_wnd:		Send window (in bytes)
 | 
						|
 * @snd_wl1:		Segment sequence number used for last window update
 | 
						|
 * @snd_wl2:		Segment acknowledgment number used for last window update
 | 
						|
 *
 | 
						|
 * @irs:		Initial receive sequence number
 | 
						|
 * @rcv_nxt:		Receive next
 | 
						|
 * @rcv_wnd:		Receive window (in bytes)
 | 
						|
 *
 | 
						|
 * @loc_timestamp:	Local timestamp
 | 
						|
 * @rmt_timestamp:	Remote timestamp
 | 
						|
 *
 | 
						|
 * @rmt_win_scale:	Remote window scale factor
 | 
						|
 *
 | 
						|
 * @lost:		Used for SACK
 | 
						|
 *
 | 
						|
 * @retry_cnt:		Number of retry attempts remaining. Only SYN, FIN
 | 
						|
 *			  or DATA segments are tried to retransmit.
 | 
						|
 * @retry_timeout:	Current retry timeout (ms)
 | 
						|
 * @retry_action:	TCP flags used for sending
 | 
						|
 * @retry_seq_num:	TCP sequence for retransmit
 | 
						|
 * retry_tx_len:	Number of data to transmit
 | 
						|
 * @retry_tx_offs:	Position in the TX stream
 | 
						|
 */
 | 
						|
struct tcp_stream {
 | 
						|
	struct in_addr	rhost;
 | 
						|
	u16		rport;
 | 
						|
	u16		lport;
 | 
						|
 | 
						|
	void		*priv;
 | 
						|
 | 
						|
	int		max_retry_count;
 | 
						|
	int		initial_timeout;
 | 
						|
	int		rx_inactiv_timeout;
 | 
						|
 | 
						|
	void		(*on_closed)(struct tcp_stream *tcp);
 | 
						|
	void		(*on_established)(struct tcp_stream *tcp);
 | 
						|
	void		(*on_rcv_nxt_update)(struct tcp_stream *tcp, u32 rx_bytes);
 | 
						|
	void		(*on_snd_una_update)(struct tcp_stream *tcp, u32 tx_bytes);
 | 
						|
	int		(*rx)(struct tcp_stream *tcp, u32 rx_offs, void *buf, int len);
 | 
						|
	int		(*tx)(struct tcp_stream *tcp, u32 tx_offs, void *buf, int maxlen);
 | 
						|
 | 
						|
	ulong		time_last_rx;
 | 
						|
	ulong		time_start;
 | 
						|
	ulong		time_delta;
 | 
						|
	void		(*time_handler)(struct tcp_stream *tcp);
 | 
						|
 | 
						|
	enum tcp_state	state;
 | 
						|
	enum tcp_status	status;
 | 
						|
	u32		rx_packets;
 | 
						|
	u32		tx_packets;
 | 
						|
 | 
						|
	int		fin_rx;
 | 
						|
	u32		fin_rx_seq;
 | 
						|
 | 
						|
	int		fin_tx;
 | 
						|
	u32		fin_tx_seq;
 | 
						|
 | 
						|
	u32		iss;
 | 
						|
	u32		snd_una;
 | 
						|
	u32		snd_nxt;
 | 
						|
	u32		snd_wnd;
 | 
						|
	u32		snd_wl1;
 | 
						|
	u32		snd_wl2;
 | 
						|
 | 
						|
	u32		irs;
 | 
						|
	u32		rcv_nxt;
 | 
						|
	u32		rcv_wnd;
 | 
						|
 | 
						|
	/* TCP option timestamp */
 | 
						|
	u32		loc_timestamp;
 | 
						|
	u32		rmt_timestamp;
 | 
						|
 | 
						|
	/* TCP window scale */
 | 
						|
	u8		rmt_win_scale;
 | 
						|
 | 
						|
	/* TCP sliding window control used to request re-TX */
 | 
						|
	struct tcp_sack_v lost;
 | 
						|
 | 
						|
	/* used for data retransmission */
 | 
						|
	int		retry_cnt;
 | 
						|
	int		retry_timeout;
 | 
						|
	u8		retry_action;
 | 
						|
	u32		retry_seq_num;
 | 
						|
	u32		retry_tx_len;
 | 
						|
	u32		retry_tx_offs;
 | 
						|
};
 | 
						|
 | 
						|
void tcp_init(void);
 | 
						|
 | 
						|
/*
 | 
						|
 * This function sets user callback called on TCP stream creation.
 | 
						|
 * Callback should:
 | 
						|
 *  + Check TCP stream endpoint and make connection verdict
 | 
						|
 *    - return non-zero value to accept connection
 | 
						|
 *    - return zero to drop connection
 | 
						|
 *  + Setup TCP stream callbacks like: on_closed(), on_established(),
 | 
						|
 *    n_rcv_nxt_update(), on_snd_una_update(), rx() and tx().
 | 
						|
 *  + Setup other stream related data
 | 
						|
 *
 | 
						|
 * WARNING: User MUST setup TCP stream on_create handler. Without it
 | 
						|
 *          no connection (including outgoung) will be created.
 | 
						|
 */
 | 
						|
void tcp_stream_set_on_create_handler(int (*on_create)(struct tcp_stream *));
 | 
						|
 | 
						|
/*
 | 
						|
 * tcp_stream_get -- Get or create TCP stream
 | 
						|
 * @is_new:	if non-zero and no stream found, then create a new one
 | 
						|
 * @rhost:	Remote host, network byte order
 | 
						|
 * @rport:	Remote port, host byte order
 | 
						|
 * @lport:	Local port, host byte order
 | 
						|
 *
 | 
						|
 * Returns: TCP stream structure or NULL (if not found/created)
 | 
						|
 */
 | 
						|
struct tcp_stream *tcp_stream_get(int is_new, struct in_addr rhost,
 | 
						|
				  u16 rport, u16 lport);
 | 
						|
 | 
						|
/*
 | 
						|
 * tcp_stream_connect -- Create new TCP stream for remote connection.
 | 
						|
 * @rhost:	Remote host, network byte order
 | 
						|
 * @rport:	Remote port, host byte order
 | 
						|
 *
 | 
						|
 * Returns: TCP new stream structure or NULL (if not created).
 | 
						|
 *          Random local port will be used.
 | 
						|
 */
 | 
						|
struct tcp_stream *tcp_stream_connect(struct in_addr rhost, u16 rport);
 | 
						|
 | 
						|
/*
 | 
						|
 * tcp_stream_put -- Return stream to a TCP subsystem. Subsystem will
 | 
						|
 *                   check stream and destroy it (if stream was already
 | 
						|
 *                   closed). Otherwize no stream change will happen.
 | 
						|
 * @tcp:	TCP stream to put
 | 
						|
 */
 | 
						|
void tcp_stream_put(struct tcp_stream *tcp);
 | 
						|
 | 
						|
/*
 | 
						|
 * tcp_stream_restart_rx_timer -- Restart RX inactivity timer. Usually there
 | 
						|
 *                                is no needs to call this function. Timer
 | 
						|
 *                                will be restarted on receiving of any valid
 | 
						|
 *                                tcp packet belonging to a stream.
 | 
						|
 *
 | 
						|
 *                                This function may be used to prevent connection
 | 
						|
 *                                break in the following case:
 | 
						|
 *                                  - u-boot is busy with very long data processing
 | 
						|
 *                                  - remote side waits for u-boot reply
 | 
						|
 *
 | 
						|
 * @tcp:	TCP stream to put
 | 
						|
 */
 | 
						|
void tcp_stream_restart_rx_timer(struct tcp_stream *tcp);
 | 
						|
 | 
						|
enum tcp_state  tcp_stream_get_state(struct tcp_stream *tcp);
 | 
						|
enum tcp_status tcp_stream_get_status(struct tcp_stream *tcp);
 | 
						|
 | 
						|
/*
 | 
						|
 * tcp_stream_rx_offs(),
 | 
						|
 * tcp_stream_tx_offs()  -- Returns offset of first unacknowledged byte
 | 
						|
 *                          in receive/transmit stream correspondingly.
 | 
						|
 *                          The result is NOT affected by sin/fin flags.
 | 
						|
 * @tcp:	TCP stream
 | 
						|
 */
 | 
						|
u32 tcp_stream_rx_offs(struct tcp_stream *tcp);
 | 
						|
u32 tcp_stream_tx_offs(struct tcp_stream *tcp);
 | 
						|
 | 
						|
/* reset tcp stream */
 | 
						|
void tcp_stream_reset(struct tcp_stream *tcp);
 | 
						|
/* force TCP stream closing, do NOT use from tcp->tx callback */
 | 
						|
void tcp_stream_close(struct tcp_stream *tcp);
 | 
						|
 | 
						|
void tcp_streams_poll(void);
 | 
						|
 | 
						|
int tcp_set_tcp_header(struct tcp_stream *tcp, uchar *pkt, int payload_len,
 | 
						|
		       u8 action, u32 tcp_seq_num, u32 tcp_ack_num);
 | 
						|
 | 
						|
void rxhand_tcp_f(union tcp_build_pkt *b, unsigned int len);
 | 
						|
 | 
						|
u16 tcp_set_pseudo_header(uchar *pkt, struct in_addr src, struct in_addr dest,
 | 
						|
			  int tcp_len, int pkt_len);
 |