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