mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-03-26 12:02:29 +07:00
Drivers: net: hyperv: Enable offloads on the host
Prior to enabling guest side offloads, enable the offloads on the host. Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8a00251a36
commit
4a0e70ae5e
@ -721,6 +721,61 @@ struct ndis_pkt_8021q_info {
|
||||
};
|
||||
};
|
||||
|
||||
struct ndis_oject_header {
|
||||
u8 type;
|
||||
u8 revision;
|
||||
u16 size;
|
||||
};
|
||||
|
||||
#define NDIS_OBJECT_TYPE_DEFAULT 0x80
|
||||
#define NDIS_OFFLOAD_PARAMETERS_REVISION_3 3
|
||||
#define NDIS_OFFLOAD_PARAMETERS_NO_CHANGE 0
|
||||
#define NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED 1
|
||||
#define NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED 2
|
||||
#define NDIS_OFFLOAD_PARAMETERS_LSOV1_ENABLED 2
|
||||
#define NDIS_OFFLOAD_PARAMETERS_RSC_DISABLED 1
|
||||
#define NDIS_OFFLOAD_PARAMETERS_RSC_ENABLED 2
|
||||
#define NDIS_OFFLOAD_PARAMETERS_TX_RX_DISABLED 1
|
||||
#define NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED 2
|
||||
#define NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED 3
|
||||
#define NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED 4
|
||||
|
||||
/*
|
||||
* New offload OIDs for NDIS 6
|
||||
*/
|
||||
#define OID_TCP_OFFLOAD_CURRENT_CONFIG 0xFC01020B /* query only */
|
||||
#define OID_TCP_OFFLOAD_PARAMETERS 0xFC01020C /* set only */
|
||||
#define OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES 0xFC01020D/* query only */
|
||||
#define OID_TCP_CONNECTION_OFFLOAD_CURRENT_CONFIG 0xFC01020E /* query only */
|
||||
#define OID_TCP_CONNECTION_OFFLOAD_HARDWARE_CAPABILITIES 0xFC01020F /* query */
|
||||
#define OID_OFFLOAD_ENCAPSULATION 0x0101010A /* set/query */
|
||||
|
||||
struct ndis_offload_params {
|
||||
struct ndis_oject_header header;
|
||||
u8 ip_v4_csum;
|
||||
u8 tcp_ip_v4_csum;
|
||||
u8 udp_ip_v4_csum;
|
||||
u8 tcp_ip_v6_csum;
|
||||
u8 udp_ip_v6_csum;
|
||||
u8 lso_v1;
|
||||
u8 ip_sec_v1;
|
||||
u8 lso_v2_ipv4;
|
||||
u8 lso_v2_ipv6;
|
||||
u8 tcp_connection_ip_v4;
|
||||
u8 tcp_connection_ip_v6;
|
||||
u32 flags;
|
||||
u8 ip_sec_v2;
|
||||
u8 ip_sec_v2_ip_v4;
|
||||
struct {
|
||||
u8 rsc_ip_v4;
|
||||
u8 rsc_ip_v6;
|
||||
};
|
||||
struct {
|
||||
u8 encapsulated_packet_task_offload;
|
||||
u8 encapsulation_types;
|
||||
};
|
||||
};
|
||||
|
||||
#define NDIS_VLAN_PPI_SIZE (sizeof(struct rndis_per_packet_info) + \
|
||||
sizeof(struct ndis_pkt_8021q_info))
|
||||
|
||||
|
@ -607,6 +607,61 @@ int rndis_filter_set_device_mac(struct hv_device *hdev, char *mac)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rndis_filter_set_offload_params(struct hv_device *hdev,
|
||||
struct ndis_offload_params *req_offloads)
|
||||
{
|
||||
struct netvsc_device *nvdev = hv_get_drvdata(hdev);
|
||||
struct rndis_device *rdev = nvdev->extension;
|
||||
struct net_device *ndev = nvdev->ndev;
|
||||
struct rndis_request *request;
|
||||
struct rndis_set_request *set;
|
||||
struct ndis_offload_params *offload_params;
|
||||
struct rndis_set_complete *set_complete;
|
||||
u32 extlen = sizeof(struct ndis_offload_params);
|
||||
int ret, t;
|
||||
|
||||
request = get_rndis_request(rdev, RNDIS_MSG_SET,
|
||||
RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
|
||||
if (!request)
|
||||
return -ENOMEM;
|
||||
|
||||
set = &request->request_msg.msg.set_req;
|
||||
set->oid = OID_TCP_OFFLOAD_PARAMETERS;
|
||||
set->info_buflen = extlen;
|
||||
set->info_buf_offset = sizeof(struct rndis_set_request);
|
||||
set->dev_vc_handle = 0;
|
||||
|
||||
offload_params = (struct ndis_offload_params *)((ulong)set +
|
||||
set->info_buf_offset);
|
||||
*offload_params = *req_offloads;
|
||||
offload_params->header.type = NDIS_OBJECT_TYPE_DEFAULT;
|
||||
offload_params->header.revision = NDIS_OFFLOAD_PARAMETERS_REVISION_3;
|
||||
offload_params->header.size = extlen;
|
||||
|
||||
ret = rndis_filter_send_request(rdev, request);
|
||||
if (ret != 0)
|
||||
goto cleanup;
|
||||
|
||||
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
|
||||
if (t == 0) {
|
||||
netdev_err(ndev, "timeout before we got aOFFLOAD set response...\n");
|
||||
/* can't put_rndis_request, since we may still receive a
|
||||
* send-completion.
|
||||
*/
|
||||
return -EBUSY;
|
||||
} else {
|
||||
set_complete = &request->response_msg.msg.set_complete;
|
||||
if (set_complete->status != RNDIS_STATUS_SUCCESS) {
|
||||
netdev_err(ndev, "Fail to set MAC on host side:0x%x\n",
|
||||
set_complete->status);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
put_rndis_request(rdev, request);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rndis_filter_query_device_link_status(struct rndis_device *dev)
|
||||
{
|
||||
@ -807,6 +862,7 @@ int rndis_filter_device_add(struct hv_device *dev,
|
||||
struct netvsc_device *net_device;
|
||||
struct rndis_device *rndis_device;
|
||||
struct netvsc_device_info *device_info = additional_info;
|
||||
struct ndis_offload_params offloads;
|
||||
|
||||
rndis_device = get_rndis_device();
|
||||
if (!rndis_device)
|
||||
@ -846,6 +902,26 @@ int rndis_filter_device_add(struct hv_device *dev,
|
||||
|
||||
memcpy(device_info->mac_adr, rndis_device->hw_mac_adr, ETH_ALEN);
|
||||
|
||||
/* Turn on the offloads; the host supports all of the relevant
|
||||
* offloads.
|
||||
*/
|
||||
memset(&offloads, 0, sizeof(struct ndis_offload_params));
|
||||
/* A value of zero means "no change"; now turn on what we
|
||||
* want.
|
||||
*/
|
||||
offloads.ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
|
||||
offloads.tcp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
|
||||
offloads.udp_ip_v4_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
|
||||
offloads.tcp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
|
||||
offloads.udp_ip_v6_csum = NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED;
|
||||
offloads.lso_v2_ipv4 = NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED;
|
||||
|
||||
|
||||
ret = rndis_filter_set_offload_params(dev, &offloads);
|
||||
if (ret)
|
||||
goto err_dev_remv;
|
||||
|
||||
|
||||
rndis_filter_query_device_link_status(rndis_device);
|
||||
|
||||
device_info->link_state = rndis_device->link_state;
|
||||
@ -855,6 +931,10 @@ int rndis_filter_device_add(struct hv_device *dev,
|
||||
device_info->link_state ? "down" : "up");
|
||||
|
||||
return ret;
|
||||
|
||||
err_dev_remv:
|
||||
rndis_filter_device_remove(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void rndis_filter_device_remove(struct hv_device *dev)
|
||||
|
Loading…
Reference in New Issue
Block a user