diff options
| author | Eli Cohen <eli@dev.mellanox.co.il> | 2010-08-26 14:17:56 +0000 | 
|---|---|---|
| committer | Roland Dreier <rolandd@cisco.com> | 2010-10-14 12:41:29 -0700 | 
| commit | ff7f5aab354dee01f29c9c00933f6d4aa590eadb (patch) | |
| tree | c6f4075f712808ba76927224fac2960f4c5353ec /drivers/infiniband/core/ud_header.c | |
| parent | 3c86aa70bf677a31b71c8292e349242e26cbc743 (diff) | |
IB/pack: IBoE UD packet packing support
Add support for packing IBoE packet headers.
Signed-off-by: Eli Cohen <eli@mellanox.co.il>
[ Clean up and fix ib_ud_header_init() a bit.  - Roland ]
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/core/ud_header.c')
| -rw-r--r-- | drivers/infiniband/core/ud_header.c | 117 | 
1 files changed, 89 insertions, 28 deletions
| diff --git a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c index 650b501eb142..cb0dd5ae2777 100644 --- a/drivers/infiniband/core/ud_header.c +++ b/drivers/infiniband/core/ud_header.c @@ -80,6 +80,29 @@ static const struct ib_field lrh_table[]  = {  	  .size_bits    = 16 }  }; +static const struct ib_field eth_table[]  = { +	{ STRUCT_FIELD(eth, dmac_h), +	  .offset_words = 0, +	  .offset_bits  = 0, +	  .size_bits    = 32 }, +	{ STRUCT_FIELD(eth, dmac_l), +	  .offset_words = 1, +	  .offset_bits  = 0, +	  .size_bits    = 16 }, +	{ STRUCT_FIELD(eth, smac_h), +	  .offset_words = 1, +	  .offset_bits  = 16, +	  .size_bits    = 16 }, +	{ STRUCT_FIELD(eth, smac_l), +	  .offset_words = 2, +	  .offset_bits  = 0, +	  .size_bits    = 32 }, +	{ STRUCT_FIELD(eth, type), +	  .offset_words = 3, +	  .offset_bits  = 0, +	  .size_bits    = 16 } +}; +  static const struct ib_field grh_table[]  = {  	{ STRUCT_FIELD(grh, ip_version),  	  .offset_words = 0, @@ -180,38 +203,38 @@ static const struct ib_field deth_table[] = {  /**   * ib_ud_header_init - Initialize UD header structure   * @payload_bytes:Length of packet payload + * @lrh_present: specify if LRH is present + * @eth_present: specify if Eth header is present   * @grh_present:GRH flag (if non-zero, GRH will be included) - * @immediate_present: specify if immediate data should be used + * @immediate_present: specify if immediate data is present   * @header:Structure to initialize - * - * ib_ud_header_init() initializes the lrh.link_version, lrh.link_next_header, - * lrh.packet_length, grh.ip_version, grh.payload_length, - * grh.next_header, bth.opcode, bth.pad_count and - * bth.transport_header_version fields of a &struct ib_ud_header given - * the payload length and whether a GRH will be included.   */  void ib_ud_header_init(int     		    payload_bytes, +		       int		    lrh_present, +		       int		    eth_present,  		       int    		    grh_present,  		       int		    immediate_present,  		       struct ib_ud_header *header)  { -	u16 packet_length; -  	memset(header, 0, sizeof *header); -	header->lrh.link_version     = 0; -	header->lrh.link_next_header = -		grh_present ? IB_LNH_IBA_GLOBAL : IB_LNH_IBA_LOCAL; -	packet_length		     = (IB_LRH_BYTES     + -					IB_BTH_BYTES     + -					IB_DETH_BYTES    + -					payload_bytes    + -					4                + /* ICRC     */ -					3) / 4;            /* round up */ - -	header->grh_present          = grh_present; +	if (lrh_present) { +		u16 packet_length; + +		header->lrh.link_version     = 0; +		header->lrh.link_next_header = +			grh_present ? IB_LNH_IBA_GLOBAL : IB_LNH_IBA_LOCAL; +		packet_length = (IB_LRH_BYTES	+ +				 IB_BTH_BYTES	+ +				 IB_DETH_BYTES	+ +				 (grh_present ? IB_GRH_BYTES : 0) + +				 payload_bytes	+ +				 4		+ /* ICRC     */ +				 3) / 4;	  /* round up */ +		header->lrh.packet_length = cpu_to_be16(packet_length); +	} +  	if (grh_present) { -		packet_length		   += IB_GRH_BYTES / 4;  		header->grh.ip_version      = 6;  		header->grh.payload_length  =  			cpu_to_be16((IB_BTH_BYTES     + @@ -222,19 +245,51 @@ void ib_ud_header_init(int     		    payload_bytes,  		header->grh.next_header     = 0x1b;  	} -	header->lrh.packet_length = cpu_to_be16(packet_length); - -	header->immediate_present	     = immediate_present;  	if (immediate_present)  		header->bth.opcode           = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE;  	else  		header->bth.opcode           = IB_OPCODE_UD_SEND_ONLY;  	header->bth.pad_count                = (4 - payload_bytes) & 3;  	header->bth.transport_header_version = 0; + +	header->lrh_present = lrh_present; +	header->eth_present = eth_present; +	header->grh_present = grh_present; +	header->immediate_present = immediate_present;  }  EXPORT_SYMBOL(ib_ud_header_init);  /** + * ib_lrh_header_pack - Pack LRH header struct into wire format + * @lrh:unpacked LRH header struct + * @buf:Buffer to pack into + * + * ib_lrh_header_pack() packs the LRH header structure @lrh into + * wire format in the buffer @buf. + */ +int ib_lrh_header_pack(struct ib_unpacked_lrh *lrh, void *buf) +{ +	ib_pack(lrh_table, ARRAY_SIZE(lrh_table), lrh, buf); +	return 0; +} +EXPORT_SYMBOL(ib_lrh_header_pack); + +/** + * ib_lrh_header_unpack - Unpack LRH structure from wire format + * @lrh:unpacked LRH header struct + * @buf:Buffer to pack into + * + * ib_lrh_header_unpack() unpacks the LRH header structure from + * wire format (in buf) into @lrh. + */ +int ib_lrh_header_unpack(void *buf, struct ib_unpacked_lrh *lrh) +{ +	ib_unpack(lrh_table, ARRAY_SIZE(lrh_table), buf, lrh); +	return 0; +} +EXPORT_SYMBOL(ib_lrh_header_unpack); + +/**   * ib_ud_header_pack - Pack UD header struct into wire format   * @header:UD header struct   * @buf:Buffer to pack into @@ -247,10 +302,16 @@ int ib_ud_header_pack(struct ib_ud_header *header,  {  	int len = 0; -	ib_pack(lrh_table, ARRAY_SIZE(lrh_table), -		&header->lrh, buf); -	len += IB_LRH_BYTES; - +	if (header->lrh_present) { +		ib_pack(lrh_table, ARRAY_SIZE(lrh_table), +			&header->lrh, buf + len); +		len += IB_LRH_BYTES; +	} +	if (header->eth_present) { +		ib_pack(eth_table, ARRAY_SIZE(eth_table), +			&header->eth, buf + len); +		len += IB_ETH_BYTES; +	}  	if (header->grh_present) {  		ib_pack(grh_table, ARRAY_SIZE(grh_table),  			&header->grh, buf + len); | 
