linux/drivers/staging/gdm72xx/gdm_wimax.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
   3 *
   4 * This software is licensed under the terms of the GNU General Public
   5 * License version 2, as published by the Free Software Foundation, and
   6 * may be copied, distributed, and modified under those terms.
   7 *
   8 * This program is distributed in the hope that it will be useful,
   9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11 * GNU General Public License for more details.
  12 */
  13
  14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  15
  16#include <linux/etherdevice.h>
  17#include <asm/byteorder.h>
  18#include <linux/ip.h>
  19#include <linux/ipv6.h>
  20#include <linux/udp.h>
  21#include <linux/in.h>
  22
  23#include "gdm_wimax.h"
  24#include "hci.h"
  25#include "wm_ioctl.h"
  26#include "netlink_k.h"
  27
  28#define gdm_wimax_send(n, d, l) \
  29        (n->phy_dev->send_func)(n->phy_dev->priv_dev, d, l, NULL, NULL)
  30#define gdm_wimax_send_with_cb(n, d, l, c, b)   \
  31        (n->phy_dev->send_func)(n->phy_dev->priv_dev, d, l, c, b)
  32#define gdm_wimax_rcv_with_cb(n, c, b)  \
  33        (n->phy_dev->rcv_func)(n->phy_dev->priv_dev, c, b)
  34
  35#define EVT_MAX_SIZE    2048
  36
  37struct evt_entry {
  38        struct list_head list;
  39        struct net_device *dev;
  40        char evt_data[EVT_MAX_SIZE];
  41        int      size;
  42};
  43
  44static void __gdm_wimax_event_send(struct work_struct *work);
  45static inline struct evt_entry *alloc_event_entry(void);
  46static inline void free_event_entry(struct evt_entry *e);
  47static struct evt_entry *get_event_entry(void);
  48static void put_event_entry(struct evt_entry *e);
  49
  50static struct {
  51        int ref_cnt;
  52        struct sock *sock;
  53        struct list_head evtq;
  54        spinlock_t evt_lock;
  55
  56        struct list_head freeq;
  57        struct work_struct ws;
  58} wm_event;
  59
  60static u8 gdm_wimax_macaddr[6] = {0x00, 0x0a, 0x3b, 0xf0, 0x01, 0x30};
  61
  62static void gdm_wimax_ind_fsm_update(struct net_device *dev, struct fsm_s *fsm);
  63static void gdm_wimax_ind_if_updown(struct net_device *dev, int if_up);
  64
  65#if defined(DEBUG_SDU)
  66static void printk_hex(u8 *buf, u32 size)
  67{
  68        int i;
  69
  70        for (i = 0; i < size; i++) {
  71                if (i && i % 16 == 0)
  72                        printk(KERN_DEBUG "\n%02x ", *buf++);
  73                else
  74                        printk(KERN_DEBUG "%02x ", *buf++);
  75        }
  76
  77        printk(KERN_DEBUG "\n");
  78}
  79
  80static const char *get_protocol_name(u16 protocol)
  81{
  82        static char buf[32];
  83        const char *name = "-";
  84
  85        switch (protocol) {
  86        case ETH_P_ARP:
  87                name = "ARP";
  88                break;
  89        case ETH_P_IP:
  90                name = "IP";
  91                break;
  92        case ETH_P_IPV6:
  93                name = "IPv6";
  94                break;
  95        }
  96
  97        sprintf(buf, "0x%04x(%s)", protocol, name);
  98        return buf;
  99}
 100
 101static const char *get_ip_protocol_name(u8 ip_protocol)
 102{
 103        static char buf[32];
 104        const char *name = "-";
 105
 106        switch (ip_protocol) {
 107        case IPPROTO_TCP:
 108                name = "TCP";
 109                break;
 110        case IPPROTO_UDP:
 111                name = "UDP";
 112                break;
 113        case IPPROTO_ICMP:
 114                name = "ICMP";
 115                break;
 116        }
 117
 118        sprintf(buf, "%u(%s)", ip_protocol, name);
 119        return buf;
 120}
 121
 122static const char *get_port_name(u16 port)
 123{
 124        static char buf[32];
 125        const char *name = "-";
 126
 127        switch (port) {
 128        case 67:
 129                name = "DHCP-Server";
 130                break;
 131        case 68:
 132                name = "DHCP-Client";
 133                break;
 134        case 69:
 135                name = "TFTP";
 136                break;
 137        }
 138
 139        sprintf(buf, "%u(%s)", port, name);
 140        return buf;
 141}
 142
 143static void dump_eth_packet(const char *title, u8 *data, int len)
 144{
 145        struct iphdr *ih = NULL;
 146        struct udphdr *uh = NULL;
 147        u16 protocol = 0;
 148        u8 ip_protocol = 0;
 149        u16 port = 0;
 150
 151        protocol = (data[12]<<8) | data[13];
 152        ih = (struct iphdr *) (data+ETH_HLEN);
 153
 154        if (protocol == ETH_P_IP) {
 155                uh = (struct udphdr *) ((char *)ih + sizeof(struct iphdr));
 156                ip_protocol = ih->protocol;
 157                port = ntohs(uh->dest);
 158        } else if (protocol == ETH_P_IPV6) {
 159                struct ipv6hdr *i6h = (struct ipv6hdr *) data;
 160                uh = (struct udphdr *) ((char *)i6h + sizeof(struct ipv6hdr));
 161                ip_protocol = i6h->nexthdr;
 162                port = ntohs(uh->dest);
 163        }
 164
 165        printk(KERN_DEBUG "[%s] len=%d, %s, %s, %s\n",
 166                title, len,
 167                get_protocol_name(protocol),
 168                get_ip_protocol_name(ip_protocol),
 169                get_port_name(port));
 170
 171        if (!(data[0] == 0xff && data[1] == 0xff)) {
 172                if (protocol == ETH_P_IP) {
 173                        printk(KERN_DEBUG "     src=%pI4\n", &ih->saddr);
 174                } else if (protocol == ETH_P_IPV6) {
 175                        printk(KERN_DEBUG "     src=%pI6\n", &ih->saddr);
 176                }
 177        }
 178
 179        #if (DUMP_PACKET & DUMP_SDU_ALL)
 180        printk_hex(data, len);
 181        #else
 182                #if (DUMP_PACKET & DUMP_SDU_ARP)
 183                if (protocol == ETH_P_ARP)
 184                        printk_hex(data, len);
 185                #endif
 186                #if (DUMP_PACKET & DUMP_SDU_IP)
 187                if (protocol == ETH_P_IP || protocol == ETH_P_IPV6)
 188                        printk_hex(data, len);
 189                #else
 190                        #if (DUMP_PACKET & DUMP_SDU_IP_TCP)
 191                        if (ip_protocol == IPPROTO_TCP)
 192                                printk_hex(data, len);
 193                        #endif
 194                        #if (DUMP_PACKET & DUMP_SDU_IP_UDP)
 195                        if (ip_protocol == IPPROTO_UDP)
 196                                printk_hex(data, len);
 197                        #endif
 198                        #if (DUMP_PACKET & DUMP_SDU_IP_ICMP)
 199                        if (ip_protocol == IPPROTO_ICMP)
 200                                printk_hex(data, len);
 201                        #endif
 202                #endif
 203        #endif
 204}
 205#endif
 206
 207
 208static inline int gdm_wimax_header(struct sk_buff **pskb)
 209{
 210        u16 buf[HCI_HEADER_SIZE / sizeof(u16)];
 211        struct sk_buff *skb = *pskb;
 212        int ret = 0;
 213
 214        if (unlikely(skb_headroom(skb) < HCI_HEADER_SIZE)) {
 215                struct sk_buff *skb2;
 216
 217                skb2 = skb_realloc_headroom(skb, HCI_HEADER_SIZE);
 218                if (skb2 == NULL)
 219                        return -ENOMEM;
 220                if (skb->sk)
 221                        skb_set_owner_w(skb2, skb->sk);
 222                kfree_skb(skb);
 223                skb = skb2;
 224        }
 225
 226        skb_push(skb, HCI_HEADER_SIZE);
 227        buf[0] = H2B(WIMAX_TX_SDU);
 228        buf[1] = H2B(skb->len - HCI_HEADER_SIZE);
 229        memcpy(skb->data, buf, HCI_HEADER_SIZE);
 230
 231        *pskb = skb;
 232        return ret;
 233}
 234
 235static void gdm_wimax_event_rcv(struct net_device *dev, u16 type, void *msg,
 236                                int len)
 237{
 238        struct nic *nic = netdev_priv(dev);
 239
 240        #if defined(DEBUG_HCI)
 241        u8 *buf = (u8 *) msg;
 242        u16 hci_cmd =  (buf[0]<<8) | buf[1];
 243        u16 hci_len = (buf[2]<<8) | buf[3];
 244        printk(KERN_DEBUG "H=>D: 0x%04x(%d)\n", hci_cmd, hci_len);
 245        #endif
 246
 247        gdm_wimax_send(nic, msg, len);
 248}
 249
 250static int gdm_wimax_event_init(void)
 251{
 252        if (!wm_event.ref_cnt) {
 253                wm_event.sock = netlink_init(NETLINK_WIMAX,
 254                                                gdm_wimax_event_rcv);
 255                if (wm_event.sock) {
 256                        INIT_LIST_HEAD(&wm_event.evtq);
 257                        INIT_LIST_HEAD(&wm_event.freeq);
 258                        INIT_WORK(&wm_event.ws, __gdm_wimax_event_send);
 259                        spin_lock_init(&wm_event.evt_lock);
 260                }
 261        }
 262
 263        if (wm_event.sock) {
 264                wm_event.ref_cnt++;
 265                return 0;
 266        }
 267
 268        pr_err("Creating WiMax Event netlink is failed\n");
 269        return -1;
 270}
 271
 272static void gdm_wimax_event_exit(void)
 273{
 274        if (wm_event.sock && --wm_event.ref_cnt == 0) {
 275                struct evt_entry *e, *temp;
 276                unsigned long flags;
 277
 278                spin_lock_irqsave(&wm_event.evt_lock, flags);
 279
 280                list_for_each_entry_safe(e, temp, &wm_event.evtq, list) {
 281                        list_del(&e->list);
 282                        free_event_entry(e);
 283                }
 284                list_for_each_entry_safe(e, temp, &wm_event.freeq, list) {
 285                        list_del(&e->list);
 286                        free_event_entry(e);
 287                }
 288
 289                spin_unlock_irqrestore(&wm_event.evt_lock, flags);
 290                netlink_exit(wm_event.sock);
 291                wm_event.sock = NULL;
 292        }
 293}
 294
 295static inline struct evt_entry *alloc_event_entry(void)
 296{
 297        return kmalloc(sizeof(struct evt_entry), GFP_ATOMIC);
 298}
 299
 300static inline void free_event_entry(struct evt_entry *e)
 301{
 302        kfree(e);
 303}
 304
 305static struct evt_entry *get_event_entry(void)
 306{
 307        struct evt_entry *e;
 308
 309        if (list_empty(&wm_event.freeq))
 310                e = alloc_event_entry();
 311        else {
 312                e = list_entry(wm_event.freeq.next, struct evt_entry, list);
 313                list_del(&e->list);
 314        }
 315
 316        return e;
 317}
 318
 319static void put_event_entry(struct evt_entry *e)
 320{
 321        BUG_ON(!e);
 322
 323        list_add_tail(&e->list, &wm_event.freeq);
 324}
 325
 326static void __gdm_wimax_event_send(struct work_struct *work)
 327{
 328        int idx;
 329        unsigned long flags;
 330        struct evt_entry *e;
 331
 332        spin_lock_irqsave(&wm_event.evt_lock, flags);
 333
 334        while (!list_empty(&wm_event.evtq)) {
 335                e = list_entry(wm_event.evtq.next, struct evt_entry, list);
 336                spin_unlock_irqrestore(&wm_event.evt_lock, flags);
 337
 338                sscanf(e->dev->name, "wm%d", &idx);
 339                netlink_send(wm_event.sock, idx, 0, e->evt_data, e->size);
 340
 341                spin_lock_irqsave(&wm_event.evt_lock, flags);
 342                list_del(&e->list);
 343                put_event_entry(e);
 344        }
 345
 346        spin_unlock_irqrestore(&wm_event.evt_lock, flags);
 347}
 348
 349static int gdm_wimax_event_send(struct net_device *dev, char *buf, int size)
 350{
 351        struct evt_entry *e;
 352        unsigned long flags;
 353
 354        #if defined(DEBUG_HCI)
 355        u16 hci_cmd =  ((u8)buf[0]<<8) | (u8)buf[1];
 356        u16 hci_len = ((u8)buf[2]<<8) | (u8)buf[3];
 357        printk(KERN_DEBUG "D=>H: 0x%04x(%d)\n", hci_cmd, hci_len);
 358        #endif
 359
 360        spin_lock_irqsave(&wm_event.evt_lock, flags);
 361
 362        e = get_event_entry();
 363        if (!e) {
 364                netdev_err(dev, "%s: No memory for event\n", __func__);
 365                spin_unlock_irqrestore(&wm_event.evt_lock, flags);
 366                return -ENOMEM;
 367        }
 368
 369        e->dev = dev;
 370        e->size = size;
 371        memcpy(e->evt_data, buf, size);
 372
 373        list_add_tail(&e->list, &wm_event.evtq);
 374        spin_unlock_irqrestore(&wm_event.evt_lock, flags);
 375
 376        schedule_work(&wm_event.ws);
 377
 378        return 0;
 379}
 380
 381static void tx_complete(void *arg)
 382{
 383        struct nic *nic = arg;
 384
 385        if (netif_queue_stopped(nic->netdev))
 386                netif_wake_queue(nic->netdev);
 387}
 388
 389int gdm_wimax_send_tx(struct sk_buff *skb, struct net_device *dev)
 390{
 391        int ret = 0;
 392        struct nic *nic = netdev_priv(dev);
 393
 394        ret = gdm_wimax_send_with_cb(nic, skb->data, skb->len, tx_complete,
 395                                        nic);
 396        if (ret == -ENOSPC) {
 397                netif_stop_queue(dev);
 398                ret = 0;
 399        }
 400
 401        if (ret) {
 402                skb_pull(skb, HCI_HEADER_SIZE);
 403                return ret;
 404        }
 405
 406        nic->stats.tx_packets++;
 407        nic->stats.tx_bytes += skb->len - HCI_HEADER_SIZE;
 408        kfree_skb(skb);
 409        return ret;
 410}
 411
 412static int gdm_wimax_tx(struct sk_buff *skb, struct net_device *dev)
 413{
 414        int ret = 0;
 415        struct nic *nic = netdev_priv(dev);
 416        struct fsm_s *fsm = (struct fsm_s *) nic->sdk_data[SIOC_DATA_FSM].buf;
 417
 418        #if defined(DEBUG_SDU)
 419        dump_eth_packet("TX", skb->data, skb->len);
 420        #endif
 421
 422        ret = gdm_wimax_header(&skb);
 423        if (ret < 0) {
 424                skb_pull(skb, HCI_HEADER_SIZE);
 425                return ret;
 426        }
 427
 428        #if !defined(LOOPBACK_TEST)
 429        if (!fsm)
 430                netdev_err(dev, "ASSERTION ERROR: fsm is NULL!!\n");
 431        else if (fsm->m_status != M_CONNECTED) {
 432                netdev_emerg(dev, "ASSERTION ERROR: Device is NOT ready. status=%d\n",
 433                             fsm->m_status);
 434                kfree_skb(skb);
 435                return 0;
 436        }
 437        #endif
 438
 439#if defined(CONFIG_WIMAX_GDM72XX_QOS)
 440        ret = gdm_qos_send_hci_pkt(skb, dev);
 441#else
 442        ret = gdm_wimax_send_tx(skb, dev);
 443#endif
 444        return ret;
 445}
 446
 447static int gdm_wimax_set_config(struct net_device *dev, struct ifmap *map)
 448{
 449        if (dev->flags & IFF_UP)
 450                return -EBUSY;
 451
 452        return 0;
 453}
 454
 455static void __gdm_wimax_set_mac_addr(struct net_device *dev, char *mac_addr)
 456{
 457        u16 hci_pkt_buf[32 / sizeof(u16)];
 458        u8 *pkt = (u8 *) &hci_pkt_buf[0];
 459        struct nic *nic = netdev_priv(dev);
 460
 461        /* Since dev is registered as a ethernet device,
 462         * ether_setup has made dev->addr_len to be ETH_ALEN
 463         */
 464        memcpy(dev->dev_addr, mac_addr, dev->addr_len);
 465
 466        /* Let lower layer know of this change by sending
 467         * SetInformation(MAC Address)
 468         */
 469        hci_pkt_buf[0] = H2B(WIMAX_SET_INFO);   /* cmd_evt */
 470        hci_pkt_buf[1] = H2B(8);                        /* size */
 471        pkt[4] = 0; /* T */
 472        pkt[5] = 6; /* L */
 473        memcpy(pkt + 6, mac_addr, dev->addr_len); /* V */
 474
 475        gdm_wimax_send(nic, pkt, HCI_HEADER_SIZE + 8);
 476}
 477
 478/* A driver function */
 479static int gdm_wimax_set_mac_addr(struct net_device *dev, void *p)
 480{
 481        struct sockaddr *addr = p;
 482
 483        if (netif_running(dev))
 484                return -EBUSY;
 485
 486        if (!is_valid_ether_addr(addr->sa_data))
 487                return -EADDRNOTAVAIL;
 488
 489        __gdm_wimax_set_mac_addr(dev, addr->sa_data);
 490
 491        return 0;
 492}
 493
 494static struct net_device_stats *gdm_wimax_stats(struct net_device *dev)
 495{
 496        struct nic *nic = netdev_priv(dev);
 497
 498        return &nic->stats;
 499}
 500
 501static int gdm_wimax_open(struct net_device *dev)
 502{
 503        struct nic *nic = netdev_priv(dev);
 504        struct fsm_s *fsm = (struct fsm_s *) nic->sdk_data[SIOC_DATA_FSM].buf;
 505
 506        netif_start_queue(dev);
 507
 508        if (fsm && fsm->m_status != M_INIT)
 509                gdm_wimax_ind_if_updown(dev, 1);
 510        return 0;
 511}
 512
 513static int gdm_wimax_close(struct net_device *dev)
 514{
 515        struct nic *nic = netdev_priv(dev);
 516        struct fsm_s *fsm = (struct fsm_s *) nic->sdk_data[SIOC_DATA_FSM].buf;
 517
 518        netif_stop_queue(dev);
 519
 520        if (fsm && fsm->m_status != M_INIT)
 521                gdm_wimax_ind_if_updown(dev, 0);
 522        return 0;
 523}
 524
 525static void kdelete(void **buf)
 526{
 527        if (buf && *buf) {
 528                kfree(*buf);
 529                *buf = NULL;
 530        }
 531}
 532
 533static int gdm_wimax_ioctl_get_data(struct data_s *dst, struct data_s *src)
 534{
 535        int size;
 536
 537        size = dst->size < src->size ? dst->size : src->size;
 538
 539        dst->size = size;
 540        if (src->size) {
 541                if (!dst->buf)
 542                        return -EINVAL;
 543                if (copy_to_user(dst->buf, src->buf, size))
 544                        return -EFAULT;
 545        }
 546        return 0;
 547}
 548
 549static int gdm_wimax_ioctl_set_data(struct data_s *dst, struct data_s *src)
 550{
 551        if (!src->size) {
 552                dst->size = 0;
 553                return 0;
 554        }
 555
 556        if (!src->buf)
 557                return -EINVAL;
 558
 559        if (!(dst->buf && dst->size == src->size)) {
 560                kdelete(&dst->buf);
 561                dst->buf = kmalloc(src->size, GFP_KERNEL);
 562                if (dst->buf == NULL)
 563                        return -ENOMEM;
 564        }
 565
 566        if (copy_from_user(dst->buf, src->buf, src->size)) {
 567                kdelete(&dst->buf);
 568                return -EFAULT;
 569        }
 570        dst->size = src->size;
 571        return 0;
 572}
 573
 574static void gdm_wimax_cleanup_ioctl(struct net_device *dev)
 575{
 576        struct nic *nic = netdev_priv(dev);
 577        int i;
 578
 579        for (i = 0; i < SIOC_DATA_MAX; i++)
 580                kdelete(&nic->sdk_data[i].buf);
 581}
 582
 583static void gdm_update_fsm(struct net_device *dev, struct fsm_s *new_fsm)
 584{
 585        struct nic *nic = netdev_priv(dev);
 586        struct fsm_s *cur_fsm =
 587                (struct fsm_s *) nic->sdk_data[SIOC_DATA_FSM].buf;
 588
 589        if (!cur_fsm)
 590                return;
 591
 592        if (cur_fsm->m_status != new_fsm->m_status ||
 593                cur_fsm->c_status != new_fsm->c_status) {
 594                if (new_fsm->m_status == M_CONNECTED)
 595                        netif_carrier_on(dev);
 596                else if (cur_fsm->m_status == M_CONNECTED) {
 597                        netif_carrier_off(dev);
 598                        #if defined(CONFIG_WIMAX_GDM72XX_QOS)
 599                        gdm_qos_release_list(nic);
 600                        #endif
 601                }
 602                gdm_wimax_ind_fsm_update(dev, new_fsm);
 603        }
 604}
 605
 606static int gdm_wimax_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 607{
 608        struct wm_req_s *req = (struct wm_req_s *) ifr;
 609        struct nic *nic = netdev_priv(dev);
 610        int ret;
 611
 612        if (cmd != SIOCWMIOCTL)
 613                return -EOPNOTSUPP;
 614
 615        switch (req->cmd) {
 616        case SIOCG_DATA:
 617        case SIOCS_DATA:
 618                if (req->data_id >= SIOC_DATA_MAX) {
 619                        netdev_err(dev, "%s error: data-index(%d) is invalid!!\n",
 620                                   __func__, req->data_id);
 621                        return -EOPNOTSUPP;
 622                }
 623                if (req->cmd == SIOCG_DATA) {
 624                        ret = gdm_wimax_ioctl_get_data(&req->data,
 625                                                &nic->sdk_data[req->data_id]);
 626                        if (ret < 0)
 627                                return ret;
 628                } else if (req->cmd == SIOCS_DATA) {
 629                        if (req->data_id == SIOC_DATA_FSM) {
 630                                /*NOTE: gdm_update_fsm should be called
 631                                before gdm_wimax_ioctl_set_data is called*/
 632                                gdm_update_fsm(dev,
 633                                                (struct fsm_s *) req->data.buf);
 634                        }
 635                        ret = gdm_wimax_ioctl_set_data(
 636                                &nic->sdk_data[req->data_id], &req->data);
 637                        if (ret < 0)
 638                                return ret;
 639                }
 640                break;
 641        default:
 642                netdev_err(dev, "%s: %x unknown ioctl\n", __func__, cmd);
 643                return -EOPNOTSUPP;
 644        }
 645
 646        return 0;
 647}
 648
 649static void gdm_wimax_prepare_device(struct net_device *dev)
 650{
 651        struct nic *nic = netdev_priv(dev);
 652        u16 buf[32 / sizeof(u16)];
 653        struct hci_s *hci = (struct hci_s *) buf;
 654        u16 len = 0;
 655        u32 val = 0;
 656
 657        #define BIT_MULTI_CS    0
 658        #define BIT_WIMAX               1
 659        #define BIT_QOS                 2
 660        #define BIT_AGGREGATION 3
 661
 662        /* GetInformation mac address */
 663        len = 0;
 664        hci->cmd_evt = H2B(WIMAX_GET_INFO);
 665        hci->data[len++] = TLV_T(T_MAC_ADDRESS);
 666        hci->length = H2B(len);
 667        gdm_wimax_send(nic, hci, HCI_HEADER_SIZE+len);
 668
 669        val = (1<<BIT_WIMAX) | (1<<BIT_MULTI_CS);
 670        #if defined(CONFIG_WIMAX_GDM72XX_QOS)
 671        val |= (1<<BIT_QOS);
 672        #endif
 673        #if defined(CONFIG_WIMAX_GDM72XX_WIMAX2)
 674        val |= (1<<BIT_AGGREGATION);
 675        #endif
 676
 677        /* Set capability */
 678        len = 0;
 679        hci->cmd_evt = H2B(WIMAX_SET_INFO);
 680        hci->data[len++] = TLV_T(T_CAPABILITY);
 681        hci->data[len++] = TLV_L(T_CAPABILITY);
 682        val = DH2B(val);
 683        memcpy(&hci->data[len], &val, TLV_L(T_CAPABILITY));
 684        len += TLV_L(T_CAPABILITY);
 685        hci->length = H2B(len);
 686        gdm_wimax_send(nic, hci, HCI_HEADER_SIZE+len);
 687
 688        netdev_info(dev, "GDM WiMax Set CAPABILITY: 0x%08X\n", DB2H(val));
 689}
 690
 691static int gdm_wimax_hci_get_tlv(u8 *buf, u8 *T, u16 *L, u8 **V)
 692{
 693        #define __U82U16(b) ((u16)((u8 *)(b))[0] | ((u16)((u8 *)(b))[1] << 8))
 694        int next_pos;
 695
 696        *T = buf[0];
 697        if (buf[1] == 0x82) {
 698                *L = B2H(__U82U16(&buf[2]));
 699                next_pos = 1/*type*/+3/*len*/;
 700        } else {
 701                *L = buf[1];
 702                next_pos = 1/*type*/+1/*len*/;
 703        }
 704        *V = &buf[next_pos];
 705
 706        next_pos += *L/*length of val*/;
 707        return next_pos;
 708}
 709
 710static int gdm_wimax_get_prepared_info(struct net_device *dev, char *buf,
 711                                        int len)
 712{
 713        u8 T, *V;
 714        u16 L;
 715        u16 cmd_evt, cmd_len;
 716        int pos = HCI_HEADER_SIZE;
 717
 718        cmd_evt = B2H(*(u16 *)&buf[0]);
 719        cmd_len = B2H(*(u16 *)&buf[2]);
 720
 721        if (len < cmd_len + HCI_HEADER_SIZE) {
 722                netdev_err(dev, "%s: invalid length [%d/%d]\n", __func__,
 723                           cmd_len + HCI_HEADER_SIZE, len);
 724                return -1;
 725        }
 726
 727        if (cmd_evt == WIMAX_GET_INFO_RESULT) {
 728                if (cmd_len < 2) {
 729                        netdev_err(dev, "%s: len is too short [%x/%d]\n",
 730                                   __func__, cmd_evt, len);
 731                        return -1;
 732                }
 733
 734                pos += gdm_wimax_hci_get_tlv(&buf[pos], &T, &L, &V);
 735                if (T == TLV_T(T_MAC_ADDRESS)) {
 736                        if (L != dev->addr_len) {
 737                                netdev_err(dev,
 738                                           "%s Invalid inofrmation result T/L [%x/%d]\n",
 739                                           __func__, T, L);
 740                                return -1;
 741                        }
 742                        netdev_info(dev, "MAC change [%pM]->[%pM]\n",
 743                                    dev->dev_addr, V);
 744                        memcpy(dev->dev_addr, V, dev->addr_len);
 745                        return 1;
 746                }
 747        }
 748
 749        gdm_wimax_event_send(dev, buf, len);
 750        return 0;
 751}
 752
 753static void gdm_wimax_netif_rx(struct net_device *dev, char *buf, int len)
 754{
 755        struct nic *nic = netdev_priv(dev);
 756        struct sk_buff *skb;
 757        int ret;
 758
 759        #if defined(DEBUG_SDU)
 760        dump_eth_packet("RX", buf, len);
 761        #endif
 762
 763        skb = dev_alloc_skb(len + 2);
 764        if (!skb) {
 765                netdev_err(dev, "%s: dev_alloc_skb failed!\n", __func__);
 766                return;
 767        }
 768        skb_reserve(skb, 2);
 769
 770        nic->stats.rx_packets++;
 771        nic->stats.rx_bytes += len;
 772
 773        memcpy(skb_put(skb, len), buf, len);
 774
 775        skb->dev = dev;
 776        skb->protocol = eth_type_trans(skb, dev); /* what will happen? */
 777
 778        ret = in_interrupt() ? netif_rx(skb) : netif_rx_ni(skb);
 779        if (ret == NET_RX_DROP)
 780                netdev_err(dev, "%s skb dropped\n", __func__);
 781}
 782
 783static void gdm_wimax_transmit_aggr_pkt(struct net_device *dev, char *buf,
 784                                        int len)
 785{
 786        #define HCI_PADDING_BYTE        4
 787        #define HCI_RESERVED_BYTE       4
 788        struct hci_s *hci;
 789        int length;
 790
 791        while (len > 0) {
 792                hci = (struct hci_s *) buf;
 793
 794                if (B2H(hci->cmd_evt) != WIMAX_RX_SDU) {
 795                        netdev_err(dev, "Wrong cmd_evt(0x%04X)\n",
 796                                   B2H(hci->cmd_evt));
 797                        break;
 798                }
 799
 800                length = B2H(hci->length);
 801                gdm_wimax_netif_rx(dev, hci->data, length);
 802
 803                if (length & 0x3) {
 804                        /* Add padding size */
 805                        length += HCI_PADDING_BYTE - (length & 0x3);
 806                }
 807
 808                length += HCI_HEADER_SIZE + HCI_RESERVED_BYTE;
 809                len -= length;
 810                buf += length;
 811        }
 812}
 813
 814static void gdm_wimax_transmit_pkt(struct net_device *dev, char *buf, int len)
 815{
 816        #if defined(CONFIG_WIMAX_GDM72XX_QOS)
 817        struct nic *nic = netdev_priv(dev);
 818        #endif
 819        u16 cmd_evt, cmd_len;
 820
 821        /* This code is added for certain rx packet to be ignored. */
 822        if (len == 0)
 823                return;
 824
 825        cmd_evt = B2H(*(u16 *)&buf[0]);
 826        cmd_len = B2H(*(u16 *)&buf[2]);
 827
 828        if (len < cmd_len + HCI_HEADER_SIZE) {
 829                if (len)
 830                        netdev_err(dev, "%s: invalid length [%d/%d]\n",
 831                                   __func__, cmd_len + HCI_HEADER_SIZE, len);
 832                return;
 833        }
 834
 835        switch (cmd_evt) {
 836        case WIMAX_RX_SDU_AGGR:
 837                gdm_wimax_transmit_aggr_pkt(dev, &buf[HCI_HEADER_SIZE],
 838                                                cmd_len);
 839                break;
 840        case WIMAX_RX_SDU:
 841                gdm_wimax_netif_rx(dev, &buf[HCI_HEADER_SIZE], cmd_len);
 842                break;
 843        #if defined(CONFIG_WIMAX_GDM72XX_QOS)
 844        case WIMAX_EVT_MODEM_REPORT:
 845                gdm_recv_qos_hci_packet(nic, buf, len);
 846                break;
 847        #endif
 848        case WIMAX_SDU_TX_FLOW:
 849                if (buf[4] == 0) {
 850                        if (!netif_queue_stopped(dev))
 851                                netif_stop_queue(dev);
 852                } else if (buf[4] == 1) {
 853                        if (netif_queue_stopped(dev))
 854                                netif_wake_queue(dev);
 855                }
 856                break;
 857        default:
 858                gdm_wimax_event_send(dev, buf, len);
 859                break;
 860        }
 861}
 862
 863static void gdm_wimax_ind_fsm_update(struct net_device *dev, struct fsm_s *fsm)
 864{
 865        u16 buf[32 / sizeof(u16)];
 866        u8 *hci_pkt_buf = (u8 *)&buf[0];
 867
 868        /* Indicate updating fsm */
 869        buf[0] = H2B(WIMAX_FSM_UPDATE);
 870        buf[1] = H2B(sizeof(struct fsm_s));
 871        memcpy(&hci_pkt_buf[HCI_HEADER_SIZE], fsm, sizeof(struct fsm_s));
 872
 873        gdm_wimax_event_send(dev, hci_pkt_buf,
 874                                HCI_HEADER_SIZE + sizeof(struct fsm_s));
 875}
 876
 877static void gdm_wimax_ind_if_updown(struct net_device *dev, int if_up)
 878{
 879        u16 buf[32 / sizeof(u16)];
 880        struct hci_s *hci = (struct hci_s *) buf;
 881        unsigned char up_down;
 882
 883        up_down = if_up ? WIMAX_IF_UP : WIMAX_IF_DOWN;
 884
 885        /* Indicate updating fsm */
 886        hci->cmd_evt = H2B(WIMAX_IF_UPDOWN);
 887        hci->length = H2B(sizeof(up_down));
 888        hci->data[0] = up_down;
 889
 890        gdm_wimax_event_send(dev, (char *)hci, HCI_HEADER_SIZE+sizeof(up_down));
 891}
 892
 893static void rx_complete(void *arg, void *data, int len)
 894{
 895        struct nic *nic = arg;
 896
 897        gdm_wimax_transmit_pkt(nic->netdev, data, len);
 898        gdm_wimax_rcv_with_cb(nic, rx_complete, nic);
 899}
 900
 901static void prepare_rx_complete(void *arg, void *data, int len)
 902{
 903        struct nic *nic = arg;
 904        int ret;
 905
 906        ret = gdm_wimax_get_prepared_info(nic->netdev, data, len);
 907        if (ret == 1)
 908                gdm_wimax_rcv_with_cb(nic, rx_complete, nic);
 909        else {
 910                if (ret < 0)
 911                        netdev_err(nic->netdev,
 912                                   "get_prepared_info failed(%d)\n", ret);
 913                gdm_wimax_rcv_with_cb(nic, prepare_rx_complete, nic);
 914                #if 0
 915                /* Re-prepare WiMax device */
 916                gdm_wimax_prepare_device(nic->netdev);
 917                #endif
 918        }
 919}
 920
 921static void start_rx_proc(struct nic *nic)
 922{
 923        gdm_wimax_rcv_with_cb(nic, prepare_rx_complete, nic);
 924}
 925
 926static struct net_device_ops gdm_netdev_ops = {
 927        .ndo_open                               = gdm_wimax_open,
 928        .ndo_stop                               = gdm_wimax_close,
 929        .ndo_set_config                 = gdm_wimax_set_config,
 930        .ndo_start_xmit                 = gdm_wimax_tx,
 931        .ndo_get_stats                  = gdm_wimax_stats,
 932        .ndo_set_mac_address    = gdm_wimax_set_mac_addr,
 933        .ndo_do_ioctl                   = gdm_wimax_ioctl,
 934};
 935
 936int register_wimax_device(struct phy_dev *phy_dev, struct device *pdev)
 937{
 938        struct nic *nic = NULL;
 939        struct net_device *dev;
 940        int ret;
 941
 942        dev = (struct net_device *)alloc_netdev(sizeof(*nic),
 943                                                "wm%d", ether_setup);
 944
 945        if (dev == NULL) {
 946                pr_err("alloc_etherdev failed\n");
 947                return -ENOMEM;
 948        }
 949
 950        SET_NETDEV_DEV(dev, pdev);
 951        dev->mtu = 1400;
 952        dev->netdev_ops = &gdm_netdev_ops;
 953        dev->flags &= ~IFF_MULTICAST;
 954        memcpy(dev->dev_addr, gdm_wimax_macaddr, sizeof(gdm_wimax_macaddr));
 955
 956        nic = netdev_priv(dev);
 957        memset(nic, 0, sizeof(*nic));
 958
 959        nic->netdev = dev;
 960        nic->phy_dev = phy_dev;
 961        phy_dev->netdev = dev;
 962
 963        /* event socket init */
 964        ret = gdm_wimax_event_init();
 965        if (ret < 0) {
 966                pr_err("Cannot create event.\n");
 967                goto cleanup;
 968        }
 969
 970        ret = register_netdev(dev);
 971        if (ret)
 972                goto cleanup;
 973
 974        #if defined(LOOPBACK_TEST)
 975        netif_start_queue(dev);
 976        netif_carrier_on(dev);
 977        #else
 978        netif_carrier_off(dev);
 979        #endif
 980
 981#ifdef CONFIG_WIMAX_GDM72XX_QOS
 982        gdm_qos_init(nic);
 983#endif
 984
 985        start_rx_proc(nic);
 986
 987        /* Prepare WiMax device */
 988        gdm_wimax_prepare_device(dev);
 989
 990        return 0;
 991
 992cleanup:
 993        pr_err("register_netdev failed\n");
 994        free_netdev(dev);
 995        return ret;
 996}
 997
 998void unregister_wimax_device(struct phy_dev *phy_dev)
 999{
1000        struct nic *nic = netdev_priv(phy_dev->netdev);
1001        struct fsm_s *fsm = (struct fsm_s *) nic->sdk_data[SIOC_DATA_FSM].buf;
1002
1003        if (fsm)
1004                fsm->m_status = M_INIT;
1005        unregister_netdev(nic->netdev);
1006
1007        gdm_wimax_event_exit();
1008
1009#if defined(CONFIG_WIMAX_GDM72XX_QOS)
1010        gdm_qos_release_list(nic);
1011#endif
1012
1013        gdm_wimax_cleanup_ioctl(phy_dev->netdev);
1014
1015        free_netdev(nic->netdev);
1016}
1017