fc_frame.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*
  2. * Copyright(c) 2007 Intel Corporation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms and conditions of the GNU General Public License,
  6. * version 2, as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope it will be useful, but WITHOUT
  9. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. * more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along with
  14. * this program; if not, write to the Free Software Foundation, Inc.,
  15. * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  16. *
  17. * Maintained at www.Open-FCoE.org
  18. */
  19. /*
  20. * Frame allocation.
  21. */
  22. #include <linux/module.h>
  23. #include <linux/kernel.h>
  24. #include <linux/skbuff.h>
  25. #include <linux/crc32.h>
  26. #include <scsi/fc_frame.h>
  27. /*
  28. * Check the CRC in a frame.
  29. */
  30. u32 fc_frame_crc_check(struct fc_frame *fp)
  31. {
  32. u32 crc;
  33. u32 error;
  34. const u8 *bp;
  35. unsigned int len;
  36. WARN_ON(!fc_frame_is_linear(fp));
  37. fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
  38. len = (fr_len(fp) + 3) & ~3; /* round up length to include fill */
  39. bp = (const u8 *) fr_hdr(fp);
  40. crc = ~crc32(~0, bp, len);
  41. error = crc ^ fr_crc(fp);
  42. return error;
  43. }
  44. EXPORT_SYMBOL(fc_frame_crc_check);
  45. /*
  46. * Allocate a frame intended to be sent via fcoe_xmit.
  47. * Get an sk_buff for the frame and set the length.
  48. */
  49. struct fc_frame *__fc_frame_alloc(size_t len)
  50. {
  51. struct fc_frame *fp;
  52. struct sk_buff *skb;
  53. WARN_ON((len % sizeof(u32)) != 0);
  54. len += sizeof(struct fc_frame_header);
  55. skb = dev_alloc_skb(len + FC_FRAME_HEADROOM + FC_FRAME_TAILROOM);
  56. if (!skb)
  57. return NULL;
  58. fp = (struct fc_frame *) skb;
  59. fc_frame_init(fp);
  60. skb_reserve(skb, FC_FRAME_HEADROOM);
  61. skb_put(skb, len);
  62. return fp;
  63. }
  64. EXPORT_SYMBOL(__fc_frame_alloc);
  65. struct fc_frame *fc_frame_alloc_fill(struct fc_lport *lp, size_t payload_len)
  66. {
  67. struct fc_frame *fp;
  68. size_t fill;
  69. fill = payload_len % 4;
  70. if (fill != 0)
  71. fill = 4 - fill;
  72. fp = __fc_frame_alloc(payload_len + fill);
  73. if (fp) {
  74. memset((char *) fr_hdr(fp) + payload_len, 0, fill);
  75. /* trim is OK, we just allocated it so there are no fragments */
  76. skb_trim(fp_skb(fp),
  77. payload_len + sizeof(struct fc_frame_header));
  78. }
  79. return fp;
  80. }