aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb4/t4_hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/cxgb4/t4_hw.c')
-rw-r--r--drivers/net/cxgb4/t4_hw.c117
1 files changed, 61 insertions, 56 deletions
diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c
index a814a3afe123..da272a98fdbc 100644
--- a/drivers/net/cxgb4/t4_hw.c
+++ b/drivers/net/cxgb4/t4_hw.c
@@ -53,8 +53,8 @@
53 * at the time it indicated completion is stored there. Returns 0 if the 53 * at the time it indicated completion is stored there. Returns 0 if the
54 * operation completes and -EAGAIN otherwise. 54 * operation completes and -EAGAIN otherwise.
55 */ 55 */
56int t4_wait_op_done_val(struct adapter *adapter, int reg, u32 mask, 56static int t4_wait_op_done_val(struct adapter *adapter, int reg, u32 mask,
57 int polarity, int attempts, int delay, u32 *valp) 57 int polarity, int attempts, int delay, u32 *valp)
58{ 58{
59 while (1) { 59 while (1) {
60 u32 val = t4_read_reg(adapter, reg); 60 u32 val = t4_read_reg(adapter, reg);
@@ -109,9 +109,9 @@ void t4_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask,
109 * Reads registers that are accessed indirectly through an address/data 109 * Reads registers that are accessed indirectly through an address/data
110 * register pair. 110 * register pair.
111 */ 111 */
112void t4_read_indirect(struct adapter *adap, unsigned int addr_reg, 112static void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
113 unsigned int data_reg, u32 *vals, unsigned int nregs, 113 unsigned int data_reg, u32 *vals,
114 unsigned int start_idx) 114 unsigned int nregs, unsigned int start_idx)
115{ 115{
116 while (nregs--) { 116 while (nregs--) {
117 t4_write_reg(adap, addr_reg, start_idx); 117 t4_write_reg(adap, addr_reg, start_idx);
@@ -120,6 +120,7 @@ void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
120 } 120 }
121} 121}
122 122
123#if 0
123/** 124/**
124 * t4_write_indirect - write indirectly addressed registers 125 * t4_write_indirect - write indirectly addressed registers
125 * @adap: the adapter 126 * @adap: the adapter
@@ -132,15 +133,16 @@ void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
132 * Writes a sequential block of registers that are accessed indirectly 133 * Writes a sequential block of registers that are accessed indirectly
133 * through an address/data register pair. 134 * through an address/data register pair.
134 */ 135 */
135void t4_write_indirect(struct adapter *adap, unsigned int addr_reg, 136static void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
136 unsigned int data_reg, const u32 *vals, 137 unsigned int data_reg, const u32 *vals,
137 unsigned int nregs, unsigned int start_idx) 138 unsigned int nregs, unsigned int start_idx)
138{ 139{
139 while (nregs--) { 140 while (nregs--) {
140 t4_write_reg(adap, addr_reg, start_idx++); 141 t4_write_reg(adap, addr_reg, start_idx++);
141 t4_write_reg(adap, data_reg, *vals++); 142 t4_write_reg(adap, data_reg, *vals++);
142 } 143 }
143} 144}
145#endif
144 146
145/* 147/*
146 * Get the reply to a mailbox command and store it in @rpl in big-endian order. 148 * Get the reply to a mailbox command and store it in @rpl in big-endian order.
@@ -345,33 +347,21 @@ int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *ecc)
345 return 0; 347 return 0;
346} 348}
347 349
348#define VPD_ENTRY(name, len) \
349 u8 name##_kword[2]; u8 name##_len; u8 name##_data[len]
350
351/* 350/*
352 * Partial EEPROM Vital Product Data structure. Includes only the ID and 351 * Partial EEPROM Vital Product Data structure. Includes only the ID and
353 * VPD-R sections. 352 * VPD-R header.
354 */ 353 */
355struct t4_vpd { 354struct t4_vpd_hdr {
356 u8 id_tag; 355 u8 id_tag;
357 u8 id_len[2]; 356 u8 id_len[2];
358 u8 id_data[ID_LEN]; 357 u8 id_data[ID_LEN];
359 u8 vpdr_tag; 358 u8 vpdr_tag;
360 u8 vpdr_len[2]; 359 u8 vpdr_len[2];
361 VPD_ENTRY(pn, 16); /* part number */
362 VPD_ENTRY(ec, EC_LEN); /* EC level */
363 VPD_ENTRY(sn, SERNUM_LEN); /* serial number */
364 VPD_ENTRY(na, 12); /* MAC address base */
365 VPD_ENTRY(port_type, 8); /* port types */
366 VPD_ENTRY(gpio, 14); /* GPIO usage */
367 VPD_ENTRY(cclk, 6); /* core clock */
368 VPD_ENTRY(port_addr, 8); /* port MDIO addresses */
369 VPD_ENTRY(rv, 1); /* csum */
370 u32 pad; /* for multiple-of-4 sizing and alignment */
371}; 360};
372 361
373#define EEPROM_STAT_ADDR 0x7bfc 362#define EEPROM_STAT_ADDR 0x7bfc
374#define VPD_BASE 0 363#define VPD_BASE 0
364#define VPD_LEN 512
375 365
376/** 366/**
377 * t4_seeprom_wp - enable/disable EEPROM write protection 367 * t4_seeprom_wp - enable/disable EEPROM write protection
@@ -396,16 +386,36 @@ int t4_seeprom_wp(struct adapter *adapter, bool enable)
396 */ 386 */
397static int get_vpd_params(struct adapter *adapter, struct vpd_params *p) 387static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
398{ 388{
399 int ret; 389 int i, ret;
400 struct t4_vpd vpd; 390 int ec, sn, v2;
401 u8 *q = (u8 *)&vpd, csum; 391 u8 vpd[VPD_LEN], csum;
392 unsigned int vpdr_len;
393 const struct t4_vpd_hdr *v;
402 394
403 ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(vpd), &vpd); 395 ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(vpd), vpd);
404 if (ret < 0) 396 if (ret < 0)
405 return ret; 397 return ret;
406 398
407 for (csum = 0; q <= vpd.rv_data; q++) 399 v = (const struct t4_vpd_hdr *)vpd;
408 csum += *q; 400 vpdr_len = pci_vpd_lrdt_size(&v->vpdr_tag);
401 if (vpdr_len + sizeof(struct t4_vpd_hdr) > VPD_LEN) {
402 dev_err(adapter->pdev_dev, "bad VPD-R length %u\n", vpdr_len);
403 return -EINVAL;
404 }
405
406#define FIND_VPD_KW(var, name) do { \
407 var = pci_vpd_find_info_keyword(&v->id_tag, sizeof(struct t4_vpd_hdr), \
408 vpdr_len, name); \
409 if (var < 0) { \
410 dev_err(adapter->pdev_dev, "missing VPD keyword " name "\n"); \
411 return -EINVAL; \
412 } \
413 var += PCI_VPD_INFO_FLD_HDR_SIZE; \
414} while (0)
415
416 FIND_VPD_KW(i, "RV");
417 for (csum = 0; i >= 0; i--)
418 csum += vpd[i];
409 419
410 if (csum) { 420 if (csum) {
411 dev_err(adapter->pdev_dev, 421 dev_err(adapter->pdev_dev,
@@ -413,12 +423,18 @@ static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
413 return -EINVAL; 423 return -EINVAL;
414 } 424 }
415 425
416 p->cclk = simple_strtoul(vpd.cclk_data, NULL, 10); 426 FIND_VPD_KW(ec, "EC");
417 memcpy(p->id, vpd.id_data, sizeof(vpd.id_data)); 427 FIND_VPD_KW(sn, "SN");
428 FIND_VPD_KW(v2, "V2");
429#undef FIND_VPD_KW
430
431 p->cclk = simple_strtoul(vpd + v2, NULL, 10);
432 memcpy(p->id, v->id_data, ID_LEN);
418 strim(p->id); 433 strim(p->id);
419 memcpy(p->ec, vpd.ec_data, sizeof(vpd.ec_data)); 434 memcpy(p->ec, vpd + ec, EC_LEN);
420 strim(p->ec); 435 strim(p->ec);
421 memcpy(p->sn, vpd.sn_data, sizeof(vpd.sn_data)); 436 i = pci_vpd_info_field_size(vpd + sn - PCI_VPD_INFO_FLD_HDR_SIZE);
437 memcpy(p->sn, vpd + sn, min(i, SERNUM_LEN));
422 strim(p->sn); 438 strim(p->sn);
423 return 0; 439 return 0;
424} 440}
@@ -537,8 +553,8 @@ static int flash_wait_op(struct adapter *adapter, int attempts, int delay)
537 * (i.e., big-endian), otherwise as 32-bit words in the platform's 553 * (i.e., big-endian), otherwise as 32-bit words in the platform's
538 * natural endianess. 554 * natural endianess.
539 */ 555 */
540int t4_read_flash(struct adapter *adapter, unsigned int addr, 556static int t4_read_flash(struct adapter *adapter, unsigned int addr,
541 unsigned int nwords, u32 *data, int byte_oriented) 557 unsigned int nwords, u32 *data, int byte_oriented)
542{ 558{
543 int ret; 559 int ret;
544 560
@@ -870,22 +886,6 @@ int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port)
870 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); 886 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
871} 887}
872 888
873/**
874 * t4_set_vlan_accel - configure HW VLAN extraction
875 * @adap: the adapter
876 * @ports: bitmap of adapter ports to operate on
877 * @on: enable (1) or disable (0) HW VLAN extraction
878 *
879 * Enables or disables HW extraction of VLAN tags for the ports specified
880 * by @ports. @ports is a bitmap with the ith bit designating the port
881 * associated with the ith adapter channel.
882 */
883void t4_set_vlan_accel(struct adapter *adap, unsigned int ports, int on)
884{
885 ports <<= VLANEXTENABLE_SHIFT;
886 t4_set_reg_field(adap, TP_OUT_CONFIG, ports, on ? ports : 0);
887}
888
889struct intr_info { 889struct intr_info {
890 unsigned int mask; /* bits to check in interrupt status */ 890 unsigned int mask; /* bits to check in interrupt status */
891 const char *msg; /* message to print or NULL */ 891 const char *msg; /* message to print or NULL */
@@ -2608,12 +2608,14 @@ int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
2608 * @promisc: 1 to enable promiscuous mode, 0 to disable it, -1 no change 2608 * @promisc: 1 to enable promiscuous mode, 0 to disable it, -1 no change
2609 * @all_multi: 1 to enable all-multi mode, 0 to disable it, -1 no change 2609 * @all_multi: 1 to enable all-multi mode, 0 to disable it, -1 no change
2610 * @bcast: 1 to enable broadcast Rx, 0 to disable it, -1 no change 2610 * @bcast: 1 to enable broadcast Rx, 0 to disable it, -1 no change
2611 * @vlanex: 1 to enable HW VLAN extraction, 0 to disable it, -1 no change
2611 * @sleep_ok: if true we may sleep while awaiting command completion 2612 * @sleep_ok: if true we may sleep while awaiting command completion
2612 * 2613 *
2613 * Sets Rx properties of a virtual interface. 2614 * Sets Rx properties of a virtual interface.
2614 */ 2615 */
2615int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid, 2616int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
2616 int mtu, int promisc, int all_multi, int bcast, bool sleep_ok) 2617 int mtu, int promisc, int all_multi, int bcast, int vlanex,
2618 bool sleep_ok)
2617{ 2619{
2618 struct fw_vi_rxmode_cmd c; 2620 struct fw_vi_rxmode_cmd c;
2619 2621
@@ -2626,15 +2628,18 @@ int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
2626 all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_MASK; 2628 all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_MASK;
2627 if (bcast < 0) 2629 if (bcast < 0)
2628 bcast = FW_VI_RXMODE_CMD_BROADCASTEN_MASK; 2630 bcast = FW_VI_RXMODE_CMD_BROADCASTEN_MASK;
2631 if (vlanex < 0)
2632 vlanex = FW_VI_RXMODE_CMD_VLANEXEN_MASK;
2629 2633
2630 memset(&c, 0, sizeof(c)); 2634 memset(&c, 0, sizeof(c));
2631 c.op_to_viid = htonl(FW_CMD_OP(FW_VI_RXMODE_CMD) | FW_CMD_REQUEST | 2635 c.op_to_viid = htonl(FW_CMD_OP(FW_VI_RXMODE_CMD) | FW_CMD_REQUEST |
2632 FW_CMD_WRITE | FW_VI_RXMODE_CMD_VIID(viid)); 2636 FW_CMD_WRITE | FW_VI_RXMODE_CMD_VIID(viid));
2633 c.retval_len16 = htonl(FW_LEN16(c)); 2637 c.retval_len16 = htonl(FW_LEN16(c));
2634 c.mtu_to_broadcasten = htonl(FW_VI_RXMODE_CMD_MTU(mtu) | 2638 c.mtu_to_vlanexen = htonl(FW_VI_RXMODE_CMD_MTU(mtu) |
2635 FW_VI_RXMODE_CMD_PROMISCEN(promisc) | 2639 FW_VI_RXMODE_CMD_PROMISCEN(promisc) |
2636 FW_VI_RXMODE_CMD_ALLMULTIEN(all_multi) | 2640 FW_VI_RXMODE_CMD_ALLMULTIEN(all_multi) |
2637 FW_VI_RXMODE_CMD_BROADCASTEN(bcast)); 2641 FW_VI_RXMODE_CMD_BROADCASTEN(bcast) |
2642 FW_VI_RXMODE_CMD_VLANEXEN(vlanex));
2638 return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok); 2643 return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok);
2639} 2644}
2640 2645