Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
net
ethernet
mellanox
mlx4
en_cq.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2007 Mellanox Technologies. All rights reserved.
3
*
4
* This software is available to you under a choice of one of two
5
* licenses. You may choose to be licensed under the terms of the GNU
6
* General Public License (GPL) Version 2, available from the file
7
* COPYING in the main directory of this source tree, or the
8
* OpenIB.org BSD license below:
9
*
10
* Redistribution and use in source and binary forms, with or
11
* without modification, are permitted provided that the following
12
* conditions are met:
13
*
14
* - Redistributions of source code must retain the above
15
* copyright notice, this list of conditions and the following
16
* disclaimer.
17
*
18
* - Redistributions in binary form must reproduce the above
19
* copyright notice, this list of conditions and the following
20
* disclaimer in the documentation and/or other materials
21
* provided with the distribution.
22
*
23
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
* SOFTWARE.
31
*
32
*/
33
34
#include <
linux/mlx4/cq.h
>
35
#include <
linux/mlx4/qp.h
>
36
#include <
linux/mlx4/cmd.h
>
37
38
#include "
mlx4_en.h
"
39
40
static
void
mlx4_en_cq_event(
struct
mlx4_cq
*cq,
enum
mlx4_event
event
)
41
{
42
return
;
43
}
44
45
46
int
mlx4_en_create_cq
(
struct
mlx4_en_priv
*
priv
,
47
struct
mlx4_en_cq
*cq,
48
int
entries
,
int
ring
,
enum
cq_type
mode
)
49
{
50
struct
mlx4_en_dev
*mdev = priv->
mdev
;
51
int
err
;
52
53
cq->
size
=
entries
;
54
cq->
buf_size
= cq->
size
*
sizeof
(
struct
mlx4_cqe
);
55
56
cq->
ring
= ring;
57
cq->
is_tx
=
mode
;
58
spin_lock_init
(&cq->
lock
);
59
60
err =
mlx4_alloc_hwq_res
(mdev->
dev
, &cq->
wqres
,
61
cq->
buf_size
, 2 *
PAGE_SIZE
);
62
if
(err)
63
return
err
;
64
65
err =
mlx4_en_map_buffer
(&cq->
wqres
.buf);
66
if
(err)
67
mlx4_free_hwq_res
(mdev->
dev
, &cq->
wqres
, cq->
buf_size
);
68
else
69
cq->
buf
= (
struct
mlx4_cqe
*) cq->
wqres
.buf.direct.buf;
70
71
return
err;
72
}
73
74
int
mlx4_en_activate_cq
(
struct
mlx4_en_priv
*
priv
,
struct
mlx4_en_cq
*cq,
75
int
cq_idx)
76
{
77
struct
mlx4_en_dev
*mdev = priv->
mdev
;
78
int
err
= 0;
79
char
name
[25];
80
struct
cpu_rmap
*rmap =
81
#ifdef CONFIG_RFS_ACCEL
82
priv->
dev
->rx_cpu_rmap;
83
#else
84
NULL
;
85
#endif
86
87
cq->
dev
= mdev->
pndev
[priv->
port
];
88
cq->
mcq
.set_ci_db = cq->
wqres
.db.db;
89
cq->
mcq
.arm_db = cq->
wqres
.db.db + 1;
90
*cq->
mcq
.set_ci_db = 0;
91
*cq->
mcq
.arm_db = 0;
92
memset
(cq->
buf
, 0, cq->
buf_size
);
93
94
if
(cq->
is_tx
==
RX
) {
95
if
(mdev->
dev
->caps.comp_pool) {
96
if
(!cq->
vector
) {
97
sprintf
(name,
"%s-%d"
, priv->
dev
->name,
98
cq->
ring
);
99
/* Set IRQ for specific name (per ring) */
100
if
(
mlx4_assign_eq
(mdev->
dev
, name, rmap,
101
&cq->
vector
)) {
102
cq->
vector
= (cq->
ring
+ 1 + priv->
port
)
103
% mdev->
dev
->caps.num_comp_vectors;
104
mlx4_warn
(mdev,
"Failed Assigning an EQ to "
105
"%s ,Falling back to legacy EQ's\n"
,
106
name);
107
}
108
}
109
}
else
{
110
cq->
vector
= (cq->
ring
+ 1 + priv->
port
) %
111
mdev->
dev
->caps.num_comp_vectors;
112
}
113
}
else
{
114
/* For TX we use the same irq per
115
ring we assigned for the RX */
116
struct
mlx4_en_cq
*rx_cq;
117
118
cq_idx = cq_idx % priv->
rx_ring_num
;
119
rx_cq = &priv->
rx_cq
[cq_idx];
120
cq->
vector
= rx_cq->
vector
;
121
}
122
123
if
(!cq->
is_tx
)
124
cq->
size
= priv->
rx_ring
[cq->
ring
].actual_size;
125
126
err =
mlx4_cq_alloc
(mdev->
dev
, cq->
size
, &cq->
wqres
.mtt, &mdev->
priv_uar
,
127
cq->
wqres
.db.dma, &cq->
mcq
, cq->
vector
, 0);
128
if
(err)
129
return
err
;
130
131
cq->
mcq
.comp = cq->
is_tx
?
mlx4_en_tx_irq
:
mlx4_en_rx_irq
;
132
cq->
mcq
.event = mlx4_en_cq_event;
133
134
if
(!cq->
is_tx
) {
135
netif_napi_add
(cq->
dev
, &cq->
napi
,
mlx4_en_poll_rx_cq
, 64);
136
napi_enable(&cq->
napi
);
137
}
138
139
return
0;
140
}
141
142
void
mlx4_en_destroy_cq
(
struct
mlx4_en_priv
*
priv
,
struct
mlx4_en_cq
*cq)
143
{
144
struct
mlx4_en_dev
*mdev = priv->
mdev
;
145
146
mlx4_en_unmap_buffer
(&cq->
wqres
.buf);
147
mlx4_free_hwq_res
(mdev->
dev
, &cq->
wqres
, cq->
buf_size
);
148
if
(priv->
mdev
->dev->caps.comp_pool && cq->
vector
)
149
mlx4_release_eq
(priv->
mdev
->dev, cq->
vector
);
150
cq->
vector
= 0;
151
cq->
buf_size
= 0;
152
cq->
buf
=
NULL
;
153
}
154
155
void
mlx4_en_deactivate_cq
(
struct
mlx4_en_priv
*
priv
,
struct
mlx4_en_cq
*cq)
156
{
157
if
(!cq->
is_tx
) {
158
napi_disable(&cq->
napi
);
159
netif_napi_del
(&cq->
napi
);
160
}
161
162
mlx4_cq_free
(priv->
mdev
->dev, &cq->
mcq
);
163
}
164
165
/* Set rx cq moderation parameters */
166
int
mlx4_en_set_cq_moder
(
struct
mlx4_en_priv
*
priv
,
struct
mlx4_en_cq
*cq)
167
{
168
return
mlx4_cq_modify
(priv->
mdev
->dev, &cq->
mcq
,
169
cq->
moder_cnt
, cq->
moder_time
);
170
}
171
172
int
mlx4_en_arm_cq
(
struct
mlx4_en_priv
*
priv
,
struct
mlx4_en_cq
*cq)
173
{
174
mlx4_cq_arm(&cq->
mcq
,
MLX4_CQ_DB_REQ_NOT
, priv->
mdev
->uar_map,
175
&priv->
mdev
->uar_lock);
176
177
return
0;
178
}
179
180
Generated on Thu Jan 10 2013 14:03:09 for Linux Kernel by
1.8.2