Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
767dcd42
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
767dcd42
编写于
5月 27, 2010
作者:
R
Roland Dreier
浏览文件
操作
浏览文件
下载
差异文件
Merge branches 'misc' and 'qib' into for-next
上级
e642df6a
7145c45a
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
200 addition
and
614 deletion
+200
-614
drivers/infiniband/hw/qib/qib_fs.c
drivers/infiniband/hw/qib/qib_fs.c
+15
-10
drivers/infiniband/hw/qib/qib_iba6120.c
drivers/infiniband/hw/qib/qib_iba6120.c
+0
-12
drivers/infiniband/hw/qib/qib_iba7322.c
drivers/infiniband/hw/qib/qib_iba7322.c
+179
-592
drivers/infiniband/hw/qib/qib_init.c
drivers/infiniband/hw/qib/qib_init.c
+6
-0
未找到文件。
drivers/infiniband/hw/qib/qib_fs.c
浏览文件 @
767dcd42
...
...
@@ -144,10 +144,11 @@ static ssize_t dev_counters_read(struct file *file, char __user *buf,
size_t
count
,
loff_t
*
ppos
)
{
u64
*
counters
;
size_t
avail
;
struct
qib_devdata
*
dd
=
private2dd
(
file
);
return
simple_read_from_buffer
(
buf
,
count
,
ppos
,
counters
,
dd
->
f_read_cntrs
(
dd
,
*
ppos
,
NULL
,
&
counters
)
);
avail
=
dd
->
f_read_cntrs
(
dd
,
*
ppos
,
NULL
,
&
counters
);
return
simple_read_from_buffer
(
buf
,
count
,
ppos
,
counters
,
avail
);
}
/* read the per-device counters */
...
...
@@ -155,10 +156,11 @@ static ssize_t dev_names_read(struct file *file, char __user *buf,
size_t
count
,
loff_t
*
ppos
)
{
char
*
names
;
size_t
avail
;
struct
qib_devdata
*
dd
=
private2dd
(
file
);
return
simple_read_from_buffer
(
buf
,
count
,
ppos
,
names
,
dd
->
f_read_cntrs
(
dd
,
*
ppos
,
&
names
,
NULL
)
);
avail
=
dd
->
f_read_cntrs
(
dd
,
*
ppos
,
&
names
,
NULL
);
return
simple_read_from_buffer
(
buf
,
count
,
ppos
,
names
,
avail
);
}
static
const
struct
file_operations
cntr_ops
[]
=
{
...
...
@@ -176,10 +178,11 @@ static ssize_t portnames_read(struct file *file, char __user *buf,
size_t
count
,
loff_t
*
ppos
)
{
char
*
names
;
size_t
avail
;
struct
qib_devdata
*
dd
=
private2dd
(
file
);
return
simple_read_from_buffer
(
buf
,
count
,
ppos
,
names
,
dd
->
f_read_portcntrs
(
dd
,
*
ppos
,
0
,
&
names
,
NULL
)
);
avail
=
dd
->
f_read_portcntrs
(
dd
,
*
ppos
,
0
,
&
names
,
NULL
);
return
simple_read_from_buffer
(
buf
,
count
,
ppos
,
names
,
avail
);
}
/* read the per-port counters for port 1 (pidx 0) */
...
...
@@ -187,10 +190,11 @@ static ssize_t portcntrs_1_read(struct file *file, char __user *buf,
size_t
count
,
loff_t
*
ppos
)
{
u64
*
counters
;
size_t
avail
;
struct
qib_devdata
*
dd
=
private2dd
(
file
);
return
simple_read_from_buffer
(
buf
,
count
,
ppos
,
counters
,
dd
->
f_read_portcntrs
(
dd
,
*
ppos
,
0
,
NULL
,
&
counters
)
);
avail
=
dd
->
f_read_portcntrs
(
dd
,
*
ppos
,
0
,
NULL
,
&
counters
);
return
simple_read_from_buffer
(
buf
,
count
,
ppos
,
counters
,
avail
);
}
/* read the per-port counters for port 2 (pidx 1) */
...
...
@@ -198,10 +202,11 @@ static ssize_t portcntrs_2_read(struct file *file, char __user *buf,
size_t
count
,
loff_t
*
ppos
)
{
u64
*
counters
;
size_t
avail
;
struct
qib_devdata
*
dd
=
private2dd
(
file
);
return
simple_read_from_buffer
(
buf
,
count
,
ppos
,
counters
,
dd
->
f_read_portcntrs
(
dd
,
*
ppos
,
1
,
NULL
,
&
counters
)
);
avail
=
dd
->
f_read_portcntrs
(
dd
,
*
ppos
,
1
,
NULL
,
&
counters
);
return
simple_read_from_buffer
(
buf
,
count
,
ppos
,
counters
,
avail
);
}
static
const
struct
file_operations
portcntr_ops
[]
=
{
...
...
drivers/infiniband/hw/qib/qib_iba6120.c
浏览文件 @
767dcd42
...
...
@@ -3475,14 +3475,6 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev,
struct
qib_devdata
*
dd
;
int
ret
;
#ifndef CONFIG_PCI_MSI
qib_early_err
(
&
pdev
->
dev
,
"QLogic PCIE device 0x%x cannot "
"work if CONFIG_PCI_MSI is not enabled
\n
"
,
ent
->
device
);
dd
=
ERR_PTR
(
-
ENODEV
);
goto
bail
;
#endif
dd
=
qib_alloc_devdata
(
pdev
,
sizeof
(
struct
qib_pportdata
)
+
sizeof
(
struct
qib_chip_specific
));
if
(
IS_ERR
(
dd
))
...
...
@@ -3554,10 +3546,6 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev,
if
(
qib_mini_init
)
goto
bail
;
#ifndef CONFIG_PCI_MSI
qib_dev_err
(
dd
,
"PCI_MSI not configured, NO interrupts
\n
"
);
#endif
if
(
qib_pcie_params
(
dd
,
8
,
NULL
,
NULL
))
qib_dev_err
(
dd
,
"Failed to setup PCIe or interrupts; "
"continuing anyway
\n
"
);
...
...
drivers/infiniband/hw/qib/qib_iba7322.c
浏览文件 @
767dcd42
...
...
@@ -42,9 +42,6 @@
#include <linux/jiffies.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_smi.h>
#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
#include <linux/dca.h>
#endif
#include "qib.h"
#include "qib_7322_regs.h"
...
...
@@ -114,40 +111,18 @@ static ushort qib_singleport;
module_param_named
(
singleport
,
qib_singleport
,
ushort
,
S_IRUGO
);
MODULE_PARM_DESC
(
singleport
,
"Use only IB port 1; more per-port buffer space"
);
/*
* Setup QMH7342 receive and transmit parameters, necessary because
* each bay, Mez connector, and IB port need different tuning, beyond
* what the switch and HCA can do automatically.
* It's expected to be done by cat'ing files to the modules file,
* rather than setting up as a module parameter.
* It's a "write-only" file, returns 0 when read back.
* The unit, port, bay (if given), and values MUST be done as a single write.
* The unit, port, and bay must precede the values to be effective.
*/
static
int
setup_qmh_params
(
const
char
*
,
struct
kernel_param
*
);
static
unsigned
dummy_qmh_params
;
module_param_call
(
qmh_serdes_setup
,
setup_qmh_params
,
param_get_uint
,
&
dummy_qmh_params
,
S_IWUSR
|
S_IRUGO
);
/* similarly for QME7342, but it's simpler */
static
int
setup_qme_params
(
const
char
*
,
struct
kernel_param
*
);
static
unsigned
dummy_qme_params
;
module_param_call
(
qme_serdes_setup
,
setup_qme_params
,
param_get_uint
,
&
dummy_qme_params
,
S_IWUSR
|
S_IRUGO
);
#define MAX_ATTEN_LEN 64
/* plenty for any real system */
/* for read back, default index is ~5m copper cable */
static
char
cable_atten
_list
[
MAX_ATTEN_LEN
]
=
"10"
;
static
struct
kparam_string
kp_
cable_atten
=
{
.
string
=
cable_atten
_list
,
static
char
txselect
_list
[
MAX_ATTEN_LEN
]
=
"10"
;
static
struct
kparam_string
kp_
txselect
=
{
.
string
=
txselect
_list
,
.
maxlen
=
MAX_ATTEN_LEN
};
static
int
setup_
cable_atten
(
const
char
*
,
struct
kernel_param
*
);
module_param_call
(
cable_atten
,
setup_cable_atten
,
param_get_string
,
&
kp_
cable_atten
,
S_IWUSR
|
S_IRUGO
);
MODULE_PARM_DESC
(
cable_atten
,
\
"
cable attenuation indices for cables with invalid EEPROM
"
);
static
int
setup_
txselect
(
const
char
*
,
struct
kernel_param
*
);
module_param_call
(
txselect
,
setup_txselect
,
param_get_string
,
&
kp_
txselect
,
S_IWUSR
|
S_IRUGO
);
MODULE_PARM_DESC
(
txselect
,
\
"
Tx serdes indices (for no QSFP or invalid QSFP data)
"
);
#define BOARD_QME7342 5
#define BOARD_QMH7342 6
...
...
@@ -540,12 +515,6 @@ struct qib_chip_specific {
u32
lastbuf_for_pio
;
u32
stay_in_freeze
;
u32
recovery_ports_initted
;
#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
u32
dca_ctrl
;
int
rhdr_cpu
[
18
];
int
sdma_cpu
[
2
];
u64
dca_rcvhdr_ctrl
[
5
];
/* B, C, D, E, F */
#endif
struct
msix_entry
*
msix_entries
;
void
**
msix_arg
;
unsigned
long
*
sendchkenable
;
...
...
@@ -574,11 +543,12 @@ struct vendor_txdds_ent {
static
void
write_tx_serdes_param
(
struct
qib_pportdata
*
,
struct
txdds_ent
*
);
#define TXDDS_TABLE_SZ 16
/* number of entries per speed in onchip table */
#define TXDDS_EXTRA_SZ 11
/* number of extra tx settings entries */
#define SERDES_CHANS 4
/* yes, it's obvious, but one less magic number */
#define H1_FORCE_VAL 8
#define H1_FORCE_QME 1
/* may be overridden via setup_
qme_params
() */
#define H1_FORCE_QMH 7
/* may be overridden via setup_
qmh_params
() */
#define H1_FORCE_QME 1
/* may be overridden via setup_
txselect
() */
#define H1_FORCE_QMH 7
/* may be overridden via setup_
txselect
() */
/* The static and dynamic registers are paired, and the pairs indexed by spd */
#define krp_static_adapt_dis(spd) (KREG_IBPORT_IDX(ADAPT_DISABLE_STATIC_SDR) \
...
...
@@ -590,15 +560,6 @@ static void write_tx_serdes_param(struct qib_pportdata *, struct txdds_ent *);
#define QDR_STATIC_ADAPT_INIT 0xffffffffffULL
/* up, disable H0,H1-8, LE */
#define QDR_STATIC_ADAPT_INIT_R1 0xf0ffffffffULL
/* r1 up, disable H0,H1-8 */
static
const
struct
txdds_ent
qmh_sdr_txdds
=
{
11
,
0
,
5
,
6
};
static
const
struct
txdds_ent
qmh_ddr_txdds
=
{
7
,
0
,
2
,
8
};
static
const
struct
txdds_ent
qmh_qdr_txdds
=
{
0
,
1
,
3
,
10
};
/* this is used for unknown mez cards also */
static
const
struct
txdds_ent
qme_sdr_txdds
=
{
11
,
0
,
4
,
4
};
static
const
struct
txdds_ent
qme_ddr_txdds
=
{
7
,
0
,
2
,
7
};
static
const
struct
txdds_ent
qme_qdr_txdds
=
{
0
,
1
,
12
,
11
};
struct
qib_chippport_specific
{
u64
__iomem
*
kpregbase
;
u64
__iomem
*
cpregbase
;
...
...
@@ -637,12 +598,8 @@ struct qib_chippport_specific {
* Per-bay per-channel rcv QMH H1 values and Tx values for QDR.
* entry zero is unused, to simplify indexing
*/
u16
h1_val
;
u8
amp
[
SERDES_CHANS
];
u8
pre
[
SERDES_CHANS
];
u8
mainv
[
SERDES_CHANS
];
u8
post
[
SERDES_CHANS
];
u8
no_eep
;
/* attenuation index to use if no qsfp info */
u8
h1_val
;
u8
no_eep
;
/* txselect table index to use if no qsfp info */
u8
ipg_tries
;
u8
ibmalfusesnap
;
struct
qib_qsfp_data
qsfp_data
;
...
...
@@ -676,52 +633,6 @@ static struct {
SYM_LSB
(
IntStatus
,
SDmaCleanupDone_1
),
2
},
};
#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
static
const
struct
dca_reg_map
{
int
shadow_inx
;
int
lsb
;
u64
mask
;
u16
regno
;
}
dca_rcvhdr_reg_map
[]
=
{
{
0
,
SYM_LSB
(
DCACtrlB
,
RcvHdrq0DCAOPH
),
~
SYM_MASK
(
DCACtrlB
,
RcvHdrq0DCAOPH
)
,
KREG_IDX
(
DCACtrlB
)
},
{
0
,
SYM_LSB
(
DCACtrlB
,
RcvHdrq1DCAOPH
),
~
SYM_MASK
(
DCACtrlB
,
RcvHdrq1DCAOPH
)
,
KREG_IDX
(
DCACtrlB
)
},
{
0
,
SYM_LSB
(
DCACtrlB
,
RcvHdrq2DCAOPH
),
~
SYM_MASK
(
DCACtrlB
,
RcvHdrq2DCAOPH
)
,
KREG_IDX
(
DCACtrlB
)
},
{
0
,
SYM_LSB
(
DCACtrlB
,
RcvHdrq3DCAOPH
),
~
SYM_MASK
(
DCACtrlB
,
RcvHdrq3DCAOPH
)
,
KREG_IDX
(
DCACtrlB
)
},
{
1
,
SYM_LSB
(
DCACtrlC
,
RcvHdrq4DCAOPH
),
~
SYM_MASK
(
DCACtrlC
,
RcvHdrq4DCAOPH
)
,
KREG_IDX
(
DCACtrlC
)
},
{
1
,
SYM_LSB
(
DCACtrlC
,
RcvHdrq5DCAOPH
),
~
SYM_MASK
(
DCACtrlC
,
RcvHdrq5DCAOPH
)
,
KREG_IDX
(
DCACtrlC
)
},
{
1
,
SYM_LSB
(
DCACtrlC
,
RcvHdrq6DCAOPH
),
~
SYM_MASK
(
DCACtrlC
,
RcvHdrq6DCAOPH
)
,
KREG_IDX
(
DCACtrlC
)
},
{
1
,
SYM_LSB
(
DCACtrlC
,
RcvHdrq7DCAOPH
),
~
SYM_MASK
(
DCACtrlC
,
RcvHdrq7DCAOPH
)
,
KREG_IDX
(
DCACtrlC
)
},
{
2
,
SYM_LSB
(
DCACtrlD
,
RcvHdrq8DCAOPH
),
~
SYM_MASK
(
DCACtrlD
,
RcvHdrq8DCAOPH
)
,
KREG_IDX
(
DCACtrlD
)
},
{
2
,
SYM_LSB
(
DCACtrlD
,
RcvHdrq9DCAOPH
),
~
SYM_MASK
(
DCACtrlD
,
RcvHdrq9DCAOPH
)
,
KREG_IDX
(
DCACtrlD
)
},
{
2
,
SYM_LSB
(
DCACtrlD
,
RcvHdrq10DCAOPH
),
~
SYM_MASK
(
DCACtrlD
,
RcvHdrq10DCAOPH
)
,
KREG_IDX
(
DCACtrlD
)
},
{
2
,
SYM_LSB
(
DCACtrlD
,
RcvHdrq11DCAOPH
),
~
SYM_MASK
(
DCACtrlD
,
RcvHdrq11DCAOPH
)
,
KREG_IDX
(
DCACtrlD
)
},
{
3
,
SYM_LSB
(
DCACtrlE
,
RcvHdrq12DCAOPH
),
~
SYM_MASK
(
DCACtrlE
,
RcvHdrq12DCAOPH
)
,
KREG_IDX
(
DCACtrlE
)
},
{
3
,
SYM_LSB
(
DCACtrlE
,
RcvHdrq13DCAOPH
),
~
SYM_MASK
(
DCACtrlE
,
RcvHdrq13DCAOPH
)
,
KREG_IDX
(
DCACtrlE
)
},
{
3
,
SYM_LSB
(
DCACtrlE
,
RcvHdrq14DCAOPH
),
~
SYM_MASK
(
DCACtrlE
,
RcvHdrq14DCAOPH
)
,
KREG_IDX
(
DCACtrlE
)
},
{
3
,
SYM_LSB
(
DCACtrlE
,
RcvHdrq15DCAOPH
),
~
SYM_MASK
(
DCACtrlE
,
RcvHdrq15DCAOPH
)
,
KREG_IDX
(
DCACtrlE
)
},
{
4
,
SYM_LSB
(
DCACtrlF
,
RcvHdrq16DCAOPH
),
~
SYM_MASK
(
DCACtrlF
,
RcvHdrq16DCAOPH
)
,
KREG_IDX
(
DCACtrlF
)
},
{
4
,
SYM_LSB
(
DCACtrlF
,
RcvHdrq17DCAOPH
),
~
SYM_MASK
(
DCACtrlF
,
RcvHdrq17DCAOPH
)
,
KREG_IDX
(
DCACtrlF
)
},
};
#endif
/* ibcctrl bits */
#define QLOGIC_IB_IBCC_LINKINITCMD_DISABLE 1
/* cycle through TS1/TS2 till OK */
...
...
@@ -2572,95 +2483,6 @@ static void qib_setup_7322_setextled(struct qib_pportdata *ppd, u32 on)
qib_write_kreg_port
(
ppd
,
krp_rcvpktledcnt
,
ledblink
);
}
#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
static
void
qib_update_rhdrq_dca
(
struct
qib_ctxtdata
*
rcd
)
{
struct
qib_devdata
*
dd
=
rcd
->
dd
;
struct
qib_chip_specific
*
cspec
=
dd
->
cspec
;
int
cpu
=
get_cpu
();
if
(
cspec
->
rhdr_cpu
[
rcd
->
ctxt
]
!=
cpu
)
{
const
struct
dca_reg_map
*
rmp
;
cspec
->
rhdr_cpu
[
rcd
->
ctxt
]
=
cpu
;
rmp
=
&
dca_rcvhdr_reg_map
[
rcd
->
ctxt
];
cspec
->
dca_rcvhdr_ctrl
[
rmp
->
shadow_inx
]
&=
rmp
->
mask
;
cspec
->
dca_rcvhdr_ctrl
[
rmp
->
shadow_inx
]
|=
(
u64
)
dca3_get_tag
(
&
dd
->
pcidev
->
dev
,
cpu
)
<<
rmp
->
lsb
;
qib_write_kreg
(
dd
,
rmp
->
regno
,
cspec
->
dca_rcvhdr_ctrl
[
rmp
->
shadow_inx
]);
cspec
->
dca_ctrl
|=
SYM_MASK
(
DCACtrlA
,
RcvHdrqDCAEnable
);
qib_write_kreg
(
dd
,
KREG_IDX
(
DCACtrlA
),
cspec
->
dca_ctrl
);
}
put_cpu
();
}
static
void
qib_update_sdma_dca
(
struct
qib_pportdata
*
ppd
)
{
struct
qib_devdata
*
dd
=
ppd
->
dd
;
struct
qib_chip_specific
*
cspec
=
dd
->
cspec
;
int
cpu
=
get_cpu
();
unsigned
pidx
=
ppd
->
port
-
1
;
if
(
cspec
->
sdma_cpu
[
pidx
]
!=
cpu
)
{
cspec
->
sdma_cpu
[
pidx
]
=
cpu
;
cspec
->
dca_rcvhdr_ctrl
[
4
]
&=
~
(
ppd
->
hw_pidx
?
SYM_MASK
(
DCACtrlF
,
SendDma1DCAOPH
)
:
SYM_MASK
(
DCACtrlF
,
SendDma0DCAOPH
));
cspec
->
dca_rcvhdr_ctrl
[
4
]
|=
(
u64
)
dca3_get_tag
(
&
dd
->
pcidev
->
dev
,
cpu
)
<<
(
ppd
->
hw_pidx
?
SYM_LSB
(
DCACtrlF
,
SendDma1DCAOPH
)
:
SYM_LSB
(
DCACtrlF
,
SendDma0DCAOPH
));
qib_write_kreg
(
dd
,
KREG_IDX
(
DCACtrlF
),
cspec
->
dca_rcvhdr_ctrl
[
4
]);
cspec
->
dca_ctrl
|=
ppd
->
hw_pidx
?
SYM_MASK
(
DCACtrlA
,
SendDMAHead1DCAEnable
)
:
SYM_MASK
(
DCACtrlA
,
SendDMAHead0DCAEnable
);
qib_write_kreg
(
dd
,
KREG_IDX
(
DCACtrlA
),
cspec
->
dca_ctrl
);
}
put_cpu
();
}
static
void
qib_setup_dca
(
struct
qib_devdata
*
dd
)
{
struct
qib_chip_specific
*
cspec
=
dd
->
cspec
;
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
cspec
->
rhdr_cpu
);
i
++
)
cspec
->
rhdr_cpu
[
i
]
=
-
1
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
cspec
->
sdma_cpu
);
i
++
)
cspec
->
sdma_cpu
[
i
]
=
-
1
;
cspec
->
dca_rcvhdr_ctrl
[
0
]
=
(
1ULL
<<
SYM_LSB
(
DCACtrlB
,
RcvHdrq0DCAXfrCnt
))
|
(
1ULL
<<
SYM_LSB
(
DCACtrlB
,
RcvHdrq1DCAXfrCnt
))
|
(
1ULL
<<
SYM_LSB
(
DCACtrlB
,
RcvHdrq2DCAXfrCnt
))
|
(
1ULL
<<
SYM_LSB
(
DCACtrlB
,
RcvHdrq3DCAXfrCnt
));
cspec
->
dca_rcvhdr_ctrl
[
1
]
=
(
1ULL
<<
SYM_LSB
(
DCACtrlC
,
RcvHdrq4DCAXfrCnt
))
|
(
1ULL
<<
SYM_LSB
(
DCACtrlC
,
RcvHdrq5DCAXfrCnt
))
|
(
1ULL
<<
SYM_LSB
(
DCACtrlC
,
RcvHdrq6DCAXfrCnt
))
|
(
1ULL
<<
SYM_LSB
(
DCACtrlC
,
RcvHdrq7DCAXfrCnt
));
cspec
->
dca_rcvhdr_ctrl
[
2
]
=
(
1ULL
<<
SYM_LSB
(
DCACtrlD
,
RcvHdrq8DCAXfrCnt
))
|
(
1ULL
<<
SYM_LSB
(
DCACtrlD
,
RcvHdrq9DCAXfrCnt
))
|
(
1ULL
<<
SYM_LSB
(
DCACtrlD
,
RcvHdrq10DCAXfrCnt
))
|
(
1ULL
<<
SYM_LSB
(
DCACtrlD
,
RcvHdrq11DCAXfrCnt
));
cspec
->
dca_rcvhdr_ctrl
[
3
]
=
(
1ULL
<<
SYM_LSB
(
DCACtrlE
,
RcvHdrq12DCAXfrCnt
))
|
(
1ULL
<<
SYM_LSB
(
DCACtrlE
,
RcvHdrq13DCAXfrCnt
))
|
(
1ULL
<<
SYM_LSB
(
DCACtrlE
,
RcvHdrq14DCAXfrCnt
))
|
(
1ULL
<<
SYM_LSB
(
DCACtrlE
,
RcvHdrq15DCAXfrCnt
));
cspec
->
dca_rcvhdr_ctrl
[
4
]
=
(
1ULL
<<
SYM_LSB
(
DCACtrlF
,
RcvHdrq16DCAXfrCnt
))
|
(
1ULL
<<
SYM_LSB
(
DCACtrlF
,
RcvHdrq17DCAXfrCnt
));
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
cspec
->
sdma_cpu
);
i
++
)
qib_write_kreg
(
dd
,
KREG_IDX
(
DCACtrlB
)
+
i
,
cspec
->
dca_rcvhdr_ctrl
[
i
]);
}
#endif
/*
* Disable MSIx interrupt if enabled, call generic MSIx code
* to cleanup, and clear pending MSIx interrupts.
...
...
@@ -2701,15 +2523,6 @@ static void qib_setup_7322_cleanup(struct qib_devdata *dd)
{
int
i
;
#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if
(
dd
->
flags
&
QIB_DCA_ENABLED
)
{
dca_remove_requester
(
&
dd
->
pcidev
->
dev
);
dd
->
flags
&=
~
QIB_DCA_ENABLED
;
dd
->
cspec
->
dca_ctrl
=
0
;
qib_write_kreg
(
dd
,
KREG_IDX
(
DCACtrlA
),
dd
->
cspec
->
dca_ctrl
);
}
#endif
qib_7322_free_irq
(
dd
);
kfree
(
dd
->
cspec
->
cntrs
);
kfree
(
dd
->
cspec
->
sendchkenable
);
...
...
@@ -3017,11 +2830,6 @@ static irqreturn_t qib_7322pintr(int irq, void *data)
if
(
dd
->
int_counter
!=
(
u32
)
-
1
)
dd
->
int_counter
++
;
#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if
(
dd
->
flags
&
QIB_DCA_ENABLED
)
qib_update_rhdrq_dca
(
rcd
);
#endif
/* Clear the interrupt bit we expect to be set. */
qib_write_kreg
(
dd
,
kr_intclear
,
((
1ULL
<<
QIB_I_RCVAVAIL_LSB
)
|
(
1ULL
<<
QIB_I_RCVURG_LSB
))
<<
rcd
->
ctxt
);
...
...
@@ -3085,11 +2893,6 @@ static irqreturn_t sdma_intr(int irq, void *data)
if
(
dd
->
int_counter
!=
(
u32
)
-
1
)
dd
->
int_counter
++
;
#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if
(
dd
->
flags
&
QIB_DCA_ENABLED
)
qib_update_sdma_dca
(
ppd
);
#endif
/* Clear the interrupt bit we expect to be set. */
qib_write_kreg
(
dd
,
kr_intclear
,
ppd
->
hw_pidx
?
INT_MASK_P
(
SDma
,
1
)
:
INT_MASK_P
(
SDma
,
0
));
...
...
@@ -3119,11 +2922,6 @@ static irqreturn_t sdma_idle_intr(int irq, void *data)
if
(
dd
->
int_counter
!=
(
u32
)
-
1
)
dd
->
int_counter
++
;
#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if
(
dd
->
flags
&
QIB_DCA_ENABLED
)
qib_update_sdma_dca
(
ppd
);
#endif
/* Clear the interrupt bit we expect to be set. */
qib_write_kreg
(
dd
,
kr_intclear
,
ppd
->
hw_pidx
?
INT_MASK_P
(
SDmaIdle
,
1
)
:
INT_MASK_P
(
SDmaIdle
,
0
));
...
...
@@ -3153,11 +2951,6 @@ static irqreturn_t sdma_progress_intr(int irq, void *data)
if
(
dd
->
int_counter
!=
(
u32
)
-
1
)
dd
->
int_counter
++
;
#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if
(
dd
->
flags
&
QIB_DCA_ENABLED
)
qib_update_sdma_dca
(
ppd
);
#endif
/* Clear the interrupt bit we expect to be set. */
qib_write_kreg
(
dd
,
kr_intclear
,
ppd
->
hw_pidx
?
INT_MASK_P
(
SDmaProgress
,
1
)
:
...
...
@@ -3188,11 +2981,6 @@ static irqreturn_t sdma_cleanup_intr(int irq, void *data)
if
(
dd
->
int_counter
!=
(
u32
)
-
1
)
dd
->
int_counter
++
;
#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if
(
dd
->
flags
&
QIB_DCA_ENABLED
)
qib_update_sdma_dca
(
ppd
);
#endif
/* Clear the interrupt bit we expect to be set. */
qib_write_kreg
(
dd
,
kr_intclear
,
ppd
->
hw_pidx
?
INT_MASK_PM
(
SDmaCleanupDone
,
1
)
:
...
...
@@ -4299,10 +4087,6 @@ static void rcvctrl_7322_mod(struct qib_pportdata *ppd, unsigned int op,
qib_write_kreg_ctxt
(
dd
,
krc_rcvhdraddr
,
ctxt
,
rcd
->
rcvhdrq_phys
);
rcd
->
seq_cnt
=
1
;
#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
if
(
dd
->
flags
&
QIB_DCA_ENABLED
)
qib_update_rhdrq_dca
(
rcd
);
#endif
}
if
(
op
&
QIB_RCVCTRL_CTXT_DIS
)
ppd
->
p_rcvctrl
&=
...
...
@@ -5360,7 +5144,13 @@ static int qib_7322_ib_updown(struct qib_pportdata *ppd, int ibup, u64 ibcs)
QIBL_IB_AUTONEG_INPROG
)))
set_7322_ibspeed_fast
(
ppd
,
ppd
->
link_speed_enabled
);
if
(
!
(
ppd
->
lflags
&
QIBL_IB_AUTONEG_INPROG
))
{
/* unlock the Tx settings, speed may change */
qib_write_kreg_port
(
ppd
,
krp_tx_deemph_override
,
SYM_MASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
reset_tx_deemphasis_override
));
qib_cancel_sends
(
ppd
);
/* on link down, ensure sane pcs state */
qib_7322_mini_pcs_reset
(
ppd
);
spin_lock_irqsave
(
&
ppd
->
sdma_lock
,
flags
);
if
(
__qib_sdma_running
(
ppd
))
__qib_sdma_process_event
(
ppd
,
...
...
@@ -5766,26 +5556,28 @@ static void qib_init_7322_qsfp(struct qib_pportdata *ppd)
}
/*
* called at device initialization time, and also if the
cable_atten
* called at device initialization time, and also if the
txselect
* module parameter is changed. This is used for cables that don't
* have valid QSFP EEPROMs (not present, or attenuation is zero).
* We initialize to the default, then if there is a specific
* unit,port match, we use that.
* unit,port match, we use that (and set it immediately, for the
* current speed, if the link is at INIT or better).
* String format is "default# unit#,port#=# ... u,p=#", separators must
* be a SPACE character. A newline terminates.
* be a SPACE character. A newline terminates. The u,p=# tuples may
* optionally have "u,p=#,#", where the final # is the H1 value
* The last specific match is used (actually, all are used, but last
* one is the one that winds up set); if none at all, fall back on default.
*/
static
void
set_no_qsfp_atten
(
struct
qib_devdata
*
dd
,
int
change
)
{
char
*
nxt
,
*
str
;
int
pidx
,
unit
,
port
,
deflt
;
u32
pidx
,
unit
,
port
,
deflt
,
h1
;
unsigned
long
val
;
int
any
=
0
;
int
any
=
0
,
seth1
;
str
=
cable_atten
_list
;
str
=
txselect
_list
;
/* default number is validated in setup_
cable_atten
() */
/* default number is validated in setup_
txselect
() */
deflt
=
simple_strtoul
(
str
,
&
nxt
,
0
);
for
(
pidx
=
0
;
pidx
<
dd
->
num_pports
;
++
pidx
)
dd
->
pport
[
pidx
].
cpspec
->
no_eep
=
deflt
;
...
...
@@ -5812,16 +5604,28 @@ static void set_no_qsfp_atten(struct qib_devdata *dd, int change)
;
continue
;
}
if
(
val
>=
TXDDS_TABLE_SZ
)
if
(
val
>=
TXDDS_TABLE_SZ
+
TXDDS_EXTRA_SZ
)
continue
;
seth1
=
0
;
h1
=
0
;
/* gcc thinks it might be used uninitted */
if
(
*
nxt
==
','
&&
nxt
[
1
])
{
str
=
++
nxt
;
h1
=
(
u32
)
simple_strtoul
(
str
,
&
nxt
,
0
);
if
(
nxt
==
str
)
while
(
*
nxt
&&
*
nxt
++
!=
' '
)
/* skip */
;
else
seth1
=
1
;
}
for
(
pidx
=
0
;
dd
->
unit
==
unit
&&
pidx
<
dd
->
num_pports
;
++
pidx
)
{
if
(
dd
->
pport
[
pidx
].
port
!=
port
||
!
dd
->
pport
[
pidx
].
link_speed_supported
)
struct
qib_pportdata
*
ppd
=
&
dd
->
pport
[
pidx
];
if
(
ppd
->
port
!=
port
||
!
ppd
->
link_speed_supported
)
continue
;
dd
->
pport
[
pidx
].
cpspec
->
no_eep
=
val
;
ppd
->
cpspec
->
no_eep
=
val
;
/* now change the IBC and serdes, overriding generic */
init_txdds_table
(
&
dd
->
pport
[
pidx
]
,
1
);
init_txdds_table
(
ppd
,
1
);
any
++
;
}
if
(
*
nxt
==
'\n'
)
...
...
@@ -5832,34 +5636,34 @@ static void set_no_qsfp_atten(struct qib_devdata *dd, int change)
* Change the IBC and serdes, but since it's
* general, don't override specific settings.
*/
for
(
pidx
=
0
;
pidx
<
dd
->
num_pports
;
++
pidx
)
{
if
(
!
dd
->
pport
[
pidx
].
link_speed_supported
)
continue
;
for
(
pidx
=
0
;
pidx
<
dd
->
num_pports
;
++
pidx
)
if
(
dd
->
pport
[
pidx
].
link_speed_supported
)
init_txdds_table
(
&
dd
->
pport
[
pidx
],
0
);
}
}
}
/* handle the
cable_atten
parameter changing */
static
int
setup_
cable_atten
(
const
char
*
str
,
struct
kernel_param
*
kp
)
/* handle the
txselect
parameter changing */
static
int
setup_
txselect
(
const
char
*
str
,
struct
kernel_param
*
kp
)
{
struct
qib_devdata
*
dd
;
unsigned
long
val
;
char
*
n
;
if
(
strlen
(
str
)
>=
MAX_ATTEN_LEN
)
{
printk
(
KERN_INFO
QIB_DRV_NAME
"
cable_atten
_values string "
printk
(
KERN_INFO
QIB_DRV_NAME
"
txselect
_values string "
"too long
\n
"
);
return
-
ENOSPC
;
}
val
=
simple_strtoul
(
str
,
&
n
,
0
);
if
(
n
==
str
||
val
>=
TXDDS_TABLE_SZ
)
{
if
(
n
==
str
||
val
>=
(
TXDDS_TABLE_SZ
+
TXDDS_EXTRA_SZ
)
)
{
printk
(
KERN_INFO
QIB_DRV_NAME
"cable_atten_values must start with a number
\n
"
);
"txselect_values must start with a number < %d
\n
"
,
TXDDS_TABLE_SZ
+
TXDDS_EXTRA_SZ
);
return
-
EINVAL
;
}
strcpy
(
cable_atten
_list
,
str
);
strcpy
(
txselect
_list
,
str
);
list_for_each_entry
(
dd
,
&
qib_dev_list
,
list
)
if
(
dd
->
deviceid
==
PCI_DEVICE_ID_QLOGIC_IB_7322
)
set_no_qsfp_atten
(
dd
,
1
);
return
0
;
}
...
...
@@ -6261,28 +6065,17 @@ static int qib_init_7322_variables(struct qib_devdata *dd)
* in adapter-specific routines.
*/
if
(
!
(
ppd
->
dd
->
flags
&
QIB_HAS_QSFP
))
{
int
i
;
const
struct
txdds_ent
*
txdds
;
if
(
!
IS_QMH
(
ppd
->
dd
)
&&
!
IS_QME
(
ppd
->
dd
))
qib_devinfo
(
ppd
->
dd
->
pcidev
,
"IB%u:%u: "
"Unknown mezzanine card type
\n
"
,
ppd
->
dd
->
unit
,
ppd
->
port
);
txdds
=
IS_QMH
(
ppd
->
dd
)
?
&
qmh_qdr_txdds
:
&
qme_qdr_txdds
;
dd
->
unit
,
ppd
->
port
);
cp
->
h1_val
=
IS_QMH
(
dd
)
?
H1_FORCE_QMH
:
H1_FORCE_QME
;
/*
*
set values in case link comes up
*
before table is written to driv
er.
*
Choose center value as default tx serdes setting
*
until changed through module paramet
er.
*/
cp
->
h1_val
=
IS_QMH
(
ppd
->
dd
)
?
H1_FORCE_QMH
:
H1_FORCE_QME
;
for
(
i
=
0
;
i
<
SERDES_CHANS
;
i
++
)
{
cp
->
amp
[
i
]
=
txdds
->
amp
;
cp
->
pre
[
i
]
=
txdds
->
pre
;
cp
->
mainv
[
i
]
=
txdds
->
main
;
cp
->
post
[
i
]
=
txdds
->
post
;
}
ppd
->
cpspec
->
no_eep
=
IS_QMH
(
dd
)
?
TXDDS_TABLE_SZ
+
2
:
TXDDS_TABLE_SZ
+
4
;
}
else
cp
->
h1_val
=
H1_FORCE_VAL
;
...
...
@@ -6299,8 +6092,7 @@ static int qib_init_7322_variables(struct qib_devdata *dd)
dd
->
rcvhdrentsize
=
QIB_RCVHDR_ENTSIZE
;
dd
->
rcvhdrsize
=
QIB_DFLT_RCVHDRSIZE
;
dd
->
rhf_offset
=
dd
->
rcvhdrentsize
-
sizeof
(
u64
)
/
sizeof
(
u32
);
dd
->
rhf_offset
=
dd
->
rcvhdrentsize
-
sizeof
(
u64
)
/
sizeof
(
u32
);
/* we always allocate at least 2048 bytes for eager buffers */
dd
->
rcvegrbufsize
=
max
(
mtu
,
2048
);
...
...
@@ -6919,13 +6711,6 @@ struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *pdev,
/* clear diagctrl register, in case diags were running and crashed */
qib_write_kreg
(
dd
,
kr_hwdiagctrl
,
0
);
#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
ret
=
dca_add_requester
(
&
pdev
->
dev
);
if
(
!
ret
)
{
dd
->
flags
|=
QIB_DCA_ENABLED
;
qib_setup_dca
(
dd
);
}
#endif
goto
bail
;
bail_cleanup:
...
...
@@ -7111,8 +6896,8 @@ static const struct txdds_ent txdds_ddr[TXDDS_TABLE_SZ] = {
static
const
struct
txdds_ent
txdds_qdr
[
TXDDS_TABLE_SZ
]
=
{
/* amp, pre, main, post */
{
2
,
2
,
15
,
6
},
/* Loopback */
{
0
,
1
,
0
,
7
},
/* 2 dB */
{
0
,
1
,
0
,
9
},
/* 3 dB */
{
0
,
1
,
0
,
7
},
/* 2 dB
(also QMH7342)
*/
{
0
,
1
,
0
,
9
},
/* 3 dB
(also QMH7342)
*/
{
0
,
1
,
0
,
11
},
/* 4 dB */
{
0
,
1
,
0
,
13
},
/* 5 dB */
{
0
,
1
,
0
,
15
},
/* 6 dB */
...
...
@@ -7128,6 +6913,57 @@ static const struct txdds_ent txdds_qdr[TXDDS_TABLE_SZ] = {
{
0
,
2
,
9
,
15
},
/* 16 dB */
};
/*
* extra entries for use with txselect, for indices >= TXDDS_TABLE_SZ.
* These are mostly used for mez cards going through connectors
* and backplane traces, but can be used to add other "unusual"
* table values as well.
*/
static
const
struct
txdds_ent
txdds_extra_sdr
[
TXDDS_EXTRA_SZ
]
=
{
/* amp, pre, main, post */
{
0
,
0
,
0
,
1
},
/* QMH7342 backplane settings */
{
0
,
0
,
0
,
1
},
/* QMH7342 backplane settings */
{
0
,
0
,
0
,
2
},
/* QMH7342 backplane settings */
{
0
,
0
,
0
,
2
},
/* QMH7342 backplane settings */
{
0
,
0
,
0
,
11
},
/* QME7342 backplane settings */
{
0
,
0
,
0
,
11
},
/* QME7342 backplane settings */
{
0
,
0
,
0
,
11
},
/* QME7342 backplane settings */
{
0
,
0
,
0
,
11
},
/* QME7342 backplane settings */
{
0
,
0
,
0
,
11
},
/* QME7342 backplane settings */
{
0
,
0
,
0
,
11
},
/* QME7342 backplane settings */
{
0
,
0
,
0
,
11
},
/* QME7342 backplane settings */
};
static
const
struct
txdds_ent
txdds_extra_ddr
[
TXDDS_EXTRA_SZ
]
=
{
/* amp, pre, main, post */
{
0
,
0
,
0
,
7
},
/* QMH7342 backplane settings */
{
0
,
0
,
0
,
7
},
/* QMH7342 backplane settings */
{
0
,
0
,
0
,
8
},
/* QMH7342 backplane settings */
{
0
,
0
,
0
,
8
},
/* QMH7342 backplane settings */
{
0
,
0
,
0
,
13
},
/* QME7342 backplane settings */
{
0
,
0
,
0
,
13
},
/* QME7342 backplane settings */
{
0
,
0
,
0
,
13
},
/* QME7342 backplane settings */
{
0
,
0
,
0
,
13
},
/* QME7342 backplane settings */
{
0
,
0
,
0
,
13
},
/* QME7342 backplane settings */
{
0
,
0
,
0
,
13
},
/* QME7342 backplane settings */
{
0
,
0
,
0
,
13
},
/* QME7342 backplane settings */
};
static
const
struct
txdds_ent
txdds_extra_qdr
[
TXDDS_EXTRA_SZ
]
=
{
/* amp, pre, main, post */
{
0
,
1
,
0
,
4
},
/* QMH7342 backplane settings */
{
0
,
1
,
0
,
5
},
/* QMH7342 backplane settings */
{
0
,
1
,
0
,
6
},
/* QMH7342 backplane settings */
{
0
,
1
,
0
,
8
},
/* QMH7342 backplane settings */
{
0
,
1
,
12
,
10
},
/* QME7342 backplane setting */
{
0
,
1
,
12
,
11
},
/* QME7342 backplane setting */
{
0
,
1
,
12
,
12
},
/* QME7342 backplane setting */
{
0
,
1
,
12
,
14
},
/* QME7342 backplane setting */
{
0
,
1
,
12
,
6
},
/* QME7342 backplane setting */
{
0
,
1
,
12
,
7
},
/* QME7342 backplane setting */
{
0
,
1
,
12
,
8
},
/* QME7342 backplane setting */
};
static
const
struct
txdds_ent
*
get_atten_table
(
const
struct
txdds_ent
*
txdds
,
unsigned
atten
)
{
...
...
@@ -7145,7 +6981,7 @@ static const struct txdds_ent *get_atten_table(const struct txdds_ent *txdds,
}
/*
* if override is set, the module parameter
cable_atten
has a value
* if override is set, the module parameter
txselect
has a value
* for this specific port, so use it, rather than our normal mechanism.
*/
static
void
find_best_ent
(
struct
qib_pportdata
*
ppd
,
...
...
@@ -7184,15 +7020,28 @@ static void find_best_ent(struct qib_pportdata *ppd,
*
ddr_dds
=
get_atten_table
(
txdds_ddr
,
qd
->
atten
[
0
]);
*
qdr_dds
=
get_atten_table
(
txdds_qdr
,
qd
->
atten
[
1
]);
return
;
}
else
{
}
else
if
(
ppd
->
cpspec
->
no_eep
<
TXDDS_TABLE_SZ
)
{
/*
* If we have no (or incomplete) data from the cable
* EEPROM, or no QSFP, use the module parameter value
* to index into the attentuation table.
*/
*
sdr_dds
=
&
txdds_sdr
[
ppd
->
cpspec
->
no_eep
];
*
ddr_dds
=
&
txdds_ddr
[
ppd
->
cpspec
->
no_eep
];
*
qdr_dds
=
&
txdds_qdr
[
ppd
->
cpspec
->
no_eep
];
* EEPROM, or no QSFP, or override is set, use the
* module parameter value to index into the attentuation
* table.
*/
idx
=
ppd
->
cpspec
->
no_eep
;
*
sdr_dds
=
&
txdds_sdr
[
idx
];
*
ddr_dds
=
&
txdds_ddr
[
idx
];
*
qdr_dds
=
&
txdds_qdr
[
idx
];
}
else
if
(
ppd
->
cpspec
->
no_eep
<
(
TXDDS_TABLE_SZ
+
TXDDS_EXTRA_SZ
))
{
/* similar to above, but index into the "extra" table. */
idx
=
ppd
->
cpspec
->
no_eep
-
TXDDS_TABLE_SZ
;
*
sdr_dds
=
&
txdds_extra_sdr
[
idx
];
*
ddr_dds
=
&
txdds_extra_ddr
[
idx
];
*
qdr_dds
=
&
txdds_extra_qdr
[
idx
];
}
else
{
/* this shouldn't happen, it's range checked */
*
sdr_dds
=
txdds_sdr
+
qib_long_atten
;
*
ddr_dds
=
txdds_ddr
+
qib_long_atten
;
*
qdr_dds
=
txdds_qdr
+
qib_long_atten
;
}
}
...
...
@@ -7203,33 +7052,24 @@ static void init_txdds_table(struct qib_pportdata *ppd, int override)
int
idx
;
int
single_ent
=
0
;
if
(
IS_QMH
(
ppd
->
dd
))
{
/* normally will be overridden, via setup_qmh() */
sdr_dds
=
&
qmh_sdr_txdds
;
ddr_dds
=
&
qmh_ddr_txdds
;
qdr_dds
=
&
qmh_qdr_txdds
;
single_ent
=
1
;
}
else
if
(
IS_QME
(
ppd
->
dd
))
{
sdr_dds
=
&
qme_sdr_txdds
;
ddr_dds
=
&
qme_ddr_txdds
;
qdr_dds
=
&
qme_qdr_txdds
;
single_ent
=
1
;
}
else
find_best_ent
(
ppd
,
&
sdr_dds
,
&
ddr_dds
,
&
qdr_dds
,
override
);
/* for mez cards or override, use the selected value for all entries */
if
(
!
(
ppd
->
dd
->
flags
&
QIB_HAS_QSFP
)
||
override
)
single_ent
=
1
;
/* Fill in the first entry with the best entry found. */
set_txdds
(
ppd
,
0
,
sdr_dds
);
set_txdds
(
ppd
,
TXDDS_TABLE_SZ
,
ddr_dds
);
set_txdds
(
ppd
,
2
*
TXDDS_TABLE_SZ
,
qdr_dds
);
/*
* for our current speed, also write that value into the
* tx serdes registers.
*/
dds
=
(
struct
txdds_ent
*
)(
ppd
->
link_speed_active
==
QIB_IB_QDR
?
qdr_dds
:
(
ppd
->
link_speed_active
==
if
(
ppd
->
lflags
&
(
QIBL_LINKINIT
|
QIBL_LINKARMED
|
QIBL_LINKACTIVE
))
{
dds
=
(
struct
txdds_ent
*
)(
ppd
->
link_speed_active
==
QIB_IB_QDR
?
qdr_dds
:
(
ppd
->
link_speed_active
==
QIB_IB_DDR
?
ddr_dds
:
sdr_dds
));
write_tx_serdes_param
(
ppd
,
dds
);
}
/* Fill in the remaining entries with the default table values. */
for
(
idx
=
1
;
idx
<
ARRAY_SIZE
(
txdds_sdr
);
++
idx
)
{
...
...
@@ -7352,6 +7192,11 @@ static int serdes_7322_init(struct qib_pportdata *ppd)
*/
init_txdds_table
(
ppd
,
0
);
/* ensure no tx overrides from earlier driver loads */
qib_write_kreg_port
(
ppd
,
krp_tx_deemph_override
,
SYM_MASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
reset_tx_deemphasis_override
));
/* Patch some SerDes defaults to "Better for IB" */
/* Timing Loop Bandwidth: cdr_timing[11:9] = 0 */
ibsd_wr_allchans
(
ppd
,
2
,
0
,
BMASK
(
11
,
9
));
...
...
@@ -7421,7 +7266,7 @@ static int serdes_7322_init(struct qib_pportdata *ppd)
QDR_STATIC_ADAPT_DOWN_R1
:
QDR_STATIC_ADAPT_DOWN
);
ppd
->
cpspec
->
qdr_dfe_on
=
1
;
/*
(
FLoop LOS gate: PPM filter enabled */
/* FLoop LOS gate: PPM filter enabled */
ibsd_wr_allchans
(
ppd
,
38
,
0
<<
10
,
1
<<
10
);
/* rx offset center enabled */
...
...
@@ -7486,68 +7331,39 @@ static void write_tx_serdes_param(struct qib_pportdata *ppd,
SYM_MASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txc0_ena
)
|
SYM_MASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txcp1_ena
)
|
SYM_MASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txcn1_ena
));
deemph
|=
1ULL
<<
SYM_LSB
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
deemph
|=
SYM_MASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
tx_override_deemphasis_select
);
deemph
|=
txdds
->
amp
<<
SYM_LSB
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
deemph
|=
(
txdds
->
amp
&
SYM_RMASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txampcntl_d2a
))
<<
SYM_LSB
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txampcntl_d2a
);
deemph
|=
txdds
->
main
<<
SYM_LSB
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
deemph
|=
(
txdds
->
main
&
SYM_RMASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txc0_ena
))
<<
SYM_LSB
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txc0_ena
);
deemph
|=
txdds
->
post
<<
SYM_LSB
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
deemph
|=
(
txdds
->
post
&
SYM_RMASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txcp1_ena
))
<<
SYM_LSB
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txcp1_ena
);
deemph
|=
txdds
->
pre
<<
SYM_LSB
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
deemph
|=
(
txdds
->
pre
&
SYM_RMASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txcn1_ena
))
<<
SYM_LSB
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txcn1_ena
);
qib_write_kreg_port
(
ppd
,
krp_tx_deemph_override
,
deemph
);
}
/*
* set per-bay, per channel parameters. For now, we ignore
* do_tx, and always set tx parameters, and set them with the same value
* for all channels, using the channel 0 value. We may switch to
* per-channel settings in the future, and that method only needs
* to be done once.
* Because this also writes the IBC txdds table with a single set
* of values, it should be called only for cases where we want to completely
* force a specific setting, typically only for mez cards.
* Set the parameters for mez cards on link bounce, so they are
* always exactly what was requested. Similar logic to init_txdds
* but does just the serdes.
*/
static
void
adj_tx_serdes
(
struct
qib_pportdata
*
ppd
)
{
struct
txdds_ent
txdds
;
int
i
;
u8
*
amp
,
*
pre
,
*
mainv
,
*
post
;
/*
* Because we use TX_DEEMPHASIS_OVERRIDE, we need to
* always do tx side, just like H1, since it is cleared
* by link down
*/
amp
=
ppd
->
cpspec
->
amp
;
pre
=
ppd
->
cpspec
->
pre
;
mainv
=
ppd
->
cpspec
->
mainv
;
post
=
ppd
->
cpspec
->
post
;
amp
[
0
]
&=
SYM_RMASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txampcntl_d2a
);
mainv
[
0
]
&=
SYM_RMASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txc0_ena
);
post
[
0
]
&=
SYM_RMASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txcp1_ena
);
pre
[
0
]
&=
SYM_RMASK
(
IBSD_TX_DEEMPHASIS_OVERRIDE_0
,
txcn1_ena
);
/*
* Use the channel zero values, only, for now, for
* all channels
*/
txdds
.
amp
=
amp
[
0
];
txdds
.
pre
=
pre
[
0
];
txdds
.
main
=
mainv
[
0
];
txdds
.
post
=
post
[
0
];
/* write the QDR table for IBC use, as backup for link down */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
txdds_qdr
);
++
i
)
set_txdds
(
ppd
,
i
+
32
,
&
txdds
);
const
struct
txdds_ent
*
sdr_dds
,
*
ddr_dds
,
*
qdr_dds
;
struct
txdds_ent
*
dds
;
write_tx_serdes_param
(
ppd
,
&
txdds
);
find_best_ent
(
ppd
,
&
sdr_dds
,
&
ddr_dds
,
&
qdr_dds
,
1
);
dds
=
(
struct
txdds_ent
*
)(
ppd
->
link_speed_active
==
QIB_IB_QDR
?
qdr_dds
:
(
ppd
->
link_speed_active
==
QIB_IB_DDR
?
ddr_dds
:
sdr_dds
));
write_tx_serdes_param
(
ppd
,
dds
);
}
/* set QDR forced value for H1, if needed */
...
...
@@ -7567,235 +7383,6 @@ static void force_h1(struct qib_pportdata *ppd)
}
}
/*
* Parse the parameters for the QMH7342, to get rx and tx serdes
* settings for that Bay, for both possible mez connectors (PCIe bus)
* and IB link (one link on mez1, two possible on mez2).
*
* Data is comma or white space separated.
*
* A set of data has 7 groups, rx and tx groups have SERDES_CHANS values,
* one per IB lane (serdes channel).
* The groups are Bay, bus# H1 rcv, and amp, pre, post, main Tx values (QDR).
* The Bay # is used only for debugging currently.
* H1 values are set whenever the link goes down, or is at cfg_test or
* cfg_wait_enh. Tx values are programmed once, when this routine is called
* (and with default values at chip initialization). Values are any base, in
* strtoul style, and values are seperated by comma, or any white space
* (space, tab, newline).
*
* An example set might look like this (white space vs
* comma used for human ease of reading)
* The ordering is a set of Bay# Bus# H1, amp, pre, post, and main for mez1 IB1,
* repeat for mez2 IB1, then mez2 IB2.
*
* B B H1:0 amp:0 pre:0 post: 0 main:0
* a u H1: 1 amp: 1 pre: 1 post: 1 main: 1
* y s H1: 2 amp: 2 pre: 2 post: 2 main: 2
* H1: 4 amp: 3 pre: 3 post: 3 main: 3
* 1 3 8,6,5,6 0,0,0,0 1,1,1,1 10,10,10,10 3,3,3,3
* 1 6 7,6,6,7 0,0,0,0 1,1,1,1 10,10,10,10 3,3,3,3
* 1 6 9,7,7,8 0,0,0,0 1,1,1,1 10,10,10,10 3,3,3,3
*/
#define N_QMH_FIELDS 22
static
int
setup_qmh_params
(
const
char
*
str
,
struct
kernel_param
*
kp
)
{
char
*
abuf
,
*
v
,
*
nv
,
*
nvp
;
struct
qib_devdata
*
dd
;
struct
qib_pportdata
*
ppd
;
u32
mez
,
vlen
,
nf
,
port
,
bay
;
int
ret
=
0
,
found
=
0
;
vlen
=
strlen
(
str
)
+
1
;
abuf
=
kmalloc
(
vlen
,
GFP_KERNEL
);
if
(
!
abuf
)
{
printk
(
KERN_INFO
QIB_DRV_NAME
" Unable to allocate QMH param buffer; ignoring
\n
"
);
return
0
;
}
memcpy
(
abuf
,
str
,
vlen
);
v
=
abuf
;
/* these 3 are because gcc can't know they are set before used */
port
=
1
;
mez
=
1
;
/* used only for debugging */
bay
=
0
;
/* used only for debugging */
ppd
=
NULL
;
for
(
nf
=
0
;
(
nv
=
strsep
(
&
v
,
",
\t\n\r
"
))
&&
nf
<
(
N_QMH_FIELDS
*
3
);)
{
u32
val
;
if
(
!*
nv
)
/* allow for multiple separators */
continue
;
val
=
simple_strtoul
(
nv
,
&
nvp
,
0
);
if
(
nv
==
nvp
)
{
printk
(
KERN_INFO
QIB_DRV_NAME
" Bay%u, mez%u IB%u non-numeric value (%s) "
"field #%u, ignoring rest
\n
"
,
bay
,
mez
,
port
,
nv
,
nf
%
(
N_QMH_FIELDS
*
3
));
ret
=
-
EINVAL
;
goto
bail
;
}
if
(
!
(
nf
%
N_QMH_FIELDS
))
{
ppd
=
NULL
;
bay
=
val
;
if
(
!
bay
||
bay
>
16
)
{
printk
(
KERN_INFO
QIB_DRV_NAME
" Invalid bay # %u, field %u, "
"ignoring rest
\n
"
,
bay
,
nf
);
ret
=
-
EINVAL
;
goto
bail
;
}
}
else
if
((
nf
%
N_QMH_FIELDS
)
==
1
)
{
u32
bus
=
val
;
if
(
nf
==
1
)
{
mez
=
1
;
port
=
1
;
}
else
if
(
nf
==
(
N_QMH_FIELDS
+
1
))
{
mez
=
2
;
port
=
1
;
}
else
{
mez
=
2
;
port
=
2
;
}
list_for_each_entry
(
dd
,
&
qib_dev_list
,
list
)
{
if
(
dd
->
deviceid
!=
PCI_DEVICE_ID_QLOGIC_IB_7322
||
!
IS_QMH
(
dd
))
continue
;
/* only for QMH cards */
if
(
dd
->
pcidev
->
bus
->
number
==
bus
)
{
found
++
;
ppd
=
&
dd
->
pport
[
port
-
1
];
}
}
}
else
if
(
ppd
)
{
u32
parm
=
(
nf
%
N_QMH_FIELDS
)
-
2
;
if
(
parm
<
SERDES_CHANS
&&
!
(
parm
%
SERDES_CHANS
))
ppd
->
cpspec
->
h1_val
=
val
;
else
if
(
parm
<
(
2
*
SERDES_CHANS
))
ppd
->
cpspec
->
amp
[
parm
%
SERDES_CHANS
]
=
val
;
else
if
(
parm
<
(
3
*
SERDES_CHANS
))
ppd
->
cpspec
->
pre
[
parm
%
SERDES_CHANS
]
=
val
;
else
if
(
parm
<
(
4
*
SERDES_CHANS
))
ppd
->
cpspec
->
post
[
parm
%
SERDES_CHANS
]
=
val
;
else
{
ppd
->
cpspec
->
mainv
[
parm
%
SERDES_CHANS
]
=
val
;
/* At the end of a port, set params */
if
(
parm
==
((
5
*
SERDES_CHANS
)
-
1
))
adj_tx_serdes
(
ppd
);
}
}
nf
++
;
}
if
(
!
found
)
{
printk
(
KERN_ERR
QIB_DRV_NAME
": No match found for qmh_serdes_setup parameter
\n
"
);
ret
=
-
EINVAL
;
}
bail:
kfree
(
abuf
);
return
ret
;
}
/*
* Similarly for QME7342, but the format is simpler, values are the
* same for all mez card positions in a blade (2 or 4 per blade), but
* are different for some blades vs others, and we don't need to
* specify different parameters for different serdes channels or different
* IB ports.
* Format is: h1 amp,pre,post,main
* Alternate format (so ports can be different): Pport# h1 amp,pre,post,main
*/
#define N_QME_FIELDS 5
static
int
setup_qme_params
(
const
char
*
str
,
struct
kernel_param
*
kp
)
{
char
*
abuf
,
*
v
,
*
nv
,
*
nvp
;
struct
qib_devdata
*
dd
;
u32
vlen
,
nf
,
port
=
0
;
u8
h1
,
tx
[
4
];
/* amp, pre, post, main */
int
ret
=
-
EINVAL
;
char
*
seplist
;
vlen
=
strlen
(
str
)
+
1
;
abuf
=
kmalloc
(
vlen
,
GFP_KERNEL
);
if
(
!
abuf
)
{
printk
(
KERN_INFO
QIB_DRV_NAME
" Unable to allocate QME param buffer; ignoring
\n
"
);
return
0
;
}
strncpy
(
abuf
,
str
,
vlen
);
v
=
abuf
;
seplist
=
"
\t
"
;
h1
=
H1_FORCE_QME
;
/* gcc can't figure out always set before used */
for
(
nf
=
0
;
(
nv
=
strsep
(
&
v
,
seplist
));
)
{
u32
val
;
if
(
!*
nv
)
/* allow for multiple separators */
continue
;
if
(
!
nf
&&
*
nv
==
'P'
)
{
/* alternate format with port */
val
=
simple_strtoul
(
++
nv
,
&
nvp
,
0
);
if
(
nv
==
nvp
||
port
>=
NUM_IB_PORTS
)
{
printk
(
KERN_INFO
QIB_DRV_NAME
" %s: non-numeric port value (%s) "
"ignoring rest
\n
"
,
__func__
,
nv
);
goto
done
;
}
port
=
val
;
continue
;
/* without incrementing nf */
}
val
=
simple_strtoul
(
nv
,
&
nvp
,
0
);
if
(
nv
==
nvp
)
{
printk
(
KERN_INFO
QIB_DRV_NAME
" %s: non-numeric value (%s) "
"field #%u, ignoring rest
\n
"
,
__func__
,
nv
,
nf
);
goto
done
;
}
if
(
!
nf
)
{
h1
=
val
;
seplist
=
","
;
}
else
tx
[
nf
-
1
]
=
val
;
if
(
++
nf
==
N_QME_FIELDS
)
{
list_for_each_entry
(
dd
,
&
qib_dev_list
,
list
)
{
int
pidx
,
i
;
if
(
dd
->
deviceid
!=
PCI_DEVICE_ID_QLOGIC_IB_7322
||
!
IS_QME
(
dd
))
continue
;
/* only for QME cards */
for
(
pidx
=
0
;
pidx
<
dd
->
num_pports
;
++
pidx
)
{
struct
qib_pportdata
*
ppd
;
ppd
=
&
dd
->
pport
[
pidx
];
if
((
port
&&
ppd
->
port
!=
port
)
||
!
ppd
->
link_speed_supported
)
continue
;
ppd
->
cpspec
->
h1_val
=
h1
;
for
(
i
=
0
;
i
<
SERDES_CHANS
;
i
++
)
{
ppd
->
cpspec
->
amp
[
i
]
=
tx
[
0
];
ppd
->
cpspec
->
pre
[
i
]
=
tx
[
1
];
ppd
->
cpspec
->
post
[
i
]
=
tx
[
2
];
ppd
->
cpspec
->
mainv
[
i
]
=
tx
[
3
];
}
adj_tx_serdes
(
ppd
);
}
}
ret
=
0
;
goto
done
;
}
}
printk
(
KERN_INFO
QIB_DRV_NAME
" %s: Only %u of %u fields provided, skipping
\n
"
,
__func__
,
nf
,
N_QME_FIELDS
);
done:
kfree
(
abuf
);
return
ret
;
}
#define SJA_EN SYM_MASK(SPC_JTAG_ACCESS_REG, SPC_JTAG_ACCESS_EN)
#define BISTEN_LSB SYM_LSB(SPC_JTAG_ACCESS_REG, bist_en)
...
...
drivers/infiniband/hw/qib/qib_init.c
浏览文件 @
767dcd42
...
...
@@ -1237,7 +1237,13 @@ static int __devinit qib_init_one(struct pci_dev *pdev,
*/
switch
(
ent
->
device
)
{
case
PCI_DEVICE_ID_QLOGIC_IB_6120
:
#ifdef CONFIG_PCI_MSI
dd
=
qib_init_iba6120_funcs
(
pdev
,
ent
);
#else
qib_early_err
(
&
pdev
->
dev
,
"QLogic PCIE device 0x%x cannot "
"work if CONFIG_PCI_MSI is not enabled
\n
"
,
ent
->
device
);
#endif
break
;
case
PCI_DEVICE_ID_QLOGIC_IB_7220
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录