linux/drivers/net/hyperv/rndis_filter.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2009, Microsoft Corporation.
   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, see <http://www.gnu.org/licenses/>.
  15 *
  16 * Authors:
  17 *   Haiyang Zhang <haiyangz@microsoft.com>
  18 *   Hank Janssen  <hjanssen@microsoft.com>
  19 */
  20#include <linux/kernel.h>
  21#include <linux/sched.h>
  22#include <linux/wait.h>
  23#include <linux/highmem.h>
  24#include <linux/slab.h>
  25#include <linux/io.h>
  26#include <linux/if_ether.h>
  27#include <linux/netdevice.h>
  28#include <linux/if_vlan.h>
  29#include <linux/nls.h>
  30
  31#include "hyperv_net.h"
  32
  33
  34#define RNDIS_EXT_LEN PAGE_SIZE
  35struct rndis_request {
  36        struct list_head list_ent;
  37        struct completion  wait_event;
  38
  39        struct rndis_message response_msg;
  40        /*
  41         * The buffer for extended info after the RNDIS response message. It's
  42         * referenced based on the data offset in the RNDIS message. Its size
  43         * is enough for current needs, and should be sufficient for the near
  44         * future.
  45         */
  46        u8 response_ext[RNDIS_EXT_LEN];
  47
  48        /* Simplify allocation by having a netvsc packet inline */
  49        struct hv_netvsc_packet pkt;
  50        /* Set 2 pages for rndis requests crossing page boundary */
  51        struct hv_page_buffer buf[2];
  52
  53        struct rndis_message request_msg;
  54        /*
  55         * The buffer for the extended info after the RNDIS request message.
  56         * It is referenced and sized in a similar way as response_ext.
  57         */
  58        u8 request_ext[RNDIS_EXT_LEN];
  59};
  60
  61static struct rndis_device *get_rndis_device(void)
  62{
  63        struct rndis_device *device;
  64
  65        device = kzalloc(sizeof(struct rndis_device), GFP_KERNEL);
  66        if (!device)
  67                return NULL;
  68
  69        spin_lock_init(&device->request_lock);
  70
  71        INIT_LIST_HEAD(&device->req_list);
  72
  73        device->state = RNDIS_DEV_UNINITIALIZED;
  74
  75        return device;
  76}
  77
  78static struct rndis_request *get_rndis_request(struct rndis_device *dev,
  79                                             u32 msg_type,
  80                                             u32 msg_len)
  81{
  82        struct rndis_request *request;
  83        struct rndis_message *rndis_msg;
  84        struct rndis_set_request *set;
  85        unsigned long flags;
  86
  87        request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL);
  88        if (!request)
  89                return NULL;
  90
  91        init_completion(&request->wait_event);
  92
  93        rndis_msg = &request->request_msg;
  94        rndis_msg->ndis_msg_type = msg_type;
  95        rndis_msg->msg_len = msg_len;
  96
  97        request->pkt.q_idx = 0;
  98
  99        /*
 100         * Set the request id. This field is always after the rndis header for
 101         * request/response packet types so we just used the SetRequest as a
 102         * template
 103         */
 104        set = &rndis_msg->msg.set_req;
 105        set->req_id = atomic_inc_return(&dev->new_req_id);
 106
 107        /* Add to the request list */
 108        spin_lock_irqsave(&dev->request_lock, flags);
 109        list_add_tail(&request->list_ent, &dev->req_list);
 110        spin_unlock_irqrestore(&dev->request_lock, flags);
 111
 112        return request;
 113}
 114
 115static void put_rndis_request(struct rndis_device *dev,
 116                            struct rndis_request *req)
 117{
 118        unsigned long flags;
 119
 120        spin_lock_irqsave(&dev->request_lock, flags);
 121        list_del(&req->list_ent);
 122        spin_unlock_irqrestore(&dev->request_lock, flags);
 123
 124        kfree(req);
 125}
 126
 127static void dump_rndis_message(struct hv_device *hv_dev,
 128                        struct rndis_message *rndis_msg)
 129{
 130        struct net_device *netdev;
 131        struct netvsc_device *net_device;
 132
 133        net_device = hv_get_drvdata(hv_dev);
 134        netdev = net_device->ndev;
 135
 136        switch (rndis_msg->ndis_msg_type) {
 137        case RNDIS_MSG_PACKET:
 138                netdev_dbg(netdev, "RNDIS_MSG_PACKET (len %u, "
 139                           "data offset %u data len %u, # oob %u, "
 140                           "oob offset %u, oob len %u, pkt offset %u, "
 141                           "pkt len %u\n",
 142                           rndis_msg->msg_len,
 143                           rndis_msg->msg.pkt.data_offset,
 144                           rndis_msg->msg.pkt.data_len,
 145                           rndis_msg->msg.pkt.num_oob_data_elements,
 146                           rndis_msg->msg.pkt.oob_data_offset,
 147                           rndis_msg->msg.pkt.oob_data_len,
 148                           rndis_msg->msg.pkt.per_pkt_info_offset,
 149                           rndis_msg->msg.pkt.per_pkt_info_len);
 150                break;
 151
 152        case RNDIS_MSG_INIT_C:
 153                netdev_dbg(netdev, "RNDIS_MSG_INIT_C "
 154                        "(len %u, id 0x%x, status 0x%x, major %d, minor %d, "
 155                        "device flags %d, max xfer size 0x%x, max pkts %u, "
 156                        "pkt aligned %u)\n",
 157                        rndis_msg->msg_len,
 158                        rndis_msg->msg.init_complete.req_id,
 159                        rndis_msg->msg.init_complete.status,
 160                        rndis_msg->msg.init_complete.major_ver,
 161                        rndis_msg->msg.init_complete.minor_ver,
 162                        rndis_msg->msg.init_complete.dev_flags,
 163                        rndis_msg->msg.init_complete.max_xfer_size,
 164                        rndis_msg->msg.init_complete.
 165                           max_pkt_per_msg,
 166                        rndis_msg->msg.init_complete.
 167                           pkt_alignment_factor);
 168                break;
 169
 170        case RNDIS_MSG_QUERY_C:
 171                netdev_dbg(netdev, "RNDIS_MSG_QUERY_C "
 172                        "(len %u, id 0x%x, status 0x%x, buf len %u, "
 173                        "buf offset %u)\n",
 174                        rndis_msg->msg_len,
 175                        rndis_msg->msg.query_complete.req_id,
 176                        rndis_msg->msg.query_complete.status,
 177                        rndis_msg->msg.query_complete.
 178                           info_buflen,
 179                        rndis_msg->msg.query_complete.
 180                           info_buf_offset);
 181                break;
 182
 183        case RNDIS_MSG_SET_C:
 184                netdev_dbg(netdev,
 185                        "RNDIS_MSG_SET_C (len %u, id 0x%x, status 0x%x)\n",
 186                        rndis_msg->msg_len,
 187                        rndis_msg->msg.set_complete.req_id,
 188                        rndis_msg->msg.set_complete.status);
 189                break;
 190
 191        case RNDIS_MSG_INDICATE:
 192                netdev_dbg(netdev, "RNDIS_MSG_INDICATE "
 193                        "(len %u, status 0x%x, buf len %u, buf offset %u)\n",
 194                        rndis_msg->msg_len,
 195                        rndis_msg->msg.indicate_status.status,
 196                        rndis_msg->msg.indicate_status.status_buflen,
 197                        rndis_msg->msg.indicate_status.status_buf_offset);
 198                break;
 199
 200        default:
 201                netdev_dbg(netdev, "0x%x (len %u)\n",
 202                        rndis_msg->ndis_msg_type,
 203                        rndis_msg->msg_len);
 204                break;
 205        }
 206}
 207
 208static int rndis_filter_send_request(struct rndis_device *dev,
 209                                  struct rndis_request *req)
 210{
 211        int ret;
 212        struct hv_netvsc_packet *packet;
 213
 214        /* Setup the packet to send it */
 215        packet = &req->pkt;
 216
 217        packet->is_data_pkt = false;
 218        packet->total_data_buflen = req->request_msg.msg_len;
 219        packet->page_buf_cnt = 1;
 220
 221        packet->page_buf[0].pfn = virt_to_phys(&req->request_msg) >>
 222                                        PAGE_SHIFT;
 223        packet->page_buf[0].len = req->request_msg.msg_len;
 224        packet->page_buf[0].offset =
 225                (unsigned long)&req->request_msg & (PAGE_SIZE - 1);
 226
 227        /* Add one page_buf when request_msg crossing page boundary */
 228        if (packet->page_buf[0].offset + packet->page_buf[0].len > PAGE_SIZE) {
 229                packet->page_buf_cnt++;
 230                packet->page_buf[0].len = PAGE_SIZE -
 231                        packet->page_buf[0].offset;
 232                packet->page_buf[1].pfn = virt_to_phys((void *)&req->request_msg
 233                        + packet->page_buf[0].len) >> PAGE_SHIFT;
 234                packet->page_buf[1].offset = 0;
 235                packet->page_buf[1].len = req->request_msg.msg_len -
 236                        packet->page_buf[0].len;
 237        }
 238
 239        packet->send_completion = NULL;
 240
 241        ret = netvsc_send(dev->net_dev->dev, packet);
 242        return ret;
 243}
 244
 245static void rndis_set_link_state(struct rndis_device *rdev,
 246                                 struct rndis_request *request)
 247{
 248        u32 link_status;
 249        struct rndis_query_complete *query_complete;
 250
 251        query_complete = &request->response_msg.msg.query_complete;
 252
 253        if (query_complete->status == RNDIS_STATUS_SUCCESS &&
 254            query_complete->info_buflen == sizeof(u32)) {
 255                memcpy(&link_status, (void *)((unsigned long)query_complete +
 256                       query_complete->info_buf_offset), sizeof(u32));
 257                rdev->link_state = link_status != 0;
 258        }
 259}
 260
 261static void rndis_filter_receive_response(struct rndis_device *dev,
 262                                       struct rndis_message *resp)
 263{
 264        struct rndis_request *request = NULL;
 265        bool found = false;
 266        unsigned long flags;
 267        struct net_device *ndev;
 268
 269        ndev = dev->net_dev->ndev;
 270
 271        spin_lock_irqsave(&dev->request_lock, flags);
 272        list_for_each_entry(request, &dev->req_list, list_ent) {
 273                /*
 274                 * All request/response message contains RequestId as the 1st
 275                 * field
 276                 */
 277                if (request->request_msg.msg.init_req.req_id
 278                    == resp->msg.init_complete.req_id) {
 279                        found = true;
 280                        break;
 281                }
 282        }
 283        spin_unlock_irqrestore(&dev->request_lock, flags);
 284
 285        if (found) {
 286                if (resp->msg_len <=
 287                    sizeof(struct rndis_message) + RNDIS_EXT_LEN) {
 288                        memcpy(&request->response_msg, resp,
 289                               resp->msg_len);
 290                        if (request->request_msg.ndis_msg_type ==
 291                            RNDIS_MSG_QUERY && request->request_msg.msg.
 292                            query_req.oid == RNDIS_OID_GEN_MEDIA_CONNECT_STATUS)
 293                                rndis_set_link_state(dev, request);
 294                } else {
 295                        netdev_err(ndev,
 296                                "rndis response buffer overflow "
 297                                "detected (size %u max %zu)\n",
 298                                resp->msg_len,
 299                                sizeof(struct rndis_message));
 300
 301                        if (resp->ndis_msg_type ==
 302                            RNDIS_MSG_RESET_C) {
 303                                /* does not have a request id field */
 304                                request->response_msg.msg.reset_complete.
 305                                        status = RNDIS_STATUS_BUFFER_OVERFLOW;
 306                        } else {
 307                                request->response_msg.msg.
 308                                init_complete.status =
 309                                        RNDIS_STATUS_BUFFER_OVERFLOW;
 310                        }
 311                }
 312
 313                complete(&request->wait_event);
 314        } else {
 315                netdev_err(ndev,
 316                        "no rndis request found for this response "
 317                        "(id 0x%x res type 0x%x)\n",
 318                        resp->msg.init_complete.req_id,
 319                        resp->ndis_msg_type);
 320        }
 321}
 322
 323/*
 324 * Get the Per-Packet-Info with the specified type
 325 * return NULL if not found.
 326 */
 327static inline void *rndis_get_ppi(struct rndis_packet *rpkt, u32 type)
 328{
 329        struct rndis_per_packet_info *ppi;
 330        int len;
 331
 332        if (rpkt->per_pkt_info_offset == 0)
 333                return NULL;
 334
 335        ppi = (struct rndis_per_packet_info *)((ulong)rpkt +
 336                rpkt->per_pkt_info_offset);
 337        len = rpkt->per_pkt_info_len;
 338
 339        while (len > 0) {
 340                if (ppi->type == type)
 341                        return (void *)((ulong)ppi + ppi->ppi_offset);
 342                len -= ppi->size;
 343                ppi = (struct rndis_per_packet_info *)((ulong)ppi + ppi->size);
 344        }
 345
 346        return NULL;
 347}
 348
 349static void rndis_filter_receive_data(struct rndis_device *dev,
 350                                   struct rndis_message *msg,
 351                                   struct hv_netvsc_packet *pkt)
 352{
 353        struct rndis_packet *rndis_pkt;
 354        u32 data_offset;
 355        struct ndis_pkt_8021q_info *vlan;
 356        struct ndis_tcp_ip_checksum_info *csum_info;
 357
 358        rndis_pkt = &msg->msg.pkt;
 359
 360        /* Remove the rndis header and pass it back up the stack */
 361        data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset;
 362
 363        pkt->total_data_buflen -= data_offset;
 364
 365        /*
 366         * Make sure we got a valid RNDIS message, now total_data_buflen
 367         * should be the data packet size plus the trailer padding size
 368         */
 369        if (pkt->total_data_buflen < rndis_pkt->data_len) {
 370                netdev_err(dev->net_dev->ndev, "rndis message buffer "
 371                           "overflow detected (got %u, min %u)"
 372                           "...dropping this message!\n",
 373                           pkt->total_data_buflen, rndis_pkt->data_len);
 374                return;
 375        }
 376
 377        /*
 378         * Remove the rndis trailer padding from rndis packet message
 379         * rndis_pkt->data_len tell us the real data length, we only copy
 380         * the data packet to the stack, without the rndis trailer padding
 381         */
 382        pkt->total_data_buflen = rndis_pkt->data_len;
 383        pkt->data = (void *)((unsigned long)pkt->data + data_offset);
 384
 385        vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO);
 386        if (vlan) {
 387                pkt->vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid |
 388                        (vlan->pri << VLAN_PRIO_SHIFT);
 389        } else {
 390                pkt->vlan_tci = 0;
 391        }
 392
 393        csum_info = rndis_get_ppi(rndis_pkt, TCPIP_CHKSUM_PKTINFO);
 394        netvsc_recv_callback(dev->net_dev->dev, pkt, csum_info);
 395}
 396
 397int rndis_filter_receive(struct hv_device *dev,
 398                                struct hv_netvsc_packet *pkt)
 399{
 400        struct netvsc_device *net_dev = hv_get_drvdata(dev);
 401        struct rndis_device *rndis_dev;
 402        struct rndis_message *rndis_msg;
 403        struct net_device *ndev;
 404        int ret = 0;
 405
 406        if (!net_dev) {
 407                ret = -EINVAL;
 408                goto exit;
 409        }
 410
 411        ndev = net_dev->ndev;
 412
 413        /* Make sure the rndis device state is initialized */
 414        if (!net_dev->extension) {
 415                netdev_err(ndev, "got rndis message but no rndis device - "
 416                          "dropping this message!\n");
 417                ret = -ENODEV;
 418                goto exit;
 419        }
 420
 421        rndis_dev = (struct rndis_device *)net_dev->extension;
 422        if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) {
 423                netdev_err(ndev, "got rndis message but rndis device "
 424                           "uninitialized...dropping this message!\n");
 425                ret = -ENODEV;
 426                goto exit;
 427        }
 428
 429        rndis_msg = pkt->data;
 430
 431        dump_rndis_message(dev, rndis_msg);
 432
 433        switch (rndis_msg->ndis_msg_type) {
 434        case RNDIS_MSG_PACKET:
 435                /* data msg */
 436                rndis_filter_receive_data(rndis_dev, rndis_msg, pkt);
 437                break;
 438
 439        case RNDIS_MSG_INIT_C:
 440        case RNDIS_MSG_QUERY_C:
 441        case RNDIS_MSG_SET_C:
 442                /* completion msgs */
 443                rndis_filter_receive_response(rndis_dev, rndis_msg);
 444                break;
 445
 446        case RNDIS_MSG_INDICATE:
 447                /* notification msgs */
 448                netvsc_linkstatus_callback(dev, rndis_msg);
 449                break;
 450        default:
 451                netdev_err(ndev,
 452                        "unhandled rndis message (type %u len %u)\n",
 453                           rndis_msg->ndis_msg_type,
 454                           rndis_msg->msg_len);
 455                break;
 456        }
 457
 458exit:
 459        if (ret != 0)
 460                pkt->status = NVSP_STAT_FAIL;
 461
 462        return ret;
 463}
 464
 465static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
 466                                  void *result, u32 *result_size)
 467{
 468        struct rndis_request *request;
 469        u32 inresult_size = *result_size;
 470        struct rndis_query_request *query;
 471        struct rndis_query_complete *query_complete;
 472        int ret = 0;
 473        unsigned long t;
 474
 475        if (!result)
 476                return -EINVAL;
 477
 478        *result_size = 0;
 479        request = get_rndis_request(dev, RNDIS_MSG_QUERY,
 480                        RNDIS_MESSAGE_SIZE(struct rndis_query_request));
 481        if (!request) {
 482                ret = -ENOMEM;
 483                goto cleanup;
 484        }
 485
 486        /* Setup the rndis query */
 487        query = &request->request_msg.msg.query_req;
 488        query->oid = oid;
 489        query->info_buf_offset = sizeof(struct rndis_query_request);
 490        query->info_buflen = 0;
 491        query->dev_vc_handle = 0;
 492
 493        if (oid == OID_GEN_RECEIVE_SCALE_CAPABILITIES) {
 494                struct ndis_recv_scale_cap *cap;
 495
 496                request->request_msg.msg_len +=
 497                        sizeof(struct ndis_recv_scale_cap);
 498                query->info_buflen = sizeof(struct ndis_recv_scale_cap);
 499                cap = (struct ndis_recv_scale_cap *)((unsigned long)query +
 500                                                     query->info_buf_offset);
 501                cap->hdr.type = NDIS_OBJECT_TYPE_RSS_CAPABILITIES;
 502                cap->hdr.rev = NDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2;
 503                cap->hdr.size = sizeof(struct ndis_recv_scale_cap);
 504        }
 505
 506        ret = rndis_filter_send_request(dev, request);
 507        if (ret != 0)
 508                goto cleanup;
 509
 510        t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
 511        if (t == 0) {
 512                ret = -ETIMEDOUT;
 513                goto cleanup;
 514        }
 515
 516        /* Copy the response back */
 517        query_complete = &request->response_msg.msg.query_complete;
 518
 519        if (query_complete->info_buflen > inresult_size) {
 520                ret = -1;
 521                goto cleanup;
 522        }
 523
 524        memcpy(result,
 525               (void *)((unsigned long)query_complete +
 526                         query_complete->info_buf_offset),
 527               query_complete->info_buflen);
 528
 529        *result_size = query_complete->info_buflen;
 530
 531cleanup:
 532        if (request)
 533                put_rndis_request(dev, request);
 534
 535        return ret;
 536}
 537
 538static int rndis_filter_query_device_mac(struct rndis_device *dev)
 539{
 540        u32 size = ETH_ALEN;
 541
 542        return rndis_filter_query_device(dev,
 543                                      RNDIS_OID_802_3_PERMANENT_ADDRESS,
 544                                      dev->hw_mac_adr, &size);
 545}
 546
 547#define NWADR_STR "NetworkAddress"
 548#define NWADR_STRLEN 14
 549
 550int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac)
 551{
 552        struct netvsc_device *nvdev = hv_get_drvdata(hdev);
 553        struct rndis_device *rdev = nvdev->extension;
 554        struct net_device *ndev = nvdev->ndev;
 555        struct rndis_request *request;
 556        struct rndis_set_request *set;
 557        struct rndis_config_parameter_info *cpi;
 558        wchar_t *cfg_nwadr, *cfg_mac;
 559        struct rndis_set_complete *set_complete;
 560        char macstr[2*ETH_ALEN+1];
 561        u32 extlen = sizeof(struct rndis_config_parameter_info) +
 562                2*NWADR_STRLEN + 4*ETH_ALEN;
 563        int ret;
 564        unsigned long t;
 565
 566        request = get_rndis_request(rdev, RNDIS_MSG_SET,
 567                RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
 568        if (!request)
 569                return -ENOMEM;
 570
 571        set = &request->request_msg.msg.set_req;
 572        set->oid = RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER;
 573        set->info_buflen = extlen;
 574        set->info_buf_offset = sizeof(struct rndis_set_request);
 575        set->dev_vc_handle = 0;
 576
 577        cpi = (struct rndis_config_parameter_info *)((ulong)set +
 578                set->info_buf_offset);
 579        cpi->parameter_name_offset =
 580                sizeof(struct rndis_config_parameter_info);
 581        /* Multiply by 2 because host needs 2 bytes (utf16) for each char */
 582        cpi->parameter_name_length = 2*NWADR_STRLEN;
 583        cpi->parameter_type = RNDIS_CONFIG_PARAM_TYPE_STRING;
 584        cpi->parameter_value_offset =
 585                cpi->parameter_name_offset + cpi->parameter_name_length;
 586        /* Multiply by 4 because each MAC byte displayed as 2 utf16 chars */
 587        cpi->parameter_value_length = 4*ETH_ALEN;
 588
 589        cfg_nwadr = (wchar_t *)((ulong)cpi + cpi->parameter_name_offset);
 590        cfg_mac = (wchar_t *)((ulong)cpi + cpi->parameter_value_offset);
 591        ret = utf8s_to_utf16s(NWADR_STR, NWADR_STRLEN, UTF16_HOST_ENDIAN,
 592                              cfg_nwadr, NWADR_STRLEN);
 593        if (ret < 0)
 594                goto cleanup;
 595        snprintf(macstr, 2*ETH_ALEN+1, "%pm", mac);
 596        ret = utf8s_to_utf16s(macstr, 2*ETH_ALEN, UTF16_HOST_ENDIAN,
 597                              cfg_mac, 2*ETH_ALEN);
 598        if (ret < 0)
 599                goto cleanup;
 600
 601        ret = rndis_filter_send_request(rdev, request);
 602        if (ret != 0)
 603                goto cleanup;
 604
 605        t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
 606        if (t == 0) {
 607                netdev_err(ndev, "timeout before we got a set response...\n");
 608                /*
 609                 * can't put_rndis_request, since we may still receive a
 610                 * send-completion.
 611                 */
 612                return -EBUSY;
 613        } else {
 614                set_complete = &request->response_msg.msg.set_complete;
 615                if (set_complete->status != RNDIS_STATUS_SUCCESS) {
 616                        netdev_err(ndev, "Fail to set MAC on host side:0x%x\n",
 617                                   set_complete->status);
 618                        ret = -EINVAL;
 619                }
 620        }
 621
 622cleanup:
 623        put_rndis_request(rdev, request);
 624        return ret;
 625}
 626
 627static int
 628rndis_filter_set_offload_params(struct hv_device *hdev,
 629                                struct ndis_offload_params *req_offloads)
 630{
 631        struct netvsc_device *nvdev = hv_get_drvdata(hdev);
 632        struct rndis_device *rdev = nvdev->extension;
 633        struct net_device *ndev = nvdev->ndev;
 634        struct rndis_request *request;
 635        struct rndis_set_request *set;
 636        struct ndis_offload_params *offload_params;
 637        struct rndis_set_complete *set_complete;
 638        u32 extlen = sizeof(struct ndis_offload_params);
 639        int ret;
 640        unsigned long t;
 641        u32 vsp_version = nvdev->nvsp_version;
 642
 643        if (vsp_version <= NVSP_PROTOCOL_VERSION_4) {
 644                extlen = VERSION_4_OFFLOAD_SIZE;
 645                /* On NVSP_PROTOCOL_VERSION_4 and below, we do not support
 646                 * UDP checksum offload.
 647                 */
 648                req_offloads->udp_ip_v4_csum = 0;
 649                req_offloads->udp_ip_v6_csum = 0;
 650        }
 651
 652        request = get_rndis_request(rdev, RNDIS_MSG_SET,
 653                RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
 654        if (!request)
 655                return -ENOMEM;
 656
 657        set = &request->request_msg.msg.set_req;
 658        set->oid = OID_TCP_OFFLOAD_PARAMETERS;
 659        set->info_buflen = extlen;
 660        set->info_buf_offset = sizeof(struct rndis_set_request);
 661        set->dev_vc_handle = 0;
 662
 663        offload_params = (struct ndis_offload_params *)((ulong)set +
 664                                set->info_buf_offset);
 665        *offload_params = *req_offloads;
 666        offload_params->header.type = NDIS_OBJECT_TYPE_DEFAULT;
 667        offload_params->header.revision = NDIS_OFFLOAD_PARAMETERS_REVISION_3;
 668        offload_params->header.size = extlen;
 669
 670        ret = rndis_filter_send_request(rdev, request);
 671        if (ret != 0)
 672                goto cleanup;
 673
 674        t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
 675        if (t == 0) {
 676                netdev_err(ndev, "timeout before we got aOFFLOAD set response...\n");
 677                /* can't put_rndis_request, since we may still receive a
 678                 * send-completion.
 679                 */
 680                return -EBUSY;
 681        } else {
 682                set_complete = &request->response_msg.msg.set_complete;
 683                if (set_complete->status != RNDIS_STATUS_SUCCESS) {
 684                        netdev_err(ndev, "Fail to set offload on host side:0x%x\n",
 685                                   set_complete->status);
 686                        ret = -EINVAL;
 687                }
 688        }
 689
 690cleanup:
 691        put_rndis_request(rdev, request);
 692        return ret;
 693}
 694
 695u8 netvsc_hash_key[HASH_KEYLEN] = {
 696        0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
 697        0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
 698        0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
 699        0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
 700        0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa
 701};
 702
 703static int rndis_filter_set_rss_param(struct rndis_device *rdev, int num_queue)
 704{
 705        struct net_device *ndev = rdev->net_dev->ndev;
 706        struct rndis_request *request;
 707        struct rndis_set_request *set;
 708        struct rndis_set_complete *set_complete;
 709        u32 extlen = sizeof(struct ndis_recv_scale_param) +
 710                     4*ITAB_NUM + HASH_KEYLEN;
 711        struct ndis_recv_scale_param *rssp;
 712        u32 *itab;
 713        u8 *keyp;
 714        int i, ret;
 715        unsigned long t;
 716
 717        request = get_rndis_request(
 718                        rdev, RNDIS_MSG_SET,
 719                        RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
 720        if (!request)
 721                return -ENOMEM;
 722
 723        set = &request->request_msg.msg.set_req;
 724        set->oid = OID_GEN_RECEIVE_SCALE_PARAMETERS;
 725        set->info_buflen = extlen;
 726        set->info_buf_offset = sizeof(struct rndis_set_request);
 727        set->dev_vc_handle = 0;
 728
 729        rssp = (struct ndis_recv_scale_param *)(set + 1);
 730        rssp->hdr.type = NDIS_OBJECT_TYPE_RSS_PARAMETERS;
 731        rssp->hdr.rev = NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2;
 732        rssp->hdr.size = sizeof(struct ndis_recv_scale_param);
 733        rssp->flag = 0;
 734        rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 |
 735                         NDIS_HASH_TCP_IPV4 | NDIS_HASH_IPV6 |
 736                         NDIS_HASH_TCP_IPV6;
 737        rssp->indirect_tabsize = 4*ITAB_NUM;
 738        rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param);
 739        rssp->hashkey_size = HASH_KEYLEN;
 740        rssp->kashkey_offset = rssp->indirect_taboffset +
 741                               rssp->indirect_tabsize;
 742
 743        /* Set indirection table entries */
 744        itab = (u32 *)(rssp + 1);
 745        for (i = 0; i < ITAB_NUM; i++)
 746                itab[i] = i % num_queue;
 747
 748        /* Set hask key values */
 749        keyp = (u8 *)((unsigned long)rssp + rssp->kashkey_offset);
 750        for (i = 0; i < HASH_KEYLEN; i++)
 751                keyp[i] = netvsc_hash_key[i];
 752
 753
 754        ret = rndis_filter_send_request(rdev, request);
 755        if (ret != 0)
 756                goto cleanup;
 757
 758        t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
 759        if (t == 0) {
 760                netdev_err(ndev, "timeout before we got a set response...\n");
 761                /* can't put_rndis_request, since we may still receive a
 762                 * send-completion.
 763                 */
 764                return -ETIMEDOUT;
 765        } else {
 766                set_complete = &request->response_msg.msg.set_complete;
 767                if (set_complete->status != RNDIS_STATUS_SUCCESS) {
 768                        netdev_err(ndev, "Fail to set RSS parameters:0x%x\n",
 769                                   set_complete->status);
 770                        ret = -EINVAL;
 771                }
 772        }
 773
 774cleanup:
 775        put_rndis_request(rdev, request);
 776        return ret;
 777}
 778
 779
 780static int rndis_filter_query_device_link_status(struct rndis_device *dev)
 781{
 782        u32 size = sizeof(u32);
 783        u32 link_status;
 784        int ret;
 785
 786        ret = rndis_filter_query_device(dev,
 787                                      RNDIS_OID_GEN_MEDIA_CONNECT_STATUS,
 788                                      &link_status, &size);
 789
 790        return ret;
 791}
 792
 793int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter)
 794{
 795        struct rndis_request *request;
 796        struct rndis_set_request *set;
 797        struct rndis_set_complete *set_complete;
 798        u32 status;
 799        int ret;
 800        unsigned long t;
 801        struct net_device *ndev;
 802
 803        ndev = dev->net_dev->ndev;
 804
 805        request = get_rndis_request(dev, RNDIS_MSG_SET,
 806                        RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
 807                        sizeof(u32));
 808        if (!request) {
 809                ret = -ENOMEM;
 810                goto cleanup;
 811        }
 812
 813        /* Setup the rndis set */
 814        set = &request->request_msg.msg.set_req;
 815        set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
 816        set->info_buflen = sizeof(u32);
 817        set->info_buf_offset = sizeof(struct rndis_set_request);
 818
 819        memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
 820               &new_filter, sizeof(u32));
 821
 822        ret = rndis_filter_send_request(dev, request);
 823        if (ret != 0)
 824                goto cleanup;
 825
 826        t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
 827
 828        if (t == 0) {
 829                netdev_err(ndev,
 830                        "timeout before we got a set response...\n");
 831                ret = -ETIMEDOUT;
 832                /*
 833                 * We can't deallocate the request since we may still receive a
 834                 * send completion for it.
 835                 */
 836                goto exit;
 837        } else {
 838                set_complete = &request->response_msg.msg.set_complete;
 839                status = set_complete->status;
 840        }
 841
 842cleanup:
 843        if (request)
 844                put_rndis_request(dev, request);
 845exit:
 846        return ret;
 847}
 848
 849
 850static int rndis_filter_init_device(struct rndis_device *dev)
 851{
 852        struct rndis_request *request;
 853        struct rndis_initialize_request *init;
 854        struct rndis_initialize_complete *init_complete;
 855        u32 status;
 856        int ret;
 857        unsigned long t;
 858
 859        request = get_rndis_request(dev, RNDIS_MSG_INIT,
 860                        RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
 861        if (!request) {
 862                ret = -ENOMEM;
 863                goto cleanup;
 864        }
 865
 866        /* Setup the rndis set */
 867        init = &request->request_msg.msg.init_req;
 868        init->major_ver = RNDIS_MAJOR_VERSION;
 869        init->minor_ver = RNDIS_MINOR_VERSION;
 870        init->max_xfer_size = 0x4000;
 871
 872        dev->state = RNDIS_DEV_INITIALIZING;
 873
 874        ret = rndis_filter_send_request(dev, request);
 875        if (ret != 0) {
 876                dev->state = RNDIS_DEV_UNINITIALIZED;
 877                goto cleanup;
 878        }
 879
 880
 881        t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
 882
 883        if (t == 0) {
 884                ret = -ETIMEDOUT;
 885                goto cleanup;
 886        }
 887
 888        init_complete = &request->response_msg.msg.init_complete;
 889        status = init_complete->status;
 890        if (status == RNDIS_STATUS_SUCCESS) {
 891                dev->state = RNDIS_DEV_INITIALIZED;
 892                ret = 0;
 893        } else {
 894                dev->state = RNDIS_DEV_UNINITIALIZED;
 895                ret = -EINVAL;
 896        }
 897
 898cleanup:
 899        if (request)
 900                put_rndis_request(dev, request);
 901
 902        return ret;
 903}
 904
 905static void rndis_filter_halt_device(struct rndis_device *dev)
 906{
 907        struct rndis_request *request;
 908        struct rndis_halt_request *halt;
 909        struct netvsc_device *nvdev = dev->net_dev;
 910        struct hv_device *hdev = nvdev->dev;
 911        ulong flags;
 912
 913        /* Attempt to do a rndis device halt */
 914        request = get_rndis_request(dev, RNDIS_MSG_HALT,
 915                                RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
 916        if (!request)
 917                goto cleanup;
 918
 919        /* Setup the rndis set */
 920        halt = &request->request_msg.msg.halt_req;
 921        halt->req_id = atomic_inc_return(&dev->new_req_id);
 922
 923        /* Ignore return since this msg is optional. */
 924        rndis_filter_send_request(dev, request);
 925
 926        dev->state = RNDIS_DEV_UNINITIALIZED;
 927
 928cleanup:
 929        spin_lock_irqsave(&hdev->channel->inbound_lock, flags);
 930        nvdev->destroy = true;
 931        spin_unlock_irqrestore(&hdev->channel->inbound_lock, flags);
 932
 933        /* Wait for all send completions */
 934        wait_event(nvdev->wait_drain,
 935                atomic_read(&nvdev->num_outstanding_sends) == 0);
 936
 937        if (request)
 938                put_rndis_request(dev, request);
 939        return;
 940}
 941
 942static int rndis_filter_open_device(struct rndis_device *dev)
 943{
 944        int ret;
 945
 946        if (dev->state != RNDIS_DEV_INITIALIZED)
 947                return 0;
 948
 949        ret = rndis_filter_set_packet_filter(dev,
 950                                         NDIS_PACKET_TYPE_BROADCAST |
 951                                         NDIS_PACKET_TYPE_ALL_MULTICAST |
 952                                         NDIS_PACKET_TYPE_DIRECTED);
 953        if (ret == 0)
 954                dev->state = RNDIS_DEV_DATAINITIALIZED;
 955
 956        return ret;
 957}
 958
 959static int rndis_filter_close_device(struct rndis_device *dev)
 960{
 961        int ret;
 962
 963        if (dev->state != RNDIS_DEV_DATAINITIALIZED)
 964                return 0;
 965
 966        ret = rndis_filter_set_packet_filter(dev, 0);
 967        if (ret == -ENODEV)
 968                ret = 0;
 969
 970        if (ret == 0)
 971                dev->state = RNDIS_DEV_INITIALIZED;
 972
 973        return ret;
 974}
 975
 976static void netvsc_sc_open(struct vmbus_channel *new_sc)
 977{
 978        struct netvsc_device *nvscdev;
 979        u16 chn_index = new_sc->offermsg.offer.sub_channel_index;
 980        int ret;
 981
 982        nvscdev = hv_get_drvdata(new_sc->primary_channel->device_obj);
 983
 984        if (chn_index >= nvscdev->num_chn)
 985                return;
 986
 987        set_per_channel_state(new_sc, nvscdev->sub_cb_buf + (chn_index - 1) *
 988                              NETVSC_PACKET_SIZE);
 989
 990        ret = vmbus_open(new_sc, nvscdev->ring_size * PAGE_SIZE,
 991                         nvscdev->ring_size * PAGE_SIZE, NULL, 0,
 992                         netvsc_channel_cb, new_sc);
 993
 994        if (ret == 0)
 995                nvscdev->chn_table[chn_index] = new_sc;
 996}
 997
 998int rndis_filter_device_add(struct hv_device *dev,
 999                                  void *additional_info)
1000{
1001        int ret;
1002        struct netvsc_device *net_device;
1003        struct rndis_device *rndis_device;
1004        struct netvsc_device_info *device_info = additional_info;
1005        struct ndis_offload_params offloads;
1006        struct nvsp_message *init_packet;
1007        unsigned long t;
1008        struct ndis_recv_scale_cap rsscap;
1009        u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
1010        u32 mtu, size;
1011
1012        rndis_device = get_rndis_device();
1013        if (!rndis_device)
1014                return -ENODEV;
1015
1016        /*
1017         * Let the inner driver handle this first to create the netvsc channel
1018         * NOTE! Once the channel is created, we may get a receive callback
1019         * (RndisFilterOnReceive()) before this call is completed
1020         */
1021        ret = netvsc_device_add(dev, additional_info);
1022        if (ret != 0) {
1023                kfree(rndis_device);
1024                return ret;
1025        }
1026
1027
1028        /* Initialize the rndis device */
1029        net_device = hv_get_drvdata(dev);
1030        net_device->num_chn = 1;
1031
1032        net_device->extension = rndis_device;
1033        rndis_device->net_dev = net_device;
1034
1035        /* Send the rndis initialization message */
1036        ret = rndis_filter_init_device(rndis_device);
1037        if (ret != 0) {
1038                rndis_filter_device_remove(dev);
1039                return ret;
1040        }
1041
1042        /* Get the MTU from the host */
1043        size = sizeof(u32);
1044        ret = rndis_filter_query_device(rndis_device,
1045                                        RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE,
1046                                        &mtu, &size);
1047        if (ret == 0 && size == sizeof(u32))
1048                net_device->ndev->mtu = mtu;
1049
1050        /* Get the mac address */
1051        ret = rndis_filter_query_device_mac(rndis_device);
1052        if (ret != 0) {
1053                rndis_filter_device_remove(dev);
1054                return ret;
1055        }
1056
1057        memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
1058
1059        /* Turn on the offloads; the host supports all of the relevant
1060         * offloads.
1061         */
1062        memset(&offloads, 0, sizeof(struct ndis_offload_params));
1063        /* A value of zero means "no change"; now turn on what we
1064         * want.
1065         */
1066        offloads.ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1067        offloads.tcp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1068        offloads.udp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1069        offloads.tcp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1070        offloads.udp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
1071        offloads.lso_v2_ipv4 = NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED;
1072
1073
1074        ret = rndis_filter_set_offload_params(dev, &offloads);
1075        if (ret)
1076                goto err_dev_remv;
1077
1078        rndis_filter_query_device_link_status(rndis_device);
1079
1080        device_info->link_state = rndis_device->link_state;
1081
1082        dev_info(&dev->device, "Device MAC %pM link state %s\n",
1083                 rndis_device->hw_mac_adr,
1084                 device_info->link_state ? "down" : "up");
1085
1086        if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5)
1087                return 0;
1088
1089        /* vRSS setup */
1090        memset(&rsscap, 0, rsscap_size);
1091        ret = rndis_filter_query_device(rndis_device,
1092                                        OID_GEN_RECEIVE_SCALE_CAPABILITIES,
1093                                        &rsscap, &rsscap_size);
1094        if (ret || rsscap.num_recv_que < 2)
1095                goto out;
1096
1097        net_device->num_chn = (num_online_cpus() < rsscap.num_recv_que) ?
1098                               num_online_cpus() : rsscap.num_recv_que;
1099        if (net_device->num_chn == 1)
1100                goto out;
1101
1102        net_device->sub_cb_buf = vzalloc((net_device->num_chn - 1) *
1103                                         NETVSC_PACKET_SIZE);
1104        if (!net_device->sub_cb_buf) {
1105                net_device->num_chn = 1;
1106                dev_info(&dev->device, "No memory for subchannels.\n");
1107                goto out;
1108        }
1109
1110        vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
1111
1112        init_packet = &net_device->channel_init_pkt;
1113        memset(init_packet, 0, sizeof(struct nvsp_message));
1114        init_packet->hdr.msg_type = NVSP_MSG5_TYPE_SUBCHANNEL;
1115        init_packet->msg.v5_msg.subchn_req.op = NVSP_SUBCHANNEL_ALLOCATE;
1116        init_packet->msg.v5_msg.subchn_req.num_subchannels =
1117                                                net_device->num_chn - 1;
1118        ret = vmbus_sendpacket(dev->channel, init_packet,
1119                               sizeof(struct nvsp_message),
1120                               (unsigned long)init_packet,
1121                               VM_PKT_DATA_INBAND,
1122                               VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
1123        if (ret)
1124                goto out;
1125        t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
1126        if (t == 0) {
1127                ret = -ETIMEDOUT;
1128                goto out;
1129        }
1130        if (init_packet->msg.v5_msg.subchn_comp.status !=
1131            NVSP_STAT_SUCCESS) {
1132                ret = -ENODEV;
1133                goto out;
1134        }
1135        net_device->num_chn = 1 +
1136                init_packet->msg.v5_msg.subchn_comp.num_subchannels;
1137
1138        vmbus_are_subchannels_present(dev->channel);
1139
1140        ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn);
1141
1142out:
1143        if (ret)
1144                net_device->num_chn = 1;
1145        return 0; /* return 0 because primary channel can be used alone */
1146
1147err_dev_remv:
1148        rndis_filter_device_remove(dev);
1149        return ret;
1150}
1151
1152void rndis_filter_device_remove(struct hv_device *dev)
1153{
1154        struct netvsc_device *net_dev = hv_get_drvdata(dev);
1155        struct rndis_device *rndis_dev = net_dev->extension;
1156
1157        /* Halt and release the rndis device */
1158        rndis_filter_halt_device(rndis_dev);
1159
1160        kfree(rndis_dev);
1161        net_dev->extension = NULL;
1162
1163        netvsc_device_remove(dev);
1164}
1165
1166
1167int rndis_filter_open(struct hv_device *dev)
1168{
1169        struct netvsc_device *net_device = hv_get_drvdata(dev);
1170
1171        if (!net_device)
1172                return -EINVAL;
1173
1174        return rndis_filter_open_device(net_device->extension);
1175}
1176
1177int rndis_filter_close(struct hv_device *dev)
1178{
1179        struct netvsc_device *nvdev = hv_get_drvdata(dev);
1180
1181        if (!nvdev)
1182                return -EINVAL;
1183
1184        return rndis_filter_close_device(nvdev->extension);
1185}
1186