Merge branch 'master' of /home/sam/kernel/linux-2.6/
[pandora-kernel.git] / drivers / s390 / net / qeth_main.c
index 021cd5d..36733b9 100644 (file)
@@ -27,7 +27,6 @@
  */
 
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/string.h>
@@ -297,12 +296,10 @@ qeth_alloc_card(void)
        struct qeth_card *card;
 
        QETH_DBF_TEXT(setup, 2, "alloccrd");
-       card = (struct qeth_card *) kmalloc(sizeof(struct qeth_card),
-                                           GFP_DMA|GFP_KERNEL);
+       card = kzalloc(sizeof(struct qeth_card), GFP_DMA|GFP_KERNEL);
        if (!card)
                return NULL;
        QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
-       memset(card, 0, sizeof(struct qeth_card));
        if (qeth_setup_channel(&card->read)) {
                kfree(card);
                return NULL;
@@ -515,7 +512,7 @@ __qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
 
        QETH_DBF_TEXT(setup, 3, "setoffl");
        QETH_DBF_HEX(setup, 3, &card, sizeof(void *));
-       
+
        if (card->dev && netif_carrier_ok(card->dev))
                netif_carrier_off(card->dev);
        recover_flag = card->state;
@@ -606,13 +603,13 @@ __qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
        list_for_each_entry(addr, &card->ip_list, entry) {
                if (card->options.layer2) {
                        if ((addr->type == todo->type) &&
-                           (memcmp(&addr->mac, &todo->mac, 
+                           (memcmp(&addr->mac, &todo->mac,
                                    OSA_ADDR_LEN) == 0)) {
                                found = 1;
                                break;
                        }
                        continue;
-               } 
+               }
                if ((addr->proto     == QETH_PROT_IPV4)  &&
                    (todo->proto     == QETH_PROT_IPV4)  &&
                    (addr->type      == todo->type)      &&
@@ -696,13 +693,13 @@ __qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
                if (card->options.layer2) {
                        if ((tmp->type  == addr->type)  &&
                            (tmp->is_multicast == addr->is_multicast) &&
-                           (memcmp(&tmp->mac, &addr->mac, 
+                           (memcmp(&tmp->mac, &addr->mac,
                                    OSA_ADDR_LEN) == 0)) {
                                found = 1;
                                break;
                        }
                        continue;
-               }        
+               }
                if ((tmp->proto        == QETH_PROT_IPV4)     &&
                    (addr->proto       == QETH_PROT_IPV4)     &&
                    (tmp->type         == addr->type)         &&
@@ -1175,7 +1172,7 @@ qeth_determine_card_type(struct qeth_card *card)
                                           "due to hardware limitations!\n");
                                card->qdio.no_out_queues = 1;
                                card->qdio.default_out_queue = 0;
-                       } 
+                       }
                        return 0;
                }
                i++;
@@ -1200,7 +1197,7 @@ qeth_probe_device(struct ccwgroup_device *gdev)
                return -ENODEV;
 
        QETH_DBF_TEXT_(setup, 2, "%s", gdev->dev.bus_id);
-       
+
        card = qeth_alloc_card();
        if (!card) {
                put_device(dev);
@@ -1222,7 +1219,7 @@ qeth_probe_device(struct ccwgroup_device *gdev)
                put_device(dev);
                qeth_free_card(card);
                return rc;
-       }                           
+       }
        if ((rc = qeth_setup_card(card))){
                QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
                put_device(dev);
@@ -1632,9 +1629,8 @@ qeth_alloc_reply(struct qeth_card *card)
 {
        struct qeth_reply *reply;
 
-       reply = kmalloc(sizeof(struct qeth_reply), GFP_ATOMIC);
+       reply = kzalloc(sizeof(struct qeth_reply), GFP_ATOMIC);
        if (reply){
-               memset(reply, 0, sizeof(struct qeth_reply));
                atomic_set(&reply->refcnt, 1);
                reply->card = card;
        };
@@ -1846,7 +1842,7 @@ struct qeth_cmd_buffer *iob)
               &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
        QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
 }
-                                                   
+
 static int
 qeth_send_control_data(struct qeth_card *card, int len,
                       struct qeth_cmd_buffer *iob,
@@ -1940,7 +1936,7 @@ qeth_osn_send_control_data(struct qeth_card *card, int len,
                wake_up(&card->wait_q);
        }
        return rc;
-}                                      
+}
 
 static inline void
 qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
@@ -1969,7 +1965,7 @@ qeth_osn_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
        memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
        return qeth_osn_send_control_data(card, s1, iob);
 }
-                                                           
+
 static int
 qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
                  int (*reply_cb)
@@ -2582,7 +2578,7 @@ qeth_process_inbound_buffer(struct qeth_card *card,
                skb->dev = card->dev;
                if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
                        vlan_tag = qeth_layer2_rebuild_skb(card, skb, hdr);
-               else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3)     
+               else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3)
                        qeth_rebuild_skb(card, skb, hdr);
                else { /*in case of OSN*/
                        skb_push(skb, sizeof(struct qeth_hdr));
@@ -2766,7 +2762,7 @@ qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
                index = i % QDIO_MAX_BUFFERS_PER_Q;
                buffer = &card->qdio.in_q->bufs[index];
                if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) &&
-                     qeth_check_qdio_errors(buffer->buffer, 
+                     qeth_check_qdio_errors(buffer->buffer,
                                             qdio_err, siga_err,"qinerr")))
                        qeth_process_inbound_buffer(card, buffer, index);
                /* clear buffer and give back to hardware */
@@ -3190,7 +3186,7 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
        if (card->qdio.state == QETH_QDIO_ALLOCATED)
                return 0;
 
-       card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q), 
+       card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q),
                                  GFP_KERNEL|GFP_DMA);
        if (!card->qdio.in_q)
                return - ENOMEM;
@@ -3348,13 +3344,11 @@ qeth_qdio_establish(struct qeth_card *card)
 
        QETH_DBF_TEXT(setup, 2, "qdioest");
 
-       qib_param_field = kmalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(char),
+       qib_param_field = kzalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(char),
                              GFP_KERNEL);
        if (!qib_param_field)
                return -ENOMEM;
 
-       memset(qib_param_field, 0, QDIO_MAX_BUFFERS_PER_Q * sizeof(char));
-
        qeth_create_qib_param_field(card, qib_param_field);
        qeth_create_qib_param_field_blkt(card, qib_param_field);
 
@@ -3481,7 +3475,7 @@ qeth_halt_channels(struct qeth_card *card)
        rc3 = qeth_halt_channel(&card->data);
        if (rc1)
                return rc1;
-       if (rc2) 
+       if (rc2)
                return rc2;
        return rc3;
 }
@@ -3496,7 +3490,7 @@ qeth_clear_channels(struct qeth_card *card)
        rc3 = qeth_clear_channel(&card->data);
        if (rc1)
                return rc1;
-       if (rc2) 
+       if (rc2)
                return rc2;
        return rc3;
 }
@@ -3803,10 +3797,10 @@ qeth_open(struct net_device *dev)
                QETH_DBF_TEXT(trace,4,"nomacadr");
                return -EPERM;
        }
-       card->dev->flags |= IFF_UP;
-       netif_start_queue(dev);
        card->data.state = CH_STATE_UP;
        card->state = CARD_STATE_UP;
+       card->dev->flags |= IFF_UP;
+       netif_start_queue(dev);
 
        if (!card->lan_online && netif_carrier_ok(dev))
                netif_carrier_off(dev);
@@ -3822,7 +3816,7 @@ qeth_stop(struct net_device *dev)
 
        card = (struct qeth_card *) dev->priv;
 
-       netif_stop_queue(dev);
+       netif_tx_disable(dev);
        card->dev->flags &= ~IFF_UP;
        if (card->state == CARD_STATE_UP)
                card->state = CARD_STATE_SOFTSETUP;
@@ -3963,7 +3957,7 @@ qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb,
 #endif
        *hdr = (struct qeth_hdr *)
                qeth_push_skb(card, skb, sizeof(struct qeth_hdr));
-       if (hdr == NULL)
+       if (*hdr == NULL)
                return -EINVAL;
        return 0;
 }
@@ -4103,7 +4097,7 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
                }
        } else { /* passthrough */
                 if((skb->dev->type == ARPHRD_IEEE802_TR) &&
-                   !memcmp(skb->data + sizeof(struct qeth_hdr) + 
+                   !memcmp(skb->data + sizeof(struct qeth_hdr) +
                    sizeof(__u16), skb->dev->broadcast, 6)) {
                        hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
                                                QETH_HDR_PASSTHRU;
@@ -4390,7 +4384,7 @@ out:
 }
 
 static inline int
-qeth_get_elements_no(struct qeth_card *card, void *hdr, 
+qeth_get_elements_no(struct qeth_card *card, void *hdr,
                     struct sk_buff *skb, int elems)
 {
        int elements_needed = 0;
@@ -4421,6 +4415,8 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
        enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
        struct qeth_eddp_context *ctx = NULL;
        int tx_bytes = skb->len;
+       unsigned short nr_frags = skb_shinfo(skb)->nr_frags;
+       unsigned short tso_size = skb_shinfo(skb)->gso_size;
        int rc;
 
        QETH_DBF_TEXT(trace, 6, "sendpkt");
@@ -4446,7 +4442,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
                return 0;
        }
        cast_type = qeth_get_cast_type(card, skb);
-       if ((cast_type == RTN_BROADCAST) && 
+       if ((cast_type == RTN_BROADCAST) &&
            (card->info.broadcast_capable == 0)){
                card->stats.tx_dropped++;
                card->stats.tx_errors++;
@@ -4456,7 +4452,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
        queue = card->qdio.out_qs
                [qeth_get_priority_queue(card, skb, ipv, cast_type)];
 
-       if (skb_shinfo(skb)->tso_size)
+       if (skb_shinfo(skb)->gso_size)
                large_send = card->options.large_send;
 
        /*are we able to do TSO ? If so ,prepare and send it from here */
@@ -4468,7 +4464,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
                        card->stats.tx_errors++;
                        dev_kfree_skb_any(skb);
                        return NETDEV_TX_OK;
-               } 
+               }
                elements_needed++;
        } else {
                if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))) {
@@ -4503,16 +4499,16 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
                card->stats.tx_packets++;
                card->stats.tx_bytes += tx_bytes;
 #ifdef CONFIG_QETH_PERF_STATS
-               if (skb_shinfo(skb)->tso_size &&
+               if (tso_size &&
                   !(large_send == QETH_LARGE_SEND_NO)) {
-                       card->perf_stats.large_send_bytes += skb->len;
+                       card->perf_stats.large_send_bytes += tx_bytes;
                        card->perf_stats.large_send_cnt++;
                }
-               if (skb_shinfo(skb)->nr_frags > 0){
+               if (nr_frags > 0){
                        card->perf_stats.sg_skbs_sent++;
                        /* nr_frags + skb->data */
                        card->perf_stats.sg_frags_sent +=
-                               skb_shinfo(skb)->nr_frags + 1;
+                               nr_frags + 1;
                }
 #endif /* CONFIG_QETH_PERF_STATS */
        }
@@ -4819,9 +4815,8 @@ qeth_arp_query(struct qeth_card *card, char *udata)
        /* get size of userspace buffer and mask_bits -> 6 bytes */
        if (copy_from_user(&qinfo, udata, 6))
                return -EFAULT;
-       if (!(qinfo.udata = kmalloc(qinfo.udata_len, GFP_KERNEL)))
+       if (!(qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL)))
                return -ENOMEM;
-       memset(qinfo.udata, 0, qinfo.udata_len);
        qinfo.udata_offset = QETH_QARP_ENTRIES_OFFSET;
        iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
                                       IPA_CMD_ASS_ARP_QUERY_INFO,
@@ -4969,11 +4964,10 @@ qeth_snmp_command(struct qeth_card *card, char *udata)
                return -EFAULT;
        }
        qinfo.udata_len = ureq->hdr.data_len;
-       if (!(qinfo.udata = kmalloc(qinfo.udata_len, GFP_KERNEL))){
+       if (!(qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL))){
                kfree(ureq);
                return -ENOMEM;
        }
-       memset(qinfo.udata, 0, qinfo.udata_len);
        qinfo.udata_offset = sizeof(struct qeth_snmp_ureq_hdr);
 
        iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL,
@@ -5380,7 +5374,7 @@ qeth_layer2_send_setdelvlan_cb(struct qeth_card *card,
         cmd = (struct qeth_ipa_cmd *) data;
         if (cmd->hdr.return_code) {
                PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "
-                         "Continuing\n",cmd->data.setdelvlan.vlan_id, 
+                         "Continuing\n",cmd->data.setdelvlan.vlan_id,
                          QETH_CARD_IFNAME(card), cmd->hdr.return_code);
                QETH_DBF_TEXT_(trace, 2, "L2VL%4x", cmd->hdr.command);
                QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));
@@ -5400,7 +5394,7 @@ qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i,
        iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
        cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
         cmd->data.setdelvlan.vlan_id = i;
-       return qeth_send_ipa_cmd(card, iob, 
+       return qeth_send_ipa_cmd(card, iob,
                                 qeth_layer2_send_setdelvlan_cb, NULL);
 }
 
@@ -5464,7 +5458,7 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
  * Examine hardware response to SET_PROMISC_MODE
  */
 static int
-qeth_setadp_promisc_mode_cb(struct qeth_card *card, 
+qeth_setadp_promisc_mode_cb(struct qeth_card *card,
                            struct qeth_reply *reply,
                            unsigned long data)
 {
@@ -5475,10 +5469,10 @@ qeth_setadp_promisc_mode_cb(struct qeth_card *card,
 
        cmd = (struct qeth_ipa_cmd *) data;
        setparms = &(cmd->data.setadapterparms);
-       
+
         qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
-       if (cmd->hdr.return_code) { 
-               QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code);      
+       if (cmd->hdr.return_code) {
+               QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code);
                setparms->data.mode = SET_PROMISC_MODE_OFF;
        }
        card->info.promisc_mode = setparms->data.mode;
@@ -5524,7 +5518,7 @@ qeth_set_multicast_list(struct net_device *dev)
 
        if (card->info.type == QETH_CARD_TYPE_OSN)
                return ;
-        
+
        QETH_DBF_TEXT(trace, 3, "setmulti");
        qeth_delete_mc_addresses(card);
        if (card->options.layer2) {
@@ -5564,12 +5558,11 @@ qeth_get_addr_buffer(enum qeth_prot_versions prot)
 {
        struct qeth_ipaddr *addr;
 
-       addr = kmalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC);
+       addr = kzalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC);
        if (addr == NULL) {
                PRINT_WARN("Not enough memory to add address\n");
                return NULL;
        }
-       memset(addr,0,sizeof(struct qeth_ipaddr));
        addr->type = QETH_IP_TYPE_NORMAL;
        addr->proto = prot;
        return addr;
@@ -5583,7 +5576,7 @@ qeth_osn_assist(struct net_device *dev,
        struct qeth_cmd_buffer *iob;
        struct qeth_card *card;
        int rc;
-       
+
        QETH_DBF_TEXT(trace, 2, "osnsdmc");
        if (!dev)
                return -ENODEV;
@@ -5662,7 +5655,7 @@ qeth_osn_deregister(struct net_device * dev)
        card->osn_info.data_cb = NULL;
        return;
 }
-                                          
+
 static void
 qeth_delete_mc_addresses(struct qeth_card *card)
 {
@@ -5826,7 +5819,7 @@ qeth_add_multicast_ipv6(struct qeth_card *card)
        struct inet6_dev *in6_dev;
 
        QETH_DBF_TEXT(trace,4,"chkmcv6");
-       if (!qeth_is_supported(card, IPA_IPV6)) 
+       if (!qeth_is_supported(card, IPA_IPV6))
                return ;
        in6_dev = in6_dev_get(card->dev);
        if (in6_dev == NULL)
@@ -6367,12 +6360,9 @@ qeth_netdev_init(struct net_device *dev)
        dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid;
        dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid;
 #endif
-       dev->hard_header = card->orig_hard_header;
        if (qeth_get_netdev_flags(card) & IFF_NOARP) {
                dev->rebuild_header = NULL;
                dev->hard_header = NULL;
-               if (card->options.fake_ll)
-                       dev->hard_header = qeth_fake_header;
                dev->header_cache_update = NULL;
                dev->hard_header_cache = NULL;
        }
@@ -6381,6 +6371,9 @@ qeth_netdev_init(struct net_device *dev)
        if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
                card->dev->dev_id = card->info.unique_id & 0xffff;
 #endif
+       if (card->options.fake_ll &&
+               (qeth_get_netdev_flags(card) & IFF_NOARP))
+                       dev->hard_header = qeth_fake_header;
        dev->hard_header_parse = NULL;
        dev->set_mac_address = qeth_layer2_set_mac_address;
        dev->flags |= qeth_get_netdev_flags(card);
@@ -6485,6 +6478,9 @@ retry:
        /*network device will be recovered*/
        if (card->dev) {
                card->dev->hard_header = card->orig_hard_header;
+               if (card->options.fake_ll &&
+                   (qeth_get_netdev_flags(card) & IFF_NOARP))
+                       card->dev->hard_header = qeth_fake_header;
                return 0;
        }
        /* at first set_online allocate netdev */
@@ -6592,7 +6588,7 @@ qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
 
        cmd = (struct qeth_ipa_cmd *) data;
        if (!card->options.layer2 || card->info.guestlan ||
-           !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {    
+           !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
                memcpy(card->dev->dev_addr,
                       &cmd->data.setadapterparms.data.change_addr.addr,
                       OSA_ADDR_LEN);
@@ -7039,14 +7035,12 @@ qeth_softsetup_ipv6(struct qeth_card *card)
 
        QETH_DBF_TEXT(trace,3,"softipv6");
 
-       netif_stop_queue(card->dev);
        rc = qeth_send_startlan(card, QETH_PROT_IPV6);
        if (rc) {
                PRINT_ERR("IPv6 startlan failed on %s\n",
                          QETH_CARD_IFNAME(card));
                return rc;
        }
-       netif_wake_queue(card->dev);
        rc = qeth_query_ipassists(card,QETH_PROT_IPV6);
        if (rc) {
                PRINT_ERR("IPv6 query ipassist failed on %s\n",
@@ -7360,7 +7354,8 @@ qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type)
                card->options.large_send = type;
                return 0;
        }
-       netif_stop_queue(card->dev);
+       if (card->state == CARD_STATE_UP)
+               netif_tx_disable(card->dev);
        card->options.large_send = type;
        switch (card->options.large_send) {
        case QETH_LARGE_SEND_EDDP:
@@ -7382,7 +7377,8 @@ qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type)
                card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
                break;
        }
-       netif_wake_queue(card->dev);
+       if (card->state == CARD_STATE_UP)
+               netif_wake_queue(card->dev);
        return rc;
 }
 
@@ -7435,7 +7431,7 @@ qeth_softsetup_card(struct qeth_card *card)
        if ((rc = qeth_setrouting_v6(card)))
                QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
 out:
-       netif_stop_queue(card->dev);
+       netif_tx_disable(card->dev);
        return 0;
 }
 
@@ -7575,7 +7571,7 @@ qeth_stop_card(struct qeth_card *card, int recovery_mode)
        if (card->read.state == CH_STATE_UP &&
            card->write.state == CH_STATE_UP &&
            (card->state == CARD_STATE_UP)) {
-               if (recovery_mode && 
+               if (recovery_mode &&
                    card->info.type != QETH_CARD_TYPE_OSN) {
                        qeth_stop(card->dev);
                } else {
@@ -7744,10 +7740,8 @@ static int
 qeth_register_netdev(struct qeth_card *card)
 {
        QETH_DBF_TEXT(setup, 3, "regnetd");
-       if (card->dev->reg_state != NETREG_UNINITIALIZED) {
-               qeth_netdev_init(card->dev);
+       if (card->dev->reg_state != NETREG_UNINITIALIZED)
                return 0;
-       }
        /* sysfs magic */
        SET_NETDEV_DEV(card->dev, &card->gdev->dev);
        return register_netdev(card->dev);
@@ -7758,7 +7752,7 @@ qeth_start_again(struct qeth_card *card, int recovery_mode)
 {
        QETH_DBF_TEXT(setup ,2, "startag");
 
-       if (recovery_mode && 
+       if (recovery_mode &&
            card->info.type != QETH_CARD_TYPE_OSN) {
                qeth_open(card->dev);
        } else {
@@ -8022,7 +8016,6 @@ static int (*qeth_old_arp_constructor) (struct neighbour *);
 
 static struct neigh_ops arp_direct_ops_template = {
        .family = AF_INET,
-       .destructor = NULL,
        .solicit = NULL,
        .error_report = NULL,
        .output = dev_queue_xmit,