X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fnet%2Fehea%2Fehea_main.c;h=63732d2305bbcf9590cf3a141046783f03690293;hb=ab6a5bb6b28a970104a34f0f6959b73cf61bdc72;hp=22c81ae4f9adcaeeafe25b1cb2e53e629d69ce1a;hpb=bb3a6449c18f6203e59195a98d633f5b5b57c133;p=linux-2.6 diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 22c81ae4f9..63732d2305 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -76,7 +76,7 @@ void ehea_dump(void *adr, int len, char *msg) { int x; unsigned char *deb = adr; for (x = 0; x < len; x += 16) { - printk(DRV_NAME "%s adr=%p ofs=%04x %016lx %016lx\n", msg, + printk(DRV_NAME " %s adr=%p ofs=%04x %016lx %016lx\n", msg, deb, x, *((u64*)&deb[0]), *((u64*)&deb[8])); deb += 16; } @@ -555,6 +555,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) { struct ehea_port *port = param; struct ehea_eqe *eqe; + struct ehea_qp *qp; u32 qp_token; eqe = ehea_poll_eq(port->qp_eq); @@ -563,9 +564,14 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry); ehea_error("QP aff_err: entry=0x%lx, token=0x%x", eqe->entry, qp_token); + + qp = port->port_res[qp_token].qp; + ehea_error_data(port->adapter, qp->fw_handle); eqe = ehea_poll_eq(port->qp_eq); } + queue_work(port->adapter->ehea_wq, &port->reset_task); + return IRQ_HANDLED; } @@ -575,8 +581,9 @@ static struct ehea_port *ehea_get_port(struct ehea_adapter *adapter, int i; for (i = 0; i < adapter->num_ports; i++) - if (adapter->port[i]->logical_port_id == logical_port) - return adapter->port[i]; + if (adapter->port[i]) + if (adapter->port[i]->logical_port_id == logical_port) + return adapter->port[i]; return NULL; } @@ -881,7 +888,7 @@ static int ehea_reg_interrupts(struct net_device *dev) , "%s-recv%d", dev->name, i); ret = ibmebus_request_irq(NULL, pr->recv_eq->attr.ist1, ehea_recv_irq_handler, - SA_INTERRUPT, pr->int_recv_name, pr); + IRQF_DISABLED, pr->int_recv_name, pr); if (ret) { ehea_error("failed registering irq for ehea_recv_int:" "port_res_nr:%d, ist=%X", i, @@ -898,7 +905,7 @@ static int ehea_reg_interrupts(struct net_device *dev) ret = ibmebus_request_irq(NULL, port->qp_eq->attr.ist1, ehea_qp_aff_irq_handler, - SA_INTERRUPT, port->int_aff_name, port); + IRQF_DISABLED, port->int_aff_name, port); if (ret) { ehea_error("failed registering irq for qp_aff_irq_handler:" "ist=%X", port->qp_eq->attr.ist1); @@ -915,7 +922,7 @@ static int ehea_reg_interrupts(struct net_device *dev) "%s-send%d", dev->name, i); ret = ibmebus_request_irq(NULL, pr->send_eq->attr.ist1, ehea_send_irq_handler, - SA_INTERRUPT, pr->int_send_name, + IRQF_DISABLED, pr->int_send_name, pr); if (ret) { ehea_error("failed registering irq for ehea_send " @@ -1255,8 +1262,8 @@ static int ehea_clean_portres(struct ehea_port *port, struct ehea_port_res *pr) static inline void write_ip_start_end(struct ehea_swqe *swqe, const struct sk_buff *skb) { - swqe->ip_start = (u8)(((u64)skb->nh.iph) - ((u64)skb->data)); - swqe->ip_end = (u8)(swqe->ip_start + skb->nh.iph->ihl * 4 - 1); + swqe->ip_start = skb_network_offset(skb); + swqe->ip_end = (u8)(swqe->ip_start + ip_hdrlen(skb) - 1); } static inline void write_tcp_offset_end(struct ehea_swqe *swqe, @@ -1293,7 +1300,7 @@ static void write_swqe2_TSO(struct sk_buff *skb, /* copy only eth/ip/tcp headers to immediate data and * the rest of skb->data to sg1entry */ - headersize = ETH_HLEN + (skb->nh.iph->ihl * 4) + (skb->h.th->doff * 4); + headersize = ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); skb_data_size = skb->len - skb->data_len; @@ -1681,6 +1688,7 @@ static void ehea_xmit2(struct sk_buff *skb, struct net_device *dev, struct ehea_swqe *swqe, u32 lkey) { if (skb->protocol == htons(ETH_P_IP)) { + const struct iphdr *iph = ip_hdr(skb); /* IPv4 */ swqe->tx_control |= EHEA_SWQE_CRC | EHEA_SWQE_IP_CHECKSUM @@ -1690,15 +1698,15 @@ static void ehea_xmit2(struct sk_buff *skb, struct net_device *dev, write_ip_start_end(swqe, skb); - if (skb->nh.iph->protocol == IPPROTO_UDP) { - if ((skb->nh.iph->frag_off & IP_MF) || - (skb->nh.iph->frag_off & IP_OFFSET)) + if (iph->protocol == IPPROTO_UDP) { + if ((iph->frag_off & IP_MF) || + (iph->frag_off & IP_OFFSET)) /* IP fragment, so don't change cs */ swqe->tx_control &= ~EHEA_SWQE_TCP_CHECKSUM; else write_udp_offset_end(swqe, skb); - } else if (skb->nh.iph->protocol == IPPROTO_TCP) { + } else if (iph->protocol == IPPROTO_TCP) { write_tcp_offset_end(swqe, skb); } @@ -1724,10 +1732,11 @@ static void ehea_xmit3(struct sk_buff *skb, struct net_device *dev, int i; if (skb->protocol == htons(ETH_P_IP)) { + const struct iphdr *iph = ip_hdr(skb); /* IPv4 */ write_ip_start_end(swqe, skb); - if (skb->nh.iph->protocol == IPPROTO_TCP) { + if (iph->protocol == IPPROTO_TCP) { swqe->tx_control |= EHEA_SWQE_CRC | EHEA_SWQE_IP_CHECKSUM | EHEA_SWQE_TCP_CHECKSUM @@ -1735,9 +1744,9 @@ static void ehea_xmit3(struct sk_buff *skb, struct net_device *dev, write_tcp_offset_end(swqe, skb); - } else if (skb->nh.iph->protocol == IPPROTO_UDP) { - if ((skb->nh.iph->frag_off & IP_MF) || - (skb->nh.iph->frag_off & IP_OFFSET)) + } else if (iph->protocol == IPPROTO_UDP) { + if ((iph->frag_off & IP_MF) || + (iph->frag_off & IP_OFFSET)) /* IP fragment, so don't change cs */ swqe->tx_control |= EHEA_SWQE_CRC | EHEA_SWQE_IMM_DATA_PRESENT; @@ -1932,8 +1941,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) int index; u64 hret; - if (port->vgrp) - port->vgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(port->vgrp, vid, NULL); cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!cb1) { @@ -2315,6 +2323,7 @@ static int ehea_setup_single_port(struct ehea_port *port, struct ehea_adapter *adapter = port->adapter; struct hcp_ehea_port_cb4 *cb4; u32 *dn_log_port_id; + int jumbo = 0; sema_init(&port->port_lock, 1); port->state = EHEA_PORT_DOWN; @@ -2356,13 +2365,25 @@ static int ehea_setup_single_port(struct ehea_port *port, if (!cb4) { ehea_error("no mem for cb4"); } else { - cb4->jumbo_frame = 1; - hret = ehea_h_modify_ehea_port(adapter->handle, - port->logical_port_id, - H_PORT_CB4, H_PORT_CB4_JUMBO, - cb4); - if (hret != H_SUCCESS) { - ehea_info("Jumbo frames not activated"); + hret = ehea_h_query_ehea_port(adapter->handle, + port->logical_port_id, + H_PORT_CB4, + H_PORT_CB4_JUMBO, cb4); + + if (hret == H_SUCCESS) { + if (cb4->jumbo_frame) + jumbo = 1; + else { + cb4->jumbo_frame = 1; + hret = ehea_h_modify_ehea_port(adapter->handle, + port-> + logical_port_id, + H_PORT_CB4, + H_PORT_CB4_JUMBO, + cb4); + if (hret == H_SUCCESS) + jumbo = 1; + } } kfree(cb4); } @@ -2401,6 +2422,9 @@ static int ehea_setup_single_port(struct ehea_port *port, goto out_free; } + ehea_info("%s: Jumbo frames are %sabled", dev->name, + jumbo == 1 ? "en" : "dis"); + port->netdev = dev; ret = 0; goto out; @@ -2522,7 +2546,7 @@ static int __devinit ehea_probe(struct ibmebus_dev *dev, (unsigned long)adapter); ret = ibmebus_request_irq(NULL, adapter->neq->attr.ist1, - ehea_interrupt_neq, SA_INTERRUPT, + ehea_interrupt_neq, IRQF_DISABLED, "ehea_neq", adapter); if (ret) { dev_err(&dev->ofdev.dev, "requesting NEQ IRQ failed"); @@ -2581,6 +2605,7 @@ static int __devexit ehea_remove(struct ibmebus_dev *dev) destroy_workqueue(adapter->ehea_wq); ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter); + tasklet_kill(&adapter->neq_tasklet); ehea_destroy_eq(adapter->neq);