@@ -137,27 +137,42 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
137137 struct qca8k_mgmt_eth_data * mgmt_eth_data ;
138138 struct qca8k_priv * priv = ds -> priv ;
139139 struct qca_mgmt_ethhdr * mgmt_ethhdr ;
140+ u32 command ;
140141 u8 len , cmd ;
142+ int i ;
141143
142144 mgmt_ethhdr = (struct qca_mgmt_ethhdr * )skb_mac_header (skb );
143145 mgmt_eth_data = & priv -> mgmt_eth_data ;
144146
145- cmd = FIELD_GET (QCA_HDR_MGMT_CMD , mgmt_ethhdr -> command );
146- len = FIELD_GET (QCA_HDR_MGMT_LENGTH , mgmt_ethhdr -> command );
147+ command = get_unaligned_le32 (& mgmt_ethhdr -> command );
148+ cmd = FIELD_GET (QCA_HDR_MGMT_CMD , command );
149+ len = FIELD_GET (QCA_HDR_MGMT_LENGTH , command );
147150
148151 /* Make sure the seq match the requested packet */
149- if (mgmt_ethhdr -> seq == mgmt_eth_data -> seq )
152+ if (get_unaligned_le32 ( & mgmt_ethhdr -> seq ) == mgmt_eth_data -> seq )
150153 mgmt_eth_data -> ack = true;
151154
152155 if (cmd == MDIO_READ ) {
153- mgmt_eth_data -> data [0 ] = mgmt_ethhdr -> mdio_data ;
156+ u32 * val = mgmt_eth_data -> data ;
157+
158+ * val = get_unaligned_le32 (& mgmt_ethhdr -> mdio_data );
154159
155160 /* Get the rest of the 12 byte of data.
156161 * The read/write function will extract the requested data.
157162 */
158- if (len > QCA_HDR_MGMT_DATA1_LEN )
159- memcpy (mgmt_eth_data -> data + 1 , skb -> data ,
160- QCA_HDR_MGMT_DATA2_LEN );
163+ if (len > QCA_HDR_MGMT_DATA1_LEN ) {
164+ __le32 * data2 = (__le32 * )skb -> data ;
165+ int data_len = min_t (int , QCA_HDR_MGMT_DATA2_LEN ,
166+ len - QCA_HDR_MGMT_DATA1_LEN );
167+
168+ val ++ ;
169+
170+ for (i = sizeof (u32 ); i <= data_len ; i += sizeof (u32 )) {
171+ * val = get_unaligned_le32 (data2 );
172+ val ++ ;
173+ data2 ++ ;
174+ }
175+ }
161176 }
162177
163178 complete (& mgmt_eth_data -> rw_done );
@@ -169,8 +184,10 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
169184 struct qca_mgmt_ethhdr * mgmt_ethhdr ;
170185 unsigned int real_len ;
171186 struct sk_buff * skb ;
172- u32 * data2 ;
187+ __le32 * data2 ;
188+ u32 command ;
173189 u16 hdr ;
190+ int i ;
174191
175192 skb = dev_alloc_skb (QCA_HDR_MGMT_PKT_LEN );
176193 if (!skb )
@@ -199,30 +216,44 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
199216 hdr |= FIELD_PREP (QCA_HDR_XMIT_DP_BIT , BIT (0 ));
200217 hdr |= FIELD_PREP (QCA_HDR_XMIT_CONTROL , QCA_HDR_XMIT_TYPE_RW_REG );
201218
202- mgmt_ethhdr -> command = FIELD_PREP (QCA_HDR_MGMT_ADDR , reg );
203- mgmt_ethhdr -> command |= FIELD_PREP (QCA_HDR_MGMT_LENGTH , real_len );
204- mgmt_ethhdr -> command |= FIELD_PREP (QCA_HDR_MGMT_CMD , cmd );
205- mgmt_ethhdr -> command |= FIELD_PREP (QCA_HDR_MGMT_CHECK_CODE ,
219+ command = FIELD_PREP (QCA_HDR_MGMT_ADDR , reg );
220+ command |= FIELD_PREP (QCA_HDR_MGMT_LENGTH , real_len );
221+ command |= FIELD_PREP (QCA_HDR_MGMT_CMD , cmd );
222+ command |= FIELD_PREP (QCA_HDR_MGMT_CHECK_CODE ,
206223 QCA_HDR_MGMT_CHECK_CODE_VAL );
207224
225+ put_unaligned_le32 (command , & mgmt_ethhdr -> command );
226+
208227 if (cmd == MDIO_WRITE )
209- mgmt_ethhdr -> mdio_data = * val ;
228+ put_unaligned_le32 ( * val , & mgmt_ethhdr -> mdio_data ) ;
210229
211230 mgmt_ethhdr -> hdr = htons (hdr );
212231
213232 data2 = skb_put_zero (skb , QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN );
214- if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN )
215- memcpy (data2 , val + 1 , len - QCA_HDR_MGMT_DATA1_LEN );
233+ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN ) {
234+ int data_len = min_t (int , QCA_HDR_MGMT_DATA2_LEN ,
235+ len - QCA_HDR_MGMT_DATA1_LEN );
236+
237+ val ++ ;
238+
239+ for (i = sizeof (u32 ); i <= data_len ; i += sizeof (u32 )) {
240+ put_unaligned_le32 (* val , data2 );
241+ data2 ++ ;
242+ val ++ ;
243+ }
244+ }
216245
217246 return skb ;
218247}
219248
220249static void qca8k_mdio_header_fill_seq_num (struct sk_buff * skb , u32 seq_num )
221250{
222251 struct qca_mgmt_ethhdr * mgmt_ethhdr ;
252+ u32 seq ;
223253
254+ seq = FIELD_PREP (QCA_HDR_MGMT_SEQ_NUM , seq_num );
224255 mgmt_ethhdr = (struct qca_mgmt_ethhdr * )skb -> data ;
225- mgmt_ethhdr -> seq = FIELD_PREP ( QCA_HDR_MGMT_SEQ_NUM , seq_num );
256+ put_unaligned_le32 ( seq , & mgmt_ethhdr -> seq );
226257}
227258
228259static int qca8k_read_eth (struct qca8k_priv * priv , u32 reg , u32 * val , int len )
@@ -1487,9 +1518,9 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk
14871518 struct qca8k_priv * priv = ds -> priv ;
14881519 const struct qca8k_mib_desc * mib ;
14891520 struct mib_ethhdr * mib_ethhdr ;
1490- int i , mib_len , offset = 0 ;
1491- u64 * data ;
1521+ __le32 * data2 ;
14921522 u8 port ;
1523+ int i ;
14931524
14941525 mib_ethhdr = (struct mib_ethhdr * )skb_mac_header (skb );
14951526 mib_eth_data = & priv -> mib_eth_data ;
@@ -1501,28 +1532,24 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk
15011532 if (port != mib_eth_data -> req_port )
15021533 goto exit ;
15031534
1504- data = mib_eth_data -> data ;
1535+ data2 = ( __le32 * ) skb -> data ;
15051536
15061537 for (i = 0 ; i < priv -> info -> mib_count ; i ++ ) {
15071538 mib = & ar8327_mib [i ];
15081539
15091540 /* First 3 mib are present in the skb head */
15101541 if (i < 3 ) {
1511- data [i ] = mib_ethhdr -> data [ i ] ;
1542+ mib_eth_data -> data [i ] = get_unaligned_le32 ( mib_ethhdr -> data + i ) ;
15121543 continue ;
15131544 }
15141545
1515- mib_len = sizeof (uint32_t );
1516-
15171546 /* Some mib are 64 bit wide */
15181547 if (mib -> size == 2 )
1519- mib_len = sizeof (uint64_t );
1520-
1521- /* Copy the mib value from packet to the */
1522- memcpy (data + i , skb -> data + offset , mib_len );
1548+ mib_eth_data -> data [i ] = get_unaligned_le64 ((__le64 * )data2 );
1549+ else
1550+ mib_eth_data -> data [i ] = get_unaligned_le32 (data2 );
15231551
1524- /* Set the offset for the next mib */
1525- offset += mib_len ;
1552+ data2 += mib -> size ;
15261553 }
15271554
15281555exit :
0 commit comments