diff options
Diffstat (limited to 'src/drivers/net/mlx_ipoib/ipoib.c')
-rw-r--r-- | src/drivers/net/mlx_ipoib/ipoib.c | 1027 |
1 files changed, 0 insertions, 1027 deletions
diff --git a/src/drivers/net/mlx_ipoib/ipoib.c b/src/drivers/net/mlx_ipoib/ipoib.c deleted file mode 100644 index 85eaac7a..00000000 --- a/src/drivers/net/mlx_ipoib/ipoib.c +++ /dev/null @@ -1,1027 +0,0 @@ -/* - This software is available to you under a choice of one of two - licenses. You may choose to be licensed under the terms of the GNU - General Public License (GPL) Version 2, available at - <http://www.fsf.org/copyleft/gpl.html>, or the OpenIB.org BSD - license, available in the LICENSE.TXT file accompanying this - software. These details are also available at - <http://openib.org/license.html>. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved. -*/ - -#include "ipoib.h" -#include "ib_driver.h" -#include "ib_mad.h" - -static const __u8 arp_packet_template[] = { - 0x00, 0x20, /* hardware type */ - 0x08, 0x00, /* protocol type */ - 20, /* hw size */ - 4, /* protocol size */ - 0x00, 0x00, /* opcode */ - - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, /* sender's mac */ - 0, 0, 0, 0, /* sender's IP address */ - - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, /* Target's mac */ - 0, 0, 0, 0 /* targets's IP address */ -}; - -struct ipoib_data_st { - __u32 ipoib_qpn; - udqp_t ipoib_qph; - ud_av_t bcast_av; - cq_t snd_cqh; - cq_t rcv_cqh; - __u8 *port_gid_raw; -} ipoib_data; - -#define NUM_MAC_ENTRIES (NUM_AVS+2) - -static struct mac_xlation_st mac_tbl[NUM_MAC_ENTRIES]; -static __u32 mac_counter = 1; -static __u32 youth_counter = 0; - -#define EQUAL_GUIDS(g1, g2) ( \ - ((g1)[0]==(g2)[0]) && \ - ((g1)[1]==(g2)[1]) && \ - ((g1)[2]==(g2)[2]) && \ - ((g1)[3]==(g2)[3]) && \ - ((g1)[4]==(g2)[4]) && \ - ((g1)[5]==(g2)[5]) && \ - ((g1)[6]==(g2)[6]) && \ - ((g1)[7]==(g2)[7]) ) - -#define MAC_IDX(i) (((mac_tbl[i].eth_mac_lsb[0])<<16) | \ - ((mac_tbl[i].eth_mac_lsb[0])<<8) | \ - (mac_tbl[i].eth_mac_lsb[0])) - -static inline const void *qpn2buf(__u32 qpn, const void *buf) -{ - ((__u8 *) buf)[0] = qpn >> 16; - ((__u8 *) buf)[1] = (qpn >> 8) & 0xff; - ((__u8 *) buf)[2] = qpn & 0xff; - return buf; -} - -static inline __u32 buf2qpn(const void *buf) -{ - __u32 qpn; - - qpn = ((((__u8 *) buf)[0]) << 16) + - ((((__u8 *) buf)[1]) << 8) + (((__u8 *) buf)[2]); - - return qpn; -} - -static int is_bcast_mac(const char *dest) -{ - int i; - __u8 mac = 0xff; - - for (i = 0; i < 6; ++i) - mac &= dest[i]; - - return mac == 0xff; -} - -/* find a free entry. if not found kick - * another entry. - */ -static int find_free_entry(void) -{ - __u32 youth = 0xffffffff; - __u8 i, remove_idx = NUM_MAC_ENTRIES; - - /* find a free entry */ - for (i = 0; i < NUM_MAC_ENTRIES; ++i) { - if (!mac_tbl[i].valid) { - mac_tbl[i].valid = 1; - mac_tbl[i].youth = youth_counter; - youth_counter++; - return i; - } - } - - for (i = 0; i < NUM_MAC_ENTRIES; ++i) { - if ((mac_tbl[i].av == NULL) && (mac_tbl[i].youth < youth)) { - youth = mac_tbl[i].youth; - remove_idx = i; - } - } - - if (remove_idx < NUM_MAC_ENTRIES) { - /* update the new youth value */ - mac_tbl[remove_idx].youth = youth_counter; - youth_counter++; - return remove_idx; - } else { - tprintf("did not find an entry to kick"); - return -1; - } -} - -static int find_qpn_gid(__u32 qpn, const __u8 * gid) -{ - __u16 i; - - for (i = 0; i < NUM_MAC_ENTRIES; ++i) { - if (mac_tbl[i].valid && - (mac_tbl[i].qpn == qpn) && - !memcmp(mac_tbl[i].gid.raw, gid, 16)) { - return i; - } - } - return -1; -} - -static void allocate_new_mac6(__u8 * mac_lsb) -{ - __u32 eth_counter; - - eth_counter = mac_counter; - mac_counter = (mac_counter + 1) & 0xffffff; - - mac_lsb[0] = eth_counter >> 16; - mac_lsb[1] = eth_counter >> 8; - mac_lsb[2] = eth_counter & 0xff; - tprintf("add mac: %x:%x:%x", mac_lsb[0], mac_lsb[1], mac_lsb[2]); -} - -static void modify_arp_reply(__u8 * eth_mac_lsb, void *data) -{ - __u8 *packet; - - /* skip 4 bytes */ - packet = ((__u8 *) data) + 4; - - /* modify hw type */ - packet[0] = 0; - packet[1] = 1; - - /* modify hw size */ - packet[4] = 6; - - /* modify sender's mac */ - packet[8] = MLX_ETH_BYTE0; - packet[9] = MLX_ETH_BYTE1; - packet[10] = MLX_ETH_BYTE2; - packet[11] = eth_mac_lsb[0]; - packet[12] = eth_mac_lsb[1]; - packet[13] = eth_mac_lsb[2]; - - /* move sender's IP address */ - memcpy(packet + 14, packet + 28, 4); - - /* set target MAC - that's us */ - packet[18] = MLX_ETH_BYTE0; - packet[19] = MLX_ETH_BYTE1; - packet[20] = MLX_ETH_BYTE2; - packet[21] = 0; - packet[22] = 0; - packet[23] = 0; - - /* move target's IP address */ - memcpy(packet + 24, packet + 52, 4); -} - -static void modify_arp_request(__u8 * eth_mac_lsb, void *data) -{ - __u8 *packet; - - /* skip 4 bytes */ - packet = ((__u8 *) data) + 4; - - /* modify hw type */ - packet[0] = 0; - packet[1] = 1; - - /* modify hw size */ - packet[4] = 6; - - /* modify sender's mac */ - packet[8] = MLX_ETH_BYTE0; - packet[9] = MLX_ETH_BYTE1; - packet[10] = MLX_ETH_BYTE2; - packet[11] = eth_mac_lsb[0]; - packet[12] = eth_mac_lsb[1]; - packet[13] = eth_mac_lsb[2]; - - /* move sender's IP address */ - memcpy(packet + 14, packet + 28, 4); - - /* set target MAC - that's us */ - packet[18] = 0; - packet[19] = 0; - packet[20] = 0; - packet[21] = 0; - packet[22] = 0; - packet[23] = 0; - - /* move target's IP address */ - memcpy(packet + 24, packet + 52, 4); -} - -static int handle_arp_packet(void *buf, void **out_buf_p, - unsigned int *new_size_p) -{ - __u16 opcode; - const void *p; - const __u8 *gid; - __u32 qpn; - int idx; - - opcode = get_opcode(buf); - switch (opcode) { - case ARP_OP_REQUESET: - case ARP_OP_REPLY: - break; - - default: - return -1; - } - - p = arp_mac20_get_sender_qpn(buf); - qpn = buf2qpn(p); - gid = arp_mac20_get_sender_gid(buf); - - if (!memcmp(gid, get_port_gid(), 16)) { - /* my own gid */ - *out_buf_p = NULL; - return 0; - } - - idx = find_qpn_gid(qpn, gid); - if (idx == -1) { - /* entry not in the table */ - idx = find_free_entry(); - if (idx == -1) { - eprintf("we're in broch\n"); - return -1; - } - allocate_new_mac6(mac_tbl[idx].eth_mac_lsb); - mac_tbl[idx].av = NULL; // free the av id it exists ?? !! - mac_tbl[idx].qpn = qpn; - memcpy(mac_tbl[idx].gid.raw, gid, 16); - } - - if (opcode == ARP_OP_REQUESET) { - modify_arp_request(mac_tbl[idx].eth_mac_lsb, buf); - } else { - /* we want to filter possible broadcast arp - replies not directed to us */ - p = arp_mac20_get_target_qpn(buf); - qpn = buf2qpn(p); - gid = arp_mac20_get_target_gid(buf); - - if ((qpn != ipoib_data.ipoib_qpn) || - (memcmp(gid, get_port_gid(), 16))) { - *out_buf_p = NULL; - return 0; - } - - modify_arp_reply(mac_tbl[idx].eth_mac_lsb, buf); - { - __u8 i; - tprintf("arp reply dump:\n"); - for (i = 4; i < 32; ++i) { - tprintf("%x: ", ((__u8 *) buf)[i]); - } - tprintf("\n"); - } - } - *out_buf_p = ((__u8 *) buf) + 4; - *new_size_p = 28; /* size of eth arp packet */ - - tprintf(""); - - return 0; -} - -static void modify_udp_csum(void *buf, __u16 size) -{ - __u8 *ptr = (__u8 *) buf; - __u32 csum = 0; - __u16 chksum; - __u16 buf_size; - __u16 *tmp; - int i; - - buf_size = (size & 1) ? size + 1 : size; - tmp = (__u16 *) (ptr + 12); /* src and dst ip addresses */ - for (i = 0; i < 4; ++i) { - csum += tmp[i]; - } - - csum += 0x1100; // udp protocol - - tmp = (__u16 *) (ptr + 26); - tmp[0] = 0; /* zero the checksum */ - - tmp = (__u16 *) (ptr + 24); - csum += tmp[0]; - - tmp = (__u16 *) (ptr + 20); - - for (i = 0; i < ((buf_size - 20) >> 1); ++i) { - csum += tmp[i]; - } - - chksum = ~((__u16) ((csum & 0xffff) + (csum >> 16))); - - tmp = (__u16 *) (ptr + 26); - tmp[0] = chksum; /* set the checksum */ -} - -static void modify_dhcp_resp(void *buf, __u16 size) -{ - set_eth_hwtype(buf); - set_eth_hwlen(buf); - set_own_mac(buf); - modify_udp_csum(buf, size); -} - -static void get_my_client_id(__u8 * my_client_id) -{ - - my_client_id[0] = 0; - qpn2buf(ipoib_data.ipoib_qpn, my_client_id + 1); - memcpy(my_client_id + 4, ipoib_data.port_gid_raw, 16); -} - -static const __u8 *get_client_id(const void *buf, int len) -{ - const __u8 *ptr; - int delta; - - if (len < 268) - return NULL; - - /* pointer to just after magic cookie */ - ptr = (const __u8 *)buf + 268; - - /* find last client identifier option */ - do { - if (ptr[0] == 255) { - /* found end of options list */ - return NULL; - } - - if (ptr[0] == 0x3d) { - /* client identifer option */ - return ptr + 3; - } - - delta = ptr[1] + 2; - ptr += delta; - len -= delta; - } while (len > 0); - - return NULL; -} - -static int handle_ipv4_packet(void *buf, void **out_buf_p, - unsigned int *new_size_p, int *is_bcast_p) -{ - void *new_buf; - __u16 new_size; - __u8 msg_type; - __u8 my_client_id[20]; - - new_buf = (void *)(((__u8 *) buf) + 4); - new_size = (*new_size_p) - 4; - *out_buf_p = new_buf; - *new_size_p = new_size; - - if (get_ip_protocl(new_buf) == IP_PROT_UDP) { - __u16 udp_dst_port; - const __u8 *client_id; - - udp_dst_port = get_udp_dst_port(new_buf); - - if (udp_dst_port == 67) { - /* filter dhcp requests */ - *out_buf_p = 0; - return 0; - } - - if (udp_dst_port == 68) { - get_my_client_id(my_client_id); - - /* packet client id */ - client_id = get_client_id(new_buf, new_size); - if (!client_id) { - *out_buf_p = 0; - return 0; - } - - if (memcmp(client_id, my_client_id, 20)) { - *out_buf_p = 0; - return 0; - } - } - } - - msg_type = get_dhcp_msg_type(new_buf); - if ((get_ip_protocl(new_buf) == IP_PROT_UDP) && - (get_udp_dst_port(new_buf) == 68) && - ((msg_type == DHCP_TYPE_RESPONSE) || (msg_type == DHCP_TYPE_ACK)) - ) { - *is_bcast_p = 1; - modify_dhcp_resp(new_buf, new_size); - } - - return 0; -} - -static int is_valid_arp(void *buf, unsigned int size) -{ - __u8 *ptr = buf; - __u16 tmp; - - if (size != 60) { - eprintf(""); - return 0; - } - if (be16_to_cpu(*((__u16 *) ptr)) != ARP_PROT_TYPE) - return 0; - - if (be16_to_cpu(*((__u16 *) (ptr + 4))) != IPOIB_HW_TYPE) - return 0; - - if (be16_to_cpu(*((__u16 *) (ptr + 6))) != IPV4_PROT_TYPE) - return 0; - - if (ptr[8] != 20) /* hw addr len */ - return 0; - - if (ptr[9] != 4) /* protocol len = 4 for IP */ - return 0; - - tmp = be16_to_cpu(*((__u16 *) (ptr + 10))); - if ((tmp != ARP_OP_REQUESET) && (tmp != ARP_OP_REPLY)) - return 0; - - return 1; -} - -static int ipoib_handle_rcv(void *buf, void **out_buf_p, - unsigned int *new_size_p, int *is_bcast_p) -{ - __u16 prot_type; - int rc; - - prot_type = get_prot_type(buf); - switch (prot_type) { - case ARP_PROT_TYPE: - tprintf(""); - if (is_valid_arp(buf, *new_size_p)) { - tprintf("got valid arp"); - rc = handle_arp_packet(buf, out_buf_p, new_size_p); - if (rc) { - eprintf(""); - return rc; - } - if (!out_buf_p) { - tprintf(""); - } - tprintf("arp for me"); - *is_bcast_p = 1; - return rc; - } else { - tprintf("got invalid arp"); - *out_buf_p = NULL; - return 0; - } - - case IPV4_PROT_TYPE: - tprintf(""); - rc = handle_ipv4_packet(buf, out_buf_p, new_size_p, is_bcast_p); - return rc; - } - eprintf("prot=0x%x", prot_type); - return -1; -} - -static int is_null_mac(const __u8 * mac) -{ - __u8 i, tmp = 0; - __u8 lmac[6]; - - memcpy(lmac, mac, 6); - - for (i = 0; i < 6; ++i) { - tmp |= lmac[i]; - } - - if (tmp == 0) - return 1; - else - return 0; -} - -static int find_mac(const __u8 * mac) -{ - int i; - const __u8 *tmp = mac + 3; - - for (i = 0; i < NUM_MAC_ENTRIES; ++i) { - tprintf("checking 0x%02x:0x%02x:0x%02x valid=%d", - mac_tbl[i].eth_mac_lsb[0], mac_tbl[i].eth_mac_lsb[1], - mac_tbl[i].eth_mac_lsb[2], mac_tbl[i].valid); - if (mac_tbl[i].valid && !memcmp(mac_tbl[i].eth_mac_lsb, tmp, 3)) - return i; - } - tprintf("mac: %x:%x:%x - dumping", tmp[0], tmp[1], tmp[2]); - for (i = 0; i < NUM_MAC_ENTRIES; ++i) { - //__u8 *gid= mac_tbl[i].gid.raw; - //__u8 *m= mac_tbl[i].eth_mac_lsb; - /*if (mac_tbl[i].valid) { - tprintf("%d: qpn=0x%lx, " - "gid=%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x, " - "av=0x%lx, " - "youth= %ld, " - "mac=%x:%x:%x\n", - i, mac_tbl[i].qpn, - gid[0], gid[1], gid[2], gid[3], gid[4], gid[5], gid[6], gid[7], - gid[8], gid[9], gid[10], gid[11], gid[12], gid[13], gid[14], gid[15], - mac_tbl[i].av, mac_tbl[i].youth, - m[0], m[1], m[2]); - } */ - } - return -1; -} - -static int send_bcast_packet(__u16 protocol, const void *data, __u16 size) -{ - ud_send_wqe_t snd_wqe, tmp_wqe; - int rc; - int is_good; - void *send_buffer; - - snd_wqe = alloc_send_wqe(ipoib_data.ipoib_qph); - if (!snd_wqe) { - eprintf(""); - return -1; - } - - send_buffer = get_send_wqe_buf(snd_wqe, 0); - *((__u32 *) send_buffer) = cpu_to_be32(protocol << 16); - prep_send_wqe_buf(ipoib_data.ipoib_qph, ipoib_data.bcast_av, - snd_wqe, data, 4, size, 0); - - rc = post_send_req(ipoib_data.ipoib_qph, snd_wqe, 1); - if (rc) { - eprintf(""); - goto ex; - } - - rc = poll_cqe_tout(ipoib_data.snd_cqh, SEND_CQE_POLL_TOUT, &tmp_wqe, - &is_good); - if (rc) { - eprintf(""); - goto ex; - } - if (!is_good) { - eprintf(""); - rc = -1; - goto ex; - } - if (tmp_wqe != snd_wqe) { - eprintf(""); - rc = -1; - goto ex; - } - - ex:free_wqe(snd_wqe); - return rc; -} - -static int send_ucast_packet(const __u8 * mac, __u16 protocol, const void *data, - __u16 size) -{ - ud_send_wqe_t snd_wqe, tmp_wqe; - ud_av_t av; - udqp_t qph; - __u16 dlid; - __u8 sl, rate; - int rc; - int i; - int is_good; - - i = find_mac(mac); - if (i < 0) { - tprintf(""); - return -1; - } - - if (!mac_tbl[i].av) { - rc = get_path_record(&mac_tbl[i].gid, &dlid, &sl, &rate); - if (rc) { - eprintf(""); - return -1; - } else { - tprintf("get_path_record() success dlid=0x%x", dlid); - } - - /* no av - allocate one */ - av = alloc_ud_av(); - if (!av) { - eprintf(""); - return -1; - } - modify_av_params(av, dlid, 1, sl, rate, &mac_tbl[i].gid, - mac_tbl[i].qpn); - mac_tbl[i].av = av; - } else { - av = mac_tbl[i].av; - } - qph = ipoib_data.ipoib_qph; - snd_wqe = alloc_send_wqe(qph); - if (!snd_wqe) { - eprintf(""); - return -1; - } - - *((__u32 *) get_send_wqe_buf(snd_wqe, 0)) = cpu_to_be32(protocol << 16); - prep_send_wqe_buf(qph, av, snd_wqe, data, 4, size, 0); - - rc = post_send_req(qph, snd_wqe, 1); - if (rc) { - eprintf(""); - return -1; - } - - rc = poll_cqe_tout(ipoib_data.snd_cqh, SEND_CQE_POLL_TOUT, &tmp_wqe, - &is_good); - if (rc) { - eprintf(""); - goto ex; - } - if (!is_good) { - eprintf(""); - rc = -1; - goto ex; - } - if (tmp_wqe != snd_wqe) { - eprintf(""); - rc = -1; - goto ex; - } - - ex:free_wqe(snd_wqe); - return rc; -} - -static void *alloc_convert_arp6_msg(const void *data, - struct arp_packet_st *ipoib_arp) -{ - void *buf; - const void *p1; - int idx; - __u8 qpn[3]; - - memcpy(ipoib_arp, arp_packet_template, sizeof arp_packet_template); - buf = ipoib_arp; - - /* update opcode */ - p1 = arp_mac6_get_opcode(data); - arp_mac20_set_opcode(p1, buf); - - /* update sender ip */ - p1 = arp_mac6_get_sender_ip(data); - arp_mac20_set_sender_ip(p1, buf); - - /* update target ip */ - p1 = arp_mac6_get_target_ip(data); - arp_mac20_set_target_ip(p1, buf); - - /* update sender mac */ - qpn2buf(ipoib_data.ipoib_qpn, qpn); - arp_mac20_set_sender_mac(qpn, ipoib_data.port_gid_raw, buf); - - /* update target mac */ - p1 = arp_mac6_get_target_mac(data); - if (!is_null_mac(p1)) { - idx = find_mac(p1); - if (idx == -1) { - __u8 *_ptr = (__u8 *) p1; - eprintf("could not find mac %x:%x:%x", - _ptr[3], _ptr[4], _ptr[5]); - return NULL; - } - qpn2buf(mac_tbl[idx].qpn, qpn); - arp_mac20_set_target_mac(qpn, mac_tbl[idx].gid.raw, buf); - } - - return buf; -} - -static __u16 set_client_id(__u8 * packet) -{ - __u8 *ptr; - __u8 y[3]; - __u16 new_size; - - /* pointer to just after magic cookie */ - ptr = packet + 268; - - /* find last option */ - do { - if (ptr[0] == 255) { - /* found end of options list */ - break; - } - ptr = ptr + ptr[1] + 2; - } while (1); - - ptr[0] = 61; /* client id option identifier */ - ptr[1] = 21; /* length of the option */ - ptr[2] = IPOIB_HW_TYPE; - ptr[3] = 0; - qpn2buf(ipoib_data.ipoib_qpn, y); - memcpy(ptr + 4, y, 3); - memcpy(ptr + 7, ipoib_data.port_gid_raw, 16); - ptr[23] = 255; - new_size = (__u16) (ptr + 24 - packet); - if (new_size & 3) { - new_size += (4 - (new_size & 3)); - } - return new_size; -} - -static __u16 calc_udp_csum(__u8 * packet) -{ - __u16 *ptr; - int i; - __u32 sum = 0; - __u16 udp_length, udp_csum; - - /* src ip, dst ip */ - ptr = (__u16 *) (packet + 12); - for (i = 0; i < 4; ++i) { - sum += be16_to_cpu(ptr[i]); - } - - /* udp protocol */ - sum += IP_PROT_UDP; - - /* udp length */ - ptr = (__u16 *) (packet + 24); - udp_length = be16_to_cpu(*ptr); - sum += udp_length; - - /* udp part */ - ptr = (__u16 *) (packet + 20); - do { - sum += be16_to_cpu(*ptr); - ptr++; - udp_length -= 2; - } while (udp_length); - - udp_csum = ~((__u16) ((sum & 0xffff) + (sum >> 16))); - return udp_csum; -} - -static __u16 modify_dhcp_request(__u8 * packet, __u16 size) -{ - __u16 csum, new_size; - - set_hw_type(packet); - zero_hw_len(packet); - zero_chaddr(packet); - set_bcast_flag(packet); - new_size = set_client_id(packet); - if (new_size > size) { - add_udp_len(packet, new_size - size); - } else - new_size = size; - set_udp_csum(packet, 0); - csum = calc_udp_csum(packet); - set_udp_csum(packet, csum); - return new_size; -} - -static __u16 copy_dhcp_message(__u8 * buf, const void *packet, __u16 size) -{ - memcpy(buf, packet, size); - return size; -} - -static void modify_ip_hdr(__u8 * buf, __u16 add_size) -{ - __u16 *ptr, ip_csum; - __u16 tmp; - __u32 sum = 0; - __u8 i; - - /* update ip length */ - ptr = (__u16 *) buf; - tmp = be16_to_cpu(ptr[1]); - ptr[1] = cpu_to_be16(tmp + add_size); - - ptr[5] = 0; /* zero csum */ - for (i = 0; i < 10; ++i) { - sum += be16_to_cpu(ptr[i]); - } - - ip_csum = ~((__u16) ((sum & 0xffff) + (sum >> 16))); - ptr[5] = cpu_to_be16(ip_csum); - -} - -static void *update_dhcp_request(const void *packet, unsigned int size, - __u16 * new_size_p) -{ - __u8 ip_proto, dhcp_message_type; - __u16 dest_port, new_size, orig_size; - static __u8 dhcp_send_buffer[576]; - - ip_proto = get_ip_protocl_type(packet); - if (ip_proto != IP_PROT_UDP) { - return NULL; - } - - dest_port = get_udp_dest_port(packet); - if (dest_port != 0x4300 /*67 */ ) - return NULL; - - dhcp_message_type = get_dhcp_message_type(packet); - if (dhcp_message_type != DHCP_TYPE_REQUEST) - return NULL; - - memset(dhcp_send_buffer, 0, sizeof dhcp_send_buffer); - orig_size = copy_dhcp_message(dhcp_send_buffer, packet, size); - - new_size = modify_dhcp_request(dhcp_send_buffer, orig_size); - if (new_size != orig_size) { - modify_ip_hdr(dhcp_send_buffer, new_size - orig_size); - } - *new_size_p = new_size; - return dhcp_send_buffer; -} - -static int ipoib_send_packet(const __u8 * mac, __u16 protocol, const void *data, - unsigned int size) -{ - const void *packet; - __u16 new_size, dhcp_req_sz; - void *tmp; - int rc; - struct arp_packet_st ipoib_arp; - - tprintf(""); - - if (protocol == ARP_PROT_TYPE) { - /* special treatment for ARP */ - tmp = alloc_convert_arp6_msg(data, &ipoib_arp); - if (!tmp) { - eprintf(""); - return -1; - } - packet = tmp; - new_size = sizeof(struct arp_packet_st); - tprintf("sending arp"); - } else { - tmp = update_dhcp_request(data, size, &dhcp_req_sz); - if (tmp) { - /* it was a dhcp request so we use a special - buffer because we may have to enlarge the size of the packet */ - tprintf("sending dhcp"); - packet = tmp; - new_size = dhcp_req_sz; - } else { - packet = data; - new_size = size; - tprintf("sending packet"); - } - } - - //eprintf("press key ..."); getchar(); - if (is_bcast_mac(mac)) { - tprintf(""); - rc = send_bcast_packet(protocol, packet, new_size); - } else { - tprintf(""); - rc = send_ucast_packet(mac, protocol, packet, new_size); - } - - return rc; -} - -static int ipoib_read_packet(__u16 * prot_p, void *data, unsigned int *size_p, - int *is_bcast_p) -{ - int rc; - struct ib_cqe_st ib_cqe; - __u8 num_cqes; - unsigned int new_size; - void *buf, *out_buf; - __u16 prot_type; - - rc = ib_poll_cq(ipoib_data.rcv_cqh, &ib_cqe, &num_cqes); - if (rc) { - return rc; - } - - if (num_cqes == 0) { - *size_p = 0; - return 0; - } - - if (ib_cqe.is_error) { - eprintf(""); - rc = -1; - goto ex_func; - } - - new_size = ib_cqe.count - GRH_SIZE; - buf = get_rcv_wqe_buf(ib_cqe.wqe, 1); - tprintf("buf=%lx", buf); - rc = ipoib_handle_rcv(buf, &out_buf, &new_size, is_bcast_p); - if (rc) { - eprintf(""); - rc = -1; - goto ex_func; - } - if (out_buf) { - tprintf(""); - prot_type = get_prot_type(buf); - *size_p = new_size; - tprintf("new_size=%d", new_size); - if (new_size > 1560) { - eprintf("sizzzzzze = %d", new_size); - } else { - memcpy(data, out_buf, new_size); - } - *prot_p = prot_type; - } else { - tprintf("skip message"); - *size_p = 0; - } - - ex_func: - if (free_wqe(ib_cqe.wqe)) { - eprintf(""); - } - - return rc; -} - -static int ipoib_init(struct pci_device *pci) -{ - int rc; - udqp_t qph; - int i; - - tprintf(""); - rc = ib_driver_init(pci, &qph); - if (rc) - return rc; - - tprintf(""); - ipoib_data.ipoib_qph = qph; - ipoib_data.ipoib_qpn = ib_get_qpn(qph); - - if(print_info) - printf("local ipoib qpn=0x%x\n", ipoib_data.ipoib_qpn); - - ipoib_data.bcast_av = ib_data.bcast_av; - ipoib_data.port_gid_raw = ib_data.port_gid.raw; - ipoib_data.snd_cqh = ib_data.ipoib_snd_cq; - ipoib_data.rcv_cqh = ib_data.ipoib_rcv_cq; - - mac_counter = 1; - youth_counter = 0; - for (i = 0; i < NUM_MAC_ENTRIES; ++i) { - mac_tbl[i].valid = 0; - mac_tbl[i].av = NULL; - } - - return 0; -} - -static int ipoib_close(int fw_fatal) -{ - int rc; - - rc = ib_driver_close(fw_fatal); - - return rc; -} |