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