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